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

📄 wm.c

📁 MCB2300_ucgui_LCD320240.rar LPC2368的uc/gui的移植
💻 C
📖 第 1 页 / 共 4 页
字号:
/*
*********************************************************************************************************
*   											 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		: WM.C
Purpose 	: Windows manager core
----------------------------------------------------------------------
*/

#include <stddef.h> 		  /* needed for definition of NULL */
#include <string.h> 		  /* required for memset */

#define WM_C
#include "WM_Intern_ConfDep.h"

#if GUI_WINSUPPORT    /* If 0, WM will not generate any code */

/*********************************************************************
*
*   			  Macros for internal use
*
**********************************************************************
*/

#define ASSIGN_IF_LESS(v0,v1) if (v1<v0) v0=v1

/*********************************************************************
*
*   		   Local typedefs
*
**********************************************************************
*/

typedef struct
{
	GUI_RECT	ClientRect;
	GUI_RECT	CurRect;
	int			Cnt;
	int			EntranceCnt;
} WM_IVR_CONTEXT;

/*********************************************************************
*
*   		   global data
*
**********************************************************************
*/

U8  				   WM_IsActive;
U16 				   WM__CreateFlags;
WM_HWIN 			   WM__hCapture;
WM_HWIN 			   WM__hWinFocus;
char				   WM__CaptureReleaseAuto;
WM_tfPollPID*   	   WM_pfPollPID;
U8  				   WM__PaintCallbackCnt;	  /* Public for assertions only */
GUI_PID_STATE   	   WM_PID__StateLast;

#if WM_SUPPORT_TRANSPARENCY
int 				   WM__TransWindowCnt;
WM_HWIN 			   WM__hATransWindow;
#endif

#if WM_SUPPORT_DIAG
void (*WM__pfShowInvalid)(WM_HWIN hWin);
#endif

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

static WM_HWIN  	  NextDrawWin;
static WM_IVR_CONTEXT _ClipContext;
static char 		  _IsInited;

/*********************************************************************
*
*   	Static routines
*
**********************************************************************
*/
/*********************************************************************
*
*   	_CheckCriticalHandles
*
* Purpose:
*   Checks the critical handles and resets the matching one
*/
static void _CheckCriticalHandles(WM_HWIN hWin)
{
	WM_CRITICAL_HANDLE * pCH;
	for (pCH = WM__pFirstCriticalHandle; pCH; pCH = pCH->pNext)
	{
		if (pCH->hWin == hWin)
		{
			pCH->hWin = 0;
		}
	}
}

/*********************************************************************
*
*   	_DesktopHandle2Index
*
* Function:
*   Convert the given desktop window into the display index.
*
* Return value:
*   Desktop index if window handle is valid.
*   else: -1
*/
static int _DesktopHandle2Index(WM_HWIN hDesktop)
{
#if GUI_NUM_LAYERS > 1
	int i;
	for (i = 0; i < GUI_NUM_LAYERS; i++)
	{
		if (hDesktop == WM__ahDesktopWin[i])
		{
			return i;
		}
	}
#else
	if (hDesktop == WM__ahDesktopWin[0])
	{
		return 0;
	}
#endif
	return -1;
}

/*********************************************************************
*
*   	_Invalidate1Abs
*
*  Invalidate given window, using absolute coordinates
*/
static void _Invalidate1Abs(WM_HWIN hWin, const GUI_RECT *pRect)
{
	GUI_RECT r;
	WM_Obj* pWin;
	int Status;
	pWin = WM_H2P(hWin);
	Status = pWin->Status;
	if ((Status & WM_SF_ISVIS) == 0)
	{
		return;   /* Window is not visible... we are done */
	}
	if ((Status & (WM_SF_HASTRANS | WM_SF_CONST_OUTLINE)) == WM_SF_HASTRANS)
	{
		return;   /* Window is transparent; transparency may change... we are done, since background will be invalidated */
	}
	if (WM__RectIsNZ(pRect) == 0)
	{
		return;   /* Nothing to do ... */
	}
	/* Calc affected area */
	GUI__IntersectRects(&r, pRect, &pWin->Rect);
	if (WM__RectIsNZ(&r))
	{
#if WM_SUPPORT_NOTIFY_VIS_CHANGED
		WM__SendMsgNoData(hWin, WM_NOTIFY_VIS_CHANGED); 			/* Notify window that visibility may have changed */
#endif

		if (pWin->Status & WM_SF_INVALID)
		{
			GUI_MergeRect(&pWin->InvalidRect, &pWin->InvalidRect, &r);
		}
		else
		{
			pWin->InvalidRect = r;
			pWin->Status |= WM_SF_INVALID;
			WM__NumInvalidWindows++;
			/* Optional code: Call external routine to notify that drawing is required */
#ifdef GUI_X_REDRAW
			{
				GUI_RECT r;
				r = pWin->Rect;
				if (WM__ClipAtParentBorders(&r, hWin))
				{
					GUI_X_REDRAW(); /* Call hook function to signal an invalidation */
				}
			}
#endif
			GUI_X_SIGNAL_EVENT();
		}
		/* Debug code: shows invalid areas */
#if (WM_SUPPORT_DIAG)
		if (WM__pfShowInvalid)
		{
			(WM__pfShowInvalid) (hWin);
		}
#endif
	}
}

