Commit 1c0d19bd authored by Marco Pesenti Gritti's avatar Marco Pesenti Gritti

merge evince-threads branch

parent 730f128d
2005-03-23 Marco Pesenti Gritti <marco@gnome.org>
* TODO:
* backend/Makefile.am:
* backend/ev-document-links.c:
(ev_document_links_has_document_links),
(ev_document_links_get_links_model):
* backend/ev-document-links.h:
* backend/ev-document.c: (ev_document_get_page_cache),
(ev_document_get_doc_mutex), (ev_document_load),
(ev_document_save), (ev_document_get_title),
(ev_document_get_n_pages), (ev_document_set_page),
(ev_document_get_page), (ev_document_set_target),
(ev_document_set_scale), (ev_document_set_page_offset),
(ev_document_get_page_size), (ev_document_get_text),
(ev_document_get_link), (ev_document_render),
(ev_document_render_pixbuf), (ev_document_scale_changed):
* backend/ev-document.h:
* backend/ev-job-queue.c: (remove_object_from_queue),
(notify_finished), (handle_job), (search_for_jobs_unlocked),
(no_jobs_available_unlocked), (ev_render_thread),
(ev_job_queue_init), (find_queue), (ev_job_queue_add_job),
(ev_job_queue_remove_job):
* backend/ev-job-queue.h:
* backend/ev-jobs.c: (ev_job_init), (ev_job_dispose),
(ev_job_class_init), (ev_job_links_init), (ev_job_links_dispose),
(ev_job_links_class_init), (ev_job_render_init),
(ev_job_render_dispose), (ev_job_render_class_init),
(ev_job_thumbnail_init), (ev_job_thumbnail_dispose),
(ev_job_thumbnail_class_init), (ev_job_finished),
(ev_job_links_new), (ev_job_links_run), (ev_job_render_new),
(ev_job_render_run), (ev_job_thumbnail_new),
(ev_job_thumbnail_run):
* backend/ev-jobs.h:
* backend/ev-link.c:
* backend/ev-link.h:
* backend/ev-page-cache.c: (ev_page_cache_init),
(ev_page_cache_class_init), (ev_page_cache_finalize),
(_ev_page_cache_new), (ev_page_cache_get_n_pages),
(ev_page_cache_get_current_page), (ev_page_cache_set_current_page),
(ev_page_cache_set_link), (ev_page_cache_get_title),
(ev_page_cache_get_size), (ev_page_cache_next_page),
(ev_page_cache_prev_page):
* backend/ev-page-cache.h:
* pdf/pdf-document.cc:
* ps/gsdefaults.c:
* ps/gsdefaults.h:
* ps/ps-document.c: (ps_document_init), (ps_document_class_init),
(push_pixbuf), (interpreter_failed), (ps_document_cleanup),
(ps_document_widget_event), (ps_document_finalize), (get_xdpi),
(get_ydpi), (setup_pixmap), (setup_page), (close_pipe),
(is_interpreter_ready), (output), (catchPipe), (input),
(start_interpreter), (check_filecompressed), (compute_dimensions),
(ps_document_enable_interpreter), (document_load),
(ps_document_next_page), (render_page), (ps_document_set_page),
(ps_document_set_scale), (render_pixbuf_idle),
(ps_document_render_pixbuf), (ps_document_document_iface_init):
* ps/ps-document.h:
* shell/Makefile.am:
* shell/ev-pixbuf-cache.c: (ev_pixbuf_cache_init),
(ev_pixbuf_cache_class_init), (ev_pixbuf_cache_finalize),
(dispose_cache_job_info), (ev_pixbuf_cache_dispose),
(ev_pixbuf_cache_new), (job_finished_cb),
(check_job_size_and_unref), (move_one_job),
(ev_pixbuf_cache_update_range), (find_job_cache),
(ev_pixbuf_cache_clear_job_sizes), (add_job_if_needed),
(ev_pixbuf_cache_add_jobs_if_needed),
(ev_pixbuf_cache_set_page_range), (ev_pixbuf_cache_get_pixbuf):
* shell/ev-pixbuf-cache.h:
* shell/ev-print-job.c: (ev_print_job_use_print_dialog_settings),
(idle_print_handler):
* shell/ev-sidebar-links.c: (ev_sidebar_links_destroy),
(selection_changed_cb), (create_loading_model),
(ev_sidebar_links_construct), (links_page_num_func),
(ev_sidebar_links_clear_document), (update_page_callback_foreach),
(update_page_callback), (job_finished_cb),
(ev_sidebar_links_set_document):
* shell/ev-sidebar-thumbnails.c:
(ev_sidebar_thumbnails_class_init), (adjustment_changed_cb),
(ev_sidebar_tree_selection_changed), (ev_sidebar_thumbnails_init),
(page_changed_cb), (thumbnail_job_completed_callback),
(ev_sidebar_thumbnails_set_document):
* shell/ev-sidebar-thumbnails.h:
* shell/ev-sidebar.c: (ev_sidebar_set_document):
* shell/ev-view.c: (ev_view_finalize), (ev_view_destroy),
(ev_view_get_offsets), (ev_view_size_request), (ev_view_realize),
(ev_view_unrealize), (highlight_find_results), (expose_bin_window),
(ev_view_select_all), (ev_view_copy), (ev_view_primary_get_cb),
(ev_view_create_invisible_cursor), (ev_view_motion_notify_event),
(ev_view_button_release_event), (ev_view_scroll_view),
(ev_view_class_init), (ev_view_init), (update_find_status_message),
(jump_to_find_result), (jump_to_find_page), (find_changed_cb),
(ev_view_new), (job_finished_cb), (page_changed_cb),
(ev_view_set_document), (go_to_link), (ev_view_zoom),
(size_to_zoom_factor), (ev_view_set_size), (ev_view_find_next),
(ev_view_find_previous):
* shell/ev-view.h:
* shell/ev-window.c: (update_action_sensitivity),
(ev_window_open_page), (update_window_title), (update_total_pages),
(page_changed_cb), (ev_window_setup_document),
(password_dialog_response), (ev_window_cmd_save_as),
(ev_window_print), (ev_window_cmd_go_previous_page),
(ev_window_cmd_go_next_page), (ev_window_cmd_go_first_page),
(ev_window_cmd_go_last_page), (ev_window_cmd_view_reload),
(find_bar_search_changed_cb), (goto_page_cb), (ev_window_init):
* shell/main.c: (main):
Merge evince-threads branch
2005-03-16 Žygimantas Beručka <uid0@akl.lt>
* configure.ac: Added "lt" to ALL_LINGUAS.
......
......@@ -12,17 +12,13 @@ Move to three page views:
Sidebar improvements for ps/pixbuf, or PDF files without a TOC. bug 164811
Improve look of combobox Thumbnails/Index bug 166683
Improve Printing Support: (libgnomeprintui?)
* Print Page Selection
* Print Page Selection bug 169099
* Print Page Layout bug 166564
Document Properties Dialog for document meta-data bug 164843
Provide Desktop icon Thumbnailer for Documents bug 163789
Make an object that handles the page count.
Move to having three sizing types:
......@@ -41,3 +37,5 @@ Encrypted PDF support
Improve Find system
Find Next/Previous don't go to other pages
Find Next/Previous doesn't focus the results
Improve look of combobox Thumbnails/Index bug 166683
Provide Desktop icon Thumbnailer for Documents bug 163789
......@@ -23,6 +23,12 @@ libevbackend_la_SOURCES= \
ev-document-security.h \
ev-document-find.c \
ev-document-find.h \
ev-job-queue.h \
ev-job-queue.c \
ev-jobs.h \
ev-jobs.c \
ev-page-cache.h \
ev-page-cache.c \
ev-ps-exporter.c \
ev-ps-exporter.h \
ev-document-misc.h \
......
......@@ -24,6 +24,7 @@
#include "config.h"
#include "ev-document-links.h"
#include "ev-job-queue.h"
GType
ev_document_links_get_type (void)
......@@ -51,51 +52,20 @@ gboolean
ev_document_links_has_document_links (EvDocumentLinks *document_links)
{
EvDocumentLinksIface *iface = EV_DOCUMENT_LINKS_GET_IFACE (document_links);
return iface->has_document_links (document_links);
}
EvDocumentLinksIter *
ev_document_links_begin_read (EvDocumentLinks *document_links)
{
EvDocumentLinksIface *iface = EV_DOCUMENT_LINKS_GET_IFACE (document_links);
return iface->begin_read (document_links);
}
gboolean retval;
EvLink *
ev_document_links_get_link (EvDocumentLinks *document_links,
EvDocumentLinksIter *iter)
{
EvDocumentLinksIface *iface = EV_DOCUMENT_LINKS_GET_IFACE (document_links);
retval = iface->has_document_links (document_links);
return iface->get_link (document_links, iter);
return retval;
}
EvDocumentLinksIter *
ev_document_links_get_child (EvDocumentLinks *document_links,
EvDocumentLinksIter *iter)
GtkTreeModel *
ev_document_links_get_links_model (EvDocumentLinks *document_links)
{
EvDocumentLinksIface *iface = EV_DOCUMENT_LINKS_GET_IFACE (document_links);
GtkTreeModel *retval;
return iface->get_child (document_links, iter);
}
gboolean
ev_document_links_next (EvDocumentLinks *document_links,
EvDocumentLinksIter *iter)
{
EvDocumentLinksIface *iface = EV_DOCUMENT_LINKS_GET_IFACE (document_links);
return iface->next (document_links, iter);
}
void
ev_document_links_free_iter (EvDocumentLinks *document_links,
EvDocumentLinksIter *iter)
{
EvDocumentLinksIface *iface = EV_DOCUMENT_LINKS_GET_IFACE (document_links);
retval = iface->get_links_model (document_links);
iface->free_iter (document_links, iter);
return retval;
}
......@@ -26,7 +26,7 @@
#include <glib-object.h>
#include <glib.h>
#include <gdk/gdk.h>
#include <gtk/gtk.h>
#include "ev-document.h"
#include "ev-link.h"
......@@ -43,37 +43,25 @@ G_BEGIN_DECLS
typedef struct _EvDocumentLinks EvDocumentLinks;
typedef struct _EvDocumentLinksIface EvDocumentLinksIface;
typedef struct _EvDocumentLinksIter EvDocumentLinksIter;
enum {
EV_DOCUMENT_LINKS_COLUMN_MARKUP,
EV_DOCUMENT_LINKS_COLUMN_LINK,
EV_DOCUMENT_LINKS_COLUMN_NUM_COLUMNS
};
struct _EvDocumentLinksIface
{
GTypeInterface base_iface;
/* Methods */
gboolean (* has_document_links) (EvDocumentLinks *document_links);
EvDocumentLinksIter *(* begin_read) (EvDocumentLinks *document_links);
EvLink *(* get_link) (EvDocumentLinks *document_links,
EvDocumentLinksIter *iter);
EvDocumentLinksIter *(* get_child) (EvDocumentLinks *document_links,
EvDocumentLinksIter *iter);
gboolean (* next) (EvDocumentLinks *document_links,
EvDocumentLinksIter *iter);
void (* free_iter) (EvDocumentLinks *document_links,
EvDocumentLinksIter *iter);
gboolean (* has_document_links) (EvDocumentLinks *document_links);
GtkTreeModel *(* get_links_model) (EvDocumentLinks *document_links);
};
GType ev_document_links_get_type (void);
gboolean ev_document_links_has_document_links (EvDocumentLinks *document_links);
EvDocumentLinksIter *ev_document_links_begin_read (EvDocumentLinks *document_links);
EvLink *ev_document_links_get_link (EvDocumentLinks *document_links,
EvDocumentLinksIter *iter);
EvDocumentLinksIter *ev_document_links_get_child (EvDocumentLinks *document_links,
EvDocumentLinksIter *iter);
gboolean ev_document_links_next (EvDocumentLinks *document_links,
EvDocumentLinksIter *iter);
void ev_document_links_free_iter (EvDocumentLinks *document_links,
EvDocumentLinksIter *iter);
GType ev_document_links_get_type (void);
gboolean ev_document_links_has_document_links (EvDocumentLinks *document_links);
GtkTreeModel *ev_document_links_get_links_model (EvDocumentLinks *document_links);
G_END_DECLS
......
......@@ -21,7 +21,9 @@
#include "config.h"
#include "ev-document.h"
#include "ev-backend-marshalers.h"
#include "ev-job-queue.h"
static void ev_document_class_init (gpointer g_class);
......@@ -33,7 +35,10 @@ enum
};
static guint signals[LAST_SIGNAL] = { 0 };
GMutex *ev_doc_mutex = NULL;
#define LOG(x)
GType
ev_document_get_type (void)
{
......@@ -98,13 +103,46 @@ ev_document_class_init (gpointer g_class)
G_PARAM_READABLE));
}
#define PAGE_CACHE_STRING "ev-page-cache"
EvPageCache *
ev_document_get_page_cache (EvDocument *document)
{
EvPageCache *page_cache;
g_return_val_if_fail (EV_IS_DOCUMENT (document), NULL);
page_cache = g_object_get_data (G_OBJECT (document), PAGE_CACHE_STRING);
if (page_cache == NULL) {
page_cache = _ev_page_cache_new (document);
g_object_set_data_full (G_OBJECT (document), PAGE_CACHE_STRING, page_cache, g_object_unref);
}
return page_cache;
}
GMutex *
ev_document_get_doc_mutex (void)
{
if (ev_doc_mutex == NULL) {
ev_doc_mutex = g_mutex_new ();
}
return ev_doc_mutex;
}
gboolean
ev_document_load (EvDocument *document,
const char *uri,
GError **error)
{
EvDocumentIface *iface = EV_DOCUMENT_GET_IFACE (document);
return iface->load (document, uri, error);
gboolean retval;
LOG ("ev_document_load");
retval = iface->load (document, uri, error);
/* Call this to make the initial cached copy */
ev_document_get_page_cache (document);
return retval;
}
gboolean
......@@ -113,7 +151,12 @@ ev_document_save (EvDocument *document,
GError **error)
{
EvDocumentIface *iface = EV_DOCUMENT_GET_IFACE (document);
return iface->save (document, uri, error);
gboolean retval;
LOG ("ev_document_save");
retval = iface->save (document, uri, error);
return retval;
}
char *
......@@ -121,6 +164,7 @@ ev_document_get_title (EvDocument *document)
{
char *title;
LOG ("ev_document_get_title");
g_object_get (document, "title", &title, NULL);
return title;
......@@ -130,7 +174,12 @@ int
ev_document_get_n_pages (EvDocument *document)
{
EvDocumentIface *iface = EV_DOCUMENT_GET_IFACE (document);
return iface->get_n_pages (document);
gint retval;
LOG ("ev_document_get_n_pages");
retval = iface->get_n_pages (document);
return retval;
}
void
......@@ -138,6 +187,8 @@ ev_document_set_page (EvDocument *document,
int page)
{
EvDocumentIface *iface = EV_DOCUMENT_GET_IFACE (document);
LOG ("ev_document_set_page");
iface->set_page (document, page);
}
......@@ -145,7 +196,12 @@ int
ev_document_get_page (EvDocument *document)
{
EvDocumentIface *iface = EV_DOCUMENT_GET_IFACE (document);
return iface->get_page (document);
int retval;
LOG ("ev_document_get_page");
retval = iface->get_page (document);
return retval;
}
void
......@@ -153,6 +209,8 @@ ev_document_set_target (EvDocument *document,
GdkDrawable *target)
{
EvDocumentIface *iface = EV_DOCUMENT_GET_IFACE (document);
LOG ("ev_document_set_target");
iface->set_target (document, target);
}
......@@ -161,6 +219,8 @@ ev_document_set_scale (EvDocument *document,
double scale)
{
EvDocumentIface *iface = EV_DOCUMENT_GET_IFACE (document);
LOG ("ev_document_set_scale");
iface->set_scale (document, scale);
}
......@@ -170,6 +230,8 @@ ev_document_set_page_offset (EvDocument *document,
int y)
{
EvDocumentIface *iface = EV_DOCUMENT_GET_IFACE (document);
LOG ("ev_document_set_page_offset");
iface->set_page_offset (document, x, y);
}
......@@ -180,6 +242,8 @@ ev_document_get_page_size (EvDocument *document,
int *height)
{
EvDocumentIface *iface = EV_DOCUMENT_GET_IFACE (document);
LOG ("ev_document_get_page_size");
iface->get_page_size (document, page, width, height);
}
......@@ -188,7 +252,12 @@ ev_document_get_text (EvDocument *document,
GdkRectangle *rect)
{
EvDocumentIface *iface = EV_DOCUMENT_GET_IFACE (document);
return iface->get_text (document, rect);
char *retval;
LOG ("ev_document_get_text");
retval = iface->get_text (document, rect);
return retval;
}
EvLink *
......@@ -197,7 +266,12 @@ ev_document_get_link (EvDocument *document,
int y)
{
EvDocumentIface *iface = EV_DOCUMENT_GET_IFACE (document);
return iface->get_link (document, x, y);
EvLink *retval;
LOG ("ev_document_get_link");
retval = iface->get_link (document, x, y);
return retval;
}
void
......@@ -208,9 +282,27 @@ ev_document_render (EvDocument *document,
int clip_height)
{
EvDocumentIface *iface = EV_DOCUMENT_GET_IFACE (document);
LOG ("ev_document_render");
iface->render (document, clip_x, clip_y, clip_width, clip_height);
}
GdkPixbuf *
ev_document_render_pixbuf (EvDocument *document)
{
EvDocumentIface *iface = EV_DOCUMENT_GET_IFACE (document);
GdkPixbuf *retval;
LOG ("ev_document_render_pixbuf");
g_assert (iface->render_pixbuf);
retval = iface->render_pixbuf (document);
return retval;
}
void
ev_document_page_changed (EvDocument *document)
{
......@@ -221,4 +313,4 @@ void
ev_document_scale_changed (EvDocument *document)
{
g_signal_emit (G_OBJECT (document), signals[SCALE_CHANGED], 0);
}
}
......@@ -37,10 +37,16 @@ G_BEGIN_DECLS
#define EV_IS_DOCUMENT_IFACE(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EV_TYPE_DOCUMENT))
#define EV_DOCUMENT_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), EV_TYPE_DOCUMENT, EvDocumentIface))
typedef struct _EvDocument EvDocument;
typedef struct _EvDocumentIface EvDocumentIface;
typedef struct _EvDocument EvDocument;
typedef struct _EvDocumentIface EvDocumentIface;
typedef struct _EvPageCache EvPageCache;
typedef struct _EvPageCacheClass EvPageCacheClass;
#include "ev-page-cache.h"
#define EV_DOCUMENT_ERROR ev_document_error_quark ()
#define EV_DOC_MUTEX (ev_document_get_doc_mutex ())
typedef enum
{
......@@ -88,12 +94,17 @@ struct _EvDocumentIface
int clip_y,
int clip_width,
int clip_height);
GdkPixbuf *(* render_pixbuf) (EvDocument *document);
};
GType ev_document_get_type (void);
GQuark ev_document_error_quark (void);
GType ev_document_get_type (void);
GQuark ev_document_error_quark (void);
EvPageCache *ev_document_get_page_cache (EvDocument *document);
GMutex *ev_document_get_doc_mutex (void);
gboolean ev_document_load (EvDocument *document,
const char *uri,
......@@ -127,6 +138,8 @@ void ev_document_render (EvDocument *document,
int clip_y,
int clip_width,
int clip_height);
/* Quick hack to test threaded rendering */
GdkPixbuf *ev_document_render_pixbuf (EvDocument *document);
void ev_document_page_changed (EvDocument *document);
void ev_document_scale_changed (EvDocument *document);
......
#include "ev-job-queue.h"
/* Like glib calling convention, all functions with _locked in their name assume
* that we've already locked the doc mutex and can freely and safely access
* data.
*/
GCond *render_cond = NULL;
GMutex *ev_queue_mutex = NULL;
static GQueue *links_queue = NULL;
static GQueue *render_queue_high = NULL;
static GQueue *render_queue_low = NULL;
static GQueue *thumbnail_queue_high = NULL;
static GQueue *thumbnail_queue_low = NULL;
static gboolean
remove_object_from_queue (GQueue *queue, EvJob *job)
{
GList *list;
list = g_queue_find (queue, job);
if (list) {
g_object_unref (G_OBJECT (job));
g_queue_delete_link (queue, list);
return TRUE;
}
return FALSE;
}
static gboolean
notify_finished (GObject *job)
{
ev_job_finished (EV_JOB (job));
return FALSE;
}
static void
handle_job (EvJob *job)
{
g_object_ref (G_OBJECT (job));
if (EV_IS_JOB_THUMBNAIL (job))
ev_job_thumbnail_run (EV_JOB_THUMBNAIL (job));
else if (EV_IS_JOB_LINKS (job))
ev_job_links_run (EV_JOB_LINKS (job));
else if (EV_IS_JOB_RENDER (job))
ev_job_render_run (EV_JOB_RENDER (job));
/* We let the idle own a ref, as we (the queue) are done with the job. */
g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
(GSourceFunc) notify_finished,
job,
g_object_unref);
}
static EvJob *
search_for_jobs_unlocked (void)
{
EvJob *job;
job = (EvJob *) g_queue_pop_head (render_queue_high);
if (job)
return job;
job = (EvJob *) g_queue_pop_head (thumbnail_queue_high);
if (job)
return job;
job = (EvJob *) g_queue_pop_head (render_queue_low);
if (job)
return job;
job = (EvJob *) g_queue_pop_head (links_queue);
if (job)
return job;
job = (EvJob *) g_queue_pop_head (thumbnail_queue_low);
if (job)
return job;
return NULL;
}
static gboolean
no_jobs_available_unlocked (void)
{
return g_queue_is_empty (render_queue_high)
&& g_queue_is_empty (render_queue_low)
&& g_queue_is_empty (links_queue)
&& g_queue_is_empty (thumbnail_queue_high)
&& g_queue_is_empty (thumbnail_queue_low);
}
/* the thread mainloop function */
static gpointer
ev_render_thread (gpointer data)
{
while (TRUE) {
EvJob *job;
g_mutex_lock (ev_queue_mutex);
if (no_jobs_available_unlocked ()) {
g_cond_wait (render_cond, ev_queue_mutex);
}
job = search_for_jobs_unlocked ();
g_mutex_unlock (ev_queue_mutex);
/* Now that we have our job, we handle it */
if (job) {
handle_job (job);
g_object_unref (G_OBJECT (job));
}
}
return NULL;
}
/* Public Functions */
void
ev_job_queue_init (void)
{
if (!g_thread_supported ()) g_thread_init (NULL);
render_cond = g_cond_new ();
ev_queue_mutex = g_mutex_new ();
links_queue = g_queue_new ();
render_queue_high = g_queue_new ();
render_queue_low = g_queue_new ();
thumbnail_queue_high = g_queue_new ();
thumbnail_queue_low = g_queue_new ();
g_thread_create (ev_render_thread, NULL, FALSE, NULL);
}
static GQueue *
find_queue (EvJob *job,
EvJobPriority priority)
{
if (EV_IS_JOB_RENDER (job)) {
if (priority == EV_JOB_PRIORITY_HIGH)
return render_queue_high;
else
return render_queue_low;
} else if (EV_IS_JOB_THUMBNAIL (job)) {
if (priority == EV_JOB_PRIORITY_HIGH)
return thumbnail_queue_high;
else
return thumbnail_queue_low;
} else if (EV_IS_JOB_LINKS (job)) {
/* the priority doesn't effect links */
return links_queue;
}
g_assert_not_reached ();
return NULL;
}
void
ev_job_queue_add_job (EvJob *job,
EvJobPriority priority)
{
GQueue *queue;
g_return_if_fail (EV_IS_JOB (job));
queue = find_queue (job, priority);
g_mutex_lock (ev_queue_mutex);
g_object_ref (job);
g_queue_push_tail (queue, job);
g_cond_broadcast (render_cond);
g_mutex_unlock (ev_queue_mutex);
}
gboolean
ev_job_queue_remove_job (EvJob *job)
{
gboolean retval = FALSE;
g_return_val_if_fail (EV_IS_JOB (job), FALSE);
g_mutex_lock (ev_queue_mutex);
if (EV_IS_JOB_THUMBNAIL (job)) {
retval = remove_object_from_queue (thumbnail_queue_high, job);
retval = retval || remove_object_from_queue (thumbnail_queue_low, job);
} else if (EV_IS_JOB_RENDER (job)) {
retval = remove_object_from_queue (render_queue_high, job);
retval = retval || remove_object_from_queue (render_queue_low, job);
} else if (EV_IS_JOB_LINKS (job)) {
retval = remove_object_from_queue (links_queue, job);
} else {
g_assert_not_reached ();
}
g_mutex_unlock (ev_queue_mutex);
return retval;
}
/* this file is part of evince, a gnome document viewer