static void create_directories(zathura_t* zathura) { static const unsigned int mode = 0700; if (g_mkdir_with_parents(zathura->config.config_dir, mode) == -1) { girara_error("Could not create '%s': %s", zathura->config.config_dir, strerror(errno)); } if (g_mkdir_with_parents(zathura->config.data_dir, mode) == -1) { girara_error("Could not create '%s': %s", zathura->config.data_dir, strerror(errno)); } }
void jumanji_db_bookmark_remove(jumanji_database_t* database, const char* url) { if (database == NULL || database->session == NULL || url == NULL) { return; } /* prepare statement */ static const char SQL_BOOKMARK_ADD[] = "DELETE FROM bookmarks WHERE url = ?;"; sqlite3_stmt* statement = jumanji_db_prepare_statement(database->session, SQL_BOOKMARK_ADD); if (statement == NULL) { return; } /* bind values */ if (sqlite3_bind_text(statement, 1, url, -1, NULL) != SQLITE_OK) { girara_error("Could not bind query parameters"); sqlite3_finalize(statement); return; } sqlite3_step(statement); sqlite3_finalize(statement); }
void jumanji_db_history_add(jumanji_database_t* database, const char* url, const char* title) { if (database == NULL || database->session == NULL || url == NULL || title == NULL) { return; } /* add to database */ static const char SQL_HISTORY_ADD[] = "REPLACE INTO history (url, title, visited) VALUES (?, ?, ?)"; sqlite3_stmt* statement = jumanji_db_prepare_statement(database->session, SQL_HISTORY_ADD); if (statement == NULL) { return; } if (sqlite3_bind_text(statement, 1, url, -1, NULL) != SQLITE_OK || sqlite3_bind_text(statement, 2, title, -1, NULL) != SQLITE_OK || sqlite3_bind_int( statement, 3, time(NULL)) != SQLITE_OK ) { girara_error("Could not bind query parameters"); sqlite3_finalize(statement); return; } sqlite3_step(statement); sqlite3_finalize(statement); }
void jumanji_db_history_clean(jumanji_database_t* database, unsigned int age) { if (database == NULL || database->session == NULL) { return; } /* prepare statement */ static const char SQL_HISTORY_CLEAN[] = "DELETE FROM history WHERE visited >= ?;"; sqlite3_stmt* statement = jumanji_db_prepare_statement(database->session, SQL_HISTORY_CLEAN); if (statement == NULL) { return; } /* bind values */ int visited = time(NULL) - age; if (sqlite3_bind_int(statement, 1, visited) != SQLITE_OK) { girara_error("Could not bind query parameters"); sqlite3_finalize(statement); return; } sqlite3_step(statement); sqlite3_finalize(statement); }
void jumanji_db_quickmark_add(jumanji_database_t* database, const char identifier, const char* url) { if (database == NULL || database->session == NULL || url == NULL) { return; } /* add to database */ static const char SQL_QUICKMARK_ADD[] = "REPLACE INTO quickmarks (identifier, url) VALUES (?, ?)"; sqlite3_stmt* statement = jumanji_db_prepare_statement(database->session, SQL_QUICKMARK_ADD); if (statement == NULL) { return; } if (sqlite3_bind_blob(statement, 1, &identifier, 1, NULL) != SQLITE_OK || sqlite3_bind_text(statement, 2, url, -1, NULL) != SQLITE_OK ) { girara_error("Could not bind query parameters"); sqlite3_finalize(statement); return; } sqlite3_step(statement); sqlite3_finalize(statement); }
char* jumanji_db_quickmark_find(jumanji_database_t* database, const char identifier) { if (database == NULL || database->session == NULL) { return NULL; } /* prepare statement */ static const char SQL_QUICKMARKS_FIND[] = "SELECT url FROM quickmarks WHERE identifier = ?;"; sqlite3_stmt* statement = jumanji_db_prepare_statement(database->session, SQL_QUICKMARKS_FIND); if (statement == NULL) { return NULL; } /* bind values */ if (sqlite3_bind_blob(statement, 1, &identifier, 1, NULL) != SQLITE_OK) { girara_error("Could not bind query parameters"); sqlite3_finalize(statement); return NULL; } char* url = NULL; while(sqlite3_step(statement) == SQLITE_ROW) { url = (char*) sqlite3_column_text(statement, 0); break; } sqlite3_finalize(statement); return url; }
void jumanji_db_quickmark_remove(jumanji_database_t* database, const char identifier) { if (database == NULL || database->session == NULL) { return; } /* prepare statement */ static const char SQL_QUICKMARK_ADD[] = "DELETE FROM quickmarks WHERE identifier = ?;"; sqlite3_stmt* statement = jumanji_db_prepare_statement(database->session, SQL_QUICKMARK_ADD); if (statement == NULL) { return; } /* bind values */ if (sqlite3_bind_blob(statement, 1, &identifier, 1, NULL) != SQLITE_OK) { girara_error("Could not bind query parameters"); sqlite3_finalize(statement); return; } sqlite3_step(statement); sqlite3_finalize(statement); }
void jumanji_db_bookmark_add(jumanji_database_t* database, const char* url, const char* title) { if (database == NULL || database->session == NULL || url == NULL || title == NULL) { return; } /* prepare statement */ static const char SQL_BOOKMARK_ADD[] = "REPLACE INTO bookmarks (url, title) VALUES (?, ?);"; sqlite3_stmt* statement = jumanji_db_prepare_statement(database->session, SQL_BOOKMARK_ADD); if (statement == NULL) { return; } /* bind values */ if (sqlite3_bind_text(statement, 1, url, -1, NULL) != SQLITE_OK || sqlite3_bind_text(statement, 2, title, -1, NULL) != SQLITE_OK ) { girara_error("Could not bind query parameters"); sqlite3_finalize(statement); return; } sqlite3_step(statement); sqlite3_finalize(statement); }
/* main function */ int main(int argc, char* argv[]) { /* init gtk */ gtk_init(&argc, &argv); gst_init(&argc, &argv); /* create nioc session */ nioc_t* nioc = nioc_create(); if (nioc == NULL) { return -1; } /* Init nioc */ if (nioc_init(nioc) == false) { girara_error("Could not initialize nioc."); nioc_free(nioc); return -1; } /* run nioc */ gtk_main(); /* free nioc */ nioc_free(nioc); return 0; }
girara_list_t* jumanji_db_history_find(jumanji_database_t* database, const char* input) { if (database == NULL || database->session == NULL || input == NULL) { return NULL; } /* prepare statement */ static const char SQL_HISTORY_FIND[] = "SELECT * FROM history WHERE " "url LIKE (SELECT '%' || ? || '%') OR " "title LIKE (SELECT '%' || ? || '%');"; sqlite3_stmt* statement = jumanji_db_prepare_statement(database->session, SQL_HISTORY_FIND); if (statement == NULL) { return NULL; } /* bind values */ if (sqlite3_bind_text(statement, 1, input, -1, NULL) != SQLITE_OK || sqlite3_bind_text(statement, 2, input, -1, NULL) != SQLITE_OK ) { girara_error("Could not bind query parameters"); sqlite3_finalize(statement); return NULL; } girara_list_t* results = girara_list_new(); if (results == NULL) { sqlite3_finalize(statement); return NULL; } girara_list_set_free_function(results, jumanji_db_free_result_link); while(sqlite3_step(statement) == SQLITE_ROW) { jumanji_db_result_link_t* link = malloc(sizeof(jumanji_db_result_link_t)); if (link == NULL) { sqlite3_finalize(statement); return NULL; } char* url = (char*) sqlite3_column_text(statement, 0); char* title = (char*) sqlite3_column_text(statement, 1); link->url = g_strdup(url); link->title = g_strdup(title); link->visited = sqlite3_column_int(statement, 2); girara_list_append(results, link); } sqlite3_finalize(statement); return results; }
static void render_job(void* data, void* user_data) { zathura_page_t* page = data; zathura_t* zathura = user_data; if (page == NULL || zathura == NULL) { return; } girara_debug("rendering page %d ...", zathura_page_get_index(page)); if (render(zathura, page) != true) { girara_error("Rendering failed (page %d)\n", zathura_page_get_index(page)); } }
void cb_window_update_icon(ZathuraRenderRequest* GIRARA_UNUSED(request), cairo_surface_t* surface, void* data) { zathura_t* zathura = data; girara_debug("updating window icon"); GdkPixbuf* pixbuf = gdk_pixbuf_get_from_surface(surface, 0, 0, cairo_image_surface_get_width(surface), cairo_image_surface_get_height(surface)); if (pixbuf == NULL) { girara_error("Unable to convert cairo surface to Gdk Pixbuf."); } gtk_window_set_icon(GTK_WINDOW(zathura->ui.session->gtk.window), pixbuf); g_object_unref(pixbuf); }
static int run_synctex_forward(const char* synctex_fwd, const char* filename, int synctex_pid) { GFile* file = g_file_new_for_commandline_arg(filename); if (file == NULL) { girara_error("Unable to handle argument '%s'.", filename); return -1; } char* real_path = g_file_get_path(file); g_object_unref(file); if (real_path == NULL) { girara_error("Failed to determine path for '%s'", filename); return -1; } int line = 0; int column = 0; char* input_file = NULL; if (synctex_parse_input(synctex_fwd, &input_file, &line, &column) == false) { girara_error("Failed to parse argument to --synctex-forward."); g_free(real_path); return -1; } const int ret = zathura_dbus_synctex_position(real_path, input_file, line, column, synctex_pid); g_free(input_file); g_free(real_path); if (ret == -1) { /* D-Bus or SyncTeX failed */ girara_error("Got no usable data from SyncTeX or D-Bus failed in some way."); } return ret; }
char* girara_file_read2(FILE* file) { if (file == NULL) { return NULL; } const off_t curpos = ftello(file); if (curpos == -1) { return NULL; } fseeko(file, 0, SEEK_END); const off_t size = ftello(file) - curpos; fseeko(file, curpos, SEEK_SET); if (size == 0) { char* content = malloc(1); content[0] = '\0'; return content; } /* this can happen on 32 bit systems */ if ((uintmax_t)size >= (uintmax_t)SIZE_MAX) { girara_error("file is too large"); return NULL; } char* buffer = malloc(size + 1); if (buffer == NULL) { return NULL; } size_t read = fread(buffer, size, 1, file); if (read != 1) { free(buffer); return NULL; } buffer[size] = '\0'; return buffer; }
bool sc_adjust_window(girara_session_t* session, girara_argument_t* argument, girara_event_t* UNUSED(event), unsigned int UNUSED(t)) { g_return_val_if_fail(session != NULL, false); g_return_val_if_fail(session->global.data != NULL, false); zathura_t* zathura = session->global.data; g_return_val_if_fail(argument != NULL, false); if (argument->n < ZATHURA_ADJUST_NONE || argument->n >= ZATHURA_ADJUST_MODE_NUMBER) { girara_error("Invalid adjust mode: %d", argument->n); girara_notify(session, GIRARA_ERROR, _("Invalid adjust mode: %d"), argument->n); } else { girara_debug("Setting adjust mode to: %d", argument->n); zathura_document_set_adjust_mode(zathura->document, argument->n); adjust_view(zathura); } return false; }
bool zathura_init(zathura_t* zathura) { if (zathura == NULL) { return false; } /* create zathura (config/data) directory */ if (g_mkdir_with_parents(zathura->config.config_dir, 0771) == -1) { girara_error("Could not create '%s': %s", zathura->config.config_dir, strerror(errno)); } if (g_mkdir_with_parents(zathura->config.data_dir, 0771) == -1) { girara_error("Could not create '%s': %s", zathura->config.data_dir, strerror(errno)); } /* load plugins */ zathura_plugin_manager_load(zathura->plugins.manager); /* configuration */ config_load_default(zathura); /* load global configuration files */ char* config_path = girara_get_xdg_path(XDG_CONFIG_DIRS); girara_list_t* config_dirs = girara_split_path_array(config_path); ssize_t size = girara_list_size(config_dirs) - 1; for (; size >= 0; --size) { const char* dir = girara_list_nth(config_dirs, size); char* file = g_build_filename(dir, ZATHURA_RC, NULL); config_load_file(zathura, file); g_free(file); } girara_list_free(config_dirs); g_free(config_path); config_load_file(zathura, GLOBAL_RC); /* load local configuration files */ char* configuration_file = g_build_filename(zathura->config.config_dir, ZATHURA_RC, NULL); config_load_file(zathura, configuration_file); g_free(configuration_file); /* UI */ if (girara_session_init(zathura->ui.session, "zathura") == false) { goto error_free; } /* girara events */ zathura->ui.session->events.buffer_changed = cb_buffer_changed; zathura->ui.session->events.unknown_command = cb_unknown_command; /* page view */ #if (GTK_MAJOR_VERSION == 3) zathura->ui.page_widget = gtk_grid_new(); gtk_grid_set_row_homogeneous(GTK_GRID(zathura->ui.page_widget), TRUE); gtk_grid_set_column_homogeneous(GTK_GRID(zathura->ui.page_widget), TRUE); #else zathura->ui.page_widget = gtk_table_new(0, 0, TRUE); #endif if (zathura->ui.page_widget == NULL) { goto error_free; } g_signal_connect(G_OBJECT(zathura->ui.session->gtk.window), "size-allocate", G_CALLBACK(cb_view_resized), zathura); /* Setup hadjustment tracker */ GtkAdjustment* hadjustment = gtk_scrolled_window_get_hadjustment( GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view)); zathura->ui.hadjustment = zathura_adjustment_clone(hadjustment); g_object_ref_sink(zathura->ui.hadjustment); /* Connect hadjustment signals */ g_signal_connect(G_OBJECT(hadjustment), "value-changed", G_CALLBACK(cb_view_vadjustment_value_changed), zathura); g_signal_connect(G_OBJECT(hadjustment), "value-changed", G_CALLBACK(cb_adjustment_track_value), zathura->ui.hadjustment); g_signal_connect(G_OBJECT(hadjustment), "changed", G_CALLBACK(cb_view_hadjustment_changed), zathura); g_signal_connect(G_OBJECT(hadjustment), "changed", G_CALLBACK(cb_adjustment_track_bounds), zathura->ui.hadjustment); /* Setup vadjustment tracker */ GtkAdjustment* vadjustment = gtk_scrolled_window_get_vadjustment( GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view)); zathura->ui.vadjustment = zathura_adjustment_clone(vadjustment); g_object_ref_sink(zathura->ui.vadjustment); /* Connect vadjustment signals */ g_signal_connect(G_OBJECT(vadjustment), "value-changed", G_CALLBACK(cb_view_vadjustment_value_changed), zathura); g_signal_connect(G_OBJECT(vadjustment), "value-changed", G_CALLBACK(cb_adjustment_track_value), zathura->ui.vadjustment); g_signal_connect(G_OBJECT(vadjustment), "changed", G_CALLBACK(cb_view_vadjustment_changed), zathura); g_signal_connect(G_OBJECT(vadjustment), "changed", G_CALLBACK(cb_adjustment_track_bounds), zathura->ui.vadjustment); /* page view alignment */ zathura->ui.page_widget_alignment = gtk_alignment_new(0.5, 0.5, 0, 0); if (zathura->ui.page_widget_alignment == NULL) { goto error_free; } gtk_container_add(GTK_CONTAINER(zathura->ui.page_widget_alignment), zathura->ui.page_widget); #if (GTK_MAJOR_VERSION == 3) gtk_widget_set_hexpand_set(zathura->ui.page_widget_alignment, TRUE); gtk_widget_set_hexpand(zathura->ui.page_widget_alignment, FALSE); gtk_widget_set_vexpand_set(zathura->ui.page_widget_alignment, TRUE); gtk_widget_set_vexpand(zathura->ui.page_widget_alignment, FALSE); #endif gtk_widget_show(zathura->ui.page_widget); /* statusbar */ zathura->ui.statusbar.file = girara_statusbar_item_add(zathura->ui.session, TRUE, TRUE, TRUE, NULL); if (zathura->ui.statusbar.file == NULL) { goto error_free; } zathura->ui.statusbar.buffer = girara_statusbar_item_add(zathura->ui.session, FALSE, FALSE, FALSE, NULL); if (zathura->ui.statusbar.buffer == NULL) { goto error_free; } zathura->ui.statusbar.page_number = girara_statusbar_item_add(zathura->ui.session, FALSE, FALSE, FALSE, NULL); if (zathura->ui.statusbar.page_number == NULL) { goto error_free; } girara_statusbar_item_set_text(zathura->ui.session, zathura->ui.statusbar.file, _("[No name]")); /* signals */ g_signal_connect(G_OBJECT(zathura->ui.session->gtk.window), "destroy", G_CALLBACK(cb_destroy), zathura); /* set page padding */ int page_padding = 1; girara_setting_get(zathura->ui.session, "page-padding", &page_padding); #if (GTK_MAJOR_VERSION == 3) gtk_grid_set_row_spacing(GTK_GRID(zathura->ui.page_widget), page_padding); gtk_grid_set_column_spacing(GTK_GRID(zathura->ui.page_widget), page_padding); #else gtk_table_set_row_spacings(GTK_TABLE(zathura->ui.page_widget), page_padding); gtk_table_set_col_spacings(GTK_TABLE(zathura->ui.page_widget), page_padding); #endif /* database */ char* database = NULL; girara_setting_get(zathura->ui.session, "database", &database); if (g_strcmp0(database, "plain") == 0) { girara_debug("Using plain database backend."); zathura->database = zathura_plaindatabase_new(zathura->config.data_dir); #ifdef WITH_SQLITE } else if (g_strcmp0(database, "sqlite") == 0) { girara_debug("Using sqlite database backend."); char* tmp = g_build_filename(zathura->config.data_dir, "bookmarks.sqlite", NULL); zathura->database = zathura_sqldatabase_new(tmp); g_free(tmp); #endif } else { girara_error("Database backend '%s' is not supported.", database); } g_free(database); if (zathura->database == NULL) { girara_error("Unable to initialize database. Bookmarks won't be available."); } else { g_object_set(zathura->ui.session->command_history, "io", zathura->database, NULL); } /* bookmarks */ zathura->bookmarks.bookmarks = girara_sorted_list_new2((girara_compare_function_t) zathura_bookmarks_compare, (girara_free_function_t) zathura_bookmark_free); /* jumplist */ zathura->jumplist.max_size = 20; girara_setting_get(zathura->ui.session, "jumplist-size", &(zathura->jumplist.max_size)); zathura->jumplist.list = girara_list_new2(g_free); zathura->jumplist.size = 0; zathura->jumplist.cur = NULL; zathura_jumplist_append_jump(zathura); zathura->jumplist.cur = girara_list_iterator(zathura->jumplist.list); /* page cache */ int cache_size = 0; girara_setting_get(zathura->ui.session, "page-cache-size", &cache_size); if (cache_size <= 0) { girara_warning("page-cache-size is not positive, using %d instead", ZATHURA_PAGE_CACHE_DEFAULT_SIZE); zathura->page_cache.size = ZATHURA_PAGE_CACHE_DEFAULT_SIZE; } else { zathura->page_cache.size = cache_size; } zathura->page_cache.cache = g_malloc(zathura->page_cache.size * sizeof(int)); zathura_page_cache_invalidate_all(zathura); return true; error_free: if (zathura->ui.page_widget != NULL) { g_object_unref(zathura->ui.page_widget); } if (zathura->ui.page_widget_alignment != NULL) { g_object_unref(zathura->ui.page_widget_alignment); } return false; }
/* main function */ 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 */ #if !GLIB_CHECK_VERSION(2, 31, 0) g_thread_init(NULL); #endif gdk_threads_init(); gtk_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; bool synctex = false; int page_number = ZATHURA_PAGE_NUMBER_UNSPECIFIED; #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" }, { "page", 'P', 0, G_OPTION_ARG_INT, &page_number, _("Page number to go to"), "number" }, { "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 }, { "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; } /* Enable/Disable synctex support */ zathura_set_synctex(zathura, synctex); /* 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) { if (page_number > 0) --page_number; document_open_idle(zathura, argv[1], password, page_number); /* 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; }
bool zathura_init(zathura_t* zathura) { if (zathura == NULL) { return false; } /* create zathura (config/data) directory */ if (g_mkdir_with_parents(zathura->config.config_dir, 0771) == -1) { girara_error("Could not create '%s': %s", zathura->config.config_dir, strerror(errno)); } if (g_mkdir_with_parents(zathura->config.data_dir, 0771) == -1) { girara_error("Could not create '%s': %s", zathura->config.data_dir, strerror(errno)); } /* load plugins */ zathura_plugin_manager_load(zathura->plugins.manager); /* configuration */ config_load_default(zathura); config_load_files(zathura); /* UI */ if (girara_session_init(zathura->ui.session, "zathura") == false) { goto error_free; } /* girara events */ zathura->ui.session->events.buffer_changed = cb_buffer_changed; zathura->ui.session->events.unknown_command = cb_unknown_command; /* zathura signals */ zathura->signals.refresh_view = g_signal_new("refresh-view", GTK_TYPE_WIDGET, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_generic, G_TYPE_NONE, 1, G_TYPE_POINTER); g_signal_connect(G_OBJECT(zathura->ui.session->gtk.view), "refresh-view", G_CALLBACK(cb_refresh_view), zathura); /* page view */ zathura->ui.page_widget = gtk_grid_new(); gtk_grid_set_row_homogeneous(GTK_GRID(zathura->ui.page_widget), TRUE); gtk_grid_set_column_homogeneous(GTK_GRID(zathura->ui.page_widget), TRUE); if (zathura->ui.page_widget == NULL) { goto error_free; } g_signal_connect(G_OBJECT(zathura->ui.session->gtk.window), "size-allocate", G_CALLBACK(cb_view_resized), zathura); GtkAdjustment* hadjustment = gtk_scrolled_window_get_hadjustment( GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view)); /* Connect hadjustment signals */ g_signal_connect(G_OBJECT(hadjustment), "value-changed", G_CALLBACK(cb_view_hadjustment_value_changed), zathura); g_signal_connect(G_OBJECT(hadjustment), "changed", G_CALLBACK(cb_view_hadjustment_changed), zathura); GtkAdjustment* vadjustment = gtk_scrolled_window_get_vadjustment( GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view)); /* Connect vadjustment signals */ g_signal_connect(G_OBJECT(vadjustment), "value-changed", G_CALLBACK(cb_view_vadjustment_value_changed), zathura); g_signal_connect(G_OBJECT(vadjustment), "changed", G_CALLBACK(cb_view_vadjustment_changed), zathura); /* page view alignment */ gtk_widget_set_halign(zathura->ui.page_widget, GTK_ALIGN_CENTER); gtk_widget_set_valign(zathura->ui.page_widget, GTK_ALIGN_CENTER); gtk_widget_set_hexpand_set(zathura->ui.page_widget, TRUE); gtk_widget_set_hexpand(zathura->ui.page_widget, FALSE); gtk_widget_set_vexpand_set(zathura->ui.page_widget, TRUE); gtk_widget_set_vexpand(zathura->ui.page_widget, FALSE); gtk_widget_show(zathura->ui.page_widget); /* statusbar */ zathura->ui.statusbar.file = girara_statusbar_item_add(zathura->ui.session, TRUE, TRUE, TRUE, NULL); if (zathura->ui.statusbar.file == NULL) { goto error_free; } zathura->ui.statusbar.buffer = girara_statusbar_item_add(zathura->ui.session, FALSE, FALSE, FALSE, NULL); if (zathura->ui.statusbar.buffer == NULL) { goto error_free; } zathura->ui.statusbar.page_number = girara_statusbar_item_add(zathura->ui.session, FALSE, FALSE, FALSE, NULL); if (zathura->ui.statusbar.page_number == NULL) { goto error_free; } girara_statusbar_item_set_text(zathura->ui.session, zathura->ui.statusbar.file, _("[No name]")); /* signals */ g_signal_connect(G_OBJECT(zathura->ui.session->gtk.window), "destroy", G_CALLBACK(cb_destroy), zathura); /* database */ char* database = NULL; girara_setting_get(zathura->ui.session, "database", &database); if (g_strcmp0(database, "plain") == 0) { girara_debug("Using plain database backend."); zathura->database = zathura_plaindatabase_new(zathura->config.data_dir); #ifdef WITH_SQLITE } else if (g_strcmp0(database, "sqlite") == 0) { girara_debug("Using sqlite database backend."); char* tmp = g_build_filename(zathura->config.data_dir, "bookmarks.sqlite", NULL); zathura->database = zathura_sqldatabase_new(tmp); g_free(tmp); #endif } else if (g_strcmp0(database, "null") != 0) { girara_error("Database backend '%s' is not supported.", database); } if (zathura->database == NULL && g_strcmp0(database, "null") != 0) { girara_error("Unable to initialize database. Bookmarks won't be available."); } else { g_object_set(G_OBJECT(zathura->ui.session->command_history), "io", zathura->database, NULL); } g_free(database); /* bookmarks */ zathura->bookmarks.bookmarks = girara_sorted_list_new2((girara_compare_function_t) zathura_bookmarks_compare, (girara_free_function_t) zathura_bookmark_free); /* jumplist */ int jumplist_size = 20; girara_setting_get(zathura->ui.session, "jumplist-size", &jumplist_size); zathura->jumplist.max_size = jumplist_size < 0 ? 0 : jumplist_size; zathura->jumplist.list = NULL; zathura->jumplist.size = 0; zathura->jumplist.cur = NULL; /* CSS for index mode */ GiraraTemplate* csstemplate = girara_session_get_template(zathura->ui.session); static const char* index_settings[] = { "index-fg", "index-bg", "index-active-fg", "index-active-bg" }; for (size_t s = 0; s < LENGTH(index_settings); ++s) { girara_template_add_variable(csstemplate, index_settings[s]); char* tmp_value = NULL; GdkRGBA rgba = { 0, 0, 0, 0 }; girara_setting_get(zathura->ui.session, index_settings[s], &tmp_value); if (tmp_value != NULL) { gdk_rgba_parse(&rgba, tmp_value); g_free(tmp_value); } char* color = gdk_rgba_to_string(&rgba); girara_template_set_variable_value(csstemplate, index_settings[s], color); g_free(color); } char* css = g_strdup_printf("%s\n%s", girara_template_get_base(csstemplate), CSS_TEMPLATE_INDEX); girara_template_set_base(csstemplate, css); g_free(css); /* Start D-Bus service */ bool dbus = true; girara_setting_get(zathura->ui.session, "dbus-service", &dbus); if (dbus == true) { zathura->dbus = zathura_dbus_new(zathura); } return true; error_free: if (zathura->ui.page_widget != NULL) { g_object_unref(zathura->ui.page_widget); } return false; }
zathura_document_t* zathura_document_open(zathura_plugin_manager_t* plugin_manager, const char* path, const char* password, zathura_error_t* error) { if (path == NULL) { return NULL; } if (g_file_test(path, G_FILE_TEST_EXISTS) == FALSE) { girara_error("File '%s' does not exist", path); return NULL; } const gchar* content_type = guess_type(path); if (content_type == NULL) { girara_error("Could not determine file type."); return NULL; } /* determine real path */ long path_max; #ifdef PATH_MAX path_max = PATH_MAX; #else path_max = pathconf(path,_PC_PATH_MAX); if (path_max <= 0) path_max = 4096; #endif char* real_path = NULL; zathura_document_t* document = NULL; real_path = malloc(sizeof(char) * path_max); if (real_path == NULL) { g_free((void*)content_type); return NULL; } if (realpath(path, real_path) == NULL) { g_free((void*)content_type); free(real_path); return NULL; } zathura_plugin_t* plugin = zathura_plugin_manager_get_plugin(plugin_manager, content_type); g_free((void*)content_type); if (plugin == NULL) { girara_error("unknown file type\n"); goto error_free; } document = g_malloc0(sizeof(zathura_document_t)); document->file_path = real_path; document->password = password; document->scale = 1.0; document->plugin = plugin; document->adjust_mode = ZATHURA_ADJUST_NONE; /* open document */ zathura_plugin_functions_t* functions = zathura_plugin_get_functions(plugin); if (functions->document_open == NULL) { girara_error("plugin has no open function\n"); goto error_free; } zathura_error_t int_error = functions->document_open(document); if (int_error != ZATHURA_ERROR_OK) { if (error != NULL) { *error = int_error; } girara_error("could not open document\n"); goto error_free; } /* read all pages */ document->pages = calloc(document->number_of_pages, sizeof(zathura_page_t*)); if (document->pages == NULL) { goto error_free; } for (unsigned int page_id = 0; page_id < document->number_of_pages; page_id++) { zathura_page_t* page = zathura_page_new(document, page_id, NULL); if (page == NULL) { goto error_free; } document->pages[page_id] = page; } return document; error_free: free(real_path); if (document != NULL && document->pages != NULL) { for (unsigned int page_id = 0; page_id < document->number_of_pages; page_id++) { zathura_page_free(document->pages[page_id]); } free(document->pages); } g_free(document); return NULL; }
void zathura_plugin_manager_load(zathura_plugin_manager_t* plugin_manager) { if (plugin_manager == NULL || plugin_manager->path == NULL) { return; } GIRARA_LIST_FOREACH(plugin_manager->path, char*, iter, plugindir) /* read all files in the plugin directory */ GDir* dir = g_dir_open(plugindir, 0, NULL); if (dir == NULL) { girara_error("could not open plugin directory: %s", plugindir); girara_list_iterator_next(iter); continue; } char* name = NULL; while ((name = (char*) g_dir_read_name(dir)) != NULL) { char* path = g_build_filename(plugindir, name, NULL); if (g_file_test(path, G_FILE_TEST_IS_REGULAR) == 0) { girara_debug("%s is not a regular file. Skipping.", path); g_free(path); continue; } if (check_suffix(path) == false) { girara_debug("%s is not a plugin file. Skipping.", path); g_free(path); continue; } zathura_plugin_t* plugin = NULL; /* load plugin */ GModule* handle = g_module_open(path, G_MODULE_BIND_LOCAL); if (handle == NULL) { girara_error("could not load plugin %s (%s)", path, g_module_error()); g_free(path); continue; } /* resolve symbols and check API and ABI version*/ zathura_plugin_api_version_t api_version = NULL; if (g_module_symbol(handle, PLUGIN_API_VERSION_FUNCTION, (gpointer*) &api_version) == FALSE || api_version == NULL) { girara_error("could not find '%s' function in plugin %s", PLUGIN_API_VERSION_FUNCTION, path); g_free(path); g_module_close(handle); continue; } if (api_version() != ZATHURA_API_VERSION) { girara_error("plugin %s has been built againt zathura with a different API version (plugin: %d, zathura: %d)", path, api_version(), ZATHURA_API_VERSION); g_free(path); g_module_close(handle); continue; } zathura_plugin_abi_version_t abi_version = NULL; if (g_module_symbol(handle, PLUGIN_ABI_VERSION_FUNCTION, (gpointer*) &abi_version) == FALSE || abi_version == NULL) { girara_error("could not find '%s' function in plugin %s", PLUGIN_ABI_VERSION_FUNCTION, path); g_free(path); g_module_close(handle); continue; } if (abi_version() != ZATHURA_ABI_VERSION) { girara_error("plugin %s has been built againt zathura with a different ABI version (plugin: %d, zathura: %d)", path, abi_version(), ZATHURA_ABI_VERSION); g_free(path); g_module_close(handle); continue; } zathura_plugin_register_service_t register_service = NULL; if (g_module_symbol(handle, PLUGIN_REGISTER_FUNCTION, (gpointer*) ®ister_service) == FALSE || register_service == NULL) { girara_error("could not find '%s' function in plugin %s", PLUGIN_REGISTER_FUNCTION, path); g_free(path); g_module_close(handle); continue; } plugin = g_try_malloc0(sizeof(zathura_plugin_t)); if (plugin == NULL) { girara_error("Failed to allocate memory for plugin."); g_free(path); g_module_close(handle); continue; } plugin->content_types = girara_list_new2(g_free); plugin->handle = handle; register_service(plugin); /* register functions */ if (plugin->register_function == NULL) { girara_error("plugin has no document functions register function"); g_free(path); g_free(plugin); g_module_close(handle); continue; } plugin->register_function(&(plugin->functions)); plugin->path = path; bool ret = register_plugin(plugin_manager, plugin); if (ret == false) { girara_error("could not register plugin %s", path); zathura_plugin_free(plugin); } else { girara_debug("successfully loaded plugin %s", path); zathura_plugin_version_function_t plugin_major = NULL, plugin_minor = NULL, plugin_rev = NULL; g_module_symbol(handle, PLUGIN_VERSION_MAJOR_FUNCTION, (gpointer*) &plugin_major); g_module_symbol(handle, PLUGIN_VERSION_MINOR_FUNCTION, (gpointer*) &plugin_minor); g_module_symbol(handle, PLUGIN_VERSION_REVISION_FUNCTION, (gpointer*) &plugin_rev); if (plugin_major != NULL && plugin_minor != NULL && plugin_rev != NULL) { plugin->version.major = plugin_major(); plugin->version.minor = plugin_minor(); plugin->version.rev = plugin_rev(); girara_debug("plugin '%s': version %u.%u.%u", path, plugin->version.major, plugin->version.minor, plugin->version.rev); } } } g_dir_close(dir); GIRARA_LIST_FOREACH_END(zathura->plugins.path, char*, iter, plugindir); }
bool zathura_init(zathura_t* zathura) { if (zathura == NULL) { return false; } /* create zathura (config/data) directory */ if (g_mkdir_with_parents(zathura->config.config_dir, 0771) == -1) { girara_error("Could not create '%s': %s", zathura->config.config_dir, strerror(errno)); } if (g_mkdir_with_parents(zathura->config.data_dir, 0771) == -1) { girara_error("Could not create '%s': %s", zathura->config.data_dir, strerror(errno)); } /* load plugins */ zathura_plugin_manager_load(zathura->plugins.manager); /* configuration */ config_load_default(zathura); /* load global configuration files */ char* config_path = girara_get_xdg_path(XDG_CONFIG_DIRS); girara_list_t* config_dirs = girara_split_path_array(config_path); ssize_t size = girara_list_size(config_dirs) - 1; for (; size >= 0; --size) { const char* dir = girara_list_nth(config_dirs, size); char* file = g_build_filename(dir, ZATHURA_RC, NULL); config_load_file(zathura, file); g_free(file); } girara_list_free(config_dirs); g_free(config_path); config_load_file(zathura, GLOBAL_RC); /* load local configuration files */ char* configuration_file = g_build_filename(zathura->config.config_dir, ZATHURA_RC, NULL); config_load_file(zathura, configuration_file); g_free(configuration_file); /* UI */ if (girara_session_init(zathura->ui.session, "zathura") == false) { goto error_free; } /* girara events */ zathura->ui.session->events.buffer_changed = cb_buffer_changed; zathura->ui.session->events.unknown_command = cb_unknown_command; /* zathura signals */ zathura->signals.refresh_view = g_signal_new("refresh-view", GTK_TYPE_WIDGET, G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_generic, G_TYPE_NONE, 1, G_TYPE_POINTER); g_signal_connect(G_OBJECT(zathura->ui.session->gtk.view), "refresh-view", G_CALLBACK(cb_refresh_view), zathura); /* page view */ #if (GTK_MAJOR_VERSION == 3) zathura->ui.page_widget = gtk_grid_new(); gtk_grid_set_row_homogeneous(GTK_GRID(zathura->ui.page_widget), TRUE); gtk_grid_set_column_homogeneous(GTK_GRID(zathura->ui.page_widget), TRUE); #else zathura->ui.page_widget = gtk_table_new(0, 0, TRUE); #endif if (zathura->ui.page_widget == NULL) { goto error_free; } g_signal_connect(G_OBJECT(zathura->ui.session->gtk.window), "size-allocate", G_CALLBACK(cb_view_resized), zathura); GtkAdjustment* hadjustment = gtk_scrolled_window_get_hadjustment( GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view)); /* Connect hadjustment signals */ g_signal_connect(G_OBJECT(hadjustment), "value-changed", G_CALLBACK(cb_view_hadjustment_value_changed), zathura); g_signal_connect(G_OBJECT(hadjustment), "changed", G_CALLBACK(cb_view_hadjustment_changed), zathura); GtkAdjustment* vadjustment = gtk_scrolled_window_get_vadjustment( GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view)); /* Connect vadjustment signals */ g_signal_connect(G_OBJECT(vadjustment), "value-changed", G_CALLBACK(cb_view_vadjustment_value_changed), zathura); g_signal_connect(G_OBJECT(vadjustment), "changed", G_CALLBACK(cb_view_vadjustment_changed), zathura); /* page view alignment */ zathura->ui.page_widget_alignment = gtk_alignment_new(0.5, 0.5, 0, 0); if (zathura->ui.page_widget_alignment == NULL) { goto error_free; } gtk_container_add(GTK_CONTAINER(zathura->ui.page_widget_alignment), zathura->ui.page_widget); #if (GTK_MAJOR_VERSION == 3) gtk_widget_set_hexpand_set(zathura->ui.page_widget_alignment, TRUE); gtk_widget_set_hexpand(zathura->ui.page_widget_alignment, FALSE); gtk_widget_set_vexpand_set(zathura->ui.page_widget_alignment, TRUE); gtk_widget_set_vexpand(zathura->ui.page_widget_alignment, FALSE); #endif gtk_widget_show(zathura->ui.page_widget); /* statusbar */ zathura->ui.statusbar.file = girara_statusbar_item_add(zathura->ui.session, TRUE, TRUE, TRUE, NULL); if (zathura->ui.statusbar.file == NULL) { goto error_free; } zathura->ui.statusbar.buffer = girara_statusbar_item_add(zathura->ui.session, FALSE, FALSE, FALSE, NULL); if (zathura->ui.statusbar.buffer == NULL) { goto error_free; } zathura->ui.statusbar.page_number = girara_statusbar_item_add(zathura->ui.session, FALSE, FALSE, FALSE, NULL); if (zathura->ui.statusbar.page_number == NULL) { goto error_free; } girara_statusbar_item_set_text(zathura->ui.session, zathura->ui.statusbar.file, _("[No name]")); /* signals */ g_signal_connect(G_OBJECT(zathura->ui.session->gtk.window), "destroy", G_CALLBACK(cb_destroy), zathura); /* database */ char* database = NULL; girara_setting_get(zathura->ui.session, "database", &database); if (g_strcmp0(database, "plain") == 0) { girara_debug("Using plain database backend."); zathura->database = zathura_plaindatabase_new(zathura->config.data_dir); #ifdef WITH_SQLITE } else if (g_strcmp0(database, "sqlite") == 0) { girara_debug("Using sqlite database backend."); char* tmp = g_build_filename(zathura->config.data_dir, "bookmarks.sqlite", NULL); zathura->database = zathura_sqldatabase_new(tmp); g_free(tmp); #endif } else { girara_error("Database backend '%s' is not supported.", database); } g_free(database); if (zathura->database == NULL) { girara_error("Unable to initialize database. Bookmarks won't be available."); } else { g_object_set(zathura->ui.session->command_history, "io", zathura->database, NULL); } /* bookmarks */ zathura->bookmarks.bookmarks = girara_sorted_list_new2((girara_compare_function_t) zathura_bookmarks_compare, (girara_free_function_t) zathura_bookmark_free); /* jumplist */ int jumplist_size = 20; girara_setting_get(zathura->ui.session, "jumplist-size", &jumplist_size); zathura->jumplist.max_size = jumplist_size < 0 ? 0 : jumplist_size; zathura->jumplist.list = NULL; zathura->jumplist.size = 0; zathura->jumplist.cur = NULL; return true; error_free: if (zathura->ui.page_widget != NULL) { g_object_unref(zathura->ui.page_widget); } if (zathura->ui.page_widget_alignment != NULL) { g_object_unref(zathura->ui.page_widget_alignment); } return false; }
jumanji_database_t* jumanji_db_init(const char* dir) { if (dir == NULL) { return NULL; } char* path = g_build_filename(dir, DATABASE, NULL); if (path == NULL) { goto error_ret; } jumanji_database_t* database = g_malloc0(sizeof(jumanji_database_t)); if (database == NULL) { goto error_free; } /* connect/create to bookmark database */ static const char SQL_BOOKMARK_INIT[] = /* bookmarks table */ "CREATE TABLE IF NOT EXISTS bookmarks (" "url TEXT PRIMARY KEY," "title TEXT" ");"; static const char SQL_HISTORY_INIT[] = /* history table */ "CREATE TABLE IF NOT EXISTS history (" "url TEXT PRIMARY KEY," "title TEXT," "visited INT" ");"; static const char SQL_QUICKMARKS_INIT[] = /* quickmarks table */ "CREATE TABLE IF NOT EXISTS quickmarks (" "identifier CHAR PRIMARY KEY," "url TEXT" ");"; if (sqlite3_open(path, &(database->session)) != SQLITE_OK) { goto error_free; } /* initialize database scheme */ if (sqlite3_exec(database->session, SQL_BOOKMARK_INIT, NULL, 0, NULL) != SQLITE_OK) { girara_error("Could not initialize database: %s\n", path); goto error_free; } if (sqlite3_exec(database->session, SQL_HISTORY_INIT, NULL, 0, NULL) != SQLITE_OK) { girara_error("Could not initialize database: %s\n", path); goto error_free; } if (sqlite3_exec(database->session, SQL_QUICKMARKS_INIT, NULL, 0, NULL) != SQLITE_OK) { girara_error("Could not initialize database: %s\n", path); goto error_free; } return database; error_free: if (database->session != NULL) { sqlite3_close(database->session); } g_free(database); error_ret: g_free(path); return NULL; }