/*********************************************************************
*
*   	_GetTopLevelWindow
*/
#if GUI_NUM_LAYERS > 1
static WM_HWIN _GetTopLevelWindow(WM_HWIN hWin)
{
	WM_Obj* pWin;
	WM_HWIN hTop;
	while (hTop = hWin, pWin = WM_H2P(hWin), (hWin = pWin->hParent) != 0)
	{
	}
	return hTop;
}
#endif

/*********************************************************************
*
*   	ResetNextDrawWin

  When drawing, we have to start at the bottom window !
*/
static void ResetNextDrawWin(void)
{
	NextDrawWin = WM_HWIN_NULL;
}


/*********************************************************************
*
*   	_GethDrawWin
*
* Return Window being drawn.
* Normally same as pAWin, except if overlaying transparent window is drawn
*
*/
static WM_HWIN _GethDrawWin(void)
{
	WM_HWIN h;
#if WM_SUPPORT_TRANSPARENCY
	if (WM__hATransWindow)
	{
		h = WM__hATransWindow;
	}
	else
	  #endif
	{
		h = GUI_Context.hAWin;
	}
	return h;
}





/*********************************************************************
*
*   	_SetClipRectUserIntersect
*/
static void _SetClipRectUserIntersect(const GUI_RECT *prSrc)
{
	if (GUI_Context.WM__pUserClipRect == NULL)
	{
		LCD_SetClipRectEx(prSrc);
	}
	else
	{
		GUI_RECT r;
		r = *GUI_Context.WM__pUserClipRect; 			
		WM__Client2Screen(WM_H2P(_GethDrawWin()), &r);     /* Convert User ClipRect into screen coordinates */
		/* Set intersection as clip rect */    
		GUI__IntersectRect(&r, prSrc);
		LCD_SetClipRectEx(&r);
	}
}


/*********************************************************************
*
*   	Public routines
*
**********************************************************************
*/
/*********************************************************************
*
*   	WM__ClipAtParentBorders
*
* Function:
*   Iterates over the window itself and all its ancestors.
*   Intersects all rectangles to
*   find out which part is actually visible.
*   Reduces the rectangle to the visible area.
*   This routines takes into account both the rectangles of the
*   ancestors as well as the WM_SF_ISVIS flag.
*
* Parameters
*   hWin	Obvious
*   pRect   Pointer to the rectangle to be clipped. May not be NULL.
*   		The parameter is IN/OUT.
*   		Note that the rectangle is clipped only if the return
*   		value indicates a valid rectangle remains.
*
* Return value:
*   1: Something is or may be visible.
*   0: Nothing is visible (outside of ancestors, no desktop, hidden)
*/
int WM__ClipAtParentBorders(GUI_RECT *pRect, WM_HWIN hWin)
{
	WM_Obj* pWin;

	/* Iterate up the window hierarchy.
	   If the window is invisible, we are done.
	   Clip at parent boarders.
	   We are done with iterating if hWin has no parent.
	*/
	do
	{
		pWin = WM_H2P(hWin);
		if ((pWin->Status & WM_SF_ISVIS) == 0)
		{
			return 0;   				  /* Invisible */
		}
		GUI__IntersectRect(pRect, &pWin->Rect);  /* And clip on borders */
		if (pWin->hParent == 0)
		{
			break;   /* hWin is now the top level window which has no parent */
		}
		hWin = pWin->hParent;   				 /* Go one level up (parent)*/
	}
	while (1);  							 /* Only way out is in the loop. Required for efficiency, no bug, even though some compilers may complain. */

	/* Now check if the top level window is a desktop window. If it is not,
	  then the window is not visible.
	*/
	if (_DesktopHandle2Index(hWin) < 0)
	{
		return 0;   		/* No desktop - (unattached) - Nothing to draw */
	}
	return 1;   			/* Something may be visible */
}

