LiVES 3.2.0
dialogs.c
Go to the documentation of this file.
1// dialogs.c
2// LiVES (lives-exe)
3// (c) G. Finch 2003 - 2020 <salsaman+lives@gmail.com>
4// Released under the GPL 3 or later
5// see file ../COPYING for licensing details
6
8
9#include "main.h"
10
11#include <fcntl.h>
12#include <unistd.h>
13#include <stdlib.h>
14#include <stdio.h>
15#include <string.h>
16
17#include "interface.h"
18#include "cvirtual.h"
19#include "resample.h"
20#include "rte_window.h"
21#include "paramwindow.h"
22#include "ce_thumbs.h"
23#include "callbacks.h"
24#include "diagnostics.h"
25
26extern void reset_frame_and_clip_index(void);
27
28#define ANIM_LIMIT 0
29
30static int extra_cb_key = 0;
31static int del_cb_key = 0;
32
33// processing
34static uint64_t event_start;
35static double audio_start;
36static boolean accelerators_swapped;
37static int frames_done;
38static double disp_fraction_done;
39static ticks_t proc_start_ticks;
40static ticks_t last_open_check_ticks;
41static ticks_t last_anim_ticks;
42static uint64_t spare_cycles, last_spare_cycles;
43static ticks_t last_kbd_ticks;
44//static ticks_t last_cpuload_ticks = 0;
45static frames_t getahead = -1, test_getahead = -1, bungle_frames;
46
47static boolean recalc_bungle_frames = 0;
48static boolean shown_paused_frames;
49static boolean td_had_focus;
50static boolean cleanup_preload;
51static boolean init_timers = TRUE;
52static boolean drop_off = FALSE;
53static int dropped;
54
55// how often to we count frames when opening
56#define OPEN_CHECK_TICKS (TICKS_PER_SECOND/10l)
57
58static volatile boolean display_ready;
59
60static int64_t sttime;
61
62static lives_time_source_t last_time_source;
63
64static int cache_hits = 0, cache_misses = 0;
65static double jitter = 0.;
66
67
68const char *get_cache_stats(void) {
69 static char buff[1024];
70 lives_snprintf(buff, 1024, "preload caches = %d, hits = %d "
71 "misses = %d,\nframe jitter = %.03f milliseconds.",
72 cache_hits + cache_misses, cache_hits, cache_misses, jitter * 1000.);
73 return buff;
74}
75
76
77void on_warn_mask_toggled(LiVESToggleButton *togglebutton, livespointer user_data) {
78 LiVESWidget *tbutton;
79
80 if (lives_toggle_button_get_active(togglebutton)) prefs->warning_mask |= LIVES_POINTER_TO_INT(user_data);
81 else prefs->warning_mask ^= LIVES_POINTER_TO_INT(user_data);
83
84 if ((tbutton = (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(togglebutton), "auto")) != NULL) {
85 // this is for the cds window - disable autoreload if we are not gonna show this window
86 if (lives_toggle_button_get_active(togglebutton)) {
87 lives_toggle_button_set_active(LIVES_TOGGLE_BUTTON(tbutton), FALSE);
89 } else {
91 }
92 }
93}
94
95
96static void add_xlays_widget(LiVESBox *box) {
97 char *tmp = (_("Show affected _layouts"));
99 lives_free(tmp);
100}
101
102
103void add_warn_check(LiVESBox *box, int warn_mask_number) {
104 LiVESWidget *checkbutton = lives_standard_check_button_new(
105 _("Do _not show this warning any more\n(can be turned back on from Preferences/Warnings)"),
106 FALSE, LIVES_BOX(box), NULL);
107
108 lives_signal_sync_connect(LIVES_GUI_OBJECT(checkbutton), LIVES_WIDGET_TOGGLED_SIGNAL,
109 LIVES_GUI_CALLBACK(on_warn_mask_toggled), LIVES_INT_TO_POINTER(warn_mask_number));
110}
111
112
113static void add_clear_ds_button(LiVESDialog *dialog) {
114 LiVESWidget *button = lives_dialog_add_button_from_stock(LIVES_DIALOG(dialog), LIVES_STOCK_CLEAR, _("_Recover disk space"),
115 LIVES_RESPONSE_RETRY);
117 lives_dialog_make_widget_first(LIVES_DIALOG(dialog), button);
118
119 lives_signal_sync_connect(LIVES_GUI_OBJECT(button), LIVES_WIDGET_CLICKED_SIGNAL,
120 LIVES_GUI_CALLBACK(on_cleardisk_activate), (livespointer)button);
121}
122
123
124static void add_clear_ds_adv(LiVESBox *box) {
125 // add a button which opens up Recover/Repair widget
126 LiVESWidget *button = lives_standard_button_new_with_label(_(" _Advanced Settings >>"),
129 LiVESWidget *hbox = lives_hbox_new(FALSE, 0);
130
131 lives_box_pack_start(LIVES_BOX(hbox), button, FALSE, FALSE, widget_opts.packing_width * 2);
133 add_fill_to_box(LIVES_BOX(box));
134
135 lives_signal_sync_connect(LIVES_GUI_OBJECT(button), LIVES_WIDGET_CLICKED_SIGNAL,
136 LIVES_GUI_CALLBACK(on_cleardisk_advanced_clicked), NULL);
137}
138
139
140static void add_perminfo(LiVESWidget *dialog) {
141 LiVESWidget *dialog_vbox = lives_dialog_get_content_area(LIVES_DIALOG(dialog));
142 LiVESWidget *hbox = lives_hbox_new(FALSE, 0), *vbox;
143 LiVESWidget *label;
144 char *txt;
145
146 lives_box_pack_end(LIVES_BOX(dialog_vbox), hbox, FALSE, FALSE, 0);
147 vbox = lives_vbox_new(FALSE, 0);
148 widget_opts.justify = LIVES_JUSTIFY_CENTER;
149 lives_standard_expander_new(_("_Show complete details"), LIVES_BOX(hbox), vbox);
151 lives_widget_apply_theme(hbox, LIVES_WIDGET_STATE_NORMAL);
152 lives_widget_apply_theme(vbox, LIVES_WIDGET_STATE_NORMAL);
153
154 if (mainw->permmgr->cmdlist) {
155 txt = lives_strdup_printf(_("Should you agree, the following commands will be run:\n%s"),
157 label = lives_standard_label_new(txt);
158 lives_box_pack_start(LIVES_BOX(vbox), label, FALSE, TRUE, widget_opts.packing_height);
159 add_fill_to_box(LIVES_BOX(vbox));
160
161 lives_free(txt);
162 }
163
164 if (mainw->permmgr->futures) {
165 txt = lives_strdup_printf(_("After this you will need to update using:\n%s\n\n"
166 "Please make a note of this.\n"),
168 label = lives_standard_label_new(txt);
169 lives_box_pack_start(LIVES_BOX(vbox), label, FALSE, TRUE, widget_opts.packing_height);
170 lives_free(txt);
171 }
172}
173
174
175static void scan_for_sets(LiVESWidget *button, livespointer data) {
176 LiVESWidget *entry = (LiVESWidget *)data;
177 LiVESWidget *label =
178 (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(button), "disp_label");
179 LiVESList *list;
180 char *txt;
181 const char *dir = lives_entry_get_text(LIVES_ENTRY(entry));
182 if (dir) list = get_set_list(dir, TRUE);
183 txt = lives_strdup_printf("%d", lives_list_length(list));
184 if (list) lives_list_free_all(&list);
185 lives_label_set_text(LIVES_LABEL(label), txt);
186 lives_free(txt);
187}
188
189
190static void extra_cb(LiVESWidget *dialog, int key) {
191 LiVESWidget *dialog_vbox = lives_dialog_get_content_area(LIVES_DIALOG(dialog));
192 LiVESWidget *bbox = lives_dialog_get_action_area(LIVES_DIALOG(dialog));
193 LiVESWidget *layout, *button, *entry, *hbox, *label;
194 char *tmp;
195 switch (key) {
196 case 1:
199
200 hbox = lives_hbox_new(FALSE, 0);
201 lives_box_pack_start(LIVES_BOX(dialog_vbox), hbox, FALSE, TRUE, 0);
202
204 LIVES_BOX(hbox), NULL);
205
206 layout = lives_layout_new(LIVES_BOX(dialog_vbox));
207 lives_layout_add_fill(LIVES_LAYOUT(layout), TRUE);
208 lives_layout_add_label(LIVES_LAYOUT(layout), _("Sets detected: "), TRUE);
209 label = lives_layout_add_label(LIVES_LAYOUT(layout), _("0"), TRUE);
210
211 lives_layout_add_fill(LIVES_LAYOUT(layout), TRUE);
212 lives_layout_add_fill(LIVES_LAYOUT(layout), TRUE);
213
214 hbox = lives_layout_hbox_new(LIVES_LAYOUT(layout));
215
216 button =
218 _("Scan other directory"), DEF_BUTTON_WIDTH,
219 DEF_BUTTON_HEIGHT, LIVES_BOX(hbox), TRUE,
220 (tmp = lives_strdup(H_("Scan other directories for "
221 "LiVES Clip Sets. May be slow "
222 "for some directories."))));
223 lives_free(tmp);
224 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(button), "disp_label", label);
225 lives_signal_sync_connect(LIVES_GUI_OBJECT(button), LIVES_WIDGET_CLICKED_SIGNAL,
226 LIVES_GUI_CALLBACK(scan_for_sets), entry);
227
228 layout = lives_layout_new(LIVES_BOX(dialog_vbox));
229 widget_opts.justify = LIVES_JUSTIFY_CENTER;
231 lives_layout_add_label(LIVES_LAYOUT(layout), _("If you believe there should be clips in the "
232 "current directory,\n"
233 "you can try to recover them by launching\n"
234 " 'Clean up Diskspace / Recover Missing Clips' "
235 "from the File menu.\n"), FALSE);
239 break;
240 case 2:
241 trash_rb(LIVES_BUTTON_BOX(bbox));
242 break;
243 default: break;
244 }
245}
246
247
248static void del_event_cb(LiVESWidget *dialog, livespointer data) {
249 int key = LIVES_POINTER_TO_INT(data);
250 switch (key) {
251 default: break;
252 }
253}
254
255//Warning or yes/no dialog
256
257// the type of message box here is with 2 or more buttons (e.g. OK/CANCEL, YES/NO, ABORT/CANCEL/RETRY)
258// if a single OK button is needed, use create_message_dialog() in inteface.c instead
259
260LiVESWidget *create_message_dialog(lives_dialog_t diat, const char *text, int warn_mask_number) {
261 LiVESWidget *dialog;
262 LiVESWidget *dialog_vbox;
263 LiVESWidget *label;
264 LiVESWidget *cancelbutton = NULL;
265 LiVESWidget *okbutton = NULL, *defbutton = NULL;
266 LiVESWidget *abortbutton = NULL;
267
268 LiVESAccelGroup *accel_group = NULL;
269 LiVESWindow *transient = widget_opts.transient;
270
271 char *colref;
272
273 int cb_key = extra_cb_key;
274 int del_key = del_cb_key;
275 extra_cb_key = 0;
276 del_cb_key = 0;
277
278 if (!transient) transient = get_transient_full();
279
280 switch (diat) {
282 dialog = lives_message_dialog_new(transient, (LiVESDialogFlags)0,
283 LIVES_MESSAGE_WARNING, LIVES_BUTTONS_NONE, NULL);
284
285 lives_window_set_title(LIVES_WINDOW(dialog), _("Warning !"));
286
288 lives_widget_set_fg_color(dialog, LIVES_WIDGET_STATE_NORMAL, &palette->dark_orange);
289
290 defbutton = okbutton = lives_dialog_add_button_from_stock(LIVES_DIALOG(dialog), LIVES_STOCK_OK, NULL,
291 LIVES_RESPONSE_OK);
292
293 lives_signal_sync_connect(LIVES_GUI_OBJECT(okbutton), LIVES_WIDGET_CLICKED_SIGNAL,
294 LIVES_GUI_CALLBACK(lives_general_button_clicked), NULL);
295
296 break;
298 dialog = lives_message_dialog_new(transient, (LiVESDialogFlags)0,
299 LIVES_MESSAGE_ERROR, LIVES_BUTTONS_NONE, NULL);
301 lives_widget_set_fg_color(dialog, LIVES_WIDGET_STATE_NORMAL, &palette->dark_red);
302
303 lives_window_set_title(LIVES_WINDOW(dialog), _("Error !"));
304
305 defbutton = okbutton = lives_dialog_add_button_from_stock(LIVES_DIALOG(dialog), LIVES_STOCK_OK, NULL,
306 LIVES_RESPONSE_OK);
307
308 lives_signal_sync_connect(LIVES_GUI_OBJECT(okbutton), LIVES_WIDGET_CLICKED_SIGNAL,
309 LIVES_GUI_CALLBACK(lives_general_button_clicked), NULL);
310 break;
312 dialog = lives_message_dialog_new(transient, (LiVESDialogFlags)0,
313 LIVES_MESSAGE_INFO, LIVES_BUTTONS_NONE, NULL);
314
315 lives_window_set_title(LIVES_WINDOW(dialog), _("Information"));
316
318 lives_widget_set_fg_color(dialog, LIVES_WIDGET_STATE_NORMAL, &palette->light_green);
319
320 defbutton = okbutton = lives_dialog_add_button_from_stock(LIVES_DIALOG(dialog), LIVES_STOCK_OK, NULL,
321 LIVES_RESPONSE_OK);
322
323 lives_signal_sync_connect(LIVES_GUI_OBJECT(okbutton), LIVES_WIDGET_CLICKED_SIGNAL,
324 LIVES_GUI_CALLBACK(lives_general_button_clicked), NULL);
325 break;
326
328 dialog = lives_message_dialog_new(transient, (LiVESDialogFlags)0, LIVES_MESSAGE_WARNING,
329 LIVES_BUTTONS_NONE, NULL);
330
332 lives_widget_set_fg_color(dialog, LIVES_WIDGET_STATE_NORMAL, &palette->dark_orange);
333
336 add_clear_ds_button(LIVES_DIALOG(dialog));
337 }
338
339 lives_window_set_title(LIVES_WINDOW(dialog), _("Warning !"));
340
342 lives_widget_set_fg_color(dialog, LIVES_WIDGET_STATE_NORMAL, &palette->dark_orange);
343
344 cancelbutton = lives_dialog_add_button_from_stock(LIVES_DIALOG(dialog), LIVES_STOCK_CANCEL, NULL,
345 LIVES_RESPONSE_CANCEL);
346
347 defbutton = okbutton = lives_dialog_add_button_from_stock(LIVES_DIALOG(dialog), LIVES_STOCK_OK, NULL,
348 LIVES_RESPONSE_OK);
349 break;
350
352 dialog = lives_message_dialog_new(transient, (LiVESDialogFlags)0, LIVES_MESSAGE_QUESTION,
353 LIVES_BUTTONS_NONE, NULL);
354
355 lives_window_set_title(LIVES_WINDOW(dialog), _("Question"));
356
358 lives_widget_set_fg_color(dialog, LIVES_WIDGET_STATE_NORMAL, &palette->light_red);
359
360 cancelbutton = lives_dialog_add_button_from_stock(LIVES_DIALOG(dialog), LIVES_STOCK_NO, NULL,
361 LIVES_RESPONSE_NO);
362
363 defbutton = okbutton = lives_dialog_add_button_from_stock(LIVES_DIALOG(dialog), LIVES_STOCK_YES, NULL,
364 LIVES_RESPONSE_YES);
365 break;
366
368 dialog = lives_message_dialog_new(transient, (LiVESDialogFlags)0, LIVES_MESSAGE_QUESTION,
369 LIVES_BUTTONS_NONE, NULL);
370 // caller will set title and buttons
372 lives_widget_set_fg_color(dialog, LIVES_WIDGET_STATE_NORMAL, &palette->light_red);
373 break;
374
380 dialog = lives_message_dialog_new(transient, (LiVESDialogFlags)0, LIVES_MESSAGE_ERROR, LIVES_BUTTONS_NONE, NULL);
381
382 if (diat != LIVES_DIALOG_RETRY_CANCEL) {
383 abortbutton = lives_dialog_add_button_from_stock(LIVES_DIALOG(dialog),
384 LIVES_STOCK_QUIT, _("_Abort"), LIVES_RESPONSE_ABORT);
385
387 lives_window_set_title(LIVES_WINDOW(dialog), _("File Error"));
388 cancelbutton = lives_dialog_add_button_from_stock(LIVES_DIALOG(dialog), LIVES_STOCK_CANCEL, NULL,
389 LIVES_RESPONSE_CANCEL);
390 okbutton = lives_dialog_add_button_from_stock(LIVES_DIALOG(dialog), LIVES_STOCK_REFRESH,
391 _("_Retry"), LIVES_RESPONSE_RETRY);
392 }
393 if (diat == LIVES_DIALOG_ABORT_OK) {
394 okbutton = lives_dialog_add_button_from_stock(LIVES_DIALOG(dialog), LIVES_STOCK_OK, NULL,
395 LIVES_RESPONSE_OK);
396 }
397 } else {
398 okbutton = lives_dialog_add_button_from_stock(LIVES_DIALOG(dialog), LIVES_STOCK_REFRESH,
399 _("_Retry"), LIVES_RESPONSE_RETRY);
400 }
401 if (diat == LIVES_DIALOG_RETRY_CANCEL) {
402 cancelbutton = lives_dialog_add_button_from_stock(LIVES_DIALOG(dialog), LIVES_STOCK_CANCEL, NULL,
403 LIVES_RESPONSE_CANCEL);
404 }
406 lives_widget_set_fg_color(dialog, LIVES_WIDGET_STATE_NORMAL, &palette->dark_red);
407 break;
408
411 dialog = lives_message_dialog_new(transient, (LiVESDialogFlags)0, LIVES_MESSAGE_ERROR,
412 LIVES_BUTTONS_NONE, NULL);
413
414 lives_window_set_title(LIVES_WINDOW(dialog), _("Missing File or Directory"));
415
417 cancelbutton = lives_dialog_add_button_from_stock(LIVES_DIALOG(dialog), LIVES_STOCK_CANCEL, NULL,
418 LIVES_RESPONSE_CANCEL);
419
421 cancelbutton = lives_dialog_add_button_from_stock(LIVES_DIALOG(dialog), LIVES_STOCK_CANCEL,
422 LIVES_STOCK_LABEL_SKIP, LIVES_RESPONSE_CANCEL);
423
424 okbutton = lives_dialog_add_button_from_stock(LIVES_DIALOG(dialog), LIVES_STOCK_REFRESH,
425 _("_Retry"), LIVES_RESPONSE_RETRY);
426
427 abortbutton = lives_dialog_add_button_from_stock(LIVES_DIALOG(dialog), LIVES_STOCK_QUIT,
428 _("_Browse"), LIVES_RESPONSE_BROWSE);
429
431 lives_widget_set_fg_color(dialog, LIVES_WIDGET_STATE_NORMAL, &palette->dark_red);
432 break;
433
434 default:
435 cancelbutton = abortbutton; // stop compiler complaining
436 return NULL;
437 }
438
439 if (del_key)
440 lives_signal_sync_connect(LIVES_GUI_OBJECT(dialog), LIVES_WIDGET_DESTROY_SIGNAL,
441 LIVES_GUI_CALLBACK(del_event_cb), LIVES_INT_TO_POINTER(del_key));
442
443 lives_window_set_default_size(LIVES_WINDOW(dialog), MIN_MSGBOX_WIDTH, -1);
445
446 lives_window_set_deletable(LIVES_WINDOW(dialog), FALSE);
447 lives_window_set_resizable(LIVES_WINDOW(dialog), FALSE);
448
449 if (mainw && mainw->mgeom)
450 lives_window_set_monitor(LIVES_WINDOW(dialog), widget_opts.monitor);
451
453 lives_dialog_set_has_separator(LIVES_DIALOG(dialog), FALSE);
454 if (palette)
455 lives_widget_set_bg_color(dialog, LIVES_WIDGET_STATE_NORMAL, &palette->normal_back);
456 }
457
459 funkify_dialog(dialog);
460 } else {
461 lives_container_set_border_width(LIVES_CONTAINER(dialog), widget_opts.border_width * 2);
462 }
463
465 widget_opts.last_label = label;
466 colref = gdk_rgba_to_string(&palette->normal_back);
467 set_css_value_direct(label, LIVES_WIDGET_STATE_NORMAL, "",
468 "caret-color", colref);
469 lives_free(colref);
470 dialog_vbox = lives_dialog_get_content_area(LIVES_DIALOG(dialog));
471 lives_box_pack_start(LIVES_BOX(dialog_vbox), label, TRUE, TRUE, 0);
472 lives_label_set_selectable(LIVES_LABEL(label), TRUE);
473
475 add_perminfo(dialog);
476
477 if (mainw) {
478 if (mainw->add_clear_ds_adv) {
480 add_clear_ds_adv(LIVES_BOX(dialog_vbox));
481 }
482
483 if (warn_mask_number > 0) {
484 add_warn_check(LIVES_BOX(dialog_vbox), warn_mask_number);
485 }
486
487 if (mainw->xlays) {
488 add_xlays_widget(LIVES_BOX(dialog_vbox));
489 }
490
492 LiVESWidget *details_button = lives_dialog_add_button_from_stock(LIVES_DIALOG(dialog), NULL, _("Show _Details"),
493 LIVES_RESPONSE_SHOW_DETAILS);
494
495 lives_signal_sync_connect(LIVES_GUI_OBJECT(details_button), LIVES_WIDGET_CLICKED_SIGNAL,
496 LIVES_GUI_CALLBACK(lives_general_button_clicked), NULL);
497 }
498 }
499
500 if (okbutton || cancelbutton) {
501 accel_group = LIVES_ACCEL_GROUP(lives_accel_group_new());
502 lives_window_add_accel_group(LIVES_WINDOW(dialog), accel_group);
503 }
504
505 if (cancelbutton) {
506 lives_widget_add_accelerator(cancelbutton, LIVES_WIDGET_CLICKED_SIGNAL, accel_group,
507 LIVES_KEY_Escape, (LiVESXModifierType)0, (LiVESAccelFlags)0);
508 }
509
510 if (okbutton && mainw && mainw->iochan) {
512 lives_widget_grab_focus(okbutton);
513 } else if (defbutton) lives_button_grab_default_special(defbutton);
514
515 lives_widget_show_all(dialog);
516 //gdk_window_show_unraised(lives_widget_get_xwindow(dialog));
517
518 if (mainw->mgeom)
519 lives_window_center(LIVES_WINDOW(dialog));
520
522 lives_window_set_modal(LIVES_WINDOW(dialog), TRUE);
523
524 if (!transient) {
525 char *wid = lives_strdup_printf("0x%08lx", (uint64_t)LIVES_XWINDOW_XID(lives_widget_get_xwindow(dialog)));
526
528 if (!wid || (capable->has_xdotool == MISSING && capable->has_wmctrl == MISSING) || !activate_x11_window(wid))
529 lives_window_set_keep_above(LIVES_WINDOW(dialog), TRUE);
530 }
531 if (cb_key) extra_cb(dialog, cb_key);
532
533 if (mainw && mainw->add_trash_rb)
534 trash_rb(LIVES_BUTTON_BOX(lives_dialog_get_action_area(LIVES_DIALOG(dialog))));
535
536 return dialog;
537}
538
539
540LIVES_GLOBAL_INLINE LiVESWidget *create_question_dialog(const char *title, const char *text) {
541 LiVESWidget *dialog;
542 char *xtitle = (char *)title;
543 if (!xtitle) xtitle = _("Question");
545 lives_window_set_title(LIVES_WINDOW(dialog), xtitle);
546 if (xtitle != title) lives_free(xtitle);
547 return dialog;
548}
549
550
551boolean do_warning_dialogf(const char *fmt, ...) {
552 va_list xargs;
553 boolean resb;
554 char *textx;
555 va_start(xargs, fmt);
556 textx = lives_strdup_vprintf(fmt, xargs);
557 va_end(xargs);
558 resb = do_warning_dialog_with_check(textx, 0);
559 lives_free(textx);
560 return resb;
561}
562
563
564LIVES_GLOBAL_INLINE boolean do_warning_dialog(const char *text) {
565 return do_warning_dialog_with_check(text, 0);
566}
567
568
569boolean do_warning_dialog_with_check(const char *text, uint64_t warn_mask_number) {
570 // show OK/CANCEL, returns FALSE if cancelled
571 LiVESWidget *warning;
572 int response = 1;
573 char *mytext;
574
575 if (warn_mask_number >= (1ul << 48)) {
576 if (!(prefs->warning_mask & warn_mask_number)) return TRUE;
577 } else {
578 if (prefs->warning_mask & warn_mask_number) return TRUE;
579 }
580
581 mytext = lives_strdup(text); // must copy this because of translation issues
582
583 warning = create_message_dialog(LIVES_DIALOG_WARN_WITH_CANCEL, mytext, warn_mask_number);
584
585 response = lives_dialog_run(LIVES_DIALOG(warning));
586 lives_widget_destroy(warning);
587
589 lives_freep((void **)&mytext);
590
591 return (response == LIVES_RESPONSE_OK);
592}
593
594
595boolean do_yesno_dialog_with_check(const char *text, uint64_t warn_mask_number) {
596 // show YES/NO, returns TRUE for YES
597 LiVESWidget *warning;
598 int response = 1;
599 char *mytext;
600
601 if (warn_mask_number >= (1ul << 48)) {
602 if (!(prefs->warning_mask & warn_mask_number)) return TRUE;
603 } else {
604 if (prefs->warning_mask & warn_mask_number) return TRUE;
605 }
606
607 mytext = lives_strdup(text); // must copy this because of translation issues
608
609 do {
610 warning = create_message_dialog(LIVES_DIALOG_YESNO, mytext, warn_mask_number);
611 response = lives_dialog_run(LIVES_DIALOG(warning));
612 lives_widget_destroy(warning);
613 } while (response == LIVES_RESPONSE_RETRY);
614
616 lives_freep((void **)&mytext);
617
618 return (response == LIVES_RESPONSE_YES);
619}
620
621
623 LiVESWindow *transient = NULL;
624 if (!prefs) return NULL;
625 if (prefs->show_gui) {
626 if (rdet && rdet->dialog) transient = LIVES_WINDOW(rdet->dialog);
627 else if (prefsw && prefsw->prefs_dialog) transient = LIVES_WINDOW(prefsw->prefs_dialog);
628 else if (!rte_window_hidden()) transient = LIVES_WINDOW(rte_window);
629 else if (LIVES_MAIN_WINDOW_WIDGET && mainw->is_ready) transient = LIVES_WINDOW(LIVES_MAIN_WINDOW_WIDGET);
630 }
631 return transient;
632}
633
634
635boolean do_yesno_dialogf(const char *fmt, ...) {
636 // show Yes/No, returns TRUE if Yes
637 LiVESWidget *warning;
638 int response;
639 va_list xargs;
640 char *textx;
641
642 va_start(xargs, fmt);
643 textx = lives_strdup_vprintf(fmt, xargs);
644 va_end(xargs);
645
646 warning = create_message_dialog(LIVES_DIALOG_YESNO, textx, 0);
647 lives_free(textx);
648 response = lives_dialog_run(LIVES_DIALOG(warning));
649 lives_widget_destroy(warning);
651 return (response == LIVES_RESPONSE_YES);
652}
653
654
655boolean do_yesno_dialog(const char *text) {
656 // show Yes/No, returns TRUE if Yes
657 LiVESWidget *warning;
658 int response;
659
660 warning = create_message_dialog(LIVES_DIALOG_YESNO, text, 0);
661 lives_widget_show_all(warning);
662 response = lives_dialog_run(LIVES_DIALOG(warning));
663 lives_widget_destroy(warning);
665 return (response == LIVES_RESPONSE_YES);
666}
667
668
669static LiVESResponseType _do_abort_cancel_retry_dialog(const char *mytext, lives_dialog_t dtype) {
670 LiVESResponseType response;
671 LiVESWidget *warning;
672
673 do {
674 warning = create_message_dialog(dtype, mytext, 0);
675 lives_widget_show_all(warning);
676 response = lives_dialog_run(LIVES_DIALOG(warning)); // looping on retry
677 lives_widget_destroy(warning);
679
680 if (response == LIVES_RESPONSE_ABORT) {
681 if (mainw->is_ready) {
682 if (dtype == LIVES_DIALOG_ABORT || do_abort_check()) {
684 if (cfile->handle) {
685 // stop any processing
687 }
688 }
690 LIVES_FATAL("Aborted");
692 exit(1);
693 }
694 } else {
696 LIVES_FATAL("Aborted");
698 exit(0);
699 }
700 }
701 } while (response == LIVES_RESPONSE_ABORT);
702
703 return response;
704}
705
706
707// returns LIVES_RESPONSE_CANCEL or LIVES_RESPONSE_RETRY
708LIVES_GLOBAL_INLINE LiVESResponseType do_abort_cancel_retry_dialog(const char *text) {
709 return _do_abort_cancel_retry_dialog(text, LIVES_DIALOG_ABORT_CANCEL_RETRY);
710}
711
712
713// always returns LIVES_RESPONSE_RETRY
714LIVES_GLOBAL_INLINE LiVESResponseType do_abort_retry_dialog(const char *text) {
715 return _do_abort_cancel_retry_dialog(text, LIVES_DIALOG_ABORT_RETRY);
716}
717
718
719// always returns LIVES_RESPONSE_OK
720LIVES_GLOBAL_INLINE LiVESResponseType do_abort_ok_dialog(const char *text) {
721 return _do_abort_cancel_retry_dialog(text, LIVES_DIALOG_ABORT_OK);
722}
723
724// does not return
725LIVES_GLOBAL_INLINE void do_abort_dialog(const char *text) {
726 _do_abort_cancel_retry_dialog(text, LIVES_DIALOG_ABORT);
727}
728
729
730LIVES_GLOBAL_INLINE LiVESResponseType do_retry_cancel_dialog(const char *text) {
731 return _do_abort_cancel_retry_dialog(text, LIVES_DIALOG_RETRY_CANCEL);
732}
733
734
735LiVESResponseType do_error_dialogf(const char *fmt, ...) {
736 // show error box
737 LiVESResponseType resi;
738 char *textx;
739 va_list xargs;
740 va_start(xargs, fmt);
741 textx = lives_strdup_vprintf(fmt, xargs);
742 va_end(xargs);
743 resi = do_error_dialog_with_check(textx, 0);
744 lives_free(textx);
745 return resi;
746}
747
748
749LIVES_GLOBAL_INLINE LiVESResponseType do_error_dialog(const char *text) {
750 // show error box
751 return do_error_dialog_with_check(text, 0);
752}
753
754
755static LiVESResponseType _do_info_dialog(const char *text, const char *exp_title, LiVESList *exp_list) {
756 LiVESResponseType ret = LIVES_RESPONSE_NONE;
757 LiVESWidget *info_box = create_message_dialog(LIVES_DIALOG_INFO, text, 0);
758
759 if (exp_list) {
760 LiVESWidget *dab = lives_dialog_get_content_area(LIVES_DIALOG(info_box));
761 add_list_expander(LIVES_BOX(dab), exp_title, ENC_DETAILS_WIN_H, ENC_DETAILS_WIN_V, exp_list);
762 lives_widget_show_all(info_box);
763 }
764
765 if (!widget_opts.non_modal) {
766 ret = lives_dialog_run(LIVES_DIALOG(info_box));
767 }
768
769 return ret;
770}
771
772
773LiVESResponseType do_info_dialogf(const char *fmt, ...) {
774 // show info box
775 LiVESResponseType resi;
776 char *textx;
777 va_list xargs;
778 va_start(xargs, fmt);
779 textx = lives_strdup_vprintf(fmt, xargs);
780 va_end(xargs);
781 resi = _do_info_dialog(textx, NULL, NULL);
782 lives_free(textx);
783 return resi;
784}
785
786
787LIVES_GLOBAL_INLINE LiVESResponseType do_info_dialog(const char *text) {
788 // show info box - blocks until OK is pressed
789 return _do_info_dialog(text, NULL, NULL);
790}
791
792
793LIVES_GLOBAL_INLINE LiVESResponseType do_info_dialog_with_expander(const char *text,
794 const char *exp_text, LiVESList *list) {
795 // show info box - blocks until OK is pressed
796 return _do_info_dialog(text, exp_text, list);
797}
798
799
800LiVESResponseType do_error_dialog_with_check(const char *text, uint64_t warn_mask_number) {
801 // show error box
802 LiVESWidget *err_box;
803 LiVESResponseType ret = LIVES_RESPONSE_NONE;
804
805 if (warn_mask_number >= (1ul << 48)) {
806 if (!(prefs->warning_mask & warn_mask_number)) return TRUE;
807 } else {
808 if (prefs->warning_mask & warn_mask_number) return TRUE;
809 }
810
811 err_box = create_message_dialog(warn_mask_number == 0 ? LIVES_DIALOG_ERROR :
812 LIVES_DIALOG_WARN, text, warn_mask_number);
813
814 if (!widget_opts.non_modal) {
815 ret = lives_dialog_run(LIVES_DIALOG(err_box));
816 }
817
818 return ret;
819}
820
821
822char *ds_critical_msg(const char *dir, char **mountpoint, uint64_t dsval) {
823 char *msg, *msgx, *tmp, *tmp2, *mp, *mpstr;
825 char *dscu = lives_format_storage_space_string(dsval);
826 if (!mountpoint || !*mountpoint) mp = get_mountpoint_for(dir);
827 else mp = *mountpoint;
828 if (mp) {
829 tmp = lives_markup_escape_text(mp, -1);
830 mpstr = lives_strdup_printf("(%s)\n", tmp);
831 lives_free(tmp);
832 } else mpstr = lives_strdup("");
833 tmp = lives_filename_to_utf8(dir, -1, NULL, NULL, NULL);
834 tmp2 = lives_markup_escape_text(tmp, -1);
835 lives_free(tmp);
837 _("<b>FREE SPACE IN THE PARTITION CONTAINING\n%s\n%sHAS FALLEN BELOW THE CRITICAL LEVEL OF %s\n"
838 "CURRENT FREE SPACE IS %s\n</b>\n\n(Disk warning levels can be configured in Preferences / Warnings.)"),
839 tmp2, mpstr, dscr, dscu);
841 lives_free(msg); lives_free(tmp2); lives_free(dscr);
842 lives_free(dscu); lives_free(mpstr);
843 if (mountpoint) {
844 if (!*mountpoint) *mountpoint = mp;
845 } else if (mp) lives_free(mp);
846 return msgx;
847}
848
849
850char *ds_warning_msg(const char *dir, char **mountpoint, uint64_t dsval, uint64_t cwarn, uint64_t nwarn) {
851 char *msg, *msgx, *tmp, *mp, *mpstr;
852 char *dscw = lives_format_storage_space_string(cwarn);
853 char *dscu = lives_format_storage_space_string(dsval);
854 char *dscn = lives_format_storage_space_string(nwarn);
855 if (!mountpoint || !*mountpoint) mp = get_mountpoint_for(dir);
856 else mp = *mountpoint;
857 if (mp) mpstr = lives_strdup_printf("(%s)\n", mp);
858 else mpstr = lives_strdup("");
860 _("Free space in the partition containing\n%s\nhas fallen below the warning level of %s\nCurrent free space is %s\n\n"
861 "(Next warning will be shown at %s. Disk warning levels can be configured in Preferences / Warnings.)"),
862 (tmp = lives_filename_to_utf8(dir, -1, NULL, NULL, NULL)), mpstr, dscw, dscu, dscn);
864 lives_free(msg); lives_free(dscw); lives_free(mpstr);
865 lives_free(dscu); lives_free(dscn);
866 if (mountpoint) {
867 if (!*mountpoint) *mountpoint = mp;
868 } else if (mp) lives_free(mp);
869 return msgx;
870}
871
872
874 char *msg = lives_strdup_printf(_("%s may not be blank.\nClick Abort to exit LiVES immediately or Ok "
875 "to continue with the default value."), what);
877 lives_free(msg);
878}
879
880
882 char *msg = lives_strdup_printf(_("-%s requires an argument, ignoring it\n"), what);
883 LIVES_WARN(msg);
884 lives_free(msg);
885}
886
887
889 char *msg = lives_strdup_printf(_("Errors were encountered when reloading LiVES' copy of the clip %s\n"
890 "Please click Abort if you wish to exit from LiVES,\n"
891 "or OK to update the clip details in LiVES and continue anyway.\n"),
892 IS_VALID_CLIP(fileno) ? mainw->files[fileno]->name : "??????");
894 lives_free(msg);
895 check_storage_space(fileno, FALSE);
896}
897
898
900 do_error_dialog(_("Audio players cannot be switched during playback."));
901}
902
903
904LiVESResponseType do_memory_error_dialog(char *op, size_t bytes) {
905 LiVESResponseType response;
906 char *sizestr, *msg;
907 if (bytes > 0) {
908 sizestr = lives_strdup_printf(_(" with size %ld bytes "), bytes);
909 } else {
910 sizestr = lives_strdup("");
911 }
912 msg = lives_strdup_printf(_("\n\nLiVES encountered a memory error when %s%s.\n"
913 "Click Abort to exit from LiVES, Cancel to abandon the operation\n"
914 "or Retry to try again. You may need to close some other applications first.\n"), op, sizestr);
915 lives_free(sizestr);
916 response = do_abort_cancel_retry_dialog(msg);
917 lives_free(msg);
918 return response;
919}
920
921
922LiVESResponseType handle_backend_errors(boolean can_retry) {
924
925 char **array;
926 char *addinfo;
927 LiVESResponseType response = LIVES_RESPONSE_NONE;
928 int pxstart = 1;
929 int numtok;
930 int i;
931
932 if (mainw->cancelled != CANCEL_NONE) return LIVES_RESPONSE_ACCEPT; // if the user/system cancelled we can expect errors !
933
934 numtok = get_token_count(mainw->msg, '|');
935
936 array = lives_strsplit(mainw->msg, "|", numtok);
937
938 if (numtok > 2 && !strcmp(array[1], "read")) {
940 if (numtok > 3 && *(array[3])) addinfo = array[3];
941 else addinfo = NULL;
942 if (mainw->current_file == -1 || cfile == NULL || !cfile->no_proc_read_errors)
943 do_read_failed_error_s(array[2], addinfo);
944 pxstart = 3;
945 THREADVAR(read_failed) = TRUE;
946 THREADVAR(read_failed_file) = lives_strdup(array[2]);
948 response = LIVES_RESPONSE_CANCEL;
949 }
950
951 else if (numtok > 2 && !strcmp(array[1], "write")) {
953 if (numtok > 3 && *(array[3])) addinfo = array[3];
954 else addinfo = NULL;
955 if (mainw->current_file == -1 || cfile == NULL || !cfile->no_proc_write_errors)
956 do_write_failed_error_s(array[2], addinfo);
957 pxstart = 3;
958 THREADVAR(write_failed) = TRUE;
959 THREADVAR(write_failed_file) = lives_strdup(array[2]);
961 response = LIVES_RESPONSE_CANCEL;
962 }
963
964 else if (numtok > 3 && !strcmp(array[1], "system")) {
966 if (numtok > 4 && *(array[4])) addinfo = array[4];
967 else addinfo = NULL;
968 if (!CURRENT_CLIP_IS_VALID || !cfile->no_proc_sys_errors) {
969 if (numtok > 5 && strstr(addinfo, "_ASKPERM_")) {
973 if (lives_ask_permission(array, numtok, 5)) response = LIVES_RESPONSE_ACCEPT;
974 else {
975 response = LIVES_RESPONSE_CANCEL;
977 goto handled;
978 }
979 } else {
980 boolean trysudo = FALSE;
981 if (addinfo && strstr(addinfo, "_TRY_SUDO_")) trysudo = TRUE;
982 response = do_system_failed_error(array[2], atoi(array[3]), addinfo,
983 can_retry, trysudo);
984 if (response == LIVES_RESPONSE_RETRY) return response;
985 }
986 }
987 pxstart = 3;
989 response = LIVES_RESPONSE_CANCEL;
990 }
991
992 // for other types of errors...more info....
994 lives_snprintf(mainw->msg, MAINW_MSG_SIZE, "\n\n");
995 for (i = pxstart; i < numtok; i++) {
996 if (!*(array[i]) || !strcmp(array[i], "ERROR")) break;
999 }
1000
1001handled:
1002 lives_strfreev(array);
1003
1004 mainw->error = TRUE;
1005 return response;
1006}
1007
1008
1010 // check return code after synchronous (foreground) backend commands
1012
1013 // TODO: consider permitting retry here
1014 if (!strncmp(mainw->msg, "error", 5)) handle_backend_errors(FALSE);
1015
1016 return TRUE;
1017}
1018
1019
1020void pump_io_chan(LiVESIOChannel *iochan) {
1021 // pump data from stdout to textbuffer
1022 char *str_return = NULL;
1023 size_t retlen = 0;
1024 size_t plen;
1025 LiVESTextBuffer *optextbuf = lives_text_view_get_buffer(mainw->optextview);
1026
1027#ifdef GUI_GTK
1028 LiVESError *gerr = NULL;
1029
1030 if (!iochan->is_readable) return;
1031 g_io_channel_read_to_end(iochan, &str_return, &retlen, &gerr);
1032 if (gerr) lives_error_free(gerr);
1033#endif
1034
1035#ifdef GUI_QT
1036 QByteArray qba = iochan->readAll();
1037 str_return = strdup(qba.constData());
1038 retlen = strlen(str_return);
1039#endif
1040 // check each line of str_return, if it contains ptext, (whitespace), then number get the number and set percentage
1041
1042 if (retlen > 0 && mainw->proc_ptr) {
1043 double max;
1044 LiVESAdjustment *adj = lives_scrolled_window_get_vadjustment(LIVES_SCROLLED_WINDOW(((xprocess *)(
1045 mainw->proc_ptr))->scrolledwindow));
1046 lives_text_buffer_insert_at_end(optextbuf, str_return);
1047 max = lives_adjustment_get_upper(adj);
1049
1050 if ((plen = strlen(prefs->encoder.ptext)) > 0) {
1051 boolean linebrk = FALSE;
1052 char *cptr = str_return;
1053 int ispct = 0;
1054
1055 if (prefs->encoder.ptext[0] == '%') {
1056 ispct = 1;
1057 plen--;
1058 }
1059
1060 while (cptr < (str_return + retlen - plen)) {
1061 if (!lives_strncmp(cptr, prefs->encoder.ptext + ispct, plen)) {
1062 cptr += plen;
1063 while (*cptr == ' ' || *cptr == '\n' || *cptr == '=') {
1064 if (*cptr == '\n') {
1065 linebrk = TRUE;
1066 break;
1067 }
1068 cptr++;
1069 }
1070 if (!linebrk) {
1071 if (ispct) mainw->proc_ptr->frames_done = (int)(strtod(cptr, NULL)
1072 * (mainw->proc_ptr->progress_end - mainw->proc_ptr->progress_start + 1.) / 100.);
1073 else mainw->proc_ptr->frames_done = atoi(cptr);
1074 }
1075 break;
1076 }
1077 cptr++;
1078 // *INDENT-OFF*
1079 }}}
1080 // *INDENT-ON*
1081
1082 lives_freep((void **)&str_return);
1083}
1084
1085
1086boolean check_storage_space(int clipno, boolean is_processing) {
1087 // check storage space in prefs->workdir
1088 lives_clip_t *sfile = NULL;
1089
1090 int64_t dsval = -1;
1091
1093 int retval;
1094 boolean did_pause = FALSE;
1095
1096 char *msg, *tmp;
1097 char *pausstr = (_("Processing has been paused."));
1098
1099 if (IS_VALID_CLIP(clipno)) sfile = mainw->files[clipno];
1100
1101 do {
1102 if (mainw->dsu_valid && capable->ds_used > -1) {
1103 dsval = capable->ds_used;
1104 } else if (prefs->disk_quota) {
1106 if (dsval >= 0) capable->ds_used = dsval;
1107 }
1109 capable->ds_free = dsval;
1110 if (ds == LIVES_STORAGE_STATUS_WARNING) {
1111 uint64_t curr_ds_warn = mainw->next_ds_warn_level;
1113 if (mainw->next_ds_warn_level > (dsval >> 1)) mainw->next_ds_warn_level = dsval >> 1;
1115 if (is_processing && sfile && mainw->proc_ptr && !mainw->effects_paused &&
1117 on_effects_paused(LIVES_BUTTON(mainw->proc_ptr->pause_button), NULL);
1118 did_pause = TRUE;
1119 }
1120
1121 tmp = ds_warning_msg(prefs->workdir, &capable->mountpoint, dsval, curr_ds_warn, mainw->next_ds_warn_level);
1122 if (!did_pause)
1123 msg = lives_strdup_printf("\n%s\n", tmp);
1124 else
1125 msg = lives_strdup_printf("\n%s\n%s\n", tmp, pausstr);
1126 lives_free(tmp);
1127 mainw->add_clear_ds_button = TRUE; // gets reset by do_warning_dialog()
1128 if (!do_warning_dialog(msg)) {
1129 lives_free(msg);
1130 lives_free(pausstr);
1132 if (is_processing) {
1133 if (sfile) sfile->nokeep = TRUE;
1134 on_cancel_keep_button_clicked(NULL, NULL); // press the cancel button
1135 }
1136 return FALSE;
1137 }
1138 lives_free(msg);
1139 } else if (ds == LIVES_STORAGE_STATUS_CRITICAL) {
1140 if (is_processing && sfile && mainw->proc_ptr && !mainw->effects_paused &&
1142 on_effects_paused(LIVES_BUTTON(mainw->proc_ptr->pause_button), NULL);
1143 did_pause = TRUE;
1144 }
1146 if (!did_pause)
1147 msg = lives_strdup_printf("\n%s\n", tmp);
1148 else {
1149 char *xpausstr = lives_markup_escape_text(pausstr, -1);
1150 msg = lives_strdup_printf("\n%s\n%s\n", tmp, xpausstr);
1151 lives_free(xpausstr);
1152 }
1153 lives_free(tmp);
1155 retval = do_abort_cancel_retry_dialog(msg);
1157 lives_free(msg);
1158 if (retval == LIVES_RESPONSE_CANCEL) {
1159 if (is_processing) {
1160 if (sfile) sfile->nokeep = TRUE;
1161 on_cancel_keep_button_clicked(NULL, NULL); // press the cancel button
1162 }
1164 lives_free(pausstr);
1165 return FALSE;
1166 }
1167 }
1168 } while (ds == LIVES_STORAGE_STATUS_CRITICAL);
1169
1172 }
1173
1174 if (did_pause && mainw->effects_paused) {
1175 on_effects_paused(LIVES_BUTTON(mainw->proc_ptr->pause_button), NULL);
1176 }
1177
1178 lives_free(pausstr);
1179
1180 return TRUE;
1181}
1182
1183
1184static void cancel_process(boolean visible) {
1185 if (visible) {
1187 if (accelerators_swapped) {
1189 lives_widget_remove_accelerator(mainw->proc_ptr->preview_button, mainw->accel_group, LIVES_KEY_p, (LiVESXModifierType)0);
1190 lives_widget_add_accelerator(mainw->playall, LIVES_WIDGET_ACTIVATE_SIGNAL, mainw->accel_group, LIVES_KEY_p,
1191 (LiVESXModifierType)0,
1192 LIVES_ACCEL_VISIBLE);
1193 }
1194 if (mainw->proc_ptr) {
1197 mainw->proc_ptr = NULL;
1198 }
1200 if (!(cfile->menuentry == NULL)) {
1201 sensitize();
1202 }
1203 } else {
1206 }
1207 if (visible && mainw->current_file > -1 && cfile->clip_type == CLIP_TYPE_DISK && ((mainw->cancelled != CANCEL_NO_MORE_PREVIEW
1209 lives_rm(cfile->info_file);
1210 }
1211}
1212
1213
1214static void disp_fraction(double fraction_done, double timesofar, xprocess * proc) {
1215 // display fraction done and estimated time remaining
1216#ifdef PROGBAR_IS_ENTRY
1217 char *tmp;
1218#endif
1219 char *prog_label;
1220 double est_time;
1221
1222 if (fraction_done > 1.) fraction_done = 1.;
1223 if (fraction_done < 0.) fraction_done = 0.;
1224
1225 if (fraction_done > disp_fraction_done + .0001)
1226 lives_progress_bar_set_fraction(LIVES_PROGRESS_BAR(proc->progressbar), fraction_done);
1227
1228 est_time = timesofar / fraction_done - timesofar;
1229 prog_label = lives_strdup_printf(_("\n%d%% done. Time remaining: %u sec\n"), (int)(fraction_done * 100.),
1230 (uint32_t)(est_time + .5));
1231#ifdef PROGBAR_IS_ENTRY
1232 tmp = lives_strtrim(prog_label);
1233 widget_opts.justify = LIVES_JUSTIFY_CENTER;
1234 lives_entry_set_text(LIVES_ENTRY(mainw->proc_ptr->label3), tmp);
1236 lives_free(tmp);
1237#else
1238 if (LIVES_IS_LABEL(proc->label3)) lives_label_set_text(LIVES_LABEL(proc->label3), prog_label);
1239#endif
1240 lives_free(prog_label);
1241
1242 disp_fraction_done = fraction_done;
1243}
1244
1245
1246static int progress_count;
1247static double progress_speed;
1248static int prog_fs_check;
1249
1250#define PROG_LOOP_VAL 200
1251
1252static void progbar_pulse_or_fraction(lives_clip_t *sfile, int frames_done, double fraction_done) {
1253 double timesofar;
1254
1255 if ((progress_count++ * progress_speed) >= PROG_LOOP_VAL) {
1256 if (frames_done <= mainw->proc_ptr->progress_end && mainw->proc_ptr->progress_end > 0 && !mainw->effects_paused &&
1257 frames_done > 0) {
1258 timesofar = (lives_get_current_ticks() - proc_start_ticks - mainw->timeout_ticks) / TICKS_PER_SECOND_DBL;
1259 if (fraction_done < 0.)
1260 fraction_done = (double)(frames_done - mainw->proc_ptr->progress_start)
1261 / (double)(mainw->proc_ptr->progress_end - mainw->proc_ptr->progress_start + 1.);
1262 disp_fraction(fraction_done, timesofar, mainw->proc_ptr);
1263 progress_count = 0;
1264 progress_speed = 4.;
1265 } else {
1266 lives_progress_bar_pulse(LIVES_PROGRESS_BAR(mainw->proc_ptr->progressbar));
1267 progress_count = 0;
1268 if (!mainw->is_rendering) progress_speed = 2.;
1269 }
1270 }
1272}
1273
1274
1275void update_progress(boolean visible) {
1276 double fraction_done, timesofar;
1277 static double est_time = 0., frac_done = -1;
1278 char *prog_label;
1279
1280 if (cfile->opening && cfile->clip_type == CLIP_TYPE_DISK && !cfile->opening_only_audio &&
1281 (cfile->hsize > 0 || cfile->vsize > 0 || cfile->frames > 0) && (!mainw->effects_paused || !shown_paused_frames)) {
1282 uint32_t apxl;
1283 ticks_t currticks = lives_get_current_ticks();
1284 if ((currticks - last_open_check_ticks) > OPEN_CHECK_TICKS *
1285 ((apxl = get_approx_ln((uint32_t)cfile->opening_frames)) < 50 ? apxl : 50) ||
1286 (mainw->effects_paused && !shown_paused_frames)) {
1287 mainw->proc_ptr->frames_done = cfile->end = cfile->opening_frames = get_frame_count(mainw->current_file,
1288 cfile->opening_frames > 1 ? cfile->opening_frames : 1);
1289 last_open_check_ticks = currticks;
1290 if (cfile->opening_frames > 1) {
1291 if (cfile->frames > 0 && cfile->frames != 123456789) {
1292 fraction_done = (double)(cfile->opening_frames - 1.) / (double)cfile->frames;
1293 if (fraction_done > 1.) fraction_done = 1.;
1294 if (!mainw->effects_paused) {
1295 timesofar = (currticks - proc_start_ticks - mainw->timeout_ticks) / TICKS_PER_SECOND_DBL;
1296 est_time = timesofar / fraction_done - timesofar;
1297 }
1298 lives_progress_bar_set_fraction(LIVES_PROGRESS_BAR(mainw->proc_ptr->progressbar), fraction_done);
1299 if (est_time != -1.) prog_label = lives_strdup_printf(_("\n%d/%d frames opened. Time remaining %u sec.\n"),
1300 cfile->opening_frames - 1, cfile->frames, (uint32_t)(est_time + .5));
1301 else prog_label = lives_strdup_printf(_("\n%d/%d frames opened.\n"), cfile->opening_frames - 1, cfile->frames);
1302 } else {
1303 lives_progress_bar_pulse(LIVES_PROGRESS_BAR(mainw->proc_ptr->progressbar));
1304 prog_label = lives_strdup_printf(_("\n%d frames opened.\n"), cfile->opening_frames - 1);
1305 }
1306#ifdef PROGBAR_IS_ENTRY
1307 widget_opts.justify = LIVES_JUSTIFY_CENTER;
1308 lives_entry_set_text(LIVES_ENTRY(mainw->proc_ptr->label3), prog_label);
1310#else
1311 lives_label_set_text(LIVES_LABEL(mainw->proc_ptr->label3), prog_label);
1312#endif
1313 lives_free(prog_label);
1314 cfile->start = cfile->end > 0 ? 1 : 0;
1315 showclipimgs();
1316 }
1317 }
1318 shown_paused_frames = mainw->effects_paused;
1319 } else {
1320 if (visible && mainw->proc_ptr->frames_done >= mainw->proc_ptr->progress_start) {
1321 if (progress_count == 0) check_storage_space(mainw->current_file, TRUE);
1322 // display progress fraction or pulse bar
1323 progbar_pulse_or_fraction(cfile, mainw->proc_ptr->frames_done, frac_done);
1324 //sched_yield();
1325 lives_usleep(prefs->sleep_time);
1326 }
1327 }
1328}
1329
1330//#define SHOW_CACHE_PREDICTIONS
1331
1332#define ENABLE_PRECACHE
1333static short scratch = SCRATCH_NONE;
1334
1335#define ANIM_LIM 1000000
1336
1337int process_one(boolean visible) {
1338 // INTERNAL PLAYER
1339 static frames_t last_req_frame = 0;
1340 static int last_pwidth = 0, last_pheight = 0;
1341 static int64_t last_seek_pos = 0;
1342 lives_clip_t *sfile = cfile;
1343 _vid_playback_plugin *old_vpp;
1344 ticks_t new_ticks;
1345 lives_time_source_t time_source;
1346 frames_t requested_frame = 0;
1347 boolean show_frame = FALSE;
1348 boolean did_switch = FALSE;
1349 int old_current_file, old_playing_file;
1350#ifdef ENABLE_PRECACHE
1351 int delta = 0;
1352#endif
1353 int aplay_file = 0;
1354#ifdef RT_AUDIO
1355 double audio_stretch = 1.0;
1356 ticks_t audio_ticks = 0;
1357#endif
1358 old_current_file = mainw->current_file;
1359
1360 if (visible) goto proc_dialog;
1361
1362 sfile = mainw->files[mainw->playing_file];
1363
1364 old_playing_file = mainw->playing_file;
1365 old_vpp = mainw->vpp;
1366
1367 // time is obtained as follows:
1368 // - if there is an external transport or clock active, we take our time from that
1369 // - else if we have a fixed output framerate (e.g. we are streaming) we take our time from
1370 // the system clock
1371 // in these cases we adjust our audio rate slightly to keep in synch with video
1372 // - otherwise, we take the time from soundcard by counting samples played (the normal case),
1373 // and we synch video with that; however, the soundcard time only updates when samples are played -
1374 // so, between updates we interpolate with the system clock and then adjust when we get a new value
1375 // from the card
1376 //g_print("process_one @ %f\n", lives_get_current_ticks() / TICKS_PER_SECOND_DBL);
1377
1378 time_source = LIVES_TIME_SOURCE_NONE;
1379
1381 if (mainw->currticks == -1) {
1384 return mainw->cancelled;
1385 }
1386
1387 if (init_timers) {
1388 init_timers = FALSE;
1392 last_req_frame = sfile->frameno - 1;
1393 getahead = test_getahead = -1;
1394 mainw->actual_frame = sfile->frameno;
1396 last_anim_ticks = mainw->currticks;
1397 }
1398
1399 /* if (mainw->wall_ticks > last_cpuload_ticks + 10 * TICKS_PER_SECOND_DBL) { */
1400 /* g_print("CPU LOAD IS %.4f\n", (double)get_cpu_load(0) / 10000.); */
1401 /* last_cpuload_ticks = mainw->wall_ticks; */
1402 /* } */
1403
1404 mainw->audio_stretch = 1.0;
1405
1406#define ADJUST_AUDIO_RATE
1407#ifdef ADJUST_AUDIO_RATE
1408 // adjust audio rate slightly if we are behind or ahead
1409 // shouldn't need this since normally we sync video to soundcard
1410 // - unless we are controlled externally (e.g. jack transport) or system clock is forced
1411 if (time_source != LIVES_TIME_SOURCE_SOUNDCARD) {
1412#ifdef ENABLE_JACK
1415 sfile->achans > 0 && (!mainw->is_rendering || (mainw->multitrack && !mainw->multitrack->is_rendering)) &&
1416 (mainw->currticks - mainw->offsetticks) > TICKS_PER_SECOND * 10 && ((audio_ticks = lives_jack_get_time(mainw->jackd)) >
1417 mainw->offsetticks || audio_ticks == -1)) {
1418 if (audio_ticks == -1) {
1419 if (mainw->cancelled == CANCEL_NONE) {
1422 return mainw->cancelled;
1423 }
1424 }
1425 if ((audio_stretch = (double)(audio_ticks - mainw->offsetticks) / (double)(mainw->currticks - mainw->offsetticks)) < 2. &&
1426 audio_stretch > 0.5) {
1427 // if audio_stretch is > 1. it means that audio is playing too fast
1428 // < 1. it is playing too slow
1429
1430 // if too fast we increase the apparent sample rate so that it gets downsampled more
1431 // if too slow we decrease the apparent sample rate so that it gets upsampled more
1432 mainw->audio_stretch = audio_stretch;
1433 }
1434 }
1435#endif
1436
1437#ifdef HAVE_PULSE_AUDIO
1440 sfile->achans > 0 && (!mainw->is_rendering || (mainw->multitrack && !mainw->multitrack->is_rendering)) &&
1442 ((audio_ticks = lives_pulse_get_time(mainw->pulsed)) >
1443 mainw->offsetticks || audio_ticks == -1)) {
1444 if (audio_ticks == -1) {
1445 if (mainw->cancelled == CANCEL_NONE) {
1446 if (sfile && !sfile->is_loaded) mainw->cancelled = CANCEL_NO_PROPOGATE;
1448 return mainw->cancelled;
1449 }
1450 }
1451 // fps is synched to external source, so we adjust the audio rate to fit
1452 if ((audio_stretch = (double)(audio_ticks - mainw->offsetticks) / (double)(mainw->clock_ticks
1453 + mainw->offsetticks)) < 2. && audio_stretch > 0.5) {
1454 // if audio_stretch is > 1. it means that audio is playing too fast
1455 // < 1. it is playing too slow
1456
1457 // if too fast we increase the apparent sample rate so that it gets downsampled more
1458 // if too slow we decrease the apparent sample rate so that it gets upsampled more
1459 mainw->audio_stretch = audio_stretch;
1460 }
1461 }
1462#endif
1463 }
1464#endif
1465
1467
1472
1473 // we allow an exception only when starting or stopping a generator
1474
1475 if (mainw->current_file != old_current_file || mainw->playing_file != old_playing_file || mainw->vpp != old_vpp) {
1476 if (!mainw->ignore_clipswitch) {
1478 return FALSE;
1479 }
1480 old_current_file = mainw->current_file;
1481 old_playing_file = mainw->playing_file;
1483 }
1484
1485 if (mainw->new_vpp) {
1487 mainw->new_vpp = NULL;
1488 old_vpp = mainw->vpp;
1489 }
1490
1491switch_point:
1492
1493 mainw->noswitch = FALSE;
1494
1495 if (mainw->new_clip != -1) {
1496 mainw->deltaticks = 0;
1497
1499 if (sfile->arate)
1500 /* g_print("HIB %d %d %d %d %ld %f %f %ld %ld %d %f\n", sfile->frameno, last_req_frame, mainw->playing_file, */
1501 /* aplay_file, sfile->aseek_pos, */
1502 /* sfile->fps * lives_pulse_get_pos(mainw->pulsed) + 1., (double)sfile->aseek_pos */
1503 /* / (double)sfile->arps / 4. * sfile->fps + 1., */
1504 /* mainw->currticks, mainw->startticks, sfile->arps, sfile->fps); */
1505
1506 sfile->frameno = sfile->last_frameno = last_req_frame + sig(sfile->pb_fps);
1507
1511 mainw->frame_layer_preload = NULL;
1512 cleanup_preload = FALSE;
1513 }
1514
1515 //g_print("ASEEK is %ld\n", sfile->aseek_pos);
1516 }
1517
1519 did_switch = TRUE;
1520
1522 if (IS_VALID_CLIP(mainw->new_clip)) goto switch_point;
1524 cancel_process(visible);
1525 return ONE_MILLION + mainw->cancelled;
1526 }
1527
1528 sfile = mainw->files[mainw->playing_file];
1529 sfile->last_frameno = sfile->frameno;
1530
1531 /* if (sfile->arate) */
1532 /* g_print("HIB2 %d %d %d %d %d %ld %f %f %ld %ld %d %f\n", mainw->actual_frame, sfile->frameno, last_req_frame, */
1533 /* mainw->playing_file, aplay_file, sfile->aseek_pos, */
1534 /* sfile->fps * lives_pulse_get_pos(mainw->pulsed) + 1., */
1535 /* (double)sfile->aseek_pos / (double)sfile->arate / 4. * sfile->fps + 1., */
1536 /* mainw->currticks, mainw->startticks, sfile->arps, sfile->fps); */
1537
1538 cache_hits = cache_misses = 0;
1541 mainw->new_clip = -1;
1542 mainw->blend_palette = WEED_PALETTE_END;
1543 getahead = -1;
1545 // TODO: add a few to bungle_frames in case of decoder unchilling
1546
1548 // this may be adjusted for accuracy | a value > 1.0 will slow audio down on switch
1549#define SWITCH_COMPENSATION 1.0
1550
1552 scratch = SCRATCH_JUMP_NORESYNC;
1553 drop_off = TRUE;
1554 last_req_frame = sfile->frameno - 1;
1556 old_current_file = mainw->current_file;
1557 old_playing_file = mainw->playing_file;
1558
1559 /* if (sfile->arate) */
1560 /* g_print("seek vals: vid %d %ld = %f %d %f\n", sfile->frameno, sfile->aseek_pos, */
1561 /* (double)sfile->aseek_pos / (double)sfile->arate / 4. * sfile->fps + 1., */
1562 /* sfile->arate, sfile->fps); */
1563 }
1564
1565 mainw->noswitch = TRUE;
1566
1568
1569 // playing back an event_list
1570 // here we need to add mainw->offsetticks, to get the correct position whe playing back in multitrack
1571 if (!mainw->proc_ptr && cfile->next_event) {
1572 // playing an event_list
1574#ifdef ENABLE_JACK_TRANSPORT
1575
1576 // handle transport jump in multitrack : end current playback and restart it from the new position
1577 // TODO: retest this and enable in the clip_editor
1578 ticks_t transtc = q_gint64(jack_transport_get_current_ticks(), cfile->fps);
1579 mainw->multitrack->pb_start_event = get_frame_event_at(mainw->multitrack->event_list, transtc, NULL, TRUE);
1581#endif
1582 } else {
1583 if (mainw->multitrack) mainw->currticks += mainw->offsetticks; // add the offset of playback start time
1584 if (mainw->currticks >= event_start) {
1585 // see if we are playing a selection and reached the end
1586 if (mainw->multitrack && mainw->multitrack->playing_sel &&
1589 else {
1590 mainw->noswitch = FALSE;
1591 cfile->next_event = process_events(cfile->next_event, FALSE, mainw->currticks);
1592 mainw->noswitch = TRUE;
1593 if (!cfile->next_event) mainw->cancelled = CANCEL_EVENT_LIST_END;
1594 }
1595 }
1596 }
1597
1599
1600 if (mainw->cancelled == CANCEL_NONE) return 0;
1601 cancel_process(visible);
1602 return mainw->cancelled;
1603 }
1604
1605 // free playback
1606
1607 //#define SHOW_CACHE_PREDICTIONS
1608#define TEST_TRIGGER 9999
1609
1611#define DROPFRAME_TRIGGER 4
1612#define JUMPFRAME_TRIGGER 99999999 // we should retain cdata->jump_limit from the initial file open
1613
1614 if (mainw->currticks - last_kbd_ticks > KEY_RPT_INTERVAL * 100000) {
1615 // if we have a cached key (ctrl-up, ctrl-down, ctrl-left, crtl-right) trigger it here
1616 // this is to avoid the keyboard repeat delay (dammit !) so we get smooth trickplay
1617 // BUT we need a timer sufficiently large so it isn't triggered on every loop, to produce a constant repeat rate
1618 // but not so large so it doesn't get triggered enough
1619 if (last_kbd_ticks > 0) handle_cached_keys();
1620 last_kbd_ticks = mainw->currticks;
1621 }
1622
1623 new_ticks = mainw->currticks;
1624 if (mainw->scratch != SCRATCH_JUMP)
1625 if (new_ticks < mainw->startticks) new_ticks = mainw->startticks;
1626
1627 show_frame = FALSE;
1628 requested_frame = sfile->frameno;
1629
1630 if (sfile->pb_fps != 0.) {
1631 // calc_new_playback_postion returns a frame request based on the player mode and the time delta
1632 //
1633 // mainw->startticks is the timecode of the last frame shown
1634 // new_ticks is the (adjusted) current time
1635 // sfile->last_frameno, sfile->pb_fps (if playing) or sfile->fps (if not) are also used in the calculation
1636 // as well as selection bounds and loop mode settings (if appropriate)
1637 //
1638 // on return, new_ticks is set to either mainw->starticks or the timecode of the next frame to show
1639 // which will be <= the current time
1640 // and requested_frame is set to the frame to show. By default this is the frame we show, but we may vary
1641 // this depending on the cached frame
1642
1643 requested_frame = calc_new_playback_position(mainw->current_file, mainw->startticks, &new_ticks);
1644 if (mainw->foreign) {
1645 if (requested_frame > sfile->frameno) {
1646 load_frame_image(sfile->frameno++);
1647 }
1649 if (mainw->cancelled != CANCEL_NONE) return mainw->cancelled;
1650 return 0;
1651 }
1652 if (requested_frame < 1 || requested_frame > sfile->frames)
1653 requested_frame = sfile->frameno;
1654 else sfile->frameno = requested_frame;
1655
1656 if (mainw->scratch != SCRATCH_NONE) scratch = mainw->scratch;
1658
1659#ifdef ENABLE_PRECACHE
1660 if (scratch != SCRATCH_NONE) {
1661 getahead = test_getahead = -1;
1662 cleanup_preload = TRUE;
1663 mainw->pred_frame = -1;
1664 // fix for a/v sync
1665 if (!did_switch) sfile->last_play_sequence = mainw->play_sequence;
1666 }
1667#endif
1668
1669 if (new_ticks != mainw->startticks && new_ticks != mainw->last_startticks
1670 && (requested_frame != last_req_frame || sfile->frames == 1
1671 || (mainw->playing_sel && sfile->start == sfile->end))) {
1672 //g_print("%ld %ld %ld %d %d %d\n", mainw->currticks, mainw->startticks, new_ticks,
1673 //sfile->last_frameno, requested_frame, last_req_frame);
1674 if (mainw->fixed_fpsd <= 0. && (!mainw->vpp || mainw->vpp->fixed_fpsd <= 0. || !mainw->ext_playback)) {
1675 show_frame = TRUE;
1676 }
1677 if (prefs->show_dev_opts) jitter = (double)(mainw->currticks - new_ticks) / TICKS_PER_SECOND_DBL;
1678#ifdef ENABLE_PRECACHE
1679 if (test_getahead > 0) {
1680 if (recalc_bungle_frames) {
1688 // and keep reshowing it until the time catches up.
1692 // ..'bungle frames' is a rough estimate of how far ahead we need to jump so that we land exaclty
1699 int dir = sig(sfile->pb_fps);
1700 delta = (test_getahead - requested_frame) * dir;
1701#ifdef SHOW_CACHE_PREDICTIONS
1702 g_print("gah (%d) %d, act %d %d, bungle %d, shouldabeen %d %s", mainw->effort, test_getahead,
1703 sfile->frameno, requested_frame,
1704 bungle_frames, bungle_frames - delta, getahead == -1 ? "(calibrating)" : "");
1705 if (delta < 0) g_print(" !!!!!\n");
1706 if (delta == 0) g_print(" EXACT\n");
1707 if (delta > 0) g_print(" >>>>\n");
1708#endif
1709 if (delta == 0) bungle_frames++;
1710 if (delta > 0 && delta < 3 && bungle_frames > 1) bungle_frames--;
1711 else bungle_frames += (requested_frame - test_getahead) * dir;
1712 if (bungle_frames <= -dir) bungle_frames = 0;
1713 if (delta >= 0 && getahead > -1) drop_off = TRUE;
1714 }
1715 recalc_bungle_frames = FALSE;
1716 test_getahead = -1;
1717 }
1718#endif
1719
1720#ifdef USE_GDK_FRAME_CLOCK
1721 if (display_ready) {
1722 show_frame = TRUE;
1724 display_ready = FALSE;
1725 }
1726#endif
1727 }
1728 }
1729
1730 // play next frame
1731 if (LIVES_LIKELY(mainw->cancelled == CANCEL_NONE)) {
1732 // calculate the audio 'frame' for non-realtime audio players
1733 // for realtime players, we did this in calc_new_playback_position()
1735 if (LIVES_UNLIKELY(mainw->loop_cont && (mainw->aframeno > (mainw->audio_end ? mainw->audio_end :
1736 sfile->laudio_time * sfile->fps)))) {
1738 }
1739 }
1740
1741 if (mainw->force_show) {
1742 show_frame = TRUE;
1743 } else {
1744 if (mainw->fixed_fpsd > 0. || (mainw->vpp && mainw->vpp->fixed_fpsd > 0. && mainw->ext_playback)) {
1745 ticks_t dticks;
1747 if ((mainw->fixed_fpsd > 0. && (dticks >= 1. / mainw->fixed_fpsd)) ||
1748 (mainw->vpp && mainw->vpp->fixed_fpsd > 0. && mainw->ext_playback &&
1749 dticks >= 1. / mainw->vpp->fixed_fpsd)) {
1750 show_frame = TRUE;
1751 }
1752 }
1753 }
1754
1755 if (show_frame) {
1756 // time to show a new frame
1757 last_spare_cycles = spare_cycles;
1758 dropped = 0;
1761 if (scratch != SCRATCH_NONE || getahead > -1 || drop_off) dropped = 0;
1762 else {
1763 if (mainw->frame_layer_preload && !cleanup_preload && mainw->pred_clip == mainw->playing_file
1764 && mainw->pred_frame != 0 && (labs(mainw->pred_frame) - mainw->actual_frame) * sig(sfile->pb_fps) > 0
1766 dropped = ABS(requested_frame - mainw->pred_frame) - 1;
1767 else
1768 dropped = ABS(requested_frame - mainw->actual_frame) - 1;
1769 if (dropped < 0) dropped = 0;
1770 }
1771#ifdef ENABLE_PRECACHE
1772 if (getahead > -1) {
1773 if (mainw->pred_frame == -getahead) {
1775 sfile->frameno = mainw->pred_frame = -mainw->pred_frame;
1776 } else {
1777 if (mainw->pred_frame == getahead) {
1778 if ((sfile->pb_fps > 0. && sfile->frameno >= getahead)
1779 || (sfile->pb_fps < 0. && sfile->frameno <= getahead)) {
1780 if (sfile->frameno != getahead) {
1781 getahead = -1;
1782 mainw->pred_frame = 0;
1783 cleanup_preload = TRUE;
1784 if (sfile->pb_fps > 0.)
1785 sfile->last_frameno = requested_frame;
1786 drop_off = FALSE;
1787 }
1788 } else {
1789 sfile->frameno = getahead;
1790 // *INDENT-OFF*
1791 }}}}
1792 // *INDENT-ON*
1793 else {
1795 if (sfile->clip_type == CLIP_TYPE_FILE && scratch == SCRATCH_NONE
1797 && dropped > 0 && ((sfile->pb_fps < 0. && !clip_can_reverse(mainw->playing_file))
1798 || abs(sfile->frameno - sfile->last_vframe_played) >= JUMPFRAME_TRIGGER
1799 || dropped >= MIN(TEST_TRIGGER, DROPFRAME_TRIGGER))) {
1800#ifdef SHOW_CACHE_PREDICTIONS
1801 if (abs(sfile->frameno - sfile->last_vframe_played) >= JUMPFRAME_TRIGGER) {
1802 lives_clip_data_t *cdata = ((lives_decoder_t *)sfile->ext_src)->cdata;
1803 if (cdata) {
1804 g_print("decoder: seek flags = %d, jump_limit = %ld, max_fps = %.4f\n", cdata->seek_flag,
1805 cdata->jump_limit, cdata->max_decode_fps);
1806 g_print("vframe jump will be %d\n", requested_frame - sfile->last_vframe_played);
1807 }
1808 }
1809#endif
1810 dir = LIVES_DIRECTION_SIG(sfile->pb_fps);
1811 if (bungle_frames <= -dir || bungle_frames == 0) bungle_frames = dir;
1812 //bungle_frames += requested_frame - mainw->actual_frame - dir;
1813 test_getahead = requested_frame + bungle_frames * dir;
1814 if (test_getahead < 1 || test_getahead > sfile->frames) test_getahead = -1;
1815 else {
1816#ifdef SHOW_CACHE_PREDICTIONS
1817 g_print("getahead jumping to %d\n", test_getahead);
1818#endif
1819 recalc_bungle_frames = TRUE;
1820 if (dropped > 0 && delta <= 0 && ((sfile->pb_fps < 0. && (!clip_can_reverse(mainw->current_file)))
1821 || (abs(sfile->frameno - sfile->last_vframe_played) >= JUMPFRAME_TRIGGER)
1822 || dropped >= DROPFRAME_TRIGGER)) {
1823 getahead = test_getahead;
1824 if (mainw->pred_frame > 0 && (mainw->pred_frame - mainw->actual_frame) * dir > 0
1826 sfile->frameno = mainw->pred_frame;
1827 else sfile->frameno = getahead;
1828 // *INDENT-OFF*
1829 }}}
1830 // *INDENT-ON*
1831#else
1832 if (1) {
1833#endif
1834 }
1835
1836#ifdef HAVE_PULSE_AUDIO
1838 if (getahead < 0 && new_ticks != mainw->startticks
1839 && (!mainw->pulsed || (mainw->pulsed->seek_pos == last_seek_pos
1840 && CLIP_HAS_AUDIO(mainw->pulsed->playing_file)))) {
1841 mainw->startticks = new_ticks;
1842 sfile->frameno = mainw->actual_frame;
1843 }
1844 }
1845#endif
1846
1847#ifdef ENABLE_PRECACHE
1848 if (mainw->pred_clip == -1) {
1850 mainw->frame_layer_preload = NULL;
1851 cleanup_preload = FALSE;
1852 } else if (cleanup_preload) {
1856 mainw->frame_layer_preload = NULL;
1857 cleanup_preload = FALSE;
1858 }
1860 cleanup_preload = FALSE;
1861 }
1862 }
1863
1864 if (mainw->frame_layer_preload && !cleanup_preload) {
1865 if (mainw->pred_clip == mainw->current_file) {
1866 frames_t pframe = labs(mainw->pred_frame);
1867 if (((sfile->pb_fps > 0. && pframe >= mainw->actual_frame &&
1868 (pframe <= requested_frame || is_virtual_frame(mainw->playing_file, sfile->frameno))) ||
1869 (sfile->pb_fps < 0. && pframe <= mainw->actual_frame &&
1870 (pframe >= requested_frame || is_virtual_frame(mainw->playing_file, sfile->frameno))))
1871 && ((getahead > -1 || pframe == requested_frame || is_layer_ready(mainw->frame_layer_preload)))) {
1872 sfile->frameno = pframe;
1873 }
1874 if (pframe == sfile->frameno) cache_hits++;
1875 else if (getahead == -1) {
1876 if ((sfile->pb_fps > 0. && pframe <= mainw->actual_frame)
1877 || (sfile->pb_fps < 0. && pframe >= mainw->actual_frame)) {
1878 cleanup_preload = TRUE;
1879 if (pframe != mainw->actual_frame) {
1880#ifdef SHOW_CACHE_PREDICTIONS
1881 g_print("WASTED cache frame %ld !!!! range was %d to %d or was not ready\n",
1883 sfile->frameno);
1884#endif
1885 cache_misses++;
1886 }
1887 // *INDENT-OFF*
1888 }}}}
1889 // *INDENT-ON*
1890
1892 sfile->last_vframe_played = sfile->frameno;
1893#endif
1894 }
1895
1896 if (prefs->pbq_adaptive && scratch == SCRATCH_NONE) {
1897 if (requested_frame != last_req_frame) {
1899 if (dropped > 0) update_effort(abs(requested_frame - last_req_frame - 1), TRUE);
1900 update_effort(spare_cycles + 1, FALSE);
1901 }
1902 }
1903
1904 if (getahead < 0) {
1907 // and keep repeating getahead until we reach it
1909 sfile->last_frameno = requested_frame;
1910 // set
1911 if (new_ticks > mainw->startticks) mainw->startticks = new_ticks;
1912 if (scratch != SCRATCH_NONE) {
1915 }
1916 }
1917
1919
1920#ifdef SHOW_CACHE_PREDICTIONS
1921 //g_print("dropped = %d, %d scyc = %ld %d %d\n", dropped, mainw->effort, spare_cycles, requested_frame, sfile->frameno);
1922#endif
1923 if (mainw->pwidth != last_pwidth || mainw->pheight != last_pheight) {
1924 mainw->pred_frame = 0;
1925 cleanup_preload = TRUE;
1926 getahead = -1;
1927 }
1928
1929 drop_off = FALSE;
1930 last_pwidth = mainw->pwidth;
1931 last_pheight = mainw->pheight;
1932 if (mainw->force_show || ((sfile->frameno != mainw->actual_frame || (sfile->frames == 1 && sfile->frameno == 1)
1933 || (mainw->playing_sel && sfile->start == sfile->end))
1934#ifdef ENABLE_PRECACHE
1935 && getahead < 0)
1936 || (getahead > -1 && mainw->frame_layer_preload && !cleanup_preload && requested_frame != last_req_frame
1937#endif
1938 )) {
1939 spare_cycles = 0;
1940 mainw->record_frame = requested_frame;
1941
1944#ifdef ENABLE_JACK
1945 // note the audio seek position
1947 aplay_file = mainw->jackd->playing_file;
1948 if (IS_VALID_CLIP(aplay_file)) {
1949 int qnt = mainw->files[aplay_file]->achans * (mainw->files[aplay_file]->asampsize >> 3);
1950 mainw->files[aplay_file]->aseek_pos =
1951 (double)((off_t)((double) mainw->jackd->seek_pos / (double)mainw->files[aplay_file]->arps
1952 / (mainw->files[aplay_file]->achans * mainw->files[aplay_file]->asampsize / 8)
1953 * mainw->files[aplay_file]->fps + .5)) / mainw->files[aplay_file]->fps
1954 * mainw->files[aplay_file]->arps * qnt;
1955 }
1956 }
1957#endif
1958
1959#ifdef HAVE_PULSE_AUDIO
1960 // note the audio seek position
1962 aplay_file = mainw->pulsed->playing_file;
1963 if (IS_VALID_CLIP(aplay_file)) {
1964 int qnt = mainw->files[aplay_file]->achans * (mainw->files[aplay_file]->asampsize >> 3);
1965 mainw->files[aplay_file]->aseek_pos = (int64_t)((double)((frames_t)((((double)mainw->pulsed->seek_pos
1966 / (double)mainw->files[aplay_file]->arps / (double)qnt)
1967 - ((double)(mainw->currticks - new_ticks) / TICKS_PER_SECOND_DBL))
1968 * mainw->files[aplay_file]->fps))
1969 / mainw->files[aplay_file]->fps * (double)mainw->files[aplay_file]->arps) * qnt;
1970
1971 /* g_print("SPOS = %ld %d %d %ld %f\n", mainw->currticks, mainw->files[aplay_file]->frameno, */
1972 /* requested_frame, mainw->pulsed->seek_pos, */
1973 /* (double) mainw->pulsed->seek_pos / (double)mainw->files[aplay_file]->arps / 4. * mainw->files[aplay_file]->fps + 1.); */
1974 }
1975 }
1976#endif
1977
1978#if 0
1980 aplay_file = mainw->nullaudio->playing_file;
1981 if (IS_VALID_CLIP(aplay_file))
1982 mainw->files[aplay_file]->aseek_pos = nullaudio_get_seek_pos();
1983 }
1984#endif
1985
1986 // load and display the new frame
1987#ifdef SHOW_CACHE_PREDICTIONS
1988 g_print("playing frame %d / %d at %ld (%ld : %ld) %.2f %ld %ld\n", sfile->frameno, requested_frame, mainw->currticks,
1989 mainw->startticks, new_ticks, (mainw->pulsed->in_use && IS_VALID_CLIP(mainw->pulsed->playing_file)
1990 && mainw->files[mainw->pulsed->playing_file]->arate != 0)
1991 ? (double)mainw->pulsed->seek_pos
1992 / (double)mainw->files[mainw->pulsed->playing_file]->arate / 4. * sfile->fps + 1. : 0. * sfile->fps + 1,
1994 last_seek_pos = mainw->pulsed->seek_pos;
1995#endif
1996
1997 load_frame_image(sfile->frameno);
1999 if (prefs->show_player_stats) {
2000 mainw->fps_measure++;
2001 }
2002
2004 mainw->actual_frame = sfile->frameno;
2006 } // end load_frame_image()
2007
2008 else spare_cycles++;
2009
2010 last_req_frame = requested_frame;
2011
2012#ifdef ENABLE_PRECACHE
2014 if (mainw->pred_clip != -1) {
2015 frames_t pframe = labs(mainw->pred_frame);
2017 || (sfile->pb_fps >= 0. && (pframe <= requested_frame || pframe < sfile->frameno))
2018 || (sfile->pb_fps < 0. && (pframe >= requested_frame || pframe > sfile->frameno))) {
2019 cleanup_preload = TRUE;
2020 getahead = -1;
2021 drop_off = FALSE;
2022 }
2023 } else mainw->frame_layer_preload = NULL;
2024 }
2025#endif
2026
2027 if (!prefs->vj_mode) {
2028 //g_print("lfi done @ %f\n", lives_get_current_ticks() / TICKS_PER_SECOND_DBL);
2030 else {
2031 if (mainw->vpp && mainw->ext_playback && mainw->vpp->fixed_fpsd > 0.)
2033 else if (mainw->fixed_fpsd > 0.)
2036 }
2037 }
2038
2041 sfile->frameno = requested_frame;
2042 scratch = SCRATCH_NONE;
2043 } // end show_frame
2044 else spare_cycles++;
2045 }
2046
2047#ifdef ENABLE_PRECACHE
2048 if (cleanup_preload) {
2050 if (getahead > -1 || is_layer_ready(mainw->frame_layer_preload)) {
2051 //wait_for_cleaner();
2052 if (mainw->pred_clip > 0) {
2055 }
2056 mainw->frame_layer_preload = NULL;
2057 mainw->pred_frame = 0;
2058 mainw->pred_clip = 0;
2059 cleanup_preload = FALSE;
2060 // *INDENT-OFF*
2061 }}}
2062 // *INDENT-ON*
2063#endif
2064
2065 // paused
2066 if (LIVES_UNLIKELY(sfile->play_paused)) {
2069 } else {
2071 && ((spare_cycles > 0ul && last_spare_cycles > 0ul) || (getahead > -1 && mainw->pred_frame != -getahead))) {
2072#ifdef SHOW_CACHE_PREDICTIONS
2073 //g_print("PRELOADING (%d %d %lu %p):", sfile->frameno, dropped, spare_cycles, mainw->frame_layer_preload);
2074#endif
2075#ifdef ENABLE_PRECACHE
2076 if (!mainw->frame_layer_preload) {
2077 if (!mainw->preview) {
2079 if (getahead > -1) mainw->pred_frame = getahead;
2080 else {
2081 if (sfile->pb_fps > 0.)
2082 mainw->pred_frame = sfile->frameno + 1 + dropped;
2083 else
2084 mainw->pred_frame = sfile->frameno - 1 - dropped;
2085 }
2086 if (mainw->pred_frame > 0 && mainw->pred_frame < sfile->frames) {
2087 const char *img_ext = get_image_ext_for_type(sfile->img_type);
2090 pull_frame_threaded(mainw->frame_layer_preload, img_ext, (weed_timecode_t)mainw->currticks, 0, 0);
2091 } else {
2092 // if the target is a clip-frame we have to decode it now, since we cannot simply decode 2 frames simultaneously
2093 // (although it could be possible in the future to have 2 clone decoders and have them leapfrog...)
2094 // NOTE: change to labs when frames_t updated
2097 (weed_timecode_t)mainw->currticks,
2098 sfile->hsize, sfile->vsize, WEED_PALETTE_END)) {
2101 mainw->frame_layer_preload = NULL;
2102 mainw->pred_clip = -1;
2103 }
2104#ifdef SHOW_CACHE_PREDICTIONS
2105 g_print("failed to load frame %ld\n", mainw->pred_frame);
2106#endif
2107 }
2108 }
2109 if (mainw->pred_clip != -1) {
2110#ifdef SHOW_CACHE_PREDICTIONS
2111 g_print("cached frame %ld\n", mainw->pred_frame);
2112#endif
2113 if (getahead > 0) {
2114 mainw->pred_frame = -getahead;
2116 }
2117 // *INDENT-OFF*
2118 }}
2119 else mainw->pred_frame = 0;
2120 }}
2121#ifdef SHOW_CACHE_PREDICTIONS
2122 //g_print("frame %ld already in cache\n", mainw->pred_frame);
2123#endif
2124#endif
2125 }}
2126 // *INDENT-ON*
2127
2128proc_dialog:
2129
2130 if (visible) {
2131 if (!mainw->proc_ptr) {
2132 // fixes a problem with opening preview with bg generator
2134 } else {
2135 if (LIVES_IS_SPIN_BUTTON(mainw->framedraw_spinbutton))
2138 // set the progress bar %
2139 update_progress(visible);
2140 }
2141
2142 frames_done = mainw->proc_ptr->frames_done;
2143
2144 if (cfile->clip_type == CLIP_TYPE_FILE && cfile->fx_frame_pump > 0) {
2145 if (virtual_to_images(mainw->current_file, cfile->fx_frame_pump, cfile->fx_frame_pump, FALSE, NULL) > 0) {
2146 cfile->fx_frame_pump++;
2147 } else mainw->cancelled = CANCEL_ERROR;
2148 if (cfile->fx_frame_pump >= cfile->end) cfile->fx_frame_pump = 0; // all frames were realised
2149 }
2150 }
2151
2152 if (LIVES_LIKELY(mainw->cancelled == CANCEL_NONE)) {
2153 lives_rfx_t *xrfx;
2154
2155 if ((xrfx = (lives_rfx_t *)mainw->vrfx_update) != NULL && fx_dialog[1]) {
2156 // the audio thread wants to update the parameter window
2157 mainw->vrfx_update = NULL;
2159 }
2160
2161 // the audio thread wants to update the parameter scroll(s)
2163
2165 if (mainw->cs_permitted) {
2167 old_current_file = mainw->current_file;
2168 }
2169
2170 if (mainw->currticks - last_anim_ticks > ANIM_LIM) {
2171 // a segfault here can indicate memory corruption in an FX plugin
2172 last_anim_ticks = mainw->currticks;
2174 }
2175
2177 if (mainw->cs_is_permitted) {
2179 if (mainw->current_file != old_current_file) mainw->cancelled = CANCEL_NO_PROPOGATE;
2180 }
2181
2182 if (!CURRENT_CLIP_IS_VALID) {
2183 if (IS_VALID_CLIP(mainw->new_clip)) goto switch_point;
2185 }
2186
2187 if (mainw->cancelled != CANCEL_NONE) {
2188 cancel_process(visible);
2189 return ONE_MILLION + mainw->cancelled;
2190 }
2191 return 0;
2192 }
2193
2194 if (LIVES_IS_PLAYING) {
2195 if (mainw->record && !mainw->record_paused)
2199 }
2200
2201 cancel_process(visible);
2202
2203 return 2000000 + mainw->cancelled;
2204}
2205#if 0
2206}
2207#endif
2208
2209#ifdef USE_GDK_FRAME_CLOCK
2210static boolean using_gdk_frame_clock;
2211static GdkFrameClock *gclock;
2212static void clock_upd(GdkFrameClock * clock, gpointer user_data) {
2213 display_ready = TRUE;
2214}
2215#endif
2216
2217
2218static boolean reset_timebase(void) {
2219 // [IMPORTANT] we subtract these from every calculation to make the numbers smaller
2220#if _POSIX_TIMERS
2221 ticks_t originticks = lives_get_current_ticks();
2222 originticks *= TICKS_TO_NANOSEC;
2223 mainw->origsecs = originticks / ONE_BILLION;
2224 mainw->orignsecs = originticks - mainw->origsecs * ONE_BILLION;
2225#else
2226
2227#ifdef USE_MONOTONIC_TIME
2228 mainw->origsecs = 0; // not used
2229 mainw->orignsecs = lives_get_monotonic_time() * 1000;
2230#else
2231
2232 /***************************************************/
2233 gettimeofday(&tv, NULL);
2234 /***************************************************/
2235
2236 mainw->origsecs = tv.tv_sec;
2237 mainw->orignsecs = tv.tv_usec * 1000;
2238#endif
2239#endif
2240
2241#ifdef HAVE_PULSE_AUDIO
2243 boolean pa_reset = TRUE;
2244 if (prefs->audio_src == AUDIO_SRC_INT) {
2245 if (mainw->pulsed && !pa_time_reset(mainw->pulsed, 0)) {
2246 pa_reset = FALSE;
2247 }
2248 } else {
2249 if (mainw->pulsed_read && !pa_time_reset(mainw->pulsed_read, 0)) {
2250 pa_reset = FALSE;
2251 }
2252 }
2253 if (!pa_reset) {
2255 return FALSE;
2256 }
2257 }
2258#endif
2259
2260#ifdef ENABLE_JACK
2261 if (mainw->jackd) {
2262 jack_time_reset(mainw->jackd, 0);
2263 }
2264 if (mainw->jackd_read) {
2265 jack_time_reset(mainw->jackd_read, 0);
2266 }
2267#endif
2268
2270 return TRUE;
2271}
2272
2273
2274boolean do_progress_dialog(boolean visible, boolean cancellable, const char *text) {
2275 // monitor progress, return FALSE if the operation was cancelled
2276
2277 // this is the outer loop for playback and all kinds of processing
2278
2279 // visible is set for processing (progress dialog is visible)
2280 // or unset for video playback (progress dialog is not shown)
2281 char *mytext = NULL;
2282 frames_t frames_done, frames;
2283 boolean got_err = FALSE;
2284 boolean markup = widget_opts.use_markup;
2285
2287
2288 // translation issues
2289 if (visible && text) mytext = lives_strdup(text);
2290
2291 if (visible) {
2292 // check we have sufficient storage space
2293 if (mainw->next_ds_warn_level != 0 &&
2295 lives_cancel_t cancelled = mainw->cancelled;
2297 if (mainw->cancelled != CANCEL_NONE) mainw->cancelled = cancelled;
2300 return FALSE;
2301 }
2302 }
2303
2304 event_start = 0;
2305 audio_start = mainw->play_start;
2306 if (visible) accelerators_swapped = FALSE;
2307 frames_done = 0;
2308 disp_fraction_done = 0.;
2310 shown_paused_frames = FALSE;
2311
2312 mainw->cevent_tc = -1;
2313
2314 progress_count = 0;
2315 progress_speed = 4.;
2316 prog_fs_check = 0;
2317
2319
2320 if (!visible) {
2323 cleanup_preload = FALSE;
2324 } else mainw->force_show = FALSE;
2325
2327 mainw->error = FALSE;
2329 if (!mainw->preview || cfile->opening) mainw->timeout_ticks = 0;
2330
2331 if (visible) {
2332 mainw->noswitch = TRUE;
2334 desensitize();
2337
2338 widget_opts.use_markup = markup;
2339 mainw->proc_ptr = create_processing(mytext);
2341
2343 mainw->proc_ptr->progress_start = cfile->progress_start;
2344 mainw->proc_ptr->progress_end = cfile->progress_end;
2345 } else {
2347 }
2348
2349 lives_freep((void **)&mytext);
2350
2351 lives_progress_bar_set_pulse_step(LIVES_PROGRESS_BAR(mainw->proc_ptr->progressbar), .01);
2352
2354
2355 if (!cancellable) {
2357 }
2358
2359 if (!LIVES_IS_INTERACTIVE) {
2365 }
2366
2367 if (cfile->opening && (capable->has_sox_play || (prefs->audio_player == AUD_PLAYER_JACK && mainw->jackd) ||
2371 lives_widget_remove_accelerator(mainw->playall, mainw->accel_group, LIVES_KEY_p, (LiVESXModifierType)0);
2372 lives_widget_add_accelerator(mainw->proc_ptr->preview_button, LIVES_WIDGET_CLICKED_SIGNAL, mainw->accel_group, LIVES_KEY_p,
2373 (LiVESXModifierType)0, (LiVESAccelFlags)0);
2374 accelerators_swapped = TRUE;
2375 }
2376 }
2377
2378 if (cfile->next_event) event_start = get_event_timecode(cfile->next_event);
2379
2381 cache_hits = cache_misses = 0;
2382 dropped = 0;
2383 init_timers = TRUE;
2384
2385 // mainw->origsecs, mainw->orignsecs is our base for quantising
2386 // (and is constant for each playback session)
2387
2388 // firstticks is to do with the audio "frame" for sox, mplayer
2389 // startticks is the ticks value of the last frame played
2390
2391 last_open_check_ticks = mainw->offsetticks = mainw->deltaticks = mainw->adjticks = 0;
2392
2393#ifdef ENABLE_JACK
2396 // if recording with external audio, wait for audio threshold before commencing
2397 mainw->jackd_read->abs_maxvol_heard = 0.;
2398 cfile->progress_end = 0;
2399 do_threaded_dialog(_("Waiting for external audio"), TRUE);
2400 while (mainw->jackd_read->abs_maxvol_heard < prefs->ahold_threshold && mainw->cancelled == CANCEL_NONE) {
2401 lives_usleep(prefs->sleep_time);
2404 }
2406 mainw->proc_ptr = NULL;
2407 if (mainw->cancelled != CANCEL_NONE) {
2409 return FALSE;
2410 }
2411 }
2412#endif
2413
2414#ifdef HAVE_PULSE_AUDIO
2415 // start audio recording now
2416 if (mainw->pulsed_read) {
2417 pulse_driver_uncork(mainw->pulsed_read);
2418 }
2420 prefs->ahold_threshold > 0.) {
2421 cfile->progress_end = 0;
2422 do_threaded_dialog(_("Waiting for external audio"), TRUE);
2423 while (mainw->pulsed_read->abs_maxvol_heard < prefs->ahold_threshold && mainw->cancelled == CANCEL_NONE) {
2424 lives_usleep(prefs->sleep_time);
2427 }
2429 if (mainw->cancelled != CANCEL_NONE) {
2431 return FALSE;
2432 }
2433 }
2434#endif
2435 last_kbd_ticks = 0;
2438 display_ready = TRUE;
2439
2440 last_time_source = LIVES_TIME_SOURCE_NONE;
2441
2443 if (!reset_timebase()) {
2445 return FALSE;
2446 }
2448 //if (mainw->disk_mon & MONITOR_GROWTH) disk_monitor_start(mainw->monitor_dir);
2450
2451 if (visible) {
2452 proc_start_ticks = lives_get_current_ticks();
2453 } else {
2454 // video playback
2457 cfile->last_frameno = cfile->frameno = mainw->play_start;
2458 }
2459
2460 if (!mainw->playing_sel) mainw->play_start = 1;
2461
2462 if (mainw->multitrack && !mainw->multitrack->is_rendering) {
2463 // playback start from middle of multitrack
2464 // calculate when we "would have started" at time 0
2466 }
2467
2468 // set initial audio seek position for current file
2469 if (cfile->achans) {
2471 cfile->aseek_pos / cfile->arps / cfile->achans / (cfile->asampsize >> 3));
2472 }
2473 frames = cfile->frames;
2474 cfile->frames = 0; // allow seek beyond video length
2475 // MUST do re-seek after setting origsecs in order to set our clock properly
2476 // re-seek to new playback start
2477#ifdef ENABLE_JACK
2478 if (prefs->audio_player == AUD_PLAYER_JACK && cfile->achans > 0 && cfile->laudio_time > 0. &&
2479 !mainw->is_rendering && !(cfile->opening && !mainw->preview) && mainw->jackd
2480 && mainw->jackd->playing_file > -1) {
2481 if (!jack_audio_seek_frame(mainw->jackd, mainw->aframeno)) {
2483 return FALSE;
2484 /* if (jack_try_reconnect()) jack_audio_seek_frame(mainw->jackd, mainw->aframeno); */
2485 /* else mainw->video_seek_ready = mainw->audio_seek_ready = TRUE; */
2486 }
2487
2489 jack_get_rec_avals(mainw->jackd);
2490 else {
2492 mainw->rec_avel = 1.;
2493 mainw->rec_aseek = 0;
2494 }
2495 /* if (prefs->audio_src == AUDIO_SRC_INT) */
2496 /* mainw->jackd->in_use = TRUE; */
2497 }
2498#endif
2499#ifdef HAVE_PULSE_AUDIO
2500 if (prefs->audio_player == AUD_PLAYER_PULSE && cfile->achans > 0 && cfile->laudio_time > 0. &&
2501 !mainw->is_rendering && !(cfile->opening && !mainw->preview) && mainw->pulsed
2502 && mainw->pulsed->playing_file > -1) {
2503 if (!pulse_audio_seek_frame(mainw->pulsed, mainw->aframeno)) {
2506 return FALSE;
2507 }
2508
2510 pulse_get_rec_avals(mainw->pulsed);
2511 else {
2513 mainw->rec_avel = 1.;
2514 mainw->rec_aseek = 0;
2515 }
2516 }
2517#endif
2518 cfile->frames = frames;
2519
2520#ifdef USE_GDK_FRAME_CLOCK
2521 using_gdk_frame_clock = FALSE;
2522 if (prefs->show_gui) {
2523 using_gdk_frame_clock = TRUE;
2524 display_ready = FALSE;
2525 gclock = gtk_widget_get_frame_clock(LIVES_MAIN_WINDOW_WIDGET);
2526 gdk_frame_clock_begin_updating(gclock);
2527 lives_signal_sync_connect(LIVES_GUI_OBJECT(gclock), "update",
2528 LIVES_GUI_CALLBACK(clock_upd), NULL);
2529 }
2530#endif
2531
2532#ifdef HAVE_PULSE_AUDIO
2533 if (mainw->pulsed_read) {
2534 mainw->pulsed_read->is_paused = FALSE;
2535 }
2536#endif
2537#ifdef ENABLE_JACK
2538 if (mainw->jackd_read) {
2539 mainw->jackd_read->is_paused = FALSE;
2540 }
2541#endif
2542
2544
2545 if (!mainw->proc_ptr && cfile->next_event) {
2547 process_events(NULL, FALSE, 0);
2548 }
2549
2551 if (mainw->multitrack && !mainw->multitrack->is_rendering) mainw->effort = EFFORT_RANGE_MAX;
2552 getahead = -1;
2553 drop_off = FALSE;
2554 bungle_frames = -1;
2555 recalc_bungle_frames = FALSE;
2556 spare_cycles = 0ul;
2557
2558 //try to open info file - or if internal_messaging is TRUE, we get mainw->msg
2559 // from the mainw->progress_fn function
2560 while (1) {
2561 while (!mainw->internal_messaging && ((!visible && (mainw->whentostop != STOP_ON_AUD_END ||
2563 !lives_file_test(cfile->info_file, LIVES_FILE_TEST_EXISTS))) {
2564 // just pulse the progress bar, or play video
2565 // returns a code if pb stopped
2566 int ret;
2567 if ((ret = process_one(visible))) {
2568 if (visible) mainw->noswitch = FALSE;
2569 //g_print("pb stopped, reason %d\n", ret);
2571#ifdef USE_GDK_FRAME_CLOCK
2572 if (using_gdk_frame_clock) {
2573 gdk_frame_clock_end_updating(gclock);
2574 }
2575#endif
2577 return FALSE;
2578 }
2579
2580 /* if (mainw->disk_mon & MONITOR_GROWTH) { */
2581 /* int64_t dsused = disk_monitor_check_result(mainw->monitor_dir); */
2582 /* if (dsused >= 0) mainw->monitor_size = dsused; */
2583 /* disk_monitor_start(mainw->monitor_dir); */
2584 /* } */
2586 int64_t dsused = disk_monitor_check_result(prefs->workdir);
2587 if (dsused >= 0) {
2588 capable->ds_used = dsused;
2589 }
2592 }
2593
2594 if (LIVES_UNLIKELY(mainw->agen_needs_reinit)) {
2595 // we are generating audio from a plugin and it needs reinit
2596 // - we do it in this thread so as not to hold up the player thread
2598 }
2599
2600 if ((visible && !mainw->internal_messaging)
2601 || (LIVES_IS_PLAYING && CURRENT_CLIP_IS_VALID && cfile->play_paused)) lives_usleep(prefs->sleep_time);
2602
2603 // normal playback, wth realtime audio player
2604 if (!visible && (mainw->whentostop != STOP_ON_AUD_END || is_realtime_aplayer(prefs->audio_player))) continue;
2605
2606 if (mainw->iochan && !progress_count) {
2607 // pump data from stdout to textbuffer
2608 // this is for encoder output
2610 }
2611 if (!mainw->internal_messaging) {
2612 // background processing (e.g. rendered effects)
2613 progbar_pulse_or_fraction(cfile, mainw->proc_ptr->frames_done, mainw->proc_ptr->frac_done);
2614 }
2615 }
2616
2617 if (!mainw->internal_messaging) {
2618 // background processing (e.g. rendered effects)
2620 progbar_pulse_or_fraction(cfile, mainw->proc_ptr->frames_done, mainw->proc_ptr->frac_done);
2621 }
2622 // else call realtime effect pass
2623 else {
2625
2627 got_err = TRUE;
2628 goto finish;
2629 }
2630
2631 // display progress fraction or pulse bar
2632 if (*mainw->msg && (frames_done = atoi(mainw->msg)) > 0) {
2633 if (mainw->msg[lives_strlen(mainw->msg) - 1] == '%')
2634 mainw->proc_ptr->frac_done = atof(mainw->msg);
2635 else
2636 mainw->proc_ptr->frames_done = atoi(mainw->msg);
2637 } else
2639 if (!mainw->effects_paused) {
2640 if (prog_fs_check-- <= 0) {
2642 prog_fs_check = PROG_LOOP_VAL;
2643 }
2644 progbar_pulse_or_fraction(cfile, mainw->proc_ptr->frames_done, mainw->proc_ptr->frac_done);
2646 }
2647
2648 if (mainw->preview_req) {
2650 mainw->noswitch = FALSE;
2651 on_preview_clicked(LIVES_BUTTON(mainw->proc_ptr->preview_button), NULL);
2652 mainw->noswitch = TRUE;
2653 }
2654
2655 // #define DEBUG
2656#ifdef DEBUG
2657 if (*(mainw->msg)) g_print("%s msg %s\n", cfile->info_file, mainw->msg);
2658#endif
2659
2660 // we got a message from the backend...
2661
2662 if (visible && (!accelerators_swapped || cfile->opening) && cancellable
2663 && (!cfile->nopreview || cfile->keep_without_preview)) {
2664 if (!cfile->nopreview && !(cfile->opening && mainw->multitrack)) {
2669 }
2670
2671 // show buttons
2672 if (cfile->opening_loc) {
2676 } else {
2680 }
2681
2682 if (!cfile->opening && !cfile->nopreview) {
2687 lives_widget_remove_accelerator(mainw->playall, mainw->accel_group, LIVES_KEY_p, (LiVESXModifierType)0);
2688 lives_widget_add_accelerator(mainw->proc_ptr->preview_button, LIVES_WIDGET_CLICKED_SIGNAL,
2689 mainw->accel_group, LIVES_KEY_p,
2690 (LiVESXModifierType)0, (LiVESAccelFlags)0);
2691 accelerators_swapped = TRUE;
2692 }
2693 }
2694
2695 // g_print("MSG is %s\n", mainw->msg);
2696
2697 if (lives_strncmp(mainw->msg, "completed", 8) && strncmp(mainw->msg, "error", 5) &&
2698 strncmp(mainw->msg, "killed", 6) && (visible ||
2699 ((lives_strncmp(mainw->msg, "video_ended", 11) || mainw->whentostop != STOP_ON_VID_END)
2700 && (lives_strncmp(mainw->msg, "audio_ended", 11) || mainw->preview ||
2702 // processing not yet completed...
2703 if (visible) {
2704 // last frame processed ->> will go from cfile->start to cfile->end
2705 int numtok = get_token_count(mainw->msg, '|');
2706 // get progress count from backend
2707 if (numtok > 1) {
2708 char **array = lives_strsplit(mainw->msg, "|", numtok);
2709 mainw->proc_ptr->frames_done = atoi(array[0]);
2710 if (numtok == 2 && *(array[1])) cfile->progress_end = atoi(array[1]);
2711 else if (numtok == 5 && *(array[4])) {
2712 // rendered generators
2713 cfile->start = cfile->undo_start = 1;
2714 cfile->frames = cfile->end = cfile->undo_end = atoi(array[0]);
2715 cfile->hsize = atoi(array[1]);
2716 cfile->vsize = atoi(array[2]);
2717 cfile->fps = cfile->pb_fps = strtod(array[3], NULL);
2718 if (cfile->fps == 0.) cfile->fps = cfile->pb_fps = prefs->default_fps;
2719 cfile->progress_end = atoi(array[4]);
2720 }
2721 lives_strfreev(array);
2722 } else {
2723 if (*mainw->msg && mainw->msg[lives_strlen(mainw->msg) - 1] == '%')
2724 mainw->proc_ptr->frac_done = atof(mainw->msg);
2725 else
2726 mainw->proc_ptr->frames_done = atoi(mainw->msg);
2727 }
2728 }
2729
2730 // do a processing pass
2731 if (process_one(visible)) {
2733#ifdef USE_GDK_FRAME_CLOCK
2734 if (using_gdk_frame_clock) {
2735 gdk_frame_clock_end_updating(gclock);
2736 }
2737#endif
2739 if (visible) mainw->noswitch = FALSE;
2740 return FALSE;
2741 }
2742
2744 int64_t dsused = disk_monitor_check_result(prefs->workdir);
2745 if (dsused >= 0) {
2746 capable->ds_used = dsused;
2747 }
2750 }
2751
2752
2753 if (LIVES_UNLIKELY(mainw->agen_needs_reinit)) {
2754 // we are generating audio from a plugin and it needs reinit
2755 // - we do it in this thread so as not to hold up the player thread
2757 }
2758
2759 if (mainw->iochan && progress_count == 0) {
2760 // pump data from stdout to textbuffer
2762 }
2763
2765 } else break;
2766 }
2767
2768#ifdef USE_GDK_FRAME_CLOCK
2769 if (using_gdk_frame_clock) {
2770 gdk_frame_clock_end_updating(gclock);
2771 }
2772#endif
2773
2774#ifdef DEBUG
2775 g_print("exit pt 3 %s\n", mainw->msg);
2776#endif
2777
2778finish:
2780
2781 //play/operation ended
2782 if (visible) {
2783 if (cfile->clip_type == CLIP_TYPE_DISK && (mainw->cancelled != CANCEL_NO_MORE_PREVIEW || !cfile->opening)) {
2784 lives_rm(cfile->info_file);
2785 }
2787 if (accelerators_swapped) {
2789 lives_widget_remove_accelerator(mainw->proc_ptr->preview_button, mainw->accel_group, LIVES_KEY_p, (LiVESXModifierType)0);
2790 lives_widget_add_accelerator(mainw->playall, LIVES_WIDGET_ACTIVATE_SIGNAL, mainw->accel_group, LIVES_KEY_p,
2791 (LiVESXModifierType)0, LIVES_ACCEL_VISIBLE);
2792 accelerators_swapped = FALSE;
2793 }
2794 if (mainw->proc_ptr) {
2795 const char *btext = NULL;
2799 mainw->proc_ptr = NULL;
2800 if (btext) {
2802 lives_free((char *)btext);
2803 }
2804 }
2806 if (cfile->menuentry) {
2807 // note - for operations to/from clipboard (file 0) we
2808 // should manually call sensitize() after operation
2809 sensitize();
2810 }
2811 } else {
2813 }
2814
2816 // get error message (if any)
2817 if (!strncmp(mainw->msg, "error", 5)) {
2819 if (mainw->cancelled || mainw->error) {
2820 if (visible) mainw->noswitch = FALSE;
2821 return FALSE;
2822 }
2823 } else {
2825 if (visible) mainw->noswitch = FALSE;
2826 return FALSE;
2827 }
2828 }
2829
2830 if (got_err) {
2831 if (visible) mainw->noswitch = FALSE;
2832 return FALSE;
2833 }
2834#ifdef DEBUG
2835 g_print("exiting progress dialog\n");
2836#endif
2837 if (visible) mainw->noswitch = FALSE;
2838 return TRUE;
2839}
2840
2841
2842#define MIN_FLASH_TIME MILLIONS(100)
2843
2844boolean do_auto_dialog(const char *text, int type) {
2845 // type 0 = normal auto_dialog
2846 // type 1 = countdown dialog for audio recording
2847 // type 2 = normal with cancel
2848
2849 FILE *infofile = NULL;
2850
2851 uint64_t time = 0, stime = 0;
2852
2853 char *label_text;
2854 char *mytext = lives_strdup(text);
2855
2856 int time_rem, last_time_rem = 10000000;
2857 lives_alarm_t alarm_handle = 0;
2858
2860
2861 if (type == 1 && mainw->rec_end_time != -1.) {
2862 stime = lives_get_current_ticks();
2863 }
2864
2865 mainw->error = FALSE;
2866
2867 mainw->proc_ptr = create_processing(mytext);
2868
2869 lives_freep((void **)&mytext);
2872
2873 if (type == 2) {
2877 }
2878 if (type == 0) {
2880 }
2881
2882 lives_progress_bar_set_pulse_step(LIVES_PROGRESS_BAR(mainw->proc_ptr->progressbar), .01);
2883
2886
2887 //lives_widget_context_update();
2888
2889 if (type == 0 || type == 2) {
2891 alarm_handle = lives_alarm_set(MIN_FLASH_TIME); // don't want to flash too fast...
2892 } else if (type == 1) {
2893 // show buttons
2897#ifdef HAVE_PULSE_AUDIO
2898 if (mainw->pulsed_read) {
2899 pulse_driver_uncork(mainw->pulsed_read);
2900 }
2901#endif
2902 if (mainw->rec_samples != 0) {
2903
2904 lives_usleep(prefs->sleep_time);
2905 }
2906 }
2907
2908 while (mainw->cancelled == CANCEL_NONE && !(infofile = fopen(cfile->info_file, "r"))) {
2909 lives_progress_bar_pulse(LIVES_PROGRESS_BAR(mainw->proc_ptr->progressbar));
2911 //lives_widget_process_updates(mainw->proc_ptr->processing);
2912 lives_usleep(prefs->sleep_time);
2913 if (type == 1 && mainw->rec_end_time != -1.) {
2914 time = lives_get_current_ticks();
2915
2916 // subtract start time
2917 time -= stime;
2918
2919 time_rem = (int)(mainw->rec_end_time - (double)time / TICKS_PER_SECOND_DBL + .5);
2920 if (time_rem >= 0 && time_rem < last_time_rem) {
2921 label_text = lives_strdup_printf(_("\nTime remaining: %d sec"), time_rem);
2922 lives_label_set_text(LIVES_LABEL(mainw->proc_ptr->label2), label_text);
2923 lives_free(label_text);
2924 last_time_rem = time_rem;
2925 } else if (time_rem < 0) break;
2926 }
2927 }
2928
2929 if (!mainw->cancelled) {
2930 if (infofile) {
2931 if (type == 0 || type == 2) {
2932 size_t bread;
2933 THREADVAR(read_failed) = FALSE;
2934 bread = lives_fread(mainw->msg, 1, MAINW_MSG_SIZE, infofile);
2935 fclose(infofile);
2936 lives_memset(mainw->msg + bread, 0, 1);
2937 if (cfile->clip_type == CLIP_TYPE_DISK) lives_rm(cfile->info_file);
2938 if (alarm_handle > 0) {
2939 ticks_t tl;
2940 while ((tl = lives_alarm_check(alarm_handle)) > 0 && !mainw->cancelled) {
2941 lives_progress_bar_pulse(LIVES_PROGRESS_BAR(mainw->proc_ptr->progressbar));
2943 lives_usleep(prefs->sleep_time);
2944 }
2945 lives_alarm_clear(alarm_handle);
2946 }
2947 } else fclose(infofile);
2948 }
2949 }
2950
2951 if (mainw->proc_ptr) {
2954 mainw->proc_ptr = NULL;
2955 }
2956
2957 if (type == 2) mainw->cancel_type = CANCEL_KILL;
2959 if (mainw->cancelled) return FALSE;
2960
2961 // get error message (if any)
2962 if (type != 1 && !strncmp(mainw->msg, "error", 5)) {
2964 if (mainw->cancelled || mainw->error) return FALSE;
2965 } else {
2968 }
2969 return TRUE;
2970}
2971
2972
2974
2976 char *extra;
2977 char *msg;
2978
2979 if (!mainw->no_exit && !mainw->only_close) extra = lives_strdup(", and LiVES will exit");
2980 else extra = lives_strdup("");
2981
2982 msg = lives_strdup_printf(
2983 _("Saving the set will cause copies of all loaded clips to remain on the disk%s.\n\n"
2984 "Please press 'Cancel' if that is not what you want.\n"), extra);
2985 lives_free(extra);
2986
2988 lives_free(msg);
2989 return FALSE;
2990 }
2991 lives_free(msg);
2992 return TRUE;
2993}
2994
2995
2997 do_error_dialogf(_("\nSorry, LiVES can only open %d files at once.\nPlease close a file and then try again."), MAX_FILES);
2998}
2999
3000
3002 char *tmp, *com = lives_strdup_printf(
3003 _("LiVES was unable to write to its working directory.\n\nThe current working directory is:\n\n%s\n\n"
3004 "Please make sure you can write to this directory."),
3005 (tmp = lives_filename_to_utf8(prefs->workdir, -1, NULL, NULL, NULL)));
3006 lives_free(tmp);
3007 if (mainw && mainw->is_ready) {
3008 do_error_dialog(com);
3009 }
3010 lives_free(com);
3011}
3012
3013
3015 do_error_dialog(_("\nLiVES currently requires either 'mplayer', 'mplayer2', or 'sox' to function. "
3016 "Please install one or other of these, and try again.\n"));
3017}
3018
3019
3022 _("\nThis function requires either mplayer or mplayer2 to operate.\nYou may wish to install "
3023 "one or other of these and try again.\n"));
3024}
3025
3026
3029 _("\nThis function requires either mplayer, mplayer2 or mpv to operate.\nYou may wish to install one or other of these "
3030 "and try again.\n"));
3031}
3032
3033
3035 do_error_dialog(_("Audio was not loaded; please install mplayer or mplayer2 if you expected audio for this clip.\n"));
3036}
3037
3038
3041 _("Audio resampling is required for this format.\nPlease install 'sox'\nOr switch to another encoder format in "
3042 "Tools | Preferences | Encoding\n"));
3043}
3044
3045
3048 _("\n\nThis encoder/format cannot use the requested audio codec.\n"
3049 "Please set the audio codec in Tools|Preferences|Encoding\n"));
3050}
3051
3052
3055 _("This layout includes generated frames.\nIt cannot be saved, you must render it to a clip first.\n"));
3056}
3057
3058
3061 _("This layout includes generated or recorded audio.\nIt cannot be saved, you must render it to a clip first.\n"));
3062}
3063
3064
3065boolean rdet_suggest_values(int width, int height, double fps, int fps_num, int fps_denom, int arate, int asigned,
3066 boolean swap_endian, boolean anr, boolean ignore_fps) {
3067 LiVESWidget *prep_dialog;
3068
3069 char *msg1 = lives_strdup_printf(_("\n\nDue to restrictions in the %s format\n"), prefs->encoder.of_desc);
3070 char *msg2 = lives_strdup(""), *msg3 = lives_strdup(""), *msg4 = lives_strdup("");
3071 char *msg5 = lives_strdup(""), *msg6 = lives_strdup(""), *msg7 = lives_strdup("");
3072 char *msg8 = lives_strdup("");
3073 char *msg_a;
3074
3075 boolean ochange = FALSE;
3076 boolean ret;
3077
3078 mainw->fx1_bool = FALSE;
3079
3080 if (swap_endian || (asigned == 1 && rdet->aendian == AFORM_UNSIGNED) || (asigned == 2 && rdet->aendian == AFORM_SIGNED) ||
3081 (fps > 0. && fps != rdet->fps) || (fps_denom > 0 && (fps_num * 1.) / (fps_denom * 1.) != rdet->fps) ||
3082 (!anr && (rdet->width != width || rdet->height != height) && height * width > 0) ||
3083 (arate != rdet->arate && arate > 0)) {
3084 lives_free(msg2);
3085 msg2 = (_("LiVES recommends the following settings:\n\n"));
3086 if (swap_endian || (asigned == 1 && rdet->aendian == AFORM_UNSIGNED) || (asigned == 2 && rdet->aendian == AFORM_SIGNED)
3087 || (arate > 0 && arate != rdet->arate)) {
3088 char *sstring;
3089 char *estring;
3090
3091 if (asigned == 1 && rdet->aendian == AFORM_UNSIGNED) sstring = (_(", signed"));
3092 else if (asigned == 2 && rdet->aendian == AFORM_SIGNED) sstring = (_(", unsigned"));
3093 else sstring = lives_strdup("");
3094
3095 if (swap_endian) {
3096 if (mainw->endian != AFORM_BIG_ENDIAN) estring = (_(", little-endian"));
3097 else estring = (_(", big-endian"));
3098 } else estring = lives_strdup("");
3099
3100 ochange = TRUE;
3101 lives_free(msg3);
3102 msg3 = lives_strdup_printf(_("Use an audio rate of %d Hz%s%s\n"), arate, sstring, estring);
3103 lives_free(sstring);
3104 lives_free(estring);
3105 }
3106 if (!ignore_fps) {
3107 ochange = TRUE;
3108 if (fps > 0 && fps != rdet->fps) {
3109 lives_free(msg4);
3110 msg4 = lives_strdup_printf(_("Set video rate to %.3f frames per second\n"), fps);
3111 } else if (fps_denom > 0 && (fps_num * 1.) / (fps_denom * 1.) != rdet->fps) {
3112 lives_free(msg4);
3113 msg4 = lives_strdup_printf(_("Set video rate to %d:%d frames per second\n"), fps_num, fps_denom);
3114 }
3115 }
3116 if (!anr && ((rdet->width != width || rdet->height != height) && height * width > 0)) {
3117 lives_free(msg5);
3118 msg5 = lives_strdup_printf(_("Set video size to %d x %d pixels\n"), width, height);
3119 mainw->fx1_bool = TRUE;
3120 }
3121 }
3122 if (anr || arate < 0) {
3123 if (arate < 1 || ((rdet->width != width || rdet->height != height) && height * width > 0)) {
3124 lives_free(msg6);
3125 if (!ochange) anr = FALSE;
3126 msg6 = (_("\nYou may wish to:\n"));
3127 if ((rdet->width != width || rdet->height != height) && height * width > 0) {
3128 lives_free(msg7);
3129 msg7 = lives_strdup_printf(_("resize video to %d x %d pixels\n"), width, height);
3130 } else anr = FALSE;
3131 if (arate < 1) {
3132 lives_free(msg8);
3133 msg8 = (_("disable audio, since the target encoder cannot encode audio\n"));
3134 }
3135 } else anr = FALSE;
3136 }
3137 msg_a = lives_strconcat(msg1, msg2, msg3, msg4, msg5, msg6, msg7, msg8, NULL);
3138 lives_free(msg1); lives_free(msg2); lives_free(msg3); lives_free(msg4);
3139 lives_free(msg5); lives_free(msg6); lives_free(msg7); lives_free(msg8);
3140 prep_dialog = create_encoder_prep_dialog(msg_a, NULL, anr);
3141 lives_free(msg_a);
3142 ret = (lives_dialog_run(LIVES_DIALOG(prep_dialog)) == LIVES_RESPONSE_OK);
3143 lives_widget_destroy(prep_dialog);
3144 return ret;
3145}
3146
3147
3148boolean do_encoder_restrict_dialog(int width, int height, double fps, int fps_num, int fps_denom, int arate, int asigned,
3149 boolean swap_endian, boolean anr, boolean save_all) {
3150 LiVESWidget *prep_dialog;
3151
3152 char *msg1 = lives_strdup_printf(_("\n\nDue to restrictions in the %s format\n"), prefs->encoder.of_desc);
3153 char *msg2 = lives_strdup(""), *msg3 = lives_strdup(""), *msg4 = lives_strdup("");
3154 char *msg5 = lives_strdup(""), *msg6 = lives_strdup(""), *msg7 = lives_strdup("");
3155 char *msg_a, *msg_b = NULL;
3156
3157 double cfps;
3158
3159 boolean ret;
3160
3161 int carate, chsize, cvsize;
3162
3163 if (rdet) {
3164 carate = rdet->arate;
3165 chsize = rdet->width;
3166 cvsize = rdet->height;
3167 cfps = rdet->fps;
3168 } else {
3169 carate = cfile->arate;
3170 chsize = cfile->hsize;
3171 cvsize = cfile->vsize;
3172 cfps = cfile->fps;
3173 }
3174
3175 if (swap_endian || asigned != 0 || (arate > 0 && arate != carate) || (fps > 0. && fps != cfps) ||
3176 (fps_denom > 0 && (fps_num * 1.) / (fps_denom * 1.) != cfps) || (!anr &&
3177 (chsize != width || cvsize != height) && height * width > 0)) {
3178 lives_free(msg2);
3179 msg2 = (_("LiVES must:\n"));
3180 if (swap_endian || asigned != 0 || (arate > 0 && arate != carate)) {
3181 char *sstring;
3182 char *estring;
3183 if (asigned == 1) sstring = (_(", signed"));
3184 else if (asigned == 2) sstring = (_(", unsigned"));
3185 else sstring = lives_strdup("");
3186
3187 if (swap_endian) {
3188 if (cfile->signed_endian & AFORM_BIG_ENDIAN) estring = (_(", little-endian"));
3189 else estring = (_(", big-endian"));
3190 } else estring = lives_strdup("");
3191
3192 lives_free(msg3);
3193 msg3 = lives_strdup_printf(_("resample audio to %d Hz%s%s\n"), arate, sstring, estring);
3194 lives_free(sstring);
3195 lives_free(estring);
3196
3197 }
3198 if (fps > 0 && fps != cfps) {
3199 lives_free(msg4);
3200 msg4 = lives_strdup_printf(_("resample video to %.3f frames per second\n"), fps);
3201 } else if (fps_denom > 0 && (fps_num * 1.) / (fps_denom * 1.) != cfps) {
3202 lives_free(msg4);
3203 msg4 = lives_strdup_printf(_("resample video to %d:%d frames per second\n"), fps_num, fps_denom);
3204 }
3205 if (!anr && ((chsize != width || cvsize != height) && height * width > 0)) {
3206 lives_free(msg5);
3207 msg5 = lives_strdup_printf(_("resize video to %d x %d pixels\n"), width, height);
3208 mainw->fx1_bool = TRUE;
3209 }
3210 }
3211 if (anr) {
3212 if ((chsize != width || cvsize != height) && height * width > 0) {
3213 lives_free(msg6);
3214 lives_free(msg7);
3215 msg6 = (_("\nYou may wish to:\n"));
3216 msg7 = lives_strdup_printf(_("Set video size to %d x %d pixels\n"), width, height);
3217 } else anr = FALSE;
3218 }
3219 msg_a = lives_strconcat(msg1, msg2, msg3, msg4, msg5, msg6, msg7, NULL);
3220 if (save_all) {
3221 msg_b = lives_strdup(
3222 _("\nYou will be able to undo these changes afterwards.\n\nClick `OK` to proceed, `Cancel` to abort.\n\n"));
3223 } else {
3224 msg_b = (_("\nChanges applied to the selection will not be permanent.\n\n"));
3225 }
3226 lives_free(msg1); lives_free(msg2); lives_free(msg3); lives_free(msg4);
3227 lives_free(msg5); lives_free(msg6); lives_free(msg7);
3228 prep_dialog = create_encoder_prep_dialog(msg_a, msg_b, anr);
3229 lives_free(msg_a);
3230 if (msg_b) lives_free(msg_b);
3231 ret = (lives_dialog_run(LIVES_DIALOG(prep_dialog)) == LIVES_RESPONSE_OK);
3232 lives_widget_destroy(prep_dialog);
3233 return ret;
3234}
3235
3236
3239 _("\n\nLiVES was unable to record a performance. There is currently insufficient memory available.\n"
3240 "Try recording for just a selection of the file."));
3241}
3242
3243
3246 return TRUE;
3247 }
3249 _("The playback speed (fps), or the audio rate\n of the clipboard does not match\n"
3250 "the playback speed or audio rate of the clip you are inserting into.\n\n"
3251 "The insertion will be adjusted to fit into the clip.\n\n"
3252 "Please press Cancel to abort the insert, or OK to continue."), WARN_MASK_FPS);
3253}
3254
3255
3257 return do_yesno_dialog(_("Current clips will be added to the clip set.\nIs that what you want ?\n"));
3258}
3259
3260
3261LIVES_GLOBAL_INLINE boolean findex_bk_dialog(const char *fname_back) {
3262 return do_yesno_dialogf(_("I can attempt to restore the frame index from a backup.\n(%s)\nShall I try ?\n"), fname_back);
3263}
3264
3265
3267 return do_yesno_dialogf(P_("\nPaste %d frame ?\n", "Paste %d frames ?\n", lframe), lframe);
3268}
3269
3271 char *msg;
3272 boolean resp;
3274 return TRUE;
3275 }
3276 msg = lives_strdup_printf(
3277 _("When opening a yuvmpeg stream, you should first create a fifo file, and then write yuv4mpeg frames to it.\n"
3278 "Now you will get a chance to browse for the fifo file here.\nFollowing that,\n"
3279 "LiVES will pause briefly until frames are received.\nYou should only click OK if you understand what you are doing, "
3280 "otherwise, click Cancel."),
3281 prefs->workdir);
3283 lives_free(msg);
3284 return resp;
3285}
3286
3287
3288boolean do_comments_dialog(int fileno, char *filename) {
3289 lives_clip_t *sfile = mainw->files[fileno];
3290
3291 boolean response;
3292 boolean encoding = FALSE;
3293
3294 commentsw = create_comments_dialog(sfile, filename);
3295
3296 if (sfile == NULL) sfile = cfile;
3297 else encoding = TRUE;
3298
3299 while (1) {
3300 if ((response = (lives_dialog_run(LIVES_DIALOG(commentsw->comments_dialog)) == LIVES_RESPONSE_OK))) {
3301 lives_snprintf(sfile->title, 1024, "%s", lives_entry_get_text(LIVES_ENTRY(commentsw->title_entry)));
3302 lives_snprintf(sfile->author, 1024, "%s", lives_entry_get_text(LIVES_ENTRY(commentsw->author_entry)));
3303 lives_snprintf(sfile->comment, 1024, "%s", lives_entry_get_text(LIVES_ENTRY(commentsw->comment_entry)));
3304
3305 save_clip_value(fileno, CLIP_DETAILS_TITLE, sfile->title);
3308
3309 if (encoding && sfile->subt && lives_toggle_button_get_active(LIVES_TOGGLE_BUTTON(commentsw->subt_checkbutton))) {
3310 char *ext = get_extension(lives_entry_get_text(LIVES_ENTRY(commentsw->subt_entry)));
3311 if (strcmp(ext, LIVES_FILE_EXT_SUB) && strcmp(ext, LIVES_FILE_EXT_SRT)) {
3314 lives_free(ext);
3315 continue;
3316 }
3317 }
3318 lives_free(ext);
3319 lives_freep((void **)&mainw->subt_save_file);
3320 mainw->subt_save_file = lives_strdup(lives_entry_get_text(LIVES_ENTRY(commentsw->subt_entry)));
3321 } else {
3322 lives_freep((void **)&mainw->subt_save_file);
3323 mainw->subt_save_file = NULL;
3324 }
3326 }
3327 break;
3328 }
3329
3331 return response;
3332}
3333
3334
3335LIVES_GLOBAL_INLINE void do_messages_window(boolean is_startup) {
3337 char *text = dump_messages(-1, -1);
3339 textwindow = create_text_window(_("Message History"), text, NULL, TRUE);
3341 lives_free(text);
3342 if (is_startup) {
3343 LiVESWidget *area =
3345 LiVESWidget *cb = lives_standard_check_button_new(_("Show messages on startup"), TRUE,
3346 LIVES_BOX(area), NULL);
3347 lives_signal_sync_connect(LIVES_GUI_OBJECT(cb), LIVES_WIDGET_TOGGLED_SIGNAL,
3348 LIVES_GUI_CALLBACK(toggle_sets_pref),
3349 (livespointer)PREF_MSG_START);
3352 }
3354 lives_scrolled_window_scroll_to(LIVES_SCROLLED_WINDOW(textwindow->scrolledwindow), LIVES_POS_BOTTOM);
3355}
3356
3357
3359 char *tmp;
3360 char *msg = lives_strdup_printf(
3361 _("After upgrading/installing, you may need to adjust the <prefix_dir> setting in your %s file"),
3362 (tmp = lives_filename_to_utf8(prefs->configfile, -1, NULL, NULL, NULL)));
3364 lives_free(msg); lives_free(tmp);
3365}
3366
3367
3369 char *tmp;
3370 char *msg = lives_strdup_printf(
3371 _("\n\nLiVES could not find any rendered effect plugins.\nPlease make sure you have them installed in\n"
3372 "%s%s%s\nor change the value of <lib_dir> in %s\n"),
3374 (tmp = lives_filename_to_utf8(prefs->configfile, -1, NULL, NULL, NULL)));
3376 lives_free(msg);
3377 lives_free(tmp);
3378}
3379
3380
3382 char *msg = (_("Sorry, unknown audio type.\n\n (Filenames must end in"));
3383 char *tmp;
3384
3385 char *filt[] = LIVES_AUDIO_LOAD_FILTER;
3386
3387 register int i = 0;
3388
3389 while (filt[i]) {
3390 if (filt[i + 1]) {
3391 tmp = lives_strdup_printf("%s or .%s)", msg, filt[i] + 2);
3392 } else if (i == 0) {
3393 tmp = lives_strdup_printf("%s .%s)", msg, filt[i] + 2);
3394 } else {
3395 tmp = lives_strdup_printf("%s, .%s)", msg, filt[i] + 2);
3396 }
3397 lives_free(msg);
3398 msg = tmp;
3399 i++;
3400 }
3401
3402 do_error_dialog(msg);
3403 lives_free(msg);
3404 d_print(_("failed (unknown type)\n"));
3405}
3406
3407
3409 return (do_yesno_dialog(
3410 _("\nDo you wish to remove the layout files associated with this set ?\n"
3411 "(They will not be usable without the set).\n")));
3412}
3413
3414
3415boolean do_set_duplicate_warning(const char *new_set) {
3416 char *msg = lives_strdup_printf(
3417 _("\nA set entitled %s already exists.\n"
3418 "Click OK to add the current clips and layouts to the existing set.\n"
3419 "Click Cancel to pick a new name.\n"), new_set);
3421 lives_free(msg);
3422 return retcode;
3423}
3424
3425
3427 return do_warning_dialog(
3428 _("\nFrames from this clip are used in some multitrack layouts.\n"
3429 "Are you sure you wish to continue ?\n."));
3430}
3431
3432
3434 return do_warning_dialog(
3435 _("\nAudio from this clip is used in some multitrack layouts.\n"
3436 "Are you sure you wish to continue ?\n."));
3437}
3438
3439
3440LIVES_GLOBAL_INLINE boolean do_gamma_import_warn(uint64_t fv, int gamma_type) {
3441 char *fvx = unhash_version(fv);
3442 boolean ret = do_yesno_dialogf(_("This clip is saved with a gamma type of %s\n"
3443 "from a future version of LiVES (%s)\n"
3444 "Opening it with the current version may result in a loss of quality\n"
3445 "Do you wish to continue ?"), weed_gamma_get_name(gamma_type), fvx);
3446 lives_free(fvx);
3447 return ret;
3448}
3449
3450
3451boolean do_mt_lb_warn(boolean lb) {
3452 char *tmp, *msg, *endis, *endised;
3453 boolean ret;
3454
3455 if (lb) {
3456 endis = _("enable");
3457 endised = _("enabled");
3458 } else {
3459 endis = _("disable");
3460 endised = _("disabled");
3461 }
3462 msg = lives_strdup_printf((tmp = _("This layout was saved with letterboxing %s\n"
3463 "To preserve the original appearance, I can override\n"
3464 "the current setting and %s letterboxing for this layout\n\n"
3465 "Click 'Yes' to proceed, or 'No' to keep the current setting\n\n"
3466 "(Note: the value for the current layout can be modified at any time\n"
3467 "via the menu option 'Tools' / 'Change Width, Height and Audio Values')\n")),
3468 endised, endis);
3469 lives_free(tmp); lives_free(endised); lives_free(endis);
3471 lives_free(msg);
3472 return ret;
3473}
3474
3475
3476static LiVESResponseType _do_df_notfound_dialog(const char *detail, const char *dfname, boolean is_dir) {
3477 LiVESWidget *warning;
3478 LiVESResponseType response;
3479 char *xdetail, *msg, *whatitis, *extra;
3480
3481 if (detail) xdetail = (char *)detail;
3482
3483 if (!is_dir) {
3484 if (!detail) {
3485 xdetail = lives_strdup(_("The file"));
3486 extra = _("could not be found.");
3487 } else extra = lives_strdup("");
3488 whatitis = (_("this file"));
3489 } else {
3490 if (!detail) {
3491 xdetail = lives_strdup(_("The directory"));
3492 extra = _("could not be found.");
3493 } else extra = lives_strdup("");
3494 whatitis = (_("this directory"));
3495 }
3496 msg = lives_strdup_printf(_("\n%s\n%s\n%s\n"
3497 "Click Retry to try again, Browse to browse to the new location.\n"
3498 "otherwise click Skip to skip loading %s.\n"), xdetail, dfname, extra, whatitis);
3500 response = lives_dialog_run(LIVES_DIALOG(warning));
3501 lives_widget_destroy(warning);
3503 lives_free(msg); lives_free(whatitis);
3504 if (xdetail != detail) lives_free(xdetail);
3505 return response;
3506}
3507
3508
3509LiVESResponseType do_dir_notfound_dialog(const char *detail, const char *dirname) {
3510 return _do_df_notfound_dialog(detail, dirname, TRUE);
3511}
3512
3513LiVESResponseType do_file_notfound_dialog(const char *detail, const char *filename) {
3514 return _do_df_notfound_dialog(detail, filename, FALSE);
3515}
3516
3517
3521 _("\n\nLiVES could not find a required decoder plugin for the clip\n%s\n"
3522 "The clip could not be loaded.\n"), fname);
3523}
3524
3525
3527 do_error_dialogf(_("\n\nThe file\n%s\nCould not be found.\n"), fname);
3528}
3529
3530
3531#ifdef ENABLE_JACK
3533 do_error_dialogf(_("\nUnable to start up jack. "
3534 "Please ensure that %s is set up correctly on your machine\n"
3535 "and also that the soundcard is not in use by another program\n"
3536 "Automatic jack startup will be disabled now.\n"),
3537 JACK_DRIVER_NAME);
3538}
3539
3541 do_error_dialog(_("\nUnable to connect to jack server. "
3542 "Please start jack before starting LiVES\n"));
3543}
3544
3546#ifdef HAVE_PULSE_AUDIO
3547 const char *otherbit = "\"lives -aplayer pulse\"";
3548#else
3549 const char *otherbit = "\"lives -aplayer sox\"";
3550#endif
3551 do_info_dialogf(_("\nAlternatively, try to start lives with either:\n\n"
3552 "\"lives -jackopts 16\", or\n\n%s\n"), otherbit);
3553}
3554
3556 do_info_dialog(_("\nAlternately, you can restart LiVES and select another audio player.\n"));
3557}
3558#endif
3559
3560LIVES_GLOBAL_INLINE void do_mt_backup_space_error(lives_mt * mt, int memreq_mb) {
3561 char *msg = lives_strdup_printf(
3562 _("\n\nLiVES needs more backup space for this layout.\nYou can increase "
3563 "the value in Preferences/Multitrack.\n"
3564 "It is recommended to increase it to at least %d MB"),
3565 memreq_mb);
3567 lives_free(msg);
3568}
3569
3570
3572 return do_yesno_dialogf(
3573 _("\nSome old layouts for the set %s already exist.\n"
3574 "It is recommended that you delete them.\nDo you wish to delete them ?\n"),
3575 new_set);
3576}
3577
3578
3581 _("\nLiVES was unable to reserve enough memory for multitrack undo.\n"
3582 "Either close some other applications, or reduce the undo memory\n"
3583 "using Preferences/Multitrack/Undo Memory\n"));
3584}
3585
3586
3588 do_error_dialog(_("\nOut of memory for undo.\nYou may need to increase the undo memory\n"
3589 "using Preferences/Multitrack/Undo Memory\n"));
3590}
3591
3592
3594 char *msg1 = (_("\nLiVES was unable to reserve enough memory for the multitrack undo buffer.\n"));
3595 char *msg2;
3596 char *msg3 = (_("or enter a smaller value.\n"));
3597
3598 if (has_mt) msg2 = (_("Try again from the clip editor, try closing some other applications\n"));
3599 else msg2 = (_("Try closing some other applications\n"));
3600
3601 do_error_dialogf("%s%s%s", msg1, msg2, msg3);
3602 lives_free(msg1); lives_free(msg2); lives_free(msg3);
3603}
3604
3605
3608 _("Multitrack is set to 0 audio channels, but this layout has audio.\n"
3609 "You should adjust the audio settings from the Tools menu.\n"),
3610 warn_mask);
3611}
3612
3613
3615 do_error_dialog(_("The current layout has audio, so audio channels may not be set to zero.\n"));
3616}
3617
3618
3621 _("Multitrack audio preview is only available with the\n\"jack\" or \"pulseaudio\" audio player.\n"
3622 "You can set this in Tools|Preferences|Playback."),
3623 warn_mask);
3624}
3625
3626
3628 return do_yesno_dialog(
3629 _("Errors were detected in the layout (which may be due to transferring from another system, "
3630 "or from an older version of LiVES).\n"
3631 "Should I try to repair the disk copy of the layout ?\n"));
3632}
3633
3634
3636 do_error_dialog(_("LiVES was unable to load the layout.\nSorry.\n"));
3637}
3638
3639
3641 do_error_dialogf(_("The program %s is required to use this feature.\nPlease install it and try again."), progname);
3642}
3643
3644
3647 _("LiVES currently requires composite from ImageMagick to do letterboxing.\n"
3648 "Please install 'imagemagick' and try again."));
3649}
3650
3651
3654 _("LiVES currently requires convert from ImageMagick to do letterboxing.\n"
3655 "Please install 'imagemagick' and try again."));
3656}
3657
3658
3659LIVES_GLOBAL_INLINE boolean do_please_install(const char *exec, uint64_t gflags) {
3660 char *extra = lives_strdup(""), *msg;
3661 if (gflags & INSTALL_CANLOCAL) {
3662 lives_free(extra);
3663 extra = lives_strdup(_("\n\nAlternately, LiVES may be able to install\na local user copy "
3664 "of the program.\n"));
3665 }
3666
3667 msg = lives_strdup_printf(_("'%s' is necessary for this feature to work.\n"
3668 "If possible, kindly install it before continuing.%s"), exec, extra);
3669
3670 if (gflags & INSTALL_CANLOCAL) {
3671 LiVESWidget *dlg = create_question_dialog(NULL, msg);
3672 LiVESResponseType ret;
3673 lives_free(msg);
3675 lives_dialog_add_button_from_stock(LIVES_DIALOG(dlg), LIVES_STOCK_CANCEL,
3676 _("Cancel / Install Later"), LIVES_RESPONSE_CANCEL);
3677 lives_dialog_add_button_from_stock(LIVES_DIALOG(dlg), LIVES_STOCK_ADD,
3678 _("Continue"), LIVES_RESPONSE_YES);
3680
3681 lives_dialog_set_button_layout(LIVES_DIALOG(dlg), LIVES_BUTTONBOX_SPREAD);
3682
3683 ret = lives_dialog_run(LIVES_DIALOG(dlg));
3686 return (ret == LIVES_RESPONSE_YES);
3687 }
3688 do_info_dialog(msg);
3689 lives_free(msg);
3690 return FALSE;
3691}
3692
3693
3694LIVES_GLOBAL_INLINE boolean do_please_install_either(const char *exec, const char *exec2) {
3695 do_info_dialogf(_("Either '%s' or '%s' must be installed for this feature to work.\n"
3696 "If possible, kindly install one or other of these before continuing\n"),
3697 exec, exec2);
3698 return FALSE;
3699}
3700
3701
3703 do_error_dialog(_("\n\nAudio rate must be greater than 0.\n"));
3704}
3705
3706
3708 return do_yesno_dialog(
3709 _("\nEvent list will be very large\nand may take a long time to display.\n"
3710 "Are you sure you wish to view it ?\n"));
3711}
3712
3713
3715 do_error_dialog(_("\n\nYou must install 'dvgrab' to use this function.\n"));
3716}
3717
3718
3721 _("\n\nAudio recording can only be done using either\nthe \"jack\" "
3722 "or the \"pulseaudio\" audio player.\n"
3723 "You may need to select one of these in Tools/Preferences/Playback.\n"));
3724}
3725
3726
3728 do_error_dialog(_("Video playback plugin failed to initialise palette !\n"));
3729}
3730
3731
3733 do_error_dialog(_("Decoder plugin failed to initialise palette !\n"));
3734}
3735
3736
3738 do_error_dialog(_("Unable to set framerate of video plugin\n"));
3739}
3740
3741
3743 do_error_dialog_with_check(_("After a crash, it is advisable to clean up the disk with\nFile|Clean up disk space\n"),
3745}
3746
3747
3749 do_error_dialog_with_check(_("Invalid clips were detected during reload.\nIt is advisable to clean up the disk with\n"
3750 "File|Clean up disk space\n"),
3752}
3753
3754
3756 do_error_dialogf(_("Stream frame size is too large for your network buffers.\nYou should do the following as root:\n\n"
3757 "echo %d > /proc/sys/net/core/rmem_max\n"), size);
3758}
3759
3760static LiVESList *tdlglist = NULL;
3761
3763 if (mainw->proc_ptr) {
3764 tdlglist = lives_list_prepend(tdlglist, mainw->proc_ptr);
3766 mainw->proc_ptr = NULL;
3767 }
3769}
3770
3773 if (tdlglist) {
3774 LiVESList *xtdlglist;
3775 mainw->proc_ptr = (xprocess *)tdlglist->data;
3776 xtdlglist = tdlglist;
3777 tdlglist = tdlglist->next;
3778 if (tdlglist) tdlglist->prev = NULL;
3779 xtdlglist->next = NULL;
3780 xtdlglist->data = NULL;
3781 lives_list_free(xtdlglist);
3787 }
3788 }
3789}
3790
3791
3792static void _threaded_dialog_spin(double fraction) {
3793 double timesofar;
3794 int progress;
3795
3796 if (fraction > 0.) {
3797 timesofar = (double)(lives_get_current_ticks() - sttime) / TICKS_PER_SECOND_DBL;
3798 disp_fraction(fraction, timesofar, mainw->proc_ptr);
3799 } else {
3801 *(mainw->msg) || !(progress = atoi(mainw->msg))) {
3802 // pulse the progress bar
3803 //#define GDB
3804#ifndef GDB
3805 if (LIVES_IS_PROGRESS_BAR(mainw->proc_ptr->progressbar)) {
3806 lives_progress_bar_pulse(LIVES_PROGRESS_BAR(mainw->proc_ptr->progressbar));
3807 }
3808#endif
3809 } else {
3810 // show fraction
3811 double fraction_done = (double)(progress - mainw->proc_ptr->progress_start)
3812 / (double)(mainw->proc_ptr->progress_end - mainw->proc_ptr->progress_start + 1.);
3813 timesofar = (double)(lives_get_current_ticks() - sttime) / TICKS_PER_SECOND_DBL;
3814 disp_fraction(fraction_done, timesofar, mainw->proc_ptr);
3815 }
3816 }
3817 // necessary
3819 //lives_widget_process_updates(mainw->proc_ptr->processing);
3820}
3821
3822
3823void threaded_dialog_spin(double fraction) {
3825 || !mainw->is_ready || !prefs->show_gui) return;
3826 if (!mainw->is_exiting) {
3827 if (THREADVAR(no_gui)) return;
3828 main_thread_execute((lives_funcptr_t)_threaded_dialog_spin, 0,
3829 NULL, "d", fraction);
3830 } else _threaded_dialog_spin(fraction);
3831}
3832
3833static void _do_threaded_dialog(const char *trans_text, boolean has_cancel) {
3834 // calling this causes a threaded progress dialog to appear
3835 // until end_threaded_dialog() is called
3836 char *copy_text;
3838 copy_text = lives_strdup(trans_text);
3840 sttime = lives_get_current_ticks();
3843 mainw->proc_ptr = create_threaded_dialog(copy_text, has_cancel, &td_had_focus);
3844 lives_free(copy_text);
3846}
3847
3848
3849void do_threaded_dialog(const char *trans_text, boolean has_cancel) {
3850 if (!prefs->show_gui) return;
3851 if (mainw->threaded_dialog || !prefs->show_gui) return;
3852 if (!mainw->is_exiting)
3853 main_thread_execute((lives_funcptr_t)_do_threaded_dialog, 0,
3854 NULL, "sb", trans_text, has_cancel);
3855 else
3856 _do_threaded_dialog(trans_text, has_cancel);
3857}
3858
3859
3860static void _end_threaded_dialog(void) {
3861 if (!mainw->threaded_dialog) return;
3863
3865
3868
3869 lives_freep((void **)&mainw->proc_ptr);
3870
3872
3873 if (prefs->show_msg_area) {
3874 // TODO
3875 if (LIVES_IS_WINDOW(LIVES_MAIN_WINDOW_WIDGET)) {
3878 gtk_window_set_focus(LIVES_WINDOW(LIVES_MAIN_WINDOW_WIDGET), mainw->msg_area);
3879 }
3880 }
3881}
3882
3884 if (THREADVAR(no_gui)) return;
3885 if (!mainw->threaded_dialog) return;
3886 if (!mainw->is_exiting)
3887 main_thread_execute((lives_funcptr_t)_end_threaded_dialog, 0, NULL, "");
3888 else _end_threaded_dialog();
3889}
3890
3891
3892void response_ok(LiVESButton * button, livespointer user_data) {
3893 lives_dialog_response(LIVES_DIALOG(lives_widget_get_toplevel(LIVES_WIDGET(button))), LIVES_RESPONSE_OK);
3894}
3895
3896
3897LiVESResponseType do_system_failed_error(const char *com, int retval, const char *addinfo,
3898 boolean can_retry, boolean trysudo) {
3899 // if can_retry is set, we can return LIVES_RESPONSE_RETRY
3900 // in all other cases we abort (exit) here.
3901 // if abort_hook_func() fails with a syserror, we don't show the abort / retry dialog, and we return LIVES_RESPONSE_NONE
3902 // from the inner call (otherwise we could get stuck in an infinite recursion)
3903 static boolean norecurse = FALSE;
3904 char *xcom, *xaddbit, *xbit, *xsudomsg;
3905 char *msg, *tmp, *emsg, *msgx, *bit;
3906 char *retstr = lives_strdup_printf("%d", retval >> 8);
3907 char *bit2 = (retval > 255) ? lives_strdup("") : lives_strdup_printf("[%s]", lives_strerror(retval));
3908 char *addbit;
3909 char *dsmsg = lives_strdup("");
3910 char *sudomsg = lives_strdup("");
3911
3912 int64_t dsval = capable->ds_used;
3913
3915 LiVESResponseType response = LIVES_RESPONSE_NONE;
3916
3917 capable->ds_free = dsval;
3918
3920 lives_free(dsmsg);
3922 dsmsg = lives_strdup_printf("%s\n", tmp);
3923 lives_free(tmp);
3924 }
3925
3926 if (addinfo) addbit = lives_strdup_printf(_("Additional info: %s\n"), addinfo);
3927 else addbit = lives_strdup("");
3928
3929 if (retval > 0) bit = lives_strdup_printf(_("The error value was %d%s\n"), retval, bit2);
3930 else bit = lives_strdup("");
3931
3932 if (trysudo) {
3933 char *retryop;
3934 if (can_retry) retryop = (_("before clicking 'Retry'"));
3935 else retryop = (_("before retrying the operation"));
3936 lives_free(sudomsg);
3937 sudomsg = lives_strdup_printf(_("\n\nYou may be able to fix this by running:\n %s %s\n"
3938 "from the commandline %s"), EXEC_SUDO, com, retryop);
3939 lives_free(retryop);
3940 }
3941
3942 xcom = lives_markup_escape_text(com, -1);
3943 xbit = lives_markup_escape_text(bit, -1);
3944 xaddbit = lives_markup_escape_text(addbit, -1);
3945 xsudomsg = lives_markup_escape_text(sudomsg, -1);
3946
3947 msg = lives_strdup_printf(_("\nLiVES failed doing the following:\n%s\nPlease check your system for "
3948 "errors.\n%s%s%s"),
3949 xcom, xbit, xaddbit, dsmsg, xsudomsg);
3950
3951 lives_free(xcom); lives_free(xbit); lives_free(xaddbit); lives_free(xsudomsg);
3952 emsg = lives_strdup_printf("Command failed doing\n%s\n%s%s", com, bit, addbit);
3953 d_print("\n"); d_print(emsg);
3954 LIVES_ERROR(emsg);
3955 lives_free(emsg);
3956
3958 if (can_retry) {
3959 if (!norecurse) {
3961 norecurse = TRUE;
3963 response = do_abort_retry_dialog(msgx);
3965 norecurse = FALSE;
3966 }
3967 } else {
3969 do_error_dialog(msgx);
3971 }
3972 lives_free(msgx); lives_free(msg); lives_free(sudomsg);
3973 lives_free(dsmsg); lives_free(bit); lives_free(bit2);
3974 lives_free(addbit); lives_free(retstr);
3975 return response;
3976}
3977
3978
3979void do_write_failed_error_s(const char *s, const char *addinfo) {
3980 char *msg, *emsg;
3981 char *addbit, *tmp;
3982 char *dsmsg = lives_strdup("");
3983
3984 char dirname[PATH_MAX];
3985 char *sutf = lives_filename_to_utf8(s, -1, NULL, NULL, NULL), *xsutf, *xaddbit;
3986
3987 boolean exists;
3988
3989 int64_t dsval = capable->ds_used;
3990
3992
3993 lives_snprintf(dirname, PATH_MAX, "%s", s);
3994 get_dirname(dirname);
3995 exists = lives_file_test(dirname, LIVES_FILE_TEST_EXISTS);
3996 ds = get_storage_status(dirname, prefs->ds_crit_level, &dsval, 0);
3997 capable->ds_free = dsval;
3998 if (!exists) lives_rmdir(dirname, FALSE);
3999
4001 lives_free(dsmsg);
4002 tmp = ds_critical_msg(dirname, &capable->mountpoint, dsval);
4003 dsmsg = lives_strdup_printf("%s\n", tmp);
4004 lives_free(tmp);
4005 }
4006
4007 if (addinfo) addbit = lives_strdup_printf(_("Additional info: %s\n"), addinfo);
4008 else addbit = lives_strdup("");
4009
4010 xsutf = lives_markup_escape_text(sutf, -1);
4011 lives_free(sutf);
4012
4013 xaddbit = lives_markup_escape_text(addbit, -1);
4014
4015 msg = lives_strdup_printf(_("\nLiVES was unable to write to the file\n%s\n"
4016 "Please check for possible error causes.\n%s"),
4017 xsutf, xaddbit, dsmsg);
4018 lives_free(xsutf); lives_free(xaddbit);
4019
4020 emsg = lives_strdup_printf("Unable to write to file\n%s\n%s", s, addbit);
4021 lives_free(addbit);
4022 d_print("\n"); d_print(emsg);
4023
4024 LIVES_ERROR(emsg);
4025 lives_free(emsg);
4026
4028 do_error_dialog(msg);
4030 lives_free(addbit); lives_free(dsmsg); lives_free(msg);
4031}
4032
4033
4034void do_read_failed_error_s(const char *s, const char *addinfo) {
4035 char *msg, *emsg;
4036 char *addbit;
4037 char *sutf = lives_filename_to_utf8(s, -1, NULL, NULL, NULL);
4038
4039 if (addinfo) addbit = lives_strdup_printf(_("Additional info: %s\n"), addinfo);
4040 else addbit = lives_strdup("");
4041
4042 msg = lives_strdup_printf(_("\nLiVES was unable to read from the file\n%s\n"
4043 "Please check for possible error causes.\n%s"),
4044 sutf, addbit);
4045 emsg = lives_strdup_printf("Unable to read from the file\n%s\n%s", s, addbit);
4046 d_print("\n"); d_print(emsg);
4047
4048 LIVES_ERROR(emsg);
4049 lives_free(emsg);
4050 lives_free(sutf);
4051
4052 do_error_dialog(msg);
4053 lives_free(msg);
4054 lives_free(addbit);
4055}
4056
4057
4058LiVESResponseType do_write_failed_error_s_with_retry(const char *fname, const char *errtext) {
4059 // err can be errno from open/fopen etc.
4060
4061 // return same as do_abort_cancel_retry_dialog() - LIVES_RESPONSE_CANCEL or LIVES_RESPONSE_RETRY (both non-zero)
4062
4063 LiVESResponseType ret;
4064 char *msg, *emsg, *tmp;
4065 char *sutf = lives_filename_to_utf8(fname, -1, NULL, NULL, NULL), *xsutf;
4066 char *dsmsg = lives_strdup("");
4067
4068 char dirname[PATH_MAX];
4069
4070 boolean exists;
4071
4072 int64_t dsval = capable->ds_used;
4073
4075
4076 lives_snprintf(dirname, PATH_MAX, "%s", fname);
4077 get_dirname(dirname);
4078 exists = lives_file_test(dirname, LIVES_FILE_TEST_EXISTS);
4079 ds = get_storage_status(dirname, prefs->ds_crit_level, &dsval, 0);
4080 capable->ds_free = dsval;
4081 if (!exists) lives_rmdir(dirname, FALSE);
4082
4084 lives_free(dsmsg);
4085 tmp = ds_critical_msg(dirname, &capable->mountpoint, dsval);
4086 dsmsg = lives_strdup_printf("%s\n", tmp);
4087 lives_free(tmp);
4088 }
4089
4090 xsutf = lives_markup_escape_text(sutf, -1);
4091
4092 if (errtext) {
4093 emsg = lives_strdup_printf("Unable to write to file %s", fname);
4094 msg = lives_strdup_printf(_("\nLiVES was unable to write to the file\n%s\n"
4095 "Please check for possible error causes.\n%s"), xsutf, dsmsg);
4096 } else {
4097 char *xerrtext = lives_markup_escape_text(errtext, -1);
4098 emsg = lives_strdup_printf("Unable to write to file %s, error was %s", fname, errtext);
4099 msg = lives_strdup_printf(_("\nLiVES was unable to write to the file\n%s\nThe error was\n%s.\n%s"),
4100 xsutf, xerrtext, dsmsg);
4101 lives_free(xerrtext);
4102 }
4103
4104 lives_free(xsutf);
4105 LIVES_ERROR(emsg);
4106 lives_free(emsg);
4107
4111
4112 lives_free(dsmsg);
4113 lives_free(msg);
4114 lives_free(sutf);
4115
4116 THREADVAR(write_failed) = FALSE; // reset this
4117
4118 return ret;
4119}
4120
4121
4122LiVESResponseType do_read_failed_error_s_with_retry(const char *fname, const char *errtext) {
4123 // err can be errno from open/fopen etc.
4124
4125 // return same as do_abort_cancel_retry_dialog() - LIVES_RESPONSE_CANCEL or LIVES_RESPONSE_RETRY (both non-zero)
4126
4127 LiVESResponseType ret;
4128 char *msg, *emsg;
4129 char *sutf = lives_filename_to_utf8(fname, -1, NULL, NULL, NULL);
4130
4131 if (!errtext) {
4132 emsg = lives_strdup_printf("Unable to read from file %s", fname);
4133 msg = lives_strdup_printf(_("\nLiVES was unable to read from the file\n%s\n"
4134 "Please check for possible error causes.\n"), sutf);
4135 } else {
4136 emsg = lives_strdup_printf("Unable to read from file %s, error was %s", fname, errtext);
4137 msg = lives_strdup_printf(_("\nLiVES was unable to read from the file\n%s\nThe error was\n%s.\n"),
4138 sutf, errtext);
4139 }
4140
4141 LIVES_ERROR(emsg);
4142 lives_free(emsg);
4143
4145
4146 lives_free(msg);
4147 lives_free(sutf);
4148
4149 THREADVAR(read_failed) = FALSE; // reset this
4150
4151 return ret;
4152}
4153
4154
4155LiVESResponseType do_header_read_error_with_retry(int clip) {
4156 LiVESResponseType ret;
4157 char *hname;
4158 if (!mainw->files[clip]) return 0;
4159
4160 hname = lives_build_filename(prefs->workdir, mainw->files[clip]->handle, LIVES_CLIP_HEADER, NULL);
4161
4162 ret = do_read_failed_error_s_with_retry(hname, NULL);
4163
4164 lives_free(hname);
4165 return ret;
4166}
4167
4168
4169boolean do_header_write_error(int clip) {
4170 // returns TRUE if we manage to clear the error
4171
4172 char *hname;
4173 LiVESResponseType retval;
4174
4175 if (mainw->files[clip] == NULL) return TRUE;
4176
4177 hname = lives_build_filename(prefs->workdir, mainw->files[clip]->handle, LIVES_CLIP_HEADER, NULL);
4178 retval = do_write_failed_error_s_with_retry(hname, NULL);
4179 if (retval == LIVES_RESPONSE_RETRY && save_clip_values(clip)) retval = 0; // on retry try to save all values
4180 lives_free(hname);
4181
4182 return (!retval);
4183}
4184
4185
4186LiVESResponseType do_header_missing_detail_error(int clip, lives_clip_details_t detail) {
4187 LiVESResponseType ret;
4188 char *hname, *key, *msg;
4189 if (!mainw->files[clip]) return 0;
4190
4191 hname = lives_build_filename(prefs->workdir, mainw->files[clip]->handle, LIVES_CLIP_HEADER, NULL);
4192
4193 key = clip_detail_to_string(detail, NULL);
4194
4195 if (!key) {
4196 msg = lives_strdup_printf("Invalid detail %d requested from file %s", detail, hname);
4197 LIVES_ERROR(msg);
4198 lives_free(msg);
4199 lives_free(hname);
4200 return 0;
4201 }
4202
4203 msg = lives_strdup_printf(_("Value for \"%s\" could not be read."), key);
4204 ret = do_read_failed_error_s_with_retry(hname, msg);
4205
4206 lives_free(msg);
4207 lives_free(key);
4208 lives_free(hname);
4209 return ret;
4210}
4211
4212
4213void do_chdir_failed_error(const char *dir) {
4214 char *dutf, *msg, *emsg = lives_strdup_printf("Failed directory change to\n%s", dir);
4215 LIVES_ERROR(emsg);
4216 lives_free(emsg);
4217 dutf = lives_filename_to_utf8(dir, -1, NULL, NULL, NULL);
4218 msg = lives_strdup_printf(_("\nLiVES failed to change directory to\n%s\n"
4219 "Please check your system for errors.\n"), dutf);
4220 lives_free(dutf);
4221 do_abort_ok_dialog(msg);
4222 lives_free(msg);
4223}
4224
4225
4226LiVESResponseType do_file_perm_error(const char *file_name, boolean allow_cancel) {
4227 LiVESResponseType resp;
4228 char *msg, *can_cancel;
4229 if (allow_cancel)
4230 can_cancel = (_(", click Cancel to continue regardless,\n"));
4231 else
4232 can_cancel = lives_strdup("");
4233
4234 msg = lives_strdup_printf(_("\nLiVES was unable to write to the file:\n%s\n"
4235 "Please check the file permissions and try again."
4236 "%sor click Abort to exit from LiVES"), file_name, can_cancel);
4237 resp = do_abort_retry_dialog(msg);
4238 if (!allow_cancel)
4239 resp = do_abort_retry_dialog(msg);
4240 else
4241 resp = do_abort_cancel_retry_dialog(msg);
4242 lives_free(msg);
4243 return resp;
4244}
4245
4246
4247LiVESResponseType do_dir_perm_error(const char *dir_name, boolean allow_cancel) {
4248 LiVESResponseType resp;
4249 char *msg, *can_cancel;
4250 if (allow_cancel)
4251 can_cancel = (_("click Cancel to continue regardless, "));
4252 else
4253 can_cancel = lives_strdup("");
4254
4255 msg = lives_strdup_printf(_("\nLiVES was unable to either create or write to the directory:\n%s\n"
4256 "Please check the directory permissions and try again,\n"
4257 "%sor click Abort to exit from LiVES"), dir_name, can_cancel);
4258 lives_free(can_cancel);
4259
4260 if (!allow_cancel)
4261 resp = do_abort_retry_dialog(msg);
4262 else
4263 resp = do_abort_cancel_retry_dialog(msg);
4264
4265 lives_free(msg);
4266 return resp;
4267}
4268
4269
4270void do_dir_perm_access_error(const char *dir_name) {
4271 char *msg = lives_strdup_printf(_("\nLiVES was unable to read from the directory:\n%s\n"), dir_name);
4272 do_abort_ok_dialog(msg);
4273 lives_free(msg);
4274}
4275
4276
4277boolean do_abort_check(void) {
4278 return do_yesno_dialog(_("\nAbort and exit immediately from LiVES\nAre you sure ?\n"));
4279}
4280
4281
4283 do_error_dialogf(_("\nThe %s cannot encode clips with image type %s.\n"
4284 "Please select another encoder from the list.\n"),
4286}
4287
4288
4290 do_error_dialog(_("\nThis card is already in use and cannot be opened multiple times.\n"));
4291}
4292
4293
4294LIVES_GLOBAL_INLINE void do_dev_busy_error(const char *devstr) {
4295 do_error_dialogf(_("\nThe device %s is in use or unavailable.\n"
4296 "- Check the device permissions\n"
4297 "- Check if this device is in use by another program.\n"
4298 "- Check if the device actually exists.\n"), devstr);
4299}
4300
4301
4303 return do_yesno_dialog(_("\nThis file already has subtitles loaded.\n"
4304 "Do you wish to overwrite the existing subtitles ?\n"));
4305}
4306
4307
4309 char *msg = (_("\nLiVES currently only supports subtitles of type"));
4310 char *tmp;
4311
4312 char *filt[] = LIVES_SUBS_FILTER;
4313
4314 register int i = 0;
4315
4316 while (filt[i]) {
4317 if (!filt[i + 1]) {
4318 tmp = lives_strdup_printf("%s or .%s\n", msg, filt[i] + 2);
4319 } else if (i > 0) {
4320 tmp = lives_strdup_printf("%s, .%s)", msg, filt[i] + 2);
4321 } else {
4322 tmp = lives_strdup_printf("%s .%s)", msg, filt[i] + 2);
4323 }
4324 lives_free(msg);
4325 msg = tmp;
4326 i++;
4327 }
4328
4329 do_error_dialog(msg);
4330 lives_free(msg);
4331}
4332
4333
4335 return do_yesno_dialog(_("\nErase all subtitles from this clip.\nAre you sure ?\n"));
4336}
4337
4338
4339boolean do_sub_type_warning(const char *ext, const char *type_ext) {
4340 boolean ret;
4341 char *msg = lives_strdup_printf(
4342 _("\nLiVES does not recognise the subtitle file type \"%s\".\n"
4343 "Click Cancel to set another file name\nor OK to continue and save as type \"%s\"\n"),
4344 ext, type_ext);
4345 ret = do_warning_dialogf(msg);
4346 lives_free(msg);
4347 return ret;
4348}
4349
4350
4352 return do_yesno_dialog(_("\nDo you wish to move the current clip sets to the new directory ?\n("
4353 "If unsure, click Yes)\n"));
4354}
4355
4356
4357LIVES_GLOBAL_INLINE boolean do_set_locked_warning(const char *setname) {
4358 return do_yesno_dialogf(
4359 _("\nWarning - the set %s\nis in use by another copy of LiVES.\n"
4360 "You are strongly advised to close the other copy before clicking Yes to continue\n.\n"
4361 "Click No to cancel loading the set.\n"),
4362 setname);
4363}
4364
4365
4367 extra_cb_key = 1;
4368 do_info_dialogf(_("No Sets could be found in the directory\n%s\n\n"
4369 "If you have Sets in another directory, you can either:\n"
4370 " - change the working directory in Preferences, or\n"
4371 " - restart lives with the -workdir switch to set it temporarily"),
4372 dir);
4373}
4374
4375
4376boolean do_foundclips_query(void) {
4377 char *text = (_("Possible lost clips were detected within the LiVES working directory.\n"
4378 "What would you like me to do with them ?\n"));
4379 char *title = (_("Missing Clips Detected"));
4380 LiVESWidget *dlg = create_question_dialog(title, text);
4381 LiVESResponseType ret;
4382 lives_free(text); lives_free(title);
4384 lives_dialog_add_button_from_stock(LIVES_DIALOG(dlg), LIVES_STOCK_CLEAR,
4385 _("Maybe later"), LIVES_RESPONSE_NO);
4386 lives_dialog_add_button_from_stock(LIVES_DIALOG(dlg), LIVES_STOCK_REMOVE,
4387 _("Try to recover them"), LIVES_RESPONSE_YES);
4389
4390 lives_dialog_set_button_layout(LIVES_DIALOG(dlg), LIVES_BUTTONBOX_SPREAD);
4391
4392 ret = lives_dialog_run(LIVES_DIALOG(dlg));
4395 return (ret == LIVES_RESPONSE_YES);
4396}
4397
4398
4400 do_error_dialog(_("\nNo video input devices could be found.\n"));
4401}
4402
4403
4405 do_error_dialog(_("\nAll video input devices are already in use.\n"));
4406}
4407
4408
4410 char *msg = (_("\n\nCLEANING AND COPYING FILES. THIS MAY TAKE SOME TIME.\nDO NOT SHUT DOWN OR "
4411 "CLOSE LIVES !\n"));
4413 lives_free(msg);
4414}
4415
4416
4417LIVES_GLOBAL_INLINE LiVESResponseType do_resize_dlg(int cwidth, int cheight, int fwidth, int fheight) {
4418 LiVESWidget *butt;
4419 LiVESResponseType resp;
4420 char *text = lives_strdup_printf(_("Some frames in this clip may be wrongly sized.\n"
4421 "The clip size is %d X %d, however at least one frame has size %d X %d\n"
4422 "What would you like to do ?"), cwidth, cheight, fwidth, fheight);
4423
4424 LiVESWidget *dialog = create_question_dialog(_("Problem Detected"), text);
4425
4426 lives_free(text);
4427
4429 lives_dialog_add_button_from_stock(LIVES_DIALOG(dialog), LIVES_STOCK_CANCEL, _("Continue anyway"),
4430 LIVES_RESPONSE_CANCEL);
4431
4432 lives_dialog_add_button_from_stock(LIVES_DIALOG(dialog), LIVES_STOCK_CLEAR, _("Use the image size"),
4433 LIVES_RESPONSE_ACCEPT);
4434
4435 butt = lives_dialog_add_button_from_stock(LIVES_DIALOG(dialog), LIVES_STOCK_REVERT_TO_SAVED,
4436 _("Resize images to clip size"),
4437 LIVES_RESPONSE_YES);
4440
4441 lives_dialog_set_button_layout(LIVES_DIALOG(dialog), LIVES_BUTTONBOX_EXPAND);
4442 resp = lives_dialog_run(LIVES_DIALOG(dialog));
4443 lives_widget_destroy(dialog);
4445 return resp;
4446}
4447
4448
4450 LiVESResponseType resp;
4451 char *text = lives_strdup_printf(_("Some frames in this clip have the wrong image format.\n"
4452 "The image format should be %s\n"
4453 "What would you like to do ?"),
4455
4456 LiVESWidget *dialog = create_question_dialog(_("Problem Detected"), text);
4457
4458 lives_free(text);
4459
4461 lives_dialog_add_button_from_stock(LIVES_DIALOG(dialog), LIVES_STOCK_CANCEL, _("Continue anyway"),
4462 LIVES_RESPONSE_CANCEL);
4463
4464 lives_dialog_add_button_from_stock(LIVES_DIALOG(dialog), LIVES_STOCK_REVERT_TO_SAVED, _("Correct the images"),
4465 LIVES_RESPONSE_OK);
4467
4468 resp = lives_dialog_run(LIVES_DIALOG(dialog));
4469 lives_widget_destroy(dialog);
4470 return resp;
4471}
4472
4473
4474LIVES_GLOBAL_INLINE void do_bad_theme_error(const char *themefile) {
4475 do_error_dialogf(_("\nThe theme file %s has missing elements.\n"
4476 "The theme could not be loaded correctly.\n"), themefile);
4477}
4478
4479
4481 char *msg = lives_strdup_printf(
4482 _("No clips were recovered for set (%s).\n"
4483 "Please check the spelling of the set name and try again.\n"),
4484 setname);
4485 d_print(msg);
4486 lives_free(msg);
4487}
4488
4489
4491 LIVES_DEBUG("upd msg !");
4492 // TRANSLATORS: make sure the menu text matches what is in gui.c
4493 char *msg = lives_strdup_printf(_("\nWelcome to LiVES version %s\n\n"
4494 "After upgrading, you are advised to run:"
4495 "\n\nFiles -> Clean up Diskspace\n"), LiVES_VERSION);
4496 return msg;
4497}
4498
4499
4501 do_error_dialogf(_("\nYou must have %s installed and in your path to use this toy.\n"
4502 "Consult your package distributor.\n"),
4504}
4505
4506
4508 do_error_dialog(_("\nYou must have a minimum of one clip loaded to use this toy.\n"));
4509}
4510
4511
4513 do_error_dialog(_("\nLiVES lost its connection to jack and was unable to reconnect.\n"
4514 "Restarting LiVES is recommended.\n"));
4515}
4516
4517
4520 _("\nLiVES lost its connection to pulseaudio and was unable to reconnect.\n"
4521 "Restarting LiVES is recommended.\n"));
4522}
4523
4524
4526 do_error_dialog(_("Please set your CD play device in Tools | Preferences | Misc\n"));
4527}
4528
4529
4531 do_error_dialogf(_("\nLiVES was unable to import the theme file\n%s\n(Theme name not found).\n"),
4532 theme_file);
4533}
4534
4535
4537 extra_cb_key = 2;
4538 del_cb_key = 2;
4539 return do_warning_dialog(_("Changes made to this clip have not been saved or backed up.\n\n"
4540 "Really close it ?"));
4541}
4542
4543
4545 return lives_strdup(
4546 _("You have chosen to change the working directory.\n"
4547 "Please make sure you have no other copies of LiVES open.\n\n"
4548 "If you do have other copies of LiVES open, please close them now, "
4549 "*before* pressing OK.\n\n"
4550 "Alternatively, press Cancel to restore the working directory to its original setting."));
4551}
4552
4553
4556 _("\nLiVES will now shut down. You need to restart it for the new "
4557 "preferences to take effect.\nClick OK to continue.\n"));
4558}
4559
4560
4561LIVES_GLOBAL_INLINE boolean do_theme_exists_warn(const char *themename) {
4562 return do_yesno_dialogf(_("\nA custom theme with the name\n%s\nalready exists. "
4563 "Would you like to overwrite it ?\n"), themename);
4564}
4565
4566
4567void add_resnn_label(LiVESDialog * dialog) {
4568 LiVESWidget *dialog_vbox = lives_dialog_get_content_area(dialog);
4569 LiVESWidget *label;
4570 LiVESWidget *hsep = lives_standard_hseparator_new();
4571 lives_box_pack_first(LIVES_BOX(dialog_vbox), hsep, FALSE, TRUE, 0);
4572 lives_widget_show(hsep);
4573 widget_opts.justify = LIVES_JUSTIFY_CENTER;
4575 "\n\nResizing of clips is no longer necessary, "
4576 "as LiVES will internally adjust frame sizes as "
4577 "needed at the appropriate moments.\n\n"
4578 "However, physically reducing the frame size may in some cases "
4579 "lead to improved playback \n"
4580 "and processing rates.\n\n"));
4582 lives_box_pack_first(LIVES_BOX(dialog_vbox), label, FALSE, TRUE, 0);
4583 lives_widget_show(label);
4584}
4585
4586
4587boolean ask_permission_dialog(int what) {
4588 if (!prefs->show_gui) return FALSE;
4589
4590 switch (what) {
4592 return do_yesno_dialogf(
4593 _("\nLiVES would like to open a local network connection (UDP port %d),\n"
4594 "to let other applications connect to it.\n"
4595 "Do you wish to allow this (for this session only) ?\n"),
4597 default:
4598 break;
4599 }
4600
4601 return FALSE;
4602}
4603
4604
4605boolean ask_permission_dialog_complex(int what, char **argv, int argc, int offs, const char *sudocom) {
4606 if (prefs->show_gui) {
4607 LiVESWidget *dlg;
4608 LiVESResponseType ret;
4609 char *text, *title, *prname, *errtxt, *errtxt2, *xsudt;
4610 char *tmp, *action, *verb;
4611 int nrem = argc - offs;
4612 //boolean retry;
4613
4614 //try_again:
4615 //retry = FALSE;
4616 switch (what) {
4619 // argv (starting at offs) should have: name_of_package_bin, grant_idx, grant_key,
4620 // cmds to run, future consequences.
4621 if (nrem < 4) return FALSE;
4622
4624 mainw->permmgr->idx = atoi(argv[offs + 1]);
4625 mainw->permmgr->key = lives_strdup(argv[offs + 2]);
4626 if (nrem >= 4) mainw->permmgr->cmdlist = argv[offs + 3];
4627 if (nrem >= 5) mainw->permmgr->futures = argv[offs + 4];
4628
4629 if (sudocom) {
4630 char *sudotext = lives_strdup_printf(_("Alternately, you can try running\n"
4631 " %s %s\n from a commandline terminal\n"),
4632 EXEC_SUDO, sudocom);
4633 xsudt = lives_markup_escape_text(sudotext, -1);
4634 lives_free(sudotext);
4635 } else xsudt = lives_strdup("");
4636
4637 prname = lives_markup_escape_text(argv[offs], -1);
4638 errtxt = lives_markup_escape_text(argv[3], -1);
4639
4640 if (errtxt && *errtxt)
4641 errtxt2 = lives_strdup_printf(_("The following error occurred when running %s:"
4642 "\n\n'%s'\n\n"), prname, errtxt);
4643 else
4644 errtxt2 = lives_strdup_printf(_("LiVES was not able to run the programe %s\n"), prname);
4645
4646 lives_free(errtxt);
4647
4648 if (what == LIVES_PERM_DOWNLOAD_LOCAL) {
4649 verb = _("download");
4650 action = _("by downloading");
4651 } else {
4652 verb = _("copying");
4653 action = lives_strdup(_("by creating"));
4654 }
4655
4656 text = lives_strdup_printf(_("%sYou may need to reinstall or update %s\n\n"
4657 "<b>Alternately, it may be possible to fix this "
4658 "%s an individual copy of the program\n%s to your "
4659 "home directory</b>\n"
4660 "Please consider the options "
4661 "and then decide how to proceed.\n"),
4662 errtxt2, prname, action, prname);
4663
4664 lives_free(prname); lives_free(xsudt); lives_free(errtxt2); lives_free(action);
4665 title = (_("Problem Detected"));
4667 dlg = create_question_dialog(title, text);
4669 lives_free(title);
4670 lives_free(text);
4672
4673 lives_dialog_add_button_from_stock(LIVES_DIALOG(dlg), LIVES_STOCK_CANCEL, NULL,
4674 LIVES_RESPONSE_CANCEL);
4675
4676 lives_dialog_add_button_from_stock(LIVES_DIALOG(dlg), LIVES_STOCK_ADD,
4677 (tmp = lives_strdup_printf(_("Proceed with %s"), verb)),
4678 LIVES_RESPONSE_YES);
4679 lives_free(tmp); lives_free(verb);
4681 ret = lives_dialog_run(LIVES_DIALOG(dlg));
4684
4685 if (ret == LIVES_RESPONSE_CANCEL) {
4686 lives_freep((void **)&mainw->permmgr->key);
4687 return FALSE;
4688 }
4689 return TRUE;
4690 default:
4691 break;
4692 }
4693 }
4694 return FALSE;
4695}
4696
4697
4699 if (!do_yesno_dialog(
4700 _("\nLiVES has detected a multitrack layout from a previous session.\n"
4701 "Would you like to try and recover it ?\n"))) {
4703 return FALSE;
4704 } else {
4705 boolean ret;
4707 //lives_widget_context_update();
4708 ret = recover_layout();
4710 return ret;
4711 }
4712}
4713
void reinit_audio_gen(void)
Definition: audio.c:3449
LIVES_GLOBAL_INLINE lives_cancel_t handle_audio_timeout(void)
Definition: audio.c:3971
#define is_realtime_aplayer(ptype)
Definition: audio.h:236
void on_effects_paused(LiVESButton *button, livespointer user_data)
Definition: callbacks.c:10122
void on_cleardisk_advanced_clicked(LiVESWidget *widget, livespointer user_data)
Definition: callbacks.c:6700
void on_preview_clicked(LiVESButton *button, livespointer user_data)
Definition: callbacks.c:10245
void on_cleardisk_activate(LiVESWidget *widget, livespointer user_data)
Definition: callbacks.c:6139
void lives_notify(int msgnumber, const char *msgstring)
Definition: callbacks.c:49
void on_cancel_keep_button_clicked(LiVESButton *button, livespointer user_data)
Definition: callbacks.c:7701
boolean clip_can_reverse(int clipno)
Definition: callbacks.c:4980
void ce_thumbs_apply_rfx_changes(void)
Definition: ce_thumbs.c:560
LIVES_GLOBAL_INLINE weed_layer_t * lives_layer_new_for_frame(int clip, frames_t frame)
Definition: colourspace.c:9833
LIVES_GLOBAL_INLINE weed_layer_t * weed_layer_free(weed_layer_t *layer)
frees pixel_data for a layer, then the layer itself
frames_t virtual_to_images(int sfileno, frames_t sframe, frames_t eframe, boolean update_progress, LiVESPixbuf **pbr)
Definition: cvirtual.c:719
boolean is_virtual_frame(int sfileno, frames_t frame)
Definition: cvirtual.c:1063
LIVES_GLOBAL_INLINE double get_inst_fps(void)
Definition: diagnostics.c:16
LIVES_GLOBAL_INLINE boolean do_existing_subs_warning(void)
Definition: dialogs.c:4302
LIVES_GLOBAL_INLINE void do_need_mplayer_mpv_dialog(void)
Definition: dialogs.c:3027
LiVESResponseType do_dir_perm_error(const char *dir_name, boolean allow_cancel)
Definition: dialogs.c:4247
LIVES_GLOBAL_INLINE LiVESWindow * get_transient_full(void)
Definition: dialogs.c:622
LIVES_GLOBAL_INLINE boolean do_set_rename_old_layouts_warning(const char *new_set)
Definition: dialogs.c:3571
LIVES_GLOBAL_INLINE void do_no_mplayer_sox_error(void)
Definition: dialogs.c:3014
LIVES_GLOBAL_INLINE void do_jack_lost_conn_error(void)
Definition: dialogs.c:4512
void pump_io_chan(LiVESIOChannel *iochan)
Definition: dialogs.c:1020
LIVES_GLOBAL_INLINE void do_do_not_close_d(void)
Definition: dialogs.c:4409
boolean do_yesno_dialog(const char *text)
Definition: dialogs.c:655
LIVES_GLOBAL_INLINE void do_messages_window(boolean is_startup)
Definition: dialogs.c:3335
LIVES_GLOBAL_INLINE void do_rmem_max_error(int size)
Definition: dialogs.c:3755
boolean do_header_write_error(int clip)
Definition: dialogs.c:4169
LIVES_GLOBAL_INLINE char * get_upd_msg(void)
Definition: dialogs.c:4490
LIVES_GLOBAL_INLINE void do_lb_convert_error(void)
Definition: dialogs.c:3652
LiVESWidget * create_message_dialog(lives_dialog_t diat, const char *text, int warn_mask_number)
Definition: dialogs.c:260
LIVES_GLOBAL_INLINE void do_mt_undo_buf_error(void)
Definition: dialogs.c:3587
boolean do_save_clipset_warn(void)
Definition: dialogs.c:2975
LiVESResponseType do_dir_notfound_dialog(const char *detail, const char *dirname)
Definition: dialogs.c:3509
LIVES_GLOBAL_INLINE void do_clip_divergence_error(int fileno)
Definition: dialogs.c:888
LIVES_GLOBAL_INLINE void do_bad_theme_import_error(const char *theme_file)
Definition: dialogs.c:4530
boolean do_set_duplicate_warning(const char *new_set)
Definition: dialogs.c:3415
LIVES_GLOBAL_INLINE void do_set_noclips_error(const char *setname)
Definition: dialogs.c:4480
LIVES_GLOBAL_INLINE boolean do_set_locked_warning(const char *setname)
Definition: dialogs.c:4357
LIVES_GLOBAL_INLINE LiVESResponseType do_info_dialog(const char *text)
Definition: dialogs.c:787
LiVESResponseType do_error_dialogf(const char *fmt,...)
Definition: dialogs.c:735
boolean do_encoder_restrict_dialog(int width, int height, double fps, int fps_num, int fps_denom, int arate, int asigned, boolean swap_endian, boolean anr, boolean save_all)
Definition: dialogs.c:3148
void do_dir_perm_access_error(const char *dir_name)
Definition: dialogs.c:4270
LIVES_GLOBAL_INLINE void do_card_in_use_error(void)
Definition: dialogs.c:4289
LiVESResponseType do_read_failed_error_s_with_retry(const char *fname, const char *errtext)
Definition: dialogs.c:4122
char * ds_warning_msg(const char *dir, char **mountpoint, uint64_t dsval, uint64_t cwarn, uint64_t nwarn)
Definition: dialogs.c:850
LIVES_GLOBAL_INLINE void do_encoder_sox_error(void)
Definition: dialogs.c:3039
LIVES_GLOBAL_INLINE LiVESResponseType do_abort_ok_dialog(const char *text)
Definition: dialogs.c:720
LIVES_GLOBAL_INLINE void do_encoder_acodec_error(void)
Definition: dialogs.c:3046
LIVES_GLOBAL_INLINE LiVESResponseType do_abort_retry_dialog(const char *text)
Definition: dialogs.c:714
boolean ask_permission_dialog(int what)
Definition: dialogs.c:4587
LIVES_GLOBAL_INLINE boolean do_theme_exists_warn(const char *themename)
Definition: dialogs.c:4561
LiVESResponseType do_system_failed_error(const char *com, int retval, const char *addinfo, boolean can_retry, boolean trysudo)
Definition: dialogs.c:3897
void do_write_failed_error_s(const char *s, const char *addinfo)
Definition: dialogs.c:3979
LIVES_GLOBAL_INLINE void do_aud_during_play_error(void)
Definition: dialogs.c:899
LIVES_GLOBAL_INLINE boolean do_erase_subs_warning(void)
Definition: dialogs.c:4334
LIVES_GLOBAL_INLINE void do_dvgrab_error(void)
Definition: dialogs.c:3714
LIVES_GLOBAL_INLINE void do_no_loadfile_error(const char *fname)
Definition: dialogs.c:3526
LIVES_GLOBAL_INLINE boolean do_move_workdir_dialog(void)
Definition: dialogs.c:4351
void do_threaded_dialog(const char *trans_text, boolean has_cancel)
Definition: dialogs.c:3849
LIVES_GLOBAL_INLINE void do_decoder_palette_error(void)
Definition: dialogs.c:3732
void update_progress(boolean visible)
Definition: dialogs.c:1275
LIVES_GLOBAL_INLINE void do_shutdown_msg(void)
Definition: dialogs.c:4554
void do_encoder_img_fmt_error(render_details *rdet)
Definition: dialogs.c:4282
LIVES_GLOBAL_INLINE void do_no_autolives_error(void)
Definition: dialogs.c:4500
LIVES_GLOBAL_INLINE boolean do_layout_recover_dialog(void)
Definition: dialogs.c:4698
boolean do_yesno_dialogf(const char *fmt,...)
Definition: dialogs.c:635
LIVES_GLOBAL_INLINE void do_no_decoder_error(const char *fname)
Definition: dialogs.c:3518
LIVES_GLOBAL_INLINE void do_mt_no_jack_error(int warn_mask)
Definition: dialogs.c:3619
LIVES_GLOBAL_INLINE void do_optarg_blank_err(const char *what)
Definition: dialogs.c:881
LIVES_GLOBAL_INLINE LiVESResponseType do_abort_cancel_retry_dialog(const char *text)
Definition: dialogs.c:708
LiVESResponseType do_file_notfound_dialog(const char *detail, const char *filename)
Definition: dialogs.c:3513
LIVES_GLOBAL_INLINE boolean do_mt_rect_prompt(void)
Definition: dialogs.c:3627
LIVES_GLOBAL_INLINE void do_pulse_lost_conn_error(void)
Definition: dialogs.c:4518
LIVES_GLOBAL_INLINE void do_vpp_fps_error(void)
Definition: dialogs.c:3737
LIVES_GLOBAL_INLINE char * workdir_ch_warning(void)
Definition: dialogs.c:4544
LiVESResponseType do_error_dialog_with_check(const char *text, uint64_t warn_mask_number)
Definition: dialogs.c:800
LiVESResponseType do_memory_error_dialog(char *op, size_t bytes)
Definition: dialogs.c:904
LIVES_GLOBAL_INLINE LiVESWidget * create_question_dialog(const char *title, const char *text)
Definition: dialogs.c:540
LIVES_GLOBAL_INLINE boolean do_reload_set_query(void)
Definition: dialogs.c:3256
LIVES_GLOBAL_INLINE void do_program_not_found_error(const char *progname)
Definition: dialogs.c:3640
LIVES_GLOBAL_INLINE void perf_mem_warning(void)
Definition: dialogs.c:3237
LIVES_GLOBAL_INLINE boolean do_layout_alter_frames_warning(void)
Definition: dialogs.c:3426
boolean do_auto_dialog(const char *text, int type)
Definition: dialogs.c:2844
LiVESResponseType do_write_failed_error_s_with_retry(const char *fname, const char *errtext)
Definition: dialogs.c:4058
LIVES_GLOBAL_INLINE void do_audio_warning(void)
Definition: dialogs.c:3034
LIVES_GLOBAL_INLINE LiVESResponseType do_resize_dlg(int cwidth, int cheight, int fwidth, int fheight)
Definition: dialogs.c:4417
LIVES_GLOBAL_INLINE void do_bad_theme_error(const char *themefile)
Definition: dialogs.c:4474
void threaded_dialog_push(void)
Definition: dialogs.c:3762
#define DROPFRAME_TRIGGER
void do_invalid_subs_error(void)
Definition: dialogs.c:4308
LIVES_GLOBAL_INLINE void do_upgrade_error_dialog(void)
Definition: dialogs.c:3358
#define MIN_FLASH_TIME
Definition: dialogs.c:2842
LIVES_GLOBAL_INLINE void do_no_sets_dialog(const char *dir)
Definition: dialogs.c:4366
boolean do_comments_dialog(int fileno, char *filename)
Definition: dialogs.c:3288
LIVES_GLOBAL_INLINE void do_lb_composite_error(void)
Definition: dialogs.c:3645
LIVES_GLOBAL_INLINE void do_after_invalid_warning(void)
Definition: dialogs.c:3748
void response_ok(LiVESButton *button, livespointer user_data)
Definition: dialogs.c:3892
LIVES_GLOBAL_INLINE LiVESResponseType do_retry_cancel_dialog(const char *text)
Definition: dialogs.c:730
char * ds_critical_msg(const char *dir, char **mountpoint, uint64_t dsval)
warn about disk space
Definition: dialogs.c:822
boolean do_close_changed_warn(void)
Definition: dialogs.c:4536
LIVES_GLOBAL_INLINE void do_nojack_rec_error(void)
Definition: dialogs.c:3719
LIVES_GLOBAL_INLINE void do_autolives_needs_clips_error(void)
Definition: dialogs.c:4507
LIVES_GLOBAL_INLINE void do_locked_in_vdevs_error(void)
Definition: dialogs.c:4404
LiVESResponseType do_info_dialogf(const char *fmt,...)
Definition: dialogs.c:773
#define ANIM_LIM
Definition: dialogs.c:1335
LIVES_GLOBAL_INLINE void do_need_mplayer_dialog(void)
Definition: dialogs.c:3020
boolean do_abort_check(void)
Definition: dialogs.c:4277
boolean do_warning_dialogf(const char *fmt,...)
Definition: dialogs.c:551
LIVES_GLOBAL_INLINE void do_mt_audchan_error(int warn_mask)
Definition: dialogs.c:3606
void threaded_dialog_pop(void)
Definition: dialogs.c:3771
LIVES_GLOBAL_INLINE void do_mt_no_audchan_error(void)
Definition: dialogs.c:3614
void end_threaded_dialog(void)
Definition: dialogs.c:3883
LIVES_GLOBAL_INLINE void too_many_files(void)
Definition: dialogs.c:2996
LIVES_GLOBAL_INLINE LiVESResponseType do_imgfmts_error(lives_img_type_t imgtype)
Definition: dialogs.c:4449
LIVES_GLOBAL_INLINE void do_rendered_fx_dialog(void)
Definition: dialogs.c:3368
LIVES_GLOBAL_INLINE boolean do_event_list_warning(void)
Definition: dialogs.c:3707
LIVES_GLOBAL_INLINE void do_mt_backup_space_error(lives_mt *mt, int memreq_mb)
Definition: dialogs.c:3560
#define ENABLE_PRECACHE
Definition: dialogs.c:1332
LIVES_GLOBAL_INLINE void do_after_crash_warning(void)
Definition: dialogs.c:3742
LIVES_GLOBAL_INLINE boolean do_gamma_import_warn(uint64_t fv, int gamma_type)
Definition: dialogs.c:3440
LIVES_GLOBAL_INLINE void do_vpp_palette_error(void)
Definition: dialogs.c:3727
boolean rdet_suggest_values(int width, int height, double fps, int fps_num, int fps_denom, int arate, int asigned, boolean swap_endian, boolean anr, boolean ignore_fps)
Definition: dialogs.c:3065
LIVES_GLOBAL_INLINE void do_mt_set_mem_error(boolean has_mt)
Definition: dialogs.c:3593
#define OPEN_CHECK_TICKS
Definition: dialogs.c:56
boolean do_foundclips_query(void)
Definition: dialogs.c:4376
LiVESResponseType handle_backend_errors(boolean can_retry)
Definition: dialogs.c:922
LIVES_GLOBAL_INLINE void do_audrate_error_dialog(void)
Definition: dialogs.c:3702
boolean do_mt_lb_warn(boolean lb)
Definition: dialogs.c:3451
LIVES_GLOBAL_INLINE void do_mt_undo_mem_error(void)
Definition: dialogs.c:3579
LIVES_GLOBAL_INLINE boolean do_please_install_either(const char *exec, const char *exec2)
Definition: dialogs.c:3694
int process_one(boolean visible)
Definition: dialogs.c:1337
LIVES_GLOBAL_INLINE boolean do_layout_alter_audio_warning(void)
Definition: dialogs.c:3433
LIVES_GLOBAL_INLINE void do_bad_layout_error(void)
Definition: dialogs.c:3635
void do_read_failed_error_s(const char *s, const char *addinfo)
Definition: dialogs.c:4034
#define JUMPFRAME_TRIGGER
LIVES_GLOBAL_INLINE void do_layout_ascrap_file_error(void)
Definition: dialogs.c:3059
void add_warn_check(LiVESBox *box, int warn_mask_number)
Definition: dialogs.c:103
LIVES_GLOBAL_INLINE LiVESResponseType do_info_dialog_with_expander(const char *text, const char *exp_text, LiVESList *list)
Definition: dialogs.c:793
const char * get_cache_stats(void)
Definition: dialogs.c:68
void do_chdir_failed_error(const char *dir)
Definition: dialogs.c:4213
#define SWITCH_COMPENSATION
LIVES_GLOBAL_INLINE LiVESResponseType do_error_dialog(const char *text)
Definition: dialogs.c:749
#define TEST_TRIGGER
LIVES_GLOBAL_INLINE void do_no_in_vdevs_error(void)
Definition: dialogs.c:4399
LIVES_GLOBAL_INLINE boolean do_warning_dialog(const char *text)
Definition: dialogs.c:564
boolean ask_permission_dialog_complex(int what, char **argv, int argc, int offs, const char *sudocom)
Definition: dialogs.c:4605
void threaded_dialog_spin(double fraction)
Definition: dialogs.c:3823
LiVESResponseType do_header_read_error_with_retry(int clip)
Definition: dialogs.c:4155
LIVES_GLOBAL_INLINE boolean do_please_install(const char *exec, uint64_t gflags)
Definition: dialogs.c:3659
boolean do_yuv4m_open_warning(void)
Definition: dialogs.c:3270
boolean check_storage_space(int clipno, boolean is_processing)
Definition: dialogs.c:1086
boolean do_sub_type_warning(const char *ext, const char *type_ext)
Definition: dialogs.c:4339
LiVESResponseType do_file_perm_error(const char *file_name, boolean allow_cancel)
Definition: dialogs.c:4226
void workdir_warning(void)
Definition: dialogs.c:3001
boolean do_clipboard_fps_warning(void)
Definition: dialogs.c:3244
void add_resnn_label(LiVESDialog *dialog)
Definition: dialogs.c:4567
void reset_frame_and_clip_index(void)
TODO: split into player, progress, dialogs.
LiVESResponseType do_header_missing_detail_error(int clip, lives_clip_details_t detail)
Definition: dialogs.c:4186
LIVES_GLOBAL_INLINE boolean paste_enough_dlg(int lframe)
Definition: dialogs.c:3266
void do_audio_import_error(void)
Definition: dialogs.c:3381
LIVES_GLOBAL_INLINE void do_dev_busy_error(const char *devstr)
Definition: dialogs.c:4294
void on_warn_mask_toggled(LiVESToggleButton *togglebutton, livespointer user_data)
Definition: dialogs.c:77
LIVES_GLOBAL_INLINE void do_abort_dialog(const char *text)
Definition: dialogs.c:725
boolean do_progress_dialog(boolean visible, boolean cancellable, const char *text)
Definition: dialogs.c:2274
LIVES_GLOBAL_INLINE void do_cd_error_dialog(void)
Definition: dialogs.c:4525
LIVES_GLOBAL_INLINE boolean findex_bk_dialog(const char *fname_back)
Definition: dialogs.c:3261
boolean do_yesno_dialog_with_check(const char *text, uint64_t warn_mask_number)
Definition: dialogs.c:595
boolean do_warning_dialog_with_check(const char *text, uint64_t warn_mask_number)
Definition: dialogs.c:569
boolean check_backend_return(lives_clip_t *sfile)
Definition: dialogs.c:1009
LIVES_GLOBAL_INLINE void do_abortblank_error(const char *what)
Definition: dialogs.c:873
LIVES_GLOBAL_INLINE boolean prompt_remove_layout_files(void)
Definition: dialogs.c:3408
LIVES_GLOBAL_INLINE void do_layout_scrap_file_error(void)
Definition: dialogs.c:3053
#define PROG_LOOP_VAL
Definition: dialogs.c:1250
void event_list_add_end_events(weed_event_t *event_list, boolean is_final)
Definition: events.c:5102
weed_plant_t * process_events(weed_plant_t *next_event, boolean process_audio, weed_timecode_t curr_tc)
Definition: events.c:3082
LIVES_GLOBAL_INLINE weed_timecode_t get_event_timecode(weed_plant_t *plant)
Definition: events.c:98
weed_plant_t * get_frame_event_at(weed_plant_t *event_list, weed_timecode_t tc, weed_plant_t *shortcut, boolean exact)
Definition: events.c:780
render_details * rdet
Definition: events.h:256
@ LIVES_RENDER_ERROR_NONE
Definition: events.h:101
@ LIVES_RENDER_ERROR
Definition: events.h:108
LiVESWidget * trash_rb(LiVESButtonBox *parent)
Definition: interface.c:1622
text_window * create_text_window(const char *title, const char *text, LiVESTextBuffer *textbuffer, boolean add_buttons)
Definition: interface.c:1390
LiVESWidget * create_encoder_prep_dialog(const char *text1, const char *text2, boolean opt_resize)
Definition: interface.c:1292
void run_diskspace_dialog(void)
Definition: interface.c:6445
xprocess * create_processing(const char *text)
Definition: interface.c:853
_commentsw * create_comments_dialog(lives_clip_t *sfile, char *filename)
Definition: interface.c:3745
xprocess * create_threaded_dialog(char *text, boolean has_cancel, boolean *td_had_focus)
Definition: interface.c:752
LiVESWidget * add_list_expander(LiVESBox *box, const char *title, int width, int height, LiVESList *xlist)
Definition: interface.c:4983
_commentsw * commentsw
Definition: interface.h:310
#define MIN_MSGBOX_WIDTH
Definition: interface.h:235
text_window * textwindow
Definition: interface.h:314
void handle_cached_keys(void)
smooth the key repeat for scratching
Definition: keyboard.c:141
#define KEY_RPT_INTERVAL
Definition: keyboard.h:76
char * get_mountpoint_for(const char *dir)
boolean activate_x11_window(const char *wid)
lives_proc_thread_t disk_monitor_start(const char *dir)
Definition: machinestate.c:717
LIVES_GLOBAL_INLINE size_t lives_strlen(const char *s)
LIVES_GLOBAL_INLINE char * lives_strtrim(const char *buff)
void disk_monitor_forget(void)
Definition: machinestate.c:769
LIVES_GLOBAL_INLINE ticks_t lives_get_current_ticks(void)
Definition: machinestate.c:835
void update_effort(int nthings, boolean badthings)
LIVES_GLOBAL_INLINE int lives_strappend(const char *string, int len, const char *xnew)
int64_t disk_monitor_check_result(const char *dir)
Definition: machinestate.c:726
lives_storage_status_t get_storage_status(const char *dir, uint64_t warn_level, int64_t *dsval, int64_t ds_resvd)
Definition: machinestate.c:693
char * lives_format_storage_space_string(uint64_t space)
Definition: machinestate.c:664
LIVES_GLOBAL_INLINE boolean lives_strncmp(const char *st1, const char *st2, size_t len)
returns FALSE if strings match
LIVES_GLOBAL_INLINE ticks_t lives_get_relative_ticks(ticks_t origsecs, ticks_t orignsecs)
Definition: machinestate.c:813
void reset_effort(void)
void * main_thread_execute(lives_funcptr_t func, int return_type, void *retval, const char *args_fmt,...)
#define lives_nanosleep(nanosec)
Definition: machinestate.h:307
#define lives_calloc
Definition: machinestate.h:67
lives_storage_status_t
disk/storage status values
Definition: machinestate.h:181
@ LIVES_STORAGE_STATUS_CRITICAL
Definition: machinestate.h:185
@ LIVES_STORAGE_STATUS_WARNING
Definition: machinestate.h:184
@ LIVES_STORAGE_STATUS_OVER_QUOTA
Definition: machinestate.h:187
#define THREADVAR(var)
Definition: machinestate.h:531
#define lives_free
Definition: machinestate.h:52
#define lives_memset
Definition: machinestate.h:61
void *(* lives_funcptr_t)(void *)
Definition: machinestate.h:378
boolean startup_message_info(const char *msg)
Definition: main.c:4987
void sensitize(void)
Definition: main.c:5078
_palette * palette
interface colour settings
Definition: main.c:101
void procw_desensitize(void)
Definition: main.c:5445
void load_frame_image(int frame)
Definition: main.c:7984
void showclipimgs(void)
Definition: main.c:5636
boolean check_layer_ready(weed_layer_t *layer)
block until layer pixel_data is ready.
Definition: main.c:7528
mainwindow * mainw
Definition: main.c:103
void desensitize(void)
Definition: main.c:5302
void do_quick_switch(int new_file)
Definition: main.c:10066
boolean pull_frame_at_size(weed_layer_t *layer, const char *image_ext, weed_timecode_t tc, int width, int height, int target_palette)
Definition: main.c:7172
void pull_frame_threaded(weed_layer_t *layer, const char *img_ext, weed_timecode_t tc, int width, int height)
Definition: main.c:7631
#define LIVES_WARN(x)
Definition: main.h:1862
void clear_mainw_msg(void)
Definition: utils.c:1435
int frames_t
Definition: main.h:99
int get_frame_count(int idx, int xsize)
sets mainw->files[idx]->frames with current framecount
Definition: utils.c:3109
char * insert_newlines(const char *text, int maxwidth)
Definition: utils.c:5591
#define CLIP_HAS_VIDEO(clip)
Definition: main.h:814
void do_jack_noopen_warn3(void)
#define CLIP_HAS_AUDIO(clip)
Definition: main.h:817
void lives_list_free_all(LiVESList **)
Definition: utils.c:4873
size_t get_token_count(const char *string, int delim)
Definition: utils.c:5430
#define is_layer_ready(layer)
Definition: main.h:1485
@ STOP_ON_AUD_END
Definition: main.h:695
@ STOP_ON_VID_END
Definition: main.h:694
#define MAX_FILES
max files is actually 1 more than this, since file 0 is the clipboard
Definition: main.h:184
void d_print_cancelled(void)
Definition: utils.c:2610
#define LIVES_DEBUG(x)
Definition: main.h:1848
char * unhash_version(uint64_t version)
Definition: utils.c:3522
#define LIVES_GLOBAL_INLINE
Definition: main.h:239
#define AFORM_SIGNED
Definition: main.h:783
ticks_t lives_get_current_playback_ticks(ticks_t origsecs, ticks_t origusecs, lives_time_source_t *time_source)
Definition: utils.c:1481
@ CANCEL_KILL
normal - kill background processes working on current clip
Definition: main.h:759
@ CANCEL_SOFT
just cancel in GUI (for keep, etc)
Definition: main.h:760
void get_dirname(char *filename)
Definition: utils.c:3167
#define LIVES_IS_PLAYING
Definition: main.h:840
#define IS_NORMAL_CLIP(clip)
Definition: main.h:833
const char * image_ext_to_lives_image_type(const char *img_ext)
Definition: utils.c:3039
void do_jack_noopen_warn4(void)
boolean lives_alarm_clear(lives_alarm_t alarm_handle)
Definition: utils.c:1732
char * clip_detail_to_string(lives_clip_details_t what, size_t *maxlenp)
Definition: utils.c:4980
void lives_kill_subprocesses(const char *dirname, boolean kill_parent)
Definition: utils.c:4516
char * get_extension(const char *filename)
Definition: utils.c:3217
#define sig(a)
Definition: main.h:268
#define AFORM_UNSIGNED
Definition: main.h:786
LiVESList * get_set_list(const char *dir, boolean utf8)
Definition: utils.c:5305
void reset_playback_clock(void)
Definition: utils.c:1474
#define LIVES_DIRECTION_SIG(dir)
Definition: main.h:864
const char * get_image_ext_for_type(lives_img_type_t imgtype)
Definition: utils.c:3025
frames_t calc_new_playback_position(int fileno, ticks_t otc, ticks_t *ntc)
Definition: utils.c:1865
uint32_t get_approx_ln(uint32_t val) GNU_CONST
Definition: utils.c:1453
boolean save_clip_values(int which_file)
Definition: saveplay.c:103
lives_clip_details_t
Definition: main.h:1141
@ CLIP_DETAILS_TITLE
Definition: main.h:1155
@ CLIP_DETAILS_AUTHOR
Definition: main.h:1156
@ CLIP_DETAILS_COMMENT
Definition: main.h:1157
void do_jack_noopen_warn(void)
lives_alarm_t lives_alarm_set(ticks_t ticks)
set alarm for now + delta ticks (10 nanosec) param ticks (10 nanoseconds) is the offset when we want ...
Definition: utils.c:1643
struct timeval tv
Definition: main.h:1136
lives_direction_t
use REVERSE / FORWARD when a sign is used, BACKWARD / FORWARD when a parity is used
Definition: main.h:851
int lives_rmdir(const char *dir, boolean force)
Definition: utils.c:4366
#define IS_VALID_CLIP(clip)
Definition: main.h:808
int lives_rm(const char *file)
Definition: utils.c:4395
int64_t ticks_t
Definition: main.h:97
capability * capable
Definition: main.h:627
@ MISSING
not yet implemented (TODO)
Definition: main.h:392
#define cfile
Definition: main.h:1833
#define INSTALL_CANLOCAL
install guidance flags
Definition: main.h:389
char * dump_messages(int start, int end)
Definition: utils.c:2338
void d_print(const char *fmt,...)
Definition: utils.c:2542
#define LIVES_ERROR(x)
Definition: main.h:1870
lives_img_type_t
Definition: main.h:774
void do_jack_noopen_warn2(void)
int calc_frame_from_time4(int filenum, double time)
nearest frame, no maximum
Definition: utils.c:1788
size_t lives_fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
Definition: utils.c:379
#define AFORM_BIG_ENDIAN
Definition: main.h:787
#define CURRENT_CLIP_IS_VALID
Definition: main.h:809
#define PATH_MAX
Definition: main.h:255
boolean lives_freep(void **ptr)
Definition: utils.c:1411
@ CLIP_TYPE_FILE
unimported video, not or partially broken in frames
Definition: main.h:765
@ CLIP_TYPE_DISK
imported video, broken into frames
Definition: main.h:764
size_t lives_fread_string(char *buff, size_t stlen, const char *fname)
Definition: utils.c:388
#define LIVES_FATAL(x)
Definition: main.h:1886
boolean save_clip_value(int which, lives_clip_details_t, void *val)
Definition: utils.c:5175
ticks_t lives_alarm_check(lives_alarm_t alarm_handle)
Definition: utils.c:1687
lives_cancel_t
cancel reason
Definition: main.h:699
@ CANCEL_EVENT_LIST_END
event_list completed
Definition: main.h:722
@ CANCEL_PREVIEW_FINISHED
effect processing finished during preview
Definition: main.h:710
@ CANCEL_NO_PROPOGATE
cancel but keep opening
Definition: main.h:707
@ CANCEL_INTERNAL_ERROR
software error: e.g set mainw->current_file directly during pb instead of mainw->new_clip
Definition: main.h:752
@ CANCEL_NONE
no cancel
Definition: main.h:701
@ CANCEL_ERROR
cancelled because of error
Definition: main.h:740
@ CANCEL_NO_MORE_PREVIEW
ran out of preview frames
Definition: main.h:716
@ CANCEL_USER
user pressed stop
Definition: main.h:704
@ CANCEL_AUDIO_ERROR
cancelled because of soundcard error
Definition: main.h:743
#define MAINW_MSG_SIZE
mainw->msg bytesize
Definition: mainwindow.h:702
#define EXEC_AUTOLIVES_PL
shipped
Definition: mainwindow.h:414
#define DEF_BUTTON_HEIGHT
Definition: mainwindow.h:183
#define MONITOR_QUOTA
Definition: mainwindow.h:1805
lives_dialog_t
Definition: mainwindow.h:239
@ LIVES_DIALOG_QUESTION
Definition: mainwindow.h:245
@ LIVES_DIALOG_CANCEL_RETRY_BROWSE
Definition: mainwindow.h:250
@ LIVES_DIALOG_ABORT_RETRY
Definition: mainwindow.h:247
@ LIVES_DIALOG_WARN_WITH_CANCEL
Definition: mainwindow.h:243
@ LIVES_DIALOG_WARN
Definition: mainwindow.h:242
@ LIVES_DIALOG_ERROR
Definition: mainwindow.h:241
@ LIVES_DIALOG_SKIP_RETRY_BROWSE
Definition: mainwindow.h:251
@ LIVES_DIALOG_ABORT_OK
Definition: mainwindow.h:246
@ LIVES_DIALOG_ABORT
Definition: mainwindow.h:252
@ LIVES_DIALOG_YESNO
Definition: mainwindow.h:244
@ LIVES_DIALOG_INFO
Definition: mainwindow.h:240
@ LIVES_DIALOG_ABORT_CANCEL_RETRY
Definition: mainwindow.h:249
@ LIVES_DIALOG_RETRY_CANCEL
Definition: mainwindow.h:248
#define TICKS_PER_SECOND
ticks per second - GLOBAL TIMEBASE
Definition: mainwindow.h:36
#define LIVES_FILE_EXT_SRT
Definition: mainwindow.h:507
#define LIVES_IS_INTERACTIVE
Definition: mainwindow.h:1710
#define PLUGIN_EXEC_DIR
Definition: mainwindow.h:599
#define SCRATCH_NONE
Definition: mainwindow.h:1027
#define ENC_DETAILS_WIN_V
Definition: mainwindow.h:169
#define LIVES_SUBS_FILTER
Definition: mainwindow.h:636
#define LIVES_MAIN_WINDOW_WIDGET
Definition: mainwindow.h:188
#define TICKS_PER_SECOND_DBL
actually microseconds / 100.
Definition: mainwindow.h:37
#define ONE_MILLION
Definition: mainwindow.h:27
#define MAX_MSG_WIDTH_CHARS
max width of text on warning/error labels
Definition: mainwindow.h:172
#define DEF_BUTTON_WIDTH
Definition: mainwindow.h:182
#define TICKS_TO_NANOSEC
Definition: mainwindow.h:39
#define LIVES_CLIP_HEADER
Definition: mainwindow.h:555
#define SCRATCH_JUMP
jump and resync audio
Definition: mainwindow.h:1031
#define EFFORT_RANGE_MAX
if set to TRUE during playback then a new frame (or possibly the current one) will be displayed ASAP
Definition: mainwindow.h:1770
_fx_dialog * fx_dialog[2]
Definition: mainwindow.h:1851
#define LIVES_AUDIO_LOAD_FILTER
Definition: mainwindow.h:637
#define SCRATCH_JUMP_NORESYNC
jump with no audio resync
Definition: mainwindow.h:1032
lives_time_source_t
timebase sources
Definition: mainwindow.h:225
@ LIVES_TIME_SOURCE_NONE
Definition: mainwindow.h:226
@ LIVES_TIME_SOURCE_SOUNDCARD
Definition: mainwindow.h:228
#define LIVES_FILE_EXT_SUB
Definition: mainwindow.h:508
#define ENC_DETAILS_WIN_H
vertical size in pixels of the encoder output window
Definition: mainwindow.h:167
#define EXEC_SUDO
other executables
Definition: mainwindow.h:434
#define ONE_BILLION
Definition: mainwindow.h:25
int lives_alarm_t
Definition: mainwindow.h:696
void recover_layout_cancelled(boolean is_startup)
Definition: multitrack.c:923
boolean recover_layout(void)
Definition: multitrack.c:1010
#define LIVES_OSC_NOTIFY_QUIT
sent when app quits
Definition: osc_notify.h:44
@ SUBTITLE_TYPE_SRT
Definition: pangotext.h:17
void update_visual_params(lives_rfx_t *rfx, boolean update_hidden)
apply internal value changes to interface widgets
Definition: paramwindow.c:3361
_vid_playback_plugin * open_vid_playback_plugin(const char *name, boolean in_use)
Definition: plugins.c:1099
#define PLUGIN_RENDERED_EFFECTS_BUILTIN
external rendered fx plugins (RFX plugins)
Definition: plugins.h:469
boolean lives_ask_permission(char **argv, int argc, int offs)
Definition: preferences.c:6031
void toggle_sets_pref(LiVESWidget *widget, livespointer prefidx)
callback to set to make a togglebutton or check_menu_item directly control a boolean pref widget is e...
Definition: preferences.c:46
int set_int_pref(const char *key, int value)
Definition: preferences.c:329
_prefs * prefs
Definition: preferences.h:847
#define LIVES_PERM_COPY_LOCAL
Definition: preferences.h:1157
#define WARN_MASK_MT_BACKUP_SPACE
Definition: preferences.h:120
#define WARN_MASK_SAVE_SET
Definition: preferences.h:90
#define WARN_MASK_CLEAN_INVALID
Definition: preferences.h:127
#define WARN_MASK_LAYOUT_LB
Definition: preferences.h:128
#define LIVES_PERM_OSC_PORTS
Definition: preferences.h:1155
#define WARN_MASK_OPEN_YUV4M
Definition: preferences.h:119
#define AUD_PLAYER_NONE
Definition: preferences.h:41
#define WARN_MASK_RENDERED_FX
Definition: preferences.h:92
#define WARN_MASK_DUPLICATE_SET
Definition: preferences.h:103
#define AUD_PLAYER_JACK
Definition: preferences.h:43
_prefsw * prefsw
Definition: preferences.h:849
#define WARN_MASK_FPS
Definition: preferences.h:87
#define AUDIO_SRC_EXT
Definition: preferences.h:206
#define LIVES_PERM_DOWNLOAD_LOCAL
Definition: preferences.h:1156
#define AUDIO_SRC_INT
Definition: preferences.h:205
#define PREF_MSG_START
Definition: preferences.h:1078
#define PREF_LIVES_WARNING_MASK
Definition: preferences.h:968
#define WARN_MASK_CLEAN_AFTER_CRASH
Definition: preferences.h:122
#define AUD_PLAYER_PULSE
Definition: preferences.h:44
LIVES_GLOBAL_INLINE ticks_t q_gint64(ticks_t in, double fps)
Definition: resample.c:25
boolean rte_window_hidden(void)
Definition: rte_window.c:55
LiVESWidget * rte_window
Definition: rte_window.h:58
LiVESWidget * comments_dialog
Definition: interface.h:124
LiVESWidget * author_entry
Definition: interface.h:126
LiVESWidget * title_entry
Definition: interface.h:125
LiVESWidget * subt_entry
Definition: interface.h:129
LiVESWidget * comment_entry
Definition: interface.h:127
LiVESWidget * subt_checkbutton
Definition: interface.h:128
char of_desc[128]
Definition: plugins.h:264
char name[64]
Definition: plugins.h:234
char ptext[512]
Definition: plugins.h:268
LiVESWidgetColor dark_orange
Definition: mainwindow.h:312
LiVESWidgetColor light_red
Definition: mainwindow.h:309
LiVESWidgetColor normal_back
Definition: mainwindow.h:324
LiVESWidgetColor dark_red
Definition: mainwindow.h:311
LiVESWidgetColor light_green
Definition: mainwindow.h:310
boolean vj_mode
Definition: preferences.h:459
_encoder encoder
from main.h
Definition: preferences.h:38
uint64_t ds_crit_level
diskspace critical level bytes
Definition: preferences.h:380
boolean pbq_adaptive
Definition: preferences.h:36
int audio_src
Definition: preferences.h:204
uint64_t disk_quota
Definition: preferences.h:383
uint64_t warning_mask
Definition: preferences.h:80
boolean show_gui
Definition: preferences.h:290
double default_fps
Definition: preferences.h:173
uint32_t osc_udp_port
Definition: preferences.h:210
char workdir[PATH_MAX]
kept in locale encoding
Definition: preferences.h:61
boolean show_msg_area
Definition: preferences.h:225
float ahold_threshold
Definition: preferences.h:440
boolean show_player_stats
Definition: preferences.h:190
char configfile[PATH_MAX]
kept in locale encoding (config settings) [default ~/.local/config/lives)
Definition: preferences.h:63
char lib_dir[PATH_MAX]
Definition: preferences.h:75
int sleep_time
Definition: preferences.h:176
boolean show_dev_opts
Definition: preferences.h:463
short audio_player
Definition: preferences.h:40
LiVESWidget * prefs_dialog
Definition: preferences.h:536
lives_checkstatus_t has_xdotool
Definition: main.h:531
lives_checkstatus_t has_sox_play
Definition: main.h:508
char * mountpoint
utf-8
Definition: main.h:610
lives_checkstatus_t has_wmctrl
Definition: main.h:530
int64_t ds_free
Definition: main.h:609
int64_t ds_used
Definition: main.h:609
int64_t jump_limit
for internal use
Definition: plugins.h:369
float max_decode_fps
optional info ////////////////
Definition: plugins.h:367
int seek_flag
plugin can change per frame
Definition: plugins.h:397
corresponds to one clip in the GUI
Definition: main.h:877
int arps
audio physical sample rate (i.e the "normal" sample rate of the clip when played at 1,...
Definition: main.h:905
frames_t frames
number of video frames
Definition: main.h:890
frames_t end
Definition: main.h:891
void * ext_src
points to opaque source for non-disk types
Definition: main.h:1040
lives_clip_type_t clip_type
Definition: main.h:886
int asampsize
audio sample size in bits (8 or 16)
Definition: main.h:908
lives_img_type_t img_type
Definition: main.h:887
frames_t last_frameno
Definition: main.h:934
frames_t last_vframe_played
Definition: main.h:1068
int vsize
frame height (vertical) in pixels
Definition: main.h:897
volatile off64_t aseek_pos
audio seek posn. (bytes) for when we switch clips
Definition: main.h:1064
char title[1024]
Definition: main.h:919
int achans
number of audio channels (0, 1 or 2)
Definition: main.h:907
double laudio_time
Definition: main.h:929
double pb_fps
current playback rate, may vary from fps, can be 0. or negative
Definition: main.h:1007
frames_t frameno
Definition: main.h:934
char info_file[PATH_MAX]
used for asynch communication with externals
Definition: main.h:1009
int hsize
frame width (horizontal) in pixels (NOT macropixels !)
Definition: main.h:896
char name[CLIP_NAME_MAXLEN]
the display name
Definition: main.h:922
lives_subtitles_t * subt
Definition: main.h:1076
char author[1024]
Definition: main.h:919
char comment[1024]
Definition: main.h:919
int arate
current audio playback rate (varies if the clip rate is changed)
Definition: main.h:906
int last_play_sequence
updated only when FINISHING playing a clip (either by switching or ending playback,...
Definition: main.h:1096
double fps
Definition: main.h:893
char handle[256]
Definition: main.h:881
boolean play_paused
Definition: main.h:1014
boolean is_loaded
should we continue loading if we come back to this clip
Definition: main.h:949
frames_t start
Definition: main.h:891
boolean nokeep
don't show the 'keep' button - e.g. for operations which resize frames
Definition: main.h:1022
lives_subtitle_type_t type
Definition: pangotext.h:39
boolean ignore_clipswitch
Definition: mainwindow.h:1023
int64_t rec_samples
Definition: mainwindow.h:1527
LiVESList * xlays
immediately (to be) affected layout maps
Definition: mainwindow.h:1477
_vid_playback_plugin * vpp
video plugin
Definition: mainwindow.h:1572
boolean ce_thumbs
Definition: mainwindow.h:1676
volatile lives_rfx_t * vrfx_update
single access for updating alarm list
Definition: mainwindow.h:1510
volatile int agen_key
which fx key is generating audio [1 based] (or 0 for none)
Definition: mainwindow.h:1649
ticks_t last_startticks
effective ticks when lasty frame was (should have been) displayed
Definition: mainwindow.h:998
volatile boolean video_seek_ready
Definition: mainwindow.h:939
double aframeno
and the audio 'frame' for when we are looping
Definition: mainwindow.h:962
volatile short scratch
Definition: mainwindow.h:1026
boolean no_exit
if TRUE, do not exit after saving set
Definition: mainwindow.h:1490
boolean only_close
only close clips - do not exit
Definition: mainwindow.h:1439
char msg[MAINW_MSG_SIZE]
Definition: mainwindow.h:724
volatile ticks_t currticks
wall clock time, updated whenever lives_get_*_ticks is called
Definition: mainwindow.h:1005
LiVESWidget * p_playbutton
Definition: mainwindow.h:1379
boolean fx1_bool
Definition: mainwindow.h:1053
double fixed_fpsd
<=0. means free playback
Definition: mainwindow.h:990
boolean tried_ds_recover
Definition: mainwindow.h:1657
void * pulsed
pulseaudio player
Definition: mainwindow.h:1463
lives_clip_t * files[MAX_FILES+1]
+1 for the clipboard
Definition: mainwindow.h:729
boolean add_clear_ds_button
Definition: mainwindow.h:1655
volatile boolean record
Definition: mainwindow.h:794
ticks_t origsecs
playback start seconds - subtracted from all other ticks to keep numbers smaller
Definition: mainwindow.h:1000
LiVESWidget * playall
Definition: mainwindow.h:1166
LiVESWidget * splash_window
splash window
Definition: mainwindow.h:1595
const char * new_vpp
Definition: mainwindow.h:1573
boolean is_rendering
Definition: mainwindow.h:821
lives_mgeometry_t * mgeom
multi-head support
Definition: mainwindow.h:1576
LiVESAccelGroup * accel_group
Definition: mainwindow.h:1228
volatile double rec_avel
Definition: mainwindow.h:968
boolean effects_paused
Definition: mainwindow.h:1055
lives_render_error_t(* progress_fn)(boolean reset)
Definition: mainwindow.h:1044
volatile boolean loop_cont
Definition: mainwindow.h:764
boolean jack_can_start
Definition: mainwindow.h:934
LiVESIOChannel * iochan
encoder text output
Definition: mainwindow.h:1605
boolean preview_req
Definition: mainwindow.h:1024
boolean dsu_valid
Definition: mainwindow.h:1791
boolean cs_is_permitted
set automatically when cs_permitted can update the clip
Definition: mainwindow.h:1021
lives_permmgr_t * permmgr
Definition: mainwindow.h:1795
LiVESTextView * optextview
Definition: mainwindow.h:1606
boolean noswitch
value set automatically to prevent 'inopportune' clip switching
Definition: mainwindow.h:1019
lives_render_error_t render_error
Definition: mainwindow.h:1664
boolean cs_permitted
set to TRUE to allow overriding of noswitch in limited circumstances
Definition: mainwindow.h:1020
volatile lives_cancel_t cancelled
Definition: mainwindow.h:798
frames64_t pred_frame
Definition: mainwindow.h:955
boolean preview
Definition: mainwindow.h:757
int current_file
Definition: mainwindow.h:727
boolean is_ready
Definition: mainwindow.h:787
boolean add_clear_ds_adv
Definition: mainwindow.h:1656
lives_cancel_type_t cancel_type
Definition: mainwindow.h:799
ticks_t orignsecs
usecs at start of playback - ditto
Definition: mainwindow.h:1001
uint64_t next_ds_warn_level
current disk space warning level for the tempdir
Definition: mainwindow.h:1666
void * jackd
jack audio player / transport
Definition: mainwindow.h:1453
short endian
Definition: mainwindow.h:817
volatile int blend_palette
here we can store the details of the blend file at the insertion point, if nothing changes we can tar...
Definition: mainwindow.h:980
volatile boolean is_exiting
set during shutdown (inverse of only_close then)
Definition: mainwindow.h:1440
frames_t fps_mini_measure
show fps stats during playback
Definition: mainwindow.h:779
void * pulsed_read
Definition: mainwindow.h:1464
ticks_t last_display_ticks
Definition: mainwindow.h:1012
ticks_t offsetticks
offset for multitrack playback start
Definition: mainwindow.h:1002
int play_sequence
currticks when last display was shown (used for fixed fps)
Definition: mainwindow.h:1013
int pwidth
PLAYBACK.
Definition: mainwindow.h:926
LiVESWidget * framedraw_spinbutton
the frame number button
Definition: mainwindow.h:1266
ticks_t firstticks
ticks when audio started playing (for non-realtime audio plugins)
Definition: mainwindow.h:1009
double rec_end_time
Definition: mainwindow.h:1526
boolean error
Definition: mainwindow.h:801
boolean ext_playback
using external video playback plugin
Definition: mainwindow.h:773
int pheight
playback height
Definition: mainwindow.h:927
int audio_end
Definition: mainwindow.h:771
frames_t play_start
Definition: mainwindow.h:931
volatile int rec_aclip
recording values - to be inserted at the following video frame
Definition: mainwindow.h:967
volatile double rec_aseek
Definition: mainwindow.h:969
lives_funcptr_t abort_hook_func
can be set to point to a function to be run before abort, for critical functions
Definition: mainwindow.h:1081
LiVESWidget * preview_box
Definition: mainwindow.h:1304
boolean playing_sel
list of set names in current workdir, mau be NULL
Definition: mainwindow.h:756
volatile ticks_t clock_ticks
unadjusted system time since pb start, measured concurrently with currticks
Definition: mainwindow.h:1003
boolean jack_can_stop
Definition: mainwindow.h:934
volatile boolean record_paused
pause during recording
Definition: mainwindow.h:1557
int ascrap_file
scrap file for recording audio scraps
Definition: mainwindow.h:875
double audio_stretch
for fixed fps modes, the value is used to speed up / slow down audio
Definition: mainwindow.h:1015
LiVESWidget * msg_area
Definition: mainwindow.h:1324
lives_mt * multitrack
holds a pointer to the entire multitrack environment; NULL in Clip Edit mode
Definition: mainwindow.h:1087
xprocess * proc_ptr
Definition: mainwindow.h:1090
boolean foreign
for external window capture
Definition: mainwindow.h:824
volatile boolean agen_needs_reinit
Definition: mainwindow.h:1650
boolean internal_messaging
internal fx
Definition: mainwindow.h:1043
boolean is_processing
states
Definition: mainwindow.h:820
boolean preview_rendering
Definition: mainwindow.h:758
char * subt_save_file
name of file to save subtitles to
Definition: mainwindow.h:1618
int pred_clip
Definition: mainwindow.h:956
LiVESWidget * m_playbutton
Definition: mainwindow.h:1369
ticks_t timeout_ticks
incremented if effect/rendering is paused/previewed
Definition: mainwindow.h:999
boolean force_show
Definition: mainwindow.h:1763
ticks_t fps_mini_ticks
Definition: mainwindow.h:780
ticks_t deltaticks
deltaticks for scratching
Definition: mainwindow.h:1006
volatile ticks_t startticks
effective ticks when current frame was (should have been) displayed
Definition: mainwindow.h:997
volatile boolean audio_seek_ready
Definition: mainwindow.h:940
int new_clip
clip we should switch to during playback; switch will happen at the designated SWITCH POINT
Definition: mainwindow.h:1022
ticks_t adjticks
used to equalise the timecode between alternate timer sources (souce -> clock adjustment)
Definition: mainwindow.h:1007
frames_t record_frame
frame number to insert in recording
Definition: mainwindow.h:964
frames_t fps_measure
show fps stats after playback
Definition: mainwindow.h:778
frames_t actual_frame
actual / last frame being displayed
Definition: mainwindow.h:959
volatile lives_whentostop_t whentostop
Definition: mainwindow.h:929
int playing_file
which number file we are playing (or -1) [generally mainw->current_file]
Definition: mainwindow.h:943
uint32_t disk_mon
Definition: mainwindow.h:1807
double inst_fps
Definition: mainwindow.h:781
weed_plant_t * frame_layer_preload
predictive caching apparatus
Definition: mainwindow.h:954
volatile boolean threaded_dialog
not really threaded ! but threaded_dialog_spin() can be called to animate it
Definition: mainwindow.h:1046
void * jackd_read
dummy
Definition: mainwindow.h:1454
weed_event_t * event_list
current event_list, for recording
Definition: mainwindow.h:803
boolean add_trash_rb
these are freed when the clip is switched or closed, or when the source frame changes or is updated
Definition: mainwindow.h:1788
ticks_t cevent_tc
timecode of currently processing event
Definition: mainwindow.h:1553
double fps
Definition: events.h:218
LiVESWidget * dialog
Definition: events.h:220
LiVESWidget * scrolledwindow
Definition: interface.h:142
LiVESWidget * dialog
Definition: interface.h:135
LiVESWidget * last_container
container which wraps last widget created + subwidgets (READONLY)
LiVESWindow * transient
transient window for dialogs, if NULL then use the default (READ / WRITE)
LiVESJustification justify
justify for labels
LiVESWidget * last_label
commonly adjusted values //////
boolean non_modal
non-modal for dialogs
int packing_height
vertical pixels between widgets
int monitor
monitor we are displaying on
lives_expand_t expand
how much space to apply between widgets
int packing_width
horizontal pixels between widgets
boolean use_markup
whether markup should be used in labels
int border_width
border width in pixels
int apply_theme
theming variation for widget (0 -> no theme, 1 -> normal colours, 2+ -> theme variants)
frames_t frames_done
Definition: mainwindow.h:717
LiVESWidget * label2
Definition: mainwindow.h:709
LiVESWidget * progressbar
Definition: mainwindow.h:707
int owner
Definition: mainwindow.h:720
frames_t progress_end
Definition: mainwindow.h:716
LiVESWidget * processing
Definition: mainwindow.h:706
LiVESWidget * stop_button
Definition: mainwindow.h:711
LiVESWidget * label3
Definition: mainwindow.h:710
LiVESWidget * cancel_button
Definition: mainwindow.h:714
LiVESWidget * pause_button
Definition: mainwindow.h:712
LiVESWidget * preview_button
Definition: mainwindow.h:713
frames_t progress_start
Definition: mainwindow.h:716
double frac_done
Definition: mainwindow.h:718
#define lives_strdup_printf(fmt,...)
Definition: support.c:27
#define _(String)
Definition: support.h:44
#define P_(String, StringPlural, n)
Definition: support.h:46
#define TRUE
Definition: videoplugin.h:59
#define FALSE
Definition: videoplugin.h:60
#define ABS(a)
Definition: videoplugin.h:63
const char * weed_gamma_get_name(int gamma)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_dialog_response(LiVESDialog *dialog, int response)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_window_present(LiVESWindow *window)
void lives_set_cursor_style(lives_cursor_t cstyle, LiVESWidget *widget)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_dialog_set_button_layout(LiVESDialog *dlg, LiVESButtonBoxStyle bstyle)
WIDGET_HELPER_GLOBAL_INLINE LiVESWidget * lives_layout_new(LiVESBox *box)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_set_bg_color(LiVESWidget *widget, LiVESWidgetState state, const LiVESWidgetColor *color)
WIDGET_HELPER_GLOBAL_INLINE LiVESWidget * lives_widget_set_tooltip_text(LiVESWidget *widget, const char *tip_text)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_window_set_title(LiVESWindow *window, const char *title)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_dialog_set_has_separator(LiVESDialog *dialog, boolean has)
WIDGET_HELPER_GLOBAL_INLINE LiVESTextBuffer * lives_text_view_get_buffer(LiVESTextView *tview)
boolean lives_window_center(LiVESWindow *window)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_is_visible(LiVESWidget *widget)
WIDGET_HELPER_GLOBAL_INLINE LiVESWidget * lives_standard_direntry_new(const char *labeltext, const char *txt, int dispwidth, int maxchars, LiVESBox *box, const char *tooltip)
WIDGET_HELPER_GLOBAL_INLINE LiVESWidget * lives_vbox_new(boolean homogeneous, int spacing)
WIDGET_HELPER_GLOBAL_INLINE LiVESWidget * lives_layout_hbox_new(LiVESLayout *layout)
WIDGET_HELPER_GLOBAL_INLINE LiVESAccelGroup * lives_accel_group_new(void)
boolean lives_button_grab_default_special(LiVESWidget *button)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_toggle_button_get_active(LiVESToggleButton *button)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_label_set_selectable(LiVESLabel *label, boolean setting)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_window_set_modal(LiVESWindow *window, boolean modal)
WIDGET_HELPER_GLOBAL_INLINE LiVESResponseType lives_dialog_run(LiVESDialog *dialog)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_box_pack_start(LiVESBox *box, LiVESWidget *child, boolean expand, boolean fill, uint32_t padding)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_progress_bar_set_pulse_step(LiVESProgressBar *pbar, double fraction)
boolean lives_text_buffer_insert_at_end(LiVESTextBuffer *tbuff, const char *text)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_window_set_deletable(LiVESWindow *window, boolean deletable)
LiVESWidget * lives_standard_expander_new(const char *ltext, LiVESBox *box, LiVESWidget *child)
WIDGET_HELPER_GLOBAL_INLINE LiVESAdjustment * lives_scrolled_window_get_vadjustment(LiVESScrolledWindow *swindow)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_queue_draw(LiVESWidget *widget)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_set_fg_color(LiVESWidget *widget, LiVESWidgetState state, const LiVESWidgetColor *color)
WIDGET_HELPER_GLOBAL_INLINE LiVESWidget * lives_message_dialog_new(LiVESWindow *parent, LiVESDialogFlags flags, LiVESMessageType type, LiVESButtonsType buttons, const char *msg_fmt,...)
LIVES_GLOBAL_INLINE void lives_label_chomp(LiVESLabel *label)
WIDGET_HELPER_GLOBAL_INLINE const char * lives_entry_get_text(LiVESEntry *entry)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_set_sensitive(LiVESWidget *widget, boolean state)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_label_set_text(LiVESLabel *label, const char *text)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_show(LiVESWidget *widget)
void funkify_dialog(LiVESWidget *dialog)
#define USE_REVEAL - not working here
WIDGET_HELPER_GLOBAL_INLINE boolean lives_button_box_make_first(LiVESButtonBox *bbox, LiVESWidget *widget)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_adjustment_set_value(LiVESAdjustment *adj, double value)
WIDGET_HELPER_GLOBAL_INLINE LiVESWidget * lives_dialog_get_content_area(LiVESDialog *dialog)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_container_set_border_width(LiVESContainer *container, uint32_t width)
WIDGET_HELPER_GLOBAL_INLINE LiVESWidget * lives_layout_add_label(LiVESLayout *layout, const char *text, boolean horizontal)
LiVESWidget * add_fill_to_box(LiVESBox *box)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_box_pack_first(LiVESBox *box, LiVESWidget *child, boolean expand, boolean fill, uint32_t padding)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_progress_bar_set_fraction(LiVESProgressBar *pbar, double fraction)
WIDGET_HELPER_GLOBAL_INLINE double lives_adjustment_get_upper(LiVESAdjustment *adj)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_window_set_default_size(LiVESWindow *window, int width, int height)
boolean lives_text_view_set_text(LiVESTextView *textview, const char *text, int len)
LIVES_GLOBAL_INLINE boolean lives_widget_destroy(LiVESWidget *widget)
LiVESWidget * lives_dialog_add_button_from_stock(LiVESDialog *dialog, const char *stock_id, const char *label, int response_id)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_set_no_show_all(LiVESWidget *widget, boolean set)
boolean set_css_value_direct(LiVESWidget *, LiVESWidgetState state, const char *selector, const char *detail, const char *value)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_toggle_button_set_active(LiVESToggleButton *button, boolean active)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_window_set_resizable(LiVESWindow *window, boolean resizable)
WIDGET_HELPER_GLOBAL_INLINE LiVESWidget * lives_layout_add_fill(LiVESLayout *layout, boolean horizontal)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_hide(LiVESWidget *widget)
LiVESWidget * lives_standard_button_new_from_stock_full(const char *stock_id, const char *label, int width, int height, LiVESBox *box, boolean fake_default, const char *ttips)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_window_set_keep_above(LiVESWindow *window, boolean set)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_show_all(LiVESWidget *widget)
boolean lives_widget_context_update(void)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_set_minimum_size(LiVESWidget *widget, int width, int height)
WIDGET_HELPER_GLOBAL_INLINE LiVESWidget * lives_hbox_new(boolean homogeneous, int spacing)
LiVESWidget * lives_standard_label_new(const char *text)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_remove_accelerator(LiVESWidget *widget, LiVESAccelGroup *acgroup, uint32_t accel_key, LiVESXModifierType accel_mods)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_entry_set_text(LiVESEntry *entry, const char *text)
double lives_scrolled_window_scroll_to(LiVESScrolledWindow *sw, LiVESPositionType pos)
char * lives_text_view_get_text(LiVESTextView *textview)
WIDGET_HELPER_GLOBAL_INLINE LiVESWidget * lives_dialog_get_action_area(LiVESDialog *dialog)
WIDGET_HELPER_GLOBAL_INLINE LiVESWidget * lives_widget_get_toplevel(LiVESWidget *widget)
WIDGET_HELPER_GLOBAL_INLINE LiVESXWindow * lives_widget_get_xwindow(LiVESWidget *widget)
LiVESWidget * lives_standard_check_button_new(const char *labeltext, boolean active, LiVESBox *box, const char *tooltip)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_grab_focus(LiVESWidget *widget)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_add_accelerator(LiVESWidget *widget, const char *accel_signal, LiVESAccelGroup *accel_group, uint32_t accel_key, LiVESXModifierType accel_mods, LiVESAccelFlags accel_flags)
WIDGET_HELPER_GLOBAL_INLINE LiVESWidget * lives_standard_hseparator_new(void)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_box_pack_end(LiVESBox *box, LiVESWidget *child, boolean expand, boolean fill, uint32_t padding)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_process_updates(LiVESWidget *widget)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_progress_bar_pulse(LiVESProgressBar *pbar)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_dialog_make_widget_first(LiVESDialog *dlg, LiVESWidget *widget)
LiVESWidget * lives_standard_formatted_label_new(const char *text)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_window_set_monitor(LiVESWindow *window, int monnum)
void lives_general_button_clicked(LiVESButton *button, livespointer data_to_free)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_window_add_accel_group(LiVESWindow *window, LiVESAccelGroup *group)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_spin_button_set_range(LiVESSpinButton *button, double min, double max)
void lives_widget_apply_theme(LiVESWidget *widget, LiVESWidgetState state)
#define LIVES_EXPAND_DEFAULT_HEIGHT
#define lives_standard_button_new_with_label(l, w, h)
@ LIVES_CURSOR_NORMAL
must be zero
@ LIVES_CURSOR_BUSY
#define LIVES_EXPAND_EXTRA_WIDTH
char LIVES_STOCK_LABEL_SKIP[32]
#define LIVES_EXPAND_EXTRA
#define LIVES_EXPAND_DEFAULT
widget_opts_t widget_opts
#define MEDIUM_ENTRY_WIDTH
Definition: widget-helper.h:31
#define LIVES_JUSTIFY_DEFAULT