dfb_system_lookup的作用就是找到当前系统运行程序的环境,比如x11,fbdev,devmem,dummy.
- dfb_system_lookup( void )
- {
- direct_modules_explore_directory( &dfb_core_systems );//得到所有的可以使用的system,这里是遍历系统system目录,把动态库加入到链表中
- direct_list_foreach( l, dfb_core_systems.entries ) {
- funcs = direct_module_ref( module );//增加一个使用引用
- if (!system_module || (!dfb_config->system ||
- !strcasecmp( dfb_config->system, module->name )))//判断当前的模块与系统要使用的模块名字是否相同
- {
- if (system_module)//标识不再使用现在的系统模块
- direct_module_unref( system_module );
- system_module = module;//更新系统使用的system模块
- system_funcs = funcs;
- funcs->GetSystemInfo( &system_info );//获取系统模块的信息
- }
- }
- return DFB_OK;
- }
dfb_system_lookup( void )
{
direct_modules_explore_directory( &dfb_core_systems );//得到所有的可以使用的system,这里是遍历系统system目录,把动态库加入到链表中
direct_list_foreach( l, dfb_core_systems.entries ) {
funcs = direct_module_ref( module );//增加一个使用引用
if (!system_module || (!dfb_config->system ||
!strcasecmp( dfb_config->system, module->name )))//判断当前的模块与系统要使用的模块名字是否相同
{
if (system_module)//标识不再使用现在的系统模块
direct_module_unref( system_module );
system_module = module;//更新系统使用的system模块
system_funcs = funcs;
funcs->GetSystemInfo( &system_info );//获取系统模块的信息
}
}
return DFB_OK;
}
1.dfb_core_systems
在core/system.c里面定义的一个全局的DirectModuleDir变量.使用双向链表把所有的system存放在里面.
- struct __D_DirectModuleDir {
- pthread_mutex_t lock;
- const char *path;//路径
- unsigned int abi_version;
- DirectLink *entries;//双向链表
- DirectModuleEntry *loading;//模块信息
- };
struct __D_DirectModuleDir {
pthread_mutex_t lock;
const char *path;//路径
unsigned int abi_version;
DirectLink *entries;//双向链表
DirectModuleEntry *loading;//模块信息
};
2. direct_modules_explore_directory
- int direct_modules_explore_directory( DirectModuleDir *directory )
- {
- dir = opendir( buf );
- while (readdir_r( dir, &tmp, &entry ) == 0 && entry) {
- void *handle;
- DirectModuleEntry *module;
- int entry_len = strlen(entry->d_name);
- if (entry_len < 4 || //库文件以.so结尾
- entry->d_name[entry_len-1] != 'o' ||
- entry->d_name[entry_len-2] != 's')
- continue;
- if (lookup_by_file( directory, entry->d_name ))//如果在链表中已经有这个库了,不需要再做下面的操作
- continue;
- module = D_CALLOC( 1, sizeof(DirectModuleEntry) );
- D_MAGIC_SET( module, DirectModuleEntry );
- module->directory = directory;
- module->dynamic = true;
- module->file = D_STRDUP( entry->d_name );
- directory->loading = module;
- if ((handle = open_module( module )) != NULL) {//调用dlopen,进行自动化注册
- if (!module->loaded) {//自动化注册没有成功进行手动注册
- int len;
- void (*func)( void );
- len = strlen( entry->d_name );
- entry->d_name[len-3] = 0;//去掉库名字里面的.so
- //去掉库名字里面的lib,如果是libdirectfb_fbdev.so,就成了directfb_fbdev,在哪定义的呢
- func = dlsym( handle, entry->d_name + 3 );
- if (func) {
- func();
- }
- if (!module->loaded) {//标识模块不可使用,并把它加入到链表里面以节约时间
- module->disabled = true;
- direct_list_prepend( &directory->entries, &module->link );
- }
- }
- if (module->disabled) {//如果库不可以使用就把它关掉 module->loaded = false; /* may call direct_modules_unregister() */
- dlclose( handle );
- }
- else {
- module->handle = handle; count++;
- }
- }
- else { //无法打开也把这个库加入到链表里为以后搜索节约时间
- module->disabled = true;
- direct_list_prepend( &directory->entries, &module->link );
- }
- directory->loading = NULL;
- }
- closedir( dir );
- return count;
- }
int direct_modules_explore_directory( DirectModuleDir *directory )
{
dir = opendir( buf );
while (readdir_r( dir, &tmp, &entry ) == 0 && entry) {
void *handle;
DirectModuleEntry *module;
int entry_len = strlen(entry->d_name);
if (entry_len < 4 || //库文件以.so结尾
entry->d_name[entry_len-1] != 'o' ||
entry->d_name[entry_len-2] != 's')
continue;
if (lookup_by_file( directory, entry->d_name ))//如果在链表中已经有这个库了,不需要再做下面的操作
continue;
module = D_CALLOC( 1, sizeof(DirectModuleEntry) );
D_MAGIC_SET( module, DirectModuleEntry );
module->directory = directory;
module->dynamic = true;
module->file = D_STRDUP( entry->d_name );
directory->loading = module;
if ((handle = open_module( module )) != NULL) {//调用dlopen,进行自动化注册
if (!module->loaded) {//自动化注册没有成功进行手动注册
int len;
void (*func)( void );
len = strlen( entry->d_name );
entry->d_name[len-3] = 0;//去掉库名字里面的.so
//去掉库名字里面的lib,如果是libdirectfb_fbdev.so,就成了directfb_fbdev,在哪定义的呢
func = dlsym( handle, entry->d_name + 3 );
if (func) {
func();
}
if (!module->loaded) {//标识模块不可使用,并把它加入到链表里面以节约时间
module->disabled = true;
direct_list_prepend( &directory->entries, &module->link );
}
}
if (module->disabled) {//如果库不可以使用就把它关掉 module->loaded = false; /* may call direct_modules_unregister() */
dlclose( handle );
}
else {
module->handle = handle; count++;
}
}
else { //无法打开也把这个库加入到链表里为以后搜索节约时间
module->disabled = true;
direct_list_prepend( &directory->entries, &module->link );
}
directory->loading = NULL;
}
closedir( dir );
return count;
}
这里还有两个问题没有搞明白:dlopen,dlsym.
在dlopen的man手册里面有这么一句话:
Instead, libraries should export routines using the __attribute__((constructor)) and __attribute__((destructor)) function attributes. See the gcc info pages for information on these. Constructor routines are executed before dlopen() returns, and destructor routines are executed before dlclose() returns.
也就是在调用dlopen打开这个库的时候,被标识的构造函数将被先执行.
在core_system.h,可以看到direct_modules_register被标识库constructor,将先被执行.很是自动化.
- void direct_modules_register( DirectModuleDir *directory,
- unsigned int abi_version,
- const char *name,
- const void *funcs )
- {
- if (directory->loading) {
- entry = directory->loading;//取得临时存放的模块
- D_MAGIC_ASSERT( entry, DirectModuleEntry );
- directory->loading = NULL;
- }
- entry->directory = directory;
- entry->loaded = true;//标识载入成功
- entry->name = D_STRDUP( name );
- entry->funcs = funcs;
- entry->disabled = suppress_module( name );
- if (abi_version != directory->abi_version) {
- entry->disabled = true;
- }
- direct_list_prepend( &directory->entries, &entry->link );//加入到链表里面
- }
void direct_modules_register( DirectModuleDir *directory,
unsigned int abi_version,
const char *name,
const void *funcs )
{
if (directory->loading) {
entry = directory->loading;//取得临时存放的模块
D_MAGIC_ASSERT( entry, DirectModuleEntry );
directory->loading = NULL;
}
entry->directory = directory;
entry->loaded = true;//标识载入成功
entry->name = D_STRDUP( name );
entry->funcs = funcs;
entry->disabled = suppress_module( name );
if (abi_version != directory->abi_version) {
entry->disabled = true;
}
direct_list_prepend( &directory->entries, &entry->link );//加入到链表里面
}
如果上面没有自动执行,也就是我们并没有对这个函数进行construct标识,那么就可以调用dlsym找到这个函数,进行手动执行了.
dlsym第一个参数是模块的处理句柄,第二个参数是函数的名称,而这个函数directfb_fbdev又是在哪定义的呢?
在fbdev.c里面调用了宏DFB_CORE_SYSTEM( fbdev ),这样就找到了directfb_fbdev的定义
- #define DFB_CORE_SYSTEM(shortname) \
- __attribute__((constructor)) void directfb_##shortname( void ); \
- \
- void \
- directfb_##shortname( void ) \
- { \
- direct_modules_register( &dfb_core_systems, \
- DFB_CORE_SYSTEM_ABI_VERSION, \
- #shortname, &system_funcs ); \
- }
#define DFB_CORE_SYSTEM(shortname) \
__attribute__((constructor)) void directfb_##shortname( void ); \
\
void \
directfb_##shortname( void ) \
{ \
direct_modules_register( &dfb_core_systems, \
DFB_CORE_SYSTEM_ABI_VERSION, \
#shortname, &system_funcs ); \
}
通过查看devmem,dummy,fbdev,osx,sdl,vnc,x11这些system的具体实现,可以看到它们都是实现也下面的结构体中的函数,然后通过这个结构体注册到系统中.
- static CoreSystemFuncs system_funcs = {
- .GetSystemInfo = system_get_info,
- .Initialize = system_initialize,
- .Join = system_join,
- .Shutdown = system_shutdown,
- .Leave = system_leave,
- .Suspend = system_suspend,
- .Resume = system_resume,
- .GetModes = system_get_modes,
- .GetCurrentMode = system_get_current_mode,
- .ThreadInit = system_thread_init,
- .InputFilter = system_input_filter,
- .MapMMIO = system_map_mmio,
- .UnmapMMIO = system_unmap_mmio,
- .GetAccelerator = system_get_accelerator,
- .VideoMemoryPhysical = system_video_memory_physical,
- .VideoMemoryVirtual = system_video_memory_virtual,
- .VideoRamLength = system_videoram_length,
- .AuxMemoryPhysical = system_aux_memory_physical,
- .AuxMemoryVirtual = system_aux_memory_virtual,
- .AuxRamLength = system_auxram_length,
- .GetBusID = system_get_busid,
- .SurfaceDataSize = system_surface_data_size,
- .SurfaceDataInit = system_surface_data_init,
- .SurfaceDataDestroy = system_surface_data_destroy,
- .GetDeviceID = system_get_deviceid
- };
static CoreSystemFuncs system_funcs = {
.GetSystemInfo = system_get_info,
.Initialize = system_initialize,
.Join = system_join,
.Shutdown = system_shutdown,
.Leave = system_leave,
.Suspend = system_suspend,
.Resume = system_resume,
.GetModes = system_get_modes,
.GetCurrentMode = system_get_current_mode,
.ThreadInit = system_thread_init,
.InputFilter = system_input_filter,
.MapMMIO = system_map_mmio,
.UnmapMMIO = system_unmap_mmio,
.GetAccelerator = system_get_accelerator,
.VideoMemoryPhysical = system_video_memory_physical,
.VideoMemoryVirtual = system_video_memory_virtual,
.VideoRamLength = system_videoram_length,
.AuxMemoryPhysical = system_aux_memory_physical,
.AuxMemoryVirtual = system_aux_memory_virtual,
.AuxRamLength = system_auxram_length,
.GetBusID = system_get_busid,
.SurfaceDataSize = system_surface_data_size,
.SurfaceDataInit = system_surface_data_init,
.SurfaceDataDestroy = system_surface_data_destroy,
.GetDeviceID = system_get_deviceid
};
通过看每一个具体的system的实现,可以看到颜色,透明度等的设置,又可以学到相关的编程知识,进行进一步的知识扩展.