/*********************************************************************
*
*   	WM__ActivateClipRect
*/
void WM__ActivateClipRect(void)
{
	if (WM_IsActive)
	{
		_SetClipRectUserIntersect(&_ClipContext.CurRect);
	}
	else
	{
		/* Window manager disabled, typically because meory device is active */
		GUI_RECT r;
		WM_Obj *pAWin;
		pAWin = WM_H2P(GUI_Context.hAWin);
		r = pAWin->Rect;
#if WM_SUPPORT_TRANSPARENCY
		if (WM__hATransWindow)
		{
			WM__ClipAtParentBorders(&r, WM__hATransWindow);
		}
#endif
		/* Take UserClipRect into account */
		_SetClipRectUserIntersect(&r);
	}
}




/*********************************************************************
*
*   	WM__InsertWindowIntoList
*
* Routine describtion
*   This routine inserts the window in the list of child windows for
*   a particular parent window.
*   The window is placed on top of all siblings with the same level.
*/
void WM__InsertWindowIntoList(WM_HWIN hWin, WM_HWIN hParent)
{
	int OnTop;
	WM_HWIN hi;
	WM_Obj * pWin;
	WM_Obj * pParent;
	WM_Obj * pi;

	if (hParent)
	{
		pWin = WM_H2P(hWin);
		pWin->hNext = 0;
		pWin->hParent = hParent;
		pParent = WM_H2P(hParent);
		OnTop = pWin->Status & WM_CF_STAYONTOP;
		hi = pParent->hFirstChild;
		/* Put it at beginning of the list if there is no child */
		if (hi == 0)
		{
			/* No child yet ... Makes things easy ! */
			pParent->hFirstChild = hWin;
			return; 						/* Early out ... We are done */
		}
		/* Put it at beginning of the list if first child is a TOP window and new one is not */
		pi = WM_H2P(hi);
		if (!OnTop)
		{
			if (pi->Status & WM_SF_STAYONTOP)
			{
				pWin->hNext = hi;
				pParent->hFirstChild = hWin;
				return; 						/* Early out ... We are done */
			}
		}
		/* Put it at the end of the list or before the last non "STAY-ON-TOP" child */
		do
		{
			WM_Obj* pNext;
			WM_HWIN hNext;
			if ((hNext = pi->hNext) == 0)
			{
				/* End of sibling list ? */
				pi->hNext = hWin;   		  /* Then modify this last element to point to new one and we are done */
				break;
			}
			pNext = WM_H2P(hNext);
			if (!OnTop)
			{
				if (pNext->Status & WM_SF_STAYONTOP)
				{
					pi->hNext = hWin;
					pWin->hNext = hNext;
					break;
				}
			}
			pi = pNext;
		}
		while (1);
#if WM_SUPPORT_NOTIFY_VIS_CHANGED
		WM__NotifyVisChanged(hWin, &pWin->Rect);
#endif
	}
}

/*********************************************************************
*
*   	WM__RemoveWindowFromList
*/
void WM__RemoveWindowFromList(WM_HWIN hWin)
{
	WM_HWIN hi, hParent;
	WM_Obj * pWin, *pParent, *pi;

	pWin = WM_H2P(hWin);
	hParent = pWin->hParent;
	if (hParent)
	{
		pParent = WM_H2P(hParent);
		hi = pParent->hFirstChild;
		if (hi == hWin)
		{
			pi = WM_H2P(hi);
			pParent->hFirstChild = pi->hNext;
		}
		else
		{
			while (hi)
			{
				pi = WM_H2P(hi);
				if (pi->hNext == hWin)
				{
					pi->hNext = pWin->hNext;
					break;
				}
				hi = pi->hNext;
			}
		}
	}
}

/*********************************************************************
*
*   	WM__DetachWindow
*
* Detaches the given window. The window still exists, it keeps all
* children, but it is no longer visible since it is taken out of
* the tree of the desktop window.

⌨️ 快捷键说明

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