1 // rte_window.c
2 // LiVES (lives-exe)
3 // (c) G. Finch 2005 - 2018 <salsaman+lives@gmail.com>
4 // released under the GNU GPL 3 or later
5 // see file ../COPYING or www.gnu.org for licensing details
6
7 #include "main.h"
8 #include "rte_window.h"
9 #include "effects.h"
10 #include "paramwindow.h"
11 #include "ce_thumbs.h"
12
13 static int old_rte_keys_virtual = 0;
14
15 static LiVESWidget **key_checks;
16 static LiVESWidget **key_grabs;
17 static LiVESWidget **mode_radios;
18 static LiVESWidget **combos;
19 static LiVESWidget **combo_entries;
20 static LiVESWidget *dummy_radio;
21 static LiVESWidget **nlabels;
22 static LiVESWidget **type_labels;
23 static LiVESWidget **param_buttons;
24 static LiVESWidget **conx_buttons;
25 static LiVESWidget **clear_buttons;
26 static LiVESWidget **info_buttons;
27 static LiVESWidget *clear_all_button;
28 static LiVESWidget *save_keymap_button;
29 static LiVESWidget *load_keymap_button;
30
31 static LiVESWidget *datacon_dialog = NULL;
32
33 static ulong *ch_fns;
34 static ulong *gr_fns;
35 static ulong *mode_ra_fns;
36
37 static int keyw = -1, modew = -1;
38
39 static LiVESList *hash_list = NULL;
40 static LiVESList *name_list = NULL;
41 static LiVESList *extended_name_list = NULL;
42
43 static boolean ca_canc;
44
45 static char *empty_string = "";
46
47 //////////////////////////////////////////////////////////////////////////////
48
49 static void set_param_and_con_buttons(int key, int mode);
50 static void check_clear_all_button(void);
51
52 static boolean rte_window_is_hidden = TRUE;
53
54
rte_window_hidden(void)55 boolean rte_window_hidden(void) {
56 return rte_window_is_hidden;
57 }
58
59
rte_window_set_interactive(boolean interactive)60 void rte_window_set_interactive(boolean interactive) {
61 register int i, j;
62 int modes = rte_getmodespk();
63 int idx;
64
65 if (!interactive) {
66 lives_widget_set_sensitive(clear_all_button, FALSE);
67 lives_widget_set_sensitive(save_keymap_button, FALSE);
68 lives_widget_set_sensitive(load_keymap_button, FALSE);
69 for (i = 0; i < prefs->rte_keys_virtual; i++) {
70 for (j = modes - 1; j >= 0; j--) {
71 idx = i * modes + j;
72 lives_widget_set_sensitive(conx_buttons[idx], FALSE);
73 lives_widget_set_sensitive(param_buttons[idx], FALSE);
74 lives_widget_set_sensitive(combos[idx], FALSE);
75 lives_widget_set_sensitive(clear_buttons[idx], FALSE);
76 lives_widget_set_sensitive(mode_radios[idx], FALSE);
77 }
78 lives_widget_set_sensitive(key_checks[i], FALSE);
79 lives_widget_set_sensitive(key_grabs[i], FALSE);
80 }
81 } else {
82 for (i = 0; i < prefs->rte_keys_virtual; i++) {
83 for (j = modes - 1; j >= 0; j--) {
84 idx = i * modes + j;
85 set_param_and_con_buttons(i, j);
86 }
87 }
88 check_clear_all_button();
89 lives_widget_set_sensitive(save_keymap_button, TRUE);
90 lives_widget_set_sensitive(load_keymap_button, TRUE);
91 }
92 }
93
94
rtew_set_key_check_state(void)95 void rtew_set_key_check_state(void) {
96 // set (delayed) keycheck state
97 register int i;
98 for (i = 0; i < prefs->rte_keys_virtual; i++) {
99 lives_signal_handler_block(key_checks[i], ch_fns[i]);
100 lives_toggle_button_set_active(LIVES_TOGGLE_BUTTON(key_checks[i]),
101 LIVES_POINTER_TO_INT(lives_widget_object_get_data(LIVES_WIDGET_OBJECT(key_checks[i]),
102 "active")));
103 lives_signal_handler_unblock(key_checks[i], ch_fns[i]);
104 }
105 }
106
107
type_label_set_text(int key,int mode)108 void type_label_set_text(int key, int mode) {
109 int modes = rte_getmodespk();
110 int idx = key * modes + mode;
111 char *type = rte_keymode_get_type(key + 1, mode), *tmp;
112
113 if (*type) {
114 lives_label_set_text(LIVES_LABEL(type_labels[idx]), (tmp = lives_strdup_printf(_("Type: %s"), type)));
115 lives_free(tmp);
116 lives_widget_set_sensitive(info_buttons[idx], TRUE);
117 lives_widget_set_sensitive(clear_buttons[idx], TRUE);
118 lives_widget_set_sensitive(mode_radios[idx], TRUE);
119 lives_widget_set_sensitive(nlabels[idx], TRUE);
120 lives_widget_set_sensitive(type_labels[idx], TRUE);
121 } else {
122 lives_label_set_text(LIVES_LABEL(type_labels[idx]), NULL);
123 lives_widget_set_sensitive(info_buttons[idx], FALSE);
124 lives_widget_set_sensitive(clear_buttons[idx], FALSE);
125 lives_widget_set_sensitive(mode_radios[idx], FALSE);
126 lives_widget_set_sensitive(nlabels[idx], FALSE);
127 lives_widget_set_sensitive(type_labels[idx], FALSE);
128 }
129 lives_free(type);
130 }
131
132
on_clear_all_clicked(LiVESButton * button,livespointer user_data)133 boolean on_clear_all_clicked(LiVESButton *button, livespointer user_data) {
134 int modes = rte_getmodespk();
135 register int i, j;
136
137 ca_canc = FALSE;
138
139 // prompt for "are you sure ?"
140 if (user_data) if (!do_warning_dialog(_("\n\nUnbind all effects from all keys/modes.\n\nAre you sure ?\n\n"))) {
141 ca_canc = TRUE;
142 return FALSE;
143 }
144
145 pconx_delete_all();
146 cconx_delete_all();
147
148 for (i = 0; i < prefs->rte_keys_virtual; i++) {
149 if (rte_window) {
150 lives_toggle_button_set_active(LIVES_TOGGLE_BUTTON(key_checks[i]), FALSE);
151 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(key_checks[i]), "active", LIVES_INT_TO_POINTER(FALSE));
152 }
153 for (j = modes - 1; j >= 0; j--) {
154 weed_delete_effectkey(i + 1, j);
155 if (rte_window) {
156 rtew_combo_set_text(i, j, "");
157 }
158 }
159 if (mainw->ce_thumbs) ce_thumbs_reset_combo(i);
160 }
161
162 if (button) lives_widget_set_sensitive(LIVES_WIDGET(button), FALSE);
163
164 return FALSE;
165 }
166
167
save_keymap2_file(char * kfname)168 static boolean save_keymap2_file(char *kfname) {
169 // save perkey defaults
170 int slen;
171 int version = 1;
172 int modes = rte_getmodespk();
173 int kfd;
174 int retval;
175 int i, j;
176
177 char *hashname, *tmp;
178
179 do {
180 retval = 0;
181 kfd = lives_create_buffered(kfname, DEF_FILE_PERMS);
182 if (kfd == -1) {
183 retval = do_write_failed_error_s_with_retry(kfname, lives_strerror(errno));
184 } else {
185 lives_write_le_buffered(kfd, &version, 4, TRUE);
186 for (i = 1; i <= prefs->rte_keys_virtual; i++) {
187 if (THREADVAR(write_failed) == kfd + 1) break;
188 for (j = 0; j < modes; j++) {
189 if (rte_keymode_valid(i, j, TRUE)) {
190 lives_write_le_buffered(kfd, &i, 4, TRUE);
191 if (THREADVAR(write_failed) == kfd + 1) break;
192 // TODO: use newer version with separator
193 hashname = lives_strdup_printf("Weed%s",
194 (tmp = make_weed_hashname(rte_keymode_get_filter_idx(i, j), TRUE, FALSE, 0, FALSE)));
195 lives_free(tmp);
196 slen = lives_strlen(hashname);
197 lives_write_le_buffered(kfd, &slen, 4, TRUE);
198 lives_write_buffered(kfd, hashname, slen, TRUE);
199 lives_free(hashname);
200 write_key_defaults(kfd, i - 1, j);
201 }
202 }
203 }
204
205 lives_close_buffered(kfd);
206
207 if (THREADVAR(write_failed) == kfd + 1) {
208 THREADVAR(write_failed) = 0;
209 retval = do_write_failed_error_s_with_retry(kfname, NULL);
210 }
211 }
212 } while (retval == LIVES_RESPONSE_RETRY);
213
214 if (retval == LIVES_RESPONSE_CANCEL) return FALSE;
215 return TRUE;
216 }
217
218
save_keymap3_file(char * kfname)219 static boolean save_keymap3_file(char *kfname) {
220 // save data connections
221
222 char *hashname;
223
224 int version = 1;
225
226 int slen;
227 int kfd;
228 int retval;
229 int count = 0, totcons, nconns;
230
231 register int i, j;
232
233 do {
234 retval = 0;
235 kfd = lives_create_buffered(kfname, DEF_FILE_PERMS);
236 if (kfd == -1) {
237 retval = do_write_failed_error_s_with_retry(kfname, lives_strerror(errno));
238 } else {
239 THREADVAR(write_failed) = FALSE;
240
241 lives_write_le_buffered(kfd, &version, 4, TRUE);
242
243 if (mainw->cconx) {
244 lives_cconnect_t *cconx = mainw->cconx;
245 int nchans;
246
247 while (cconx) {
248 count++;
249 cconx = cconx->next;
250 }
251
252 lives_write_le_buffered(kfd, &count, 4, TRUE);
253 if (THREADVAR(write_failed)) goto write_failed1;
254
255 cconx = mainw->cconx;
256 while (cconx) {
257 totcons = 0;
258 j = 0;
259
260 lives_write_le_buffered(kfd, &cconx->okey, 4, TRUE);
261 if (THREADVAR(write_failed)) goto write_failed1;
262
263 lives_write_le_buffered(kfd, &cconx->omode, 4, TRUE);
264 if (THREADVAR(write_failed)) goto write_failed1;
265
266 // TODO: use newer version with separator
267 hashname = make_weed_hashname(rte_keymode_get_filter_idx(cconx->okey + 1, cconx->omode), TRUE, FALSE, 0, FALSE);
268 slen = lives_strlen(hashname);
269 lives_write_le_buffered(kfd, &slen, 4, TRUE);
270 lives_write_buffered(kfd, hashname, slen, TRUE);
271 lives_free(hashname);
272
273 nchans = cconx->nchans;
274 lives_write_le_buffered(kfd, &nchans, 4, TRUE);
275 if (THREADVAR(write_failed)) goto write_failed1;
276
277 for (i = 0; i < nchans; i++) {
278 lives_write_le_buffered(kfd, &cconx->chans[i], 4, TRUE);
279 if (THREADVAR(write_failed)) goto write_failed1;
280
281 nconns = cconx->nconns[i];
282 lives_write_le_buffered(kfd, &nconns, 4, TRUE);
283 if (THREADVAR(write_failed)) goto write_failed1;
284
285 totcons += nconns;
286
287 while (j < totcons) {
288 lives_write_le_buffered(kfd, &cconx->ikey[j], 4, TRUE);
289 if (THREADVAR(write_failed)) goto write_failed1;
290
291 lives_write_le_buffered(kfd, &cconx->imode[j], 4, TRUE);
292 if (THREADVAR(write_failed)) goto write_failed1;
293
294 // TODO: use newer version with separator
295 hashname =
296 make_weed_hashname(rte_keymode_get_filter_idx(cconx->ikey[j] + 1, cconx->imode[j]), TRUE, FALSE, 0, FALSE);
297 slen = lives_strlen(hashname);
298 lives_write_le_buffered(kfd, &slen, 4, TRUE);
299 lives_write_buffered(kfd, hashname, slen, TRUE);
300 lives_free(hashname);
301
302 lives_write_le_buffered(kfd, &cconx->icnum[j], 4, TRUE);
303 if (THREADVAR(write_failed)) goto write_failed1;
304
305 j++;
306 }
307 }
308
309 cconx = cconx->next;
310 }
311 } else {
312 lives_write_le_buffered(kfd, &count, 4, TRUE);
313 if (THREADVAR(write_failed)) goto write_failed1;
314 }
315
316 if (mainw->pconx) {
317 lives_pconnect_t *pconx = mainw->pconx;
318
319 int nparams;
320
321 count = 0;
322
323 while (pconx) {
324 count++;
325 pconx = pconx->next;
326 }
327
328 lives_write_le_buffered(kfd, &count, 4, TRUE);
329 if (THREADVAR(write_failed) == kfd + 1) goto write_failed1;
330
331 pconx = mainw->pconx;
332 while (pconx) {
333 totcons = 0;
334 j = 0;
335
336 lives_write_le_buffered(kfd, &pconx->okey, 4, TRUE);
337 if (THREADVAR(write_failed) == kfd + 1) goto write_failed1;
338
339 lives_write_le_buffered(kfd, &pconx->omode, 4, TRUE);
340 if (THREADVAR(write_failed) == kfd + 1) goto write_failed1;
341
342 // TODO: use newer version with separator
343 hashname =
344 make_weed_hashname(rte_keymode_get_filter_idx(pconx->okey + 1, pconx->omode), TRUE, FALSE, 0, FALSE);
345 slen = lives_strlen(hashname);
346 lives_write_le_buffered(kfd, &slen, 4, TRUE);
347 lives_write_buffered(kfd, hashname, slen, TRUE);
348 lives_free(hashname);
349
350 nparams = pconx->nparams;
351 lives_write_le_buffered(kfd, &nparams, 4, TRUE);
352 if (THREADVAR(write_failed) == kfd + 1) goto write_failed1;
353
354 for (i = 0; i < nparams; i++) {
355 lives_write_le_buffered(kfd, &pconx->params[i], 4, TRUE);
356 if (THREADVAR(write_failed) == kfd + 1) goto write_failed1;
357
358 nconns = pconx->nconns[i];
359 lives_write_le_buffered(kfd, &nconns, 4, TRUE);
360 if (THREADVAR(write_failed) == kfd + 1) goto write_failed1;
361
362 totcons += nconns;
363
364 while (j < totcons) {
365 lives_write_le_buffered(kfd, &pconx->ikey[j], 4, TRUE);
366 if (THREADVAR(write_failed)) goto write_failed1;
367
368 lives_write_le_buffered(kfd, &pconx->imode[j], 4, TRUE);
369 if (THREADVAR(write_failed) == kfd + 1) goto write_failed1;
370
371 // TODO: use newer version with separator
372 hashname =
373 make_weed_hashname(rte_keymode_get_filter_idx(pconx->ikey[j] + 1, pconx->imode[j]), TRUE, FALSE, 0, FALSE);
374 slen = lives_strlen(hashname);
375 lives_write_le_buffered(kfd, &slen, 4, TRUE);
376 lives_write_buffered(kfd, hashname, slen, TRUE);
377 lives_free(hashname);
378
379 lives_write_le_buffered(kfd, &pconx->ipnum[j], 4, TRUE);
380 if (THREADVAR(write_failed) == kfd + 1) goto write_failed1;
381
382 lives_write_le_buffered(kfd, &pconx->autoscale[j], 4, TRUE);
383 if (THREADVAR(write_failed) == kfd + 1) goto write_failed1;
384
385 j++;
386 }
387 }
388
389 pconx = pconx->next;
390 }
391 } else {
392 lives_write_le_buffered(kfd, &count, 4, TRUE);
393 if (THREADVAR(write_failed) == kfd + 1) goto write_failed1;
394 }
395
396 write_failed1:
397 lives_close_buffered(kfd);
398
399 if (THREADVAR(write_failed) == kfd + 1) {
400 THREADVAR(write_failed) = 0;
401 retval = do_write_failed_error_s_with_retry(kfname, NULL);
402 }
403 }
404 } while (retval == LIVES_RESPONSE_RETRY);
405
406 if (retval == LIVES_RESPONSE_CANCEL) return FALSE;
407 return TRUE;
408 }
409
410
on_save_keymap_clicked(LiVESButton * button,livespointer user_data)411 static boolean on_save_keymap_clicked(LiVESButton *button, livespointer user_data) {
412 // format is binary
413 // (4 bytes key) (4 bytes hlen) (hlen bytes hashname) then a dump of the weed plant default values
414
415 // if we have data connections, we will save a second file
416
417 char *keymap_file2 = lives_build_filename(prefs->config_datadir, DEF_KEYMAP_FILE2, NULL); // perkey defs
418 char *keymap_file3 = lives_build_filename(prefs->config_datadir, DEF_KEYMAP_FILE3, NULL); // data connections
419
420 LiVESResponseType retval = LIVES_RESPONSE_NONE;
421
422 if (button) {
423 if (!do_warning_dialog(_("\n\nClick 'OK' to save this keymap as your default\n\n"))) {
424 lives_free(keymap_file3);
425 lives_free(keymap_file2);
426 return FALSE;
427 }
428 d_print(_("Saving keymap to %s\n"), keymap_file2);
429 } else {
430 d_print(_("\nUpdating keymap file %s..."), keymap_file2);
431 }
432
433 // if we have default values, save them
434 if (!save_keymap2_file(keymap_file2)) {
435 lives_rm(keymap_file2);
436 retval = LIVES_RESPONSE_CANCEL;
437 }
438
439 // if we have data connections, save them
440 if (mainw->pconx || mainw->cconx) {
441 if (!save_keymap3_file(keymap_file3)) {
442 lives_rm(keymap_file3);
443 retval = LIVES_RESPONSE_CANCEL;
444 }
445 } else lives_rm(keymap_file3);
446
447 lives_free(keymap_file3);
448 lives_free(keymap_file2);
449
450 if (retval == LIVES_RESPONSE_CANCEL) d_print_file_error_failed();
451 else d_print_done();
452
453 return FALSE;
454 }
455
456
on_save_rte_defs_activate(LiVESMenuItem * menuitem,livespointer user_data)457 void on_save_rte_defs_activate(LiVESMenuItem *menuitem, livespointer user_data) {
458 char *msg;
459
460 int fd;
461 int retval;
462 int numfx;
463
464 register int i;
465
466 if (!prefs->fxdefsfile) {
467 prefs->fxdefsfile = lives_build_filename(prefs->config_datadir, FX_DEFS_FILENAME, NULL);
468 }
469
470 if (!prefs->fxsizesfile) {
471 prefs->fxsizesfile = lives_build_filename(prefs->config_datadir, FX_SIZES_FILENAME, NULL);
472 }
473
474 d_print(_("Saving real time effect defaults to %s..."), prefs->fxdefsfile);
475
476 numfx = rte_get_numfilters();
477
478 do {
479 do_threaded_dialog(_("Saving real time effect defaults..."), FALSE);
480 retval = LIVES_RESPONSE_NONE;
481 if ((fd = lives_create_buffered(prefs->fxdefsfile, DEF_FILE_PERMS)) == -1) {
482 end_threaded_dialog();
483 msg = lives_strdup_printf(_("\n\nUnable to write defaults file\n%s\nError code %d\n"), prefs->fxdefsfile, errno);
484 retval = do_abort_cancel_retry_dialog(msg);
485 lives_free(msg);
486 } else {
487 msg = lives_strdup_printf("%s\n", FX_DEFS_VERSIONSTRING_1_1);
488 lives_write_buffered(fd, msg, lives_strlen(msg), TRUE);
489 lives_free(msg);
490
491 if (THREADVAR(write_failed) == fd + 1) {
492 THREADVAR(write_failed) = 0;
493 end_threaded_dialog();
494 retval = do_write_failed_error_s_with_retry(prefs->fxdefsfile, NULL);
495 } else {
496 // break on file write error
497 for (i = 0; i < numfx; i++) {
498 if (!write_filter_defaults(fd, i)) {
499 end_threaded_dialog();
500 retval = do_write_failed_error_s_with_retry(prefs->fxdefsfile, NULL);
501 break;
502 }
503 }
504 }
505 lives_close_buffered(fd);
506 }
507 } while (retval == LIVES_RESPONSE_RETRY);
508
509 if (retval == LIVES_RESPONSE_CANCEL) {
510 d_print_file_error_failed();
511 return;
512 }
513
514 threaded_dialog_spin(0.);
515
516 do {
517 retval = LIVES_RESPONSE_NONE;
518 if ((fd = lives_create_buffered(prefs->fxsizesfile, DEF_FILE_PERMS)) == -1) {
519 end_threaded_dialog();
520 retval = do_write_failed_error_s_with_retry(prefs->fxsizesfile, lives_strerror(errno));
521 lives_free(msg);
522 } else {
523 msg = lives_strdup_printf("%s\n", FX_SIZES_VERSIONSTRING_2);
524 lives_write_buffered(fd, msg, lives_strlen(msg), TRUE);
525 lives_free(msg);
526 if (THREADVAR(write_failed) == fd + 1) {
527 THREADVAR(write_failed) = 0;
528 end_threaded_dialog();
529 retval = do_write_failed_error_s_with_retry(prefs->fxsizesfile, NULL);
530 } else {
531 for (i = 0; i < numfx; i++) {
532 if (!write_generator_sizes(fd, i)) {
533 end_threaded_dialog();
534 retval = do_write_failed_error_s_with_retry(prefs->fxsizesfile, NULL);
535 break;
536 }
537 }
538 }
539 lives_close_buffered(fd);
540 }
541 if (retval == LIVES_RESPONSE_RETRY) do_threaded_dialog(_("Saving real time effect defaults..."), FALSE);
542 } while (retval == LIVES_RESPONSE_RETRY);
543
544 if (retval == LIVES_RESPONSE_CANCEL) {
545 d_print_file_error_failed();
546 return;
547 }
548
549 d_print_done();
550 end_threaded_dialog();
551
552 return;
553 }
554
555
load_rte_defs(void)556 void load_rte_defs(void) {
557 ssize_t bytes;
558 char *buf, *msg;
559 size_t msglen;
560 int fd;
561 int retval;
562
563 if (!prefs->fxdefsfile) {
564 prefs->fxdefsfile = lives_build_filename(prefs->config_datadir, FX_DEFS_FILENAME, NULL);
565 }
566
567 if (lives_file_test(prefs->fxdefsfile, LIVES_FILE_TEST_EXISTS)) {
568 do {
569 retval = 0;
570 if ((fd = lives_open_buffered_rdonly(prefs->fxdefsfile)) == -1) {
571 retval = do_read_failed_error_s_with_retry(prefs->fxdefsfile, lives_strerror(errno));
572 } else {
573 THREADVAR(read_failed) = FALSE;
574 d_print(_("Loading real time effect defaults from %s..."), prefs->fxdefsfile);
575
576 msg = lives_strdup_printf("%s\n", FX_DEFS_VERSIONSTRING_1_1);
577 msglen = lives_strlen(msg);
578 buf = lives_malloc(msglen + 1);
579 bytes = lives_read_buffered(fd, buf, msglen, TRUE);
580 if (bytes == (ssize_t)msglen && !lives_strncmp((char *)buf, msg, msglen)) {
581 if (read_filter_defaults(fd)) {
582 d_print_done();
583 } else {
584 d_print_file_error_failed();
585 retval = do_read_failed_error_s_with_retry(prefs->fxdefsfile, NULL);
586 }
587 } else {
588 d_print_file_error_failed();
589 if (bytes < (ssize_t)msglen) {
590 retval = do_read_failed_error_s_with_retry(prefs->fxdefsfile, NULL);
591 }
592 }
593
594 lives_close_buffered(fd);
595
596 lives_free(buf);
597 lives_free(msg);
598 }
599 } while (retval == LIVES_RESPONSE_RETRY);
600 }
601
602 if (!prefs->fxsizesfile) {
603 prefs->fxsizesfile = lives_build_filename(prefs->config_datadir, FX_SIZES_FILENAME, NULL);
604 }
605
606 if (lives_file_test(prefs->fxsizesfile, LIVES_FILE_TEST_EXISTS)) {
607 do {
608 retval = 0;
609 if ((fd = lives_open_buffered_rdonly(prefs->fxsizesfile)) == -1) {
610 retval = do_read_failed_error_s_with_retry(prefs->fxsizesfile, lives_strerror(errno));
611 if (retval == LIVES_RESPONSE_CANCEL) return;
612 } else {
613 d_print(_("Loading generator default sizes from %s..."), prefs->fxsizesfile);
614
615 msg = lives_strdup_printf("%s\n", FX_SIZES_VERSIONSTRING_2);
616 msglen = lives_strlen(msg);
617 buf = lives_malloc(msglen + 1);
618 bytes = lives_read_buffered(fd, buf, msglen, TRUE);
619 if (bytes == (ssize_t)msglen && !strncmp((char *)buf, msg, msglen)) {
620 if (read_generator_sizes(fd)) {
621 d_print_done();
622 } else {
623 d_print_file_error_failed();
624 retval = do_read_failed_error_s_with_retry(prefs->fxsizesfile, NULL);
625 }
626 } else {
627 d_print_file_error_failed();
628 if (bytes < (ssize_t)msglen) {
629 retval = do_read_failed_error_s_with_retry(prefs->fxsizesfile, NULL);
630 }
631 }
632 lives_close_buffered(fd);
633
634 lives_free(buf);
635 lives_free(msg);
636 }
637 } while (retval == LIVES_RESPONSE_RETRY);
638 }
639
640 return;
641 }
642
643
check_clear_all_button(void)644 static void check_clear_all_button(void) {
645 int modes = rte_getmodespk();
646 int i, j;
647 boolean hasone = FALSE;
648
649 for (i = 0; i < prefs->rte_keys_virtual; i++) {
650 for (j = modes - 1; j >= 0; j--) {
651 if (rte_keymode_valid(i + 1, j, TRUE)) hasone = TRUE;
652 }
653 }
654
655 lives_widget_set_sensitive(LIVES_WIDGET(clear_all_button), hasone);
656 }
657
658
read_perkey_defaults(int kfd,int key,int mode,int version)659 static boolean read_perkey_defaults(int kfd, int key, int mode, int version) {
660 boolean ret = TRUE;
661 int nparams;
662 ssize_t bytes = lives_read_le_buffered(kfd, &nparams, 4, TRUE);
663
664 if (nparams > 65536) {
665 lives_printerr("Too many params, file is probably broken.\n");
666 return FALSE;
667 }
668
669 if (bytes < sizint) {
670 return FALSE;
671 }
672
673 if (nparams > 0) {
674 ret = read_key_defaults(kfd, nparams, key, mode, version);
675 }
676 return ret;
677 }
678
679
load_datacons(const char * fname,uint8_t ** badkeymap)680 static boolean load_datacons(const char *fname, uint8_t **badkeymap) {
681 weed_plant_t **ochans, **ichans, **iparams;
682
683 weed_plant_t *filter;
684
685 ssize_t bytes;
686
687 char *hashname;
688
689 boolean ret = TRUE;
690 boolean is_valid, is_valid2;
691 boolean eof = FALSE;
692
693 int kfd;
694
695 int retval;
696
697 int hlen;
698
699 int version, nchans, nparams, nconns, ncconx, npconx;
700
701 int nichans, nochans, niparams, noparams, error;
702
703 int okey, omode, ocnum, opnum, ikey, imode, icnum, ipnum, autoscale;
704
705 int maxmodes = rte_getmodespk();
706
707 register int i, j, k, count;
708
709 do {
710 retval = 0;
711 if ((kfd = lives_open_buffered_rdonly(fname)) == -1) {
712 retval = do_read_failed_error_s_with_retry(fname, lives_strerror(errno));
713 } else {
714 THREADVAR(read_failed) = FALSE;
715
716 bytes = lives_read_le_buffered(kfd, &version, 4, TRUE);
717 if (bytes < 4) {
718 eof = TRUE;
719 break;
720 }
721
722 bytes = lives_read_le_buffered(kfd, &ncconx, 4, TRUE);
723 if (bytes < 4) {
724 eof = TRUE;
725 break;
726 }
727
728 for (count = 0; count < ncconx; count++) {
729 is_valid = TRUE;
730
731 bytes = lives_read_le_buffered(kfd, &okey, 4, TRUE);
732 if (bytes < 4) {
733 eof = TRUE;
734 break;
735 }
736
737 if (okey < 0 || okey >= prefs->rte_keys_virtual) is_valid = FALSE;
738
739 bytes = lives_read_le_buffered(kfd, &omode, 4, TRUE);
740 if (bytes < 4) {
741 eof = TRUE;
742 break;
743 }
744
745 bytes = lives_read_le_buffered(kfd, &hlen, 4, TRUE);
746 if (bytes < 4) {
747 eof = TRUE;
748 break;
749 }
750
751 hashname = (char *)lives_malloc(hlen + 1);
752
753 if (!hashname) {
754 eof = TRUE;
755 break;
756 }
757
758 bytes = lives_read_buffered(kfd, hashname, hlen, TRUE);
759 if (bytes < hlen) {
760 eof = TRUE;
761 lives_free(hashname);
762 break;
763 }
764
765 lives_memset(hashname + hlen, 0, 1);
766
767 if (omode < 0 || omode >= maxmodes) is_valid = FALSE;
768
769 if (is_valid) {
770 // if we had bad/missing fx, adjust the omode value
771 for (i = 0; i < omode; i++) omode -= badkeymap[okey][omode];
772 }
773
774 if (omode < 0 || omode >= maxmodes) is_valid = FALSE;
775
776 if (is_valid) {
777 int fidx = rte_keymode_get_filter_idx(okey + 1, omode);
778 if (fidx == -1) is_valid = FALSE;
779 else {
780 // TODO: use newer version with separator
781 char *hashname2 = make_weed_hashname(fidx, TRUE, FALSE, 0, FALSE);
782 if (strcmp(hashname, hashname2)) is_valid = FALSE;
783 lives_free(hashname2);
784 if (!is_valid) {
785 hashname2 = make_weed_hashname(fidx, TRUE, TRUE, 0, FALSE);
786 if (!strcmp(hashname, hashname2)) is_valid = TRUE;
787 lives_free(hashname2);
788 }
789 }
790 }
791
792 lives_free(hashname);
793
794 bytes = lives_read_le_buffered(kfd, &nchans, 4, TRUE);
795 if (bytes < 4) {
796 eof = TRUE;
797 break;
798 }
799
800 for (i = 0; i < nchans; i++) {
801 is_valid2 = is_valid;
802
803 bytes = lives_read_le_buffered(kfd, &ocnum, 4, TRUE);
804 if (bytes < 4) {
805 eof = TRUE;
806 break;
807 }
808
809 // check ocnum
810 filter = rte_keymode_get_filter(okey + 1, omode);
811 nochans = weed_leaf_num_elements(filter, WEED_LEAF_OUT_CHANNEL_TEMPLATES);
812 if (ocnum >= nochans) is_valid2 = FALSE;
813 else {
814 ochans = weed_get_plantptr_array(filter, WEED_LEAF_OUT_CHANNEL_TEMPLATES, &error);
815 if (!has_alpha_palette(ochans[ocnum], filter)) is_valid2 = FALSE;
816 lives_free(ochans);
817 }
818
819 bytes = lives_read_le_buffered(kfd, &nconns, 4, TRUE);
820 if (bytes < 4) {
821 eof = TRUE;
822 break;
823 }
824
825 for (j = 0; j < nconns; j++) {
826 bytes = lives_read_le_buffered(kfd, &ikey, 4, TRUE);
827 if (bytes < 4) {
828 eof = TRUE;
829 break;
830 }
831
832 bytes = lives_read_le_buffered(kfd, &imode, 4, TRUE);
833 if (bytes < 4) {
834 eof = TRUE;
835 break;
836 }
837
838 bytes = lives_read_le_buffered(kfd, &hlen, 4, TRUE);
839 if (bytes < 4) {
840 eof = TRUE;
841 break;
842 }
843
844 hashname = (char *)lives_malloc(hlen + 1);
845
846 if (!hashname) {
847 eof = TRUE;
848 break;
849 }
850
851 bytes = lives_read_buffered(kfd, hashname, hlen, TRUE);
852 if (bytes < hlen) {
853 eof = TRUE;
854 lives_free(hashname);
855 break;
856 }
857
858 lives_memset(hashname + hlen, 0, 1);
859
860 if (imode < 0 || (ikey >= 0 && imode >= maxmodes)) is_valid2 = FALSE;
861
862 if (is_valid2) {
863 // if we had bad/missing fx, adjust the omode value
864 for (k = 0; k < imode; k++) imode -= badkeymap[ikey][imode];
865 }
866
867 if (imode < 0 || (ikey >= 0 && imode >= maxmodes)) is_valid2 = FALSE;
868
869 if (is_valid2) {
870 int fidx = rte_keymode_get_filter_idx(ikey + 1, imode);
871 if (fidx == -1) is_valid2 = FALSE;
872 else {
873 // TODO: use newer version with separator
874 char *hashname2 = make_weed_hashname(fidx, TRUE, FALSE, 0, FALSE);
875 if (strcmp(hashname, hashname2)) is_valid2 = FALSE;
876 lives_free(hashname2);
877 if (!is_valid2) {
878 hashname2 = make_weed_hashname(fidx, TRUE, TRUE, 0, FALSE);
879 if (!strcmp(hashname, hashname2)) is_valid2 = TRUE;
880 lives_free(hashname2);
881 }
882 }
883 }
884
885 lives_free(hashname);
886
887 bytes = lives_read_le_buffered(kfd, &icnum, 4, TRUE);
888 if (bytes < 4) {
889 eof = TRUE;
890 break;
891 }
892
893 // check icnum
894 filter = rte_keymode_get_filter(ikey + 1, imode);
895 nichans = weed_leaf_num_elements(filter, WEED_LEAF_IN_CHANNEL_TEMPLATES);
896 if (icnum >= nichans) is_valid2 = FALSE;
897 else {
898 ichans = weed_get_plantptr_array(filter, WEED_LEAF_IN_CHANNEL_TEMPLATES, &error);
899 if (!has_alpha_palette(ichans[icnum], filter)) is_valid2 = FALSE;
900 lives_free(ichans);
901 }
902
903 if (is_valid2) cconx_add_connection(okey, omode, ocnum, ikey, imode, icnum);
904 }
905
906 if (eof) break;
907 }
908
909 if (eof) break;
910 }
911
912 if (eof) break;
913
914 // params
915
916 bytes = lives_read_le_buffered(kfd, &npconx, 4, TRUE);
917 if (bytes < 4) {
918 eof = TRUE;
919 break;
920 }
921
922 for (count = 0; count < npconx; count++) {
923 is_valid = TRUE;
924
925 bytes = lives_read_le_buffered(kfd, &okey, 4, TRUE);
926 if (bytes < 4) {
927 eof = TRUE;
928 break;
929 }
930
931 if (okey < 0 || okey >= prefs->rte_keys_virtual) is_valid = FALSE;
932
933 bytes = lives_read_le_buffered(kfd, &omode, 4, TRUE);
934 if (bytes < 4) {
935 eof = TRUE;
936 break;
937 }
938
939 bytes = lives_read_le_buffered(kfd, &hlen, 4, TRUE);
940 if (bytes < 4) {
941 eof = TRUE;
942 break;
943 }
944
945 hashname = (char *)lives_malloc(hlen + 1);
946
947 if (!hashname) {
948 eof = TRUE;
949 break;
950 }
951
952 bytes = lives_read_buffered(kfd, hashname, hlen, TRUE);
953 if (bytes < hlen) {
954 eof = TRUE;
955 lives_free(hashname);
956 break;
957 }
958
959 lives_memset(hashname + hlen, 0, 1);
960
961 if (omode < 0 || omode >= maxmodes) is_valid = FALSE;
962
963 if (is_valid) {
964 // if we had bad/missing fx, adjust the omode value
965 for (i = 0; i < omode; i++) omode -= badkeymap[okey][omode];
966 }
967
968 if (omode < 0 || omode >= maxmodes) is_valid = FALSE;
969
970 if (is_valid) {
971 int fidx = rte_keymode_get_filter_idx(okey + 1, omode);
972 if (fidx == -1) is_valid = FALSE;
973 else {
974 // TODO: use newer version with separator
975 char *hashname2 = make_weed_hashname(fidx, TRUE, FALSE, 0, FALSE);
976 if (strcmp(hashname, hashname2)) is_valid = FALSE;
977 lives_free(hashname2);
978 if (!is_valid) {
979 hashname2 = make_weed_hashname(fidx, TRUE, TRUE, 0, FALSE);
980 if (!strcmp(hashname, hashname2)) is_valid = TRUE;
981 lives_free(hashname2);
982 }
983 }
984 }
985
986 lives_free(hashname);
987
988 bytes = lives_read_le_buffered(kfd, &nparams, 4, TRUE);
989 if (bytes < 4) {
990 eof = TRUE;
991 break;
992 }
993
994 for (i = 0; i < nparams; i++) {
995 is_valid2 = is_valid;
996
997 bytes = lives_read_le_buffered(kfd, &opnum, 4, TRUE);
998 if (bytes < 4) {
999 eof = TRUE;
1000 break;
1001 }
1002
1003 // check opnum
1004 filter = rte_keymode_get_filter(okey + 1, omode);
1005 noparams = weed_leaf_num_elements(filter, WEED_LEAF_OUT_PARAMETER_TEMPLATES);
1006 if (opnum >= noparams) is_valid2 = FALSE;
1007
1008 bytes = lives_read_le_buffered(kfd, &nconns, 4, TRUE);
1009 if (bytes < 4) {
1010 eof = TRUE;
1011 break;
1012 }
1013
1014 for (j = 0; j < nconns; j++) {
1015 bytes = lives_read_le_buffered(kfd, &ikey, 4, TRUE);
1016 if (bytes < 4) {
1017 eof = TRUE;
1018 break;
1019 }
1020
1021 bytes = lives_read_le_buffered(kfd, &imode, 4, TRUE);
1022 if (bytes < 4) {
1023 eof = TRUE;
1024 break;
1025 }
1026
1027 bytes = lives_read_le_buffered(kfd, &hlen, 4, TRUE);
1028 if (bytes < 4) {
1029 eof = TRUE;
1030 break;
1031 }
1032
1033 hashname = (char *)lives_malloc(hlen + 1);
1034
1035 if (!hashname) {
1036 eof = TRUE;
1037 break;
1038 }
1039
1040 bytes = lives_read_buffered(kfd, hashname, hlen, TRUE);
1041 if (bytes < hlen) {
1042 eof = TRUE;
1043 lives_free(hashname);
1044 break;
1045 }
1046
1047 lives_memset(hashname + hlen, 0, 1);
1048
1049 if (imode < 0 || (ikey >= 0 && imode >= maxmodes)) is_valid2 = FALSE;
1050
1051 if (is_valid2 && ikey >= 0) {
1052 // if we had bad/missing fx, adjust the omode value
1053 for (k = 0; k < imode; k++) imode -= badkeymap[ikey][imode];
1054 }
1055
1056 if (imode < 0 || (ikey >= 0 && imode >= maxmodes)) is_valid2 = FALSE;
1057
1058 if (is_valid2 && ikey >= 0) {
1059 int fidx = rte_keymode_get_filter_idx(ikey + 1, imode);
1060 if (fidx == -1) is_valid2 = FALSE;
1061 else {
1062 // TODO: use newer version with separator
1063 char *hashname2 = make_weed_hashname(fidx, TRUE, FALSE, 0, FALSE);
1064 if (strcmp(hashname, hashname2)) is_valid2 = FALSE;
1065 lives_free(hashname2);
1066 if (!is_valid2) {
1067 hashname2 = make_weed_hashname(fidx, TRUE, TRUE, 0, FALSE);
1068 if (!strcmp(hashname, hashname2)) is_valid2 = TRUE;
1069 lives_free(hashname2);
1070 }
1071 }
1072 }
1073
1074 lives_free(hashname);
1075
1076 bytes = lives_read_le_buffered(kfd, &ipnum, 4, TRUE);
1077 if (bytes < 4) {
1078 eof = TRUE;
1079 break;
1080 }
1081
1082 if (ikey >= 0) {
1083 // check ipnum
1084 filter = rte_keymode_get_filter(ikey + 1, imode);
1085 niparams = weed_leaf_num_elements(filter, WEED_LEAF_IN_PARAMETER_TEMPLATES);
1086 if (ipnum >= niparams) is_valid2 = FALSE;
1087 else {
1088 if (ipnum >= 0) {
1089 iparams = weed_get_plantptr_array(filter, WEED_LEAF_IN_PARAMETER_TEMPLATES, &error);
1090 if (weed_plant_has_leaf(iparams[ipnum], WEED_LEAF_HOST_INTERNAL_CONNECTION)) is_valid2 = FALSE;
1091 lives_free(iparams);
1092 }
1093 }
1094 }
1095
1096 bytes = lives_read_le_buffered(kfd, &autoscale, 4, TRUE);
1097 if (bytes < 4) {
1098 eof = TRUE;
1099 break;
1100 }
1101
1102 if (is_valid2) {
1103 pconx_add_connection(okey, omode, opnum, ikey, imode, ipnum, autoscale);
1104 }
1105 }
1106
1107 if (eof) break;
1108 }
1109
1110 if (eof) break;
1111 }
1112
1113 lives_close_buffered(kfd);
1114 }
1115 } while (retval == LIVES_RESPONSE_RETRY);
1116
1117 if (retval == LIVES_RESPONSE_CANCEL) {
1118 d_print_cancelled();
1119 return FALSE;
1120 }
1121
1122 return ret;
1123 }
1124
1125
set_param_and_con_buttons(int key,int mode)1126 static void set_param_and_con_buttons(int key, int mode) {
1127 weed_plant_t *filter = rte_keymode_get_filter(key + 1, mode);
1128
1129 int modes = rte_getmodespk();
1130 int idx = key * modes + mode;
1131
1132 if (filter) {
1133 lives_widget_set_sensitive(conx_buttons[idx], TRUE);
1134 if (num_in_params(filter, TRUE, TRUE) > 0) lives_widget_set_sensitive(param_buttons[idx], TRUE);
1135 else lives_widget_set_sensitive(param_buttons[idx], FALSE);
1136 lives_widget_set_sensitive(combos[idx], TRUE);
1137 if (combos[idx + 1] && mode < modes - 1) lives_widget_set_sensitive(combos[idx + 1], TRUE);
1138 } else {
1139 lives_widget_set_sensitive(conx_buttons[idx], FALSE);
1140 lives_widget_set_sensitive(param_buttons[idx], FALSE);
1141 if (mode == 0 || rte_keymode_get_filter(key + 1, mode - 1))
1142 lives_widget_set_sensitive(combos[idx], TRUE);
1143 else
1144 lives_widget_set_sensitive(combos[idx], FALSE);
1145 }
1146
1147 type_label_set_text(key, mode);
1148 }
1149
1150
on_load_keymap_clicked(LiVESButton * button,livespointer user_data)1151 boolean on_load_keymap_clicked(LiVESButton *button, livespointer user_data) {
1152 // show file errors at this level
1153 FILE *kfile = NULL;
1154
1155 LiVESList *list = NULL, *new_list = NULL;
1156
1157 size_t linelen;
1158 ssize_t bytes;
1159
1160 char buff[65536];
1161 char *msg, *tmp;
1162 char *whole = lives_strdup(""), *whole2;
1163 char *hashname, *hashname_new = NULL;
1164
1165 char *line = NULL;
1166 char *whashname;
1167
1168 char *keymap_file = lives_build_filename(prefs->config_datadir, DEF_KEYMAP_FILE_OLD, NULL); // only for back. compat
1169 char *keymap_file2 = lives_build_filename(prefs->config_datadir, DEF_KEYMAP_FILE2, NULL); // perkey defs
1170 char *keymap_file3 = lives_build_filename(prefs->config_datadir, DEF_KEYMAP_FILE3, NULL); // data connections
1171
1172 int *def_modes = NULL;
1173 uint8_t **badkeymap = NULL;
1174
1175 boolean notfound = FALSE;
1176 boolean has_error = FALSE;
1177 boolean eof = FALSE;
1178
1179 int modes = rte_getmodespk();
1180 int kfd = -1;
1181 int version;
1182 int hlen;
1183 int retval;
1184
1185 int key, mode;
1186 int update = 0;
1187
1188 int i;
1189
1190 if (lives_file_test(keymap_file2, LIVES_FILE_TEST_EXISTS)) {
1191 // per key defaults / newer style keymap
1192 lives_free(keymap_file);
1193 keymap_file = keymap_file2;
1194 } else {
1195 lives_freep((void **)&keymap_file2);
1196 }
1197
1198 d_print(_("Loading default keymap from %s..."), keymap_file);
1199
1200 if (!lives_file_test(keymap_file, LIVES_FILE_TEST_EXISTS)) {
1201 d_print(_("file not found, skipping.\n"));
1202 lives_freep((void **)&keymap_file);
1203 lives_freep((void **)&keymap_file2);
1204 lives_freep((void **)&keymap_file3);
1205 return FALSE;
1206 } else {
1207 do {
1208 retval = 0;
1209
1210 if (keymap_file2) {
1211 if ((kfd = lives_open_buffered_rdonly(keymap_file)) < 0) has_error = TRUE;
1212 } else {
1213 if (!(kfile = fopen(keymap_file, "r"))) {
1214 has_error = TRUE;
1215 }
1216 }
1217
1218 if (has_error) {
1219 msg = lives_strdup_printf(_("\n\nUnable to read from keymap file\n%s\nError code %d\n"), keymap_file, errno);
1220 retval = do_abort_cancel_retry_dialog(msg);
1221 lives_free(msg);
1222
1223 if (retval == LIVES_RESPONSE_CANCEL) {
1224 lives_free(keymap_file);
1225 d_print_file_error_failed();
1226 return FALSE;
1227 }
1228 }
1229 } while (retval == LIVES_RESPONSE_RETRY);
1230
1231 on_clear_all_clicked(NULL, user_data);
1232
1233 if (ca_canc) {
1234 // user cancelled
1235 mainw->error = FALSE;
1236 d_print_cancelled();
1237 return FALSE;
1238 }
1239 }
1240
1241 def_modes = (int *)lives_malloc(prefs->rte_keys_virtual * sizint);
1242 for (i = 0; i < prefs->rte_keys_virtual; i++) def_modes[i] = -1;
1243
1244 badkeymap = (uint8_t **)lives_malloc(prefs->rte_keys_virtual * sizeof(uint8_t *));
1245 for (i = 0; i < prefs->rte_keys_virtual; i++) {
1246 badkeymap[i] = (uint8_t *)lives_calloc(modes, 1);
1247 }
1248
1249 if (!keymap_file2) {
1250 // version 1 file
1251 while (fgets(buff, 65536, kfile)) {
1252 if (*buff) {
1253 line = (lives_strstrip(buff));
1254 if ((linelen = lives_strlen(line))) {
1255 whole2 = lives_strconcat(whole, line, NULL);
1256 if (whole2 != whole) lives_free(whole);
1257 whole = whole2;
1258 if (linelen < (size_t)65535) {
1259 list = lives_list_append(list, lives_strdup(whole));
1260 lives_free(whole);
1261 whole = lives_strdup("");
1262 // *INDENT-OFF*
1263 }}}}
1264 // *INDENT-ON*
1265
1266 fclose(kfile);
1267
1268 if (!strcmp((char *)lives_list_nth_data(list, 0), "LiVES keymap file version 2") ||
1269 !strcmp((char *)lives_list_nth_data(list, 0), "LiVES keymap file version 1")) update = 1;
1270 else {
1271 if (!strcmp((char *)lives_list_nth_data(list, 0), "LiVES keymap file version 3")) update = 2;
1272 else {
1273 goto cleanup1;
1274 }
1275 }
1276 } else {
1277 // newer style
1278 // read version
1279 bytes = lives_read_le_buffered(kfd, &version, 4, TRUE);
1280 if (bytes < sizint) {
1281 eof = TRUE;
1282 }
1283 }
1284
1285 lives_free(whole);
1286
1287 for (i = 1; (!keymap_file2 && i < lives_list_length(list)) || (keymap_file2 && !eof); i++) {
1288 char **array;
1289
1290 if (!keymap_file2) {
1291 // old style
1292
1293 line = (char *)lives_list_nth_data(list, i);
1294
1295 if (get_token_count(line, '|') < 2) {
1296 d_print(_("Invalid line %d in %s\n"), i, keymap_file2 ? keymap_file2 : keymap_file);
1297 continue;
1298 }
1299
1300 array = lives_strsplit(line, "|", -1);
1301
1302 if (!strcmp(array[0], "defaults")) {
1303 lives_strfreev(array);
1304 array = lives_strsplit(line, "|", 2);
1305 lives_freep((void **)&prefs->fxdefsfile);
1306 prefs->fxdefsfile = lives_strdup(array[1]);
1307 lives_strfreev(array);
1308 continue;
1309 }
1310
1311 if (!strcmp(array[0], "sizes")) {
1312 lives_strfreev(array);
1313 array = lives_strsplit(line, "|", 2);
1314 lives_freep((void **)&prefs->fxsizesfile);
1315 prefs->fxsizesfile = lives_strdup(array[1]);
1316 lives_strfreev(array);
1317 continue;
1318 }
1319
1320 key = atoi(array[0]);
1321
1322 hashname = lives_strdup(array[1]);
1323 lives_strfreev(array);
1324
1325 if (update > 0) {
1326 if (update == 1) hashname_new = lives_strdup_printf("%d|Weed%s1\n", key, hashname);
1327 if (update == 2) hashname_new = lives_strdup_printf("%d|Weed%s\n", key, hashname);
1328 new_list = lives_list_append(new_list, hashname_new);
1329 lives_free(hashname);
1330 continue;
1331 }
1332 } else {
1333 // newer style
1334 // file format is: (4 bytes int)key(4 bytes int)hlen(hlen bytes)hashname
1335
1336 //read key and hashname
1337 bytes = lives_read_le_buffered(kfd, &key, 4, TRUE);
1338 if (bytes < 4) {
1339 eof = TRUE;
1340 break;
1341 }
1342
1343 bytes = lives_read_le_buffered(kfd, &hlen, 4, TRUE);
1344 if (bytes < 4) {
1345 eof = TRUE;
1346 break;
1347 }
1348
1349 hashname = (char *)lives_malloc(hlen + 1);
1350
1351 if (!hashname) {
1352 eof = TRUE;
1353 break;
1354 }
1355
1356 bytes = lives_read_buffered(kfd, hashname, hlen, TRUE);
1357 if (bytes < hlen) {
1358 g_print("keyl %d wanted %d got %ld\n", i, hlen, bytes);
1359 eof = TRUE;
1360 lives_free(hashname);
1361 break;
1362 }
1363
1364 lives_memset(hashname + hlen, 0, 1);
1365
1366 array = lives_strsplit(hashname, "|", -1);
1367 lives_free(hashname);
1368 hashname = lives_strdup(array[0]);
1369 lives_strfreev(array);
1370 }
1371
1372 if (key < 1 || key > prefs->rte_keys_virtual) {
1373 d_print((tmp = lives_strdup_printf(_("Invalid key %d in %s\n"), key, keymap_file)));
1374 LIVES_ERROR(tmp);
1375 lives_free(tmp);
1376 notfound = TRUE;
1377 lives_free(hashname);
1378 if (keymap_file2) {
1379 // read param defaults
1380 if (!read_perkey_defaults(kfd, -1, -1, version)) break; // file read error
1381 }
1382 continue;
1383 }
1384
1385 def_modes[key - 1]++;
1386
1387 if (strncmp(hashname, "Weed", 4) || lives_strlen(hashname) < 5) {
1388 d_print((tmp = lives_strdup_printf(_("Invalid effect %s in %s\n"), hashname, keymap_file)));
1389 LIVES_ERROR(tmp);
1390 lives_free(tmp);
1391 notfound = TRUE;
1392 lives_free(hashname);
1393 badkeymap[key - 1][def_modes[key - 1]]++;
1394 if (keymap_file2) {
1395 // read param defaults
1396 if (!read_perkey_defaults(kfd, -1, -1, version)) break; // file read error
1397 }
1398 def_modes[key - 1]--;
1399 continue;
1400 }
1401
1402 // ignore "Weed"
1403 whashname = hashname + 4;
1404
1405 if ((mode = weed_add_effectkey(key, whashname, TRUE)) == -1) {
1406 // could not locate effect
1407 if (!prefs->startup_phase) {
1408 d_print((tmp = lives_strdup_printf(_("Unknown effect %s in\n%s\n"), whashname, keymap_file)));
1409 LIVES_WARN(tmp);
1410 lives_free(tmp);
1411 }
1412 notfound = TRUE;
1413 lives_free(hashname);
1414 badkeymap[key - 1][def_modes[key - 1]]++;
1415 if (keymap_file2) {
1416 // read param defaults
1417 if (!read_perkey_defaults(kfd, -1, -1, version)) break; // file read error
1418 }
1419 def_modes[key - 1]--;
1420 continue;
1421 }
1422
1423 lives_free(hashname);
1424
1425 if (mode == -2) {
1426 d_print((tmp = lives_strdup_printf
1427 (_("This version of LiVES cannot mix generators/non-generators on the same key (%d) !\n"), key)));
1428 LIVES_ERROR(tmp);
1429 lives_free(tmp);
1430 badkeymap[key - 1][def_modes[key - 1]]++;
1431 if (keymap_file2) {
1432 // read param defaults
1433 if (!read_perkey_defaults(kfd, -1, -1, version)) break; // file read error
1434 }
1435 def_modes[key - 1]--;
1436 continue;
1437 }
1438 if (mode == -3) {
1439 d_print((tmp = lives_strdup_printf(_("Too many effects bound to key %d.\n"), key)));
1440 LIVES_ERROR(tmp);
1441 lives_free(tmp);
1442 if (keymap_file2) {
1443 // read param defaults
1444 if (!read_perkey_defaults(kfd, -1, -1, version)) break; // file read error
1445 }
1446 def_modes[key - 1]--;
1447 continue;
1448 }
1449 if (rte_window) {
1450 int idx = (key - 1) * modes + mode;
1451 int fx_idx = rte_keymode_get_filter_idx(key, mode);
1452
1453 rtew_combo_set_text(key - 1, mode, (tmp = rte_keymode_get_filter_name(key, mode, FALSE)));
1454 lives_free(tmp);
1455
1456 if (fx_idx != -1) {
1457 hashname = (char *)lives_list_nth_data(hash_list, fx_idx);
1458 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(combos[idx]), "hashname", hashname);
1459 } else lives_widget_object_set_data(LIVES_WIDGET_OBJECT(combos[idx]), "hashname", empty_string);
1460
1461 // set parameters button sensitive/insensitive
1462 set_param_and_con_buttons(key - 1, mode);
1463 }
1464
1465 if (keymap_file2) {
1466 // read param defaults
1467 if (!read_perkey_defaults(kfd, key - 1, def_modes[key - 1], version)) break; // file read error
1468 }
1469 }
1470
1471 if (!keymap_file2) {
1472 lives_list_free_all(&list);
1473
1474 if (update > 0) {
1475 d_print(_("update required.\n"));
1476 on_save_keymap_clicked(NULL, NULL);
1477 lives_list_free_all(&new_list);
1478 on_load_keymap_clicked(NULL, NULL);
1479 } else d_print_done();
1480 } else {
1481 if (kfd != -1) lives_close_buffered(kfd);
1482 if (prefs->startup_phase && notfound) {
1483 on_save_keymap_clicked(NULL, NULL);
1484 }
1485 d_print_done();
1486 }
1487
1488 if (update == 0) {
1489 if (lives_file_test(keymap_file3, LIVES_FILE_TEST_EXISTS)) {
1490 d_print(_("Loading data connection map from %s..."), keymap_file3);
1491
1492 if (load_datacons(keymap_file3, badkeymap)) d_print_done();
1493 }
1494
1495 if (mainw->is_ready) {
1496 check_clear_all_button();
1497 if (notfound) do_warning_dialog(_("\n\nSome effects could not be located.\n\n"));
1498 } else load_rte_defs(); // file errors shown inside
1499 }
1500
1501 cleanup1:
1502
1503 if (badkeymap) {
1504 for (i = 0; i < prefs->rte_keys_virtual; i++) {
1505 lives_free(badkeymap[i]);
1506 }
1507
1508 lives_free(badkeymap);
1509 }
1510 lives_freep((void **)&keymap_file); // frees keymap_file2 if applicable
1511 lives_freep((void **)&keymap_file3);
1512 lives_freep((void **)&def_modes);
1513 if (mainw->ce_thumbs) ce_thumbs_reset_combos();
1514 if (rte_window) check_clear_all_button();
1515
1516 return FALSE;
1517 }
1518
1519
on_rte_info_clicked(LiVESButton * button,livespointer user_data)1520 void on_rte_info_clicked(LiVESButton * button, livespointer user_data) {
1521 weed_plant_t *filter;
1522
1523 LiVESWidget *dialog;
1524
1525 LiVESWidget *vbox;
1526 LiVESWidget *hbox;
1527 LiVESWidget *label;
1528 LiVESWidget *textview;
1529 LiVESWidget *scrolledwindow;
1530 LiVESWidget *ok_button;
1531
1532 char *filter_name, *filter_author, *filter_copyright;
1533 char *filter_extra_authors = NULL;
1534 char *filter_description;
1535 char *url, *license, *type;
1536 char *plugin_name, *plname, *package_name;
1537 char *tmp;
1538
1539 boolean has_desc = FALSE;
1540 boolean has_url = FALSE;
1541 boolean has_license = FALSE;
1542 boolean has_copyright = FALSE;
1543
1544 int filter_version;
1545 int weed_error;
1546
1547 int key_mode = LIVES_POINTER_TO_INT(user_data);
1548 int modes = rte_getmodespk();
1549 int key = (int)(key_mode / modes);
1550 int mode = key_mode - key * modes;
1551 int window_width = RFX_WINSIZE_H;
1552
1553 ////////////////////////
1554
1555 if (!rte_keymode_valid(key + 1, mode, TRUE)) return;
1556
1557 type = rte_keymode_get_type(key + 1, mode);
1558
1559 plugin_name = rte_keymode_get_plugin_name(key + 1, mode);
1560 filter = rte_keymode_get_filter(key + 1, mode);
1561 filter_name = weed_get_string_value(filter, WEED_LEAF_NAME, &weed_error);
1562 package_name = weed_filter_get_package_name(filter);
1563 filter_author = weed_get_string_value(filter, WEED_LEAF_AUTHOR, &weed_error);
1564 if (weed_plant_has_leaf(filter, WEED_LEAF_EXTRA_AUTHORS)) filter_extra_authors = weed_get_string_value(filter,
1565 WEED_LEAF_EXTRA_AUTHORS, &weed_error);
1566 if (weed_plant_has_leaf(filter, WEED_LEAF_COPYRIGHT)) {
1567 filter_copyright = weed_get_string_value(filter, WEED_LEAF_COPYRIGHT, &weed_error);
1568 has_copyright = TRUE;
1569 }
1570 if (weed_plant_has_leaf(filter, WEED_LEAF_DESCRIPTION)) {
1571 filter_description = weed_get_string_value(filter, WEED_LEAF_DESCRIPTION, &weed_error);
1572 has_desc = TRUE;
1573 }
1574 if (weed_plant_has_leaf(filter, WEED_LEAF_URL)) {
1575 url = weed_get_string_value(filter, WEED_LEAF_URL, &weed_error);
1576 has_url = TRUE;
1577 }
1578
1579 if (weed_plant_has_leaf(filter, WEED_LEAF_LICENSE)) {
1580 license = weed_get_string_value(filter, WEED_LEAF_LICENSE, &weed_error);
1581 has_license = TRUE;
1582 }
1583
1584 filter_version = weed_get_int_value(filter, WEED_LEAF_VERSION, &weed_error);
1585
1586 tmp = lives_strdup_printf(_("Information for %s"), filter_name);
1587
1588 dialog = lives_standard_dialog_new(tmp, FALSE, RTE_INFO_WIDTH, RTE_INFO_HEIGHT);
1589
1590 lives_free(tmp);
1591
1592 vbox = lives_dialog_get_content_area(LIVES_DIALOG(dialog));
1593
1594 widget_opts.justify = LIVES_JUSTIFY_CENTER;
1595 label = lives_standard_label_new((tmp = lives_strdup_printf(_("Effect name: %s"), filter_name)));
1596 lives_free(tmp);
1597 lives_box_pack_start(LIVES_BOX(vbox), label, TRUE, FALSE, widget_opts.packing_height);
1598
1599 label = lives_standard_label_new((tmp = lives_strdup_printf(_("Type: %s"), type)));
1600 lives_free(tmp);
1601 lives_box_pack_start(LIVES_BOX(vbox), label, TRUE, FALSE, widget_opts.packing_height);
1602
1603 plname = lives_strdup_printf("%s.%s", plugin_name, DLL_NAME);
1604 label = lives_standard_label_new((tmp = lives_strdup_printf(_("Plugin name: %s"), plname)));
1605 lives_free(tmp); lives_free(plname);
1606 lives_box_pack_start(LIVES_BOX(vbox), label, TRUE, FALSE, widget_opts.packing_height);
1607
1608 if (package_name) {
1609 label = lives_standard_label_new((tmp = lives_strdup_printf(_("Package name: %s"), package_name)));
1610 lives_free(tmp);
1611 lives_box_pack_start(LIVES_BOX(vbox), label, TRUE, FALSE, widget_opts.packing_height);
1612 }
1613
1614 label = lives_standard_label_new((tmp = lives_strdup_printf(_("Author: %s"), filter_author)));
1615 lives_free(tmp);
1616 lives_box_pack_start(LIVES_BOX(vbox), label, TRUE, FALSE, widget_opts.packing_height);
1617
1618 if (filter_extra_authors) {
1619 label = lives_standard_label_new((tmp = lives_strdup_printf(_("and: %s"), filter_extra_authors)));
1620 lives_free(tmp);
1621 lives_box_pack_start(LIVES_BOX(vbox), label, TRUE, FALSE, widget_opts.packing_height);
1622 }
1623
1624 if (has_url) {
1625 label = lives_standard_label_new((tmp = lives_strdup_printf(_("URL: %s"), url)));
1626 lives_free(tmp);
1627 lives_box_pack_start(LIVES_BOX(vbox), label, TRUE, FALSE, widget_opts.packing_height);
1628 }
1629
1630 label = lives_standard_label_new((tmp = lives_strdup_printf(_("Version: %d"), filter_version)));
1631 lives_free(tmp);
1632 lives_box_pack_start(LIVES_BOX(vbox), label, TRUE, FALSE, widget_opts.packing_height);
1633
1634 if (has_desc) {
1635 hbox = lives_hbox_new(FALSE, widget_opts.packing_width);
1636 lives_box_pack_start(LIVES_BOX(vbox), hbox, TRUE, FALSE, widget_opts.packing_height);
1637
1638 label = lives_standard_label_new(_("Description: "));
1639 lives_box_pack_start(LIVES_BOX(hbox), label, FALSE, FALSE, widget_opts.packing_height);
1640
1641 widget_opts.justify = LIVES_JUSTIFY_DEFAULT;
1642 textview = lives_standard_text_view_new(filter_description, NULL);
1643 widget_opts.justify = LIVES_JUSTIFY_CENTER;
1644
1645 widget_opts.expand = LIVES_EXPAND_EXTRA_WIDTH | LIVES_EXPAND_DEFAULT_HEIGHT;
1646 scrolledwindow = lives_standard_scrolled_window_new(window_width * 2, RFX_WINSIZE_V / 2, textview);
1647 lives_box_pack_start(LIVES_BOX(hbox), scrolledwindow, TRUE, TRUE, widget_opts.packing_height);
1648 widget_opts.expand = LIVES_EXPAND_DEFAULT;
1649 if (palette->style & STYLE_1) {
1650 lives_widget_set_text_color(textview, LIVES_WIDGET_STATE_NORMAL, &palette->normal_fore);
1651 lives_widget_set_base_color(textview, LIVES_WIDGET_STATE_NORMAL, &palette->normal_back);
1652 lives_widget_set_bg_color(lives_bin_get_child(LIVES_BIN(scrolledwindow)),
1653 LIVES_WIDGET_STATE_NORMAL, &palette->nice1);
1654 }
1655 }
1656
1657 if (has_license) {
1658 label = lives_standard_label_new((tmp = lives_strdup_printf(_("License: %s"), license)));
1659 lives_free(tmp);
1660 lives_box_pack_start(LIVES_BOX(vbox), label, TRUE, FALSE, widget_opts.packing_height);
1661 }
1662
1663 if (has_copyright) {
1664 label = lives_standard_label_new((tmp = lives_strdup_printf(_("Copyright: %s"), filter_copyright)));
1665 lives_free(tmp);
1666 lives_box_pack_start(LIVES_BOX(vbox), label, TRUE, FALSE, widget_opts.packing_height);
1667 }
1668
1669 widget_opts.justify = LIVES_JUSTIFY_DEFAULT;
1670
1671 add_fill_to_box(LIVES_BOX(vbox));
1672
1673 ok_button = lives_dialog_add_button_from_stock(LIVES_DIALOG(dialog), LIVES_STOCK_CLOSE, _("_Close Window"),
1674 LIVES_RESPONSE_OK);
1675
1676 lives_button_grab_default_special(ok_button);
1677
1678 lives_signal_connect(LIVES_GUI_OBJECT(ok_button), LIVES_WIDGET_CLICKED_SIGNAL,
1679 LIVES_GUI_CALLBACK(lives_general_button_clicked), NULL);
1680
1681 lives_free(filter_name);
1682 lives_free(filter_author);
1683 lives_freep((void **)&filter_extra_authors);
1684 lives_freep((void **)&package_name);
1685 if (has_desc) lives_free(filter_description);
1686 if (has_url) lives_free(url);
1687 if (has_license) lives_free(license);
1688 if (has_copyright) lives_free(filter_copyright);
1689 lives_free(plugin_name);
1690 lives_free(type);
1691
1692 lives_widget_show_all(dialog);
1693 lives_window_center(LIVES_WINDOW(dialog));
1694 }
1695
1696
on_clear_clicked(LiVESButton * button,livespointer user_data)1697 void on_clear_clicked(LiVESButton * button, livespointer user_data) {
1698 // this is for the "delete" buttons, c.f. clear_all
1699
1700 int idx = LIVES_POINTER_TO_INT(user_data);
1701 int modes = rte_getmodespk();
1702 int key = (int)(idx / modes);
1703 int mode = idx - key * modes;
1704
1705 int newmode;
1706
1707 register int i;
1708
1709 weed_delete_effectkey(key + 1, mode);
1710
1711 pconx_delete(FX_DATA_WILDCARD, FX_DATA_WILDCARD, FX_DATA_WILDCARD, key, mode, FX_DATA_WILDCARD);
1712 pconx_delete(key, mode, FX_DATA_WILDCARD, -1, FX_DATA_WILDCARD, FX_DATA_WILDCARD);
1713
1714 cconx_delete(FX_DATA_WILDCARD, FX_DATA_WILDCARD, FX_DATA_WILDCARD, key, mode, FX_DATA_WILDCARD);
1715 cconx_delete(key, mode, FX_DATA_WILDCARD, FX_DATA_WILDCARD, FX_DATA_WILDCARD, FX_DATA_WILDCARD);
1716
1717 newmode = rte_key_getmode(key + 1);
1718
1719 if (mainw->ce_thumbs) ce_thumbs_set_mode_combo(key, newmode);
1720
1721 if (rte_window) {
1722 rtew_set_mode_radio(key, newmode);
1723 }
1724
1725 for (i = mode; i < rte_getmodespk() - 1; i++) {
1726 pconx_remap_mode(key, i + 1, i);
1727 cconx_remap_mode(key, i + 1, i);
1728
1729 if (rte_window) {
1730 int fx_idx = rte_keymode_get_filter_idx(key, mode);
1731 idx = key * modes + i;
1732 rtew_combo_set_text(key, i, lives_entry_get_text(LIVES_ENTRY(combo_entries[idx + 1])));
1733
1734 if (fx_idx != -1) {
1735 char *hashname = (char *)lives_list_nth_data(hash_list, fx_idx);
1736 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(combos[idx]), "hashname", hashname);
1737 } else lives_widget_object_set_data(LIVES_WIDGET_OBJECT(combos[idx]), "hashname", empty_string);
1738
1739 // set parameters button sensitive/insensitive
1740 set_param_and_con_buttons(key, i);
1741 }
1742 }
1743 idx++;
1744
1745 if (rte_window) {
1746 rtew_combo_set_text(key, i, "");
1747 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(combos[idx]), "hashname", empty_string);
1748
1749 // set parameters button sensitive/insensitive
1750 set_param_and_con_buttons(key, i);
1751 }
1752
1753 if (!rte_keymode_valid(key + 1, 0, TRUE)) {
1754 if (rte_window) rtew_set_keych(key, FALSE);
1755 if (mainw->ce_thumbs) ce_thumbs_set_keych(key, FALSE);
1756 }
1757 if (rte_window) check_clear_all_button();
1758
1759 if (mainw->ce_thumbs) ce_thumbs_reset_combo(key);
1760 }
1761
1762
on_datacon_clicked(LiVESButton * button,livespointer user_data)1763 static void on_datacon_clicked(LiVESButton * button, livespointer user_data) {
1764 int idx = LIVES_POINTER_TO_INT(user_data);
1765 int modes = rte_getmodespk();
1766 int key = (int)(idx / modes);
1767 int mode = idx - key * modes;
1768
1769 //if (datacon_dialog!=NULL) on_datacon_cancel_clicked(NULL,NULL);
1770 datacon_dialog = make_datacon_window(key, mode);
1771 }
1772
1773
check_string_choice_params(weed_plant_t * inst)1774 void check_string_choice_params(weed_plant_t *inst) {
1775 int nparams;
1776 weed_plant_t **in_params = weed_instance_get_in_params(inst, &nparams);
1777 weed_plant_t *gui, *tgui;
1778 for (int i = 0; i < nparams; i++) {
1779 if ((gui = weed_param_get_gui(in_params[i], FALSE)) != NULL && weed_plant_has_leaf(gui, WEED_LEAF_CHOICES)) {
1780 tgui = weed_paramtmpl_get_gui(weed_param_get_template(in_params[i]), TRUE);
1781 weed_leaf_copy(tgui, WEED_LEAF_CHOICES, gui, WEED_LEAF_CHOICES);
1782 }
1783 }
1784 }
1785
1786
on_params_clicked(LiVESButton * button,livespointer user_data)1787 static void on_params_clicked(LiVESButton * button, livespointer user_data) {
1788 int idx = LIVES_POINTER_TO_INT(user_data);
1789 int modes = rte_getmodespk();
1790 int key = (int)(idx / modes);
1791 int mode = idx - key * modes;
1792
1793 weed_plant_t *inst;
1794 lives_rfx_t *rfx;
1795
1796 filter_mutex_lock(key);
1797 if ((inst = rte_keymode_get_instance(key + 1, mode)) == NULL) {
1798 // create a new detached instance for the dialog
1799 weed_plant_t *filter = rte_keymode_get_filter(key + 1, mode);
1800 if (!filter) {
1801 filter_mutex_unlock(key);
1802 return;
1803 }
1804 inst = weed_instance_from_filter(filter);
1805 weed_set_boolean_value(inst, WEED_LEAF_HOST_NORECORD, WEED_TRUE);
1806
1807 // do some fiddly stuff to show the key defs.
1808 filter_mutex_unlock(key);
1809 weed_reinit_effect(inst, TRUE);
1810 filter_mutex_lock(key);
1811 check_string_choice_params(inst);
1812 apply_key_defaults(inst, key, mode);
1813 filter_mutex_unlock(key);
1814 weed_reinit_effect(inst, TRUE);
1815 filter_mutex_lock(key);
1816 } else weed_instance_ref(inst);
1817
1818 filter_mutex_unlock(key);
1819
1820 if (fx_dialog[1]) {
1821 lives_widget_destroy(fx_dialog[1]->dialog);
1822 rfx = fx_dialog[1]->rfx;
1823 on_paramwindow_button_clicked(NULL, rfx);
1824 lives_freep((void **)&fx_dialog[1]);
1825 }
1826
1827 rfx = weed_to_rfx(inst, FALSE);
1828 rfx->min_frames = -1;
1829 keyw = key;
1830 modew = mode;
1831
1832 widget_opts.non_modal = TRUE;
1833 on_fx_pre_activate(rfx, TRUE, NULL);
1834 widget_opts.non_modal = FALSE;
1835
1836 // record the key so we know whose parameters to record later
1837 weed_set_int_value((weed_plant_t *)rfx->source, WEED_LEAF_HOST_KEY, key);
1838
1839 fx_dialog[1]->key = key;
1840 fx_dialog[1]->mode = mode;
1841 fx_dialog[1]->rfx = rfx;
1842 weed_instance_unref(inst);
1843 }
1844
1845
on_rtew_delete_event(LiVESWidget * widget,LiVESXEventDelete * event,livespointer user_data)1846 boolean on_rtew_delete_event(LiVESWidget * widget, LiVESXEventDelete * event, livespointer user_data) {
1847 old_rte_keys_virtual = prefs->rte_keys_virtual;
1848 lives_widget_set_sensitive(mainw->mt_menu, TRUE);
1849 lives_widget_set_sensitive(mainw->rte_defs_menu, TRUE);
1850 if (!user_data) {
1851 // first time around we come here, and just hide the window
1852 if (mainw->play_window && !mainw->fs && (prefs->play_monitor == widget_opts.monitor + 1 || capable->nmonitors == 1)) {
1853 lives_window_set_transient_for(LIVES_WINDOW(mainw->play_window), get_transient_full());
1854 }
1855 lives_widget_hide(rte_window);
1856 rte_window_is_hidden = TRUE;
1857 } else {
1858 // when we reshow it we check if the number of fx keys has changed. If so we come back to this branch
1859 // and recreate the window from scratch
1860 lives_list_free_all(&hash_list);
1861 lives_list_free_all(&name_list);
1862 lives_list_free_all(&extended_name_list);
1863
1864 lives_free(key_checks);
1865 lives_free(key_grabs);
1866 lives_free(mode_radios);
1867 lives_free(combo_entries);
1868 lives_free(combos);
1869 lives_free(ch_fns);
1870 lives_free(mode_ra_fns);
1871 lives_free(gr_fns);
1872 lives_free(nlabels);
1873 lives_free(type_labels);
1874 lives_free(info_buttons);
1875 lives_free(param_buttons);
1876 lives_free(conx_buttons);
1877 lives_free(clear_buttons);
1878 }
1879 return FALSE;
1880 }
1881
1882
on_rtew_ok_clicked(LiVESButton * button,livespointer user_data)1883 static boolean on_rtew_ok_clicked(LiVESButton * button, livespointer user_data) {
1884 on_rtew_delete_event(NULL, NULL, NULL);
1885 return TRUE;
1886 }
1887
1888
do_mix_error(void)1889 LIVES_LOCAL_INLINE void do_mix_error(void) {
1890 widget_opts.non_modal = TRUE;
1891 do_error_dialog(_("\n\nThis version of LiVES does not allowing mixing of "
1892 "generators and non-generators on the same key.\n\n"));
1893 widget_opts.non_modal = FALSE;
1894 return;
1895 }
1896
1897
1898 enum {
1899 EXTENDED_NAME_COLUMN,
1900 NAME_COLUMN,
1901 HASH_COLUMN,
1902 NUM_COLUMNS
1903 };
1904
rtew_combo_set_text(int key,int mode,const char * txt)1905 void rtew_combo_set_text(int key, int mode, const char *txt) {
1906 // key is zero based
1907 int key_mode = key * rte_getmodespk() + mode;
1908 lives_entry_set_text(LIVES_ENTRY(combo_entries[key_mode]), txt);
1909 type_label_set_text(key, mode);
1910 }
1911
1912
fx_changed(LiVESCombo * combo,livespointer user_data)1913 void fx_changed(LiVESCombo * combo, livespointer user_data) {
1914 LiVESTreeIter iter1;
1915 LiVESTreeModel *model;
1916
1917 char *txt;
1918 char *tmp;
1919 char *hashname1;
1920 char *hashname2 = (char *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(combo), "hashname");
1921
1922 int key_mode = LIVES_POINTER_TO_INT(user_data);
1923 int modes = rte_getmodespk();
1924 int key = (int)(key_mode / modes);
1925 int mode = key_mode - key * modes;
1926
1927 int i, error;
1928
1929 if (lives_combo_get_active_index(combo) == -1) return; // -1 is returned after we set our own text (without the type)
1930
1931 lives_combo_get_active_iter(combo, &iter1);
1932 model = lives_combo_get_model(combo);
1933
1934 lives_tree_model_get(model, &iter1, HASH_COLUMN, &hashname1, -1);
1935 if (!hashname1) {
1936 lives_entry_set_text(LIVES_ENTRY(combo_entries[key_mode]), (tmp = rte_keymode_get_filter_name(key + 1, mode, FALSE)));
1937 lives_free(tmp);
1938 return;
1939 }
1940
1941 if (!strcmp(hashname1, hashname2)) {
1942 lives_free(hashname1);
1943 return;
1944 }
1945
1946 if (!rte_keymode_valid(key + 1, mode, TRUE)) {
1947 for (i = mode - 1; i >= 0; i--) {
1948 if (rte_keymode_valid(key + 1, i, TRUE)) {
1949 mode = i + 1;
1950 i = -1;
1951 }
1952 if (i == 0) mode = 0;
1953 }
1954 }
1955
1956 lives_widget_grab_focus(combo_entries[key_mode]);
1957
1958 if ((error = rte_switch_keymode(key + 1, mode, hashname1)) < 0) {
1959 lives_entry_set_text(LIVES_ENTRY(combo_entries[key_mode]), (tmp = rte_keymode_get_filter_name(key + 1, mode, FALSE)));
1960 lives_free(tmp);
1961
1962 if (error == -2) do_mix_error();
1963 if (error == -1) {
1964 d_print(_("LiVES could not locate the effect %s.\n"), rte_keymode_get_filter_name(key + 1, mode, FALSE));
1965 }
1966 return;
1967 }
1968
1969 // prevents a segfault
1970 lives_combo_get_active_iter(combo, &iter1);
1971 model = lives_combo_get_model(combo);
1972
1973 lives_tree_model_get(model, &iter1, NAME_COLUMN, &txt, -1);
1974 rtew_combo_set_text(key, mode, txt);
1975 lives_free(txt);
1976
1977 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(combo), "hashname", hashname1);
1978
1979 // set parameters button sensitive/insensitive
1980 set_param_and_con_buttons(key, mode);
1981
1982 check_clear_all_button();
1983
1984 pconx_delete(FX_DATA_WILDCARD, FX_DATA_WILDCARD, FX_DATA_WILDCARD, key, mode, FX_DATA_WILDCARD_KEEP_ACTIVATED);
1985 pconx_delete(key, mode, FX_DATA_WILDCARD, FX_DATA_WILDCARD, FX_DATA_WILDCARD, FX_DATA_WILDCARD);
1986
1987 cconx_delete(FX_DATA_WILDCARD, FX_DATA_WILDCARD, FX_DATA_WILDCARD, key, mode, FX_DATA_WILDCARD);
1988 cconx_delete(key, mode, FX_DATA_WILDCARD, FX_DATA_WILDCARD, FX_DATA_WILDCARD, FX_DATA_WILDCARD);
1989
1990 if (mainw->ce_thumbs) ce_thumbs_reset_combos();
1991 }
1992
1993 static LiVESTreeStore *tstore = NULL;
1994
rte_window_fx_model(void)1995 static LiVESTreeModel *rte_window_fx_model(void) {
1996 weed_plant_t *pinfo;
1997 LiVESTreeIter iter1, iter2, iter3;
1998
1999 LiVESList *list = extended_name_list;
2000 LiVESList *pname_list = name_list;
2001 LiVESList *phash_list = hash_list;
2002
2003 lives_fx_cat_t cat;
2004
2005 char *pkg = NULL, *pkgstring, *fxname, *typestr;
2006
2007 int fx_idx = 0;
2008
2009 if (tstore) return (LiVESTreeModel *)tstore;
2010
2011 tstore = lives_tree_store_new(NUM_COLUMNS, LIVES_COL_TYPE_STRING, LIVES_COL_TYPE_STRING, LIVES_COL_TYPE_STRING);
2012 while (list) {
2013 weed_plant_t *filter = get_weed_filter(weed_get_idx_for_hashname((char *)phash_list->data, TRUE));
2014 if (!prefs->show_dev_opts && ((weed_filter_hints_unstable(filter)
2015 && !prefs->unstable_fx) ||
2016 weed_get_boolean_value(filter, WEED_LEAF_HOST_MENU_HIDE, NULL) == WEED_TRUE
2017 || ((enabled_in_channels(filter, FALSE) > 1 &&
2018 !has_video_chans_in(filter, FALSE)) ||
2019 (weed_filter_hints_hidden(filter)
2020 || weed_filter_is_converter(filter))
2021 || enabled_in_channels(filter, TRUE) == 1000000))) {
2022 list = list->next;
2023 fx_idx++;
2024 pname_list = pname_list->next;
2025 phash_list = phash_list->next;
2026 continue; // skip audio transitions, compositors and hidden entries
2027 }
2028
2029 fxname = lives_strdup((const char *)pname_list->data);
2030 cat = weed_filter_categorise(filter,
2031 enabled_in_channels(filter, TRUE),
2032 enabled_out_channels(filter, TRUE));
2033 typestr = lives_fx_cat_to_text(cat, TRUE);
2034
2035 pinfo = weed_get_plantptr_value(filter, WEED_LEAF_PLUGIN_INFO, NULL);
2036 if (weed_plant_has_leaf(pinfo, WEED_LEAF_PACKAGE_NAME))
2037 pkgstring = weed_get_string_value(pinfo, WEED_LEAF_PACKAGE_NAME, NULL);
2038 else pkgstring = NULL;
2039
2040 if (pkgstring) {
2041 // package effect
2042 if (pkg && lives_strcmp(pkg, pkgstring)) {
2043 // new package
2044 lives_freep((void **)&pkg);
2045 }
2046
2047 if (!pkg) {
2048 // add package to menu
2049 pkg = pkgstring;
2050
2051 /* TRANSLATORS: example " - LADSPA plugins -" */
2052 pkgstring = lives_strdup_printf(_(" - %s plugins -"), pkg);
2053 lives_tree_store_prepend(tstore, &iter1, NULL);
2054 lives_tree_store_set(tstore, &iter1, EXTENDED_NAME_COLUMN, pkgstring, -1);
2055 lives_free(pkgstring);
2056 }
2057 // add to package submenu
2058
2059 // get a new or existing iterator for the category (set in iter2)
2060 lives_tree_store_find_iter(tstore, EXTENDED_NAME_COLUMN, typestr, &iter1, &iter2);
2061 lives_tree_store_append(tstore, &iter3, &iter2);
2062 lives_tree_store_set(tstore, &iter3, EXTENDED_NAME_COLUMN, list->data, NAME_COLUMN, fxname,
2063 HASH_COLUMN, lives_list_nth_data(hash_list, fx_idx), -1);
2064 } else {
2065 //if (pkg) lives_freep((void **)&pkg);
2066 // get a new or existing iterator for the category
2067 lives_tree_store_find_iter(tstore, EXTENDED_NAME_COLUMN, typestr, NULL, &iter1);
2068
2069 lives_tree_store_append(tstore, &iter2, &iter1); /* Acquire an iterator */
2070 lives_tree_store_set(tstore, &iter2, EXTENDED_NAME_COLUMN, list->data, NAME_COLUMN, fxname,
2071 HASH_COLUMN, lives_list_nth_data(hash_list, fx_idx), -1);
2072 }
2073 lives_free(fxname);
2074 lives_free(typestr);
2075
2076 list = list->next;
2077 fx_idx++;
2078 pname_list = pname_list->next;
2079 phash_list = phash_list->next;
2080 }
2081
2082 lives_freep((void **)&pkg);
2083
2084 return (LiVESTreeModel *)tstore;
2085 }
2086
2087
create_rte_window(void)2088 LiVESWidget *create_rte_window(void) {
2089 LiVESWidget *irte_window = rte_window;
2090 LiVESWidget *table;
2091 LiVESWidget *hbox;
2092 LiVESWidget *hbox2;
2093
2094 LiVESWidget *vbox, *vbox2;
2095 LiVESWidget *label;
2096 LiVESWidget *combo;
2097 LiVESWidget *ok_button;
2098 LiVESWidget *top_vbox;
2099 LiVESWidget *hbuttonbox;
2100
2101 LiVESWidget *scrolledwindow;
2102
2103 LiVESSList *mode_group = NULL;
2104 LiVESSList *grab_group = NULL;
2105
2106 LiVESAccelGroup *rtew_accel_group;
2107
2108 LiVESTreeModel *model;
2109
2110 char *tmp, *tmp2, *labelt;
2111
2112 int modes = rte_getmodespk();
2113
2114 int idx;
2115
2116 int winsize_h;
2117 int winsize_v;
2118
2119 register int i, j;
2120
2121 ///////////////////////////////////////////////////////////////////////////
2122
2123 lives_set_cursor_style(LIVES_CURSOR_BUSY, NULL);
2124 lives_widget_context_update();
2125 mainw->no_context_update = TRUE;
2126
2127 winsize_h = GUI_SCREEN_WIDTH - SCR_WIDTH_SAFETY;
2128 winsize_v = GUI_SCREEN_HEIGHT - SCR_HEIGHT_SAFETY;
2129
2130 if (irte_window) {
2131 if (prefs->rte_keys_virtual != old_rte_keys_virtual) {
2132 // number of fx keys changed, rebuild the window
2133 mainw->no_context_update = FALSE;
2134 return refresh_rte_window();
2135 }
2136 goto rte_window_ready;
2137 }
2138
2139 key_checks = (LiVESWidget **)lives_malloc((prefs->rte_keys_virtual) * sizeof(LiVESWidget *));
2140 key_grabs = (LiVESWidget **)lives_malloc((prefs->rte_keys_virtual) * sizeof(LiVESWidget *));
2141 mode_radios = (LiVESWidget **)lives_malloc((prefs->rte_keys_virtual) * modes * sizeof(LiVESWidget *));
2142 combo_entries = (LiVESWidget **)lives_malloc((prefs->rte_keys_virtual) * modes * sizeof(LiVESWidget *));
2143 combos = (LiVESWidget **)lives_malloc((prefs->rte_keys_virtual) * modes * sizeof(LiVESWidget *));
2144 info_buttons = (LiVESWidget **)lives_malloc((prefs->rte_keys_virtual) * modes * sizeof(LiVESWidget *));
2145 param_buttons = (LiVESWidget **)lives_malloc((prefs->rte_keys_virtual) * modes * sizeof(LiVESWidget *));
2146 conx_buttons = (LiVESWidget **)lives_malloc((prefs->rte_keys_virtual) * modes * sizeof(LiVESWidget *));
2147 clear_buttons = (LiVESWidget **)lives_malloc((prefs->rte_keys_virtual) * modes * sizeof(LiVESWidget *));
2148 nlabels = (LiVESWidget **)lives_malloc((prefs->rte_keys_virtual) * modes * sizeof(LiVESWidget *));
2149 type_labels = (LiVESWidget **)lives_malloc((prefs->rte_keys_virtual) * modes * sizeof(LiVESWidget *));
2150
2151 ch_fns = (ulong *)lives_malloc((prefs->rte_keys_virtual) * sizeof(ulong));
2152 gr_fns = (ulong *)lives_malloc((prefs->rte_keys_virtual) * sizeof(ulong));
2153 mode_ra_fns = (ulong *)lives_malloc((prefs->rte_keys_virtual) * modes * sizeof(ulong));
2154
2155 irte_window = lives_window_new(LIVES_WINDOW_TOPLEVEL);
2156 lives_window_set_transient_for(LIVES_WINDOW(irte_window), LIVES_WINDOW(LIVES_MAIN_WINDOW_WIDGET));
2157
2158 if (palette->style & STYLE_1) {
2159 lives_widget_set_bg_color(irte_window, LIVES_WIDGET_STATE_NORMAL, &palette->menu_and_bars);
2160 lives_widget_set_text_color(irte_window, LIVES_WIDGET_STATE_NORMAL, &palette->menu_and_bars_fore);
2161 }
2162 lives_window_set_title(LIVES_WINDOW(irte_window), _("Real Time Effect Mapping"));
2163 lives_window_add_accel_group(LIVES_WINDOW(irte_window), mainw->accel_group);
2164
2165 table = lives_table_new(prefs->rte_keys_virtual, modes + 1, FALSE);
2166
2167 lives_table_set_row_spacings(LIVES_TABLE(table), 16 * widget_opts.scale);
2168 lives_table_set_col_spacings(LIVES_TABLE(table), 4 * widget_opts.scale);
2169
2170 // dummy button for "no grab", we dont show this...there is a button instead
2171 dummy_radio = lives_radio_button_new(grab_group);
2172 grab_group = lives_radio_button_get_group(LIVES_RADIO_BUTTON(dummy_radio));
2173 lives_widget_set_no_show_all(dummy_radio, TRUE);
2174
2175 if (!name_list) name_list = weed_get_all_names(FX_LIST_NAME);
2176 if (!extended_name_list) extended_name_list = weed_get_all_names(FX_LIST_EXTENDED_NAME);
2177 if (!hash_list) hash_list = weed_get_all_names(FX_LIST_HASHNAME);
2178
2179 model = rte_window_fx_model();
2180
2181 for (i = 0; i < prefs->rte_keys_virtual * modes; i++) {
2182 // create combo entry model
2183 combos[i] = NULL;
2184 }
2185
2186 for (i = 0; i < prefs->rte_keys_virtual; i++) {
2187 hbox = lives_hbox_new(FALSE, 0);
2188 lives_table_attach(LIVES_TABLE(table), hbox, i, i + 1, 0, 1,
2189 (LiVESAttachOptions)(LIVES_EXPAND | LIVES_FILL),
2190 (LiVESAttachOptions)(LIVES_EXPAND | LIVES_FILL), 0, 0);
2191 lives_container_set_border_width(LIVES_CONTAINER(hbox), widget_opts.border_width);
2192
2193 if (i < 9) labelt = lives_strdup_printf("%d", i + 1);
2194 else {
2195 switch (i) {
2196 case 9:
2197 labelt = (_("minus")); break;
2198 case 10:
2199 labelt = (_("equals")); break;
2200 default:
2201 labelt = lives_strdup("????");
2202 break;
2203 }
2204 }
2205
2206 widget_opts.use_markup = TRUE;
2207 label = lives_standard_label_new((tmp = lives_strdup_printf(_("<big><b>Ctrl-%s</b></big>"), labelt)));
2208 widget_opts.use_markup = FALSE;
2209 lives_free(labelt);
2210 lives_free(tmp);
2211
2212 lives_box_pack_start(LIVES_BOX(hbox), label, TRUE, FALSE, widget_opts.packing_width);
2213
2214 hbox2 = lives_hbox_new(FALSE, 0);
2215
2216 //key_checks[i] = lives_standard_check_button_new(_("Key active"), (mainw->rte & (GU641 << i)), LIVES_BOX(hbox2), NULL);
2217 key_checks[i] = lives_standard_switch_new(_("Key active"), (mainw->rte & (GU641 << i)), LIVES_BOX(hbox2), NULL);
2218
2219 lives_box_pack_start(LIVES_BOX(hbox), hbox2, FALSE, FALSE, widget_opts.packing_width);
2220
2221 lives_toggle_button_set_active(LIVES_TOGGLE_BUTTON(key_checks[i]), mainw->rte & (GU641 << i));
2222 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(key_checks[i]), "active",
2223 LIVES_INT_TO_POINTER(lives_toggle_button_get_active(LIVES_TOGGLE_BUTTON(key_checks[i]))));
2224
2225 ch_fns[i] = lives_signal_connect_after(LIVES_GUI_OBJECT(key_checks[i]), LIVES_WIDGET_TOGGLED_SIGNAL,
2226 LIVES_GUI_CALLBACK(rte_on_off_callback_hook), LIVES_INT_TO_POINTER(i + 1));
2227
2228 hbox2 = lives_hbox_new(FALSE, 0);
2229 lives_box_pack_start(LIVES_BOX(hbox), hbox2, FALSE, FALSE, widget_opts.packing_width);
2230
2231 key_grabs[i] = lives_standard_radio_button_new((tmp = (_("Key grab"))), &grab_group, LIVES_BOX(hbox2),
2232 (tmp2 = (_("Grab keyboard for this effect key"))));
2233 lives_free(tmp);
2234 lives_free(tmp2);
2235 lives_toggle_button_set_active(LIVES_TOGGLE_BUTTON(key_grabs[i]), mainw->rte_keys == i);
2236
2237 gr_fns[i] = lives_signal_connect_after(LIVES_GUI_OBJECT(key_grabs[i]), LIVES_WIDGET_TOGGLED_SIGNAL,
2238 LIVES_GUI_CALLBACK(grabkeys_callback_hook), LIVES_INT_TO_POINTER(i));
2239
2240 mode_group = NULL;
2241
2242 for (j = 0; j < modes; j++) {
2243 idx = i * modes + j;
2244 hbox = lives_hbox_new(FALSE, 0);
2245 lives_table_attach(LIVES_TABLE(table), hbox, i, i + 1, j + 1, j + 2,
2246 (LiVESAttachOptions)(LIVES_EXPAND | LIVES_FILL),
2247 (LiVESAttachOptions)(LIVES_EXPAND | LIVES_FILL), 0, 0);
2248 lives_container_set_border_width(LIVES_CONTAINER(hbox), widget_opts.border_width * 1.5);
2249
2250 hbox2 = lives_hbox_new(FALSE, 0);
2251
2252 lives_box_pack_start(LIVES_BOX(hbox), hbox2, FALSE, FALSE, widget_opts.packing_width);
2253
2254 mode_radios[idx] = lives_standard_radio_button_new(_("Mode active"), &mode_group, LIVES_BOX(hbox2), NULL);
2255
2256 if (rte_key_getmode(i + 1) == j) lives_toggle_button_set_active(LIVES_TOGGLE_BUTTON(mode_radios[idx]), TRUE);
2257
2258 mode_ra_fns[idx] = lives_signal_connect_after(LIVES_GUI_OBJECT(mode_radios[idx]), LIVES_WIDGET_TOGGLED_SIGNAL,
2259 LIVES_GUI_CALLBACK(rtemode_callback_hook), LIVES_INT_TO_POINTER(idx));
2260
2261
2262 type_labels[idx] = lives_standard_label_new("");
2263
2264 lives_label_set_line_wrap(LIVES_LABEL(type_labels[idx]), TRUE);
2265 lives_label_set_line_wrap_mode(LIVES_LABEL(type_labels[idx]), LINGO_WRAP_WORD_CHAR);
2266 lives_label_seT_lines(LIVES_LABEL(type_labels[idx]), 3);
2267 lives_label_set_ellipsize(LIVES_LABEL(type_labels[idx]), LIVES_ELLIPSIZE_END);
2268
2269 info_buttons[idx] = lives_standard_button_new_with_label(_("Info"),
2270 DEF_BUTTON_WIDTH / 3, DEF_BUTTON_HEIGHT);
2271 param_buttons[idx] = lives_standard_button_new_with_label(_("Set Parameters"),
2272 DEF_BUTTON_WIDTH, DEF_BUTTON_HEIGHT);
2273 lives_widget_set_valign(param_buttons[idx], LIVES_ALIGN_CENTER);
2274 conx_buttons[idx] = lives_standard_button_new_with_label(_("Set Connections"),
2275 DEF_BUTTON_WIDTH, DEF_BUTTON_HEIGHT);
2276 lives_widget_set_valign(conx_buttons[idx], LIVES_ALIGN_CENTER);
2277 clear_buttons[idx] = lives_standard_button_new_with_label(_("Clear"),
2278 DEF_BUTTON_WIDTH / 3, DEF_BUTTON_HEIGHT);
2279
2280 vbox = lives_vbox_new(FALSE, 0);
2281 lives_box_pack_start(LIVES_BOX(hbox), vbox, FALSE, FALSE, 0);
2282
2283 vbox2 = lives_vbox_new(FALSE, 0);
2284 lives_box_pack_end(LIVES_BOX(hbox), vbox2, FALSE, FALSE, widget_opts.packing_width);
2285
2286 lives_container_set_border_width(LIVES_CONTAINER(vbox), 0);
2287
2288 hbox = lives_hbox_new(FALSE, 0);
2289
2290 lives_box_pack_start(LIVES_BOX(vbox), hbox, FALSE, FALSE, widget_opts.packing_height);
2291
2292 nlabels[idx] = lives_standard_label_new(_("Effect name:"));
2293
2294 lives_box_pack_start(LIVES_BOX(hbox), nlabels[idx], FALSE, FALSE, widget_opts.packing_width);
2295
2296 combos[idx] = combo = lives_standard_combo_new_with_model(model, LIVES_BOX(hbox));
2297 lives_combo_set_entry_text_column(LIVES_COMBO(combo), EXTENDED_NAME_COLUMN);
2298
2299 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(combo), "hashname", empty_string);
2300
2301 lives_box_pack_start(LIVES_BOX(vbox2), info_buttons[idx], FALSE, FALSE, widget_opts.packing_height);
2302 lives_box_pack_start(LIVES_BOX(vbox2), clear_buttons[idx], FALSE, FALSE, widget_opts.packing_height);
2303
2304 combo_entries[idx] = lives_combo_get_entry(LIVES_COMBO(combo));
2305
2306 lives_entry_set_text(LIVES_ENTRY(combo_entries[idx]), (tmp = rte_keymode_get_filter_name(i + 1, j, FALSE)));
2307 lives_free(tmp);
2308
2309 lives_entry_set_editable(LIVES_ENTRY(combo_entries[idx]), FALSE);
2310
2311 hbox = lives_hbox_new(FALSE, 0);
2312 lives_box_pack_start(LIVES_BOX(vbox), hbox, FALSE, FALSE, widget_opts.packing_height);
2313
2314 lives_signal_sync_connect(LIVES_GUI_OBJECT(combo), LIVES_WIDGET_CHANGED_SIGNAL,
2315 LIVES_GUI_CALLBACK(fx_changed), LIVES_INT_TO_POINTER(i * rte_getmodespk() + j));
2316
2317 lives_signal_sync_connect(LIVES_GUI_OBJECT(info_buttons[idx]), LIVES_WIDGET_CLICKED_SIGNAL,
2318 LIVES_GUI_CALLBACK(on_rte_info_clicked), LIVES_INT_TO_POINTER(idx));
2319
2320 lives_signal_sync_connect(LIVES_GUI_OBJECT(clear_buttons[idx]), LIVES_WIDGET_CLICKED_SIGNAL,
2321 LIVES_GUI_CALLBACK(on_clear_clicked), LIVES_INT_TO_POINTER(idx));
2322
2323 lives_signal_sync_connect(LIVES_GUI_OBJECT(param_buttons[idx]), LIVES_WIDGET_CLICKED_SIGNAL,
2324 LIVES_GUI_CALLBACK(on_params_clicked), LIVES_INT_TO_POINTER(idx));
2325
2326 lives_signal_sync_connect(LIVES_GUI_OBJECT(conx_buttons[idx]), LIVES_WIDGET_CLICKED_SIGNAL,
2327 LIVES_GUI_CALLBACK(on_datacon_clicked), LIVES_INT_TO_POINTER(idx));
2328
2329 lives_box_pack_start(LIVES_BOX(hbox), type_labels[idx], FALSE, FALSE, widget_opts.packing_width);
2330 lives_box_pack_start(LIVES_BOX(hbox), conx_buttons[idx], FALSE, FALSE, widget_opts.packing_width);
2331 lives_box_pack_start(LIVES_BOX(hbox), param_buttons[idx], FALSE, FALSE, widget_opts.packing_width);
2332
2333 // set parameters button sensitive/insensitive
2334 set_param_and_con_buttons(i, j);
2335 }
2336 }
2337
2338 scrolledwindow = lives_standard_scrolled_window_new(winsize_h, winsize_v, table);
2339
2340 top_vbox = lives_vbox_new(FALSE, 0);
2341
2342 lives_box_pack_start(LIVES_BOX(top_vbox), dummy_radio, FALSE, FALSE, 0);
2343 lives_box_pack_start(LIVES_BOX(top_vbox), scrolledwindow, TRUE, TRUE, widget_opts.packing_height);
2344
2345 lives_container_add(LIVES_CONTAINER(irte_window), top_vbox);
2346
2347 hbuttonbox = lives_hbox_new(FALSE, 0);
2348 lives_box_pack_start(LIVES_BOX(top_vbox), hbuttonbox, FALSE, TRUE, 0);
2349
2350 add_fill_to_box(LIVES_BOX(hbuttonbox));
2351 lives_widget_apply_theme(hbuttonbox, LIVES_WIDGET_STATE_NORMAL);
2352
2353 clear_all_button = lives_dialog_add_button_from_stock(NULL, LIVES_STOCK_CLEAR, _("_Clear all effects"),
2354 LIVES_RESPONSE_RESET);
2355
2356 lives_box_pack_start(LIVES_BOX(hbuttonbox), clear_all_button, TRUE, TRUE, widget_opts.packing_width);
2357
2358 save_keymap_button = lives_dialog_add_button_from_stock(NULL, LIVES_STOCK_SAVE_AS, _("_Save as default keymap"),
2359 LIVES_RESPONSE_ACCEPT);
2360
2361 lives_box_pack_start(LIVES_BOX(hbuttonbox), save_keymap_button, TRUE, TRUE, widget_opts.packing_width);
2362
2363 load_keymap_button = lives_dialog_add_button_from_stock(NULL, LIVES_STOCK_OPEN, _("_Load default keymap"),
2364 LIVES_RESPONSE_BROWSE);
2365
2366 lives_box_pack_start(LIVES_BOX(hbuttonbox), load_keymap_button, TRUE, TRUE, widget_opts.packing_width);
2367
2368 ok_button = lives_dialog_add_button_from_stock(NULL, LIVES_STOCK_CLOSE, _("Close _window"),
2369 LIVES_RESPONSE_OK);
2370
2371 lives_box_pack_start(LIVES_BOX(hbuttonbox), ok_button, TRUE, TRUE, widget_opts.packing_width);
2372
2373 add_fill_to_box(LIVES_BOX(hbuttonbox));
2374
2375 lives_widget_set_size_request(clear_all_button, DLG_BUTTON_WIDTH, DLG_BUTTON_HEIGHT);
2376 lives_widget_set_margin(clear_all_button, widget_opts.border_width);
2377
2378 lives_widget_set_size_request(save_keymap_button, DLG_BUTTON_WIDTH, DLG_BUTTON_HEIGHT);
2379 lives_widget_set_margin(save_keymap_button, widget_opts.border_width);
2380
2381 lives_widget_set_size_request(load_keymap_button, DLG_BUTTON_WIDTH, DLG_BUTTON_HEIGHT);
2382 lives_widget_set_margin(load_keymap_button, widget_opts.border_width);
2383
2384 lives_widget_set_size_request(ok_button, DLG_BUTTON_WIDTH, DLG_BUTTON_HEIGHT);
2385 lives_widget_set_margin(ok_button, widget_opts.border_width);
2386
2387 rtew_accel_group = LIVES_ACCEL_GROUP(lives_accel_group_new());
2388 lives_window_add_accel_group(LIVES_WINDOW(irte_window), rtew_accel_group);
2389
2390 lives_widget_add_accelerator(ok_button, LIVES_WIDGET_CLICKED_SIGNAL, rtew_accel_group,
2391 LIVES_KEY_Escape, (LiVESXModifierType)0, (LiVESAccelFlags)0);
2392
2393 lives_signal_connect(LIVES_GUI_OBJECT(irte_window), LIVES_WIDGET_DELETE_EVENT,
2394 LIVES_GUI_CALLBACK(on_rtew_ok_clicked), NULL);
2395
2396 lives_signal_sync_connect(LIVES_GUI_OBJECT(ok_button), LIVES_WIDGET_CLICKED_SIGNAL,
2397 LIVES_GUI_CALLBACK(on_rtew_ok_clicked), NULL);
2398
2399 lives_signal_connect(LIVES_GUI_OBJECT(save_keymap_button), LIVES_WIDGET_CLICKED_SIGNAL,
2400 LIVES_GUI_CALLBACK(on_save_keymap_clicked), NULL);
2401
2402 lives_signal_connect(LIVES_GUI_OBJECT(load_keymap_button), LIVES_WIDGET_CLICKED_SIGNAL,
2403 LIVES_GUI_CALLBACK(on_load_keymap_clicked),
2404 LIVES_INT_TO_POINTER(1));
2405
2406 lives_signal_connect(LIVES_GUI_OBJECT(clear_all_button), LIVES_WIDGET_CLICKED_SIGNAL,
2407 LIVES_GUI_CALLBACK(on_clear_all_clicked),
2408 LIVES_INT_TO_POINTER(1));
2409
2410 rte_window_ready:
2411 // TODO: ignore button clicks until window is fully shown
2412
2413 rte_window_is_hidden = FALSE;
2414
2415 //lives_window_set_modal(LIVES_WINDOW(irte_window), TRUE);
2416 lives_widget_show_all(irte_window);
2417
2418 if (prefs->open_maximised) {
2419 lives_window_maximize(LIVES_WINDOW(irte_window));
2420 }
2421
2422 lives_widget_show_now(irte_window);
2423
2424 lives_widget_set_sensitive(mainw->mt_menu, FALSE);
2425 lives_widget_set_sensitive(mainw->rte_defs_menu, FALSE);
2426
2427 lives_set_cursor_style(LIVES_CURSOR_NORMAL, NULL);
2428 lives_set_cursor_style(LIVES_CURSOR_NORMAL, irte_window);
2429 mainw->no_context_update = FALSE;
2430 return irte_window;
2431 }
2432
2433
refresh_rte_window(void)2434 LiVESWidget *refresh_rte_window(void) {
2435 if (rte_window) {
2436 lives_set_cursor_style(LIVES_CURSOR_BUSY, NULL);
2437 lives_set_cursor_style(LIVES_CURSOR_BUSY, rte_window);
2438 lives_widget_context_update();
2439 on_rtew_delete_event(NULL, NULL, NULL);
2440 lives_widget_destroy(rte_window);
2441 rte_window = create_rte_window();
2442 rte_window_set_interactive(prefs->interactive);
2443 }
2444 return rte_window;
2445 }
2446
2447
on_assign_rte_keys_activate(LiVESMenuItem * menuitem,livespointer user_data)2448 void on_assign_rte_keys_activate(LiVESMenuItem * menuitem, livespointer user_data) {
2449 if (rte_window && !rte_window_is_hidden) {
2450 on_rtew_delete_event(NULL, NULL, NULL);
2451 } else {
2452 rte_window = create_rte_window();
2453 rte_window_set_interactive(prefs->interactive);
2454 lives_widget_show(rte_window);
2455 if (mainw->play_window && !mainw->fs && (prefs->play_monitor == widget_opts.monitor + 1 || capable->nmonitors == 1)) {
2456 lives_widget_hide(mainw->play_window);
2457 lives_window_set_transient_for(LIVES_WINDOW(mainw->play_window), LIVES_WINDOW(rte_window));
2458 lives_widget_show(mainw->play_window);
2459 }
2460 }
2461 }
2462
2463
rtew_set_keych(int key,boolean on)2464 void rtew_set_keych(int key, boolean on) {
2465 lives_signal_handler_block(key_checks[key], ch_fns[key]);
2466 lives_toggle_button_set_active(LIVES_TOGGLE_BUTTON(key_checks[key]), on);
2467 lives_signal_handler_unblock(key_checks[key], ch_fns[key]);
2468 lives_widget_object_set_data(LIVES_WIDGET_OBJECT(key_checks[key]), "active", LIVES_INT_TO_POINTER(on));
2469 }
2470
2471
rtew_set_keygr(int key)2472 void rtew_set_keygr(int key) {
2473 if (key >= 0) {
2474 lives_signal_handler_block(key_grabs[key], gr_fns[key]);
2475 lives_toggle_button_set_active(LIVES_TOGGLE_BUTTON(key_grabs[key]), TRUE);
2476 lives_signal_handler_unblock(key_grabs[key], gr_fns[key]);
2477 } else {
2478 lives_toggle_button_set_active(LIVES_TOGGLE_BUTTON(dummy_radio), TRUE);
2479 }
2480 }
2481
2482
rtew_set_mode_radio(int key,int mode)2483 void rtew_set_mode_radio(int key, int mode) {
2484 int modes = rte_getmodespk();
2485 lives_signal_handler_block(mode_radios[key * modes + mode], mode_ra_fns[key * modes + mode]);
2486 lives_toggle_button_set_active(LIVES_TOGGLE_BUTTON(mode_radios[key * modes + mode]), TRUE);
2487 lives_signal_handler_unblock(mode_radios[key * modes + mode], mode_ra_fns[key * modes + mode]);
2488 }
2489
2490
update_pwindow(int key,int i,LiVESList * list)2491 void update_pwindow(int key, int i, LiVESList * list) {
2492 // called only from weed_set_blend_factor() and from setting param in ce_thumbs
2493
2494 weed_plant_t *inst;
2495 lives_rfx_t *rfx;
2496 int keyw, modew;
2497
2498 if (fx_dialog[1]) {
2499 keyw = fx_dialog[1]->key;
2500 modew = fx_dialog[1]->mode;
2501 if (key == keyw) {
2502 if (!(inst = rte_keymode_get_instance(key + 1, modew))) return;
2503 weed_instance_unref(inst);
2504 rfx = fx_dialog[1]->rfx;
2505 mainw->block_param_updates = TRUE;
2506 set_param_from_list(list, &rfx->params[i], 0, TRUE, TRUE);
2507 mainw->block_param_updates = FALSE;
2508 }
2509 }
2510 }
2511
2512
rte_set_defs_activate(LiVESMenuItem * menuitem,livespointer user_data)2513 void rte_set_defs_activate(LiVESMenuItem * menuitem, livespointer user_data) {
2514 int idx = LIVES_POINTER_TO_INT(user_data);
2515 weed_plant_t *filter = get_weed_filter(idx);
2516 lives_rfx_t *rfx;
2517
2518 if (fx_dialog[1]) {
2519 rfx = fx_dialog[1]->rfx;
2520 on_paramwindow_button_clicked(NULL, rfx);
2521 lives_widget_destroy(fx_dialog[1]->dialog);
2522 lives_freep((void **)&fx_dialog[1]);
2523 }
2524
2525 rfx = weed_to_rfx(filter, TRUE);
2526 rfx->min_frames = -1;
2527 on_fx_pre_activate(rfx, TRUE, NULL);
2528 }
2529
2530
rte_set_key_defs(LiVESButton * button,lives_rfx_t * rfx)2531 void rte_set_key_defs(LiVESButton * button, lives_rfx_t *rfx) {
2532 int key, mode;
2533 if (mainw->textwidget_focus) {
2534 LiVESWidget *textwidget = (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(mainw->textwidget_focus),
2535 TEXTWIDGET_KEY);
2536 after_param_text_changed(textwidget, rfx);
2537 }
2538
2539 if (rfx->num_params > 0) {
2540 key = fx_dialog[1]->key;
2541 mode = fx_dialog[1]->mode;
2542 set_key_defaults((weed_plant_t *)rfx->source, key, mode);
2543 }
2544 }
2545
2546
rte_set_defs_ok(LiVESButton * button,lives_rfx_t * rfx)2547 void rte_set_defs_ok(LiVESButton * button, lives_rfx_t *rfx) {
2548 weed_plant_t *ptmpl, *filter;
2549
2550 lives_colRGB48_t *rgbp;
2551
2552 register int i;
2553
2554 if (mainw->textwidget_focus) {
2555 LiVESWidget *textwidget = (LiVESWidget *)lives_widget_object_get_data(LIVES_WIDGET_OBJECT(mainw->textwidget_focus),
2556 TEXTWIDGET_KEY);
2557 after_param_text_changed(textwidget, rfx);
2558 }
2559
2560 if (rfx->num_params > 0) {
2561 filter = weed_instance_get_filter((weed_plant_t *)rfx->source, TRUE);
2562 for (i = 0; i < rfx->num_params; i++) {
2563 ptmpl = weed_filter_in_paramtmpl(filter, i, FALSE);
2564 if (weed_paramtmpl_value_irrelevant(ptmpl)) continue;
2565 switch (rfx->params[i].type) {
2566 case LIVES_PARAM_COLRGB24:
2567 rgbp = (lives_colRGB48_t *)rfx->params[i].value;
2568 update_weed_color_value(filter, i, rgbp->red, rgbp->green, rgbp->blue, 0, rfx);
2569 break;
2570 case LIVES_PARAM_STRING:
2571 weed_set_string_value(ptmpl, WEED_LEAF_HOST_DEFAULT, (char *)rfx->params[i].value);
2572 break;
2573 case LIVES_PARAM_STRING_LIST:
2574 weed_set_int_array(ptmpl, WEED_LEAF_HOST_DEFAULT, 1, (int *)rfx->params[i].value);
2575 break;
2576 case LIVES_PARAM_NUM:
2577 if (weed_leaf_seed_type(ptmpl, WEED_LEAF_DEFAULT) == WEED_SEED_DOUBLE)
2578 weed_set_double_array(ptmpl, WEED_LEAF_HOST_DEFAULT, 1,
2579 (double *)rfx->params[i].value);
2580 else weed_set_int_array(ptmpl, WEED_LEAF_HOST_DEFAULT, 1, (int *)rfx->params[i].value);
2581 break;
2582 case LIVES_PARAM_BOOL:
2583 weed_set_boolean_array(ptmpl, WEED_LEAF_HOST_DEFAULT, 1, (int *)rfx->params[i].value);
2584 break;
2585 default:
2586 break;
2587 // *INDENT-OFF*
2588 }}}
2589 // *INDENT-ON*
2590 }
2591
2592
rte_set_defs_cancel(LiVESButton * button,lives_rfx_t * rfx)2593 void rte_set_defs_cancel(LiVESButton * button, lives_rfx_t *rfx) {
2594 on_paramwindow_button_clicked(button, rfx);
2595 lives_freep((void **)&fx_dialog[1]);
2596 }
2597
2598
rte_reset_defs_clicked(LiVESButton * button,lives_rfx_t * rfx)2599 void rte_reset_defs_clicked(LiVESButton * button, lives_rfx_t *rfx) {
2600 weed_plant_t **ptmpls, **inp, **xinp;
2601 weed_plant_t **ctmpls;
2602
2603 weed_plant_t *filter, *inst;
2604
2605 LiVESList *child_list;
2606
2607 LiVESWidget *pbox, *cancelbutton;
2608
2609 boolean is_generic_defs = FALSE;
2610 boolean add_pcons = FALSE;
2611
2612 int nchans;
2613
2614 int poffset = 0, ninpar, x;
2615
2616 int i;
2617
2618 cancelbutton = fx_dialog[1]->cancelbutton;
2619
2620 if (cancelbutton) is_generic_defs = TRUE;
2621
2622 inst = (weed_plant_t *)rfx->source;
2623
2624 filter = weed_instance_get_filter(inst, TRUE);
2625
2626 if (rfx->num_params > 0) {
2627 if (is_generic_defs) {
2628 // for generic, reset from plugin supplied defs
2629 ptmpls = weed_get_plantptr_array(filter, WEED_LEAF_IN_PARAMETER_TEMPLATES, NULL);
2630 for (i = 0; i < rfx->num_params; i++) {
2631 if (weed_plant_has_leaf(ptmpls[i], WEED_LEAF_HOST_DEFAULT)) weed_leaf_delete(ptmpls[i], WEED_LEAF_HOST_DEFAULT);
2632 }
2633 lives_free(ptmpls);
2634 }
2635
2636 inp = weed_params_create(filter, TRUE);
2637
2638 resetdefs1:
2639 filter = weed_instance_get_filter(inst, FALSE);
2640
2641 // reset params back to default defaults
2642 weed_in_parameters_free(inst);
2643
2644 ninpar = num_in_params(filter, FALSE, FALSE);
2645 if (ninpar == 0) xinp = NULL;
2646
2647 xinp = (weed_plant_t **)lives_malloc((ninpar + 1) * sizeof(weed_plant_t *));
2648 x = 0;
2649 for (i = poffset; i < poffset + ninpar; i++) xinp[x++] = inp[i];
2650 xinp[x] = NULL;
2651 poffset += ninpar;
2652
2653 weed_set_plantptr_array(inst, WEED_LEAF_IN_PARAMETERS, weed_flagset_array_count(xinp, TRUE), xinp);
2654 lives_free(xinp);
2655
2656 if (weed_plant_has_leaf(inst, WEED_LEAF_HOST_NEXT_INSTANCE)) {
2657 // handle compound fx
2658 inst = weed_get_plantptr_value(inst, WEED_LEAF_HOST_NEXT_INSTANCE, NULL);
2659 add_pcons = TRUE;
2660 goto resetdefs1;
2661 }
2662
2663 lives_free(inp);
2664
2665 inst = (weed_plant_t *)rfx->source;
2666 filter = weed_instance_get_filter(inst, TRUE);
2667
2668 if (add_pcons) {
2669 add_param_connections(inst);
2670 }
2671
2672 rfx_params_free(rfx);
2673 lives_free(rfx->params);
2674
2675 rfx->params = weed_params_to_rfx(rfx->num_params, inst, FALSE);
2676 }
2677
2678 if (is_generic_defs) {
2679 if (weed_plant_has_leaf(filter, WEED_LEAF_HOST_FPS)) weed_leaf_delete(filter, WEED_LEAF_HOST_FPS);
2680
2681 if (weed_plant_has_leaf(filter, WEED_LEAF_OUT_CHANNEL_TEMPLATES)) {
2682 ctmpls = weed_get_plantptr_array(filter, WEED_LEAF_OUT_CHANNEL_TEMPLATES, NULL);
2683 nchans = weed_leaf_num_elements(filter, WEED_LEAF_OUT_CHANNEL_TEMPLATES);
2684 for (i = 0; i < nchans; i++) {
2685 if (weed_plant_has_leaf(ctmpls[i], WEED_LEAF_HOST_WIDTH)) weed_leaf_delete(ctmpls[i], WEED_LEAF_HOST_WIDTH);
2686 if (weed_plant_has_leaf(ctmpls[i], WEED_LEAF_HOST_HEIGHT)) weed_leaf_delete(ctmpls[i], WEED_LEAF_HOST_HEIGHT);
2687 }
2688 }
2689 } else {
2690 int key = fx_dialog[1]->key;
2691 int mode = fx_dialog[1]->mode;
2692 set_key_defaults(inst, key, mode);
2693 }
2694
2695 if (!LIVES_IS_WIDGET(fx_dialog[1]->dialog)) return;
2696 pbox = lives_dialog_get_content_area(LIVES_DIALOG(fx_dialog[1]->dialog));
2697
2698 // redraw the window
2699 child_list = lives_container_get_children(LIVES_CONTAINER(pbox));
2700 // remove focus from any widget we are ripping out
2701 lives_container_set_focus_child(LIVES_CONTAINER(pbox), NULL);
2702 for (i = 0; i < lives_list_length(child_list); i++) {
2703 LiVESWidget *widget = (LiVESWidget *)lives_list_nth_data(child_list, i);
2704 if (lives_widget_is_ancestor(LIVES_WIDGET(button), widget)) continue;
2705 lives_widget_destroy(widget);
2706 }
2707
2708 if (child_list) lives_list_free(child_list);
2709
2710 make_param_box(LIVES_VBOX(pbox), rfx);
2711 lives_widget_show_all(pbox);
2712
2713 lives_widget_queue_draw(fx_dialog[1]->dialog);
2714 }
2715
2716
load_default_keymap(void)2717 void load_default_keymap(void) {
2718 // called on startup
2719 if (!hash_list) hash_list = weed_get_all_names(FX_LIST_HASHNAME);
2720 on_load_keymap_clicked(NULL, NULL);
2721 threaded_dialog_spin(0.);
2722 }
2723