bool sc_goto(girara_session_t* session, girara_argument_t* argument, girara_event_t* UNUSED(event), unsigned int 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); g_return_val_if_fail(zathura->document != NULL, false); zathura_jumplist_add(zathura); if (t != 0) { /* add offset */ t += zathura_document_get_page_offset(zathura->document); page_set(zathura, t - 1); } else if (argument->n == TOP) { page_set(zathura, 0); } else if (argument->n == BOTTOM) { page_set(zathura, zathura_document_get_number_of_pages(zathura->document) - 1); } zathura_jumplist_add(zathura); return false; }
bool cb_unknown_command(girara_session_t* session, const char* input) { g_return_val_if_fail(session != NULL, false); g_return_val_if_fail(session->global.data != NULL, false); g_return_val_if_fail(input != NULL, false); zathura_t* zathura = session->global.data; if (zathura->document == NULL) { return false; } /* check for number */ const size_t size = strlen(input); for (size_t i = 0; i < size; i++) { if (g_ascii_isdigit(input[i]) == FALSE) { return false; } } zathura_jumplist_add(zathura); page_set(zathura, atoi(input) - 1); zathura_jumplist_add(zathura); 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; }
void cb_index_row_activated(GtkTreeView* tree_view, GtkTreePath* path, GtkTreeViewColumn* UNUSED(column), void* data) { zathura_t* zathura = data; if (tree_view == NULL || zathura == NULL || zathura->ui.session == NULL) { return; } GtkTreeModel *model; GtkTreeIter iter; g_object_get(tree_view, "model", &model, NULL); if(gtk_tree_model_get_iter(model, &iter, path)) { zathura_index_element_t* index_element; gtk_tree_model_get(model, &iter, 2, &index_element, -1); if (index_element == NULL) { return; } sc_toggle_index(zathura->ui.session, NULL, NULL, 0); /* zathura_jumplist_save is called when entering index mode */ zathura_link_evaluate(zathura, index_element->link); zathura_jumplist_add(zathura); } g_object_unref(model); }
bool sc_goto(girara_session_t* session, girara_argument_t* argument, girara_event_t* UNUSED(event), unsigned int 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); g_return_val_if_fail(zathura->document != NULL, false); zathura_jumplist_save(zathura); if (t != 0) { /* add offset */ t += zathura_document_get_page_offset(zathura->document); page_set(zathura, t - 1); } else if (argument->n == TOP) { page_set(zathura, 0); } else if (argument->n == BOTTOM) { page_set(zathura, zathura_document_get_number_of_pages(zathura->document) - 1); } /* adjust horizontal position */ GtkAdjustment* hadjustment = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(session->gtk.view)); cb_view_hadjustment_changed(hadjustment, zathura); zathura_jumplist_add(zathura); return false; }
bool sc_search(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); g_return_val_if_fail(zathura->document != NULL, false); const unsigned int num_pages = zathura_document_get_number_of_pages(zathura->document); const unsigned int cur_page = zathura_document_get_current_page_number(zathura->document); GtkWidget *cur_page_widget = zathura_page_get_widget(zathura, zathura_document_get_page(zathura->document, cur_page)); bool nohlsearch, first_time_after_abort; gboolean draw; nohlsearch = first_time_after_abort = false; draw = FALSE; girara_setting_get(session, "nohlsearch", &nohlsearch); if (nohlsearch == false) { g_object_get(G_OBJECT(cur_page_widget), "draw-search-results", &draw, NULL); if (draw == false) { first_time_after_abort = true; } document_draw_search_results(zathura, true); } int diff = argument->n == FORWARD ? 1 : -1; if (zathura->global.search_direction == BACKWARD) diff = -diff; zathura_page_t* target_page = NULL; int target_idx = 0; for (unsigned int page_id = 0; page_id < num_pages; ++page_id) { int tmp = cur_page + diff * page_id; zathura_page_t* page = zathura_document_get_page(zathura->document, (tmp + num_pages) % num_pages); if (page == NULL) { continue; } GtkWidget* page_widget = zathura_page_get_widget(zathura, page); int num_search_results = 0, current = -1; g_object_get(G_OBJECT(page_widget), "search-current", ¤t, "search-length", &num_search_results, NULL); if (num_search_results == 0 || current == -1) { continue; } if (first_time_after_abort == true || (tmp + num_pages) % num_pages != cur_page) { target_page = page; target_idx = diff == 1 ? 0 : num_search_results - 1; break; } if (diff == 1 && current < num_search_results - 1) { /* the next result is on the same page */ target_page = page; target_idx = current + 1; } else if (diff == -1 && current > 0) { target_page = page; target_idx = current - 1; } else { /* the next result is on a different page */ g_object_set(G_OBJECT(page_widget), "search-current", -1, NULL); for (int npage_id = 1; page_id < num_pages; ++npage_id) { int ntmp = cur_page + diff * (page_id + npage_id); zathura_page_t* npage = zathura_document_get_page(zathura->document, (ntmp + 2*num_pages) % num_pages); GtkWidget* npage_page_widget = zathura_page_get_widget(zathura, npage); g_object_get(G_OBJECT(npage_page_widget), "search-length", &num_search_results, NULL); if (num_search_results != 0) { target_page = npage; target_idx = diff == 1 ? 0 : num_search_results - 1; break; } } } break; } if (target_page != NULL) { girara_list_t* results = NULL; GtkWidget* page_widget = zathura_page_get_widget(zathura, target_page); GObject* obj_page_widget = G_OBJECT(page_widget); g_object_set(obj_page_widget, "search-current", target_idx, NULL); g_object_get(obj_page_widget, "search-results", &results, NULL); /* Need to adjust rectangle to page scale and orientation */ zathura_rectangle_t* rect = girara_list_nth(results, target_idx); zathura_rectangle_t rectangle = recalc_rectangle(target_page, *rect); bool search_hadjust = true; girara_setting_get(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, zathura_page_get_index(target_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); /* 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 */ zathura_jumplist_add(zathura); position_set(zathura, pos_x, pos_y); zathura_jumplist_add(zathura); } return false; }
bool sc_bisect(girara_session_t* session, girara_argument_t* argument, girara_event_t* UNUSED(event), unsigned int 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); g_return_val_if_fail(zathura->document != NULL, false); const unsigned int num_pages = zathura_document_get_number_of_pages(zathura->document); const unsigned int cur_page = zathura_document_get_current_page_number(zathura->document); /* process arguments */ int direction; if (t > 0 && t <= num_pages) { /* bisect between cur_page and t */ t -= 1; if (t == cur_page) { /* nothing to do */ return false; } else if (t > cur_page) { zathura->bisect.start = cur_page; zathura->bisect.end = t; direction = BACKWARD; } else { zathura->bisect.start = t; zathura->bisect.end = cur_page; direction = FORWARD; } } else if (argument != NULL) { direction = argument->n; /* setup initial bisect range */ zathura_jump_t* jump = zathura_jumplist_current(zathura); if (jump == NULL) { girara_debug("bisecting between first and last page because there are no jumps"); zathura->bisect.start = 0; zathura->bisect.end = num_pages - 1; } else if (jump->page != cur_page || jump->page != zathura->bisect.last_jump) { girara_debug("last jump doesn't match up, starting new bisecting"); zathura->bisect.start = 0; zathura->bisect.end = num_pages - 1; unsigned int prev_page; if (direction == FORWARD) { prev_page = num_pages - 1; } else { prev_page = 0; } /* check if we have previous jumps */ if (zathura_jumplist_has_previous(zathura) == true) { zathura_jumplist_backward(zathura); jump = zathura_jumplist_current(zathura); if (jump != NULL) { prev_page = jump->page; } zathura_jumplist_forward(zathura); } zathura->bisect.start = MIN(prev_page, cur_page); zathura->bisect.end = MAX(prev_page, cur_page); zathura->bisect.last_jump = cur_page; } } else { return false; } girara_debug("bisecting between %d and %d, at %d", zathura->bisect.start, zathura->bisect.end, cur_page); if (zathura->bisect.start == zathura->bisect.end) { /* nothing to do */ return false; } unsigned int next_page = cur_page; unsigned int next_start = zathura->bisect.start; unsigned int next_end = zathura->bisect.end; /* here we have next_start <= next_page <= next_end */ /* bisect step */ switch(direction) { case FORWARD: if (cur_page != zathura->bisect.end) { next_page = (cur_page + zathura->bisect.end) / 2; if (next_page == cur_page) { ++next_page; } next_start = cur_page; } break; case BACKWARD: if (cur_page != zathura->bisect.start) { next_page = (cur_page + zathura->bisect.start) / 2; if (next_page == cur_page) { --next_page; } next_end = cur_page; } break; } if (next_page == cur_page) { /* nothing to do */ return false; } girara_debug("bisecting between %d and %d, jumping to %d", zathura->bisect.start, zathura->bisect.end, next_page); zathura->bisect.last_jump = next_page; zathura->bisect.start = next_start; zathura->bisect.end = next_end; zathura_jumplist_add(zathura); page_set(zathura, next_page); zathura_jumplist_add(zathura); return false; }
bool sc_toggle_index(girara_session_t* session, girara_argument_t* UNUSED(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; if (zathura->document == NULL) { return false; } girara_tree_node_t* document_index = NULL; GtkWidget* treeview = NULL; GtkTreeModel* model = NULL; GtkCellRenderer* renderer = NULL; GtkCellRenderer* renderer2 = NULL; if (zathura->ui.index == NULL) { /* create new index widget */ zathura->ui.index = gtk_scrolled_window_new(NULL, NULL); if (zathura->ui.index == NULL) { goto error_ret; } gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(zathura->ui.index), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); /* create index */ document_index = zathura_document_index_generate(zathura->document, NULL); if (document_index == NULL) { girara_notify(session, GIRARA_WARNING, _("This document does not contain any index")); goto error_free; } model = GTK_TREE_MODEL(gtk_tree_store_new(3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER)); if (model == NULL) { goto error_free; } treeview = gtk_tree_view_new_with_model(model); if (treeview == NULL) { goto error_free; } gtk_style_context_add_class(gtk_widget_get_style_context(treeview), "indexmode"); g_object_unref(model); renderer = gtk_cell_renderer_text_new(); if (renderer == NULL) { goto error_free; } renderer2 = gtk_cell_renderer_text_new(); if (renderer2 == NULL) { goto error_free; } document_index_build(model, NULL, document_index); girara_node_free(document_index); /* setup widget */ gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW (treeview), 0, "Title", renderer, "markup", 0, NULL); gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW (treeview), 1, "Target", renderer2, "text", 1, NULL); gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(treeview), FALSE); g_object_set(G_OBJECT(renderer), "ellipsize", PANGO_ELLIPSIZE_END, NULL); g_object_set(G_OBJECT(gtk_tree_view_get_column(GTK_TREE_VIEW(treeview), 0)), "expand", TRUE, NULL); gtk_tree_view_column_set_alignment(gtk_tree_view_get_column(GTK_TREE_VIEW(treeview), 1), 1.0f); gtk_tree_view_set_cursor(GTK_TREE_VIEW(treeview), gtk_tree_path_new_first(), NULL, FALSE); g_signal_connect(G_OBJECT(treeview), "row-activated", G_CALLBACK(cb_index_row_activated), zathura); gtk_container_add(GTK_CONTAINER(zathura->ui.index), treeview); gtk_widget_show(treeview); } if (gtk_widget_get_visible(GTK_WIDGET(zathura->ui.index))) { girara_set_view(session, zathura->ui.page_widget); gtk_widget_hide(GTK_WIDGET(zathura->ui.index)); girara_mode_set(zathura->ui.session, zathura->modes.normal); /* refresh view */ refresh_view(zathura); } else { /* save current position to the jumplist */ zathura_jumplist_add(zathura); girara_set_view(session, zathura->ui.index); gtk_widget_show(GTK_WIDGET(zathura->ui.index)); girara_mode_set(zathura->ui.session, zathura->modes.index); } return false; error_free: if (zathura->ui.index != NULL) { g_object_ref_sink(zathura->ui.index); zathura->ui.index = NULL; } if (document_index != NULL) { girara_node_free(document_index); } error_ret: return false; }
bool sc_search(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); g_return_val_if_fail(zathura->document != NULL, false); const int num_pages = zathura_document_get_number_of_pages(zathura->document); const int cur_page = zathura_document_get_current_page_number(zathura->document); int diff = argument->n == FORWARD ? 1 : -1; if (zathura->global.search_direction == BACKWARD) diff = -diff; zathura_page_t* target_page = NULL; int target_idx = 0; for (int page_id = 0; page_id < num_pages; ++page_id) { int tmp = cur_page + diff * page_id; zathura_page_t* page = zathura_document_get_page(zathura->document, (tmp + num_pages) % num_pages); if (page == NULL) { continue; } GtkWidget* page_widget = zathura_page_get_widget(zathura, page); int num_search_results = 0, current = -1; g_object_get(page_widget, "search-current", ¤t, "search-length", &num_search_results, NULL); if (num_search_results == 0 || current == -1) { continue; } if (diff == 1 && current < num_search_results - 1) { /* the next result is on the same page */ target_page = page; target_idx = current + 1; } else if (diff == -1 && current > 0) { target_page = page; target_idx = current - 1; } else { /* the next result is on a different page */ zathura_jumplist_save(zathura); g_object_set(page_widget, "search-current", -1, NULL); for (int npage_id = 1; page_id < num_pages; ++npage_id) { int ntmp = cur_page + diff * (page_id + npage_id); zathura_page_t* npage = zathura_document_get_page(zathura->document, (ntmp + 2*num_pages) % num_pages); zathura_document_set_current_page_number(zathura->document, zathura_page_get_index(npage)); GtkWidget* npage_page_widget = zathura_page_get_widget(zathura, npage); g_object_get(npage_page_widget, "search-length", &num_search_results, NULL); if (num_search_results != 0) { target_page = npage; target_idx = diff == 1 ? 0 : num_search_results - 1; break; } } zathura_jumplist_add(zathura); } break; } if (target_page != NULL) { girara_list_t* results = NULL; GtkWidget* page_widget = zathura_page_get_widget(zathura, target_page); g_object_set(page_widget, "search-current", target_idx, NULL); g_object_get(page_widget, "search-results", &results, NULL); zathura_rectangle_t* rect = girara_list_nth(results, target_idx); zathura_rectangle_t rectangle = recalc_rectangle(target_page, *rect); page_offset_t offset; page_calculate_offset(zathura, target_page, &offset); GtkAdjustment* view_vadjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view)); int y = offset.y - gtk_adjustment_get_page_size(view_vadjustment) / 2 + rectangle.y1; set_adjustment(view_vadjustment, y); bool search_hadjust = true; girara_setting_get(session, "search-hadjust", &search_hadjust); if (search_hadjust == true) { GtkAdjustment* view_hadjustment = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view)); int x = offset.x - gtk_adjustment_get_page_size(view_hadjustment) / 2 + rectangle.x1; set_adjustment(view_hadjustment, x); } } return false; }
static bool handle_link(GtkEntry* entry, girara_session_t* session, zathura_link_action_t action) { g_return_val_if_fail(session != NULL, FALSE); g_return_val_if_fail(session->global.data != NULL, FALSE); zathura_t* zathura = session->global.data; bool eval = true; char* input = gtk_editable_get_chars(GTK_EDITABLE(entry), 0, -1); if (input == NULL || strlen(input) == 0) { eval = false; } int index = 0; if (eval == true) { index = atoi(input); if (index == 0 && g_strcmp0(input, "0") != 0) { girara_notify(session, GIRARA_WARNING, _("Invalid input '%s' given."), input); eval = false; } index = index - 1; } /* set pages to draw links */ bool invalid_index = true; unsigned int number_of_pages = zathura_document_get_number_of_pages(zathura->document); for (unsigned int page_id = 0; page_id < number_of_pages; page_id++) { zathura_page_t* page = zathura_document_get_page(zathura->document, page_id); if (page == NULL || zathura_page_get_visibility(page) == false) { continue; } GtkWidget* page_widget = zathura_page_get_widget(zathura, page); g_object_set(page_widget, "draw-links", FALSE, NULL); if (eval == true) { zathura_link_t* link = zathura_page_widget_link_get(ZATHURA_PAGE(page_widget), index); if (link != NULL) { invalid_index = false; switch (action) { case ZATHURA_LINK_ACTION_FOLLOW: zathura_jumplist_save(zathura); zathura_link_evaluate(zathura, link); zathura_jumplist_add(zathura); break; case ZATHURA_LINK_ACTION_DISPLAY: zathura_link_display(zathura, link); break; } } } } if (eval == true && invalid_index == true) { girara_notify(session, GIRARA_WARNING, _("Invalid index '%s' given."), input); } g_free(input); return (eval == TRUE) ? TRUE : FALSE; }
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 sc_bisect(girara_session_t* session, girara_argument_t* argument, girara_event_t* UNUSED(event), unsigned int 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); g_return_val_if_fail(zathura->document != NULL, false); unsigned int number_of_pages, cur_page, prev_page, prev2_page; bool have_prev, have_prev2; zathura_jump_t* prev_jump = NULL; zathura_jump_t* prev2_jump = NULL; number_of_pages= zathura_document_get_number_of_pages(zathura->document); cur_page = zathura_document_get_current_page_number(zathura->document); prev_page = prev2_page = 0; have_prev = have_prev2 = false; /* save position at current jump point */ zathura_jumplist_save(zathura); /* process arguments */ int direction; if (t > 0 && t <= number_of_pages) { /* jump to page t, and bisect between cur_page and t */ page_set(zathura, t-1); zathura_jumplist_add(zathura); if (t-1 > cur_page) { direction = BACKWARD; } else { direction = FORWARD; } } else if (argument != NULL) { direction = argument->n; } else { return false; } cur_page = zathura_document_get_current_page_number(zathura->document); if (zathura_jumplist_has_previous(zathura)) { /* If there is a previous jump, get its page */ zathura_jumplist_backward(zathura); prev_jump = zathura_jumplist_current(zathura); if (prev_jump) { prev_page = prev_jump->page; have_prev = true; } if (zathura_jumplist_has_previous(zathura)) { /* If there is a second previous jump, get its page. */ zathura_jumplist_backward(zathura); prev2_jump = zathura_jumplist_current(zathura); if (prev2_jump) { prev2_page = prev2_jump->page; have_prev2 = true; } zathura_jumplist_forward(zathura); } zathura_jumplist_forward(zathura); } /* now, we are back at the initial jump. prev_page and prev2_page contain the pages for previous and second previous jump if they exist. */ /* bisect */ switch(direction) { case FORWARD: if (have_prev && cur_page <= prev_page) { /* add a new jump point */ if (cur_page < prev_page) { page_set(zathura, (cur_page + prev_page)/2); zathura_jumplist_add(zathura); } } else if (have_prev2 && cur_page <= prev2_page) { /* save current position at previous jump point */ if (cur_page < prev2_page) { zathura_jumplist_backward(zathura); zathura_jumplist_save(zathura); zathura_jumplist_forward(zathura); page_set(zathura, (cur_page + prev2_page)/2); zathura_jumplist_save(zathura); } } else { /* none of prev_page or prev2_page comes after cur_page */ page_set(zathura, (cur_page + number_of_pages - 1)/2); zathura_jumplist_add(zathura); } break; case BACKWARD: if (have_prev && prev_page <= cur_page) { /* add a new jump point */ if (prev_page < cur_page) { page_set(zathura, (cur_page + prev_page)/2); zathura_jumplist_add(zathura); } } else if (have_prev2 && prev2_page <= cur_page) { /* save current position at previous jump point */ if (prev2_page < cur_page) { zathura_jumplist_backward(zathura); zathura_jumplist_save(zathura); zathura_jumplist_forward(zathura); page_set(zathura, (cur_page + prev2_page)/2); zathura_jumplist_save(zathura); } } else { /* none of prev_page or prev2_page comes before cur_page */ page_set(zathura, cur_page/2); zathura_jumplist_add(zathura); } break; } /* adjust horizontal position */ GtkAdjustment* hadjustment = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(session->gtk.view)); cb_view_hadjustment_changed(hadjustment, zathura); return false; }