Chinaunix首页 | 论坛 | 博客
  • 博客访问: 457349
  • 博文数量: 64
  • 博客积分: 3271
  • 博客等级: 中校
  • 技术积分: 727
  • 用 户 组: 普通用户
  • 注册时间: 2009-07-30 18:42
文章分类

全部博文(64)

文章存档

2013年(1)

2011年(19)

2010年(42)

2009年(2)

分类: C/C++

2011-07-28 15:01:36

evince 的程序入口在shell/Main.c中;

  1. int main (int argc, char *argv[])
  2. {
  3.     GOptionContext *context;
  4.     GError *error = NULL;

GOptionContext用于处理命令行传递的参数。

命令行参数处理完成后进入 

  1. if (!ev_init ())
  2.                 return 1;

ev_init()函数用于backend相关的处理,evince 支持pdf,xps,odf等等backend;


  1. #if defined(WITH_SMCLIENT) && defined(GDK_WINDOWING_X11)
  2.     egg_set_desktop_file (GNOMEDATADIR "/applications/evince.desktop");
  3. #else
  4.     /* Manually set name and icon */
  5.     g_set_application_name (_("Document Viewer"));
  6.     gtk_window_set_default_icon_name ("evince");
  7. #endif /* WITH_SMCLIENT && GDK_WINDOWING_X11 */

  8.     ev_application_load_session (EV_APP);
  9.     load_files (file_arguments);

然后调用ev_application_load_session,此函数完成了创建窗体,并且显示文档。EV_APP是一个函数宏,些函数完成了application的创建。

  1. #define EV_APP (ev_application_get_instance ())
  1. /**
  2. * ev_application_get_instance:
  3. *
  4. * Checks for #EvApplication instance, if it doesn't exist it does create it.
  5. *
  6. * Returns: an instance of the #EvApplication data.
  7. */
  8. EvApplication *
  9. ev_application_get_instance (void)
  10. {
  11.     if (!instance) {
  12.         instance = EV_APPLICATION (g_object_new (EV_TYPE_APPLICATION, NULL));
  13.     }

  14.     return instance;
  15. }

 直接创建了一个Application对象的instance。

ev_application_load_session,顾名,猜测其主要用于加载会话(session).


  1. /* Session */
  2. gboolean ev_application_load_session (EvApplication *application)
  3. {
  4.     GKeyFile *state_file;
  5.     gchar *uri;

  6. #ifdef WITH_SMCLIENT
  7.     if (egg_sm_client_is_resumed (application->smclient)) {
  8.         state_file = egg_sm_client_get_state_file (application->smclient);
  9.         if (!state_file)
  10.             return FALSE;
  11.     } else
  12. #endif /* WITH_SMCLIENT */
  13.         return FALSE;

  14.     uri = g_key_file_get_string (state_file, "Evince", "uri", NULL);
  15.     if (!uri)
  16.         return FALSE;

  17.     ev_application_open_uri_at_dest (application, uri,
  18.                      gdk_screen_get_default (),
  19.                      NULL, 0, NULL,
  20.                      GDK_CURRENT_TIME);
  21.     g_free (uri);
  22.     g_key_file_free (state_file);

  23.     return TRUE;
  24. }

如果没有#define WITH_SMCLIENT,即证明没有会话可加载,则函数直接返回为FALSE;如果定义,则检测保存在application中的smclient所 指向的state_file是否存在,不存在,也直接返回;然后根据stat_file获取Evince组的session 的uri.

然后调用

  1. ev_application_open_uri_at_dest

此函数是真正完成工作的函数。它根据给定的application, uri,绘制窗体,加载文件。在load_file函数中也会对它进行调用。


  1. void ev_application_open_uri_at_dest (EvApplication *application,
  2.                  const char *uri,
  3.                  GdkScreen *screen,
  4.                  EvLinkDest *dest,
  5.                  EvWindowRunMode mode,
  6.                  const gchar *search_string,
  7.                  guint timestamp)
  8. {
  9.     g_return_if_fail (uri != NULL);

  10.     if (application->uri && strcmp (application->uri, uri) != 0) {
  11.         /* spawn a new evince process */
  12.         ev_spawn (uri, screen, dest, mode, search_string, timestamp);
  13.         return;
  14.     } else if (!application->uri) {
  15.         application->uri = g_strdup (uri);
  16.     }

  17. #ifdef ENABLE_DBUS
  18.     /* Register the uri or send Reload to
  19.      * remote instance if already registered
  20.      */
  21.     ev_application_register_uri (application, uri, screen, dest, mode, search_string, timestamp);
  22. #else
  23.     _ev_application_open_uri_at_dest (application, uri, screen, dest, mode, search_string, timestamp);
  24. #endif /* ENABLE_DBUS */
  25. }

如果application有一个uri,并且跟现在的uri不同则创建一个新的evince进程。如果没有,则把当前的uri赋值给application->uri。

假如未启用dbus,程序则进入:

  1. _ev_application_open_uri_at_dest (application, uri, screen, dest, mode, search_string, timestamp);

 原型如下:


  1. static void
  2. _ev_application_open_uri_at_dest (EvApplication *application,
  3.                   const gchar *uri,
  4.                   GdkScreen *screen,
  5.                   EvLinkDest *dest,
  6.                   EvWindowRunMode mode,
  7.                   const gchar *search_string,
  8.                   guint timestamp)
  9. {
  10.     EvWindow *ev_window;

  11.     ev_window = ev_application_get_empty_window (application, screen);
  12.     if (!ev_window)
  13.         ev_window = EV_WINDOW (ev_window_new ());

  14.     ev_application_open_uri_in_window (application, uri, ev_window,
  15.                        screen, dest, mode,
  16.                        search_string,
  17.                        timestamp);
  18. }

此函数先找到一个空的窗体,分为两种情况,

1.直接在application结构体中的windows list 中寻找空的窗体。

2.查找不成功,调用ev_window_new 创建一个新的窗体。

窗体创建成功后进入
  1. ev_application_open_uri_in_window

  1. static void
  2. ev_application_open_uri_in_window (EvApplication *application,
  3.                  const char *uri,
  4.                  EvWindow *ev_window,
  5.                  GdkScreen *screen,
  6.                  EvLinkDest *dest,
  7.                  EvWindowRunMode mode,
  8.                  const gchar *search_string,
  9.                  guint timestamp)
  10. {
  11. #ifdef GDK_WINDOWING_X11
  12.     GdkWindow *gdk_window;
  13. #endif

  14.     if (screen) {
  15.         ev_stock_icons_set_screen (screen);
  16.         gtk_window_set_screen (GTK_WINDOW (ev_window), screen);
  17.     }

  18.     /* We need to load uri before showing the window, so
  19.      we can restore window size without flickering */
  20.     ev_window_open_uri (ev_window, uri, dest, mode, search_string);

  21.     if (!gtk_widget_get_realized (GTK_WIDGET (ev_window)))
  22.         gtk_widget_realize (GTK_WIDGET (ev_window));

  23. #ifdef GDK_WINDOWING_X11
  24.     gdk_window = gtk_widget_get_window (GTK_WIDGET (ev_window));

  25.     if (timestamp <= 0)
  26.         timestamp = gdk_x11_get_server_time (gdk_window);
  27.     gdk_x11_window_set_user_time (gdk_window, timestamp);

  28.     gtk_window_present (GTK_WINDOW (ev_window));
  29. #else
  30.     gtk_window_present_with_time (GTK_WINDOW (ev_window), timestamp);
  31. #endif /* GDK_WINDOWING_X11 */
  32. }
函数主要做2件事情 :
1、调用ev_window_open_uri (ev_window, uri, dest, mode, search_string)打开文档;
2、调用gtk_window_present(GTK_WINDOW(ev_window))显示。





阅读(1879) | 评论(0) | 转发(0) |
0

上一篇:evince-自定义类型

下一篇:iis7配置fastcgi

给主人留下些什么吧!~~