Mercurial > geeqie.yaz
annotate src/slideshow.c @ 276:4f526d436873
Implement secure rc file saving.
First data is written to a temporary file, then if nothing
was wrong, this file is renamed to the final name.
This way the risk of corrupted rc file is greatly reduced.
The code is borrowed from ELinks (http://elinks.cz).
author | zas_ |
---|---|
date | Tue, 08 Apr 2008 21:55:58 +0000 |
parents | f6e307c7bad6 |
children | 9995c5fb202a |
rev | line source |
---|---|
1 | 1 /* |
196 | 2 * Geeqie |
9 | 3 * (C) 2004 John Ellis |
1 | 4 * |
5 * Author: John Ellis | |
6 * | |
9 | 7 * This software is released under the GNU General Public License (GNU GPL). |
8 * Please read the included file COPYING for more information. | |
9 * This software comes with no warranty of any kind, use at your own risk! | |
1 | 10 */ |
11 | |
9 | 12 |
1 | 13 #include "gqview.h" |
9 | 14 #include "collect.h" |
15 #include "image.h" | |
16 #include "slideshow.h" | |
138 | 17 #include "filelist.h" |
1 | 18 |
9 | 19 #include "layout.h" |
20 #include "layout_image.h" | |
21 #include "ui_fileops.h" | |
1 | 22 |
9 | 23 |
24 static void slideshow_timer_reset(SlideShowData *ss, gint reset); | |
25 | |
1 | 26 |
9 | 27 void slideshow_free(SlideShowData *ss) |
28 { | |
89
b3149a34d0dd
Sat Oct 28 14:41:10 2006 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
29 if (!ss) return; |
b3149a34d0dd
Sat Oct 28 14:41:10 2006 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
30 |
9 | 31 slideshow_timer_reset(ss, FALSE); |
1 | 32 |
9 | 33 if (ss->stop_func) ss->stop_func(ss, ss->stop_data); |
3 | 34 |
138 | 35 if (ss->filelist) filelist_free(ss->filelist); |
9 | 36 if (ss->cd) collection_unref(ss->cd); |
37 g_free(ss->layout_path); | |
1 | 38 |
9 | 39 g_list_free(ss->list); |
40 g_list_free(ss->list_done); | |
1 | 41 |
138 | 42 file_data_unref(ss->slide_fd); |
9 | 43 |
44 g_free(ss); | |
1 | 45 } |
46 | |
9 | 47 static GList *generate_list(SlideShowData *ss) |
1 | 48 { |
49 GList *list = NULL; | |
50 | |
9 | 51 if (ss->from_selection) |
52 { | |
53 list = layout_selection_list_by_index(ss->layout); | |
54 } | |
55 else | |
1 | 56 { |
57 gint i; | |
9 | 58 for(i = 0; i < ss->slide_count; i++) |
1 | 59 { |
60 list = g_list_prepend(list, GINT_TO_POINTER(i)); | |
61 } | |
9 | 62 list = g_list_reverse(list); |
1 | 63 } |
64 | |
65 return list; | |
66 } | |
67 | |
9 | 68 static GList *generate_random_list(SlideShowData *ss) |
1 | 69 { |
70 GList *src_list = NULL; | |
71 GList *list = NULL; | |
72 GList *work; | |
73 | |
9 | 74 src_list = generate_list(ss); |
1 | 75 |
76 while(src_list) | |
77 { | |
9 | 78 gint p = (double)rand() / ((double)RAND_MAX + 1.0) * g_list_length(src_list); |
1 | 79 work = g_list_nth(src_list, p); |
80 list = g_list_prepend(list, work->data); | |
81 src_list = g_list_remove(src_list, work->data); | |
82 } | |
83 | |
84 return list; | |
85 } | |
86 | |
9 | 87 static void slideshow_list_init(SlideShowData *ss, gint start_index) |
1 | 88 { |
9 | 89 if (ss->list_done) |
1 | 90 { |
9 | 91 g_list_free(ss->list_done); |
92 ss->list_done = NULL; | |
1 | 93 } |
94 | |
9 | 95 if (ss->list) g_list_free(ss->list); |
3 | 96 |
1 | 97 if (slideshow_random) |
98 { | |
9 | 99 ss->list = generate_random_list(ss); |
1 | 100 } |
101 else | |
102 { | |
9 | 103 ss->list = generate_list(ss); |
104 if (start_index >= 0) | |
3 | 105 { |
9 | 106 /* start with specified image by skipping to it */ |
107 gint i = 0; | |
108 | |
109 while(ss->list && i < start_index) | |
110 { | |
111 ss->list_done = g_list_prepend (ss->list_done, ss->list->data); | |
112 ss->list = g_list_remove(ss->list, ss->list->data); | |
113 i++; | |
114 } | |
3 | 115 } |
116 } | |
117 } | |
118 | |
9 | 119 gint slideshow_should_continue(SlideShowData *ss) |
1 | 120 { |
138 | 121 FileData *imd_fd; |
9 | 122 const gchar *path; |
123 | |
89
b3149a34d0dd
Sat Oct 28 14:41:10 2006 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
124 if (!ss) return FALSE; |
b3149a34d0dd
Sat Oct 28 14:41:10 2006 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
125 |
138 | 126 imd_fd = image_get_fd(ss->imd); |
9 | 127 |
138 | 128 if ( ((imd_fd == NULL) != (ss->slide_fd == NULL)) || |
129 (imd_fd && ss->slide_fd && imd_fd != ss->slide_fd) ) return FALSE; | |
9 | 130 |
138 | 131 if (ss->filelist) return TRUE; |
9 | 132 |
133 if (ss->cd) | |
134 { | |
135 if (g_list_length(ss->cd->list) == ss->slide_count) | |
136 return TRUE; | |
137 else | |
138 return FALSE; | |
139 } | |
140 | |
141 if (!ss->layout) return FALSE; | |
142 path = layout_get_path(ss->layout); | |
143 | |
144 if (path && ss->layout_path && | |
145 strcmp(path, ss->layout_path) == 0) | |
146 { | |
147 if (ss->from_selection && ss->slide_count == layout_selection_count(ss->layout, NULL)) return TRUE; | |
148 if (!ss->from_selection && ss->slide_count == layout_list_count(ss->layout, NULL)) return TRUE; | |
149 } | |
150 | |
151 return FALSE; | |
152 } | |
153 | |
154 static gint slideshow_step(SlideShowData *ss, gint forward) | |
155 { | |
156 gint row; | |
157 | |
158 if (!slideshow_should_continue(ss)) | |
1 | 159 { |
160 return FALSE; | |
161 } | |
162 | |
9 | 163 if (forward) |
164 { | |
165 if (!ss->list) return TRUE; | |
1 | 166 |
9 | 167 row = GPOINTER_TO_INT(ss->list->data); |
168 ss->list_done = g_list_prepend (ss->list_done, ss->list->data); | |
169 ss->list = g_list_remove(ss->list, ss->list->data); | |
170 } | |
171 else | |
172 { | |
173 if (!ss->list_done || !ss->list_done->next) return TRUE; | |
3 | 174 |
9 | 175 ss->list = g_list_prepend(ss->list, ss->list_done->data); |
176 ss->list_done = g_list_remove(ss->list_done, ss->list_done->data); | |
177 row = GPOINTER_TO_INT(ss->list_done->data); | |
3 | 178 } |
179 | |
138 | 180 file_data_unref(ss->slide_fd); |
181 ss->slide_fd = NULL; | |
3 | 182 |
138 | 183 if (ss->filelist) |
9 | 184 { |
138 | 185 ss->slide_fd = file_data_ref((FileData *)g_list_nth_data(ss->filelist, row)); |
186 image_change_fd(ss->imd, ss->slide_fd, image_zoom_get_default(ss->imd, zoom_mode)); | |
9 | 187 } |
188 else if (ss->cd) | |
189 { | |
190 CollectInfo *info; | |
3 | 191 |
9 | 192 info = g_list_nth_data(ss->cd->list, row); |
138 | 193 ss->slide_fd = file_data_ref(info->fd); |
9 | 194 |
195 image_change_from_collection(ss->imd, ss->cd, info, image_zoom_get_default(ss->imd, zoom_mode)); | |
3 | 196 } |
197 else | |
198 { | |
138 | 199 ss->slide_fd = file_data_ref(layout_list_get_fd(ss->layout, row)); |
9 | 200 |
201 if (ss->from_selection) | |
202 { | |
138 | 203 image_change_fd(ss->imd, ss->slide_fd, image_zoom_get_default(ss->imd, zoom_mode)); |
9 | 204 layout_status_update_info(ss->layout, NULL); |
205 } | |
206 else | |
207 { | |
208 layout_image_set_index(ss->layout, row); | |
209 } | |
3 | 210 } |
211 | |
9 | 212 if (!ss->list && slideshow_repeat) |
213 { | |
214 slideshow_list_init(ss, -1); | |
215 } | |
3 | 216 |
9 | 217 if (!ss->list) |
1 | 218 { |
219 return FALSE; | |
220 } | |
221 | |
9 | 222 /* read ahead */ |
1 | 223 |
9 | 224 if (enable_read_ahead) |
1 | 225 { |
9 | 226 gint r; |
227 if (forward) | |
228 { | |
229 if (!ss->list) return TRUE; | |
230 r = GPOINTER_TO_INT(ss->list->data); | |
231 } | |
232 else | |
233 { | |
234 if (!ss->list_done || !ss->list_done->next) return TRUE; | |
235 r = GPOINTER_TO_INT(ss->list_done->next->data); | |
236 } | |
1 | 237 |
138 | 238 if (ss->filelist) |
9 | 239 { |
138 | 240 image_prebuffer_set(ss->imd, g_list_nth_data(ss->filelist, r)); |
9 | 241 } |
242 else if (ss->cd) | |
243 { | |
244 CollectInfo *info; | |
245 info = g_list_nth_data(ss->cd->list, r); | |
138 | 246 if (info) image_prebuffer_set(ss->imd, info->fd); |
9 | 247 } |
248 else if (ss->from_selection) | |
249 { | |
138 | 250 image_prebuffer_set(ss->imd, layout_list_get_fd(ss->layout, r)); |
9 | 251 } |
1 | 252 } |
253 | |
254 return TRUE; | |
255 } | |
256 | |
3 | 257 static gint slideshow_loop_cb(gpointer data) |
258 { | |
9 | 259 SlideShowData *ss = data; |
1 | 260 |
9 | 261 if (ss->paused) return TRUE; |
1 | 262 |
9 | 263 if (!slideshow_step(ss, TRUE)) |
3 | 264 { |
9 | 265 ss->timeout_id = -1; |
266 slideshow_free(ss); | |
1 | 267 return FALSE; |
268 } | |
269 | |
270 return TRUE; | |
271 } | |
272 | |
9 | 273 static void slideshow_timer_reset(SlideShowData *ss, gint reset) |
274 { | |
275 if (reset) | |
276 { | |
277 if (slideshow_delay < 1) slideshow_delay = 1; | |
278 | |
279 if (ss->timeout_id != -1) g_source_remove(ss->timeout_id); | |
280 ss->timeout_id = g_timeout_add(slideshow_delay * 1000 / SLIDESHOW_SUBSECOND_PRECISION, | |
281 slideshow_loop_cb, ss); | |
282 } | |
283 else if (ss->timeout_id != -1) | |
284 { | |
285 g_source_remove(ss->timeout_id); | |
286 ss->timeout_id = -1; | |
287 } | |
288 } | |
289 | |
290 void slideshow_next(SlideShowData *ss) | |
291 { | |
89
b3149a34d0dd
Sat Oct 28 14:41:10 2006 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
292 if (!ss) return; |
b3149a34d0dd
Sat Oct 28 14:41:10 2006 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
293 |
9 | 294 if (!slideshow_step(ss, TRUE)) |
295 { | |
296 slideshow_free(ss); | |
297 return; | |
298 } | |
299 | |
300 slideshow_timer_reset(ss, TRUE); | |
301 } | |
302 | |
303 void slideshow_prev(SlideShowData *ss) | |
304 { | |
89
b3149a34d0dd
Sat Oct 28 14:41:10 2006 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
305 if (!ss) return; |
b3149a34d0dd
Sat Oct 28 14:41:10 2006 John Ellis <johne@verizon.net>
gqview
parents:
9
diff
changeset
|
306 |
9 | 307 if (!slideshow_step(ss, FALSE)) |
308 { | |
309 slideshow_free(ss); | |
310 return; | |
311 } | |
312 | |
313 slideshow_timer_reset(ss, TRUE); | |
314 } | |
315 | |
316 static SlideShowData *real_slideshow_start(ImageWindow *imd, LayoutWindow *lw, | |
138 | 317 GList *filelist, gint start_point, |
9 | 318 CollectionData *cd, CollectInfo *start_info, |
319 void (*stop_func)(SlideShowData *, gpointer), gpointer stop_data) | |
320 { | |
321 SlideShowData *ss; | |
322 gint start_index = -1; | |
323 | |
138 | 324 if (!filelist && !cd && layout_list_count(lw, NULL) < 1) return NULL; |
9 | 325 |
326 ss = g_new0(SlideShowData, 1); | |
327 | |
328 ss->imd = imd; | |
329 | |
138 | 330 ss->filelist = filelist; |
9 | 331 ss->cd = cd; |
332 ss->layout = lw; | |
333 ss->layout_path = NULL; | |
334 | |
335 ss->list = NULL; | |
336 ss->list_done = NULL; | |
337 | |
338 ss->from_selection = FALSE; | |
339 | |
119
197b8d2e52ce
Thu Nov 30 09:55:42 2006 John Ellis <johne@verizon.net>
gqview
parents:
89
diff
changeset
|
340 ss->stop_func = NULL; |
9 | 341 |
342 ss->timeout_id = -1; | |
343 ss->paused = FALSE; | |
344 | |
138 | 345 if (ss->filelist) |
9 | 346 { |
138 | 347 ss->slide_count = g_list_length(ss->filelist); |
9 | 348 } |
349 else if (ss->cd) | |
350 { | |
351 collection_ref(ss->cd); | |
352 ss->slide_count = g_list_length(ss->cd->list); | |
353 if (!slideshow_random && start_info) | |
354 { | |
355 start_index = g_list_index(ss->cd->list, start_info); | |
356 } | |
357 } | |
358 else | |
359 { | |
360 /* layout method */ | |
361 | |
362 ss->slide_count = layout_selection_count(ss->layout, NULL); | |
363 ss->layout_path = g_strdup(layout_get_path(ss->layout)); | |
364 if (ss->slide_count < 2) | |
365 { | |
366 ss->slide_count = layout_list_count(ss->layout, NULL); | |
367 if (!slideshow_random && start_point >= 0 && start_point < ss->slide_count) | |
368 { | |
369 start_index = start_point; | |
370 } | |
371 } | |
372 else | |
373 { | |
374 ss->from_selection = TRUE; | |
375 } | |
376 } | |
377 | |
378 slideshow_list_init(ss, start_index); | |
379 | |
138 | 380 ss->slide_fd = file_data_ref(image_get_fd(ss->imd)); |
9 | 381 if (slideshow_step(ss, TRUE)) |
382 { | |
383 slideshow_timer_reset(ss, TRUE); | |
119
197b8d2e52ce
Thu Nov 30 09:55:42 2006 John Ellis <johne@verizon.net>
gqview
parents:
89
diff
changeset
|
384 |
197b8d2e52ce
Thu Nov 30 09:55:42 2006 John Ellis <johne@verizon.net>
gqview
parents:
89
diff
changeset
|
385 ss->stop_func = stop_func; |
197b8d2e52ce
Thu Nov 30 09:55:42 2006 John Ellis <johne@verizon.net>
gqview
parents:
89
diff
changeset
|
386 ss->stop_data = stop_data; |
9 | 387 } |
388 else | |
389 { | |
119
197b8d2e52ce
Thu Nov 30 09:55:42 2006 John Ellis <johne@verizon.net>
gqview
parents:
89
diff
changeset
|
390 slideshow_free(ss); |
9 | 391 ss = NULL; |
392 } | |
393 | |
394 return ss; | |
395 } | |
396 | |
138 | 397 SlideShowData *slideshow_start_from_filelist(ImageWindow *imd, GList *list, |
9 | 398 void (*stop_func)(SlideShowData *, gpointer), gpointer stop_data) |
399 { | |
400 return real_slideshow_start(imd, NULL, list, -1, NULL, NULL, stop_func, stop_data); | |
401 } | |
402 | |
403 SlideShowData *slideshow_start_from_collection(ImageWindow *imd, CollectionData *cd, | |
404 void (*stop_func)(SlideShowData *, gpointer), gpointer stop_data, | |
405 CollectInfo *start_info) | |
406 { | |
407 return real_slideshow_start(imd, NULL, NULL, -1, cd, start_info, stop_func, stop_data); | |
408 } | |
409 | |
410 SlideShowData *slideshow_start(ImageWindow *imd, LayoutWindow *lw, gint start_point, | |
411 void (*stop_func)(SlideShowData *, gpointer), gpointer stop_data) | |
412 { | |
413 return real_slideshow_start(imd, lw, NULL, start_point, NULL, NULL, stop_func, stop_data); | |
414 } | |
415 | |
416 gint slideshow_paused(SlideShowData *ss) | |
417 { | |
418 if (!ss) return FALSE; | |
419 | |
420 return ss->paused; | |
421 } | |
422 | |
423 void slideshow_pause_set(SlideShowData *ss, gint paused) | |
424 { | |
425 if (!ss) return; | |
426 | |
427 ss->paused = paused; | |
428 } | |
429 | |
430 gint slideshow_pause_toggle(SlideShowData *ss) | |
431 { | |
432 slideshow_pause_set(ss, !slideshow_paused(ss)); | |
433 return slideshow_paused(ss); | |
434 } | |
435 | |
436 |