题目起的有点大,主要就是想在看代码时记录下来一些心得轨迹,以后也有个参考。
首先我想从结构上对dt进行一个剖析,期间有不懂的先记下来,dt用了很多我不懂的东西,列举如下:
Gtk+/Cairo
OpenMP
OpenCL
SQLite3
GEGL
GConf
Glade
还有很多图像处理的知识我也晕头转向,Git也是初次接触。。。好多要学的啊,囧!
最后肯定要深入到细节中去,尤其是自己要做的snapshot那部分更是要透彻理解。
先看一下darktable.h中的结构体
在darktable.c中有且只有一个实例darktable_t darktable,它保存了dt运行时的所有信息。
db_insert, plugin_threadsafe是两个互斥变量,gui肯定是dt的界面了,其他的还没看。
main.c有两个重要的函数调用
if(dt_init(argc, argv, 1)) exit(1);
//此函数在darktable.c中,初始化各项资源,调用了一堆函数,后面慢慢分析。
dt_gui_gtk_run(darktable.gui);
//此函数在gtk.c中,调用gtk_main();进入主循环,等待用户输入事件,最后程序结束时又调用了gdk_threads_leave();因为这个函数和gdk_threads_enter();是成对出现的,所以其他的地方一定调用了这个enter函数。我查了一下,有很多地方使用了这两个函数但都是成对的在一个函数中出现的,但是在dt_gui_gtk_init()中有一个enter没有匹配的leave,这就明白了,dt_init调用了dt_gui_gtk_init进行gui的初始化,然后dt_gui_gtk_run中在程序退出时调用leave退出临界区。
if (!g_thread_supported ()) g_thread_init(NULL);
gdk_threads_init();
gdk_threads_enter();
gtk_init (&argc, &argv);
上面是在dt_gui_gtk_init()中的语句,其实可以这样想,glib是最底层的支持所以要先初始化,然后gdk的线程才可以创建和使用。
另外对于gdk_threads_init();文档说“This call must be made before any use of the main loop from GTK+; to be safe, call it before gtk_init()
.” 【http://developer.gnome.org/gdk/stable/gdk-Threads.html】
进入dt_init()的内部看看。。。
#define GETTEXT_PACKAGE "darktable"
#define DARKTABLE_LOCALEDIR "/usr/share/locale"
#define PACKAGE_NAME "darktable"
#define PACKAGE_VERSION "0.8+235~g44e9db7"
#define PACKAGE_STRING PACKAGE_NAME " " PACKAGE_VERSION
#define PACKAGE_BUGREPORT "hanatos@gmail.com"
#define DARKTABLE_LIBDIR "/usr/lib"
#define DARKTABLE_DATADIR "/usr/share/darktable"
通过config.cmake.h生成的一些宏定义,在build/config.h中,记下来,
bindtextdomain ("darktable", "/usr/share/locale");
bind_textdomain_codeset ("darktable", "UTF-8");
textdomain ("darktable");
这三条语句是用上面宏替换后的样子,在shell中通过find /usr/share/locale -name darktable*可以在不同目录中找到许多darktable.mo文件,第一条语句就是为了绑定.mo文件的。
这三条语句可以通过man查看。总之,就是与本地化/国际化(i18n)相关的东西,耽误太多时间了,先放一放,重心不在这儿!!
唉,先停下来,感觉想的东西一旦落实到文字上就处处掣肘,是不是我的表达能力太差了,不能把想法解释清楚?