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

📄 pw_window.c

📁 Very very small GUI. Usefull for small system, without OS or small OS. Event driven, support user m
💻 C
📖 第 1 页 / 共 4 页
字号:
#include <i_pwin.h>#include "guidebug.h"#include <string.h>
/* -------------------------------------------------------------------------- */#define _WINDOW_IS_CLIP_REGION_NON_EMPTY(_win_)  \        ((_win_)->clip_reg.regs_num > 0) #define _WINDOW_SET_CLIP_REGION_TO_ALL(_win_)                         \    IPW_MACRO_START                                                   \        if (PW_NULL != (_win_)->clip_reg.regs)                        \        {                                                             \            IPW_CHECK_COND((_win_)->clip_reg.regs_num > 0);           \            IPw_RegionFreeList((_win_)->clip_reg.regs);               \        }                                                             \        (_win_)->clip_reg.regs = IPw_RegionNew();                     \        IPW_FAIL((_win_)->clip_reg.regs != PW_NULL,                   \                 ("Out of free regions!"));                           \        (_win_)->clip_reg.regs_num = 1;                               \        IPW_RECT_COPY(&(_win_)->clip_reg.regs->area, &(_win_)->area); \        IPW_RECT_COPY(&(_win_)->clip_reg.bounds, &(_win_)->area);     \    IPW_MACRO_END #define _WINDOW_SET_CLIP_REGION_TO_EMPTY(_win_)                    \    IPW_MACRO_START                                                \        if (PW_NULL != (_win_)->clip_reg.regs)                     \        {                                                          \            IPW_CHECK_COND((_win_)->clip_reg.regs_num > 0);        \            IPw_RegionFreeList((_win_)->clip_reg.regs);            \        }                                                          \        (_win_)->clip_reg.regs = PW_NULL;                          \        (_win_)->clip_reg.regs_num = 0;                            \        IPW_RECT_EMPTY(&(_win_)->clip_reg.bounds);                 \    IPW_MACRO_END #define _WINDOW_COPY_CLIP_REGION(_dst_, _src_)                     \    IPW_MACRO_START                                                \        (_dst_)->regs_num = (_src_)->regs_num;                     \        (_dst_)->regs = IPw_RegionNewListFromList((_src_),         \            &(_dst_)->regs_num, PW_NULL);                          \        IPW_FAIL((_dst_)->regs_num == (_src_)->regs_num,           \                 ("Out of free regions!"));                        \        IPW_RECT_COPY(&(_dst_)->bounds, &(_src_)->bounds);         \    IPW_MACRO_END #define _WINDOW_FREE_CLIP_REGION(_creg_)                           \    IPW_MACRO_START                                                \        if (PW_NULL != (_creg_)->regs)                             \        {                                                          \            IPW_CHECK_COND((_creg_)->regs_num > 0);                \            IPw_RegionFreeList((_creg_)->regs);                    \        }                                                          \    IPW_MACRO_END /* -------------------------------------------------------------------------- *//** *  Next free client data id. *  @see Pw_WindowGetNewClientDataId */ static Pw_Int _cdata_next_id = 1;/* -------------------------------------------------------------------------- *//** *  Initializes basic new window attributes. *  @param dpy pointer to display of window *  @param win pointer to window to create *  @return a newly created window (same as @p win) *  @internal */ static Pw_Window* _WindowNew(Pw_Display* dpy, Pw_Window* win){     IPW_TRACE_ENTER(WN2);    IPW_CHECK_PTR(dpy);    IPW_CHECK_PTR(win);    IPW_TRACE3(WN2, p, win, win->parent, dpy);    /* Quick check for empty window space */    IPW_FAIL(PW_NULL == win->parent, ("dirty or used window space %p", win));    /* Set the display */    win->dpy = dpy;    /* Set the window area */    IPW_RECT_EMPTY(&win->area);    /* Set other window attributes */    win->parent       = PW_NULL;    win->children     = PW_NULL;    win->children_num = 0;    win->prev         = PW_NULL;    win->next         = PW_NULL;    win->focus_accept = FALSE;    win->mapped       = FALSE;    /* Set window clip region to empty */    win->clip_reg.regs_num = 0;    win->clip_reg.regs = PW_NULL;    IPW_RECT_EMPTY(&win->clip_reg.bounds);        /* Set window callback functions to null */    win->event_cb   = PW_NULL;    win->repaint_cb = PW_NULL;    /* Set client data to null */    win->cdata_id = -1;    win->cdata    = PW_NULL;    IPW_TRACE_EXIT_V(WN2, p, win);    return(win);}/** *  Adds window @p win to parent window @p parent. *  @param win    pointer to window *  @param parent pointer to parent window *  @internal */ static void _WindowAddToParent(Pw_Window* win, Pw_Window* parent){    IPW_TRACE_ENTER(WN2);    IPW_CHECK_PTR(win);    IPW_CHECK_PTR(parent);    IPW_TRACE2(WN2, p, win, parent);    IPW_TRACE3(WN1, p, win->next, win->prev, win->parent);    IPW_TRACE1(WN1, d, parent->children_num);    /*      * Window should not be added to another window      * if it already has a parent     */    IPW_CHECK_COND(PW_NULL == win->parent);     /* Increase parent window child count */    parent->children_num++;    /* Check if this window is the first child of parent window */     if (PW_NULL == parent->children)    {        /* First child */        parent->children = win;        win->prev = PW_NULL;        win->next = PW_NULL;    }    else    {        /* Not the first child - add the window on top (start of the list) */        parent->children->prev = win;        win->next = parent->children;        win->prev = PW_NULL;        parent->children = win;    }    /* Set the window parent pointer */    win->parent = parent;    IPW_TRACE3(WN1, p, win->next, win->prev, win->parent);    IPW_TRACE1(WN1, d, parent->children_num);    IPW_TRACE_EXIT(WN2);}/** *  Removes window @p win from parent window. *  @param win pointer to window *  @internal */  static void _WindowRemoveFromParent(Pw_Window* win){    Pw_Window* cld_win;    Pw_Window* pre_win;    IPW_TRACE_ENTER(WN2);    IPW_CHECK_PTR(win);    IPW_TRACE2(WN2, p, win, win->parent);    IPW_CHECK_COND(PW_NULL != win->parent);    IPW_TRACE1(WN1, d, win->parent->children_num);    /* Find previous window of this window in its parent child list */    cld_win = win->parent->children;    pre_win = PW_NULL;    while ((cld_win != win) && (PW_NULL != cld_win))    {        pre_win = cld_win;        cld_win = cld_win->next;    }    IPW_CHECK_COND(PW_NULL != cld_win);     IPW_TRACE2(WN1, p, pre_win, cld_win->next);    if (PW_NULL == pre_win)     {        /*          * This window is the first window in its parent         * child list - just correct parents first child pointer         */         win->parent->children = cld_win->next;        if (PW_NULL != cld_win->next)            cld_win->next->prev = PW_NULL;    }    else    {        /*         * This window is not the first window in its parent         * child list - corrent previous window next pointer         * to point to this window next window         */         pre_win->next = cld_win->next;        if (PW_NULL != cld_win->next)            cld_win->next->prev = pre_win;    }    /* Decrease this window parent child count */    win->parent->children_num--;    IPW_TRACE1(WN1, d, win->parent->children_num);    /* Set window parent to NULL */    win->parent = PW_NULL;    IPW_TRACE_EXIT(WN2);}/** *  Sets the clip region of all of window @p win children to empty (invisible). *  @param win pointer to window *  @internal */ static void _WindowSetChildrenClipRegionToEmpty(Pw_Window* win){    Pw_Window* cld_win;    IPW_TRACE_ENTER(WN2);    IPW_CHECK_PTR(win);    IPW_TRACE2(WN1, p, win, win->children);    /*      * Set the clip region of current child window to empty and     * then call this function recursively for all of current      * child window children     */     cld_win = win->children;    while (PW_NULL != cld_win)    {        IPW_TRACE1(WN1, p, cld_win);        _WINDOW_SET_CLIP_REGION_TO_EMPTY(cld_win);        _WindowSetChildrenClipRegionToEmpty(cld_win);        cld_win = cld_win->next;    }     IPW_TRACE_EXIT(WN2);}/** *  Updates window @p win clip region and the clip region of its children. *  @param win pointer to window *  @internal */  static void _WindowUpdateClipRegion(Pw_Window* win){    Pw_Window*     par_win;      Pw_Window*     cur_win;        Pw_Window*     tmp_win;       Pw_RegionList* clip_reg;     Pw_Region*     reg;         IPW_TRACE_ENTER(WN2);    IPW_CHECK_PTR(win);        /* If this window is not mapped we have nothing to do */    if (!win->mapped)    {        IPW_TRACE_EXIT(WN2);        return;    }    /*      * Start with the whole window area and then remove the obscured parts      */
    _WINDOW_SET_CLIP_REGION_TO_ALL(win);    /* Set the ptr to this window clip region */    clip_reg = &win->clip_reg;    /*     * Find the visible region of this window trough all of     * its parents (up to the root window wich parent is NULL)     */     par_win = win->parent;    while (PW_NULL != par_win)    {        IPW_TRACE_RECT2(WN1, &par_win->area, &clip_reg->regs->area);        /* Calculate the visible window part trough the current parent */        IPw_RectIntersect(&clip_reg->regs->area, &par_win->area);        IPW_TRACE_RECT(WN1, &clip_reg->regs->area);        if (!IPW_RECT_IS_VALID(&clip_reg->regs->area))        {            /*              * This window is not visible at all (and all             * of its children are not visible as well)              */            _WINDOW_SET_CLIP_REGION_TO_EMPTY(win);            _WindowSetChildrenClipRegionToEmpty(win);            IPW_TRACE_EXIT(WN2);            return;        }        par_win = par_win->parent;    }    /*     * Remove parts wich are obscured by windows on top of this window - this     * are the children of this window parent that are on top of this window     * and the children of this window parent parent that are on top of this      * window parent, and so on until we reach the root window     */    tmp_win = win;     par_win = win->parent;     while (PW_NULL != par_win)    {        IPW_TRACE1(WN1, p, par_win);        /*         *  Exclude window area of windows on top of this         *  window or on top of one of this window parents -         *  we stop when we reach tmp_win (in the first loop         *  tmp_win is this window and in the following loop its         *  one of this window parents)         */         cur_win = par_win->children; /* Child window on top */        while (cur_win != tmp_win)        {            IPW_TRACE2M(WN1, p, cur_win, d, cur_win->mapped);            /* If window is not mapped it can't obscure anything */            if (cur_win->mapped)            {                /*                  * Exclude current window area from this window and check                 * if the number of clip rectangles has reached the limit                 */                 if (!IPw_RectExcludeFromRegionList(&(cur_win->area), clip_reg))                {                    Pw_Int fcnt;                    /*                     *  Too many clip rectangles - just make this window                      *  and all of its children invisible                     */                     IPW_WARN(FALSE, ("Out of free regions for window (%p)!",                              win));                    IPW_TRACE1(WN1, d, win->clip_reg.regs_num);                    _WINDOW_SET_CLIP_REGION_TO_EMPTY(win);                    _WindowSetChildrenClipRegionToEmpty(win);                    fcnt = IPw_RegionGetFreeCnt();                    IPW_TRACE1(WN1, d, fcnt);                    IPW_TRACE_EXIT(WN2);                    return;                }                IPW_TRACE1(WN1, d, clip_reg->regs_num);            }            cur_win = cur_win->next;        }        tmp_win = par_win;        par_win = par_win->parent;    }    /* Calculate the bounds of this window clip region */    if (PW_NULL != clip_reg->regs)     {        reg = clip_reg->regs;        IPW_RECT_COPY(&clip_reg->bounds, &reg->area);        IPW_TRACE_RECT(WN1, &reg->area);        reg = reg->next;        while (PW_NULL != reg)        {            IPW_TRACE_RECT(WN1, &reg->area);            IPw_RectUnionize(&clip_reg->bounds, &reg->area);            reg = reg->next;        }    }    else    {        IPW_RECT_EMPTY(&clip_reg->bounds);    }    IPW_TRACE_RECT(WN1, &clip_reg->bounds);    IPW_CHECK_RLIST_HARD(&win->clip_reg);    /* Update the clip region for all children of this window */     cur_win = win->children;    while (PW_NULL != cur_win)    {        _WindowUpdateClipRegion(cur_win);        cur_win = cur_win->next;    }    IPW_TRACE_EXIT(WN2);}/** *  Creates window @p win graphic context @p gc with clip region @p clip. *  @param win  pointer to window *  @param clip pointer to clip rectangle *  @param gc   pointer to gc *  @return true if gc applays to a visible region  *  @internal */ static Pw_Bool _WindowCreateGC(Pw_Window* win, Pw_Rectangle* clip, Pw_GC* gc){    IPW_TRACE_ENTER(WN2);    IPW_CHECK_PTR2(win, gc);    IPW_TRACE3(WN1, p, win, clip, gc);    gc->d.type = Pw_DrawableWindowType; /* Set the type */    gc->d.comp.window = win;          /* Set the window */    gc->d.lld = win->dpy->dd->lld;    /* Set low level drawing routines */    gc->xoff  = win->area.x;          /* Set the x offset (origin) */    gc->yoff  = win->area.y;          /* Set the y offset (origin) */    gc->color = pw_black_pixel;       /* Set the color */
    gc->font  = PW_NULL;              /* Set the font REMIND: default font?!? */

⌨️ 快捷键说明

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