📄 pw_window.c
字号:
/* * Check if this GC applays to whole window * area or just a part of window area */ if (PW_NULL == clip) { /* GC applays to whole window area */ gc->clip_reg.regs = win->clip_reg.regs; gc->clip_reg.regs_num = win->clip_reg.regs_num; IPW_RECT_COPY(&gc->clip_reg.bounds, &win->clip_reg.bounds); } else { /* GC applays only to a part of window area */ Pw_Rectangle r; Pw_Region* wreg; Pw_Region* greg; IPW_TRACE_RECT(WN1, clip); gc->clip_reg.regs = PW_NULL; gc->clip_reg.regs_num = 0; IPW_RECT_EMPTY(&gc->clip_reg.bounds); IPW_TRACE_RLIST(WN1, &win->clip_reg); greg = PW_NULL; wreg = win->clip_reg.regs; while (PW_NULL != wreg) { IPW_RECT_COPY(&r, &wreg->area); if (IPw_RectIntersect(&r, clip)) { if (0 == gc->clip_reg.regs_num) { IPW_RECT_COPY(&gc->clip_reg.bounds, &r); greg = gc->clip_reg.regs = IPw_RegionNew(); } else { IPw_RectUnionize(&gc->clip_reg.bounds, &r); greg->next = IPw_RegionNew(); greg = greg->next; } IPW_FAIL(PW_NULL != greg, ("Out of free regions!")); IPW_RECT_COPY(&greg->area, &r); gc->clip_reg.regs_num++; IPW_TRACE_RECT(WN1, &greg->area); IPW_TRACE_RLIST(WN1, &gc->clip_reg); } wreg = wreg->next; } } IPW_TRACE_RLIST(WN1, &gc->clip_reg); IPW_CHECK_GC(gc); IPW_TRACE_EXIT_V(WN2, d, (gc->clip_reg.regs_num > 0)); return(gc->clip_reg.regs_num > 0);}/** * Destroys graphic context @p gc. * @param gc pointer to gc * @internal */ static void _WindowDestroyGC(Pw_GC* gc){ IPW_TRACE_ENTER(WN2); IPW_CHECK_PTR(gc); IPW_CHECK_GC(gc); IPW_TRACE2(WN1, p, gc->clip_reg.regs, gc->d.comp.window->clip_reg.regs); /* * If gc doesn't have any extra clip, then the clip region * points to its window clip region - so we must not free it! * See _WindowCreateGC */ if (gc->clip_reg.regs != gc->d.comp.window->clip_reg.regs) IPw_RegionFreeList(gc->clip_reg.regs); IPW_TRACE_EXIT(WN2);}/** * Repaints the region @p clip of window @p win and its children if requested. * If the region @p clip equals NULL the whole window is repainted. * @param win pointer to window * @param clip pointer to clip rectangle (area of window @p win to repaint) * @param repaint_childs if true repaint all window @p win children * @internal */ static void _WindowRepaint(Pw_Window* win, Pw_Rectangle* clip, Pw_Bool repaint_childs){ IPW_TRACE_ENTER(WN2); IPW_CHECK_PTR(win); IPW_CHECK_WINDOW(win); IPW_TRACE3M(WN1, p, win, p, clip, d, repaint_childs); /* Start repaint only if this window is visible and mapped */
if (_WINDOW_IS_CLIP_REGION_NON_EMPTY(win) && win->mapped) { Pw_GC gc; /* * Get this window gc and continue with repaint * only if gc's clip region is nonempty */ if (_WindowCreateGC(win, clip, &gc)) { /* Send repaint event */ IPw_EventSendRepaint(win, &gc); /* Repaint this window children if requested */ if (repaint_childs) { Pw_Window* cld_win; /* Child window */ cld_win = win->children; while (PW_NULL != cld_win) { IPW_TRACE1(WN1, p, cld_win); _WindowRepaint(cld_win, clip, TRUE); cld_win = cld_win->next; } } _WindowDestroyGC(&gc); } } IPW_TRACE_EXIT(WN2);}/** * Updates the clip region of all windows and their children * below window @p win. * @param win pointer to window * @internal */ static void _WindowUpdateClipRegionsBelow(Pw_Window* win){ Pw_Window* blw_win; IPW_TRACE_ENTER(WN2); IPW_CHECK_PTR(win); blw_win = win->next;
while (PW_NULL != blw_win) { IPW_TRACE1(WN1, p, blw_win); _WindowUpdateClipRegion(blw_win); blw_win = blw_win->next; } IPW_TRACE_EXIT(WN2);}/** * Repaint the region @p clip of all windows and their children * below window @p win area. * @param win pointer to window * @param clip pointer to clip rectangle * @internal */ static void _WindowRepaintBelow(Pw_Window* win, Pw_Rectangle* clip){ Pw_Window* blw_win; IPW_TRACE_ENTER(WN2); IPW_CHECK_PTR(win); IPW_TRACE2(WN1, p, win, clip); blw_win = win->next; while (PW_NULL != blw_win) { IPW_TRACE1(WN1, p, blw_win); if (PW_NULL == clip || IPW_RECT_IS_OVER(clip, &blw_win->area)) _WindowRepaint(blw_win, clip, TRUE); blw_win = blw_win->next; } IPW_TRACE_EXIT(WN2);}/** * Refreshes the display. * This function should be called after all repainting is done - * two separate areas can be specified, if areas intersect the * refreshing will be optimized. * @param dpy pointer to display * @param r1 pointer to display area 1 * @param r2 pointer to display area 2 * @internal */ static void _DisplayRefresh(Pw_Display* dpy, Pw_Rectangle* r1, Pw_Rectangle* r2){ Pw_Rectangle rect; IPW_TRACE_ENTER(WN2); IPW_CHECK_PTR2(dpy, dpy->dd); IPW_TRACE2(WN1, p, r1, r2); if (PW_NULL == r1) { IPW_TRACE_EXIT(WN2); return; } IPW_RECT_COPY(&rect, r1); if (PW_NULL == r2) { IPW_TRACE_RECT(WN1, &rect); dpy->dd->display_refresh(dpy, &rect); IPW_TRACE_EXIT(WN2); return; } if (IPW_RECT_IS_OVER(r1, r2)) { IPw_RectUnionize(&rect, r2); IPW_TRACE_RECT(WN1, &rect); dpy->dd->display_refresh(dpy, &rect); } else { IPW_TRACE_RECT(WN1, &rect); dpy->dd->display_refresh(dpy, &rect); IPW_RECT_COPY(&rect, r2); IPW_TRACE_RECT(WN1, &rect); dpy->dd->display_refresh(dpy, &rect); } IPW_TRACE_EXIT(WN2);}/** * Sets the mapped flag of all window win children to @p mapped flag. * @param win pointer to window * @param mapped mapped flag * @internal */ static void _WindowSetChildrensMappedFlag(Pw_Window* win, Pw_Bool mapped){ Pw_Window* cld_win; IPW_TRACE_ENTER(WN2); IPW_CHECK_PTR(win); IPW_TRACE2M(WN1, p, win, d, mapped); cld_win = win->children; /* Set mapped flag for all of this window children */ while (PW_NULL != cld_win) { IPW_TRACE1(WN1, p, cld_win); cld_win->mapped = mapped; _WindowSetChildrensMappedFlag(cld_win, mapped); cld_win = cld_win->next; } IPW_TRACE_EXIT(WN2);}/* -------------------------------------------------------------------------- *//** * Creates the root window for new display. * @param dpy pointer to new display * @param width new display width * @param height new display height * @return the pointer to root window of new display * @internal */ Pw_Window* IPw_RootWindowCreate(Pw_Display* dpy, Pw_Coord width, Pw_Coord height){ Pw_Window* root; IPW_TRACE_ENTER(WN3); IPW_CHECK_PTR(dpy); IPW_CHECK_COND(width > 0 && height > 0); IPW_TRACE2(WN2, d, width, height); /* Create new window */ root = _WindowNew(dpy, &dpy->root_win); /* Set root window area */ root->area.x = 0; root->area.y = 0; root->area.w = width; root->area.h = height; /* Set root window clip region to all */ _WINDOW_SET_CLIP_REGION_TO_ALL(root); /* Set the mapped flag */ root->mapped = TRUE; IPW_CHECK_WINDOW(root); IPW_TRACE_EXIT_V(WN3, p, root); return(root);}/** * Clears window @p win event hooks. * @param win pointer to window * @internal */ void IPw_WindowClearEventHooks(Pw_Window* win){ Pw_uInt i; IPW_TRACE_ENTER(WN3); IPW_CHECK_PTR(win); IPW_CHECK_WINDOW(win); IPW_TRACE1(WN2, p, win); /* Clear window win xinput hooks (if any) */ for (i = 0; i < PW_XINPUTS_MAX_NUM; i++) { if (win->dpy->xinput_win[i] == win) { IPW_TRACE1(WN1, d, i); win->dpy->xinput_win[i] = PW_NULL; } } IPW_TRACE_EXIT(WN2);}#if IPW_CHECK_EN(WINDOW_STRUCT)Pw_Bool IPw_WindowCheck(Pw_Window* win){ Pw_Int i; Pw_Window* cld_win; if (PW_NULL == win->dpy) { IPW_ASSERT(FALSE, ("Window (%p) display == NULL!", win)); return(FALSE); } if (win->area.w < 0 || win->area.h < 0) { IPW_ASSERT(FALSE, ("Window (%p) area w = %d h = %d!", win, win->area.w, win->area.h)); return(FALSE); } if (win->parent == PW_NULL && win != &win->dpy->root_win) { IPW_ASSERT(FALSE, ("Window (%p) parent == NULL && win != root!", win)); return(FALSE); } if (win == win->dpy->focus_win && !win->focus_accept) { IPW_ASSERT(FALSE, ("Window (%p) in focus, but doesn't accept focus!", win)); return(FALSE); } i = 0; cld_win = win->children; while (PW_NULL != cld_win) { if (PW_NULL != cld_win->next && cld_win->next->prev != cld_win) { IPW_ASSERT(FALSE, ("Window (%p) child list broken at %d" " (clds %d %d)!", win, i, cld_win, cld_win->next)); return(FALSE); } cld_win = cld_win->next; i++; } if (i != win->children_num) { IPW_ASSERT(FALSE, ("Window (%p) children list num error %d != %d!", win, i, win->children_num)); return(FALSE); } if (PW_NULL != win->parent) { cld_win = win->parent->children; while (PW_NULL != cld_win && win != cld_win) { if (PW_NULL != cld_win->next && cld_win->next->prev != cld_win) { IPW_ASSERT(FALSE, ("Window (%p) child list broken" " (clds %d %d)!", win->parent, i, cld_win, cld_win->next)); return(FALSE); } cld_win = cld_win->next; } if (cld_win != win) { IPW_ASSERT(FALSE, ("Window (%p) not in its parent (%p) child list!", win, win->parent)); return(FALSE); } }#if IPW_CHECK_EN(REGION_LIST) if (!IPw_RegionListCheck(&win->clip_reg, TRUE)) { IPW_ASSERT(FALSE, ("Window (%p) clip region error!", win)); return(FALSE); }#endif /* IPW_CHECK_EN(REGION_LIST) */ return(TRUE);}#endif /* IPW_CHECK_EN(WINDOW_STRUCT) *//* -------------------------------------------------------------------------- *//** * Creates a new window. * @param parent pointer to new window parent * @param x new window top left corner x coord * @param y new window top left corner y coord * @param w new window width * @param h new window height * @param win pointer to window to create * @return pointer to newly created window */ Pw_Window* Pw_WindowCreate(Pw_Window* parent,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -