LiVES 3.2.0
callbacks.c
Go to the documentation of this file.
1
2// callbacks.c
3// LiVES
4// (c) G. Finch 2003 - 2020 <salsaman+lives@gmail.com>
5// released under the GNU GPL 3 or later
6// see file ../COPYING for licensing details
7
8#include <unistd.h>
9#include <stdlib.h>
10#include <string.h>
11#include <fcntl.h>
12#include <stdio.h>
13#include <sys/stat.h>
14#include <dlfcn.h>
15
16#include "main.h"
17#include "callbacks.h"
18#include "interface.h"
19#include "effects.h"
20#include "resample.h"
21#include "rte_window.h"
22#include "events.h"
23#include "audio.h"
24#include "cvirtual.h"
25#include "paramwindow.h"
26#include "ce_thumbs.h"
27#include "startup.h"
28#include "diagnostics.h"
29
30#ifdef LIBAV_TRANSCODE
31#include "transcode.h"
32#endif
33
34#ifdef HAVE_YUV4MPEG
35#include "lives-yuv4mpeg.h"
36#endif
37
38#ifdef HAVE_UNICAP
39#include "videodev.h"
40#endif
41
42#ifdef ENABLE_OSC
43#include "osc.h"
44#endif
45
46static char file_name[PATH_MAX];
47
48
49void lives_notify(int msgnumber, const char *msgstring) {
50#ifdef IS_LIBLIVES
51 binding_cb(msgnumber, msgstring, mainw->id);
52#endif
53#ifdef ENABLE_OSC
54 lives_osc_notify(msgnumber, msgstring);
55#endif
56
57#ifdef TEST_NOTIFY
58 if (msgnumber == LIVES_OSC_NOTIFY_CLIPSET_OPENED) {
59 char *details = lives_strdup_printf(_("'LiVES opened the clip set' '%s'"), msgstring);
60 char *tmp = lives_strdup_printf("notify-send %s", details);
61 lives_system(tmp, TRUE);
62 lives_free(tmp);
63 lives_free(details);
64 }
65
66 if (msgnumber == LIVES_OSC_NOTIFY_CLIPSET_SAVED) {
67 char *details = lives_strdup_printf(_("'LiVES saved the clip set' '%s'"), msgstring);
68 char *tmp = lives_strdup_printf("notify-send %s", details);
69 lives_system(tmp, TRUE);
70 lives_free(tmp);
71 lives_free(details);
72 }
73#endif
74}
75
76
77LIVES_GLOBAL_INLINE void lives_notify_int(int msgnumber, int msgint) {
78 char *tmp = lives_strdup_printf("%d", msgint);
79 lives_notify(msgnumber, tmp);
80 lives_free(tmp);
81}
82
83
84boolean on_LiVES_delete_event(LiVESWidget *widget, LiVESXEventDelete *event, livespointer user_data) {
85 if (!LIVES_IS_INTERACTIVE) return TRUE;
86 on_quit_activate(NULL, NULL);
87 return TRUE;
88}
89
90
91static void cleanup_set_dir(const char *set_name) {
92 // this function is called:
93 // - when a set is saved and merged with an existing one
94 // - when a set is deleted
95 // - when the last clip in a set is closed
96
97 char *lfiles, *ofile, *sdir;
98
99 sdir = lives_build_path(prefs->workdir, set_name, LAYOUTS_DIRNAME, NULL);
100 if (lives_file_test(sdir, LIVES_FILE_TEST_IS_DIR))
101 lives_rmdir(sdir, FALSE);
102 lives_free(sdir);
103
104 sdir = lives_build_filename(prefs->workdir, set_name, CLIPS_DIRNAME, NULL);
105 if (lives_file_test(sdir, LIVES_FILE_TEST_IS_DIR))
106 lives_rmdir(sdir, FALSE);
107 lives_free(sdir);
108
109 // remove any stale lockfiles
110 lfiles = SET_LOCK_FILES(set_name);
111 lives_rmglob(lfiles);
112 lives_free(lfiles);
113
114 ofile = lives_build_filename(prefs->workdir, set_name, CLIP_ORDER_FILENAME, NULL);
115 lives_rm(ofile);
116 lives_free(ofile);
117
118 ofile = lives_build_filename(prefs->workdir, set_name,
120 lives_rm(ofile);
121 lives_free(ofile);
122
123 lives_sync(1);
124
125 sdir = lives_build_path(prefs->workdir, set_name, NULL);
126 lives_rmdir(sdir, FALSE); // set to FALSE in case the user placed extra files there
127 lives_free(sdir);
128
129 if (prefs->ar_clipset && !strcmp(prefs->ar_clipset_name, set_name)) {
133 }
135}
136
137
138#ifndef VALGRIND_ON
139#ifdef _lives_free
140#undef lives_free
141#define lives_free(a) (mainw->is_exiting ? a : _lives_free(a))
142#endif
143#endif
144
145void lives_exit(int signum) {
146 char *tmp, *com;
147 int i;
148
149 if (!mainw) _exit(0);
150
151 if (!mainw->only_close) {
153
154 // unlock all mutexes to prevent deadlocks
155#ifdef HAVE_PULSE_AUDIO
156 /* if (mainw->pulsed || mainw->pulsed_read) */
157 /* pa_mloop_unlock(); */
158#endif
159
160 // recursive
161 while (!pthread_mutex_unlock(&mainw->instance_ref_mutex));
162 while (!pthread_mutex_unlock(&mainw->abuf_mutex));
163
164 // non-recursive
165 pthread_mutex_trylock(&mainw->abuf_frame_mutex);
166 pthread_mutex_unlock(&mainw->abuf_frame_mutex);
167 pthread_mutex_trylock(&mainw->fxd_active_mutex);
168 pthread_mutex_unlock(&mainw->fxd_active_mutex);
169 pthread_mutex_trylock(&mainw->event_list_mutex);
170 pthread_mutex_unlock(&mainw->event_list_mutex);
171 pthread_mutex_trylock(&mainw->clip_list_mutex);
172 pthread_mutex_unlock(&mainw->clip_list_mutex);
173 pthread_mutex_trylock(&mainw->vpp_stream_mutex);
174 pthread_mutex_unlock(&mainw->vpp_stream_mutex);
175 pthread_mutex_trylock(&mainw->cache_buffer_mutex);
176 pthread_mutex_unlock(&mainw->cache_buffer_mutex);
177 pthread_mutex_trylock(&mainw->audio_filewriteend_mutex);
178 pthread_mutex_unlock(&mainw->audio_filewriteend_mutex);
179 pthread_mutex_trylock(&mainw->fbuffer_mutex);
180 pthread_mutex_unlock(&mainw->fbuffer_mutex);
181 pthread_mutex_trylock(&mainw->alarmlist_mutex);
182 pthread_mutex_unlock(&mainw->alarmlist_mutex);
183 // filter mutexes are unlocked in weed_unload_all
184
185 if (pthread_mutex_trylock(&mainw->exit_mutex)) pthread_exit(NULL);
186
188 backup_recording(NULL, NULL);
189 }
190
191 //lives_threadpool_finish();
192 //show_weed_stats();
193 }
194
195 if (mainw->is_ready) {
196 if (mainw->multitrack && mainw->multitrack->idlefunc > 0) {
197 //lives_source_remove(mainw->multitrack->idlefunc);
198 mainw->multitrack->idlefunc = 0;
199 }
200
202
203 if (mainw->toy_type != LIVES_TOY_NONE) {
204 on_toy_activate(NULL, LIVES_INT_TO_POINTER(LIVES_TOY_NONE));
205 }
206
207 if (mainw->alives_pgid > 0) {
208 autolives_toggle(NULL, NULL);
209 }
210
211#ifdef VALGRIND_ON
214 }
215
216 if (mainw->multitrack && !mainw->only_close) {
217 lives_freep((void **)&mainw->multitrack->undo_mem);
218 }
219
220 if (mainw->multi_opts.set && !mainw->only_close && mainw->multi_opts.aparam_view_list) {
221 lives_list_free(mainw->multi_opts.aparam_view_list);
222 }
223#endif
224
225#ifdef VALGRIND_ON
226 if (LIVES_IS_PLAYING) {
228 if (mainw->ext_playback) {
229 pthread_mutex_lock(&mainw->vpp_stream_mutex);
231 pthread_mutex_unlock(&mainw->vpp_stream_mutex);
234 mainw->stream_ticks = -1;
235 }
236
237 // tell non-realtime audio players (sox or mplayer) to stop
240 char *lsname = lives_build_filename(prefs->workdir, mainw->files[mainw->aud_file_to_kill]->handle, NULL);
241 lives_touch(lsname);
242 lives_free(lsname);
243 com = lives_strdup_printf("%s stop_audio \"%s\"", prefs->backend, mainw->files[mainw->aud_file_to_kill]->handle);
244 lives_system(com, TRUE);
245 lives_free(com);
246 }
247 }
248#endif
249 // stop any background processing for the current clip
251 if (cfile->handle && CURRENT_CLIP_IS_NORMAL) {
253 }
254 }
255
256 // prevent crash in "threaded" dialog
257 mainw->current_file = -1;
258
259 if (!mainw->only_close) {
260 // shut down audio players
261#ifdef HAVE_PULSE_AUDIO
262 if (mainw->pulsed) pulse_close_client(mainw->pulsed);
263 if (mainw->pulsed_read) pulse_close_client(mainw->pulsed_read);
264 pulse_shutdown();
265#endif
266#ifdef ENABLE_JACK
267 lives_jack_end();
268 if (mainw->jackd) {
269 jack_close_device(mainw->jackd);
270 }
271 if (mainw->jackd_read) {
272 jack_close_device(mainw->jackd_read);
273 }
274#endif
275 }
276
277 if (mainw->vpp && !mainw->only_close) {
278 if (mainw->memok) {
279 if (mainw->write_vpp_file) {
280 // save video playback plugin parameters
281 char *vpp_file = lives_build_filename(prefs->config_datadir, VPP_DEFS_FILE, NULL);
282 save_vpp_defaults(mainw->vpp, vpp_file);
283 }
284 }
286 }
287
288 if (mainw->memok) {
289 if (!mainw->leave_recovery) {
291 // hide the main window
295 }
296
298 // if we changed the workdir, remove everything but sets from the old dir
299 // create the new directory, and then move any sets over
304
305 // TODO *** - check for namespace collisions between sets in old dir and sets in new dir
306
307 // use backend to move the sets
308 com = lives_strdup_printf("%s move_workdir \"%s\"", prefs->backend_sync,
310 lives_system(com, FALSE);
311 lives_free(com);
312 }
313 lives_snprintf(prefs->workdir, PATH_MAX, "%s", future_prefs->workdir);
314 }
315
316 if (mainw->leave_files && !mainw->fatal) {
317 d_print(_("Saving as set %s..."), mainw->set_name);
319 }
320
321 for (i = 1; i <= MAX_FILES; i++) {
322 if (mainw->files[i]) {
323 mainw->current_file = i;
325 if (cfile->event_list_back) event_list_free(cfile->event_list_back);
326 if (cfile->event_list) event_list_free(cfile->event_list);
327
328 cfile->event_list = cfile->event_list_back = NULL;
329
330 lives_list_free_all(&cfile->layout_map);
331
332 if (cfile->laudio_drawable) {
333 if (mainw->laudio_drawable == cfile->laudio_drawable) mainw->laudio_drawable = NULL;
334 lives_painter_surface_destroy(cfile->laudio_drawable);
335 cfile->laudio_drawable = NULL;
336 }
337
338 if (cfile->raudio_drawable) {
339 if (mainw->raudio_drawable == cfile->raudio_drawable) mainw->raudio_drawable = NULL;
340 lives_painter_surface_destroy(cfile->raudio_drawable);
341 cfile->raudio_drawable = NULL;
342 }
344
346 // must do this before we move it
349 }
350 lives_freep((void **)&mainw->files[i]->frame_index);
351 cfile->layout_map = NULL;
352 }
353
354 if (mainw->files[i]) {
360 if (!IS_NORMAL_CLIP(i) || (i == 0 && !mainw->only_close)
362 || (i == mainw->scrap_file && (mainw->only_close ||
364 || (i == mainw->ascrap_file && (mainw->only_close ||
366 || (i > 0 && !mainw->only_close && mainw->multitrack
367 && i == mainw->multitrack->render_file && !CLIP_HAS_VIDEO(i)
368 && !CLIP_HAS_AUDIO(i))) {
369 if (mainw->only_close || !IS_NORMAL_CLIP(i)) {
370 int current_file = mainw->current_file;
371 mainw->current_file = i;
372 close_current_file(current_file);
373 } else {
374 char *permitname;
377 permitname = lives_build_filename(prefs->workdir, mainw->files[i]->handle,
379 lives_touch(permitname);
380 lives_free(permitname);
381 com = lives_strdup_printf("%s close \"%s\"", prefs->backend, mainw->files[i]->handle);
382 lives_system(com, FALSE);
383 lives_free(com);
385 }
386 } else {
388 // or just clean them up -
389 // remove the following: "*.mgk *.bak *.pre *.tmp pause audio.* audiodump* audioclip";
390 if (!prefs->vj_mode) {
391 if (prefs->autoclean) {
392 com = lives_strdup_printf("%s clear_tmp_files \"%s\"",
394 lives_system(com, FALSE);
396 lives_free(com);
397 }
398 if (IS_NORMAL_CLIP(i)) {
399 char *fname = lives_build_filename(prefs->workdir, mainw->files[i]->handle,
400 TOTALSAVE_NAME, NULL);
401 int fd = lives_create_buffered(fname, DEF_FILE_PERMS);
402 lives_write_buffered(fd, (const char *)mainw->files[i], sizeof(lives_clip_t), TRUE);
404 }
405 }
406 if (mainw->files[i]->frameno != mainw->files[i]->saved_frameno) {
408 // *INDENT-OFF*
409 }}}}
410 // *INDENT-ON*
411 if (prefs->autoclean) {
412 com = lives_strdup_printf("%s empty_trash . general", prefs->backend);
413 lives_system(com, FALSE);
414 lives_free(com);
415 }
416
417 if (*mainw->set_name) {
420 if (mainw->only_close) {
424 for (i = 1; i <= MAX_FILES; i++) {
425 if (IS_NORMAL_CLIP(i) && (!mainw->multitrack || i != mainw->multitrack->render_file)) {
426 mainw->current_file = i;
429 }
430 }
432 }
433
434 if (*mainw->set_name) {
436 // delete the current set (this is for DELETE_SET)
437 cleanup_set_dir(mainw->set_name);
441 } else {
443 }
444 }
445 }
446
447 if (mainw->only_close) {
449 if (!mainw->multitrack) resize(1);
454
456 if (mainw->current_file > -1) sensitize();
458 d_print_done();
460
461 if (mainw->multitrack) {
462 mainw->current_file = mainw->multitrack->render_file;
463 mainw->multitrack->file_selected = -1;
467 } else {
468 if (prefs->show_msg_area) {
471 if (mainw->idlemax == 0) {
472 lives_idle_add_simple(resize_message_area, NULL);
473 }
475 }
476 }
478 return;
479 }
481 }
482
483 // stop valgrind from complaining
484#ifdef VALGRIND_ON
485 if (mainw->frame_layer) {
488 mainw->frame_layer = NULL;
489 }
490#endif
495 }
496
498
499#ifdef VALGRIND_ON
501
503 LiVESList *dummy_list = plugin_request("encoders", prefs->encoder.name, "finalise");
504 lives_list_free_all(&dummy_list);
505 }
507 rfx_free_all();
509#endif
510
511#ifdef ENABLE_OSC
512 if (prefs->osc_udp_started) lives_osc_end();
513#endif
515
516#ifdef VALGRIND_ON
519
520 mainw->msg_adj = NULL;
522
523 if (mainw->multitrack) {
525
526 if (mainw->multitrack->event_list) {
527 event_list_free(mainw->multitrack->event_list);
528 mainw->multitrack->event_list = NULL;
529 }
530 }
531
532 lives_freep((void **)&prefs->fxdefsfile);
533 lives_freep((void **)&prefs->fxsizesfile);
534 lives_freep((void **)&capable->wm_name);
535 lives_freep((void **)&mainw->recovery_file);
536
537 for (i = 0; i < NUM_LIVES_STRING_CONSTANTS; i++) lives_freep((void **)&mainw->string_constants[i]);
538 for (i = 0; i < mainw->n_screen_areas; i++) lives_freep((void **)&mainw->screen_areas[i].name);
539
540 lives_freep((void **)&mainw->foreign_visual);
541 lives_freep((void **)&THREADVAR(read_failed_file));
542 lives_freep((void **)&THREADVAR(write_failed_file));
543 lives_freep((void **)&THREADVAR(bad_aud_file));
544
545 lives_freep((void **)&mainw->old_vhash);
546 lives_freep((void **)&mainw->version_hash);
547 lives_freep((void **)&mainw->multitrack);
548 lives_freep((void **)&mainw->mgeom);
550 if (mainw->fonts_array) lives_strfreev(mainw->fonts_array);
551#ifdef ENABLE_NLS
552 //lives_freep((void **)&trString);
553#endif
554#endif
556 }
557 tmp = lives_strdup_printf("signal: %d", signum);
559 lives_free(tmp);
560
561 exit(0);
562}
563
564
565#ifndef VALGRIND_ON
566#ifdef _lives_free
567#undef lives_free
568#define lives_free _lives_free
569#endif
570#endif
571
572
573static void open_sel_range_activate(int frames, double fps) {
574 // open selection range dialog
575 LiVESWidget *opensel_dialog;
576 mainw->fc_buttonresponse = LIVES_RESPONSE_NONE; // reset button state
577 mainw->fx1_val = 0.;
578 mainw->fx2_val = frames > 1000. ? 1000. : (double)frames;
579 opensel_dialog = create_opensel_dialog(frames, fps);
580 lives_widget_show_all(opensel_dialog);
581}
582
583
584static boolean read_file_details_generic(const char *fname) {
586 char *tmpdir, *dirname, *com;
587 const char *prefix = "_fsp";
588 dirname = get_worktmp(prefix);
589 if (dirname) tmpdir = lives_build_path(prefs->workdir, dirname, NULL);
590 else {
591 dirname = lives_strdup_printf("%s%lu", prefix, gen_unique_id());
592 tmpdir = lives_build_path(prefs->workdir, dirname, NULL);
593 if (!lives_make_writeable_dir(tmpdir)) {
595 lives_free(tmpdir); lives_free(dirname);
597 return FALSE;
598 }
599 }
600
601 // check details
602 com = lives_strdup_printf("%s get_details %s \"%s\" \"%s\" %d", prefs->backend_sync,
603 dirname, fname, prefs->image_ext, 0);
605 lives_free(com); lives_free(dirname);
606
607 lives_rmdir(tmpdir, TRUE);
608 lives_free(tmpdir);
609
610 if (THREADVAR(com_failed)) {
611 THREADVAR(com_failed) = FALSE;
613 return FALSE;
614 }
615 return TRUE;
616}
617
618
619void on_open_sel_activate(LiVESMenuItem * menuitem, livespointer user_data) {
620 // OPEN A FILE
621 LiVESWidget *chooser;
622 char **array;
623 char *fname, *tmp;
624 double fps;
625 int resp, npieces, frames;
627
628 if (mainw->multitrack) {
629 if (mainw->multitrack->idlefunc > 0) {
631 mainw->multitrack->idlefunc = 0;
633 }
637 }
638
639 while (1) {
640 chooser = choose_file_with_preview((*mainw->vid_load_dir) ? mainw->vid_load_dir : NULL, NULL, NULL,
642 resp = lives_dialog_run(LIVES_DIALOG(chooser));
643
645
646 if (resp != LIVES_RESPONSE_ACCEPT) {
648 if (mainw->multitrack) {
651 }
652 return;
653 }
654
655 fname = lives_file_chooser_get_filename(LIVES_FILE_CHOOSER(chooser));
656
657 if (!fname) {
658 if (mainw->multitrack) {
661 }
662 return;
663 }
664
665 lives_snprintf(file_name, PATH_MAX, "%s", (tmp = lives_filename_to_utf8(fname, -1, NULL, NULL, NULL)));
666 lives_free(tmp);
667
668 lives_widget_destroy(LIVES_WIDGET(chooser));
669
670 lives_snprintf(mainw->vid_load_dir, PATH_MAX, "%s", file_name);
672
674
675 if (prefs->save_directories) {
677 }
678
679 if (!read_file_details_generic(fname)) {
680 lives_free(fname);
681 if (mainw->multitrack) {
684 }
685 return;
686 }
687 lives_free(fname);
688
689 npieces = get_token_count(mainw->msg, '|');
690 if (npieces < 8) {
692 if (mainw->multitrack) {
695 }
696 return;
697 }
698
699 array = lives_strsplit(mainw->msg, "|", npieces);
700 frames = atoi(array[2]);
701 fps = lives_strtod(array[7], NULL);
702 lives_strfreev(array);
703
704 if (frames == 0) {
705 do_error_dialog("LiVES could not extract any video frames from this file.\nSorry.\n");
707 if (mainw->multitrack) {
710 }
711 continue;
712 }
713 break;
714 }
715
716 open_sel_range_activate(frames, fps);
717}
718
719
720void on_open_vcd_activate(LiVESMenuItem * menuitem, livespointer device_type) {
721 LiVESWidget *vcdtrack_dialog;
722 int type = LIVES_POINTER_TO_INT(device_type);
724
725 if (mainw->multitrack) {
726 if (mainw->multitrack->idlefunc > 0) {
728 mainw->multitrack->idlefunc = 0;
730 }
734 }
735
736 mainw->fx1_val = 1;
737 mainw->fx2_val = 1;
739
740 vcdtrack_dialog = create_cdtrack_dialog(type, NULL);
741 lives_widget_show_all(vcdtrack_dialog);
742}
743
744
745void on_open_loc_activate(LiVESMenuItem * menuitem, livespointer user_data) {
746 // need non-instant opening (for now)
748
749 if (!HAS_EXTERNAL_PLAYER) {
751 return;
752 }
753
754 if (mainw->multitrack) {
755 if (mainw->multitrack->idlefunc > 0) {
757 mainw->multitrack->idlefunc = 0;
759 }
763 }
764
767}
768
769
770void on_open_utube_activate(LiVESMenuItem * menuitem, livespointer user_data) {
772
773 lives_remote_clip_request_t *req = NULL, *req2;
774 char *tmpdir;
777 return;
778 }
779 tmpdir = get_systmp("ytdl", TRUE);
780 if (!tmpdir) return;
781
783
784 if (mainw->multitrack) {
785 if (mainw->multitrack->idlefunc > 0) {
787 mainw->multitrack->idlefunc = 0;
789 }
793 }
794
795 do {
797 req = run_youtube_dialog(req);
798 if (!req) {
799 if (mainw->multitrack) {
802 }
803 goto final123;
804 }
805 req2 = on_utube_select(req, tmpdir);
806#ifndef ALLOW_NONFREE_CODECS
807 req2 = NULL;
808#endif
809 if (req2 && mainw->cancelled == CANCEL_RETRY) req = req2;
810 else {
811 lives_free(req);
812 req = NULL;
813 }
814 } while (mainw->cancelled == CANCEL_RETRY);
815
816final123:
817 if (mainw->permmgr) {
818 lives_freep((void **)&mainw->permmgr->key);
820 mainw->permmgr = NULL;
821 }
822 if (tmpdir) {
823 if (lives_file_test(tmpdir, LIVES_FILE_TEST_EXISTS)) {
824 lives_rmdir(tmpdir, TRUE);
825 }
826 lives_free(tmpdir);
827 }
828
829 if (!mainw->multitrack) sensitize();
830}
831
832
833void on_recent_activate(LiVESMenuItem * menuitem, livespointer user_data) {
834 char file[PATH_MAX];
835 double start = 0.;
836 int end = 0, pno;
837 char *pref;
839
840 pno = LIVES_POINTER_TO_INT(user_data);
841
842 if (mainw->multitrack) {
843 if (mainw->multitrack->idlefunc > 0) {
845 mainw->multitrack->idlefunc = 0;
847 }
849 }
850
851 //lives_widget_process_updates(LIVES_MAIN_WINDOW_WIDGET);
852
853 pref = lives_strdup_printf("%s%d", PREF_RECENT, pno);
854
855 get_utf8_pref(pref, file, PATH_MAX);
856
857 lives_free(pref);
858
859 if (get_token_count(file, '\n') > 1) {
860 char **array = lives_strsplit(file, "\n", 2);
861 lives_snprintf(file, PATH_MAX, "%s", array[0]);
863 mainw->file_open_params = lives_strdup(array[1]);
864 lives_strfreev(array);
865 }
866
867 if (get_token_count(file, '|') > 2) {
868 char **array = lives_strsplit(file, "|", 3);
869 lives_snprintf(file, PATH_MAX, "%s", array[0]);
870 start = lives_strtod(array[1], NULL);
871 end = atoi(array[2]);
872 lives_strfreev(array);
873 }
874 deduce_file(file, start, end);
875
876 if (mainw->multitrack) {
881 }
882}
883
884
885void on_location_select(LiVESButton * button, livespointer user_data) {
886 lives_snprintf(file_name, PATH_MAX, "%s", lives_entry_get_text(LIVES_ENTRY(locw->entry)));
890
893 if (prefs->no_bandwidth) {
894 mainw->file_open_params = lives_strdup("nobandwidth");
895 } else mainw->file_open_params = lives_strdup("sendbandwidth");
897 open_file(file_name);
898
899 if (mainw->multitrack) {
904 }
905}
906
907#define USE_YTDL
908
909//ret updated req if fmt sel. needs change
911 char *com, *full_dfile = NULL, *tmp, *ddir, *dest = NULL;
912 char *overrdkey = NULL;
913 char *mpf = NULL, *mpt = NULL;
914 lives_remote_clip_request_t *reqout = NULL;
915 boolean hasnone = FALSE, hasalts = FALSE;
916 boolean keep_old_dir = FALSE;
917 boolean forcecheck = FALSE;
918 boolean bres;
919 boolean badfile = FALSE;
920 int keep_frags = 0;
921 int manage_ds = 0;
922 int current_file = mainw->current_file;
923 int audchoice = 0;
924
926
927 // if possible, download to a temp dir first, that way we can cleanly delete leftover fragments, etc.
928 if (tmpdir) {
929 ddir = lives_build_path(tmpdir, req->fname, NULL);
930 keep_frags = 1;
931 if (lives_file_test(ddir, LIVES_FILE_TEST_IS_DIR)) {
932 if (check_dir_access(ddir, FALSE)) {
933 keep_old_dir = TRUE;
934 }
935 }
936 if (!keep_old_dir) {
937 LiVESResponseType resp;
938 char *xdir = lives_build_path(tmpdir, "*", NULL);
939 lives_rmdir(xdir, TRUE);
940 lives_free(xdir);
941 do {
942 resp = LIVES_RESPONSE_NONE;
943 if (!lives_make_writeable_dir(ddir)) {
944 resp = do_dir_perm_error(ddir, TRUE);
945 if (resp == LIVES_RESPONSE_CANCEL) goto cleanup_ut;
946 }
947 } while (resp == LIVES_RESPONSE_RETRY);
948 }
949 } else ddir = req->save_dir;
950
953 // then we monitor continuously
954 mpf = get_mountpoint_for(ddir);
955 if (mpf && *mpf && !lives_strcmp(mpf, capable->mountpoint)) {
956 manage_ds = 1;
957 }
958 }
959 if (!manage_ds && ddir != req->save_dir) {
960 mpt = get_mountpoint_for(req->save_dir);
961 if (mpf && *mpf && mpt && *mpt) {
962 if (lives_strcmp(mpf, mpt)) {
967 // final dest is ours, we will check warn, crit and overflow
968 manage_ds = 2;
969 } else {
970 // final dest is not ours, we will only check overflow
971 manage_ds = 3;
972 // *INDENT-OFF*
973 }}}}
974 // *INDENT-ON*
975
976 lives_freep((void **)&mpf);
977
981 if (manage_ds == 2) manage_ds = 3;
982 else manage_ds = 0;
983 }
984
985 mainw->error = FALSE;
986
987 // do minimal ds checking until we hit full download
988 forcecheck = FALSE;
989
990 if (!get_temp_handle(-1)) {
991 // we failed because we ran out of file handles; this hsould almost never happen
993 goto cleanup_ut;
994 }
995
996 while (1) {
997retry:
998 lives_rm(cfile->info_file);
999 if (req->do_update) {
1005 goto cleanup_ut;
1006 } else {
1007#ifdef YTDL_URL
1010 if (mainw->permmgr && mainw->permmgr->key && req->do_update) {
1012 overrdkey = mainw->permmgr->key;
1013 }
1014#else
1016 if (capable->has_youtube_dl != LOCAL) {
1017 char *todir = lives_build_path(capable->home_dir, LOCAL_HOME_DIR, "bin", NULL);
1018 char *to = lives_build_filename(todir, EXEC_YOUTUBE_DL, NULL);
1019 if (!lives_file_test(to, LIVES_FILE_TEST_IS_EXECUTABLE)) {
1020 char from[PATH_MAX];
1023 else
1025 if (lives_strlen(from) > 10) {
1026 if (check_dir_access(todir, TRUE)) {
1027 lives_cp(from, to);
1028 }
1029 }
1030 }
1031 lives_free(todir); lives_free(to);
1033 }
1034 }
1035 }
1036#endif
1037
1038 // get format list
1039
1040 // for now, we dont't pass req->desired_fps or req->audchoice
1041 // also we could send req->sub_lang...
1042
1043 if (!mainw->save_with_sound) audchoice = -1;
1044
1045 com = lives_strdup_printf("%s download_clip \"%s\" \"%s\" \"%s\" \"%s\" \"%s\" %d %d %d \"%s\" %d "
1046 "%d %d %d %s", prefs->backend, cfile->handle, req->URI, ddir,
1047 req->fname, req->format, req->desired_width, req->desired_height,
1048 req->matchsize, req->vidchoice, audchoice, keep_frags,
1049 req->do_update, req->debug,
1050 overrdkey ? (tmp = lives_strdup_printf(" %s", overrdkey))
1051 : (tmp = lives_strdup("")));
1052 lives_free(tmp);
1053
1054 if (mainw->permmgr) {
1055 lives_freep((void **)&mainw->permmgr->key);
1057 overrdkey = NULL;
1058 mainw->permmgr = NULL;
1059 }
1060
1061 mainw->error = FALSE;
1062 lives_system(com, FALSE);
1063 lives_free(com);
1064
1065 if (THREADVAR(com_failed)) {
1067 mainw->error = FALSE;
1068 req->allownf = TRUE;
1069 reqout = req;
1070 reqout->do_update = TRUE;
1072 goto cleanup_ut;
1073 }
1074
1075#ifndef USE_YTDL
1076 break;
1077#endif
1078
1079 // we expect to get back a list of available formats
1080 // or the selected format
1081 if (*(req->vidchoice)) break;
1082
1083 if (!do_auto_dialog(_("Getting format list"), 2)) {
1086 if (mainw->cancelled == CANCEL_ERROR) {
1088 mainw->error = TRUE;
1089 }
1091 else if (mainw->error) {
1093 if (mainw->permmgr) {
1094 if (mainw->cancelled == CANCEL_NONE &&
1095 mainw->permmgr->key && *mainw->permmgr->key) {
1096 req->do_update = TRUE;
1097 mainw->error = FALSE;
1098 goto retry;
1099 } else {
1100 req->do_update = FALSE;
1102 mainw->permmgr = NULL;
1103 }
1104 } else {
1105 do_error_dialogf(_("Unable to download media from the requested URL:\n%s\n\n"
1106 "NB: Obtaining the address by right clicking on the target itself "
1107 "can sometimes work better\n\n\nAlso, please note that downloading of 'Private' videos "
1108 "from Youtube is not possible,\nthey need to be changed to 'Unlisted' "
1109 "in order for the download to succeed.\n"), req->URI);
1110 }
1111 if (reqout) reqout->do_update = TRUE;
1112 }
1113 mainw->error = FALSE;
1115 reqout = req;
1116 goto cleanup_ut;
1117 }
1118
1119 if (!(*mainw->msg)) {
1120 hasnone = TRUE;
1121 }
1122#ifdef ALLOW_NONFREE_CODECS
1123 else if (!lives_strncmp(mainw->msg, "completed|altfmts", 17)) {
1124 hasalts = TRUE;
1125 }
1126#endif
1127
1128 if (hasnone || hasalts) {
1130 if (hasnone) {
1132 _("\nLiVES was unable to download the clip.\nPlease check the clip URL and make sure you have \n"
1133 "the latest youtube-dl installed.\n"));
1134 } else {
1135#ifdef ALLOW_NONFREE_CODECS
1136 if (do_yesno_dialog(
1137 _("\nLiVES was unable to download the clip in the desired format\nWould you like to try using an alternate "
1138 "format selection ?"))) {
1139 mainw->error = FALSE;
1141 req->allownf = TRUE;
1142 reqout = req;
1143#endif
1144 }
1145 }
1146 goto cleanup_ut;
1147 }
1148
1149 if (req->matchsize == LIVES_MATCH_CHOICE && !*req->vidchoice) {
1150 // show a list of the video formats and let the user pick one
1151 if (!youtube_select_format(req)) {
1152 goto cleanup_ut;
1153 }
1154 // we try again, this time with req->vidchoice set
1156 } else {
1157 // returned completed|vidchoice|audchoice
1158 char **array = lives_strsplit(mainw->msg, "|", 3);
1159 lives_snprintf(req->vidchoice, 512, "%s", array[1]);
1160 lives_snprintf(req->audchoice, 512, "%s", array[2]);
1161 lives_strfreev(array);
1162 }
1163 }
1164
1165 // backend should now be downloading the clip
1166
1167 // do more intensive diskspace checking
1168 forcecheck = TRUE;
1169
1170 if (manage_ds == 1) {
1172 // we will only monitor for CRIT, other statuses will be checked at the end
1174 }
1175
1176 cfile->nopreview = TRUE;
1177 cfile->no_proc_sys_errors = TRUE;
1178
1181
1182 lives_snprintf(req->ext, 16, "%s", req->format);
1183
1184 full_dfile = lives_strdup_printf("%s.%s", req->fname, req->ext);
1185
1186 bres = do_progress_dialog(TRUE, TRUE, _("Downloading clip"));
1187 cfile->no_proc_sys_errors = FALSE;
1188 if (!bres || mainw->error) badfile = TRUE;
1189 else {
1190 dest = lives_build_filename(req->save_dir, full_dfile, NULL);
1191 if (ddir != req->save_dir) {
1193 char *from = lives_build_filename(ddir, full_dfile, NULL);
1194 off_t clipsize;
1195 if (!lives_file_test(from, LIVES_FILE_TEST_EXISTS) || (clipsize = sget_file_size(from)) <= 0) {
1196 badfile = TRUE;
1197 } else {
1198 if (manage_ds == 2 || manage_ds == 3) {
1199 LiVESResponseType resp;
1200 do {
1201 char *msg = NULL;
1202 int64_t dsu = -1;
1203 resp = LIVES_RESPONSE_OK;
1204 dstate = get_storage_status(req->save_dir, mainw->next_ds_warn_level, &dsu, clipsize);
1205 if (dstate == LIVES_STORAGE_STATUS_OVERFLOW) {
1206 msg =
1207 lives_strdup_printf(_("There is insufficient disk space in %s to move the downloaded clip.\n"), mpt);
1208 } else if (manage_ds != 3) {
1210 msg = lives_strdup_printf(_("Moving the downloaded clip to\n%s\nwill bring free disk space in %s\n"
1211 "below the %s level of %s\n"), mpt);
1212 }
1213 }
1214
1215 if (msg) {
1216 char *cs = lives_format_storage_space_string(clipsize);
1217 char *vs = lives_format_storage_space_string(dsu);
1218 char *xmsg = lives_strdup_printf("%s\n(Free space in volume = %s, clip size = %s)\n"
1219 "You can either try deleting some files from %s and clicking on Retry\n"
1220 "or else click Cancel to cancel the download.\n", msg, vs, cs, mpt);
1221 resp = do_retry_cancel_dialog(xmsg);
1222 lives_free(xmsg); lives_free(msg);
1223 lives_free(cs); lives_free(vs);
1224 }
1225 } while (resp == LIVES_RESPONSE_RETRY);
1226 if (resp == LIVES_RESPONSE_CANCEL) {
1227 badfile = TRUE;
1228 }
1229 }
1230 }
1231 if (!badfile) {
1233 LiVESResponseType resp;
1234 req->do_update = FALSE;
1235 if (tmpdir) {
1236 if (lives_mv(from, dest)) {
1237 lives_free(from);
1238 lives_free(dest);
1239 badfile = TRUE;
1240 goto cleanup_ut;
1241 }
1242 }
1243 do {
1244 resp = LIVES_RESPONSE_NONE;
1245 if (!lives_file_test(dest, LIVES_FILE_TEST_EXISTS)) {
1246 char *errtxt = lives_strdup_printf(_("Failed to move %s to %s\n"), from, dest);
1247 resp = do_write_failed_error_s_with_retry(dest, errtxt);
1248 lives_free(errtxt);
1249 }
1250 } while (resp == LIVES_RESPONSE_RETRY);
1251 if (resp == LIVES_RESPONSE_CANCEL) {
1252 badfile = TRUE;
1253 }
1254 }
1255 lives_free(from);
1256 }
1257 }
1258
1259 if (badfile) {
1261 if (mainw->error) {
1264 _("\nLiVES was unable to download the clip.\nPlease check the clip URL and make sure you have \n"
1265 "the latest youtube-dl installed.\n(Note: try right-clicking on the clip itself to copy its address)\n"));
1266 mainw->error = FALSE;
1267 }
1268 }
1269
1270cleanup_ut:
1271 close_temp_handle(current_file);
1272 lives_freep((void **)&mpt);
1273
1274 if (manage_ds) {
1276 boolean recheck = FALSE;
1277 boolean tempdir_removed = FALSE;
1278 int64_t dsu = -1;
1279 if (prefs->disk_quota) {
1280 size_t wdlen = lives_strlen(prefs->workdir);
1281 size_t tlen = lives_strlen(req->save_dir);
1282 if (tlen >= wdlen && lives_strncmp(req->save_dir, prefs->workdir, wdlen)) {
1284 }
1285 }
1287 capable->ds_free = dsu;
1288 THREADVAR(com_failed) = FALSE;
1289 if (dstat != LIVES_STORAGE_STATUS_NORMAL) {
1290 // Houston, we hava problem !
1291 if (!forcecheck) recheck = TRUE;
1292 if (tmpdir) {
1294 lives_freep((void **)&mpt);
1295 mpt = get_mountpoint_for(tmpdir);
1296 if (!lives_strcmp(mpt, capable->mountpoint)) {
1297 tempdir_removed = TRUE;
1298 lives_rmdir(tmpdir, TRUE);
1299 if (!THREADVAR(com_failed)) {
1300 recheck = TRUE;
1301 // *INDENT-OFF*
1302 }}}}
1303 // *INDENT-ON*
1304
1305 if (recheck) {
1306 if (prefs->disk_quota) {
1307 mainw->dsu_valid = TRUE;
1309 }
1311 capable->ds_free = dsu;
1312 }
1313 if (dstat != LIVES_STORAGE_STATUS_NORMAL) {
1314 if (!tempdir_removed) {
1315 if (tmpdir) {
1317 lives_freep((void **)&mpt);
1318 mpt = get_mountpoint_for(tmpdir);
1319 if (!lives_strcmp(mpt, capable->mountpoint)) {
1320 lives_rmdir(tmpdir, TRUE);
1321 if (!THREADVAR(com_failed)) {
1322 if (prefs->disk_quota) {
1324 }
1326 capable->ds_free = dsu;
1327 // *INDENT-OFF*
1328 }}}}}
1329 // *INDENT-ON*
1330 if (dstat != LIVES_STORAGE_STATUS_NORMAL) {
1332 // we should probably offer if warn or quota too
1334 lives_rm(dest);
1335 badfile = TRUE;
1336 }
1337 if (!check_storage_space(-1, FALSE)) {
1338 badfile = TRUE;
1339 }
1340 }
1341 }
1342
1343 mainw->img_concat_clip = -1;
1345
1346 if (dest) {
1347 if (!badfile) {
1348 open_file(dest);
1349 if (mainw->multitrack) {
1353 }
1354 }
1355 lives_free(dest);
1356 }
1357 if (mainw->multitrack) {
1359 }
1360 return reqout;
1361 }
1362
1363
1364 void on_stop_clicked(LiVESMenuItem * menuitem, livespointer user_data) {
1365 // 'enough' button for open, open location, and record audio
1366
1367#ifdef ENABLE_JACK
1368 if (mainw->jackd && mainw->jackd_read && mainw->jackd_read->in_use) {
1370 return;
1371 }
1372#endif
1373#ifdef HAVE_PULSE_AUDIO
1374 if (mainw->pulsed && mainw->pulsed_read && mainw->pulsed_read->in_use) {
1376 return;
1377 }
1378#endif
1379
1382 if (mainw->proc_ptr) {
1388 }
1389 }
1390
1391 // resume to allow return
1394 }
1395 }
1396
1397
1398 void on_save_as_activate(LiVESMenuItem * menuitem, livespointer user_data) {
1399 if (cfile->frames == 0) {
1400 on_export_audio_activate(NULL, NULL);
1401 return;
1402 }
1403 save_file(mainw->current_file, cfile->start, cfile->end, NULL);
1404 }
1405
1406
1407#ifdef LIBAV_TRANSCODE
1408 void on_transcode_activate(LiVESMenuItem * menuitem, livespointer user_data) {
1409 if (!CURRENT_CLIP_IS_VALID) return;
1410 transcode_clip(cfile->start, cfile->end, FALSE, NULL);
1411 }
1412#endif
1413
1414
1415 void on_save_selection_activate(LiVESMenuItem * menuitem, livespointer user_data) {
1416 if (!CURRENT_CLIP_IS_VALID) return;
1417 save_file(mainw->current_file, cfile->start, cfile->end, NULL);
1418 }
1419
1420
1421 static void check_remove_layout_files(void) {
1423 // delete layout directory
1424 char *laydir = lives_build_filename(prefs->workdir, mainw->set_name, LAYOUTS_DIRNAME, NULL);
1425 lives_rmdir(laydir, TRUE);
1426 lives_free(laydir);
1427 d_print(_("Layouts were removed for set %s.\n"), mainw->set_name);
1428 }
1429 }
1430
1431
1432 void on_close_activate(LiVESMenuItem * menuitem, livespointer user_data) {
1433 char *warn, *extra;
1434 boolean lmap_errors = FALSE, acurrent = FALSE, only_current = FALSE;
1436
1437 if (mainw->multitrack) {
1438 if (mainw->multitrack->idlefunc > 0) {
1440 mainw->multitrack->idlefunc = 0;
1442 }
1444 mainw->current_file = mainw->multitrack->file_selected;
1445 } else desensitize();
1446
1450
1452 if (acurrent) {
1453 if (!mainw->xlays) only_current = TRUE;
1455 }
1456
1457 if (mainw->xlays) {
1458 char *title = get_menu_name(cfile, FALSE);
1459 if (strlen(title) > 128) {
1460 lives_free(title);
1461 title = (_("This file"));
1462 }
1463 if (acurrent) extra = (_(",\n - including the current layout - "));
1464 else extra = lives_strdup("");
1465 if (!only_current) warn = lives_strdup_printf(_("\n%s\nis used in some multitrack layouts%s.\n\nReally close it ?"),
1466 title, extra);
1467 else warn = lives_strdup_printf(_("\n%s\nis used in the current layout.\n\nReally close it ?"), title);
1468 lives_free(title);
1469 lives_free(extra);
1470 if (!do_warning_dialog(warn)) {
1471 lives_free(warn);
1473 goto close_done;
1474 }
1475 lives_free(warn);
1476 add_lmap_error(LMAP_ERROR_CLOSE_FILE, cfile->name, cfile->layout_map, 0, 1, 0., acurrent);
1477 lmap_errors = TRUE;
1479 }
1480 }
1481 if (!lmap_errors) {
1482 if (cfile->changed) {
1483 if (!do_close_changed_warn()) {
1484 goto close_done;
1485 }
1486 }
1487 }
1488
1489 if (mainw->sl_undo_mem && (cfile->stored_layout_frame != 0 || cfile->stored_layout_audio != 0.)) {
1490 // need to invalidate undo/redo stack, in case file was used in some layout undo
1492 }
1493
1494 if (mainw->multitrack) {
1496 }
1497
1499
1500 if (mainw->multitrack) {
1501 mainw->current_file = mainw->multitrack->render_file;
1504 if (mainw->multitrack->event_list) only_current = FALSE;
1505 }
1506
1507 if (lmap_errors && !only_current && mainw->cliplist) popup_lmap_errors(NULL, NULL);
1508
1509 if (!mainw->cliplist && *mainw->set_name) {
1510 boolean has_layout_map = FALSE;
1511
1512 // check for layout maps
1514 has_layout_map = TRUE;
1515 }
1516
1517 if (has_layout_map) {
1518 check_remove_layout_files();
1520 }
1521 // the user closed the last clip in the set, we should remove the set
1522 d_print(_("Removing set %s since it is now empty..."));
1523 cleanup_set_dir(mainw->set_name);
1524 lives_memset(mainw->set_name, 0, 1);
1525 mainw->was_set = FALSE;
1527 d_print_done();
1528 }
1529
1530close_done:
1531 if (mainw->multitrack) {
1534 } else sensitize();
1535 }
1536
1537
1538 void on_import_proj_activate(LiVESMenuItem * menuitem, livespointer user_data) {
1539 char *com;
1540 char *filt[] = {"*."LIVES_FILE_EXT_PROJECT, NULL};
1541 char *proj_file = choose_file(NULL, NULL, filt, LIVES_FILE_CHOOSER_ACTION_OPEN, NULL, NULL);
1542 char *new_set;
1543 char *set_dir;
1544 char *msg;
1545
1546 int current_file = mainw->current_file;
1547
1548 if (!proj_file) return;
1549 com = lives_strdup_printf("%s get_proj_set \"%s\"", prefs->backend_sync, proj_file);
1551 lives_free(com);
1552
1553 if (THREADVAR(com_failed)) {
1554 THREADVAR(com_failed) = FALSE;
1555 lives_free(proj_file);
1556 return;
1557 }
1558
1559 if (!(*mainw->msg)) {
1560 lives_free(proj_file);
1562 do_error_dialog(_("\nInvalid project file.\n"));
1564 return;
1565 }
1566
1567 if (!is_legal_set_name(mainw->msg, TRUE, FALSE)) return;
1568
1569 new_set = lives_strdup(mainw->msg);
1570 set_dir = lives_build_filename(prefs->workdir, new_set, NULL);
1571
1572 if (lives_file_test(set_dir, LIVES_FILE_TEST_IS_DIR)) {
1573 msg = lives_strdup_printf(
1574 _("\nA set called %s already exists.\nIn order to import this project, you must rename or delete the existing set.\n"
1575 "You can do this by File|Reload Set, and giving the set name\n%s\n"
1576 "then File|Close/Save all Clips and provide a new set name or discard it.\n"
1577 "Once you have done this, you will be able to import the new project.\n"),
1578 new_set, new_set);
1579 do_error_dialog(msg);
1580 lives_free(msg);
1581 lives_free(proj_file);
1582 lives_free(set_dir);
1583 lives_free(new_set);
1584 return;
1585 }
1586
1587 lives_free(set_dir);
1588
1589 d_print(_("Importing the project %s as set %s..."), proj_file, new_set);
1590
1591 if (!get_temp_handle(-1)) {
1592 lives_free(proj_file);
1593 lives_free(new_set);
1595 return;
1596 }
1597
1598 com = lives_strdup_printf("%s import_project \"%s\" \"%s\"", prefs->backend, cfile->handle, proj_file);
1599 lives_system(com, FALSE);
1600 lives_free(com);
1601 lives_free(proj_file);
1602
1603 if (THREADVAR(com_failed)) {
1604 mainw->current_file = close_temp_handle(current_file);
1605 lives_free(new_set);
1607 return;
1608 }
1609
1610 do_progress_dialog(TRUE, FALSE, _("Importing project"));
1611
1612 mainw->current_file = close_temp_handle(current_file);
1613 sensitize();
1614
1615 if (mainw->error) {
1616 lives_free(new_set);
1618 return;
1619 }
1620
1621 d_print_done();
1622
1623 reload_set(new_set);
1624 lives_free(new_set);
1625 }
1626
1627
1628 void on_export_proj_activate(LiVESMenuItem * menuitem, livespointer user_data) {
1629 char *filt[] = {"*."LIVES_FILE_EXT_PROJECT, NULL};
1630 char *def_file;
1631 char *proj_file;
1632 char *com, *tmp;
1633
1634 if (!*mainw->set_name) {
1635 int response;
1636 char new_set_name[MAX_SET_NAME_LEN];
1637 do {
1638 // prompt for a set name, advise user to save set
1641 response = lives_dialog_run(LIVES_DIALOG(renamew->dialog));
1642 if (response == LIVES_RESPONSE_CANCEL) {
1644 return;
1645 }
1646 lives_snprintf(new_set_name, MAX_SET_NAME_LEN, "%s", (tmp = U82F(lives_entry_get_text(LIVES_ENTRY(renamew->entry)))));
1648 lives_freep((void **)&renamew);
1649 lives_free(tmp);
1651
1652 } while (!is_legal_set_name(new_set_name, FALSE, FALSE));
1653 lives_snprintf(mainw->set_name, MAX_SET_NAME_LEN, "%s", new_set_name);
1654 }
1655
1657 if (!check_for_layout_del(NULL, FALSE)) return;
1658 }
1659
1661
1662 if (!mainw->was_set) {
1663 mainw->no_exit = TRUE;
1664 if (!on_save_set_activate(NULL, NULL)) return;
1665 mainw->no_exit = FALSE;
1666 mainw->was_set = TRUE;
1668 }
1669
1671 proj_file = choose_file(NULL, def_file, filt, LIVES_FILE_CHOOSER_ACTION_SAVE, NULL, NULL);
1672 lives_free(def_file);
1673
1674 if (!proj_file) return;
1675
1676 lives_rm((tmp = lives_filename_from_utf8(proj_file, -1, NULL, NULL, NULL)));
1677 lives_free(tmp);
1678
1679 d_print(_("Exporting project %s..."), proj_file);
1680
1681 com = lives_strdup_printf("%s export_project \"%s\" \"%s\" \"%s\"", prefs->backend, cfile->handle, mainw->set_name, proj_file);
1682 lives_system(com, FALSE);
1683 lives_free(com);
1684
1685 if (THREADVAR(com_failed)) {
1686 lives_free(proj_file);
1688 return;
1689 }
1690
1691 do_progress_dialog(TRUE, FALSE, _("Exporting project"));
1692
1693 if (mainw->error) d_print_failed();
1694 else d_print_done();
1695
1696 lives_free(proj_file);
1697 }
1698
1699
1700 void on_export_theme_activate(LiVESMenuItem * menuitem, livespointer user_data) {
1701 lives_colRGBA64_t lcol;
1702
1703 char *filt[] = {"*."LIVES_FILE_EXT_TAR_GZ, NULL};
1704
1705 char theme_name[128];
1706
1707 char *file_name, *tmp, *tmp2, *com, *fname;
1708 char *sepimg_ext, *frameimg_ext, *sepimg, *frameimg;
1709 char *themedir, *thfile, *themefile;
1710 char *pstyle;
1711
1712 int response;
1713
1714 desensitize();
1715
1716 do {
1717 // prompt for a set name, advise user to save set
1720 response = lives_dialog_run(LIVES_DIALOG(renamew->dialog));
1721 if (response == LIVES_RESPONSE_CANCEL) return;
1722 lives_snprintf(theme_name, 128, "%s", (tmp = U82F(lives_entry_get_text(LIVES_ENTRY(renamew->entry)))));
1724 lives_freep((void **)&renamew);
1725 lives_free(tmp);
1727
1728 } while (!do_std_checks(U82F(theme_name), _("Theme"), 64, NULL));
1729
1730 fname = lives_strdup_printf("%s.%s", theme_name, LIVES_FILE_EXT_TAR_GZ);
1731
1732 file_name = choose_file(capable->home_dir, fname, filt,
1733 LIVES_FILE_CHOOSER_ACTION_SAVE, _("Choose a directory to export to"), NULL);
1734
1735 lives_free(fname);
1736
1737 if (!file_name) {
1738 return;
1739 }
1740
1743
1744 // create a header.theme file in tmp, then zip it up with the images
1745
1746 sepimg_ext = get_extension(mainw->sepimg_path);
1747 frameimg_ext = get_extension(mainw->frameblank_path);
1748
1750 themedir = lives_build_filename(prefs->workdir, thfile, NULL);
1751 themefile = lives_build_filename(themedir, THEME_HEADER, NULL);
1752#ifdef GUI_GTK
1753#if !GTK_CHECK_VERSION(3, 0, 0)
1754 lives_free(themefile);
1755 themefile = lives_build_filename(themedir, THEME_HEADER_2, NULL);
1756#endif
1757#endif
1758 lives_free(thfile);
1759
1760 thfile = lives_strdup_printf("%s.%s", THEME_SEP_IMG_LITERAL, sepimg_ext);
1761 sepimg = lives_build_filename(themedir, thfile, NULL);
1762 lives_free(thfile);
1763
1764 thfile = lives_strdup_printf("%s.%s", THEME_FRAME_IMG_LITERAL, frameimg_ext);
1765 frameimg = lives_build_filename(themedir, thfile, NULL);
1766
1767 lives_free(sepimg_ext);
1768 lives_free(frameimg_ext);
1769
1770 lives_mkdir_with_parents(themedir, capable->umask);
1771
1772 set_theme_pref(themefile, THEME_DETAIL_NAME, theme_name);
1773
1774 pstyle = lives_strdup_printf("%d", palette->style);
1775 set_theme_pref(themefile, THEME_DETAIL_STYLE, pstyle);
1776 lives_free(pstyle);
1777
1780
1783
1786
1789
1792
1795
1796 if (mainw->fx1_bool) {
1799
1802
1806
1810
1812
1815 }
1816
1817 lives_free(themefile);
1818
1819 d_print(_("Exporting theme as %s..."), file_name);
1820
1821 // copy images for packaging
1822 lives_cp(mainw->sepimg_path, sepimg);
1823 lives_free(sepimg);
1824
1825 if (THREADVAR(com_failed)) {
1826 lives_rmdir(themedir, TRUE);
1827 lives_free(frameimg);
1828 lives_free(file_name);
1829 lives_free(themedir);
1831 sensitize();
1832 return;
1833 }
1834
1835 lives_cp(mainw->frameblank_path, frameimg);
1836 lives_free(frameimg);
1837
1838 if (THREADVAR(com_failed)) {
1839 lives_rmdir(themedir, TRUE);
1840 lives_free(file_name);
1841 lives_free(themedir);
1843 sensitize();
1844 return;
1845 }
1846
1847 com = lives_strdup_printf("%s create_package \"%s\" \"%s\"", prefs->backend_sync,
1848 (tmp = lives_filename_from_utf8(file_name, -1, NULL, NULL, NULL)),
1849 (tmp2 = lives_filename_from_utf8(themedir, -1, NULL, NULL, NULL)));
1850
1851 lives_free(tmp);
1852 lives_free(tmp2);
1853 lives_free(file_name);
1854
1855 lives_system(com, TRUE);
1856 lives_free(com);
1857
1858 lives_rmdir(themedir, TRUE);
1859 lives_free(themedir);
1860
1861 if (THREADVAR(com_failed)) {
1863 sensitize();
1864 return;
1865 }
1866
1867 d_print_done();
1868 sensitize();
1870 }
1871
1872
1873 void on_import_theme_activate(LiVESMenuItem * menuitem, livespointer user_data) {
1874 char *filt[] = {"*."LIVES_FILE_EXT_TAR_GZ, NULL};
1875 char tname[128];
1876
1877 char *importcheckdir, *themeheader, *themedir;
1878 char *com;
1879 char *theme_file;
1880
1881 desensitize();
1882
1883 theme_file = choose_file(NULL, NULL, filt, LIVES_FILE_CHOOSER_ACTION_OPEN, NULL, NULL);
1884
1885 if (!theme_file) {
1886 sensitize();
1887 return;
1888 }
1891
1892
1893 importcheckdir = lives_build_filename(prefs->workdir, IMPORTS_DIRNAME, NULL);
1894 lives_rmdir(importcheckdir, TRUE);
1895
1896 // unpackage file to get the theme name
1897 com = lives_strdup_printf("%s import_package \"%s\" \"%s\"", prefs->backend_sync, U82F(theme_file), importcheckdir);
1898 lives_system(com, FALSE);
1899 lives_free(com);
1900
1901 if (THREADVAR(com_failed)) {
1902 lives_rmdir(importcheckdir, TRUE);
1903 lives_free(importcheckdir);
1904 lives_free(theme_file);
1906 sensitize();
1907 return;
1908 }
1909
1910 themeheader = lives_build_filename(prefs->workdir, IMPORTS_DIRNAME, THEME_HEADER, NULL);
1911
1912 if (get_pref_from_file(themeheader, THEME_DETAIL_NAME, tname, 128) == LIVES_RESPONSE_NO) {
1913 // failed to get name
1914 lives_rmdir(importcheckdir, TRUE);
1915 lives_free(importcheckdir);
1916 lives_free(themeheader);
1918 do_bad_theme_import_error(theme_file);
1919 lives_free(theme_file);
1920 sensitize();
1921 return;
1922 }
1923
1924 lives_rmdir(importcheckdir, TRUE);
1925 lives_free(importcheckdir);
1926 lives_free(themeheader);
1927
1928 d_print(_("Importing theme \"%s\" from %s..."), tname, theme_file);
1929
1930 if (!do_std_checks(U82F(tname), _("Theme"), 64, NULL)) {
1931 lives_free(theme_file);
1934 return;
1935 }
1936
1937 // check for existing dupes
1938
1939 themedir = lives_build_filename(prefs->config_datadir, PLUGIN_THEMES, tname, NULL);
1940
1941 if (lives_file_test(themedir, LIVES_FILE_TEST_IS_DIR)) {
1942 if (!do_theme_exists_warn(tname)) {
1944 lives_free(themedir);
1945 lives_free(theme_file);
1947 sensitize();
1948 return;
1949 }
1950 lives_rmdir(themedir, TRUE);
1951 }
1952
1953 // name was OK, unpack into custom dir
1954 com = lives_strdup_printf("%s import_package \"%s\" \"%s\"", prefs->backend_sync, U82F(theme_file), themedir);
1955 lives_system(com, FALSE);
1956 lives_free(com);
1957
1958 lives_free(theme_file);
1959
1960 if (THREADVAR(com_failed)) {
1961 lives_rmdir(themedir, TRUE);
1962 lives_free(themedir);
1965 sensitize();
1966 return;
1967 }
1968
1969 lives_free(themedir);
1970
1971 lives_snprintf(prefs->theme, 64, "%s", tname);
1972
1973 // try to set theme colours
1974 if (!set_palette_colours(TRUE)) {
1975 lives_snprintf(prefs->theme, 64, "%s", future_prefs->theme);
1978 sensitize();
1979 return;
1980 }
1981
1982 lives_snprintf(future_prefs->theme, 64, "%s", prefs->theme);
1984
1989
1990 d_print_done();
1991 sensitize();
1993 }
1994
1995
1996 void on_backup_activate(LiVESMenuItem * menuitem, livespointer user_data) {
1997 char *filt[] = {"*."LIVES_FILE_EXT_BACKUP, NULL};
1998 char *file_name;
1999 char *defname, *text;
2000
2001 defname = lives_strdup_printf("%s.%s", cfile->name, LIVES_FILE_EXT_BACKUP);
2002
2003 text = lives_strdup_printf(_("Backup as %s File"), LIVES_FILE_EXT_BACKUP);
2004
2005 file_name = choose_file((*mainw->proj_save_dir) ? mainw->proj_save_dir : NULL, defname, filt,
2006 LIVES_FILE_CHOOSER_ACTION_SAVE, text, NULL);
2007
2008 lives_free(text);
2009 lives_free(defname);
2010
2011 if (!file_name) return;
2012
2013 backup_file(mainw->current_file, 1, cfile->frames, file_name);
2014
2015 lives_snprintf(mainw->proj_save_dir, PATH_MAX, "%s", file_name);
2017 lives_free(file_name);
2018 }
2019
2020
2021 void on_restore_activate(LiVESMenuItem * menuitem, livespointer user_data) {
2022 char *filt[] = {"*."LIVES_FILE_EXT_BACKUP, NULL};
2023 char *file_name, *text;
2024
2025 text = lives_strdup_printf(_("Restore %s File"), LIVES_FILE_EXT_BACKUP);
2026
2027 file_name = choose_file((*mainw->proj_load_dir) ? mainw->proj_load_dir : NULL, text, filt,
2028 LIVES_FILE_CHOOSER_ACTION_OPEN, text, NULL);
2029
2030 lives_free(text);
2031
2032 if (!file_name) return;
2033
2034 restore_file(file_name);
2035
2036 lives_snprintf(mainw->proj_load_dir, PATH_MAX, "%s", file_name);
2038 lives_free(file_name);
2040 }
2041
2042
2043 void mt_memory_free(void) {
2044 int i;
2045
2047
2048 mainw->multitrack->no_expose = TRUE;
2049
2052 if (mainw->multitrack->audio_vols) lives_list_free(mainw->multitrack->audio_vols);
2053 }
2054
2055 if (mainw->multitrack->video_draws) {
2056 for (i = 0; i < mainw->multitrack->num_video_tracks; i++) {
2058 }
2059 lives_list_free(mainw->multitrack->video_draws);
2060 }
2061
2064
2065 lives_list_free(mainw->multitrack->tl_marks);
2066
2067 if (mainw->multitrack->event_list) event_list_free(mainw->multitrack->event_list);
2068 mainw->multitrack->event_list = NULL;
2069
2071
2073
2075 }
2076
2077
2078 void del_current_set(boolean exit_after) {
2079 char *msg;
2080 boolean moc = mainw->only_close, crec;
2081 mainw->only_close = !exit_after;
2084
2085 if (mainw->multitrack) {
2087
2088 if (mainw->multitrack->event_list) {
2089 event_list_free(mainw->multitrack->event_list);
2090 mainw->multitrack->event_list = NULL;
2091 }
2092 }
2093
2094 // check for layout maps
2096 check_remove_layout_files();
2097 }
2098
2101
2103
2105
2106 if (mainw->clips_available) {
2107 if (*mainw->set_name)
2108 msg = lives_strdup_printf(_("Deleting set %s..."), mainw->set_name);
2109 else
2110 msg = lives_strdup(_("Deleting set..."));
2111 d_print(msg);
2112 lives_free(msg);
2113
2114 do_threaded_dialog(_("Deleting set"), FALSE);
2115 }
2116
2117 crec = prefs->crash_recovery;
2119
2120 // do a lot of cleanup, delete files
2121 lives_exit(0);
2122 prefs->crash_recovery = crec;
2123
2124 if (*mainw->set_name) {
2125 d_print(_("Set %s was permanently deleted from the disk.\n"), mainw->set_name);
2126 lives_memset(mainw->set_name, 0, 1);
2127 }
2128 mainw->only_close = moc;
2130 }
2131
2132
2133 void on_quit_activate(LiVESMenuItem * menuitem, livespointer user_data) {
2134 char *tmp;
2135 boolean legal_set_name;
2136
2138
2139 if (user_data && LIVES_POINTER_TO_INT(user_data) == 1) {
2140 mainw->no_exit = TRUE;
2142 } else {
2143 mainw->no_exit = FALSE;
2145 }
2146
2147 // stop if playing
2148 if (LIVES_IS_PLAYING) {
2151 return;
2152 }
2153
2154 if (mainw->multitrack) {
2155 if (mainw->multitrack->idlefunc > 0) {
2157 mainw->multitrack->idlefunc = 0;
2159 }
2161 }
2162
2163 if (mainw->multitrack && mainw->multitrack->event_list) {
2164 if (mainw->only_close) {
2166 if (mainw->multitrack) {
2169 }
2170 return;
2171 // *INDENT-OFF*
2172 }}}
2173 // *INDENT-ON*
2174
2176 if (!check_for_layout_del(NULL, FALSE)) {
2178 return;
2179 }
2180 } else if (mainw->stored_layout_undos) {
2182 }
2183
2186
2188 lives_exit(0);
2189 } else {
2190 char *set_name;
2191 _entryw *cdsw = create_cds_dialog(1);
2192 LiVESResponseType resp;
2193 do {
2194 legal_set_name = TRUE;
2196 resp = lives_dialog_run(LIVES_DIALOG(cdsw->dialog));
2197
2198 if (resp == LIVES_RESPONSE_RETRY) continue;
2199
2200 if (resp == LIVES_RESPONSE_CANCEL) {
2202 lives_free(cdsw);
2204 if (mainw->multitrack) {
2207 }
2209 return;
2210 }
2211 if (resp == LIVES_RESPONSE_ACCEPT) {
2212 // save set
2213 if ((legal_set_name = is_legal_set_name((set_name = U82F(lives_entry_get_text(LIVES_ENTRY(cdsw->entry)))),
2214 TRUE, FALSE))) {
2216 lives_free(cdsw);
2217
2220
2222
2223 on_save_set_activate(NULL, (tmp = U82F(set_name)));
2224 lives_free(tmp);
2225 lives_free(set_name);
2226
2227 if (!mainw->no_exit) lives_exit(0);
2228
2229 if (mainw->multitrack) {
2232 }
2234 if (mainw->cs_manage) lives_idle_add_simple(run_diskspace_dialog_idle, NULL);
2236 return;
2237 }
2238 resp = LIVES_RESPONSE_RETRY;
2240 lives_free(set_name);
2241 }
2242 if (resp == LIVES_RESPONSE_RESET) {
2243 char *what, *expl;
2244 // TODO
2245 //if (check_for_executable(&capable->has_gio, EXEC_GIO)) mainw->add_trash_rb = TRUE;
2246 if (mainw->was_set) {
2247 what = lives_strdup_printf(_("Set '%s'"), mainw->set_name);
2248 expl = lives_strdup("");
2249 } else {
2250 what = (_("All currently open clips"));
2251 expl = (_("<b>(Note: original source material will NOT be affected !)</b>"));
2253 }
2254 if (!do_warning_dialogf(_("\n\n%s will be permanently deleted from the disk.\nAre you sure ?\n\n%s"), what, expl)) {
2255 resp = LIVES_RESPONSE_ABORT;
2256 }
2258 lives_free(what); lives_free(expl);
2259 //mainw->add_trash_rb = FALSE;
2260 }
2261 } while (resp == LIVES_RESPONSE_ABORT || resp == LIVES_RESPONSE_RETRY);
2262
2264 lives_free(cdsw);
2265
2266 // discard clipset
2268 }
2269
2271 }
2272
2273
2274 // TODO - split into undo.c
2275 void on_undo_activate(LiVESWidget * menuitem, livespointer user_data) {
2276 char *com, *tmp;
2277
2278 boolean bad_header = FALSE;
2279 boolean retvalb;
2280
2281 int ostart = cfile->start;
2282 int oend = cfile->end;
2283 int current_file = mainw->current_file;
2284 int switch_file = current_file;
2285 int asigned, aendian;
2286 int i;
2287
2288 if (mainw->multitrack) return;
2289
2292 cfile->undoable = FALSE;
2293 cfile->redoable = TRUE;
2296
2297 mainw->osc_block = TRUE;
2298
2299 d_print("");
2300
2301 if (menuitem) {
2303 d_print("%s...", lives_menu_item_get_text(LIVES_WIDGET(menuitem)));
2305 }
2306
2307 if (cfile->undo_action == UNDO_INSERT_SILENCE) {
2308 double start = cfile->undo1_dbl;
2309 // if old audio end < start then we want to delete from oae to end
2310 if (cfile->old_laudio_time < start) cfile->undo1_dbl = cfile->old_laudio_time;
2311 on_del_audio_activate(NULL, NULL);
2312 cfile->undo_action = UNDO_INSERT_SILENCE;
2313 set_redoable(_("Insert Silence"), TRUE);
2314 cfile->undo1_dbl = start;
2315 }
2316
2317 if (cfile->undo_action == UNDO_CUT || cfile->undo_action == UNDO_DELETE || cfile->undo_action == UNDO_DELETE_AUDIO) {
2318 int reset_achans = 0;
2319 lives_rm(cfile->info_file);
2320 if (cfile->achans != cfile->undo_achans) {
2321 if (cfile->audio_waveform) {
2322 for (i = 0; i < cfile->achans; lives_freep((void **)&cfile->audio_waveform[i++]));
2323 lives_freep((void **)&cfile->audio_waveform);
2324 lives_freep((void **)&cfile->aw_sizes);
2325 }
2326 }
2327
2328 cfile->arate = cfile->undo_arate;
2329 cfile->signed_endian = cfile->undo_signed_endian;
2330 cfile->achans = cfile->undo_achans;
2331 cfile->asampsize = cfile->undo_asampsize;
2332 cfile->arps = cfile->undo_arps;
2333
2334 if (cfile->frames == 0) {
2335 cfile->hsize = cfile->ohsize;
2336 cfile->vsize = cfile->ovsize;
2337 }
2338
2339 if (cfile->undo_action == UNDO_DELETE_AUDIO) {
2340 if (cfile->undo1_dbl == cfile->undo2_dbl && cfile->undo1_dbl == 0.) {
2341 // undo delete_all_audio
2342 reset_achans = cfile->undo_achans;
2343 com = lives_strdup_printf("%s undo_audio \"%s\"", prefs->backend_sync, cfile->handle);
2344 }
2345 // undo delete selected audio
2346 // (set with with_audio==2 [audio only],therfore start,end,where are in secs.; times==-1)
2347 else com = lives_strdup_printf("%s insert \"%s\" \"%s\" %.8f 0. %.8f \"%s\" 2 0 0 0 0 %d %d %d %d %d -1",
2348 prefs->backend,
2349 cfile->handle, get_image_ext_for_type(cfile->img_type), cfile->undo1_dbl,
2350 cfile->undo2_dbl - cfile->undo1_dbl, cfile->handle, cfile->arps, cfile->achans,
2351 cfile->asampsize, !(cfile->signed_endian & AFORM_UNSIGNED),
2352 !(cfile->signed_endian & AFORM_BIG_ENDIAN));
2353 } else {
2354 // undo cut or delete (times to insert is -1)
2355 // start,end, where are in frames
2356 cfile->undo1_boolean &= mainw->ccpd_with_sound;
2357 com = lives_strdup_printf("%s insert \"%s\" \"%s\" %d %d %d \"%s\" %d %d 0 0 %.3f %d %d %d %d %d -1",
2358 prefs->backend, cfile->handle,
2359 get_image_ext_for_type(cfile->img_type), cfile->undo_start - 1, cfile->undo_start,
2360 cfile->undo_end, cfile->handle, cfile->undo1_boolean, cfile->frames, cfile->fps,
2361 cfile->arps, cfile->achans, cfile->asampsize, !(cfile->signed_endian & AFORM_UNSIGNED),
2362 !(cfile->signed_endian & AFORM_BIG_ENDIAN));
2363
2364 }
2365
2366 lives_system(com, FALSE);
2367 lives_free(com);
2368
2369 if (THREADVAR(com_failed)) return;
2370
2371 // show a progress dialog, not cancellable
2372 do_progress_dialog(TRUE, FALSE, _("Undoing"));
2373
2374 if (mainw->error) {
2376 //cfile->may_be_damaged=TRUE;
2377 return;
2378 }
2379
2380 if (cfile->undo_action != UNDO_DELETE_AUDIO) {
2381 cfile->insert_start = cfile->undo_start;
2382 cfile->insert_end = cfile->undo_end;
2383
2384 if (cfile->start >= cfile->undo_start) {
2385 cfile->start += cfile->undo_end - cfile->undo_start + 1;
2386 }
2387 if (cfile->end >= cfile->undo_start) {
2388 cfile->end += cfile->undo_end - cfile->undo_start + 1;
2389 }
2390
2391 cfile->frames += cfile->undo_end - cfile->undo_start + 1;
2392 if (cfile->frames > 0) {
2393 if (cfile->start == 0) {
2394 cfile->start = 1;
2395 }
2396 if (cfile->end == 0) {
2397 cfile->end = cfile->frames;
2398 }
2399 }
2400 if (cfile->frame_index_back) {
2402 }
2403 if (!save_clip_value(mainw->current_file, CLIP_DETAILS_FRAMES, &cfile->frames)) bad_header = TRUE;
2404 showclipimgs();
2405 }
2406 if (reset_achans > 0) {
2407 if (cfile->audio_waveform) {
2408 for (i = 0; i < cfile->achans; lives_freep((void **)&cfile->audio_waveform[i++]));
2409 lives_freep((void **)&cfile->audio_waveform);
2410 lives_freep((void **)&cfile->aw_sizes);
2411 }
2412 asigned = !(cfile->signed_endian & AFORM_UNSIGNED);
2413 aendian = cfile->signed_endian & AFORM_BIG_ENDIAN;
2414 cfile->achans = reset_achans;
2415 if (!save_clip_value(mainw->current_file, CLIP_DETAILS_ACHANS, &cfile->achans)) bad_header = TRUE;
2416 if (!save_clip_value(mainw->current_file, CLIP_DETAILS_ARATE, &cfile->arps)) bad_header = TRUE;
2417 if (!save_clip_value(mainw->current_file, CLIP_DETAILS_PB_ARATE, &cfile->arate)) bad_header = TRUE;
2418 if (!save_clip_value(mainw->current_file, CLIP_DETAILS_ASAMPS, &cfile->asampsize)) bad_header = TRUE;
2419 if (!save_clip_value(mainw->current_file, CLIP_DETAILS_AENDIAN, &aendian)) bad_header = TRUE;
2420 if (!save_clip_value(mainw->current_file, CLIP_DETAILS_ASIGNED, &asigned)) bad_header = TRUE;
2421 }
2422
2423 showclipimgs();
2424
2425 if (bad_header) do_header_write_error(mainw->current_file);
2426 }
2427
2428 if (cfile->undo_action == UNDO_RESIZABLE || cfile->undo_action == UNDO_RENDER || cfile->undo_action == UNDO_EFFECT ||
2429 cfile->undo_action == UNDO_MERGE || (cfile->undo_action == UNDO_ATOMIC_RESAMPLE_RESIZE &&
2430 (cfile->frames != cfile->old_frames || cfile->hsize != cfile->ohsize ||
2431 cfile->vsize != cfile->ovsize || cfile->fps != cfile->undo1_dbl))) {
2432 char *audfile;
2433
2434 com = lives_strdup_printf("%s undo \"%s\" %d %d \"%s\"", prefs->backend, cfile->handle, cfile->undo_start, cfile->undo_end,
2435 get_image_ext_for_type(cfile->img_type));
2436 lives_rm(cfile->info_file);
2437 lives_system(com, FALSE);
2438 lives_free(com);
2439
2440 if (THREADVAR(com_failed)) return;
2441
2443 mainw->error = FALSE;
2444
2445 // show a progress dialog, not cancellable
2446 cfile->progress_start = cfile->undo_start;
2447 cfile->progress_end = cfile->undo_end;
2448 do_progress_dialog(TRUE, FALSE, _("Undoing"));
2449
2450 if (cfile->undo_action == UNDO_RENDER || cfile->undo_action == UNDO_MERGE) {
2452 tmp = lives_strdup_printf("%s.%s", audfile, LIVES_FILE_EXT_BAK);
2453 lives_free(audfile);
2454 audfile = tmp;
2455 if (lives_file_test(audfile, LIVES_FILE_TEST_EXISTS)) {
2456 // restore overwritten audio
2457 com = lives_strdup_printf("%s undo_audio \"%s\"", prefs->backend_sync, cfile->handle);
2458 lives_rm(cfile->info_file);
2459 lives_system(com, FALSE);
2460 lives_free(com);
2461 if (THREADVAR(com_failed)) {
2462 lives_free(audfile);
2463 return;
2464 }
2465 retvalb = do_auto_dialog(_("Restoring audio"), 0);
2466 if (!retvalb) {
2468 //cfile->may_be_damaged=TRUE;
2469 return;
2470 }
2471 }
2472 lives_free(audfile);
2473 }
2474
2475 if (cfile->frame_index_back) {
2476 int *tmpindex = cfile->frame_index;
2477 cfile->clip_type = CLIP_TYPE_FILE;
2478 cfile->frame_index = cfile->frame_index_back;
2479 if (cfile->undo_action == UNDO_RENDER) {
2480 do_threaded_dialog(_("Clearing frame images"), FALSE);
2481 clean_images_from_virtual(cfile, cfile->undo_start, cfile->undo_end);
2483 cfile->frame_index_back = NULL;
2485 } else {
2487 cfile->frame_index_back = tmpindex;
2488 }
2489 }
2490 }
2491
2492 if (cfile->undo_action == UNDO_ATOMIC_RESAMPLE_RESIZE && (cfile->frames != cfile->old_frames ||
2493 cfile->hsize != cfile->ohsize || cfile->vsize != cfile->ovsize)) {
2494
2495 if (cfile->frames > cfile->old_frames) {
2496 com = lives_strdup_printf("%s cut \"%s\" %d %d %d %d \"%s\" %.3f %d %d %d",
2497 prefs->backend, cfile->handle, cfile->old_frames + 1,
2498 cfile->frames, FALSE, cfile->frames, get_image_ext_for_type(cfile->img_type),
2499 cfile->fps, cfile->arate, cfile->achans, cfile->asampsize);
2500
2501 cfile->progress_start = cfile->old_frames + 1;
2502 cfile->progress_end = cfile->frames;
2503
2504 lives_rm(cfile->info_file);
2505 lives_system(com, FALSE);
2506 lives_free(com);
2507
2508 if (THREADVAR(com_failed)) return;
2509
2510 // show a progress dialog, not cancellable
2511 do_progress_dialog(TRUE, FALSE, _("Deleting excess frames"));
2512
2513 if (cfile->clip_type == CLIP_TYPE_FILE) {
2514 delete_frames_from_virtual(mainw->current_file, cfile->old_frames + 1, cfile->frames);
2515 }
2516 }
2517
2518 cfile->frames = cfile->old_frames;
2519 cfile->hsize = cfile->ohsize;
2520 cfile->vsize = cfile->ovsize;
2521 if (!save_clip_value(mainw->current_file, CLIP_DETAILS_WIDTH, &cfile->hsize)) bad_header = TRUE;
2522 if (!save_clip_value(mainw->current_file, CLIP_DETAILS_HEIGHT, &cfile->vsize)) bad_header = TRUE;
2523 cfile->fps = cfile->undo1_dbl;
2524 if (cfile->clip_type == CLIP_TYPE_FILE && cfile->ext_src) {
2525 lives_clip_data_t *cdata = ((lives_decoder_t *)cfile->ext_src)->cdata;
2526 double dfps = (double)cdata->fps;
2527 if (!save_clip_value(mainw->current_file, CLIP_DETAILS_FPS, &dfps)) bad_header = TRUE;
2528 } else {
2529 if (!save_clip_value(mainw->current_file, CLIP_DETAILS_FPS, &cfile->fps)) bad_header = TRUE;
2530 }
2531 if (!save_clip_value(mainw->current_file, CLIP_DETAILS_PB_FPS, &cfile->fps)) bad_header = TRUE;
2532 cfile->redoable = FALSE;
2533 // force a resize in switch_to_file
2534 switch_file = 0;
2535
2536 if (bad_header) do_header_write_error(mainw->current_file);
2537 }
2538
2539 if (cfile->undo_action == UNDO_RENDER) {
2540 cfile->frames = cfile->old_frames;
2541 if (!save_clip_value(mainw->current_file, CLIP_DETAILS_FRAMES, &cfile->frames)) bad_header = TRUE;
2542 showclipimgs();
2543 if (bad_header) do_header_write_error(mainw->current_file);
2544 }
2545
2546 if (cfile->undo_action == UNDO_INSERT || cfile->undo_action == UNDO_MERGE
2547 || cfile->undo_action == UNDO_INSERT_WITH_AUDIO) {
2548 boolean ccpd_with_sound = mainw->ccpd_with_sound;
2549 if (!(cfile->undo_action == UNDO_MERGE && cfile->insert_start == cfile->undo_start && cfile->insert_end == cfile->undo_end)) {
2550 if (cfile->undo_action == UNDO_MERGE) {
2551 if (cfile->insert_start == cfile->undo_start) {
2552 cfile->insert_start = cfile->undo_end + 1;
2553 }
2554 if (cfile->insert_end == cfile->undo_end) {
2555 cfile->insert_end = cfile->undo_start - 1;
2556 }
2557 }
2558 cfile->start = cfile->insert_start;
2559 cfile->end = cfile->insert_end;
2560
2561 if (cfile->undo_action == UNDO_INSERT_WITH_AUDIO) mainw->ccpd_with_sound = TRUE;
2562 else mainw->ccpd_with_sound = FALSE;
2563 on_delete_activate(NULL, NULL);
2564
2565 cfile->start = ostart;
2566 if (ostart >= cfile->insert_start) {
2567 cfile->start -= cfile->insert_end - cfile->insert_start + 1;
2568 if (cfile->start < cfile->insert_start - 1) {
2569 cfile->start = cfile->insert_start - 1;
2570 }
2571 }
2572 cfile->end = oend;
2573 if (oend >= cfile->insert_start) {
2574 cfile->end -= cfile->insert_end - cfile->insert_start + 1;
2575 if (cfile->end < cfile->insert_start - 1) {
2576 cfile->end = cfile->insert_start - 1;
2577 }
2578 }
2579 // TODO - use lives_clip_start macro
2580 if (cfile->start < 1) cfile->start = cfile->frames > 0 ? 1 : 0;
2581 if (cfile->end < 1) cfile->end = cfile->frames > 0 ? 1 : 0;
2582
2583 cfile->insert_start = cfile->insert_end = 0;
2584 }
2585 mainw->ccpd_with_sound = ccpd_with_sound;
2586 if (!save_clip_value(mainw->current_file, CLIP_DETAILS_FRAMES, &cfile->frames)) bad_header = TRUE;
2587 showclipimgs();
2588 if (bad_header) do_header_write_error(mainw->current_file);
2589 }
2590
2591 if (cfile->undo_action == UNDO_REC_AUDIO) {
2592 mainw->fx1_val = cfile->arate;
2593 mainw->fx2_val = cfile->achans;
2594 mainw->fx3_val = cfile->asampsize;
2595 mainw->fx4_val = cfile->signed_endian;
2596 mainw->fx5_val = cfile->arps;
2597 }
2598
2599 if (cfile->undo_action == UNDO_AUDIO_RESAMPLE || cfile->undo_action == UNDO_REC_AUDIO ||
2600 cfile->undo_action == UNDO_FADE_AUDIO || cfile->undo_action == UNDO_AUDIO_VOL ||
2601 cfile->undo_action == UNDO_TRIM_AUDIO || cfile->undo_action == UNDO_APPEND_AUDIO ||
2602 (cfile->undo_action == UNDO_ATOMIC_RESAMPLE_RESIZE && cfile->arate != cfile->undo1_int)) {
2603 com = lives_strdup_printf("%s undo_audio \"%s\"", prefs->backend_sync, cfile->handle);
2605 mainw->error = FALSE;
2606 lives_system(com, FALSE);
2607 lives_free(com);
2608
2609 if (THREADVAR(com_failed)) {
2612 return;
2613 }
2614 if (!do_auto_dialog(_("Undoing"), 0)) {
2617 return;
2618 }
2619 }
2620
2621 if ((cfile->undo_action == UNDO_AUDIO_RESAMPLE) || (cfile->undo_action == UNDO_ATOMIC_RESAMPLE_RESIZE &&
2622 cfile->arate != cfile->undo1_int)) {
2623 cfile->arate += cfile->undo1_int;
2624 cfile->undo1_int = cfile->arate - cfile->undo1_int;
2625 cfile->arate -= cfile->undo1_int;
2626
2627 cfile->achans += cfile->undo2_int;
2628 cfile->undo2_int = cfile->achans - cfile->undo2_int;
2629 cfile->achans -= cfile->undo2_int;
2630
2631 cfile->asampsize += cfile->undo3_int;
2632 cfile->undo3_int = cfile->asampsize - cfile->undo3_int;
2633 cfile->asampsize -= cfile->undo3_int;
2634
2635 cfile->arps += cfile->undo4_int;
2636 cfile->undo4_int = cfile->arps - cfile->undo4_int;
2637 cfile->arps -= cfile->undo4_int;
2638
2639 cfile->signed_endian += cfile->undo1_uint;
2640 cfile->undo1_uint = cfile->signed_endian - cfile->undo1_uint;
2641 cfile->signed_endian -= cfile->undo1_uint;
2642
2643 asigned = !(cfile->signed_endian & AFORM_UNSIGNED);
2644 aendian = cfile->signed_endian & AFORM_BIG_ENDIAN;
2645
2646 if (!save_clip_value(mainw->current_file, CLIP_DETAILS_ARATE, &cfile->arps)) bad_header = TRUE;
2647 if (!save_clip_value(mainw->current_file, CLIP_DETAILS_PB_ARATE, &cfile->arate)) bad_header = TRUE;
2648 if (!save_clip_value(mainw->current_file, CLIP_DETAILS_ACHANS, &cfile->achans)) bad_header = TRUE;
2649 if (!save_clip_value(mainw->current_file, CLIP_DETAILS_ASAMPS, &cfile->asampsize)) bad_header = TRUE;
2650 if (!save_clip_value(mainw->current_file, CLIP_DETAILS_AENDIAN, &aendian)) bad_header = TRUE;
2651 if (!save_clip_value(mainw->current_file, CLIP_DETAILS_ASIGNED, &asigned)) bad_header = TRUE;
2652
2653 if (bad_header) do_header_write_error(mainw->current_file);
2654 }
2655
2656 if (cfile->undo_action == UNDO_NEW_AUDIO) {
2657 lives_rm(cfile->info_file);
2658 com = lives_strdup_printf("%s undo_audio \"%s\"", prefs->backend_sync, cfile->handle);
2659 lives_system(com, FALSE);
2660 lives_free(com);
2661
2662 if (THREADVAR(com_failed)) return;
2663
2665 mainw->error = FALSE;
2666
2667 if (!do_auto_dialog(_("Restoring audio"), 0)) {
2669 return;
2670 }
2671
2672 if (cfile->achans != cfile->undo_achans) {
2673 if (cfile->audio_waveform) {
2674 for (i = 0; i < cfile->achans; lives_freep((void **)&cfile->audio_waveform[i++]));
2675 lives_freep((void **)&cfile->audio_waveform);
2676 lives_freep((void **)&cfile->aw_sizes);
2677 }
2678 }
2679
2680 cfile->achans = cfile->undo_achans;
2681 cfile->arate = cfile->undo_arate;
2682 cfile->arps = cfile->undo_arps;
2683 cfile->asampsize = cfile->undo_asampsize;
2684 cfile->signed_endian = cfile->undo_signed_endian;
2685
2686 asigned = !(cfile->signed_endian & AFORM_UNSIGNED);
2687 aendian = cfile->signed_endian & AFORM_BIG_ENDIAN;
2688
2689 if (!save_clip_value(mainw->current_file, CLIP_DETAILS_ARATE, &cfile->arps)) bad_header = TRUE;
2690 if (!save_clip_value(mainw->current_file, CLIP_DETAILS_PB_ARATE, &cfile->arate)) bad_header = TRUE;
2691 if (!save_clip_value(mainw->current_file, CLIP_DETAILS_ACHANS, &cfile->achans)) bad_header = TRUE;
2692 if (!save_clip_value(mainw->current_file, CLIP_DETAILS_ASAMPS, &cfile->asampsize)) bad_header = TRUE;
2693 if (!save_clip_value(mainw->current_file, CLIP_DETAILS_AENDIAN, &aendian)) bad_header = TRUE;
2694 if (!save_clip_value(mainw->current_file, CLIP_DETAILS_ASIGNED, &asigned)) bad_header = TRUE;
2695
2696 if (bad_header) do_header_write_error(mainw->current_file);
2697 }
2698
2699 if (cfile->undo_action == UNDO_CHANGE_SPEED) {
2700 cfile->fps += cfile->undo1_dbl;
2701 cfile->undo1_dbl = cfile->fps - cfile->undo1_dbl;
2702 cfile->fps -= cfile->undo1_dbl;
2703
2704 cfile->arate += cfile->undo1_int;
2705 cfile->undo1_int = cfile->arate - cfile->undo1_int;
2706 cfile->arate -= cfile->undo1_int;
2708 /* save_clip_value(mainw->current_file, CLIP_DETAILS_FPS, &cfile->fps); */
2709 if (cfile->clip_type == CLIP_TYPE_FILE && cfile->ext_src) {
2710 lives_clip_data_t *cdata = ((lives_decoder_t *)cfile->ext_src)->cdata;
2711 double dfps = (double)cdata->fps;
2712 if (!save_clip_value(mainw->current_file, CLIP_DETAILS_FPS, &dfps)) bad_header = TRUE;
2713 } else {
2714 if (!save_clip_value(mainw->current_file, CLIP_DETAILS_FPS, &cfile->fps)) bad_header = TRUE;
2715 }
2716 if (!save_clip_value(mainw->current_file, CLIP_DETAILS_PB_FPS, &cfile->fps)) bad_header = TRUE;
2717 if (!save_clip_value(mainw->current_file, CLIP_DETAILS_PB_ARATE, &cfile->arate)) bad_header = TRUE;
2718
2719 if (bad_header) do_header_write_error(mainw->current_file);
2720 }
2721
2722 if (cfile->undo_action == UNDO_INSERT || cfile->undo_action == UNDO_INSERT_WITH_AUDIO || cfile->undo_action == UNDO_MERGE ||
2723 cfile->undo_action == UNDO_NEW_AUDIO) {
2724 cfile->redoable = FALSE;
2725 }
2726
2727 if (menuitem) {
2729 d_print_done();
2731 }
2732
2733 if (cfile->undo_action == UNDO_RESAMPLE) {
2734 cfile->start = (int)((cfile->start - 1) / cfile->fps * cfile->undo1_dbl + 1.);
2735 if ((cfile->end = (int)(cfile->end / cfile->fps * cfile->undo1_dbl + .49999)) < 1) cfile->end = 1;
2736 cfile->fps += cfile->undo1_dbl;
2737 cfile->undo1_dbl = cfile->fps - cfile->undo1_dbl;
2738 cfile->fps -= cfile->undo1_dbl;
2739
2740 // deorder the frames
2741 cfile->frames = deorder_frames(cfile->old_frames, mainw->current_file == 0 && !prefs->conserve_space);
2742
2743 if (!save_clip_value(mainw->current_file, CLIP_DETAILS_FRAMES, &cfile->frames)) bad_header = TRUE;
2744 if (cfile->clip_type == CLIP_TYPE_FILE && cfile->ext_src) {
2745 lives_clip_data_t *cdata = ((lives_decoder_t *)cfile->ext_src)->cdata;
2746 double dfps = (double)cdata->fps;
2747 if (!save_clip_value(mainw->current_file, CLIP_DETAILS_FPS, &dfps)) bad_header = TRUE;
2748 } else {
2749 if (!save_clip_value(mainw->current_file, CLIP_DETAILS_FPS, &cfile->fps)) bad_header = TRUE;
2750 }
2751 if (!save_clip_value(mainw->current_file, CLIP_DETAILS_PB_FPS, &cfile->fps)) bad_header = TRUE;
2752
2753 if (bad_header) do_header_write_error(mainw->current_file);
2754
2755 if (mainw->current_file > 0) {
2756 com = lives_strdup_printf(_("Length of video is now %d frames at %.3f frames per second.\n"), cfile->frames, cfile->fps);
2757 } else {
2759 com = lives_strdup_printf(_("Clipboard was resampled to %d frames.\n"), cfile->frames);
2760 }
2761 d_print(com);
2762 lives_free(com);
2764 showclipimgs();
2765 }
2766
2767 if (cfile->end > cfile->frames) {
2768 cfile->end = cfile->frames;
2769 }
2770
2771 if (cfile->undo_action == UNDO_RESIZABLE) {
2772 cfile->vsize += cfile->ovsize;
2773 cfile->ovsize = cfile->vsize - cfile->ovsize;
2774 cfile->vsize -= cfile->ovsize;
2775 cfile->hsize += cfile->ohsize;
2776 cfile->ohsize = cfile->hsize - cfile->ohsize;
2777 cfile->hsize -= cfile->ohsize;
2778 if (!save_clip_value(mainw->current_file, CLIP_DETAILS_WIDTH, &cfile->hsize)) bad_header = TRUE;
2779 if (!save_clip_value(mainw->current_file, CLIP_DETAILS_HEIGHT, &cfile->vsize)) bad_header = TRUE;
2780
2781 // force a resize in switch_to_file
2782 switch_file = 0;
2783
2784 if (bad_header) do_header_write_error(mainw->current_file);
2785 }
2786
2787 if (current_file > 0) {
2788 switch_to_file((mainw->current_file = switch_file), current_file);
2789 }
2790
2791 if (cfile->undo_action == UNDO_RENDER) {
2793 mainw->event_list = cfile->event_list_back;
2794 cfile->event_list_back = NULL;
2796 }
2798
2799 if (!mainw->multitrack) {
2802 }
2803 }
2804
2805
2806 void on_redo_activate(LiVESWidget * menuitem, livespointer user_data) {
2807 char *com;
2808
2809 int ostart = cfile->start;
2810 int oend = cfile->end;
2811 int current_file = mainw->current_file;
2812 int i;
2813
2814 mainw->osc_block = TRUE;
2815
2816 cfile->undoable = TRUE;
2817 cfile->redoable = FALSE;
2822
2823 d_print("");
2824
2825 if (menuitem) {
2827 d_print("%s...", lives_menu_item_get_text(menuitem));
2829 }
2830
2831 if (cfile->undo_action == UNDO_INSERT_SILENCE) {
2832 on_ins_silence_activate(NULL, NULL);
2835 d_print_done();
2837 sensitize();
2838 return;
2839 }
2840 if (cfile->undo_action == UNDO_CHANGE_SPEED) {
2841 on_change_speed_ok_clicked(NULL, NULL);
2843 d_print_done();
2844 return;
2845 }
2846 if (cfile->undo_action == UNDO_RESAMPLE) {
2847 on_resample_vid_ok(NULL, NULL);
2849 return;
2850 }
2851 if (cfile->undo_action == UNDO_AUDIO_RESAMPLE) {
2852 on_resaudio_ok_clicked(NULL, NULL);
2854 d_print_done();
2855 return;
2856 }
2857 if (cfile->undo_action == UNDO_CUT || cfile->undo_action == UNDO_DELETE) {
2858 cfile->start = cfile->undo_start;
2859 cfile->end = cfile->undo_end;
2861 }
2862 if (cfile->undo_action == UNDO_CUT) {
2863 on_cut_activate(NULL, NULL);
2865 }
2866 if (cfile->undo_action == UNDO_DELETE) {
2867 on_delete_activate(NULL, NULL);
2869 }
2870 if (cfile->undo_action == UNDO_DELETE_AUDIO) {
2871 on_del_audio_activate(NULL, NULL);
2873 d_print_done();
2874 return;
2875 }
2876 if (cfile->undo_action == UNDO_CUT || cfile->undo_action == UNDO_DELETE) {
2877 cfile->start = ostart;
2878 cfile->end = oend;
2879 if (mainw->current_file == current_file) {
2880 if (cfile->start >= cfile->undo_start) {
2881 cfile->start -= cfile->undo_end - cfile->undo_start + 1;
2882 if (cfile->start < cfile->undo_start - 1) {
2883 cfile->start = cfile->undo_start - 1;
2884 }
2885 }
2886 if (cfile->end >= cfile->undo_start) {
2887 cfile->end -= cfile->undo_end - cfile->undo_start + 1;
2888 if (cfile->end < cfile->undo_start - 1) {
2889 cfile->end = cfile->undo_start - 1;
2890 }
2891 }
2893 }
2895 return;
2896 }
2897
2898 if (cfile->undo_action == UNDO_REC_AUDIO) {
2899 if (cfile->audio_waveform) {
2900 for (i = 0; i < cfile->achans; lives_freep((void **)&cfile->audio_waveform[i++]));
2901 lives_freep((void **)&cfile->audio_waveform);
2902 lives_freep((void **)&cfile->aw_sizes);
2903 }
2904 cfile->arate = mainw->fx1_val;
2905 cfile->achans = mainw->fx2_val;
2906 cfile->asampsize = mainw->fx3_val;
2907 cfile->signed_endian = mainw->fx4_val;
2908 cfile->arps = mainw->fx5_val;
2910 }
2911
2912 if (cfile->undo_action == UNDO_REC_AUDIO || cfile->undo_action == UNDO_FADE_AUDIO
2913 || cfile->undo_action == UNDO_TRIM_AUDIO || cfile->undo_action == UNDO_AUDIO_VOL ||
2914 cfile->undo_action == UNDO_APPEND_AUDIO) {
2915 com = lives_strdup_printf("%s undo_audio \"%s\"", prefs->backend_sync, cfile->handle);
2916 lives_rm(cfile->info_file);
2917 lives_system(com, FALSE);
2918 lives_free(com);
2919
2920 if (THREADVAR(com_failed)) {
2923 return;
2924 }
2925
2926 // show a progress dialog, not cancellable
2927 do_progress_dialog(TRUE, FALSE, _("Redoing"));
2928
2929 if (mainw->error) {
2932 return;
2933 }
2934
2935 d_print_done();
2938 return;
2939 }
2940
2941 com = lives_strdup_printf("%s redo \"%s\" %d %d \"%s\"", prefs->backend, cfile->handle, cfile->undo_start, cfile->undo_end,
2942 get_image_ext_for_type(cfile->img_type));
2943 lives_rm(cfile->info_file);
2944 lives_system(com, FALSE);
2945 lives_free(com);
2946
2947 if (THREADVAR(com_failed)) {
2949 return;
2950 }
2951
2952 cfile->progress_start = cfile->undo_start;
2953 cfile->progress_end = cfile->undo_end;
2954
2955 // show a progress dialog, not cancellable
2956 do_progress_dialog(TRUE, FALSE, _("Redoing"));
2958
2959 if (mainw->error) {
2961 return;
2962 }
2963
2964 if (cfile->clip_type == CLIP_TYPE_FILE && (cfile->undo_action == UNDO_EFFECT || cfile->undo_action == UNDO_RESIZABLE)) {
2965 int *tmpindex = cfile->frame_index;
2966 cfile->frame_index = cfile->frame_index_back;
2967 cfile->frame_index_back = tmpindex;
2968 cfile->clip_type = CLIP_TYPE_FILE;
2970 }
2971
2972 if (cfile->undo_action == UNDO_RESIZABLE) {
2973 cfile->vsize += cfile->ovsize;
2974 cfile->ovsize = cfile->vsize - cfile->ovsize;
2975 cfile->vsize -= cfile->ovsize;
2976 cfile->hsize += cfile->ohsize;
2977 cfile->ohsize = cfile->hsize - cfile->ohsize;
2978 cfile->hsize -= cfile->ohsize;
2979 switch_to_file((mainw->current_file = 0), current_file);
2980 } else {
2981 if (cfile->end <= cfile->undo_end) load_end_image(cfile->end);
2982 if (cfile->start >= cfile->undo_start) load_start_image(cfile->start);
2983 }
2984
2985 d_print_done();
2987 }
2988
2989
2991
2992 void on_copy_activate(LiVESMenuItem * menuitem, livespointer user_data) {
2993 char *com;
2994
2995 int current_file = mainw->current_file;
2996 int start, end;
2997 int i;
2998
2999 desensitize();
3000
3001 d_print(""); // force switchtext
3002
3003 if (mainw->ccpd_with_sound && cfile->achans > 0)
3004 d_print(_("Copying frames %d to %d (with sound) to the clipboard..."), cfile->start, cfile->end);
3005 else
3006 d_print(lives_strdup_printf(_("Copying frames %d to %d to the clipboard..."), cfile->start, cfile->end));
3007
3009
3010 lives_rm(cfile->info_file);
3012
3013 start = cfile->start;
3014 end = cfile->end;
3015
3016 if (cfile->clip_type == CLIP_TYPE_FILE) {
3017 // for virtual frames, we copy only the frame_index
3018 clipboard->clip_type = CLIP_TYPE_FILE;
3019 clipboard->interlace = cfile->interlace;
3020 clipboard->deinterlace = cfile->deinterlace;
3021 clipboard->frame_index = frame_index_copy(cfile->frame_index, end - start + 1, start - 1);
3022 clipboard->frames = end - start + 1;
3023 check_if_non_virtual(0, 1, clipboard->frames);
3024 if (clipboard->clip_type == CLIP_TYPE_FILE) {
3026 clipboard->ext_src_type = LIVES_EXT_SRC_DECODER;
3027 end = -end; // allow missing frames
3028 lives_snprintf(clipboard->file_name, PATH_MAX, "%s", cfile->file_name);
3029 }
3030 }
3031
3032 mainw->fx1_val = 1;
3033 mainw->fx1_bool = FALSE;
3034
3035 clipboard->img_type = cfile->img_type;
3036
3037 // copy audio and frames
3038 com = lives_strdup_printf("%s insert \"%s\" \"%s\" 0 %d %d \"%s\" %d 0 0 0 %.3f %d %d %d %d %d", prefs->backend,
3039 clipboard->handle, get_image_ext_for_type(clipboard->img_type),
3040 start, end, cfile->handle, mainw->ccpd_with_sound, cfile->fps, cfile->arate,
3041 cfile->achans, cfile->asampsize, !(cfile->signed_endian & AFORM_UNSIGNED),
3042 !(cfile->signed_endian & AFORM_BIG_ENDIAN));
3043
3044 if (clipboard->clip_type == CLIP_TYPE_FILE) end = -end;
3045
3046 lives_system(com, FALSE);
3047 lives_free(com);
3048
3049 if (THREADVAR(com_failed)) {
3051 sensitize();
3052 return;
3053 }
3054
3055 // we need to set this to look at the right info_file
3056 mainw->current_file = 0;
3057 cfile->progress_start = clipboard->start = 1;
3058 cfile->progress_end = clipboard->end = end - start + 1;
3059
3060 // stop the 'preview' and 'pause' buttons from appearing
3061 cfile->nopreview = TRUE;
3062 if (!do_progress_dialog(TRUE, TRUE, _("Copying to the clipboard"))) {
3063#ifdef IS_MINGW
3064 // kill any active processes: for other OSes the backend does this
3066#endif
3067
3068 // close clipboard, it is invalid
3070 close_temp_handle(current_file);
3071
3072 sensitize();
3074 return;
3075 }
3076
3077 cfile->nopreview = FALSE;
3078 mainw->current_file = current_file;
3079
3080 //set all clipboard details
3081 clipboard->frames = clipboard->old_frames = clipboard->end;
3082 clipboard->hsize = cfile->hsize;
3083 clipboard->vsize = cfile->vsize;
3084 clipboard->bpp = cfile->bpp;
3085 clipboard->gamma_type = cfile->gamma_type;
3086 clipboard->undo1_dbl = clipboard->fps = cfile->fps;
3087 clipboard->ratio_fps = cfile->ratio_fps;
3088 clipboard->is_loaded = TRUE;
3089 lives_snprintf(clipboard->type, 40, "Frames");
3090
3091 clipboard->asampsize = clipboard->arate = clipboard->achans = 0;
3092 clipboard->afilesize = 0l;
3093
3094 if (mainw->ccpd_with_sound) {
3095 if (clipboard->audio_waveform) {
3096 for (i = 0; i < clipboard->achans; lives_freep((void **)&clipboard->audio_waveform[i++]));
3097 lives_freep((void **)&clipboard->audio_waveform);
3098 lives_freep((void **)&clipboard->aw_sizes);
3099 }
3100 clipboard->achans = cfile->achans;
3101 clipboard->asampsize = cfile->asampsize;
3102
3103 clipboard->arate = cfile->arate;
3104 clipboard->arps = cfile->arps;
3105 clipboard->signed_endian = cfile->signed_endian;
3106
3107 reget_afilesize(0);
3108 }
3109
3110 clipboard->start = 1;
3111 clipboard->end = clipboard->frames;
3112
3114
3115 sensitize();
3116 d_print_done();
3117 }
3118
3119
3120 void on_cut_activate(LiVESMenuItem * menuitem, livespointer user_data) {
3121 uint32_t chk_mask = 0;
3122 int current_file = mainw->current_file;
3123
3124 if (menuitem) {
3125 char *tmp = (_("Cutting"));
3129 if (!check_for_layout_errors(tmp, mainw->current_file, cfile->start, cfile->end, &chk_mask)) {
3130 lives_free(tmp);
3131 return;
3132 }
3133 lives_free(tmp);
3134 }
3135
3136 on_copy_activate(menuitem, user_data);
3137 if (mainw->cancelled) {
3139 return;
3140 }
3141
3142 on_delete_activate(NULL, user_data);
3143 if (mainw->current_file == current_file) {
3144 set_undoable(_("Cut"), TRUE);
3145 cfile->undo_action = UNDO_CUT;
3146 }
3147
3148 if (chk_mask != 0) popup_lmap_errors(NULL, LIVES_INT_TO_POINTER(chk_mask));
3149 }
3150
3151
3152 void on_paste_as_new_activate(LiVESMenuItem * menuitem, livespointer user_data) {
3153#define VIRT_PASTE
3154#ifndef VIRT_PASTE
3155 char *msg;
3156#endif
3157 char *com;
3158 int old_file = mainw->current_file;
3159 frames_t cbframes, lframe;
3160
3161 if (!clipboard) return;
3162
3164
3165 if (!get_new_handle(mainw->current_file, NULL)) {
3166 mainw->current_file = old_file;
3167 return;
3168 }
3169
3170 lframe = cbframes = clipboard->frames;
3171
3172 //set file details
3173 cfile->hsize = clipboard->hsize;
3174 cfile->vsize = clipboard->vsize;
3175 cfile->pb_fps = cfile->fps = clipboard->fps;
3176 cfile->ratio_fps = clipboard->ratio_fps;
3177 cfile->changed = TRUE;
3178 cfile->is_loaded = TRUE;
3179 cfile->img_type = clipboard->img_type;
3180 cfile->gamma_type = clipboard->gamma_type;
3181
3183
3184#ifndef VIRT_PASTE
3185 msg = (_("Pulling frames from clipboard..."));
3186
3187 if ((lframe = realize_all_frames(0, msg, TRUE)) < cbframes) {
3188 if (!paste_enough_dlg(lframe - 1)) {
3189 lives_free(msg);
3190 close_current_file(old_file);
3191 sensitize();
3192 return;
3193 }
3194 lframe--;
3195 }
3196 lives_free(msg);
3197#else
3199 lframe = -lframe;
3200#endif
3201
3202 cfile->progress_start = cfile->start = cbframes > 0 ? 1 : 0;
3203 cfile->progress_end = cfile->end = cfile->frames = cbframes;
3204
3206 d_print(_("Pasting %d frames to new clip %s..."), lframe, cfile->name);
3208
3209 if (clipboard->achans > 0 && clipboard->arate > 0) {
3210 com = lives_strdup_printf("%s insert \"%s\" \"%s\" 0 1 %d \"%s\" %d 0 0 0 %.3f %d %d %d %d %d",
3211 prefs->backend, cfile->handle,
3212 get_image_ext_for_type(cfile->img_type), lframe, clipboard->handle,
3213 mainw->ccpd_with_sound, clipboard->fps, clipboard->arate, clipboard->achans,
3214 clipboard->asampsize, !(cfile->signed_endian & AFORM_UNSIGNED),
3215 !(cfile->signed_endian & AFORM_BIG_ENDIAN));
3216 } else {
3217 com = lives_strdup_printf("%s insert \"%s\" \"%s\" 0 1 %d \"%s\" %d 0 0 0 %.3f 0 0 0 0 0",
3218 prefs->backend, cfile->handle,
3219 get_image_ext_for_type(cfile->img_type), lframe, clipboard->handle,
3220 FALSE, clipboard->fps);
3221
3222 if (clipboard->achans > 0 && clipboard->arate < 0) {
3223 int zero = 0;
3224 double chvols = 1.;
3225 double avels = -1.;
3226 double aseeks = (double)clipboard->afilesize / (double)(-clipboard->arate * clipboard->asampsize / 8 * clipboard->achans);
3227 ticks_t tc = (ticks_t)(aseeks * TICKS_PER_SECOND_DBL);
3228 cfile->arate = clipboard->arate = -clipboard->arate;
3229 cfile->arps = clipboard->arps;
3230 cfile->achans = clipboard->achans;
3231 cfile->asampsize = clipboard->asampsize;
3232 cfile->afilesize = clipboard->afilesize;
3233 cfile->signed_endian = clipboard->signed_endian;
3234 render_audio_segment(1, &zero, mainw->current_file, &avels, &aseeks, 0, tc, &chvols, 1., 1., NULL);
3235 }
3236 }
3237
3238 lives_system(com, FALSE);
3239 lives_free(com);
3240
3241 if (THREADVAR(com_failed)) {
3243 close_current_file(old_file);
3244 return;
3245 }
3246
3247 cfile->nopreview = TRUE;
3248
3250
3251 // show a progress dialog, not cancellable
3252 if (!do_progress_dialog(TRUE, TRUE, _("Pasting"))) {
3253 mainw->disk_mon = 0;
3254 if (mainw->error) d_print_failed();
3255 close_current_file(old_file);
3256 return;
3257 }
3258 cfile->nopreview = FALSE;
3259 mainw->disk_mon = 0;
3260
3261 if (mainw->ccpd_with_sound) {
3262 if (cfile->audio_waveform) {
3263 for (int i = 0; i < cfile->achans; lives_freep((void **)&cfile->audio_waveform[i++]));
3264 lives_freep((void **)&cfile->audio_waveform);
3265 lives_freep((void **)&cfile->aw_sizes);
3266 }
3267 cfile->arate = clipboard->arate;
3268 cfile->arps = clipboard->arps;
3269 cfile->achans = clipboard->achans;
3270 cfile->asampsize = clipboard->asampsize;
3271 cfile->afilesize = clipboard->afilesize;
3272 cfile->signed_endian = clipboard->signed_endian;
3273 if (cfile->afilesize > 0) d_print(_("...added audio..."));
3274 }
3275
3276#ifdef VIRT_PASTE
3277 if (clipboard->frame_index) {
3278 cfile->frame_index = frame_index_copy(clipboard->frame_index, cbframes, 0);
3279 }
3280
3281 cfile->clip_type = clipboard->clip_type;
3282
3283 if (cfile->clip_type == CLIP_TYPE_FILE) {
3285 lives_snprintf(cfile->file_name, PATH_MAX, "%s", clipboard->file_name);
3286 }
3287#endif
3288
3289 if (cfile->frame_index) save_frame_index(mainw->current_file);
3290
3291 // add entry to window menu
3294 close_current_file(old_file);
3295 return;
3296 }
3297
3299
3301 d_print_done();
3302
3303 mainw->last_dprint_file = old_file;
3304 d_print(""); // force switchtext
3305
3308 }
3309
3310
3311 void on_insert_pre_activate(LiVESMenuItem * menuitem, livespointer user_data) {
3313
3315 mainw->fx1_bool = FALSE;
3316 mainw->fx1_val = 1;
3317
3319 }
3320
3321
3322 void on_insert_activate(LiVESButton * button, livespointer user_data) {
3323 double times_to_insert;
3324 double audio_stretch;
3325
3326 char *com;
3327
3328 boolean with_sound = mainw->fx2_bool;
3329 boolean bad_header = FALSE;
3330 boolean insert_silence = FALSE;
3331
3332 // have we resampled ?
3333 boolean cb_audio_change = FALSE;
3334 boolean cb_video_change = FALSE;
3335
3336 boolean virtual_ins = FALSE;
3337 boolean all_virtual = FALSE;
3338
3339 uint32_t chk_mask = 0;
3340
3341 int where = cfile->start - 1;
3342 int start = cfile->start, ostart = start;
3343 int end = cfile->end, oend = end;
3344
3345 int hsize = cfile->hsize;
3346 int vsize = cfile->vsize;
3347
3348 int cfile_signed = 0, cfile_endian = 0, clipboard_signed = 0, clipboard_endian = 0;
3349 int current_file = mainw->current_file;
3350
3351 int orig_frames = cfile->frames;
3352 int ocarps = clipboard->arps;
3353 int leave_backup = 1;
3354 int remainder_frames;
3355 int insert_start;
3356 int cb_start = 1, cb_end = clipboard->frames;
3357 int i;
3358
3359 // if it is an insert into the original file, and we can do fast seek, we can insert virtual frames
3360 if (button && mainw->current_file == clipboard->cb_src && !check_if_non_virtual(0, 1, clipboard->frames)) {
3361 lives_clip_data_t *cdata = ((lives_decoder_t *)cfile->ext_src)->cdata;
3362 if (cdata->seek_flag & LIVES_SEEK_FAST) {
3363 virtual_ins = TRUE;
3364 if (count_virtual_frames(clipboard->frame_index, 1, clipboard->frames) == clipboard->frames) all_virtual = TRUE;
3365 }
3366 }
3367
3368 // don't ask smogrify to resize if frames are the same size and type
3369 if (all_virtual || (((cfile->hsize == clipboard->hsize && cfile->vsize == clipboard->vsize) || orig_frames == 0) &&
3370 (cfile->img_type == clipboard->img_type))) hsize = vsize = 0;
3371 else {
3372 if (!capable->has_convert) {
3375 _("This operation requires resizing or converting of frames.\n"
3376 "Please install 'convert' from the Image-magick package, and then restart LiVES.\n"));
3378 mainw->error = TRUE;
3379 if (button) {
3382 }
3383 return;
3384 }
3385 }
3386
3387 if (button) {
3390 // call to update fx1_val, in case activates_default was called from spin entry
3392 }
3393
3394 times_to_insert = mainw->fx1_val;
3395
3396 // fit video to audio if requested
3397 if (mainw->fx1_bool && (cfile->asampsize * cfile->arate * cfile->achans != 0)) {
3398 // "insert to fit audio" : number of inserts is (audio_time - sel_end_time) / clipboard_time
3399 times_to_insert = (cfile->laudio_time - (cfile->frames > 0 ? (double)cfile->end / cfile->fps : 0.)) / ((
3400 double)clipboard->frames / clipboard->fps);
3401 }
3402
3403 if (times_to_insert < 0. && (mainw->fx1_bool)) {
3406 _("\n\nVideo is longer than audio.\nTry selecting all frames, and then using \n"
3407 "the 'Trim Audio' function from the Audio menu."));
3408 mainw->error = TRUE;
3410 return;
3411 }
3412
3413 if (with_sound) {
3414 cfile_signed = !(cfile->signed_endian & AFORM_UNSIGNED);
3415 cfile_endian = !(cfile->signed_endian & AFORM_BIG_ENDIAN);
3416
3417 clipboard_signed = !(clipboard->signed_endian & AFORM_UNSIGNED);
3418 clipboard_endian = !(clipboard->signed_endian & AFORM_BIG_ENDIAN);
3419
3420 if ((cfile->achans * cfile->arps * cfile->asampsize > 0) && (cfile->achans != clipboard->achans ||
3421 (cfile->arps != clipboard->arps && clipboard->achans > 0) ||
3422 cfile->asampsize != clipboard->asampsize ||
3423 cfile_signed != clipboard_signed || cfile_endian != clipboard_endian ||
3424 cfile->arate != clipboard->arate)) {
3425 if (!(capable->has_sox_sox)) {
3426 if (cfile->arps != clipboard->arps) {
3428 do_error_dialog(_("LiVES cannot insert because the audio rates do not match.\n"
3429 "Please install 'sox', and try again."));
3430 mainw->error = TRUE;
3432 return;
3433 // *INDENT-OFF*
3434 }}}}
3435 // *INDENT-ON*
3436
3437 if (mainw->insert_after) insert_start = cfile->end + 1;
3438 else insert_start = cfile->start;
3439
3440 if (button) {
3441 char *tmp = (_("Insertion"));
3443 if (with_sound) chk_mask |= WARN_MASK_LAYOUT_SHIFT_AUDIO | WARN_MASK_LAYOUT_ALTER_AUDIO;
3444 if (!check_for_layout_errors(tmp, mainw->current_file, insert_start, 0, &chk_mask)) {
3445 lives_free(tmp);
3446 return;
3447 }
3448 lives_free(tmp);
3449 }
3450
3451 if (button) {
3452 if ((cfile->fps != clipboard->fps && orig_frames > 0) || (cfile->arps != clipboard->arps && clipboard->achans > 0 &&
3453 with_sound)) {
3454 if (!do_clipboard_fps_warning()) {
3456 mainw->error = TRUE;
3457 return;
3458 }
3459 }
3460 if (prefs->ins_resample && clipboard->fps != cfile->fps && orig_frames != 0) {
3461 cb_end = count_resampled_frames(clipboard->frames, clipboard->fps, cfile->fps);
3462 }
3463 } else {
3464 // called from on_merge_activate()
3465 cb_start = mainw->fx1_start;
3466 cb_end = mainw->fx2_start;
3467
3468 // we will use leave_backup as this will leave our
3469 // merge backup in place
3470 leave_backup = -1;
3471 }
3472
3473 cfile->insert_start = insert_start;
3474 cfile->insert_end = cfile->insert_start - 1;
3475
3476 if (mainw->insert_after) where = cfile->end;
3477
3478 // at least we should try to convert the audio to match...
3479 // if with_sound is TRUE, and clipboard has no audio, we will insert silence (unless target
3480 // also has no audio
3481 if (with_sound) {
3482 if (clipboard->achans == 0) {
3483 if (cfile->achans > 0) insert_silence = TRUE;
3484 with_sound = FALSE;
3485 } else {
3486 if ((cfile->achans * cfile->arps * cfile->asampsize > 0)
3487 && clipboard->achans > 0 && (cfile->achans != clipboard->achans ||
3488 cfile->arps != clipboard->arps || clipboard->vol != 1. || cfile->vol != 1. ||
3489 cfile->asampsize != clipboard->asampsize ||
3490 cfile_signed != clipboard_signed ||
3491 cfile_endian != clipboard_endian || cfile->arate != clipboard->arate)) {
3492
3493 cb_audio_change = TRUE;
3494
3495 if (clipboard->arps != clipboard->arps || cfile->arate != clipboard->arate) {
3496 // pb rate != real rate - stretch to pb rate and resample
3497 if ((audio_stretch = (double)clipboard->arps / (double)clipboard->arate *
3498 (double)cfile->arate / (double)cfile->arps) != 1.) {
3499 if (audio_stretch < 0.) {
3500 // clipboard audio should be reversed
3501 // we will create a temp handle, copy the audio, and then render it back reversed
3502 if (!get_temp_handle(-1)) {
3504 return;
3505 } else {
3507 char *fnamefrom = lives_get_audio_file_name(0);
3508 int zero = 0;
3509 float volx = 1.;
3510 double chvols = 1.;
3511 double avels = -1.;
3512 double aseeks = (double)clipboard->afilesize / (double)(-clipboard->arate
3513 * clipboard->asampsize / 8 * clipboard->achans);
3514 ticks_t tc = (ticks_t)(aseeks * TICKS_PER_SECOND_DBL);
3515 if (cfile->vol > 0.001) volx = clipboard->vol / cfile->vol;
3516 render_audio_segment(1, &zero, mainw->current_file, &avels, &aseeks, 0, tc, &chvols, volx, volx, NULL);
3517 reget_afilesize(0);
3519 if (cfile->afilesize == clipboard->afilesize) {
3520 lives_mv(fnameto, fnamefrom);
3521 }
3522 close_temp_handle(current_file);
3523 clipboard->arate = -clipboard->arate;
3524 lives_free(fnamefrom);
3525 lives_free(fnameto);
3526 }
3527 } else {
3528 lives_rm(clipboard->info_file);
3529 com = lives_strdup_printf("%s resample_audio \"%s\" %d %d %d %d %d %d %d %d %d %d %.4f",
3530 prefs->backend,
3531 clipboard->handle, clipboard->arps, clipboard->achans, clipboard->asampsize,
3532 clipboard_signed, clipboard_endian, cfile->arps, clipboard->achans,
3533 clipboard->asampsize, clipboard_signed, clipboard_endian, audio_stretch);
3534 lives_system(com, FALSE);
3535 lives_free(com);
3536
3537 if (THREADVAR(com_failed)) {
3539 return;
3540 }
3541
3542 mainw->current_file = 0;
3543 mainw->error = FALSE;
3544 do_progress_dialog(TRUE, FALSE, _("Resampling clipboard audio"));
3545 mainw->current_file = current_file;
3546 if (mainw->error) {
3549 return;
3550 }
3551
3552 // not really, but we pretend...
3553 clipboard->arps = cfile->arps;
3554 }
3555 }
3556 }
3557
3558 if (clipboard->achans > 0 && (cfile->achans != clipboard->achans || cfile->arps != clipboard->arps ||
3559 cfile->asampsize != clipboard->asampsize || cfile_signed != clipboard_signed ||
3560 cfile_endian != clipboard_endian)) {
3561 lives_rm(clipboard->info_file);
3562 com = lives_strdup_printf("%s resample_audio \"%s\" %d %d %d %d %d %d %d %d %d %d",
3563 prefs->backend, clipboard->handle,
3564 clipboard->arps, clipboard->achans, clipboard->asampsize, clipboard_signed,
3565 clipboard_endian, cfile->arps, cfile->achans, cfile->asampsize, cfile_signed, cfile_endian);
3566 lives_system(com, FALSE);
3567 lives_free(com);
3568
3569 if (THREADVAR(com_failed)) {
3571 return;
3572 }
3573
3574 mainw->current_file = 0;
3575 do_progress_dialog(TRUE, FALSE, _("Resampling clipboard audio"));
3576 mainw->current_file = current_file;
3577
3578 if (mainw->error) {
3581 return;
3582 }
3583 }
3584
3585 if (clipboard->achans > 0 && clipboard->afilesize == 0l) {
3586 if (prefs->conserve_space) {
3587 // oops...
3588 if (clipboard->audio_waveform) {
3589 for (i = 0; i < clipboard->achans; lives_freep((void **)&clipboard->audio_waveform[i++]));
3590 lives_freep((void **)&clipboard->audio_waveform);
3591 lives_freep((void **)&clipboard->aw_sizes);
3592 }
3593 clipboard->achans = clipboard->arate = clipboard->asampsize = 0;
3594 with_sound = FALSE;
3597 (_("\n\nLiVES was unable to resample the clipboard audio. \nClipboard audio has been erased.\n"));
3599 } else {
3600 lives_rm(clipboard->info_file);
3601 mainw->current_file = 0;
3602 com = lives_strdup_printf("%s undo_audio \"%s\"", prefs->backend_sync, clipboard->handle);
3603 lives_system(com, FALSE);
3604 lives_free(com);
3605 mainw->current_file = current_file;
3606
3607 clipboard->arps = ocarps;
3608 reget_afilesize(0);
3609
3610 if (!do_yesno_dialog
3611 (_("\n\nLiVES was unable to resample the clipboard audio.\n"
3612 "Do you wish to continue with the insert \nusing unchanged audio ?\n"))) {
3613 mainw->error = TRUE;
3615 return;
3616 // *INDENT-OFF*
3617 }}}}}}
3618 // *INDENT-ON*
3619
3620 if (!virtual_ins) {
3621 char *msg = (_("Pulling frames from clipboard..."));
3622 if (realize_all_frames(0, msg, FALSE) <= 0) {
3623 lives_free(msg);
3624 sensitize();
3626 return;
3627 }
3628 lives_free(msg);
3629 }
3630
3631 d_print(""); // force switchtext
3632
3633 // if pref is set, resample clipboard video
3634 if (prefs->ins_resample && cfile->fps != clipboard->fps && orig_frames > 0) {
3635 if (!resample_clipboard(cfile->fps)) {
3637 return;
3638 }
3639 cb_video_change = TRUE;
3640 }
3641
3642 if (mainw->fx1_bool && (cfile->asampsize * cfile->arate * cfile->achans != 0)) {
3643 // in theory this should not change after resampling, but we will recalculate anyway
3644
3645 // "insert to fit audio" : number of inserts is (audio_time - video_time) / clipboard_time
3646 times_to_insert = (cfile->laudio_time - cfile->frames > 0 ? (double)cfile->frames / cfile->fps : 0.) / ((
3647 double)clipboard->frames / clipboard->fps);
3648 }
3649
3650 switch_clip(1, current_file, TRUE);
3651
3652 if (cb_end > clipboard->frames) {
3653 cb_end = clipboard->frames;
3654 }
3655
3656 if (with_sound && cfile->achans == 0) {
3657 int asigned = !(clipboard->signed_endian & AFORM_UNSIGNED);
3658 int endian = clipboard->signed_endian & AFORM_BIG_ENDIAN;
3659
3660 cfile->achans = clipboard->achans;
3661 cfile->asampsize = clipboard->asampsize;
3662 cfile->arps = cfile->arate = clipboard->arate;
3663 cfile->signed_endian = clipboard->signed_endian;
3664
3665 if (!save_clip_value(mainw->current_file, CLIP_DETAILS_ARATE, &cfile->arps)) bad_header = TRUE;
3666 if (!save_clip_value(mainw->current_file, CLIP_DETAILS_PB_ARATE, &cfile->arate)) bad_header = TRUE;
3667 if (!save_clip_value(mainw->current_file, CLIP_DETAILS_ACHANS, &cfile->achans)) bad_header = TRUE;
3668 if (!save_clip_value(mainw->current_file, CLIP_DETAILS_ASIGNED, &asigned)) bad_header = TRUE;
3669 if (!save_clip_value(mainw->current_file, CLIP_DETAILS_AENDIAN, &endian)) bad_header = TRUE;
3670 if (!save_clip_value(mainw->current_file, CLIP_DETAILS_ASAMPS, &cfile->asampsize)) bad_header = TRUE;
3671
3672 if (bad_header) do_header_write_error(mainw->current_file);
3673 }
3674
3675 // first remainder frames
3676 remainder_frames = (int)(times_to_insert - (double)(int)times_to_insert) * clipboard->frames;
3677
3678 end = clipboard->frames;
3679 if (virtual_ins) end = -end;
3680
3681 if (!mainw->insert_after && remainder_frames > 0) {
3682 d_print(_("Inserting %d%s frames from the clipboard..."), remainder_frames,
3683 times_to_insert > 1. ? " remainder" : "");
3684
3685 com = lives_strdup_printf("%s insert \"%s\" \"%s\" %d %d %d \"%s\" %d %d %d %d %.3f %d %d %d %d %d",
3686 prefs->backend, cfile->handle,
3687 get_image_ext_for_type(cfile->img_type), where, clipboard->frames - remainder_frames + 1,
3688 end, clipboard->handle, with_sound, cfile->frames, hsize, vsize, cfile->fps,
3689 cfile->arate, cfile->achans, cfile->asampsize, !(cfile->signed_endian & AFORM_UNSIGNED),
3690 !(cfile->signed_endian & AFORM_BIG_ENDIAN));
3691
3692 lives_rm(cfile->info_file);
3693 lives_system(com, FALSE);
3694 lives_free(com);
3695
3696 if (THREADVAR(com_failed)) {
3699 return;
3700 }
3701
3702 cfile->progress_start = 1;
3703 cfile->progress_end = remainder_frames;
3704
3706 do_progress_dialog(TRUE, FALSE, _("Inserting"));
3707 mainw->disk_mon = 0;
3708
3709 if (mainw->error) {
3713 return;
3714 }
3715
3716 if (cfile->clip_type == CLIP_TYPE_FILE || virtual_ins) {
3717 insert_images_in_virtual(mainw->current_file, where, remainder_frames, clipboard->frame_index,
3718 clipboard->frames - remainder_frames + 1);
3719 }
3720
3721 cfile->frames += remainder_frames;
3722 where += remainder_frames;
3723
3724 cfile->insert_end += remainder_frames;
3725
3726 if (!mainw->insert_after) {
3727 cfile->start += remainder_frames;
3728 cfile->end += remainder_frames;
3729 }
3730
3731 if (with_sound) {
3733 } else get_play_times();
3734 d_print_done();
3735 }
3736
3737 // inserts of whole clipboard
3738 if ((int)times_to_insert > 1) {
3739 d_print("");
3740 d_print(_("Inserting %d times from the clipboard%s..."), (int)times_to_insert, with_sound ?
3741 " (with sound)" : "");
3742 } else if ((int)times_to_insert > 0) {
3743 d_print("");
3744 d_print(_("Inserting %d frames from the clipboard%s..."), cb_end - cb_start + 1, with_sound ?
3745 " (with sound)" : "");
3746 }
3747
3748 if (virtual_ins) cb_end = -cb_end;
3749
3750 // for an insert after a merge we set our start posn. -ve
3751 // this should indicate to the back end to leave our
3752 // backup frames alone
3753
3754 com = lives_strdup_printf("%s insert \"%s\" \"%s\" %d %d %d \"%s\" %d %d %d %d %.3f %d %d %d %d %d %d",
3755 prefs->backend, cfile->handle,
3756 get_image_ext_for_type(cfile->img_type), where, cb_start * leave_backup, cb_end,
3757 clipboard->handle, with_sound, cfile->frames, hsize, vsize, cfile->fps, cfile->arate,
3758 cfile->achans, cfile->asampsize, !(cfile->signed_endian & AFORM_UNSIGNED),
3759 !(cfile->signed_endian & AFORM_BIG_ENDIAN), (int)times_to_insert);
3760
3761 if (virtual_ins) cb_end = -cb_end;
3762
3763 cfile->progress_start = 1;
3764 cfile->progress_end = (cb_end - cb_start + 1) * (int)times_to_insert + cfile->frames - where;
3765 lives_rm(cfile->info_file);
3766 lives_system(com, FALSE);
3767 lives_free(com);
3768
3769 if (THREADVAR(com_failed)) {
3772 return;
3773 }
3774
3775 // show a progress dialog
3776 cfile->nopreview = TRUE;
3778 if (!do_progress_dialog(TRUE, TRUE, _("Inserting"))) {
3779 // cancelled
3780 cfile->nopreview = FALSE;
3781 mainw->disk_mon = 0;
3782
3783 if (mainw->error) {
3786 return;
3787 }
3788
3789 // clean up moved/inserted frames
3790 com = lives_strdup_printf("%s undo_insert \"%s\" %d %d %d \"%s\"",
3791 prefs->backend, cfile->handle, where + 1,
3792 where + (cb_end - cb_start + 1) * (int)times_to_insert, cfile->frames,
3793 get_image_ext_for_type(cfile->img_type));
3794 lives_system(com, FALSE);
3795 lives_free(com);
3796
3797 do_progress_dialog(TRUE, FALSE, _("Cancelling"));
3798
3799 cfile->start = ostart;
3800 cfile->end = oend;
3801
3802 if (with_sound) {
3803 // desample clipboard audio
3804 if (cb_audio_change && !prefs->conserve_space) {
3805 lives_rm(clipboard->info_file);
3806 com = lives_strdup_printf("%s undo_audio \"%s\"", prefs->backend_sync, clipboard->handle);
3807 mainw->current_file = 0;
3808 lives_system(com, FALSE);
3809 lives_free(com);
3810 mainw->current_file = current_file;
3811 clipboard->arps = ocarps;
3812 reget_afilesize(0);
3813 }
3814 }
3815
3816 if (cb_video_change) {
3817 // desample clipboard video
3818 mainw->current_file = 0;
3820 on_undo_activate(NULL, NULL);
3822 mainw->current_file = current_file;
3823 }
3824
3825 switch_clip(1, current_file, TRUE);
3826 set_undoable(NULL, FALSE);
3829 return;
3830 }
3831 mainw->disk_mon = 0;
3832
3834 cfile->nopreview = FALSE;
3835
3836 if (cfile->clip_type == CLIP_TYPE_FILE || virtual_ins) {
3837 insert_images_in_virtual(mainw->current_file, where, (cb_end - cb_start + 1) * (int)times_to_insert, clipboard->frame_index,
3838 cb_start * leave_backup);
3839 }
3840
3841 cfile->frames += (cb_end - cb_start + 1) * (int)times_to_insert;
3842 where += (cb_end - cb_start + 1) * (int)times_to_insert;
3843 cfile->insert_end += (cb_end - cb_start + 1) * (int)times_to_insert;
3844
3845 if (!mainw->insert_after) {
3846 cfile->start += (cb_end - cb_start + 1) * (int)times_to_insert;
3847 cfile->end += (cb_end - cb_start + 1) * (int)times_to_insert;
3848 }
3849
3850 if (with_sound == 1) {
3852 } else get_play_times();
3853 d_print_done();
3854
3855 // last remainder frames
3856
3857 if (mainw->insert_after && remainder_frames > 0) {
3858 d_print(_("Inserting %d%s frames from the clipboard..."), remainder_frames,
3859 times_to_insert > 1. ? " remainder" : "");
3860
3861 if (virtual_ins) remainder_frames = -remainder_frames;
3862
3863 com = lives_strdup_printf("%s insert \"%s\" \"%s\" %d %d %d \"%s\" %d %d %d %d %3f %d %d %d %d %d",
3864 prefs->backend, cfile->handle,
3865 get_image_ext_for_type(cfile->img_type), where, 1, remainder_frames, clipboard->handle,
3866 with_sound, cfile->frames, hsize, vsize, cfile->fps, cfile->arate, cfile->achans,
3867 cfile->asampsize, !(cfile->signed_endian & AFORM_UNSIGNED),
3868 !(cfile->signed_endian & AFORM_BIG_ENDIAN));
3869
3870 lives_rm(cfile->info_file);
3871 lives_system(com, FALSE);
3872
3873 if (THREADVAR(com_failed)) {
3876 return;
3877 }
3878
3879 if (virtual_ins) remainder_frames = -remainder_frames;
3880
3881 cfile->progress_start = 1;
3882 cfile->progress_end = remainder_frames;
3883
3885 do_progress_dialog(TRUE, FALSE, _("Inserting"));
3886 mainw->disk_mon = 0;
3887
3888 if (mainw->error) {
3891 return;
3892 }
3893
3894 if (cfile->clip_type == CLIP_TYPE_FILE || virtual_ins) {
3895 insert_images_in_virtual(mainw->current_file, where, remainder_frames, clipboard->frame_index, 1);
3896 }
3897
3898 cfile->frames += remainder_frames;
3899 cfile->insert_end += remainder_frames;
3900 lives_free(com);
3901
3902 if (!mainw->insert_after) {
3903 cfile->start += remainder_frames;
3904 cfile->end += remainder_frames;
3905 }
3907
3908 d_print_done();
3909 }
3910
3911 // if we had deferred audio, we insert silence in selection
3912 if (insert_silence) {
3913 cfile->undo1_dbl = calc_time_from_frame(mainw->current_file, cfile->insert_start);
3914 cfile->undo2_dbl = calc_time_from_frame(mainw->current_file, cfile->insert_end + 1);
3915 cfile->undo_arate = cfile->arate;
3916 cfile->undo_signed_endian = cfile->signed_endian;
3917 cfile->undo_achans = cfile->achans;
3918 cfile->undo_asampsize = cfile->asampsize;
3919 cfile->undo_arps = cfile->arps;
3920
3921 on_ins_silence_activate(NULL, NULL);
3922
3923 with_sound = TRUE;
3924 }
3925
3926 // insert done
3927
3928 // start or end can be zero if we inserted into pure audio
3929 if (cfile->start == 0 && cfile->frames > 0) cfile->start = 1;
3930 if (cfile->end == 0) cfile->end = cfile->frames;
3931
3932 if (cfile->frames > 0 && orig_frames == 0) {
3933 lives_snprintf(cfile->type, 40, "Frames");
3934 cfile->orig_file_name = FALSE;
3935 cfile->hsize = clipboard->hsize;
3936 cfile->vsize = clipboard->vsize;
3937 cfile->bpp = clipboard->bpp;
3938 cfile->fps = cfile->pb_fps = clipboard->fps;
3939 if (!save_clip_value(mainw->current_file, CLIP_DETAILS_WIDTH, &cfile->hsize)) bad_header = TRUE;
3940 if (!save_clip_value(mainw->current_file, CLIP_DETAILS_HEIGHT, &cfile->vsize)) bad_header = TRUE;
3941 if (!save_clip_value(mainw->current_file, CLIP_DETAILS_BPP, &cfile->bpp)) bad_header = TRUE;
3942 if (cfile->clip_type == CLIP_TYPE_FILE && cfile->ext_src) {
3943 lives_clip_data_t *cdata = ((lives_decoder_t *)cfile->ext_src)->cdata;
3944 double dfps = (double)cdata->fps;
3945 if (!save_clip_value(mainw->current_file, CLIP_DETAILS_FPS, &dfps)) bad_header = TRUE;
3946 } else {
3947 if (!save_clip_value(mainw->current_file, CLIP_DETAILS_FPS, &cfile->fps)) bad_header = TRUE;
3948 }
3949 if (!save_clip_value(mainw->current_file, CLIP_DETAILS_PB_FPS, &cfile->fps)) bad_header = TRUE;
3950
3951 if (bad_header) do_header_write_error(mainw->current_file);
3952 }
3953
3955 lives_spin_button_set_range(LIVES_SPIN_BUTTON(mainw->spinbutton_end), cfile->frames == 0 ? 0 : 1, cfile->frames);
3956 lives_spin_button_set_value(LIVES_SPIN_BUTTON(mainw->spinbutton_end), cfile->end);
3958
3960 lives_spin_button_set_range(LIVES_SPIN_BUTTON(mainw->spinbutton_start), cfile->frames == 0 ? 0 : 1, cfile->frames);
3961 lives_spin_button_set_value(LIVES_SPIN_BUTTON(mainw->spinbutton_start), cfile->start);
3963
3964 set_undoable(_("Insert"), TRUE);
3965 cfile->undo1_boolean = with_sound;
3967
3968 // mark new file size as 'Unknown'
3969 cfile->f_size = 0l;
3970 cfile->changed = TRUE;
3971
3972 if (with_sound) {
3973 cfile->undo_action = UNDO_INSERT_WITH_AUDIO;
3974 if (cb_audio_change && !prefs->conserve_space && clipboard->achans > 0) {
3975 lives_rm(clipboard->info_file);
3976 mainw->current_file = 0;
3977 com = lives_strdup_printf("%s undo_audio \"%s\"", prefs->backend_sync, clipboard->handle);
3978 lives_system(com, FALSE);
3979 lives_free(com);
3980 mainw->current_file = current_file;
3981 clipboard->arps = ocarps;
3982 reget_afilesize(0);
3983 }
3984 } else cfile->undo_action = UNDO_INSERT;
3985
3986 if (cb_video_change) {
3987 mainw->current_file = 0;
3989 on_undo_activate(NULL, NULL);
3991 mainw->current_file = current_file;
3992 }
3993
3994 if (!save_clip_value(mainw->current_file, CLIP_DETAILS_FRAMES, &cfile->frames)) bad_header = TRUE;
3995
3996 if (bad_header) do_header_write_error(mainw->current_file);
3997 switch_clip(1, current_file, TRUE);
3998 mainw->error = FALSE;
3999
4001
4002 if (mainw->sl_undo_mem && (cfile->stored_layout_frame != 0 || (with_sound && cfile->stored_layout_audio != 0.))) {
4003 // need to invalidate undo/redo stack, in case file was used in some layout undo
4005 }
4006
4007 if (chk_mask != 0) popup_lmap_errors(NULL, LIVES_INT_TO_POINTER(chk_mask));
4008 }
4009
4059 boolean check_for_layout_errors(const char *operation, int fileno, int start, int end, uint32_t *in_mask) {
4060 lives_clip_t *sfile;
4061 LiVESList *xlays = NULL;
4062 uint32_t ret_mask = 0, mask = *in_mask;
4063 boolean cancelled = FALSE;
4064
4065 if (!IS_VALID_CLIP(fileno)) return 0;
4066 sfile = mainw->files[fileno];
4067 if (start < 1) start = 1;
4068
4069 if (mask & WARN_MASK_LAYOUT_DELETE_FRAMES) {
4070 if ((xlays = layout_frame_is_affected(fileno, start, end, NULL)) != NULL) {
4071 if (sfile->tcache_dubious_from > 0) free_thumb_cache(fileno, sfile->tcache_dubious_from);
4072 sfile->tcache_dubious_from = start;
4076 mainw->xlays = xlays;
4078 (_("%s will cause missing frames in some multitrack layouts.\nAre you sure you wish to continue ?\n"), operation)) {
4079 cancelled = TRUE;
4080 }
4081 }
4082
4083 if (!cancelled) {
4084 buffer_lmap_error(LMAP_ERROR_DELETE_FRAMES, sfile->name, (livespointer)sfile->layout_map, fileno,
4086 sfile->stored_layout_fps, sfile->fps) >= start);
4087 }
4088 lives_list_free_all(&xlays);
4089 }
4090 }
4091
4092 if (mask & WARN_MASK_LAYOUT_DELETE_AUDIO) {
4093 if ((xlays = layout_audio_is_affected(fileno, (start - 1.) / sfile->fps, (end - 1.) / sfile->fps, NULL)) != NULL) {
4096 if (!cancelled) {
4098 mainw->xlays = xlays;
4100 (_("%s will cause missing audio in some multitrack layouts.\nAre you sure you wish to continue ?\n"), operation)) {
4101 cancelled = TRUE;
4102 }
4103 }
4104 if (!cancelled) {
4105 buffer_lmap_error(LMAP_ERROR_DELETE_AUDIO, sfile->name, (livespointer)sfile->layout_map, fileno, 0,
4106 (start - 1.) / sfile->fps, (start - 1.) / sfile->fps < sfile->stored_layout_audio);
4107 }
4108 }
4109 }
4110 lives_list_free_all(&xlays);
4111 }
4112
4113 if ((ret_mask & WARN_MASK_LAYOUT_DELETE_FRAMES) == 0) {
4114 if (mask & WARN_MASK_LAYOUT_SHIFT_FRAMES) {
4115 if ((xlays = layout_frame_is_affected(fileno, start, 0, NULL)) != NULL) {
4116 if (sfile->tcache_dubious_from > 0) free_thumb_cache(fileno, sfile->tcache_dubious_from);
4117 sfile->tcache_dubious_from = start;
4120 mainw->xlays = xlays;
4122 (_("%s will cause frames to shift in some multitrack layouts.\nAre you sure you wish to continue ?\n"),
4123 operation)) {
4124 cancelled = TRUE;
4125 }
4126 }
4127 if (!cancelled) {
4128 buffer_lmap_error(LMAP_ERROR_SHIFT_FRAMES, sfile->name, (livespointer)sfile->layout_map, fileno,
4129 start, 0., start <= count_resampled_frames(sfile->stored_layout_frame,
4130 sfile->stored_layout_fps, sfile->fps));
4131 }
4132 }
4133 lives_list_free_all(&xlays);
4134 }
4135 }
4136
4137 if ((ret_mask & WARN_MASK_LAYOUT_DELETE_AUDIO) == 0) {
4138 if (mask & WARN_MASK_LAYOUT_SHIFT_AUDIO) {
4139 if ((xlays = layout_audio_is_affected(fileno, (start - 1.) / sfile->fps, 0., NULL)) != NULL) {
4141 if (!cancelled) {
4143 mainw->xlays = xlays;
4145 (_("%s will cause audio to shift in some multitrack layouts.\nAre you sure you wish to continue ?\n"),
4146 operation)) {
4147 cancelled = TRUE;
4148 }
4149 }
4150 if (!cancelled) {
4151 buffer_lmap_error(LMAP_ERROR_SHIFT_AUDIO, sfile->name, (livespointer)sfile->layout_map, fileno, 0,
4152 (start - 1.) / sfile->fps, (start - 1.) / sfile->fps <= sfile->stored_layout_audio);
4153 }
4154 }
4155 lives_list_free_all(&xlays);
4156 }
4157 }
4158 }
4159
4161 if (mask & WARN_MASK_LAYOUT_ALTER_FRAMES) {
4162 if ((xlays = layout_frame_is_affected(fileno, start, end, NULL)) != NULL) {
4163 if (sfile->tcache_dubious_from > 0) free_thumb_cache(fileno, sfile->tcache_dubious_from);
4164 sfile->tcache_dubious_from = start;
4167 mainw->xlays = xlays;
4169 cancelled = TRUE;
4170 }
4171 }
4172 if (!cancelled) {
4173 buffer_lmap_error(LMAP_ERROR_ALTER_FRAMES, sfile->name, (livespointer)sfile->layout_map, fileno, 0, 0.,
4174 sfile->stored_layout_frame > 0);
4175 }
4176 lives_list_free_all(&xlays);
4177 }
4178 }
4179 }
4180
4182 if (mask & WARN_MASK_LAYOUT_ALTER_AUDIO) {
4183 if ((xlays = layout_audio_is_affected(fileno, 0., 0., NULL)) != NULL) {
4184 ret_mask |= WARN_MASK_LAYOUT_ALTER_AUDIO;
4185 if (!cancelled) {
4187 mainw->xlays = xlays;
4189 cancelled = TRUE;
4190 }
4191 }
4192 }
4193 if (!cancelled) {
4194 buffer_lmap_error(LMAP_ERROR_ALTER_AUDIO, sfile->name, (livespointer)sfile->layout_map, fileno, 0, 0.,
4195 sfile->stored_layout_audio > 0.);
4196 }
4197 lives_list_free_all(&xlays);
4198 }
4199 }
4200 }
4201
4202 mainw->xlays = NULL;
4203 *in_mask = ret_mask;
4204 return !cancelled;
4205 }
4206
4207
4208 void on_delete_activate(LiVESMenuItem * menuitem, livespointer user_data) {
4209 char *com;
4210
4211 boolean bad_header = FALSE;
4212
4213 uint32_t chk_mask = 0;
4214
4215 int frames_cut = cfile->end - cfile->start + 1;
4216 int start = cfile->start;
4217 int end = cfile->end;
4218
4219 // occasionally we get a keyboard misread, so this should prevent that
4220 if (LIVES_IS_PLAYING) return;
4221
4222 if (cfile->start <= 1 && cfile->end == cfile->frames) {
4223 if (!mainw->osc_auto && menuitem != LIVES_MENU_ITEM(mainw->cut) && (cfile->achans == 0 ||
4224 ((cfile->end - 1.) / cfile->fps >= cfile->laudio_time &&
4227 (_("\nDeleting all frames will close this file.\nAre you sure ?"))) close_current_file(0);
4228 return;
4229 }
4230 }
4231
4232 if (menuitem) {
4233 char *tmp = (_("Deletion"));
4237 if (!check_for_layout_errors(tmp, mainw->current_file, cfile->start, cfile->end, &chk_mask)) {
4238 lives_free(tmp);
4239 return;
4240 }
4241 lives_free(tmp);
4242 }
4243
4244 if (cfile->start <= 1 && cfile->end == cfile->frames) {
4245 cfile->ohsize = cfile->hsize;
4246 cfile->ovsize = cfile->vsize;
4247 }
4248
4249 cfile->undo_start = cfile->start;
4250 cfile->undo_end = cfile->end;
4251 cfile->undo1_boolean = mainw->ccpd_with_sound;
4252
4253 if (menuitem || mainw->osc_auto) {
4254 d_print(""); // force switchtext
4255 d_print(_("Deleting frames %d to %d%s..."), cfile->start, cfile->end,
4256 mainw->ccpd_with_sound && cfile->achans > 0 ? " (with sound)" : "");
4257 }
4258
4259 com = lives_strdup_printf("%s cut \"%s\" %d %d %d %d \"%s\" %.3f %d %d %d",
4260 prefs->backend, cfile->handle, cfile->start, cfile->end,
4262 cfile->fps, cfile->arate, cfile->achans, cfile->asampsize);
4263 lives_rm(cfile->info_file);
4264 lives_system(com, FALSE);
4265 lives_free(com);
4266
4267 if (THREADVAR(com_failed)) {
4270 return;
4271 }
4272
4273 cfile->progress_start = cfile->start;
4274 cfile->progress_end = cfile->frames;
4275
4276 // show a progress dialog, not cancellable
4277 do_progress_dialog(TRUE, FALSE, _("Deleting"));
4278
4279 if (cfile->clip_type == CLIP_TYPE_FILE) {
4281 }
4282
4283 cfile->frames -= frames_cut;
4284
4285 cfile->undo_arate = cfile->arate;
4286 cfile->undo_signed_endian = cfile->signed_endian;
4287 cfile->undo_achans = cfile->achans;
4288 cfile->undo_asampsize = cfile->asampsize;
4289 cfile->undo_arps = cfile->arps;
4290
4291 if (mainw->ccpd_with_sound) {
4293 } else get_play_times();
4294
4295 if (cfile->frames == 0) {
4296 if (cfile->afilesize == 0l) {
4298 return;
4299 }
4300 lives_snprintf(cfile->type, 40, "Audio");
4301 cfile->hsize = cfile->vsize = 0;
4302 if (!save_clip_value(mainw->current_file, CLIP_DETAILS_WIDTH, &cfile->hsize)) bad_header = TRUE;
4303 if (!save_clip_value(mainw->current_file, CLIP_DETAILS_HEIGHT, &cfile->vsize)) bad_header = TRUE;
4304
4305 if (bad_header) do_header_write_error(mainw->current_file);
4306 cfile->orig_file_name = FALSE;
4307 desensitize();
4308 sensitize();
4309 }
4310
4311 if (!mainw->selwidth_locked || cfile->start > cfile->frames) {
4312 if (--start == 0 && cfile->frames > 0) {
4313 start = 1;
4314 }
4315 }
4316
4317 cfile->start = start;
4318
4319 if (!mainw->selwidth_locked) {
4320 cfile->end = start;
4321 } else {
4322 cfile->end = end;
4323 if (cfile->end > cfile->frames) {
4324 cfile->end = cfile->frames;
4325 }
4326 }
4327
4329 lives_spin_button_set_range(LIVES_SPIN_BUTTON(mainw->spinbutton_end), cfile->frames == 0 ? 0 : 1, cfile->frames);
4330 lives_spin_button_set_value(LIVES_SPIN_BUTTON(mainw->spinbutton_end), cfile->end);
4332
4334 lives_spin_button_set_range(LIVES_SPIN_BUTTON(mainw->spinbutton_start), cfile->frames == 0 ? 0 : 1, cfile->frames);
4335 lives_spin_button_set_value(LIVES_SPIN_BUTTON(mainw->spinbutton_start), cfile->start);
4337
4338 // menuitem is NULL if we came here from undo_insert
4339 if (!menuitem && !mainw->osc_auto) return;
4340
4341 if (!save_clip_value(mainw->current_file, CLIP_DETAILS_FRAMES, &cfile->frames)) bad_header = TRUE;
4342
4343 showclipimgs();
4344
4346
4347 if (bad_header) do_header_write_error(mainw->current_file);
4348
4349 // mark new file size as 'Unknown'
4350 cfile->f_size = 0l;
4351 cfile->changed = TRUE;
4352
4353 set_undoable(_("Delete"), TRUE);
4354 cfile->undo_action = UNDO_DELETE;
4355 d_print_done();
4356
4357 if (mainw->sl_undo_mem && (cfile->stored_layout_frame != 0 || (mainw->ccpd_with_sound &&
4358 cfile->stored_layout_audio != 0.))) {
4359 // need to invalidate undo/redo stack, in case file was used in some layout undo
4361 }
4362
4363 if (chk_mask != 0) popup_lmap_errors(NULL, LIVES_INT_TO_POINTER(chk_mask));
4364 }
4365
4366
4367 void on_select_all_activate(LiVESWidget * widget, livespointer user_data) {
4368 if (!CURRENT_CLIP_IS_VALID) return;
4369
4370 if (mainw->selwidth_locked) {
4372 if (widget) do_error_dialog(_("\n\nSelection is locked.\n"));
4374 return;
4375 }
4376
4377 lives_spin_button_set_value(LIVES_SPIN_BUTTON(mainw->spinbutton_start), 1);
4378 lives_spin_button_set_value(LIVES_SPIN_BUTTON(mainw->spinbutton_end), cfile->frames);
4379
4380 cfile->start = cfile->frames > 0 ? 1 : 0;
4381 cfile->end = cfile->frames;
4382
4384
4385 showclipimgs();
4386 }
4387
4388
4389 void on_select_start_only_activate(LiVESMenuItem * menuitem, livespointer user_data) {
4390 if (mainw->current_file == -1) return;
4391 lives_spin_button_set_value(LIVES_SPIN_BUTTON(mainw->spinbutton_end), cfile->start);
4392 }
4393
4394
4395 void on_select_end_only_activate(LiVESMenuItem * menuitem, livespointer user_data) {
4396 if (mainw->current_file == -1) return;
4397 lives_spin_button_set_value(LIVES_SPIN_BUTTON(mainw->spinbutton_start), cfile->end);
4398 }
4399
4400
4401 void on_select_invert_activate(LiVESMenuItem * menuitem, livespointer user_data) {
4402 if (cfile->start == 1) {
4403 lives_spin_button_set_value(LIVES_SPIN_BUTTON(mainw->spinbutton_start), cfile->end + 1);
4404 lives_spin_button_set_value(LIVES_SPIN_BUTTON(mainw->spinbutton_end), cfile->frames);
4405 } else {
4406 lives_spin_button_set_value(LIVES_SPIN_BUTTON(mainw->spinbutton_end), cfile->start - 1);
4407 lives_spin_button_set_value(LIVES_SPIN_BUTTON(mainw->spinbutton_start), 1);
4408 }
4409
4411
4412 showclipimgs();
4413 }
4414
4415
4416 void on_select_last_activate(LiVESMenuItem * menuitem, livespointer user_data) {
4417 if (cfile->undo_start > cfile->frames) cfile->undo_start = cfile->frames;
4418 if (cfile->undo_end > cfile->frames) cfile->undo_end = cfile->frames;
4419
4420 lives_spin_button_set_value(LIVES_SPIN_BUTTON(mainw->spinbutton_start), cfile->undo_start);
4421 lives_spin_button_set_value(LIVES_SPIN_BUTTON(mainw->spinbutton_end), cfile->undo_end);
4422
4423 cfile->start = cfile->undo_start;
4424 cfile->end = cfile->undo_end;
4425
4427
4428 showclipimgs();
4429 }
4430
4431
4432 void on_select_new_activate(LiVESMenuItem * menuitem, livespointer user_data) {
4433 if (cfile->insert_start > cfile->frames) cfile->insert_start = cfile->frames;
4434 if (cfile->insert_end > cfile->frames) cfile->insert_end = cfile->frames;
4435
4436 lives_spin_button_set_value(LIVES_SPIN_BUTTON(mainw->spinbutton_start), cfile->insert_start);
4437 lives_spin_button_set_value(LIVES_SPIN_BUTTON(mainw->spinbutton_end), cfile->insert_end);
4438
4439 cfile->start = cfile->insert_start;
4440 cfile->end = cfile->insert_end;
4441
4443
4444 showclipimgs();
4445 }
4446
4447
4448 void on_select_to_end_activate(LiVESMenuItem * menuitem, livespointer user_data) {
4449 lives_spin_button_set_value(LIVES_SPIN_BUTTON(mainw->spinbutton_end), cfile->frames);
4450 cfile->end = cfile->frames;
4452 load_end_image(cfile->end);
4453 }
4454
4455
4456 void on_select_to_aend_activate(LiVESMenuItem * menuitem, livespointer user_data) {
4457 int end = calc_frame_from_time4(mainw->current_file, cfile->laudio_time);
4458 if (end > cfile->frames) end = cfile->frames;
4459 if (end < cfile->start) end = cfile->start;
4460 lives_spin_button_set_value(LIVES_SPIN_BUTTON(mainw->spinbutton_end), end);
4461 cfile->end = end;
4463 load_end_image(cfile->end);
4464 }
4465
4466
4467 void on_select_from_start_activate(LiVESMenuItem * menuitem, livespointer user_data) {
4468 lives_spin_button_set_value(LIVES_SPIN_BUTTON(mainw->spinbutton_start), 1);
4469 cfile->start = cfile->frames > 0 ? 1 : 0;
4471 load_start_image(cfile->start);
4472 }
4473
4474
4475 void on_lock_selwidth_activate(LiVESMenuItem * menuitem, livespointer user_data) {
4479 }
4480
4481
4482 void play_all(boolean from_menu) {
4484
4485 if (mainw->multitrack) {
4486 if (!LIVES_IS_PLAYING) {
4487 if (!mainw->multitrack->playing_sel) multitrack_playall(mainw->multitrack);
4489 } else on_pause_clicked();
4490 return;
4491 }
4492
4493 if (!LIVES_IS_PLAYING) {
4494 if (mainw->proc_ptr && from_menu) {
4495 on_preview_clicked(LIVES_BUTTON(mainw->proc_ptr->preview_button), NULL);
4496 return;
4497 }
4498
4499 if (!mainw->osc_auto) {
4500 if (cfile->frames > 0) {
4502 cfile->pointer_time);
4503 } else {
4505 cfile->pointer_time); // real_pointer_time ???
4506 }
4507 mainw->play_end = cfile->frames;
4508 }
4509
4511 if (CURRENT_CLIP_IS_NORMAL) lives_rm(cfile->info_file);
4512
4513 play_file();
4514
4515 /* if (CURRENT_CLIP_IS_VALID) { */
4516 /* if (1 || !cfile->play_paused) { */
4517 /* //cfile->pointer_time = (cfile->last_frameno - 1.) / cfile->fps; */
4518 /* lives_ce_update_timeline(0, cfile->real_pointer_time); */
4519 /* } else { */
4520 /* lives_ce_update_timeline(cfile->frameno, 0); */
4521 /* //cfile->pointer_time = (cfile->last_frameno - 1.) / cfile->fps; */
4522 /* //cfile->play_paused = TRUE; */
4523 /* mainw->cancelled = CANCEL_USER; */
4524 /* } */
4525 //}
4526 }
4527 }
4528
4529
4530 void on_playall_activate(LiVESMenuItem * menuitem, livespointer user_data) {
4531 if (menuitem && mainw->go_away) return;
4532 start_playback(menuitem ? 8 : 0);
4533 }
4534
4535
4536 void play_sel(void) {
4537 if (!mainw->is_rendering) {
4538 mainw->play_start = cfile->start;
4539 mainw->play_end = cfile->end;
4541 }
4542
4543 if (!mainw->preview) {
4544 int orig_play_frame = calc_frame_from_time(mainw->current_file, cfile->pointer_time);
4545 if (orig_play_frame > mainw->play_start && orig_play_frame < mainw->play_end) {
4546 mainw->play_start = orig_play_frame;
4547 }
4548 }
4549
4551
4552 play_file();
4553
4555 lives_ce_update_timeline(0, cfile->real_pointer_time);
4556
4557 // in case we are rendering and previewing, in case we now have audio
4562 }
4563 }
4564
4565
4566 void on_playsel_activate(LiVESMenuItem * menuitem, livespointer user_data) {
4567 // play part of a clip (in clip editor)
4569
4570 if (mainw->proc_ptr && menuitem) {
4571 on_preview_clicked(LIVES_BUTTON(mainw->proc_ptr->preview_button), NULL);
4572 return;
4573 }
4574 if (LIVES_POINTER_TO_INT(user_data)) play_file();
4575 else start_playback(1);
4576 }
4577
4578
4579 void on_playclip_activate(LiVESMenuItem * menuitem, livespointer user_data) {
4580 // play the clipboard
4581 int current_file;
4582 if (mainw->multitrack) return;
4583
4584 current_file = mainw->pre_play_file = mainw->current_file;
4585 mainw-> oloop = mainw->loop;
4587
4588 // switch to the clipboard
4589 switch_to_file(current_file, 0);
4593
4594 mainw->play_start = 1;
4595 mainw->play_end = clipboard->frames;
4597 mainw->loop = FALSE;
4598
4599 lives_rm(cfile->info_file);
4600
4601 start_playback(5);
4602 }
4603
4604
4605 void on_record_perf_activate(LiVESMenuItem * menuitem, livespointer user_data) {
4606 // real time recording
4607
4608 if (mainw->multitrack) return;
4609
4610 if (LIVES_IS_PLAYING) {
4611 // we are playing a clip
4612 if (!mainw->record || mainw->record_paused) {
4613 // recording is starting
4615
4616 toggle_record();
4617
4619 || prefs->audio_src == AUDIO_SRC_EXT) &&
4621 if (mainw->ascrap_file == -1) {
4623 }
4624 if (mainw->ascrap_file != -1) {
4625 mainw->rec_samples = -1; // record unlimited
4627 mainw->rec_avel = 1.;
4631
4632#ifdef ENABLE_JACK
4634 char *lives_header = lives_build_filename(prefs->workdir, mainw->files[mainw->ascrap_file]->handle,
4635 LIVES_CLIP_HEADER, NULL);
4636 mainw->clip_header = fopen(lives_header, "w"); // speed up clip header writes
4637 lives_free(lives_header);
4638
4639 if (mainw->agen_key == 0 && !mainw->agen_needs_reinit) {
4640 jack_rec_audio_to_clip(mainw->ascrap_file, -1, RECA_EXTERNAL);
4641 mainw->jackd_read->is_paused = FALSE;
4642 mainw->jackd_read->in_use = TRUE;
4643 } else {
4644 if (mainw->jackd) {
4645 jack_rec_audio_to_clip(mainw->ascrap_file, -1, RECA_GENERATED);
4646 }
4647 }
4648 if (mainw->clip_header) fclose(mainw->clip_header);
4649 mainw->clip_header = NULL;
4650 }
4651
4652#endif
4653#ifdef HAVE_PULSE_AUDIO
4655 char *lives_header = lives_build_filename(prefs->workdir, mainw->files[mainw->ascrap_file]->handle,
4656 LIVES_CLIP_HEADER, NULL);
4657 mainw->clip_header = fopen(lives_header, "w"); // speed up clip header writes
4658 lives_free(lives_header);
4659
4660 if (mainw->agen_key == 0 && !mainw->agen_needs_reinit) {
4661 pulse_rec_audio_to_clip(mainw->ascrap_file, -1, RECA_EXTERNAL);
4662 mainw->pulsed_read->is_paused = FALSE;
4663 mainw->pulsed_read->in_use = TRUE;
4664 } else {
4665 if (mainw->pulsed) {
4666 pulse_rec_audio_to_clip(mainw->ascrap_file, -1, RECA_GENERATED);
4667 }
4668 }
4669 if (mainw->clip_header) fclose(mainw->clip_header);
4670 mainw->clip_header = NULL;
4671 }
4672#endif
4673 }
4674 return;
4675 }
4676
4677 if (prefs->rec_opts & REC_AUDIO) {
4678 // recording INTERNAL audio
4679#ifdef ENABLE_JACK
4681 jack_get_rec_avals(mainw->jackd);
4682 }
4683#endif
4684#ifdef HAVE_PULSE_AUDIO
4686 pulse_get_rec_avals(mainw->pulsed);
4687 }
4688#endif
4689 }
4690 return;
4691 }
4692
4693 // end record during playback
4695 mainw->record_paused = TRUE; // pause recording of further events
4696 enable_record();
4697 return;
4698 }
4699
4700 // out of playback
4701
4702 // record performance
4703 if (!mainw->record) {
4704 // TODO - change message depending on rec_opts
4705 d_print(_("Ready to record. Use 'control' and cursor keys during playback to record your performance.\n"
4706 "(To cancel, press 'r' or click on Play|Record Performance again before you play.)\n"));
4707 mainw->record = TRUE;
4708 toggle_record();
4710 } else {
4711 d_print(_("Record cancelled.\n"));
4712 enable_record();
4713 mainw->record = FALSE;
4714 }
4715 }
4716
4717
4718 boolean record_toggle_callback(LiVESAccelGroup * group, LiVESWidgetObject * obj, uint32_t keyval, LiVESXModifierType mod,
4719 livespointer user_data) {
4720 // from osc
4721 boolean start = (boolean)LIVES_POINTER_TO_INT(user_data);
4722
4723 if ((start && (!mainw->record || mainw->record_paused)) || (!start && (mainw->record && !mainw->record_paused)))
4724 on_record_perf_activate(NULL, NULL);
4725
4726 return TRUE;
4727 }
4728
4729
4730 void on_rewind_activate(LiVESMenuItem * menuitem, livespointer user_data) {
4731 if (LIVES_IS_PLAYING) return;
4732
4733 if (mainw->multitrack) {
4735 return;
4736 }
4737
4738 cfile->pointer_time = lives_ce_update_timeline(0, 0.);
4740 mainw->ptrtime = cfile->pointer_time;
4745 }
4746
4747
4748 void on_stop_activate(LiVESMenuItem * menuitem, livespointer user_data) {
4749 // stop during playback
4750
4751 if (mainw->multitrack && mainw->multitrack->is_paused && !LIVES_IS_PLAYING) {
4752 mainw->multitrack->is_paused = FALSE;
4753 mainw->multitrack->playing_sel = FALSE;
4754 mt_tl_move(mainw->multitrack, mainw->multitrack->pb_unpaused_start_time);
4757 return;
4758 }
4759
4761 }
4762
4763
4764 boolean on_stop_activate_by_del(LiVESWidget * widget, LiVESXEventDelete * event, livespointer user_data) {
4765 // called if the user closes the separate play window
4767 on_sepwin_pressed(NULL, NULL);
4768 }
4769 return TRUE;
4770 }
4771
4772
4773 void on_pause_clicked(void) {
4776 }
4777
4778
4779 void on_encoder_entry_changed(LiVESCombo * combo, livespointer ptr) {
4780 LiVESList *encoder_capabilities = NULL;
4781 LiVESList *ofmt_all = NULL;
4782 LiVESList *ofmt = NULL;
4783
4784 const char *new_encoder_name = lives_combo_get_active_text(combo);
4785 char *msg;
4786 char **array;
4787 int i;
4789 LiVESList *dummy_list;
4790
4791 if (!strlen(new_encoder_name)) return;
4792
4793 if (!strcmp(new_encoder_name, mainw->string_constants[LIVES_STRING_CONSTANT_ANY])) {
4794 LiVESList *ofmt = NULL;
4795 ofmt = lives_list_append(ofmt, lives_strdup(mainw->string_constants[LIVES_STRING_CONSTANT_ANY]));
4796
4798 // ---
4800 // ---
4802
4803 lives_combo_populate(LIVES_COMBO(rdet->ofmt_combo), ofmt);
4807
4808 lives_list_free(ofmt);
4809 if (prefs->acodec_list) {
4811 }
4812 prefs->acodec_list = lives_list_append(prefs->acodec_list, lives_strdup(mainw->string_constants[LIVES_STRING_CONSTANT_ANY]));
4813
4815
4817
4819
4820 return;
4821 }
4822
4823 // finalise old plugin
4825
4827 // initialise new plugin
4828 if ((dummy_list = plugin_request(PLUGIN_ENCODERS, new_encoder_name, "init")) == NULL) {
4829 if (*mainw->msg) {
4830 msg = lives_strdup_printf(_("\n\nThe '%s' plugin reports:\n%s\n"), new_encoder_name, mainw->msg);
4831 } else {
4833 (_("\n\nUnable to find the 'init' method in the %s plugin.\nThe plugin may be broken or not installed correctly."),
4834 new_encoder_name);
4835 }
4836
4837 if (mainw->is_ready) {
4839 }
4840
4841 lives_free(msg);
4842
4843 if (prefsw) {
4845 // ---
4847 // ---
4849 }
4850
4851 if (rdet) {
4853 // ---
4855 // ---
4857 }
4858
4859 dummy_list = plugin_request(PLUGIN_ENCODERS, prefs->encoder.name, "init");
4860 lives_list_free_all(&dummy_list);
4861 return;
4862 }
4863 lives_list_free_all(&dummy_list);
4864
4865 lives_snprintf(future_prefs->encoder.name, 64, "%s", new_encoder_name);
4866
4867 if ((encoder_capabilities = plugin_request(PLUGIN_ENCODERS, future_prefs->encoder.name, "get_capabilities")) == NULL) {
4869
4870 if (prefsw) {
4872 // ---
4874 // ---
4876 }
4877
4878 if (rdet) {
4880 // ---
4882 // ---
4884 }
4885
4887 lives_snprintf(future_prefs->encoder.name, 64, "%s", prefs->encoder.name);
4888 return;
4889 }
4890 prefs->encoder.capabilities = atoi((char *)lives_list_nth_data(encoder_capabilities, 0));
4891 lives_list_free_all(&encoder_capabilities);
4892
4893 // fill list with new formats
4894 if ((ofmt_all = plugin_request_by_line(PLUGIN_ENCODERS, future_prefs->encoder.name, "get_formats"))) {
4895 for (i = 0; i < lives_list_length(ofmt_all); i++) {
4896 if (get_token_count((char *)lives_list_nth_data(ofmt_all, i), '|') > 2) {
4897 array = lives_strsplit((char *)lives_list_nth_data(ofmt_all, i), "|", -1);
4898 ofmt = lives_list_append(ofmt, lives_strdup(array[1]));
4899 lives_strfreev(array);
4900 }
4901 }
4902
4903 if (prefsw) {
4904 // we have to block here, otherwise on_ofmt_changed gets called for every added entry !
4906
4907 lives_combo_populate(LIVES_COMBO(prefsw->ofmt_combo), ofmt);
4908
4910 }
4911
4912 if (rdet) {
4913 // we have to block here, otherwise on_ofmt_changed gets called for every added entry !
4915
4916 lives_combo_populate(LIVES_COMBO(rdet->ofmt_combo), ofmt);
4917
4919 }
4920
4921 lives_list_free(ofmt);
4922
4923 // set default (first) output type
4924 array = lives_strsplit((char *)lives_list_nth_data(ofmt_all, 0), "|", -1);
4925
4926 if (rdet) {
4927 lives_combo_set_active_string(LIVES_COMBO(rdet->ofmt_combo), array[1]);
4928
4929 if (!prefsw && strcmp(prefs->encoder.name, future_prefs->encoder.name)) {
4930 lives_snprintf(prefs->encoder.name, 64, "%s", future_prefs->encoder.name);
4932 lives_snprintf(prefs->encoder.of_restrict, 1024, "%s", future_prefs->encoder.of_restrict);
4934 }
4936 rdet->encoder_name = lives_strdup(prefs->encoder.name);
4938 }
4939
4940 if (prefsw) {
4941 lives_combo_set_active_string(LIVES_COMBO(prefsw->ofmt_combo), array[1]);
4942 }
4944 lives_strfreev(array);
4945 if (ofmt_all) {
4946 lives_list_free_all(&ofmt_all);
4947 }
4948 }
4949 }
4950
4951
4952 void on_insertwsound_toggled(LiVESToggleButton * togglebutton, livespointer user_data) {
4953 if (lives_toggle_button_get_active(LIVES_TOGGLE_BUTTON(togglebutton))) {
4955 } else {
4957 }
4959 }
4960
4961
4963 static int loop_lock_frame = -1;
4964 static lives_direction_t ofwd;
4965
4966 void unlock_loop_lock(void) {
4967 mainw->loop = mainw->oloop;
4972 mainw->play_start = cfile->start;
4973 mainw->play_end = cfile->end;
4974 }
4975 loop_lock_frame = -1;
4977 }
4978
4979
4980 boolean clip_can_reverse(int clipno) {
4982 || !IS_VALID_CLIP(clipno) || mainw->preview) return FALSE;
4983 else {
4984 lives_clip_t *sfile = mainw->files[clipno];
4985 if (sfile->clip_type == CLIP_TYPE_DISK) return TRUE;
4986 if (sfile->next_event) return FALSE;
4987 if (sfile->clip_type == CLIP_TYPE_FILE) {
4988 lives_clip_data_t *cdata = ((lives_decoder_t *)sfile->ext_src)->cdata;
4989 if (!cdata || !(cdata->seek_flag & LIVES_SEEK_FAST_REV)) return FALSE;
4990 }
4991 }
4992 return TRUE;
4993 }
4994
4995
4996 boolean dirchange_callback(LiVESAccelGroup * group, LiVESWidgetObject * obj, uint32_t keyval, LiVESXModifierType mod,
4997 livespointer area_enum) {
4998 int area = LIVES_POINTER_TO_INT(area_enum);
4999
5000 if (!(mod & LIVES_ALT_MASK) && (mod & LIVES_CONTROL_MASK) && mainw->loop_locked) {
5001 boolean do_ret = FALSE;
5002 if (!clip_can_reverse(mainw->current_file) || !mainw->ping_pong || ((cfile->pb_fps >= 0. && ofwd == LIVES_DIRECTION_FORWARD)
5003 || (cfile->pb_fps < 0. && ofwd == LIVES_DIRECTION_BACKWARD))) do_ret = TRUE;
5005 if (do_ret) return TRUE;
5006 }
5007
5008 if (area == SCREEN_AREA_FOREGROUND) {
5010 || (!clip_can_reverse(mainw->current_file) && cfile->pb_fps > 0.)) return TRUE;
5011 // change play direction
5012 if (cfile->play_paused) {
5013 if (!clip_can_reverse(mainw->current_file) && cfile->freeze_fps > 0.) return TRUE;
5014 cfile->freeze_fps = -cfile->freeze_fps;
5015 return TRUE;
5016 }
5017
5020
5022 lives_spin_button_set_value(LIVES_SPIN_BUTTON(mainw->spinbutton_pb_fps), -cfile->pb_fps);
5024
5025 // make sure this is called, sometimes we switch clips too soon...
5026 changed_fps_during_pb(LIVES_SPIN_BUTTON(mainw->spinbutton_pb_fps), NULL);
5027 } else if (area == SCREEN_AREA_BACKGROUND) {
5029 || (!clip_can_reverse(mainw->blend_file) && mainw->files[mainw->blend_file]->pb_fps >= 0.)) return TRUE;
5031 }
5032 return TRUE;
5033 }
5034
5035
5054 boolean dirchange_lock_callback(LiVESAccelGroup * group, LiVESWidgetObject * obj, uint32_t keyval, LiVESXModifierType mod,
5055 livespointer area_enum) {
5056
5057 //if (!clip_can_reverse(mainw->current_file)) return TRUE;
5058
5059 if (!mainw->loop_locked && loop_lock_frame == -1) loop_lock_frame = mainw->actual_frame;
5060 else {
5061 // temporary loop_cont / ping-pong
5063 if ((!mainw->loop_locked && mainw->actual_frame < loop_lock_frame) || (mainw->loop_locked && cfile->pb_fps < 0)) {
5066 if (!mainw->loop_locked) mainw->play_end = loop_lock_frame;
5067 } else {
5068 if (!mainw->loop_locked) mainw->play_start = loop_lock_frame;
5071 }
5072 if (!mainw->loop_locked) {
5073 mainw->oloop = mainw->loop;
5079 }
5080 mainw->loop_cont = TRUE;
5082 mainw->ping_pong = TRUE;
5083 mainw->loop = FALSE;
5085 loop_lock_frame = -1;
5086 }
5088 return dirchange_callback(group, obj, keyval, mod, area_enum);
5089 return TRUE;
5090 }
5091
5092
5093 void on_volch_pressed(LiVESButton * button, livespointer user_data) {
5094 lives_direction_t dirn = LIVES_POINTER_TO_INT(user_data);
5095 if (!CURRENT_CLIP_IS_VALID || mainw->preview || (mainw->is_processing && cfile->is_loaded) || !mainw->cliplist) return;
5096 if (dirn == LIVES_DIRECTION_UP) cfile->vol += .01;
5097 else cfile->vol -= .01;
5098 if (cfile->vol > 2.) cfile->vol = 2.;
5099 if (cfile->vol < 0.) cfile->vol = 0.;
5101 d_print_overlay(.5, _("Clip volume: %.2f"), cfile->vol);
5102 }
5103
5104
5105 boolean fps_reset_callback(LiVESAccelGroup * group, LiVESWidgetObject * obj, uint32_t keyval, LiVESXModifierType mod,
5106 livespointer area_enum) {
5107 // reset playback fps (cfile->pb_fps) to normal fps (cfile->fps)
5108 // also resync the audio
5109 int area;
5110 if (!LIVES_IS_PLAYING || mainw->multitrack) return TRUE;
5111
5112 area = LIVES_POINTER_TO_INT(area_enum);
5113 if (area == SCREEN_AREA_BACKGROUND) {
5114 if (!IS_NORMAL_CLIP(mainw->blend_file)) return TRUE;
5116 return TRUE;
5117 }
5118
5120
5121 if (mainw->loop_locked) {
5122 dirchange_callback(group, obj, keyval, LIVES_CONTROL_MASK, SCREEN_AREA_FOREGROUND);
5123 }
5124
5126 resync_audio(((double)cfile->frameno));
5127 /* + (double)(lives_get_current_playback_ticks(mainw->origsecs, mainw->orignsecs, NULL) */
5128 /* - mainw->startticks) / TICKS_PER_SECOND_DBL * cfile->pb_fps); */
5129 }
5130
5131 // change play direction
5132 if (cfile->play_paused) {
5133 if (cfile->freeze_fps < 0.) cfile->freeze_fps = -cfile->fps;
5134 else cfile->freeze_fps = cfile->fps;
5135 return TRUE;
5136 }
5137
5139 if (cfile->pb_fps > 0.) lives_spin_button_set_value(LIVES_SPIN_BUTTON(mainw->spinbutton_pb_fps), cfile->fps);
5140 else lives_spin_button_set_value(LIVES_SPIN_BUTTON(mainw->spinbutton_pb_fps), -cfile->fps);
5142
5143 // make sure this is called, sometimes we switch clips too soon...
5144 changed_fps_during_pb(LIVES_SPIN_BUTTON(mainw->spinbutton_pb_fps), NULL);
5145
5146 return TRUE;
5147 }
5148
5149
5150 boolean prevclip_callback(LiVESAccelGroup * group, LiVESWidgetObject * obj, uint32_t keyval, LiVESXModifierType mod,
5151 livespointer user_data) {
5152 LiVESList *list_index;
5153 int i = 0;
5154 int num_tried = 0, num_clips;
5155 int type = 0;
5156
5157 // prev clip
5158 // type = 0 : if the effect is a transition, this will change the background clip
5159 // type = 1 fg only
5160 // type = 2 bg only
5161
5162 if (!LIVES_IS_INTERACTIVE) return TRUE;
5163 if (mainw->go_away) return TRUE;
5164
5165 if (!CURRENT_CLIP_IS_VALID || mainw->preview || (mainw->is_processing && cfile->is_loaded) ||
5166 !mainw->cliplist) return TRUE;
5167
5168 if (user_data) type = LIVES_POINTER_TO_INT(user_data);
5169
5170 if (type == 1 && mainw->new_clip != -1) return TRUE;
5171
5172 if (type == 2 || (mainw->active_sa_clips == SCREEN_AREA_BACKGROUND && mainw->playing_file > 0 && type != 1
5173 && !(type == 0 && !IS_NORMAL_CLIP(mainw->blend_file)))) {
5174 if (!IS_VALID_CLIP(mainw->blend_file)) return TRUE;
5175 list_index = lives_list_find(mainw->cliplist, LIVES_INT_TO_POINTER(mainw->blend_file));
5176 } else {
5177 list_index = lives_list_find(mainw->cliplist,
5178 LIVES_INT_TO_POINTER(mainw->swapped_clip == -1 ? mainw->current_file : mainw->swapped_clip));
5179 }
5180 mainw->swapped_clip = -1;
5181
5182 num_clips = lives_list_length(mainw->cliplist);
5183
5184 do {
5185 if (num_tried++ == num_clips) return TRUE; // we might have only audio clips, and then we will block here
5186 if (!list_index || ((list_index = list_index->prev) == NULL)) list_index = lives_list_last(mainw->cliplist);
5187 i = LIVES_POINTER_TO_INT(list_index->data);
5188 } while ((!mainw->files[i] || mainw->files[i]->opening || mainw->files[i]->restoring || i == mainw->scrap_file ||
5189 i == mainw->ascrap_file || (!mainw->files[i]->frames && LIVES_IS_PLAYING)) &&
5190 i != ((type == 2 || (mainw->playing_file > 0 && mainw->active_sa_clips == SCREEN_AREA_BACKGROUND && type != 1)) ?
5192
5193 switch_clip(type, i, FALSE);
5194
5195 return TRUE;
5196 }
5197
5198
5199 boolean nextclip_callback(LiVESAccelGroup * group, LiVESWidgetObject * obj, uint32_t keyval, LiVESXModifierType mod,
5200 livespointer user_data) {
5201 LiVESList *list_index;
5202 int i;
5203 int num_tried = 0, num_clips;
5204
5205 int type = 0;
5206
5207 if (!LIVES_IS_INTERACTIVE) return TRUE;
5208 if (mainw->go_away) return TRUE;
5209 // next clip
5210 // if the effect is a transition, this will change the background clip
5211 if (!CURRENT_CLIP_IS_VALID || mainw->preview || (mainw->is_processing && cfile->is_loaded) ||
5212 !mainw->cliplist) return TRUE;
5213
5214 if (user_data) type = LIVES_POINTER_TO_INT(user_data);
5215
5216 if (type == 1 && mainw->new_clip != -1) return TRUE;
5217
5218 if (type == 2 || (mainw->active_sa_clips == SCREEN_AREA_BACKGROUND && mainw->playing_file > 0 && type != 1
5219 && !(type == 0 && !IS_NORMAL_CLIP(mainw->blend_file)))) {
5220 if (!IS_VALID_CLIP(mainw->blend_file)) return TRUE;
5221 list_index = lives_list_find(mainw->cliplist, LIVES_INT_TO_POINTER(mainw->blend_file));
5222 } else {
5223 list_index = lives_list_find(mainw->cliplist,
5224 LIVES_INT_TO_POINTER(mainw->swapped_clip == -1 ? mainw->current_file : mainw->swapped_clip));
5225 }
5226 mainw->swapped_clip = -1;
5227
5228 num_clips = lives_list_length(mainw->cliplist);
5229
5230 do {
5231 if (num_tried++ == num_clips) return TRUE; // we might have only audio clips, and then we will block here
5232 if (!list_index || ((list_index = list_index->next) == NULL)) list_index = mainw->cliplist;
5233 i = LIVES_POINTER_TO_INT(list_index->data);
5234 } while ((!mainw->files[i] || mainw->files[i]->opening || mainw->files[i]->restoring || i == mainw->scrap_file ||
5235 i == mainw->ascrap_file || (!mainw->files[i]->frames && LIVES_IS_PLAYING)) &&
5236 i != ((type == 2 || (mainw->playing_file > 0 && mainw->active_sa_clips == SCREEN_AREA_BACKGROUND && type != 1)) ?
5238
5239 switch_clip(type, i, FALSE);
5240
5241 return TRUE;
5242 }
5243
5244
5245 static LiVESResponseType rewrite_orderfile(boolean is_append, boolean add, boolean * got_new_handle) {
5246 char *ordfile = lives_build_filename(prefs->workdir, mainw->set_name, CLIP_ORDER_FILENAME, NULL);
5247 char *ordfile_new = lives_build_filename(prefs->workdir, mainw->set_name, CLIP_ORDER_FILENAME "." LIVES_FILE_EXT_NEW, NULL);
5248 char *cwd = lives_get_current_dir();
5249 char *new_dir;
5250 char *dfile, *ord_entry;
5251 char buff[PATH_MAX] = {0};
5252 char new_handle[256] = {0};
5253 LiVESResponseType retval;
5254 LiVESList *cliplist;
5255 int ord_fd, i;
5256
5257 do {
5258 // create the orderfile which lists all the clips in order
5259 retval = LIVES_RESPONSE_NONE;
5260 if (!is_append) ord_fd = creat(ordfile_new, DEF_FILE_PERMS);
5261 else {
5262 lives_cp(ordfile, ordfile_new);
5263 ord_fd = open(ordfile_new, O_CREAT | O_WRONLY | O_APPEND, DEF_FILE_PERMS);
5264 }
5265
5266 if (ord_fd < 0) {
5267 retval = do_write_failed_error_s_with_retry(ordfile, lives_strerror(errno));
5268 if (retval == LIVES_RESPONSE_CANCEL) {
5269 lives_free(ordfile);
5270 lives_free(ordfile_new);
5271 lives_chdir(cwd, FALSE);
5272 lives_free(cwd);
5273 return retval;
5274 }
5275 }
5276
5277 else {
5278 char *oldval, *newval;
5279
5280 for (cliplist = mainw->cliplist; cliplist; cliplist = cliplist->next) {
5281 if (THREADVAR(write_failed)) break;
5284
5285 i = LIVES_POINTER_TO_INT(cliplist->data);
5286 if (IS_NORMAL_CLIP(i) && i != mainw->scrap_file && i != mainw->ascrap_file) {
5287 lives_snprintf(buff, PATH_MAX, "%s", mainw->files[i]->handle);
5288 get_basename(buff);
5289 if (*buff) {
5290 lives_snprintf(new_handle, 256, "%s/%s/%s", mainw->set_name, CLIPS_DIRNAME, buff);
5291 } else {
5292 lives_snprintf(new_handle, 256, "%s/%s/%s", mainw->set_name, CLIPS_DIRNAME, mainw->files[i]->handle);
5293 }
5294
5295 if (strcmp(new_handle, mainw->files[i]->handle)) {
5296 if (!add) continue;
5297
5298 new_dir = lives_build_path(prefs->workdir, new_handle, NULL);
5299 if (lives_file_test(new_dir, LIVES_FILE_TEST_IS_DIR)) {
5300 // get a new unique handle
5301 get_temp_handle(i);
5302 lives_snprintf(new_handle, 256, "%s/%s/%s", mainw->set_name, CLIPS_DIRNAME, mainw->files[i]->handle);
5303 }
5304 lives_free(new_dir);
5305
5306 // move the files
5307 oldval = lives_build_path(prefs->workdir, mainw->files[i]->handle, NULL);
5308 newval = lives_build_path(prefs->workdir, new_handle, NULL);
5309
5310 lives_mv(oldval, newval);
5311 lives_free(oldval);
5312 lives_free(newval);
5313
5314 if (THREADVAR(com_failed)) {
5315 close(ord_fd);
5317 lives_free(ordfile);
5318 lives_free(ordfile_new);
5319 lives_chdir(cwd, FALSE);
5320 lives_free(cwd);
5321 return FALSE;
5322 }
5323
5324 *got_new_handle = TRUE;
5325
5326 lives_snprintf(mainw->files[i]->handle, 256, "%s", new_handle);
5327 dfile = lives_build_filename(prefs->workdir, mainw->files[i]->handle, LIVES_STATUS_FILE_NAME, NULL);
5328 lives_snprintf(mainw->files[i]->info_file, PATH_MAX, "%s", dfile);
5329 lives_free(dfile);
5330 }
5331
5332 ord_entry = lives_strdup_printf("%s\n", mainw->files[i]->handle);
5333 lives_write(ord_fd, ord_entry, strlen(ord_entry), FALSE);
5334 lives_free(ord_entry);
5335 }
5336 }
5337
5338 if (THREADVAR(write_failed) == ord_fd) {
5339 THREADVAR(write_failed) = 0;
5340 retval = do_write_failed_error_s_with_retry(ordfile, NULL);
5341 }
5342 }
5343 } while (retval == LIVES_RESPONSE_RETRY);
5344
5345 close(ord_fd);
5346
5347 if (retval == LIVES_RESPONSE_CANCEL) lives_rm(ordfile_new);
5348 else lives_cp(ordfile_new, ordfile);
5349
5350 lives_free(ordfile);
5351 lives_free(ordfile_new);
5352
5353 lives_chdir(cwd, FALSE);
5354 lives_free(cwd);
5355 return retval;
5356 }
5357
5358
5359 boolean on_save_set_activate(LiVESWidget * widget, livespointer user_data) {
5360 // here is where we save clipsets
5361 // SAVE CLIPSET FUNCTION
5362 // also handles migration and merging of sets
5363 // new_set_name can be passed in userdata, it should be in filename encoding
5364 // TODO - caller to do end_threaded_dialog()
5365
5369
5370 char new_set_name[MAX_SET_NAME_LEN] = {0};
5371
5372 char *old_set = lives_strdup(mainw->set_name);
5373 char *layout_map_file, *layout_map_dir, *new_clips_dir, *current_clips_dir;
5374 //char *tmp;
5375 char *text;
5376
5377 char *tmp;
5378 char *osetn, *nsetn, *dfile;
5379
5380 boolean is_append = FALSE; // we will overwrite the target layout.map file
5381 boolean response;
5382 boolean got_new_handle = FALSE;
5383
5384 int retval;
5385
5386 if (!mainw->cliplist) return FALSE;
5387
5388 // warn the user what will happen
5389 if (!user_data && !do_save_clipset_warn()) return FALSE;
5390
5392 // if we have a current layout, give the user the chance to change their mind
5393 if (!check_for_layout_del(NULL, FALSE)) return FALSE;
5394 }
5395
5396 if (!user_data) {
5397 // this was called from the GUI
5398 do {
5399 // prompt for a set name, advise user to save set
5401 response = lives_dialog_run(LIVES_DIALOG(renamew->dialog));
5402 if (response == LIVES_RESPONSE_CANCEL) return FALSE;
5403 lives_snprintf(new_set_name, MAX_SET_NAME_LEN, "%s",
5404 (tmp = U82F(lives_entry_get_text(LIVES_ENTRY(renamew->entry)))));
5405 lives_free(tmp);
5409 } while (!is_legal_set_name(new_set_name, TRUE, FALSE));
5410 } else lives_snprintf(new_set_name, MAX_SET_NAME_LEN, "%s", (char *)user_data);
5411
5413
5414 lives_snprintf(mainw->set_name, MAX_SET_NAME_LEN, "%s", new_set_name);
5415
5416 if (lives_strcmp(mainw->set_name, old_set)) {
5417 // The user CHANGED the set name
5418 // we must migrate all physical files for the set, and possibly merge with another set
5419
5420 new_clips_dir = CLIPS_DIR(mainw->set_name);
5421 // check if target clips dir exists, ask if user wants to append files
5422 if (lives_file_test(new_clips_dir, LIVES_FILE_TEST_IS_DIR)) {
5423 lives_free(new_clips_dir);
5424 if (mainw->osc_auto == 0) {
5426 lives_snprintf(mainw->set_name, MAX_SET_NAME_LEN, "%s", old_set);
5427 return FALSE;
5428 }
5429 } else if (mainw->osc_auto == 1) return FALSE;
5430
5431 is_append = TRUE;
5432 } else {
5433 lives_free(new_clips_dir);
5434 layout_map_file = lives_build_filename(prefs->workdir, mainw->set_name, LAYOUTS_DIRNAME,
5435 LAYOUT_MAP_FILENAME, NULL);
5436 // if target has layouts dir but no clips, it means we have old layouts !
5437 if (lives_file_test(layout_map_file, LIVES_FILE_TEST_EXISTS)) {
5439 // user answered "yes" - delete
5440 // clear _old_layout maps
5441 char *dfile = lives_build_filename(prefs->workdir, mainw->set_name, LAYOUTS_DIRNAME, NULL);
5442 lives_rm(dfile);
5443 //lives_free(dfile);
5444 }
5445 }
5446 lives_free(layout_map_file);
5447 }
5448 }
5449
5450 text = lives_strdup_printf(_("Saving set %s"), mainw->set_name);
5452 lives_free(text);
5453
5455
5456 THREADVAR(com_failed) = FALSE;
5457
5458 current_clips_dir = lives_build_filename(prefs->workdir, old_set, CLIPS_DIRNAME "/", NULL);
5459 if (*old_set && strcmp(mainw->set_name, old_set)
5460 && lives_file_test(current_clips_dir, LIVES_FILE_TEST_IS_DIR)) {
5461 // set name was changed for an existing set
5462 if (!is_append) {
5463 // create new dir, in case it doesn't already exist
5464 dfile = lives_build_filename(prefs->workdir, mainw->set_name, CLIPS_DIRNAME, NULL);
5465 if (!lives_make_writeable_dir(dfile)) {
5466 // abort if we cannot create the new subdir
5467 LIVES_ERROR("Could not create directory");
5468 LIVES_ERROR(dfile);
5470 lives_snprintf(mainw->set_name, MAX_SET_NAME_LEN, "%s", old_set);
5471 lives_free(dfile);
5473 return FALSE;
5474 }
5475 lives_free(dfile);
5476 }
5477 } else {
5478 // saving as same name (or as new set)
5479 dfile = lives_build_filename(prefs->workdir, mainw->set_name, CLIPS_DIRNAME, NULL);
5480 if (!lives_make_writeable_dir(dfile)) {
5481 // abort if we cannot create the new subdir
5482 LIVES_ERROR("Could not create directory");
5483 LIVES_ERROR(dfile);
5485 lives_snprintf(mainw->set_name, MAX_SET_NAME_LEN, "%s", old_set);
5486 lives_free(dfile);
5488 return FALSE;
5489 }
5490 lives_free(dfile);
5491 }
5492 lives_free(current_clips_dir);
5493
5496
5497 retval = rewrite_orderfile(is_append, TRUE, &got_new_handle);
5498
5499 if (retval == LIVES_RESPONSE_CANCEL) {
5501 return FALSE;
5502 }
5503
5504 if (mainw->num_sets > -1) mainw->num_sets++;
5505 if (!*old_set) mainw->set_list = lives_list_prepend(mainw->set_list, mainw->set_name);
5506
5507 if (got_new_handle && !*old_set) migrate_layouts(NULL, mainw->set_name);
5508
5509 if (*old_set && lives_strcmp(old_set, mainw->set_name)) {
5510 layout_map_dir = lives_build_path(prefs->workdir, old_set, LAYOUTS_DIRNAME, NULL);
5511 layout_map_file = lives_build_filename(layout_map_dir, LAYOUT_MAP_FILENAME, NULL);
5512 // update details for layouts - needs_set, current_layout_map and affected_layout_map
5513 if (lives_file_test(layout_map_file, LIVES_FILE_TEST_EXISTS)) {
5514 migrate_layouts(old_set, mainw->set_name);
5515 // save updated layout.map (with new handles), we will move it below
5516
5517 save_layout_map(NULL, NULL, NULL, layout_map_dir);
5518
5519 got_new_handle = FALSE;
5520 }
5521 lives_free(layout_map_file);
5522 lives_free(layout_map_dir);
5523
5524 if (is_append) {
5525 osetn = lives_build_filename(prefs->workdir, old_set, LAYOUTS_DIRNAME, LAYOUT_MAP_FILENAME, NULL);
5526 nsetn = lives_build_filename(prefs->workdir, mainw->set_name, LAYOUTS_DIRNAME, LAYOUT_MAP_FILENAME, NULL);
5527
5528 if (lives_file_test(osetn, LIVES_FILE_TEST_EXISTS)) {
5529 //append current layout.map to target one
5530 lives_cat(osetn, nsetn, TRUE);
5531 lives_rm(osetn);
5532 }
5533 lives_free(osetn);
5534 lives_free(nsetn);
5535 }
5536
5537 osetn = lives_build_path(prefs->workdir, old_set, LAYOUTS_DIRNAME, NULL);
5538
5539 if (lives_file_test(osetn, LIVES_FILE_TEST_IS_DIR)) {
5540 nsetn = lives_build_filename(prefs->workdir, mainw->set_name, NULL);
5541
5542 // move any layouts from old set to new (including layout.map)
5543 lives_cp_keep_perms(osetn, nsetn);
5544
5545 lives_free(nsetn);
5546 }
5547
5548 lives_free(osetn);
5549
5550 // remove the old set (should be empty now)
5551 cleanup_set_dir(old_set);
5552 }
5553
5554 if (!mainw->was_set && !strcmp(old_set, mainw->set_name)) {
5555 // set name was set by export or save layout, now we need to update our layout map
5556 layout_map_dir = lives_build_filename(prefs->workdir, old_set, LAYOUTS_DIRNAME, NULL);
5557 layout_map_file = lives_build_filename(layout_map_dir, LAYOUT_MAP_FILENAME, NULL);
5558 if (lives_file_test(layout_map_file, LIVES_FILE_TEST_EXISTS)) save_layout_map(NULL, NULL, NULL, layout_map_dir);
5559 mainw->was_set = TRUE;
5560 got_new_handle = FALSE;
5561 lives_free(layout_map_dir);
5562 lives_free(layout_map_file);
5564 }
5565
5566 if (mainw->current_layouts_map && strcmp(old_set, mainw->set_name) && !mainw->suppress_layout_warnings) {
5567 // warn the user about layouts if the set name changed
5568 // but, don't bother the user with errors if we are exiting
5570 popup_lmap_errors(NULL, NULL);
5571 }
5572
5574
5575 lives_free(old_set);
5579
5580 // do a lot of cleanup here, but leave files
5581 lives_exit(0);
5583 //end_threaded_dialog();
5584
5586 return TRUE;
5587 }
5588
5589
5590 char *on_load_set_activate(LiVESMenuItem * menuitem, livespointer user_data) {
5591 // get set name (use a modified rename window)
5592 char *set_name = NULL;
5593 LiVESResponseType resp;
5595
5596 if (mainw->multitrack) {
5597 if (mainw->multitrack->idlefunc > 0) {
5599 mainw->multitrack->idlefunc = 0;
5601 }
5603 }
5604
5606 if (!renamew) return NULL;
5607
5608 resp = lives_dialog_run(LIVES_DIALOG(renamew->dialog));
5609
5610 if (resp == LIVES_RESPONSE_OK) {
5611 set_name = U82F(lives_entry_get_text(LIVES_ENTRY(renamew->entry)));
5612 }
5613
5614 // need to clean up renamew
5617 lives_freep((void **)&renamew);
5618
5619 if (resp == LIVES_RESPONSE_OK) {
5620 if (!is_legal_set_name(set_name, TRUE, TRUE)) {
5621 lives_freep((void **)&set_name);
5622 } else {
5623 if (!user_data) {
5624 if (mainw->cliplist)
5625 if (!do_reload_set_query()) return NULL;
5626 reload_set(set_name);
5627 lives_free(set_name);
5628 if (mainw->num_sets > -1) mainw->num_sets--;
5629 return NULL;
5630 }
5631 }
5632 }
5633
5634 return set_name;
5635 }
5636
5637
5638 void lock_set_file(const char *set_name) {
5639 // function is called when a set is opened, to prevent multiple acces to the same set
5640 char *setdir = lives_build_path(prefs->workdir, set_name, NULL);
5641 if (lives_file_test(setdir, LIVES_FILE_TEST_IS_DIR)) {
5642 char *set_lock_file = lives_strdup_printf("%s.%d", SET_LOCK_FILENAME, capable->mainpid);
5643 char *set_locker = SET_LOCK_FILE(set_name, set_lock_file);
5644 lives_touch(set_locker);
5645 lives_free(set_locker);
5646 lives_free(set_lock_file);
5647 }
5648 lives_free(setdir);
5649 }
5650
5651
5652 void unlock_set_file(const char *set_name) {
5653 char *set_lock_file = lives_strdup_printf("%s.%d", SET_LOCK_FILENAME, capable->mainpid);
5654 char *set_locker = SET_LOCK_FILE(set_name, set_lock_file);
5655 lives_rm(set_locker);
5656 lives_free(set_lock_file);
5657 lives_free(set_locker);
5658 }
5659
5660
5661 boolean reload_set(const char *set_name) {
5662 // this is the main clip set loader
5663
5664 // CLIP SET LOADER
5665
5666 // setname should be in filesystem encoding
5667
5668 FILE *orderfile;
5669 lives_clip_t *sfile;
5670
5671 char *msg, *com, *ordfile, *cwd, *clipdir, *handle = NULL;
5672
5673 boolean added_recovery = FALSE;
5674 boolean keep_threaded_dialog = FALSE;
5675 boolean hadbad = FALSE;
5676
5677 int last_file = -1, new_file = -1;
5678 int current_file = mainw->current_file;
5679 int clipnum = 0;
5680 int maxframe;
5682
5683 if (mainw->multitrack) {
5684 if (mainw->multitrack->idlefunc > 0) {
5686 mainw->multitrack->idlefunc = 0;
5688 }
5689 }
5690 lives_memset(mainw->set_name, 0, 1);
5691
5692 // check if set is locked
5693 if (!check_for_lock_file(set_name, 0)) {
5694 if (!mainw->recovering_files) {
5696 if (mainw->multitrack) {
5697 mainw->current_file = mainw->multitrack->render_file;
5700 }
5701 }
5702 return FALSE;
5703 }
5704
5705 lives_snprintf(mainw->msg, MAINW_MSG_SIZE, "none");
5706
5707 // check if we already have a threaded dialog running (i.e. we are called from startup)
5708 if (mainw->threaded_dialog) keep_threaded_dialog = TRUE;
5709
5710 if (prefs->show_gui && !keep_threaded_dialog) {
5711 char *tmp;
5712 msg = lives_strdup_printf(_("Loading clips from set %s"), (tmp = F2U8(set_name)));
5714 lives_free(msg);
5715 lives_free(tmp);
5716 }
5717
5718 ordfile = lives_build_filename(prefs->workdir, set_name, CLIP_ORDER_FILENAME, NULL);
5719
5720 orderfile = fopen(ordfile, "r"); // no we can't assert this, because older sets did not have this file
5721 lives_free(ordfile);
5722
5724 THREADVAR(read_failed) = FALSE;
5725
5726 // lock the set
5727 lock_set_file(set_name);
5728
5729 cwd = lives_get_current_dir();
5730
5731 while (1) {
5733
5735
5736 if (!orderfile) {
5737 // old style (pre 0.9.6)
5738 com = lives_strdup_printf("%s get_next_in_set \"%s\" \"%s\" %d", prefs->backend_sync, mainw->msg,
5739 set_name, capable->mainpid);
5740 lives_system(com, FALSE);
5741 lives_free(com);
5742 } else {
5743 if (!lives_fgets(mainw->msg, MAINW_MSG_SIZE, orderfile)) clear_mainw_msg();
5744 else lives_memset(mainw->msg + lives_strlen(mainw->msg) - 1, 0, 1);
5745 }
5746
5747 if (!(*mainw->msg) || (!strncmp(mainw->msg, "none", 4))) {
5749 if (!keep_threaded_dialog) end_threaded_dialog();
5750
5751 if (orderfile) fclose(orderfile);
5752
5753 //mainw->current_file = current_file;
5754
5755 if (!mainw->multitrack) {
5756 if (last_file > 0) {
5758 switch_to_file(current_file, last_file);
5760 }
5761 }
5762
5763 if (clipnum == 0) {
5764 do_set_noclips_error(set_name);
5765 } else {
5766 char *tmp;
5769
5770 // MUST set set_name before calling this
5772
5773 // TODO - check for missing frames and audio in layouts
5774
5775 if (hadbad) rewrite_orderfile(FALSE, FALSE, NULL);
5776
5777 d_print(_("%d clips and %d layouts were recovered from set (%s).\n"),
5778 clipnum, lives_list_length(mainw->current_layouts_map), (tmp = F2U8(set_name)));
5779 lives_free(tmp);
5780 lives_snprintf(mainw->set_name, MAX_SET_NAME_LEN, "%s", set_name);
5782 }
5783
5785 if (!mainw->multitrack) {
5786 if (mainw->is_ready) {
5787 if (clipnum > 0 && CURRENT_CLIP_IS_VALID) {
5788 showclipimgs();
5789 }
5790 // force a redraw
5793 }
5794 } else {
5795 mainw->current_file = mainw->multitrack->render_file;
5800 }
5801 if (!keep_threaded_dialog) end_threaded_dialog();
5802 lives_chdir(cwd, FALSE);
5803 lives_free(cwd);
5804 if (mainw->multitrack)
5805 mt_clip_select(mainw->multitrack, TRUE); // scroll clip on screen
5806 sensitize();
5807 return TRUE;
5808 }
5809
5810 if (clipnum > 0)
5811 mainw->was_set = TRUE;
5812
5813 if (prefs->crash_recovery && !added_recovery) {
5814 char *recovery_entry = lives_build_filename(set_name, "*", NULL);
5815 add_to_recovery_file(recovery_entry);
5816 lives_free(recovery_entry);
5817 added_recovery = TRUE;
5818 }
5819
5820 clipdir = lives_build_filename(prefs->workdir, mainw->msg, NULL);
5821 if (orderfile) {
5822 // newer style (0.9.6+)
5823
5824 if (!lives_file_test(clipdir, LIVES_FILE_TEST_IS_DIR)) {
5825 lives_free(clipdir);
5826 continue;
5827 }
5829
5830 //create a new cfile and fill in the details
5831 handle = lives_strndup(mainw->msg, 256);
5832 }
5833
5834 // changes mainw->current_file on success
5835 sfile = create_cfile(-1, handle, FALSE);
5836 if (handle) lives_free(handle);
5837 handle = NULL;
5839
5840 if (!sfile) {
5841 lives_free(clipdir);
5843
5844 if (!keep_threaded_dialog) end_threaded_dialog();
5845
5846 if (mainw->multitrack) {
5847 mainw->current_file = mainw->multitrack->render_file;
5852 }
5853
5855 lives_chdir(cwd, FALSE);
5856 lives_free(cwd);
5857 fclose(orderfile);
5858 return FALSE;
5859 }
5860
5861 // get file details
5862 if (!read_headers(mainw->current_file, clipdir, NULL)) {
5867 lives_free(clipdir);
5869 mainw->files[mainw->current_file] = NULL;
5872 hadbad = TRUE;
5873 continue;
5874 }
5875 lives_free(clipdir);
5876
5878
5889 if ((maxframe = load_frame_index(mainw->current_file)) > 0) {
5890 // CLIP_TYPE_FILE
5903 if (!reload_clip(mainw->current_file, maxframe)) {
5905 continue;
5906 }
5907 if (cfile->clip_type == CLIP_TYPE_FILE && cfile->header_version >= 102) cfile->fps = cfile->pb_fps;
5908
5914 if (!cfile->checked && cfile->img_type == IMG_TYPE_UNKNOWN) {
5915 lives_clip_data_t *cdata = ((lives_decoder_t *)cfile->ext_src)->cdata;
5916 int fvirt = count_virtual_frames(cfile->frame_index, 1, cfile->frames);
5922 if (fvirt < cfile->frames) check_clip_integrity(mainw->current_file, cdata, cfile->frames);
5923 }
5924 cfile->checked = TRUE;
5925 } else {
5927
5931 boolean isok = TRUE;
5932 if (!cfile->checked) isok = check_clip_integrity(mainw->current_file, NULL, cfile->frames);
5933 cfile->checked = TRUE;
5937 if (!check_frame_count(mainw->current_file, isok)) {
5938 cfile->frames = get_frame_count(mainw->current_file, 1);
5939 if (cfile->frames == -1) {
5942 continue;
5943 }
5944 cfile->needs_update = TRUE;
5945 }
5946 }
5947
5948 if (!prefs->vj_mode) {
5949 if (cfile->achans > 0 && cfile->afilesize == 0) {
5951 }
5952 }
5953
5954 last_file = new_file;
5955
5956 if (++clipnum == 1) {
5959 lives_snprintf(mainw->set_name, MAX_SET_NAME_LEN, "%s", set_name);
5960 }
5961
5963 open_set_file(clipnum);
5964 if (cfile->clip_type == CLIP_TYPE_FILE && cfile->header_version >= 102) cfile->fps = cfile->pb_fps;
5965
5968
5970 cfile->was_in_set = TRUE;
5971
5972 if (cfile->frameno > cfile->frames) cfile->frameno = cfile->last_frameno = 1;
5973
5974 if (cfile->needs_update || cfile->needs_silent_update) {
5975 if (cfile->needs_update) do_clip_divergence_error(mainw->current_file);
5977 cfile->needs_silent_update = cfile->needs_update = FALSE;
5978 }
5979
5981
5982 if (prefs->autoload_subs) {
5985 }
5986
5988
5989 cfile->saved_frameno = cfile->frameno;
5990 if (cfile->frameno > cfile->frames && cfile->frameno > 1) cfile->frameno = cfile->frames;
5991 cfile->last_frameno = cfile->frameno;
5992
5993 cfile->pointer_time = cfile->real_pointer_time = calc_time_from_frame(mainw->current_file, cfile->frameno);
5994 if (cfile->real_pointer_time > CLIP_TOTAL_TIME(mainw->current_file))
5995 cfile->real_pointer_time = CLIP_TOTAL_TIME(mainw->current_file);
5996 if (cfile->pointer_time > cfile->video_time) cfile->pointer_time = 0.;
5997
5998 if (cfile->achans) {
5999 cfile->aseek_pos = (off64_t)((double)(cfile->real_pointer_time * cfile->arate) * cfile->achans *
6000 (cfile->asampsize / 8));
6001 if (cfile->aseek_pos > cfile->afilesize) cfile->aseek_pos = 0.;
6002 }
6003
6004 // add to clip menu
6007 cfile->start = cfile->frames > 0 ? 1 : 0;
6008 cfile->end = cfile->frames;
6009 cfile->is_loaded = TRUE;
6010 cfile->changed = TRUE;
6011 lives_rm(cfile->info_file);
6012 set_main_title(cfile->name, 0);
6014
6015 if (!mainw->multitrack) {
6016 resize(1);
6017 }
6018
6019 if (mainw->multitrack && mainw->multitrack->is_ready) {
6020 new_file = mainw->current_file;
6021 mainw->current_file = mainw->multitrack->render_file;
6022 mt_init_clips(mainw->multitrack, new_file, TRUE);
6025 }
6026
6028 }
6029
6030 // should never reach here
6031 lives_chdir(cwd, FALSE);
6032 lives_free(cwd);
6033 return TRUE;
6034 }
6035
6036
6037 static void recover_lost_clips(LiVESList * reclist) {
6038 if (!do_foundclips_query()) return;
6039
6040 //d_print_cancelled();
6041
6042 // save set
6044 on_quit_activate(NULL, LIVES_INT_TO_POINTER(1));
6045 if (mainw->clips_available) return;
6046 }
6047
6048 // recover files
6049 mainw->recovery_list = reclist;
6050 recover_files(NULL, TRUE);
6051
6053
6054 if (!CURRENT_CLIP_IS_VALID) {
6055 int start_file;
6056 for (start_file = MAX_FILES; start_file > 0; start_file--) {
6057 if (IS_VALID_CLIP(start_file)
6058 && (mainw->files[start_file]->frames > 0 || mainw->files[start_file]->afilesize > 0)) break;
6059 }
6060 switch_to_file(-1, start_file);
6061 }
6062 do_info_dialogf(P_("$d clip was recovered", "%d clips were recovered\n",
6064 }
6065
6066
6067 static boolean handle_remnants(LiVESList * recnlist, const char *trashremdir, LiVESList **rem_list) {
6068 LiVESResponseType resp;
6069 LiVESList *list = recnlist;
6070 char *unrecdir = lives_build_path(prefs->workdir, UNREC_CLIPS_DIR, NULL);
6071 char *text = lives_strdup_printf(_("Some clips could not be recovered.\n"
6072 "These items can be deleted or moved to the directory\n%s\n"
6073 "What would you like to do with them ?"), unrecdir);
6074 LiVESWidget *dialog = create_question_dialog(_("Unrecoverable Clips"), text), *bbox, *cancelbutton;
6075
6076 lives_free(text);
6077
6078 cancelbutton = lives_dialog_add_button_from_stock(LIVES_DIALOG(dialog), LIVES_STOCK_CANCEL, _("Ignore"),
6079 LIVES_RESPONSE_CANCEL);
6080
6081 lives_dialog_add_button_from_stock(LIVES_DIALOG(dialog), LIVES_STOCK_DELETE, _("Delete them"),
6082 LIVES_RESPONSE_NO);
6083
6084 lives_dialog_add_button_from_stock(LIVES_DIALOG(dialog), LIVES_STOCK_SAVE, _("Move them"),
6085 LIVES_RESPONSE_OK);
6086
6087 bbox = lives_dialog_get_action_area(LIVES_DIALOG(dialog));
6088 trash_rb(LIVES_BUTTON_BOX(bbox));
6089 lives_dialog_add_escape(LIVES_DIALOG(dialog), cancelbutton);
6090
6091 resp = lives_dialog_run(LIVES_DIALOG(dialog));
6092 lives_widget_destroy(dialog);
6094 THREADVAR(com_failed) = FALSE;
6095
6096 if (resp == LIVES_RESPONSE_CANCEL) return FALSE;
6097
6098 if (resp == LIVES_RESPONSE_OK) {
6099 // move from workdir to workdir/unrec
6100 char *from, *to, *norem;
6101 char *ucdir = lives_build_path(prefs->workdir, UNREC_CLIPS_DIR, NULL);
6102 lives_mkdir_with_parents(ucdir, capable->umask);
6103 if (!lives_file_test(ucdir, LIVES_FILE_TEST_IS_DIR)) return FALSE;
6104 norem = lives_build_filename(ucdir, LIVES_FILENAME_NOREMOVE, NULL);
6105 lives_touch(norem);
6106 lives_free(norem);
6107 for (; list; list = list->next) {
6108 from = lives_build_path(prefs->workdir, (char *)list->data, NULL);
6109 to = lives_build_path(ucdir, (char *)list->data, NULL);
6110 lives_mv(from, to);
6111 lives_free(from); lives_free(to);
6112 if (THREADVAR(com_failed)) {
6113 THREADVAR(com_failed) = FALSE;
6114 return FALSE;
6115 }
6116 }
6117 lives_free(ucdir);
6118 } else {
6119 char *tfile;
6120 lives_file_dets_t *fdets;
6121 // touch files in remdir, also prepend to remdir so we dont skip removal
6122 for (; list; list = list->next) {
6123 tfile = lives_build_filename(trashremdir, (char *)list->data, NULL);
6124 lives_touch(tfile);
6125 lives_free(tfile);
6126 if (THREADVAR(com_failed)) {
6127 THREADVAR(com_failed) = FALSE;
6128 return FALSE;
6129 }
6131 fdets->name = lives_strdup((char *)list->data);
6132 *rem_list = lives_list_prepend(*rem_list, fdets);
6133 }
6134 }
6135 return TRUE;
6136 }
6137
6138
6139 void on_cleardisk_activate(LiVESWidget * widget, livespointer user_data) {
6140 // recover disk space
6141 lives_file_dets_t *filedets;
6142 lives_proc_thread_t tinfo;
6143 LiVESTextBuffer *tbuff;
6144 LiVESWidget *top_vbox;
6145
6146 LiVESList *lists[3];
6147 LiVESList **left_list, **rec_list, **rem_list;
6148 LiVESList *list;
6149
6150 int64_t bytes = 0, fspace = -1;
6151 int64_t ds_warn_level = mainw->next_ds_warn_level;
6152
6153 uint64_t ukey;
6154
6155 char *uidgid;
6156 char *trashdir = NULL, *full_trashdir = NULL;
6157
6158 char *markerfile, *filedir;
6159 char *com, *msg, *tmp;
6160 char *extra = lives_strdup("");
6161
6162 LiVESResponseType retval = LIVES_RESPONSE_NONE, resp;
6163
6164 boolean gotsize = FALSE;
6165
6166 int current_file = mainw->current_file;
6167 int marker_fd;
6168 int i, ntok, nitems = 0;
6169
6171
6173
6174 if (user_data) lives_widget_hide(lives_widget_get_toplevel(LIVES_WIDGET(user_data)));
6175
6176 rec_list = &lists[0];
6177 rem_list = &lists[1];
6178 left_list = &lists[2];
6179
6180 *rec_list = *rem_list = *left_list = NULL;
6181
6185 lives_free(extra);
6186 extra = (_("\n\nIf potential missing clips are detected, you will be provided "
6187 "the option to try to recover them\n"
6188 "before they are removed permanently from the disk.\n\n"
6189 "<b>You will also have an opportunity to view and revise the list of items to be removed "
6190 "before continuing.</b>\n"));
6191 }
6193 if (!do_warning_dialogf(
6194 _("LiVES will attempt to recover some disk space.\n"
6195 "Unnecessary files will be removed from %s\n"
6196 "You should <b>ONLY</b> run this if you have no other copies of LiVES running on this machine.\n"
6197 "%s\nClick OK to proceed.\n"), tmp = lives_markup_escape_text(prefs->workdir, -1), extra)) {
6199 lives_free(tmp);
6200 lives_free(extra);
6201 mainw->next_ds_warn_level = ds_warn_level;
6202 goto end;
6203 }
6205 lives_free(extra);
6206
6207 if (CURRENT_CLIP_IS_VALID) cfile->cb_src = current_file;
6208
6210
6211 d_print(_("Cleaning up disk space..."));
6212 // get a temporary clip for receiving data from backend
6213 if (!get_temp_handle(-1)) {
6216 mainw->next_ds_warn_level = ds_warn_level;
6217 return;
6218 }
6219
6220 if (mainw->multitrack) {
6221 if (mainw->multitrack->idlefunc > 0) {
6223 mainw->multitrack->idlefunc = 0;
6225 }
6227 }
6228
6229 ukey = gen_unique_id();
6230 uidgid = lives_strdup_printf("-%d-%d", lives_getuid(), lives_getgid());
6231 trashdir = lives_strdup_printf("%s%lu%s", TRASH_NAME, ukey, uidgid);
6232
6233 for (i = 0; i < MAX_FILES; i++) {
6234 // mark all free-floating files (directories) which we do not want to remove
6235 // we do error checking here
6236 if (mainw->files[i] && *mainw->files[i]->handle) {
6237 filedir = lives_build_path(prefs->workdir, mainw->files[i]->handle, NULL);
6238 if (lives_file_test(filedir, LIVES_FILE_TEST_IS_DIR)) {
6239 markerfile = lives_build_filename(filedir, LIVES_FILENAME_INUSE, NULL);
6240 lives_echo(trashdir, markerfile, FALSE);
6241 lives_free(markerfile);
6242 if (mainw->files[i]->undo_action != UNDO_NONE) {
6243 markerfile = lives_build_filename(filedir, LIVES_FILENAME_NOCLEAN, NULL);
6244 do {
6245 retval = LIVES_RESPONSE_NONE;
6246 marker_fd = creat(markerfile, S_IRUSR | S_IWUSR);
6247 if (marker_fd < 0) {
6248 retval = do_write_failed_error_s_with_retry(markerfile, lives_strerror(errno));
6249 }
6250 } while (retval == LIVES_RESPONSE_RETRY);
6251 if (marker_fd >= 0) close(marker_fd);
6252 lives_free(markerfile);
6253 if (retval == LIVES_RESPONSE_CANCEL) goto cleanup;
6254 // *INDENT-OFF*
6255 }}}}
6256 // *INDENT-ON*
6257
6258 full_trashdir = lives_build_path(prefs->workdir, trashdir, NULL);
6259
6260 do {
6261 resp = LIVES_RESPONSE_NONE;
6262 if (!lives_make_writeable_dir(full_trashdir) || !check_dir_access(full_trashdir, TRUE)) {
6263 resp = do_dir_perm_error(full_trashdir, TRUE);
6264 if (resp == LIVES_RESPONSE_CANCEL) goto cleanup;
6265 }
6266 } while (resp == LIVES_RESPONSE_RETRY);
6267
6268 // get space before
6269 fspace = get_ds_free(prefs->workdir);
6270
6271 //if (prefs->autoclean) {
6272 // clearup old
6274
6275 com = lives_strdup_printf("%s empty_trash %s general %s", prefs->backend, cfile->handle,
6276 TRASH_NAME);
6277 lives_rm(cfile->info_file);
6278 lives_system(com, FALSE);
6279 lives_free(com);
6280 do_auto_dialog(_("Removing general trash"), 0);
6281
6282 THREADVAR(com_failed) = FALSE;
6283
6284 if (CURRENT_CLIP_IS_VALID) lives_rm(cfile->info_file);
6285
6287 "si", _("Analysing Disk"), 0);
6288 tbuff = lives_text_buffer_new();
6289 com = lives_strdup_printf("%s disk_check %s %u %s", prefs->backend, cfile->handle,
6290 prefs->clear_disk_opts, trashdir);
6291 lives_free(uidgid);
6292 lives_popen(com, TRUE, (char *)tbuff, 0);
6293 lives_free(com);
6294
6296
6297 if (*mainw->msg && (ntok = get_token_count(mainw->msg, '|')) > 1) {
6298 char **array = lives_strsplit(mainw->msg, "|", 2);
6299 if (!strcmp(array[0], "completed")) {
6300 nitems = atoi(array[1]);
6301 }
6302 lives_strfreev(array);
6303 }
6304
6305 // remove the protective markers
6306 for (i = 0; i < MAX_FILES; i++) {
6307 if (mainw->files[i] && *mainw->files[i]->handle) {
6308 filedir = lives_build_path(prefs->workdir, mainw->files[i]->handle, NULL);
6309 if (lives_file_test(filedir, LIVES_FILE_TEST_IS_DIR)) {
6310 markerfile = lives_build_filename(prefs->workdir, mainw->files[i]->handle,
6311 LIVES_FILENAME_INUSE, NULL);
6312 lives_rm(markerfile);
6313 lives_free(markerfile);
6314 if (mainw->files[i]->undo_action != UNDO_NONE) {
6315 markerfile = lives_build_filename(prefs->workdir, mainw->files[i]->handle,
6317 lives_rm(markerfile);
6318 lives_free(markerfile);
6319 // *INDENT-OFF*
6320 }}}}
6321 // *INDENT-ON*
6322
6323 if (THREADVAR(com_failed)) {
6324 THREADVAR(com_failed) = FALSE;
6325 } else {
6326 LiVESAccelGroup *accel_group = LIVES_ACCEL_GROUP(lives_accel_group_new());
6327 LiVESWidget *button, *accb, *hbox, *label;
6328 lives_proc_thread_t recinfo, reminfo, leaveinfo;
6329 char *remtrashdir, *op, *from, *to;
6330 int orig;
6331
6332 if (nitems) {
6333 char *dirname = lives_build_path(full_trashdir, TRASH_RECOVER, NULL);
6334 recinfo =
6335 dir_to_file_details(rec_list, dirname, prefs->workdir,
6337 lives_free(dirname);
6338
6339 dirname = lives_build_path(full_trashdir, TRASH_REMOVE, NULL);
6340 reminfo =
6341 dir_to_file_details(rem_list, dirname, prefs->workdir,
6343 lives_free(dirname);
6344
6345 dirname = lives_build_path(full_trashdir, TRASH_LEAVE, NULL);
6346 leaveinfo =
6347 dir_to_file_details(left_list, dirname, prefs->workdir,
6349 lives_free(dirname);
6350 } else {
6351 *rec_list = lives_list_append(*rec_list, NULL);
6352 *rem_list = lives_list_append(*rem_list, NULL);
6353 *left_list = lives_list_append(*left_list, NULL);
6354 }
6355
6357 textwindow = create_text_window(_("Disk Analysis Log"), NULL, tbuff, FALSE);
6359
6360 lives_window_add_accel_group(LIVES_WINDOW(textwindow->dialog), accel_group);
6361
6362 top_vbox = lives_dialog_get_content_area(LIVES_DIALOG(textwindow->dialog));
6363
6364 hbox = lives_hbox_new(FALSE, 0);
6365 lives_box_pack_start(LIVES_BOX(top_vbox), hbox, FALSE, FALSE, widget_opts.packing_height);
6366 msg = lives_strdup_printf(_("\nAnalysis of directory %s complete.\n\n"), prefs->workdir);
6367 label = lives_standard_label_new(msg);
6368 lives_free(msg);
6369
6370 lives_box_pack_start(LIVES_BOX(hbox), label, TRUE, TRUE, 0);
6371 lives_widget_set_halign(label, LIVES_ALIGN_CENTER);
6372
6373 if (!nitems) {
6374 hbox = lives_hbox_new(FALSE, 0);
6375 lives_box_pack_start(LIVES_BOX(top_vbox), hbox, FALSE, FALSE, widget_opts.packing_height);
6376 msg = _("No items to be removed or recovered were detected.\n");
6377 label = lives_standard_label_new(msg);
6378 lives_free(msg);
6379
6380 lives_box_pack_start(LIVES_BOX(hbox), label, TRUE, TRUE, 0);
6381 lives_widget_set_halign(label, LIVES_ALIGN_CENTER);
6382 }
6383
6386
6387 widget_opts.justify = LIVES_JUSTIFY_CENTER;
6388 lives_standard_expander_new(_("Show _Log"), LIVES_BOX(top_vbox),
6389 textwindow->vbox);
6392
6393 add_fill_to_box(LIVES_BOX(top_vbox));
6394
6395 button =
6397 LIVES_STOCK_CANCEL, nitems ? NULL :
6398 LIVES_STOCK_LABEL_CLOSE_WINDOW, LIVES_RESPONSE_CANCEL);
6399
6400 lives_widget_add_accelerator(button, LIVES_WIDGET_CLICKED_SIGNAL, accel_group,
6401 LIVES_KEY_Escape, (LiVESXModifierType)0, (LiVESAccelFlags)0);
6402
6405 LIVES_STOCK_EDIT, nitems ? _("_Check and Filter Results")
6406 : _("Show Results"), LIVES_RESPONSE_BROWSE);
6407
6410
6411 if (nitems) {
6412 LiVESWidget *bbox = lives_dialog_get_action_area(LIVES_DIALOG(textwindow->dialog));
6413 lives_button_box_set_child_non_homogeneous(LIVES_BUTTON_BOX(bbox), button, TRUE);
6414 lives_button_box_set_layout(LIVES_BUTTON_BOX(bbox), LIVES_BUTTONBOX_START);
6415 }
6416
6417 retval = lives_dialog_run(LIVES_DIALOG(textwindow->dialog));
6420
6421 if (retval != LIVES_RESPONSE_CANCEL) {
6422 retval = filter_cleanup(full_trashdir, rec_list, rem_list, left_list);
6423 }
6424
6425 if (!nitems) {
6426 gotsize = TRUE;
6427 goto cleanup;
6428 }
6429
6430 lives_proc_thread_cancel(recinfo);
6431 lives_proc_thread_cancel(reminfo);
6432 lives_proc_thread_cancel(leaveinfo);
6433
6434 if (retval == LIVES_RESPONSE_CANCEL) {
6435 com = lives_strdup_printf("%s restore_trash %s", prefs->backend, trashdir);
6436 lives_system(com, FALSE);
6437 lives_free(com);
6438 goto cleanup;
6439 }
6440
6442
6443 // first we need to move some entries at the list starts
6444 // type now indicates the origin list, since moved entries were prepended
6445 // we can stop when orig == current list
6446
6447 THREADVAR(com_failed) = FALSE;
6448
6449 for (list = *rem_list; list && list->data; list = list->next) {
6450 filedets = (lives_file_dets_t *)list->data;
6451 orig = filedets->type & ~LIVES_FILE_TYPE_FLAG_SPECIAL;
6452 if (orig == 1) break;
6453 to = lives_build_path(full_trashdir, TRASH_REMOVE, filedets->name, NULL);
6454 if (!orig) {
6455 // moved from rec_list to rem_list
6456 from = lives_build_path(full_trashdir, TRASH_RECOVER, filedets->name, NULL);
6457 } else {
6458 // moved from left_list to rem_list
6459 from = lives_build_path(full_trashdir, TRASH_LEAVE, filedets->name, NULL);
6460 }
6461 lives_mv(from, to);
6462 lives_free(from);
6463 lives_free(to);
6464 if (THREADVAR(com_failed)) {
6465 THREADVAR(com_failed) = FALSE;
6466 goto cleanup;
6467 }
6468 }
6469
6470 for (list = *left_list; list && list->data; list = list->next) {
6471 filedets = (lives_file_dets_t *)list->data;
6472 orig = filedets->type;
6473 if (orig == 2) break;
6474 to = lives_build_path(full_trashdir, TRASH_LEAVE, filedets->name, NULL);
6475 if (!orig) {
6476 // moved from rec_list to left_list
6477 from = lives_build_path(full_trashdir, TRASH_RECOVER, filedets->name, NULL);
6478 } else {
6479 // moved from rem_list to left_list
6480 from = lives_build_path(full_trashdir, TRASH_REMOVE, filedets->name, NULL);
6481 }
6482 lives_mv(from, to);
6483 lives_free(from);
6484 lives_free(to);
6485 if (THREADVAR(com_failed)) {
6486 THREADVAR(com_failed) = FALSE;
6487 goto cleanup;
6488 }
6489 }
6490
6491 list = *rec_list;
6492
6493 if (list && list->data) {
6495 // create a list with just the names
6496 LiVESList *recnlist = NULL;
6497
6498 for (; list && list->data; list = list->next) {
6499 filedets = (lives_file_dets_t *)list->data;
6500 if (*filedets->name)
6501 recnlist = lives_list_prepend(recnlist, lives_strdup(filedets->name));
6502 }
6503 recnlist = lives_list_reverse(recnlist);
6504
6505 // close the temporary clip
6506 close_temp_handle(current_file);
6507
6509 recover_lost_clips(recnlist);
6511
6514
6515 for (list = mainw->cliplist; list; list = list->next) {
6516 int clipno = LIVES_POINTER_TO_INT(list->data);
6517 LiVESList *list2 = recnlist;
6518 for (; list2; list2 = list2->next) {
6519 if (!strcmp(mainw->files[clipno]->handle, (char *)list2->data)) {
6520 if (list2->prev) list2->prev->next = list2->next;
6521 if (list2->next) list2->next->prev = list2->prev;
6522 if (recnlist == list2) recnlist = list2->next;
6523 list2->next = list2->prev = NULL;
6524 lives_list_free(list2);
6525 break;
6526 }
6527 }
6528 }
6529
6530 current_file = mainw->current_file;
6531
6532 // get a temporary clip for receiving data from backend
6533 if (!get_temp_handle(-1)) {
6534 lives_list_free_all(&recnlist);
6535 mainw->next_ds_warn_level = ds_warn_level;
6536 goto cleanup;
6537 }
6538
6539 if (recnlist) {
6540 boolean bresp;
6541 remtrashdir = lives_build_path(full_trashdir, TRASH_REMOVE, NULL);
6542
6545 bresp = handle_remnants(recnlist, remtrashdir, rem_list);
6547 if (!bresp) {
6548 // if failed / cancelled, add to left_list
6549 lives_file_dets_t *fdets;
6550 for (list = recnlist; list; list = list->next) {
6552 fdets->name = lives_strdup((char *)list->data);
6553 *left_list = lives_list_prepend(*left_list, fdets);
6554 }
6555 }
6556 lives_list_free_all(&recnlist);
6557 lives_free(remtrashdir);
6558 }
6559 }
6560 // now finally we remove all in rem_list, this is done in the backend
6561 list = *rem_list;
6562 if (list && list->data) {
6563 if (prefs->pref_trash) op = lives_strdup("giotrash");
6564 else op = lives_strdup("delete");
6565
6566 remtrashdir = lives_build_path(trashdir, TRASH_REMOVE, NULL);
6567
6568 if (CURRENT_CLIP_IS_VALID) lives_rm(cfile->info_file);
6569
6571 "si", _("Clearing Disk"), 0);
6572 tbuff = lives_text_buffer_new();
6573
6574 com = lives_strdup_printf("%s empty_trash \"%s\" %s \"%s\"",
6575 prefs->backend, cfile->handle, op, remtrashdir);
6576 lives_free(op);
6577 lives_free(remtrashdir);
6578
6579 lives_popen(com, TRUE, (char *)tbuff, 0);
6580 lives_free(com);
6582
6583 lives_rm(cfile->info_file);
6584 }
6585
6586 if (THREADVAR(com_failed)) {
6587 THREADVAR(com_failed) = FALSE;
6588 goto cleanup;
6589 }
6590
6591 bytes = get_ds_free(prefs->workdir) - fspace;
6592 gotsize = TRUE;
6593 }
6594
6595cleanup:
6596
6597 if (trashdir) lives_free(trashdir);
6598
6599 if (full_trashdir) {
6600 lives_rmdir(full_trashdir, TRUE);
6601 lives_free(full_trashdir);
6602 }
6603
6604 if (*rec_list) free_fdets_list(rec_list);
6605
6606 // close the temporary clip
6607 close_temp_handle(current_file);
6608
6609 if (bytes < 0) bytes = 0;
6611
6612 if (gotsize && retval != LIVES_RESPONSE_CANCEL && !THREADVAR(com_failed) && fspace > -1) {
6613 LiVESWidget *dialog, *tview;
6614
6615 d_print_done();
6616
6617 msg = lives_strdup_printf(_("%s of disk space was recovered.\n"),
6618 lives_format_storage_space_string((uint64_t)bytes));
6619
6620 dialog = create_message_dialog(LIVES_DIALOG_INFO, msg, 0);
6621 lives_free(msg);
6622
6623 list = *rem_list;
6624 top_vbox = lives_dialog_get_content_area(LIVES_DIALOG(dialog));
6625
6626 if (list && list->data) {
6629 tview = scrolled_textview(NULL, tbuff, RFX_WINSIZE_H * 2, NULL);
6631 widget_opts.justify = LIVES_JUSTIFY_CENTER;
6632 lives_standard_expander_new(_("Show _Log"), LIVES_BOX(top_vbox), tview);
6634 }
6635
6636 list = *left_list;
6637
6638 if (list && list->data) {
6639 char *text = NULL, *item;
6640 LiVESWidget *label = lives_standard_label_new(_("Some files and directories may be removed manually "
6641 "if desired.\nClick for details:\n"));
6642 LiVESWidget *hbox = lives_hbox_new(FALSE, 0);
6643
6644 lives_box_pack_start(LIVES_BOX(top_vbox), hbox, FALSE, FALSE, widget_opts.packing_height);
6645 lives_box_pack_start(LIVES_BOX(hbox), label, TRUE, TRUE, 0);
6646 lives_widget_set_halign(label, LIVES_ALIGN_CENTER);
6647
6648 for (; list && list->data; list = list->next) {
6649 filedets = (lives_file_dets_t *)list->data;
6650 item = lives_build_path(prefs->workdir, filedets->name, NULL);
6651 text = lives_concat_sep(text, "\n", item);
6652 }
6653
6655 tview = scrolled_textview(text, NULL, RFX_WINSIZE_H * 2, NULL);
6657 lives_free(text);
6658
6659 widget_opts.justify = LIVES_JUSTIFY_CENTER;
6660 lives_standard_expander_new(_("Show _Remaining Items"),
6661 LIVES_BOX(top_vbox), tview);
6663 }
6664
6665 lives_dialog_run(LIVES_DIALOG(dialog));
6666 } else {
6667 if (retval != LIVES_RESPONSE_CANCEL) d_print_failed();
6668 else d_print_cancelled();
6669 }
6670
6671 if (*rem_list) free_fdets_list(rem_list);
6672 if (*left_list) free_fdets_list(left_list);
6673
6674 mainw->next_ds_warn_level = ds_warn_level;
6675
6676 if (user_data) {
6679 mainw->dsu_valid = TRUE;
6680 lives_idle_add_simple(update_dsu, NULL);
6681 }
6682 lives_widget_show(lives_widget_get_toplevel(LIVES_WIDGET(user_data)));
6683 } else {
6685 sensitize();
6686 }
6687
6688
6689end:
6690 if (mainw->multitrack) {
6694 // *INDENT-OFF*
6695 }}}
6696 // *INDENT-ON*
6697 }
6698
6699
6700 void on_cleardisk_advanced_clicked(LiVESWidget * widget, livespointer user_data) {
6701 // make cleardisk adv window
6702
6703 // show various options and OK/Cancel button
6704
6705 // on OK set clear_disk opts
6706 int response;
6707 LiVESWidget *dialog;
6708 do {
6710 lives_widget_show_all(dialog);
6711 response = lives_dialog_run(LIVES_DIALOG(dialog));
6712 lives_widget_destroy(dialog);
6713 if (response == LIVES_RESPONSE_RETRY) prefs->clear_disk_opts = 0;
6714 } while (response == LIVES_RESPONSE_RETRY);
6715
6717 }
6718
6719
6720 void on_show_keys_activate(LiVESMenuItem * menuitem, livespointer user_data) {do_keys_window();}
6721
6722
6723 void on_vj_realize_activate(LiVESMenuItem * menuitem, livespointer user_data) {
6724 frames_t ret;
6725 char *msg = (_("Pre-decoding all frames in this clip..."));
6726 d_print(msg);
6727
6728 desensitize();
6729
6731 lives_free(msg);
6732 if (ret <= 0) d_print_failed();
6733 else if (ret < cfile->frames) d_print_enough(ret);
6734 else d_print_done();
6735
6736 sensitize();
6737 }
6738
6739
6740 void on_vj_reset_activate(LiVESMenuItem * menuitem, livespointer user_data) {
6741 LiVESList *clip_list = mainw->cliplist;
6742
6743 boolean bad_header = FALSE;
6744
6745 int i;
6746
6747 //mainw->soft_debug=TRUE;
6748
6749 do_threaded_dialog(_("Resetting frame rates and frame values..."), FALSE);
6750
6751 while (clip_list) {
6752 i = LIVES_POINTER_TO_INT(clip_list->data);
6753 mainw->files[i]->pb_fps = mainw->files[i]->fps;
6754 mainw->files[i]->frameno = 1;
6755 mainw->files[i]->aseek_pos = 0;
6756
6757 if (!save_clip_value(i, CLIP_DETAILS_PB_FPS, &mainw->files[i]->fps)) bad_header = TRUE;
6758 if (!save_clip_value(i, CLIP_DETAILS_PB_FRAMENO, &mainw->files[i]->frameno)) bad_header = TRUE;
6759
6760 threaded_dialog_spin((double)i / (double)mainw->clips_available);
6761
6762 if (bad_header) {
6763 if (!do_header_write_error(i)) break;
6764 } else clip_list = clip_list->next;
6765 }
6766
6768 }
6769
6770
6771 void on_show_messages_activate(LiVESMenuItem * menuitem, livespointer user_data) {
6773 }
6774
6775
6776 void on_show_file_info_activate(LiVESMenuItem * menuitem, livespointer user_data) {
6777 char buff[512];
6778 lives_clipinfo_t *filew;
6779
6780 char *sigs, *ends, *tmp;
6781
6782 if (!CURRENT_CLIP_IS_VALID) return;
6783
6784 filew = create_clip_info_window(cfile->achans, FALSE);
6785
6786 if (cfile->frames > 0) {
6787 // type
6788 lives_snprintf(buff, 512, _("External: %s\nInternal: %s (%d bpp) / %s"), cfile->type,
6789 (tmp = lives_strdup((cfile->clip_type == CLIP_TYPE_YUV4MPEG ||
6790 cfile->clip_type == CLIP_TYPE_VIDEODEV) ? (_("buffered")) :
6793 lives_free(tmp);
6794
6795 if (cfile->clip_type == CLIP_TYPE_FILE) {
6796 lives_decoder_t *dplug = (lives_decoder_t *)cfile->ext_src;
6798 const char *decname = dpsys->name;
6799 lives_strappendf(buff, 512, _("\ndecoder: %s"), decname);
6800 }
6801 lives_text_view_set_text(LIVES_TEXT_VIEW(filew->textview_type), buff, -1);
6802 // fps
6803 lives_snprintf(buff, 512, " %.3f%s", cfile->fps, cfile->ratio_fps ? "..." : "");
6804
6805 lives_text_view_set_text(LIVES_TEXT_VIEW(filew->textview_fps), buff, -1);
6806 // image size
6807 lives_snprintf(buff, 512, " %dx%d", cfile->hsize, cfile->vsize);
6808 lives_text_view_set_text(LIVES_TEXT_VIEW(filew->textview_size), buff, -1);
6809 // frames
6810 if ((cfile->opening && !cfile->opening_audio && cfile->frames == 0) || cfile->frames == 123456789) {
6811 lives_snprintf(buff, 512, "%s", _(" Opening..."));
6812 } else {
6813 lives_snprintf(buff, 512, " %d", cfile->frames);
6814
6815 if (cfile->frame_index) {
6816 int fvirt = count_virtual_frames(cfile->frame_index, 1, cfile->frames);
6817 char *tmp = lives_strdup_printf(_("\n(%d virtual)"), fvirt);
6818 lives_strappend(buff, 512, tmp);
6819 lives_free(tmp);
6820 tmp = lives_strdup_printf(_("\n(%d decoded)"), cfile->frames - fvirt);
6821 lives_strappend(buff, 512, tmp);
6822 lives_free(tmp);
6823 }
6824
6825 }
6826 lives_text_view_set_text(LIVES_TEXT_VIEW(filew->textview_frames), buff, -1);
6827 // video time
6828 if ((cfile->opening && !cfile->opening_audio && cfile->frames == 0) || cfile->frames == 123456789) {
6829 lives_snprintf(buff, 512, "%s", _(" Opening..."));
6830 } else {
6831 lives_snprintf(buff, 512, _(" %.2f sec."), cfile->video_time);
6832 }
6833 lives_text_view_set_text(LIVES_TEXT_VIEW(filew->textview_vtime), buff, -1);
6834 // file size
6835 if (cfile->f_size > 0l) {
6836 char *file_ds = lives_format_storage_space_string((uint64_t)cfile->f_size);
6837 lives_snprintf(buff, 512, " %s", file_ds);
6838 lives_free(file_ds);
6839 } else lives_snprintf(buff, 512, "%s", _(" Unknown"));
6840 lives_text_view_set_text(LIVES_TEXT_VIEW(filew->textview_fsize), buff, -1);
6841 }
6842
6843 if (cfile->achans > 0) {
6844 if (cfile->opening) {
6845 lives_snprintf(buff, 512, "%s", _(" Opening..."));
6846 } else {
6847 lives_snprintf(buff, 512, _(" %.2f sec."), cfile->laudio_time);
6848 }
6849 lives_text_view_set_text(LIVES_TEXT_VIEW(filew->textview_ltime), buff, -1);
6850
6851 if (cfile->signed_endian & AFORM_UNSIGNED) sigs = (_("unsigned"));
6852 else sigs = (_("signed"));
6853
6854 if (cfile->signed_endian & AFORM_BIG_ENDIAN) ends = (_("big-endian"));
6855 else ends = (_("little-endian"));
6856
6857 lives_snprintf(buff, 512, _(" %d Hz %d bit\n%s %s"), cfile->arate, cfile->asampsize, sigs, ends);
6858 lives_text_view_set_text(LIVES_TEXT_VIEW(filew->textview_lrate), buff, -1);
6859
6860 lives_free(sigs);
6861 lives_free(ends);
6862 }
6863
6864 if (cfile->achans > 1) {
6865 if (cfile->signed_endian & AFORM_UNSIGNED) sigs = (_("unsigned"));
6866 else sigs = (_("signed"));
6867
6868 if (cfile->signed_endian & AFORM_BIG_ENDIAN) ends = (_("big-endian"));
6869 else ends = (_("little-endian"));
6870
6871 lives_snprintf(buff, 512, _(" %d Hz %d bit\n%s %s"), cfile->arate, cfile->asampsize, sigs, ends);
6872 lives_text_view_set_text(LIVES_TEXT_VIEW(filew->textview_rrate), buff, -1);
6873
6874 lives_free(sigs);
6875 lives_free(ends);
6876
6877 if (cfile->opening) {
6878 lives_snprintf(buff, 512, "%s", _(" Opening..."));
6879 } else {
6880 lives_snprintf(buff, 512, _(" %.2f sec."), cfile->raudio_time);
6881 }
6882 lives_text_view_set_text(LIVES_TEXT_VIEW(filew->textview_rtime), buff, -1);
6883 }
6884 }
6885
6886
6887 void on_show_file_comments_activate(LiVESMenuItem * menuitem, livespointer user_data) {
6889 }
6890
6891
6892 void on_show_clipboard_info_activate(LiVESMenuItem * menuitem, livespointer user_data) {
6893 int current_file = mainw->current_file;
6894 mainw->current_file = 0;
6895 on_show_file_info_activate(menuitem, user_data);
6896 mainw->current_file = current_file;
6897 }
6898
6899
6900 void switch_clip(int type, int newclip, boolean force) {
6901 // generic switch clip callback
6902
6903 // This is the new single entry function for switching clips.
6904 // It should eventually replace switch_to_file() and do_quick_switch()
6905
6906 // type = 0 : if we are playing and a transition is active, this will change the background clip
6907 // type = 1 fg only
6908 // type = 2 bg only
6909
6911 (mainw->is_processing && cfile && cfile->is_loaded) || !mainw->cliplist) return;
6912
6913 mainw->blend_palette = WEED_PALETTE_END;
6914
6915 if (type == 2 || (mainw->active_sa_clips == SCREEN_AREA_BACKGROUND && mainw->playing_file > 0 && type != 1
6917 if (mainw->num_tr_applied < 1 || newclip == mainw->blend_file) return;
6918
6919 // switch bg clip
6923 weed_plant_t *inst = mainw->files[mainw->blend_file]->ext_src;
6924 if (inst) {
6925 mainw->osc_block = TRUE;
6926 if (weed_plant_has_leaf(inst, WEED_LEAF_HOST_KEY)) {
6927 int key = weed_get_int_value(inst, WEED_LEAF_HOST_KEY, NULL);
6928 rte_key_on_off(key + 1, FALSE);
6929 }
6931 }
6932 }
6933
6934 //chill_decoder_plugin(mainw->blend_file);
6935 mainw->blend_file = newclip;
6939 }
6940 mainw->blend_palette = WEED_PALETTE_END;
6941 return;
6942 }
6943
6944 // switch fg clip
6945
6946 if (!force && (newclip == mainw->current_file && (!LIVES_IS_PLAYING || mainw->playing_file == newclip))) return;
6947 if (cfile && !cfile->is_loaded) mainw->cancelled = CANCEL_NO_PROPOGATE;
6948
6949 if (LIVES_IS_PLAYING) {
6950 mainw->new_clip = newclip;
6951 mainw->blend_palette = WEED_PALETTE_END;
6952 } else {
6953 if (!cfile || (force && newclip == mainw->current_file)) mainw->current_file = -1;
6955 }
6956 }
6957
6958
6959 void switch_clip_activate(LiVESMenuItem * menuitem, livespointer user_data) {
6960 // switch clips from the clips menu
6961
6962 register int i;
6963 if (mainw->current_file < 1 || mainw->preview || (mainw->is_processing && cfile->is_loaded) || !mainw->cliplist) return;
6964
6965 for (i = 1; i < MAX_FILES; i++) {
6966 if (mainw->files[i]) {
6967 if (LIVES_MENU_ITEM(menuitem) == LIVES_MENU_ITEM(mainw->files[i]->menuentry) &&
6968 lives_check_menu_item_get_active(LIVES_CHECK_MENU_ITEM(mainw->files[i]->menuentry))) {
6969 switch_clip(0, i, FALSE);
6970 return;
6971 // *INDENT-OFF*
6972 }}}
6973 // *INDENT-ON*
6974 }
6975
6976
6977 void on_about_activate(LiVESMenuItem * menuitem, livespointer user_data) {
6978
6979#ifdef GUI_GTK
6980#if GTK_CHECK_VERSION(2, 14, 0)
6981 char *license = (_(
6982 "This program is free software; you can redistribute it and/or modify\n"
6983 "it under the terms of the GNU General Public License as published by\n"
6984 "the Free Software Foundation; either version 3 of the License, or\n"
6985 "(at your option) any later version.\n"
6986 "\n"
6987 "This program is distributed in the hope that it will be useful,\n"
6988 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
6989 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
6990 "GNU General Public License for more details.\n"
6991 "\n"
6992 "You should have received a copy of the GNU General Public License\n"
6993 "along with this program; if not, write to the Free Software\n"
6994 "Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA.\n"));
6995
6996 char *comments = (_("A video editor and VJ program."));
6997 char *title = (_("About LiVES"));
6998
6999 char *translator_credits = (_("translator_credits"));
7000
7001#if GTK_CHECK_VERSION(3, 0, 0)
7002 char *authors[2] = {LIVES_AUTHOR_EMAIL, NULL};
7003#else
7004 gtk_about_dialog_set_url_hook(activate_url, NULL, NULL);
7005 gtk_about_dialog_set_email_hook(activate_url, NULL, NULL);
7006#endif
7007
7008 gtk_show_about_dialog(LIVES_WINDOW(LIVES_MAIN_WINDOW_WIDGET),
7009 "logo", NULL,
7010 "name", PACKAGE_NAME,
7011 "version", LiVES_VERSION,
7012 "comments", comments,
7013 "copyright", "(C) "LIVES_COPYRIGHT_YEARS" salsaman <"LIVES_AUTHOR_EMAIL"> and others",
7014 "website", LIVES_WEBSITE,
7015 "license", license,
7016 "title", title,
7017 "translator_credits", translator_credits,
7018#if GTK_CHECK_VERSION(3, 0, 0)
7019 "authors", authors,
7020 "license-type", GTK_LICENSE_GPL_3_0,
7021#endif
7022 NULL);
7023
7024 lives_free(translator_credits);
7025 lives_free(comments);
7026 lives_free(title);
7027 lives_free(license);
7028 return;
7029#endif
7030#endif
7032 do_error_dialogf(_("LiVES Version %s\n"
7033 "(c) G. Finch (salsaman) %s\n\n"
7034 "Released under the GPL 3 or later (http://www.gnu.org/licenses/gpl.txt)\n"
7035 "LiVES is distributed WITHOUT WARRANTY\n\n"
7036 "Contact the author at:\n%s\n"
7037 "Homepage: %s"),
7040 }
7041
7042
7043 void show_manual_activate(LiVESMenuItem * menuitem, livespointer user_data) {
7044 show_manual_section(NULL, NULL);
7045 }
7046
7047
7048 void email_author_activate(LiVESMenuItem * menuitem, livespointer user_data) {
7050 }
7051
7052
7053 void report_bug_activate(LiVESMenuItem * menuitem, livespointer user_data) {
7055 }
7056
7057
7058 void suggest_feature_activate(LiVESMenuItem * menuitem, livespointer user_data) {
7060 }
7061
7062
7063 void help_translate_activate(LiVESMenuItem * menuitem, livespointer user_data) {
7065 }
7066
7067
7068 void donate_activate(LiVESMenuItem * menuitem, livespointer user_data) {
7069 const char *link = lives_strdup_printf("%s%s", LIVES_DONATE_URL, !user_data ? "" : (char *)user_data);
7070 activate_url_inner(link);
7071 }
7072
7073
7074 static char *fsp_ltext;
7075 static char *fsp_info_file;
7076 static char *file_open_params;
7077
7078 static boolean fs_preview_idle(void *data) {
7079 LiVESWidget *widget = (LiVESWidget *)data;
7080 FILE *ifile;
7081
7082 if (!(ifile = fopen(fsp_info_file, "r")) && mainw->in_fs_preview && mainw->fc_buttonresponse
7083 == LIVES_RESPONSE_NONE) {
7084 return TRUE;
7085 }
7086
7088
7089 if (LIVES_IS_BUTTON(widget))
7090 lives_button_set_label(LIVES_BUTTON(widget), fsp_ltext);
7092 lives_free(fsp_ltext);
7093
7094 if (ifile) {
7095 fclose(ifile);
7096 }
7097
7099 lives_free(fsp_info_file);
7100
7101 lives_freep((void **)&file_open_params);
7102 if (LIVES_IS_WIDGET(widget))
7104 return FALSE;
7105 }
7106
7107
7108 void on_fs_preview_clicked(LiVESWidget * widget, livespointer user_data) {
7109 // file selector preview
7110 double start_time = 0.;
7111
7112 uint64_t xwin = 0;
7113
7114 char **array;
7115
7116 int preview_frames = 0;
7117 int preview_type = LIVES_POINTER_TO_INT(user_data);
7118 int height = 0, width = 0;
7119 int fwidth = -1, fheight = -1;
7120 int owidth, oheight, npieces, border = 0;
7121 boolean with_audio = mainw->save_with_sound;
7122
7123 char *thm_dir = NULL;
7124 char *tmp, *tmp2;
7125 char *com;
7126 char *type;
7127
7128 file_open_params = NULL;
7129
7130 if (mainw->in_fs_preview) {
7132 return;
7133 }
7134 fsp_ltext = NULL;
7135
7139 return;
7140 }
7141
7142 if (preview_type == LIVES_PREVIEW_TYPE_RANGE) {
7143 // open selection
7144 start_time = mainw->fx1_val;
7145 preview_frames = (int)mainw->fx2_val;
7146 } else {
7147 // open file
7148 lives_snprintf(file_name, PATH_MAX, "%s",
7149 (tmp = lives_filename_to_utf8((tmp2
7150 = lives_file_chooser_get_filename(LIVES_FILE_CHOOSER(lives_widget_get_toplevel(widget)))),
7151 -1, NULL, NULL, NULL)));
7152 lives_free(tmp);
7153 lives_free(tmp2);
7154 }
7155
7156 // get file detaisl
7157 if (!read_file_details_generic(file_name)) return;
7158
7159 npieces = get_token_count(mainw->msg, '|');
7160 if (npieces < 4) {
7162 return;
7163 }
7164 array = lives_strsplit(mainw->msg, "|", npieces);
7165 type = lives_strdup(array[3]);
7166
7167 if (npieces > 5) {
7168 width = atoi(array[4]);
7169 height = atoi(array[5]);
7170 }
7171 lives_strfreev(array);
7172
7173 if (!strcmp(type, "image") || !strcmp(type, prefs->image_type)) {
7174 if (preview_type == LIVES_PREVIEW_TYPE_VIDEO_AUDIO || preview_type == LIVES_PREVIEW_TYPE_IMAGE_ONLY) {
7176
7177 thm_dir = get_worktmp("_thm");
7178
7179 if (thm_dir && capable->has_identify) {
7180 mainw->error = FALSE;
7181
7184
7185 // make thumb from any image file
7186
7187 com = lives_strdup_printf("%s make_thumb %s %d %d \"%s\" \"%s\"", prefs->backend_sync, thm_dir, fwidth,
7188 fheight, prefs->image_ext, (tmp = lives_filename_from_utf8(file_name, -1, NULL, NULL, NULL)));
7189 lives_free(tmp);
7190
7192 lives_free(com);
7193
7194 npieces = get_token_count(mainw->msg, '|');
7195 if (npieces < 3) {
7196 THREADVAR(com_failed) = FALSE;
7198 return;
7199 }
7200 if (!THREADVAR(com_failed)) {
7201 array = lives_strsplit(mainw->msg, "|", 3);
7202 width = atoi(array[1]);
7203 height = atoi(array[2]);
7204 lives_strfreev(array);
7205 } else height = width = 0;
7206 THREADVAR(com_failed) = FALSE;
7207 } else {
7208 height = width = 0;
7209 }
7210
7211 if (height > 0 && width > 0) {
7212 // draw image
7213 LiVESXWindow *xwin;
7214 LiVESError *error = NULL;
7215 char *thumbfile = lives_strdup_printf("%08d.%s", 1, prefs->image_ext);
7216 char *thumb = lives_build_filename(prefs->workdir, thm_dir, thumbfile, NULL);
7217 LiVESPixbuf *pixbuf = lives_pixbuf_new_from_file((tmp = lives_filename_from_utf8(thumb, -1, NULL, NULL, NULL)), &error);
7218 lives_free(thumbfile);
7219 lives_free(thumb);
7220 lives_free(tmp);
7221 if (!error) {
7222 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(mainw->fs_playimg), "pixbuf", pixbuf);
7223 owidth = width;
7224 oheight = height;
7225
7226 calc_maxspect(fwidth, fheight, &width, &height);
7227
7228 width = (width >> 1) << 1;
7229 height = (height >> 1) << 1;
7230
7231 if (width > owidth || height > oheight) {
7232 width = owidth;
7233 height = oheight;
7234 }
7235
7236 if (width < 4 || height < 4) {
7239 return;
7240 }
7242 lives_alignment_set(mainw->fs_playalign, 0.5, 0.5, (float)width / (float)fwidth,
7243 (float)height / (float)fheight);
7244 border = MIN(fwidth - width, fheight - height);
7245 lives_container_set_border_width(LIVES_CONTAINER(mainw->fs_playarea), border >> 1);
7249 if (LIVES_IS_XWINDOW(xwin)) {
7252 lives_xwindow_create_similar_surface(xwin, LIVES_PAINTER_CONTENT_COLOR,
7253 width, height);
7254 if (mainw->fsp_func == 0)
7255 mainw->fsp_func = lives_signal_sync_connect(LIVES_GUI_OBJECT(mainw->fs_playimg), LIVES_WIDGET_EXPOSE_EVENT,
7256 LIVES_GUI_CALLBACK(all_expose), &mainw->fsp_surface);
7257 }
7259 } else {
7260 lives_error_free(error);
7261 }
7262 }
7263
7264 if (thm_dir) {
7265 lives_rmdir(thm_dir, TRUE);
7266 lives_free(thm_dir);
7267 }
7268 if (height > 0 || width > 0 || preview_type == LIVES_PREVIEW_TYPE_IMAGE_ONLY) {
7270 return;
7271 }
7272 }
7273 return;
7274 }
7275
7279
7280 if (!HAS_EXTERNAL_PLAYER) {
7281 char *msg;
7283 msg = (_("\n\nYou need to install mplayer, mplayer2 or mpv to be able to preview this file.\n"));
7284 } else {
7285 msg = (_("\n\nYou need to install mplayer, mplayer2, mpv or imageMagick to be able to preview this file.\n"));
7286 }
7287 do_error_dialog(msg);
7288 lives_free(msg);
7290 return;
7291 }
7292
7293 mainw->fsp_tmpdir = get_worktmp("_fsp");
7294
7295 if (!mainw->fsp_tmpdir) {
7298 return;
7299 }
7300
7301 fsp_info_file = lives_build_filename(mainw->fsp_tmpdir, LIVES_STATUS_FILE_NAME, NULL);
7302
7304
7305 if (preview_type != LIVES_PREVIEW_TYPE_AUDIO_ONLY) {
7306 if (!strcmp(type, "Audio")) {
7307 preview_frames = -1;
7308 } else {
7309 if (height == 0 || width == 0) {
7310 width = DEF_FRAME_HSIZE / 2;
7311 height = DEF_FRAME_VSIZE / 2;
7312 }
7313
7314 owidth = width;
7315 oheight = height;
7316
7319
7320 calc_maxspect(fwidth, fheight, &width, &height);
7321
7322 width = (width >> 1) << 1;
7323 height = (height >> 1) << 1;
7324
7325 if (width > owidth || height > oheight) {
7326 width = owidth;
7327 height = oheight;
7328 }
7329
7330 if (width < 4 || height < 4) {
7333 return;
7334 }
7335 lives_widget_set_bg_color(mainw->fs_playframe, LIVES_WIDGET_STATE_NORMAL, &palette->black);
7337 lives_alignment_set(mainw->fs_playalign, 0.5, 0.5, (float)width / (float)fwidth,
7338 (float)height / (float)fheight);
7339 border = MIN(fwidth - width, fheight - height);
7340 lives_container_set_border_width(LIVES_CONTAINER(mainw->fs_playarea), border >> 1);
7342 }
7343 } else preview_frames = -1;
7344
7345 if (!USE_MPV) {
7346 if (with_audio && prefs->audio_player == AUD_PLAYER_JACK) {
7347 file_open_params = lives_strdup_printf("%s %s -ao jack", mainw->file_open_params != NULL ?
7349 } else if (with_audio && prefs->audio_player == AUD_PLAYER_PULSE) {
7350 file_open_params = lives_strdup_printf("%s %s -ao pulse", mainw->file_open_params != NULL ?
7352 } else {
7353 file_open_params = lives_strdup_printf("%s %s -ao null", mainw->file_open_params != NULL ?
7355 }
7356 } else {
7357 if (with_audio && prefs->audio_player == AUD_PLAYER_JACK) {
7358 file_open_params = lives_strdup_printf("%s %s --ao=jack", mainw->file_open_params != NULL ?
7360 } else if (with_audio && prefs->audio_player == AUD_PLAYER_PULSE) {
7361 file_open_params = lives_strdup_printf("%s %s --ao=pulse", mainw->file_open_params != NULL ?
7363 } else {
7364 file_open_params = lives_strdup_printf("%s %s --ao=null", mainw->file_open_params != NULL ?
7366 }
7367 }
7368
7369 if (preview_type == LIVES_PREVIEW_TYPE_VIDEO_AUDIO || preview_type == LIVES_PREVIEW_TYPE_RANGE) {
7370 xwin = lives_widget_get_xwinid(mainw->fs_playarea, "Unsupported display type for preview.");
7371 if (xwin == -1) {
7373 lives_free(fsp_info_file);
7375 return;
7376 }
7377 }
7378
7379 if (file_open_params) {
7380 com = lives_strdup_printf("%s fs_preview %s %"PRIu64" %d %d %.2f %d %d \"%s\" \"%s\"", prefs->backend, mainw->fsp_tmpdir,
7381 xwin, width, height, start_time, preview_frames, (int)(prefs->volume * 100.),
7382 (tmp = lives_filename_from_utf8(file_name, -1, NULL, NULL, NULL)), file_open_params);
7383
7384 } else {
7385 com = lives_strdup_printf("%s fs_preview %s %"PRIu64" %d %d %.2f %d %d \"%s\"", prefs->backend, mainw->fsp_tmpdir,
7386 xwin, width, height, start_time, preview_frames, (int)(prefs->volume * 100.),
7387 (tmp = lives_filename_from_utf8(file_name, -1, NULL, NULL, NULL)));
7388 }
7389
7390 lives_free(tmp);
7392 lives_rm(fsp_info_file);
7393 lives_system(com, FALSE);
7394 lives_free(com);
7395
7396 if (THREADVAR(com_failed)) {
7397 THREADVAR(com_failed) = FALSE;
7399 lives_free(fsp_info_file);
7401 return;
7402 }
7403
7404 tmp = (_("\nStop Preview\n"));
7405 fsp_ltext = lives_strdup(lives_button_get_label(LIVES_BUTTON(widget)));
7407 lives_button_set_label(LIVES_BUTTON(widget), tmp);
7408 if (preview_type == LIVES_PREVIEW_TYPE_RANGE) {
7410 }
7411 lives_free(tmp);
7412
7413 // loop here until preview has finished, or the user presses OK or Cancel
7414 lives_idle_add_simple(fs_preview_idle, (livespointer)widget);
7415 }
7416
7417
7418 void on_open_activate(LiVESMenuItem * menuitem, livespointer user_data) {
7419 // OPEN A FILE (single or multiple)
7420 LiVESWidget *chooser;
7421 LiVESResponseType resp;
7423
7424 if (mainw->multitrack) {
7425 if (mainw->multitrack->idlefunc > 0) {
7427 mainw->multitrack->idlefunc = 0;
7429 }
7433 }
7434
7435 chooser = choose_file_with_preview((*mainw->vid_load_dir) ? mainw->vid_load_dir : NULL, NULL, NULL,
7437
7438 resp = lives_dialog_run(LIVES_DIALOG(chooser));
7439
7441
7442 if (resp == LIVES_RESPONSE_ACCEPT) on_ok_file_open_clicked(LIVES_FILE_CHOOSER(chooser), NULL);
7443 else on_filechooser_cancel_clicked(chooser);
7444 }
7445
7446
7447 void on_ok_file_open_clicked(LiVESFileChooser * chooser, LiVESSList * fnames) {
7448 // this is also called from drag target
7449
7450 LiVESSList *ofnames;
7451
7452 if (chooser) {
7453 fnames = lives_file_chooser_get_filenames(chooser);
7454
7455 lives_widget_destroy(LIVES_WIDGET(chooser));
7456
7457 if (!fnames) return;
7458
7459 if (!fnames->data) {
7460 lives_list_free_all((LiVESList **)&fnames);
7461 return;
7462 }
7463
7464 lives_snprintf(mainw->vid_load_dir, PATH_MAX, "%s", (char *)fnames->data);
7466
7468
7469 if (prefs->save_directories) {
7471 }
7472
7474 }
7475
7476 ofnames = fnames;
7477 mainw->img_concat_clip = -1;
7478
7479 while (fnames && mainw->cancelled == CANCEL_NONE) {
7480 lives_snprintf(file_name, PATH_MAX, "%s", (char *)fnames->data);
7481 lives_free((livespointer)fnames->data);
7482 open_file(file_name);
7483 fnames = fnames->next;
7484 }
7485
7486 lives_slist_free(ofnames);
7487
7489 mainw->img_concat_clip = -1;
7490
7491 if (mainw->multitrack) {
7496 }
7497 }
7498
7499
7500#ifdef GUI_GTK
7501 // TODO
7502 // files dragged onto target from outside - try to open them
7503 void drag_from_outside(LiVESWidget * widget, GdkDragContext * dcon, int x, int y,
7504 GtkSelectionData * data, uint32_t info, uint32_t time, livespointer user_data) {
7505 GSList *fnames = NULL;
7506#if GTK_CHECK_VERSION(3, 0, 0)
7507 char *filelist = (char *)gtk_selection_data_get_data(data);
7508#else
7509 char *filelist = (char *)data->data;
7510#endif
7511 char *nfilelist, **array;
7512 int nfiles, i;
7513
7514 if (!filelist) {
7515 gtk_drag_finish(dcon, FALSE, FALSE, time);
7516 return;
7517 }
7518
7519 if ((mainw->multitrack && !lives_widget_is_sensitive(mainw->multitrack->open_menu)) ||
7521 gtk_drag_finish(dcon, FALSE, FALSE, time);
7522 return;
7523 }
7524
7525 nfilelist = subst(filelist, "file://", "");
7526
7527 nfiles = get_token_count(nfilelist, '\n');
7528 array = lives_strsplit(nfilelist, "\n", nfiles);
7529 lives_free(nfilelist);
7530
7531 for (i = 0; i < nfiles; i++) {
7532 fnames = lives_slist_append(fnames, array[i]);
7533 }
7534
7535 on_ok_file_open_clicked(NULL, fnames);
7536
7537 // fn will free array elements and fnames
7538
7539 lives_free(array);
7540
7541 gtk_drag_finish(dcon, TRUE, FALSE, time);
7542 }
7543#endif
7544
7545
7546 void on_opensel_range_ok_clicked(LiVESButton * button, livespointer user_data) {
7547 // open file selection
7548 boolean needs_idlefunc;
7549
7551
7552 needs_idlefunc = mainw->mt_needs_idlefunc;
7554 lives_general_button_clicked(button, NULL);
7555 mainw->mt_needs_idlefunc = needs_idlefunc;
7556
7557 mainw->img_concat_clip = -1;
7558 open_file_sel(file_name, mainw->fx1_val, (int)mainw->fx2_val);
7559
7560 if (mainw->multitrack) {
7565 }
7566 }
7567
7568
7569 void end_fs_preview(void) {
7570 // clean up if we were playing a preview - should be called from all callbacks
7571 // where there is a possibility of fs preview still playing
7572 static boolean singleton = FALSE;
7573 char *com;
7574
7575 if (singleton) return;
7576 singleton = TRUE;
7577
7578 lives_widget_set_bg_color(mainw->fs_playframe, LIVES_WIDGET_STATE_NORMAL, &palette->normal_back);
7579
7580 if (mainw->fs_playarea) {
7581 LiVESPixbuf *pixbuf = NULL;
7582 pixbuf = (LiVESPixbuf *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(mainw->fs_playarea), "pixbuf");
7583 if (pixbuf) lives_widget_object_unref(pixbuf);
7584 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(mainw->fs_playarea), "pixbuf", NULL);
7585 if (mainw->fsp_func != 0) {
7587 mainw->fsp_func = 0;
7588 }
7589 if (mainw->fsp_surface) {
7591 mainw->fsp_surface = NULL;
7592 }
7594 }
7595
7596 if (mainw->in_fs_preview) {
7597 if (mainw->fsp_tmpdir) {
7598 char *permitname = lives_build_filename(prefs->workdir, mainw->fsp_tmpdir,
7601 lives_touch(permitname);
7602 lives_free(permitname);
7603 com = lives_strdup_printf("%s close \"%s\"", prefs->backend, mainw->fsp_tmpdir);
7604 lives_freep((void **)&mainw->fsp_tmpdir);
7605 lives_system(com, TRUE);
7606 lives_free(com);
7607 }
7609 }
7611 singleton = FALSE;
7612 }
7613
7614
7615 void on_save_textview_clicked(LiVESButton * button, livespointer user_data) {
7616 LiVESTextView *textview = (LiVESTextView *)user_data;
7617 char *filt[] = {"*." LIVES_FILE_EXT_TEXT, NULL};
7618 int fd;
7619 char *btext;
7620 char *save_file;
7621 boolean needs_idlefunc;
7622
7623 lives_widget_hide(lives_widget_get_toplevel(LIVES_WIDGET(button)));
7625
7626 save_file = choose_file(NULL, NULL, filt, LIVES_FILE_CHOOSER_ACTION_SAVE, NULL, NULL);
7627
7628 if (!save_file) {
7629 lives_widget_show(lives_widget_get_toplevel(LIVES_WIDGET(button)));
7630 return;
7631 }
7632
7633#ifndef IS_MINGW
7634 if ((fd = creat(save_file, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)) == -1) {
7635#else
7636 if ((fd = creat(save_file, S_IRUSR | S_IWUSR)) == -1) {
7637#endif
7638 lives_widget_show(lives_widget_get_toplevel(LIVES_WIDGET(button)));
7639 do_write_failed_error_s(save_file, lives_strerror(errno));
7641 return;
7642 }
7643
7644 btext = lives_text_view_get_text(textview);
7645
7646 needs_idlefunc = mainw->mt_needs_idlefunc;
7648 lives_general_button_clicked(button, NULL);
7649 mainw->mt_needs_idlefunc = needs_idlefunc;
7650
7651 THREADVAR(write_failed) = FALSE;
7652 lives_write(fd, btext, strlen(btext), FALSE);
7653 lives_free(btext);
7654
7655 close(fd);
7656
7657 if (THREADVAR(write_failed)) {
7658 do_write_failed_error_s(save_file, lives_strerror(errno));
7659 } else {
7660 char *msg = lives_strdup_printf(_("Text was saved as\n%s\n"), save_file);
7661 do_error_dialog(msg);
7662 lives_free(msg);
7663 }
7664
7666#if 0
7667 }
7668#endif
7669 }
7670
7671
7672 void on_filechooser_cancel_clicked(LiVESWidget * widget) {
7673 lives_widget_destroy(widget);
7674
7675 if (mainw->multitrack) {
7678 } else if (!CURRENT_CLIP_IS_CLIPBOARD && CURRENT_CLIP_IS_VALID && !cfile->opening) {
7680 }
7681 }
7682
7683
7684 void on_cancel_opensel_clicked(LiVESButton * button, livespointer user_data) {
7685 boolean needs_idlefunc;
7686
7688 needs_idlefunc = mainw->mt_needs_idlefunc;
7690 lives_general_button_clicked(button, NULL);
7691 mainw->mt_needs_idlefunc = needs_idlefunc;
7692
7693 if (mainw->multitrack) {
7696 }
7697 lives_menu_item_activate(LIVES_MENU_ITEM(mainw->open_sel)); // returm to the fileselector
7698 }
7699
7700
7701 void on_cancel_keep_button_clicked(LiVESButton * button, livespointer user_data) {
7702 // Cancel/Keep from progress dialog
7703 char *com = NULL;
7704
7705 uint32_t keep_frames = 0;
7706
7707 boolean killprocs = FALSE;
7708
7709 if (CURRENT_CLIP_IS_VALID && cfile->opening && mainw->effects_paused) {
7710 on_stop_clicked(NULL, NULL);
7711 return;
7712 }
7713
7715
7722 }
7724
7725 if ((!mainw->effects_paused || cfile->nokeep) && (!mainw->multitrack ||
7726 (mainw->multitrack && (!mainw->multitrack->is_rendering ||
7727 !mainw->preview)))) {
7728 // Cancel
7729 if (mainw->cancel_type == CANCEL_SOFT) {
7730 // cancel in record audio
7733 return;
7734 } else if (mainw->cancel_type == CANCEL_KILL) {
7735 // kill processes and subprocesses working on cfile
7736 killprocs = TRUE;
7737 }
7738
7739 if (CURRENT_CLIP_IS_VALID && !cfile->opening && !mainw->internal_messaging) {
7740 // if we are opening, this is 'stop' in the preview, so don't cancel
7741 // otherwise, come here
7742
7743 // kill off the background process
7744 if (killprocs) {
7746 }
7747
7748 // resume for next time
7749 if (mainw->effects_paused) {
7750 lives_freep((void **)&com);
7751 com = lives_strdup_printf("%s resume \"%s\"", prefs->backend_sync, cfile->handle);
7752 lives_system(com, FALSE);
7753 }
7754 }
7755
7757
7758 if (mainw->is_rendering) {
7759 if (CURRENT_CLIP_IS_VALID) cfile->frames = 0;
7761 } else {
7762 // see if there was a message from backend
7763
7764 if (mainw->cancel_type != CANCEL_SOFT) {
7766 if (lives_strncmp(mainw->msg, "completed", 9)) {
7768 } else {
7769 // processing finished before we could cancel
7771 }
7772 } else d_print_cancelled();
7773 }
7774 } else {
7775 // Keep
7776 if (mainw->cancel_type == CANCEL_SOFT) {
7778 return;
7779 }
7780 if (!mainw->is_rendering) {
7781 keep_frames = mainw->proc_ptr->frames_done - cfile->progress_start
7782 + cfile->start - 1 + mainw->internal_messaging * 2;
7784 keep_frames = atoi(mainw->msg) - cfile->progress_start + cfile->start - 1 + 2;
7785 } else keep_frames = cfile->frames + 1;
7786 if (keep_frames > mainw->internal_messaging) {
7787 d_print_enough(keep_frames - cfile->start);
7789 if (!mainw->internal_messaging) {
7791 com = lives_strdup_printf("%s resume \"%s\"", prefs->backend_sync, cfile->handle);
7792 lives_system(com, FALSE);
7793 lives_free(com);
7794 if (!mainw->keep_pre) com = lives_strdup_printf("%s mv_mgk \"%s\" %d %d \"%s\"", prefs->backend, cfile->handle,
7795 cfile->start, keep_frames - 1, get_image_ext_for_type(cfile->img_type));
7796 else {
7797 com = lives_strdup_printf("%s mv_pre \"%s\" %d %d \"%s\" &", prefs->backend_sync, cfile->handle,
7798 cfile->start, keep_frames - 1, get_image_ext_for_type(cfile->img_type));
7799 mainw->keep_pre = FALSE;
7800 }
7801 } else {
7803 if (!mainw->keep_pre) com = lives_strdup_printf("%s mv_mgk \"%s\" %d %d \"%s\"", prefs->backend, cfile->handle,
7804 cfile->start, keep_frames - 1, get_image_ext_for_type(cfile->img_type));
7805 else {
7806 com = lives_strdup_printf("%s mv_pre \"%s\" %d %d \"%s\" &", prefs->backend_sync, cfile->handle,
7807 cfile->start, keep_frames - 1, get_image_ext_for_type(cfile->img_type));
7808 mainw->keep_pre = FALSE;
7809 }
7810 }
7811 if (!mainw->is_rendering || mainw->multitrack) {
7812 lives_rm(cfile->info_file);
7813 lives_system(com, FALSE);
7814 cfile->undo_end = keep_frames - 1;
7815 } else mainw->cancelled = CANCEL_KEEP;
7817 } else {
7818 // no frames there, nothing to keep
7820
7823 com = lives_strdup_printf("%s resume \"%s\"", prefs->backend_sync, cfile->handle);
7824 lives_system(com, FALSE);
7825 }
7827 }
7828 }
7829
7830 lives_freep((void **)&com);
7831 }
7832
7833
7837 textwindow = create_text_window(_("Encoder Debug Output"),
7841 }
7842
7843
7844 void on_full_screen_pressed(LiVESButton * button, livespointer user_data) {
7845 // toolbar button (full screen)
7846 // ignore if audio only clip
7848 lives_check_menu_item_set_active(LIVES_CHECK_MENU_ITEM(mainw->full_screen), !mainw->fs);
7849 }
7850
7851
7852 static void _on_full_screen_activate(LiVESMenuItem * menuitem, livespointer user_data) {
7853
7854 // ignore if audio only clip
7856
7857 if (!user_data) {
7858 // toggle can be overridden by setting user_data non-NULL
7859 mainw->fs = !mainw->fs;
7860 }
7861 mainw->blend_palette = WEED_PALETTE_END;
7862
7863 if (!mainw->fs) {
7864 lives_widget_set_tooltip_text(mainw->t_fullscreen, _("Fullscreen playback (f)"));
7866 } else {
7867 lives_widget_set_tooltip_text(mainw->t_fullscreen, _("Fullscreen playback off (f)"));
7869 }
7870
7871 if (LIVES_IS_PLAYING) {
7872 if (mainw->fs) {
7873 // switch TO full screen during pb
7874 if (!mainw->multitrack && !mainw->sep_win) {
7877 }
7878 if (mainw->sep_win) {
7881 }
7882 if (cfile->frames == 1 || cfile->play_paused) {
7884 }
7885
7886 if (mainw->ext_playback && mainw->vpp->fheight > -1 && mainw->vpp->fwidth > -1) {
7887 // fixed o/p size for stream
7888 if (mainw->vpp->fwidth == 0 || mainw->vpp->fheight == 0) {
7889 mainw->vpp->fwidth = cfile->hsize;
7890 mainw->vpp->fheight = cfile->vsize;
7891 }
7894 }
7895 } else {
7896 // switch from fullscreen during pb
7897 if (mainw->sep_win) {
7898 // separate window
7904 }
7905 if (mainw->ext_playback) {
7906#ifndef IS_MINGW
7909#else
7912#endif
7913 } else {
7914 // multi monitors don't like this it seems, breaks the window
7916 }
7917
7918 if (!mainw->faded) unfade_background();
7920
7921 if (!mainw->multitrack && mainw->opwx > -1) {
7922 //opwx and opwy were stored when we first switched to full screen
7924 mainw->opwx = mainw->opwy = -1;
7925 } else {
7926 if (mainw->play_window) {
7927 lives_window_center(LIVES_WINDOW(mainw->play_window));
7930 }
7931 }
7932 if (!mainw->multitrack) {
7934 if (cfile->frames == 1 || cfile->play_paused) {
7936 }
7937 }
7938 } else {
7939 // switch FROM fullscreen during pb
7940 // in frame window
7941 if (!mainw->multitrack) {
7942 if (!mainw->faded) {
7943 if (mainw->double_size) {
7949 } else {
7955 if (mainw->double_size) {
7957 resize(2.);
7958 } else {
7960 resize(1.);
7961 }
7962 }
7963
7966 // *INDENT-OFF*
7967 }}
7968 if (!mainw->multitrack && !mainw->faded) {
7972 }}}
7973 // *INDENT-ON*
7975 } else {
7976 // not playing
7977 if (!mainw->multitrack) {
7978 if (mainw->fs) {
7981 } else {
7984 // *INDENT-OFF*
7985 }}}
7986 // *INDENT-ON*
7987 }
7988
7989
7990 void on_full_screen_activate(LiVESMenuItem * menuitem, livespointer user_data) {
7991 main_thread_execute((lives_funcptr_t)_on_full_screen_activate, 0, NULL, "vv", menuitem, user_data);
7992 }
7993
7994 void on_double_size_pressed(LiVESButton * button, livespointer user_data) {
7995 // toolbar button (separate window)
7996 lives_check_menu_item_set_active(LIVES_CHECK_MENU_ITEM(mainw->dsize), !mainw->double_size);
7997 }
7998
7999
8000 void on_double_size_activate(LiVESMenuItem * menuitem, livespointer user_data) {
8001
8002 if (mainw->multitrack || (CURRENT_CLIP_IS_VALID && !CURRENT_CLIP_HAS_VIDEO && !user_data)) return;
8003
8004 if (!user_data) {
8006 }
8007
8008 if (!CURRENT_CLIP_IS_VALID) return;
8009 mainw->blend_palette = WEED_PALETTE_END;
8010
8011 mainw->opwx = mainw->opwy = -1;
8012
8014 if (mainw->play_window) {
8016 sched_yield();
8017 if (!mainw->double_size) lives_window_center(LIVES_WINDOW(mainw->play_window));
8018 } else {
8019 // in-frame
8020 if (mainw->double_size) {
8021 if (!mainw->faded) {
8022 if (palette->style & STYLE_1) {
8024 }
8026 }
8028 resize(2.);
8029 } else {
8031 resize(1.);
8032 if (!mainw->faded) {
8033 if (palette->style & STYLE_1) {
8035 }
8037 // *INDENT-OFF*
8038 }}}}
8039 // *INDENT-ON*
8041 }
8042
8043
8044 void on_sepwin_pressed(LiVESButton * button, livespointer user_data) {
8045 if (mainw->go_away) return;
8046
8047 // toolbar button (separate window)
8048 if (mainw->multitrack) {
8049 lives_check_menu_item_set_active(LIVES_CHECK_MENU_ITEM(mainw->multitrack->sepwin), !mainw->sep_win);
8050 lives_check_menu_item_set_active(LIVES_CHECK_MENU_ITEM(mainw->sepwin), mainw->sep_win);
8051 } else lives_check_menu_item_set_active(LIVES_CHECK_MENU_ITEM(mainw->sepwin), !mainw->sep_win);
8052 }
8053
8054
8055 void on_sepwin_activate(LiVESMenuItem * menuitem, livespointer user_data) {
8056
8057 if (mainw->go_away) return;
8058
8060 mainw->blend_palette = WEED_PALETTE_END;
8061
8062 if (mainw->multitrack) {
8063 if (!LIVES_IS_PLAYING) return;
8065 mainw->multitrack->redraw_block = TRUE; // stop pb cursor from updating
8067 mainw->multitrack->redraw_block = FALSE;
8068 }
8069
8070 if (mainw->sep_win) {
8071 lives_widget_set_tooltip_text(mainw->m_sepwinbutton, _("Hide the play window (s)"));
8072 lives_widget_set_tooltip_text(mainw->t_sepwin, _("Hide the play window (s)"));
8075 } else {
8076 lives_widget_set_tooltip_text(mainw->m_sepwinbutton, _("Show the play window (s)"));
8077 lives_widget_set_tooltip_text(mainw->t_sepwin, _("Play in separate window (s)"));
8080 }
8081
8084 else kill_play_window();
8085 /* if (mainw->multitrack && !LIVES_IS_PLAYING) { */
8086 /* activate_mt_preview(mainw->multitrack); // show frame preview */
8087 /* } */
8088 } else {
8089 if (LIVES_IS_PLAYING) {
8090 if (mainw->sep_win) {
8091 // switch to separate window during pb
8092 if (!mainw->multitrack) {
8096 cfile->opening))) {
8098 }
8099 if ((!mainw->faded && mainw->fs && ((prefs->play_monitor != widget_opts.monitor && prefs->play_monitor > 0 &&
8100 capable->nmonitors > 1))) ||
8101 (mainw->fs && mainw->vpp &&
8104 showclipimgs();
8105 }
8106 if (mainw->fs && !mainw->faded) {
8108 resize(1.);
8109 } else {
8110 if (mainw->faded) {
8112 //lives_widget_hide(mainw->playframe);
8117 } else {
8118 if (mainw->double_size) {
8119 // switch back to single size as we are scooping the player out
8121 resize(1.);
8122 if (!mainw->faded) {
8123 if (palette->style & STYLE_1) {
8125 }
8127 // *INDENT-OFF*
8128 }}}}}
8129 // *INDENT-ON*
8130 else {
8132 }
8134
8135 mainw->pw_scroll_func = lives_signal_connect(LIVES_GUI_OBJECT(mainw->play_window), LIVES_WIDGET_SCROLL_EVENT,
8136 LIVES_GUI_CALLBACK(on_mouse_scroll), NULL);
8137
8138 if (mainw->ext_playback && mainw->vpp->fheight > -1 && mainw->vpp->fwidth > -1) {
8139 // fixed o/p size for stream
8140 if ((mainw->vpp->fwidth == 0 || mainw->vpp->fheight == 0) && CURRENT_CLIP_IS_VALID) {
8141 mainw->vpp->fwidth = cfile->hsize;
8142 mainw->vpp->fheight = cfile->vsize;
8143 }
8146
8149 }
8150 resize(1.);
8152 }
8153
8154 if (mainw->play_window && LIVES_IS_XWINDOW(lives_widget_get_xwindow(mainw->play_window))) {
8157 }
8158 } else {
8159 // switch from separate window during playback
8160 if (mainw->ext_playback) {
8161#ifndef IS_MINGW
8164#else
8167#endif
8168 }
8169 if (mainw->fs) {
8173 }
8174 }
8175
8177
8178 if (!mainw->multitrack) {
8180 if (!mainw->fs) {
8181 if (!mainw->double_size) {
8183 resize(1.);
8184 } else {
8185 if (palette->style & STYLE_1) {
8187 }
8190 resize(2.);
8191 }
8192 } else {
8193 // fullscreen
8198 // *INDENT-OFF*
8199 }}
8202 }}}}
8203 // *INDENT-ON*
8205 }
8206
8207
8208 void on_showfct_activate(LiVESMenuItem * menuitem, livespointer user_data) {
8211 if (!prefs->hide_framebar) {
8213 } else {
8214 if (prefs->hide_framebar) {
8216 // *INDENT-OFF*
8217 }}}
8218 // *INDENT-ON*
8219 }
8220
8221
8222 void on_sticky_activate(LiVESMenuItem * menuitem, livespointer user_data) {
8223 // type is SEPWIN_TYPE_STICKY (shown even when not playing)
8224 // or SEPWIN_TYPE_NON_STICKY (shown only when playing)
8225 boolean make_perm = (prefs->sepwin_type == future_prefs->sepwin_type);
8228 } else {
8230 }
8231 }
8232
8233
8234 void on_fade_pressed(LiVESButton * button, livespointer user_data) {
8235 // toolbar button (unblank background)
8237 return;
8238 lives_check_menu_item_set_active(LIVES_CHECK_MENU_ITEM(mainw->fade), !mainw->faded);
8239 }
8240
8241
8242 void on_fade_activate(LiVESMenuItem * menuitem, livespointer user_data) {
8243 mainw->faded = !mainw->faded;
8245 capable->nmonitors > 1))) {
8246 if (mainw->faded) {
8249 } else {
8255 if (!prefs->hide_framebar && !(prefs->hfbwnp && !LIVES_IS_PLAYING)) {
8257 }
8261 // *INDENT-OFF*
8262 }}}
8263 // *INDENT-ON*
8264 }
8265
8266
8267 void on_showsubs_toggled(LiVESWidgetObject * obj, livespointer user_data) {
8269 if (mainw->current_file > 0 && !mainw->multitrack) {
8270 if (mainw->play_window) {
8272 }
8273 showclipimgs();
8274 }
8275 }
8276
8277
8278 void on_boolean_toggled(LiVESWidgetObject * obj, livespointer user_data) {
8279 boolean *ppref = (boolean *)user_data;
8280 *ppref = !(*ppref);
8281 }
8282
8283
8284 void on_audio_toggled(LiVESWidget * tbutton, LiVESWidget * label) {
8285 boolean state;
8286 if (!LIVES_IS_INTERACTIVE) return;
8287
8288 state = lives_toggle_tool_button_get_active(LIVES_TOGGLE_TOOL_BUTTON(tbutton));
8289 lives_widget_set_sensitive(tbutton, !state);
8290
8291 if (tbutton == mainw->ext_audio_checkbutton) {
8293 } else {
8295 }
8296 }
8297
8298 void on_loop_video_activate(LiVESMenuItem * menuitem, livespointer user_data) {
8299 if (mainw->current_file == 0) return;
8300 mainw->loop = !mainw->loop;
8303 }
8304
8305
8306 void on_loop_button_activate(LiVESMenuItem * menuitem, livespointer user_data) {
8307 if (mainw->multitrack) {
8308 lives_signal_handler_block(mainw->multitrack->loop_continue, mainw->multitrack->loop_cont_func);
8309 lives_check_menu_item_set_active(LIVES_CHECK_MENU_ITEM(mainw->multitrack->loop_continue), !mainw->loop_cont);
8310 lives_signal_handler_unblock(mainw->multitrack->loop_continue, mainw->multitrack->loop_cont_func);
8311 }
8313 }
8314
8315
8316 void on_loop_cont_activate(LiVESMenuItem * menuitem, livespointer user_data) {
8317
8319
8320 if (mainw->loop_cont) {
8321 lives_widget_set_tooltip_text(mainw->m_loopbutton, _("Switch continuous looping off (o)"));
8323 } else {
8324 lives_widget_set_tooltip_text(mainw->m_loopbutton, _("Switch continuous looping on (o)"));
8326 }
8327
8330 else mainw->whentostop = NEVER_STOP;
8331
8332 if (mainw->preview_box) {
8333 if (mainw->loop_cont)
8335 else
8337 }
8338
8339#ifdef ENABLE_JACK
8341 if (mainw->jackd && (mainw->loop_cont || mainw->whentostop == NEVER_STOP)) {
8344 else mainw->jackd->loop = AUDIO_LOOP_FORWARD;
8345 } else if (mainw->jackd) mainw->jackd->loop = AUDIO_LOOP_NONE;
8346 }
8347#endif
8348#ifdef HAVE_PULSE_AUDIO
8353 else mainw->pulsed->loop = AUDIO_LOOP_FORWARD;
8354 } else if (mainw->pulsed) mainw->pulsed->loop = AUDIO_LOOP_NONE;
8355 }
8356#endif
8357 }
8358
8359
8360 void on_ping_pong_activate(LiVESMenuItem * menuitem, livespointer user_data) {
8362#ifdef ENABLE_JACK
8365 else mainw->jackd->loop = AUDIO_LOOP_FORWARD;
8366 }
8367#endif
8368#ifdef HAVE_PULSE_AUDIO
8371 else mainw->pulsed->loop = AUDIO_LOOP_FORWARD;
8372 }
8373#endif
8374 }
8375
8376
8377 void on_volume_slider_value_changed(LiVESScaleButton * sbutton, livespointer user_data) {
8379 }
8380
8381
8382 void on_mute_button_activate(LiVESMenuItem * menuitem, livespointer user_data) {
8383 if (mainw->multitrack) {
8384 lives_signal_handler_block(mainw->multitrack->mute_audio, mainw->multitrack->mute_audio_func);
8385 lives_check_menu_item_set_active(LIVES_CHECK_MENU_ITEM(mainw->multitrack->mute_audio), !mainw->mute);
8386 lives_signal_handler_unblock(mainw->multitrack->mute_audio, mainw->multitrack->mute_audio_func);
8387 }
8388 lives_check_menu_item_set_active(LIVES_CHECK_MENU_ITEM(mainw->mute_audio), !mainw->mute);
8389 }
8390
8391
8392 boolean mute_audio_callback(LiVESAccelGroup * group, LiVESWidgetObject * obj, uint32_t keyval, LiVESXModifierType mod,
8393 livespointer user_data) {
8394 lives_check_menu_item_set_active(LIVES_CHECK_MENU_ITEM(mainw->mute_audio), !mainw->mute);
8395 return TRUE;
8396 }
8397
8398
8399 void on_mute_activate(LiVESMenuItem * menuitem, livespointer user_data) {
8400
8401 mainw->mute = !mainw->mute;
8402
8403 // change the mute icon
8404
8405 if (mainw->mute) {
8407 if (mainw->preview_box) {
8409 }
8410#ifdef ENABLE_JACK
8412 if (LIVES_IS_PLAYING) {
8414 weed_plant_t *event = get_last_frame_event(mainw->event_list);
8415 insert_audio_event_at(event, -1, mainw->jackd->playing_file, 0., 0.); // audio switch off
8416 }
8417 mainw->jackd->mute = TRUE;
8418 mainw->jackd->in_use = TRUE;
8419 }
8420 }
8421#endif
8422#ifdef HAVE_PULSE_AUDIO
8424 if (LIVES_IS_PLAYING) {
8426 weed_plant_t *event = get_last_frame_event(mainw->event_list);
8427 insert_audio_event_at(event, -1, mainw->pulsed->playing_file, 0., 0.); // audio switch off
8428 }
8429 mainw->pulsed->mute = TRUE;
8430 mainw->pulsed->in_use = TRUE;
8431 }
8432 }
8433#endif
8434 lives_widget_set_tooltip_text(mainw->m_mutebutton, _("Unmute the audio (z)"));
8435 if (mainw->preview_box) lives_widget_set_tooltip_text(mainw->p_mutebutton, _("Unmute the audio (z)"));
8436 } else {
8437#ifdef ENABLE_JACK
8439 if (LIVES_IS_PLAYING) {
8441 jack_get_rec_avals(mainw->jackd);
8442 }
8443 mainw->jackd->mute = FALSE;
8444 mainw->jackd->in_use = TRUE;
8445 }
8446 }
8447#endif
8448#ifdef HAVE_PULSE_AUDIO
8450 if (LIVES_IS_PLAYING) {
8452 pulse_get_rec_avals(mainw->pulsed);
8453 }
8454 mainw->pulsed->mute = FALSE;
8455 mainw->pulsed->in_use = TRUE;
8456 }
8457 }
8458#endif
8460 if (mainw->preview_box) {
8462 }
8463
8464 lives_widget_set_tooltip_text(mainw->m_mutebutton, _("Mute the audio (z)"));
8465 if (mainw->preview_box) lives_widget_set_tooltip_text(mainw->p_mutebutton, _("Mute the audio (z)"));
8466
8467#ifdef ENABLE_JACK
8469 mainw->jackd->mute = mainw->mute;
8470 }
8471#endif
8472#ifdef HAVE_PULSE_AUDIO
8474 mainw->pulsed->mute = mainw->mute;
8475 }
8476#endif
8477 }
8478 }
8479
8480#define GEN_SPB_LINK(n, bit) case n: mainw->fx##n##_##bit = \
8481 lives_spin_button_get_value(LIVES_SPIN_BUTTON(spinbutton)); break
8482#define GEN_SPB_LINK_I(n, bit) case n: mainw->fx##n##_##bit = \
8483 lives_spin_button_get_value_as_int(LIVES_SPIN_BUTTON(spinbutton)); break
8484
8485 void on_spin_value_changed(LiVESSpinButton * spinbutton, livespointer user_data) {
8486 // TODO - use array
8487 switch (LIVES_POINTER_TO_INT(user_data)) {
8488 GEN_SPB_LINK(1, val); GEN_SPB_LINK(2, val);
8489 GEN_SPB_LINK(3, val); GEN_SPB_LINK(4, val);
8490 default: break;
8491 }
8492 }
8493
8494
8495 void on_spin_start_value_changed(LiVESSpinButton * spinbutton, livespointer user_data) {
8496 // generic
8497 // TODO - use array
8498 switch (LIVES_POINTER_TO_INT(user_data)) {
8499 GEN_SPB_LINK_I(1, start); GEN_SPB_LINK_I(2, start);
8500 GEN_SPB_LINK_I(3, start); GEN_SPB_LINK_I(4, start);
8501 default: break;
8502 }
8503 }
8504
8505
8506 void on_spin_step_value_changed(LiVESSpinButton * spinbutton, livespointer user_data) {
8507 // generic
8508 // TODO - use array
8509 switch (LIVES_POINTER_TO_INT(user_data)) {
8510 GEN_SPB_LINK_I(1, step); GEN_SPB_LINK_I(2, step);
8511 GEN_SPB_LINK_I(3, step); GEN_SPB_LINK_I(4, step);
8512 default: break;
8513 }
8514 }
8515
8516
8517 void on_spin_end_value_changed(LiVESSpinButton * spinbutton, livespointer user_data) {
8518 // generic
8519 // TODO - use array
8520 switch (LIVES_POINTER_TO_INT(user_data)) {
8521 GEN_SPB_LINK_I(1, end); GEN_SPB_LINK_I(2, end);
8522 GEN_SPB_LINK_I(3, end); GEN_SPB_LINK_I(4, end);
8523 default: break;
8524 }
8525 }
8526
8527
8528 void on_rev_clipboard_activate(LiVESMenuItem * menuitem, livespointer user_data) {
8529 // reverse the clipboard
8530 char *com;
8531 int current_file = mainw->current_file;
8532 mainw->current_file = 0;
8533
8534 if (!check_if_non_virtual(0, 1, cfile->frames)) {
8535 lives_clip_data_t *cdata = ((lives_decoder_t *)cfile->ext_src)->cdata;
8536 char *msg = (_("Pulling frames from clipboard..."));
8537 if (!(cdata->seek_flag & LIVES_SEEK_FAST)) {
8538 if (realize_all_frames(0, msg, FALSE) <= 0) {
8539 mainw->current_file = current_file;
8540 lives_free(msg);
8541 sensitize();
8542 return;
8543 }
8544 lives_free(msg);
8545 }
8546 }
8547
8548 d_print(_("Reversing clipboard..."));
8549 com = lives_strdup_printf("%s reverse \"%s\" %d %d \"%s\"", prefs->backend, clipboard->handle, 1, clipboard->frames,
8550 get_image_ext_for_type(cfile->img_type));
8551
8552 lives_rm(cfile->info_file);
8553 lives_system(com, FALSE);
8554 lives_free(com);
8555
8556 if (!THREADVAR(com_failed)) {
8557 cfile->progress_start = 1;
8558 cfile->progress_end = cfile->frames;
8559
8560 // show a progress dialog, not cancellable
8561 do_progress_dialog(TRUE, FALSE, _("Reversing clipboard"));
8562 }
8563
8564 if (THREADVAR(com_failed) || mainw->error) d_print_failed();
8565 else {
8566 if (clipboard->frame_index) reverse_frame_index(0);
8567 d_print_done();
8568 }
8569 clipboard->arate = -clipboard->arate;
8570 clipboard->aseek_pos = clipboard->afilesize;
8571 mainw->current_file = current_file;
8572 sensitize();
8573 }
8574
8575
8576 void on_load_subs_activate(LiVESMenuItem * menuitem, livespointer user_data) {
8577 char *subfile;
8578 char *filt[] = LIVES_SUBS_FILTER;
8579 char filename[512];
8580 char *subfname, *isubfname;
8582 char *lfile_name;
8583 char *ttl;
8584
8585 if (!CURRENT_CLIP_IS_VALID) return;
8586
8587 if (cfile->subt) if (!do_existing_subs_warning()) return;
8588
8589 // try to repaint the screen, as it may take a few seconds to get a directory listing
8591
8592 ttl = (_("Load Subtitles"));
8593
8594 if (*mainw->vid_load_dir) {
8595 subfile = choose_file(mainw->vid_load_dir, NULL, filt, LIVES_FILE_CHOOSER_ACTION_OPEN, ttl, NULL);
8596 } else subfile = choose_file(NULL, NULL, filt, LIVES_FILE_CHOOSER_ACTION_OPEN, ttl, NULL);
8597 lives_free(ttl);
8598
8599 if (!subfile) return; // cancelled
8600
8601 lives_snprintf(filename, 512, "%s", subfile);
8602 lives_free(subfile);
8603
8604 get_filename(filename, FALSE); // strip extension
8605 isubfname = lives_strdup_printf("%s.%s", filename, LIVES_FILE_EXT_SRT);
8606 lfile_name = lives_filename_from_utf8(isubfname, -1, NULL, NULL, NULL);
8607
8608 if (lives_file_test(lfile_name, LIVES_FILE_TEST_EXISTS)) {
8609 subfname = lives_build_filename(prefs->workdir, cfile->handle, SUBS_FILENAME "." LIVES_FILE_EXT_SRT, NULL);
8610 subtype = SUBTITLE_TYPE_SRT;
8611 } else {
8612 lives_free(isubfname);
8613 lives_free(lfile_name);
8614 isubfname = lives_strdup_printf("%s.%s", filename, LIVES_FILE_EXT_SUB);
8615 lfile_name = lives_filename_from_utf8(isubfname, -1, NULL, NULL, NULL);
8616
8617 if (lives_file_test(isubfname, LIVES_FILE_TEST_EXISTS)) {
8618 subfname = lives_build_filename(prefs->workdir, cfile->handle, SUBS_FILENAME "." LIVES_FILE_EXT_SUB, NULL);
8619 subtype = SUBTITLE_TYPE_SUB;
8620 } else {
8621 lives_free(isubfname);
8623 lives_free(lfile_name);
8624 return;
8625 }
8626 }
8627
8628 if (cfile->subt) {
8629 // erase any existing subs
8630 on_erase_subs_activate(NULL, NULL);
8632 }
8633
8634 lives_cp(lfile_name, subfname);
8635
8636 if (THREADVAR(com_failed)) {
8637 lives_free(subfname);
8638 lives_free(isubfname);
8639 lives_free(lfile_name);
8640 return;
8641 }
8642
8643 subtitles_init(cfile, subfname, subtype);
8644 lives_free(subfname);
8645
8646 if (!mainw->multitrack) {
8647 // force update
8649 }
8650
8651 d_print(_("Loaded subtitle file: %s\n"), isubfname);
8652
8653 lives_free(isubfname);
8654 lives_free(lfile_name);
8655 }
8656
8657
8658 void on_save_subs_activate(LiVESMenuItem * menuitem, livespointer user_data) {
8659 char *subfile;
8660 char xfname[512];
8661 char xfname2[512];
8662
8663 // try to repaint the screen, as it may take a few seconds to get a directory listing
8665
8666 lives_snprintf(xfname, 512, "%s", mainw->subt_save_file);
8667 get_dirname(xfname);
8668
8669 lives_snprintf(xfname2, 512, "%s", mainw->subt_save_file);
8670 get_basename(xfname2);
8671
8672 subfile = choose_file(xfname, xfname2, NULL, LIVES_FILE_CHOOSER_ACTION_SAVE, NULL, NULL);
8673
8674 if (!subfile) return; // cancelled
8675
8676 lives_free(subfile);
8677 }
8678
8679
8680 void on_erase_subs_activate(LiVESMenuItem * menuitem, livespointer user_data) {
8681 char *sfname;
8682
8683 if (!CURRENT_CLIP_IS_VALID || !cfile->subt) return;
8684
8685 if (menuitem)
8686 if (!do_erase_subs_warning()) return;
8687
8688 switch (cfile->subt->type) {
8689 case SUBTITLE_TYPE_SRT:
8690 sfname = lives_build_filename(prefs->workdir, cfile->handle, SUBS_FILENAME "." LIVES_FILE_EXT_SRT, NULL);
8691 break;
8692
8693 case SUBTITLE_TYPE_SUB:
8694 sfname = lives_build_filename(prefs->workdir, cfile->handle, SUBS_FILENAME "." LIVES_FILE_EXT_SUB, NULL);
8695 break;
8696
8697 default:
8698 return;
8699 }
8700
8702
8703 lives_rm(sfname);
8704 lives_free(sfname);
8705
8706 if (menuitem) {
8707 // force update
8708 if (!mainw->multitrack) {
8710 }
8711 d_print(_("Subtitles were erased.\n"));
8712 }
8713 }
8714
8715
8716 void on_load_audio_activate(LiVESMenuItem * menuitem, livespointer user_data) {
8717 LiVESWidget *chooser;
8718 char *filt[] = LIVES_AUDIO_LOAD_FILTER;
8719 LiVESResponseType resp;
8721
8722 if (mainw->multitrack) {
8723 if (mainw->multitrack->idlefunc > 0) {
8725 mainw->multitrack->idlefunc = 0;
8727 }
8731 }
8732
8733 chooser = choose_file_with_preview((*mainw->audio_dir) ? mainw->audio_dir : NULL, _("Select Audio File"), filt,
8735
8736 resp = lives_dialog_run(LIVES_DIALOG(chooser));
8737
8739
8740 if (resp != LIVES_RESPONSE_ACCEPT) on_filechooser_cancel_clicked(chooser);
8741 else on_open_new_audio_clicked(LIVES_FILE_CHOOSER(chooser), NULL);
8742 }
8743
8744
8745 void on_open_new_audio_clicked(LiVESFileChooser * chooser, livespointer user_data) {
8746 // open audio file
8747 // also called from osc.c
8748
8749 char *a_type;
8750 char *com, *tmp;
8751 char **array;
8752
8753 uint32_t chk_mask = 0;
8754
8755 int oundo_start;
8756 int oundo_end;
8757 int israw = 1;
8758 int asigned, aendian;
8759
8760 boolean bad_header = FALSE;
8761 boolean preparse = FALSE;
8762 boolean gotit = FALSE;
8763
8764 register int i;
8765
8766 if (!CURRENT_CLIP_IS_VALID) return;
8767
8768 tmp = (_("Loading new audio"));
8770 if (!check_for_layout_errors(tmp, mainw->current_file, 1, 0, &chk_mask)) {
8771 lives_free(tmp);
8772 if (mainw->multitrack) {
8775 }
8776 return;
8777 }
8778
8779 cfile->undo_arate = cfile->arate;
8780 cfile->undo_achans = cfile->achans;
8781 cfile->undo_asampsize = cfile->asampsize;
8782 cfile->undo_signed_endian = cfile->signed_endian;
8783 cfile->undo_arps = cfile->arps;
8784
8785 oundo_start = cfile->undo_start;
8786 oundo_end = cfile->undo_end;
8787
8788 if (!user_data) {
8789 char *filename = lives_file_chooser_get_filename(chooser);
8790 lives_snprintf(file_name, PATH_MAX, "%s", (tmp = lives_filename_to_utf8(filename, -1, NULL, NULL, NULL)));
8791 lives_free(filename);
8792 lives_free(tmp);
8793 } else lives_snprintf(file_name, PATH_MAX, "%s", (char *)user_data);
8794
8795 lives_snprintf(mainw->audio_dir, PATH_MAX, "%s", file_name);
8798 lives_widget_destroy(LIVES_WIDGET(chooser));
8800
8801 a_type = get_extension(file_name);
8802
8803 if (strlen(a_type)) {
8804 char *filt[] = LIVES_AUDIO_LOAD_FILTER;
8805 for (i = 0; filt[i]; i++) {
8806 if (!lives_ascii_strcasecmp(a_type, filt[i] + 2)) gotit = TRUE; // skip past "*." in filt
8807 }
8808 }
8809
8810 if (gotit) {
8811 com = lives_strdup_printf("%s audioopen \"%s\" \"%s\"", prefs->backend, cfile->handle,
8812 (tmp = lives_filename_from_utf8(file_name, -1, NULL, NULL, NULL)));
8813 lives_free(tmp);
8814 } else {
8815 lives_free(a_type);
8817
8818 if (mainw->multitrack) {
8821 }
8823 return;
8824 }
8825
8826 if (!lives_ascii_strncasecmp(a_type, LIVES_FILE_EXT_WAV, 3)) israw = 0;
8827
8828 if (HAS_EXTERNAL_PLAYER) {
8829 if (read_file_details(file_name, TRUE, FALSE)) {
8830 if (get_token_count(mainw->msg, '|') >= 14) {
8831 array = lives_strsplit(mainw->msg, "|", -1);
8832 cfile->arate = atoi(array[9]);
8833 cfile->achans = atoi(array[10]);
8834 cfile->asampsize = atoi(array[11]);
8835 cfile->signed_endian = get_signed_endian(atoi(array[12]), atoi(array[13]));
8836 lives_strfreev(array);
8837 preparse = TRUE;
8838 }
8839 }
8840 }
8841
8842 if (!preparse) {
8843 // TODO !!! - need some way to identify audio without invoking mplayer
8844 cfile->arate = cfile->arps = DEFAULT_AUDIO_RATE;
8845 cfile->achans = DEFAULT_AUDIO_CHANS;
8846 cfile->asampsize = DEFAULT_AUDIO_SAMPS;
8847 cfile->signed_endian = mainw->endian;
8848 }
8849
8850 if (cfile->undo_arate > 0) cfile->arps = cfile->undo_arps / cfile->undo_arate * cfile->arate;
8851 else cfile->arps = cfile->arate;
8852
8853 d_print(""); // force switchtext
8854 d_print(_("Opening audio %s, type %s..."), file_name, a_type);
8855 lives_free(a_type);
8856
8857 lives_rm(cfile->info_file);
8858 lives_system(com, FALSE);
8859 lives_free(com);
8860
8861 if (THREADVAR(com_failed)) {
8862 cfile->arate = cfile->undo_arate;
8863 cfile->achans = cfile->undo_achans;
8864 cfile->asampsize = cfile->undo_asampsize;
8865 cfile->signed_endian = cfile->undo_signed_endian;
8866 cfile->arps = cfile->undo_arps;
8867 cfile->undo_start = oundo_start;
8868 cfile->undo_end = oundo_end;
8869 sensitize();
8870 if (mainw->multitrack) {
8873 }
8876 return;
8877 }
8878
8879 cfile->opening = cfile->opening_audio = cfile->opening_only_audio = TRUE;
8880
8881 cfile->undo_start = 1;
8882 cfile->undo_end = cfile->frames;
8883
8884 // show audio [opening...] in main window
8886
8887 if (!(do_progress_dialog(TRUE, TRUE, _("Opening audio")))) {
8889
8891 mainw->error = FALSE;
8892 lives_rm(cfile->info_file);
8893 com = lives_strdup_printf("%s cancel_audio \"%s\"", prefs->backend, cfile->handle);
8894 lives_system(com, FALSE);
8895 do_auto_dialog(_("Cancelling"), 0);
8896 lives_free(com);
8897 cfile->opening_audio = cfile->opening = cfile->opening_only_audio = FALSE;
8898 cfile->arate = cfile->undo_arate;
8899 cfile->achans = cfile->undo_achans;
8900 cfile->asampsize = cfile->undo_asampsize;
8901 cfile->signed_endian = cfile->undo_signed_endian;
8902 cfile->arps = cfile->undo_arps;
8903 cfile->undo_start = oundo_start;
8904 cfile->undo_end = oundo_end;
8905 sensitize();
8906 if (mainw->multitrack) {
8909 }
8911 if (mainw->error) d_print_failed();
8913 return;
8914 }
8915
8916 cfile->opening_audio = cfile->opening = cfile->opening_only_audio = FALSE;
8917
8918 cfile->afilesize = 0;
8919
8920 if (get_token_count(mainw->msg, '|') > 6) {
8921 array = lives_strsplit(mainw->msg, "|", 7);
8922 cfile->arate = atoi(array[1]);
8923 cfile->achans = atoi(array[2]);
8924 cfile->asampsize = atoi(array[3]);
8925 cfile->signed_endian = get_signed_endian(atoi(array[4]), atoi(array[5]));
8926 cfile->afilesize = atol(array[6]);
8927 lives_strfreev(array);
8928
8929 if (cfile->undo_arate > 0) cfile->arps = cfile->undo_arps / cfile->undo_arate * cfile->arate;
8930 else cfile->arps = cfile->arate;
8931 }
8932
8935
8936 if (cfile->afilesize == 0) {
8938
8940 mainw->error = FALSE;
8941 lives_rm(cfile->info_file);
8942
8943 com = lives_strdup_printf("%s cancel_audio \"%s\"", prefs->backend, cfile->handle);
8944
8945 lives_system(com, FALSE);
8946 lives_free(com);
8947
8948 if (!THREADVAR(com_failed)) do_auto_dialog(_("Cancelling"), 0);
8949
8950 cfile->arate = cfile->undo_arate;
8951 cfile->achans = cfile->undo_achans;
8952 cfile->asampsize = cfile->undo_asampsize;
8953 cfile->signed_endian = cfile->undo_signed_endian;
8954 cfile->arps = cfile->undo_arps;
8955 cfile->undo_start = oundo_start;
8956 cfile->undo_end = oundo_end;
8957 sensitize();
8958 if (mainw->multitrack) {
8961 }
8964 return;
8965 }
8966
8967 cfile->changed = TRUE;
8968 d_print_done();
8969
8970 d_print(P_("New audio: %d Hz %d channel %d bps\n", "New audio: %d Hz %d channels %d bps\n",
8971 cfile->achans),
8972 cfile->arate, cfile->achans, cfile->asampsize);
8973
8975 mainw->error = FALSE;
8976 lives_rm(cfile->info_file);
8977
8978 com = lives_strdup_printf("%s commit_audio \"%s\" %d", prefs->backend, cfile->handle, israw);
8979 lives_system(com, FALSE);
8980 lives_free(com);
8981
8982 if (THREADVAR(com_failed)) {
8983 cfile->arate = cfile->undo_arate;
8984 cfile->achans = cfile->undo_achans;
8985 cfile->asampsize = cfile->undo_asampsize;
8986 cfile->signed_endian = cfile->undo_signed_endian;
8987 cfile->arps = cfile->undo_arps;
8988 cfile->undo_start = oundo_start;
8989 cfile->undo_end = oundo_end;
8990 sensitize();
8991 if (mainw->multitrack) {
8994 }
8997 return;
8998 }
8999
9000 if (!do_auto_dialog(_("Committing audio"), 0)) {
9001 //cfile->may_be_damaged=TRUE;
9003 if (mainw->multitrack) {
9006 }
9008 return;
9009 }
9010
9011 if (prefs->save_directories) {
9013 }
9014 if (!prefs->conserve_space) {
9015 cfile->undo_action = UNDO_NEW_AUDIO;
9016 set_undoable(_("New Audio"), TRUE);
9017 }
9018
9019 asigned = !(cfile->signed_endian & AFORM_UNSIGNED);
9020 aendian = cfile->signed_endian & AFORM_BIG_ENDIAN;
9021
9022 if (!save_clip_value(mainw->current_file, CLIP_DETAILS_ARATE, &cfile->arps)) bad_header = TRUE;
9023 if (!save_clip_value(mainw->current_file, CLIP_DETAILS_PB_ARATE, &cfile->arate)) bad_header = TRUE;
9024 if (!save_clip_value(mainw->current_file, CLIP_DETAILS_ACHANS, &cfile->achans)) bad_header = TRUE;
9025 if (!save_clip_value(mainw->current_file, CLIP_DETAILS_ASAMPS, &cfile->asampsize)) bad_header = TRUE;
9026 if (!save_clip_value(mainw->current_file, CLIP_DETAILS_AENDIAN, &aendian)) bad_header = TRUE;
9027 if (!save_clip_value(mainw->current_file, CLIP_DETAILS_ASIGNED, &asigned)) bad_header = TRUE;
9028
9029 if (bad_header) do_header_write_error(mainw->current_file);
9030
9031 if (!mainw->multitrack) {
9033 }
9034
9035 if (chk_mask != 0) popup_lmap_errors(NULL, LIVES_INT_TO_POINTER(chk_mask));
9036
9037 if (mainw->multitrack) {
9040 }
9041 }
9042
9043
9044 void on_load_cdtrack_activate(LiVESMenuItem * menuitem, livespointer user_data) {
9045 LiVESWidget *cdtrack_dialog;
9046
9048
9049 if (!strlen(prefs->cdplay_device)) {
9051 return;
9052 }
9053
9054 mainw->fx1_val = 1;
9055 cdtrack_dialog = create_cdtrack_dialog(LIVES_DEVICE_CD, NULL);
9056 lives_widget_show_all(cdtrack_dialog);
9057 }
9058
9059
9060 void on_eject_cd_activate(LiVESMenuItem * menuitem, livespointer user_data) {
9061 char *com;
9062
9064
9065 if (!strlen(prefs->cdplay_device)) {
9067 return;
9068 }
9069
9070 if (strlen(capable->eject_cmd)) {
9072
9073 lives_system(com, TRUE);
9074 lives_free(com);
9075 }
9076 }
9077
9078
9079 void on_load_cdtrack_ok_clicked(LiVESButton * button, livespointer user_data) {
9080 char *com;
9081 char **array;
9082
9083 boolean was_new = FALSE;
9084
9085 uint32_t chk_mask = 0;
9086
9087 int new_file = mainw->first_free_file;
9088 int asigned, endian;
9089
9090 boolean bad_header = FALSE;
9091 boolean needs_idlefunc = mainw->mt_needs_idlefunc;
9093 lives_general_button_clicked(button, NULL);
9094 mainw->mt_needs_idlefunc = needs_idlefunc;
9095
9097 char *tmp = (_("Loading new audio"));
9099 if (!check_for_layout_errors(tmp, mainw->current_file, 1, 0, &chk_mask)) {
9100 lives_free(tmp);
9101 return;
9102 }
9103 lives_free(tmp);
9104 }
9105
9106 d_print(_("Opening CD track %d from %s..."), (int)mainw->fx1_val, prefs->cdplay_device);
9107
9108 if (!CURRENT_CLIP_IS_VALID) {
9109 if (!get_new_handle(new_file, lives_strdup_printf(_("CD track %d"), (int)mainw->fx1_val))) {
9111 return;
9112 }
9113
9114 mainw->current_file = new_file;
9115 lives_snprintf(cfile->type, 40, "CD track %d on %s", (int)mainw->fx1_val, prefs->cdplay_device);
9118 was_new = TRUE;
9119 cfile->opening = cfile->opening_audio = cfile->opening_only_audio = TRUE;
9120 cfile->hsize = DEF_FRAME_HSIZE;
9121 cfile->vsize = DEF_FRAME_VSIZE;
9122 } else {
9123 cfile->undo_arate = cfile->arate;
9124 cfile->undo_achans = cfile->achans;
9125 cfile->undo_asampsize = cfile->asampsize;
9126 cfile->undo_signed_endian = cfile->signed_endian;
9127 cfile->undo_arps = cfile->arps;
9128 }
9129
9130 com = lives_strdup_printf("%s cdopen \"%s\" %d", prefs->backend, cfile->handle, (int)mainw->fx1_val);
9131
9132 lives_rm(cfile->info_file);
9133 lives_system(com, FALSE);
9134 lives_free(com);
9135
9136 if (THREADVAR(com_failed)) {
9137 cfile->arate = cfile->undo_arate;
9138 cfile->achans = cfile->undo_achans;
9139 cfile->asampsize = cfile->undo_asampsize;
9140 cfile->signed_endian = cfile->undo_signed_endian;
9141 cfile->arps = cfile->undo_arps;
9142
9143 sensitize();
9145 if (was_new) close_current_file(0);
9147 return;
9148 }
9149
9150 if (!(do_progress_dialog(TRUE, TRUE, _("Opening CD track...")))) {
9152
9153 if (!was_new) {
9155 mainw->error = FALSE;
9156 lives_rm(cfile->info_file);
9157
9158 com = lives_strdup_printf("%s cancel_audio \"%s\"", prefs->backend, cfile->handle);
9159 lives_system(com, FALSE);
9160 lives_free(com);
9161
9162 if (!THREADVAR(com_failed)) do_auto_dialog(_("Cancelling"), 0);
9163
9164 cfile->arate = cfile->undo_arate;
9165 cfile->achans = cfile->undo_achans;
9166 cfile->asampsize = cfile->undo_asampsize;
9167 cfile->signed_endian = cfile->undo_signed_endian;
9168 cfile->arps = cfile->undo_arps;
9169
9170 sensitize();
9172 }
9173
9174 if (was_new) close_current_file(0);
9175
9176 if (mainw->error) {
9178 }
9179
9181 return;
9182 }
9183
9185
9186 if (mainw->error) {
9187 d_print(_("Error loading CD track\n"));
9188
9190
9191 if (!was_new) {
9192 com = lives_strdup_printf("%s cancel_audio \"%s\"", prefs->backend, cfile->handle);
9194 mainw->error = FALSE;
9195 lives_rm(cfile->info_file);
9196 lives_system(com, FALSE);
9197 lives_free(com);
9198
9199 if (!THREADVAR(com_failed)) do_auto_dialog(_("Cancelling"), 0);
9200
9201 cfile->arate = cfile->undo_arate;
9202 cfile->achans = cfile->undo_achans;
9203 cfile->asampsize = cfile->undo_asampsize;
9204 cfile->signed_endian = cfile->undo_signed_endian;
9205 cfile->arps = cfile->undo_arps;
9206
9207 sensitize();
9209 }
9210
9211 if (was_new) close_current_file(0);
9213 return;
9214 }
9215
9216 array = lives_strsplit(mainw->msg, "|", 5);
9217 cfile->arate = atoi(array[1]);
9218 cfile->achans = atoi(array[2]);
9219 cfile->asampsize = atoi(array[3]);
9220 cfile->afilesize = strtol(array[4], NULL, 10);
9221 lives_strfreev(array);
9222
9223 if (!was_new && cfile->undo_arate > 0) cfile->arps = cfile->undo_arps / cfile->undo_arate * cfile->arate;
9224 else cfile->arps = cfile->arate;
9225
9226 asigned = !(cfile->signed_endian & AFORM_UNSIGNED);
9227 endian = cfile->signed_endian & AFORM_BIG_ENDIAN;
9228
9229 if (cfile->afilesize == 0l) {
9230 d_print(_("Error loading CD track\n"));
9231
9232 if (!was_new) {
9233 com = lives_strdup_printf("%s cancel_audio \"%s\"", prefs->backend, cfile->handle);
9235 mainw->error = FALSE;
9236 lives_rm(cfile->info_file);
9237 lives_system(com, FALSE);
9238 lives_free(com);
9239
9240 if (!THREADVAR(com_failed)) do_auto_dialog(_("Cancelling"), 0);
9241
9242 cfile->achans = cfile->undo_achans;
9243 cfile->arate = cfile->undo_arate;
9244 cfile->arps = cfile->undo_arps;
9245 cfile->asampsize = cfile->undo_asampsize;
9246 cfile->signed_endian = cfile->undo_signed_endian;
9247
9249 }
9250
9251 if (was_new) close_current_file(0);
9253 return;
9254 }
9255
9256 cfile->opening = cfile->opening_audio = cfile->opening_only_audio = FALSE;
9257
9259 mainw->error = FALSE;
9260 lives_rm(cfile->info_file);
9261
9262 com = lives_strdup_printf("%s commit_audio \"%s\"", prefs->backend, cfile->handle);
9263 lives_system(com, FALSE);
9264 lives_free(com);
9265
9266 if (THREADVAR(com_failed)) {
9268 cfile->achans = cfile->undo_achans;
9269 cfile->arate = cfile->undo_arate;
9270 cfile->arps = cfile->undo_arps;
9271 cfile->asampsize = cfile->undo_asampsize;
9272 cfile->signed_endian = cfile->undo_signed_endian;
9273
9275
9276 if (was_new) close_current_file(0);
9278 return;
9279 }
9280
9281 if (!do_auto_dialog(_("Committing audio"), 0)) {
9284 return;
9285 }
9286
9287 if (!save_clip_value(mainw->current_file, CLIP_DETAILS_ARATE, &cfile->arps)) bad_header = TRUE;
9288 if (!save_clip_value(mainw->current_file, CLIP_DETAILS_PB_ARATE, &cfile->arate)) bad_header = TRUE;
9289 if (!save_clip_value(mainw->current_file, CLIP_DETAILS_ACHANS, &cfile->achans)) bad_header = TRUE;
9290 if (!save_clip_value(mainw->current_file, CLIP_DETAILS_ASIGNED, &asigned)) bad_header = TRUE;
9291 if (!save_clip_value(mainw->current_file, CLIP_DETAILS_AENDIAN, &endian)) bad_header = TRUE;
9292 if (!save_clip_value(mainw->current_file, CLIP_DETAILS_ASAMPS, &cfile->asampsize)) bad_header = TRUE;
9293
9294 if (bad_header) do_header_write_error(mainw->current_file);
9295
9297 cfile->changed = TRUE;
9298 d_print_done();
9299 d_print(P_("New audio: %d Hz %d channel %d bps\n", "New audio: %d Hz %d channels %d bps\n", cfile->achans),
9300 cfile->arate, cfile->achans, cfile->asampsize);
9301
9302 if (!was_new) {
9303 if (!prefs->conserve_space) {
9304 cfile->undo_action = UNDO_NEW_AUDIO;
9305 set_undoable(_("New Audio"), TRUE);
9306 }
9307 }
9308
9310
9312
9313 if (chk_mask != 0) popup_lmap_errors(NULL, LIVES_INT_TO_POINTER(chk_mask));
9314 }
9315
9316
9317 void on_load_vcd_ok_clicked(LiVESButton * button, livespointer user_data) {
9318 boolean needs_idlefunc = mainw->mt_needs_idlefunc;
9320 lives_general_button_clicked(button, NULL);
9321 mainw->mt_needs_idlefunc = needs_idlefunc;
9322
9323 if (LIVES_POINTER_TO_INT(user_data) == LIVES_DEVICE_DVD) {
9324 lives_snprintf(file_name, PATH_MAX, "dvd://%d", (int)mainw->fx1_val);
9326 if (USE_MPV) mainw->file_open_params = lives_strdup_printf("--chapter=%d --aid=%d", (int)mainw->fx2_val, (int)mainw->fx3_val);
9327 else mainw->file_open_params = lives_strdup_printf("-chapter %d -aid %d", (int)mainw->fx2_val, (int)mainw->fx3_val);
9328 } else {
9329 lives_snprintf(file_name, PATH_MAX, "vcd://%d", (int)mainw->fx1_val);
9330 }
9331 open_sel_range_activate(0, 0.);
9332 }
9333
9334
9335 void popup_lmap_errors(LiVESMenuItem * menuitem, livespointer user_data) {
9336 // popup layout map errors dialog
9337 LiVESWidget *vbox;
9338 LiVESWidget *button;
9340
9341 uint32_t chk_mask = 0;
9342
9344
9345 if (!menuitem && user_data) {
9347 chk_mask = (uint32_t)LIVES_POINTER_TO_INT(user_data);
9348 if (((chk_mask ^ prefs->warning_mask) & chk_mask) == 0) return;
9349 }
9350
9352 textwindow = create_text_window(_("Layout Errors"), NULL, mainw->layout_textbuffer, FALSE);
9354
9355 vbox = lives_dialog_get_content_area(LIVES_DIALOG(textwindow->dialog));
9356
9357 add_warn_check(LIVES_BOX(vbox), WARN_MASK_LAYOUT_POPUP);
9358
9359 button = lives_dialog_add_button_from_stock(LIVES_DIALOG(textwindow->dialog), LIVES_STOCK_CLOSE, _("_Close Window"),
9360 LIVES_RESPONSE_OK);
9361
9362 lives_signal_sync_connect(LIVES_GUI_OBJECT(button), LIVES_WIDGET_CLICKED_SIGNAL,
9363 LIVES_GUI_CALLBACK(lives_general_button_clicked),
9364 textwindow);
9365
9367
9368 textwindow->clear_button = lives_dialog_add_button_from_stock(LIVES_DIALOG(textwindow->dialog), LIVES_STOCK_CLEAR,
9369 _("Clear _Errors"),
9370 LIVES_RESPONSE_CANCEL);
9371
9372 lives_signal_sync_connect(LIVES_GUI_OBJECT(textwindow->clear_button), LIVES_WIDGET_CLICKED_SIGNAL,
9373 LIVES_GUI_CALLBACK(on_lerrors_clear_clicked),
9374 LIVES_INT_TO_POINTER(FALSE));
9375
9377
9378 textwindow->delete_button = lives_dialog_add_button_from_stock(LIVES_DIALOG(textwindow->dialog), LIVES_STOCK_DELETE,
9379 _("_Delete affected layouts"), LIVES_RESPONSE_CANCEL);
9380
9381 lives_button_box_set_layout(LIVES_BUTTON_BOX(lives_widget_get_parent(textwindow->delete_button)), LIVES_BUTTONBOX_SPREAD);
9382
9384
9385 lives_signal_sync_connect(LIVES_GUI_OBJECT(textwindow->delete_button), LIVES_WIDGET_CLICKED_SIGNAL,
9386 LIVES_GUI_CALLBACK(on_lerrors_delete_clicked), NULL);
9387
9389 }
9390
9391
9392 void on_rename_activate(LiVESMenuItem * menuitem, livespointer user_data) {
9395 }
9396
9397
9398 void autolives_toggle(LiVESMenuItem * menuitem, livespointer user_data) {
9399 // TODO: allow mapping of change types to random ranges in the backend
9400 // TODO: allow user selection of all ports
9401#ifdef ENABLE_OSC
9402 autolives_window *alwindow = NULL;
9403 int trigtime;
9404 char *apb;
9405 char *mute;
9406 char *trigopt;
9407 char *debug;
9408 char string[PATH_MAX];
9409 char *com = NULL;
9410 boolean cancelled = FALSE;
9411
9412 if (mainw->alives_pgid > 0) {
9413 // already running, kill the old process
9415 mainw->alives_pgid = 0;
9416
9417 // restore pre-playback rte state
9419 goto autolives_fail;
9420 }
9421
9422 if (!lives_check_menu_item_get_active(LIVES_CHECK_MENU_ITEM(mainw->autolives))) return;
9423
9424 if (!CURRENT_CLIP_IS_VALID) {
9426 goto autolives_fail;
9427 }
9428
9429 if (cfile->event_list || cfile->opening || mainw->multitrack || mainw->is_processing || mainw->preview) {
9430 // ignore if doing something more important
9431 goto autolives_fail;
9432 }
9433
9434 // search for autolives.pl
9435 if (!capable->has_autolives) {
9437 if (strlen(string)) capable->has_autolives = TRUE;
9438 else {
9440 goto autolives_fail;
9441 }
9442 }
9443
9444 alwindow = autolives_pre_dialog();
9445 if (!alwindow) {
9446 goto autolives_fail;
9447 }
9448 if (lives_dialog_run(LIVES_DIALOG(alwindow->dialog)) == LIVES_RESPONSE_CANCEL) {
9449 // user cancelled
9450 cancelled = TRUE;
9451 goto autolives_fail;
9452 }
9453
9454 // check if osc is started; if not ask permission
9455 if (!prefs->osc_udp_started) {
9456 char typep[32];
9457 char *inst = (char *)typep;
9458 lives_snprintf(typep, 32, "%d", LIVES_PERM_OSC_PORTS);
9459 if (!lives_ask_permission((char **)&inst, 1, 0)) {
9460 // permission not given
9461 goto autolives_fail;
9462 }
9463
9464 // try: start up osc
9465 prefs->osc_udp_started = lives_osc_init(prefs->osc_udp_port);
9466 if (!prefs->osc_udp_started) {
9467 goto autolives_fail;
9468 }
9469 }
9470
9471 // build the command to run
9472 trigtime = lives_spin_button_get_value_as_int(LIVES_SPIN_BUTTON(alwindow->atrigger_spin));
9473 if (!lives_toggle_button_get_active(LIVES_TOGGLE_BUTTON(alwindow->apb_button))) apb = lives_strdup(" -waitforplay");
9474 else apb = lives_strdup("");
9475 if (lives_toggle_button_get_active(LIVES_TOGGLE_BUTTON(alwindow->mute_button))) mute = lives_strdup(" -mute");
9476 else mute = lives_strdup("");
9477 if (lives_toggle_button_get_active(LIVES_TOGGLE_BUTTON(alwindow->atrigger_button))) {
9478 // timed
9479 trigopt = lives_strdup_printf(" -time %d", trigtime);
9480 } else {
9481 // omc
9482 trigopt = lives_strdup_printf(" -omc %d", prefs->osc_udp_port - 2);
9483 }
9484 if (lives_toggle_button_get_active(LIVES_TOGGLE_BUTTON(alwindow->debug_button))) {
9485 debug = lives_strdup(" -debug");
9486 } else {
9487 debug = lives_strdup("");
9488 }
9489 lives_widget_destroy(alwindow->dialog);
9490 lives_free(alwindow);
9491
9492 // store the current key/mode state
9494
9495 com = lives_strdup_printf("/usr/bin/%s localhost %d %d%s%s%s%s", EXEC_AUTOLIVES_PL, prefs->osc_udp_port,
9496 prefs->osc_udp_port - 1, apb,
9497 trigopt, mute,
9498 debug);
9499
9501
9502 lives_free(debug);
9503 lives_free(trigopt);
9504 lives_free(apb);
9505 lives_free(mute);
9506 if (com) lives_free(com);
9507 return;
9508
9509autolives_fail:
9510 if (alwindow) {
9511 if (!cancelled) lives_widget_destroy(alwindow->dialog);
9512 lives_free(alwindow);
9513 }
9514
9515 lives_check_menu_item_set_active(LIVES_CHECK_MENU_ITEM(mainw->autolives), FALSE);
9516
9517#endif
9518 }
9519
9520
9521 void on_rename_clip_name(LiVESButton * button, livespointer user_data) {
9522 char title[256];
9523 boolean bad_header = FALSE;
9524
9525 if (!user_data) {
9526 lives_snprintf(title, 256, "%s", lives_entry_get_text(LIVES_ENTRY(renamew->entry)));
9529 } else lives_snprintf(title, 256, "%s", (char *)user_data);
9530
9531 if (!(strlen(title))) return;
9532
9533 if (!user_data) {
9534 set_main_title(title, 0);
9535 }
9536
9538 lives_menu_item_set_text(cfile->menuentry, title, FALSE);
9539
9540 lives_snprintf(cfile->name, 256, "%s", title);
9541
9543
9544 if (bad_header) do_header_write_error(mainw->current_file);
9545 cfile->was_renamed = TRUE;
9546 }
9547 }
9548
9549
9550 void on_toy_activate(LiVESMenuItem * menuitem, livespointer user_data) {
9551 if (menuitem && mainw->toy_type == LIVES_POINTER_TO_INT(user_data)) {
9552 // switch is off
9553 user_data = LIVES_INT_TO_POINTER(LIVES_TOY_NONE);
9554 }
9555
9556 switch (mainw->toy_type) {
9557 // old status
9562 if (LIVES_IS_PLAYING) {
9563 if (mainw->faded) {
9566 }
9568 showclipimgs();
9569 }
9570 }
9571 break;
9572 case LIVES_TOY_TV:
9574 lives_check_menu_item_set_active(LIVES_CHECK_MENU_ITEM(mainw->toy_tv), FALSE);
9576 break;
9577 default:
9579 lives_check_menu_item_set_active(LIVES_CHECK_MENU_ITEM(mainw->toy_none), FALSE);
9581 break;
9582 }
9583
9584 mainw->toy_type = (lives_toy_t)LIVES_POINTER_TO_INT(user_data);
9585
9586 switch (mainw->toy_type) {
9587 case LIVES_TOY_NONE:
9589 lives_check_menu_item_set_active(LIVES_CHECK_MENU_ITEM(mainw->toy_none), TRUE);
9591 return;
9593 break;
9594 case LIVES_TOY_TV:
9595 // load in the lives TV clip
9597
9598 // if we choose to discard it, discard it....otherwise keep it
9599 if (prefs->discard_tv) {
9601 } else {
9602 // keep it
9603 int current_file = mainw->current_file;
9604 char *com = lives_strdup_printf("%s commit_audio \"%s\"", prefs->backend, cfile->handle);
9605 cfile->start = 1;
9606 cfile->frames = get_frame_count(mainw->current_file, 1);
9607 cfile->end = cfile->frames;
9608 cfile->opening = cfile->opening_loc = cfile->opening_audio = cfile->opening_only_audio = FALSE;
9609 cfile->is_loaded = TRUE;
9610 lives_system(com, FALSE);
9611 save_clip_values(current_file);
9613 if (!mainw->multitrack) {
9614 switch_to_file((mainw->current_file = 0), current_file);
9615 sensitize();
9616 }
9617 }
9618 break;
9619 default:
9620 if (mainw->faded && !mainw->foreign) {
9623 }
9624 }
9625 }
9626
9627
9628 void on_preview_spinbutton_changed(LiVESSpinButton * spinbutton, livespointer user_data) {
9629 // update the play window preview
9630 int preview_frame;
9631 static volatile boolean updated = FALSE;
9632
9633 if (updated) return;
9634
9636 return;
9637 }
9638 if ((preview_frame = lives_spin_button_get_value_as_int(LIVES_SPIN_BUTTON(spinbutton))) == mainw->preview_frame) {
9639 return;
9640 }
9641 // prevent multiple updates from interfering
9642 updated = TRUE;
9644 //lives_widget_process_updates(LIVES_MAIN_WINDOW_WIDGET);
9645 mainw->preview_frame = preview_frame;
9648 updated = FALSE;
9649 }
9650
9651
9652 void on_prv_link_toggled(LiVESToggleButton * togglebutton, livespointer user_data) {
9653 if (!lives_toggle_button_get_active(togglebutton)) return;
9654 mainw->prv_link = LIVES_POINTER_TO_INT(user_data);
9656 // block spinbutton in play window
9658 } else {
9660 }
9663 }
9664
9665
9666 void update_sel_menu(void) {
9667 if (mainw->multitrack || mainw->selwidth_locked) return;
9668
9678 return;
9679 }
9680
9681 lives_widget_set_sensitive(mainw->select_new, cfile->insert_start > 0);
9683
9684 if (cfile->end > cfile->start) {
9687 } else {
9690 }
9691 if (cfile->start == 1 && cfile->end == cfile->frames) {
9695 } else {
9696 if (cfile->start == 1 || cfile->end == cfile->frames)
9698 else
9700
9703 }
9704
9707
9708 if (cfile->end < cfile->frames) {
9710 } else {
9713 }
9714 if (cfile->achans > 0) {
9715 int audframe = calc_frame_from_time4(mainw->current_file, cfile->laudio_time);
9716 if (audframe <= cfile->frames && audframe >= cfile->start && audframe != cfile->end)
9720 }
9721
9722
9723 void on_spinbutton_start_value_changed(LiVESSpinButton * spinbutton, livespointer user_data) {
9724 int start, ostart;
9725 boolean rdrw_bars = TRUE;
9726 static volatile boolean updated = FALSE;
9727
9728 if (updated) return;
9729
9731 return;
9732 }
9733 if ((start = lives_spin_button_get_value_as_int(LIVES_SPIN_BUTTON(spinbutton))) == cfile->start) {
9734 return;
9735 }
9736
9737 // prevent multiple updates from interfering
9738 updated = TRUE;
9741
9742 ostart = cfile->start;
9743 cfile->start = start;
9744
9745 if (mainw->selwidth_locked) {
9747 int new_end = cfile->end + cfile->start - ostart;
9749 if (new_end > cfile->frames) {
9750 lives_spin_button_set_value(LIVES_SPIN_BUTTON(mainw->spinbutton_start), cfile->start - cfile->end + cfile->frames);
9751 lives_spin_button_set_value(LIVES_SPIN_BUTTON(mainw->spinbutton_end), cfile->frames);
9752 lives_spin_button_update(LIVES_SPIN_BUTTON(mainw->spinbutton_end));
9753 } else {
9754 if (cfile->start < ostart && cfile->fps > 0.) {
9755 redraw_timer_bars((double)(cfile->start - 1.) / cfile->fps, (double)ostart / cfile->fps, 0);
9756 rdrw_bars = FALSE;
9757 }
9758 lives_spin_button_set_value(LIVES_SPIN_BUTTON(mainw->spinbutton_end), new_end);
9759 lives_spin_button_update(LIVES_SPIN_BUTTON(mainw->spinbutton_end));
9760 }
9762 }
9764
9765 if (!LIVES_IS_PLAYING && mainw->play_window && cfile->is_loaded) {
9767 if (mainw->prv_link == PRV_START && mainw->preview_frame != cfile->start)
9769 }
9770
9772
9773 if (cfile->start > cfile->end) {
9774 lives_spin_button_set_value(LIVES_SPIN_BUTTON(mainw->spinbutton_end), cfile->start);
9775 }
9777 if (rdrw_bars && cfile->fps > 0.) {
9778 if (cfile->start < ostart)
9779 redraw_timer_bars((double)(cfile->start - 1.) / cfile->fps, (double)ostart / cfile->fps, 0);
9780 else
9781 redraw_timer_bars((double)(ostart - 1.) / cfile->fps, (double)cfile->start / cfile->fps, 0);
9782 }
9783
9785 updated = FALSE;
9786 }
9787
9788
9789 void on_spinbutton_end_value_changed(LiVESSpinButton * spinbutton, livespointer user_data) {
9790 int end, oend;
9791 boolean rdrw_bars = TRUE;
9792 static volatile boolean updated = FALSE;
9793
9794 if (updated) return;
9795
9797 return;
9798 }
9799 if ((end = lives_spin_button_get_value_as_int(LIVES_SPIN_BUTTON(spinbutton))) == cfile->end) {
9800 return;
9801 }
9802
9803 // prevent multiple updates from interfering
9804 updated = TRUE;
9805
9808
9809 oend = cfile->end;
9810 cfile->end = end;
9811
9812 if (mainw->selwidth_locked) {
9813 int new_start = cfile->start + cfile->end - oend;
9815 if (new_start < 1) {
9816 lives_spin_button_set_value(LIVES_SPIN_BUTTON(mainw->spinbutton_end), cfile->end - cfile->start + 1);
9817 lives_spin_button_set_value(LIVES_SPIN_BUTTON(mainw->spinbutton_start), 1);
9818 lives_spin_button_update(LIVES_SPIN_BUTTON(mainw->spinbutton_start));
9819 } else {
9820 lives_spin_button_set_value(LIVES_SPIN_BUTTON(mainw->spinbutton_start), new_start);
9821 if (cfile->end > oend && cfile->fps > 0.) {
9822 redraw_timer_bars((double)oend / cfile->fps, (double)(cfile->end + 1) / cfile->fps, 0);
9823 rdrw_bars = FALSE;
9824 }
9825 lives_spin_button_update(LIVES_SPIN_BUTTON(mainw->spinbutton_start));
9826 }
9828 }
9830
9831 if (!LIVES_IS_PLAYING && mainw->play_window && cfile->is_loaded) {
9833 if (mainw->prv_link == PRV_END && mainw->preview_frame != cfile->end)
9835 }
9836
9838
9839 if (cfile->end < cfile->start) {
9840 lives_spin_button_set_value(LIVES_SPIN_BUTTON(mainw->spinbutton_start), cfile->end);
9841 }
9842
9844 if (rdrw_bars && cfile->fps > 0.) {
9845 if (cfile->end > oend)
9846 redraw_timer_bars((double)oend / cfile->fps, (double)(cfile->end + 1) / cfile->fps, 0);
9847 else
9848 redraw_timer_bars((double)cfile->end / cfile->fps, (double)(oend + 1) / cfile->fps, 0);
9849 }
9850
9852 updated = FALSE;
9853 }
9854
9855
9856 boolean all_expose(LiVESWidget * widget, lives_painter_t *cr, livespointer psurf) {
9857 lives_painter_surface_t **surf = (lives_painter_surface_t **)psurf;
9858 if (surf) {
9859 if (*surf) {
9860 lives_painter_set_source_surface(cr, *surf, 0., 0.);
9862 } else {
9863 return TRUE;
9864 }
9865 }
9866 return TRUE;
9867 }
9868
9869
9870 boolean all_expose_overlay(LiVESWidget * widget, lives_painter_t *creb, livespointer psurf) {
9872 if (mainw->go_away) return FALSE;
9873 if (LIVES_IS_PLAYING && mainw->faded) return FALSE;
9874 if (!CURRENT_CLIP_IS_VALID) return FALSE;
9875 else {
9876 int bar_height;
9877 int allocy;
9878 double allocwidth = (double)lives_widget_get_allocation_width(mainw->video_draw), allocheight;
9879 double offset;
9880 double ptrtime = mainw->ptrtime;
9881 frames_t frame;
9882 int which = 0;
9883
9884 offset = ptrtime / CURRENT_CLIP_TOTAL_TIME * allocwidth;
9885
9887
9888 if (palette->style & STYLE_LIGHT) {
9890 } else {
9892 }
9893
9894 if (!(frame = calc_frame_from_time(mainw->current_file, ptrtime)))
9895 frame = cfile->frames;
9896
9897 if (cfile->frames > 0 && (which == 0 || which == 1)) {
9898 if (mainw->video_drawable) {
9899 bar_height = CE_VIDBAR_HEIGHT;
9900
9901 allocheight = (double)lives_widget_get_allocation_height(mainw->vidbar) + bar_height + widget_opts.packing_height * 2.5;
9903 lives_painter_move_to(creb, offset, allocy);
9904 lives_painter_line_to(creb, offset, allocy + allocheight);
9906 }
9907 }
9908
9909 if (LIVES_IS_PLAYING) {
9910 if (which == 0) lives_ruler_set_value(LIVES_RULER(mainw->hruler), ptrtime);
9911 if (cfile->achans > 0 && cfile->is_loaded && prefs->audio_src != AUDIO_SRC_EXT) {
9913#ifdef ENABLE_JACK
9915 offset = allocwidth * ((double)mainw->jackd->seek_pos / cfile->arate / cfile->achans /
9916 cfile->asampsize * 8) / CURRENT_CLIP_TOTAL_TIME;
9917 }
9918#endif
9919#ifdef HAVE_PULSE_AUDIO
9921 offset = allocwidth * ((double)mainw->pulsed->seek_pos / cfile->arate / cfile->achans /
9922 cfile->asampsize * 8) / CURRENT_CLIP_TOTAL_TIME;
9923 }
9924#endif
9925 } else offset = allocwidth * (mainw->aframeno - .5) / cfile->fps / CURRENT_CLIP_TOTAL_TIME;
9926 }
9927 } else {
9928 offset = cfile->real_pointer_time / CURRENT_CLIP_TOTAL_TIME * allocwidth;
9929 }
9930
9931 if (cfile->achans > 0) {
9932 bar_height = CE_AUDBAR_HEIGHT;
9933 if (mainw->laudio_drawable && (which == 0 || which == 2)) {
9934 allocheight = (double)lives_widget_get_allocation_height(mainw->laudbar) + bar_height
9937 lives_painter_move_to(creb, offset, allocy);
9938 lives_painter_line_to(creb, offset, allocy + allocheight);
9939 }
9940
9941 if (cfile->achans > 1 && (which == 0 || which == 3)) {
9942 if (mainw->raudio_drawable) {
9943 allocheight = (double)lives_widget_get_allocation_height(mainw->raudbar)
9944 + bar_height + widget_opts.packing_height * 2.5;
9946 lives_painter_move_to(creb, offset, allocy);
9947 lives_painter_line_to(creb, offset, allocy + allocheight);
9948 }
9949 }
9950 }
9951
9953 return TRUE;
9954 }
9955 }
9956
9957
9958 boolean all_expose_pb(LiVESWidget * widget, lives_painter_t *cr, livespointer psurf) {
9959 if (LIVES_IS_PLAYING) all_expose(widget, cr, psurf);
9960 return TRUE;
9961 }
9962
9963 boolean all_expose_nopb(LiVESWidget * widget, lives_painter_t *cr, livespointer psurf) {
9964 if (!LIVES_IS_PLAYING) all_expose(widget, cr, psurf);
9965 return TRUE;
9966 }
9967
9968 boolean expose_vid_draw(LiVESWidget * widget, lives_painter_t *cr, livespointer psurf) {
9969 if (mainw->video_drawable) {
9972 }
9973 return TRUE;
9974 }
9975
9976 boolean config_vid_draw(LiVESWidget * widget, LiVESXEventConfigure * event, livespointer user_data) {
9980 update_timer_bars(0, 0, 0, 0, 1);
9981 return TRUE;
9982 }
9983
9984 boolean expose_laud_draw(LiVESWidget * widget, lives_painter_t *cr, livespointer psurf) {
9985 if (mainw->laudio_drawable) {
9988 }
9989 return TRUE;
9990 }
9991
9992 boolean config_laud_draw(LiVESWidget * widget, LiVESXEventConfigure * event, livespointer user_data) {
9993 if (IS_VALID_CLIP(mainw->drawsrc)) {
9994 lives_painter_surface_t *surf = lives_widget_create_painter_surface(widget);
9995 lives_painter_surface_t *laudio_drawable;
9996
9997 clear_widget_bg(widget, surf);
9998 laudio_drawable = mainw->laudio_drawable;
9999 mainw->laudio_drawable = surf;
10000
10001 if (laudio_drawable) {
10002 lives_painter_surface_destroy(laudio_drawable);
10003 }
10005 }
10006 return TRUE;
10007 }
10008
10009
10010 boolean expose_raud_draw(LiVESWidget * widget, lives_painter_t *cr, livespointer psurf) {
10011 if (mainw->raudio_drawable) {
10014 }
10015 return TRUE;
10016 }
10017
10018 boolean config_raud_draw(LiVESWidget * widget, LiVESXEventConfigure * event, livespointer user_data) {
10019 if (IS_VALID_CLIP(mainw->drawsrc)) {
10020 lives_painter_surface_t *surf = lives_widget_create_painter_surface(widget);
10021 lives_painter_surface_t *raudio_drawable;
10022
10023 clear_widget_bg(widget, surf);
10024 raudio_drawable = mainw->raudio_drawable;
10025 mainw->raudio_drawable = surf;
10026
10027 if (raudio_drawable) {
10028 lives_painter_surface_destroy(raudio_drawable);
10029 }
10031 }
10032 return TRUE;
10033 }
10034
10035 boolean config_event2(LiVESWidget * widget, LiVESXEventConfigure * event, livespointer user_data) {
10037 return TRUE;
10038 }
10039
10040
10042 boolean all_config(LiVESWidget * widget, LiVESXEventConfigure * event, livespointer ppsurf) {
10043 lives_painter_surface_t **psurf = (lives_painter_surface_t **)ppsurf;
10044 if (mainw->no_configs) return TRUE;
10045
10046 if (!psurf) return FALSE;
10047 if (*psurf) lives_painter_surface_destroy(*psurf);
10048 *psurf = lives_widget_create_painter_surface(widget);
10049
10050#ifdef USE_SPECIAL_BUTTONS
10051 if (LIVES_IS_DRAWING_AREA(widget)) {
10052 LiVESWidget *parent = lives_widget_get_parent(widget);
10053 if (parent && LIVES_IS_BUTTON(parent) && is_standard_widget(parent)) {
10054 sbutt_render(parent, 0, NULL);
10055 return FALSE;
10056 }
10057 }
10058#endif
10059
10060 clear_widget_bg(widget, *psurf);
10061
10062 if (widget == mainw->start_image)
10064 else if (widget == mainw->end_image)
10066 else if (widget == mainw->preview_image)
10068 else if (widget == mainw->msg_area && !mainw->multitrack)
10069 msg_area_config(widget);
10070 else if (widget == mainw->dsu_widget)
10071 draw_dsu_widget(widget);
10072 else if (mainw->multitrack) {
10073 if (widget == mainw->multitrack->timeline_reg)
10075 else if (widget == mainw->multitrack->in_image || widget == mainw->multitrack->out_image) {
10077 } else if (widget == mainw->play_image) {
10078 lives_idle_add_simple(mt_idle_show_current_frame, (livespointer)mainw->multitrack);
10079 //lives_widget_queue_draw(mainw->multitrack->preview_frame);
10080 //set_mt_play_sizes_cfg(mainw->multitrack);
10081 //mt_show_current_frame(mainw->multitrack, FALSE);
10082 } else if (widget == mainw->multitrack->msg_area) {
10083 msg_area_config(widget);
10084 }
10085 }
10086 return FALSE;
10087 }
10088
10089
10090 boolean config_event(LiVESWidget * widget, LiVESXEventConfigure * event, livespointer user_data) {
10091 if (!mainw->configured) {
10093 return FALSE;
10094 }
10095 if (widget == LIVES_MAIN_WINDOW_WIDGET) {
10096 int scr_width, scr_height;
10097 scr_width = GUI_SCREEN_PHYS_WIDTH;
10098 scr_height = GUI_SCREEN_PHYS_HEIGHT;
10099 if (event->width != scr_width || event->height != scr_height) {
10101 if (scr_width != GUI_SCREEN_PHYS_WIDTH || scr_height != GUI_SCREEN_PHYS_HEIGHT) {
10102 if (!mainw->ignore_screen_size) {
10103 if (prefs->show_dev_opts) {
10104 g_printerr("VALLS %d %d %d %d %d %d\n", event->width, event->height, scr_width, scr_height,
10106 }
10108 if (!CURRENT_CLIP_IS_VALID) {
10110 // *INDENT-OFF*
10111 }}}
10113 }}
10114 // *INDENT-ON*
10115
10116 return FALSE;
10117 }
10118
10119
10120 // these two really belong with the processing widget
10121
10122 void on_effects_paused(LiVESButton * button, livespointer user_data) {
10123 char *com = NULL;
10124 const char *stockim;
10125 ticks_t xticks;
10126
10127 if (mainw->iochan || cfile->opening) {
10128 // pause during encoding (if we start using mainw->iochan for other things, this will
10129 // need changing...)
10130 if (!mainw->effects_paused) {
10132
10133 if (!cfile->opening) {
10134 lives_button_set_label(LIVES_BUTTON(button), _("Resume"));
10135 lives_label_set_text(LIVES_LABEL(mainw->proc_ptr->label2), _("\nPaused\n(click Resume to continue processing)"));
10136 d_print(_("paused..."));
10137 }
10138 } else {
10140
10141 if (!cfile->opening) {
10142 lives_button_set_label(LIVES_BUTTON(button), _("Paus_e"));
10143 lives_label_set_text(LIVES_LABEL(mainw->proc_ptr->label2), _("\nPlease Wait"));
10144 d_print(_("resumed..."));
10145 }
10146 }
10147 }
10148
10149 if (!mainw->iochan) {
10150 // pause during effects processing or opening
10152 if (!mainw->effects_paused) {
10153 mainw->timeout_ticks -= xticks;
10154 com = lives_strdup_printf("%s pause \"%s\"", prefs->backend_sync, cfile->handle);
10155 if (!mainw->preview) {
10156 lives_button_set_label(LIVES_BUTTON(button), _("Resume"));
10157 if (!cfile->nokeep) {
10158 char *tmp, *ltext;
10159
10160 if (!cfile->opening) {
10161 ltext = (_("Keep"));
10162 } else {
10163 ltext = (_("Enough"));
10164 }
10165 stockim = LIVES_STOCK_KEEP;
10167 lives_button_set_label(LIVES_BUTTON(mainw->proc_ptr->cancel_button), ltext);
10169 (tmp = lives_strdup_printf
10170 (_("\nPaused\n(click %s to keep what you have and stop)\n(click "
10171 "Resume to continue processing)"), ltext)));
10172 lives_free(tmp);
10173 lives_free(ltext);
10174 }
10176 mainw->multitrack->opts.render_audp)) {
10177 // render audio up to current tc
10178 mainw->flush_audio_tc = q_gint64((double)cfile->undo_end / cfile->fps * TICKS_PER_SECOND_DBL, cfile->fps);
10180 mainw->flush_audio_tc = 0;
10182 cfile->laudio_time = (double)(cfile->afilesize / (cfile->asampsize >> 3) / cfile->achans) / (double)cfile->arate;
10183 if (cfile->achans > 1) {
10184 cfile->raudio_time = cfile->laudio_time;
10185 }
10186 }
10187 d_print(_("paused..."));
10188 }
10189#ifdef ENABLE_JACK
10190 if (mainw->jackd && mainw->jackd_read && mainw->jackd_read->in_use)
10193#endif
10194#ifdef HAVE_PULSE_AUDIO
10195 if (mainw->pulsed && mainw->pulsed_read && mainw->pulsed_read->in_use)
10198#endif
10199 } else {
10200 mainw->timeout_ticks += xticks;
10201 com = lives_strdup_printf("%s resume \"%s\"", prefs->backend_sync, cfile->handle);
10202 if (!mainw->preview) {
10203 if (cfile->opening || !cfile->nokeep) lives_button_set_label(LIVES_BUTTON(button), _("Pause/_Enough"));
10204 else lives_button_set_label(LIVES_BUTTON(button), _("Paus_e"));
10205 lives_button_set_label(LIVES_BUTTON(mainw->proc_ptr->cancel_button), _("Cancel"));
10206 stockim = LIVES_STOCK_CANCEL;
10208 lives_label_set_text(LIVES_LABEL(mainw->proc_ptr->label2), _("\nPlease Wait"));
10209 d_print(_("resumed..."));
10210 }
10211#ifdef ENABLE_JACK
10212 if (mainw->jackd && mainw->jackd_read && mainw->jackd_read->in_use)
10215#endif
10216#ifdef HAVE_PULSE_AUDIO
10217 if (mainw->pulsed && mainw->pulsed_read && mainw->pulsed_read->in_use)
10220#endif
10221 }
10222
10223 if (!cfile->opening && !mainw->internal_messaging
10224 && !(
10225#ifdef ENABLE_JACK
10226 (mainw->jackd && mainw->jackd_read && mainw->jackd_read->in_use)
10227#else
10228 0
10229#endif
10230 ||
10231#ifdef HAVE_PULSE_AUDIO
10232 (mainw->pulsed && mainw->pulsed_read && mainw->pulsed->in_use)
10233#else
10234 0
10235#endif
10236 )) {
10237 lives_system(com, FALSE);
10238 }
10239 }
10240 lives_freep((void **)&com);
10242 }
10243
10244
10245 void on_preview_clicked(LiVESButton * button, livespointer user_data) {
10246 // play an effect/tool preview
10247 // IMPORTANT: cfile->undo_start and cfile->undo_end determine which frames
10248 // should be played
10249
10250 weed_plant_t *filter_map = mainw->filter_map; // back this up in case we are rendering
10251 weed_plant_t *afilter_map = mainw->afilter_map; // back this up in case we are rendering
10252 weed_plant_t *audio_event = mainw->audio_event;
10253
10254 uint64_t old_rte; //TODO - block better
10255 ticks_t xticks;
10256
10257 static volatile boolean in_preview_func = FALSE;
10258
10259 boolean resume_after;
10260 boolean ointernal_messaging = mainw->internal_messaging;
10261
10262 int ostart = cfile->start;
10263 int oend = cfile->end;
10264
10265 int toy_type = mainw->toy_type;
10266
10267 int current_file = mainw->current_file;
10268
10269 if (in_preview_func) {
10270 // called a second time from playback loop
10271 // this is a special value of cancel - don't propogate it to "open"
10273 return;
10274 }
10275
10276 if (mainw->noswitch) {
10278 return;
10279 }
10280
10281 in_preview_func = TRUE;
10282
10283 old_rte = mainw->rte;
10284 xticks = lives_get_current_ticks();
10285 mainw->timeout_ticks -= xticks;
10286
10289 // for realtime fx previews, we will switch all effects off and restore old
10290 // value after
10292 }
10293
10294 if (!LIVES_IS_PLAYING) {
10295 if (cfile->opening) {
10296 if (!cfile->opening_only_audio) {
10299 }
10301
10302 if (!mainw->multitrack && !cfile->is_loaded) {
10303 if (mainw->play_window) {
10304 cfile->is_loaded = TRUE;
10306 cfile->is_loaded = FALSE;
10307 }
10308 }
10309 }
10310
10311 resume_after = FALSE;
10312
10313 if (mainw->multitrack) {
10315 if (cfile->opening) {
10318 }
10319 }
10320
10321 if (user_data) {
10322 // called from multitrack
10323 /* if (mainw->play_window) { */
10324 /* resize_play_window(); */
10325 /* } */
10326 if (mainw->multitrack && mainw->multitrack->is_rendering) {
10327 mainw->play_start = 1;
10328 mainw->play_end = cfile->frames;
10329 } else {
10330 mainw->play_start = 1;
10331 mainw->play_end = INT_MAX;
10332 }
10333 } else {
10334 mainw->preview = TRUE;
10336 mainw->play_start = cfile->start = cfile->undo_start;
10337 mainw->play_end = cfile->end = cfile->undo_end;
10338 } else {
10340 // render audio up to current tc
10341 mainw->flush_audio_tc = q_gint64((double)cfile->undo_end / cfile->fps * TICKS_PER_SECOND_DBL, cfile->fps);
10343 mainw->flush_audio_tc = 0;
10345 cfile->laudio_time = (double)(cfile->afilesize / (cfile->asampsize >> 3) / cfile->achans) / (double)cfile->arate;
10346 if (cfile->achans > 1) {
10347 cfile->raudio_time = cfile->laudio_time;
10348 }
10349 }
10351 mainw->play_end = INT_MAX;
10352 }
10353 }
10354
10355 if (cfile->opening) mainw->effects_paused = TRUE;
10356 else {
10357 // stop effects processing (if preferred)
10359 if (!(mainw->effects_paused)) {
10360 on_effects_paused(LIVES_BUTTON(mainw->proc_ptr->pause_button), NULL);
10361 resume_after = TRUE;
10362 }
10363 }
10364 }
10365
10366 if (button) lives_button_set_label(LIVES_BUTTON(button), _("Stop"));
10367 if (mainw->proc_ptr) {
10371 }
10372 if (!cfile->opening) {
10374 }
10375
10376 desensitize();
10377
10378 if (cfile->opening || cfile->opening_only_audio) {
10380 if (!mainw->multitrack && !cfile->opening_audio) {
10381 showclipimgs();
10382 }
10383 resize(1);
10384 }
10385
10386 if (ointernal_messaging) {
10387 lives_sync(3);
10388 }
10389 current_file = mainw->current_file;
10390 resize(1);
10391
10392 // play the clip
10393 on_playsel_activate(NULL, LIVES_INT_TO_POINTER(TRUE));
10394
10395 if (current_file != mainw->current_file) {
10396 if (mainw->is_rendering) {
10397 mainw->files[current_file]->next_event = cfile->next_event;
10398 cfile->next_event = NULL;
10399 mainw->current_file = current_file;
10400 } else if (!mainw->multitrack) {
10401 switch_to_file((mainw->current_file = 0), current_file);
10402 }
10403 }
10404
10405 if (mainw->is_rendering) {
10408 }
10409
10410 if (cfile->opening) mainw->effects_paused = FALSE;
10411 else {
10412 // restart effects processing (if necessary)
10413 if (resume_after) on_effects_paused(LIVES_BUTTON(mainw->proc_ptr->pause_button), NULL);
10414 }
10415 // user_data is non-NULL if called from multitrack. We want to preserve the value of cancelled.
10416 if (!user_data) mainw->cancelled = CANCEL_NONE;
10417
10418 cfile->start = ostart;
10419 cfile->end = oend;
10420
10421 mainw->toy_type = (lives_toy_t)toy_type;
10423
10424 if (mainw->proc_ptr) {
10425 // proc_ptr can be NULL if we finished loading with a bg generator running
10427 if (button) lives_button_set_label(LIVES_BUTTON(button), _("Preview"));
10430 }
10431 mainw->preview = FALSE;
10432 desensitize();
10434
10435 if (!cfile->opening) {
10437 } else {
10438 /* for (i=1;i<MAX_FILES;i++) {
10439 if (mainw->files[i]!=NULL) {
10440 if (mainw->files[i]->menuentry!=NULL) {
10441 lives_widget_set_sensitive (mainw->files[i]->menuentry, TRUE);
10442 }}}*/
10443 if (!mainw->multitrack && mainw->play_window) {
10445 }
10446 }
10447 }
10448
10451
10452 // redraw our bars for the clip
10453 if (!mainw->merge && !mainw->multitrack) {
10455 }
10456 if (ointernal_messaging) {
10458
10459 // switch realtime fx back on
10460 mainw->rte = old_rte;
10461 }
10462
10463 if (mainw->play_window && mainw->fs && !mainw->multitrack) {
10464 // this prevents a hang when the separate window is visible
10465 // it may be the first time we have shown it
10467
10468 }
10469 xticks = lives_get_current_ticks();
10470 mainw->timeout_ticks += xticks;
10471 mainw->filter_map = filter_map;
10472 mainw->afilter_map = afilter_map;
10473 mainw->audio_event = audio_event;
10474
10475 if (mainw->multitrack) {
10476 current_file = mainw->current_file;
10477 mainw->current_file = mainw->multitrack->render_file;
10479 mainw->current_file = current_file;
10480 }
10481
10482 in_preview_func = FALSE;
10483 }
10484
10485
10486 void vj_mode_toggled(LiVESCheckMenuItem * menuitem, livespointer user_data) {
10488 if (!(do_yesno_dialog_with_check(_("VJ Mode is specifically designed to make LiVES ready for realtime presentation.\n"
10489 "Enabling VJ restart will have the following effects:\n"
10490 "\n\n - On startup, audio source will be set to external. "
10491 "Clips willl reload without audio (although the audio files will remain on the disk).\n"
10492 "Additionally, when playing external audio, LiVES uses the system clock for frame timings "
10493 "(rather than the soundcard) which may allow for slightly smoother playback.\n"
10494 "\n - only the lightest of checks will be done when reloading clips (unless a problem is detected "
10495 "during the reload.)\n\n"
10496 "Startup will be almost instantaneous, however in the rare occurence of corruption to "
10497 "a clip audio file, this will not be detected, as the file will not be loaded."
10498 "\nOn startup, LiVES will grab the keyboard and screen focus if it can,"
10499 "\n - Shutdown will be slightly more rapid as no cleanup of the working directory will be attempted"
10500 "\n - Rendered effects will not be loaded, which will further reduce the startup time. "
10501 "(Realtime effects will still be loaded as usual)\n"
10502 "\n - Any crash recovery files will be auto reloaded "
10503 "making it convenient to terminate LiVES using ctrl-c or simply shutting down the machine\n"
10504 "\n - Continuous looping of video will be enabled automatically on startup"),
10507 lives_check_menu_item_set_active(LIVES_CHECK_MENU_ITEM(mainw->vj_mode), FALSE);
10509 return;
10510 }
10511 }
10513 }
10514
10515
10522 void changed_fps_during_pb(LiVESSpinButton * spinbutton, livespointer user_data) {
10524 double new_fps;
10525
10526 if (!LIVES_IS_PLAYING) return;
10527 if (!CURRENT_CLIP_IS_VALID) return;
10528
10529 new_fps = lives_fix(lives_spin_button_get_value(LIVES_SPIN_BUTTON(spinbutton)), 3);
10530
10531 if (!user_data && ((!cfile->play_paused && cfile->pb_fps == new_fps) || (cfile->play_paused && new_fps == 0.))) {
10533 return;
10534 }
10535
10537
10538 if (new_fps != cfile->pb_fps && fabs(new_fps) > .001 && !cfile->play_paused) {
10541 ticks_t delta_ticks;
10542 delta_ticks = (mainw->currticks - mainw->startticks);
10543 delta_ticks = (ticks_t)((double)delta_ticks + fabs(cfile->pb_fps / new_fps));
10545 mainw->startticks = mainw->currticks - delta_ticks;
10546 }
10547
10548 cfile->pb_fps = new_fps;
10550
10552 if (new_fps >= 0.) cfile->adirection = LIVES_DIRECTION_FORWARD;
10553 else cfile->adirection = LIVES_DIRECTION_REVERSE;
10554 // update our audio player
10555#ifdef ENABLE_JACK
10557 if (mainw->jackd->playing_file == mainw->current_file) {
10558 mainw->jackd->sample_in_rate = cfile->arate * cfile->pb_fps / cfile->fps;
10560 && mainw->agen_key == 0 && !mainw->agen_needs_reinit) {
10561 jack_get_rec_avals(mainw->jackd);
10562 // *INDENT-OFF*
10563 }}}
10564 // *INDENT-ON*
10565#endif
10566
10567#ifdef HAVE_PULSE_AUDIO
10569 if (mainw->pulsed->playing_file == mainw->current_file) {
10570 mainw->pulsed->in_arate = cfile->arate * cfile->pb_fps / cfile->fps;
10571 if (mainw->pulsed->fd >= 0) {
10572 if (mainw->pulsed->in_arate > 0.) {
10574 } else {
10576 }
10577 }
10579 && mainw->agen_key == 0 && !mainw->agen_needs_reinit) {
10580 pulse_get_rec_avals(mainw->pulsed);
10581 // *INDENT-OFF*
10582 }}}
10583 // *INDENT-ON*
10584#endif
10585 }
10586
10587 if (cfile->play_paused && new_fps != 0.) {
10588 cfile->freeze_fps = new_fps;
10589 // unfreeze the clip at the new (non-zero) fps rate
10590 freeze_callback(NULL, NULL, 0, (LiVESXModifierType)0, NULL);
10591 return;
10592 }
10593
10594 if (cfile->pb_fps == 0. && !cfile->play_paused) {
10595 // freeze the clip
10596 freeze_callback(NULL, NULL, 0, (LiVESXModifierType)0, NULL);
10597 return;
10598 }
10599 }
10600
10601
10602 boolean on_mouse_scroll(LiVESWidget * widget, LiVESXEventScroll * event, livespointer user_data) {
10603 lives_mt *mt = (lives_mt *)user_data;
10604 LiVESXModifierType kstate = (LiVESXModifierType)event->state;
10605 uint32_t type = 1;
10606
10607 if (!LIVES_IS_INTERACTIVE) return FALSE;
10608 if (mt) {
10609 // multitrack mode
10610 if ((kstate & LIVES_DEFAULT_MOD_MASK) == LIVES_CONTROL_MASK) {
10611 if (lives_get_scroll_direction(event) == LIVES_SCROLL_UP) mt_zoom_in(NULL, mt);
10612 else if (lives_get_scroll_direction(event) == LIVES_SCROLL_DOWN) mt_zoom_out(NULL, mt);
10613 return FALSE;
10614 }
10615
10616 if (!prefs->mouse_scroll_clips) return FALSE;
10617
10618 if (mt->poly_state == POLY_CLIPS) {
10619 // check if mouse pointer is over clip scroll tab
10620 LiVESXWindow *window = lives_display_get_window_at_pointer
10621 ((LiVESXDevice *)mainw->mgeom[widget_opts.monitor].mouse_device,
10622 mt->display, NULL, NULL);
10623
10624 if (widget == mt->clip_scroll || window == lives_widget_get_xwindow(mt->poly_box)) {
10625 // scroll fwd / back in clips
10626 if (lives_get_scroll_direction(event) == LIVES_SCROLL_UP) mt_prevclip(NULL, NULL, 0, (LiVESXModifierType)0, user_data);
10627 else if (lives_get_scroll_direction(event) == LIVES_SCROLL_DOWN) mt_nextclip(NULL, NULL, 0, (LiVESXModifierType)0, user_data);
10628 }
10629 }
10630 return FALSE;
10631 }
10632
10633 // clip editor mode
10634
10635 if (!prefs->mouse_scroll_clips) return FALSE;
10636
10637 if ((kstate & LIVES_DEFAULT_MOD_MASK) == (LIVES_CONTROL_MASK | LIVES_SHIFT_MASK)) type = 2; // bg
10638 else if ((kstate & LIVES_DEFAULT_MOD_MASK) == LIVES_CONTROL_MASK) type = 0; // fg or bg
10639
10640 if (lives_get_scroll_direction(event) == LIVES_SCROLL_UP) prevclip_callback(NULL, NULL, 0, (LiVESXModifierType)0,
10641 LIVES_INT_TO_POINTER(type));
10642 else if (lives_get_scroll_direction(event) == LIVES_SCROLL_DOWN) nextclip_callback(NULL, NULL, 0, (LiVESXModifierType)0,
10643 LIVES_INT_TO_POINTER(type));
10644
10645 return TRUE;
10646 }
10647
10648
10649 // next few functions are for the timer bars
10650 boolean on_mouse_sel_update(LiVESWidget * widget, LiVESXEventMotion * event, livespointer user_data) {
10651 if (!LIVES_IS_INTERACTIVE) return FALSE;
10652
10654 int x, sel_current;
10655 double tpos;
10656
10658 LIVES_MAIN_WINDOW_WIDGET, &x, NULL);
10661 sel_current = calc_frame_from_time3(mainw->current_file, tpos);
10662 else
10663 sel_current = calc_frame_from_time(mainw->current_file, tpos);
10664
10665 if (mainw->sel_move == SEL_MOVE_SINGLE) {
10666 sel_current = calc_frame_from_time3(mainw->current_file, tpos);
10667 lives_spin_button_set_value(LIVES_SPIN_BUTTON(mainw->spinbutton_start), sel_current);
10668 lives_spin_button_set_value(LIVES_SPIN_BUTTON(mainw->spinbutton_end), sel_current);
10669 }
10670
10671 if (mainw->sel_move == SEL_MOVE_START || (mainw->sel_move == SEL_MOVE_AUTO && sel_current < mainw->sel_start)) {
10672 sel_current = calc_frame_from_time(mainw->current_file, tpos);
10673 if (LIVES_IS_PLAYING && sel_current > cfile->end) sel_current = cfile->end;
10674 lives_spin_button_set_value(LIVES_SPIN_BUTTON(mainw->spinbutton_start), sel_current);
10675 } else if (mainw->sel_move == SEL_MOVE_END || (mainw->sel_move == SEL_MOVE_AUTO && sel_current > mainw->sel_start)) {
10676 sel_current = calc_frame_from_time2(mainw->current_file, tpos);
10677 if (LIVES_IS_PLAYING && sel_current <= cfile->start) sel_current = cfile->start + 1;
10678 lives_spin_button_set_value(LIVES_SPIN_BUTTON(mainw->spinbutton_end), sel_current - 1);
10679 }
10680 }
10681 return FALSE;
10682 }
10683
10684
10685 boolean on_mouse_sel_reset(LiVESWidget * widget, LiVESXEventButton * event, livespointer user_data) {
10686 if (!LIVES_IS_INTERACTIVE) return FALSE;
10687
10688 if (mainw->current_file <= 0) return FALSE;
10689 mainw->sel_start = 0;
10690 if (!mainw->mouse_blocked) {
10693 }
10694 return FALSE;
10695 }
10696
10697
10698 boolean on_mouse_sel_start(LiVESWidget * widget, LiVESXEventButton * event, livespointer user_data) {
10699 int x;
10700
10701 if (!LIVES_IS_INTERACTIVE) return FALSE;
10702
10703 if (mainw->current_file <= 0) return FALSE;
10704
10706 LIVES_MAIN_WINDOW_WIDGET, &x, NULL);
10707
10709 (double)x / (double)(lives_widget_get_allocation_width(mainw->video_draw) - 1)
10711
10712 if (event->button == 3 && !mainw->selwidth_locked) {
10719 }
10720
10721 else {
10722 if (event->button == 2 && !mainw->selwidth_locked) {
10729 }
10730
10731 else {
10732 if (!mainw->selwidth_locked) {
10733 if ((mainw->sel_start < cfile->end && ((mainw->sel_start - cfile->start) <= (cfile->end - mainw->sel_start))) ||
10734 mainw->sel_start < cfile->start) {
10735 if (LIVES_IS_PLAYING && mainw->sel_start >= cfile->end) {
10736 mainw->sel_start = cfile->end;
10738 }
10741 } else {
10745 if (LIVES_IS_PLAYING && mainw->sel_start <= cfile->start) {
10746 mainw->sel_start = cfile->start;
10748 } else
10751 }
10752 } else {
10753 // locked selection
10754 if (mainw->sel_start > cfile->end) {
10755 // past end
10756 if (cfile->end + cfile->end - cfile->start + 1 <= cfile->frames) {
10757 lives_spin_button_set_value(LIVES_SPIN_BUTTON(mainw->spinbutton_end), cfile->end + cfile->end - cfile->start + 1);
10759 }
10760 } else {
10761 if (mainw->sel_start >= cfile->start) {
10762 if (mainw->sel_start > cfile->start + (cfile->end - cfile->start + 1) / 2) {
10763 // nearer to end
10766 } else {
10767 // nearer to start
10770 }
10771 } else {
10772 // before start
10773 if (cfile->start - cfile->end + cfile->start - 1 >= 1) {
10774 lives_spin_button_set_value(LIVES_SPIN_BUTTON(mainw->spinbutton_end), cfile->start - 1);
10776 // *INDENT-OFF*
10777 }}}}}}
10778 // *INDENT-ON*
10779
10780 if (mainw->mouse_blocked) {// stops a warning if the user clicks around a lot...
10783 }
10784 return FALSE;
10785 }
10786
10787
10788#ifdef ENABLE_GIW_3
10789 void on_hrule_value_changed(LiVESWidget * widget, livespointer user_data) {
10790 if (!LIVES_IS_INTERACTIVE) return;
10792
10793 if (LIVES_IS_PLAYING) {
10795 if (pfile->frames > 0) {
10797 giw_timeline_get_value(GIW_TIMELINE(widget)));
10799 }
10800 return;
10801 }
10802
10803 cfile->pointer_time = lives_ce_update_timeline(0, giw_timeline_get_value(GIW_TIMELINE(widget)));
10804 if (cfile->frames > 0) cfile->frameno = cfile->last_frameno = calc_frame_from_time(mainw->current_file, cfile->pointer_time);
10805
10806 if (cfile->pointer_time > 0.) {
10808 lives_widget_set_sensitive(mainw->trim_to_pstart, (cfile->achans * cfile->frames > 0));
10810 if (mainw->preview_box) {
10812 }
10813 } else {
10817 if (mainw->preview_box) {
10819 }
10820 }
10821 mainw->ptrtime = cfile->pointer_time;
10823 }
10824
10825#else
10826
10827 boolean on_hrule_update(LiVESWidget * widget, LiVESXEventMotion * event, livespointer user_data) {
10828 LiVESXModifierType modmask;
10829 LiVESXDevice *device;
10830 int x;
10831 if (LIVES_IS_PLAYING) return TRUE;
10832 if (!LIVES_IS_INTERACTIVE) return TRUE;
10834
10835 device = (LiVESXDevice *)mainw->mgeom[widget_opts.monitor].mouse_device;
10836 lives_widget_get_modmask(device, widget, &modmask);
10837
10838 if (!(modmask & LIVES_BUTTON1_MASK)) return TRUE;
10839
10840 lives_widget_get_pointer(device, widget, &x, NULL);
10841 cfile->pointer_time = lives_ce_update_timeline(0,
10842 (double)x / (double()lives_widget_get_allocation_width(widget) - 1)
10844 if (cfile->frames > 0) cfile->frameno = calc_frame_from_time(mainw->current_file, cfile->pointer_time);
10845 return TRUE;
10846 }
10847
10848
10849 boolean on_hrule_reset(LiVESWidget * widget, LiVESXEventButton * event, livespointer user_data) {
10850 //button release
10851 int x;
10852
10853 if (LIVES_IS_PLAYING) return FALSE;
10854 if (!LIVES_IS_INTERACTIVE) return FALSE;
10856
10858 widget, &x, NULL);
10859 cfile->pointer_time = lives_ce_update_timeline(0,
10860 (double)x / (double)(lives_widget_get_allocation_width(widget) - 1)
10862 if (cfile->frames > 0) {
10863 cfile->last_frameno = cfile->frameno = calc_frame_from_time(mainw->current_file, cfile->pointer_time);
10864 }
10865 if (cfile->pointer_time > 0.) {
10867 lives_widget_set_sensitive(mainw->trim_to_pstart, (cfile->achans * cfile->frames > 0));
10869 if (mainw->preview_box) {
10871 }
10872 } else {
10876 if (mainw->preview_box) {
10878 }
10879 }
10880 return FALSE;
10881 }
10882
10883
10884 boolean on_hrule_set(LiVESWidget * widget, LiVESXEventButton * event, livespointer user_data) {
10885 // button press
10886 int x;
10887
10888 if (!LIVES_IS_INTERACTIVE) return FALSE;
10890
10892 widget, &x, NULL);
10893
10894 cfile->pointer_time = lives_ce_update_timeline(0,
10895 (double)x / (double)(lives_widget_get_allocation_width(widget) - 1)
10897 if (cfile->frames > 0) cfile->frameno = cfile->last_frameno = calc_frame_from_time(mainw->current_file, cfile->pointer_time);
10899
10900 mainw->ptrtime = cfile->pointer_time;
10902 g_print("HRSET\n");
10903 return TRUE;
10904 }
10905
10906#endif
10907
10908
10909 boolean frame_context(LiVESWidget * widget, LiVESXEventButton * event, livespointer which) {
10910 //popup a context menu when we right click on a frame
10911
10912 LiVESWidget *save_frame_as;
10913 LiVESWidget *menu;
10914
10915 int frame = 0;
10916
10917 if (!LIVES_IS_INTERACTIVE) return FALSE;
10919
10920 if (mainw->multitrack && !mainw->multitrack->event_list) return FALSE;
10921
10922 // only accept right mouse clicks
10923
10924 if (event->button != 3) return FALSE;
10925
10926 if (!mainw->multitrack) {
10927 switch (LIVES_POINTER_TO_INT(which)) {
10928 case 1:
10929 // start frame
10930 frame = cfile->start;
10931 break;
10932 case 2:
10933 // end frame
10934 frame = cfile->end;
10935 break;
10936 default:
10937 // preview frame
10938 frame = mainw->preview_frame;
10939 break;
10940 }
10941 }
10942
10943 menu = lives_menu_new();
10944 lives_menu_set_title(LIVES_MENU(menu), _("Selected Frame"));
10945
10946 if (palette->style & STYLE_1) {
10947 lives_widget_set_bg_color(menu, LIVES_WIDGET_STATE_NORMAL, &palette->menu_and_bars);
10948 lives_widget_set_fg_color(menu, LIVES_WIDGET_STATE_NORMAL, &palette->menu_and_bars_fore);
10949 }
10950
10951 if (cfile->frames > 0 || mainw->multitrack) {
10952 save_frame_as = lives_standard_menu_item_new_with_label(_("_Save Frame as..."));
10953 lives_signal_sync_connect(LIVES_GUI_OBJECT(save_frame_as), LIVES_WIDGET_ACTIVATE_SIGNAL,
10954 LIVES_GUI_CALLBACK(save_frame),
10955 LIVES_INT_TO_POINTER(frame));
10956
10958 lives_container_add(LIVES_CONTAINER(menu), save_frame_as);
10959 }
10960
10962 lives_menu_popup(LIVES_MENU(menu), event);
10963
10964 return FALSE;
10965 }
10966
10967
10968 void on_less_pressed(LiVESButton * button, livespointer user_data) {
10970
10971 if (!LIVES_IS_PLAYING || mainw->internal_messaging || (mainw->is_processing && cfile->is_loaded)) return;
10972 if (cfile->next_event) return;
10973
10974 if (mainw->rte_keys != -1) {
10977 }
10978 }
10979
10980
10981 void on_slower_pressed(LiVESButton * button, livespointer user_data) {
10982 double change = 1., new_fps;
10983
10984 int type = 0;
10985
10986 lives_clip_t *sfile = cfile;
10988
10989 if (!LIVES_IS_PLAYING || mainw->internal_messaging || (mainw->is_processing && cfile->is_loaded)) return;
10990 if (mainw->record && !(prefs->rec_opts & REC_FRAMES)) return;
10991 if (cfile->next_event) return;
10992
10993 if (mainw->record && !mainw->record_paused && !(prefs->rec_opts & REC_FPS)) return;
10994
10995 if (user_data) {
10996 type = LIVES_POINTER_TO_INT(user_data);
10997 if (type == SCREEN_AREA_BACKGROUND) {
10998 if (!IS_NORMAL_CLIP(mainw->blend_file)) return;
10999 sfile = mainw->files[mainw->blend_file];
11000 } else if (!IS_NORMAL_CLIP(mainw->current_file)) return;
11001 }
11002
11003 if (sfile->next_event) return;
11004
11005 change *= prefs->fpschange_amount / TICKS_PER_SECOND_DBL * (double)KEY_RPT_INTERVAL * sfile->pb_fps;
11006 if (button) change *= 4.;
11007 if (sfile->pb_fps == 0.) return;
11008 if (sfile->pb_fps > 0.) {
11009 if (sfile->pb_fps < 0.1 || sfile->pb_fps < change) sfile->pb_fps = change;
11010 new_fps = sfile->pb_fps - change;
11011 if (sfile == cfile) lives_spin_button_set_value(LIVES_SPIN_BUTTON(mainw->spinbutton_pb_fps), new_fps);
11012 else sfile->pb_fps = new_fps;
11013 } else {
11014 if (sfile->pb_fps > change) sfile->pb_fps = change;
11015 if (sfile == cfile) lives_spin_button_set_value(LIVES_SPIN_BUTTON(mainw->spinbutton_pb_fps), (sfile->pb_fps - change));
11016 else sfile->pb_fps -= change;
11017 }
11018 }
11019
11020
11021 void on_more_pressed(LiVESButton * button, livespointer user_data) {
11023
11024 if (!LIVES_IS_PLAYING || mainw->internal_messaging || (mainw->is_processing && cfile->is_loaded)) return;
11025 if (cfile->next_event) return;
11026
11027 if (mainw->rte_keys != -1) {
11030 }
11031 }
11032
11033
11034 void on_faster_pressed(LiVESButton * button, livespointer user_data) {
11035 double change = 1.;
11036 int type = 0;
11037
11038 lives_clip_t *sfile = cfile;
11040
11041 if (!LIVES_IS_PLAYING || mainw->internal_messaging || (mainw->is_processing && cfile->is_loaded)) return;
11042 if (mainw->record && !(prefs->rec_opts & REC_FRAMES)) return;
11043 if (cfile->next_event) return;
11044
11045 if (mainw->record && !mainw->record_paused && !(prefs->rec_opts & REC_FPS)) return;
11046
11047 if (user_data) {
11048 type = LIVES_POINTER_TO_INT(user_data);
11049 if (type == SCREEN_AREA_BACKGROUND) {
11050 if (!IS_NORMAL_CLIP(mainw->blend_file)) return;
11051 sfile = mainw->files[mainw->blend_file];
11052 } else if (!IS_NORMAL_CLIP(mainw->current_file)) return;
11053 }
11054
11055 if (sfile->play_paused && sfile->freeze_fps < 0.) {
11056 sfile->pb_fps = -.00000001; // want to keep this as a negative value so when we unfreeze we still play in reverse
11057 }
11058
11059 if (sfile->next_event) return;
11060
11062 * (sfile->pb_fps == 0. ? 1. : sfile->pb_fps);
11063 if (button) change *= 4.;
11064
11065 if (sfile->pb_fps >= 0.) {
11066 if (sfile->pb_fps == FPS_MAX) return;
11067 if (sfile->pb_fps < 0.5) sfile->pb_fps = .5;
11068 if (sfile->pb_fps > FPS_MAX - change) sfile->pb_fps = FPS_MAX - change;
11069 if (sfile == cfile) lives_spin_button_set_value(LIVES_SPIN_BUTTON(mainw->spinbutton_pb_fps), (sfile->pb_fps + change));
11070 else sfile->pb_fps = sfile->pb_fps + change;
11071 } else {
11072 if (sfile->pb_fps == -FPS_MAX) return;
11073 if (sfile->pb_fps < -FPS_MAX - change) sfile->pb_fps = -FPS_MAX - change;
11074 if (sfile == cfile) lives_spin_button_set_value(LIVES_SPIN_BUTTON(mainw->spinbutton_pb_fps), (sfile->pb_fps + change));
11075 else sfile->pb_fps = sfile->pb_fps + change;
11076 }
11077 }
11078
11079
11080 void on_back_pressed(LiVESButton * button, livespointer user_data) {
11081 int type = 0;
11083 if (mainw->internal_messaging || (mainw->is_processing && cfile->is_loaded)) return;
11085
11086 if (mainw->record && !(prefs->rec_opts & REC_FRAMES)) return;
11087 if (cfile->next_event) return;
11088
11089 if (!LIVES_IS_PLAYING) {
11090 if (cfile->real_pointer_time > 0.) {
11091 cfile->real_pointer_time--;
11092 if (cfile->real_pointer_time < 0.) cfile->real_pointer_time = 0.;
11093 lives_ce_update_timeline(0, cfile->real_pointer_time);
11094 }
11095 return;
11096 }
11097
11098 if (user_data) {
11099 type = LIVES_POINTER_TO_INT(user_data);
11100 if (type == SCREEN_AREA_BACKGROUND) return; // TODO: implement scratch play for the blend file
11101 }
11102
11103 if (button) mainw->scratch |= SCRATCH_BACK_EXTRA;
11104 else mainw->scratch = SCRATCH_BACK;
11105 }
11106
11107
11108 void on_forward_pressed(LiVESButton * button, livespointer user_data) {
11109 int type = 0;
11111 if (mainw->internal_messaging || (mainw->is_processing && cfile->is_loaded)) return;
11112
11113 if (mainw->record && !(prefs->rec_opts & REC_FRAMES)) return;
11114 if (cfile->next_event) return;
11115
11116 if (!LIVES_IS_PLAYING) {
11117 if (cfile->real_pointer_time < CURRENT_CLIP_TOTAL_TIME) {
11118 cfile->real_pointer_time++;
11119 if (cfile->real_pointer_time > CURRENT_CLIP_TOTAL_TIME) cfile->real_pointer_time = CURRENT_CLIP_TOTAL_TIME;
11120 lives_ce_update_timeline(0, cfile->real_pointer_time);
11121 }
11122 return;
11123 }
11124
11125 if (user_data) {
11126 type = LIVES_POINTER_TO_INT(user_data);
11127 if (type == SCREEN_AREA_BACKGROUND) return; // TODO: implement scratch play for the blend file
11128 }
11129
11130 if (button) mainw->scratch = SCRATCH_FWD_EXTRA;
11131 else mainw->scratch = SCRATCH_FWD;
11132 }
11133
11134
11135 boolean freeze_callback(LiVESAccelGroup * group, LiVESWidgetObject * obj, uint32_t keyval, LiVESXModifierType mod,
11136 livespointer user_data) {
11137 weed_timecode_t tc;
11138 static boolean norecurse = FALSE;
11139
11140 if (norecurse) return TRUE;
11141
11142 if (mainw->multitrack && (LIVES_IS_PLAYING || mainw->multitrack->is_paused)) {
11143 on_playall_activate(NULL, NULL);
11144 return TRUE;
11145 }
11147 if (!LIVES_IS_PLAYING || (mainw->is_processing && cfile->is_loaded)) return TRUE;
11148 if (mainw->record && !(prefs->rec_opts & REC_FRAMES)) return TRUE;
11149
11150 // TODO: make pref (reset keymode grab on freeze)
11151 //if (group) mainw->rte_keys = -1;
11152
11153 if (cfile->play_paused) {
11154 cfile->pb_fps = cfile->freeze_fps;
11155 if (cfile->pb_fps != 0.) mainw->period = TICKS_PER_SECOND_DBL / cfile->pb_fps;
11156 else mainw->period = INT_MAX;
11157 cfile->play_paused = FALSE;
11158 if (mainw->record && !mainw->record_paused) {
11159 pthread_mutex_lock(&mainw->event_list_mutex);
11160 // write a RECORD_START marker
11163 pthread_mutex_unlock(&mainw->event_list_mutex);
11164 }
11165 } else {
11166 if (mainw->record) {
11167 pthread_mutex_lock(&mainw->event_list_mutex);
11168 // write a RECORD_END marker
11171 pthread_mutex_unlock(&mainw->event_list_mutex);
11172 }
11173
11174 cfile->freeze_fps = cfile->pb_fps;
11175 cfile->play_paused = TRUE;
11176 cfile->pb_fps = 0.;
11178 }
11179
11180 if (group) {
11181 norecurse = TRUE;
11182 lives_spin_button_set_value(LIVES_SPIN_BUTTON(mainw->spinbutton_pb_fps), cfile->pb_fps);
11183 norecurse = FALSE;
11184 }
11185
11186 if (prefs->audio_src == AUDIO_SRC_INT) {
11187#ifdef ENABLE_JACK
11191 mainw->jackd->is_paused = cfile->play_paused;
11192 if (mainw->record && !mainw->record_paused && (prefs->rec_opts & REC_AUDIO) && mainw->agen_key == 0 &&
11194 if (cfile->play_paused) {
11195 weed_plant_t *event = get_last_frame_event(mainw->event_list);
11196 insert_audio_event_at(event, -1, mainw->jackd->playing_file, 0., 0.); // audio switch off
11197 } else {
11198 jack_get_rec_avals(mainw->jackd);
11199 }
11200 }
11201#ifdef ENABLE_JACK_TRANSPORT
11202 if (cfile->play_paused) jack_pb_stop();
11203 else jack_pb_start(-1.);
11204#endif
11205 }
11206#endif
11207#ifdef HAVE_PULSE_AUDIO
11209 && mainw->pulsed->playing_file == mainw->playing_file && (prefs->audio_opts & AUDIO_OPTS_FOLLOW_FPS)) {
11210 if (!cfile->play_paused) mainw->pulsed->in_arate = cfile->arate * cfile->pb_fps / cfile->fps;
11211 mainw->pulsed->is_paused = cfile->play_paused;
11212 if (mainw->record && !mainw->record_paused && (prefs->rec_opts & REC_AUDIO) && mainw->agen_key == 0 &&
11214 if (cfile->play_paused) {
11215 if (!mainw->mute) {
11216 weed_plant_t *event = get_last_frame_event(mainw->event_list);
11217 insert_audio_event_at(event, -1, mainw->pulsed->playing_file, 0., 0.); // audio switch off
11218 }
11219 } else {
11220 pulse_get_rec_avals(mainw->pulsed);
11221 }
11222 }
11223 }
11224#endif
11225 }
11227 return TRUE;
11228 }
11229
11230
11231 boolean nervous_callback(LiVESAccelGroup * group, LiVESWidgetObject * obj, uint32_t keyval, LiVESXModifierType mod,
11232 livespointer clip_number) {
11233 if (mainw->multitrack) return FALSE;
11235 return TRUE;
11236 }
11237
11238
11248 boolean aud_lock_callback(LiVESAccelGroup * group, LiVESWidgetObject * obj, uint32_t keyval, LiVESXModifierType mod,
11249 livespointer statep) {
11250 boolean state = LIVES_POINTER_TO_INT(statep);
11253 || prefs->audio_src == AUDIO_SRC_EXT) return TRUE;
11254
11255 if (!state) {
11256 // lock OFF
11258 return TRUE;
11259 }
11263 resync_audio(cfile->frameno);
11264 changed_fps_during_pb(LIVES_SPIN_BUTTON(mainw->spinbutton_pb_fps), LIVES_INT_TO_POINTER(TRUE));
11265 }
11266 }
11268 return TRUE;
11269 }
11270
11271
11272 char *get_palette_name_for_clip(int clipno) {
11273 lives_clip_t *sfile;
11274 char *palname = NULL;
11275 if (!IS_VALID_CLIP(clipno)) return NULL;
11276 sfile = mainw->files[clipno];
11277 if (IS_NORMAL_CLIP(clipno)) {
11278 if (is_virtual_frame(clipno, sfile->frameno)) {
11279 lives_clip_data_t *cdata = ((lives_decoder_t *)sfile->ext_src)->cdata;
11280 palname = lives_strdup(weed_palette_get_name_full(cdata->current_palette, cdata->YUV_clamping, cdata->YUV_subspace));
11281 } else {
11282 palname = lives_strdup(weed_palette_get_name((sfile->bpp == 24 ? WEED_PALETTE_RGB24 : WEED_PALETTE_RGBA32)));
11283 }
11284 } else switch (sfile->clip_type) {
11285 case CLIP_TYPE_GENERATOR: {
11286 weed_plant_t *inst = (weed_plant_t *)sfile->ext_src;
11287 if (inst) {
11288 weed_plant_t *channel = get_enabled_channel(inst, 0, FALSE);
11289 if (channel) {
11290 int clamping, subspace, pal;
11291 pal = weed_channel_get_palette_yuv(channel, &clamping, NULL, &subspace);
11292 palname = lives_strdup(weed_palette_get_name_full(pal, clamping, subspace));
11293 }
11294 }
11295 }
11296 break;
11297 case CLIP_TYPE_VIDEODEV: {
11298#ifdef HAVE_UNICAP
11299 lives_vdev_t *ldev = (lives_vdev_t *)sfile->ext_src;
11300 palname = lives_strdup(weed_palette_get_name_full(ldev->current_palette, ldev->YUV_clamping, 0));
11301#endif
11302 }
11303 break;
11304 default: break;
11305 }
11306 if (!palname) palname = lives_strdup("??????");
11307 return palname;
11308 }
11309
11310
11311 boolean show_sync_callback(LiVESAccelGroup * group, LiVESWidgetObject * obj, uint32_t keyval, LiVESXModifierType mod,
11312 livespointer keybd) {
11313 if (!LIVES_IS_PLAYING) return FALSE;
11315
11316 if (!prefs->show_dev_opts) {
11317 int last_dprint_file = mainw->last_dprint_file;
11319 d_print_overlay(2.0, _("Playing frame %d / %d, at fps %.3f\n"),
11320 mainw->actual_frame, cfile->frames, cfile->pb_fps);
11322 mainw->last_dprint_file = last_dprint_file;
11323 return FALSE;
11324 }
11325
11326#ifdef USE_LIVES_MFUNCS
11327 show_memstats();
11328#endif
11329
11330 lives_freep((void **)&mainw->overlay_msg);
11331
11332 if (!keybd) mainw->lockstats = !mainw->lockstats;
11333 if (!mainw->lockstats) return FALSE;
11334
11336 return FALSE;
11337 }
11338
11344 boolean storeclip_callback(LiVESAccelGroup * group, LiVESWidgetObject * obj, uint32_t keyval, LiVESXModifierType mod,
11345 livespointer clip_number) {
11346 // ctrl-fn key will store a clip for higher switching
11347 int clip = LIVES_POINTER_TO_INT(clip_number) - 1;
11348 register int i;
11349
11350 if (!LIVES_IS_INTERACTIVE) return TRUE;
11351
11353 || (mainw->is_processing && cfile->is_loaded) || !mainw->cliplist) return TRUE;
11354
11355 if (clip >= FN_KEYS - 1) {
11356 // last fn key will clear all
11357 for (i = 0; i < FN_KEYS - 1; i++) {
11358 mainw->clipstore[i][0] = -1;
11359 }
11360 return TRUE;
11361 }
11362
11363 if (!IS_VALID_CLIP(mainw->clipstore[clip][0])) {
11364 mainw->clipstore[clip][0] = mainw->current_file;
11365 if (LIVES_IS_PLAYING) {
11366 mainw->clipstore[clip][1] = mainw->actual_frame;
11367 } else {
11368 int frame = calc_frame_from_time4(mainw->current_file, cfile->pointer_time);
11369 if (frame <= cfile->frames) mainw->clipstore[clip][1] = frame;
11370 else mainw->clipstore[clip][1] = 1;
11371 }
11372 } else {
11373 lives_clip_t *sfile = mainw->files[mainw->clipstore[clip][0]];
11374 if (LIVES_IS_PLAYING) {
11375 sfile->frameno = sfile->last_frameno = mainw->clipstore[clip][1];
11377 }
11378 if ((LIVES_IS_PLAYING && mainw->clipstore[clip][0] != mainw->playing_file)
11379 || (!LIVES_IS_PLAYING && mainw->clipstore[clip][0] != mainw->current_file)) {
11380 switch_clip(0, mainw->clipstore[clip][0], TRUE);
11381 }
11382 if (!LIVES_IS_PLAYING) {
11383 cfile->real_pointer_time = (mainw->clipstore[clip][1] - 1.) / cfile->fps;
11384 lives_ce_update_timeline(0, cfile->real_pointer_time);
11385 }
11387 }
11388 return TRUE;
11389 }
11390
11391
11392 void on_toolbar_hide(LiVESButton * button, livespointer user_data) {
11397 }
11398
11399
11400 void on_capture_activate(LiVESMenuItem * menuitem, livespointer user_data) {
11401 char **array;
11402 double rec_end_time = -1.;
11403 char *com;
11404 boolean sgui;
11405 int curr_file = mainw->current_file;
11406 LiVESResponseType response;
11408
11409#if !GTK_CHECK_VERSION(3, 0, 0)
11410#ifndef GDK_WINDOWING_X11
11412 _("\n\nThis function will only work with X11.\nPlease send a patch to get it working on other platforms.\n\n"));
11413 return;
11414#endif
11415#endif
11416
11417 if (!capable->has_xwininfo) {
11418 do_error_dialog(_("\n\nYou must install \"xwininfo\" before you can use this feature\n\n"));
11419 return;
11420 }
11421
11422 if (mainw->first_free_file == ALL_USED) {
11424 return;
11425 }
11426
11427 if (mainw->multitrack) {
11428 if (mainw->multitrack->idlefunc > 0) {
11430 mainw->multitrack->idlefunc = 0;
11432 }
11434 }
11435
11438 resaudw = create_resaudw(8, NULL, NULL);
11439 } else {
11440 resaudw = create_resaudw(9, NULL, NULL);
11441 }
11442 response = lives_dialog_run(LIVES_DIALOG(resaudw->dialog));
11443
11444 if (response != LIVES_RESPONSE_OK) {
11446
11447 if (mainw->multitrack) {
11450 }
11451 return;
11452 }
11453
11456 mainw->rec_arate = (int)atoi(lives_entry_get_text(LIVES_ENTRY(resaudw->entry_arate)));
11457 mainw->rec_achans = (int)atoi(lives_entry_get_text(LIVES_ENTRY(resaudw->entry_achans)));
11458 mainw->rec_asamps = (int)atoi(lives_entry_get_text(LIVES_ENTRY(resaudw->entry_asamps)));
11459
11460 if (lives_toggle_button_get_active(LIVES_TOGGLE_BUTTON(resaudw->rb_unsigned))) {
11462 }
11463 if (lives_toggle_button_get_active(LIVES_TOGGLE_BUTTON(resaudw->rb_bigend))) {
11465 }
11466 } else {
11468 }
11469
11471
11472 if (!lives_toggle_button_get_active(LIVES_TOGGLE_BUTTON(resaudw->unlim_radiobutton))) {
11473 rec_end_time = (lives_spin_button_get_value(LIVES_SPIN_BUTTON(resaudw->hour_spinbutton)) * 60.
11474 + lives_spin_button_get_value(LIVES_SPIN_BUTTON(resaudw->minute_spinbutton))) * 60.
11476 mainw->rec_vid_frames = (rec_end_time * mainw->rec_fps + .5);
11477 } else mainw->rec_vid_frames = -1;
11478
11481
11482 lives_freep((void **)&resaudw);
11483
11487 return;
11488 }
11489
11490 if (rec_end_time == 0.) {
11492 do_error_dialog(_("\nRecord time must be greater than 0.\n"));
11494 if (mainw->multitrack) {
11497 }
11498 return;
11499 }
11500
11503
11504 sgui = prefs->show_gui;
11505 prefs->show_gui = FALSE;
11506
11507 if (!(do_warning_dialog(
11508 _("Capture an External Window:\n\nClick on 'OK', then click on any desktop window to select it\n"
11509 "Click 'Cancel' to cancel\n\n")))) {
11510 if (sgui) {
11511 prefs->show_gui = TRUE;
11513 }
11514 d_print(_("External window was released.\n"));
11515 if (mainw->multitrack) {
11518 }
11519 return;
11520 }
11521
11522 prefs->show_gui = sgui;
11523
11524 // an example of using 'get_temp_handle()' ////////
11525 if (!get_temp_handle(-1)) {
11526 if (prefs->show_gui) {
11529 }
11530
11531 if (mainw->multitrack) {
11534 }
11535 return;
11536 }
11537
11538 com = lives_strdup_printf("%s get_window_id \"%s\"", prefs->backend, cfile->handle);
11539 lives_system(com, FALSE);
11540 lives_free(com);
11541
11542 if (THREADVAR(com_failed)) {
11543 close_temp_handle(curr_file);
11544 if (prefs->show_gui) {
11547 }
11548
11549 if (mainw->multitrack) {
11552 }
11553 return;
11554 }
11555
11556 do_progress_dialog(TRUE, FALSE, _("Click on any desktop window to capture it\n"
11557 "When a blank LiVES window appears behind it, "
11558 "then it is being recorded.\n\n"
11559 "<b><big>To end recording, switch focus to the LiVES window,\n"
11560 "and press the 'q' key.</big></b>\n"));
11561
11562 if (get_token_count(mainw->msg, '|') < 6) {
11563 close_temp_handle(curr_file);
11564 if (prefs->show_gui) {
11567 }
11568
11569 if (mainw->multitrack) {
11572 }
11573 return;
11574 }
11575
11576 array = lives_strsplit(mainw->msg, "|", -1);
11577#if IS_MINGW
11578 mainw->foreign_id = (HWND)atoi(array[1]);
11579#else
11580#if GTK_CHECK_VERSION(3, 0, 0) || defined GUI_QT
11581 mainw->foreign_id = (Window)atoi(array[1]);
11582#else
11583 mainw->foreign_id = (GdkNativeWindow)atoi(array[1]);
11584#endif
11585#endif
11586 mainw->foreign_width = atoi(array[2]);
11587 mainw->foreign_height = atoi(array[3]);
11588 mainw->foreign_bpp = atoi(array[4]);
11589 mainw->foreign_visual = lives_strdup(array[5]);
11590 lives_strfreev(array);
11591
11592 close_temp_handle(curr_file);
11593
11595
11596 d_print(_("\nExternal window captured. Width=%d, height=%d, bpp=%d. *Do not resize*\n\n"
11597 "Stop or 'q' to finish.\n(Default of %.3f frames per second will be used.)\n"),
11599
11600 // start another copy of LiVES and wait for it to return values
11601 com = lives_strdup_printf("%s -capture %d %u %d %d %s %d %d %.4f %d %d %d %d \"%s\"",
11607
11608 // force the dialog to disappear
11610
11611 lives_system(com, FALSE);
11612
11613 if (prefs->show_gui) {
11615 }
11616
11618
11621 do_error_dialog(_("LiVES was unable to capture this window. Sorry.\n"));
11623 sensitize();
11624 }
11625
11626 if (mainw->multitrack) {
11631 }
11632 }
11633
11634
11636 // this is in the second copy of lives, we are now going to grab frames from the X window
11637 char *capfilename = lives_strdup_printf(".capture.%d", mainw->foreign_key);
11638 char *capfile = lives_build_filename(prefs->workdir, capfilename, NULL);
11639
11640 char buf[32];
11641
11642 boolean retval;
11643 int capture_fd;
11644 register int i;
11645
11646 retval = prepare_to_play_foreign();
11647
11648 lives_freep((void **)&mainw->foreign_visual);
11649
11650 if (!retval) exit(2);
11651
11652 mainw->record_foreign = TRUE; // for now...
11653
11654 play_file();
11655
11656 // pass the handle and frames back to the caller
11657 capture_fd = creat(capfile, S_IRUSR | S_IWUSR);
11658 if (capture_fd < 0) {
11659 lives_free(capfile);
11660 exit(1);
11661 }
11662
11663 for (i = 1; i < MAX_FILES; i++) {
11664 if (!mainw->files[i]) break;
11665 lives_write(capture_fd, mainw->files[i]->handle, lives_strlen(mainw->files[i]->handle), TRUE);
11666 lives_write(capture_fd, "|", 1, TRUE);
11667 lives_snprintf(buf, 32, "%d", cfile->frames);
11668 lives_write(capture_fd, buf, strlen(buf), TRUE);
11669 lives_write(capture_fd, "|", 1, TRUE);
11670 }
11671
11672 close(capture_fd);
11673 lives_free(capfilename);
11674 lives_free(capfile);
11675 exit(0);
11676 }
11677
11678
11679 // TODO - move all encoder related stuff from here and plugins.c into encoders.c
11680 void on_encoder_ofmt_changed(LiVESCombo * combo, livespointer user_data) {
11681 // change encoder format in the encoder plugin
11682 render_details *rdet = (render_details *)user_data;
11683
11684 LiVESList *ofmt_all = NULL;
11685
11686 char **array;
11687 int counter, i;
11688 const char *new_fmt;
11689
11690 if (!rdet) {
11691 new_fmt = lives_combo_get_active_text(LIVES_COMBO(prefsw->ofmt_combo));
11692 } else {
11693 new_fmt = lives_combo_get_active_text(LIVES_COMBO(rdet->ofmt_combo));
11694 }
11695
11696 if (!strlen(new_fmt) || !strcmp(new_fmt, mainw->string_constants[LIVES_STRING_CONSTANT_ANY])) {
11697 return;
11698 }
11699
11700 if ((ofmt_all = plugin_request_by_line(PLUGIN_ENCODERS, future_prefs->encoder.name, "get_formats")) != NULL) {
11701 // get details for the current format
11702 counter = 0;
11703 for (i = 0; i < lives_list_length(ofmt_all); i++) {
11704 if (get_token_count((char *)lives_list_nth_data(ofmt_all, i), '|') > 2) {
11705 array = lives_strsplit((char *)lives_list_nth_data(ofmt_all, i), "|", -1);
11706
11707 if (!strcmp(array[1], new_fmt)) {
11708 if (prefsw) {
11710 lives_combo_set_active_index(LIVES_COMBO(prefsw->ofmt_combo), counter);
11712 }
11713 if (rdet) {
11715 lives_combo_set_active_index(LIVES_COMBO(rdet->ofmt_combo), counter);
11717 }
11718 lives_snprintf(future_prefs->encoder.of_name, 64, "%s", array[0]);
11719 lives_snprintf(future_prefs->encoder.of_desc, 128, "%s", array[1]);
11720
11721 future_prefs->encoder.of_allowed_acodecs = atoi(array[2]);
11722 lives_snprintf(future_prefs->encoder.of_restrict, 1024, "%s", array[3]);
11723 lives_strfreev(array);
11724 break;
11725 }
11726 lives_strfreev(array);
11727 counter++;
11728 }
11729 }
11730 lives_list_free_all(&ofmt_all);
11731
11732 if (rdet && !prefsw) {
11735 lives_snprintf(prefs->encoder.of_name, 64, "%s", future_prefs->encoder.of_name);
11736 lives_snprintf(prefs->encoder.of_desc, 128, "%s", future_prefs->encoder.of_desc);
11737 lives_snprintf(prefs->encoder.of_restrict, 1024, "%s", future_prefs->encoder.of_restrict);
11740 }
11741 }
11743 } else {
11745 }
11746 }
11747
11748 // TODO - move all this to audio.c
11749
11750 void on_export_audio_activate(LiVESMenuItem * menuitem, livespointer user_data) {
11751
11752 char *filt[] = {"*."LIVES_FILE_EXT_WAV, NULL};
11753 char *filename, *file_name;
11754 char *com, *tmp;
11755
11756 double start, end;
11757
11758 int nrate = cfile->arps;
11759 int asigned = !(cfile->signed_endian & AFORM_UNSIGNED);
11760
11761 if (cfile->end > 0 && !LIVES_POINTER_TO_INT(user_data)) {
11762 filename = choose_file((*mainw->audio_dir) ? mainw->audio_dir : NULL, NULL,
11763 filt, LIVES_FILE_CHOOSER_ACTION_SAVE, _("Export Selected Audio as..."), NULL);
11764 } else {
11765 filename = choose_file((*mainw->audio_dir) ? mainw->audio_dir : NULL, NULL,
11766 filt, LIVES_FILE_CHOOSER_ACTION_SAVE, _("Export Audio as..."), NULL);
11767 }
11768
11769 if (!filename) return;
11770 file_name = ensure_extension(filename, LIVES_FILE_EXT_WAV);
11771 lives_free(filename);
11772
11773 // warn if arps!=arate
11774 if (cfile->arate != cfile->arps) {
11776 _("\n\nThe audio playback speed has been altered for this clip.\nClick 'OK' to export at the new speed, "
11777 "or 'Cancel' to export at the original rate.\n"))) {
11778 nrate = cfile->arate;
11779 }
11780 }
11781
11782 if (cfile->start * cfile->end > 0 && !LIVES_POINTER_TO_INT(user_data)) {
11783 lives_snprintf(mainw->msg, MAINW_MSG_SIZE, _("Exporting audio frames %d to %d as %s..."), cfile->start, cfile->end, file_name);
11784 start = calc_time_from_frame(mainw->current_file, cfile->start);
11786 } else {
11787 lives_snprintf(mainw->msg, MAINW_MSG_SIZE, _("Exporting audio as %s..."), file_name);
11788 start = 0.;
11789 end = 0.;
11790 }
11791
11792 d_print(mainw->msg);
11793
11794 com = lives_strdup_printf("%s export_audio \"%s\" %.8f %.8f %d %d %d %d %d \"%s\"", prefs->backend, cfile->handle,
11795 start, end, cfile->arps, cfile->achans, cfile->asampsize, asigned, nrate,
11796 (tmp = lives_filename_from_utf8(file_name, -1, NULL, NULL, NULL)));
11797 lives_free(tmp);
11798
11799 lives_rm(cfile->info_file);
11800 lives_system(com, FALSE);
11801 lives_free(com);
11802
11803 if (THREADVAR(com_failed)) {
11804 lives_free(file_name);
11806 return;
11807 }
11808
11809 do_progress_dialog(TRUE, FALSE, _("Exporting audio"));
11810
11811 if (mainw->error) {
11816 } else {
11817 d_print_done();
11818 lives_snprintf(mainw->audio_dir, PATH_MAX, "%s", file_name);
11820 }
11821 lives_free(file_name);
11822 }
11823
11824
11825 void on_normalise_audio_activate(LiVESMenuItem * menuitem, livespointer user_data) {
11826 char *com;
11827
11828 if (!CURRENT_CLIP_HAS_AUDIO) return;
11829
11830 d_print(_("Normalising audio..."));
11831
11832 if (menuitem) desensitize();
11833 do_threaded_dialog(_("Normalizing audio..."), TRUE);
11834
11836
11837 if (!prefs->conserve_space) {
11838 com = lives_strdup_printf("%s backup_audio \"%s\"", prefs->backend_sync, cfile->handle);
11839 lives_system(com, FALSE);
11840 lives_free(com);
11841 if (THREADVAR(com_failed)) {
11844 if (menuitem) sensitize();
11845 return;
11846 }
11847 }
11848 normalise_audio(mainw->current_file, 0., 0., .95);
11849
11850 if (THREADVAR(write_failed) || THREADVAR(read_failed)) {
11851 THREADVAR(read_failed) = THREADVAR(write_failed) = 0;
11854 if (menuitem) sensitize();
11855 return;
11856 }
11857
11858 if (mainw->cancelled != CANCEL_NONE) {
11859 com = lives_strdup_printf("%s undo_audio \"%s\"", prefs->backend_sync, cfile->handle);
11861 lives_system(com, FALSE);
11862 lives_free(com);
11865 if (menuitem) sensitize();
11866 return;
11867 }
11868
11869 if (menuitem) cfile->changed = TRUE;
11871
11872 if (!prefs->conserve_space) {
11873 set_undoable(_("Normalise audio"), TRUE);
11874 cfile->undo_action = UNDO_AUDIO_VOL;
11875 }
11876 if (menuitem) sensitize();
11878 d_print_done();
11879 }
11880
11881
11882 void on_append_audio_activate(LiVESMenuItem * menuitem, livespointer user_data) {
11883 LiVESWidget *chooser;
11884
11885 char *filt[] = LIVES_AUDIO_LOAD_FILTER;
11886
11887 char *com, *tmp, *tmp2;
11888 char *a_type;
11889
11890 uint32_t chk_mask = WARN_MASK_LAYOUT_ALTER_AUDIO;
11891
11892 boolean gotit = FALSE;
11893
11894 int asigned = !(cfile->signed_endian & AFORM_UNSIGNED);
11895 int aendian = !(cfile->signed_endian & AFORM_BIG_ENDIAN);
11896
11897 int resp;
11898
11899 register int i;
11900
11901 if (!CURRENT_CLIP_IS_VALID) return;
11902
11903 if (!check_for_layout_errors(NULL, mainw->current_file, 1, 0, &chk_mask)) {
11904 return;
11905 }
11906
11907 chooser = choose_file_with_preview((*mainw->audio_dir) ? mainw->audio_dir : NULL, _("Append Audio File"), filt,
11909
11910 resp = lives_dialog_run(LIVES_DIALOG(chooser));
11911
11913
11914 if (resp != LIVES_RESPONSE_ACCEPT) {
11917 return;
11918 }
11919
11920 lives_snprintf(file_name, PATH_MAX, "%s",
11921 (tmp = lives_filename_to_utf8((tmp2 = lives_file_chooser_get_filename(LIVES_FILE_CHOOSER(
11922 chooser))),
11923 -1, NULL, NULL, NULL)));
11924 lives_free(tmp);
11925 lives_free(tmp2);
11926
11927 lives_widget_destroy(LIVES_WIDGET(chooser));
11928
11930
11931 lives_snprintf(mainw->audio_dir, PATH_MAX, "%s", file_name);
11933
11934 a_type = get_extension(file_name);
11935
11936 if (strlen(a_type)) {
11937 char *filt[] = LIVES_AUDIO_LOAD_FILTER;
11938 for (i = 0; filt[i]; i++) {
11939 if (!lives_ascii_strcasecmp(a_type, filt[i] + 2)) gotit = TRUE; // skip past "*." in filt
11940 }
11941 }
11942
11943 if (gotit) {
11944 com = lives_strdup_printf("%s append_audio \"%s\" \"%s\" %d %d %d %d %d \"%s\"", prefs->backend, cfile->handle,
11945 a_type, cfile->arate,
11946 cfile->achans, cfile->asampsize, asigned, aendian,
11947 (tmp = lives_filename_from_utf8(file_name, -1, NULL, NULL, NULL)));
11948 lives_free(tmp);
11949 } else {
11950 lives_free(a_type);
11952 if (mainw->multitrack) {
11955 }
11957 return;
11958 }
11959
11960 lives_free(a_type);
11961
11962 lives_snprintf(mainw->msg, MAINW_MSG_SIZE, _("Appending audio file %s..."), file_name);
11963 d_print(""); // force switchtext
11964 d_print(mainw->msg);
11965
11966 lives_rm(cfile->info_file);
11967 lives_system(com, FALSE);
11968 lives_free(com);
11969
11970 if (THREADVAR(com_failed)) {
11971 if (mainw->multitrack) {
11974 }
11976 return;
11977 }
11978
11979 if (!do_progress_dialog(TRUE, TRUE, _("Appending audio"))) {
11981
11983 mainw->error = FALSE;
11984 lives_rm(cfile->info_file);
11985 com = lives_strdup_printf("%s cancel_audio \"%s\"", prefs->backend, cfile->handle);
11986 lives_system(com, FALSE);
11987 if (!THREADVAR(com_failed)) {
11988 do_auto_dialog(_("Cancelling"), 0);
11990 }
11991 lives_free(com);
11993 if (mainw->error) d_print_failed();
11994 if (mainw->multitrack) {
11997 }
11999 return;
12000 }
12001
12002 if (mainw->error) {
12007 } else {
12009
12010 com = lives_strdup_printf("%s commit_audio \"%s\"", prefs->backend, cfile->handle);
12012 mainw->error = FALSE;
12013 lives_rm(cfile->info_file);
12014 lives_system(com, FALSE);
12015 lives_free(com);
12016
12017 if (THREADVAR(com_failed)) {
12019 if (mainw->multitrack) {
12022 }
12024 return;
12025 }
12026
12027 do_auto_dialog(_("Committing audio"), 0);
12029 if (mainw->error) {
12034 } else {
12035 get_dirname(file_name);
12036 lives_snprintf(mainw->audio_dir, PATH_MAX, "%s", file_name);
12038 cfile->changed = TRUE;
12039 d_print_done();
12040 }
12041 }
12042 cfile->undo_action = UNDO_APPEND_AUDIO;
12043 set_undoable(_("Append Audio"), !prefs->conserve_space);
12044
12045 if (mainw->multitrack) {
12048 }
12049 if (chk_mask != 0) popup_lmap_errors(NULL, LIVES_INT_TO_POINTER(chk_mask));
12050 }
12051
12052
12053 boolean on_trim_audio_activate(LiVESMenuItem * menuitem, livespointer user_data) {
12054 // type 0 == trim selected
12055 // type 1 == trim to play pointer
12056
12057 char *com, *msg, *tmp;
12058
12059 double start, end;
12060
12062
12063 int type = LIVES_POINTER_TO_INT(user_data);
12064
12065 if (!CURRENT_CLIP_IS_VALID) return FALSE;
12066
12067 if (type == 0) {
12068 start = calc_time_from_frame(mainw->current_file, cfile->start);
12069 end = calc_time_from_frame(mainw->current_file, cfile->end + 1);
12070 } else {
12071 start = 0.;
12072 end = cfile->pointer_time;
12073 }
12074
12075 tmp = (_("Deletion"));
12077 calc_frame_from_time(mainw->current_file, end), &chk_mask)) {
12078 lives_free(tmp);
12079 return FALSE;
12080 }
12081 lives_free(tmp);
12082
12083 if (end > cfile->laudio_time && end > cfile->raudio_time)
12084 msg = lives_strdup_printf(_("Padding audio to %.2f seconds..."), end);
12085 else
12086 msg = lives_strdup_printf(_("Trimming audio from %.2f to %.2f seconds..."), start, end);
12087
12088 d_print(msg);
12089 lives_free(msg);
12090
12091 com = lives_strdup_printf("%s trim_audio \"%s\" %.8f %.8f %d %d %d %d %d", prefs->backend, cfile->handle,
12092 start, end, cfile->arate,
12093 cfile->achans, cfile->asampsize, !(cfile->signed_endian & AFORM_UNSIGNED),
12094 !(cfile->signed_endian & AFORM_BIG_ENDIAN));
12095 lives_rm(cfile->info_file);
12096 lives_system(com, FALSE);
12097 lives_free(com);
12098
12099 if (THREADVAR(com_failed)) {
12102 return FALSE;
12103 }
12104
12105 do_progress_dialog(TRUE, FALSE, _("Trimming/Padding audio"));
12106
12107 if (mainw->error) {
12110 return FALSE;
12111 }
12112
12113 if (!prefs->conserve_space) {
12114 set_undoable(_("Trim/Pad Audio"), !prefs->conserve_space);
12115 cfile->undo_action = UNDO_TRIM_AUDIO;
12116 }
12117
12119 cfile->changed = TRUE;
12120 d_print_done();
12121
12122 if (mainw->sl_undo_mem && cfile->stored_layout_audio != 0.) {
12123 // need to invalidate undo/redo stack, in case file was used in some layout undo
12125 }
12126
12127 if (chk_mask != 0) popup_lmap_errors(NULL, LIVES_INT_TO_POINTER(chk_mask));
12128 return TRUE;
12129 }
12130
12131 void on_voladj_activate(LiVESMenuItem * menuitem, livespointer user_data) {create_new_pb_speed(3);}
12132
12133 void on_fade_audio_activate(LiVESMenuItem * menuitem, livespointer user_data) {
12134 // type == 0 fade in
12135 // type == 1 fade out
12136
12137 double startt, endt, startv, endv, time = 0.;
12138 char *msg, *msg2, *utxt, *com;
12139
12140 uint32_t chk_mask = 0;
12141
12142 lives_alarm_t alarm_handle;
12143 int type;
12144
12145 aud_dialog_t *aud_d = NULL;
12146
12147 if (!CURRENT_CLIP_IS_VALID) return;
12148
12149 if (menuitem) {
12150 cfile->undo1_int = type = LIVES_POINTER_TO_INT(user_data);
12151 aud_d = create_audfade_dialog(type);
12152 if (lives_dialog_run(LIVES_DIALOG(aud_d->dialog)) == LIVES_RESPONSE_CANCEL) {
12153 lives_free(aud_d);
12154 return;
12155 }
12156
12157 time = lives_spin_button_get_value(LIVES_SPIN_BUTTON(aud_d->time_spin));
12158
12160 } else {
12161 type = cfile->undo1_int;
12162 }
12163
12164 if (!menuitem || !aud_d->is_sel) {
12165 if (!menuitem) {
12166 endt = cfile->undo1_dbl;
12167 startt = cfile->undo2_dbl;
12168 } else {
12169 if (type == 0) {
12170 cfile->undo2_dbl = startt = 0.;
12171 cfile->undo1_dbl = endt = time;
12172 } else {
12173 cfile->undo1_dbl = endt = cfile->laudio_time;
12174 cfile->undo2_dbl = startt = cfile->laudio_time - time;
12175 }
12176 }
12177 } else {
12178 cfile->undo2_dbl = startt = ((double)cfile->start - 1.) / cfile->fps;
12179 cfile->undo1_dbl = endt = (double)cfile->end / cfile->fps;
12180 }
12181
12182 if (type == 0) {
12183 startv = 0.;
12184 endv = 1.;
12185 msg2 = (_("Fading audio in"));
12186 utxt = (_("Fade audio in"));
12187 } else {
12188 startv = 1.;
12189 endv = 0.;
12190 msg2 = (_("Fading audio out"));
12191 utxt = (_("Fade audio out"));
12192 }
12193
12194 if (menuitem) {
12196 if (!check_for_layout_errors(NULL, mainw->current_file, 1, 0, &chk_mask)) {
12197 return;
12198 }
12199
12200 if (!aud_d->is_sel)
12201 msg = lives_strdup_printf(_("%s over %.1f seconds..."), msg2, time);
12202 else
12203 msg = lives_strdup_printf(_("%s from time %.2f seconds to %.2f seconds..."), msg2, startt, endt);
12204 d_print(msg);
12205 lives_free(msg);
12206 lives_free(msg2);
12207 }
12208
12209 desensitize();
12210 do_threaded_dialog(_("Fading audio..."), FALSE);
12212
12215
12216 if (!prefs->conserve_space) {
12217 com = lives_strdup_printf("%s backup_audio \"%s\"", prefs->backend_sync, cfile->handle);
12218 lives_system(com, FALSE);
12219 lives_free(com);
12220
12221 if (THREADVAR(com_failed)) {
12222 lives_alarm_clear(alarm_handle);
12225 sensitize();
12227 return;
12228 }
12229 }
12230
12231 aud_fade(mainw->current_file, startt, endt, startv, endv);
12233
12234 while (lives_alarm_check(alarm_handle) > 0) {
12235 lives_usleep(prefs->sleep_time);
12236 }
12237
12238 lives_alarm_clear(alarm_handle);
12239
12241 d_print_done();
12242
12243 cfile->changed = TRUE;
12245
12246 if (!prefs->conserve_space) {
12247 set_undoable(utxt, TRUE);
12248 cfile->undo_action = UNDO_FADE_AUDIO;
12249 }
12250 lives_free(utxt);
12251 sensitize();
12252
12253 lives_freep((void **)&aud_d);
12254 if (chk_mask != 0) popup_lmap_errors(NULL, LIVES_INT_TO_POINTER(chk_mask));
12255 }
12256
12257
12258 boolean on_del_audio_activate(LiVESMenuItem * menuitem, livespointer user_data) {
12259 double start, end;
12260 char *com, *tmp, *msg = NULL;
12261
12262 uint32_t chk_mask = 0;
12263
12264 boolean bad_header = FALSE;
12265
12266 int i;
12267
12268 if (!CURRENT_CLIP_IS_VALID) return FALSE;
12269
12270 if (!menuitem) {
12271 // undo/redo
12272 start = cfile->undo1_dbl;
12273 end = cfile->undo2_dbl;
12274 } else {
12275 if (LIVES_POINTER_TO_INT(user_data)) {
12276 tmp = (_("Deleting all audio"));
12278 if (!check_for_layout_errors(tmp, mainw->current_file, 1, 0, &chk_mask)) {
12279 lives_free(tmp);
12280 return FALSE;
12281 }
12282 lives_free(tmp);
12283
12285 if (do_warning_dialog(_("\nDeleting all audio will close this file.\nAre you sure ?"))) close_current_file(0);
12287 return FALSE;
12288 }
12289 msg = (_("Deleting all audio..."));
12290 start = end = 0.;
12291 } else {
12292 start = calc_time_from_frame(mainw->current_file, cfile->start);
12293 end = calc_time_from_frame(mainw->current_file, cfile->end + 1);
12294 msg = lives_strdup_printf(_("Deleting audio from %.2f to %.2f seconds..."), start, end);
12295 start *= (double)cfile->arate / (double)cfile->arps;
12296 end *= (double)cfile->arate / (double)cfile->arps;
12297
12298 tmp = (_("Deleting audio"));
12300 if (!check_for_layout_errors(tmp, mainw->current_file, 1, 0, &chk_mask)) {
12301 lives_free(tmp);
12302 return FALSE;
12303 }
12304 }
12305
12306 cfile->undo1_dbl = start;
12307 cfile->undo2_dbl = end;
12308 }
12309
12310 cfile->undo_arate = cfile->arate;
12311 cfile->undo_signed_endian = cfile->signed_endian;
12312 cfile->undo_achans = cfile->achans;
12313 cfile->undo_asampsize = cfile->asampsize;
12314 cfile->undo_arps = cfile->arps;
12315
12316 if (msg) {
12317 d_print("");
12318 d_print(msg);
12319 lives_free(msg);
12320 }
12321
12322 com = lives_strdup_printf("%s delete_audio \"%s\" %.8f %.8f %d %d %d", prefs->backend,
12323 cfile->handle, start, end, cfile->arps,
12324 cfile->achans, cfile->asampsize);
12325 lives_rm(cfile->info_file);
12326 lives_system(com, FALSE);
12327 lives_free(com);
12328
12329 if (THREADVAR(com_failed)) {
12330 if (menuitem) d_print_failed();
12332 return FALSE;
12333 }
12334
12335 do_progress_dialog(TRUE, FALSE, _("Deleting Audio"));
12336
12337 if (mainw->error) {
12338 if (menuitem) d_print_failed();
12340 return FALSE;
12341 }
12342
12343 set_undoable(_("Delete Audio"), TRUE);
12344 cfile->undo_action = UNDO_DELETE_AUDIO;
12345
12347 cfile->changed = TRUE;
12348 sensitize();
12349
12350 if (cfile->laudio_time == 0. || cfile->raudio_time == 0.) {
12351 if (cfile->audio_waveform) {
12352 for (i = 0; i < cfile->achans; lives_freep((void **)&cfile->audio_waveform[i++]));
12353 lives_freep((void **)&cfile->audio_waveform);
12354 lives_freep((void **)&cfile->aw_sizes);
12355 }
12356 if (cfile->laudio_time == cfile->raudio_time) cfile->achans = 0;
12357 else cfile->achans = 1;
12358 if (!save_clip_value(mainw->current_file, CLIP_DETAILS_ACHANS, &cfile->achans)) bad_header = TRUE;
12359
12360 if (bad_header) do_header_write_error(mainw->current_file);
12361 }
12362
12363 if (menuitem) {
12364 d_print_done();
12365 }
12366
12367 if (mainw->sl_undo_mem && cfile->stored_layout_audio != 0.) {
12368 // need to invalidate undo/redo stack, in case file was used in some layout undo
12370 }
12371
12372 if (chk_mask != 0) popup_lmap_errors(NULL, LIVES_INT_TO_POINTER(chk_mask));
12373
12374 return TRUE;
12375 }
12376
12377
12378 void on_rb_audrec_time_toggled(LiVESToggleButton * togglebutton, livespointer user_data) {
12379 _resaudw *resaudw = (_resaudw *)user_data;
12380 if (!resaudw) return;
12381 if (lives_toggle_button_get_active(togglebutton)) {
12385 } else {
12389 }
12390 }
12391
12392
12393 void on_recaudclip_activate(LiVESMenuItem * menuitem, livespointer user_data) {
12396 return;
12397 }
12398
12403 mainw->rec_end_time = -1.;
12404 resaudw = create_resaudw(5, NULL, NULL);
12406 }
12407
12408 static uint32_t lmap_error_recsel;
12409
12410 void on_recaudsel_activate(LiVESMenuItem * menuitem, livespointer user_data) {
12411 uint32_t chk_mask = WARN_MASK_LAYOUT_ALTER_AUDIO;
12412
12413 lmap_error_recsel = 0;
12414
12415 if (!CURRENT_CLIP_IS_VALID) return;
12418 return;
12419 }
12420
12421 if (!check_for_layout_errors(NULL, mainw->current_file, 1, 0, &chk_mask)) {
12422 return;
12423 }
12424
12425 lmap_error_recsel = chk_mask;
12426
12427 mainw->rec_end_time = (cfile->end - cfile->start + 1.) / cfile->fps;
12428
12429 if (cfile->achans > 0) {
12430 mainw->fx1_val = cfile->arate;
12431 mainw->fx2_val = cfile->achans;
12432 mainw->fx3_val = cfile->asampsize;
12433 mainw->fx4_val = cfile->signed_endian;
12434 resaudw = create_resaudw(7, NULL, NULL);
12435 } else {
12440 resaudw = create_resaudw(6, NULL, NULL);
12441 }
12443 }
12444
12445
12446 void on_recaudclip_ok_clicked(LiVESButton * button, livespointer user_data) {
12447#ifdef RT_AUDIO
12448 ticks_t ins_pt;
12449 double aud_start, aud_end, vel = 1., vol = 1.;
12450
12451 uint32_t chk_mask;
12452
12453 boolean backr = FALSE;
12454
12455 int asigned = 1, aendian = 1;
12456 int old_file = mainw->current_file, new_file;
12457 int type = LIVES_POINTER_TO_INT(user_data);
12458 int oachans = 0, oarate = 0, oarps = 0, ose = 0, oasamps = 0;
12459
12460 char *com;
12461
12462 // type == 0 - new clip
12463 // type == 1 - existing clip
12464
12465 if (type == 1) d_print(""); // show switch message, if appropriate
12466
12468 if (!get_new_handle(mainw->current_file, NULL)) {
12469 mainw->current_file = old_file;
12470 return;
12471 }
12472
12473 cfile->is_loaded = TRUE;
12474 cfile->img_type = IMG_TYPE_BEST; // override the pref
12475
12476 cfile->arps = cfile->arate = (int)atoi(lives_entry_get_text(LIVES_ENTRY(resaudw->entry_arate)));
12477 cfile->achans = (int)atoi(lives_entry_get_text(LIVES_ENTRY(resaudw->entry_achans)));
12478 cfile->asampsize = (int)atoi(lives_entry_get_text(LIVES_ENTRY(resaudw->entry_asamps)));
12479
12480 mainw->rec_samples = -1;
12481 mainw->rec_end_time = -1.;
12482
12483 if (type == 0) {
12484 if (!lives_toggle_button_get_active(LIVES_TOGGLE_BUTTON(resaudw->unlim_radiobutton))) {
12486 + lives_spin_button_get_value(LIVES_SPIN_BUTTON(resaudw->minute_spinbutton))) * 60.
12489 }
12490 }
12491
12492 if (lives_toggle_button_get_active(LIVES_TOGGLE_BUTTON(resaudw->rb_unsigned))) {
12493 asigned = 0;
12494 }
12495 if (lives_toggle_button_get_active(LIVES_TOGGLE_BUTTON(resaudw->rb_bigend))) {
12496 aendian = 0;
12497 }
12498
12500
12501 cfile->signed_endian = get_signed_endian(asigned, aendian);
12504
12505 lives_freep((void **)&resaudw);
12506
12507 if (cfile->arate <= 0) {
12510 close_temp_handle(old_file);
12511 return;
12512 }
12513
12514 if (mainw->rec_end_time == 0.) {
12516 do_error_dialog(_("\nRecord time must be greater than 0.\n"));
12519 close_temp_handle(old_file);
12520 return;
12521 }
12522
12523 asigned = !asigned;
12524
12525 if (type == 0) {
12526 lives_snprintf(cfile->type, 40, "Audio");
12528
12530 }
12531
12533
12534 if (type == 1) {
12535 oachans = mainw->files[old_file]->achans;
12536 oarate = mainw->files[old_file]->arate;
12537 oarps = mainw->files[old_file]->arps;
12538 oasamps = mainw->files[old_file]->asampsize;
12539 ose = mainw->files[old_file]->signed_endian;
12540
12541 mainw->files[old_file]->arate = mainw->files[old_file]->arps = cfile->arate;
12542 mainw->files[old_file]->asampsize = cfile->asampsize;
12543 mainw->files[old_file]->achans = cfile->achans;
12544 mainw->files[old_file]->signed_endian = cfile->signed_endian;
12545 }
12546
12549
12550#ifdef ENABLE_JACK
12552 jack_rec_audio_to_clip(mainw->current_file, old_file, type == 0 ? RECA_NEW_CLIP : RECA_EXISTING);
12553 }
12554#endif
12555#ifdef HAVE_PULSE_AUDIO
12557 pulse_rec_audio_to_clip(mainw->current_file, old_file, type == 0 ? RECA_NEW_CLIP : RECA_EXISTING);
12558 }
12559#endif
12560
12561 if (type == 1) {
12562 // set these again, as playsel may have reset them
12563 mainw->files[old_file]->arate = mainw->files[old_file]->arps = cfile->arate;
12564 mainw->files[old_file]->asampsize = cfile->asampsize;
12565 mainw->files[old_file]->achans = cfile->achans;
12566 mainw->files[old_file]->signed_endian = cfile->signed_endian;
12567 }
12568
12569 if (type != 1 && mainw->cancelled == CANCEL_USER) {
12571 if (type == 1) {
12572 mainw->files[old_file]->arps = oarps;
12573 mainw->files[old_file]->arate = oarate;
12574 mainw->files[old_file]->achans = oachans;
12575 mainw->files[old_file]->asampsize = oasamps;
12576 mainw->files[old_file]->signed_endian = ose;
12577 }
12579 close_temp_handle(old_file);
12583 return;
12584 }
12585
12588
12589 if (type == 1) {
12590 // set these again in case reget_afilesize() reset them
12591 cfile->arate = cfile->arps = mainw->files[old_file]->arate;
12592 cfile->asampsize = mainw->files[old_file]->asampsize;
12593 cfile->achans = mainw->files[old_file]->achans;
12594 cfile->signed_endian = mainw->files[old_file]->signed_endian;
12595
12596 do_threaded_dialog(_("Committing audio"), FALSE);
12597 aud_start = 0.;
12599 aud_end = cfile->laudio_time;
12600
12601 if (aud_end == 0.) {
12603 close_temp_handle(old_file);
12605 d_print("nothing recorded...");
12607 return;
12608 }
12609
12610 ins_pt = (mainw->files[old_file]->start - 1.) / mainw->files[old_file]->fps * TICKS_PER_SECOND_DBL;
12611
12612 if (!prefs->conserve_space && oachans > 0) {
12613 com = lives_strdup_printf("%s backup_audio \"%s\"", prefs->backend_sync, mainw->files[old_file]->handle);
12614 lives_system(com, FALSE);
12615 lives_free(com);
12616
12617 if (THREADVAR(com_failed)) {
12619 close_temp_handle(old_file);
12622 return;
12623 }
12624 }
12625
12626 THREADVAR(read_failed) = THREADVAR(write_failed) = FALSE;
12627 lives_freep((void **)&THREADVAR(read_failed_file));
12628
12629 // insert audio from old (new) clip to current
12630 render_audio_segment(1, &(mainw->current_file), old_file, &vel, &aud_start, ins_pt,
12631 ins_pt + (ticks_t)((aud_end - aud_start)*TICKS_PER_SECOND_DBL), &vol, vol, vol, NULL);
12632
12634 close_current_file(old_file);
12635
12636 if (THREADVAR(write_failed)) {
12637 // on failure
12638 int outfile = (mainw->multitrack ? mainw->multitrack->render_file : mainw->current_file);
12639 char *outfilename = lives_get_audio_file_name(outfile);
12640 do_write_failed_error_s(outfilename, NULL);
12641 lives_free(outfilename);
12642
12643 if (!prefs->conserve_space && type == 1) {
12644 // try to recover backup
12645 com = lives_strdup_printf("%s undo_audio \"%s\"", prefs->backend_sync, mainw->files[old_file]->handle);
12646 lives_system(com, FALSE);
12647 lives_free(com);
12648 backr = TRUE;
12649 }
12650 }
12651
12652 if (THREADVAR(read_failed)) {
12653 do_read_failed_error_s(THREADVAR(read_failed_file), NULL);
12654 lives_freep((void **)&THREADVAR(read_failed_file));
12655 if (!prefs->conserve_space && type == 1 && !backr) {
12656 // try to recover backup
12657 com = lives_strdup_printf("%s undo_audio \"%s\"", prefs->backend_sync, mainw->files[old_file]->handle);
12658 lives_system(com, FALSE);
12659 lives_free(com);
12660 }
12661 }
12662 }
12663
12665 cfile->changed = TRUE;
12667
12669
12670 new_file = mainw->current_file;
12671 if (type == 0) {
12672 if (!mainw->multitrack) {
12673 switch_to_file((mainw->current_file = 0), new_file);
12674 }
12675 } else {
12676 if (!prefs->conserve_space) {
12677 set_undoable(_("Record new audio"), TRUE);
12678 cfile->undo_action = UNDO_REC_AUDIO;
12679 }
12680 }
12681
12682 d_print_done();
12684
12685 chk_mask = lmap_error_recsel;
12686 if (chk_mask != 0) popup_lmap_errors(NULL, LIVES_INT_TO_POINTER(chk_mask));
12687 lmap_error_recsel = 0;
12689
12690#endif
12691 }
12692
12693
12694 boolean on_ins_silence_activate(LiVESMenuItem * menuitem, livespointer user_data) {
12695 double start = 0, end = 0;
12696 char *com;
12697
12698 uint32_t chk_mask = 0;
12699
12700 boolean has_new_audio = FALSE;
12701
12702 int i;
12703
12704 if (!CURRENT_CLIP_IS_VALID) return FALSE;
12705
12707 has_new_audio = TRUE;
12708 }
12709
12710 if (!menuitem) {
12711 // redo
12712 if (cfile->achans != cfile->undo_achans) {
12713 if (cfile->audio_waveform) {
12714 for (i = 0; i < cfile->achans; lives_freep((void **)&cfile->audio_waveform[i++]));
12715 lives_freep((void **)&cfile->audio_waveform);
12716 lives_freep((void **)&cfile->aw_sizes);
12717 }
12718 }
12719 start = cfile->undo1_dbl;
12720 end = cfile->undo2_dbl;
12721 cfile->arate = cfile->undo_arate;
12722 cfile->signed_endian = cfile->undo_signed_endian;
12723 cfile->achans = cfile->undo_achans;
12724 cfile->asampsize = cfile->undo_asampsize;
12725 cfile->arps = cfile->undo_arps;
12726 }
12727
12728 if (!cfile->achans) {
12733 resaudw = create_resaudw(2, NULL, NULL);
12734 if (lives_dialog_run(LIVES_DIALOG(resaudw->dialog)) != LIVES_RESPONSE_OK) return FALSE;
12735 if (mainw->error) {
12736 mainw->error = FALSE;
12737 return FALSE;
12738 }
12739
12740 cfile->undo_arate = cfile->arate;
12741 cfile->undo_signed_endian = cfile->signed_endian;
12742 cfile->undo_achans = cfile->achans;
12743 cfile->undo_asampsize = cfile->asampsize;
12744 }
12745
12746 if (menuitem) {
12747 char *tmp = (_("Inserting silence"));
12749
12750 start = calc_time_from_frame(mainw->current_file, cfile->start);
12751 end = calc_time_from_frame(mainw->current_file, cfile->end + 1);
12752
12753 if (!check_for_layout_errors(tmp, mainw->current_file, cfile->start, cfile->end, &chk_mask)) {
12754 lives_free(tmp);
12755 return FALSE;
12756 }
12757 lives_free(tmp);
12758
12759 d_print(""); // force switchtext
12760 d_print(_("Inserting silence from %.2f to %.2f seconds..."), start, end);
12761 }
12762
12763 cfile->undo1_dbl = start;
12764 start *= (double)cfile->arate / (double)cfile->arps;
12765 cfile->undo2_dbl = end;
12766 end *= (double)cfile->arate / (double)cfile->arps;
12767
12768 // store values for undo
12769 cfile->old_laudio_time = cfile->laudio_time;
12770 cfile->old_raudio_time = cfile->raudio_time;
12771
12772 // with_sound is 2 (audio only), therefore start, end, where, are in seconds. rate is -ve to indicate silence
12773 com = lives_strdup_printf("%s insert \"%s\" \"%s\" %.8f 0. %.8f \"%s\" 2 0 0 0 0 %d %d %d %d %d 1",
12774 prefs->backend, cfile->handle,
12775 get_image_ext_for_type(cfile->img_type), start, end - start, cfile->handle, -cfile->arps,
12776 cfile->achans, cfile->asampsize, !(cfile->signed_endian & AFORM_UNSIGNED),
12777 !(cfile->signed_endian & AFORM_BIG_ENDIAN));
12778
12779 lives_rm(cfile->info_file);
12780 lives_system(com, FALSE);
12781 lives_free(com);
12782
12783 if (THREADVAR(com_failed)) {
12785 if (has_new_audio) cfile->achans = cfile->arate = cfile->asampsize = cfile->arps = 0;
12787 return FALSE;
12788 }
12789
12790 do_progress_dialog(TRUE, FALSE, _("Inserting Silence"));
12791
12792 if (mainw->error) {
12794 if (has_new_audio) cfile->achans = cfile->arate = cfile->asampsize = cfile->arps = 0;
12796 return FALSE;
12797 }
12798
12799 if (has_new_audio) {
12800 cfile->arate = cfile->arps = cfile->undo_arate;
12801 cfile->signed_endian = cfile->undo_signed_endian;
12802 cfile->achans = cfile->undo_achans;
12803 cfile->asampsize = cfile->undo_asampsize;
12804 }
12805
12806 set_undoable(_("Insert Silence"), TRUE);
12807 cfile->undo_action = UNDO_INSERT_SILENCE;
12808
12810 cfile->changed = TRUE;
12811
12813
12814 if (menuitem) {
12815 sensitize();
12816 d_print_done();
12817 }
12818
12819 if (mainw->sl_undo_mem && cfile->stored_layout_audio != 0.) {
12820 // need to invalidate undo/redo stack, in case file was used in some layout undo
12822 }
12823
12824 if (chk_mask != 0) popup_lmap_errors(NULL, LIVES_INT_TO_POINTER(chk_mask));
12825
12826 return TRUE;
12827 }
12828
12829
12830 void on_ins_silence_details_clicked(LiVESButton * button, livespointer user_data) {
12831 int asigned = 1, aendian = 1;
12832 boolean bad_header = FALSE;
12833
12834 cfile->arps = cfile->arate = (int)atoi(lives_entry_get_text(LIVES_ENTRY(resaudw->entry_arate)));
12835 cfile->achans = (int)atoi(lives_entry_get_text(LIVES_ENTRY(resaudw->entry_achans)));
12836 cfile->asampsize = (int)atoi(lives_entry_get_text(LIVES_ENTRY(resaudw->entry_asamps)));
12837 if (lives_toggle_button_get_active(LIVES_TOGGLE_BUTTON(resaudw->rb_unsigned))) {
12838 asigned = 0;
12839 }
12840 if (lives_toggle_button_get_active(LIVES_TOGGLE_BUTTON(resaudw->rb_bigend))) {
12841 aendian = 0;
12842 }
12843 cfile->signed_endian = get_signed_endian(asigned, aendian);
12846
12847 lives_freep((void **)&resaudw);
12848 if (cfile->arate <= 0) {
12850 cfile->achans = cfile->arate = cfile->arps = cfile->asampsize = 0;
12851 if (!save_clip_value(mainw->current_file, CLIP_DETAILS_ARATE, &cfile->arps)) bad_header = TRUE;
12852 if (!save_clip_value(mainw->current_file, CLIP_DETAILS_PB_ARATE, &cfile->arate)) bad_header = TRUE;
12853 if (!save_clip_value(mainw->current_file, CLIP_DETAILS_ACHANS, &cfile->achans)) bad_header = TRUE;
12854 if (!save_clip_value(mainw->current_file, CLIP_DETAILS_ASAMPS, &cfile->asampsize)) bad_header = TRUE;
12855
12856 if (bad_header) do_header_write_error(mainw->current_file);
12857 mainw->error = TRUE;
12858 return;
12859 }
12860 mainw->error = FALSE;
12861 }
12862
12863
12864 void on_lerrors_clear_clicked(LiVESButton * button, livespointer user_data) {
12865 boolean close = LIVES_POINTER_TO_INT(user_data);
12867
12868 if (mainw->multitrack) {
12869 if (mainw->multitrack->idlefunc > 0) {
12871 mainw->multitrack->idlefunc = 0;
12873 }
12875 }
12876
12878 save_layout_map(NULL, NULL, NULL, NULL);
12879 if (close) {
12880 boolean needs_idlefunc = mainw->mt_needs_idlefunc;
12883 mainw->mt_needs_idlefunc = needs_idlefunc;
12884 } else {
12888
12889 if (mainw->multitrack) {
12892 }
12893 }
12894 }
12895
12896
12897 void on_lerrors_delete_clicked(LiVESButton * button, livespointer user_data) {
12898 int num_maps = lives_list_length(mainw->affected_layouts_map);
12899 char *msg = lives_strdup_printf(P_("\nDelete %d layout...are you sure ?\n", "\nDelete %d layouts...are you sure ?\n", num_maps),
12900 num_maps);
12902
12903 if (mainw->multitrack) {
12904 if (mainw->multitrack->idlefunc > 0) {
12906 mainw->multitrack->idlefunc = 0;
12908 }
12910 }
12911
12912 if (!do_warning_dialog(msg)) {
12913 lives_free(msg);
12914 if (mainw->multitrack) {
12917 }
12918 return;
12919 }
12920
12921 lives_free(msg);
12923 on_lerrors_clear_clicked(button, LIVES_INT_TO_POINTER(TRUE));
12924 }
void audio_free_fnames(void)
Definition: audio.c:71
int64_t render_audio_segment(int nfiles, int *from_files, int to_file, double *avels, double *fromtime, weed_timecode_t tc_start, weed_timecode_t tc_end, double *chvol, double opvol_start, double opvol_end, lives_audio_buf_t *obuf)
render a chunk of audio, apply effects and mixing it
Definition: audio.c:1276
boolean resync_audio(double frameno)
resync audio playback to the current video frame
Definition: audio.c:2822
void aud_fade(int fileno, double startt, double endt, double startv, double endv)
fade in/fade out
Definition: audio.c:1813
void stop_audio_stream(void)
Definition: audio.c:3906
LIVES_GLOBAL_INLINE char * lives_get_audio_file_name(int fnum)
Definition: audio.c:55
boolean normalise_audio(int fnum, double start, double end, float thresh)
Definition: audio.c:280
LIVES_GLOBAL_INLINE lives_cancel_t handle_audio_timeout(void)
Definition: audio.c:3971
#define DEFAULT_AUDIO_SAMPS
Definition: audio.h:25
#define is_realtime_aplayer(ptype)
Definition: audio.h:236
#define DEFAULT_AUDIO_CHANS
Definition: audio.h:24
#define DEFAULT_AUDIO_RATE
defaults for when not specifed
Definition: audio.h:23
@ RECA_EXISTING
Definition: audio.h:199
@ RECA_GENERATED
Definition: audio.h:201
@ RECA_EXTERNAL
Definition: audio.h:200
@ RECA_NEW_CLIP
Definition: audio.h:198
@ AUDIO_LOOP_FORWARD
Definition: audio.h:147
@ AUDIO_LOOP_NONE
Definition: audio.h:146
@ AUDIO_LOOP_PINGPONG
Definition: audio.h:148
void on_boolean_toggled(LiVESWidgetObject *obj, livespointer user_data)
Definition: callbacks.c:8278
void on_select_new_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:4432
void on_prv_link_toggled(LiVESToggleButton *togglebutton, livespointer user_data)
Definition: callbacks.c:9652
#define GEN_SPB_LINK_I(n, bit)
Definition: callbacks.c:8482
void on_effects_paused(LiVESButton *button, livespointer user_data)
Definition: callbacks.c:10122
void on_eject_cd_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:9060
boolean storeclip_callback(LiVESAccelGroup *group, LiVESWidgetObject *obj, uint32_t keyval, LiVESXModifierType mod, livespointer clip_number)
jump to a stored clip / frame position during free playback clip number and frame position can be sto...
Definition: callbacks.c:11344
void email_author_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:7048
void on_recaudsel_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:12410
void on_select_from_start_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:4467
void on_showsubs_toggled(LiVESWidgetObject *obj, livespointer user_data)
Definition: callbacks.c:8267
void on_spin_end_value_changed(LiVESSpinButton *spinbutton, livespointer user_data)
Definition: callbacks.c:8517
boolean config_laud_draw(LiVESWidget *widget, LiVESXEventConfigure *event, livespointer user_data)
Definition: callbacks.c:9992
void on_cut_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:3120
void on_spin_start_value_changed(LiVESSpinButton *spinbutton, livespointer user_data)
Definition: callbacks.c:8495
void on_export_theme_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:1700
void changed_fps_during_pb(LiVESSpinButton *spinbutton, livespointer user_data)
This is a super important function : almost everything related to velocity direction changes during p...
Definition: callbacks.c:10522
void on_cleardisk_advanced_clicked(LiVESWidget *widget, livespointer user_data)
Definition: callbacks.c:6700
void on_save_textview_clicked(LiVESButton *button, livespointer user_data)
Definition: callbacks.c:7615
void unlock_loop_lock(void)
Definition: callbacks.c:4966
boolean show_sync_callback(LiVESAccelGroup *group, LiVESWidgetObject *obj, uint32_t keyval, LiVESXModifierType mod, livespointer keybd)
Definition: callbacks.c:11311
boolean on_trim_audio_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:12053
void on_ins_silence_details_clicked(LiVESButton *button, livespointer user_data)
Definition: callbacks.c:12830
boolean all_expose_overlay(LiVESWidget *widget, lives_painter_t *creb, livespointer psurf)
Definition: callbacks.c:9870
void on_encoder_ofmt_changed(LiVESCombo *combo, livespointer user_data)
Definition: callbacks.c:11680
void on_select_invert_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:4401
void on_rewind_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:4730
boolean prevclip_callback(LiVESAccelGroup *group, LiVESWidgetObject *obj, uint32_t keyval, LiVESXModifierType mod, livespointer user_data)
Definition: callbacks.c:5150
void on_save_subs_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:8658
void on_erase_subs_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:8680
void on_rename_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:9392
void on_recaudclip_ok_clicked(LiVESButton *button, livespointer user_data)
Definition: callbacks.c:12446
void drag_from_outside(LiVESWidget *widget, GdkDragContext *dcon, int x, int y, GtkSelectionData *data, uint32_t info, uint32_t time, livespointer user_data)
Definition: callbacks.c:7503
void on_vj_realize_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:6723
boolean dirchange_lock_callback(LiVESAccelGroup *group, LiVESWidgetObject *obj, uint32_t keyval, LiVESXModifierType mod, livespointer area_enum)
set in / out points for video looping during free playback, it is possible to set in / out points for...
Definition: callbacks.c:5054
boolean config_vid_draw(LiVESWidget *widget, LiVESXEventConfigure *event, livespointer user_data)
Definition: callbacks.c:9976
void on_back_pressed(LiVESButton *button, livespointer user_data)
Definition: callbacks.c:11080
void suggest_feature_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:7058
boolean on_save_set_activate(LiVESWidget *widget, livespointer user_data)
Definition: callbacks.c:5359
void on_save_selection_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:1415
void on_select_to_aend_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:4456
void on_slower_pressed(LiVESButton *button, livespointer user_data)
Definition: callbacks.c:10981
void on_sepwin_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:8055
void on_import_theme_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:1873
void on_mute_button_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:8382
boolean all_expose_pb(LiVESWidget *widget, lives_painter_t *cr, livespointer psurf)
Definition: callbacks.c:9958
void on_delete_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:4208
boolean on_hrule_update(LiVESWidget *widget, LiVESXEventMotion *event, livespointer user_data)
Definition: callbacks.c:10827
void on_show_keys_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:6720
void on_preview_spinbutton_changed(LiVESSpinButton *spinbutton, livespointer user_data)
Definition: callbacks.c:9628
void on_sticky_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:8222
void switch_clip_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:6959
boolean config_event(LiVESWidget *widget, LiVESXEventConfigure *event, livespointer user_data)
Definition: callbacks.c:10090
void on_volch_pressed(LiVESButton *button, livespointer user_data)
Definition: callbacks.c:5093
void on_open_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:7418
void show_manual_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:7043
void on_show_file_info_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:6776
void on_loop_video_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:8298
void end_fs_preview(void)
Definition: callbacks.c:7569
boolean nervous_callback(LiVESAccelGroup *group, LiVESWidgetObject *obj, uint32_t keyval, LiVESXModifierType mod, livespointer clip_number)
Definition: callbacks.c:11231
void on_volume_slider_value_changed(LiVESScaleButton *sbutton, livespointer user_data)
Definition: callbacks.c:8377
void on_loop_button_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:8306
void on_open_vcd_activate(LiVESMenuItem *menuitem, livespointer device_type)
Definition: callbacks.c:720
void on_lock_selwidth_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:4475
void on_cancel_opensel_clicked(LiVESButton *button, livespointer user_data)
Definition: callbacks.c:7684
boolean on_mouse_sel_reset(LiVESWidget *widget, LiVESXEventButton *event, livespointer user_data)
Definition: callbacks.c:10685
void on_open_new_audio_clicked(LiVESFileChooser *chooser, livespointer user_data)
Definition: callbacks.c:8745
boolean reload_set(const char *set_name)
Definition: callbacks.c:5661
void on_showfct_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:8208
void on_redo_activate(LiVESWidget *menuitem, livespointer user_data)
Definition: callbacks.c:2806
void help_translate_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:7063
void on_full_screen_pressed(LiVESButton *button, livespointer user_data)
Definition: callbacks.c:7844
boolean all_expose_nopb(LiVESWidget *widget, lives_painter_t *cr, livespointer psurf)
Definition: callbacks.c:9963
void on_show_messages_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:6771
void on_ping_pong_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:8360
void play_all(boolean from_menu)
Definition: callbacks.c:4482
void on_restore_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:2021
void on_export_audio_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:11750
void update_sel_menu(void)
Definition: callbacks.c:9666
void on_mute_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:8399
void on_double_size_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:8000
void on_fade_audio_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:12133
void unlock_set_file(const char *set_name)
Definition: callbacks.c:5652
boolean dirchange_callback(LiVESAccelGroup *group, LiVESWidgetObject *obj, uint32_t keyval, LiVESXModifierType mod, livespointer area_enum)
Definition: callbacks.c:4996
void on_rb_audrec_time_toggled(LiVESToggleButton *togglebutton, livespointer user_data)
Definition: callbacks.c:12378
void on_playclip_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:4579
void on_forward_pressed(LiVESButton *button, livespointer user_data)
Definition: callbacks.c:11108
void on_faster_pressed(LiVESButton *button, livespointer user_data)
Definition: callbacks.c:11034
void on_show_file_comments_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:6887
void on_spin_value_changed(LiVESSpinButton *spinbutton, livespointer user_data)
Definition: callbacks.c:8485
boolean expose_raud_draw(LiVESWidget *widget, lives_painter_t *cr, livespointer psurf)
Definition: callbacks.c:10010
void on_sepwin_pressed(LiVESButton *button, livespointer user_data)
Definition: callbacks.c:8044
void on_filechooser_cancel_clicked(LiVESWidget *widget)
Definition: callbacks.c:7672
void on_rename_clip_name(LiVESButton *button, livespointer user_data)
Definition: callbacks.c:9521
void donate_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:7068
void on_load_cdtrack_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:9044
void popup_lmap_errors(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:9335
void on_spin_step_value_changed(LiVESSpinButton *spinbutton, livespointer user_data)
Definition: callbacks.c:8506
void play_sel(void)
Definition: callbacks.c:4536
boolean on_stop_activate_by_del(LiVESWidget *widget, LiVESXEventDelete *event, livespointer user_data)
Definition: callbacks.c:4764
boolean nextclip_callback(LiVESAccelGroup *group, LiVESWidgetObject *obj, uint32_t keyval, LiVESXModifierType mod, livespointer user_data)
Definition: callbacks.c:5199
void on_recaudclip_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:12393
void switch_clip(int type, int newclip, boolean force)
Definition: callbacks.c:6900
boolean all_expose(LiVESWidget *widget, lives_painter_t *cr, livespointer psurf)
Definition: callbacks.c:9856
void on_select_all_activate(LiVESWidget *widget, livespointer user_data)
Definition: callbacks.c:4367
void on_load_audio_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:8716
void on_record_perf_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:4605
void on_open_loc_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:745
void on_open_utube_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:770
void on_fade_pressed(LiVESButton *button, livespointer user_data)
Definition: callbacks.c:8234
void on_preview_clicked(LiVESButton *button, livespointer user_data)
Definition: callbacks.c:10245
void on_load_subs_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:8576
void on_fs_preview_clicked(LiVESWidget *widget, livespointer user_data)
Definition: callbacks.c:7108
boolean fps_reset_callback(LiVESAccelGroup *group, LiVESWidgetObject *obj, uint32_t keyval, LiVESXModifierType mod, livespointer area_enum)
Definition: callbacks.c:5105
boolean on_mouse_scroll(LiVESWidget *widget, LiVESXEventScroll *event, livespointer user_data)
Definition: callbacks.c:10602
void on_full_screen_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:7990
boolean all_config(LiVESWidget *widget, LiVESXEventConfigure *event, livespointer ppsurf)
genric func. to create surfaces
Definition: callbacks.c:10042
boolean config_event2(LiVESWidget *widget, LiVESXEventConfigure *event, livespointer user_data)
Definition: callbacks.c:10035
void on_loop_cont_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:8316
void on_spinbutton_end_value_changed(LiVESSpinButton *spinbutton, livespointer user_data)
Definition: callbacks.c:9789
void on_location_select(LiVESButton *button, livespointer user_data)
Definition: callbacks.c:885
void vj_mode_toggled(LiVESCheckMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:10486
void on_pause_clicked(void)
Definition: callbacks.c:4773
lives_remote_clip_request_t * on_utube_select(lives_remote_clip_request_t *req, const char *tmpdir)
Definition: callbacks.c:910
void on_copy_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:2992
LIVES_GLOBAL_INLINE void lives_notify_int(int msgnumber, int msgint)
Definition: callbacks.c:77
void on_load_vcd_ok_clicked(LiVESButton *button, livespointer user_data)
Definition: callbacks.c:9317
void on_insert_activate(LiVESButton *button, livespointer user_data)
Definition: callbacks.c:3322
void on_toy_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:9550
void on_insertwsound_toggled(LiVESToggleButton *togglebutton, livespointer user_data)
Definition: callbacks.c:4952
void lives_exit(int signum)
Definition: callbacks.c:145
void mt_memory_free(void)
Definition: callbacks.c:2043
boolean expose_vid_draw(LiVESWidget *widget, lives_painter_t *cr, livespointer psurf)
Definition: callbacks.c:9968
boolean frame_context(LiVESWidget *widget, LiVESXEventButton *event, livespointer which)
Definition: callbacks.c:10909
void on_encoder_entry_changed(LiVESCombo *combo, livespointer ptr)
Definition: callbacks.c:4779
void on_save_as_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:1398
void on_more_pressed(LiVESButton *button, livespointer user_data)
Definition: callbacks.c:11021
void on_quit_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:2133
void on_lerrors_delete_clicked(LiVESButton *button, livespointer user_data)
Definition: callbacks.c:12897
void on_about_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:6977
void on_cleardisk_activate(LiVESWidget *widget, livespointer user_data)
Definition: callbacks.c:6139
boolean freeze_callback(LiVESAccelGroup *group, LiVESWidgetObject *obj, uint32_t keyval, LiVESXModifierType mod, livespointer user_data)
Definition: callbacks.c:11135
void lives_notify(int msgnumber, const char *msgstring)
Definition: callbacks.c:49
void on_close_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:1432
void on_playall_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:4530
void autolives_toggle(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:9398
void on_rev_clipboard_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:8528
void on_lerrors_clear_clicked(LiVESButton *button, livespointer user_data)
Definition: callbacks.c:12864
void on_show_clipboard_info_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:6892
#define GEN_SPB_LINK(n, bit)
Definition: callbacks.c:8480
void on_less_pressed(LiVESButton *button, livespointer user_data)
Definition: callbacks.c:10968
boolean on_mouse_sel_start(LiVESWidget *widget, LiVESXEventButton *event, livespointer user_data)
Definition: callbacks.c:10698
void on_cancel_keep_button_clicked(LiVESButton *button, livespointer user_data)
Definition: callbacks.c:7701
void lock_set_file(const char *set_name)
Definition: callbacks.c:5638
boolean record_toggle_callback(LiVESAccelGroup *group, LiVESWidgetObject *obj, uint32_t keyval, LiVESXModifierType mod, livespointer user_data)
Definition: callbacks.c:4718
void on_details_button_clicked(void)
Definition: callbacks.c:7834
void on_load_cdtrack_ok_clicked(LiVESButton *button, livespointer user_data)
Definition: callbacks.c:9079
void on_double_size_pressed(LiVESButton *button, livespointer user_data)
Definition: callbacks.c:7994
void on_fade_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:8242
boolean on_ins_silence_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:12694
void on_stop_clicked(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:1364
void on_insert_pre_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:3311
void on_append_audio_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:11882
void on_vj_reset_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:6740
void on_undo_activate(LiVESWidget *menuitem, livespointer user_data)
Definition: callbacks.c:2275
boolean mute_audio_callback(LiVESAccelGroup *group, LiVESWidgetObject *obj, uint32_t keyval, LiVESXModifierType mod, livespointer user_data)
Definition: callbacks.c:8392
void on_recent_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:833
boolean on_LiVES_delete_event(LiVESWidget *widget, LiVESXEventDelete *event, livespointer user_data)
Definition: callbacks.c:84
void on_voladj_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:12131
void report_bug_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:7053
void on_capture_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:11400
void on_audio_toggled(LiVESWidget *tbutton, LiVESWidget *label)
Definition: callbacks.c:8284
char * on_load_set_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:5590
boolean on_mouse_sel_update(LiVESWidget *widget, LiVESXEventMotion *event, livespointer user_data)
Definition: callbacks.c:10650
boolean config_raud_draw(LiVESWidget *widget, LiVESXEventConfigure *event, livespointer user_data)
Definition: callbacks.c:10018
void on_export_proj_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:1628
void on_opensel_range_ok_clicked(LiVESButton *button, livespointer user_data)
Definition: callbacks.c:7546
void on_select_to_end_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:4448
void on_select_end_only_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:4395
void on_select_last_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:4416
void on_capture2_activate(void)
Definition: callbacks.c:11635
void on_spinbutton_start_value_changed(LiVESSpinButton *spinbutton, livespointer user_data)
Definition: callbacks.c:9723
void on_playsel_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:4566
void on_ok_file_open_clicked(LiVESFileChooser *chooser, LiVESSList *fnames)
Definition: callbacks.c:7447
void on_open_sel_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:619
boolean on_hrule_reset(LiVESWidget *widget, LiVESXEventButton *event, livespointer user_data)
Definition: callbacks.c:10849
boolean check_for_layout_errors(const char *operation, int fileno, int start, int end, uint32_t *in_mask)
check for layout errors, using in_mask as a guide (mask values are taken from prefs->warn_mask,...
Definition: callbacks.c:4059
char * get_palette_name_for_clip(int clipno)
Definition: callbacks.c:11272
void on_import_proj_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:1538
boolean expose_laud_draw(LiVESWidget *widget, lives_painter_t *cr, livespointer psurf)
Definition: callbacks.c:9984
boolean on_hrule_set(LiVESWidget *widget, LiVESXEventButton *event, livespointer user_data)
Definition: callbacks.c:10884
void on_backup_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:1996
boolean clip_can_reverse(int clipno)
Definition: callbacks.c:4980
void on_select_start_only_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:4389
void on_paste_as_new_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:3152
void on_toolbar_hide(LiVESButton *button, livespointer user_data)
Definition: callbacks.c:11392
void on_stop_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:4748
boolean on_del_audio_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:12258
void del_current_set(boolean exit_after)
Definition: callbacks.c:2078
void on_normalise_audio_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: callbacks.c:11825
boolean aud_lock_callback(LiVESAccelGroup *group, LiVESWidgetObject *obj, uint32_t keyval, LiVESXModifierType mod, livespointer statep)
lock or unlock audio track changes in free playback if lock is switched on then the prefs to follow v...
Definition: callbacks.c:11248
void on_resaudio_ok_clicked(LiVESButton *, LiVESEntry *entry)
Definition: resample.c:1159
void on_resample_vid_ok(LiVESButton *, LiVESEntry *entry)
Definition: resample.c:1379
void ce_thumbs_highlight_current_clip(void)
Definition: ce_thumbs.c:673
LIVES_GLOBAL_INLINE void init_conversions(int intent)
Definition: colourspace.c:1804
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 * frame_index_copy(frames_t *findex, frames_t nframes, frames_t offset)
Definition: cvirtual.c:1052
frames_t count_virtual_frames(frames_t *findex, frames_t start, frames_t end)
count virtual frames between start and end (inclusive)
Definition: cvirtual.c:20
void clean_images_from_virtual(lives_clip_t *sfile, frames_t oldsframe, frames_t oldframes)
Definition: cvirtual.c:1025
frames_t load_frame_index(int fileno)
Definition: cvirtual.c:114
void reverse_frame_index(int sfileno)
Definition: cvirtual.c:985
boolean save_frame_index(int fileno)
Definition: cvirtual.c:56
boolean check_if_non_virtual(int fileno, frames_t start, frames_t end)
Definition: cvirtual.c:644
void insert_images_in_virtual(int sfileno, frames_t where, frames_t frames, frames_t *frame_index, frames_t start)
Definition: cvirtual.c:885
void restore_frame_index_back(int sfileno)
Definition: cvirtual.c:1000
frames_t realize_all_frames(int clipno, const char *msg, boolean enough)
Definition: cvirtual.c:849
void delete_frames_from_virtual(int sfileno, frames_t start, frames_t end)
Definition: cvirtual.c:938
boolean is_virtual_frame(int sfileno, frames_t frame)
Definition: cvirtual.c:1063
boolean check_clip_integrity(int fileno, const lives_clip_data_t *cdata, frames_t maxframe)
Definition: cvirtual.c:296
char * get_stats_msg(boolean calc_only)
Definition: diagnostics.c:22
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 boolean do_set_rename_old_layouts_warning(const char *new_set)
Definition: dialogs.c:3571
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
boolean do_header_write_error(int clip)
Definition: dialogs.c:4169
LiVESWidget * create_message_dialog(lives_dialog_t diat, const char *text, int warn_mask_number)
Definition: dialogs.c:260
boolean do_save_clipset_warn(void)
Definition: dialogs.c:2975
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
LiVESResponseType do_error_dialogf(const char *fmt,...)
Definition: dialogs.c:735
LIVES_GLOBAL_INLINE boolean do_theme_exists_warn(const char *themename)
Definition: dialogs.c:4561
void do_write_failed_error_s(const char *s, const char *addinfo)
Definition: dialogs.c:3979
LIVES_GLOBAL_INLINE boolean do_erase_subs_warning(void)
Definition: dialogs.c:4334
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_no_autolives_error(void)
Definition: dialogs.c:4500
LiVESResponseType do_error_dialog_with_check(const char *text, uint64_t warn_mask_number)
Definition: dialogs.c:800
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 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
void do_invalid_subs_error(void)
Definition: dialogs.c:4308
boolean do_comments_dialog(int fileno, char *filename)
Definition: dialogs.c:3288
LIVES_GLOBAL_INLINE LiVESResponseType do_retry_cancel_dialog(const char *text)
Definition: dialogs.c:730
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
LiVESResponseType do_info_dialogf(const char *fmt,...)
Definition: dialogs.c:773
boolean do_warning_dialogf(const char *fmt,...)
Definition: dialogs.c:551
void end_threaded_dialog(void)
Definition: dialogs.c:3883
LIVES_GLOBAL_INLINE void too_many_files(void)
Definition: dialogs.c:2996
boolean do_foundclips_query(void)
Definition: dialogs.c:4376
LIVES_GLOBAL_INLINE void do_audrate_error_dialog(void)
Definition: dialogs.c:3702
LIVES_GLOBAL_INLINE boolean do_layout_alter_audio_warning(void)
Definition: dialogs.c:3433
void do_read_failed_error_s(const char *s, const char *addinfo)
Definition: dialogs.c:4034
void add_warn_check(LiVESBox *box, int warn_mask_number)
Definition: dialogs.c:103
LIVES_GLOBAL_INLINE LiVESResponseType do_error_dialog(const char *text)
Definition: dialogs.c:749
LIVES_GLOBAL_INLINE boolean do_warning_dialog(const char *text)
Definition: dialogs.c:564
void threaded_dialog_spin(double fraction)
Definition: dialogs.c:3823
LIVES_GLOBAL_INLINE boolean do_please_install(const char *exec, uint64_t gflags)
Definition: dialogs.c:3659
boolean check_storage_space(int clipno, boolean is_processing)
Definition: dialogs.c:1086
void workdir_warning(void)
Definition: dialogs.c:3001
boolean do_clipboard_fps_warning(void)
Definition: dialogs.c:3244
LIVES_GLOBAL_INLINE boolean paste_enough_dlg(int lframe)
Definition: dialogs.c:3266
void do_audio_import_error(void)
Definition: dialogs.c:3381
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
boolean do_yesno_dialog_with_check(const char *text, uint64_t warn_mask_number)
Definition: dialogs.c:595
boolean check_backend_return(lives_clip_t *sfile)
Definition: dialogs.c:1009
LIVES_GLOBAL_INLINE boolean prompt_remove_layout_files(void)
Definition: dialogs.c:3408
void pconx_delete_all(void)
Definition: effects-data.c:153
void cconx_delete_all(void)
void weed_set_blend_factor(int hotkey)
void weed_unload_all(void)
unload all effects
weed_plant_t * get_enabled_channel(weed_plant_t *inst, int which, boolean is_in)
for FILTER_INST
Definition: effects-weed.c:536
#define WEED_LEAF_HOST_KEY
Definition: effects-weed.h:67
boolean rte_key_on_off(int key, boolean on)
Definition: effects.c:1232
void rte_keymodes_restore(int nkeys)
Definition: effects.c:1269
void rte_keymodes_backup(int nkeys)
Definition: effects.c:1257
void event_list_add_end_events(weed_event_t *event_list, boolean is_final)
Definition: events.c:5102
weed_plant_t * get_last_frame_event(weed_plant_t *event_list)
Definition: events.c:419
weed_plant_t * append_marker_event(weed_plant_t *event_list, weed_timecode_t tc, int marker_type)
Definition: events.c:1382
void insert_audio_event_at(weed_plant_t *event, int track, int clipnum, double seek, double vel)
Definition: events.c:1243
boolean deal_with_render_choice(boolean add_deinit)
Definition: events.c:5159
lives_render_error_t render_events_cb(boolean dummy)
Definition: events.c:4447
LIVES_GLOBAL_INLINE weed_timecode_t get_event_timecode(weed_plant_t *plant)
Definition: events.c:98
LIVES_GLOBAL_INLINE weed_plant_t * get_last_event(weed_plant_t *event_list)
Definition: events.c:124
boolean backup_recording(char **esave_file, char **asave_file)
Definition: events.c:5028
void event_list_free(weed_plant_t *event_list)
Definition: events.c:2313
double event_list_get_start_secs(weed_plant_t *event_list)
Definition: events.c:4618
#define EVENT_MARKER_RECORD_START
Definition: events.h:355
#define EVENT_MARKER_RECORD_END
Definition: events.h:356
render_details * rdet
Definition: events.h:256
void fade_background(void)
Definition: gui.c:3216
void resize_widgets_for_monitor(boolean do_get_play_times)
Definition: gui.c:3752
void enable_record(void)
Definition: gui.c:3706
void reset_message_area(void)
Definition: gui.c:4734
void toggle_record(void)
Definition: gui.c:3712
void fullscreen_internal(void)
Definition: gui.c:3440
void resize_play_window(void)
Definition: gui.c:4349
void load_theme_images(void)
Definition: gui.c:65
void make_play_window(void)
actually in gui.c
Definition: gui.c:3932
void kill_play_window(void)
Definition: gui.c:4386
void add_to_clipmenu(void)
Definition: gui.c:4512
void unfade_background(void)
Definition: gui.c:3324
char * get_menu_name(lives_clip_t *sfile, boolean add_setname)
Definition: gui.c:4487
char * choose_file(const char *dir, const char *fname, char **const filt, LiVESFileChooserAction act, const char *title, LiVESWidget *extra_widget)
Definition: interface.c:4080
LiVESWidget * create_cdtrack_dialog(int type, livespointer user_data)
Definition: interface.c:3138
void draw_dsu_widget(LiVESWidget *dsu_widget)
Definition: interface.c:5910
autolives_window * autolives_pre_dialog(void)
Definition: interface.c:4846
LiVESWidget * create_cleardisk_advanced_dialog(void)
Definition: interface.c:4481
double lives_ce_update_timeline(int frame, double x)
pointer position in timeline
Definition: interface.c:207
boolean update_dsu(livespointer data)
Definition: interface.c:6064
lives_clipinfo_t * create_clip_info_window(int audio_channels, boolean is_mt)
Definition: interface.c:1048
void do_keys_window(void)
Definition: interface.c:4733
aud_dialog_t * create_audfade_dialog(int type)
Definition: interface.c:3660
LiVESWidget * trash_rb(LiVESButtonBox *parent)
Definition: interface.c:1622
void create_new_pb_speed(short type)
window change speed from Tools menu
Definition: interface.c:3464
text_window * create_text_window(const char *title, const char *text, LiVESTextBuffer *textbuffer, boolean add_buttons)
Definition: interface.c:1390
LiVESWidget * choose_file_with_preview(const char *dir, const char *title, char **const filt, int filesel_type)
Definition: interface.c:4228
_entryw * create_rename_dialog(int type)
Definition: interface.c:2792
boolean msg_area_config(LiVESWidget *widget)
Definition: interface.c:6938
void update_timer_bars(int posx, int posy, int width, int height, int which)
draw the timer bars
Definition: interface.c:288
LiVESResponseType filter_cleanup(const char *trashdir, LiVESList **rec_list, LiVESList **rem_list, LiVESList **left_list)
Definition: interface.c:1981
void show_playbar_labels(int clipno)
Definition: interface.c:77
void redraw_timeline(int clipno)
Definition: interface.c:3412
_entryw * create_cds_dialog(int type)
Definition: interface.c:4348
_entryw * create_location_dialog(void)
Definition: interface.c:2350
LiVESWidget * scrolled_textview(const char *text, LiVESTextBuffer *textbuffer, int window_width, LiVESWidget **ptextview)
Definition: interface.c:1368
boolean youtube_select_format(lives_remote_clip_request_t *req)
Definition: interface.c:5495
_insertw * create_insert_dialog(void)
Definition: interface.c:1458
void redraw_timer_bars(double oldx, double newx, int which)
paint a damage region
Definition: interface.c:623
boolean run_diskspace_dialog_idle(livespointer data)
Definition: interface.c:5752
lives_remote_clip_request_t * run_youtube_dialog(lives_remote_clip_request_t *req)
Definition: interface.c:5071
LiVESWidget * create_opensel_dialog(int frames, double fps)
Definition: interface.c:2228
#define LIVES_PREVIEW_TYPE_IMAGE_ONLY
Definition: interface.h:174
#define LIVES_PREVIEW_TYPE_RANGE
Definition: interface.h:173
#define LIVES_PREVIEW_TYPE_VIDEO_AUDIO
Definition: interface.h:170
#define LIVES_FILE_SELECTION_VIDEO_AUDIO_MULTI
Definition: interface.h:179
_insertw * insertw
Definition: interface.h:313
@ LIVES_MATCH_CHOICE
Definition: interface.h:249
@ LIVES_MATCH_SPECIFIED
Definition: interface.h:250
#define CE_VIDBAR_HEIGHT
clip edit vid/aud bar height
Definition: interface.h:17
_entryw * locw
Definition: interface.h:312
#define LIVES_PREVIEW_TYPE_AUDIO_ONLY
Definition: interface.h:172
#define CE_AUDBAR_HEIGHT
clip edit vid/aud bar height
Definition: interface.h:20
text_window * textwindow
Definition: interface.h:314
#define LIVES_FILE_SELECTION_AUDIO_ONLY
Definition: interface.h:178
_entryw * renamew
Definition: interface.h:311
#define LIVES_FILE_SELECTION_VIDEO_AUDIO
Definition: interface.h:177
#define KEY_RPT_INTERVAL
Definition: keyboard.h:76
void binding_cb(lives_callback_t cb_type, const char *msgstring, ulong id)
Definition: liblives.cpp:2326
void * struct_from_template(lives_struct_type st_type)
Definition: lsd-tab.c:76
@ LIVES_STRUCT_FILE_DETS_T
Definition: lsd-tab.h:13
error("LSD_RANDFUNC(ptr, size) must be defined")
LIVES_GLOBAL_INLINE const char * lives_strappendf(const char *string, int len, const char *fmt,...)
boolean show_desktop_panel(void)
LIVES_GLOBAL_INLINE int lives_getgid(void)
LIVES_GLOBAL_INLINE boolean lives_strcmp(const char *st1, const char *st2)
returns FALSE if strings match
LIVES_GLOBAL_INLINE boolean lives_proc_thread_cancel(lives_proc_thread_t tinfo)
off_t get_dir_size(const char *dirname)
weed_plantptr_t lives_proc_thread_t
lives proc_threads API
char * get_mountpoint_for(const char *dir)
uint64_t get_ds_free(const char *dir)
Definition: machinestate.c:776
LIVES_GLOBAL_INLINE size_t lives_strlen(const char *s)
off_t sget_file_size(const char *name)
Definition: machinestate.c:962
void free_fdets_list(LiVESList **listp)
LIVES_GLOBAL_INLINE char * lives_concat_sep(char *st, const char *sep, char *x)
LIVES_GLOBAL_INLINE ticks_t lives_get_current_ticks(void)
Definition: machinestate.c:835
boolean disk_monitor_running(const char *dir)
Definition: machinestate.c:715
LIVES_GLOBAL_INLINE int lives_strappend(const char *string, int len, const char *xnew)
LIVES_GLOBAL_INLINE int lives_getuid(void)
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 void lives_proc_thread_join(lives_proc_thread_t tinfo)
uint64_t gen_unique_id(void)
Definition: machinestate.c:68
off_t reget_afilesize_inner(int fileno)
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
char * get_worktmp(const char *prefix)
void * main_thread_execute(lives_funcptr_t func, int return_type, void *retval, const char *args_fmt,...)
lives_proc_thread_t dir_to_file_details(LiVESList **listp, const char *dir, const char *orig_loc, uint64_t extra)
create a list from a (sub)directory '.
lives_proc_thread_t lives_proc_thread_create(lives_thread_attr_t attr, lives_funcptr_t func, int return_type, const char *args_fmt,...)
create the specific plant which defines a background task to be run
char * get_systmp(const char *suff, boolean is_dir)
void reget_afilesize(int fileno)
Definition: machinestate.c:972
lives_storage_status_t
disk/storage status values
Definition: machinestate.h:181
@ LIVES_STORAGE_STATUS_CRITICAL
Definition: machinestate.h:185
@ LIVES_STORAGE_STATUS_NORMAL
Definition: machinestate.h:183
@ LIVES_STORAGE_STATUS_WARNING
Definition: machinestate.h:184
@ LIVES_STORAGE_STATUS_OVERFLOW
Definition: machinestate.h:186
#define THREADVAR(var)
Definition: machinestate.h:531
#define lives_free
Definition: machinestate.h:52
#define lives_memset
Definition: machinestate.h:61
#define EXTRA_DETAILS_CLIPHDR
Definition: machinestate.h:333
#define PRIu64
Definition: machinestate.h:170
void *(* lives_funcptr_t)(void *)
Definition: machinestate.h:378
#define EXTRA_DETAILS_DIRSIZE
Definition: machinestate.h:327
#define EXTRA_DETAILS_EMPTY_DIRS
Definition: machinestate.h:328
#define LIVES_THRDATTR_NONE
Definition: machinestate.h:437
void load_end_image(int frame)
Definition: main.c:5922
void set_drawing_area_from_pixbuf(LiVESWidget *widget, LiVESPixbuf *pixbuf, lives_painter_surface_t *surface)
Definition: main.c:5525
void sensitize(void)
Definition: main.c:5078
void load_start_image(int frame)
Definition: main.c:5650
_palette * palette
interface colour settings
Definition: main.c:101
boolean resize_message_area(livespointer data)
Definition: main.c:3588
void procw_desensitize(void)
Definition: main.c:5445
boolean set_palette_colours(boolean force_reload)
Definition: main.c:2663
void showclipimgs(void)
Definition: main.c:5636
void resize(double scale)
Definition: main.c:10230
void load_preview_image(boolean update_always)
Definition: main.c:6205
void set_main_title(const char *file, int untitled)
Definition: main.c:5005
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
boolean switch_audio_clip(int new_file, boolean activate)
Definition: main.c:9808
void switch_to_file(int old_file, int new_file)
Definition: main.c:9646
void get_monitors(boolean reset)
Definition: main.c:400
void close_current_file(int file_to_switch_to)
close current file, and try to switch to file_to_switch_to
Definition: main.c:9373
void clear_mainw_msg(void)
Definition: utils.c:1435
ulong open_file_sel(const char *file_name, double start_time, int frames)
Definition: saveplay.c:309
int lives_close_buffered(int fd)
Definition: utils.c:716
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
#define IMG_TYPE_BEST
Definition: main.h:781
#define CLIP_HAS_VIDEO(clip)
Definition: main.h:814
void get_basename(char *filename)
Definition: utils.c:3194
ssize_t lives_popen(const char *com, boolean allow_error, char *buff, ssize_t buflen)
Definition: utils.c:194
boolean add_lmap_error(lives_lmap_error_t lerror, const char *name, livespointer user_data, int clipno, int frameno, double atime, boolean affects_current)
Definition: utils.c:2673
lives_pid_t lives_fork(const char *com)
Definition: utils.c:288
#define CLIP_HAS_AUDIO(clip)
Definition: main.h:817
void activate_url(LiVESAboutDialog *about, const char *link, livespointer data)
Definition: utils.c:4624
#define clipboard
Definition: main.h:1835
void lives_list_free_all(LiVESList **)
Definition: utils.c:4873
boolean check_frame_count(int idx, boolean last_chkd)
check number of frames is correct for files of type CLIP_TYPE_DISK
Definition: utils.c:3074
#define LIVES_EXT_SRC_DECODER
Definition: main.h:1044
int lives_cat(const char *from, const char *to, boolean append)
Definition: utils.c:4484
void get_play_times(void)
recalculate video / audio lengths and draw the timer bars
Definition: utils.c:3672
@ UNDO_AUDIO_RESAMPLE
Definition: main.h:667
@ UNDO_EFFECT
Definition: main.h:661
@ UNDO_RENDER
resample/reorder/resize/apply effects
Definition: main.h:680
@ UNDO_APPEND_AUDIO
Definition: main.h:668
@ UNDO_REC_AUDIO
record audio to selection
Definition: main.h:686
@ UNDO_NEW_AUDIO
Definition: main.h:674
@ UNDO_MERGE
Definition: main.h:663
@ UNDO_INSERT_WITH_AUDIO
Definition: main.h:688
@ UNDO_DELETE_AUDIO
Definition: main.h:672
@ UNDO_CHANGE_SPEED
Definition: main.h:666
@ UNDO_INSERT
Definition: main.h:669
@ UNDO_AUDIO_VOL
Definition: main.h:683
@ UNDO_RESIZABLE
Definition: main.h:662
@ UNDO_TRIM_AUDIO
Definition: main.h:665
@ UNDO_INSERT_SILENCE
Definition: main.h:673
@ UNDO_RESAMPLE
Definition: main.h:664
@ UNDO_NONE
Definition: main.h:660
@ UNDO_ATOMIC_RESAMPLE_RESIZE
resample/resize and resample audio for encoding
Definition: main.h:677
@ UNDO_CUT
Definition: main.h:670
@ UNDO_FADE_AUDIO
Definition: main.h:682
@ UNDO_DELETE
Definition: main.h:671
size_t get_token_count(const char *string, int delim)
Definition: utils.c:5430
ssize_t lives_write(int fd, livesconstpointer buf, ssize_t count, boolean allow_fail)
#define USE_MPV
some shared structures
Definition: main.h:1112
@ NEVER_STOP
Definition: main.h:693
#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
void d_print_file_error_failed(void)
Definition: utils.c:2625
void get_total_time(lives_clip_t *file)
calculate laudio, raudio and video time (may be deprecated and replaced with macros)
Definition: utils.c:3690
void lives_sync(int times)
Definition: utils.c:115
double calc_time_from_frame(int clip, int frame)
Definition: utils.c:1756
void cached_list_free(LiVESList **list)
Definition: utils.c:4881
boolean read_file_details(const char *file_name, boolean only_check_for_audio, boolean open_image)
Definition: saveplay.c:207
void backup_file(int clip, int start, int end, const char *filename)
Definition: saveplay.c:4264
int lives_touch(const char *tfile)
Definition: utils.c:4455
#define LIVES_COPYRIGHT_YEARS
Definition: main.h:198
#define LIVES_GLOBAL_INLINE
Definition: main.h:239
boolean get_temp_handle(int index)
get a temp "handle" from disk.
Definition: saveplay.c:3571
int lives_chdir(const char *path, boolean no_error_dlg)
Definition: utils.c:1393
#define CURRENT_CLIP_IS_CLIPBOARD
Definition: main.h:848
ticks_t lives_get_current_playback_ticks(ticks_t origsecs, ticks_t origusecs, lives_time_source_t *time_source)
Definition: utils.c:1481
char * subst(const char *string, const char *from, const char *to)
Definition: utils.c:5484
void maybe_add_mt_idlefunc(void)
@ 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
#define ANNOY_DISPLAY
Definition: main.h:441
#define ANNOY_FS
Definition: main.h:449
ssize_t lives_write_buffered(int fd, const char *buf, ssize_t count, boolean allow_fail)
Definition: utils.c:1226
void get_dirname(char *filename)
Definition: utils.c:3167
#define DEF_FILE_PERMS
non-executable, is modified by the umask
Definition: main.h:209
int calc_frame_from_time3(int filenum, double time)
nearest frame rounded down, [1, frames+1]
Definition: utils.c:1778
#define LIVES_IS_PLAYING
Definition: main.h:840
#define IS_NORMAL_CLIP(clip)
Definition: main.h:833
void play_file(void)
play the current clip from 'mainw->play_start' to 'mainw->play_end'
Definition: saveplay.c:2213
void close_scrap_file(boolean remove)
Definition: saveplay.c:5583
void close_ascrap_file(boolean remove)
Definition: saveplay.c:5612
void clear_lmap_errors(void)
Definition: utils.c:2858
boolean lives_make_writeable_dir(const char *newdir)
Definition: utils.c:5721
int lives_create_buffered(const char *pathname, int mode)
Definition: utils.c:698
void lives_suspend_resume_process(const char *dirname, boolean suspend)
Definition: utils.c:4527
ulong deduce_file(const char *filename, double start_time, int end)
Definition: saveplay.c:238
#define CURRENT_CLIP_TOTAL_TIME
Definition: main.h:846
void open_set_file(int clipnum)
Definition: saveplay.c:4864
#define CURRENT_CLIP_HAS_AUDIO
Definition: main.h:818
boolean d_print_overlay(double timeout_seconds, const char *fmt,...)
Definition: utils.c:2523
boolean lives_alarm_clear(lives_alarm_t alarm_handle)
Definition: utils.c:1732
boolean start_playback(int type)
Definition: saveplay.c:94
void set_redoable(const char *what, boolean sensitive)
Definition: utils.c:4813
#define HAS_EXTERNAL_PLAYER
Definition: main.h:1113
void get_filename(char *filename, boolean strip_dir)
Definition: utils.c:3205
int lives_system(const char *com, boolean allow_error)
Definition: utils.c:145
int lives_killpg(lives_pgid_t pgrp, int sig)
Definition: utils.c:1432
boolean restore_clip_binfmt(int clipno)
Definition: saveplay.c:6022
void find_when_to_stop(void)
Definition: utils.c:3722
void set_undoable(const char *what, boolean sensitive)
Definition: utils.c:4784
boolean rewrite_recovery_file(void)
Definition: saveplay.c:6473
void lives_kill_subprocesses(const char *dirname, boolean kill_parent)
Definition: utils.c:4516
char * get_extension(const char *filename)
Definition: utils.c:3217
boolean get_new_handle(int index, const char *name)
Definition: saveplay.c:3821
ulong restore_file(const char *filename)
Definition: saveplay.c:4964
int free_n_msgs(int frval)
Definition: utils.c:2381
#define AFORM_UNSIGNED
Definition: main.h:786
void reload_subs(int fileno)
Definition: saveplay.c:4942
#define CLIPBOARD_FILE
Definition: main.h:1834
boolean do_std_checks(const char *type_name, const char *type, size_t maxlen, const char *nreject)
Definition: utils.c:2929
char * lives_fgets(char *s, int size, FILE *stream)
Definition: utils.c:368
int lives_cp(const char *from, const char *to)
Definition: utils.c:4414
int count_resampled_frames(int in_frames, double orig_fps, double resampled_fps)
Definition: resample.c:72
int close_temp_handle(int new_clip)
close cfile and switch to new clip (may be -1)
Definition: saveplay.c:3498
const char * get_image_ext_for_type(lives_img_type_t imgtype)
Definition: utils.c:3025
void remove_layout_files(LiVESList *lmap)
Definition: utils.c:3559
lives_clip_t * create_cfile(int new_file, const char *handle, boolean is_loaded)
set default values for a clip (in memory)
Definition: saveplay.c:3656
boolean open_ascrap_file(void)
Definition: saveplay.c:5278
int lives_rmglob(const char *files)
Definition: utils.c:4404
#define FPS_MAX
maximum fps we will allow (double)
Definition: main.h:218
void update_play_times(void)
like get_play_times, but will force redraw of audio waveforms
Definition: utils.c:3677
boolean reload_clip(int fileno, int maxframe)
Definition: saveplay.c:5735
int lives_mv(const char *from, const char *to)
Definition: utils.c:4446
boolean save_clip_values(int which_file)
Definition: saveplay.c:103
@ CLIP_DETAILS_PB_FPS
Definition: main.h:1144
@ CLIP_DETAILS_ASAMPS
Definition: main.h:1153
@ CLIP_DETAILS_HEIGHT
Definition: main.h:1146
@ CLIP_DETAILS_FPS
Definition: main.h:1143
@ CLIP_DETAILS_CLIPNAME
Definition: main.h:1160
@ CLIP_DETAILS_WIDTH
Definition: main.h:1145
@ CLIP_DETAILS_PB_FRAMENO
Definition: main.h:1158
@ CLIP_DETAILS_ASIGNED
Definition: main.h:1151
@ CLIP_DETAILS_ACHANS
Definition: main.h:1150
@ CLIP_DETAILS_AENDIAN
Definition: main.h:1152
@ CLIP_DETAILS_PB_ARATE
Definition: main.h:1149
@ CLIP_DETAILS_BPP
Definition: main.h:1142
@ CLIP_DETAILS_ARATE
Definition: main.h:1148
@ CLIP_DETAILS_FRAMES
Definition: main.h:1154
#define RES_HIDE
Definition: main.h:456
#define CURRENT_CLIP_HAS_VIDEO
Definition: main.h:815
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
void set_sel_label(LiVESWidget *label)
Definition: utils.c:4838
lives_direction_t
use REVERSE / FORWARD when a sign is used, BACKWARD / FORWARD when a parity is used
Definition: main.h:851
@ LIVES_DIRECTION_REVERSE
Definition: main.h:852
@ LIVES_DIRECTION_UP
Definition: main.h:857
@ LIVES_DIRECTION_FORWARD
Definition: main.h:854
@ LIVES_DIRECTION_BACKWARD
Definition: main.h:853
int lives_rmdir(const char *dir, boolean force)
Definition: utils.c:4366
#define IS_VALID_CLIP(clip)
Definition: main.h:808
const char * get_deinterlace_string(void)
Definition: saveplay.c:230
void get_location(const char *exe, char *val, int maxlen)
Definition: utils.c:3407
void d_print_enough(int frames)
Definition: utils.c:2630
void save_frame(LiVESMenuItem *menuitem, livespointer user_data)
Definition: saveplay.c:1186
int lives_rm(const char *file)
Definition: utils.c:4395
int64_t ticks_t
Definition: main.h:97
void d_print_failed(void)
Definition: utils.c:2615
#define CURRENT_CLIP_IS_NORMAL
Definition: main.h:838
#define LIVES_TV_CHANNEL1
Definition: main.h:1837
boolean after_foreign_play(void)
Definition: utils.c:4193
capability * capable
Definition: main.h:627
#define RESTYPE_ACTION
Definition: main.h:462
@ UNCHECKED
Definition: main.h:393
@ LOCAL
Definition: main.h:395
#define cfile
Definition: main.h:1833
boolean prepare_to_play_foreign(void)
Definition: utils.c:4055
boolean check_for_lock_file(const char *set_name, int type)
check for set lock file do this via the back-end (smogrify) this allows for the locking scheme to be ...
Definition: utils.c:2894
void reset_clipmenu(void)
Definition: utils.c:4290
void d_print(const char *fmt,...)
Definition: utils.c:2542
#define LIVES_ERROR(x)
Definition: main.h:1870
boolean check_dir_access(const char *dir, boolean leaveit)
Definition: utils.c:4542
@ IMG_TYPE_UNKNOWN
Definition: main.h:775
@ IMG_TYPE_JPEG
Definition: main.h:776
int calc_frame_from_time4(int filenum, double time)
nearest frame, no maximum
Definition: utils.c:1788
int lives_cp_keep_perms(const char *from, const char *to)
Definition: utils.c:4437
int lives_echo(const char *text, const char *to, boolean append)
Definition: utils.c:4500
boolean check_for_executable(lives_checkstatus_t *cap, const char *exec)
Definition: utils.c:3434
LiVESList * lives_list_delete_string(LiVESList *, const char *string) WARN_UNUSED
Definition: utils.c:5801
void add_to_recovery_file(const char *handle)
Definition: saveplay.c:6460
boolean read_headers(int clipno, const char *dir, const char *file_name)
Definition: saveplay.c:4465
void activate_url_inner(const char *link)
Definition: utils.c:4607
boolean lives_buffered_rdonly_set_reversed(int fd, boolean val)
Definition: utils.c:681
boolean recover_files(char *recovery_file, boolean auto_recover)
Definition: saveplay.c:6033
LiVESList * lives_list_append_unique(LiVESList *xlist, const char *add)
Definition: utils.c:5776
#define AFORM_BIG_ENDIAN
Definition: main.h:787
#define CURRENT_CLIP_IS_VALID
Definition: main.h:809
void unbuffer_lmap_errors(boolean add)
Definition: utils.c:2656
char * ensure_extension(const char *fname, const char *ext) WARN_UNUSED
Definition: utils.c:3232
void recover_layout_map(int numclips)
Definition: saveplay.c:5632
uint32_t get_signed_endian(boolean is_signed, boolean little_endian)
produce bitmapped value
Definition: utils.c:5408
void calc_maxspect(int rwidth, int rheight, int *cwidth, int *cheight)
Definition: utils.c:2174
void d_print_done(void)
Definition: utils.c:2620
#define PATH_MAX
Definition: main.h:255
void buffer_lmap_error(lives_lmap_error_t lerror, const char *name, livespointer user_data, int clipno, int frameno, double atime, boolean affects_current)
Definition: utils.c:2640
boolean lives_freep(void **ptr)
Definition: utils.c:1411
boolean is_legal_set_name(const char *set_name, boolean allow_dupes, boolean leeway)
Definition: utils.c:2975
@ CLIP_TYPE_VIDEODEV
frames from video device
Definition: main.h:771
@ CLIP_TYPE_YUV4MPEG
yuv4mpeg stream
Definition: main.h:769
@ CLIP_TYPE_FILE
unimported video, not or partially broken in frames
Definition: main.h:765
@ CLIP_TYPE_GENERATOR
frames from generator plugin
Definition: main.h:766
@ 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
double lives_fix(double val, int decimals) GNU_CONST
Definition: utils.c:1446
int calc_frame_from_time2(int filenum, double time)
nearest frame [1, frames+1]
Definition: utils.c:1768
void init_clipboard(void)
Definition: utils.c:2238
boolean save_clip_value(int which, lives_clip_details_t, void *val)
Definition: utils.c:5175
#define CLIP_TOTAL_TIME(clip)
Definition: main.h:830
ulong open_file(const char *filename)
Definition: saveplay.c:261
ticks_t lives_alarm_check(lives_alarm_t alarm_handle)
Definition: utils.c:1687
@ CANCEL_RETRY
an error occurred, retry the operation
Definition: main.h:749
@ CANCEL_APP_QUIT
application quit
Definition: main.h:713
@ CANCEL_NO_PROPOGATE
cancel but keep opening
Definition: main.h:707
@ CANCEL_NONE
no cancel
Definition: main.h:701
@ CANCEL_ERROR
cancelled because of error
Definition: main.h:740
@ CANCEL_KEEP
user pressed 'Keep'
Definition: main.h:734
@ CANCEL_USER
user pressed stop
Definition: main.h:704
@ CANCEL_AUDIO_ERROR
cancelled because of soundcard error
Definition: main.h:743
@ CANCEL_USER_PAUSED
cancelled and paused
Definition: main.h:746
void show_manual_section(const char *lang, const char *section)
Definition: utils.c:4629
void set_default_comment(lives_clip_t *sfile, const char *extrat)
Definition: saveplay.c:1251
int calc_frame_from_time(int filenum, double time)
nearest frame [1, frames]
Definition: utils.c:1759
void save_file(int clip, int start, int end, const char *filename)
Definition: saveplay.c:1260
#define SEL_MOVE_SINGLE
Definition: mainwindow.h:891
#define MAINW_MSG_SIZE
mainw->msg bytesize
Definition: mainwindow.h:702
#define EXEC_AUTOLIVES_PL
shipped
Definition: mainwindow.h:414
#define THEME_DETAIL_MT_TLREG
Definition: mainwindow.h:286
lives_toy_t
toy types
Definition: mainwindow.h:233
@ LIVES_TOY_NONE
Definition: mainwindow.h:234
@ LIVES_TOY_MAD_FRAMES
Definition: mainwindow.h:235
@ LIVES_TOY_TV
Definition: mainwindow.h:236
#define LIVES_TRANSLATE_URL
Definition: mainwindow.h:527
#define THEME_DETAIL_FXCOL
Definition: mainwindow.h:285
#define SCRATCH_BACK_EXTRA
Definition: mainwindow.h:1035
#define LIVES_WEBSITE
Definition: mainwindow.h:520
#define THEME_DETAIL_MT_MARK
Definition: mainwindow.h:287
#define THEME_DETAIL_ALT_BACK
Definition: mainwindow.h:279
#define LIVES_IMAGE_TYPE_JPEG
Definition: mainwindow.h:479
#define SCRATCH_BACK
Definition: mainwindow.h:1028
#define THEME_LITERAL
Definition: mainwindow.h:546
#define THEME_DETAIL_INFO_TEXT
Definition: mainwindow.h:280
#define MONITOR_QUOTA
Definition: mainwindow.h:1805
#define ALL_USED
Definition: mainwindow.h:192
#define LIVES_STATUS_FILE_NAME
Definition: mainwindow.h:532
#define IMPORTS_DIRNAME
Definition: mainwindow.h:621
#define LAYOUTS_DIRNAME
Definition: mainwindow.h:619
#define LIVES_SIGHUP
Definition: mainwindow.h:1861
#define CLIPS_DIR(set)
Definition: mainwindow.h:633
@ LIVES_DIALOG_INFO
Definition: mainwindow.h:240
#define THEME_DETAIL_MT_TCFG
Definition: mainwindow.h:289
#define SCRATCH_REV
set on direction change (video)
Definition: mainwindow.h:1030
#define LIVES_SHORTEST_TIMEOUT
Definition: mainwindow.h:41
#define EFFECT_NONE
Definition: mainwindow.h:208
#define LIVES_FILE_EXT_SRT
Definition: mainwindow.h:507
#define THEME_SEP_IMG_LITERAL
Definition: mainwindow.h:547
#define LIVES_FILE_EXT_BACKUP
Definition: mainwindow.h:500
#define THEME_DETAIL_ALT_FORE
Definition: mainwindow.h:278
#define TOTALSAVE_NAME
Definition: mainwindow.h:535
#define THEME_HEADER_2
Definition: mainwindow.h:550
#define LIVES_IS_INTERACTIVE
Definition: mainwindow.h:1710
#define SCRATCH_NONE
Definition: mainwindow.h:1027
#define GUI_SCREEN_PHYS_WIDTH
Definition: mainwindow.h:101
#define TEMPFILE_MARKER
Definition: mainwindow.h:574
#define LIVES_FILE_EXT_WAV
Definition: mainwindow.h:511
#define LIVES_SUBS_FILTER
Definition: mainwindow.h:636
#define LIVES_FEATURE_URL
Definition: mainwindow.h:526
#define LIVES_MAIN_WINDOW_WIDGET
Definition: mainwindow.h:188
#define DEF_IDLE_MAX
Definition: mainwindow.h:1740
#define LIVES_FILE_EXT_TEXT
Definition: mainwindow.h:494
@ LIVES_DEVICE_CD
Definition: mainwindow.h:260
@ LIVES_DEVICE_DVD
Definition: mainwindow.h:261
#define EXEC_IDENTIFY
Definition: mainwindow.h:395
#define TICKS_PER_SECOND_DBL
actually microseconds / 100.
Definition: mainwindow.h:37
#define LIVES_DONATE_URL
Definition: mainwindow.h:524
#define THEME_DETAIL_CE_SEL
Definition: mainwindow.h:292
@ NUM_LIVES_STRING_CONSTANTS
Definition: mainwindow.h:379
@ LIVES_STRING_CONSTANT_CL
"the current layout"
Definition: mainwindow.h:374
@ LIVES_STRING_CONSTANT_ANY
Definition: mainwindow.h:370
#define PRV_START
Definition: mainwindow.h:1313
#define SUBS_FILENAME
Definition: mainwindow.h:562
#define THEME_DETAIL_MT_EVBOX
Definition: mainwindow.h:288
#define LOOP_LOCK_MIN_FRAMES
Definition: mainwindow.h:59
#define EXEC_YOUTUBE_DL
Definition: mainwindow.h:399
#define LIVES_FILE_EXT_BAK
Definition: mainwindow.h:495
#define TRASH_RECOVER
Definition: mainwindow.h:583
#define THEME_DETAIL_AUDCOL
Definition: mainwindow.h:283
#define PRV_END
Definition: mainwindow.h:1314
#define THEME_DETAIL_NAME
Definition: mainwindow.h:272
#define SET_LOCK_FILENAME
Definition: mainwindow.h:566
#define LIVES_FILE_EXT_TMP
Definition: mainwindow.h:486
#define DVD_AUDIO_CHAN_DEFAULT
Definition: mainwindow.h:256
#define EXEC_MPLAYER2
Definition: mainwindow.h:387
#define SEL_MOVE_END
Definition: mainwindow.h:889
#define STYLE_LIGHT
Definition: mainwindow.h:304
#define THEME_DETAIL_INFO_BASE
Definition: mainwindow.h:281
#define THEME_DETAIL_MT_TCBG
Definition: mainwindow.h:290
#define LIVES_AUDIO_TYPE_PCM
Definition: mainwindow.h:483
#define THEME_FRAME_IMG_LITERAL
Definition: mainwindow.h:548
#define EXEC_YOUTUBE_DLC
Definition: mainwindow.h:400
#define UNREC_CLIPS_DIR
Definition: mainwindow.h:586
#define THEME_DETAIL_CE_UNSEL
Definition: mainwindow.h:293
#define TRASH_NAME
Definition: mainwindow.h:581
#define LIVES_CLIP_HEADER
Definition: mainwindow.h:555
#define DEF_FRAME_HSIZE
Definition: mainwindow.h:152
#define LIVES_FILENAME_INUSE
Definition: mainwindow.h:578
#define SCRATCH_JUMP
jump and resync audio
Definition: mainwindow.h:1031
#define MAX_SET_NAME_LEN
sets
Definition: mainwindow.h:748
#define THEME_DETAIL_FRAME_SURROUND
Definition: mainwindow.h:291
#define LIVES_FILE_EXT_NEW
Definition: mainwindow.h:491
#define LIVES_FILE_TYPE_FLAG_SPECIAL
Definition: mainwindow.h:462
#define EXEC_MKTEMP
Definition: mainwindow.h:430
#define SET_LOCK_FILE(set_name, lockfile)
Definition: mainwindow.h:623
#define CLIPS_DIRNAME
Definition: mainwindow.h:620
#define SCRATCH_FWD
Definition: mainwindow.h:1029
#define THEME_DETAIL_NORMAL_BACK
Definition: mainwindow.h:277
#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
#define STYLE_1
turn on theming if set
Definition: mainwindow.h:299
#define RFX_WINSIZE_H
size of the fx dialog windows scrollwindow
Definition: mainwindow.h:175
#define THEME_DETAIL_NORMAL_FORE
Definition: mainwindow.h:276
#define LIVES_IMAGE_TYPE_PNG
Definition: mainwindow.h:480
#define SCRATCH_FWD_EXTRA
Definition: mainwindow.h:1034
#define GUI_SCREEN_PHYS_HEIGHT
Definition: mainwindow.h:102
#define EXEC_MPV
Definition: mainwindow.h:388
#define THEME_DETAIL_STYLE
Definition: mainwindow.h:273
#define CLIP_ORDER_FILENAME
Definition: mainwindow.h:564
#define LIVES_AUDIO_LOAD_FILTER
Definition: mainwindow.h:637
#define SCRATCH_JUMP_NORESYNC
jump with no audio resync
Definition: mainwindow.h:1032
#define LIVES_FILE_EXT_TAR_GZ
Definition: mainwindow.h:505
#define TRASH_REMOVE
Definition: mainwindow.h:582
#define LIVES_FILE_EXT_SUB
Definition: mainwindow.h:508
#define EXEC_MPLAYER
Definition: mainwindow.h:386
#define SCREEN_AREA_BACKGROUND
Definition: mainwindow.h:1681
#define SET_LOCK_FILES(set_name)
Definition: mainwindow.h:624
#define SEL_MOVE_START
which bar should we move ?
Definition: mainwindow.h:888
#define DEF_FRAME_VSIZE
Definition: mainwindow.h:153
#define LAYOUT_MAP_FILENAME
Definition: mainwindow.h:571
#define SEL_MOVE_AUTO
Definition: mainwindow.h:890
#define LOCAL_HOME_DIR
Definition: mainwindow.h:604
#define LIVES_FILENAME_NOCLEAN
Definition: mainwindow.h:579
#define THEME_DETAIL_VIDCOL
Definition: mainwindow.h:284
#define TRASH_LEAVE
Definition: mainwindow.h:584
#define LIVES_AUTHOR_EMAIL
Definition: mainwindow.h:523
int lives_alarm_t
Definition: mainwindow.h:696
#define SCREEN_AREA_FOREGROUND
Definition: mainwindow.h:1680
#define LIVES_BUG_URL
Definition: mainwindow.h:525
#define FN_KEYS
number of function keys
Definition: mainwindow.h:195
#define LIVES_FILENAME_NOREMOVE
Definition: mainwindow.h:577
#define LIVES_FILE_EXT_PROJECT
Definition: mainwindow.h:501
#define THEME_HEADER
Definition: mainwindow.h:549
#define CHECK_CRIT
Definition: mainwindow.h:1753
#define EXEC_PIP
Definition: mainwindow.h:401
void mt_tl_move(lives_mt *mt, double pos)
Definition: multitrack.c:3595
void mt_clip_select(lives_mt *mt, boolean scroll)
Definition: multitrack.c:3024
boolean show_in_out_images(livespointer user_data)
Definition: multitrack.c:11878
void mt_desensitise(lives_mt *mt)
Definition: multitrack.c:16979
void recover_layout_cancelled(boolean is_startup)
Definition: multitrack.c:923
void multitrack_playall(lives_mt *mt)
Definition: multitrack.c:17345
void unpaint_lines(lives_mt *mt)
Definition: multitrack.c:14150
void stored_event_list_free_undos(void)
Definition: multitrack.c:5842
void polymorph(lives_mt *mt, lives_mt_poly_state_t poly)
Definition: multitrack.c:12777
void save_layout_map(int *lmap, double *lmap_audio, const char *file, const char *dir)
Definition: multitrack.c:19714
void wipe_layout(lives_mt *mt)
Definition: multitrack.c:21936
void draw_region(lives_mt *mt)
Definition: multitrack.c:18159
void mt_sensitise(lives_mt *mt)
Definition: multitrack.c:17052
void mt_post_playback(lives_mt *mt)
Definition: multitrack.c:17284
void mt_prepare_for_playback(lives_mt *mt)
Definition: multitrack.c:17259
void multitrack_play_sel(LiVESMenuItem *menuitem, livespointer user_data)
Definition: multitrack.c:17449
boolean used_in_current_layout(lives_mt *mt, int file)
Definition: multitrack.c:9180
boolean mt_idle_show_current_frame(livespointer data)
Definition: multitrack.c:11015
LiVESList * layout_audio_is_affected(int clipno, double stime, double etime, LiVESList *xlays)
Definition: multitrack.c:22281
boolean mt_prevclip(LiVESAccelGroup *group, LiVESWidgetObject *obj, uint32_t keyval, LiVESXModifierType mod, livespointer user_data)
Definition: multitrack.c:3096
void migrate_layouts(const char *old_set_name, const char *new_set_name)
Definition: multitrack.c:22115
void delete_audio_tracks(lives_mt *mt, LiVESList *list, boolean full)
Definition: multitrack.c:5986
void mt_zoom_in(LiVESMenuItem *menuitem, livespointer user_data)
Definition: multitrack.c:4419
void stored_event_list_free_all(boolean wiped)
Definition: multitrack.c:5897
boolean check_for_layout_del(lives_mt *mt, boolean exiting)
Definition: multitrack.c:5924
void mt_zoom_out(LiVESMenuItem *menuitem, livespointer user_data)
Definition: multitrack.c:4429
void free_thumb_cache(int fnum, frames_t fromframe)
Definition: multitrack.c:1148
void delete_video_track(lives_mt *mt, int layer, boolean full)
Definition: multitrack.c:10121
LiVESList * layout_frame_is_affected(int clipno, int start, int end, LiVESList *xlays)
Definition: multitrack.c:22247
void mt_show_current_frame(lives_mt *mt, boolean return_layer)
preview the current frame
Definition: multitrack.c:3214
void event_list_free_undos(lives_mt *mt)
Definition: multitrack.c:5827
void mt_init_clips(lives_mt *mt, int orig_file, boolean add)
Definition: multitrack.c:10859
boolean mt_nextclip(LiVESAccelGroup *group, LiVESWidgetObject *obj, uint32_t keyval, LiVESXModifierType mod, livespointer user_data)
Definition: multitrack.c:3107
@ LMAP_ERROR_DELETE_AUDIO
Definition: multitrack.h:1020
@ LMAP_ERROR_SHIFT_FRAMES
Definition: multitrack.h:1023
@ LMAP_ERROR_ALTER_FRAMES
Definition: multitrack.h:1024
@ LMAP_ERROR_DELETE_FRAMES
Definition: multitrack.h:1019
@ LMAP_INFO_SETNAME_CHANGED
Definition: multitrack.h:1029
@ LMAP_ERROR_CLOSE_FILE
Definition: multitrack.h:1018
@ LMAP_ERROR_ALTER_AUDIO
Definition: multitrack.h:1026
@ LMAP_ERROR_SHIFT_AUDIO
Definition: multitrack.h:1025
@ POLY_CLIPS
Definition: multitrack.h:123
@ POLY_NONE
Definition: multitrack.h:122
#define LIVES_OSC_NOTIFY_CLIP_OPENED
sent after a clip is opened
Definition: osc_notify.h:46
#define LIVES_OSC_NOTIFY_CLIPSET_SAVED
sent after a clip set is closed
Definition: osc_notify.h:50
#define LIVES_OSC_NOTIFY_QUIT
sent when app quits
Definition: osc_notify.h:44
#define LIVES_OSC_NOTIFY_CLIPSET_OPENED
sent after a clip set is opened
Definition: osc_notify.h:49
void subtitles_free(lives_clip_t *sfile)
Definition: pangotext.c:976
boolean subtitles_init(lives_clip_t *sfile, char *fname, lives_subtitle_type_t subtype)
Definition: pangotext.c:996
lives_subtitle_type_t
Definition: pangotext.h:15
@ SUBTITLE_TYPE_SUB
Definition: pangotext.h:18
@ SUBTITLE_TYPE_SRT
Definition: pangotext.h:17
@ SUBTITLE_TYPE_NONE
Definition: pangotext.h:16
void unload_decoder_plugins(void)
Definition: plugins.c:2411
void vid_playback_plugin_exit(void)
Definition: plugins.c:1413
void do_plugin_encoder_error(const char *plugin_name)
Definition: plugins.c:1531
void close_vid_playback_plugin(_vid_playback_plugin *vpp)
Definition: plugins.c:998
void save_vpp_defaults(_vid_playback_plugin *vpp, char *vpp_file)
Definition: plugins.c:181
LIVES_GLOBAL_INLINE LiVESList * plugin_request_by_line(const char *plugin_type, const char *plugin_name, const char *request)
Definition: plugins.c:59
void close_clip_decoder(int clipno)
Definition: plugins.c:2382
lives_decoder_t * clone_decoder(int fileno)
Definition: plugins.c:2181
void rfx_free_all(void)
Definition: plugins.c:3010
LIVES_GLOBAL_INLINE LiVESList * plugin_request(const char *plugin_type, const char *plugin_name, const char *request)
Definition: plugins.c:54
#define PLUGIN_ENCODERS
Definition: plugins.h:98
#define VPP_LOCAL_DISPLAY
Definition: plugins.h:69
@ LIVES_INTENTION_RENDER
Definition: plugins.h:48
#define LIVES_SEEK_FAST
good
Definition: plugins.h:312
#define VPP_DEFS_FILE
Definition: plugins.h:121
#define PLUGIN_THEMES
smogrify handles the directory differently for themes
Definition: plugins.h:106
#define LIVES_SEEK_FAST_REV
Definition: plugins.h:313
void pref_change_xcolours(void)
Definition: preferences.c:5852
int set_boolean_pref(const char *key, boolean value)
Definition: preferences.c:354
boolean pref_factory_float(const char *prefidx, float newval, boolean permanent)
Definition: preferences.c:1192
boolean lives_ask_permission(char **argv, int argc, int offs)
Definition: preferences.c:6031
void set_theme_colour_pref(const char *themefile, const char *key, lives_colRGBA64_t *lcol)
Definition: preferences.c:393
void pref_change_images(void)
Definition: preferences.c:5835
void set_theme_pref(const char *themefile, const char *key, const char *value)
Definition: preferences.c:317
LIVES_GLOBAL_INLINE LiVESResponseType get_pref_from_file(const char *filename, const char *key, char *val, int maxlen)
Definition: preferences.c:106
void pref_change_colours(void)
Definition: preferences.c:5866
int set_string_pref(const char *key, const char *value)
Definition: preferences.c:290
int set_utf8_pref(const char *key, const char *value)
Definition: preferences.c:306
boolean pref_factory_int(const char *prefidx, int newval, boolean permanent)
Definition: preferences.c:1053
void save_future_prefs(void)
Definition: preferences.c:2394
boolean pref_factory_bool(const char *prefidx, boolean newval, boolean permanent)
Definition: preferences.c:717
void set_acodec_list_from_allowed(_prefsw *prefsw, render_details *rdet)
Definition: preferences.c:2437
int set_int_pref(const char *key, int value)
Definition: preferences.c:329
LiVESResponseType get_utf8_pref(const char *key, char *val, int maxlen)
Definition: preferences.c:112
#define PREF_VID_LOAD_DIR
Definition: preferences.h:954
#define REC_FPS
Definition: preferences.h:198
#define WARN_MASK_LAYOUT_DELETE_FRAMES
Definition: preferences.h:96
#define PREF_RECENT
Definition: preferences.h:956
#define PREF_REC_EXT_AUDIO
Definition: preferences.h:892
#define PREF_CLEAR_DISK_OPTS
Definition: preferences.h:981
#define WARN_MASK_VJMODE_ENTER
Definition: preferences.h:126
_prefs * prefs
Definition: preferences.h:847
#define PREF_MASTER_VOLUME
Definition: preferences.h:1099
#define SEPWIN_TYPE_NON_STICKY
Definition: preferences.h:187
#define PREF_OUTPUT_TYPE
Definition: preferences.h:929
#define PREF_AR_CLIPSET
Definition: preferences.h:934
#define AUDIO_OPTS_FOLLOW_CLIPS
Definition: preferences.h:255
#define WARN_MASK_LAYOUT_DELETE_AUDIO
Definition: preferences.h:110
#define WARN_MASK_LAYOUT_ALTER_FRAMES
off by default on a fresh install
Definition: preferences.h:102
#define PREF_GUI_THEME
Definition: preferences.h:926
#define LIVES_CDISK_REMOVE_ORPHAN_CLIPS
Definition: preferences.h:393
#define SEPWIN_TYPE_STICKY
Definition: preferences.h:188
#define LIVES_PERM_OSC_PORTS
Definition: preferences.h:1155
#define REC_AUDIO
Definition: preferences.h:201
#define PREF_SHOW_TOOLBAR
Definition: preferences.h:1038
#define WARN_MASK_LAYOUT_POPUP
Definition: preferences.h:121
#define JACK_OPTS_NOPLAY_WHEN_PAUSED
play audio even when transport paused
Definition: preferences.h:236
#define WARN_MASK_LAYOUT_CLOSE_FILE
Definition: preferences.h:95
#define AUDIO_OPTS_FOLLOW_FPS
Definition: preferences.h:256
#define WARN_MASK_LAYOUT_ALTER_AUDIO
off by default on a fresh install
Definition: preferences.h:116
#define AUD_PLAYER_JACK
Definition: preferences.h:43
_prefsw * prefsw
Definition: preferences.h:849
#define WARN_MASK_LAYOUT_SHIFT_FRAMES
off by default on a fresh install
Definition: preferences.h:99
_future_prefs * future_prefs
Definition: preferences.h:848
#define REC_FRAMES
Definition: preferences.h:197
#define AUDIO_SRC_EXT
Definition: preferences.h:206
#define AUDIO_SRC_INT
Definition: preferences.h:205
#define PREF_VJMODE
Definition: preferences.h:1068
#define PREF_AUDIO_DIR
Definition: preferences.h:949
#define PREF_SEPWIN_TYPE
Definition: preferences.h:894
#define WARN_MASK_LAYOUT_SHIFT_AUDIO
off by default on a fresh install
Definition: preferences.h:113
#define AUD_PLAYER_PULSE
Definition: preferences.h:44
#define PREF_ENCODER
Definition: preferences.h:928
_resaudw * create_resaudw(short type, render_details *rdet, LiVESWidget *top_vbox)
resample audio window
Definition: resample.c:1521
int deorder_frames(int old_frames, boolean leave_bak)
leave_bak is a special mode for the clipboard
Definition: resample.c:2208
void on_change_speed_ok_clicked(LiVESButton *button, livespointer user_data)
Definition: resample.c:2025
LIVES_GLOBAL_INLINE ticks_t q_gint64(ticks_t in, double fps)
Definition: resample.c:25
boolean resample_clipboard(double new_fps)
call this to resample clipboard video
Definition: resample.c:2250
_resaudw * resaudw
Definition: resample.h:38
char of_desc[128]
Definition: plugins.h:264
char name[64]
Definition: plugins.h:234
uint32_t capabilities
Definition: plugins.h:255
char of_name[64]
Definition: plugins.h:263
char of_restrict[1024]
Definition: plugins.h:266
int of_allowed_acodecs
Definition: plugins.h:265
LiVESWidget * entry
Definition: interface.h:95
LiVESWidget * dialog
Definition: interface.h:94
boolean ar_clipset
Definition: preferences.h:840
char theme[64]
Definition: preferences.h:800
char workdir[PATH_MAX]
Definition: preferences.h:799
boolean vj_mode
Definition: preferences.h:839
uint32_t audio_opts
Definition: preferences.h:830
short sepwin_type
Definition: preferences.h:832
_encoder encoder
Definition: preferences.h:820
LiVESWidget * fit_checkbutton
Definition: interface.h:118
LiVESWidget * with_sound
Definition: interface.h:115
LiVESWidget * insert_dialog
Definition: interface.h:114
lives_colRGBA64_t ce_sel
Definition: mainwindow.h:348
LiVESWidgetColor mt_timecode_bg
Definition: mainwindow.h:332
LiVESWidgetColor normal_fore
Definition: mainwindow.h:325
LiVESWidgetColor info_base
Definition: mainwindow.h:330
int style
Definition: mainwindow.h:297
lives_colRGBA64_t mt_evbox
Definition: mainwindow.h:346
lives_colRGBA64_t mt_timeline_reg
Definition: mainwindow.h:342
LiVESWidgetColor menu_and_bars
Definition: mainwindow.h:327
lives_colRGBA64_t audcol
Definition: mainwindow.h:339
LiVESWidgetColor info_text
Definition: mainwindow.h:329
LiVESWidgetColor white
Definition: mainwindow.h:306
LiVESWidgetColor normal_back
Definition: mainwindow.h:324
LiVESWidgetColor black
Definition: mainwindow.h:307
lives_colRGBA64_t frame_surround
Definition: mainwindow.h:344
lives_colRGBA64_t ce_unsel
Definition: mainwindow.h:349
lives_colRGBA64_t mt_mark
Definition: mainwindow.h:345
LiVESWidgetColor menu_and_bars_fore
Definition: mainwindow.h:328
lives_colRGBA64_t fxcol
Definition: mainwindow.h:341
lives_colRGBA64_t vidcol
Definition: mainwindow.h:340
LiVESWidgetColor mt_timecode_fg
Definition: mainwindow.h:333
char backend[PATH_MAX *4]
Definition: preferences.h:411
boolean discard_tv
Definition: preferences.h:194
boolean vj_mode
Definition: preferences.h:459
boolean save_directories
Definition: preferences.h:195
_encoder encoder
from main.h
Definition: preferences.h:38
boolean show_urgency_msgs
Definition: preferences.h:310
boolean crash_recovery
TRUE==maintain mainw->recovery file.
Definition: preferences.h:259
uint64_t ds_crit_level
diskspace critical level bytes
Definition: preferences.h:380
volatile uint32_t audio_opts
Definition: preferences.h:254
boolean rec_desktop_audio
Definition: preferences.h:288
boolean hfbwnp
Definition: preferences.h:436
int audio_src
Definition: preferences.h:204
uint64_t disk_quota
Definition: preferences.h:383
char * fxsizesfile
Definition: preferences.h:248
int play_monitor
Definition: preferences.h:306
uint64_t warning_mask
Definition: preferences.h:80
boolean hide_framebar
Definition: preferences.h:434
boolean show_gui
Definition: preferences.h:290
boolean no_bandwidth
Definition: preferences.h:208
float volume
audio volume level (for jack and pulse)
Definition: preferences.h:457
char ar_clipset_name[128]
locale
Definition: preferences.h:285
uint32_t osc_udp_port
Definition: preferences.h:210
boolean pause_effect_during_preview
Definition: preferences.h:174
char workdir[PATH_MAX]
kept in locale encoding
Definition: preferences.h:61
int rec_opts
Definition: preferences.h:196
boolean autoclean
remove temp files on shutdown / startup
Definition: preferences.h:481
boolean show_msg_area
Definition: preferences.h:225
char config_datadir[PATH_MAX]
kept in locale encoding (general config files) (default ~/.local/share/lives)
Definition: preferences.h:64
uint32_t clear_disk_opts
Definition: preferences.h:402
LiVESList * acodec_list
Definition: preferences.h:251
char cdplay_device[PATH_MAX]
locale encoding
Definition: preferences.h:172
short rte_keys_virtual
Definition: preferences.h:223
LiVESList * disabled_decoders
Definition: preferences.h:408
double fpschange_amount
Definition: preferences.h:230
boolean ins_resample
Definition: preferences.h:184
boolean show_subtitles
Definition: preferences.h:192
uint32_t jack_opts
Definition: preferences.h:232
short sepwin_type
Definition: preferences.h:186
boolean show_overlay_msgs
Definition: preferences.h:311
int sleep_time
Definition: preferences.h:176
boolean mouse_scroll_clips
Definition: preferences.h:323
double blendchange_amount
Definition: preferences.h:228
char theme[64]
the theme name
Definition: preferences.h:29
char image_type[16]
Definition: preferences.h:77
boolean pref_trash
user prefers trash to delete
Definition: preferences.h:480
boolean render_audio
Definition: preferences.h:298
boolean show_dev_opts
Definition: preferences.h:463
boolean ar_clipset
auto-reload
Definition: preferences.h:284
boolean show_desktop_panel
Definition: preferences.h:483
boolean conserve_space
Definition: preferences.h:183
char * fxdefsfile
Definition: preferences.h:247
char backend_sync[PATH_MAX *4]
Definition: preferences.h:410
short audio_player
Definition: preferences.h:40
boolean show_tool
Definition: preferences.h:185
char image_ext[16]
Definition: preferences.h:78
uint64_t ds_warn_level
diskspace warn level bytes
Definition: preferences.h:378
boolean osc_udp_started
Definition: preferences.h:209
boolean autoload_subs
Definition: preferences.h:345
boolean rr_crash
Definition: preferences.h:488
LiVESWidget * encoder_combo
Definition: preferences.h:614
ulong encoder_name_fn
Definition: preferences.h:532
LiVESWidget * ofmt_combo
Definition: preferences.h:595
ulong encoder_ofmt_fn
Definition: preferences.h:531
resample audio window
Definition: resample.h:18
LiVESWidget * minute_spinbutton
Definition: resample.h:29
LiVESWidget * hour_spinbutton
Definition: resample.h:28
LiVESWidget * entry_asamps
Definition: resample.h:22
LiVESWidget * second_spinbutton
Definition: resample.h:30
LiVESWidget * fps_spinbutton
Definition: resample.h:31
LiVESWidget * rb_unsigned
Definition: resample.h:24
LiVESWidget * unlim_radiobutton
Definition: resample.h:27
LiVESWidget * rb_bigend
Definition: resample.h:25
LiVESWidget * entry_arate
Definition: resample.h:20
LiVESWidget * entry_achans
Definition: resample.h:21
LiVESWidget * dialog
Definition: resample.h:19
uint64_t capabilities
Definition: plugins.h:177
void(* exit_screen)(uint16_t mouse_x, uint16_t mouse_y)
Definition: plugins.h:146
LiVESWidget * time_spin
Definition: interface.h:153
boolean is_sel
Definition: interface.h:154
LiVESWidget * dialog
Definition: interface.h:152
LiVESWidget * apb_button
Definition: interface.h:211
LiVESWidget * mute_button
Definition: interface.h:212
LiVESWidget * atrigger_spin
Definition: interface.h:210
LiVESWidget * atrigger_button
Definition: interface.h:209
LiVESWidget * debug_button
Definition: interface.h:213
LiVESWidget * dialog
Definition: interface.h:208
char home_dir[PATH_MAX]
home directory - default location for config file - locale encoding
Definition: main.h:544
lives_checkstatus_t has_identify
Definition: main.h:516
int nmonitors
Definition: main.h:588
pid_t mainpid
Definition: main.h:591
lives_checkstatus_t has_mpv
Definition: main.h:513
char * mountpoint
utf-8
Definition: main.h:610
lives_checkstatus_t has_pip
Definition: main.h:534
lives_checkstatus_t has_encoder_plugins
Definition: main.h:571
lives_checkstatus_t has_composite
Definition: main.h:515
lives_checkstatus_t has_mplayer2
Definition: main.h:512
int64_t ds_free
Definition: main.h:609
int64_t ds_used
Definition: main.h:609
char * myname_full
Definition: main.h:579
lives_checkstatus_t has_xwininfo
Definition: main.h:524
lives_checkstatus_t has_autolives
Definition: main.h:510
lives_checkstatus_t has_youtube_dl
Definition: main.h:532
wm_caps_t wm_caps
Definition: main.h:607
lives_checkstatus_t has_mktemp
Definition: main.h:540
lives_checkstatus_t has_sox_sox
Definition: main.h:509
char * wm_name
window manager name, may be different from wm_caps.wwm_name
Definition: main.h:605
lives_checkstatus_t has_jackd
Definition: main.h:522
char eject_cmd[PATH_MAX]
Definition: main.h:564
lives_checkstatus_t has_mplayer
Definition: main.h:511
mode_t umask
Definition: main.h:597
lives_checkstatus_t has_pulse_audio
Definition: main.h:523
lives_checkstatus_t has_youtube_dlc
Definition: main.h:533
lives_checkstatus_t has_convert
Definition: main.h:514
int current_palette
plugin should init this to palettes[0] if URI changes
Definition: plugins.h:378
int seek_flag
plugin can change per frame
Definition: plugins.h:397
corresponds to one clip in the GUI
Definition: main.h:877
lives_undo_t undo_action
undo
Definition: main.h:954
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 tcache_dubious_from
height for thumbnail cache (width is fixed, but if this changes, invalidate)
Definition: main.h:1099
LiVESWidget * menuentry
Definition: main.h:1011
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
frames_t * frame_index
index of frames for CLIP_TYPE_FILE >0 means corresponding frame within original clip -1 means corresp...
Definition: main.h:1004
frames_t saved_frameno
Definition: main.h:1025
frames_t stored_layout_frame
experimental for player
Definition: main.h:1071
frames_t last_frameno
Definition: main.h:934
double stored_layout_audio
Definition: main.h:1073
boolean restoring
Definition: main.h:948
volatile off64_t aseek_pos
audio seek posn. (bytes) for when we switch clips
Definition: main.h:1064
int achans
number of audio channels (0, 1 or 2)
Definition: main.h:907
LiVESList * layout_map
Definition: main.h:1037
uint32_t signed_endian
bitfield
Definition: main.h:909
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
int ext_src_type
Definition: main.h:1051
char info_file[PATH_MAX]
used for asynch communication with externals
Definition: main.h:1009
char name[CLIP_NAME_MAXLEN]
the display name
Definition: main.h:922
double stored_layout_fps
Definition: main.h:1074
size_t afilesize
Definition: main.h:912
double freeze_fps
pb_fps for paused / frozen clips
Definition: main.h:1013
int bpp
bits per pixel of the image frames, 24 or 32
Definition: main.h:901
int arate
current audio playback rate (varies if the clip rate is changed)
Definition: main.h:906
lives_painter_surface_t * raudio_drawable
Definition: main.h:1084
double fps
Definition: main.h:893
weed_plant_t * next_event
Definition: main.h:1035
char handle[256]
Definition: main.h:881
lives_painter_surface_t * laudio_drawable
Definition: main.h:1084
boolean play_paused
Definition: main.h:1014
boolean opening
Definition: main.h:946
frames_t start
Definition: main.h:891
LiVESWidget * textview_ltime
Definition: interface.h:85
LiVESWidget * textview_lrate
Definition: interface.h:87
LiVESWidget * textview_fsize
Definition: interface.h:84
LiVESWidget * textview_rrate
Definition: interface.h:88
LiVESWidget * textview_rtime
Definition: interface.h:86
LiVESWidget * textview_type
Definition: interface.h:79
LiVESWidget * textview_fps
Definition: interface.h:80
LiVESWidget * textview_frames
Definition: interface.h:82
LiVESWidget * textview_vtime
Definition: interface.h:83
LiVESWidget * textview_size
Definition: interface.h:81
const char * name
plugin name
Definition: plugins.h:414
const lives_decoder_sys_t * decoder
Definition: plugins.h:450
LiVESXDevice * mouse_device
unused for gtk+ < 3.0.0
Definition: mainwindow.h:357
char save_dir[PATH_MAX]
Definition: interface.h:255
lives_size_match_t matchsize
Definition: interface.h:262
char * foreign_visual
Definition: mainwindow.h:846
LiVESWidget * autolives
Definition: mainwindow.h:1220
int64_t rec_samples
Definition: mainwindow.h:1527
LiVESList * set_list
number of sets in workdir (minus the current set), -1 if not checked
Definition: mainwindow.h:753
LiVESList * xlays
immediately (to be) affected layout maps
Definition: mainwindow.h:1477
char * overlay_msg
Definition: mainwindow.h:1644
LiVESWidget * raudbar
Definition: mainwindow.h:1286
LiVESWidget * video_draw
Definition: mainwindow.h:1383
LiVESWidget * m_sepwinbutton
Definition: mainwindow.h:1369
_vid_playback_plugin * vpp
video plugin
Definition: mainwindow.h:1572
LiVESWidget * m_rewindbutton
Definition: mainwindow.h:1369
boolean ce_thumbs
Definition: mainwindow.h:1676
int swapped_clip
maintains the current cliplist postion even if we swap fg and bg clips
Definition: mainwindow.h:850
weed_plant_t * frame_layer
Definition: mainwindow.h:948
boolean close_keep_frames
special value for when generating to clipboard
Definition: mainwindow.h:1438
lives_painter_surface_t * fsp_surface
Definition: mainwindow.h:1079
LiVESWidget * open
menus
Definition: mainwindow.h:1107
boolean msg_area_configed
Definition: mainwindow.h:1443
LiVESWidget * rewind
Definition: mainwindow.h:1171
boolean nervous
some VJ effects / toys
Definition: mainwindow.h:849
LiVESWidget * sepwin
Definition: mainwindow.h:1176
volatile int agen_key
which fx key is generating audio [1 based] (or 0 for none)
Definition: mainwindow.h:1649
pthread_mutex_t abuf_frame_mutex
used to synch audio buffer for generators
Definition: mainwindow.h:1496
LiVESWidget * redo
Definition: mainwindow.h:1147
pthread_mutex_t instance_ref_mutex
refcounting for instances
Definition: mainwindow.h:1504
int img_concat_clip
when opening multiple, image files can get concatenated here (prefs->concat_images)
Definition: mainwindow.h:1561
frames_t rec_vid_frames
values to be written to the event list concurrent with next video ftame event
Definition: mainwindow.h:1529
double aframeno
and the audio 'frame' for when we are looping
Definition: mainwindow.h:962
pthread_mutex_t audio_filewriteend_mutex
sync for ending writing audio to file
Definition: mainwindow.h:1503
int osc_auto
bypass user choices automatically
Definition: mainwindow.h:918
LiVESTextBuffer * layout_textbuffer
stores layout errors
Definition: mainwindow.h:1468
pthread_mutex_t alarmlist_mutex
append / remove with file_buffer list
Definition: mainwindow.h:1507
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
volatile uint64_t rte
current max for VJ mode == 64 effects on fg clip
Definition: mainwindow.h:867
int preview_frame
Definition: mainwindow.h:1309
LiVESWidget * p_loopbutton
Definition: mainwindow.h:1379
pthread_mutex_t event_list_mutex
prevent simultaneous writing to event_list by audio and video threads
Definition: mainwindow.h:1499
char msg[MAINW_MSG_SIZE]
Definition: mainwindow.h:724
LiVESWidget * preview_image
Definition: mainwindow.h:1305
volatile ticks_t currticks
wall clock time, updated whenever lives_get_*_ticks is called
Definition: mainwindow.h:1005
LiVESWidget * merge
Definition: mainwindow.h:1152
LiVESWidget * p_playbutton
Definition: mainwindow.h:1379
char * fsp_tmpdir
Definition: mainwindow.h:796
int last_dprint_file
message output settings
Definition: mainwindow.h:1535
boolean fx1_bool
Definition: mainwindow.h:1053
boolean tried_ds_recover
Definition: mainwindow.h:1657
LiVESWidget * dsize
Definition: mainwindow.h:1186
unsigned char * sl_undo_mem
Definition: mainwindow.h:812
void * pulsed
pulseaudio player
Definition: mainwindow.h:1463
LiVESWidget * framebar
Definition: mainwindow.h:1389
double blend_factor
keyboard control parameter
Definition: mainwindow.h:872
boolean leave_recovery
Definition: mainwindow.h:1482
lives_clip_t * files[MAX_FILES+1]
+1 for the clipboard
Definition: mainwindow.h:729
LiVESWidget * fs_playimg
Definition: mainwindow.h:1260
int rec_signed_endian
Definition: mainwindow.h:1532
volatile boolean record
Definition: mainwindow.h:794
pthread_mutex_t fbuffer_mutex
Definition: mainwindow.h:1506
boolean suppress_layout_warnings
Definition: mainwindow.h:1798
int n_messages
Definition: mainwindow.h:1731
boolean no_configs
Definition: mainwindow.h:1803
ticks_t origsecs
playback start seconds - subtracted from all other ticks to keep numbers smaller
Definition: mainwindow.h:1000
char * recovery_file
the filename of our recover file
Definition: mainwindow.h:1481
boolean oloop
Definition: mainwindow.h:766
boolean is_rendering
Definition: mainwindow.h:821
lives_mgeometry_t * mgeom
multi-head support
Definition: mainwindow.h:1576
volatile double rec_avel
Definition: mainwindow.h:968
boolean clip_switched
for recording - did we switch clips ?
Definition: mainwindow.h:793
boolean fx2_bool
Definition: mainwindow.h:1053
boolean selwidth_locked
Definition: mainwindow.h:786
LiVESWidget * laudbar
Definition: mainwindow.h:1286
boolean effects_paused
Definition: mainwindow.h:1055
int sel_start
Definition: mainwindow.h:884
boolean go_away
Definition: mainwindow.h:1614
char frameblank_path[PATH_MAX]
???
Definition: mainwindow.h:1717
volatile boolean loop_cont
Definition: mainwindow.h:764
boolean oping_pong
Definition: mainwindow.h:768
lives_painter_surface_t * raudio_drawable
Definition: mainwindow.h:1386
int foreign_width
Definition: mainwindow.h:844
char * string_constants[NUM_LIVES_STRING_CONSTANTS]
Definition: mainwindow.h:1539
LiVESIOChannel * iochan
encoder text output
Definition: mainwindow.h:1605
boolean preview_req
Definition: mainwindow.h:1024
double fx2_val
Definition: mainwindow.h:1049
boolean dsu_valid
Definition: mainwindow.h:1791
boolean ignore_screen_size
applied during frame reconfig events
Definition: mainwindow.h:1745
mt_opts multi_opts
some multitrack options that survive between mt calls
Definition: mainwindow.h:1492
LiVESWidget * fs_playframe
Definition: mainwindow.h:1259
ulong fsp_func
fileselector preview expose (for image thumbnails)
Definition: mainwindow.h:1075
LiVESWidget * select_to_end
Definition: mainwindow.h:1157
volatile boolean ext_audio
using external video playback plugin to stream audio
Definition: mainwindow.h:774
LiVESWidget * fs_playalign
Definition: mainwindow.h:1258
lives_permmgr_t * permmgr
Definition: mainwindow.h:1795
LiVESWidget * vj_load_set
Definition: mainwindow.h:1232
LiVESWidget * playframe
Definition: mainwindow.h:1098
LiVESTextView * optextview
Definition: mainwindow.h:1606
LiVESWidget * sa_button
Definition: mainwindow.h:1290
LiVESWidget * select_last
Definition: mainwindow.h:1162
boolean noswitch
value set automatically to prevent 'inopportune' clip switching
Definition: mainwindow.h:1019
char proj_load_dir[PATH_MAX]
Definition: mainwindow.h:735
LiVESList * cliplist
hash table of clips in menu order
Definition: mainwindow.h:743
volatile lives_cancel_t cancelled
Definition: mainwindow.h:798
LiVESWidget * sel_label
Definition: mainwindow.h:1227
LiVESWidget * preview_spinbutton
Definition: mainwindow.h:1306
LiVESWidget * pf_grid
Definition: mainwindow.h:1101
ulong toy_func_lives_tv
Definition: mainwindow.h:1069
boolean preview
Definition: mainwindow.h:757
lives_storage_status_t ds_status
Definition: mainwindow.h:1750
int rec_asamps
Definition: mainwindow.h:1532
LiVESWidget * open_sel
Definition: mainwindow.h:1108
boolean osc_block
TODO - make this a mutex and more finely grained : things we need to block are (clip switches,...
Definition: mainwindow.h:916
int current_file
Definition: mainwindow.h:727
boolean is_ready
Definition: mainwindow.h:787
lives_screen_area_t * screen_areas
Definition: mainwindow.h:1687
boolean add_clear_ds_adv
Definition: mainwindow.h:1656
lives_cancel_type_t cancel_type
Definition: mainwindow.h:799
LiVESWidget * message_box
Definition: mainwindow.h:1323
LiVESWidget * t_fullscreen
Definition: mainwindow.h:1339
pthread_mutex_t clip_list_mutex
prevent adding/removing to cliplist while another thread could be reading it
Definition: mainwindow.h:1500
ticks_t orignsecs
usecs at start of playback - ditto
Definition: mainwindow.h:1001
LiVESWidget * showfct
Definition: mainwindow.h:1179
LiVESWidget * play_window
Definition: mainwindow.h:947
uint64_t next_ds_warn_level
current disk space warning level for the tempdir
Definition: mainwindow.h:1666
LiVESWidget * select_to_aend
Definition: mainwindow.h:1158
LiVESWidget * eventbox4
Definition: mainwindow.h:1334
LiVESWidget * loop_video
Definition: mainwindow.h:1173
void * jackd
jack audio player / transport
Definition: mainwindow.h:1453
short endian
Definition: mainwindow.h:817
boolean loop
Definition: mainwindow.h:763
lives_pgid_t alives_pgid
Definition: mainwindow.h:877
int last_transition_loops
Definition: mainwindow.h:862
double fx5_val
Definition: mainwindow.h:1049
boolean ccpd_with_sound
Definition: mainwindow.h:785
int scrap_file
we throw odd sized frames here when recording in real time; used if a source is a generator or stream
Definition: mainwindow.h:874
LiVESWidget * frame2
Definition: mainwindow.h:1095
boolean insert_after
Definition: mainwindow.h:880
boolean configured
Definition: mainwindow.h:788
LiVESAdjustment * msg_adj
Definition: mainwindow.h:1326
int num_tr_applied
number of transitions active
Definition: mainwindow.h:871
LiVESWidget * spinbutton_pb_fps
Definition: mainwindow.h:1391
boolean recovering_files
Definition: mainwindow.h:1485
LiVESWidget * spinbutton_end
Definition: mainwindow.h:1288
double period
timing variables
Definition: mainwindow.h:996
LiVESWidget * fs_playarea
for the fileselection preview
Definition: mainwindow.h:1257
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
int n_screen_areas
Definition: mainwindow.h:1684
LiVESList * recovery_list
crash recovery system
Definition: mainwindow.h:1480
volatile boolean is_exiting
set during shutdown (inverse of only_close then)
Definition: mainwindow.h:1440
boolean cs_manage
Definition: mainwindow.h:1789
boolean no_switch_dprint
Definition: mainwindow.h:1536
LiVESWidget * toy_tv
Definition: mainwindow.h:1219
boolean mouse_blocked
Definition: mainwindow.h:1085
weed_plant_t * filter_map
Definition: mainwindow.h:1298
weed_plant_t * blend_layer
Definition: mainwindow.h:977
boolean fs
Definition: mainwindow.h:762
LiVESWidget * full_screen
Definition: mainwindow.h:1172
void * pulsed_read
Definition: mainwindow.h:1464
LiVESWidget * m_mutebutton
Definition: mainwindow.h:1370
LiVESWidget * select_from_start
Definition: mainwindow.h:1159
pthread_mutex_t vpp_stream_mutex
prevent from writing audio when stream is closing
Definition: mainwindow.h:1501
LiVESWidget * select_invert
Definition: mainwindow.h:1163
int blend_file
background clip details
Definition: mainwindow.h:976
LiVESWidget * toys_menu
Definition: mainwindow.h:1407
LiVESWidget * p_mutebutton
Definition: mainwindow.h:1379
char proj_save_dir[PATH_MAX]
Definition: mainwindow.h:736
boolean was_set
Definition: mainwindow.h:750
boolean opening_multi
flag to indicate multiple file selection
Definition: mainwindow.h:1555
LiVESWidget * m_stopbutton
Definition: mainwindow.h:1369
LiVESWidget * select_end_only
Definition: mainwindow.h:1161
double fx1_val
Definition: mainwindow.h:1049
int pwidth
PLAYBACK.
Definition: mainwindow.h:926
LiVESWidget * tb_hbox
Definition: mainwindow.h:1350
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
LiVESWidget * ext_audio_checkbutton
Definition: mainwindow.h:1358
boolean suppress_dprint
tidy up, e.g. by blocking "switched to file..." and "closed file..." messages
Definition: mainwindow.h:1537
LiVESWidget * sep_image
Definition: mainwindow.h:1229
short sel_move
Definition: mainwindow.h:885
int pheight
playback height
Definition: mainwindow.h:927
LiVESWidget * t_sepwin
Definition: mainwindow.h:1340
weed_plant_t * audio_event
Definition: mainwindow.h:1300
pthread_mutex_t abuf_mutex
mutices
Definition: mainwindow.h:1495
frames_t play_start
Definition: mainwindow.h:931
LiVESWidget * playclip
Definition: mainwindow.h:1168
boolean opening_loc
opening location (streaming)
Definition: mainwindow.h:790
int aud_file_to_kill
Definition: mainwindow.h:909
LiVESWidget * select_all
Definition: mainwindow.h:1155
volatile int rec_aclip
recording values - to be inserted at the following video frame
Definition: mainwindow.h:967
boolean sep_win
Definition: mainwindow.h:761
LiVESWidget * eventbox3
Definition: mainwindow.h:1333
ulong spin_start_func
Definition: mainwindow.h:1064
char * urgency_msg
OSD.
Definition: mainwindow.h:1643
LiVESWidget * m_loopbutton
Definition: mainwindow.h:1370
LiVESWidget * p_rewindbutton
Definition: mainwindow.h:1379
volatile double rec_aseek
Definition: mainwindow.h:969
ulong toy_func_random_frames
Definition: mainwindow.h:1068
double rec_fps
Definition: mainwindow.h:1528
lives_painter_surface_t * video_drawable
Definition: mainwindow.h:1386
double ptrtime
Definition: mainwindow.h:899
boolean leave_files
TRUE to leave clip files on disk even when closing (default FALSE)
Definition: mainwindow.h:751
weed_event_t * stored_event_list
stored mt -> clip editor
Definition: mainwindow.h:804
LiVESWidget * mute_audio
Definition: mainwindow.h:1177
char sepimg_path[PATH_MAX]
Definition: mainwindow.h:1718
int fc_buttonresponse
Definition: mainwindow.h:1715
ulong toy_func_none
Definition: mainwindow.h:1067
LiVESWidget * preview_box
Definition: mainwindow.h:1304
LiVESWidget * stop
Definition: mainwindow.h:1170
boolean playing_sel
list of set names in current workdir, mau be NULL
Definition: mainwindow.h:756
int clips_available
Definition: mainwindow.h:740
LiVESWidget * start_image
Definition: mainwindow.h:1320
char * old_vhash
Definition: mainwindow.h:1758
LiVESWidget * spinbutton_start
Definition: mainwindow.h:1288
double fx4_val
Definition: mainwindow.h:1049
ulong preview_spin_func
Definition: mainwindow.h:1310
LiVESList * current_layouts_map
map of all layouts for set
Definition: mainwindow.h:1470
boolean jack_can_stop
Definition: mainwindow.h:934
volatile boolean in_fs_preview
Definition: mainwindow.h:797
pthread_mutex_t fxd_active_mutex
prevent simultaneous writing to active_dummy by audio and video threads
Definition: mainwindow.h:1498
lives_toy_t toy_type
Definition: mainwindow.h:851
volatile boolean record_paused
pause during recording
Definition: mainwindow.h:1557
int ascrap_file
scrap file for recording audio scraps
Definition: mainwindow.h:875
boolean keep_pre
set if previewed frames should be retained as processed frames (for rendered effects / generators)
Definition: mainwindow.h:1567
char * file_open_params
extra parameters for opening special files
Definition: mainwindow.h:906
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
int num_sets
Definition: mainwindow.h:752
boolean faded
Definition: mainwindow.h:759
xprocess * proc_ptr
Definition: mainwindow.h:1090
volatile boolean ping_pong
Definition: mainwindow.h:765
boolean record_starting
start recording at next frame
Definition: mainwindow.h:1559
uint32_t foreign_key
Definition: mainwindow.h:829
LiVESList * stored_layout_undos
Definition: mainwindow.h:810
int active_sa_clips
Definition: mainwindow.h:1686
boolean foreign
for external window capture
Definition: mainwindow.h:824
volatile boolean agen_needs_reinit
Definition: mainwindow.h:1650
boolean memok
set to FALSE if a segfault is received, ie. we should assume all memory is corrupted and exit ASAP
Definition: mainwindow.h:1776
LiVESWidget * toy_none
Definition: mainwindow.h:1217
pthread_mutex_t cache_buffer_mutex
sync for jack playback termination
Definition: mainwindow.h:1502
boolean stored_event_list_changed
Definition: mainwindow.h:805
boolean save_with_sound
Definition: mainwindow.h:784
ulong pw_scroll_func
Definition: mainwindow.h:1442
lives_painter_surface_t * laudio_drawable
Definition: mainwindow.h:1386
char ** fonts_array
Definition: mainwindow.h:1620
Window foreign_id
Definition: mainwindow.h:840
LiVESWidget * end_image
Definition: mainwindow.h:1320
LiVESWidget * vj_mode
Definition: mainwindow.h:1239
boolean fatal
got fatal signal
Definition: mainwindow.h:789
boolean internal_messaging
internal fx
Definition: mainwindow.h:1043
boolean is_processing
states
Definition: mainwindow.h:820
LiVESWidget * undo
Definition: mainwindow.h:1146
int rte_keys
which effect is bound to keyboard (m) modechange and ctrl-alt-up-arrow / ctrl-alt-down-arrow param ch...
Definition: mainwindow.h:870
char set_name[256]
Definition: mainwindow.h:749
lives_painter_surface_t * play_surface
Definition: mainwindow.h:950
char audio_dir[PATH_MAX]
Definition: mainwindow.h:733
boolean write_vpp_file
video playback plugin was updated; write settings to a file on exit
Definition: mainwindow.h:1040
LiVESWidget * cut
Definition: mainwindow.h:1149
int clipstore[FN_KEYS - 1][2]
stored clips (bookmarks) [0] = clip, [1] = frame
Definition: mainwindow.h:986
char * subt_save_file
name of file to save subtitles to
Definition: mainwindow.h:1618
ulong vj_mode_func
Definition: mainwindow.h:1076
int first_free_file
Definition: mainwindow.h:728
frames_t play_end
Definition: mainwindow.h:931
LiVESWidget * dsu_widget
Definition: mainwindow.h:1792
LiVESWidget * eventbox2
Definition: mainwindow.h:1332
boolean double_size
Definition: mainwindow.h:760
LiVESWidget * m_playbutton
Definition: mainwindow.h:1369
ticks_t timeout_ticks
incremented if effect/rendering is paused/previewed
Definition: mainwindow.h:999
ulong mouse_fn1
Definition: mainwindow.h:1084
boolean force_show
Definition: mainwindow.h:1763
LiVESWidget * play_image
Definition: mainwindow.h:946
boolean lockstats
Definition: mainwindow.h:1774
char * version_hash
Definition: mainwindow.h:1757
volatile ticks_t startticks
effective ticks when current frame was (should have been) displayed
Definition: mainwindow.h:997
weed_plant_t * afilter_map
Definition: mainwindow.h:1299
LiVESWidget * toy_random_frames
Definition: mainwindow.h:1218
int new_clip
clip we should switch to during playback; switch will happen at the designated SWITCH POINT
Definition: mainwindow.h:1022
LiVESWidget * hruler
Definition: mainwindow.h:1230
boolean record_foreign
Definition: mainwindow.h:825
LiVESList * affected_layouts_map
map of layouts with errors
Definition: mainwindow.h:1469
boolean mute
Definition: mainwindow.h:770
boolean mt_needs_idlefunc
set if we need to re-add the idlefunc for autobackup
Definition: mainwindow.h:1088
LiVESWidget * frame1
Definition: mainwindow.h:1094
LiVESWidget * select_submenu
Definition: mainwindow.h:1154
LiVESWidget * fade
Definition: mainwindow.h:1185
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
LiVESWidget * select_start_only
Definition: mainwindow.h:1160
LiVESWidget * trim_to_pstart
Definition: mainwindow.h:1204
uint32_t disk_mon
Definition: mainwindow.h:1807
int foreign_height
Definition: mainwindow.h:844
ulong spin_end_func
Definition: mainwindow.h:1065
int rec_achans
Definition: mainwindow.h:1532
boolean loop_locked
Definition: mainwindow.h:769
FILE * clip_header
Definition: mainwindow.h:1521
ulong pb_fps_func
Definition: mainwindow.h:1063
ticks_t flush_audio_tc
reserved space for mbar
Definition: mainwindow.h:1735
int pre_play_file
the current file before playback started
Definition: mainwindow.h:973
double fx3_val
Definition: mainwindow.h:1049
LiVESWidget * select_new
Definition: mainwindow.h:1156
int foreign_bpp
Definition: mainwindow.h:845
volatile boolean threaded_dialog
not really threaded ! but threaded_dialog_spin() can be called to animate it
Definition: mainwindow.h:1046
char vid_load_dir[PATH_MAX]
Definition: mainwindow.h:730
boolean oloop_cont
Definition: mainwindow.h:767
pthread_mutex_t exit_mutex
prevent multiple threads trying to run cleanup
Definition: mainwindow.h:1505
void * jackd_read
dummy
Definition: mainwindow.h:1454
weed_event_t * event_list
current event_list, for recording
Definition: mainwindow.h:803
LiVESList * hdrs_cache
cache of a file header (e.g. header.lives)
Definition: mainwindow.h:1518
LiVESWidget * playarea
Definition: mainwindow.h:1321
LiVESWidget * vidbar
Definition: mainwindow.h:1286
LiVESWidget * loop_continue
Definition: mainwindow.h:1174
ticks_t stream_ticks
ticks since first frame sent to playback plugin
Definition: mainwindow.h:1011
LiVESWidget * acodec_combo
Definition: events.h:226
boolean enc_changed
Definition: events.h:244
ulong encoder_ofmt_fn
Definition: events.h:243
LiVESWidget * okbutton
Definition: events.h:221
LiVESWidget * ofmt_combo
Definition: events.h:225
LiVESWidget * encoder_combo
Definition: events.h:224
ulong encoder_name_fn
Definition: events.h:242
char * encoder_name
Definition: events.h:245
LiVESWidget * vbox
Definition: interface.h:141
LiVESWidget * dialog
Definition: interface.h:135
LiVESWidget * delete_button
Definition: interface.h:137
LiVESWidget * clear_button
Definition: interface.h:136
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
boolean use_markup
whether markup should be used in labels
int border_width
border width in pixels
uint64_t pan_annoy
Definition: main.h:471
uint64_t pan_res
Definition: main.h:472
frames_t frames_done
Definition: mainwindow.h:717
LiVESWidget * label2
Definition: mainwindow.h:709
LiVESWidget * processing
Definition: mainwindow.h:706
LiVESWidget * stop_button
Definition: mainwindow.h:711
LiVESWidget * cancel_button
Definition: mainwindow.h:714
LiVESWidget * pause_button
Definition: mainwindow.h:712
LiVESWidget * preview_button
Definition: mainwindow.h:713
#define lives_strdup_printf(fmt,...)
Definition: support.c:27
#define _(String)
Definition: support.h:44
#define P_(String, StringPlural, n)
Definition: support.h:46
int boolean
Definition: videoplugin.h:54
#define TRUE
Definition: videoplugin.h:59
#define FALSE
Definition: videoplugin.h:60
char * weed_palette_get_name_full(int pal, int clamping, int subspace)
WEED_GLOBAL_INLINE int weed_channel_get_palette_yuv(weed_plant_t *channel, int *clamping, int *sampling, int *subspace)
const char * weed_palette_get_name(int pal)
boolean lives_combo_populate(LiVESCombo *combo, LiVESList *list)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_set_app_paintable(LiVESWidget *widget, boolean paintable)
WIDGET_HELPER_GLOBAL_INLINE double lives_ruler_set_value(LiVESRuler *ruler, double value)
void lives_set_cursor_style(lives_cursor_t cstyle, LiVESWidget *widget)
WIDGET_HELPER_GLOBAL_INLINE void lives_menu_item_set_text(LiVESWidget *menuitem, const char *text, boolean use_mnemonic)
WIDGET_HELPER_GLOBAL_INLINE double lives_scale_button_get_value(LiVESScaleButton *scale)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_window_unfullscreen(LiVESWindow *window)
WIDGET_HELPER_GLOBAL_INLINE int lives_widget_get_allocation_width(LiVESWidget *widget)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_spin_button_set_value(LiVESSpinButton *button, double value)
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 char * lives_file_chooser_get_filename(LiVESFileChooser *chooser)
WIDGET_HELPER_GLOBAL_INLINE LiVESScrollDirection lives_get_scroll_direction(LiVESXEventScroll *event)
boolean lives_window_center(LiVESWindow *window)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_button_box_set_child_non_homogeneous(LiVESButtonBox *bbox, LiVESWidget *child, boolean set)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_is_sensitive(LiVESWidget *widget)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_window_move(LiVESWindow *window, int x, int y)
WIDGET_HELPER_GLOBAL_INLINE LiVESAccelGroup * lives_accel_group_new(void)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_menu_popup(LiVESMenu *menu, LiVESXEventButton *event)
boolean lives_button_grab_default_special(LiVESWidget *button)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_set_opacity(LiVESWidget *widget, double opacity)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_spin_button_update(LiVESSpinButton *button)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_menu_item_activate(LiVESMenuItem *menuitem)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_toggle_button_get_active(LiVESToggleButton *button)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_painter_set_source_surface(lives_painter_t *cr, lives_painter_surface_t *surface, double x, double y)
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_widget_get_modmask(LiVESXDevice *device, LiVESWidget *widget, LiVESXModifierType *modmask)
WIDGET_HELPER_GLOBAL_INLINE LiVESWidget * lives_menu_new(void)
WIDGET_HELPER_GLOBAL_INLINE boolean clear_widget_bg(LiVESWidget *widget, lives_painter_surface_t *s)
WIDGET_HELPER_GLOBAL_INLINE LiVESSList * lives_file_chooser_get_filenames(LiVESFileChooser *chooser)
WIDGET_HELPER_GLOBAL_INLINE LiVESPixbuf * lives_pixbuf_new_from_file(const char *filename, LiVESError **error)
WIDGET_HELPER_GLOBAL_INLINE const char * lives_menu_item_get_text(LiVESWidget *menuitem)
LiVESWidget * lives_standard_expander_new(const char *ltext, LiVESBox *box, LiVESWidget *child)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_signal_handler_unblock(livespointer instance, unsigned long handler_id)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_grab_remove(LiVESWidget *widget)
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 LiVESTextBuffer * lives_text_buffer_new(void)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_unparent(LiVESWidget *widget)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_check_menu_item_get_active(LiVESCheckMenuItem *item)
LIVES_GLOBAL_INLINE void lives_label_chomp(LiVESLabel *label)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_combo_set_active_index(LiVESCombo *combo, int index)
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_painter_surface_destroy(lives_painter_surface_t *surf)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_label_set_text(LiVESLabel *label, const char *text)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_signal_handler_block(livespointer instance, unsigned long handler_id)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_show(LiVESWidget *widget)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_signal_handler_disconnect(livespointer instance, unsigned long handler_id)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_window_set_decorated(LiVESWindow *window, boolean set)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_object_unref(livespointer object)
decrease refcount by one: if refcount==0, object is destroyed
WIDGET_HELPER_GLOBAL_INLINE boolean lives_combo_set_active_string(LiVESCombo *combo, const char *active_str)
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 boolean lives_widget_set_halign(LiVESWidget *widget, LiVESAlign align)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_check_menu_item_set_active(LiVESCheckMenuItem *item, boolean state)
WIDGET_HELPER_GLOBAL_INLINE const char * lives_button_get_label(LiVESButton *button)
WIDGET_HELPER_GLOBAL_INLINE LiVESAccelGroup * lives_dialog_add_escape(LiVESDialog *dlg, LiVESWidget *button)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_menu_set_title(LiVESMenu *menu, const char *title)
LiVESWidget * add_fill_to_box(LiVESBox *box)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_painter_set_line_width(lives_painter_t *cr, double width)
WIDGET_HELPER_GLOBAL_INLINE lives_colRGBA64_t * widget_color_to_lives_rgba(lives_colRGBA64_t *lcolor, LiVESWidgetColor *color)
WIDGET_HELPER_GLOBAL_INLINE const char * lives_combo_get_active_text(LiVESCombo *combo)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_painter_paint(lives_painter_t *cr)
WIDGET_HELPER_GLOBAL_INLINE int lives_spin_button_get_value_as_int(LiVESSpinButton *button)
WIDGET_HELPER_GLOBAL_INLINE uint64_t lives_widget_get_xwinid(LiVESWidget *widget, const char *msg)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_object_ref(livespointer object)
increase refcount by one
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_get_pointer(LiVESXDevice *device, LiVESWidget *widget, int *x, int *y)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_table_set_column_homogeneous(LiVESTable *table, boolean homogeneous)
boolean lives_text_view_set_text(LiVESTextView *textview, const char *text, int len)
LIVES_GLOBAL_INLINE boolean lives_widget_destroy(LiVESWidget *widget)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_toggle_tool_button_get_active(LiVESToggleToolButton *button)
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_container_add(LiVESContainer *container, LiVESWidget *widget)
void hide_cursor(LiVESXWindow *window)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_button_box_set_layout(LiVESButtonBox *bbox, LiVESButtonBoxStyle bstyle)
WIDGET_HELPER_GLOBAL_INLINE double lives_spin_button_get_value(LiVESSpinButton *button)
WIDGET_HELPER_GLOBAL_INLINE LiVESXWindow * lives_display_get_window_at_pointer(LiVESXDevice *device, LiVESXDisplay *display, int *win_x, int *win_y)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_hide(LiVESWidget *widget)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_show_all(LiVESWidget *widget)
WIDGET_HELPER_GLOBAL_INLINE boolean is_standard_widget(LiVESWidget *widget)
WIDGET_HELPER_GLOBAL_INLINE LiVESWidgetColor * lives_painter_set_source_rgb_from_lives_widget_color(lives_painter_t *cr, LiVESWidgetColor *wcol)
WIDGET_HELPER_GLOBAL_INLINE int lives_widget_get_allocation_y(LiVESWidget *widget)
boolean lives_widget_context_update(void)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_painter_move_to(lives_painter_t *cr, double x, double y)
WIDGET_HELPER_GLOBAL_INLINE lives_painter_surface_t * lives_widget_create_painter_surface(LiVESWidget *widget)
WIDGET_HELPER_GLOBAL_INLINE LiVESWidget * lives_widget_get_parent(LiVESWidget *widget)
WIDGET_HELPER_GLOBAL_INLINE LiVESWidget * lives_hbox_new(boolean homogeneous, int spacing)
LIVES_GLOBAL_INLINE boolean lives_button_set_image_from_stock(LiVESButton *button, const char *stock_id)
LiVESWidget * lives_standard_menu_item_new_with_label(const char *label)
LiVESWidget * lives_standard_label_new(const char *text)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_painter_line_to(lives_painter_t *cr, double x, double y)
WIDGET_HELPER_GLOBAL_INLINE int lives_widget_get_allocation_height(LiVESWidget *widget)
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)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_set_size_request(LiVESWidget *widget, int width, int height)
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 boolean lives_source_remove(uint32_t handle)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_painter_stroke(lives_painter_t *cr)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_button_set_label(LiVESButton *button, const char *label)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_process_updates(LiVESWidget *widget)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_queue_draw_if_visible(LiVESWidget *widget)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_alignment_set(LiVESWidget *alignment, float xalign, float yalign, float xscale, float yscale)
void lives_general_button_clicked(LiVESButton *button, livespointer data_to_free)
WIDGET_HELPER_GLOBAL_INLINE lives_painter_surface_t * lives_xwindow_create_similar_surface(LiVESXWindow *window, lives_painter_content_t cont, int width, int height)
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)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_queue_draw_and_update(LiVESWidget *widget)
#define LIVES_EXPAND_DEFAULT_HEIGHT
#define LIVES_EXPAND_NONE
@ LIVES_CURSOR_NORMAL
must be zero
@ LIVES_CURSOR_BUSY
#define LIVES_EXPAND_EXTRA_WIDTH
char LIVES_STOCK_LABEL_CLOSE_WINDOW[32]
#define LIVES_EXPAND_EXTRA
#define LIVES_EXPAND_DEFAULT
ulong lives_signal_connect(LiVESWidget *, const char *signal_name, ulong funcptr, livespointer data)
widget_opts_t widget_opts
#define LIVES_EXPAND_DEFAULT_WIDTH
#define LIVES_JUSTIFY_DEFAULT