/* * 功能:用于对LCUI进行初始化操作 * 说明:每个使用LCUI实现图形界面的程序,都需要先调用此函数进行LCUI的初始化 * */ int LCUI_Init(void) { if( System.is_inited ) { return -1; } System.is_inited = TRUE; System.func_atexit = NULL; System.exit_code = 0; System.state = STATE_ACTIVE; System.main_tid = LCUIThread_SelfID(); LCUI_ShowCopyrightText(); LCUIApp_Init(); /* 初始化各个模块 */ LCUI_InitEvent(); LCUI_InitFont(); LCUI_InitTimer(); LCUI_InitDevice(); LCUI_InitKeyboard(); LCUI_InitMouse(); LCUI_InitCursor(); LCUI_InitWidget(); LCUI_InitDisplay(); { LCUI_Pos pos; pos.x = LCUIDisplay_GetWidth()/2; pos.y = LCUIDisplay_GetHeight()/2; /* 让鼠标游标居中显示 */ LCUICursor_SetPos( pos ); LCUICursor_Show(); } return 0; }
/** 检测当前是否在主线程上 */ LCUI_BOOL LCUI_IsOnMainLoop(void) { if( !MainApp.loop ) { return FALSE; } return (MainApp.loop->tid == LCUIThread_SelfID()); }
/* * 功能:创建一个LCUI程序 * 说明:此函数会将程序信息添加至程序列表 * 返回值:成功则返回程序的ID,失败则返回-1 **/ static int LCUIAppList_Add( void ) { LCUI_App app; LCUIApp_Init (&app); /* 初始化程序数据结构体 */ app.id = LCUIThread_SelfID(); /* 保存ID */ Queue_Add(&LCUI_Sys.app_list, &app); /* 添加至队列 */ LCUIApp_RegisterMainThread( app.id ); /* 注册程序主线程 */ return 0; }
/* 获取指向程序数据的指针 */ LCUI_API LCUI_App* LCUIApp_GetSelf( void ) { LCUI_Thread id; id = LCUIThread_SelfID(); /* 获取本线程ID */ if(id == LCUI_Sys.display_thread || id == LCUI_Sys.dev_thread || id == LCUI_Sys.self_id || id == LCUI_Sys.timer_thread ) {/* 由于内核及其它线程ID没有被记录,只有直接返回LCUI主程序的线程ID了 */ return LCUIApp_Find((LCUI_ID)LCUI_Sys.self_id); } id = LCUIThread_GetRootThreadID( id ); return LCUIApp_Find( (LCUI_ID)id ); }
LCUIThread_Create( LCUI_Thread *tidp, void (*start_rtn)(void*), void * arg ) { Thread_TreeNode *tt; LCUI_Thread cur_tid; /* 先获取当前所在线程的ID */ cur_tid = LCUIThread_SelfID(); /* 在线程树中查找匹配的线程ID,并得到该结点的指针 */ tt = ThreadTree_Find( &thread_tree, cur_tid ); /* 如果没有搜索到,那就新增,并获得该结点指针 */ if(tt == NULL) { tt = ThreadTreeNode_AddNew( &thread_tree, cur_tid ); if(tt == NULL) { return -1; } } _LCUIThread_Create( tidp, start_rtn, arg ); /* 将得到的线程ID添加至结点 */ ThreadTreeNode_AddNew( tt, *tidp ); return 0; }
/** 运行目标主循环 */ int LCUI_MainLoop_Run( LCUI_MainLoop loop ) { if( loop->state == STATE_RUNNING ) { _DEBUG_MSG("error: main-loop already running."); return -1; } DEBUG_MSG("loop: %p, enter\n", loop); loop->state = STATE_RUNNING; /* 将主循环记录插入至列表表头 */ LinkedList_Goto( &MainApp.loop_list, 0 ); LinkedList_Insert( &MainApp.loop_list, loop ); MainApp.loop = loop; LCUIMutex_Lock( &MainApp.loop_changed ); /* 广播,让其它线程交出主循环运行权 */ LCUICond_Broadcast( &MainApp.loop_cond ); /* 获取运行权 */ LCUIMutex_Lock( &MainApp.loop_mutex ); LCUIMutex_Unlock( &MainApp.loop_changed ); loop->tid = LCUIThread_SelfID(); while( loop->state != STATE_EXITED ) { if( LinkedList_GetTotal(&MainApp.task_list) <= 0 ) { DEBUG_MSG("loop: %p, sleeping...\n", loop); LCUICond_TimedWait( &MainApp.loop_cond, 1000 ); DEBUG_MSG("loop: %p, wakeup\n", loop); /** 如果当前运行的主循环不是自己 */ if( MainApp.loop != loop ) { loop->state = STATE_PAUSED; DEBUG_MSG("loop: %p, release control.\n", loop); LCUIMutex_Unlock( &MainApp.loop_mutex ); /* 等待其它线程获得主循环运行权 */ LCUIMutex_Lock( &MainApp.loop_changed ); LCUIMutex_Unlock( &MainApp.loop_changed ); DEBUG_MSG("loop: %p, waiting...\n", loop); /* 等待其它线程释放主循环运行权 */ LCUIMutex_Lock( &MainApp.loop_mutex ); } continue; } DEBUG_MSG("loop: %p, run task.\n", loop); LCUI_RunTask(); } loop->state = STATE_EXITED; LinkedList_Goto( &MainApp.loop_list, 0 ); LinkedList_Delete( &MainApp.loop_list ); /* 获取处于列表表头的主循环 */ loop = (LCUI_MainLoop)LinkedList_Get( &MainApp.loop_list ); if( loop ) { /* 改变当前运行的主循环 */ MainApp.loop = loop; LCUICond_Broadcast( &MainApp.loop_cond ); } /* 释放运行权 */ LCUIMutex_Unlock( &MainApp.loop_mutex ); /* 如果列表为空,一般意味着LCUI需要退出了 */ if( LinkedList_GetTotal( &MainApp.loop_list ) <= 0 ) { /** 广播,通知相关线程开始进行清理操作 */ LCUICond_Broadcast( &MainApp.loop_list_empty ); } DEBUG_MSG("loop: %p, exit\n", loop); return 0; }
LCUIModule_Thread_Init( void ) { Thread_TreeNode_Init( &thread_tree ); /* 初始化根线程结点 */ thread_tree.tid = LCUIThread_SelfID(); /* 当前线程ID作为根结点 */ LCUI_Sys.self_id = thread_tree.tid; /* 保存线程ID */ }