From 8d0b292027ecf2b315461f9691d70b4a1dd5a946 Mon Sep 17 00:00:00 2001 From: Sebastian Ramacher Date: Fri, 8 Dec 2023 17:47:20 +0100 Subject: [PATCH] Implement rendering of signature information --- zathura/config.c | 237 +++++++++++++++++++----------------- zathura/page-widget.c | 272 ++++++++++++++++++++++++++++-------------- zathura/zathura.c | 21 ++++ zathura/zathura.h | 8 ++ 4 files changed, 342 insertions(+), 196 deletions(-) diff --git a/zathura/config.c b/zathura/config.c index 2d9f3b4..69a7188 100644 --- a/zathura/config.c +++ b/zathura/config.c @@ -194,9 +194,22 @@ cb_window_statbusbar_changed(girara_session_t* session, const char* name, } } -void -config_load_default(zathura_t* zathura) -{ +static void cb_show_signature_info(girara_session_t* session, const char* UNUSED(name), + girara_setting_type_t UNUSED(type), const void* value, void* UNUSED(data)) { + g_return_if_fail(value != NULL); + g_return_if_fail(session != NULL); + g_return_if_fail(session->global.data != NULL); + zathura_t* zathura = session->global.data; + + if (zathura->document == NULL) { + return; + } + + zathura_show_signature_information(zathura, *(const bool*)value); + update_visible_pages(zathura); +} + +void config_load_default(zathura_t* zathura) { if (zathura == NULL || zathura->ui.session == NULL) { return; } @@ -363,113 +376,121 @@ config_load_default(zathura_t* zathura) /* default to no sandbox when running in WSL */ const char* string_value = running_under_wsl() ? "none" : "normal"; girara_setting_add(gsession, "sandbox", string_value, STRING, true, _("Sandbox level"), cb_sandbox_changed, NULL); + bool_value = false; + girara_setting_add(gsession, "show-signature-information", &bool_value, BOOLEAN, false, + _("Disable additional information for signatures embedded in the document."), + cb_show_signature_info, NULL); -#define DEFAULT_SHORTCUTS(mode) \ - girara_shortcut_add(gsession, 0, GDK_KEY_a, NULL, sc_adjust_window, (mode), ZATHURA_ADJUST_BESTFIT, NULL); \ - girara_shortcut_add(gsession, 0, GDK_KEY_s, NULL, sc_adjust_window, (mode), ZATHURA_ADJUST_WIDTH, NULL); \ -\ - girara_shortcut_add(gsession, 0, GDK_KEY_F, NULL, sc_display_link, (mode), 0, NULL); \ - girara_shortcut_add(gsession, 0, GDK_KEY_c, NULL, sc_copy_link, (mode), 0, NULL); \ -\ - girara_shortcut_add(gsession, 0, GDK_KEY_slash, NULL, sc_focus_inputbar, (mode), 0, &("/")); \ - girara_shortcut_add(gsession, GDK_SHIFT_MASK, GDK_KEY_slash, NULL, sc_focus_inputbar, (mode), 0, &("/")); \ - girara_shortcut_add(gsession, 0, GDK_KEY_question, NULL, sc_focus_inputbar, (mode), 0, &("?")); \ - girara_shortcut_add(gsession, 0, GDK_KEY_colon, NULL, sc_focus_inputbar, (mode), 0, &(":")); \ - girara_shortcut_add(gsession, 0, GDK_KEY_o, NULL, sc_focus_inputbar, (mode), 0, &(":open ")); \ - girara_shortcut_add(gsession, 0, GDK_KEY_O, NULL, sc_focus_inputbar, (mode), APPEND_FILEPATH, &(":open ")); \ -\ - girara_shortcut_add(gsession, 0, GDK_KEY_f, NULL, sc_follow, (mode), 0, NULL); \ -\ - girara_shortcut_add(gsession, 0, 0, "gg", sc_goto, (mode), TOP, NULL); \ - girara_shortcut_add(gsession, 0, 0, "G", sc_goto, (mode), BOTTOM, NULL); \ -\ - girara_shortcut_add(gsession, 0, GDK_KEY_m, NULL, sc_mark_add, (mode), 0, NULL); \ - girara_shortcut_add(gsession, 0, GDK_KEY_apostrophe, NULL, sc_mark_evaluate, (mode), 0, NULL); \ -\ - girara_shortcut_add(gsession, 0, GDK_KEY_J, NULL, sc_navigate, (mode), NEXT, NULL); \ - girara_shortcut_add(gsession, 0, GDK_KEY_K, NULL, sc_navigate, (mode), PREVIOUS, NULL); \ - girara_shortcut_add(gsession, GDK_MOD1_MASK, GDK_KEY_Right, NULL, sc_navigate, (mode), NEXT, NULL); \ - girara_shortcut_add(gsession, GDK_MOD1_MASK, GDK_KEY_Left, NULL, sc_navigate, (mode), PREVIOUS, NULL); \ - girara_shortcut_add(gsession, 0, GDK_KEY_Page_Down, NULL, sc_navigate, (mode), NEXT, NULL); \ - girara_shortcut_add(gsession, 0, GDK_KEY_Page_Up, NULL, sc_navigate, (mode), PREVIOUS, NULL); \ -\ - girara_shortcut_add(gsession, GDK_CONTROL_MASK, GDK_KEY_p, NULL, sc_print, (mode), 0, NULL); \ -\ - girara_shortcut_add(gsession, GDK_CONTROL_MASK, GDK_KEY_r, NULL, sc_recolor, (mode), 0, NULL); \ -\ - girara_shortcut_add(gsession, 0, GDK_KEY_R, NULL, sc_reload, (mode), 0, NULL); \ -\ - girara_shortcut_add(gsession, 0, GDK_KEY_r, NULL, sc_rotate, (mode), ROTATE_CW, NULL); \ -\ - girara_shortcut_add(gsession, 0, GDK_KEY_h, NULL, sc_scroll, (mode), LEFT, NULL); \ - girara_shortcut_add(gsession, 0, GDK_KEY_j, NULL, sc_scroll, (mode), DOWN, NULL); \ - girara_shortcut_add(gsession, 0, GDK_KEY_k, NULL, sc_scroll, (mode), UP, NULL); \ - girara_shortcut_add(gsession, 0, GDK_KEY_l, NULL, sc_scroll, (mode), RIGHT, NULL); \ - girara_shortcut_add(gsession, 0, GDK_KEY_Left, NULL, sc_scroll, (mode), LEFT, NULL); \ - girara_shortcut_add(gsession, 0, GDK_KEY_Up, NULL, sc_scroll, (mode), UP, NULL); \ - girara_shortcut_add(gsession, 0, GDK_KEY_Down, NULL, sc_scroll, (mode), DOWN, NULL); \ - girara_shortcut_add(gsession, 0, GDK_KEY_H, NULL, sc_scroll, (mode), PAGE_TOP, NULL); \ - girara_shortcut_add(gsession, 0, GDK_KEY_L, NULL, sc_scroll, (mode), PAGE_BOTTOM, NULL); \ - girara_shortcut_add(gsession, 0, GDK_KEY_Right, NULL, sc_scroll, (mode), RIGHT, NULL); \ - girara_shortcut_add(gsession, GDK_CONTROL_MASK, GDK_KEY_t, NULL, sc_scroll, (mode), HALF_LEFT, NULL); \ - girara_shortcut_add(gsession, GDK_CONTROL_MASK, GDK_KEY_d, NULL, sc_scroll, (mode), HALF_DOWN, NULL); \ - girara_shortcut_add(gsession, GDK_CONTROL_MASK, GDK_KEY_u, NULL, sc_scroll, (mode), HALF_UP, NULL); \ - girara_shortcut_add(gsession, GDK_CONTROL_MASK, GDK_KEY_y, NULL, sc_scroll, (mode), HALF_RIGHT, NULL); \ - girara_shortcut_add(gsession, 0, GDK_KEY_t, NULL, sc_scroll, (mode), FULL_LEFT, NULL); \ - girara_shortcut_add(gsession, GDK_CONTROL_MASK, GDK_KEY_f, NULL, sc_scroll, (mode), FULL_DOWN, NULL); \ - girara_shortcut_add(gsession, GDK_CONTROL_MASK, GDK_KEY_b, NULL, sc_scroll, (mode), FULL_UP, NULL); \ - girara_shortcut_add(gsession, 0, GDK_KEY_y, NULL, sc_scroll, (mode), FULL_RIGHT, NULL); \ - girara_shortcut_add(gsession, 0, GDK_KEY_space, NULL, sc_scroll, (mode), FULL_DOWN, NULL); \ - girara_shortcut_add(gsession, GDK_SHIFT_MASK, GDK_KEY_space, NULL, sc_scroll, (mode), FULL_UP, NULL); \ - girara_shortcut_add(gsession, 0, GDK_KEY_Y, NULL, sc_copy_filepath, (mode), 0, NULL); \ -\ - girara_shortcut_add(gsession, GDK_CONTROL_MASK, GDK_KEY_o, NULL, sc_jumplist, (mode), BACKWARD, NULL); \ - girara_shortcut_add(gsession, GDK_CONTROL_MASK, GDK_KEY_i, NULL, sc_jumplist, (mode), FORWARD, NULL); \ -\ - girara_shortcut_add(gsession, GDK_CONTROL_MASK, GDK_KEY_j, NULL, sc_bisect, (mode), FORWARD, NULL); \ - girara_shortcut_add(gsession, GDK_CONTROL_MASK, GDK_KEY_k, NULL, sc_bisect, (mode), BACKWARD, NULL); \ -\ - girara_shortcut_add(gsession, 0, GDK_KEY_n, NULL, sc_search, (mode), FORWARD, NULL); \ - girara_shortcut_add(gsession, 0, GDK_KEY_N, NULL, sc_search, (mode), BACKWARD, NULL); \ -\ - girara_shortcut_add(gsession, 0, GDK_KEY_P, NULL, sc_snap_to_page, (mode), 0, NULL); \ -\ - girara_shortcut_add(gsession, 0, GDK_KEY_Tab, NULL, sc_toggle_index, (mode), 0, NULL); \ - girara_shortcut_add(gsession, GDK_CONTROL_MASK, GDK_KEY_n, NULL, girara_sc_toggle_statusbar, (mode), 0, NULL); \ - girara_shortcut_add(gsession, GDK_CONTROL_MASK, GDK_KEY_m, NULL, girara_sc_toggle_inputbar, (mode), 0, NULL); \ - girara_shortcut_add(gsession, 0, GDK_KEY_d, NULL, sc_toggle_page_mode, (mode), 0, NULL); \ -\ - girara_shortcut_add(gsession, 0, GDK_KEY_q, NULL, sc_quit, (mode), 0, NULL); \ -\ - girara_shortcut_add(gsession, 0, GDK_KEY_plus, NULL, sc_zoom, (mode), ZOOM_IN, NULL); \ - girara_shortcut_add(gsession, 0, GDK_KEY_KP_Add, NULL, sc_zoom, (mode), ZOOM_IN, NULL); \ - girara_shortcut_add(gsession, 0, GDK_KEY_minus, NULL, sc_zoom, (mode), ZOOM_OUT, NULL); \ - girara_shortcut_add(gsession, 0, GDK_KEY_KP_Subtract,NULL, sc_zoom, (mode), ZOOM_OUT, NULL); \ - girara_shortcut_add(gsession, 0, GDK_KEY_equal, NULL, sc_zoom, (mode), ZOOM_SPECIFIC, NULL); \ - girara_shortcut_add(gsession, 0, 0, "zi", sc_zoom, (mode), ZOOM_IN, NULL); \ - girara_shortcut_add(gsession, 0, 0, "zI", sc_zoom, (mode), ZOOM_IN, NULL); \ - girara_shortcut_add(gsession, 0, 0, "zo", sc_zoom, (mode), ZOOM_OUT, NULL); \ - girara_shortcut_add(gsession, 0, 0, "zO", sc_zoom, (mode), ZOOM_OUT, NULL); \ - girara_shortcut_add(gsession, 0, 0, "z0", sc_zoom, (mode), ZOOM_ORIGINAL, NULL); \ - girara_shortcut_add(gsession, 0, 0, "zz", sc_zoom, (mode), ZOOM_SPECIFIC, NULL); \ - girara_shortcut_add(gsession, 0, 0, "zZ", sc_zoom, (mode), ZOOM_SPECIFIC, NULL); +#define DEFAULT_SHORTCUTS(mode) \ + girara_shortcut_add(gsession, 0, GDK_KEY_a, NULL, sc_adjust_window, (mode), ZATHURA_ADJUST_BESTFIT, NULL); \ + girara_shortcut_add(gsession, 0, GDK_KEY_s, NULL, sc_adjust_window, (mode), ZATHURA_ADJUST_WIDTH, NULL); \ + \ + girara_shortcut_add(gsession, 0, GDK_KEY_F, NULL, sc_display_link, (mode), 0, NULL); \ + girara_shortcut_add(gsession, 0, GDK_KEY_c, NULL, sc_copy_link, (mode), 0, NULL); \ + \ + girara_shortcut_add(gsession, 0, GDK_KEY_slash, NULL, sc_focus_inputbar, (mode), 0, &("/")); \ + girara_shortcut_add(gsession, GDK_SHIFT_MASK, GDK_KEY_slash, NULL, sc_focus_inputbar, (mode), 0, &("/")); \ + girara_shortcut_add(gsession, 0, GDK_KEY_question, NULL, sc_focus_inputbar, (mode), 0, &("?")); \ + girara_shortcut_add(gsession, 0, GDK_KEY_colon, NULL, sc_focus_inputbar, (mode), 0, &(":")); \ + girara_shortcut_add(gsession, 0, GDK_KEY_o, NULL, sc_focus_inputbar, (mode), 0, &(":open ")); \ + girara_shortcut_add(gsession, 0, GDK_KEY_O, NULL, sc_focus_inputbar, (mode), APPEND_FILEPATH, &(":open ")); \ + \ + girara_shortcut_add(gsession, 0, GDK_KEY_f, NULL, sc_follow, (mode), 0, NULL); \ + \ + girara_shortcut_add(gsession, 0, 0, "gg", sc_goto, (mode), TOP, NULL); \ + girara_shortcut_add(gsession, 0, 0, "G", sc_goto, (mode), BOTTOM, NULL); \ + \ + girara_shortcut_add(gsession, 0, GDK_KEY_m, NULL, sc_mark_add, (mode), 0, NULL); \ + girara_shortcut_add(gsession, 0, GDK_KEY_apostrophe, NULL, sc_mark_evaluate, (mode), 0, NULL); \ + \ + girara_shortcut_add(gsession, 0, GDK_KEY_J, NULL, sc_navigate, (mode), NEXT, NULL); \ + girara_shortcut_add(gsession, 0, GDK_KEY_K, NULL, sc_navigate, (mode), PREVIOUS, NULL); \ + girara_shortcut_add(gsession, GDK_MOD1_MASK, GDK_KEY_Right, NULL, sc_navigate, (mode), NEXT, NULL); \ + girara_shortcut_add(gsession, GDK_MOD1_MASK, GDK_KEY_Left, NULL, sc_navigate, (mode), PREVIOUS, NULL); \ + girara_shortcut_add(gsession, 0, GDK_KEY_Page_Down, NULL, sc_navigate, (mode), NEXT, NULL); \ + girara_shortcut_add(gsession, 0, GDK_KEY_Page_Up, NULL, sc_navigate, (mode), PREVIOUS, NULL); \ + \ + girara_shortcut_add(gsession, GDK_CONTROL_MASK, GDK_KEY_p, NULL, sc_print, (mode), 0, NULL); \ + \ + girara_shortcut_add(gsession, GDK_CONTROL_MASK, GDK_KEY_r, NULL, sc_recolor, (mode), 0, NULL); \ + \ + girara_shortcut_add(gsession, 0, GDK_KEY_R, NULL, sc_reload, (mode), 0, NULL); \ + \ + girara_shortcut_add(gsession, 0, GDK_KEY_r, NULL, sc_rotate, (mode), ROTATE_CW, NULL); \ + \ + girara_shortcut_add(gsession, 0, GDK_KEY_h, NULL, sc_scroll, (mode), LEFT, NULL); \ + girara_shortcut_add(gsession, 0, GDK_KEY_j, NULL, sc_scroll, (mode), DOWN, NULL); \ + girara_shortcut_add(gsession, 0, GDK_KEY_k, NULL, sc_scroll, (mode), UP, NULL); \ + girara_shortcut_add(gsession, 0, GDK_KEY_l, NULL, sc_scroll, (mode), RIGHT, NULL); \ + girara_shortcut_add(gsession, 0, GDK_KEY_Left, NULL, sc_scroll, (mode), LEFT, NULL); \ + girara_shortcut_add(gsession, 0, GDK_KEY_Up, NULL, sc_scroll, (mode), UP, NULL); \ + girara_shortcut_add(gsession, 0, GDK_KEY_Down, NULL, sc_scroll, (mode), DOWN, NULL); \ + girara_shortcut_add(gsession, 0, GDK_KEY_H, NULL, sc_scroll, (mode), PAGE_TOP, NULL); \ + girara_shortcut_add(gsession, 0, GDK_KEY_L, NULL, sc_scroll, (mode), PAGE_BOTTOM, NULL); \ + girara_shortcut_add(gsession, 0, GDK_KEY_Right, NULL, sc_scroll, (mode), RIGHT, NULL); \ + girara_shortcut_add(gsession, GDK_CONTROL_MASK, GDK_KEY_t, NULL, sc_scroll, (mode), HALF_LEFT, NULL); \ + girara_shortcut_add(gsession, GDK_CONTROL_MASK, GDK_KEY_d, NULL, sc_scroll, (mode), HALF_DOWN, NULL); \ + girara_shortcut_add(gsession, GDK_CONTROL_MASK, GDK_KEY_u, NULL, sc_scroll, (mode), HALF_UP, NULL); \ + girara_shortcut_add(gsession, GDK_CONTROL_MASK, GDK_KEY_y, NULL, sc_scroll, (mode), HALF_RIGHT, NULL); \ + girara_shortcut_add(gsession, 0, GDK_KEY_t, NULL, sc_scroll, (mode), FULL_LEFT, NULL); \ + girara_shortcut_add(gsession, GDK_CONTROL_MASK, GDK_KEY_f, NULL, sc_scroll, (mode), FULL_DOWN, NULL); \ + girara_shortcut_add(gsession, GDK_CONTROL_MASK, GDK_KEY_b, NULL, sc_scroll, (mode), FULL_UP, NULL); \ + girara_shortcut_add(gsession, 0, GDK_KEY_y, NULL, sc_scroll, (mode), FULL_RIGHT, NULL); \ + girara_shortcut_add(gsession, 0, GDK_KEY_space, NULL, sc_scroll, (mode), FULL_DOWN, NULL); \ + girara_shortcut_add(gsession, GDK_SHIFT_MASK, GDK_KEY_space, NULL, sc_scroll, (mode), FULL_UP, NULL); \ + girara_shortcut_add(gsession, 0, GDK_KEY_Y, NULL, sc_copy_filepath, (mode), 0, NULL); \ + \ + girara_shortcut_add(gsession, GDK_CONTROL_MASK, GDK_KEY_o, NULL, sc_jumplist, (mode), BACKWARD, NULL); \ + girara_shortcut_add(gsession, GDK_CONTROL_MASK, GDK_KEY_i, NULL, sc_jumplist, (mode), FORWARD, NULL); \ + \ + girara_shortcut_add(gsession, GDK_CONTROL_MASK, GDK_KEY_j, NULL, sc_bisect, (mode), FORWARD, NULL); \ + girara_shortcut_add(gsession, GDK_CONTROL_MASK, GDK_KEY_k, NULL, sc_bisect, (mode), BACKWARD, NULL); \ + \ + girara_shortcut_add(gsession, 0, GDK_KEY_n, NULL, sc_search, (mode), FORWARD, NULL); \ + girara_shortcut_add(gsession, 0, GDK_KEY_N, NULL, sc_search, (mode), BACKWARD, NULL); \ + \ + girara_shortcut_add(gsession, 0, GDK_KEY_P, NULL, sc_snap_to_page, (mode), 0, NULL); \ + \ + girara_shortcut_add(gsession, 0, GDK_KEY_Tab, NULL, sc_toggle_index, (mode), 0, NULL); \ + girara_shortcut_add(gsession, GDK_CONTROL_MASK, GDK_KEY_n, NULL, girara_sc_toggle_statusbar, (mode), 0, NULL); \ + girara_shortcut_add(gsession, GDK_CONTROL_MASK, GDK_KEY_m, NULL, girara_sc_toggle_inputbar, (mode), 0, NULL); \ + girara_shortcut_add(gsession, 0, GDK_KEY_d, NULL, sc_toggle_page_mode, (mode), 0, NULL); \ + \ + girara_shortcut_add(gsession, 0, GDK_KEY_q, NULL, sc_quit, (mode), 0, NULL); \ + \ + girara_shortcut_add(gsession, 0, GDK_KEY_plus, NULL, sc_zoom, (mode), ZOOM_IN, NULL); \ + girara_shortcut_add(gsession, 0, GDK_KEY_KP_Add, NULL, sc_zoom, (mode), ZOOM_IN, NULL); \ + girara_shortcut_add(gsession, 0, GDK_KEY_minus, NULL, sc_zoom, (mode), ZOOM_OUT, NULL); \ + girara_shortcut_add(gsession, 0, GDK_KEY_KP_Subtract, NULL, sc_zoom, (mode), ZOOM_OUT, NULL); \ + girara_shortcut_add(gsession, 0, GDK_KEY_equal, NULL, sc_zoom, (mode), ZOOM_SPECIFIC, NULL); \ + girara_shortcut_add(gsession, 0, 0, "zi", sc_zoom, (mode), ZOOM_IN, NULL); \ + girara_shortcut_add(gsession, 0, 0, "zI", sc_zoom, (mode), ZOOM_IN, NULL); \ + girara_shortcut_add(gsession, 0, 0, "zo", sc_zoom, (mode), ZOOM_OUT, NULL); \ + girara_shortcut_add(gsession, 0, 0, "zO", sc_zoom, (mode), ZOOM_OUT, NULL); \ + girara_shortcut_add(gsession, 0, 0, "z0", sc_zoom, (mode), ZOOM_ORIGINAL, NULL); \ + girara_shortcut_add(gsession, 0, 0, "zz", sc_zoom, (mode), ZOOM_SPECIFIC, NULL); \ + girara_shortcut_add(gsession, 0, 0, "zZ", sc_zoom, (mode), ZOOM_SPECIFIC, NULL); -#define DEFAULT_MOUSE_EVENTS(mode) \ - girara_mouse_event_add(gsession, 0, 0, sc_mouse_scroll, (mode), GIRARA_EVENT_SCROLL_UP, UP, NULL); \ - girara_mouse_event_add(gsession, 0, 0, sc_mouse_scroll, (mode), GIRARA_EVENT_SCROLL_DOWN, DOWN, NULL); \ - girara_mouse_event_add(gsession, 0, 0, sc_mouse_scroll, (mode), GIRARA_EVENT_SCROLL_LEFT, LEFT, NULL); \ - girara_mouse_event_add(gsession, 0, 0, sc_mouse_scroll, (mode), GIRARA_EVENT_SCROLL_RIGHT, RIGHT, NULL); \ - girara_mouse_event_add(gsession, 0, 0, sc_mouse_scroll, (mode), GIRARA_EVENT_SCROLL_BIDIRECTIONAL, BIDIRECTIONAL, NULL); \ -\ - girara_mouse_event_add(gsession, GDK_SHIFT_MASK, 0, sc_mouse_scroll, (mode), GIRARA_EVENT_SCROLL_UP, LEFT, NULL); \ - girara_mouse_event_add(gsession, GDK_SHIFT_MASK, 0, sc_mouse_scroll, (mode), GIRARA_EVENT_SCROLL_DOWN, RIGHT, NULL); \ -\ - girara_mouse_event_add(gsession, GDK_CONTROL_MASK, 0, sc_mouse_zoom, (mode), GIRARA_EVENT_SCROLL_UP, UP, NULL); \ - girara_mouse_event_add(gsession, GDK_CONTROL_MASK, 0, sc_mouse_zoom, (mode), GIRARA_EVENT_SCROLL_DOWN, DOWN, NULL); \ - girara_mouse_event_add(gsession, GDK_CONTROL_MASK, 0, sc_mouse_zoom, (mode), GIRARA_EVENT_SCROLL_BIDIRECTIONAL, BIDIRECTIONAL, NULL); \ - girara_mouse_event_add(gsession, 0, GIRARA_MOUSE_BUTTON2, sc_mouse_scroll, (mode), GIRARA_EVENT_BUTTON_PRESS, 0, NULL); \ - girara_mouse_event_add(gsession, GDK_BUTTON2_MASK, GIRARA_MOUSE_BUTTON2, sc_mouse_scroll, (mode), GIRARA_EVENT_BUTTON_RELEASE, 0, NULL); \ - girara_mouse_event_add(gsession, GDK_BUTTON2_MASK, 0, sc_mouse_scroll, (mode), GIRARA_EVENT_MOTION_NOTIFY, 0, NULL); \ +#define DEFAULT_MOUSE_EVENTS(mode) \ + girara_mouse_event_add(gsession, 0, 0, sc_mouse_scroll, (mode), GIRARA_EVENT_SCROLL_UP, UP, NULL); \ + girara_mouse_event_add(gsession, 0, 0, sc_mouse_scroll, (mode), GIRARA_EVENT_SCROLL_DOWN, DOWN, NULL); \ + girara_mouse_event_add(gsession, 0, 0, sc_mouse_scroll, (mode), GIRARA_EVENT_SCROLL_LEFT, LEFT, NULL); \ + girara_mouse_event_add(gsession, 0, 0, sc_mouse_scroll, (mode), GIRARA_EVENT_SCROLL_RIGHT, RIGHT, NULL); \ + girara_mouse_event_add(gsession, 0, 0, sc_mouse_scroll, (mode), GIRARA_EVENT_SCROLL_BIDIRECTIONAL, BIDIRECTIONAL, \ + NULL); \ + \ + girara_mouse_event_add(gsession, GDK_SHIFT_MASK, 0, sc_mouse_scroll, (mode), GIRARA_EVENT_SCROLL_UP, LEFT, NULL); \ + girara_mouse_event_add(gsession, GDK_SHIFT_MASK, 0, sc_mouse_scroll, (mode), GIRARA_EVENT_SCROLL_DOWN, RIGHT, NULL); \ + \ + girara_mouse_event_add(gsession, GDK_CONTROL_MASK, 0, sc_mouse_zoom, (mode), GIRARA_EVENT_SCROLL_UP, UP, NULL); \ + girara_mouse_event_add(gsession, GDK_CONTROL_MASK, 0, sc_mouse_zoom, (mode), GIRARA_EVENT_SCROLL_DOWN, DOWN, NULL); \ + girara_mouse_event_add(gsession, GDK_CONTROL_MASK, 0, sc_mouse_zoom, (mode), GIRARA_EVENT_SCROLL_BIDIRECTIONAL, \ + BIDIRECTIONAL, NULL); \ + girara_mouse_event_add(gsession, 0, GIRARA_MOUSE_BUTTON2, sc_mouse_scroll, (mode), GIRARA_EVENT_BUTTON_PRESS, 0, \ + NULL); \ + girara_mouse_event_add(gsession, GDK_BUTTON2_MASK, GIRARA_MOUSE_BUTTON2, sc_mouse_scroll, (mode), \ + GIRARA_EVENT_BUTTON_RELEASE, 0, NULL); \ + girara_mouse_event_add(gsession, GDK_BUTTON2_MASK, 0, sc_mouse_scroll, (mode), GIRARA_EVENT_MOTION_NOTIFY, 0, NULL); /* Define mode-less shortcuts * girara adds them only for normal mode, so passing 0 as mode is currently diff --git a/zathura/page-widget.c b/zathura/page-widget.c index ac40263..216381e 100644 --- a/zathura/page-widget.c +++ b/zathura/page-widget.c @@ -58,6 +58,12 @@ typedef struct zathura_page_widget_private_s { zathura_rectangle_t bounds; /**< Highlight bounds */ gboolean draw; /**< Draw highlighted region */ } highlighter; + + struct { + girara_list_t* list; /**< List of signatures on the page */ + gboolean retrieved; /**< True if we already tried to retrieve the list of signatures */ + gboolean draw; /**< True if links should be drawn */ + } signatures; } ZathuraPagePrivate; G_DEFINE_TYPE_WITH_CODE(ZathuraPage, zathura_page_widget, GTK_TYPE_DRAWING_AREA, G_ADD_PRIVATE(ZathuraPage)) @@ -97,6 +103,7 @@ enum properties_e { PROP_SEARCH_RESULTS_CURRENT, PROP_DRAW_SEARCH_RESULTS, PROP_LAST_VIEW, + PROP_DRAW_SIGNATURES, }; enum { @@ -148,6 +155,10 @@ zathura_page_widget_class_init(ZathuraPageClass* class) g_param_spec_int("search-length", "search-length", "The number of search results", -1, INT_MAX, 0, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS)); g_object_class_install_property(object_class, PROP_DRAW_SEARCH_RESULTS, g_param_spec_boolean("draw-search-results", "draw-search-results", "Set to true if search results should be drawn", FALSE, G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property(object_class, PROP_DRAW_SIGNATURES, + g_param_spec_boolean("draw-signatures", "draw-signatures", + "Set to true if signatures should be drawn", FALSE, + G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS)); /* add signals */ signals[TEXT_SELECTED] = g_signal_new("text-selected", @@ -244,8 +255,12 @@ zathura_page_widget_init(ZathuraPage* widget) priv->highlighter.bounds.y2 = -1; priv->highlighter.draw = false; - const unsigned int event_mask = GDK_BUTTON_PRESS_MASK | - GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK | GDK_LEAVE_NOTIFY_MASK; + priv->signatures.list = NULL; + priv->signatures.retrieved = false; + priv->signatures.draw = false; + + const unsigned int event_mask = + GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK | GDK_LEAVE_NOTIFY_MASK; gtk_widget_add_events(GTK_WIDGET(widget), event_mask); } @@ -384,99 +399,118 @@ get_text_extents(const char* string, zathura_t* zathura, cairo_font_weight_t wei return text; } -static void -zathura_page_widget_set_property(GObject* object, guint prop_id, const GValue* value, GParamSpec* pspec) -{ - ZathuraPage* pageview = ZATHURA_PAGE(object); +static void zathura_page_widget_set_property(GObject* object, guint prop_id, const GValue* value, GParamSpec* pspec) { + ZathuraPage* pageview = ZATHURA_PAGE(object); ZathuraPagePrivate* priv = zathura_page_widget_get_instance_private(pageview); cairo_text_extents_t text; switch (prop_id) { - case PROP_PAGE: - priv->page = g_value_get_pointer(value); - break; - case PROP_ZATHURA: - priv->zathura = g_value_get_pointer(value); - break; - case PROP_DRAW_LINKS: - priv->links.draw = g_value_get_boolean(value); - /* get links */ - if (priv->links.draw == TRUE && priv->links.retrieved == FALSE) { - priv->links.list = zathura_page_links_get(priv->page, NULL); - priv->links.retrieved = TRUE; - priv->links.n = (priv->links.list == NULL) ? 0 : girara_list_size(priv->links.list); - } + case PROP_PAGE: + priv->page = g_value_get_pointer(value); + break; + case PROP_ZATHURA: + priv->zathura = g_value_get_pointer(value); + break; + case PROP_DRAW_LINKS: + priv->links.draw = g_value_get_boolean(value); + /* get links */ + if (priv->links.draw == TRUE && priv->links.retrieved == FALSE) { + priv->links.list = zathura_page_links_get(priv->page, NULL); + priv->links.retrieved = TRUE; + priv->links.n = (priv->links.list == NULL) ? 0 : girara_list_size(priv->links.list); + } - if (priv->links.retrieved == TRUE && priv->links.list != NULL) { - /* get size of text that should be large enough for every link hint */ - text = get_text_extents("888", priv->zathura, CAIRO_FONT_WEIGHT_BOLD); + if (priv->links.retrieved == TRUE && priv->links.list != NULL) { + /* get size of text that should be large enough for every link hint */ + text = get_text_extents("888", priv->zathura, CAIRO_FONT_WEIGHT_BOLD); - GIRARA_LIST_FOREACH_BODY(priv->links.list, zathura_link_t*, link, - if (link != NULL) { - /* redraw link area */ - zathura_rectangle_t rectangle = recalc_rectangle(priv->page, zathura_link_get_position(link)); - redraw_rect(pageview, &rectangle); + for (size_t idx = 0; idx != girara_list_size(priv->links.list); ++idx) { + zathura_link_t* link = girara_list_nth(priv->links.list, idx); + if (link != NULL) { + /* redraw link area */ + zathura_rectangle_t rectangle = recalc_rectangle(priv->page, zathura_link_get_position(link)); + redraw_rect(pageview, &rectangle); - /* also redraw area for link hint */ - rectangle.x2 = rectangle.x1 + text.width; - rectangle.y1 = rectangle.y2 - text.height; - redraw_rect(pageview, &rectangle); - } - ); - } - break; - case PROP_LINKS_OFFSET: - priv->links.offset = g_value_get_int(value); - break; - case PROP_SEARCH_RESULTS: - if (priv->search.list != NULL && priv->search.draw) { - redraw_all_rects(pageview, priv->search.list); - girara_list_free(priv->search.list); - } - priv->search.list = g_value_get_pointer(value); - if (priv->search.list != NULL && priv->search.draw) { - priv->links.draw = FALSE; - redraw_all_rects(pageview, priv->search.list); - } - priv->search.current = -1; - break; - case PROP_SEARCH_RESULTS_CURRENT: { - g_return_if_fail(priv->search.list != NULL); - if (priv->search.current >= 0 && priv->search.current < (signed) girara_list_size(priv->search.list)) { - zathura_rectangle_t* rect = girara_list_nth(priv->search.list, priv->search.current); - zathura_rectangle_t rectangle = recalc_rectangle(priv->page, *rect); - redraw_rect(pageview, &rectangle); - } - int val = g_value_get_int(value); - if (val < 0) { - priv->search.current = girara_list_size(priv->search.list); - } else { - priv->search.current = val; - if (priv->search.draw == TRUE && val >= 0 && val < (signed) girara_list_size(priv->search.list)) { - zathura_rectangle_t* rect = girara_list_nth(priv->search.list, priv->search.current); - zathura_rectangle_t rectangle = recalc_rectangle(priv->page, *rect); + /* also redraw area for link hint */ + rectangle.x2 = rectangle.x1 + text.width; + rectangle.y1 = rectangle.y2 - text.height; redraw_rect(pageview, &rectangle); } } - break; } - case PROP_DRAW_SEARCH_RESULTS: - priv->search.draw = g_value_get_boolean(value); - - /* - * we do the following instead of only redrawing the rectangles of the - * search results in order to avoid the rectangular margins that appear - * around the search terms after their highlighted rectangular areas are - * redrawn without highlighting. - */ - - if (priv->search.list != NULL && zathura_page_get_visibility(priv->page)) { - gtk_widget_queue_draw(GTK_WIDGET(object)); + break; + case PROP_LINKS_OFFSET: + priv->links.offset = g_value_get_int(value); + break; + case PROP_SEARCH_RESULTS: + if (priv->search.list != NULL && priv->search.draw) { + redraw_all_rects(pageview, priv->search.list); + girara_list_free(priv->search.list); + } + priv->search.list = g_value_get_pointer(value); + if (priv->search.list != NULL && priv->search.draw) { + priv->links.draw = FALSE; + redraw_all_rects(pageview, priv->search.list); + } + priv->search.current = -1; + break; + case PROP_SEARCH_RESULTS_CURRENT: { + g_return_if_fail(priv->search.list != NULL); + if (priv->search.current >= 0 && priv->search.current < (signed)girara_list_size(priv->search.list)) { + zathura_rectangle_t* rect = girara_list_nth(priv->search.list, priv->search.current); + zathura_rectangle_t rectangle = recalc_rectangle(priv->page, *rect); + redraw_rect(pageview, &rectangle); + } + int val = g_value_get_int(value); + if (val < 0) { + priv->search.current = girara_list_size(priv->search.list); + } else { + priv->search.current = val; + if (priv->search.draw == TRUE && val >= 0 && val < (signed)girara_list_size(priv->search.list)) { + zathura_rectangle_t* rect = girara_list_nth(priv->search.list, priv->search.current); + zathura_rectangle_t rectangle = recalc_rectangle(priv->page, *rect); + redraw_rect(pageview, &rectangle); } - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + } + break; + } + case PROP_DRAW_SEARCH_RESULTS: + priv->search.draw = g_value_get_boolean(value); + + /* + * we do the following instead of only redrawing the rectangles of the + * search results in order to avoid the rectangular margins that appear + * around the search terms after their highlighted rectangular areas are + * redrawn without highlighting. + */ + + if (priv->search.list != NULL && zathura_page_get_visibility(priv->page)) { + gtk_widget_queue_draw(GTK_WIDGET(object)); + } + break; + case PROP_DRAW_SIGNATURES: + priv->signatures.draw = g_value_get_boolean(value); + /* get links */ + if (priv->signatures.draw == TRUE && priv->signatures.retrieved == FALSE) { + priv->signatures.list = zathura_page_get_signatures(priv->page, NULL); + priv->signatures.retrieved = TRUE; + } + + if (priv->signatures.retrieved == TRUE && priv->signatures.list != NULL) { + for (size_t idx = 0; idx != girara_list_size(priv->signatures.list); ++idx) { + zathura_signature_info_t* signature = girara_list_nth(priv->signatures.list, idx); + if (signature == NULL) { + continue; + } + /* redraw signature area */ + zathura_rectangle_t rectangle = recalc_rectangle(priv->page, signature->position); + redraw_rect(pageview, &rectangle); + } + } + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); } } @@ -523,12 +557,10 @@ get_safe_device_factors(cairo_surface_t* surface) return factors; } -static gboolean -zathura_page_widget_draw(GtkWidget* widget, cairo_t* cairo) -{ - ZathuraPage* page = ZATHURA_PAGE(widget); - ZathuraPagePrivate* priv = zathura_page_widget_get_instance_private(page); - zathura_t* zathura = priv->zathura; +static gboolean zathura_page_widget_draw(GtkWidget* widget, cairo_t* cairo) { + ZathuraPage* page = ZATHURA_PAGE(widget); + ZathuraPagePrivate* priv = zathura_page_widget_get_instance_private(page); + zathura_t* zathura = priv->zathura; zathura_document_t* document = zathura_page_get_document(priv->page); const unsigned int page_height = gtk_widget_get_allocated_height(widget); @@ -637,6 +669,70 @@ zathura_page_widget_draw(GtkWidget* widget, cairo_t* cairo) } } + /* draw signatures */ + if (priv->signatures.draw == true && priv->signatures.list != NULL) { + for (size_t idx = 0; idx != girara_list_size(priv->signatures.list); ++idx) { + zathura_signature_info_t* signature = girara_list_nth(priv->signatures.list, idx); + if (signature == NULL) { + continue; + } + + GdkRGBA color; + char* text = NULL; + bool free_text = false; + switch (signature->state) { + case ZATHURA_SIGNATURE_VALID: { + color = zathura->ui.colors.signature_success; + + char* sig_time = g_date_time_format(signature->time, "%F %T"); + text = g_strdup_printf(_("Signature is valid.\nThis document is signed by\n %s\non %s."), signature->signer, + sig_time); + free_text = true; + g_free(sig_time); + break; + } + case ZATHURA_SIGNATURE_CERTIFICATE_EXPIRED: + color = zathura->ui.colors.signature_warning; + text = _("Signature certificate is expired."); + break; + case ZATHURA_SIGNATURE_CERTIFICATE_REVOKED: + color = zathura->ui.colors.signature_error; + text = _("Signature certificate is revoked."); + break; + case ZATHURA_SIGNATURE_CERTIFICATE_UNTRUSTED: + color = zathura->ui.colors.signature_error; + text = _("Signature certificate is not trusted."); + break; + case ZATHURA_SIGNATURE_CERTIFICATE_INVALID: + color = zathura->ui.colors.signature_error; + text = _("Signature certificate is invalid."); + break; + default: + color = zathura->ui.colors.signature_error; + text = _("Signature is invalid."); + } + + /* draw position */ + zathura_rectangle_t rectangle = recalc_rectangle(priv->page, signature->position); + cairo_set_source_rgba(cairo, color.red, color.green, color.blue, color.alpha); + cairo_rectangle(cairo, rectangle.x1, rectangle.y1, (rectangle.x2 - rectangle.x1), + (rectangle.y2 - rectangle.y1)); + cairo_fill(cairo); + + /* draw text */ + const GdkRGBA color_fg = zathura->ui.colors.highlight_color_fg; + cairo_set_source_rgba(cairo, color_fg.red, color_fg.green, color_fg.blue, transparency); + cairo_text_extents_t extents; + cairo_text_extents(cairo, text, &extents); + + cairo_move_to(cairo, rectangle.x1 + 1, rectangle.y1 + extents.height + 1); + cairo_show_text(cairo, text); + if (free_text == true) { + g_free(text); + } + } + } + /* draw search results */ if (priv->search.list != NULL && priv->search.draw == true) { int idx = 0; diff --git a/zathura/zathura.c b/zathura/zathura.c index 19cbc8b..c0ff579 100644 --- a/zathura/zathura.c +++ b/zathura/zathura.c @@ -1349,6 +1349,9 @@ document_open(zathura_t* zathura, const char* path, const char* uri, const char* position_set(zathura, file_info.position_x, file_info.position_y); } + bool show_signature_information = false; + girara_setting_get(zathura->ui.session, "show-signature-information", &show_signature_information); + zathura_show_signature_information(zathura, show_signature_information); update_visible_pages(zathura); return true; @@ -1896,3 +1899,21 @@ zathura_signal_sigterm(gpointer data) return TRUE; } #endif + +void zathura_show_signature_information(zathura_t* zathura, bool show) { + if (zathura->document == NULL) { + return; + } + + GValue show_sig_info_value = {0}; + g_value_init(&show_sig_info_value, G_TYPE_BOOLEAN); + g_value_set_boolean(&show_sig_info_value, show); + + const unsigned int number_of_pages = zathura_document_get_number_of_pages(zathura->document); + for (unsigned int page = 0; page != number_of_pages; ++page) { + // draw signature info + g_object_set_property(G_OBJECT(zathura->pages[page]), "draw-signatures", &show_sig_info_value); + } + + g_value_unset(&show_sig_info_value); +} diff --git a/zathura/zathura.h b/zathura/zathura.h index 93b4756..1b878e5 100644 --- a/zathura/zathura.h +++ b/zathura/zathura.h @@ -455,4 +455,12 @@ void statusbar_page_number_update(zathura_t* zathura); */ char* get_formatted_filename(zathura_t* zathura, bool statusbar); +/** + * Show additional signature information + * + * @param zathura The zathura session + * @param show Whether to show the signature information + */ +void zathura_show_signature_information(zathura_t* zathura, bool show); + #endif // ZATHURA_H