LiVES  3.2.0
startup.c
Go to the documentation of this file.
1 // startup.c
2 // LiVES
3 // (c) G. Finch 2010 - 2020 <salsaman+lives@gmail.com>
4 // released under the GNU GPL 3 or later
5 // see file ../COPYING for licensing details
6 
7 // functions for first time startup
8 
9 #include "main.h"
10 #include "interface.h"
11 #include "rte_window.h"
12 #include "startup.h"
13 
14 static boolean allpassed;
15 
16 LiVESWidget *assist;
17 
18 static uint64_t oldver = 0;
19 
20 boolean migrate_config(const char *old_vhash, const char *newconfigfile) {
21  // on a fresh install, we check if there is an older config file, and if so, migrate it
22  oldver = atoll(old_vhash);
25  if (oldver > 0 && oldver < 3200000) {
26  char *ocfdir = lives_build_path(capable->home_dir, LIVES_DEF_CONFIG_DATADIR_OLD, NULL);
27  lives_cp(prefs->configfile, newconfigfile);
28  if (lives_file_test(ocfdir, LIVES_FILE_TEST_IS_DIR)) {
29  char *fname, *fname2;
31  lives_free(ocfdir);
32  fname = lives_build_filename(prefs->config_datadir, DEF_KEYMAP_FILE_OLD, NULL);
33  if (lives_file_test(fname, LIVES_FILE_TEST_EXISTS)) {
34  lives_rm(fname);
35  }
36  lives_free(fname);
37  fname = lives_build_filename(prefs->config_datadir, DEF_KEYMAP_FILE2_OLD, NULL); // perkey defs
38  if (lives_file_test(fname, LIVES_FILE_TEST_EXISTS)) {
39  fname2 = lives_build_filename(prefs->config_datadir, DEF_KEYMAP_FILE2, NULL); // perkey defs
40  lives_mv(fname, fname2);
41  lives_free(fname2);
42  }
43  lives_free(fname);
44  fname = lives_build_filename(prefs->config_datadir, DEF_KEYMAP_FILE3_OLD, NULL); // data connections
45  if (lives_file_test(fname, LIVES_FILE_TEST_EXISTS)) {
46  fname2 = lives_build_filename(prefs->config_datadir, DEF_KEYMAP_FILE3, NULL); // data connections
47  lives_mv(fname, fname2);
48  lives_free(fname2);
49  }
50  lives_free(fname);
51  }
52  return TRUE;
53  }
54  return FALSE;
55 }
56 
57 
58 void cleanup_old_config(void) {
59  if (oldver > 0 && oldver < 3200000) {
60  char *oldconfig = lives_build_filename(capable->home_dir, LIVES_DEF_CONFIG_FILE_OLD, NULL);
61  char *oldconfigdir = lives_build_path(capable->home_dir, LIVES_DEF_CONFIG_DATADIR_OLD, NULL);
62  if (do_yesno_dialogf(_("The locations of LiVES configuration files have changed.\n"
63  "%s is now %s\nand %s is now %s\nThe files have been copied to the new locations.\n"
64  "\nWould you like me to remove the old files ?\n"),
65  oldconfig, prefs->configfile, oldconfigdir, prefs->config_datadir)) {
66  lives_rm(oldconfig);
67  lives_free(oldconfig);
68  oldconfig = lives_build_filename(capable->home_dir, LIVES_DEF_CONFIG_FILE_OLD ".", NULL);
69  lives_rmglob(oldconfig);
70  lives_free(oldconfig);
71  oldconfig = lives_build_filename(capable->home_dir, LIVES_DEF_CONFIG_FILE_OLD "~", NULL);
72  lives_rm(oldconfig);
73  if (lives_file_test(oldconfigdir, LIVES_FILE_TEST_IS_DIR)) {
74  lives_rmdir(oldconfigdir, TRUE);
75  }
76  }
77  lives_free(oldconfig);
78  lives_free(oldconfigdir);
79  }
80 }
81 
82 
83 boolean build_init_config(const char *config_datadir, boolean prompt) {
85  boolean create = TRUE;
86  if (prompt) {
87  if (!do_yesno_dialogf(_("Should I create default items in\n%s ?"), config_datadir)) create = FALSE;
88  }
89  if (create) {
90  LiVESResponseType retval;
91  char *keymap_file, *stock_icons_dir, *devmapdir;
92 
93  if (!lives_file_test(config_datadir, LIVES_FILE_TEST_IS_DIR)) {
95  while (1) {
96  if (!lives_make_writeable_dir(config_datadir)) {
97  do_dir_perm_error(config_datadir, FALSE);
98  continue;
99  }
100  break;
101  // *INDENT-OFF*
102  }}
103  // *INDENT-ON*
104 
106  keymap_file = lives_build_filename(config_datadir, DEF_KEYMAP_FILE2, NULL);
107  if (!lives_file_test(keymap_file, LIVES_FILE_TEST_EXISTS)) {
108  char *tmp, *keymap_template = lives_build_filename(prefs->prefix_dir, DATA_DIR, DEF_KEYMAP_FILE2, NULL);
110  do {
111  retval = LIVES_RESPONSE_NONE;
112  if (!lives_file_test(keymap_template, LIVES_FILE_TEST_EXISTS)) {
113  retval = do_file_notfound_dialog(_("LiVES was unable to find the default keymap file"),
114  keymap_template);
115  if (retval == LIVES_RESPONSE_BROWSE) {
116  char *dirx = lives_build_path(prefs->prefix_dir, DATA_DIR, NULL);
117  char *xkeymap_template = choose_file(dirx, DEF_KEYMAP_FILE2, NULL,
118  LIVES_FILE_CHOOSER_ACTION_SELECT_FILE, NULL, NULL);
119  if (xkeymap_template && *xkeymap_template) {
120  lives_free(keymap_template);
121  keymap_template = xkeymap_template;
122  }
123  continue;
124  }
125  }
126  } while (retval == LIVES_RESPONSE_RETRY);
127 
128  if (retval != LIVES_RESPONSE_CANCEL) {
129  do {
130  retval = LIVES_RESPONSE_NONE;
131  lives_cp(keymap_template, keymap_file);
132  if (!lives_file_test(keymap_file, LIVES_FILE_TEST_EXISTS)) {
133  // give up
135  (_("Unable to create default keymap file: %s\nPlease make sure the directory\n%s\nis writable.\n"),
136  keymap_file, config_datadir)));
137 
138  retval = do_abort_cancel_retry_dialog(tmp);
139  }
140  } while (retval == LIVES_RESPONSE_RETRY);
141  lives_free(keymap_template);
142  }
143  }
144  lives_free(keymap_file);
145 
147  keymap_file = lives_build_filename(config_datadir, DEF_KEYMAP_FILE3, NULL);
148  if (!lives_file_test(keymap_file, LIVES_FILE_TEST_EXISTS)) {
149  char *keymap_template = lives_build_filename(prefs->prefix_dir, DATA_DIR, DEF_KEYMAP_FILE3, NULL);
150  retval = LIVES_RESPONSE_NONE;
151  if (lives_file_test(keymap_template, LIVES_FILE_TEST_EXISTS)) {
152  lives_cp(keymap_template, keymap_file);
153  }
154  }
155  lives_free(keymap_file);
156 
157  devmapdir = lives_build_path(config_datadir, LIVES_DEVICEMAP_DIR, NULL);
158  if (1 || !lives_file_test(devmapdir, LIVES_FILE_TEST_IS_DIR)) {
159 #ifdef ENABLE_OSC
160  char *sys_devmap_dir = lives_build_path(prefs->prefix_dir, DATA_DIR, LIVES_DEVICEMAP_DIR, NULL);
162  do {
163  retval = LIVES_RESPONSE_NONE;
164  if (!lives_file_test(sys_devmap_dir, LIVES_FILE_TEST_IS_DIR)) {
165  retval = do_dir_notfound_dialog(_("LiVES was unable to find its default device maps in\n"),
166  sys_devmap_dir);
167  if (retval == LIVES_RESPONSE_BROWSE) {
168  char *xsys_devmap_dir = choose_file(sys_devmap_dir, NULL, NULL,
169  LIVES_FILE_CHOOSER_ACTION_SELECT_FOLDER, NULL, NULL);
170  if (xsys_devmap_dir && *xsys_devmap_dir) {
171  lives_free(sys_devmap_dir);
172  sys_devmap_dir = xsys_devmap_dir;
173  }
174  continue;
175  }
176  }
177  } while (retval == LIVES_RESPONSE_RETRY);
178 
179  if (retval != LIVES_RESPONSE_CANCEL) {
180  do {
181  retval = LIVES_RESPONSE_NONE;
182  if (!lives_make_writeable_dir(devmapdir))
183  retval = do_dir_perm_error(devmapdir, TRUE);
184  } while (retval == LIVES_RESPONSE_RETRY);
185 
186  if (retval != LIVES_RESPONSE_CANCEL) {
187  lives_cp_recursive(sys_devmap_dir, config_datadir, TRUE);
188  }
189  }
190  lives_free(sys_devmap_dir);
191 #endif
192  }
193  lives_free(devmapdir);
194 
195 #ifdef GUI_GTK
196  stock_icons_dir = lives_build_path(config_datadir, STOCK_ICONS_DIR, NULL);
198  if (!lives_file_test(stock_icons_dir, LIVES_FILE_TEST_IS_DIR)) {
199  char *sys_stock_icons_dir = lives_build_path(prefs->prefix_dir, DATA_DIR, STOCK_ICONS_DIR, NULL);
200  if (mainw && mainw->splash_window) {
203  }
204  do {
205  retval = LIVES_RESPONSE_NONE;
206  if (!lives_file_test(sys_stock_icons_dir, LIVES_FILE_TEST_IS_DIR)) {
207  retval = do_dir_notfound_dialog(_("LiVES was unable to find its default icons in\n"),
208  sys_stock_icons_dir);
209  if (retval == LIVES_RESPONSE_BROWSE) {
210  char *xsys_stock_icons_dir = choose_file(sys_stock_icons_dir, NULL, NULL,
211  LIVES_FILE_CHOOSER_ACTION_SELECT_FOLDER, NULL, NULL);
212  if (xsys_stock_icons_dir && *xsys_stock_icons_dir) {
213  lives_free(sys_stock_icons_dir);
214  sys_stock_icons_dir = xsys_stock_icons_dir;
215  }
216  continue;
217  }
218  }
219  } while (retval == LIVES_RESPONSE_RETRY);
220 
221  if (retval != LIVES_RESPONSE_CANCEL) {
222  do {
223  retval = LIVES_RESPONSE_NONE;
224  if (!lives_make_writeable_dir(stock_icons_dir))
225  retval = do_dir_perm_error(stock_icons_dir, TRUE);
226  } while (retval == LIVES_RESPONSE_RETRY);
227 
228  if (retval != LIVES_RESPONSE_CANCEL) {
229  lives_cp_recursive(sys_stock_icons_dir, config_datadir, TRUE);
230  }
231  }
232  lives_free(sys_stock_icons_dir);
233  }
234  lives_free(stock_icons_dir);
235 #endif
237 
238  return TRUE;
239  }
240  return FALSE;
241 }
242 
243 
244 static LiVESResponseType prompt_existing_dir(const char *dirname, uint64_t freespace, boolean wrtable) {
245  // can return LIVES_RESPONSE_OK, LIVES_RESPONSE_CANCEL or LIVES_RESPONSE_RETRY
246  char *msg;
247  if (wrtable) {
248  if (dirs_equal(dirname, capable->home_dir)) {
249  if (!do_yesno_dialog(
250  _("You have chosen to use your home directory as the LiVES working directory.\n"
251  "This is NOT recommended as it will possibly result in the loss of unrelated files.\n"
252  "Click Yes if you REALLY want to continue, or No to create or select another directory.\n")))
253  return LIVES_RESPONSE_CANCEL;
254  } else {
255  msg = lives_format_storage_space_string(freespace);
256  boolean res = do_yesno_dialogf(
257  _("A directory named\n%s\nalready exists. Do you wish to use this directory ?\n\n(Free space = %s)\n"),
258  dirname, msg);
259  lives_free(msg);
260  if (!res) return LIVES_RESPONSE_CANCEL;
261  return LIVES_RESPONSE_OK;
262  }
263  } else {
264  msg = lives_strdup_printf(_("A directory named\n%s\nalready exists.\nHowever, LiVES could not write to this directory "
265  "or read its free space.\nClick Abort to exit from LiVES, or Retry to select another "
266  "location.\n"), dirname);
267 
269  lives_free(msg);
270  return LIVES_RESPONSE_RETRY;
271  }
272  return LIVES_RESPONSE_OK;
273 }
274 
275 
276 static boolean prompt_new_dir(char *dirname, uint64_t freespace, boolean wrtable) {
277  boolean res;
278  if (wrtable) {
279  char *fspstr = lives_format_storage_space_string(freespace);
280  res = do_warning_dialogf(_("\nCreate the directory\n%s\n?\n\n(Free space = %s)"), dirname, fspstr);
281  lives_free(fspstr);
282  } else {
283  res = do_error_dialogf(_("\nLiVES could not write to the directory\n%s\n"
284  "Please try again and choose a different location.\n"),
285  dirname);
286  }
287  return res;
288 }
289 
290 
291 void filename_toolong_error(const char *fname, const char *ftype, size_t max, boolean can_retry) {
292  char *rstr, *msg;
293  if (can_retry) rstr = _("\nPlease click Retry to select an alternative directory, or Abort to exit immediately"
294  "from LiVES\n");
295  else rstr = lives_strdup("");
296 
297  msg = lives_strdup_printf(_("The name of the %s provided\n(%s)\nis too long (maximum is %d characters)\n%s"),
298  ftype, fname, max, rstr);
299  if (can_retry) do_abort_retry_dialog(msg);
300  else startup_message_fatal(msg);
301  lives_free(msg); lives_free(rstr);
302 }
303 
304 void dir_toolong_error(const char *dirname, const char *dirtype, size_t max, boolean can_retry) {
305  char *rstr, *msg;
306  if (can_retry) rstr = _("\nPlease click Retry to select an alternative directory, or Abort to exit immediately"
307  "from LiVES\n");
308  else rstr = lives_strdup("");
309  msg = lives_strdup_printf(_("The name of the %s provided\n(%s)\nis too long (maximum is %d characters)\n%s"),
310  dirtype, dirname, max, rstr);
311  if (can_retry) do_abort_retry_dialog(msg);
312  else startup_message_fatal(msg);
313  lives_free(msg); lives_free(rstr);
314 }
315 
316 
317 void close_file(int current_file, boolean tshoot) {
318  if (tshoot) close_current_file(current_file);
319  else {
320 #ifdef IS_MINGW
321  // kill any active processes: for other OSes the backend does this
323 #endif
324  close_temp_handle(current_file);
325  }
326 }
327 
328 
329 LiVESResponseType check_workdir_valid(char **pdirname, LiVESDialog * dialog, boolean fullcheck) {
330  // returns LIVES_RESPONSE_RETRY or LIVES_RESPONSE_OK
331  char cdir[PATH_MAX];
332  uint64_t freesp;
333  size_t chklen = strlen(LIVES_DEF_WORK_NAME) + strlen(LIVES_DIR_SEP) * 2;
334  char *tmp;
335 
336  if (!pdirname || !*pdirname) return LIVES_RESPONSE_RETRY;
337 
338  if (lives_strlen(*pdirname) > (PATH_MAX - MAX_SET_NAME_LEN * 2)) {
339  do_error_dialog(_("Directory name is too long !"));
340  return LIVES_RESPONSE_RETRY;
341  }
342 
343  // append a dirsep to the end if there isnt one
344  lives_snprintf(cdir, PATH_MAX, "%s", *pdirname);
345  ensure_isdir(cdir);
346 
347  *pdirname = lives_strdup(cdir);
348 
349  if (strlen(*pdirname) > (PATH_MAX - MAX_SET_NAME_LEN * 2)) {
350  do_error_dialog(_("Directory name is too long !"));
351  return LIVES_RESPONSE_RETRY;
352  }
353 
354  if (fullcheck) {
355  // if it's an existing dir, append "livesprojects" to the end unless it is already
356  if (lives_file_test(*pdirname, LIVES_FILE_TEST_EXISTS) &&
357  (strlen(*pdirname) < chklen || strncmp(*pdirname + strlen(*pdirname) - chklen,
359  tmp = lives_build_path(*pdirname, LIVES_DEF_WORK_NAME, NULL);
360  lives_free(*pdirname);
361  *pdirname = tmp;
362  }
363 
364  if (lives_strlen(*pdirname) > (PATH_MAX - MAX_SET_NAME_LEN * 2)) {
365  do_error_dialog(_("Directory name is too long !"));
366  return LIVES_RESPONSE_RETRY;
367  }
368  }
369 
370  if (!check_dir_access(*pdirname, FALSE)) {
371  do_dir_perm_error(*pdirname, FALSE);
372  return LIVES_RESPONSE_RETRY;
373  }
374 
375  if (fullcheck) {
376  if (lives_file_test(*pdirname, LIVES_FILE_TEST_IS_DIR)) {
377  if (is_writeable_dir(*pdirname)) {
378  freesp = get_ds_free(*pdirname);
379  widget_opts.transient = LIVES_WINDOW(dialog);
380  if (!prompt_existing_dir(*pdirname, freesp, TRUE)) {
381  widget_opts.transient = NULL;
382  return LIVES_RESPONSE_RETRY;
383  }
384  widget_opts.transient = NULL;
385  } else {
386  if (!prompt_existing_dir(*pdirname, 0, FALSE)) {
387  return LIVES_RESPONSE_RETRY;
388  }
389  }
390  } else {
391  if (is_writeable_dir(*pdirname)) {
392  freesp = get_ds_free(*pdirname);
393  if (!prompt_new_dir(*pdirname, freesp, TRUE)) {
394  lives_rmdir(*pdirname, FALSE);
395  return LIVES_RESPONSE_RETRY;
396  }
397  } else {
398  if (!prompt_new_dir(*pdirname, 0, FALSE)) {
399  lives_rmdir(*pdirname, FALSE);
400  return LIVES_RESPONSE_RETRY;
401  // *INDENT-OFF*
402  }}}}
403  // *INDENT-ON*
404 
405  if (!lives_make_writeable_dir(*pdirname)) {
406  return do_dir_perm_error(*pdirname, FALSE);
407  }
408 
409  return LIVES_RESPONSE_OK;
410 }
411 
412 
413 boolean do_workdir_query(void) {
414  LiVESWidget *dirbutton;
415  LiVESResponseType response;
416  char *dirname = NULL, *mp;
417  _entryw *wizard = create_rename_dialog(6);
418 
420  dirbutton = lives_label_get_mnemonic_widget(LIVES_LABEL(widget_opts.last_label));
421  lives_widget_object_set_data(LIVES_WIDGET_OBJECT(dirbutton), FILESEL_TYPE_KEY,
422  LIVES_INT_TO_POINTER(LIVES_DIR_SELECTION_CREATE_FOLDER));
423 
424  if (mainw->splash_window) {
425  char *wid;
427  lives_widget_show_all(wizard->dialog);
428  lives_widget_show_now(wizard->dialog);
429  gtk_window_set_urgency_hint(LIVES_WINDOW(wizard->dialog), TRUE); // dont know if this actually does anything...
430  wid = lives_strdup_printf("0x%08lx", (uint64_t)LIVES_XWINDOW_XID(lives_widget_get_xwindow(wizard->dialog)));
431  if (!wid || !activate_x11_window(wid)) lives_window_set_keep_above(LIVES_WINDOW(wizard->dialog), TRUE);
432  }
433 
434  do {
435  lives_freep((void **)&dirname);
436  response = lives_dialog_run(LIVES_DIALOG(wizard->dialog));
437  if (response == LIVES_RESPONSE_CANCEL) return FALSE;
438 
439  // TODO: should we convert to locale encoding ??
440  dirname = lives_strdup(lives_entry_get_text(LIVES_ENTRY(wizard->entry)));
441  } while (lives_strcmp(dirname, prefs->workdir) &&
442  check_workdir_valid(&dirname, LIVES_DIALOG(wizard->dialog), TRUE) == LIVES_RESPONSE_RETRY);
443 
444  mp = get_mountpoint_for(dirname);
445  if (lives_strcmp(mp, capable->mountpoint) || !strcmp(mp, "??????")) {
447  mainw->dsu_valid = FALSE;
450  capable->mountpoint = mp;
451  }
452 
453  lives_widget_destroy(wizard->dialog);
454  lives_freep((void **)&wizard);
455 
457 
458  if (mainw->is_ready) {
459  lives_snprintf(future_prefs->workdir, PATH_MAX, "%s", dirname);
460  return TRUE;
461  }
462 
463  lives_snprintf(prefs->workdir, PATH_MAX, "%s", dirname);
464  lives_snprintf(prefs->backend, PATH_MAX * 4, "%s -s \"%s\" -WORKDIR=\"%s\" -CONFIGFILE=\"%s\" --", EXEC_PERL,
466  lives_snprintf(prefs->backend_sync, PATH_MAX * 4, "%s", prefs->backend);
467 
470 
472 
473  lives_free(dirname);
474 
475  return TRUE;
476 }
477 
478 
479 static void on_init_aplayer_toggled(LiVESToggleButton * tbutton, livespointer user_data) {
480  int audp = LIVES_POINTER_TO_INT(user_data);
481 
482  if (!lives_toggle_button_get_active(tbutton)) return;
483 
484  prefs->audio_player = audp;
485 
486  switch (audp) {
487  case AUD_PLAYER_PULSE:
489  break;
490  case AUD_PLAYER_JACK:
492  break;
493  case AUD_PLAYER_SOX:
495  break;
496  }
497 }
498 
499 
500 boolean do_audio_choice_dialog(short startup_phase) {
501  LiVESWidget *dialog, *dialog_vbox, *radiobutton2 = NULL, *label;
502  LiVESWidget *okbutton, *cancelbutton;
503  LiVESWidget *hbox;
504 
505 #ifdef HAVE_PULSE_AUDIO
506  LiVESWidget *radiobutton0;
507 #endif
508 
509 #ifdef ENABLE_JACK
510  LiVESWidget *radiobutton1;
511 #endif
512 
513  LiVESAccelGroup *accel_group;
514 
515  LiVESSList *radiobutton_group = NULL;
516 
517  char *txt0, *txt1, *txt2, *txt3, *txt4, *txt5, *txt6, *msg, *wid;
518 
519  LiVESResponseType response;
520 
521  if (startup_phase == 2) {
522  txt0 = (_("LiVES FAILED TO START YOUR SELECTED AUDIO PLAYER !\n\n"));
523  } else {
524  prefs->audio_player = -1;
525  txt0 = lives_strdup("");
526  }
527 
528  txt1 = lives_strdup(
529  _("Before starting LiVES, you need to choose an audio player.\n\nPULSE AUDIO is recommended for most users"));
530 
531 #ifndef HAVE_PULSE_AUDIO
532  txt2 = (_(", but this version of LiVES was not compiled with pulse audio support.\n\n"));
533 #else
534  if (!capable->has_pulse_audio) {
535  txt2 = lives_strdup(
536  _(", but you do not have pulseaudio installed on your system.\n "
537  "You are advised to install pulseaudio first before running LiVES.\n\n"));
538  } else txt2 = lives_strdup(".\n\n");
539 #endif
540 
541  txt3 = (_("JACK audio is recommended for pro users"));
542 
543 #ifndef ENABLE_JACK
544  txt4 = (_(", but this version of LiVES was not compiled with jack audio support.\n\n"));
545 #else
546  if (!capable->has_jackd) {
547  txt4 = (_(", but you do not have jackd installed. You may wish to install jackd first before running LiVES.\n\n"));
548  } else {
549  txt4 = lives_strdup(
550  _(", but may prevent LiVES from starting on some systems.\nIf LiVES will not start with jack,"
551  "you can restart and try with another audio player instead.\n\n"));
552  }
553 #endif
554 
555  txt5 = (_("SOX may be used if neither of the preceding players work, "));
556 
557  if (capable->has_sox_play) {
558  txt6 = (_("but many audio features will be disabled.\n\n"));
559  } else {
560  txt6 = (_("but you do not have sox installed.\nYou are advised to install it before running LiVES.\n\n"));
561  }
562 
563  msg = lives_strdup_printf("%s%s%s%s%s%s%s", txt0, txt1, txt2, txt3, txt4, txt5, txt6);
564 
565  lives_free(txt0); lives_free(txt1); lives_free(txt2);
566  lives_free(txt3); lives_free(txt4); lives_free(txt5);
567  lives_free(txt6);
568 
569  dialog = lives_standard_dialog_new(_("Choose an audio player"), FALSE, -1, -1);
570 
571  accel_group = LIVES_ACCEL_GROUP(lives_accel_group_new());
572  lives_window_add_accel_group(LIVES_WINDOW(dialog), accel_group);
573 
574  dialog_vbox = lives_dialog_get_content_area(LIVES_DIALOG(dialog));
575 
576  // TODO: add_param_label_to_box()
577  label = lives_standard_label_new(msg);
578  lives_container_add(LIVES_CONTAINER(dialog_vbox), label);
579  lives_free(msg);
580 
581 #ifdef HAVE_PULSE_AUDIO
582  hbox = lives_hbox_new(FALSE, 0);
583  lives_box_pack_start(LIVES_BOX(dialog_vbox), hbox, FALSE, FALSE, widget_opts.packing_height);
584  radiobutton0 = lives_standard_radio_button_new(_("Use _pulseaudio player"), &radiobutton_group, LIVES_BOX(hbox), NULL);
586 #endif
587 
588 #ifdef ENABLE_JACK
589  hbox = lives_hbox_new(FALSE, 0);
590  lives_box_pack_start(LIVES_BOX(dialog_vbox), hbox, FALSE, FALSE, widget_opts.packing_height);
591  radiobutton1 = lives_standard_radio_button_new(_("Use _jack audio player"), &radiobutton_group, LIVES_BOX(hbox), NULL);
592 #endif
593 
594  if (capable->has_sox_play) {
595  hbox = lives_hbox_new(FALSE, 0);
596  lives_box_pack_start(LIVES_BOX(dialog_vbox), hbox, FALSE, FALSE, widget_opts.packing_height);
597  radiobutton2 = lives_standard_radio_button_new(_("Use _sox audio player"), &radiobutton_group, LIVES_BOX(hbox), NULL);
599  }
600 
601 #ifdef HAVE_PULSE_AUDIO
604  lives_toggle_button_set_active(LIVES_TOGGLE_BUTTON(radiobutton0), TRUE);
606  }
607 #endif
608 #ifdef ENABLE_JACK
611  lives_toggle_button_set_active(LIVES_TOGGLE_BUTTON(radiobutton1), TRUE);
613  }
614 #endif
615  if (capable->has_sox_play) {
617  lives_toggle_button_set_active(LIVES_TOGGLE_BUTTON(radiobutton2), TRUE);
619  }
620  }
621 
622 #ifdef HAVE_PULSE_AUDIO
623  lives_signal_sync_connect(LIVES_GUI_OBJECT(radiobutton0), LIVES_WIDGET_TOGGLED_SIGNAL,
624  LIVES_GUI_CALLBACK(on_init_aplayer_toggled),
625  LIVES_INT_TO_POINTER(AUD_PLAYER_PULSE));
626 #endif
627 
628 #ifdef ENABLE_JACK
629  lives_signal_sync_connect(LIVES_GUI_OBJECT(radiobutton1), LIVES_WIDGET_TOGGLED_SIGNAL,
630  LIVES_GUI_CALLBACK(on_init_aplayer_toggled),
631  LIVES_INT_TO_POINTER(AUD_PLAYER_JACK));
632 #endif
633 
634  if (capable->has_sox_play) {
635  lives_signal_sync_connect(LIVES_GUI_OBJECT(radiobutton2), LIVES_WIDGET_TOGGLED_SIGNAL,
636  LIVES_GUI_CALLBACK(on_init_aplayer_toggled),
637  LIVES_INT_TO_POINTER(AUD_PLAYER_SOX));
638  }
639  cancelbutton = lives_dialog_add_button_from_stock(LIVES_DIALOG(dialog), LIVES_STOCK_CANCEL, NULL,
640  LIVES_RESPONSE_CANCEL);
641 
642  lives_widget_add_accelerator(cancelbutton, LIVES_WIDGET_CLICKED_SIGNAL, accel_group,
643  LIVES_KEY_Escape, (LiVESXModifierType)0, (LiVESAccelFlags)0);
644 
645  okbutton = lives_dialog_add_button_from_stock(LIVES_DIALOG(dialog), LIVES_STOCK_GO_FORWARD, _("_Next"),
646  LIVES_RESPONSE_OK);
647 
648  lives_widget_show_all(dialog);
650 
651  lives_widget_show_now(dialog);
652  lives_widget_grab_focus(okbutton);
653 
654  if (prefs->audio_player == -1) {
656  return LIVES_RESPONSE_CANCEL;
657  }
658 
659  if (mainw->splash_window) {
661  }
662 
663  wid = lives_strdup_printf("0x%08lx", (uint64_t)LIVES_XWINDOW_XID(lives_widget_get_xwindow(dialog)));
664  if (!wid || !activate_x11_window(wid)) lives_window_set_keep_above(LIVES_WINDOW(dialog), TRUE);
665 
666  response = lives_dialog_run(LIVES_DIALOG(dialog));
667 
668  lives_widget_destroy(dialog);
669 
670  if (mainw->splash_window) {
672  }
673 
678  }
679 
680  return (response == LIVES_RESPONSE_OK);
681 }
682 
683 
684 static void add_test(LiVESWidget * table, int row, char *ttext, boolean noskip) {
685  LiVESWidget *label = lives_standard_label_new(ttext);
686 
687  lives_table_attach(LIVES_TABLE(table), label, 0, 1, row, row + 1, (LiVESAttachOptions)0, (LiVESAttachOptions)0, 10, 10);
688  lives_widget_show(label);
689 
690  if (!noskip) {
691  LiVESWidget *image = lives_image_new_from_stock(LIVES_STOCK_REMOVE, LIVES_ICON_SIZE_LARGE_TOOLBAR);
692  // TRANSLATORS - as in "skipped test"
693  label = lives_standard_label_new(_("Skipped"));
694 
695  lives_table_attach(LIVES_TABLE(table), label, 1, 2, row, row + 1, (LiVESAttachOptions)0, (LiVESAttachOptions)0, 10, 10);
696  lives_widget_show(label);
697 
698  lives_table_attach(LIVES_TABLE(table), image, 2, 3, row, row + 1, (LiVESAttachOptions)0, (LiVESAttachOptions)0, 0, 10);
699  lives_widget_show(image);
700  }
701 
703 }
704 
705 
706 static boolean pass_test(LiVESWidget * table, int row) {
707  // TRANSLATORS - as in "passed test"
708  LiVESWidget *label = lives_standard_label_new(_("Passed"));
709 
710 #if GTK_CHECK_VERSION(3, 10, 0)
711  LiVESWidget *image = lives_image_new_from_stock(LIVES_STOCK_ADD, LIVES_ICON_SIZE_LARGE_TOOLBAR);
712 #else
713  LiVESWidget *image = lives_image_new_from_stock(LIVES_STOCK_APPLY, LIVES_ICON_SIZE_LARGE_TOOLBAR);
714 #endif
715 
716  lives_table_attach(LIVES_TABLE(table), label, 1, 2, row, row + 1, (LiVESAttachOptions)0, (LiVESAttachOptions)0, 10, 10);
717  lives_widget_show(label);
718 
719  lives_table_attach(LIVES_TABLE(table), image, 2, 3, row, row + 1, (LiVESAttachOptions)0, (LiVESAttachOptions)0, 0, 10);
720  lives_widget_show(image);
721 
723  return TRUE;
724 }
725 
726 
727 static boolean _fail_test(LiVESWidget * table, int row, char *ftext, const char *type) {
728  LiVESWidget *label;
729 #if GTK_CHECK_VERSION(3, 10, 0)
730  LiVESWidget *image = lives_image_new_from_stock(LIVES_STOCK_REMOVE, LIVES_ICON_SIZE_LARGE_TOOLBAR);
731 #else
732  LiVESWidget *image = lives_image_new_from_stock(LIVES_STOCK_CANCEL, LIVES_ICON_SIZE_LARGE_TOOLBAR);
733 #endif
734 
735  label = lives_standard_label_new(ftext);
736 
737  lives_table_attach(LIVES_TABLE(table), label, 3, 4, row, row + 1, (LiVESAttachOptions)0, (LiVESAttachOptions)0, 10, 10);
738  lives_widget_show(label);
739 
740  // TRANSLATORS - as in "failed test"
741  label = lives_standard_label_new(type);
742 
743  lives_table_attach(LIVES_TABLE(table), label, 1, 2, row, row + 1, (LiVESAttachOptions)0, (LiVESAttachOptions)0, 10, 10);
744  lives_widget_show(label);
745 
746  lives_table_attach(LIVES_TABLE(table), image, 2, 3, row, row + 1, (LiVESAttachOptions)0, (LiVESAttachOptions)0, 0, 10);
747  lives_widget_show(image);
748 
750  return FALSE;
751 }
752 
753 LIVES_LOCAL_INLINE boolean fail_test(LiVESWidget * table, int row, char *ftext) {
754  allpassed = FALSE;
755  return _fail_test(table, row, ftext, _("Failed"));
756 }
757 
758 LIVES_LOCAL_INLINE boolean skip_test(LiVESWidget * table, int row, char *ftext) {
759  return _fail_test(table, row, ftext, _("Skipped"));
760 }
761 
762 LIVES_LOCAL_INLINE char *get_resource(char *fname) {
763  return lives_build_filename(prefs->prefix_dir, DATA_DIR, LIVES_RESOURCES_DIR, fname, NULL);
764 }
765 
766 
767 boolean do_startup_tests(boolean tshoot) {
768  LiVESWidget *dialog;
769  LiVESWidget *dialog_vbox;
770 
771  LiVESWidget *label;
772  LiVESWidget *table;
773  LiVESWidget *okbutton;
774  LiVESWidget *cancelbutton;
775 
776  LiVESAccelGroup *accel_group;
777 
778  char mppath[PATH_MAX];
779 
780  char *com, *rname, *afile, *tmp;
781  char *image_ext = lives_strdup(prefs->image_ext);
782  char *title, *msg;
783 
784  const char *mp_cmd;
785  const char *lookfor;
786 
787  uint8_t *abuff;
788 
789  off_t fsize;
790 
791  boolean success, success2, success3, success4;
792  boolean imgext_switched = FALSE;
793 
794  LiVESResponseType response;
795  int res;
796  int current_file = mainw->current_file;
797 
798  int out_fd, info_fd, testcase = 0;
799 
800  allpassed = TRUE;
801 
804 
805  if (mainw->multitrack) {
806  if (mainw->multitrack->idlefunc > 0) {
808  mainw->multitrack->idlefunc = 0;
809  }
811  }
812 
813  if (!tshoot) {
814  title = (_("Testing Configuration"));
815  } else {
816  title = (_("Troubleshoot"));
817  }
818 
819  dialog = lives_standard_dialog_new(title, FALSE, -1, -1);
820 
821  accel_group = LIVES_ACCEL_GROUP(lives_accel_group_new());
822  lives_window_add_accel_group(LIVES_WINDOW(dialog), accel_group);
823 
824  lives_free(title);
825 
826  dialog_vbox = lives_dialog_get_content_area(LIVES_DIALOG(dialog));
827 
828  label = lives_standard_label_new(_("LiVES will now run some basic configuration tests\n"));
829  lives_container_add(LIVES_CONTAINER(dialog_vbox), label);
830 
831  cancelbutton = lives_dialog_add_button_from_stock(LIVES_DIALOG(dialog), LIVES_STOCK_CANCEL, NULL,
832  LIVES_RESPONSE_CANCEL);
833 
834  lives_widget_add_accelerator(cancelbutton, LIVES_WIDGET_CLICKED_SIGNAL, accel_group,
835  LIVES_KEY_Escape, (LiVESXModifierType)0, (LiVESAccelFlags)0);
836 
837  if (!tshoot) {
838  okbutton = lives_dialog_add_button_from_stock(LIVES_DIALOG(dialog), LIVES_STOCK_GO_FORWARD, _("_Next"),
839  LIVES_RESPONSE_OK);
840  } else okbutton = lives_dialog_add_button_from_stock(LIVES_DIALOG(dialog), LIVES_STOCK_OK, NULL,
841  LIVES_RESPONSE_OK);
842 
844  lives_widget_grab_focus(okbutton);
845 
847 
848  table = lives_table_new(10, 4, FALSE);
849  lives_container_add(LIVES_CONTAINER(dialog_vbox), table);
850 
851  if (!tshoot) {
852  char *wid;
853  if (mainw->splash_window) {
855  }
856  gtk_window_set_urgency_hint(LIVES_WINDOW(dialog), TRUE);
857  lives_widget_show_all(dialog);
858  lives_widget_show_now(dialog);
860 
861  gtk_window_set_urgency_hint(LIVES_WINDOW(dialog), TRUE); // dont know if this actually does anything...
862  wid = lives_strdup_printf("0x%08lx", (uint64_t)LIVES_XWINDOW_XID(lives_widget_get_xwindow(dialog)));
863  if (!wid || !activate_x11_window(wid)) lives_window_set_keep_above(LIVES_WINDOW(dialog), TRUE);
864  }
865 
867 
868  // check for sox presence
869 
870  add_test(table, testcase, _("Checking for \"sox\" presence"), TRUE);
871 
872  if (!capable->has_sox_sox) {
873  success = fail_test(table, testcase, _("You should install sox to be able to use all the audio features in LiVES"));
874  lives_widget_grab_focus(cancelbutton);
875  } else {
876  success = pass_test(table, testcase);
877  }
878 
879  // test if sox can convert raw 44100 -> wav 22050
880  add_test(table, ++testcase, _("Checking if sox can convert audio"), success);
881 
883  lives_snprintf(prefs->image_ext, 16, "%s", LIVES_FILE_EXT_PNG);
884  lives_snprintf(prefs->image_type, 16, "%s", LIVES_IMAGE_TYPE_PNG);
885 
886  get_temp_handle(-1);
887 
888  if (success) {
889  info_fd = -1;
890 
891  lives_rm(cfile->info_file);
892 
893  // write 1 second of silence
895  out_fd = lives_open3(afile, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR);
896 
897  if (out_fd < 0) THREADVAR(write_failed) = TRUE;
898  else THREADVAR(write_failed) = FALSE;
899 
900  if (!THREADVAR(write_failed)) {
901  int bytes = 44100 * 4;
902  abuff = (uint8_t *)lives_calloc(44100, 4);
903  if (!abuff) {
904  tmp = lives_strdup_printf(_("Unable to allocate %d bytes memory."), bytes);
905  fail_test(table, testcase, tmp);
906  lives_free(tmp);
907  } else {
908  lives_write(out_fd, abuff, bytes, TRUE);
909  close(out_fd);
910  lives_free(abuff);
911  }
912  }
913 
914  if (THREADVAR(write_failed)) {
915  tmp = lives_strdup_printf(_("Unable to write to: %s"), afile);
916  fail_test(table, testcase, tmp);
917  lives_free(tmp);
918  }
919 
920  lives_free(afile);
921 
922  if (!THREADVAR(write_failed)) {
923  afile = lives_build_filename(prefs->workdir, cfile->handle, "testout.wav", NULL);
924 
925  com = lives_strdup_printf("%s export_audio \"%s\" 0. 0. 44100 2 16 1 22050 \"%s\"", prefs->backend_sync,
926  cfile->handle, afile);
927  lives_system(com, TRUE);
928  if (THREADVAR(com_failed)) {
929  THREADVAR(com_failed) = FALSE;
930  tmp = lives_strdup_printf(_("Command failed: %s"), com);
931  fail_test(table, testcase, tmp);
932  lives_free(tmp);
933  }
934 
935  lives_free(com);
936 
937  while (mainw->cancelled == CANCEL_NONE && (info_fd = open(cfile->info_file, O_RDONLY)) == -1) {
938  lives_usleep(prefs->sleep_time);
940  }
941 
942  if (info_fd != -1) {
943  close(info_fd);
944 
945  lives_sync(1);
946 
947  fsize = sget_file_size(afile);
948  lives_rm(afile);
949  lives_free(afile);
950 
951  if (fsize <= 0)
952  fail_test(table, testcase, _("You should install sox_fmt_all or similar"));
953  else pass_test(table, testcase);
954  }
955  }
956  }
957 
958  if (tshoot) {
959  lives_snprintf(prefs->image_ext, 16, "%s", image_ext);
960  lives_snprintf(prefs->image_type, 16, "%s", image_ext_to_lives_image_type(prefs->image_ext));
961  }
962 
963  if (mainw->cancelled != CANCEL_NONE) {
965  close_file(current_file, tshoot);
966  lives_widget_destroy(dialog);
968 
969  if (!mainw->multitrack) {
972  }
973 
974  return FALSE;
975  }
976 
977  // check for mplayer presence
978  success2 = TRUE;
979 
980  add_test(table, ++testcase, _("Checking for \"mplayer\", \"mplayer2\" or \"mpv\" presence"), TRUE);
981 
983  success2 = fail_test(table, testcase,
984  _("You should install mplayer, mplayer2 or mpv to be able to use all the decoding features in LiVES"));
985  }
986 
987  if (!success && !capable->has_mplayer2 && !capable->has_mplayer) {
988  success2 = FALSE;
989  }
990 
991  if (!success2) {
992  if (!success) {
993  lives_widget_destroy(dialog);
995 
997  close_file(current_file, tshoot);
999 
1000  if (mainw->multitrack) {
1002  mainw->multitrack->idlefunc = mt_idle_add(mainw->multitrack);
1003  }
1004 
1005  return FALSE;
1006  }
1007  } else {
1008  success2 = pass_test(table, testcase);
1009  }
1010 
1011  // if present
1012 
1013  // check if mplayer can decode audio
1014 
1015  if (capable->has_mplayer) mp_cmd = EXEC_MPLAYER;
1016  else if (capable->has_mplayer2) mp_cmd = EXEC_MPLAYER2;
1017  else mp_cmd = EXEC_MPV;
1018 
1019  get_location(mp_cmd, mppath, PATH_MAX);
1020  lives_snprintf(prefs->video_open_command, PATH_MAX + 2, "\"%s\"", mppath);
1022 
1023  msg = lives_strdup_printf(_("Checking if %s can convert audio"), mp_cmd);
1024  add_test(table, ++testcase, msg, success2);
1025  lives_free(msg);
1026 
1027  res = 1;
1028 
1029  if (success2) {
1030  // TODO - add a timeout
1031 #ifndef IS_MINGW
1032  com = lives_strdup_printf("LANG=en LANGUAGE=en %s -ao help | %s pcm >/dev/null 2>&1", prefs->video_open_command,
1033  capable->grep_cmd);
1034  res = lives_system(com, TRUE);
1035  lives_free(com);
1036 #else
1037  com = lives_strdup_printf("%s -ao help | %s pcm >NUL 2>&1", prefs->video_open_command, capable->grep_cmd);
1038  res = lives_system(com, TRUE);
1039  lives_free(com);
1040 #endif
1041  }
1042 
1043  if (res == 0) {
1044  pass_test(table, testcase);
1045  } else {
1046  fail_test(table, testcase, _("You should install mplayer,mplayer2 or mpv with pcm/wav support"));
1047  }
1048 
1049  // check if mplayer can decode to png/(alpha)
1050 
1051  rname = get_resource("");
1053  if (!lives_file_test(rname, LIVES_FILE_TEST_IS_DIR)) {
1055  success4 = FALSE;
1056  } else success4 = TRUE;
1057 
1058 #ifdef ALLOW_PNG24
1059  msg = lives_strdup_printf(_("Checking if %s can decode to png"), mp_cmd);
1060 #else
1061  msg = lives_strdup_printf(_("Checking if %s can decode to png/alpha"), mp_cmd);
1062 #endif
1063  add_test(table, ++testcase, msg, success2);
1064  lives_free(msg);
1065 
1066  success3 = FALSE;
1067 
1068  if (success2 && !success4) {
1069  tmp = lives_strdup_printf(_("Resource directory %s not found !"), rname);
1070  skip_test(table, testcase, tmp);
1071  lives_free(tmp);
1072 
1073  msg = lives_strdup_printf(_("Checking less rigorously"), mp_cmd);
1074  add_test(table, ++testcase, msg, TRUE);
1075  lives_free(msg);
1076 
1077  res = 1;
1078 
1079  if (!strcmp(mp_cmd, "mpv")) lookfor = "image";
1080  else lookfor = "png file";
1081 
1082 #ifndef IS_MINGW
1083  com = lives_strdup_printf("LANG=en LANGUAGE=en %s -vo help | %s -i \"%s\" >/dev/null 2>&1",
1085 #else
1086  com = lives_strdup_printf("%s -vo help | %s -i \"%s\" >NUL 2>&1", prefs->video_open_command,
1087  capable->grep_cmd, lookfor);
1088 #endif
1089  res = lives_system(com, TRUE);
1090  lives_free(com);
1091 
1092  if (!res) {
1093  pass_test(table, testcase);
1094  success3 = TRUE;
1095  }
1096  }
1097 
1098  lives_free(rname);
1099 
1100  // try to open resource vidtest.avi
1101  if (!success3 && success2 && success4) {
1102  info_fd = -1;
1103 
1104  lives_rm(cfile->info_file);
1105 
1107 
1108  com = lives_strdup_printf("%s open_test \"%s\" %s \"%s\" 0 png", prefs->backend_sync, cfile->handle,
1110  (tmp = lives_filename_from_utf8(rname, -1, NULL, NULL, NULL)));
1111  lives_free(tmp);
1112  lives_free(rname);
1113 
1114  lives_system(com, TRUE);
1115  if (THREADVAR(com_failed)) {
1116  THREADVAR(com_failed) = FALSE;
1117  tmp = lives_strdup_printf(_("Command failed: %s"), com);
1118  fail_test(table, testcase, tmp);
1119  lives_free(tmp);
1120  }
1121 
1122  lives_free(com);
1123 
1124  while (mainw->cancelled == CANCEL_NONE && (info_fd = open(cfile->info_file, O_RDONLY)) == -1) {
1125  lives_usleep(prefs->sleep_time);
1126  }
1127 
1128  if (info_fd != -1) {
1129  close(info_fd);
1130 
1131  lives_sync(1);
1132 
1133  cfile->img_type = IMG_TYPE_PNG;
1134  cfile->frames = get_frame_count(mainw->current_file, 1);
1135 
1136  if (cfile->frames <= 0) {
1137  msg = lives_strdup_printf(_("You may wish to upgrade %s to a newer version"), mp_cmd);
1138  fail_test(table, testcase, msg);
1139  lives_free(msg);
1140  }
1141 
1142  else {
1143  pass_test(table, testcase);
1144  success3 = TRUE;
1145  }
1146  }
1147  }
1148 
1149  if (mainw->cancelled != CANCEL_NONE) {
1151  close_file(current_file, tshoot);
1152  lives_widget_destroy(dialog);
1154 
1155  if (mainw->multitrack) {
1157  mainw->multitrack->idlefunc = mt_idle_add(mainw->multitrack);
1158  }
1159 
1160  return FALSE;
1161  }
1162 
1163  // check if mplayer can decode to jpeg
1164 
1165  msg = lives_strdup_printf(_("Checking if %s can decode to jpeg"), mp_cmd);
1166  add_test(table, ++testcase, msg, success2);
1167  lives_free(msg);
1168  res = 1;
1169 
1170  if (!strcmp(mp_cmd, "mpv")) {
1171  if (success2 && success3 && !success4) {
1172  tmp = (_("Already checked"));
1173  skip_test(table, testcase - 1, tmp);
1174  lives_free(tmp);
1175  goto jpgdone;
1176  }
1177  lookfor = "image";
1178  } else lookfor = "jpeg file";
1179 
1180  if (success2) {
1181 #ifndef IS_MINGW
1182  com = lives_strdup_printf("LANG=en LANGUAGE=en %s -vo help | %s -i \"%s\" >/dev/null 2>&1",
1184  res = lives_system(com, TRUE);
1185  lives_free(com);
1186 #else
1187  com = lives_strdup_printf("%s -vo help | %s -i \"%s\" >NUL 2>&1", prefs->video_open_command,
1188  capable->grep_cmd, lookfor);
1189  res = lives_system(com, TRUE);
1190  lives_free(com);
1191 #endif
1192  }
1193 
1194  if (res == 0) {
1195  pass_test(table, testcase);
1196  if (!success3) {
1197  if (!strcmp(prefs->image_ext, LIVES_FILE_EXT_PNG)) imgext_switched = TRUE;
1199  lives_snprintf(prefs->image_ext, 16, "%s", LIVES_FILE_EXT_JPG);
1200  lives_snprintf(prefs->image_type, 16, "%s", LIVES_IMAGE_TYPE_JPEG);
1201  }
1202  } else {
1203  if (!success3) {
1204 #ifdef ALLOW_PNG24
1205  msg = lives_strdup_printf(_("You should install %s with either png or jpeg support"), mp_cmd);
1206 #else
1207  msg = lives_strdup_printf(_("You should install %s with either png/alpha or jpeg support"), mp_cmd);
1208 #endif
1209  fail_test(table, testcase, msg);
1210  lives_free(msg);
1211  } else {
1212  msg = lives_strdup_printf(_("You may wish to add jpeg output support to %s"), mp_cmd);
1213  fail_test(table, testcase, msg);
1214  lives_free(msg);
1215  }
1216  }
1217 
1218  // TODO - check each enabled decoder plugin in turn
1219 
1220 jpgdone:
1221  // check for convert
1222 
1223  add_test(table, ++testcase, _("Checking for \"convert\" presence"), TRUE);
1224 
1225  if (!capable->has_convert) {
1226  success = fail_test(table, testcase, _("Install imageMagick to be able to use all of the rendered effects"));
1227  } else {
1228  success = pass_test(table, testcase);
1229  }
1230 
1231  close_file(current_file, tshoot);
1232  mainw->current_file = current_file;
1233 
1234  lives_widget_set_sensitive(okbutton, TRUE);
1235  lives_widget_grab_focus(okbutton);
1236  /* if (!tshoot) { */
1237  /* if (allpassed) { */
1238  /* } else { */
1239  /* lives_widget_grab_focus(cancelbutton); */
1240  /* } */
1241  /* } */
1242 
1243  if (tshoot) {
1244  lives_widget_hide(cancelbutton);
1245  if (imgext_switched) {
1246  label = lives_standard_label_new(
1247  _("\n\n\tImage decoding type has been switched to jpeg. You can revert this in Preferences/Decoding.\t\n"));
1248  lives_container_add(LIVES_CONTAINER(dialog_vbox), label);
1249  }
1250  lives_widget_show(label);
1251  } else {
1252  label = lives_standard_label_new(
1253  _("\n\n\tClick Cancel to exit and install any missing components, or Next to continue\t\n"));
1254  lives_container_add(LIVES_CONTAINER(dialog_vbox), label);
1255  lives_widget_show(label);
1256  }
1257 
1258  response = lives_dialog_run(LIVES_DIALOG(dialog));
1259 
1260  lives_widget_destroy(dialog);
1262 
1263  if (mainw->splash_window) {
1265  }
1266 
1267  if (mainw->multitrack) {
1269  mainw->multitrack->idlefunc = mt_idle_add(mainw->multitrack);
1270  }
1271 
1272  return (response == LIVES_RESPONSE_OK);
1273 }
1274 
1275 
1277  // prompt for startup ce or startup mt
1278  LiVESWidget *dialog, *dialog_vbox, *radiobutton, *label;
1279  /* LiVESWidget *okbutton; */
1280  /* LiVESWidget *quotabutton; */
1281  LiVESWidget *hbox;
1282  LiVESSList *radiobutton_group = NULL;
1283  LiVESResponseType resp;
1284  char *txt1, *txt2, *txt3, *msg, *wid;
1285 
1286  txt1 = (_("\n\nFinally, you can choose the default startup interface for LiVES.\n"));
1287  txt2 = (_("\n\nLiVES has two main interfaces and you can start up with either of them.\n"));
1288  txt3 = (_("\n\nThe default can always be changed later from Preferences.\n"));
1289 
1290  msg = lives_strdup_printf("%s%s%s", txt1, txt2, txt3);
1291 
1292  lives_free(txt1); lives_free(txt2); lives_free(txt3);
1293 
1294  dialog = lives_standard_dialog_new(_("Choose the Startup Interface"), FALSE, -1, -1);
1295  //if (transient) lives_window_set_transient_for(LIVES_WINDOW(dialog), NULL);
1296 
1297  dialog_vbox = lives_dialog_get_content_area(LIVES_DIALOG(dialog));
1298 
1299  label = lives_standard_label_new(msg);
1300  lives_container_add(LIVES_CONTAINER(dialog_vbox), label);
1301  lives_free(msg);
1302 
1303  hbox = lives_hbox_new(FALSE, 0);
1304  lives_box_pack_start(LIVES_BOX(dialog_vbox), hbox, FALSE, FALSE, widget_opts.packing_height);
1305  lives_standard_radio_button_new(_("Start in _Clip Edit mode"), &radiobutton_group, LIVES_BOX(hbox), NULL);
1306 
1307  label = lives_standard_label_new(_("This is the best choice for simple editing tasks and for VJs\n"));
1308 
1309  lives_box_pack_start(LIVES_BOX(dialog_vbox), label, FALSE, FALSE, widget_opts.packing_height);
1310 
1311  hbox = lives_hbox_new(FALSE, 0);
1312  lives_box_pack_start(LIVES_BOX(dialog_vbox), hbox, FALSE, FALSE, widget_opts.packing_height);
1313  radiobutton = lives_standard_radio_button_new(_("Start in _Multitrack mode"), &radiobutton_group, LIVES_BOX(hbox), NULL);
1314 
1315  label = lives_standard_label_new(_("This is a better choice for complex editing tasks involving multiple clips.\n"));
1316 
1317  lives_box_pack_start(LIVES_BOX(dialog_vbox), label, FALSE, FALSE, widget_opts.packing_height);
1318 
1320  lives_toggle_button_set_active(LIVES_TOGGLE_BUTTON(radiobutton), TRUE);
1321  }
1322 
1323  add_fill_to_box(LIVES_BOX(dialog_vbox));
1324 
1326  lives_dialog_add_button_from_stock(LIVES_DIALOG(dialog), NULL,
1327  _("Set Quota Limits (Optional)"), LIVES_RESPONSE_SHOW_DETAILS);
1329 
1330  lives_dialog_add_button_from_stock(LIVES_DIALOG(dialog), LIVES_STOCK_GO_FORWARD,
1331  _("Finish"), LIVES_RESPONSE_OK);
1332 
1333  /* lives_button_grab_default_special(okbutton); */
1334  /* lives_widget_grab_focus(okbutton); */
1335 
1337  lives_widget_show_now(dialog);
1338 
1339  wid = lives_strdup_printf("0x%08lx", (uint64_t)LIVES_XWINDOW_XID(lives_widget_get_xwindow(dialog)));
1340  if (!wid || !activate_x11_window(wid)) lives_window_set_keep_above(LIVES_WINDOW(dialog), TRUE);
1341 
1342  if (mainw->splash_window) {
1344  }
1345 
1346  resp = lives_dialog_run(LIVES_DIALOG(dialog));
1347  if (resp == LIVES_RESPONSE_SHOW_DETAILS) prefs->show_disk_quota = TRUE;
1348  else prefs->show_disk_quota = FALSE;
1349 
1350  if (lives_toggle_button_get_active(LIVES_TOGGLE_BUTTON(radiobutton)))
1352 
1354 
1355  lives_widget_destroy(dialog);
1356  if (mainw->splash_window) {
1358  }
1359 }
1360 
1361 
1362 void on_troubleshoot_activate(LiVESMenuItem * menuitem, livespointer user_data) {do_startup_tests(TRUE);}
1363 
1364 
1365 static char *explain_missing(const char *exe) {
1366  char *pt2, *pt1 = lives_strdup_printf(_("\t'%s' was not found on your system.\n"
1367  "Installation is recommended as it provides the following features\n\t- "), exe);
1368  if (!lives_strcmp(exe, EXEC_FILE)) pt2 = (_("Enables easier identification of file types,\n\n"));
1369  else if (!lives_strcmp(exe, EXEC_GZIP)) pt2 = (_("Enables reduction in file size for some files,\n\n"));
1370  else if (!lives_strcmp(exe, EXEC_DU)) pt2 = (_("Enables measuring of disk space used,\n\n"));
1371  else if (!lives_strcmp(exe, EXEC_FFPROBE)) pt2 = (_("Assists in the identification of video clips\n\n"));
1372  else if (!lives_strcmp(exe, EXEC_IDENTIFY)) pt2 = (_("Assists in the identification of image files\n\n"));
1373  else if (!lives_strcmp(exe, EXEC_CONVERT)) pt2 = (_("Required for many rendered effects in the clip editor.\n\n"));
1374  else if (!lives_strcmp(exe, EXEC_COMPOSITE)) pt2 = (_("Enables clip merging in the clip editor.\n\n"));
1375  else if (!lives_strcmp(exe, EXEC_PYTHON)) pt2 = (_("Allows use of some additional encoder plugins\n\n"));
1376  else if (!lives_strcmp(exe, EXEC_MD5SUM)) pt2 = (_("Allows checking for file changes, "
1377  "enabling additional files to be cached in memory.\n\n"));
1378  else if (!lives_strcmp(exe, EXEC_YOUTUBE_DL)) pt2 = (_("Enables download and import of files from "
1379  "Youtube and other sites.\n\n"));
1380  else if (!lives_strcmp(exe, EXEC_XWININFO)) pt2 = (_("Enables identification of external windows "
1381  "so that they can be recorded.\n\n"));
1382  else {
1383  lives_free(pt1);
1384  pt1 = lives_strdup_printf(_("\t'%s' was not found on your system.\n"
1385  "Installation is optional, but may enable additional features\n\t- "), exe);
1386  if (!lives_strcmp(exe, EXEC_XDOTOOL)) pt2 = (_("Enables adjustment of windows within the desktop,\n\n"));
1387  else return lives_strdup_free(pt1, "");
1388  }
1389  return lives_concat(pt1, pt2);
1390 }
1391 
1392 
1393 #define ADD_TO_TEXT(what, exec) if (!capable->has_##what) { \
1394  text = lives_concat(text, explain_missing(exec)) ;\
1395 }
1396 
1397 void explain_missing_activate(LiVESMenuItem * menuitem, livespointer user_data) {
1398  char *title = (_("What is missing ?")), *text = lives_strdup("");
1399 
1401 
1402  ADD_TO_TEXT(file, EXEC_FILE);
1403  ADD_TO_TEXT(du, EXEC_DU);
1404  ADD_TO_TEXT(identify, EXEC_IDENTIFY);
1405  ADD_TO_TEXT(md5sum, EXEC_MD5SUM);
1406  ADD_TO_TEXT(ffprobe, EXEC_FFPROBE);
1407  ADD_TO_TEXT(convert, EXEC_CONVERT);
1408  ADD_TO_TEXT(composite, EXEC_COMPOSITE);
1409  ADD_TO_TEXT(python, EXEC_PYTHON);
1410  ADD_TO_TEXT(gzip, EXEC_GZIP);
1411  ADD_TO_TEXT(youtube_dl, EXEC_YOUTUBE_DL);
1412  ADD_TO_TEXT(xwininfo, EXEC_XWININFO);
1413  if (!(*text)) {
1414  lives_free(title); lives_free(text);
1415  do_info_dialog(_("All optional components located\n"));
1416  return;
1417  }
1418  text = lives_concat(text, (_("\n\nIf you DO have any of these missing components, please ensure they are "
1419  "located in your $PATH before restarting LiVES")));
1421  create_text_window(title, text, NULL, TRUE);
1423  lives_free(title);
1424  lives_free(text);
1425 }
1426 #undef ADD_TO_TEXT
1427 
PREF_STARTUP_INTERFACE
#define PREF_STARTUP_INTERFACE
Definition: preferences.h:966
lives_format_storage_space_string
char * lives_format_storage_space_string(uint64_t space)
Definition: machinestate.c:664
lives_freep
boolean lives_freep(void **ptr)
Definition: utils.c:1411
is_writeable_dir
boolean is_writeable_dir(const char *dir)
Definition: utils.c:5701
do_startup_tests
boolean do_startup_tests(boolean tshoot)
Definition: startup.c:767
lives_source_remove
WIDGET_HELPER_GLOBAL_INLINE boolean lives_source_remove(uint32_t handle)
Definition: widget-helper.c:7361
EXEC_PERL
#define EXEC_PERL
Definition: mainwindow.h:385
activate_x11_window
boolean activate_x11_window(const char *wid)
Definition: machinestate.c:2998
EXEC_PYTHON
#define EXEC_PYTHON
Definition: mainwindow.h:413
LIVES_DEF_WORK_NAME
#define LIVES_DEF_WORK_NAME
Definition: mainwindow.h:616
LIVES_LOCAL_INLINE
#define LIVES_LOCAL_INLINE
Definition: main.h:246
widget_opts_t::transient
LiVESWindow * transient
transient window for dialogs, if NULL then use the default (READ / WRITE)
Definition: widget-helper.h:1423
EXEC_IDENTIFY
#define EXEC_IDENTIFY
Definition: mainwindow.h:395
rte_window.h
check_dir_access
boolean check_dir_access(const char *dir, boolean leaveit)
Definition: utils.c:4542
lives_dialog_add_button_from_stock
LiVESWidget * lives_dialog_add_button_from_stock(LiVESDialog *dialog, const char *stock_id, const char *label, int response_id)
Definition: widget-helper.c:9892
lives_free
#define lives_free
Definition: machinestate.h:52
capability::ds_tot
int64_t ds_tot
Definition: main.h:609
on_troubleshoot_activate
void on_troubleshoot_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: startup.c:1362
lives_label_get_mnemonic_widget
WIDGET_HELPER_GLOBAL_INLINE LiVESWidget * lives_label_get_mnemonic_widget(LiVESLabel *label)
Definition: widget-helper.c:6095
do_file_notfound_dialog
LiVESResponseType do_file_notfound_dialog(const char *detail, const char *filename)
Definition: dialogs.c:3513
lives_widget_add_accelerator
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)
Definition: widget-helper.c:2953
choose_file
char * choose_file(const char *dir, const char *fname, char **const filt, LiVESFileChooserAction act, const char *title, LiVESWidget *extra_widget)
Definition: interface.c:4080
mainwindow::is_ready
boolean is_ready
Definition: mainwindow.h:787
_entryw::dialog
LiVESWidget * dialog
Definition: interface.h:94
EXEC_MPV
#define EXEC_MPV
Definition: mainwindow.h:388
lives_cp_recursive
int lives_cp_recursive(const char *from, const char *to, boolean incl_dir)
Definition: utils.c:4423
lives_get_audio_file_name
LIVES_GLOBAL_INLINE char * lives_get_audio_file_name(int fnum)
Definition: audio.c:55
mt_desensitise
void mt_desensitise(lives_mt *mt)
Definition: multitrack.c:16979
lives_widget_destroy
LIVES_GLOBAL_INLINE boolean lives_widget_destroy(LiVESWidget *widget)
Definition: widget-helper.c:1553
do_yesno_dialogf
boolean do_yesno_dialogf(const char *fmt,...)
Definition: dialogs.c:635
lives_widget_grab_focus
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_grab_focus(LiVESWidget *widget)
Definition: widget-helper.c:4712
lives_sync
void lives_sync(int times)
Definition: utils.c:115
_prefs::workdir
char workdir[PATH_MAX]
kept in locale encoding
Definition: preferences.h:61
DEF_KEYMAP_FILE2_OLD
#define DEF_KEYMAP_FILE2_OLD
Definition: rte_window.h:19
filename_toolong_error
void filename_toolong_error(const char *fname, const char *ftype, size_t max, boolean can_retry)
Definition: startup.c:291
lives_dialog_get_content_area
WIDGET_HELPER_GLOBAL_INLINE LiVESWidget * lives_dialog_get_content_area(LiVESDialog *dialog)
Definition: widget-helper.c:2479
capability::has_pulse_audio
lives_checkstatus_t has_pulse_audio
Definition: main.h:523
PREF_WORKING_DIR_OLD
#define PREF_WORKING_DIR_OLD
Definition: preferences.h:906
do_audio_choice_dialog
boolean do_audio_choice_dialog(short startup_phase)
Definition: startup.c:500
mainwindow::current_file
int current_file
Definition: mainwindow.h:727
mainwindow::splash_window
LiVESWidget * splash_window
splash window
Definition: mainwindow.h:1595
lives_cp
int lives_cp(const char *from, const char *to)
Definition: utils.c:4414
EXEC_XWININFO
#define EXEC_XWININFO
Definition: mainwindow.h:422
cfile
#define cfile
Definition: main.h:1833
lives_widget_hide
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_hide(LiVESWidget *widget)
Definition: widget-helper.c:1514
ADD_TO_TEXT
#define ADD_TO_TEXT(what, exec)
Definition: startup.c:1393
DEF_KEYMAP_FILE3_OLD
#define DEF_KEYMAP_FILE3_OLD
Definition: rte_window.h:20
mainwindow::vol_label
LiVESWidget * vol_label
Definition: mainwindow.h:1365
lives_table_attach
WIDGET_HELPER_GLOBAL_INLINE boolean lives_table_attach(LiVESTable *table, LiVESWidget *child, uint32_t left, uint32_t right, uint32_t top, uint32_t bottom, LiVESAttachOptions xoptions, LiVESAttachOptions yoptions, uint32_t xpad, uint32_t ypad)
Definition: widget-helper.c:7035
EXEC_GZIP
#define EXEC_GZIP
Definition: mainwindow.h:407
LIVES_RESOURCES_DIR
#define LIVES_RESOURCES_DIR
Definition: mainwindow.h:617
lives_standard_dialog_new
LiVESWidget * lives_standard_dialog_new(const char *title, boolean add_std_buttons, int width, int height)
Definition: widget-helper.c:9971
do_startup_interface_query
void do_startup_interface_query(void)
Definition: startup.c:1276
prefs
_prefs * prefs
Definition: preferences.h:847
lives_strcmp
LIVES_GLOBAL_INLINE boolean lives_strcmp(const char *st1, const char *st2)
returns FALSE if strings match
Definition: machinestate.c:1506
_prefs::backend
char backend[PATH_MAX *4]
Definition: preferences.h:411
_prefs::audio_player
short audio_player
Definition: preferences.h:40
lives_dialog_run
WIDGET_HELPER_GLOBAL_INLINE LiVESResponseType lives_dialog_run(LiVESDialog *dialog)
Definition: widget-helper.c:1783
LIVES_FILE_EXT_JPG
#define LIVES_FILE_EXT_JPG
Definition: mainwindow.h:488
dir_toolong_error
void dir_toolong_error(const char *dirname, const char *dirtype, size_t max, boolean can_retry)
Definition: startup.c:304
lives_open3
int lives_open3(const char *pathname, int flags, mode_t mode)
Definition: utils.c:94
DEF_KEYMAP_FILE_OLD
#define DEF_KEYMAP_FILE_OLD
Definition: rte_window.h:18
create_text_window
text_window * create_text_window(const char *title, const char *text, LiVESTextBuffer *textbuffer, boolean add_buttons)
Definition: interface.c:1390
set_string_pref_priority
int set_string_pref_priority(const char *key, const char *value)
Definition: preferences.c:298
do_info_dialog
LIVES_GLOBAL_INLINE LiVESResponseType do_info_dialog(const char *text)
Definition: dialogs.c:787
_prefs::image_type
char image_type[16]
Definition: preferences.h:77
_prefs::backend_sync
char backend_sync[PATH_MAX *4]
Definition: preferences.h:410
lives_button_grab_default_special
boolean lives_button_grab_default_special(LiVESWidget *button)
Definition: widget-helper.c:7587
lives_widget_get_xwindow
WIDGET_HELPER_GLOBAL_INLINE LiVESXWindow * lives_widget_get_xwindow(LiVESWidget *widget)
Definition: widget-helper.c:4759
add_fill_to_box
LiVESWidget * add_fill_to_box(LiVESBox *box)
Definition: widget-helper.c:12377
STOCK_ICONS_DIR
#define STOCK_ICONS_DIR
Definition: mainwindow.h:613
build_init_config
boolean build_init_config(const char *config_datadir, boolean prompt)
Definition: startup.c:83
_future_prefs::startup_interface
int startup_interface
Definition: preferences.h:825
ensure_isdir
boolean ensure_isdir(char *fname)
Definition: utils.c:3346
FILESEL_TYPE_KEY
#define FILESEL_TYPE_KEY
Definition: widget-helper.h:1493
do_error_dialog
LIVES_GLOBAL_INLINE LiVESResponseType do_error_dialog(const char *text)
Definition: dialogs.c:749
lives_window_add_accel_group
WIDGET_HELPER_GLOBAL_INLINE boolean lives_window_add_accel_group(LiVESWindow *window, LiVESAccelGroup *group)
Definition: widget-helper.c:2968
TRUE
#define TRUE
Definition: videoplugin.h:59
IMG_TYPE_PNG
@ IMG_TYPE_PNG
Definition: main.h:777
EXEC_FFPROBE
#define EXEC_FFPROBE
Definition: mainwindow.h:396
migrate_config
boolean migrate_config(const char *old_vhash, const char *newconfigfile)
Definition: startup.c:20
do_dir_perm_error
LiVESResponseType do_dir_perm_error(const char *dir_name, boolean allow_cancel)
Definition: dialogs.c:4247
capability::has_mpv
lives_checkstatus_t has_mpv
Definition: main.h:513
THREADVAR
#define THREADVAR(var)
Definition: machinestate.h:531
lives_table_new
WIDGET_HELPER_GLOBAL_INLINE LiVESWidget * lives_table_new(uint32_t rows, uint32_t cols, boolean homogeneous)
Definition: widget-helper.c:6931
mainwindow::cancelled
volatile lives_cancel_t cancelled
Definition: mainwindow.h:798
mainwindow::ds_status
lives_storage_status_t ds_status
Definition: mainwindow.h:1750
is_realtime_aplayer
#define is_realtime_aplayer(ptype)
Definition: audio.h:236
get_frame_count
int get_frame_count(int idx, int xsize)
sets mainw->files[idx]->frames with current framecount
Definition: utils.c:3109
widget_opts_t::last_label
LiVESWidget * last_label
commonly adjusted values //////
Definition: widget-helper.h:1406
assist
LiVESWidget * assist
Definition: startup.c:16
DATA_DIR
#define DATA_DIR
Definition: mainwindow.h:590
capable
capability * capable
Definition: main.h:627
lives_toggle_button_get_active
WIDGET_HELPER_GLOBAL_INLINE boolean lives_toggle_button_get_active(LiVESToggleButton *button)
Definition: widget-helper.c:4472
skip_test
LIVES_LOCAL_INLINE boolean skip_test(LiVESWidget *table, int row, char *ftext)
Definition: startup.c:758
LIVES_DEF_CONFIG_DATADIR_OLD
#define LIVES_DEF_CONFIG_DATADIR_OLD
pre 3.2.0
Definition: mainwindow.h:611
d_print
void d_print(const char *fmt,...)
Definition: utils.c:2542
close_current_file
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
EXEC_MPLAYER2
#define EXEC_MPLAYER2
Definition: mainwindow.h:387
EXEC_COMPOSITE
#define EXEC_COMPOSITE
Definition: mainwindow.h:394
_prefs::prefix_dir
char prefix_dir[PATH_MAX]
Definition: preferences.h:74
capability::ds_free
int64_t ds_free
Definition: main.h:609
PREF_VIDEO_OPEN_COMMAND
#define PREF_VIDEO_OPEN_COMMAND
Definition: preferences.h:924
lives_make_writeable_dir
boolean lives_make_writeable_dir(const char *newdir)
Definition: utils.c:5721
_prefs::video_open_command
char video_open_command[PATH_MAX *2]
Definition: preferences.h:170
EXEC_YOUTUBE_DL
#define EXEC_YOUTUBE_DL
Definition: mainwindow.h:399
lives_mv
int lives_mv(const char *from, const char *to)
Definition: utils.c:4446
mainwindow::recaudio_submenu
LiVESWidget * recaudio_submenu
Definition: mainwindow.h:1194
AUDIO_PLAYER_JACK
#define AUDIO_PLAYER_JACK
Definition: preferences.h:49
LIVES_DEVICEMAP_DIR
#define LIVES_DEVICEMAP_DIR
Definition: mainwindow.h:615
lives_standard_label_new
LiVESWidget * lives_standard_label_new(const char *text)
Definition: widget-helper.c:8601
DEF_KEYMAP_FILE3
#define DEF_KEYMAP_FILE3
Definition: rte_window.h:16
mainwindow::dsu_valid
boolean dsu_valid
Definition: mainwindow.h:1791
lives_rmglob
int lives_rmglob(const char *files)
Definition: utils.c:4404
_entryw::entry
LiVESWidget * entry
Definition: interface.h:95
interface.h
_prefs::image_ext
char image_ext[16]
Definition: preferences.h:78
PREF_AUDIO_PLAYER
#define PREF_AUDIO_PLAYER
Definition: preferences.h:910
capability::has_mplayer
lives_checkstatus_t has_mplayer
Definition: main.h:511
get_resource
LIVES_LOCAL_INLINE char * get_resource(char *fname)
Definition: startup.c:762
capability::mountpoint
char * mountpoint
utf-8
Definition: main.h:610
get_location
void get_location(const char *exe, char *val, int maxlen)
Definition: utils.c:3407
LIVES_EXPAND_DEFAULT_HEIGHT
#define LIVES_EXPAND_DEFAULT_HEIGHT
Definition: widget-helper.h:1312
EXEC_CONVERT
#define EXEC_CONVERT
Definition: mainwindow.h:393
explain_missing_activate
void explain_missing_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: startup.c:1397
image_ext_to_lives_image_type
const char * image_ext_to_lives_image_type(const char *img_ext)
Definition: utils.c:3039
LIVES_DEF_CONFIG_FILE_OLD
#define LIVES_DEF_CONFIG_FILE_OLD
pre 3.2.0
Definition: mainwindow.h:610
capability::has_file
lives_checkstatus_t has_file
Definition: main.h:506
CANCEL_NONE
@ CANCEL_NONE
no cancel
Definition: main.h:701
widget_opts_t::packing_height
int packing_height
vertical pixels between widgets
Definition: widget-helper.h:1411
sget_file_size
off_t sget_file_size(const char *name)
Definition: machinestate.c:962
close_file
void close_file(int current_file, boolean tshoot)
Definition: startup.c:317
lives_hbox_new
WIDGET_HELPER_GLOBAL_INLINE LiVESWidget * lives_hbox_new(boolean homogeneous, int spacing)
Definition: widget-helper.c:3253
check_for_executable
boolean check_for_executable(lives_checkstatus_t *cap, const char *exec)
Definition: utils.c:3434
close_temp_handle
int close_temp_handle(int new_clip)
close cfile and switch to new clip (may be -1)
Definition: saveplay.c:3498
LIVES_TEST_VIDEO_NAME
#define LIVES_TEST_VIDEO_NAME
Definition: startup.h:10
set_int_pref
int set_int_pref(const char *key, int value)
Definition: preferences.c:329
lives_strdup_printf
#define lives_strdup_printf(fmt,...)
Definition: support.c:27
lives_rmdir
int lives_rmdir(const char *dir, boolean force)
Definition: utils.c:4366
lives_calloc
#define lives_calloc
Definition: machinestate.h:67
PREF_WORKING_DIR
#define PREF_WORKING_DIR
Definition: preferences.h:905
_prefs::show_disk_quota
boolean show_disk_quota
Definition: preferences.h:485
EXEC_FILE
#define EXEC_FILE
Definition: mainwindow.h:398
LIVES_IMAGE_TYPE_JPEG
#define LIVES_IMAGE_TYPE_JPEG
Definition: mainwindow.h:479
get_mountpoint_for
char * get_mountpoint_for(const char *dir)
Definition: machinestate.c:1030
get_ds_free
uint64_t get_ds_free(const char *dir)
Definition: machinestate.c:776
LIVES_MAIN_WINDOW_WIDGET
#define LIVES_MAIN_WINDOW_WIDGET
Definition: mainwindow.h:188
do_no_mplayer_sox_error
LIVES_GLOBAL_INLINE void do_no_mplayer_sox_error(void)
Definition: dialogs.c:3014
_entryw
Definition: interface.h:93
EXEC_MPLAYER
#define EXEC_MPLAYER
Definition: mainwindow.h:386
lives_strlen
LIVES_GLOBAL_INLINE size_t lives_strlen(const char *s)
Definition: machinestate.c:1468
future_prefs
_future_prefs * future_prefs
Definition: preferences.h:848
lives_widget_set_sensitive
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_set_sensitive(LiVESWidget *widget, boolean state)
Definition: widget-helper.c:1477
lives_accel_group_new
WIDGET_HELPER_GLOBAL_INLINE LiVESAccelGroup * lives_accel_group_new(void)
Definition: widget-helper.c:2915
capability::home_dir
char home_dir[PATH_MAX]
home directory - default location for config file - locale encoding
Definition: main.h:544
fail_test
LIVES_LOCAL_INLINE boolean fail_test(LiVESWidget *table, int row, char *ftext)
Definition: startup.c:753
mainwindow::multitrack
lives_mt * multitrack
holds a pointer to the entire multitrack environment; NULL in Clip Edit mode
Definition: mainwindow.h:1087
lives_window_set_keep_above
WIDGET_HELPER_GLOBAL_INLINE boolean lives_window_set_keep_above(LiVESWindow *window, boolean set)
Definition: widget-helper.c:2709
mainwindow::has_session_workdir
boolean has_session_workdir
Definition: mainwindow.h:1659
capability::backend_path
char backend_path[PATH_MAX]
Definition: main.h:546
LIVES_IMAGE_TYPE_PNG
#define LIVES_IMAGE_TYPE_PNG
Definition: mainwindow.h:480
mainwindow::suppress_dprint
boolean suppress_dprint
tidy up, e.g. by blocking "switched to file..." and "closed file..." messages
Definition: mainwindow.h:1537
lives_image_new_from_stock
WIDGET_HELPER_GLOBAL_INLINE LiVESWidget * lives_image_new_from_stock(const char *stock_id, LiVESIconSize size)
Definition: widget-helper.c:2412
capability::has_mplayer2
lives_checkstatus_t has_mplayer2
Definition: main.h:512
main.h
AUDIO_PLAYER_SOX
#define AUDIO_PLAYER_SOX
Definition: preferences.h:48
AUD_PLAYER_SOX
#define AUD_PLAYER_SOX
Definition: preferences.h:42
DEF_KEYMAP_FILE2
#define DEF_KEYMAP_FILE2
Definition: rte_window.h:15
LIVES_EXPAND_DEFAULT
#define LIVES_EXPAND_DEFAULT
Definition: widget-helper.h:1314
do_workdir_query
boolean do_workdir_query(void)
Definition: startup.c:413
capability::has_jackd
lives_checkstatus_t has_jackd
Definition: main.h:522
lives_widget_show_now
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_show_now(LiVESWidget *widget)
Definition: widget-helper.c:1544
MAX_SET_NAME_LEN
#define MAX_SET_NAME_LEN
sets
Definition: mainwindow.h:748
capability::has_sox_sox
lives_checkstatus_t has_sox_sox
Definition: main.h:509
_prefs::sleep_time
int sleep_time
Definition: preferences.h:176
mainw
mainwindow * mainw
Definition: main.c:103
capability::ds_used
int64_t ds_used
Definition: main.h:609
do_warning_dialogf
boolean do_warning_dialogf(const char *fmt,...)
Definition: dialogs.c:551
check_workdir_valid
LiVESResponseType check_workdir_valid(char **pdirname, LiVESDialog *dialog, boolean fullcheck)
Definition: startup.c:329
AUDIO_PLAYER_PULSE
#define AUDIO_PLAYER_PULSE
used in pref and for external players (e.g -ao pulse, -aplayer pulse)
Definition: preferences.h:51
lives_kill_subprocesses
void lives_kill_subprocesses(const char *dirname, boolean kill_parent)
Definition: utils.c:4516
lives_container_add
WIDGET_HELPER_GLOBAL_INLINE boolean lives_container_add(LiVESContainer *container, LiVESWidget *widget)
Definition: widget-helper.c:4929
_prefs::startup_interface
int startup_interface
Definition: preferences.h:336
lives_system
int lives_system(const char *com, boolean allow_error)
Definition: utils.c:145
lives_widget_show_all
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_show_all(LiVESWidget *widget)
Definition: widget-helper.c:1523
capability::has_sox_play
lives_checkstatus_t has_sox_play
Definition: main.h:508
do_abort_retry_dialog
LIVES_GLOBAL_INLINE LiVESResponseType do_abort_retry_dialog(const char *text)
Definition: dialogs.c:714
EXEC_DU
#define EXEC_DU
Definition: mainwindow.h:408
do_yesno_dialog
boolean do_yesno_dialog(const char *text)
Definition: dialogs.c:655
lives_toggle_button_set_active
WIDGET_HELPER_GLOBAL_INLINE boolean lives_toggle_button_set_active(LiVESToggleButton *button, boolean active)
Definition: widget-helper.c:4483
widget_opts
widget_opts_t widget_opts
Definition: widget-helper.h:1442
lives_entry_get_text
WIDGET_HELPER_GLOBAL_INLINE const char * lives_entry_get_text(LiVESEntry *entry)
Definition: widget-helper.c:6203
PATH_MAX
#define PATH_MAX
Definition: main.h:255
widget_opts_t::expand
lives_expand_t expand
how much space to apply between widgets
Definition: widget-helper.h:1408
LIVES_DIR_SEP
#define LIVES_DIR_SEP
Definition: main.h:197
AUD_PLAYER_PULSE
#define AUD_PLAYER_PULSE
Definition: preferences.h:44
mt_sensitise
void mt_sensitise(lives_mt *mt)
Definition: multitrack.c:17052
AUD_PLAYER_JACK
#define AUD_PLAYER_JACK
Definition: preferences.h:43
lives_write
ssize_t lives_write(int fd, livesconstpointer buf, ssize_t count, boolean allow_fail)
capability::has_convert
lives_checkstatus_t has_convert
Definition: main.h:514
do_dir_notfound_dialog
LiVESResponseType do_dir_notfound_dialog(const char *detail, const char *dirname)
Definition: dialogs.c:3509
lives_widget_process_updates
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_process_updates(LiVESWidget *widget)
Definition: widget-helper.c:1658
do_abort_cancel_retry_dialog
LIVES_GLOBAL_INLINE LiVESResponseType do_abort_cancel_retry_dialog(const char *text)
Definition: dialogs.c:708
LIVES_DIR_SELECTION_CREATE_FOLDER
#define LIVES_DIR_SELECTION_CREATE_FOLDER
Definition: interface.h:185
startup_message_fatal
void startup_message_fatal(char *msg)
Definition: main.c:4962
_prefs::configfile
char configfile[PATH_MAX]
kept in locale encoding (config settings) [default ~/.local/config/lives)
Definition: preferences.h:63
create_rename_dialog
_entryw * create_rename_dialog(int type)
Definition: interface.c:2792
_prefs::config_datadir
char config_datadir[PATH_MAX]
kept in locale encoding (general config files) (default ~/.local/share/lives)
Definition: preferences.h:64
mainwindow::vol_toolitem
LiVESWidget * vol_toolitem
Definition: mainwindow.h:1364
LIVES_FILE_EXT_PNG
#define LIVES_FILE_EXT_PNG
Definition: mainwindow.h:487
LIVES_STORAGE_STATUS_UNKNOWN
@ LIVES_STORAGE_STATUS_UNKNOWN
Definition: machinestate.h:182
_future_prefs::workdir
char workdir[PATH_MAX]
Definition: preferences.h:799
EXEC_MD5SUM
#define EXEC_MD5SUM
Definition: mainwindow.h:405
FALSE
#define FALSE
Definition: videoplugin.h:60
LIVES_EXPAND_EXTRA_WIDTH
#define LIVES_EXPAND_EXTRA_WIDTH
Definition: widget-helper.h:1316
capability::grep_cmd
char grep_cmd[PATH_MAX]
Definition: main.h:560
mt_idle_add
uint32_t mt_idle_add(lives_mt *mt)
Definition: multitrack.c:901
_
#define _(String)
Definition: support.h:44
dirs_equal
boolean dirs_equal(const char *dira, const char *dirb)
Definition: utils.c:3390
do_error_dialogf
LiVESResponseType do_error_dialogf(const char *fmt,...)
Definition: dialogs.c:735
cleanup_old_config
void cleanup_old_config(void)
Definition: startup.c:58
lives_rm
int lives_rm(const char *file)
Definition: utils.c:4395
STARTUP_MT
#define STARTUP_MT
Definition: preferences.h:339
lives_concat
LIVES_GLOBAL_INLINE char * lives_concat(char *st, char *x)
Definition: machinestate.c:1426
PREF_DEFAULT_IMAGE_TYPE
#define PREF_DEFAULT_IMAGE_TYPE
Definition: preferences.h:922
EXEC_XDOTOOL
#define EXEC_XDOTOOL
Definition: mainwindow.h:427
lives_widget_show
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_show(LiVESWidget *widget)
Definition: widget-helper.c:1505
lives_widget_context_update
boolean lives_widget_context_update(void)
Definition: widget-helper.c:11878
get_temp_handle
boolean get_temp_handle(int index)
get a temp "handle" from disk.
Definition: saveplay.c:3571
set_string_pref
int set_string_pref(const char *key, const char *value)
Definition: preferences.c:290
lives_standard_radio_button_new
LiVESWidget * lives_standard_radio_button_new(const char *labeltext, LiVESSList **rbgroup, LiVESBox *box, const char *tooltip)
Definition: widget-helper.c:9265
startup.h
lives_box_pack_start
WIDGET_HELPER_GLOBAL_INLINE boolean lives_box_pack_start(LiVESBox *box, LiVESWidget *child, boolean expand, boolean fill, uint32_t padding)
Definition: widget-helper.c:3281