nanox的open,close,mainloop有了,然后就是它提供的画图函数了。先只看link to app的情况,主要文件是nanox/srvfunc.c,那么注释一下该文件主要函数window方面的
GrNewWindow 新建一个window
|--GsFindWindow 根据父window id找到父window的handle
|--NewWindow 在父window上建立一个新window
|--|--malloc(sizeof(GR_WINDOW)) 分配新window结构空间
|--|--window.*=* 为新window结构体赋初值
GrNewInputWindow 新建一个input window
它与GrNewWindow的差别是
GrNewWindow :window->output = GR_TRUE
GrNewInputWindow :window->output = GR_FALSE
GrNewPixmap 新建一个pixmap,通常是为画一张图片准备的一块区域,pix就是pixel(点)
|--rootwp->psd->AllocateMemGC(rootwp->psd); 根据root window的屏设备指针分配一个新的屏设备结构 typedef struct _mwscreendevice *PSD;
|--malloc(sizeof(GR_PIXMAP)); 分配pixmap结构空间
|--GdCalcMemGCAlloc 根据要分配的pixmap宽高计算出分配的实际空间,所以需要用到屏设备的参数确定一个点要分配多少字节size
|--calloc(size, 1); 分配size的空间
|--pp->psd = psd; 把psd挂在当前pixmap下
|-- psd->MapMemGC 初始化这块mem,并把画图函数指针挂进来
GrMapWindow 显示一个window
|--GsFindWindow id转换为handle
|-- GsWpRealizeWindow 让window和它的子window可视
|--|--GsDeliverUpdateEvent(wp, GR_UPDATE_MAP... 发送更新map事件
|--|--if (!wp->mapped ... 如果是unmap就返回
|--|--if (wp->output) 如果不是inputwindow就显示
|--|--|--GsDrawBorder 画window边框
|--|--|--GsWpClearWindow 刷新window内部
|--|--|--|--GsSetClipWindow 判断该window刷新的部分有没有超过父window,超过就不刷新
|--|--|--|--GsWpDrawBackgroundPixmap 如果有背景pixmap就刷新
|--|--|--|--GdFillRect 如果没有背景pixmap就刷新background color
|--|--|--|--不需要刷背景就不刷
|--|--|--|--GsDeliverExposureEvent 有必要就发送exposure刷新事件
|--|--for (wp = wp->children ... GsWpRealizeWindow 递归调用将子window也刷新
GrUnmapWindow 隐藏一个window
它与GrMapWindow的差别是
GrMapWindow:wp->mapped = GR_TRUE;
GrUnmapWindow :wp->mapped = GR_FALSE;
wp->mapped = GR_TRUE;
GrMoveWindow 移动window
|--GsFindWindow id转换为handle
|-- if (wp->mapped && wp == wp->parent->children && wp->parent->id == GR_ROOT_WINDOW_ID && !wp->clipregion) 如果该window可视,父window是root window,不在刷不到的区域那么刷局部
|--|--GrNewPixmap 临时新建一个pixmap为了存放window内容
|--|--GrCopyArea 把当前window内容拷贝到pixmap里
|--|--OffsetWindow 根据offset计算出新window坐标
|--|--GrCopyArea 把存放了老window内容的pixmap拷贝到新window坐标地点
|--|--GsExposeArea 刷新新老window并集的矩形区域
|--|--GrDestroyWindow 销毁临时建立的pixmap
|--|--DeliverUpdateMoveEventAndChildren 发送更新移动事件
|-- else 刷整个屏
|--|--GsWpUnrealizeWindow 隐藏该window
|--|--OffsetWindow 根据offset计算出新window坐标
|--|--GsWpRealizeWindow 显示新window
|--|--DeliverUpdateMoveEventAndChildren 发送更新移动事件
GrRaiseWindow 让当前窗口显示在最上面
|--GsFindWindow id转换为handle
|-- if (wp->parent->children == wp) 如果该窗口已经在最上面就返回,wp->parent->children存放的是父window中最上面的子window
|--GsCheckOverlap 如果该窗口还有兄弟窗口,就检查兄弟窗口是否覆盖住了该窗口
|--wp->parent->children = wp; 该窗口为父窗口最上面的window
|--if (overlap) 如果有覆盖就刷新
|--|--GsDrawBorder 画window边框
|--|--GsExposeArea 更新该window的整块区域
GrLowerWindow 让当前窗口显示在最下面
|--GsFindWindow id转换为handle
|--if (wp->siblings == NULL) 如果没有兄弟窗口,那么也就没有最上最下的说法了,返回
|--if (prevwp == wp) wp->parent->children = wp->siblings; 如果当前窗口在最上面就让它的兄弟窗口显示在最上面
|--while (expwp && (expwp != wp)) ... expwp = expwp->siblings; 循环整个兄弟窗口链表找到兄弟窗口计算重叠区域并刷新,siblings是一个兄弟窗口链表
|--|--GsCheckOverlap 计算窗口与它的下一个兄弟窗口的重叠区域
|--|--GsExposeArea 刷新当前窗口,当while循环后当前窗口为它下一个兄弟窗口时就会刷新它的兄弟窗口,所以一个个刷,第一个刷的是自己,所以自己才能是最下面一层的窗口
GrDestroyWindow 销毁一个窗口或pixmap
|--GsFindWindow id转换为handle
|-- if (wp) 如果是GsFindWindow返回不为0就是window
|--|--GsWpDestroyWindow 那么销毁window
|--|--|--GsWpUnrealizeWindow 如果该window在显示,先隐藏
|--|--|--GsDeliverUpdateEvent 发送更新事件
|--|--|--while (wp->children) GsWpDestroyWindow(wp->children); 递归销毁子窗口
|--|--|--该free的free,该清零的清零
|-- else 如果是GsFindWindow返回为0就是pixmap
|--|--GsFindPixmap id转换为handle
|--|-- free pixmap那块区域,free pixmap结构体,free当初建立的psd
GrKillWindow 将当前window所属的client销毁或nanox server终止
|--GsFindWindow id转换为handle
|--GsClose(wp->owner->id) 根据client id销毁当前client在server中的连接
|--|-- #if NONETWORK 如果是link app
|--|--|--GsDropClient --connectcount; link app的连接就是1,减一后connectcount为0
|--|-- #else 如果是C/S
|--|--|--GsDropClient 销毁client,connectcount减一
|--|--if(!persistent_mode && connectcount == 0) 如果连接数为0,终止nanox server
|--|--|--GsTerminate 终止nanox server
|--|--|--|--#if !NONETWORK 如果是C/S关闭socket
|--|--|--|--|--GsCloseSocket 关闭socket
|--|--|--|--关闭屏,鼠标,键盘
|--|--|--|--exit(0); 退出
在window刷新的时候还有鼠标cursor需要特殊处理,比如移动刷新window时不能把cursor的图片也拷进来了。这个就不写了
GrNewWindow 新建一个window
|--GsFindWindow 根据父window id找到父window的handle
|--NewWindow 在父window上建立一个新window
|--|--malloc(sizeof(GR_WINDOW)) 分配新window结构空间
|--|--window.*=* 为新window结构体赋初值
GrNewInputWindow 新建一个input window
它与GrNewWindow的差别是
GrNewWindow :window->output = GR_TRUE
GrNewInputWindow :window->output = GR_FALSE
GrNewPixmap 新建一个pixmap,通常是为画一张图片准备的一块区域,pix就是pixel(点)
|--rootwp->psd->AllocateMemGC(rootwp->psd); 根据root window的屏设备指针分配一个新的屏设备结构 typedef struct _mwscreendevice *PSD;
|--malloc(sizeof(GR_PIXMAP)); 分配pixmap结构空间
|--GdCalcMemGCAlloc 根据要分配的pixmap宽高计算出分配的实际空间,所以需要用到屏设备的参数确定一个点要分配多少字节size
|--calloc(size, 1); 分配size的空间
|--pp->psd = psd; 把psd挂在当前pixmap下
|-- psd->MapMemGC 初始化这块mem,并把画图函数指针挂进来
GrMapWindow 显示一个window
|--GsFindWindow id转换为handle
|-- GsWpRealizeWindow 让window和它的子window可视
|--|--GsDeliverUpdateEvent(wp, GR_UPDATE_MAP... 发送更新map事件
|--|--if (!wp->mapped ... 如果是unmap就返回
|--|--if (wp->output) 如果不是inputwindow就显示
|--|--|--GsDrawBorder 画window边框
|--|--|--GsWpClearWindow 刷新window内部
|--|--|--|--GsSetClipWindow 判断该window刷新的部分有没有超过父window,超过就不刷新
|--|--|--|--GsWpDrawBackgroundPixmap 如果有背景pixmap就刷新
|--|--|--|--GdFillRect 如果没有背景pixmap就刷新background color
|--|--|--|--不需要刷背景就不刷
|--|--|--|--GsDeliverExposureEvent 有必要就发送exposure刷新事件
|--|--for (wp = wp->children ... GsWpRealizeWindow 递归调用将子window也刷新
GrUnmapWindow 隐藏一个window
它与GrMapWindow的差别是
GrMapWindow:wp->mapped = GR_TRUE;
GrUnmapWindow :wp->mapped = GR_FALSE;
wp->mapped = GR_TRUE;
GrMoveWindow 移动window
|--GsFindWindow id转换为handle
|-- if (wp->mapped && wp == wp->parent->children && wp->parent->id == GR_ROOT_WINDOW_ID && !wp->clipregion) 如果该window可视,父window是root window,不在刷不到的区域那么刷局部
|--|--GrNewPixmap 临时新建一个pixmap为了存放window内容
|--|--GrCopyArea 把当前window内容拷贝到pixmap里
|--|--OffsetWindow 根据offset计算出新window坐标
|--|--GrCopyArea 把存放了老window内容的pixmap拷贝到新window坐标地点
|--|--GsExposeArea 刷新新老window并集的矩形区域
|--|--GrDestroyWindow 销毁临时建立的pixmap
|--|--DeliverUpdateMoveEventAndChildren 发送更新移动事件
|-- else 刷整个屏
|--|--GsWpUnrealizeWindow 隐藏该window
|--|--OffsetWindow 根据offset计算出新window坐标
|--|--GsWpRealizeWindow 显示新window
|--|--DeliverUpdateMoveEventAndChildren 发送更新移动事件
GrRaiseWindow 让当前窗口显示在最上面
|--GsFindWindow id转换为handle
|-- if (wp->parent->children == wp) 如果该窗口已经在最上面就返回,wp->parent->children存放的是父window中最上面的子window
|--GsCheckOverlap 如果该窗口还有兄弟窗口,就检查兄弟窗口是否覆盖住了该窗口
|--wp->parent->children = wp; 该窗口为父窗口最上面的window
|--if (overlap) 如果有覆盖就刷新
|--|--GsDrawBorder 画window边框
|--|--GsExposeArea 更新该window的整块区域
GrLowerWindow 让当前窗口显示在最下面
|--GsFindWindow id转换为handle
|--if (wp->siblings == NULL) 如果没有兄弟窗口,那么也就没有最上最下的说法了,返回
|--if (prevwp == wp) wp->parent->children = wp->siblings; 如果当前窗口在最上面就让它的兄弟窗口显示在最上面
|--while (expwp && (expwp != wp)) ... expwp = expwp->siblings; 循环整个兄弟窗口链表找到兄弟窗口计算重叠区域并刷新,siblings是一个兄弟窗口链表
|--|--GsCheckOverlap 计算窗口与它的下一个兄弟窗口的重叠区域
|--|--GsExposeArea 刷新当前窗口,当while循环后当前窗口为它下一个兄弟窗口时就会刷新它的兄弟窗口,所以一个个刷,第一个刷的是自己,所以自己才能是最下面一层的窗口
GrDestroyWindow 销毁一个窗口或pixmap
|--GsFindWindow id转换为handle
|-- if (wp) 如果是GsFindWindow返回不为0就是window
|--|--GsWpDestroyWindow 那么销毁window
|--|--|--GsWpUnrealizeWindow 如果该window在显示,先隐藏
|--|--|--GsDeliverUpdateEvent 发送更新事件
|--|--|--while (wp->children) GsWpDestroyWindow(wp->children); 递归销毁子窗口
|--|--|--该free的free,该清零的清零
|-- else 如果是GsFindWindow返回为0就是pixmap
|--|--GsFindPixmap id转换为handle
|--|-- free pixmap那块区域,free pixmap结构体,free当初建立的psd
GrKillWindow 将当前window所属的client销毁或nanox server终止
|--GsFindWindow id转换为handle
|--GsClose(wp->owner->id) 根据client id销毁当前client在server中的连接
|--|-- #if NONETWORK 如果是link app
|--|--|--GsDropClient --connectcount; link app的连接就是1,减一后connectcount为0
|--|-- #else 如果是C/S
|--|--|--GsDropClient 销毁client,connectcount减一
|--|--if(!persistent_mode && connectcount == 0) 如果连接数为0,终止nanox server
|--|--|--GsTerminate 终止nanox server
|--|--|--|--#if !NONETWORK 如果是C/S关闭socket
|--|--|--|--|--GsCloseSocket 关闭socket
|--|--|--|--关闭屏,鼠标,键盘
|--|--|--|--exit(0); 退出
在window刷新的时候还有鼠标cursor需要特殊处理,比如移动刷新window时不能把cursor的图片也拷进来了。这个就不写了