diff --git a/main.c b/main.c index 7ffd90c..3590e1f 100644 --- a/main.c +++ b/main.c @@ -1,33 +1,146 @@ /* See LICENSE file for license and copyright information */ #include +#include #include #include +#include #include #include "zathura.h" +#include "utils.h" /* main function */ -int main(int argc, char* argv[]) +int +main(int argc, char* argv[]) { + /* init locale */ setlocale(LC_ALL, ""); bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR); bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8"); textdomain(GETTEXT_PACKAGE); + /* init gtk */ g_thread_init(NULL); gdk_threads_init(); gtk_init(&argc, &argv); - zathura_t* zathura = zathura_init(argc, argv); + /* create zathura session */ + zathura_t* zathura = zathura_create(); if (zathura == NULL) { return -1; } + /* parse command line arguments */ + gchar* config_dir = NULL; + gchar* data_dir = NULL; + gchar* plugin_path = NULL; + gchar* loglevel = NULL; + gchar* password = NULL; + gchar* synctex_editor = NULL; + bool forkback = false; + bool print_version = false; + +#if (GTK_MAJOR_VERSION == 3) + Window embed = 0; +#else + GdkNativeWindow embed = 0; +#endif + + GOptionEntry entries[] = { + { "reparent", 'e', 0, G_OPTION_ARG_INT, &embed, _("Reparents to window specified by xid"), "xid" }, + { "config-dir", 'c', 0, G_OPTION_ARG_FILENAME, &config_dir, _("Path to the config directory"), "path" }, + { "data-dir", 'd', 0, G_OPTION_ARG_FILENAME, &data_dir, _("Path to the data directory"), "path" }, + { "plugins-dir", 'p', 0, G_OPTION_ARG_STRING, &plugin_path, _("Path to the directories containing plugins"), "path" }, + { "fork", '\0',0, G_OPTION_ARG_NONE, &forkback, _("Fork into the background"), NULL }, + { "password", 'w', 0, G_OPTION_ARG_STRING, &password, _("Document password"), "password" }, + { "debug", 'l', 0, G_OPTION_ARG_STRING, &loglevel, _("Log level (debug, info, warning, error)"), "level" }, + { "version", 'v', 0, G_OPTION_ARG_NONE, &print_version, _("Print version information"), NULL }, + { "synctex-editor-command", 'x', 0, G_OPTION_ARG_STRING, &synctex_editor, _("Synctex editor (forwarded to the synctex command)"), "cmd" }, + { NULL, '\0', 0, 0, NULL, NULL, NULL } + }; + + GOptionContext* context = g_option_context_new(" [file1] [file2] [...]"); + g_option_context_add_main_entries(context, entries, NULL); + + GError* error = NULL; + if (g_option_context_parse(context, &argc, &argv, &error) == false) { + girara_error("Error parsing command line arguments: %s\n", error->message); + g_option_context_free(context); + g_error_free(error); + + return -1; + } + g_option_context_free(context); + + /* Fork into the background if the user really wants to ... */ + if (forkback == true) { + int pid = fork(); + if (pid > 0) { /* parent */ + exit(0); + } else if (pid < 0) { /* error */ + girara_error("Couldn't fork."); + } + + setsid(); + } + + /* Set log level. */ + if (loglevel == NULL || g_strcmp0(loglevel, "info") == 0) { + girara_set_debug_level(GIRARA_INFO); + } else if (g_strcmp0(loglevel, "warning") == 0) { + girara_set_debug_level(GIRARA_WARNING); + } else if (g_strcmp0(loglevel, "error") == 0) { + girara_set_debug_level(GIRARA_ERROR); + } + + zathura_set_xid(zathura, embed); + zathura_set_config_dir(zathura, config_dir); + zathura_set_data_dir(zathura, data_dir); + zathura_set_plugin_dir(zathura, plugin_path); + zathura_set_synctex_editor_command(zathura, synctex_editor); + zathura_set_argv(zathura, argv); + + /* Init zathura */ + if(zathura_init(zathura) == false) { + girara_error("Could not initialize zathura."); + zathura_free(zathura); + return -1; + } + + /* Print version */ + if (print_version == true) { + char* string = zathura_get_version_string(zathura, false); + if (string != NULL) { + fprintf(stdout, "%s\n", string); + } + zathura_free(zathura); + + return 0; + } + + /* open document if passed */ + if (argc > 1) { + document_open_idle(zathura, argv[1], password); + + /* open additional files */ + for (int i = 2; i < argc; i++) { + char* new_argv[] = { + *(zathura->global.arguments), + argv[i], + NULL + }; + + g_spawn_async(NULL, new_argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, NULL); + } + } + + /* run zathura */ gdk_threads_enter(); gtk_main(); gdk_threads_leave(); + /* free zathura */ zathura_free(zathura); return 0; diff --git a/zathura.c b/zathura.c index afe9307..a364b0e 100644 --- a/zathura.c +++ b/zathura.c @@ -57,132 +57,18 @@ static gboolean purge_pages(gpointer data); /* function implementation */ zathura_t* -zathura_init(int argc, char* argv[]) +zathura_create(void) { - /* parse command line options */ -#if (GTK_MAJOR_VERSION == 2) - GdkNativeWindow embed = 0; -#else - Window embed = 0; -#endif - - gchar* config_dir = NULL, *data_dir = NULL, *plugin_path = NULL, *loglevel = NULL, *password = NULL, *synctex_editor = NULL; - bool forkback = false, print_version = false, synctex = false; - - GOptionEntry entries[] = { - { "reparent", 'e', 0, G_OPTION_ARG_INT, &embed, _("Reparents to window specified by xid"), "xid" }, - { "config-dir", 'c', 0, G_OPTION_ARG_FILENAME, &config_dir, _("Path to the config directory"), "path" }, - { "data-dir", 'd', 0, G_OPTION_ARG_FILENAME, &data_dir, _("Path to the data directory"), "path" }, - { "plugins-dir", 'p', 0, G_OPTION_ARG_STRING, &plugin_path, _("Path to the directories containing plugins"), "path" }, - { "fork", '\0', 0, G_OPTION_ARG_NONE, &forkback, _("Fork into the background"), NULL }, - { "password", 'w', 0, G_OPTION_ARG_STRING, &password, _("Document password"), "password" }, - { "debug", 'l', 0, G_OPTION_ARG_STRING, &loglevel, _("Log level (debug, info, warning, error)"), "level" }, - { "version", 'v', 0, G_OPTION_ARG_NONE, &print_version, _("Print version information"), NULL }, - { "synctex", 's', 0, G_OPTION_ARG_NONE, &synctex, _("Enable synctex support"), NULL }, - { "editor-command", 'x', 0, G_OPTION_ARG_STRING, &synctex_editor, _("Synctex editor (this flag is forwarded to the synctex command)"), "cmd" }, - { NULL, '\0', 0, 0, NULL, NULL, NULL } - }; - - GOptionContext* context = g_option_context_new(" [file1] [file2] [...]"); - g_option_context_add_main_entries(context, entries, NULL); - - GError* error = NULL; - if (g_option_context_parse(context, &argc, &argv, &error) == false) { - printf("Error parsing command line arguments: %s\n", error->message); - g_option_context_free(context); - g_error_free(error); - return NULL; - } - g_option_context_free(context); - - /* Fork into the background if the user really wants to ... */ - if (forkback == true) { - int pid = fork(); - if (pid > 0) { /* parent */ - exit(0); - } else if (pid < 0) { /* error */ - printf("Error: couldn't fork."); - } - - setsid(); - } - - /* Set log level. */ - if (loglevel == NULL || g_strcmp0(loglevel, "info") == 0) { - girara_set_debug_level(GIRARA_INFO); - } else if (g_strcmp0(loglevel, "warning") == 0) { - girara_set_debug_level(GIRARA_WARNING); - } else if (g_strcmp0(loglevel, "error") == 0) { - girara_set_debug_level(GIRARA_ERROR); - } - zathura_t* zathura = g_malloc0(sizeof(zathura_t)); /* global settings */ zathura->global.recolor = false; zathura->global.update_page_number = true; - zathura->global.arguments = argv; /* plugins */ zathura->plugins.manager = zathura_plugin_manager_new(); if (zathura->plugins.manager == NULL) { - goto error_free; - } - - /* configuration and data */ - if (config_dir != NULL) { - zathura->config.config_dir = g_strdup(config_dir); - } else { - gchar* path = girara_get_xdg_path(XDG_CONFIG); - zathura->config.config_dir = g_build_filename(path, "zathura", NULL); - g_free(path); - } - - if (data_dir != NULL) { - zathura->config.data_dir = g_strdup(data_dir); - } else { - gchar* path = girara_get_xdg_path(XDG_DATA); - zathura->config.data_dir = g_build_filename(path, "zathura", NULL); - g_free(path); - } - - /* synctex */ - zathura->synctex.enabled = synctex; - if (synctex_editor) { - zathura->synctex.editor = g_strdup(synctex_editor); - } - - /* create zathura (config/data) directory */ - g_mkdir_with_parents(zathura->config.config_dir, 0771); - g_mkdir_with_parents(zathura->config.data_dir, 0771); - - if (plugin_path != NULL) { - girara_list_t* paths = girara_split_path_array(plugin_path); - GIRARA_LIST_FOREACH(paths, char*, iter, path) - zathura_plugin_manager_add_dir(zathura->plugins.manager, path); - GIRARA_LIST_FOREACH_END(paths, char*, iter, path); - girara_list_free(paths); - } else { -#ifdef ZATHURA_PLUGINDIR - girara_list_t* paths = girara_split_path_array(ZATHURA_PLUGINDIR); - GIRARA_LIST_FOREACH(paths, char*, iter, path) - zathura_plugin_manager_add_dir(zathura->plugins.manager, path); - GIRARA_LIST_FOREACH_END(paths, char*, iter, path); - girara_list_free(paths); -#endif - } - - /* load plugins */ - zathura_plugin_manager_load(zathura->plugins.manager); - - /* Print version */ - if (print_version == true) { - char* string = zathura_get_version_string(zathura, false); - if (string != NULL) { - fprintf(stdout, "%s\n", string); - } - - goto error_free; // FIXME + goto error_out; } /* UI */ @@ -192,6 +78,29 @@ zathura_init(int argc, char* argv[]) zathura->ui.session->global.data = zathura; + return zathura; + +error_out: + + zathura_free(zathura); + + return NULL; +} + +bool +zathura_init(zathura_t* zathura) +{ + if (zathura == NULL) { + return false; + } + + /* create zathura (config/data) directory */ + g_mkdir_with_parents(zathura->config.config_dir, 0771); + g_mkdir_with_parents(zathura->config.data_dir, 0771); + + /* load plugins */ + zathura_plugin_manager_load(zathura->plugins.manager); + /* configuration */ config_load_default(zathura); @@ -215,9 +124,7 @@ zathura_init(int argc, char* argv[]) config_load_file(zathura, configuration_file); g_free(configuration_file); - /* initialize girara */ - zathura->ui.session->gtk.embed = embed; - + /* UI */ if (girara_session_init(zathura->ui.session, "zathura") == false) { goto error_free; } @@ -313,33 +220,12 @@ zathura_init(int argc, char* argv[]) zathura->bookmarks.bookmarks = girara_sorted_list_new2((girara_compare_function_t) zathura_bookmarks_compare, (girara_free_function_t) zathura_bookmark_free); - /* open document if passed */ - if (argc > 1) { - zathura_document_info_t* document_info = g_malloc0(sizeof(zathura_document_info_t)); - - document_info->zathura = zathura; - document_info->path = argv[1]; - document_info->password = password; - gdk_threads_add_idle(document_info_open, document_info); - - /* open additional files */ - for (int i = 2; i < argc; i++) { - char* new_argv[] = { - *(zathura->global.arguments), - argv[i], - NULL - }; - - g_spawn_async(NULL, new_argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, NULL); - } - } - /* add even to purge old pages */ int interval = 30; girara_setting_get(zathura->ui.session, "page-store-interval", &interval); g_timeout_add_seconds(interval, purge_pages, zathura); - return zathura; + return true; error_free: @@ -351,11 +237,7 @@ error_free: g_object_unref(zathura->ui.page_widget_alignment); } -error_out: - - zathura_free(zathura); - - return NULL; + return false; } void @@ -402,6 +284,94 @@ zathura_free(zathura_t* zathura) g_free(zathura); } +void +#if (GTK_MAJOR_VERSION == 2) +zathura_set_xid(zathura_t* zathura, GdkNativeWindow xid) +#else +zathura_set_xid(zathura_t* zathura, Window xid) +#endif +{ + g_return_if_fail(zathura != NULL); + + zathura->ui.session->gtk.embed = xid; +} + +void +zathura_set_config_dir(zathura_t* zathura, const char* dir) +{ + g_return_if_fail(zathura != NULL); + + if (dir != NULL) { + zathura->config.config_dir = g_strdup(dir); + } else { + gchar* path = girara_get_xdg_path(XDG_CONFIG); + zathura->config.config_dir = g_build_filename(path, "zathura", NULL); + g_free(path); + } +} + +void +zathura_set_data_dir(zathura_t* zathura, const char* dir) +{ + if (dir != NULL) { + zathura->config.data_dir = g_strdup(dir); + } else { + gchar* path = girara_get_xdg_path(XDG_DATA); + zathura->config.data_dir = g_build_filename(path, "zathura", NULL); + g_free(path); + } + + g_return_if_fail(zathura != NULL); +} + +void +zathura_set_plugin_dir(zathura_t* zathura, const char* dir) +{ + g_return_if_fail(zathura != NULL); + g_return_if_fail(zathura->plugins.manager != NULL); + + if (dir != NULL) { + girara_list_t* paths = girara_split_path_array(dir); + GIRARA_LIST_FOREACH(paths, char*, iter, path) + zathura_plugin_manager_add_dir(zathura->plugins.manager, path); + GIRARA_LIST_FOREACH_END(paths, char*, iter, path); + girara_list_free(paths); + } else { +#ifdef ZATHURA_PLUGINDIR + girara_list_t* paths = girara_split_path_array(ZATHURA_PLUGINDIR); + GIRARA_LIST_FOREACH(paths, char*, iter, path) + zathura_plugin_manager_add_dir(zathura->plugins.manager, path); + GIRARA_LIST_FOREACH_END(paths, char*, iter, path); + girara_list_free(paths); +#endif + } + +} + +void +zathura_set_synctex_editor_command(zathura_t* zathura, const char* command) +{ + g_return_if_fail(zathura != NULL); + + if (zathura->synctex.editor != NULL) { + g_free(zathura->synctex.editor); + } + + if (command != NULL) { + zathura->synctex.editor = g_strdup(command); + } else { + zathura->synctex.editor = NULL; + } +} + +void +zathura_set_argv(zathura_t* zathura, char** argv) +{ + g_return_if_fail(zathura != NULL); + + zathura->global.arguments = argv; +} + static gchar* prepare_document_open_from_stdin(zathura_t* zathura) { @@ -717,6 +687,22 @@ error_out: return false; } +void +document_open_idle(zathura_t* zathura, const char* path, const char* password) +{ + if (zathura == NULL || path == NULL) { + return; + } + + zathura_document_info_t* document_info = g_malloc0(sizeof(zathura_document_info_t)); + + document_info->zathura = zathura; + document_info->path = path; + document_info->password = password; + + gdk_threads_add_idle(document_info_open, document_info); +} + bool document_save(zathura_t* zathura, const char* path, bool overwrite) { diff --git a/zathura.h b/zathura.h index bbc8ce6..bfe26de 100644 --- a/zathura.h +++ b/zathura.h @@ -121,14 +121,20 @@ struct zathura_s } file_monitor; }; +/** + * Creates a zathura session + * + * @return zathura session object or NULL if zathura could not be creeated + */ +zathura_t* zathura_create(void); + /** * Initializes zathura * - * @param argc Number of arguments - * @param argv Values of arguments - * @return zathura session object or NULL if zathura could not been initialized + * @param zathura The zathura session + * @return true if initialization has been successful */ -zathura_t* zathura_init(int argc, char* argv[]); +bool zathura_init(zathura_t* zathura); /** * Free zathura session @@ -137,6 +143,58 @@ zathura_t* zathura_init(int argc, char* argv[]); */ void zathura_free(zathura_t* zathura); +/** + * Set parent window id + * + * @param zathura The zathura session + * @param xid The window id + */ +#if (GTK_MAJOR_VERSION == 2) +void zathura_set_xid(zathura_t* zathura, GdkNativeWindow xid); +#else +void zathura_set_xid(zathura_t* zathura, Window xid); +#endif + +/** + * Set the path to the configuration directory + * + * @param zathura The zathura session + * @param dir Directory path + */ +void zathura_set_config_dir(zathura_t* zathura, const char* dir); + +/** + * Set the path to the data directory + * + * @param zathura The zathura session + * @param dir Directory path + */ +void zathura_set_data_dir(zathura_t* zathura, const char* dir); + +/** + * Set the path to the plugin directory + * + * @param zathura The zathura session + * @param dir Directory path + */ +void zathura_set_plugin_dir(zathura_t* zathura, const char* dir); + +/** + * Enables synctex support and sets the synctex editor command + * + * @param zathura The zathura session + * @param command Synctex editor command + */ +void zathura_set_synctex_editor_command(zathura_t* zathura, const char* command); + +/** + * Sets the program parameters + * + * @param zathura The zathura session + * @param argv List of arguments + */ +void zathura_set_argv(zathura_t* zathura, char** argv); + /** * Opens a file * @@ -148,6 +206,15 @@ void zathura_free(zathura_t* zathura); */ bool document_open(zathura_t* zathura, const char* path, const char* password); +/** + * Opens a file (idle) + * + * @param zathura The zathura session + * @param path The path to the file + * @param password The password of the file + */ +void document_open_idle(zathura_t* zathura, const char* path, const char* password); + /** * Save a open file *