} END_TEST START_TEST(test_datastructures_sorted_list) { girara_list_t* list = girara_sorted_list_new2((girara_compare_function_t) g_strcmp0, (girara_free_function_t) g_free); fail_unless((list != NULL), NULL); girara_list_t* unsorted_list = girara_list_new2((girara_free_function_t) g_free); fail_unless((unsorted_list != NULL), NULL); static const char* test_strings[] = { "A", "C", "Baa", "Za", "Bba", "Bab", NULL }; static const char* test_strings_sorted[] = { "A", "Baa", "Bab", "Bba", "C", "Za", NULL }; // append for (const char** p = test_strings; *p != NULL; ++p) { girara_list_append(list, (void*)g_strdup(*p)); girara_list_append(unsorted_list, (void*)g_strdup(*p)); } fail_unless((girara_list_size(list) == sizeof(test_strings) / sizeof(char*) - 1), NULL); fail_unless((girara_list_size(unsorted_list) == sizeof(test_strings) / sizeof(char*) - 1), NULL); // check sorting const char** p = test_strings_sorted; GIRARA_LIST_FOREACH(list, const char*, iter, value) fail_unless((g_strcmp0(value, *p) == 0), NULL); ++p; GIRARA_LIST_FOREACH_END(list, const char*, iter, value); girara_list_sort(unsorted_list, (girara_compare_function_t) g_strcmp0); p = test_strings_sorted; GIRARA_LIST_FOREACH(unsorted_list, const char*, iter, value) fail_unless((g_strcmp0(value, *p) == 0), NULL); ++p; GIRARA_LIST_FOREACH_END(unsorted_list, const char*, iter, value); girara_list_free(list); girara_list_free(unsorted_list); } END_TEST
} END_TEST START_TEST(test_datastructures_list_free_already_cleared) { // free cleared list girara_list_t* list = girara_list_new(); fail_unless((list != NULL), NULL); girara_list_append(list, (void*) 0xDEAD); fail_unless((girara_list_size(list) == 1), NULL); girara_list_clear(list); fail_unless((girara_list_size(list) == 0), NULL); girara_list_free(list); } END_TEST
bool cmd_search_engine(girara_session_t* session, girara_list_t* argument_list) { g_return_val_if_fail(session != NULL, false); g_return_val_if_fail(session->global.data != NULL, false); jumanji_t* jumanji = (jumanji_t*) session->global.data; if (jumanji->global.search_engines == NULL) { return false; } if (girara_list_size(argument_list) < 2) { return false; } char* identifier = (char*) girara_list_nth(argument_list, 0); char* url = (char*) girara_list_nth(argument_list, 1); /* search for existing search engine */ if (girara_list_size(jumanji->global.search_engines) > 0) { girara_list_iterator_t* iter = girara_list_iterator(jumanji->global.search_engines); do { jumanji_search_engine_t* search_engine = (jumanji_search_engine_t*) girara_list_iterator_data(iter); if (search_engine == NULL) { continue; } if (!g_strcmp0(search_engine->identifier, identifier)) { g_free(search_engine->url); search_engine->url = g_strdup(url); return true; } } while (girara_list_iterator_next(iter)); girara_list_iterator_free(iter); } /* create new entry */ jumanji_search_engine_t* search_engine = malloc(sizeof(jumanji_search_engine_t)); if (search_engine == NULL) { return false; } search_engine->url = g_strdup(url); search_engine->identifier = g_strdup(identifier); girara_list_append(jumanji->global.search_engines, search_engine); return true; }
bool cmd_savef(girara_session_t* session, girara_list_t* argument_list) { g_return_val_if_fail(session != NULL, false); g_return_val_if_fail(session->global.data != NULL, false); zathura_t* zathura = session->global.data; if (zathura->document == NULL) { girara_notify(session, GIRARA_ERROR, _("No document opened.")); return false; } if (girara_list_size(argument_list) == 1) { if (document_save(zathura, girara_list_nth(argument_list, 0), true) == true) { girara_notify(session, GIRARA_INFO, _("Document saved.")); } else { girara_notify(session, GIRARA_INFO, _("Failed to save document.")); } } else { girara_notify(session, GIRARA_ERROR, _("Invalid number of arguments.")); return false; } return true; }
bool cmd_marks_add(girara_session_t* session, girara_list_t* argument_list) { g_return_val_if_fail(session != NULL, false); g_return_val_if_fail(session->global.data != NULL, false); zathura_t* zathura = (zathura_t*) session->global.data; if (girara_list_size(argument_list) < 1) { return false; } char* key_string = girara_list_nth(argument_list, 0); if (key_string == NULL) { return false; } if (strlen(key_string) < 1 || strlen(key_string) > 1) { return false; } char key = key_string[0]; if (((key >= 0x41 && key <= 0x5A) || (key >= 0x61 && key <= 0x7A)) == false) { return false; } mark_add(zathura, key); return false; }
bool cmd_offset(girara_session_t* session, girara_list_t* argument_list) { g_return_val_if_fail(session != NULL, false); g_return_val_if_fail(session->global.data != NULL, false); zathura_t* zathura = session->global.data; if (zathura->document == NULL) { girara_notify(session, GIRARA_ERROR, _("No document opened.")); return false; } /* no argument: take current page as offset */ int page_offset = zathura_document_get_current_page_number(zathura->document); /* retrieve offset from argument */ if (girara_list_size(argument_list) == 1) { const char* value = girara_list_nth(argument_list, 0); if (value != NULL) { page_offset = atoi(value); if (page_offset == 0 && strcmp(value, "0") != 0) { girara_notify(session, GIRARA_WARNING, _("Argument must be a number.")); return false; } } } zathura_document_set_page_offset(zathura->document, page_offset); return true; }
bool cmd_bookmark_delete(girara_session_t* session, girara_list_t* argument_list) { g_return_val_if_fail(session != NULL, false); g_return_val_if_fail(session->global.data != NULL, false); zathura_t* zathura = session->global.data; if (zathura->document == NULL) { girara_notify(session, GIRARA_ERROR, _("No document opened.")); return false; } const unsigned int argc = girara_list_size(argument_list); if (argc != 1) { girara_notify(session, GIRARA_ERROR, _("Invalid number of arguments given.")); return false; } const char* bookmark = girara_list_nth(argument_list, 0); if (zathura_bookmark_remove(zathura, bookmark)) { girara_notify(session, GIRARA_INFO, _("Removed bookmark: %s"), bookmark); } else { girara_notify(session, GIRARA_ERROR, _("Failed to remove bookmark: %s"), bookmark); } return true; }
bool cmd_bookmark_add(girara_session_t* session, girara_list_t* argument_list) { g_return_val_if_fail(session != NULL, false); g_return_val_if_fail(session->global.data != NULL, false); jumanji_t* jumanji = session->global.data; if (jumanji->database == NULL) { return false; } int number_of_arguments = girara_list_size(argument_list); char* url = NULL; char* title = NULL; if (number_of_arguments > 0) { url = girara_list_nth(argument_list, 0); title = (number_of_arguments > 1) ? girara_list_nth(argument_list, 1) : NULL; } else { jumanji_tab_t* tab = jumanji_tab_get_current(jumanji); if (tab != NULL && tab->web_view != NULL) { url = (char*) webkit_web_view_get_uri(WEBKIT_WEB_VIEW(tab->web_view)); title = (char*) webkit_web_view_get_title(WEBKIT_WEB_VIEW(tab->web_view)); } } gchar* escaped_url = g_markup_escape_text(url, -1); jumanji_db_bookmark_add(jumanji->database, url, title); girara_notify(session, GIRARA_INFO, "Added bookmark: %s", escaped_url); g_free(escaped_url); return true; }
bool cmd_open(girara_session_t* session, girara_list_t* argument_list) { g_return_val_if_fail(session != NULL, false); g_return_val_if_fail(session->global.data != NULL, false); zathura_t* zathura = session->global.data; const int argc = girara_list_size(argument_list); if (argc > 2) { girara_notify(session, GIRARA_ERROR, _("Too many arguments.")); return false; } else if (argc >= 1) { if (zathura->document != NULL) { document_close(zathura, false); } document_open(zathura, girara_list_nth(argument_list, 0), (argc == 2) ? girara_list_nth(argument_list, 1) : NULL, ZATHURA_PAGE_NUMBER_UNSPECIFIED); } else { girara_notify(session, GIRARA_ERROR, _("No arguments given.")); return false; } return true; }
bool cmd_bookmark_create(girara_session_t* session, girara_list_t* argument_list) { g_return_val_if_fail(session != NULL, false); g_return_val_if_fail(session->global.data != NULL, false); zathura_t* zathura = session->global.data; if (zathura->document == NULL) { girara_notify(session, GIRARA_ERROR, _("No document opened.")); return false; } const unsigned int argc = girara_list_size(argument_list); if (argc != 1) { girara_notify(session, GIRARA_ERROR, _("Invalid number of arguments given.")); return false; } const char* bookmark_name = girara_list_nth(argument_list, 0); zathura_bookmark_t* bookmark = zathura_bookmark_get(zathura, bookmark_name); if (bookmark != NULL) { bookmark->page = zathura_document_get_current_page_number(zathura->document) + 1; girara_notify(session, GIRARA_INFO, _("Bookmark successfuly updated: %s"), bookmark_name); return true; } bookmark = zathura_bookmark_add(zathura, bookmark_name, zathura_document_get_current_page_number(zathura->document) + 1); if (bookmark == NULL) { girara_notify(session, GIRARA_ERROR, _("Could not create bookmark: %s"), bookmark_name); return false; } girara_notify(session, GIRARA_INFO, _("Bookmark successfuly created: %s"), bookmark_name); return true; }
bool cmd_bookmark_delete(girara_session_t* session, girara_list_t* argument_list) { g_return_val_if_fail(session != NULL, false); g_return_val_if_fail(session->global.data != NULL, false); jumanji_t* jumanji = session->global.data; if (jumanji->database == NULL) { return false; } char* url = NULL; if (girara_list_size(argument_list) > 0) { url = girara_list_nth(argument_list, 0); } else { jumanji_tab_t* tab = jumanji_tab_get_current(jumanji); if (tab != NULL && tab->web_view != NULL) { url = (char*) webkit_web_view_get_uri(WEBKIT_WEB_VIEW(tab->web_view)); } } gchar* escaped_url = g_markup_escape_text(url, -1); jumanji_db_bookmark_remove(jumanji->database, url); girara_notify(session, GIRARA_INFO, "Removed bookmark: %s", escaped_url); g_free(escaped_url); return true; }
bool cmd_bookmark_open(girara_session_t* session, girara_list_t* argument_list) { g_return_val_if_fail(session != NULL, false); g_return_val_if_fail(session->global.data != NULL, false); zathura_t* zathura = session->global.data; if (zathura->document == NULL) { girara_notify(session, GIRARA_ERROR, _("No document opened.")); return false; } const unsigned int argc = girara_list_size(argument_list); if (argc != 1) { girara_notify(session, GIRARA_ERROR, _("Invalid number of arguments given.")); return false; } const char* bookmark_name = girara_list_nth(argument_list, 0); zathura_bookmark_t* bookmark = zathura_bookmark_get(zathura, bookmark_name); if (bookmark == NULL) { girara_notify(session, GIRARA_ERROR, _("No such bookmark: %s"), bookmark_name); return false; } zathura_jumplist_add(zathura); page_set(zathura, bookmark->page - 1); if (bookmark->x != DBL_MIN && bookmark->y != DBL_MIN) { position_set(zathura, bookmark->x, bookmark->y); } zathura_jumplist_add(zathura); return true; }
bool cmd_marks_delete(girara_session_t* session, girara_list_t* argument_list) { g_return_val_if_fail(session != NULL, false); g_return_val_if_fail(session->global.data != NULL, false); zathura_t* zathura = (zathura_t*) session->global.data; if (girara_list_size(argument_list) < 1) { return false; } if (girara_list_size(zathura->global.marks) == 0) { return false; } GIRARA_LIST_FOREACH(argument_list, char*, iter, key_string) if (key_string == NULL) { continue; } for (unsigned int i = 0; i < strlen(key_string); i++) { char key = key_string[i]; if (((key >= 0x41 && key <= 0x5A) || (key >= 0x61 && key <= 0x7A)) == false) { continue; } /* search for existing mark */ girara_list_iterator_t* mark_iter = girara_list_iterator(zathura->global.marks); do { zathura_mark_t* mark = (zathura_mark_t*) girara_list_iterator_data(mark_iter); if (mark == NULL) { continue; } if (mark->key == key) { girara_list_remove(zathura->global.marks, mark); continue; } } while (girara_list_iterator_next(mark_iter) != NULL); girara_list_iterator_free(mark_iter); } GIRARA_LIST_FOREACH_END(argument_list, char*, iter, key_string); return true; }
} END_TEST START_TEST(test_split_path) { fail_unless(girara_split_path_array(NULL) == NULL, NULL); fail_unless(girara_split_path_array("") == NULL, NULL); girara_list_t* res = girara_split_path_array("one/path"); fail_unless(res != NULL, NULL); fail_unless(girara_list_size(res) == 1, NULL); fail_unless(g_strcmp0(girara_list_nth(res, 0), "one/path") == 0, NULL); girara_list_free(res); res = girara_split_path_array("first/path:second/path"); fail_unless(res != NULL, NULL); fail_unless(girara_list_size(res) == 2, NULL); fail_unless(g_strcmp0(girara_list_nth(res, 0), "first/path") == 0, NULL); fail_unless(g_strcmp0(girara_list_nth(res, 1), "second/path") == 0, NULL); girara_list_free(res); } END_TEST
} END_TEST START_TEST(test_datastructures_list_prepend) { girara_list_t* list = girara_list_new(); fail_unless((list != NULL), NULL); /* test parameters */ girara_list_prepend(list, NULL); fail_unless((girara_list_size(list) != 0), NULL); girara_list_free(list); } END_TEST
} END_TEST START_TEST(test_datastructures_list_free_free_function_remove) { // remove with free function list_free_called = 0; girara_list_t* list = girara_list_new2(list_free); fail_unless((list != NULL), NULL); girara_list_append(list, (void*)0xDEAD); girara_list_remove(list, (void*)0xDEAD); fail_unless((girara_list_size(list) == 0), NULL); girara_list_free(list); fail_unless((list_free_called == 1), NULL); } END_TEST
void config_load_files(zathura_t* 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); girara_config_parse(zathura->ui.session, file); g_free(file); } girara_list_free(config_dirs); g_free(config_path); girara_config_parse(zathura->ui.session, GLOBAL_RC); /* load local configuration files */ char* configuration_file = g_build_filename(zathura->config.config_dir, ZATHURA_RC, NULL); girara_config_parse(zathura->ui.session, configuration_file); g_free(configuration_file); }
bool cmd_export(girara_session_t* session, girara_list_t* argument_list) { g_return_val_if_fail(session != NULL, false); g_return_val_if_fail(session->global.data != NULL, false); zathura_t* zathura = session->global.data; if (zathura->document == NULL) { girara_notify(session, GIRARA_ERROR, _("No document opened.")); return false; } if (girara_list_size(argument_list) != 2) { girara_notify(session, GIRARA_ERROR, _("Invalid number of arguments given.")); return false; } const char* file_identifier = girara_list_nth(argument_list, 0); const char* file_name = girara_list_nth(argument_list, 1); if (file_name == NULL || file_identifier == NULL) { return false; } char* export_path = girara_fix_path(file_name); if (export_path == NULL) { return false; } /* attachment */ if (strncmp(file_identifier, "attachment-", strlen("attachment-")) == 0) { if (zathura_document_attachment_save(zathura->document, file_identifier + strlen("attachment-"), export_path) == false) { girara_notify(session, GIRARA_ERROR, _("Couldn't write attachment '%s' to '%s'."), file_identifier, file_name); } else { girara_notify(session, GIRARA_INFO, _("Wrote attachment '%s' to '%s'."), file_identifier, export_path); } /* image */ } else if (strncmp(file_identifier, "image-p", strlen("image-p")) == 0 && strlen(file_identifier) >= 10) { /* parse page id */ const char* input = file_identifier + strlen("image-p"); int page_id = atoi(input); if (page_id == 0) { goto image_error; } /* parse image id */ input = strstr(input, "-"); if (input == NULL) { goto image_error; } int image_id = atoi(input + 1); if (image_id == 0) { goto image_error; } /* get image */ zathura_page_t* page = zathura_document_get_page(zathura->document, page_id - 1); if (page == NULL) { goto image_error; } girara_list_t* images = zathura_page_images_get(page, NULL); if (images == NULL) { goto image_error; } zathura_image_t* image = girara_list_nth(images, image_id - 1); if (image == NULL) { goto image_error; } cairo_surface_t* surface = zathura_page_image_get_cairo(page, image, NULL); if (surface == NULL) { goto image_error; } if (cairo_surface_write_to_png(surface, export_path) == CAIRO_STATUS_SUCCESS) { girara_notify(session, GIRARA_INFO, _("Wrote image '%s' to '%s'."), file_identifier, export_path); } else { girara_notify(session, GIRARA_ERROR, _("Couldn't write image '%s' to '%s'."), file_identifier, file_name); } goto error_ret; image_error: girara_notify(session, GIRARA_ERROR, _("Unknown image '%s'."), file_identifier); goto error_ret; /* unknown */ } else { girara_notify(session, GIRARA_ERROR, _("Unknown attachment or image '%s'."), file_identifier); } error_ret: g_free(export_path); return true; }
static girara_list_t* list_files(zathura_t* zathura, const char* current_path, const char* current_file, unsigned int current_file_length, bool is_dir, bool check_file_ext) { if (zathura == NULL || zathura->ui.session == NULL || current_path == NULL) { return NULL; } /* read directory */ GDir* dir = g_dir_open(current_path, 0, NULL); if (dir == NULL) { return NULL; } girara_list_t* res = girara_sorted_list_new2((girara_compare_function_t)compare_case_insensitive, (girara_free_function_t)g_free); bool show_hidden = false; girara_setting_get(zathura->ui.session, "show-hidden", &show_hidden); bool show_directories = true; girara_setting_get(zathura->ui.session, "show-directories", &show_directories); /* read files */ char* name = NULL; while ((name = (char*) g_dir_read_name(dir)) != NULL) { char* e_name = g_filename_display_name(name); if (e_name == NULL) { goto error_free; } size_t e_length = strlen(e_name); if (show_hidden == false && e_name[0] == '.') { g_free(e_name); continue; } if ((current_file_length > e_length) || strncmp(current_file, e_name, current_file_length)) { g_free(e_name); continue; } char* tmp = "/"; if (is_dir == true || g_strcmp0(current_path, "/") == 0) { tmp = ""; }; char* full_path = g_strdup_printf("%s%s%s", current_path, tmp, e_name); if (g_file_test(full_path, G_FILE_TEST_IS_DIR) == true) { if (show_directories == false) { g_free(e_name); g_free(full_path); continue; } girara_list_append(res, full_path); } else if (check_file_ext == false || file_valid_extension(zathura, full_path) == true) { girara_list_append(res, full_path); } else { g_free(full_path); } g_free(e_name); } g_dir_close(dir); if (girara_list_size(res) == 1) { char* path = girara_list_nth(res, 0); if (g_file_test(path, G_FILE_TEST_IS_DIR) == true) { char* newpath = g_strdup_printf("%s/", path); girara_list_clear(res); girara_list_append(res, newpath); } } return res; error_free: girara_list_free(res); return NULL; }
bool cmd_proxy(girara_session_t* session, girara_list_t* argument_list) { g_return_val_if_fail(session != NULL, false); g_return_val_if_fail(session->global.data != NULL, false); jumanji_t* jumanji = (jumanji_t*) session->global.data; if (jumanji->global.proxies == NULL) { return false; } unsigned int number_of_arguments = girara_list_size(argument_list); if (number_of_arguments < 1) { return false; } char* url = (char*) girara_list_nth(argument_list, 0); char* description = (number_of_arguments > 1) ? (char*) girara_list_nth(argument_list, 1) : NULL; if (url == NULL) { return false; } url = (strstr(url, "://") != NULL) ? g_strdup(url) : g_strconcat("http://", url, NULL); /* search for existing proxy */ if (girara_list_size(jumanji->global.proxies) > 0) { girara_list_iterator_t* iter = girara_list_iterator(jumanji->global.proxies); do { jumanji_proxy_t* proxy = (jumanji_proxy_t*) girara_list_iterator_data(iter); if (proxy == NULL) { continue; } if (!g_strcmp0(proxy->url, url)) { g_free(proxy->url); g_free(proxy->description); proxy->url = g_strdup(url); proxy->description = description ? g_strdup(description) : NULL; g_free(url); girara_list_iterator_free(iter); return true; } } while (girara_list_iterator_next(iter)); girara_list_iterator_free(iter); } /* create new entry */ jumanji_proxy_t* proxy = malloc(sizeof(jumanji_proxy_t)); if (proxy == NULL) { g_free(url); return false; } proxy->url = url; proxy->description = description != NULL ? g_strdup(description) : NULL; girara_list_append(jumanji->global.proxies, proxy); return true; }
void synctex_highlight_rects(zathura_t* zathura, unsigned int page, girara_list_t** rectangles) { const unsigned int number_of_pages = zathura_document_get_number_of_pages(zathura->document); for (unsigned int p = 0; p != number_of_pages; ++p) { GObject* widget = G_OBJECT(zathura->pages[p]); g_object_set(widget, "draw-links", FALSE, "search-results", rectangles[p], NULL); if (p == page) { g_object_set(widget, "search-current", 0, NULL); } } document_draw_search_results(zathura, true); girara_list_t* rect_list = rectangles[page]; if (rect_list == NULL || girara_list_size(rect_list) == 0) { girara_debug("No rectangles for the given page. Jumping to page %u.", page); page_set(zathura, page); return; } bool search_hadjust = true; girara_setting_get(zathura->ui.session, "search-hadjust", &search_hadjust); /* compute the position of the center of the page */ double pos_x = 0; double pos_y = 0; page_number_to_position(zathura->document, page, 0.5, 0.5, &pos_x, &pos_y); /* correction to center the current result */ /* NOTE: rectangle is in viewport units, already scaled and rotated */ unsigned int cell_height = 0; unsigned int cell_width = 0; zathura_document_get_cell_size(zathura->document, &cell_height, &cell_width); unsigned int doc_height = 0; unsigned int doc_width = 0; zathura_document_get_document_size(zathura->document, &doc_height, &doc_width); /* Need to adjust rectangle to page scale and orientation */ zathura_page_t* doc_page = zathura_document_get_page(zathura->document, page); zathura_rectangle_t* rect = girara_list_nth(rect_list, 0); if (rect == NULL) { girara_debug("List of rectangles is broken. Jumping to page %u.", page); page_set(zathura, page); return; } zathura_rectangle_t rectangle = recalc_rectangle(doc_page, *rect); /* compute the center of the rectangle, which will be aligned to the center of the viewport */ double center_x = (rectangle.x1 + rectangle.x2) / 2; double center_y = (rectangle.y1 + rectangle.y2) / 2; pos_y += (center_y - (double)cell_height/2) / (double)doc_height; if (search_hadjust == true) { pos_x += (center_x - (double)cell_width/2) / (double)doc_width; } /* move to position */ girara_debug("Jumping to page %u position (%f, %f).", page, pos_x, pos_y); zathura_jumplist_add(zathura); position_set(zathura, pos_x, pos_y); zathura_jumplist_add(zathura); }
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; }
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; }
bool cmd_search(girara_session_t* session, const char* input, girara_argument_t* argument) { g_return_val_if_fail(session != NULL, false); g_return_val_if_fail(input != NULL, false); g_return_val_if_fail(argument != NULL, false); g_return_val_if_fail(session->global.data != NULL, false); zathura_t* zathura = session->global.data; if (zathura->document == NULL || strlen(input) == 0) { return false; } zathura_error_t error = ZATHURA_ERROR_OK; /* set search direction */ zathura->global.search_direction = argument->n; unsigned int number_of_pages = zathura_document_get_number_of_pages(zathura->document); unsigned int current_page_number = zathura_document_get_current_page_number(zathura->document); /* reset search highlighting */ bool nohlsearch = false; girara_setting_get(session, "nohlsearch", &nohlsearch); /* search pages */ for (unsigned int page_id = 0; page_id < number_of_pages; ++page_id) { unsigned int index = (page_id + current_page_number) % number_of_pages; zathura_page_t* page = zathura_document_get_page(zathura->document, index); if (page == NULL) { continue; } GtkWidget* page_widget = zathura_page_get_widget(zathura, page); g_object_set(page_widget, "draw-links", FALSE, NULL); zathura_renderer_lock(zathura->sync.render_thread); girara_list_t* result = zathura_page_search_text(page, input, &error); zathura_renderer_unlock(zathura->sync.render_thread); if (result == NULL || girara_list_size(result) == 0) { girara_list_free(result); g_object_set(page_widget, "search-results", NULL, NULL); if (error == ZATHURA_ERROR_NOT_IMPLEMENTED) { break; } else { continue; } } g_object_set(page_widget, "search-results", result, NULL); if (argument->n == BACKWARD) { /* start at bottom hit in page */ g_object_set(page_widget, "search-current", girara_list_size(result) - 1, NULL); } else { g_object_set(page_widget, "search-current", 0, NULL); } } girara_argument_t* arg = g_try_malloc0(sizeof(girara_argument_t)); if (arg == NULL) { return false; } arg->n = FORWARD; sc_search(session, arg, NULL, 0); g_free(arg); return true; }