📄 wm.c
字号:
static int FindNext_IVR(void) {
if (ClipContext.Cnt ==0) {
ClipContext.CurRect = GUI_Context.pAWin->Rect;
return 1; /* IVR is valid ! */
}
return 0; /* Nothing left to draw */
}
#endif
/*********************************************************************
*
* Get next IVR
Sets the next clipping rectangle. If a valid one has
been found (and set), 1 is returned in order to indicate
that the drawing operation needs to be executed.
Returning 0 signals that we have iterated over all
rectangles.
Returns: 0 if no valid rectangle is found
1 if rectangle has been found
*/
int WM__GetNextIVR (void) {
#if GUI_SUPPORT_CURSOR
static char _CursorHidden;
#endif
/* If WM is not active, we have no rectangles to return */
if (WM_IsActive==0)
return 0;
if (ClipContext.EntranceCnt > 1) {
ClipContext.EntranceCnt--;
return 0;
}
#if GUI_SUPPORT_CURSOR
if (_CursorHidden) {
_CursorHidden = 0;
(*GUI_CURSOR_pfTempUnhide) ();
}
#endif
++ClipContext.Cnt;
/* Find next rectangle and use it as ClipRect */
if (!FindNext_IVR()) {
ClipContext.EntranceCnt--; /* This search is over ! */
return 0; /* Could not find an other one ! */
}
/* Hide cursor if necessary */
LCD_SetClipRectEx(&ClipContext.CurRect);
#if GUI_SUPPORT_CURSOR
if (GUI_CURSOR_pfTempHide) {
_CursorHidden = (*GUI_CURSOR_pfTempHide) ( &ClipContext.CurRect);
}
#endif
return 1;
}
/*********************************************************************
*
* Init IVR search
This routine is called from the clipping level
(the WM_ITERATE_START macro) when starting an iteration over the
visible rectangles.
Return value:
0 : There is no valid rectangle (nothing to do ...)
1 : There is a valid rectangle
*/
int WM__InitIVRSearch(const GUI_RECT* pMaxRect) {
GUI_RECT r;
WM_Obj* pAWin;
/* If WM is not active -> nothing to do, leave cliprect alone */
if (WM_IsActive==0)
return 1;
/* If we entered multiple times, leave Cliprect alone */
if (++ClipContext.EntranceCnt > 1)
return 1;
pAWin = WM_H2P(GUI_Context.hAWin);
ClipContext.Cnt = -1;
/* When using callback mechanism, it is legal to reduce drawing
area to the invalid area ! */
if (IsInCallback) {
WM__GetInvalidRectAbs(pAWin, &r);
} else { /* Not using callback mechanism, therefor allow entire rectangle */
if (pAWin->Status & WM_SF_ISVIS) {
r = pAWin->Rect;
} else {
--ClipContext.EntranceCnt;
return 0; /* window is not even visible ! */
}
}
/* If the drawing routine has specified a rectangle, use it to reduce the rectangle */
if (pMaxRect) {
GUI__IntersectRect(&r, pMaxRect);
}
/* If user has reduced the cliprect size, reduce the rectangle */
if (GUI_Context.WM__pUserClipRect) {
GUI_RECT rUser = *(GUI_Context.WM__pUserClipRect);
WM__Client2Screen(pAWin, &rUser);
GUI__IntersectRect(&r, &rUser);
}
/* Iterate over all ancestors and clip at their borders */
_ClipAtParentBorders(&r, pAWin);
/* Store the rectangle and find the first rectangle of the area */
ClipContext.ClientRect = r;
return WM__GetNextIVR();
}
/*
********************************************
* *
* Set default *
* *
********************************************
This routine sets the defaults for WM and the layers below.
It is used before a drawing routine is called in order to
make sure that defaults are set (in case the default settings
had been altered before by the application)
*/
void WM_SetDefault(void) {
GL_SetDefault();
GUI_Context.WM__pUserClipRect = NULL; /* No add. clipping */
}
/*
********************************************
*
* Callback for Paint message
*
********************************************
This callback is used by the window manger in conjunction with banding
memory devices. A pointer to this routine is given to the banding memory device.
This callback in turn will send the paint message to the window.
*/
#if GUI_SUPPORT_MEMDEV
static void cbPaint(void* pMsg) {
WM_SendMessage(((WM_MESSAGE*)pMsg)->hWin, (WM_MESSAGE*) pMsg);
}
#endif
/*
********************************************
* *
* Draw next window *
* *
********************************************
*/
static void _DrawNext(void) {
int UpdateRem = 1;
WM_HWIN iWin = (NextDrawWin == WM_HWIN_NULL) ? WM__FirstWin : NextDrawWin;
GUI_CONTEXT ContextOld;
GUI_SaveContext(&ContextOld);
/* Make sure the next window to redraw is valid */
for (; (iWin!=WM_HWIN_NULL) && UpdateRem; ) {
WM_Obj* pWin = WM_H2P(iWin);
if (pWin->Status & WM_SF_INVALID) {
U8 Status = (pWin->Status &= ~WM_SF_INVALID); /* Clear invalid flag */
WM__NumInvalidWindows--;
/* Send WM_PAINT if window is visible and a callback is defined */
if ((pWin->cb != NULL) && (Status & WM_SF_ISVIS)) {
WM_MESSAGE Msg;
Msg.hWin = iWin;
Msg.MsgId = WM_PAINT;
Msg.Data.p = (GUI_RECT*)&pWin->InvalidRect;
WM_SelectWindow(iWin);
WM_SetDefault();
#if GUI_SUPPORT_MEMDEV
if (Status & WM_SF_MEMDEV) {
GUI_RECT r = pWin->InvalidRect;
GUI_MoveRect (&r, pWin->Rect.x0, pWin->Rect.y0);
GUI_MEMDEV_Draw(&r, cbPaint, &Msg, 0, (Status & WM_SF_HASTRANS) ? GUI_MEMDEV_HASTRANS : 0);
} else
#endif
WM_SendMessage(iWin, &Msg);
UpdateRem--; /* Only the given number of windows at a time ... */
}
}
iWin = pWin->hNextLin;
}
NextDrawWin = iWin; /* Remember the window */
GUI_RestoreContext(&ContextOld);
}
/*
*****************************************************************
* *
* Idle loop *
* *
*****************************************************************
*/
int WM_Exec1(void) {
/* Poll PID if necessary */
if (WM_pfPollPID) {
WM_pfPollPID();
}
if (WM_pfHandlePID) {
if (WM_pfHandlePID())
return 1; /* We have done something ... */
}
if (GUI_PollKeyMsg()) {
return 1; /* We have done something ... */
}
if (WM_IsActive && WM__NumInvalidWindows) {
WM_LOCK();
_DrawNext();
WM_UNLOCK();
return 1; /* We have done something ... */
}
return 0; /* There was nothing to do ... */
}
int WM_Exec(void) {
int r = 0;
while (WM_Exec1()) {
r = 1; /* We have done something */
}
return r;
}
/****************************************************************
* *
* Callback for background window *
* *
*****************************************************************
*/
static WM_RESULT cbBackWin( WM_MESSAGE* pMsg) {
WM_KEY_INFO* pKeyInfo;
switch (pMsg->MsgId) {
case WM_KEY:
pKeyInfo = (WM_KEY_INFO*)pMsg->Data.p;
if (pKeyInfo->PressedCnt == 0) {
GUI_StoreKey(pKeyInfo->Key);
}
break;
case WM_PAINT:
if (WM__BkColor != GUI_INVALID_COLOR) {
GUI_SetBkColor(WM__BkColor);
GUI_Clear();
}
default:
WM_DefaultProc(pMsg);
}
}
/****************************************************************
*
* WM_Activate / WM_Deactivate
*
*****************************************************************
*/
void WM_Activate(void) {
WM_IsActive = 1; /* Running */
}
void WM_Deactivate(void) {
WM_IsActive = 0; /* No clipping performed by WM */
WM__SetMaxClipRect(WM_H2P(WM_HBKWIN));
}
/*
*****************************************************************
* *
* WM_Init *
* *
*****************************************************************
*/
void WM_Init(void) {
if (!_IsInited) {
WM_HWIN hWin;
NextDrawWin = WM__FirstWin = WM_HWIN_NULL;
GUI_Context.WM__pUserClipRect = NULL;
WM__NumWindows = WM__NumInvalidWindows =0;
/* Make sure we have at least one window. This greatly simplifies the
drawing routines as they do not have to check if the window is valid.
*/
hWin = WM_CreateWindow(0, 0, GUI_XMAX, GUI_YMAX, WM_CF_SHOW, cbBackWin, 0);
WM_SelectWindow(hWin);
WM_Activate();
_IsInited =1;
}
}
/*
******************************************************
* *
* Default procedure *
* *
******************************************************
*/
WM_RESULT WM_DefaultProc(WM_MESSAGE* pMsg) {
WM_HWIN hWin = pMsg->hWin;
void *p = pMsg->Data.p;
WM_Obj* pWin = WM_H2P(hWin);
/* Exec message */
switch (pMsg->MsgId) {
case WM_GETCLIENTRECT: /* return client window in window coordinates */
WM__GetClientRectWin(pWin, (GUI_RECT*)p);
break;
case WM_GETORG:
((GUI_POINT*)p)->x = pWin->Rect.x0;
((GUI_POINT*)p)->y = pWin->Rect.y0;
break;
case WM_GET_INSIDE_RECT: /* return client window in absolute (screen) coordinates */
WM__GetClientRectWin(pWin, (GUI_RECT*)p);
break;
case WM_GET_CLIENT_WINDOW: /* return handle to client window. For most windows, there is no seperate client window, so it is the same handle */
pMsg->Data.v = hWin;
return; /* Message handled */
case WM_KEY:
WM_SendToParent(hWin, pMsg);
return; /* Message handled */
case WM_GET_BKCOLOR:
pMsg->Data.Color = GUI_INVALID_COLOR;
return; /* Message handled */
}
/* Message not handled. If it queries something, we return 0 to be on the safe side. */
pMsg->Data.v = 0;
pMsg->Data.p = 0;
}
#else
void WM(void) {} /* avoid empty object files */
#endif /* WM_MAX_WINDOW */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -