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
14static boolean allpassed;
15
16LiVESWidget *assist;
17
18static uint64_t oldver = 0;
19
20boolean 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
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
83boolean 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
197 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
244static 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
276static 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
291void 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
304void 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
317void 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
329LiVESResponseType 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
413boolean do_workdir_query(void) {
414 LiVESWidget *dirbutton;
415 LiVESResponseType response;
416 char *dirname = NULL, *mp;
417 _entryw *wizard = create_rename_dialog(6);
418
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;
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, "??????")) {
450 capable->mountpoint = mp;
451 }
452
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
479static 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
500boolean 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
684static 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
706static 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
727static 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
753LIVES_LOCAL_INLINE boolean fail_test(LiVESWidget * table, int row, char *ftext) {
754 allpassed = FALSE;
755 return _fail_test(table, row, ftext, _("Failed"));
756}
757
758LIVES_LOCAL_INLINE boolean skip_test(LiVESWidget * table, int row, char *ftext) {
759 return _fail_test(table, row, ftext, _("Skipped"));
760}
761
763 return lives_build_filename(prefs->prefix_dir, DATA_DIR, LIVES_RESOURCES_DIR, fname, NULL);
764}
765
766
767boolean 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) {
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) {
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
1220jpgdone:
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
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) {
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 {
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) {
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
1362void on_troubleshoot_activate(LiVESMenuItem * menuitem, livespointer user_data) {do_startup_tests(TRUE);}
1363
1364
1365static 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
1397void 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
LIVES_GLOBAL_INLINE char * lives_get_audio_file_name(int fnum)
Definition: audio.c:55
#define is_realtime_aplayer(ptype)
Definition: audio.h:236
LiVESResponseType do_dir_perm_error(const char *dir_name, boolean allow_cancel)
Definition: dialogs.c:4247
LIVES_GLOBAL_INLINE void do_no_mplayer_sox_error(void)
Definition: dialogs.c:3014
boolean do_yesno_dialog(const char *text)
Definition: dialogs.c:655
LiVESResponseType do_dir_notfound_dialog(const char *detail, const char *dirname)
Definition: dialogs.c:3509
LIVES_GLOBAL_INLINE LiVESResponseType do_info_dialog(const char *text)
Definition: dialogs.c:787
LiVESResponseType do_error_dialogf(const char *fmt,...)
Definition: dialogs.c:735
LIVES_GLOBAL_INLINE LiVESResponseType do_abort_retry_dialog(const char *text)
Definition: dialogs.c:714
boolean do_yesno_dialogf(const char *fmt,...)
Definition: dialogs.c:635
LIVES_GLOBAL_INLINE LiVESResponseType do_abort_cancel_retry_dialog(const char *text)
Definition: dialogs.c:708
LiVESResponseType do_file_notfound_dialog(const char *detail, const char *filename)
Definition: dialogs.c:3513
boolean do_warning_dialogf(const char *fmt,...)
Definition: dialogs.c:551
LIVES_GLOBAL_INLINE LiVESResponseType do_error_dialog(const char *text)
Definition: dialogs.c:749
char * choose_file(const char *dir, const char *fname, char **const filt, LiVESFileChooserAction act, const char *title, LiVESWidget *extra_widget)
Definition: interface.c:4080
text_window * create_text_window(const char *title, const char *text, LiVESTextBuffer *textbuffer, boolean add_buttons)
Definition: interface.c:1390
_entryw * create_rename_dialog(int type)
Definition: interface.c:2792
#define LIVES_DIR_SELECTION_CREATE_FOLDER
Definition: interface.h:185
LIVES_GLOBAL_INLINE boolean lives_strcmp(const char *st1, const char *st2)
returns FALSE if strings match
char * get_mountpoint_for(const char *dir)
uint64_t get_ds_free(const char *dir)
Definition: machinestate.c:776
boolean activate_x11_window(const char *wid)
LIVES_GLOBAL_INLINE size_t lives_strlen(const char *s)
off_t sget_file_size(const char *name)
Definition: machinestate.c:962
char * lives_format_storage_space_string(uint64_t space)
Definition: machinestate.c:664
LIVES_GLOBAL_INLINE char * lives_concat(char *st, char *x)
#define lives_calloc
Definition: machinestate.h:67
@ LIVES_STORAGE_STATUS_UNKNOWN
Definition: machinestate.h:182
#define THREADVAR(var)
Definition: machinestate.h:531
#define lives_free
Definition: machinestate.h:52
void startup_message_fatal(char *msg)
Definition: main.c:4962
mainwindow * mainw
Definition: main.c:103
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
int get_frame_count(int idx, int xsize)
sets mainw->files[idx]->frames with current framecount
Definition: utils.c:3109
ssize_t lives_write(int fd, livesconstpointer buf, ssize_t count, boolean allow_fail)
void lives_sync(int times)
Definition: utils.c:115
boolean get_temp_handle(int index)
get a temp "handle" from disk.
Definition: saveplay.c:3571
boolean ensure_isdir(char *fname)
Definition: utils.c:3346
boolean lives_make_writeable_dir(const char *newdir)
Definition: utils.c:5721
const char * image_ext_to_lives_image_type(const char *img_ext)
Definition: utils.c:3039
int lives_open3(const char *pathname, int flags, mode_t mode)
Definition: utils.c:94
boolean dirs_equal(const char *dira, const char *dirb)
Definition: utils.c:3390
#define LIVES_LOCAL_INLINE
Definition: main.h:246
int lives_system(const char *com, boolean allow_error)
Definition: utils.c:145
void lives_kill_subprocesses(const char *dirname, boolean kill_parent)
Definition: utils.c:4516
boolean is_writeable_dir(const char *dir)
Definition: utils.c:5701
int lives_cp(const char *from, const char *to)
Definition: utils.c:4414
int close_temp_handle(int new_clip)
close cfile and switch to new clip (may be -1)
Definition: saveplay.c:3498
int lives_rmglob(const char *files)
Definition: utils.c:4404
int lives_mv(const char *from, const char *to)
Definition: utils.c:4446
int lives_rmdir(const char *dir, boolean force)
Definition: utils.c:4366
void get_location(const char *exe, char *val, int maxlen)
Definition: utils.c:3407
int lives_cp_recursive(const char *from, const char *to, boolean incl_dir)
Definition: utils.c:4423
int lives_rm(const char *file)
Definition: utils.c:4395
capability * capable
Definition: main.h:627
#define cfile
Definition: main.h:1833
void d_print(const char *fmt,...)
Definition: utils.c:2542
boolean check_dir_access(const char *dir, boolean leaveit)
Definition: utils.c:4542
@ IMG_TYPE_PNG
Definition: main.h:777
boolean check_for_executable(lives_checkstatus_t *cap, const char *exec)
Definition: utils.c:3434
#define PATH_MAX
Definition: main.h:255
#define LIVES_DIR_SEP
Definition: main.h:197
boolean lives_freep(void **ptr)
Definition: utils.c:1411
@ CANCEL_NONE
no cancel
Definition: main.h:701
#define EXEC_XDOTOOL
Definition: mainwindow.h:427
#define STOCK_ICONS_DIR
Definition: mainwindow.h:613
#define LIVES_IMAGE_TYPE_JPEG
Definition: mainwindow.h:479
#define EXEC_DU
Definition: mainwindow.h:408
#define EXEC_GZIP
Definition: mainwindow.h:407
#define EXEC_FILE
Definition: mainwindow.h:398
#define DATA_DIR
Definition: mainwindow.h:590
#define LIVES_MAIN_WINDOW_WIDGET
Definition: mainwindow.h:188
#define LIVES_RESOURCES_DIR
Definition: mainwindow.h:617
#define EXEC_IDENTIFY
Definition: mainwindow.h:395
#define EXEC_FFPROBE
Definition: mainwindow.h:396
#define LIVES_DEVICEMAP_DIR
Definition: mainwindow.h:615
#define EXEC_YOUTUBE_DL
Definition: mainwindow.h:399
#define LIVES_FILE_EXT_PNG
Definition: mainwindow.h:487
#define EXEC_MPLAYER2
Definition: mainwindow.h:387
#define EXEC_PERL
Definition: mainwindow.h:385
#define MAX_SET_NAME_LEN
sets
Definition: mainwindow.h:748
#define LIVES_DEF_CONFIG_DATADIR_OLD
pre 3.2.0
Definition: mainwindow.h:611
#define EXEC_XWININFO
Definition: mainwindow.h:422
#define LIVES_DEF_WORK_NAME
Definition: mainwindow.h:616
#define EXEC_PYTHON
Definition: mainwindow.h:413
#define LIVES_IMAGE_TYPE_PNG
Definition: mainwindow.h:480
#define LIVES_DEF_CONFIG_FILE_OLD
pre 3.2.0
Definition: mainwindow.h:610
#define EXEC_MPV
Definition: mainwindow.h:388
#define LIVES_FILE_EXT_JPG
Definition: mainwindow.h:488
#define EXEC_MD5SUM
Definition: mainwindow.h:405
#define EXEC_MPLAYER
Definition: mainwindow.h:386
#define EXEC_CONVERT
Definition: mainwindow.h:393
#define EXEC_COMPOSITE
Definition: mainwindow.h:394
uint32_t mt_idle_add(lives_mt *mt)
Definition: multitrack.c:901
void mt_desensitise(lives_mt *mt)
Definition: multitrack.c:16979
void mt_sensitise(lives_mt *mt)
Definition: multitrack.c:17052
int set_string_pref(const char *key, const char *value)
Definition: preferences.c:290
int set_string_pref_priority(const char *key, const char *value)
Definition: preferences.c:298
int set_int_pref(const char *key, int value)
Definition: preferences.c:329
#define PREF_WORKING_DIR_OLD
Definition: preferences.h:906
_prefs * prefs
Definition: preferences.h:847
#define PREF_AUDIO_PLAYER
Definition: preferences.h:910
#define AUD_PLAYER_SOX
Definition: preferences.h:42
#define PREF_WORKING_DIR
Definition: preferences.h:905
#define AUDIO_PLAYER_JACK
Definition: preferences.h:49
#define AUDIO_PLAYER_SOX
Definition: preferences.h:48
#define PREF_STARTUP_INTERFACE
Definition: preferences.h:966
#define AUDIO_PLAYER_PULSE
used in pref and for external players (e.g -ao pulse, -aplayer pulse)
Definition: preferences.h:51
#define PREF_DEFAULT_IMAGE_TYPE
Definition: preferences.h:922
#define PREF_VIDEO_OPEN_COMMAND
Definition: preferences.h:924
#define STARTUP_MT
Definition: preferences.h:339
#define AUD_PLAYER_JACK
Definition: preferences.h:43
_future_prefs * future_prefs
Definition: preferences.h:848
#define AUD_PLAYER_PULSE
Definition: preferences.h:44
#define DEF_KEYMAP_FILE3_OLD
Definition: rte_window.h:20
#define DEF_KEYMAP_FILE_OLD
Definition: rte_window.h:18
#define DEF_KEYMAP_FILE2_OLD
Definition: rte_window.h:19
#define DEF_KEYMAP_FILE3
Definition: rte_window.h:16
#define DEF_KEYMAP_FILE2
Definition: rte_window.h:15
void cleanup_old_config(void)
Definition: startup.c:58
void filename_toolong_error(const char *fname, const char *ftype, size_t max, boolean can_retry)
Definition: startup.c:291
boolean do_startup_tests(boolean tshoot)
Definition: startup.c:767
LiVESWidget * assist
Definition: startup.c:16
void close_file(int current_file, boolean tshoot)
Definition: startup.c:317
void do_startup_interface_query(void)
Definition: startup.c:1276
LiVESResponseType check_workdir_valid(char **pdirname, LiVESDialog *dialog, boolean fullcheck)
Definition: startup.c:329
boolean migrate_config(const char *old_vhash, const char *newconfigfile)
Definition: startup.c:20
LIVES_LOCAL_INLINE boolean skip_test(LiVESWidget *table, int row, char *ftext)
Definition: startup.c:758
boolean do_workdir_query(void)
Definition: startup.c:413
void explain_missing_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: startup.c:1397
void on_troubleshoot_activate(LiVESMenuItem *menuitem, livespointer user_data)
Definition: startup.c:1362
#define ADD_TO_TEXT(what, exec)
Definition: startup.c:1393
LIVES_LOCAL_INLINE boolean fail_test(LiVESWidget *table, int row, char *ftext)
Definition: startup.c:753
boolean do_audio_choice_dialog(short startup_phase)
Definition: startup.c:500
boolean build_init_config(const char *config_datadir, boolean prompt)
Definition: startup.c:83
LIVES_LOCAL_INLINE char * get_resource(char *fname)
Definition: startup.c:762
void dir_toolong_error(const char *dirname, const char *dirtype, size_t max, boolean can_retry)
Definition: startup.c:304
#define LIVES_TEST_VIDEO_NAME
Definition: startup.h:10
LiVESWidget * entry
Definition: interface.h:95
LiVESWidget * dialog
Definition: interface.h:94
char workdir[PATH_MAX]
Definition: preferences.h:799
int startup_interface
Definition: preferences.h:825
char backend[PATH_MAX *4]
Definition: preferences.h:411
int startup_interface
Definition: preferences.h:336
char video_open_command[PATH_MAX *2]
Definition: preferences.h:170
char workdir[PATH_MAX]
kept in locale encoding
Definition: preferences.h:61
char config_datadir[PATH_MAX]
kept in locale encoding (general config files) (default ~/.local/share/lives)
Definition: preferences.h:64
char prefix_dir[PATH_MAX]
Definition: preferences.h:74
char configfile[PATH_MAX]
kept in locale encoding (config settings) [default ~/.local/config/lives)
Definition: preferences.h:63
boolean show_disk_quota
Definition: preferences.h:485
int sleep_time
Definition: preferences.h:176
char image_type[16]
Definition: preferences.h:77
char backend_sync[PATH_MAX *4]
Definition: preferences.h:410
short audio_player
Definition: preferences.h:40
char image_ext[16]
Definition: preferences.h:78
lives_checkstatus_t has_file
Definition: main.h:506
char home_dir[PATH_MAX]
home directory - default location for config file - locale encoding
Definition: main.h:544
char backend_path[PATH_MAX]
Definition: main.h:546
char grep_cmd[PATH_MAX]
Definition: main.h:560
lives_checkstatus_t has_sox_play
Definition: main.h:508
lives_checkstatus_t has_mpv
Definition: main.h:513
char * mountpoint
utf-8
Definition: main.h:610
int64_t ds_tot
Definition: main.h:609
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
lives_checkstatus_t has_sox_sox
Definition: main.h:509
lives_checkstatus_t has_jackd
Definition: main.h:522
lives_checkstatus_t has_mplayer
Definition: main.h:511
lives_checkstatus_t has_pulse_audio
Definition: main.h:523
lives_checkstatus_t has_convert
Definition: main.h:514
LiVESWidget * vol_toolitem
Definition: mainwindow.h:1364
LiVESWidget * splash_window
splash window
Definition: mainwindow.h:1595
boolean dsu_valid
Definition: mainwindow.h:1791
volatile lives_cancel_t cancelled
Definition: mainwindow.h:798
lives_storage_status_t ds_status
Definition: mainwindow.h:1750
int current_file
Definition: mainwindow.h:727
boolean is_ready
Definition: mainwindow.h:787
boolean suppress_dprint
tidy up, e.g. by blocking "switched to file..." and "closed file..." messages
Definition: mainwindow.h:1537
LiVESWidget * recaudio_submenu
Definition: mainwindow.h:1194
boolean has_session_workdir
Definition: mainwindow.h:1659
LiVESWidget * vol_label
Definition: mainwindow.h:1365
lives_mt * multitrack
holds a pointer to the entire multitrack environment; NULL in Clip Edit mode
Definition: mainwindow.h:1087
LiVESWindow * transient
transient window for dialogs, if NULL then use the default (READ / WRITE)
LiVESWidget * last_label
commonly adjusted values //////
int packing_height
vertical pixels between widgets
lives_expand_t expand
how much space to apply between widgets
#define lives_strdup_printf(fmt,...)
Definition: support.c:27
#define _(String)
Definition: support.h:44
#define TRUE
Definition: videoplugin.h:59
#define FALSE
Definition: videoplugin.h:60
WIDGET_HELPER_GLOBAL_INLINE LiVESWidget * lives_image_new_from_stock(const char *stock_id, LiVESIconSize size)
WIDGET_HELPER_GLOBAL_INLINE LiVESAccelGroup * lives_accel_group_new(void)
boolean lives_button_grab_default_special(LiVESWidget *button)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_toggle_button_get_active(LiVESToggleButton *button)
WIDGET_HELPER_GLOBAL_INLINE 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)
LiVESWidget * lives_standard_dialog_new(const char *title, boolean add_std_buttons, int width, int height)
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 LiVESWidget * lives_table_new(uint32_t rows, uint32_t cols, boolean homogeneous)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_show(LiVESWidget *widget)
WIDGET_HELPER_GLOBAL_INLINE LiVESWidget * lives_dialog_get_content_area(LiVESDialog *dialog)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_show_now(LiVESWidget *widget)
LiVESWidget * add_fill_to_box(LiVESBox *box)
LIVES_GLOBAL_INLINE boolean lives_widget_destroy(LiVESWidget *widget)
LiVESWidget * lives_dialog_add_button_from_stock(LiVESDialog *dialog, const char *stock_id, const char *label, int response_id)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_container_add(LiVESContainer *container, LiVESWidget *widget)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_toggle_button_set_active(LiVESToggleButton *button, boolean active)
WIDGET_HELPER_GLOBAL_INLINE LiVESWidget * lives_label_get_mnemonic_widget(LiVESLabel *label)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_hide(LiVESWidget *widget)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_window_set_keep_above(LiVESWindow *window, boolean set)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_widget_show_all(LiVESWidget *widget)
boolean lives_widget_context_update(void)
WIDGET_HELPER_GLOBAL_INLINE LiVESWidget * lives_hbox_new(boolean homogeneous, int spacing)
LiVESWidget * lives_standard_label_new(const char *text)
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)
WIDGET_HELPER_GLOBAL_INLINE LiVESXWindow * lives_widget_get_xwindow(LiVESWidget *widget)
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_widget_process_updates(LiVESWidget *widget)
LiVESWidget * lives_standard_radio_button_new(const char *labeltext, LiVESSList **rbgroup, LiVESBox *box, const char *tooltip)
WIDGET_HELPER_GLOBAL_INLINE boolean lives_window_add_accel_group(LiVESWindow *window, LiVESAccelGroup *group)
#define LIVES_EXPAND_DEFAULT_HEIGHT
#define LIVES_EXPAND_EXTRA_WIDTH
#define LIVES_EXPAND_DEFAULT
widget_opts_t widget_opts
#define FILESEL_TYPE_KEY