From 8394bd8dcca396e663fd69a4c3fd914b59b3ae4f Mon Sep 17 00:00:00 2001 From: Moritz Lipp Date: Mon, 12 Apr 2010 19:22:47 +0200 Subject: [PATCH 1/7] Scroll and click event callbacks defined Two callbacks for "scroll" and "click" events has been defined and connected to the view. --- zathura.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/zathura.c b/zathura.c index 25f7f62..8df09c6 100644 --- a/zathura.c +++ b/zathura.c @@ -339,6 +339,8 @@ gboolean cb_inputbar_activate(GtkEntry*, gpointer); gboolean cb_inputbar_form_activate(GtkEntry*, gpointer); gboolean cb_view_kb_pressed(GtkWidget*, GdkEventKey*, gpointer); gboolean cb_view_resized(GtkWidget*, GtkAllocation*, gpointer); +gboolean cb_view_button_pressed(GtkWidget*, GdkEventButton*, gpointer); +gboolean cb_view_scrolled(GtkWidget*, GdkEventScroll*, gpointer); /* configuration */ #include "config.h" @@ -445,8 +447,10 @@ init_zathura() gtk_box_set_spacing(Zathura.UI.continuous, 5); /* view */ - g_signal_connect(G_OBJECT(Zathura.UI.view), "key-press-event", G_CALLBACK(cb_view_kb_pressed), NULL); - g_signal_connect(G_OBJECT(Zathura.UI.view), "size-allocate", G_CALLBACK(cb_view_resized), NULL); + g_signal_connect(G_OBJECT(Zathura.UI.view), "key-press-event", G_CALLBACK(cb_view_kb_pressed), NULL); + g_signal_connect(G_OBJECT(Zathura.UI.view), "size-allocate", G_CALLBACK(cb_view_resized), NULL); + g_signal_connect(G_OBJECT(Zathura.UI.view), "button-press-event", G_CALLBACK(cb_view_button_pressed), NULL); + g_signal_connect(G_OBJECT(Zathura.UI.view), "scroll-event", G_CALLBACK(cb_view_scrolled), NULL); gtk_container_add(GTK_CONTAINER(Zathura.UI.view), GTK_WIDGET(Zathura.UI.viewport)); gtk_viewport_set_shadow_type(Zathura.UI.viewport, GTK_SHADOW_NONE); @@ -3061,6 +3065,17 @@ cb_view_resized(GtkWidget* widget, GtkAllocation* allocation, gpointer data) return TRUE; } +gboolean +cb_view_button_pressed(GtkWidget* widget, GdkEventButton* event, gpointer data) +{ + return TRUE; +} + +gboolean +cb_view_scrolled(GtkWidget* widget, GdkEventScroll* event, gpointer data) +{ + return TRUE; +} /* main function */ int main(int argc, char* argv[]) From f8eb8b7a9fa42f169d937251d677172ba40b871c Mon Sep 17 00:00:00 2001 From: Moritz Lipp Date: Mon, 12 Apr 2010 19:38:07 +0200 Subject: [PATCH 2/7] Implemented scrolling --- config.def.h | 9 +++++++++ zathura.c | 20 +++++++++++++++++++- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/config.def.h b/config.def.h index 35507f7..768b4ea 100644 --- a/config.def.h +++ b/config.def.h @@ -103,6 +103,15 @@ InputbarShortcut inputbar_shortcuts[] = { {GDK_CONTROL_MASK, GDK_w, isc_string_manipulation, { DELETE_LAST_WORD } }, }; +/* mouse settings */ +MouseScrollEvent mouse_scroll_events[] = { + /* direction, function, argument */ + {GDK_SCROLL_LEFT, sc_scroll, { LEFT } }, + {GDK_SCROLL_UP, sc_scroll, { UP } }, + {GDK_SCROLL_DOWN, sc_scroll, { DOWN } }, + {GDK_SCROLL_RIGHT, sc_scroll, { RIGHT } }, +}; + /* commands */ Command commands[] = { /* command, abbreviation, function, completion, description */ diff --git a/zathura.c b/zathura.c index 8df09c6..879cdfb 100644 --- a/zathura.c +++ b/zathura.c @@ -85,6 +85,13 @@ typedef struct Argument argument; } InputbarShortcut; +typedef struct +{ + int direction; + void (*function)(Argument*); + Argument argument; +} MouseScrollEvent; + typedef struct { char* command; @@ -1255,6 +1262,7 @@ sc_adjust_window(Argument* argument) Zathura.PDF.scale = (view_size / page_width) * 100; draw(Zathura.PDF.page_number); + update_status(); } void @@ -3074,7 +3082,17 @@ cb_view_button_pressed(GtkWidget* widget, GdkEventButton* event, gpointer data) gboolean cb_view_scrolled(GtkWidget* widget, GdkEventScroll* event, gpointer data) { - return TRUE; + int i; + for(i = 0; i < LENGTH(mouse_scroll_events); i++) + { + if(event->direction == mouse_scroll_events[i].direction) + { + mouse_scroll_events[i].function(&(mouse_scroll_events[i].argument)); + return TRUE; + } + } + + return FALSE; } /* main function */ From 68d74e09f8b03d51e30499b75d98fe7f37433177 Mon Sep 17 00:00:00 2001 From: Moritz Lipp Date: Mon, 12 Apr 2010 23:55:14 +0200 Subject: [PATCH 3/7] Added GtkEventBox to catch mouse events This commited introduces a GtkEventBox called document that is responsible for catching all mouse events like "released" or "motion". --- zathura.c | 43 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 35 insertions(+), 8 deletions(-) diff --git a/zathura.c b/zathura.c index 879cdfb..fe9c81b 100644 --- a/zathura.c +++ b/zathura.c @@ -158,6 +158,7 @@ struct GtkWidget *index; GtkWidget *information; GtkWidget *drawing_area; + GtkWidget *document; } UI; struct @@ -347,6 +348,8 @@ gboolean cb_inputbar_form_activate(GtkEntry*, gpointer); gboolean cb_view_kb_pressed(GtkWidget*, GdkEventKey*, gpointer); gboolean cb_view_resized(GtkWidget*, GtkAllocation*, gpointer); gboolean cb_view_button_pressed(GtkWidget*, GdkEventButton*, gpointer); +gboolean cb_view_button_release(GtkWidget*, GdkEventButton*, gpointer); +gboolean cb_view_motion_notify(GtkWidget*, GdkEventMotion*, gpointer); gboolean cb_view_scrolled(GtkWidget*, GdkEventScroll*, gpointer); /* configuration */ @@ -438,6 +441,7 @@ init_zathura() Zathura.UI.statusbar = gtk_event_box_new(); Zathura.UI.statusbar_entries = GTK_BOX(gtk_hbox_new(FALSE, 0)); Zathura.UI.inputbar = GTK_ENTRY(gtk_entry_new()); + Zathura.UI.document = gtk_event_box_new(); /* window */ gtk_window_set_title(Zathura.UI.window, "zathura"); @@ -453,11 +457,19 @@ init_zathura() /* continuous */ gtk_box_set_spacing(Zathura.UI.continuous, 5); + /* events */ + gtk_container_add(GTK_CONTAINER(Zathura.UI.document), GTK_WIDGET(Zathura.UI.drawing_area)); + gtk_widget_add_events(GTK_WIDGET(Zathura.UI.document), GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | + GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK); + + g_signal_connect(G_OBJECT(Zathura.UI.document), "button-press-event", G_CALLBACK(cb_view_button_pressed), NULL); + g_signal_connect(G_OBJECT(Zathura.UI.document), "button-release-event", G_CALLBACK(cb_view_button_release), NULL); + g_signal_connect(G_OBJECT(Zathura.UI.document), "motion-notify-event", G_CALLBACK(cb_view_motion_notify), NULL); + /* view */ - g_signal_connect(G_OBJECT(Zathura.UI.view), "key-press-event", G_CALLBACK(cb_view_kb_pressed), NULL); - g_signal_connect(G_OBJECT(Zathura.UI.view), "size-allocate", G_CALLBACK(cb_view_resized), NULL); - g_signal_connect(G_OBJECT(Zathura.UI.view), "button-press-event", G_CALLBACK(cb_view_button_pressed), NULL); - g_signal_connect(G_OBJECT(Zathura.UI.view), "scroll-event", G_CALLBACK(cb_view_scrolled), NULL); + g_signal_connect(G_OBJECT(Zathura.UI.view), "key-press-event", G_CALLBACK(cb_view_kb_pressed), NULL); + g_signal_connect(G_OBJECT(Zathura.UI.view), "size-allocate", G_CALLBACK(cb_view_resized), NULL); + g_signal_connect(G_OBJECT(Zathura.UI.view), "scroll-event", G_CALLBACK(cb_view_scrolled), NULL); gtk_container_add(GTK_CONTAINER(Zathura.UI.view), GTK_WIDGET(Zathura.UI.viewport)); gtk_viewport_set_shadow_type(Zathura.UI.viewport, GTK_SHADOW_NONE); @@ -1064,7 +1076,7 @@ set_page(int page) argument.n = TOP; sc_scroll(&argument); - switch_view(Zathura.UI.drawing_area); + switch_view(Zathura.UI.document); draw(page); } @@ -1220,7 +1232,7 @@ sc_abort(Argument* argument) /* Set back to normal mode */ change_mode(NORMAL); - switch_view(Zathura.UI.drawing_area); + switch_view(Zathura.UI.document); } void @@ -1498,7 +1510,7 @@ sc_toggle_index(Argument* argument) if(!show) switch_view(Zathura.UI.index); else - switch_view(Zathura.UI.drawing_area); + switch_view(Zathura.UI.document); show = !show; } @@ -2216,7 +2228,7 @@ cmd_info(int argc, char** argv) if(!visible) switch_view(Zathura.UI.information); else - switch_view(Zathura.UI.drawing_area); + switch_view(Zathura.UI.document); visible = !visible; @@ -3075,6 +3087,21 @@ cb_view_resized(GtkWidget* widget, GtkAllocation* allocation, gpointer data) gboolean cb_view_button_pressed(GtkWidget* widget, GdkEventButton* event, gpointer data) +{ + if(!Zathura.PDF.document) + return FALSE; + + return TRUE; +} + +gboolean +cb_view_button_release(GtkWidget* widget, GdkEventButton* event, gpointer data) +{ + return TRUE; +} + +gboolean +cb_view_motion_notify(GtkWidget* widget, GdkEventMotion* event, gpointer data) { return TRUE; } From 97a878a317af5387b48aef456dbcdba82a226bc9 Mon Sep 17 00:00:00 2001 From: Moritz Lipp Date: Tue, 13 Apr 2010 00:22:56 +0200 Subject: [PATCH 4/7] Draw marked area This commit draws an rectangle in the marked area. --- config.def.h | 1 + zathura.c | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/config.def.h b/config.def.h index 768b4ea..51aef3f 100644 --- a/config.def.h +++ b/config.def.h @@ -40,6 +40,7 @@ static const char recolor_darkcolor[] = "#353535"; static const char recolor_lightcolor[] = "#DBDBDB"; static const char search_highlight[] = "#9FBC00"; +static const char select_text[] = "#000000"; /* statusbar */ static const char DEFAULT_TEXT[] = "[No Name]"; diff --git a/zathura.c b/zathura.c index fe9c81b..05ffb30 100644 --- a/zathura.c +++ b/zathura.c @@ -182,6 +182,7 @@ struct GdkColor recolor_darkcolor; GdkColor recolor_lightcolor; GdkColor search_highlight; + GdkColor select_text; PangoFontDescription *font; } Style; @@ -198,6 +199,12 @@ struct int adjust_mode; } Global; + struct + { + gdouble x; + gdouble y; + } SelectPoint; + struct { char* filename; @@ -244,6 +251,7 @@ struct GStaticMutex pdflib_lock; GStaticMutex document_lock; GStaticMutex search_lock; + GStaticMutex select_lock; } Lock; struct @@ -391,6 +399,7 @@ init_zathura() /* init mutexes */ g_static_mutex_init(&(Zathura.Lock.pdflib_lock)); g_static_mutex_init(&(Zathura.Lock.search_lock)); + g_static_mutex_init(&(Zathura.Lock.select_lock)); g_static_mutex_init(&(Zathura.Lock.document_lock)); /* look */ @@ -413,6 +422,7 @@ init_zathura() gdk_color_parse(recolor_darkcolor, &(Zathura.Style.recolor_darkcolor)); gdk_color_parse(recolor_lightcolor, &(Zathura.Style.recolor_lightcolor)); gdk_color_parse(search_highlight, &(Zathura.Style.search_highlight)); + gdk_color_parse(select_text, &(Zathura.Style.select_text)); Zathura.Style.font = pango_font_description_from_string(font); /* other */ @@ -3091,12 +3101,34 @@ cb_view_button_pressed(GtkWidget* widget, GdkEventButton* event, gpointer data) if(!Zathura.PDF.document) return FALSE; + /* clean page */ + draw(Zathura.PDF.page_number); + g_static_mutex_lock(&(Zathura.Lock.select_lock)); + Zathura.SelectPoint.x = event->x; + Zathura.SelectPoint.y = event->y; + g_static_mutex_unlock(&(Zathura.Lock.select_lock)); + return TRUE; } gboolean cb_view_button_release(GtkWidget* widget, GdkEventButton* event, gpointer data) { + if(!Zathura.PDF.document) + return FALSE; + + g_static_mutex_lock(&(Zathura.Lock.select_lock)); + cairo_t *cairo = cairo_create(Zathura.PDF.surface); + cairo_set_source_rgba(cairo, Zathura.Style.select_text.red, Zathura.Style.select_text.green, + Zathura.Style.select_text.blue, TRANSPARENCY); + + cairo_rectangle(cairo, event->x, event->y, (Zathura.SelectPoint.x - event->x), + (Zathura.SelectPoint.y - event->y)); + cairo_fill(cairo); + g_static_mutex_unlock(&(Zathura.Lock.select_lock)); + gtk_widget_queue_draw(Zathura.UI.drawing_area); + + return TRUE; } From e17a8b433a5fc528a0c3b59ed31a8043a9a27cd7 Mon Sep 17 00:00:00 2001 From: Moritz Lipp Date: Tue, 13 Apr 2010 09:47:47 +0200 Subject: [PATCH 5/7] Calculate drawing rectangle and copy text to cb This commit calculates the rectangle that will be drawn correctly. Now the mapped rectangle is calculated wrong, but it gets the text of the document and copies it to the clipboard. --- zathura.c | 126 +++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 87 insertions(+), 39 deletions(-) diff --git a/zathura.c b/zathura.c index 05ffb30..02bbc04 100644 --- a/zathura.c +++ b/zathura.c @@ -275,6 +275,7 @@ void init_zathura(); void add_marker(int); void build_index(GtkTreeModel*, GtkTreeIter*, PopplerIndexIter*); void change_mode(int); +void calculate_offset(GtkWidget*, double*, double*); void highlight_result(int, PopplerRectangle*); void draw(int); void eval_marker(int); @@ -754,6 +755,42 @@ change_mode(int mode) notify(DEFAULT, mode_text); } +void +calculate_offset(GtkWidget* widget, double* offset_x, double* offset_y) +{ + double page_width, page_height, width, height; + double scale = ((double) Zathura.PDF.scale / 100.0); + + g_static_mutex_lock(&(Zathura.Lock.pdflib_lock)); + poppler_page_get_size(Zathura.PDF.pages[Zathura.PDF.page_number]->page, &page_width, &page_height); + g_static_mutex_unlock(&(Zathura.Lock.pdflib_lock)); + + if(Zathura.PDF.rotate == 0 || Zathura.PDF.rotate == 180) + { + width = page_width * scale; + height = page_height * scale; + } + else + { + width = page_height * scale; + height = page_width * scale; + } + + int window_x, window_y; + gdk_drawable_get_size(widget->window, &window_x, &window_y); + + if (window_x > width) + *offset_x = (window_x - width) / 2; + else + *offset_x = 0; + + if (window_y > height) + *offset_y = (window_y - height) / 2; + else + *offset_y = 0; + +} + void eval_marker(int id) { @@ -2767,46 +2804,14 @@ gboolean cb_draw(GtkWidget* widget, GdkEventExpose* expose, gpointer data) return FALSE; int page_id = Zathura.PDF.page_number; - if(page_id < 0 || page_id > Zathura.PDF.number_of_pages) return FALSE; gdk_window_clear(widget->window); cairo_t *cairo = gdk_cairo_create(widget->window); - double page_width, page_height, width, height; - double scale = ((double) Zathura.PDF.scale / 100.0); - - g_static_mutex_lock(&(Zathura.Lock.pdflib_lock)); - poppler_page_get_size(Zathura.PDF.pages[page_id]->page, &page_width, &page_height); - g_static_mutex_unlock(&(Zathura.Lock.pdflib_lock)); - - if(Zathura.PDF.rotate == 0 || Zathura.PDF.rotate == 180) - { - width = page_width * scale; - height = page_height * scale; - } - else - { - width = page_height * scale; - height = page_width * scale; - } - - int window_x, window_y; - gdk_drawable_get_size(widget->window, &window_x, &window_y); - - int offset_x, offset_y; - - if (window_x > width) - offset_x = (window_x - width) / 2; - else - offset_x = 0; - - if (window_y > height) - offset_y = (window_y - height) / 2; - else - offset_y = 0; - + double offset_x, offset_y; + calculate_offset(widget, &offset_x, &offset_y); cairo_set_source_surface(cairo, Zathura.PDF.surface, offset_x, offset_y); cairo_paint(cairo); @@ -3117,17 +3122,60 @@ cb_view_button_release(GtkWidget* widget, GdkEventButton* event, gpointer data) if(!Zathura.PDF.document) return FALSE; + double scale, offset_x, offset_y; + PopplerRectangle rectangle; + cairo_t* cairo; + + /* build selection rectangle */ + rectangle.x1 = event->x; + rectangle.y1 = event->y; + g_static_mutex_lock(&(Zathura.Lock.select_lock)); - cairo_t *cairo = cairo_create(Zathura.PDF.surface); + rectangle.x2 = Zathura.SelectPoint.x; + rectangle.y2 = Zathura.SelectPoint.y; + g_static_mutex_unlock(&(Zathura.Lock.select_lock)); + + /* calculate offset */ + calculate_offset(widget, &offset_x, &offset_y); + + /* draw selection rectangle */ + cairo = cairo_create(Zathura.PDF.surface); cairo_set_source_rgba(cairo, Zathura.Style.select_text.red, Zathura.Style.select_text.green, Zathura.Style.select_text.blue, TRANSPARENCY); - - cairo_rectangle(cairo, event->x, event->y, (Zathura.SelectPoint.x - event->x), - (Zathura.SelectPoint.y - event->y)); + cairo_rectangle(cairo, rectangle.x1 - offset_x, rectangle.y1 - offset_y, + (rectangle.x2 - rectangle.x1), (rectangle.y2 - rectangle.y1)); cairo_fill(cairo); - g_static_mutex_unlock(&(Zathura.Lock.select_lock)); gtk_widget_queue_draw(Zathura.UI.drawing_area); + /* reset points of the rectangle so that p1 is in the top-left corner + * and p2 is in the bottom right corner */ + if(rectangle.x1 > rectangle.x2) + { + double d = rectangle.x1 - rectangle.x2; + rectangle.x1 = rectangle.x1 - d; + rectangle.x2 = rectangle.x2 - d; + } + if(rectangle.y2 > rectangle.y1) + { + double d = rectangle.y2 - rectangle.y1; + rectangle.y1 = rectangle.y1 + d; + rectangle.y2 = rectangle.y2 - d; + } + + /* resize selection rectangle to document page */ + scale = ((double) Zathura.PDF.scale / 100.0); + rectangle.x1 = (rectangle.x1 - offset_x) / scale; + rectangle.y1 = (rectangle.y1 - offset_y) / scale; + rectangle.x2 = (rectangle.x2 - offset_x) / scale; + rectangle.y2 = (rectangle.y2 - offset_y) / scale; + + g_static_mutex_lock(&(Zathura.Lock.pdflib_lock)); + char* selected_text = poppler_page_get_text(Zathura.PDF.pages[Zathura.PDF.page_number]->page, + POPPLER_SELECTION_GLYPH, &rectangle); + + if(selected_text) + gtk_clipboard_set_text(gtk_clipboard_get(GDK_SELECTION_PRIMARY), selected_text, -1); + g_static_mutex_unlock(&(Zathura.Lock.pdflib_lock)); return TRUE; } From ee182e035a59b64d9d3f39393de4eb09cc535171 Mon Sep 17 00:00:00 2001 From: Moritz Lipp Date: Tue, 18 May 2010 00:19:09 +0200 Subject: [PATCH 6/7] Select right text in rectangle With this commit zathura selects the text in the selected rectangle and copies it to the clipboard. --- zathura.c | 119 +++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 81 insertions(+), 38 deletions(-) diff --git a/zathura.c b/zathura.c index 02bbc04..58054c5 100644 --- a/zathura.c +++ b/zathura.c @@ -384,7 +384,7 @@ init_directories() } GError* error = NULL; - if(!g_key_file_load_from_file(Zathura.Bookmarks.data, bookmarks, + if(!g_key_file_load_from_file(Zathura.Bookmarks.data, bookmarks, G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS, &error)) { notify(ERROR, g_strdup_printf("Could not load bookmark file: %s", error->message)); @@ -483,7 +483,7 @@ init_zathura() g_signal_connect(G_OBJECT(Zathura.UI.view), "scroll-event", G_CALLBACK(cb_view_scrolled), NULL); gtk_container_add(GTK_CONTAINER(Zathura.UI.view), GTK_WIDGET(Zathura.UI.viewport)); gtk_viewport_set_shadow_type(Zathura.UI.viewport, GTK_SHADOW_NONE); - + #if SHOW_SCROLLBARS gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(Zathura.UI.view), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); #else @@ -707,11 +707,11 @@ draw(int page_id) float sg = ((float) g2 - g1) / (max - min); float sb = ((float) b2 - b1) / (max - min); - for (y = 0; y < height; y++) + for (y = 0; y < height; y++) { unsigned char* data = image + y * rowstride; - for (x = 0; x < width; x++) + for (x = 0; x < width; x++) { mean = (data[0] + data[1] + data[2]) / 3; data[2] = sr * (mean - min) + r1 + 0.5; @@ -844,7 +844,7 @@ void notify(int level, char* message) gtk_widget_modify_text(GTK_WIDGET(Zathura.UI.inputbar), GTK_STATE_NORMAL, &(Zathura.Style.inputbar_fg)); break; } - + if(message) gtk_entry_set_text(Zathura.UI.inputbar, message); } @@ -943,11 +943,11 @@ open_file(char* path, char* password) { if(strcmp(keys[i], BM_PAGE_ENTRY)) { - Zathura.Bookmarks.bookmarks = realloc(Zathura.Bookmarks.bookmarks, - (Zathura.Bookmarks.number_of_bookmarks + 1) * sizeof(Bookmark)); + Zathura.Bookmarks.bookmarks = realloc(Zathura.Bookmarks.bookmarks, + (Zathura.Bookmarks.number_of_bookmarks + 1) * sizeof(Bookmark)); Zathura.Bookmarks.bookmarks[Zathura.Bookmarks.number_of_bookmarks].id = keys[i]; - Zathura.Bookmarks.bookmarks[Zathura.Bookmarks.number_of_bookmarks].page = + Zathura.Bookmarks.bookmarks[Zathura.Bookmarks.number_of_bookmarks].page = g_key_file_get_integer(Zathura.Bookmarks.data, file, keys[i], NULL); Zathura.Bookmarks.number_of_bookmarks++; @@ -1085,7 +1085,7 @@ void setCompletionRowColor(GtkBox* results, int mode, int id) { GtkEventBox *row = (GtkEventBox*) g_list_nth_data(gtk_container_get_children(GTK_CONTAINER(results)), id); - + if(row) { GtkBox *col = (GtkBox*) g_list_nth_data(gtk_container_get_children(GTK_CONTAINER(row)), 0); @@ -1250,7 +1250,7 @@ watch_file(void* parameter) /* reopen and restore settings */ cmd_close(0, NULL); open_file(path, password); - + Zathura.PDF.scale = scale; gdk_threads_enter(); @@ -1358,7 +1358,7 @@ sc_change_mode(Argument* argument) change_mode(argument->n); } -void +void sc_focus_inputbar(Argument* argument) { if(argument->data) @@ -1429,7 +1429,7 @@ sc_navigate(Argument* argument) if(argument->n == NEXT) new_page = (new_page + number_of_pages + 1) % number_of_pages; - else if(argument->n == PREVIOUS) + else if(argument->n == PREVIOUS) new_page = (new_page + number_of_pages - 1) % number_of_pages; set_page(new_page); @@ -1617,13 +1617,13 @@ isc_command_history(Argument* argument) } } -void +void isc_completion(Argument* argument) { gchar *input = gtk_editable_get_chars(GTK_EDITABLE(Zathura.UI.inputbar), 1, -1); gchar identifier = gtk_editable_get_chars(GTK_EDITABLE(Zathura.UI.inputbar), 0, 1)[0]; int length = strlen(input); - + if(!length && !identifier) return; @@ -1933,8 +1933,8 @@ cmd_bookmark(int argc, char** argv) } /* add new bookmark */ - Zathura.Bookmarks.bookmarks = realloc(Zathura.Bookmarks.bookmarks, - (Zathura.Bookmarks.number_of_bookmarks + 1) * sizeof(Bookmark)); + Zathura.Bookmarks.bookmarks = realloc(Zathura.Bookmarks.bookmarks, + (Zathura.Bookmarks.number_of_bookmarks + 1) * sizeof(Bookmark)); Zathura.Bookmarks.bookmarks[Zathura.Bookmarks.number_of_bookmarks].id = id->str; Zathura.Bookmarks.bookmarks[Zathura.Bookmarks.number_of_bookmarks].page = Zathura.PDF.page_number; @@ -1948,7 +1948,7 @@ cmd_open_bookmark(int argc, char** argv) { if(!Zathura.PDF.document || argc < 1) return TRUE; - + /* get id */ int i; GString *id = g_string_new(""); @@ -2157,7 +2157,7 @@ cmd_export(int argc, char** argv) if(argv[1][0] == '~') { - file = malloc(((int) strlen(filename) + (int) strlen(argv[1]) + file = malloc(((int) strlen(filename) + (int) strlen(argv[1]) + (int) strlen(getenv("HOME")) - 1) * sizeof(char)); file = g_strdup_printf("%s%s%s", getenv("HOME"), argv[1] + 1, filename); } @@ -2688,7 +2688,7 @@ cc_set(char* input) } /* buffer command implementation */ -void +void bcmd_goto(char* buffer, Argument* argument) { int b_length = strlen(buffer); @@ -3031,7 +3031,7 @@ cb_view_kb_pressed(GtkWidget *widget, GdkEventKey *event, gpointer data) int i; for(i = 0; i < LENGTH(shortcuts); i++) { - if (event->keyval == shortcuts[i].key && + if (event->keyval == shortcuts[i].key && (((event->state & shortcuts[i].mask) == shortcuts[i].mask) || shortcuts[i].mask == 0) && (Zathura.Global.mode == shortcuts[i].mode || shortcuts[i].mode == -1)) { @@ -3122,7 +3122,7 @@ cb_view_button_release(GtkWidget* widget, GdkEventButton* event, gpointer data) if(!Zathura.PDF.document) return FALSE; - double scale, offset_x, offset_y; + double scale, offset_x, offset_y, page_width, page_height; PopplerRectangle rectangle; cairo_t* cairo; @@ -3147,36 +3147,79 @@ cb_view_button_release(GtkWidget* widget, GdkEventButton* event, gpointer data) cairo_fill(cairo); gtk_widget_queue_draw(Zathura.UI.drawing_area); - /* reset points of the rectangle so that p1 is in the top-left corner - * and p2 is in the bottom right corner */ - if(rectangle.x1 > rectangle.x2) - { - double d = rectangle.x1 - rectangle.x2; - rectangle.x1 = rectangle.x1 - d; - rectangle.x2 = rectangle.x2 - d; - } - if(rectangle.y2 > rectangle.y1) - { - double d = rectangle.y2 - rectangle.y1; - rectangle.y1 = rectangle.y1 + d; - rectangle.y2 = rectangle.y2 - d; - } - /* resize selection rectangle to document page */ + g_static_mutex_lock(&(Zathura.Lock.pdflib_lock)); + poppler_page_get_size(Zathura.PDF.pages[Zathura.PDF.page_number]->page, &page_width, &page_height); + g_static_mutex_unlock(&(Zathura.Lock.pdflib_lock)); + scale = ((double) Zathura.PDF.scale / 100.0); rectangle.x1 = (rectangle.x1 - offset_x) / scale; rectangle.y1 = (rectangle.y1 - offset_y) / scale; rectangle.x2 = (rectangle.x2 - offset_x) / scale; rectangle.y2 = (rectangle.y2 - offset_y) / scale; + /* rotation */ + int rotate = Zathura.PDF.rotate; + double x1 = rectangle.x1; + double x2 = rectangle.x2; + double y1 = rectangle.y1; + double y2 = rectangle.y2; + + switch(rotate) + { + case 90: + rectangle.x1 = y1; + rectangle.y1 = page_height - x2; + rectangle.x2 = y2; + rectangle.y2 = page_height - x1; + break; + case 180: + rectangle.x1 = (page_height - y1); + rectangle.y1 = (page_width - x2); + rectangle.x2 = (page_height - y2); + rectangle.y2 = (page_width - x1); + break; + case 270: + rectangle.x1 = page_width - y2; + rectangle.y1 = x1; + rectangle.x2 = page_width - y1; + rectangle.y2 = x2; + break; + } + + /* reset points of the rectangle so that p1 is in the top-left corner + * and p2 is in the bottom right corner */ + if(rectangle.x1 > rectangle.x2) + { + double d = rectangle.x1; + rectangle.x1 = rectangle.x2; + rectangle.x2 = d; + } + if(rectangle.y2 > rectangle.y1) + { + double d = rectangle.y1; + rectangle.y1 = rectangle.y2; + rectangle.y2 = d; + } + + /* adapt y coordinates */ + rectangle.y1 = page_height - rectangle.y1; + rectangle.y2 = page_height - rectangle.y2; + + /* get selected text */ g_static_mutex_lock(&(Zathura.Lock.pdflib_lock)); - char* selected_text = poppler_page_get_text(Zathura.PDF.pages[Zathura.PDF.page_number]->page, - POPPLER_SELECTION_GLYPH, &rectangle); + char* selected_text = poppler_page_get_text( + Zathura.PDF.pages[Zathura.PDF.page_number]->page,POPPLER_SELECTION_GLYPH, + &rectangle); if(selected_text) + { gtk_clipboard_set_text(gtk_clipboard_get(GDK_SELECTION_PRIMARY), selected_text, -1); + g_free(selected_text); + } g_static_mutex_unlock(&(Zathura.Lock.pdflib_lock)); + return TRUE; } From d2973805c031b0b86981d41dcc396246f837e5e1 Mon Sep 17 00:00:00 2001 From: Moritz Lipp Date: Tue, 18 May 2010 00:48:46 +0200 Subject: [PATCH 7/7] Custom selection style --- config.def.h | 1 + zathura.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/config.def.h b/config.def.h index 51aef3f..e087dce 100644 --- a/config.def.h +++ b/config.def.h @@ -56,6 +56,7 @@ static const char DEFAULT_TEXT[] = "[No Name]"; #define SHOW_SCROLLBARS 0 #define ADJUST_OPEN ADJUST_BESTFIT #define RECOLOR_OPEN 0 +#define SELECTION_STYLE POPPLER_SELECTION_GLYPH /* shortcuts */ Shortcut shortcuts[] = { diff --git a/zathura.c b/zathura.c index 58054c5..54518df 100644 --- a/zathura.c +++ b/zathura.c @@ -3209,7 +3209,7 @@ cb_view_button_release(GtkWidget* widget, GdkEventButton* event, gpointer data) /* get selected text */ g_static_mutex_lock(&(Zathura.Lock.pdflib_lock)); char* selected_text = poppler_page_get_text( - Zathura.PDF.pages[Zathura.PDF.page_number]->page,POPPLER_SELECTION_GLYPH, + Zathura.PDF.pages[Zathura.PDF.page_number]->page,SELECTION_STYLE, &rectangle); if(selected_text)