]> www.fi.muni.cz Git - evince.git/blobdiff - libview/ev-view.c
[libview] Remove unused bin_window variable.
[evince.git] / libview / ev-view.c
index d1b6f33d0ae6ace40fb2d67bb72e8197b5955e7b..85cf501edb7d8cff505d096d55a02a0d47015e71 100644 (file)
@@ -28,7 +28,7 @@
 #include <gtk/gtk.h>
 #include <gdk/gdkkeysyms.h>
 
-#include "ev-mapping.h"
+#include "ev-mapping-list.h"
 #include "ev-document-forms.h"
 #include "ev-document-images.h"
 #include "ev-document-links.h"
@@ -54,6 +54,8 @@ enum {
        SIGNAL_EXTERNAL_LINK,
        SIGNAL_POPUP_MENU,
        SIGNAL_SELECTION_CHANGED,
+       SIGNAL_SYNC_SOURCE,
+       SIGNAL_ANNOT_ADDED,
        N_SIGNALS
 };
 
@@ -175,6 +177,11 @@ static AtkObject *ev_view_get_accessible                     (GtkWidget *widget)
 /*** Drawing ***/
 static void       highlight_find_results                     (EvView             *view,
                                                              int                 page);
+static void       highlight_forward_search_results           (EvView             *view,
+                                                             int                 page);
+static void       focus_annotation                           (EvView             *view,
+                                                             int                 page,
+                                                             GdkRectangle       *clip);
 static void       draw_one_page                              (EvView             *view,
                                                              gint                page,
                                                              cairo_t            *cr,
@@ -186,14 +193,14 @@ static void       show_loading_window                        (EvView
 static void       hide_loading_window                        (EvView             *view);
 static void       ev_view_reload_page                        (EvView             *view,
                                                              gint                page,
-                                                             GdkRegion          *region);
+                                                             cairo_region_t     *region);
 static void       ev_view_loading_window_move                (EvView             *view);
 
 /*** Callbacks ***/
 static void       ev_view_change_page                        (EvView             *view,
                                                              gint                new_page);
 static void       job_finished_cb                            (EvPixbufCache      *pixbuf_cache,
-                                                             GdkRegion          *region,
+                                                             cairo_region_t     *region,
                                                              EvView             *view);
 static void       ev_view_page_changed_cb                    (EvDocumentModel    *model,
                                                              gint                old_page,
@@ -253,7 +260,6 @@ static void       jump_to_find_result                        (EvView
 static void       jump_to_find_page                          (EvView             *view, 
                                                              EvViewFindDirection direction,
                                                              gint                shift);
-
 /*** Selection ***/
 static void       compute_selections                         (EvView             *view,
                                                              EvSelectionStyle    style,
@@ -801,15 +807,13 @@ compute_scroll_increment (EvView        *view,
 {
        GtkWidget *widget = GTK_WIDGET (view);
        GtkAdjustment *adjustment = view->vadjustment;
-       GdkRegion *text_region, *region;
+       cairo_region_t *text_region, *region;
        GtkAllocation allocation;
        gint page;
        GdkRectangle rect;
        EvRectangle doc_rect;
        GdkRectangle page_area;
        GtkBorder border;
-       GdkRectangle *recs;
-       gint n_recs;
        gdouble fraction = 1.0;
 
        if (scroll != GTK_SCROLL_PAGE_BACKWARD && scroll != GTK_SCROLL_PAGE_FORWARD)
@@ -818,7 +822,7 @@ compute_scroll_increment (EvView        *view,
        page = scroll == GTK_SCROLL_PAGE_BACKWARD ? view->start_page : view->end_page;
 
        text_region = ev_page_cache_get_text_mapping (view->page_cache, page);
-       if (!text_region || gdk_region_empty (text_region))
+       if (!text_region || cairo_region_is_empty (text_region))
                return gtk_adjustment_get_page_size (adjustment);
 
        gtk_widget_get_allocation (widget, &allocation);
@@ -834,37 +838,37 @@ compute_scroll_increment (EvView        *view,
        rect.y = doc_rect.y1;
        rect.width = doc_rect.x2 - doc_rect.x1;
        rect.height = MAX (1, doc_rect.y2 - doc_rect.y1);
-       region = gdk_region_rectangle (&rect);
+       region = cairo_region_create_rectangle (&rect);
 
-       gdk_region_intersect (region, text_region);
-       gdk_region_get_rectangles (region, &recs, &n_recs);
-       gdk_region_destroy (region);
-       if (n_recs > 0) {
+       cairo_region_intersect (region, text_region);
+       if (cairo_region_num_rectangles (region)) {
                EvRenderContext *rc;
                EvPage  *ev_page;
+               cairo_region_t *sel_region;
 
+               cairo_region_get_rectangle (region, 0, &rect);
                ev_page = ev_document_get_page (view->document, page);
                rc = ev_render_context_new (ev_page, view->rotation, view->scale);
                g_object_unref (ev_page);
                /* Get the selection region to know the height of the line */
-               doc_rect.x1 = doc_rect.x2 = recs[0].x + 0.5;
-               doc_rect.y1 = doc_rect.y2 = recs[0].y + 0.5;
+               doc_rect.x1 = doc_rect.x2 = rect.x + 0.5;
+               doc_rect.y1 = doc_rect.y2 = rect.y + 0.5;
 
                ev_document_doc_mutex_lock ();
-               region = ev_selection_get_selection_region (EV_SELECTION (view->document),
-                                                           rc, EV_SELECTION_STYLE_LINE,
-                                                           &doc_rect);
+               sel_region = ev_selection_get_selection_region (EV_SELECTION (view->document),
+                                                               rc, EV_SELECTION_STYLE_LINE,
+                                                               &doc_rect);
                ev_document_doc_mutex_unlock ();
 
                g_object_unref (rc);
-               g_free (recs);
-               gdk_region_get_rectangles (region, &recs, &n_recs);
-               gdk_region_destroy (region);
-               if (n_recs > 0) {
-                       fraction = 1 - (recs[0].height / gtk_adjustment_get_page_size (adjustment));
+
+               if (cairo_region_num_rectangles (sel_region) > 0) {
+                       cairo_region_get_rectangle (sel_region, 0, &rect);
+                       fraction = 1 - (rect.height / gtk_adjustment_get_page_size (adjustment));
                }
-               g_free (recs);
+               cairo_region_destroy (sel_region);
        }
+       cairo_region_destroy (region);
 
        return gtk_adjustment_get_page_size (adjustment) * fraction;
 
@@ -1361,7 +1365,7 @@ location_in_text (EvView  *view,
                  gdouble  x,
                  gdouble  y)
 {
-       GdkRegion *region;
+       cairo_region_t *region;
        gint page = -1;
        gint x_offset = 0, y_offset = 0;
 
@@ -1373,7 +1377,7 @@ location_in_text (EvView  *view,
        region = ev_page_cache_get_text_mapping (view->page_cache, page);
 
        if (region)
-               return gdk_region_point_in (region, x_offset / view->scale, y_offset / view->scale);
+               return cairo_region_contains_point (region, x_offset / view->scale, y_offset / view->scale);
        else
                return FALSE;
 }
@@ -1397,7 +1401,7 @@ location_in_selected_text (EvView  *view,
                        continue;
                
                if (selection->covered_region &&
-                   gdk_region_point_in (selection->covered_region, x_offset, y_offset))
+                   cairo_region_contains_point (selection->covered_region, x_offset, y_offset))
                        return TRUE;
        }
 
@@ -1462,11 +1466,11 @@ get_doc_point_from_location (EvView  *view,
 }
 
 static void
-ev_view_get_area_from_mapping (EvView       *view,
-                              guint         page,
-                              GList        *mapping_list,
-                              gconstpointer data,
-                              GdkRectangle *area)
+ev_view_get_area_from_mapping (EvView        *view,
+                              guint          page,
+                              EvMappingList *mapping_list,
+                              gconstpointer  data,
+                              GdkRectangle  *area)
 {
        EvMapping *mapping;
 
@@ -1485,7 +1489,7 @@ ev_view_get_link_at_location (EvView  *view,
 {
        gint page = -1;
        gint x_new = 0, y_new = 0;
-       GList *link_mapping;
+       EvMappingList *link_mapping;
 
        if (!EV_IS_DOCUMENT_LINKS (view->document))
                return NULL;
@@ -1829,6 +1833,12 @@ ev_view_handle_cursor_over_xy (EvView *view, gint x, gint y)
        if (view->cursor == EV_VIEW_CURSOR_HIDDEN)
                return;
 
+       if (view->adding_annot) {
+               if (view->cursor != EV_VIEW_CURSOR_ADD)
+                       ev_view_set_cursor (view, EV_VIEW_CURSOR_ADD);
+               return;
+       }
+
        if (view->drag_info.in_drag) {
                if (view->cursor != EV_VIEW_CURSOR_DRAG)
                        ev_view_set_cursor (view, EV_VIEW_CURSOR_DRAG);
@@ -1863,7 +1873,8 @@ ev_view_handle_cursor_over_xy (EvView *view, gint x, gint y)
                if (view->cursor == EV_VIEW_CURSOR_LINK ||
                    view->cursor == EV_VIEW_CURSOR_IBEAM ||
                    view->cursor == EV_VIEW_CURSOR_DRAG ||
-                   view->cursor == EV_VIEW_CURSOR_AUTOSCROLL)
+                   view->cursor == EV_VIEW_CURSOR_AUTOSCROLL ||
+                   view->cursor == EV_VIEW_CURSOR_ADD)
                        ev_view_set_cursor (view, EV_VIEW_CURSOR_NORMAL);
        }
 
@@ -1879,7 +1890,7 @@ ev_view_get_image_at_location (EvView  *view,
 {
        gint page = -1;
        gint x_new = 0, y_new = 0;
-       GList *image_mapping;
+       EvMappingList *image_mapping;
 
        if (!EV_IS_DOCUMENT_IMAGES (view->document))
                return NULL;
@@ -1903,7 +1914,7 @@ ev_view_get_form_field_at_location (EvView  *view,
 {
        gint page = -1;
        gint x_new = 0, y_new = 0;
-       GList *forms_mapping;
+       EvMappingList *forms_mapping;
        
        if (!EV_IS_DOCUMENT_FORMS (view->document))
                return NULL;
@@ -1919,12 +1930,12 @@ ev_view_get_form_field_at_location (EvView  *view,
                return NULL;
 }
 
-static GdkRegion *
+static cairo_region_t *
 ev_view_form_field_get_region (EvView      *view,
                               EvFormField *field)
 {
-       GdkRectangle view_area;
-       GList       *forms_mapping;
+       GdkRectangle   view_area;
+       EvMappingList *forms_mapping;
 
        forms_mapping = ev_page_cache_get_form_field_mapping (view->page_cache,
                                                              field->page->index);
@@ -1932,7 +1943,7 @@ ev_view_form_field_get_region (EvView      *view,
                                       forms_mapping,
                                       field, &view_area);
 
-       return gdk_region_rectangle (&view_area);
+       return cairo_region_create_rectangle (&view_area);
 }
 
 static gboolean
@@ -1955,15 +1966,16 @@ ev_view_form_field_button_create_widget (EvView      *view,
                                         EvFormField *field)
 {
        EvFormFieldButton *field_button = EV_FORM_FIELD_BUTTON (field);
-       GdkRegion         *field_region = NULL;
+       cairo_region_t    *field_region = NULL;
        
        switch (field_button->type) {
                case EV_FORM_FIELD_BUTTON_PUSH:
                        return NULL;
                case EV_FORM_FIELD_BUTTON_CHECK:
                case EV_FORM_FIELD_BUTTON_RADIO: {
-                       gboolean  state;
-                       GList    *forms_mapping, *l;
+                       gboolean       state;
+                       EvMappingList *forms_mapping;
+                       GList         *l;
 
                        state = ev_document_forms_form_field_button_get_state (EV_DOCUMENT_FORMS (view->document),
                                                                               field);
@@ -1980,9 +1992,9 @@ ev_view_form_field_button_create_widget (EvView      *view,
                         */
                        forms_mapping = ev_page_cache_get_form_field_mapping (view->page_cache,
                                                                              field->page->index);
-                       for (l = forms_mapping; l; l = g_list_next (l)) {
+                       for (l = ev_mapping_list_get_list (forms_mapping); l; l = g_list_next (l)) {
                                EvFormField *button = ((EvMapping *)(l->data))->data;
-                               GdkRegion   *button_region;
+                               cairo_region_t *button_region;
 
                                if (button->id == field->id)
                                        continue;
@@ -1994,8 +2006,8 @@ ev_view_form_field_button_create_widget (EvView      *view,
                                        continue;
 
                                button_region = ev_view_form_field_get_region (view, button);
-                               gdk_region_union (field_region, button_region);
-                               gdk_region_destroy (button_region);
+                               cairo_region_union (field_region, button_region);
+                               cairo_region_destroy (button_region);
                        }
                        
                        ev_document_forms_form_field_button_set_state (EV_DOCUMENT_FORMS (view->document),
@@ -2006,7 +2018,7 @@ ev_view_form_field_button_create_widget (EvView      *view,
        }
 
        ev_view_reload_page (view, field->page->index, field_region);
-       gdk_region_destroy (field_region);
+       cairo_region_destroy (field_region);
        
        return NULL;
 }
@@ -2024,7 +2036,7 @@ ev_view_form_field_text_save (EvView    *view,
        
        if (field->changed) {
                EvFormFieldText *field_text = EV_FORM_FIELD_TEXT (field);
-               GdkRegion       *field_region;
+               cairo_region_t  *field_region;
 
                field_region = ev_view_form_field_get_region (view, field);
                
@@ -2032,7 +2044,7 @@ ev_view_form_field_text_save (EvView    *view,
                                                            field, field_text->text);
                field->changed = FALSE;
                ev_view_reload_page (view, field->page->index, field_region);
-               gdk_region_destroy (field_region);
+               cairo_region_destroy (field_region);
        }
 }
 
@@ -2132,7 +2144,7 @@ ev_view_form_field_choice_save (EvView    *view,
        if (field->changed) {
                GList             *l;
                EvFormFieldChoice *field_choice = EV_FORM_FIELD_CHOICE (field);
-               GdkRegion         *field_region;
+               cairo_region_t    *field_region;
 
                field_region = ev_view_form_field_get_region (view, field);
 
@@ -2149,7 +2161,7 @@ ev_view_form_field_choice_save (EvView    *view,
                }
                field->changed = FALSE;
                ev_view_reload_page (view, field->page->index, field_region);
-               gdk_region_destroy (field_region);
+               cairo_region_destroy (field_region);
        }
 }
 
@@ -2338,9 +2350,9 @@ ev_view_handle_form_field (EvView      *view,
                           gdouble      x,
                           gdouble      y)
 {
-       GtkWidget   *field_widget = NULL;
-       GList       *form_field_mapping;
-       GdkRectangle view_area;
+       GtkWidget     *field_widget = NULL;
+       EvMappingList *form_field_mapping;
+       GdkRectangle   view_area;
 
        if (field->is_read_only)
                return;
@@ -2400,11 +2412,19 @@ ev_view_window_child_move (EvView            *view,
                           gint               x,
                           gint               y)
 {
+       GtkAllocation allocation;
+       gint          width, height;
+
+       gtk_widget_get_allocation (GTK_WIDGET (view), &allocation);
+       gtk_window_get_size (GTK_WINDOW (child->window), &width, &height);
+
        child->x = x;
        child->y = y;
        gtk_window_move (GTK_WINDOW (child->window),
-                        MAX (child->parent_x, x),
-                        MAX (child->parent_y, y));
+                        CLAMP (x, child->parent_x,
+                               child->parent_x + allocation.width - width),
+                        CLAMP (y, child->parent_y,
+                               child->parent_y + allocation.height - height));
 }
 
 static void
@@ -2482,7 +2502,7 @@ ev_view_find_window_child_for_annot (EvView       *view,
                        continue;
 
                wannot = ev_annotation_window_get_annotation (EV_ANNOTATION_WINDOW (child->window));
-               if (wannot == annot || strcmp (wannot->name, annot->name) == 0)
+               if (ev_annotation_equal (wannot, annot))
                        return child;
        }
 
@@ -2565,37 +2585,73 @@ annotation_window_moved (EvAnnotationWindow *window,
 }
 
 static void
-ev_view_annotation_save (EvView       *view,
-                        EvAnnotation *annot)
+ev_view_annotation_save_contents (EvView       *view,
+                                 GParamSpec   *pspec,
+                                 EvAnnotation *annot)
 {
        if (!view->document)
                return;
 
-       if (!annot->changed)
-               return;
+       ev_document_doc_mutex_lock ();
+       ev_document_annotations_save_annotation (EV_DOCUMENT_ANNOTATIONS (view->document),
+                                                annot, EV_ANNOTATIONS_SAVE_CONTENTS);
+       ev_document_doc_mutex_unlock ();
+}
 
-       ev_document_annotations_annotation_set_contents (EV_DOCUMENT_ANNOTATIONS (view->document),
-                                                        annot, annot->contents);
-       annot->changed = FALSE;
+static GtkWidget *
+ev_view_create_annotation_window (EvView       *view,
+                                 EvAnnotation *annot,
+                                 GtkWindow    *parent)
+{
+       GtkWidget   *window;
+       EvRectangle  doc_rect;
+       GdkRectangle view_rect;
+       guint        page;
+
+       window = ev_annotation_window_new (annot, parent);
+       g_signal_connect (window, "grab_focus",
+                         G_CALLBACK (annotation_window_grab_focus),
+                         view);
+       g_signal_connect (window, "closed",
+                         G_CALLBACK (annotation_window_closed),
+                         view);
+       g_signal_connect (window, "moved",
+                         G_CALLBACK (annotation_window_moved),
+                         view);
+       g_signal_connect_swapped (annot, "notify::contents",
+                                 G_CALLBACK (ev_view_annotation_save_contents),
+                                 view);
+       g_object_set_data (G_OBJECT (annot), "popup", window);
+
+       page = ev_annotation_get_page_index (annot);
+       ev_annotation_window_get_rectangle (EV_ANNOTATION_WINDOW (window), &doc_rect);
+       doc_rect_to_view_rect (view, page, &doc_rect, &view_rect);
+       view_rect.x -= view->scroll_x;
+       view_rect.y -= view->scroll_y;
+
+       ev_view_window_child_put (view, window, page,
+                                 view_rect.x, view_rect.y,
+                                 doc_rect.x1, doc_rect.y1);
+
+       return window;
 }
 
 static void
 show_annotation_windows (EvView *view,
                         gint    page)
 {
-       GList     *annots, *l;
-       GtkWindow *parent;
+       EvMappingList *annots;
+       GList         *l;
+       GtkWindow     *parent;
 
        parent = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (view)));
 
        annots = ev_page_cache_get_annot_mapping (view->page_cache, page);
 
-       for (l = annots; l && l->data; l = g_list_next (l)) {
+       for (l = ev_mapping_list_get_list (annots); l && l->data; l = g_list_next (l)) {
                EvAnnotation      *annot;
                EvViewWindowChild *child;
                GtkWidget         *window;
-               EvRectangle       *doc_rect;
-               GdkRectangle       view_rect;
 
                annot = ((EvMapping *)(l->data))->data;
 
@@ -2619,30 +2675,7 @@ show_annotation_windows (EvView *view,
                        g_object_set_data (G_OBJECT (annot), "popup", window);
                        ev_view_window_child_move_with_parent (view, window);
                } else {
-                       window = ev_annotation_window_new (annot, parent);
-                       g_signal_connect (window, "grab_focus",
-                                         G_CALLBACK (annotation_window_grab_focus),
-                                         view);
-                       g_signal_connect (window, "closed",
-                                         G_CALLBACK (annotation_window_closed),
-                                         view);
-                       g_signal_connect (window, "moved",
-                                         G_CALLBACK (annotation_window_moved),
-                                         view);
-                       g_object_set_data (G_OBJECT (annot), "popup", window);
-
-                       doc_rect = (EvRectangle *)ev_annotation_window_get_rectangle (EV_ANNOTATION_WINDOW (window));
-                       doc_rect_to_view_rect (view, page, doc_rect, &view_rect);
-                       view_rect.x -= view->scroll_x;
-                       view_rect.y -= view->scroll_y;
-
-                       ev_view_window_child_put (view, window, page,
-                                                 view_rect.x, view_rect.y,
-                                                 doc_rect->x1, doc_rect->y1);
-
-                       g_object_weak_ref (G_OBJECT (annot),
-                                          (GWeakNotify)ev_view_annotation_save,
-                                          view);
+                       ev_view_create_annotation_window (view, annot, parent);
                }
        }
 }
@@ -2651,11 +2684,12 @@ static void
 hide_annotation_windows (EvView *view,
                         gint    page)
 {
-       GList *annots, *l;
+       EvMappingList *annots;
+       GList         *l;
 
        annots = ev_page_cache_get_annot_mapping (view->page_cache, page);
 
-       for (l = annots; l && l->data; l = g_list_next (l)) {
+       for (l = ev_mapping_list_get_list (annots); l && l->data; l = g_list_next (l)) {
                EvAnnotation *annot;
                GtkWidget    *window;
 
@@ -2677,7 +2711,7 @@ ev_view_get_annotation_at_location (EvView  *view,
 {
        gint page = -1;
        gint x_new = 0, y_new = 0;
-       GList *annotations_mapping;
+       EvMappingList *annotations_mapping;
 
        if (!EV_IS_DOCUMENT_ANNOTATIONS (view->document))
                return NULL;
@@ -2693,6 +2727,23 @@ ev_view_get_annotation_at_location (EvView  *view,
                return NULL;
 }
 
+static void
+ev_view_annotation_show_popup_window (EvView    *view,
+                                     GtkWidget *window)
+{
+       EvViewWindowChild *child;
+
+       if (!window)
+               return;
+
+       child = ev_view_get_window_child (view, window);
+       if (!child->visible) {
+               child->visible = TRUE;
+               ev_view_window_child_move (view, child, child->x, child->y);
+               gtk_widget_show (window);
+       }
+}
+
 static void
 ev_view_handle_annotation (EvView       *view,
                           EvAnnotation *annot,
@@ -2704,21 +2755,13 @@ ev_view_handle_annotation (EvView       *view,
                GtkWidget *window;
 
                window = g_object_get_data (G_OBJECT (annot), "popup");
-               if (window) {
-                       EvViewWindowChild *child;
-
-                       child = ev_view_get_window_child (view, window);
-                       if (!child->visible) {
-                               child->visible = TRUE;
-                               ev_view_window_child_move (view, child, child->x, child->y);
-                               gtk_widget_show (window);
-                       }
-               }
+               ev_view_annotation_show_popup_window (view, window);
        }
 
        if (EV_IS_ANNOTATION_ATTACHMENT (annot)) {
-               EvAttachment *attachment = EV_ANNOTATION_ATTACHMENT (annot)->attachment;
+               EvAttachment *attachment;
 
+               attachment = ev_annotation_attachment_get_attachment (EV_ANNOTATION_ATTACHMENT (annot));
                if (attachment) {
                        GError *error = NULL;
 
@@ -2735,6 +2778,170 @@ ev_view_handle_annotation (EvView       *view,
        }
 }
 
+static void
+ev_view_create_annotation (EvView          *view,
+                          EvAnnotationType annot_type,
+                          gint             x,
+                          gint             y)
+{
+       EvAnnotation   *annot;
+       GdkPoint        point;
+       GdkRectangle    page_area;
+       GtkBorder       border;
+       EvRectangle     doc_rect, popup_rect;
+       EvPage         *page;
+       GdkColor        color = { 0, 65535, 65535, 0 };
+       GdkRectangle    view_rect;
+       cairo_region_t *region;
+
+       point.x = x;
+       point.y = y;
+       ev_view_get_page_extents (view, view->current_page, &page_area, &border);
+       view_point_to_doc_point (view, &point, &page_area,
+                                &doc_rect.x1, &doc_rect.y1);
+       doc_rect.x2 = doc_rect.x1 + 24;
+       doc_rect.y2 = doc_rect.y1 + 24;
+
+       ev_document_doc_mutex_lock ();
+       page = ev_document_get_page (view->document, view->current_page);
+       switch (annot_type) {
+       case EV_ANNOTATION_TYPE_TEXT:
+               annot = ev_annotation_text_new (page);
+               break;
+       case EV_ANNOTATION_TYPE_ATTACHMENT:
+               /* TODO */
+               g_object_unref (page);
+               ev_document_doc_mutex_unlock ();
+               return;
+       default:
+               g_assert_not_reached ();
+       }
+       g_object_unref (page);
+
+       ev_annotation_set_color (annot, &color);
+
+       if (EV_IS_ANNOTATION_MARKUP (annot)) {
+               popup_rect.x1 = doc_rect.x2;
+               popup_rect.x2 = popup_rect.x1 + 200;
+               popup_rect.y1 = doc_rect.y2;
+               popup_rect.y2 = popup_rect.y1 + 150;
+               g_object_set (annot,
+                             "rectangle", &popup_rect,
+                             "has_popup", TRUE,
+                             "popup_is_open", FALSE,
+                             "label", g_get_real_name (),
+                             "opacity", 1.0,
+                             NULL);
+       }
+       ev_document_annotations_add_annotation (EV_DOCUMENT_ANNOTATIONS (view->document),
+                                               annot, &doc_rect);
+       ev_document_doc_mutex_unlock ();
+
+       /* If the page didn't have annots, mark the cache as dirty */
+       if (!ev_page_cache_get_annot_mapping (view->page_cache, view->current_page))
+               ev_page_cache_mark_dirty (view->page_cache, view->current_page);
+
+       if (EV_IS_ANNOTATION_MARKUP (annot)) {
+               GtkWindow *parent;
+               GtkWidget *window;
+
+               parent = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (view)));
+               window = ev_view_create_annotation_window (view, annot, parent);
+
+               /* Show the annot window the first time */
+               ev_view_annotation_show_popup_window (view, window);
+       }
+
+       doc_rect_to_view_rect (view, view->current_page, &doc_rect, &view_rect);
+       view_rect.x -= view->scroll_x;
+       view_rect.y -= view->scroll_y;
+       region = cairo_region_create_rectangle (&view_rect);
+       ev_view_reload_page (view, view->current_page, region);
+       cairo_region_destroy (region);
+
+       g_signal_emit (view, signals[SIGNAL_ANNOT_ADDED], 0, annot);
+}
+
+void
+ev_view_focus_annotation (EvView    *view,
+                         EvMapping *annot_mapping)
+{
+       GdkRectangle  view_rect;
+       EvAnnotation *annot;
+       guint         page;
+
+       if (!EV_IS_DOCUMENT_ANNOTATIONS (view->document))
+               return;
+
+       if (view->focus_annotation == annot_mapping)
+               return;
+
+       view->focus_annotation = annot_mapping;
+       annot = (EvAnnotation *)annot_mapping->data;
+
+       page = ev_annotation_get_page_index (annot);
+       ev_document_model_set_page (view->model, page);
+
+       doc_rect_to_view_rect (view, page,
+                              &annot_mapping->area, &view_rect);
+       ensure_rectangle_is_visible (view, &view_rect);
+       gtk_widget_queue_draw (GTK_WIDGET (view));
+}
+
+void
+ev_view_begin_add_annotation (EvView          *view,
+                             EvAnnotationType annot_type)
+{
+       if (annot_type == EV_ANNOTATION_TYPE_UNKNOWN)
+               return;
+
+       if (view->adding_annot)
+               return;
+
+       view->adding_annot = TRUE;
+       view->adding_annot_type = annot_type;
+       ev_view_set_cursor (view, EV_VIEW_CURSOR_ADD);
+}
+
+void
+ev_view_cancel_add_annotation (EvView *view)
+{
+       gint x, y;
+
+       if (!view->adding_annot)
+               return;
+
+       view->adding_annot = FALSE;
+       gtk_widget_get_pointer (GTK_WIDGET (view), &x, &y);
+       ev_view_handle_cursor_over_xy (view, x, y);
+}
+
+static gboolean
+ev_view_synctex_backward_search (EvView *view,
+                                gdouble x,
+                                gdouble y)
+{
+       gint page = -1;
+       gint x_new = 0, y_new = 0;
+       EvSourceLink *link;
+
+       if (!ev_document_has_synctex (view->document))
+               return FALSE;
+
+       if (!get_doc_point_from_location (view, x, y, &page, &x_new, &y_new))
+               return FALSE;
+
+       link = ev_document_synctex_backward_search (view->document, page, x_new, y_new);
+       if (link) {
+               g_signal_emit (view, signals[SIGNAL_SYNC_SOURCE], 0, link);
+               g_free (link);
+
+               return TRUE;
+       }
+
+       return FALSE;
+}
+
 /*** GtkWidget implementation ***/
 
 static void
@@ -2933,7 +3140,7 @@ ev_view_size_allocate (GtkWidget      *widget,
        for (l = children; l && l->data; l = g_list_next (l)) {
                EvFormField   *field;
                GdkRectangle   view_area;
-               GList         *form_field_mapping;
+               EvMappingList *form_field_mapping;
                GtkAllocation  child_allocation;
                GtkRequisition child_requisition;
                GtkWidget     *child = (GtkWidget *)l->data;
@@ -2976,7 +3183,7 @@ ev_view_size_allocate (GtkWidget      *widget,
 
                child = (EvViewWindowChild *)l->data;
 
-               doc_rect = *ev_annotation_window_get_rectangle (EV_ANNOTATION_WINDOW (child->window));
+               ev_annotation_window_get_rectangle (EV_ANNOTATION_WINDOW (child->window), &doc_rect);
                if (child->moved) {
                        doc_rect.x1 = child->orig_x;
                        doc_rect.y1 = child->orig_y;
@@ -3138,6 +3345,10 @@ ev_view_expose_event (GtkWidget      *widget,
                        highlight_find_results (view, i);
                if (page_ready && EV_IS_DOCUMENT_ANNOTATIONS (view->document))
                        show_annotation_windows (view, i);
+               if (page_ready && view->focus_annotation)
+                       focus_annotation (view, i, &event->area);
+               if (page_ready && view->synctex_result)
+                       highlight_forward_search_results (view, i);
        }
 
        cairo_destroy (cr);
@@ -3193,9 +3404,9 @@ get_link_area (EvView       *view,
               EvLink       *link,
               GdkRectangle *area)
 {
-       GList *link_mapping;
-       gint   page;
-       gint   x_offset = 0, y_offset = 0;
+       EvMappingList *link_mapping;
+       gint           page;
+       gint           x_offset = 0, y_offset = 0;
 
        x += view->scroll_x;
        y += view->scroll_y;
@@ -3215,9 +3426,9 @@ get_annot_area (EvView       *view,
               EvAnnotation *annot,
               GdkRectangle *area)
 {
-       GList *annot_mapping;
-       gint   page;
-       gint   x_offset = 0, y_offset = 0;
+       EvMappingList *annot_mapping;
+       gint           page;
+       gint           x_offset = 0, y_offset = 0;
 
        x += view->scroll_x;
        y += view->scroll_y;
@@ -3243,14 +3454,18 @@ ev_view_query_tooltip (GtkWidget  *widget,
        gchar        *text;
 
        annot = ev_view_get_annotation_at_location (view, x, y);
-       if (annot && annot->contents) {
-               GdkRectangle annot_area;
+       if (annot) {
+               const gchar *contents;
 
-               get_annot_area (view, x, y, annot, &annot_area);
-               gtk_tooltip_set_text (tooltip, annot->contents);
-               gtk_tooltip_set_tip_area (tooltip, &annot_area);
+               if ((contents = ev_annotation_get_contents (annot))) {
+                       GdkRectangle annot_area;
 
-               return TRUE;
+                       get_annot_area (view, x, y, annot, &annot_area);
+                       gtk_tooltip_set_text (tooltip, contents);
+                       gtk_tooltip_set_tip_area (tooltip, &annot_area);
+
+                       return TRUE;
+               }
        }
 
        link = ev_view_get_link_at_location (view, x, y);
@@ -3318,13 +3533,15 @@ ev_view_button_press_event (GtkWidget      *widget,
                window = EV_ANNOTATION_WINDOW (view->window_child_focus->window);
                annot = ev_annotation_window_get_annotation (window);
                ev_annotation_window_ungrab_focus (window);
-               ev_view_annotation_save (view, annot);
                view->window_child_focus = NULL;
        }
        
        view->pressed_button = event->button;
        view->selection_info.in_drag = FALSE;
 
+       if (view->adding_annot)
+               return FALSE;
+
        if (view->scroll_info.autoscrolling)
                return TRUE;
        
@@ -3334,6 +3551,9 @@ ev_view_button_press_event (GtkWidget      *widget,
                        EvAnnotation *annot;
                        EvFormField *field;
 
+                       if (event->state & GDK_CONTROL_MASK)
+                               return ev_view_synctex_backward_search (view, event->x , event->y);
+
                        if (EV_IS_SELECTION (view->document) && view->selection_info.selections) {
                                if (event->type == GDK_3BUTTON_PRESS) {
                                        start_selection_for_event (view, event);
@@ -3362,7 +3582,16 @@ ev_view_button_press_event (GtkWidget      *widget,
                                view->image_dnd_info.start.y = event->y + view->scroll_y;
                        } else {
                                ev_view_remove_all (view);
-                               
+
+                               if (view->synctex_result) {
+                                       g_free (view->synctex_result);
+                                       view->synctex_result = NULL;
+                                       gtk_widget_queue_draw (widget);
+                               }
+
+                               if (view->focus_annotation)
+                                       view->focus_annotation = NULL;
+
                                if (EV_IS_SELECTION (view->document))
                                        start_selection_for_event (view, event);
                        }
@@ -3767,7 +3996,12 @@ ev_view_button_release_event (GtkWidget      *widget,
                view->pressed_button = -1;
 
                return TRUE;
-       } 
+       }
+
+       if (view->pressed_button == 1 && event->state & GDK_CONTROL_MASK) {
+               view->pressed_button = -1;
+               return TRUE;
+       }
 
        if (view->drag_info.in_drag) {
                view->drag_info.release_timeout_id =
@@ -3781,6 +4015,19 @@ ev_view_button_release_event (GtkWidget      *widget,
 
        view->drag_info.in_drag = FALSE;
 
+       if (view->adding_annot && view->pressed_button == 1) {
+               view->adding_annot = FALSE;
+               ev_view_handle_cursor_over_xy (view, event->x, event->y);
+               view->pressed_button = -1;
+
+               ev_view_create_annotation (view,
+                                          view->adding_annot_type,
+                                          event->x + view->scroll_x,
+                                          event->y + view->scroll_y);
+
+               return FALSE;
+       }
+
        if (view->pressed_button == 2) {
                ev_view_handle_cursor_over_xy (view, event->x, event->y);
        }
@@ -3980,6 +4227,53 @@ highlight_find_results (EvView *view, int page)
         }
 }
 
+static void
+highlight_forward_search_results (EvView *view, int page)
+{
+       GdkWindow   *bin_window;
+       GdkRectangle rect;
+       cairo_t     *cr;
+       EvMapping   *mapping = view->synctex_result;
+
+       if (GPOINTER_TO_INT (mapping->data) != page)
+               return;
+
+       bin_window = gtk_layout_get_bin_window (GTK_LAYOUT (view));
+       doc_rect_to_view_rect (view, page, &mapping->area, &rect);
+
+       cr = gdk_cairo_create (bin_window);
+       cairo_set_source_rgb (cr, 1., 0., 0.);
+       cairo_rectangle (cr,
+                        rect.x - view->scroll_x,
+                        rect.y - view->scroll_y,
+                        rect.width, rect.height);
+       cairo_stroke (cr);
+       cairo_destroy (cr);
+}
+
+static void
+focus_annotation (EvView       *view,
+                 gint          page,
+                 GdkRectangle *clip)
+{
+       GtkWidget    *widget = GTK_WIDGET (view);
+       GdkRectangle  rect;
+       EvMapping    *mapping = view->focus_annotation;
+       EvAnnotation *annot = (EvAnnotation *)mapping->data;
+
+       if (ev_annotation_get_page_index (annot) != page)
+               return;
+
+       doc_rect_to_view_rect (view, page, &mapping->area, &rect);
+       gtk_paint_focus (gtk_widget_get_style (widget),
+                        gtk_layout_get_bin_window (GTK_LAYOUT (view)),
+                        gtk_widget_get_state (widget),
+                        NULL, widget, NULL,
+                        rect.x - view->scroll_x,
+                        rect.y - view->scroll_y,
+                        rect.width + 1, rect.height + 1);
+}
+
 static void
 ev_view_loading_window_move (EvView *view)
 {
@@ -4064,7 +4358,6 @@ draw_one_page (EvView       *view,
               GdkRectangle *expose_area,
               gboolean     *page_ready)
 {
-       GdkWindow   *bin_window;
        GdkRectangle overlap;
        GdkRectangle real_page_area;
        gint         current_page;
@@ -4084,10 +4377,9 @@ draw_one_page (EvView       *view,
        real_page_area.height -= (border->top + border->bottom);
        *page_ready = TRUE;
 
-       bin_window = gtk_layout_get_bin_window (GTK_LAYOUT (view));
        current_page = ev_document_model_get_page (view->model);
        inverted_colors = ev_document_model_get_inverted_colors (view->model);
-       ev_document_misc_paint_one_page (bin_window,
+       ev_document_misc_paint_one_page (cr,
                                         GTK_WIDGET (view),
                                         page_area, border,
                                         page == current_page,
@@ -4168,6 +4460,7 @@ draw_one_page (EvView       *view,
                cairo_surface_set_device_offset (selection_surface,
                                                 overlap.x - real_page_area.x,
                                                 overlap.y - real_page_area.y);
+
                cairo_set_source_surface (cr, selection_surface, 0, 0);
                cairo_paint (cr);
                cairo_restore (cr);
@@ -4184,6 +4477,11 @@ ev_view_finalize (GObject *object)
        clear_selection (view);
        clear_link_selected (view);
 
+       if (view->synctex_result) {
+               g_free (view->synctex_result);
+               view->synctex_result = NULL;
+       }
+
        if (view->image_dnd_info.image)
                g_object_unref (view->image_dnd_info.image);
        view->image_dnd_info.image = NULL;
@@ -4275,10 +4573,12 @@ ev_view_get_accessible (GtkWidget *widget)
                factory = atk_registry_get_factory (registry,
                                                    derived_type);
                derived_atk_type = atk_object_factory_get_accessible_type (factory);
-               if (g_type_is_a (derived_atk_type, GTK_TYPE_ACCESSIBLE)) 
-                       atk_registry_set_factory_type (registry, 
+               if (g_type_is_a (derived_atk_type, GTK_TYPE_ACCESSIBLE)) {
+                       atk_registry_set_factory_type (registry,
                                                       EV_TYPE_VIEW,
                                                       ev_view_accessible_factory_get_type ());
+                       EV_VIEW (widget)->a11y_enabled = TRUE;
+               }
                first_time = FALSE;
        } 
        return GTK_WIDGET_CLASS (ev_view_parent_class)->get_accessible (widget);
@@ -4362,6 +4662,22 @@ ev_view_class_init (EvViewClass *class)
                         g_cclosure_marshal_VOID__VOID,
                          G_TYPE_NONE, 0,
                          G_TYPE_NONE);
+       signals[SIGNAL_SYNC_SOURCE] = g_signal_new ("sync-source",
+                        G_TYPE_FROM_CLASS (object_class),
+                        G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+                        G_STRUCT_OFFSET (EvViewClass, sync_source),
+                        NULL, NULL,
+                        g_cclosure_marshal_VOID__POINTER,
+                        G_TYPE_NONE, 1,
+                        G_TYPE_POINTER);
+       signals[SIGNAL_ANNOT_ADDED] = g_signal_new ("annot-added",
+                        G_TYPE_FROM_CLASS (object_class),
+                        G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+                        G_STRUCT_OFFSET (EvViewClass, annot_added),
+                        NULL, NULL,
+                        g_cclosure_marshal_VOID__OBJECT,
+                        G_TYPE_NONE, 1,
+                        EV_TYPE_ANNOTATION);
 
        binding_set = gtk_binding_set_by_class (class);
 
@@ -4434,15 +4750,32 @@ ev_view_change_page (EvView *view,
 }
 
 static void
-job_finished_cb (EvPixbufCache *pixbuf_cache,
-                GdkRegion     *region,
-                EvView        *view)
+job_finished_cb (EvPixbufCache  *pixbuf_cache,
+                cairo_region_t *region,
+                EvView         *view)
 {
        if (region) {
                GdkWindow *bin_window;
 
                bin_window = gtk_layout_get_bin_window (GTK_LAYOUT (view));
+#if GTK_CHECK_VERSION(2, 90, 5)
                gdk_window_invalidate_region (bin_window, region, TRUE);
+#else
+       {
+               GdkRegion *gdk_region = gdk_region_new ();
+               guint      n_recs = cairo_region_num_rectangles (region);
+               guint      i;
+
+               for (i = 0; i < n_recs; i++) {
+                       cairo_rectangle_int_t rect;
+
+                       cairo_region_get_rectangle (region, i, &rect);
+                       gdk_region_union_with_rect (gdk_region, (GdkRectangle *)&rect);
+               }
+               gdk_window_invalidate_region (bin_window, gdk_region, TRUE);
+               gdk_region_destroy (gdk_region);
+       }
+#endif
        } else {
                gtk_widget_queue_draw (GTK_WIDGET (view));
        }
@@ -4550,6 +4883,14 @@ setup_caches (EvView *view)
        view->height_to_page_cache = ev_view_get_height_to_page_cache (view);
        view->pixbuf_cache = ev_pixbuf_cache_new (GTK_WIDGET (view), view->model, view->pixbuf_cache_size);
        view->page_cache = ev_page_cache_new (view->document);
+       if (view->a11y_enabled) {
+               EvJobPageDataFlags flags = ev_page_cache_get_flags (view->page_cache);
+
+               ev_page_cache_set_flags (view->page_cache,
+                                        flags |
+                                        EV_PAGE_DATA_INCLUDE_TEXT_LAYOUT |
+                                        EV_PAGE_DATA_INCLUDE_TEXT);
+       }
        inverted_colors = ev_document_model_get_inverted_colors (view->model);
        ev_pixbuf_cache_set_inverted_colors (view->pixbuf_cache, inverted_colors);
        g_signal_connect (view->pixbuf_cache, "job-finished", G_CALLBACK (job_finished_cb), view);
@@ -4878,9 +5219,9 @@ ev_view_set_model (EvView          *view,
 }
 
 static void
-ev_view_reload_page (EvView    *view,
-                    gint       page,
-                    GdkRegion *region)
+ev_view_reload_page (EvView         *view,
+                    gint            page,
+                    cairo_region_t *region)
 {
        ev_pixbuf_cache_reload_page (view->pixbuf_cache,
                                     region,
@@ -5274,6 +5615,34 @@ ev_view_find_cancel (EvView *view)
        view->find_pages = NULL;
 }
 
+/*** Synctex ***/
+void
+ev_view_highlight_forward_search (EvView       *view,
+                                 EvSourceLink *link)
+{
+       EvMapping   *mapping;
+       gint         page;
+       GdkRectangle view_rect;
+
+       if (!ev_document_has_synctex (view->document))
+               return;
+
+       mapping = ev_document_synctex_forward_search (view->document, link);
+       if (!mapping)
+               return;
+
+       if (view->synctex_result)
+               g_free (view->synctex_result);
+       view->synctex_result = mapping;
+
+       page = GPOINTER_TO_INT (mapping->data);
+       ev_document_model_set_page (view->model, page);
+
+       doc_rect_to_view_rect (view, page, &mapping->area, &view_rect);
+       ensure_rectangle_is_visible (view, &view_rect);
+       gtk_widget_queue_draw (GTK_WIDGET (view));
+}
+
 /*** Selections ***/
 
 /* compute_new_selection_rect/text calculates the area currently selected by
@@ -5445,7 +5814,7 @@ merge_selection_region (EvView *view,
        while (new_list_ptr || old_list_ptr) {
                EvViewSelection *old_sel, *new_sel;
                int cur_page;
-               GdkRegion *region = NULL;
+               cairo_region_t *region = NULL;
 
                new_sel = (new_list_ptr) ? (new_list_ptr->data) : NULL;
                old_sel = (old_list_ptr) ? (old_list_ptr->data) : NULL;
@@ -5480,15 +5849,15 @@ merge_selection_region (EvView *view,
                /* seed the cache with a new page.  We are going to need the new
                 * region too. */
                if (new_sel) {
-                       GdkRegion *tmp_region = NULL;
+                       cairo_region_t *tmp_region = NULL;
 
                        ev_pixbuf_cache_get_selection_surface (view->pixbuf_cache,
                                                               cur_page,
                                                               view->scale,
                                                               &tmp_region);
 
-                       if (tmp_region && !gdk_region_empty (tmp_region)) {
-                               new_sel->covered_region = gdk_region_copy (tmp_region);
+                       if (tmp_region && !cairo_region_is_empty (tmp_region)) {
+                               new_sel->covered_region = cairo_region_reference (tmp_region);
                        }
                }
 
@@ -5498,24 +5867,52 @@ merge_selection_region (EvView *view,
                                /* We only want to redraw the areas that have
                                 * changed, so we xor the old and new regions
                                 * and redraw if it's different */
-                               region = gdk_region_copy (old_sel->covered_region);
-                               gdk_region_xor (region, new_sel->covered_region);
-                               if (gdk_region_empty (region)) {
-                                       gdk_region_destroy (region);
+                               region = cairo_region_copy (old_sel->covered_region);
+#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 9, 12)
+                               cairo_region_xor (region, new_sel->covered_region);
+#else
+                               cairo_region_t *tbr;
+                               tbr = cairo_region_copy (new_sel->covered_region);
+
+                               /* xor old_sel, new_sel*/
+                               cairo_region_subtract (tbr, region);
+                               cairo_region_subtract (region, new_sel->covered_region);
+                               cairo_region_union (region, tbr);
+                               cairo_region_destroy (tbr);
+#endif
+
+                               if (cairo_region_is_empty (region)) {
+                                       cairo_region_destroy (region);
                                        region = NULL;
+                               } else {
+                                       gint num_rectangles = cairo_region_num_rectangles (region);
+                                       GdkRectangle r;
+
+                                       /* We need to make the damage region a little bigger
+                                        * because the edges of the old selection might change
+                                        */
+                                       cairo_region_get_rectangle (region, 0, &r);
+                                       r.x -= 5;
+                                       r.width = 5;
+                                       cairo_region_union_rectangle (region, &r);
+
+                                       cairo_region_get_rectangle (region, num_rectangles - 1, &r);
+                                       r.x += r.width;
+                                       r.width = 5;
+                                       cairo_region_union_rectangle (region, &r);
                                }
                        } else if (old_sel->covered_region) {
-                               region = gdk_region_copy (old_sel->covered_region);
+                               region = cairo_region_copy (old_sel->covered_region);
                        } else if (new_sel->covered_region) {
-                               region = gdk_region_copy (new_sel->covered_region);
+                               region = cairo_region_copy (new_sel->covered_region);
                        }
                } else if (old_sel && !new_sel) {
-                       if (old_sel->covered_region && !gdk_region_empty (old_sel->covered_region)) {
-                               region = gdk_region_copy (old_sel->covered_region);
+                       if (old_sel->covered_region && !cairo_region_is_empty (old_sel->covered_region)) {
+                               region = cairo_region_copy (old_sel->covered_region);
                        }
                } else if (!old_sel && new_sel) {
-                       if (new_sel->covered_region && !gdk_region_empty (new_sel->covered_region)) {
-                               region = gdk_region_copy (new_sel->covered_region);
+                       if (new_sel->covered_region && !cairo_region_is_empty (new_sel->covered_region)) {
+                               region = cairo_region_copy (new_sel->covered_region);
                        }
                } else {
                        g_assert_not_reached ();
@@ -5528,19 +5925,29 @@ merge_selection_region (EvView *view,
                        GtkBorder    border;
 
                        bin_window = gtk_layout_get_bin_window (GTK_LAYOUT (view));
-
-                       /* I don't know why but the region is smaller
-                        * than expected. This hack fixes it, I guess
-                        * 10 pixels more won't hurt
-                        */
-                       gdk_region_shrink (region, -5, -5);
-
                        ev_view_get_page_extents (view, cur_page, &page_area, &border);
-                       gdk_region_offset (region,
+                       cairo_region_translate (region,
                                           page_area.x + border.left - view->scroll_x,
                                           page_area.y + border.top - view->scroll_y);
+#if GTK_CHECK_VERSION(2, 90, 5)
                        gdk_window_invalidate_region (bin_window, region, TRUE);
-                       gdk_region_destroy (region);
+#else
+               {
+                       GdkRegion *gdk_region = gdk_region_new ();
+                       guint      n_recs = cairo_region_num_rectangles (region);
+                       guint      i;
+
+                       for (i = 0; i < n_recs; i++) {
+                               cairo_rectangle_int_t rect;
+
+                               cairo_region_get_rectangle (region, i, &rect);
+                               gdk_region_union_with_rect (gdk_region, (GdkRectangle *)&rect);
+                       }
+                       gdk_window_invalidate_region (bin_window, gdk_region, TRUE);
+                       gdk_region_destroy (gdk_region);
+               }
+#endif
+                       cairo_region_destroy (region);
                }
        }
 
@@ -5570,7 +5977,7 @@ static void
 selection_free (EvViewSelection *selection)
 {
        if (selection->covered_region)
-               gdk_region_destroy (selection->covered_region);
+               cairo_region_destroy (selection->covered_region);
        g_free (selection);
 }