//----合并区域简化版----------------------------------------------------------- //功能: 把给定的剪切域队列中可合并的区域合并,简化版的意思是,队列中的区域已经按 // 左->右,从上->下的顺序排列,合并后,多余的clip将被释放。 //参数: clipq: 指向待合并的队列首 //返回: 无 //----------------------------------------------------------------------------- struct tagClipRect * __GK_CombineClip_s(struct tagClipRect *clipq) { struct tagClipRect *clip,*clip1,*tempclip; if(clipq == NULL) return NULL; //合并剪切域 clip = clipq; clip1 = clipq->next; //执行水平合并,由于clip是按照先横后纵的方式划分的,因此水平合并只需要查 //看相邻矩形是否可以合并即可 while(clip1 != clipq) { if((clip1->rect.top == clip->rect.top) &&(clip1->rect.bottom == clip->rect.bottom) &&(clip1->rect.left == clip->rect.right)) //可合并 { clip->rect.right = clip1->rect.right; clip->next = clip1->next; clip1->next->previous = clip; Mb_Free(g_ptClipRectPool,clip1); clip1 = clip->next; } else if((clip1->rect.top == clip->rect.top) //存在剪切域相同的情况 &&(clip1->rect.bottom == clip->rect.bottom) &&(clip1->rect.left == clip->rect.left) &&(clip1->rect.right== clip->rect.right)) { clip->next = clip1->next; clip1->next->previous = clip; Mb_Free(g_ptClipRectPool,clip1); clip1 = clip->next; }else { clip = clip1; clip1 = clip1->next; } } //执行垂直合并,可合并的矩形可能不相邻,故需两重循环才能完成。 clip = clipq; do{ clip1 = clip->next; while(clip1 != clip) { if((clip1->rect.left == clip->rect.left) &&(clip1->rect.right == clip->rect.right) &&(clip->rect.bottom == clip1->rect.top)) //可合并 { clip->rect.bottom = clip1->rect.bottom; clip1->previous->next = clip1->next; clip1->next->previous = clip1->previous; tempclip = clip1; clip1 = clip1->next; Mb_Free(g_ptClipRectPool,tempclip); }else clip1 = clip1->next; } clip = clip->next; }while(clip != clipq); return clipq; }
// ========================================================================= // 函数功能:删除整个菜单分支包括祖先节点 // 输入参数:pMenuitem,待删除的菜单分支祖先节点 // 输出参数: // 返回值 :true成功 false失败 // 说明 :删除当前菜单项的所有后代菜单以及当前菜单(逻辑上和物理上),通过循环删除 // 端节点来实现 // ========================================================================= bool_t DelMenuBranchCompletely(struct menu_item * pMenuitem) { bool_t result=false; struct menu_item *temp_menuitem=pMenuitem; if((struct tagRscNode *)pMenuitem==pg_menuitem_root)//this is an menuitem root node { printf("Invalid para---DelMenuBranchCompletely\n"); return result; } while((temp_menuitem=SearchSubTernalMenuitem(pMenuitem))!=NULL) { printf("begin to delete the menuitem=%s\n",temp_menuitem->node.name); Rsc_DelNode((struct tagRscNode *)temp_menuitem); Mb_Free(pg_menuitem_pool, temp_menuitem); } if(Rsc_GetParent((struct tagRscNode *)pMenuitem)==pg_menuitem_root) { menuitem_tree_count--; } printf("begin to delete the menuitem=%s\n",pMenuitem->node.name); Rsc_DelNode((struct tagRscNode *)(&(pMenuitem->node))); Mb_Free(pg_menuitem_pool, pMenuitem); result=true; return result; }
//----从MultiplexSets删除对象----------------------------------------------------- //功能: MultiplexAdd的逆函数 //参数: Sets,被操作的MultiplexSets指针 // ObjectHead,被操作的Object队列头指针的指针 //返回: true=成功,false=失败。 //----------------------------------------------------------------------------- bool_t Multiplex_DelObject(struct tagMultiplexSetsCB *Sets, struct tagMultiplexObjectCB **ObjectHead) { struct tagMultiplexObjectCB *Object,*following = NULL; if ((Sets == NULL) || (ObjectHead == NULL)) return false; Lock_MutexPend(&MultiplexMutex, CN_TIMEOUT_FOREVER); Object = *ObjectHead; while (Object != NULL) { //查找被删除的对象控制块 if (Object->MySets != Sets) { following = Object; Object = Object->NextSets; } else break; } if (Object != NULL) { //下面检查被删除的Object是否已经触发, if (__ObjectIsActived(Object->PendingBit, Object->SensingBit & ~0x80000000, Object->SensingBit & 0x80000000)) { if (Sets->Actived != 0) { Sets->Actived--; if (Sets->Actived == 0) Sets->SetsActived = false; } } Sets->ObjectSum--; if (Object->NextObject != Object) { //链表中不止一个结点 Object->NextObject->PreObject = Object->PreObject; Object->PreObject->NextObject = Object->NextObject; if (Object == Sets->ObjectQ) { Sets->ObjectQ = Object->NextObject; } if (Object == Sets->ActiveQ) { Sets->ActiveQ = Object->NextObject; } } else { //链表只有一个结点 if (Object == Sets->ObjectQ) { Sets->ObjectQ = NULL; } if (Object == Sets->ActiveQ) { Sets->ActiveQ = NULL; } } if (following == NULL) { *ObjectHead = NULL; } else { following->NextObject = Object->NextObject; } Mb_Free(g_ptMultiplexObjectPool, Object); } Lock_MutexPost(&MultiplexMutex); return true; }
// ============================================================================= // 函数功能:删除看门狗 // 输入参数:wdt,待删除的看门狗 // 输出参数: // 返回值 :true成功,false失败 // 说明 :和Wdt_Create成对调用 // ============================================================================= bool_t Wdt_Delete(tagWdt *wdt) { bool_t result = false; if(NULL != wdt) { result = Wdt_Delete_s(wdt); if(result) { Mb_Free(ptWdtPool,wdt); } } return result; }
//----释放clip队列------------------------------------------------------------- //功能: 释放一个clip队列的所有节点,该队列是一个双向循环队列。 //参数: clip,指向待释放队列的一个节点的指针 //返回: 无 //----------------------------------------------------------------------------- struct tagClipRect *__GK_FreeClipQueue(struct tagClipRect *clip) { struct tagClipRect *temp,*temp1; if(clip != NULL) { temp = clip; do { temp1 = temp->next; Mb_Free(g_ptClipRectPool,temp); temp = temp1; }while(temp != clip); } return NULL; }
// ============================================================================= // 函数功能: Socket_Free // 释放套接字内存空间 // 输入参数: fd, 待释放的套接字 // 输出参数: 无 // 返回值 :无 // 说明 : // ============================================================================= bool_t Socket_Free(tagSocket *sockfd) { if(NULL != sockfd) { Lock_MutexDelete(sockfd->sync); sockfd->valid = false; sockfd->socktype = EN_SOCKET_NOTSURE; Mb_Free(pgSocketPool, (void *)sockfd); return true; } else { return false; } }
//----卸载输入设备------------------------------------------------------------- //功能: 把输入设备从资源接点删除,从"input device"资源的子资源中,找到 // "device_name"资源接点,删除之,并把内存释放到pg_stdin_device_pool // 内存池中 //参数: device_name,目标设备的资源名 //返回: true = 成功删除,0=失败。 //----------------------------------------------------------------------------- bool_t Stddev_UnInstallDevice(char *device_name) { struct tagRscNode *temp; struct tagStdinDeviceRsc *djy_stdin; djy_stdin = (struct tagStdinDeviceRsc *)Rsc_SearchSon( &s_ptStdinDeviceRscTree->stdin_device_node,device_name); if(djy_stdin == NULL) return false; temp = &djy_stdin->stdin_device_node; if(Rsc_DelNode(temp) != NULL) { Mb_Free(g_ptStdinDevicePool,djy_stdin); return true; } else return false; }
// ============================================================================= // 函数功能:创建看门狗 // 输入参数: // dogname,看门狗名字 // yip_cylce,狗叫周期,单位为微秒 // yiphook,狗叫善后函数指针 // yip_action,狗叫动作,当yiphook为空或者返回default时采用此值 // levepara,看门狗超时的原因以及超时容忍次数等限制参数 // 输出参数: // 返回值 :创建的虚拟看门狗,NULL表示失败 // 说明 :务必保证看门狗善后函数返回值的定义符合标准,见enum _EN_EXP_DEAL_TYPE // 的声明(exp_api.h文件) // 创建的看门狗若成功,则下次狗叫时间为当前时间+yip_cycle=time // ============================================================================= tagWdt *Wdt_Create(char *dogname,u32 yip_cycle,\ fnYipHook yiphook,ptu32_t yip_action, tagWdtTolerate *levelpara) { tagWdt *result; tagWdt *wdt; result = NULL; wdt = Mb_Malloc(ptWdtPool,0); if(NULL != wdt) { result = Wdt_Create_s(wdt,dogname,yip_cycle,yiphook,yip_action, levelpara); if(NULL == result) { Mb_Free(ptWdtPool,wdt); } } return result; }
//----备份clip_link--------------------------------------------------------- //功能: 备份剪切域队列。 //参数: clip_link,被备份的剪切域队列 //返回: 备份的队列,出错则返回NULL //----------------------------------------------------------------------------- struct tagClipRect * __GK_CopyClipLink(struct tagClipRect *clip_link) { struct tagClipRect *clip1,*clip2,*clip_rsc,*result = NULL; clip_rsc = clip_link; if(clip_rsc == NULL) return NULL; //创建第一个节点 clip1 = (struct tagClipRect*)Mb_Malloc(g_ptClipRectPool,0); if(clip1 == NULL) return NULL; clip1->rect = clip_rsc->rect; result = clip1; clip1->next = NULL; clip_rsc = clip_rsc->next; while(clip_rsc != clip_link) { clip2 = (struct tagClipRect*)Mb_Malloc(g_ptClipRectPool,0); if(clip2 == NULL) goto error_exit; clip2->rect = clip_rsc->rect; clip_rsc = clip_rsc->next; clip1->next = clip2; clip2->previous = clip1; clip2->next = NULL; clip1 = clip2; } //以下两句使copy_clip链表形成闭环 result->previous = clip1; clip1->next = result; return result; error_exit: clip1 = result; do { clip2 = clip1->next; Mb_Free(g_ptClipRectPool,clip1); clip1 = clip2; }while(clip2 != NULL); return NULL; }
// ========================================================================= // 函数功能:释放菜单项所占用的空间 // 输入参数:待释放的菜单项pMenuitem // 输出参数: // 返回值 : true:成功,false:失败(其node节点没有clean) // 说明 :本函数仅仅会释放那些没有逻辑关联的菜单项,如果其node还没有clean掉,则不会释放 // ========================================================================= bool_t FreeMenuitem(struct menu_item * pMenuitem) { bool_t result=false; if(NULL==pMenuitem) { printf("This is an empty pMenuitem!\n"); result=true; return result; } else if((pMenuitem->node.child!=NULL)||(pMenuitem->node.parent!=NULL)||\ (pMenuitem->node.previous!=NULL)||(pMenuitem->node.next!=NULL)) { printf("use DelMenuBranchCompletely(struct menu_item * pMenuitem)!\n"); return result; } else { Mb_Free(pg_menuitem_pool,(void *)pMenuitem); result = true; return result; } }
// ============================================================================= // 函数功能: Socket_New // 分配套接字内存空间 // 输入参数: 无 // 输出参数: 无 // 返回值 :NULL表示分配不成功(内存不足),否则返回分配的套接字结构 // 说明 :分配时空间已经被初始化完毕 // ============================================================================= tagSocket* Socket_New(void) { tagSocket *result; result = Mb_Malloc(pgSocketPool, CN_TIMEOUT_FOREVER); if(NULL != result) { memset(result,0,sizeof(tagSocket)); result->sync = Lock_MutexCreate(NULL); if(NULL != result->sync) { //init the socket result->valid = true; result->socktype = EN_SOCKET_NOTSURE; sgDebugSocket = result; } else { Mb_Free(pgSocketPool, (void *)result); result = NULL; } } return result; }
//----提取剪切域队列重叠部分--------------------------------------------------- //功能: 提取src队列中的所有矩形与sub队列中重叠的部分,用ins参数返回; // src中非重叠的部分也形成新的剪切域队列,从different返回。 //参数: src,被减的队列指针,执行后,本队列将被释放或转移 // sub,减数队列指针 // ins,src与sub相交的部分 // different,src与sub不相交的部分 //返回: 无 //----------------------------------------------------------------------------- void __GK_ClipLinkSub(struct tagClipRect *src,struct tagClipRect *sub, struct tagClipRect **ins,struct tagClipRect **different) { struct tagClipRect *difftemp = NULL; //不重叠的部分暂存 struct tagClipRect *worksrc; //src中矩形被减产生的工作子队列 struct tagClipRect *LoopSrc; struct tagClipRect *EndLoop; struct tagClipRect *workloop; //工作子队列的循环遍历指针 struct tagClipRect *subloop; //减数队列的循环遍历指针 struct tagClipRect *clip_ints=NULL; //用于收集重叠的区域 struct tagClipRect *temp1; //临时变量 struct tagRectangle ints_rect,src_rect; bool_t EndSub; ufast_t uftemp; //减数队列为空 if(sub == NULL) { //被减数队列为空 if(src == NULL) {//src与sub相交、不相交的部分都为空 *ins = NULL; *different = NULL; return; }else {//src与sub相交部分为空、不相交的部分为src *ins = NULL; *different = src; return; } }else //减数队列不为空 { //被减数队列为空 if(src == NULL) {//src与sub相交、不相交的部分都为空 *ins = NULL; *different = NULL;// // *different = sub; return; } } //被减数队列、减数队列都不为空 LoopSrc = src; do{ worksrc = LoopSrc; LoopSrc = LoopSrc->next; worksrc->next = worksrc; worksrc->previous = worksrc; subloop = sub; do{ workloop = worksrc; EndLoop = worksrc->previous; EndSub = false; //此处用循环是必要的,减sub中第一个矩形时worksrc只有一个矩形,可 //以不用循环来处理,但减第二个矩形时,worksrc可能分裂成一个队列。 do { if(__GK_GetRectInts(&workloop->rect,&subloop->rect,&ints_rect)) {//矩形相交 temp1 = (struct tagClipRect *)Mb_Malloc(g_ptClipRectPool,0); temp1->rect = ints_rect; //把相交区域加入clip_ints __GK_ClipConnect(&clip_ints,temp1); src_rect = workloop->rect; uftemp = 0; //以下提取workloop中与subloop中不相交的部分,直接替代src队列 //中workloop的位置 if(subloop->rect.top > src_rect.top) //上部矩形 { //首个矩形,覆盖原结点 workloop->rect.bottom = subloop->rect.top; workloop = workloop->next; uftemp++; } if(subloop->rect.left > src_rect.left) //左部矩形 { //首个矩形,覆盖原结点 if(uftemp == 0) { workloop->rect.right = subloop->rect.left; if(src_rect.bottom < subloop->rect.bottom) workloop->rect.bottom = src_rect.bottom; else workloop->rect.bottom = subloop->rect.bottom; workloop = workloop->next; }else { temp1 = (struct tagClipRect *)Mb_Malloc(g_ptClipRectPool,0); temp1->rect.left = src_rect.left; temp1->rect.top = subloop->rect.top; temp1->rect.right = subloop->rect.left; if(src_rect.bottom < subloop->rect.bottom) temp1->rect.bottom = src_rect.bottom; else temp1->rect.bottom = subloop->rect.bottom; __GK_ClipConnect(&workloop,temp1); } uftemp++; } if(subloop->rect.right < src_rect.right) //右部矩形 { //首个矩形,覆盖原结点 if(uftemp == 0) { workloop->rect.left = subloop->rect.right; if(src_rect.bottom < subloop->rect.bottom) workloop->rect.bottom = src_rect.bottom; else workloop->rect.bottom = subloop->rect.bottom; workloop = workloop->next; }else { temp1 = (struct tagClipRect *)Mb_Malloc(g_ptClipRectPool,0); temp1->rect.left = subloop->rect.right; if(src_rect.top < subloop->rect.top) temp1->rect.top = subloop->rect.top; else temp1->rect.top = src_rect.top; temp1->rect.right = src_rect.right; if(src_rect.bottom < subloop->rect.bottom) temp1->rect.bottom = src_rect.bottom; else temp1->rect.bottom = subloop->rect.bottom; __GK_ClipConnect(&workloop,temp1); } uftemp++; } if(subloop->rect.bottom < src_rect.bottom) //下部矩形 { //首个矩形,覆盖原结点 if(uftemp == 0) { workloop->rect.top = subloop->rect.bottom; workloop = workloop->next; }else { temp1 = (struct tagClipRect *)Mb_Malloc(g_ptClipRectPool,0); temp1->rect.left = src_rect.left; temp1->rect.top = subloop->rect.bottom; temp1->rect.right = src_rect.right; temp1->rect.bottom = src_rect.bottom; __GK_ClipConnect(&workloop,temp1); } uftemp++; } if(uftemp == 0) //源矩形被完全覆盖, { if(worksrc->next == worksrc) //源队列只有一个矩形 { Mb_Free(g_ptClipRectPool,worksrc); worksrc = NULL; // workloop = NULL; EndSub = true; }else { temp1 = workloop; workloop = workloop->next; temp1->previous->next = workloop; workloop->previous = temp1->previous; if(worksrc == temp1) worksrc = workloop; if(EndLoop == temp1) EndSub = true; Mb_Free(g_ptClipRectPool,temp1); } } else { workloop = workloop->next; } } else //矩形不相交 { workloop = workloop->next; } if(workloop->previous == EndLoop) EndSub = true; }while(EndSub == false); if(worksrc == NULL) break; subloop = subloop->next; }while(subloop != sub); __GK_ClipLinkConnect(&difftemp,worksrc); }while(src != LoopSrc); *different = difftemp; *ins = clip_ints; }
//----获取被修改区域----------------------------------------------------------- //功能: 获取一个窗口的被修改部分的剪切域,形成双向循环链表,链表中的clip以先 // 左->右,再上->下的顺序排列,并清零changed_msk数组。 //参数: gkwin,目标窗口 //返回: 链表指针,NULL表示窗口未被修改 //----------------------------------------------------------------------------- struct tagClipRect *__GK_GetChangedClip(struct tagGkWinRsc *gkwin) { struct tagClipRect *clip=NULL,*clip1,*tempclip,*clip_head = NULL; u8 *msk; u32 offset_bit,offset,msk_line_words; s16 loopx,loopy; bool_t start; s32 width,height; if(gkwin->change_flag == CN_GKWIN_CHANGE_ALL) //整个窗口均被修改 { clip = (struct tagClipRect *)Mb_Malloc(g_ptClipRectPool,0); if(clip != NULL) { clip->rect.left = gkwin->limit_left + gkwin->absx0; clip->rect.top = gkwin->limit_top + gkwin->absy0; clip->rect.right = gkwin->limit_right + gkwin->absx0; clip->rect.bottom = gkwin->limit_bottom + gkwin->absy0; clip->next = clip; clip->previous = clip; gkwin->change_flag = CN_GKWIN_CHANGE_NONE; return clip; //把整个窗口的可显示区域当作一个剪切域返回 } else return NULL; }else if(gkwin->change_flag == CN_GKWIN_CHANGE_NONE) //没有修改 { return NULL; }else //部分修改,先按x方向取得剪切域,再按y方向合并 { offset = 0; //首行字偏移量 msk = gkwin->changed_msk.bm_bits; width = gkwin->wm_bitmap->width; height = gkwin->wm_bitmap->height; msk_line_words = gkwin->changed_msk.linebytes; for(loopy = 0; loopy < height; loopy +=8) { start = false; //开始一段连续的被修改区域 offset_bit = 0; //起始块的位偏移 for(loopx = 0; loopx < width; loopx+=8) { if(msk[offset+offset_bit/8]&(u8)(1<<(8-(offset_bit%8)-1))) { //该块的changed flag为true。 if(start == false) //changed block开始被修改 { start = true; clip =(struct tagClipRect*)Mb_Malloc(g_ptClipRectPool,0); if(clip != NULL) { clip->rect.left = gkwin->absx0 + offset_bit*8; clip->rect.top = loopy + gkwin->absy0; clip->rect.right = clip->rect.left + 8; clip->rect.bottom = clip->rect.top + 8; } else { __GK_FreeClipQueue(clip_head); return NULL; } }else //changed block持续 { clip->rect.right += 8; } }else //如果本行的最后一块也是被改写的块,则程序不会走到这里 { if(start == true) //changed block结束 { __GK_ClipConnect(&clip_head,clip); start = false; } } offset_bit++; } //本行最后一块是被改写块,需要在这里把该区域加入被修改区域 if(start == true) __GK_ClipConnect(&clip_head,clip); offset += msk_line_words; } //至此,x方向条状clip已经生成,现在沿y方向合并 clip = clip_head; do{ clip1 = clip->next; while(clip1 != clip) { if((clip1->rect.left == clip->rect.left) &&(clip1->rect.right == clip->rect.right) &&((clip->rect.bottom)== clip1->rect.top))//可合并 { clip->rect.bottom += 8; clip1->previous->next = clip1->next; clip1->next->previous = clip1->previous; tempclip = clip1; clip1 = clip1->next; Mb_Free(g_ptClipRectPool,tempclip); }else clip1 = clip1->next; } clip = clip->next; }while(clip != clip_head); gkwin->change_flag = CN_GKWIN_CHANGE_NONE; } memset(msk,0,msk_line_words * gkwin->changed_msk.height); return clip_head; }
// ============================================================================= // 函数功能:释放vncclip的存储空间, // 输入参数: // 输出参数: // 返回值 :NULL,失败,否则成功 // 说明 :这是从VNC的内存池分配的空间,所以一般的情况下,请不要擅自删除,使用API函数 // 对应的分配和删除 // ============================================================================= void free_vncclip_space(struct tagClipRect *clip) { Mb_Free(pg_vncclip_pool,clip); }