]> www.fi.muni.cz Git - evince.git/blob - backend/ev-jobs.c
Use document info from page cache instead of document itself. fix for crash
[evince.git] / backend / ev-jobs.c
1 #include "ev-jobs.h"
2 #include "ev-job-queue.h"
3 #include "ev-document-thumbnails.h"
4 #include "ev-document-links.h"
5 #include "ev-async-renderer.h"
6
7 static void ev_job_init                 (EvJob               *job);
8 static void ev_job_class_init           (EvJobClass          *class);
9 static void ev_job_links_init           (EvJobLinks          *job);
10 static void ev_job_links_class_init     (EvJobLinksClass     *class);
11 static void ev_job_render_init          (EvJobRender         *job);
12 static void ev_job_render_class_init    (EvJobRenderClass    *class);
13 static void ev_job_thumbnail_init       (EvJobThumbnail      *job);
14 static void ev_job_thumbnail_class_init (EvJobThumbnailClass *class);
15
16 enum
17 {
18         FINISHED,
19         LAST_SIGNAL
20 };
21
22 static guint job_signals[LAST_SIGNAL] = { 0 };
23
24 G_DEFINE_TYPE (EvJob, ev_job, G_TYPE_OBJECT)
25 G_DEFINE_TYPE (EvJobLinks, ev_job_links, EV_TYPE_JOB)
26 G_DEFINE_TYPE (EvJobRender, ev_job_render, EV_TYPE_JOB)
27 G_DEFINE_TYPE (EvJobThumbnail, ev_job_thumbnail, EV_TYPE_JOB)
28
29
30 static void ev_job_init (EvJob *job) { /* Do Nothing */ }
31
32 static void
33 ev_job_dispose (GObject *object)
34 {
35         EvJob *job;
36
37         job = EV_JOB (object);
38
39         if (job->document) {
40                 g_object_unref (job->document);
41                 job->document = NULL;
42         }
43
44         (* G_OBJECT_CLASS (ev_job_parent_class)->dispose) (object);
45 }
46
47 static void
48 ev_job_class_init (EvJobClass *class)
49 {
50         GObjectClass *oclass;
51
52         oclass = G_OBJECT_CLASS (class);
53
54         oclass->dispose = ev_job_dispose;
55
56         job_signals [FINISHED] =
57                 g_signal_new ("finished",
58                               EV_TYPE_JOB,
59                               G_SIGNAL_RUN_LAST,
60                               G_STRUCT_OFFSET (EvJobClass, finished),
61                               NULL, NULL,
62                               g_cclosure_marshal_VOID__VOID,
63                               G_TYPE_NONE, 0);
64 }
65
66
67 static void ev_job_links_init (EvJobLinks *job) { /* Do Nothing */ }
68
69 static void
70 ev_job_links_dispose (GObject *object)
71 {
72         EvJobLinks *job;
73
74         job = EV_JOB_LINKS (object);
75
76         if (job->model) {
77                 g_object_unref (job->model);
78                 job->model = NULL;
79         }
80
81         (* G_OBJECT_CLASS (ev_job_links_parent_class)->dispose) (object);
82 }
83
84 static void
85 ev_job_links_class_init (EvJobLinksClass *class)
86 {
87         GObjectClass *oclass;
88
89         oclass = G_OBJECT_CLASS (class);
90
91         oclass->dispose = ev_job_links_dispose;
92 }
93
94
95 static void ev_job_render_init (EvJobRender *job) { /* Do Nothing */ }
96
97 static void
98 ev_job_render_dispose (GObject *object)
99 {
100         EvJobRender *job;
101
102         job = EV_JOB_RENDER (object);
103
104         if (job->pixbuf) {
105                 g_object_unref (job->pixbuf);
106                 job->pixbuf = NULL;
107         }
108
109         (* G_OBJECT_CLASS (ev_job_render_parent_class)->dispose) (object);
110 }
111
112 static void
113 ev_job_render_class_init (EvJobRenderClass *class)
114 {
115         GObjectClass *oclass;
116
117         oclass = G_OBJECT_CLASS (class);
118
119         oclass->dispose = ev_job_render_dispose;
120 }
121
122 static void ev_job_thumbnail_init (EvJobThumbnail *job) { /* Do Nothing */ }
123
124 static void
125 ev_job_thumbnail_dispose (GObject *object)
126 {
127         EvJobThumbnail *job;
128
129         job = EV_JOB_THUMBNAIL (object);
130
131         if (job->thumbnail) {
132                 g_object_unref (job->thumbnail);
133                 job->thumbnail = NULL;
134         }
135
136         (* G_OBJECT_CLASS (ev_job_thumbnail_parent_class)->dispose) (object);
137 }
138
139 static void
140 ev_job_thumbnail_class_init (EvJobThumbnailClass *class)
141 {
142         GObjectClass *oclass;
143
144         oclass = G_OBJECT_CLASS (class);
145
146         oclass->dispose = ev_job_thumbnail_dispose;
147 }
148
149 /* Public functions */
150 void
151 ev_job_finished (EvJob *job)
152 {
153         g_return_if_fail (EV_IS_JOB (job));
154
155         g_signal_emit (job, job_signals[FINISHED], 0);
156 }
157
158 EvJob *
159 ev_job_links_new (EvDocument *document)
160 {
161         EvJob *job;
162
163         job = g_object_new (EV_TYPE_JOB_LINKS, NULL);
164         job->document = g_object_ref (document);
165
166         return job;
167 }
168
169 void
170 ev_job_links_run (EvJobLinks *job)
171 {
172         g_return_if_fail (EV_IS_JOB_LINKS (job));
173
174         ev_document_doc_mutex_lock ();
175         job->model = ev_document_links_get_links_model (EV_DOCUMENT_LINKS (EV_JOB (job)->document));
176         EV_JOB (job)->finished = TRUE;
177         ev_document_doc_mutex_unlock ();
178 }
179
180
181 EvJob *
182 ev_job_render_new (EvDocument *document,
183                    gint        page,
184                    double      scale,
185                    gint        width,
186                    gint        height,
187                    gboolean    include_links)
188 {
189         EvJobRender *job;
190
191         job = g_object_new (EV_TYPE_JOB_RENDER, NULL);
192
193         EV_JOB (job)->document = g_object_ref (document);
194         job->page = page;
195         job->scale = scale;
196         job->target_width = width;
197         job->target_height = height;
198         job->include_links = include_links;
199
200         if (EV_IS_ASYNC_RENDERER (document)) {  
201                 EV_JOB (job)->async = TRUE;
202         }
203
204         return EV_JOB (job);
205 }
206
207 static void
208 render_finished_cb (EvDocument *document, GdkPixbuf *pixbuf, EvJobRender *job)
209 {
210         g_signal_handlers_disconnect_by_func (EV_JOB (job)->document,
211                                               render_finished_cb, job);
212
213         EV_JOB (job)->finished = TRUE;
214         job->pixbuf = g_object_ref (pixbuf);
215         ev_job_finished (EV_JOB (job));
216 }
217
218 void
219 ev_job_render_run (EvJobRender *job)
220 {
221         g_return_if_fail (EV_IS_JOB_RENDER (job));
222
223         ev_document_doc_mutex_lock ();
224
225         if (EV_JOB (job)->async) {
226                 EvAsyncRenderer *renderer = EV_ASYNC_RENDERER (EV_JOB (job)->document);
227                 ev_async_renderer_render_pixbuf (renderer, job->page, job->scale);
228                 g_signal_connect (EV_JOB (job)->document, "render_finished",
229                                   G_CALLBACK (render_finished_cb), job);
230         } else {
231                 job->pixbuf = ev_document_render_pixbuf (EV_JOB (job)->document,
232                                                          job->page,
233                                                          job->scale);
234                 if (job->include_links)
235                         job->link_mapping = ev_document_get_links (EV_JOB (job)->document, job->page);
236
237                 EV_JOB (job)->finished = TRUE;
238         }
239
240         ev_document_doc_mutex_unlock ();
241 }
242
243 EvJob *
244 ev_job_thumbnail_new (EvDocument *document,
245                       gint        page,
246                       gint        requested_width)
247 {
248         EvJobThumbnail *job;
249
250         job = g_object_new (EV_TYPE_JOB_THUMBNAIL, NULL);
251
252         EV_JOB (job)->document = g_object_ref (document);
253         job->page = page;
254         job->requested_width = requested_width;
255
256         return EV_JOB (job);
257 }
258
259 void
260 ev_job_thumbnail_run (EvJobThumbnail *job)
261 {
262         g_return_if_fail (EV_IS_JOB_THUMBNAIL (job));
263
264         ev_document_doc_mutex_lock ();
265
266         job->thumbnail =
267                 ev_document_thumbnails_get_thumbnail (EV_DOCUMENT_THUMBNAILS (EV_JOB (job)->document),
268                                                       job->page,
269                                                       job->requested_width,
270                                                       TRUE);
271         EV_JOB (job)->finished = TRUE;
272
273         ev_document_doc_mutex_unlock ();
274 }