1 // osc.c
2 // LiVES (lives-exe)
3 // (c) G. Finch 2004 - 2016 <salsaman@gmail.com>
4 // Released under the GPL 3 or later
5 // see file ../COPYING for licensing details
6 
7 #ifndef IS_MINGW
8 #include <netinet/in.h>
9 #endif
10 
11 #include "main.h"
12 
13 #ifdef ENABLE_OSC
14 
15 #include "osc.h"
16 #include "htmsocket.h"
17 #include "callbacks.h"
18 #include "effects.h"
19 #include "rte_window.h"
20 #include "resample.h"
21 #include "paramwindow.h"
22 #include "ce_thumbs.h"
23 #ifdef HAVE_UNICAP
24 #include "videodev.h"
25 #endif
26 #include "lbindings.h"
27 
28 void *status_socket = NULL;
29 void *notify_socket = NULL;
30 
31 static lives_osc *livesOSC = NULL;
32 
33 static char constval[OSC_CONSTLEN];
34 
35 static boolean via_shortcut = FALSE;
36 
37 #define FX_MAX FX_KEYS_MAX_VIRTUAL-1
38 
39 // TODO: replace mainw->osc_block with filter_mutex_lock()
40 
osc_init_generator(livespointer data)41 static boolean osc_init_generator(livespointer data) {
42   // do this via an idle function, as it will trigger playback and hang
43   mainw->osc_auto = 1; ///< request notifiction of success
44   rte_key_toggle(LIVES_POINTER_TO_INT(data));
45   mainw->osc_auto = 0;
46   return FALSE;
47 }
48 
49 
50 /* convert a big endian 32 bit string to an int for internal use */
51 
toInt(const char * b)52 static int toInt(const char *b) {
53   if (capable->byte_order == LIVES_LITTLE_ENDIAN) {
54     return (((int) b[3]) & 0xff) + ((((int) b[2]) & 0xff) << 8) + ((((int) b[1]) & 0xff) << 16) +
55            ((((int) b[0]) & 0xff) << 24);
56   }
57   return (((int) b[0]) & 0xff) + ((((int) b[1]) & 0xff) << 8) + ((((int) b[2]) & 0xff) << 16) +
58          ((((int) b[3]) & 0xff) << 24);
59 }
60 
61 
62 static boolean using_types;
63 static int osc_header_len;
64 static int offset;
65 
66 
lives_osc_get_num_arguments(const void * vargs)67 static int lives_osc_get_num_arguments(const void *vargs) {
68   // check if using type tags and get num_arguments
69   const char *args = (const char *)vargs;
70   if (args[0] != 0x2c) return 0;
71   return strlen(args) - 1;
72 }
73 
74 
lives_osc_check_arguments(int arglen,const void * vargs,const char * check_pattern,boolean calc_header_len)75 static boolean lives_osc_check_arguments(int arglen, const void *vargs, const char *check_pattern, boolean calc_header_len) {
76   // check if using type tags and get header_len
77   // should be called from each cb that uses parameters
78   const char *args = (const char *)vargs;
79   int header_len;
80 
81   osc_header_len = 0;
82   offset = 0;
83 
84   using_types = FALSE;
85   if (arglen < 4 || args[0] != 0x2c) return FALSE; // missing comma or typetags
86   using_types = TRUE;
87 
88   header_len = pad4(strlen(check_pattern) + 1);
89 
90   if (arglen < header_len) return FALSE;
91   if (!strncmp(check_pattern, ++args, strlen(check_pattern))) {
92     if (calc_header_len) osc_header_len = header_len;
93     return TRUE;
94   }
95   return FALSE;
96 }
97 
98 
99 /* not used yet */
100 /*static void lives_osc_parse_char_argument(const void *vargs, char *dst)
101   {
102   const char *args = (char*)vargs;
103   strncpy(dst, args+osc_header_len+offset,1);
104   offset+=4;
105   }*/
106 
107 
lives_osc_parse_string_argument(const void * vargs,char * dst)108 static void lives_osc_parse_string_argument(const void *vargs, char *dst) {
109   const char *args = (char *)vargs;
110   lives_snprintf(dst, OSC_STRING_SIZE, "%s", args + osc_header_len + offset);
111   offset += pad4(strlen(dst));
112 }
113 
114 
lives_osc_parse_int_argument(const void * vargs,int * arguments)115 static void lives_osc_parse_int_argument(const void *vargs, int *arguments) {
116   const char *args = (char *)vargs;
117   arguments[0] = toInt(args + osc_header_len + offset);
118   offset += 4;
119 }
120 
121 
lives_osc_parse_float_argument(const void * vargs,float * arguments)122 static void lives_osc_parse_float_argument(const void *vargs, float *arguments) {
123   const char *args = (char *)vargs;
124   arguments[0] = LEFloat_to_BEFloat(*((float *)(args + osc_header_len + offset)));
125   offset += 4;
126 }
127 
128 
129 /* memory allocation functions of libOMC_dirty (OSC) */
lives_osc_malloc(int num_bytes)130 void *lives_osc_malloc(int num_bytes) {
131   return lives_malloc(num_bytes);
132 }
133 
134 
135 // status returns
136 
lives_status_send(const char * msg)137 boolean lives_status_send(const char *msg) {
138   if (!status_socket) return FALSE;
139   else {
140     // note we send the terminating \nul
141     boolean retval = lives_stream_out(status_socket, strlen(msg) + 1, (void *)msg);
142     return retval;
143   }
144 }
145 
146 
lives_osc_notify(int msgnumber,const char * msgstring)147 boolean lives_osc_notify(int msgnumber, const char *msgstring) {
148   if (!notify_socket) return FALSE;
149   if (!prefs || (!prefs->omc_events && (msgnumber != LIVES_OSC_NOTIFY_SUCCESS
150                                         && msgnumber != LIVES_OSC_NOTIFY_FAILED))) return FALSE;
151   else {
152     char *msg;
153     boolean retval;
154     if (msgstring) {
155       msg = lives_strdup_printf("%d|%s\n", msgnumber, msgstring);
156     } else msg = lives_strdup_printf("%d\n", msgnumber);
157     retval = lives_stream_out(notify_socket, strlen(msg) + 1, (void *)msg);
158     lives_free(msg);
159     return retval;
160   }
161 }
162 
163 
lives_osc_notify_success(const char * msg)164 boolean lives_osc_notify_success(const char *msg) {
165   if (prefs->omc_noisy)
166     lives_osc_notify(LIVES_OSC_NOTIFY_SUCCESS, msg);
167   return TRUE;
168 }
169 
170 
lives_osc_notify_failure(void)171 boolean lives_osc_notify_failure(void) {
172   if (prefs->omc_noisy)
173     lives_osc_notify(LIVES_OSC_NOTIFY_FAILED, NULL);
174   return FALSE;
175 }
176 
177 /* unused */
178 /*
179   void lives_osc_notify_cancel (void) {
180   if (prefs->omc_noisy);
181   lives_osc_notify(LIVES_OSC_NOTIFY_CANCELLED,NULL);
182   }*/
183 
184 
lives_osc_close_status_socket(void)185 void lives_osc_close_status_socket(void) {
186   if (status_socket) CloseHTMSocket(status_socket);
187   status_socket = NULL;
188 }
189 
190 
lives_osc_close_notify_socket(void)191 void lives_osc_close_notify_socket(void) {
192   if (notify_socket) CloseHTMSocket(notify_socket);
193   notify_socket = NULL;
194 }
195 
196 
get_value_of(const int what)197 LIVES_INLINE const char *get_value_of(const int what) {
198   lives_snprintf(constval, OSC_CONSTLEN, "%d", what);
199   return (const char *)&constval;
200 }
201 
202 
get_omc_const(const char * cname)203 static const char *get_omc_const(const char *cname) {
204   // looping modes
205   if (!strcmp(cname, "LIVES_LOOP_MODE_NONE")) return "0";
206   if (!strcmp(cname, "LIVES_LOOP_MODE_CONTINUOUS")) return "1";
207   if (!strcmp(cname, "LIVES_LOOP_MODE_FIT_AUDIO")) return "2";
208 
209   // interface modes
210   if (!strcmp(cname, "LIVES_INTERFACE_MODE_CLIPEDIT")) return "0";
211   if (!strcmp(cname, "LIVES_INTERFACE_MODE_MULTITRACK")) return "1";
212 
213   // status
214   if (!strcmp(cname, "LIVES_STATUS_NOTREADY")) return "0";
215   if (!strcmp(cname, "LIVES_STATUS_READY")) return "1";
216   if (!strcmp(cname, "LIVES_STATUS_PLAYING")) return "2";
217   if (!strcmp(cname, "LIVES_STATUS_PROCESSING")) return "3";
218   if (!strcmp(cname, "LIVES_STATUS_PREVIEW")) return "4";
219 
220   // parameter types
221   if (!strcmp(cname, "LIVES_PARAM_TYPE_INTEGER"))
222     return get_value_of((const int)WEED_PARAM_INTEGER);
223   if (!strcmp(cname, "LIVES_PARAM_TYPE_FLOAT"))
224     return get_value_of((const int)WEED_PARAM_FLOAT);
225   if (!strcmp(cname, "LIVES_PARAM_TYPE_BOOL"))
226     return get_value_of((const int)WEED_PARAM_SWITCH);
227   if (!strcmp(cname, "LIVES_PARAM_TYPE_STRING"))
228     return get_value_of((const int)WEED_PARAM_TEXT);
229   if (!strcmp(cname, "LIVES_PARAM_TYPE_COLOR"))
230     return get_value_of((const int)WEED_PARAM_COLOR);
231 
232   // colorspaces
233   if (!strcmp(cname, "LIVES_COLORSPACE_RGB_INT"))
234     return "1";
235   if (!strcmp(cname, "LIVES_COLORSPACE_RGBA_INT"))
236     return "2";
237   if (!strcmp(cname, "LIVES_COLORSPACE_RGB_FLOAT"))
238     return "3";
239   if (!strcmp(cname, "LIVES_COLORSPACE_RGBA_FLOAT"))
240     return "4";
241 
242   // boolean values
243   if (!strcmp(cname, "LIVES_TRUE")) return "1";
244   if (!strcmp(cname, "LIVES_FALSE")) return "0";
245 
246   // parameter flags
247   if (!strcmp(cname, "LIVES_PARAM_FLAGS_REINIT_ON_VALUE_CHANGE"))
248     return get_value_of((const int)WEED_PARAMETER_REINIT_ON_VALUE_CHANGE);
249   if (!strcmp(cname, "LIVES_PARAM_FLAGS_VARIABLE_SIZE"))
250     return get_value_of((const int)WEED_PARAMETER_VARIABLE_SIZE);
251   if (!strcmp(cname, "LIVES_PARAM_FLAGS_VALUE_PER_CHANNEL"))
252     return get_value_of((const int)WEED_PARAMETER_VALUE_PER_CHANNEL);
253 
254   // notification types
255   if (!strcmp(cname, "LIVES_OSC_NOTIFY_SUCCESS"))
256     return get_value_of((const int)LIVES_OSC_NOTIFY_SUCCESS);
257   if (!strcmp(cname, "LIVES_OSC_NOTIFY_FAILED"))
258     return get_value_of((const int)LIVES_OSC_NOTIFY_FAILED);
259 
260   // notification events
261   if (!strcmp(cname, "LIVES_OSC_NOTIFY_FRAME_SYNCH"))
262     return get_value_of((const int)LIVES_OSC_NOTIFY_FRAME_SYNCH);
263   if (!strcmp(cname, "LIVES_OSC_NOTIFY_PLAYBACK_STARTED"))
264     return get_value_of((const int)LIVES_OSC_NOTIFY_PLAYBACK_STARTED);
265   if (!strcmp(cname, "LIVES_OSC_NOTIFY_PLAYBACK_STOPPED"))
266     return get_value_of((const int)LIVES_OSC_NOTIFY_PLAYBACK_STOPPED);
267   if (!strcmp(cname, "LIVES_OSC_NOTIFY_PLAYBACK_STOPPED_RD"))
268     return get_value_of((const int)LIVES_OSC_NOTIFY_PLAYBACK_STOPPED_RD);
269   if (!strcmp(cname, "LIVES_OSC_NOTIFY_RECORD_STARTED"))
270     return get_value_of((const int)LIVES_OSC_NOTIFY_RECORD_STARTED);
271   if (!strcmp(cname, "LIVES_OSC_NOTIFY_RECORD_STOPPED"))
272     return get_value_of((const int)LIVES_OSC_NOTIFY_RECORD_STOPPED);
273   if (!strcmp(cname, "LIVES_OSC_NOTIFY_QUIT"))
274     return get_value_of((const int)LIVES_OSC_NOTIFY_QUIT);
275   if (!strcmp(cname, "LIVES_OSC_NOTIFY_CLIP_OPENED"))
276     return get_value_of((const int)LIVES_OSC_NOTIFY_CLIP_OPENED);
277   if (!strcmp(cname, "LIVES_OSC_NOTIFY_CLIP_CLOSED"))
278     return get_value_of((const int)LIVES_OSC_NOTIFY_CLIP_CLOSED);
279   if (!strcmp(cname, "LIVES_OSC_NOTIFY_CLIPSET_OPENED"))
280     return get_value_of((const int)LIVES_OSC_NOTIFY_CLIPSET_OPENED);
281   if (!strcmp(cname, "LIVES_OSC_NOTIFY_CLIPSET_SAVED"))
282     return get_value_of((const int)LIVES_OSC_NOTIFY_CLIPSET_SAVED);
283   if (!strcmp(cname, "LIVES_OSC_NOTIFY_SUCCESS"))
284     return get_value_of((const int)LIVES_OSC_NOTIFY_SUCCESS);
285   if (!strcmp(cname, "LIVES_OSC_NOTIFY_FAILED"))
286     return get_value_of((const int)LIVES_OSC_NOTIFY_FAILED);
287   if (!strcmp(cname, "LIVES_OSC_NOTIFY_CANCELLED"))
288     return get_value_of((const int)LIVES_OSC_NOTIFY_CANCELLED);
289   if (!strcmp(cname, "LIVES_OSC_NOTIFY_MODE_CHANGED"))
290     return get_value_of((const int)LIVES_OSC_NOTIFY_MODE_CHANGED);
291 
292   // audio sources
293   if (!strcmp(cname, "LIVES_AUDIO_SOURCE_INTERNAL"))
294     return get_value_of((const int)AUDIO_SRC_INT);
295   if (!strcmp(cname, "LIVES_AUDIO_SOURCE_EXTERNAL"))
296     return get_value_of((const int)AUDIO_SRC_EXT);
297 
298   // generic constants
299   if (!strcmp(cname, "LIVES_FPS_MAX"))
300     return get_value_of((const int)FPS_MAX);
301 
302   if (!strcmp(cname, "LIVES_DEFAULT_OVERRIDDEN"))
303     return "2";
304 
305   IGN_RET(lives_osc_notify_failure());
306 
307   return "";
308 }
309 
310 
lives_osc_format_result(weed_plant_t * plant,const char * key,int st,int end)311 static char *lives_osc_format_result(weed_plant_t *plant, const char *key, int st, int end) {
312   int stype;
313   int error, i;
314 
315   char *retval = NULL, *tmp;
316 
317   if (end == -1) end = weed_leaf_num_elements(plant, key);
318 
319   if (end <= st) return lives_strdup("");
320 
321   stype = weed_leaf_seed_type(plant, key);
322 
323   switch (stype) {
324   case WEED_SEED_INT: {
325     int *vals = weed_get_int_array(plant, key, &error);
326     for (i = st; i < end; i++) {
327       if (!retval) tmp = lives_strdup_printf("%d", vals[i]);
328       else {
329         tmp = lives_strdup_printf("%s,%d", retval, vals[i]);
330         lives_free(retval);
331       }
332       retval = tmp;
333     }
334     lives_free(vals);
335     break;
336   }
337 
338   case WEED_SEED_DOUBLE: {
339     double *vals = weed_get_double_array(plant, key, &error);
340     for (i = st; i < end; i++) {
341       if (!retval) tmp = lives_strdup_printf("%f", vals[i]);
342       else {
343         tmp = lives_strdup_printf("%s,%f", retval, vals[i]);
344         lives_free(retval);
345       }
346       retval = tmp;
347     }
348     lives_free(vals);
349     break;
350   }
351 
352   case WEED_SEED_BOOLEAN: {
353     int *vals = weed_get_boolean_array(plant, key, &error);
354     for (i = st; i < end; i++) {
355       if (!retval) tmp = lives_strdup_printf("%d", vals[i] == WEED_TRUE);
356       else {
357         tmp = lives_strdup_printf("%s,%d", retval, vals[i] == WEED_TRUE);
358         lives_free(retval);
359       }
360       retval = tmp;
361     }
362     lives_free(vals);
363     //g_print("get from %p %s %s\n", plant, key, tmp);
364 
365     break;
366   }
367 
368   case WEED_SEED_STRING: {
369     char **vals = weed_get_string_array(plant, key, &error);
370     char *tmp2;
371     for (i = st; i < end; i++) {
372       if (!retval) tmp = lives_strdup_printf("\"%s\"", (tmp2 = subst(vals[i], "\"", "\\\"")));
373       else {
374         tmp = lives_strdup_printf("%s,\"%s\"", retval, (tmp2 = subst(vals[i], "\"", "\\\"")));
375         lives_free(retval);
376       }
377       lives_free(tmp2);
378       retval = tmp;
379       lives_free(vals[i]);
380     }
381     lives_free(vals);
382     break;
383   }
384   }
385   return retval;
386 }
387 
388 
389 ///////////////////////////////////// CALLBACKS FOR OSC ////////////////////////////////////////
390 // TODO - handle clipboard playback
391 
lives_osc_cb_test(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)392 boolean lives_osc_cb_test(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
393   int val = lives_osc_get_num_arguments(vargs);
394   lives_printerr("got %d\n", val);
395   return TRUE;
396 }
397 
398 
399 /* /video/play */
lives_osc_cb_play(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)400 boolean lives_osc_cb_play(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
401   float ent, stt;
402   double entd, sttd;
403 
404   if (mainw->go_away) return lives_osc_notify_failure();
405   mainw->osc_auto = 1; ///< request early notifiction of success
406 
407   if (mainw->current_file <= 0 || mainw->playing_file != -1) return lives_osc_notify_failure();
408 
409   mainw->play_start = calc_frame_from_time(mainw->current_file,
410                       cfile->pointer_time);
411   mainw->play_end = cfile->frames;
412 
413   if (!lives_osc_check_arguments(arglen, vargs, "ff", FALSE)) {
414     if (!lives_osc_check_arguments(arglen, vargs, "f", FALSE)) {
415       if (!lives_osc_check_arguments(arglen, vargs, "", FALSE)) {
416         return lives_osc_notify_failure();
417       }
418     } else {
419       lives_osc_check_arguments(arglen, vargs, "f", TRUE);
420       lives_osc_parse_float_argument(vargs, &stt);
421       sttd = (double)stt;
422       mainw->play_start = calc_frame_from_time(mainw->current_file,
423                           sttd);
424     }
425   } else {
426     lives_osc_check_arguments(arglen, vargs, "ff", TRUE);
427     lives_osc_parse_float_argument(vargs, &stt);
428     lives_osc_parse_float_argument(vargs, &ent);
429     sttd = (double)stt;
430     entd = (double)ent;
431     mainw->play_end = calc_frame_from_time(mainw->current_file,
432                                            entd);
433     mainw->play_start = calc_frame_from_time(mainw->current_file,
434                         sttd);
435   }
436 
437   start_playback_async(3);
438 
439   return TRUE;
440 }
441 
442 
lives_osc_cb_playsel(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)443 boolean lives_osc_cb_playsel(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
444   if (mainw->go_away) return lives_osc_notify_failure();
445   if (!LIVES_IS_PLAYING && mainw->current_file > 0 && !mainw->is_processing) {
446     start_playback_async(4);
447   }
448   return TRUE;
449 }
450 
451 
lives_osc_cb_play_reverse(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)452 boolean lives_osc_cb_play_reverse(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
453   if (mainw->multitrack) return lives_osc_notify_failure();
454 
455   if (!CURRENT_CLIP_IS_NORMAL || !LIVES_IS_PLAYING)
456     return lives_osc_notify_failure();
457   dirchange_callback(NULL, NULL, 0, (LiVESXModifierType)0, LIVES_INT_TO_POINTER(SCREEN_AREA_FOREGROUND));
458   return lives_osc_notify_success(NULL);
459 }
460 
461 
lives_osc_cb_bgplay_reverse(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)462 boolean lives_osc_cb_bgplay_reverse(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
463   if (mainw->multitrack) return lives_osc_notify_failure();
464 
465   if (!IS_NORMAL_CLIP(mainw->blend_file) || mainw->blend_file == mainw->current_file ||  !LIVES_IS_PLAYING)
466     return lives_osc_notify_failure();
467 
468   mainw->files[mainw->blend_file]->pb_fps = -mainw->files[mainw->blend_file]->pb_fps;
469 
470   return lives_osc_notify_success(NULL);
471 }
472 
473 
lives_osc_cb_play_forward(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)474 boolean lives_osc_cb_play_forward(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
475   if (mainw->go_away) return lives_osc_notify_failure(); // not ready to play yet
476 
477   if (!CURRENT_CLIP_IS_NORMAL)
478     if (mainw->playing_file == 1) return lives_osc_notify_failure();
479 
480   if (!LIVES_IS_PLAYING && mainw->current_file > 0 && !mainw->is_processing) {
481     start_playback_async(3);
482     return TRUE;
483   } else if (mainw->playing_file > 0) {
484     if (cfile->pb_fps < 0 || (cfile->play_paused && cfile->freeze_fps < 0))
485       dirchange_callback(NULL, NULL, 0, (LiVESXModifierType)0, LIVES_INT_TO_POINTER(SCREEN_AREA_FOREGROUND));
486     if (cfile->play_paused) freeze_callback(NULL, NULL, 0, (LiVESXModifierType)0, NULL);
487     return lives_osc_notify_success(NULL);
488   }
489 
490   return lives_osc_notify_failure();
491 }
492 
493 
lives_osc_cb_play_backward(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)494 boolean lives_osc_cb_play_backward(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
495   if (mainw->go_away) return lives_osc_notify_failure();
496   if (mainw->multitrack) return lives_osc_notify_failure();
497 
498   if (!CURRENT_CLIP_IS_NORMAL) return lives_osc_notify_failure();
499 
500   if (!LIVES_IS_PLAYING && mainw->current_file > 0 && !mainw->is_processing) {
501     mainw->reverse_pb = TRUE;
502     start_playback_async(3);
503     return TRUE;
504   } else if (mainw->playing_file > 0) {
505     if (cfile->pb_fps > 0 || (cfile->play_paused && cfile->freeze_fps > 0))
506       dirchange_callback(NULL, NULL, 0, (LiVESXModifierType)0, LIVES_INT_TO_POINTER(SCREEN_AREA_FOREGROUND));
507     if (cfile->play_paused) freeze_callback(NULL, NULL, 0, (LiVESXModifierType)0, NULL);
508     return lives_osc_notify_success(NULL);
509   }
510 
511   return lives_osc_notify_failure();
512 }
513 
514 
lives_osc_cb_play_faster(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)515 boolean lives_osc_cb_play_faster(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
516   if (mainw->multitrack) return lives_osc_notify_failure();
517   if (!LIVES_IS_PLAYING) return lives_osc_notify_failure();
518 
519   on_faster_pressed(NULL, LIVES_INT_TO_POINTER(SCREEN_AREA_FOREGROUND));
520   return lives_osc_notify_success(NULL);
521 }
522 
523 
lives_osc_cb_bgplay_faster(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)524 boolean lives_osc_cb_bgplay_faster(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
525   if (mainw->multitrack) return lives_osc_notify_failure();
526   if (!LIVES_IS_PLAYING) return lives_osc_notify_failure();
527 
528   if (!IS_VALID_CLIP(mainw->blend_file) || mainw->blend_file == mainw->current_file) return lives_osc_notify_failure();
529 
530   on_faster_pressed(NULL, LIVES_INT_TO_POINTER(SCREEN_AREA_BACKGROUND));
531   return lives_osc_notify_success(NULL);
532 }
533 
534 
lives_osc_cb_play_slower(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)535 boolean lives_osc_cb_play_slower(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
536   if (mainw->multitrack) return lives_osc_notify_failure();
537   if (!LIVES_IS_PLAYING) return lives_osc_notify_failure();
538 
539   on_slower_pressed(NULL, LIVES_INT_TO_POINTER(SCREEN_AREA_FOREGROUND));
540   return lives_osc_notify_success(NULL);
541 }
542 
543 
lives_osc_cb_bgplay_slower(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)544 boolean lives_osc_cb_bgplay_slower(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
545   if (mainw->multitrack) return lives_osc_notify_failure();
546   if (!LIVES_IS_PLAYING) return lives_osc_notify_failure();
547 
548   if (!IS_VALID_CLIP(mainw->blend_file) || mainw->blend_file == mainw->current_file) return lives_osc_notify_failure();
549 
550   on_slower_pressed(NULL, LIVES_INT_TO_POINTER(SCREEN_AREA_BACKGROUND));
551   return lives_osc_notify_success(NULL);
552 }
553 
554 
lives_osc_cb_play_reset(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)555 boolean lives_osc_cb_play_reset(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
556   if (mainw->multitrack) return lives_osc_notify_failure();
557   if (!LIVES_IS_PLAYING) return lives_osc_notify_failure();
558 
559   fps_reset_callback(NULL, NULL, 0, (LiVESXModifierType)0, NULL);
560   if (cfile->pb_fps < 0 || (cfile->play_paused &&
561                             cfile->freeze_fps < 0)) dirchange_callback(NULL, NULL, 0,
562                                   (LiVESXModifierType)0, LIVES_INT_TO_POINTER(SCREEN_AREA_FOREGROUND));
563   if (cfile->play_paused) freeze_callback(NULL, NULL, 0, (LiVESXModifierType)0, NULL);
564 
565   return lives_osc_notify_success(NULL);
566 }
567 
568 
lives_osc_cb_bgplay_reset(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)569 boolean lives_osc_cb_bgplay_reset(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
570   if (mainw->multitrack) return lives_osc_notify_failure();
571   if (!LIVES_IS_PLAYING) return lives_osc_notify_failure();
572 
573   if (!IS_VALID_CLIP(mainw->blend_file) || mainw->blend_file == mainw->current_file) return lives_osc_notify_failure();
574 
575   if (mainw->files[mainw->blend_file]->play_paused) {
576     mainw->files[mainw->blend_file]->play_paused = FALSE;
577   }
578 
579   if (mainw->files[mainw->blend_file]->pb_fps >= 0.) mainw->files[mainw->blend_file]->pb_fps =
580       mainw->files[mainw->blend_file]->fps;
581   else mainw->files[mainw->blend_file]->pb_fps = -mainw->files[mainw->blend_file]->fps;
582   return lives_osc_notify_success(NULL);
583 }
584 
585 
586 /* /video/stop */
lives_osc_cb_stop(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)587 boolean lives_osc_cb_stop(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
588   if (LIVES_IS_PLAYING) {
589     on_stop_activate(NULL, NULL); // should send play stop event
590     return lives_osc_notify_success(NULL);
591   } else return lives_osc_notify_failure();
592 }
593 
594 
lives_osc_cb_set_loop(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)595 boolean lives_osc_cb_set_loop(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
596   int lmode;
597 
598   if (lives_osc_check_arguments(arglen, vargs, "i", FALSE)) {
599     lives_osc_check_arguments(arglen, vargs, "i", TRUE);
600     lives_osc_parse_int_argument(vargs, &lmode);
601   } else return lives_osc_notify_failure();
602 
603   if (lmode == atoi(get_omc_const("LIVES_LOOP_MODE_NONE"))) {
604     if (mainw->loop_cont) on_loop_button_activate(NULL, NULL);
605     if (mainw->loop) lives_check_menu_item_set_active(LIVES_CHECK_MENU_ITEM(mainw->loop_video), !mainw->loop);
606   } else {
607     if (lmode & atoi(get_omc_const("LIVES_LOOP_MODE_CONTINUOUS"))) {
608       if (!mainw->loop_cont) on_loop_button_activate(NULL, NULL);
609     } else if (mainw->loop_cont) on_loop_button_activate(NULL, NULL);
610 
611     if (lmode & atoi(get_omc_const("LIVES_LOOP_MODE_FIT_AUDIO"))) {
612       if (!mainw->loop) lives_check_menu_item_set_active(LIVES_CHECK_MENU_ITEM(mainw->loop_video), TRUE);
613     } else if (mainw->loop) lives_check_menu_item_set_active(LIVES_CHECK_MENU_ITEM(mainw->loop_video), FALSE);
614   }
615 
616   return lives_osc_notify_success(NULL);
617 }
618 
619 
lives_osc_cb_get_loop(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)620 boolean lives_osc_cb_get_loop(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
621   int lmode = 0;
622   char *lmodes;
623 
624   if (mainw->loop) lmode |= atoi(get_omc_const("LIVES_LOOP_MODE_FIT_AUDIO"));
625   if (mainw->loop_cont) lmode |= atoi(get_omc_const("LIVES_LOOP_MODE_CONTINUOUS"));
626 
627   lmodes = lives_strdup_printf("%d", lmode);
628   lives_status_send(lmodes);
629   lives_free(lmodes);
630   return TRUE;
631 }
632 
633 
lives_osc_cb_set_pingpong(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)634 boolean lives_osc_cb_set_pingpong(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
635   int lmode;
636   char *boolstr;
637 
638   if (lives_osc_check_arguments(arglen, vargs, "i", FALSE)) {
639     lives_osc_check_arguments(arglen, vargs, "i", TRUE);
640     lives_osc_parse_int_argument(vargs, &lmode);
641     boolstr = lives_strdup_printf("%d", lmode);
642     if (!strcmp(boolstr, get_omc_const("LIVES_TRUE"))) lmode = TRUE;
643     else {
644       if (!strcmp(boolstr, get_omc_const("LIVES_FALSE"))) lmode = FALSE;
645       else {
646         lives_free(boolstr);
647         return lives_osc_notify_failure();
648       }
649     }
650     lives_free(boolstr);
651   } else return lives_osc_notify_failure();
652 
653   if ((lmode && !mainw->ping_pong) || (!lmode && mainw->ping_pong))
654     lives_check_menu_item_set_active(LIVES_CHECK_MENU_ITEM(mainw->loop_ping_pong), !mainw->ping_pong);
655 
656   return lives_osc_notify_success(NULL);
657 }
658 
659 
lives_osc_cb_get_pingpong(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)660 boolean lives_osc_cb_get_pingpong(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
661   if (mainw->ping_pong) return lives_status_send(get_omc_const("LIVES_TRUE"));
662   return lives_status_send(get_omc_const("LIVES_FALSE"));
663 }
664 
665 
lives_osc_cb_set_fps(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)666 boolean lives_osc_cb_set_fps(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
667   int fpsi;
668   float fps;
669   if (mainw->multitrack) return lives_osc_notify_failure();
670   if (lives_osc_check_arguments(arglen, vargs, "i", FALSE)) {
671     lives_osc_check_arguments(arglen, vargs, "i", TRUE);
672     lives_osc_parse_int_argument(vargs, &fpsi);
673     fps = (float)fpsi;
674   } else {
675     if (!lives_osc_check_arguments(arglen, vargs, "f", TRUE)) return lives_osc_notify_failure();
676     lives_osc_parse_float_argument(vargs, &fps);
677   }
678 
679   if (LIVES_IS_PLAYING) lives_spin_button_set_value(LIVES_SPIN_BUTTON(mainw->spinbutton_pb_fps), (double)(fps));
680   return lives_osc_notify_success(NULL);
681 }
682 
683 
lives_osc_cb_bgset_fps(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)684 boolean lives_osc_cb_bgset_fps(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
685   int fpsi;
686   float fps;
687 
688   if (mainw->multitrack) return lives_osc_notify_failure();
689   if (!IS_VALID_CLIP(mainw->blend_file) || mainw->blend_file == mainw->current_file) return lives_osc_notify_failure();
690 
691   if (lives_osc_check_arguments(arglen, vargs, "i", FALSE)) {
692     lives_osc_check_arguments(arglen, vargs, "i", TRUE);
693     lives_osc_parse_int_argument(vargs, &fpsi);
694     fps = (float)fpsi;
695   } else {
696     if (!lives_osc_check_arguments(arglen, vargs, "f", TRUE)) return lives_osc_notify_failure();
697     lives_osc_parse_float_argument(vargs, &fps);
698   }
699 
700   mainw->files[mainw->blend_file]->pb_fps = (double)fps;
701   return lives_osc_notify_success(NULL);
702 }
703 
704 
lives_osc_cb_set_fps_ratio(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)705 boolean lives_osc_cb_set_fps_ratio(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
706   int fpsi;
707   float fps;
708   if (mainw->multitrack) return lives_osc_notify_failure();
709   if (lives_osc_check_arguments(arglen, vargs, "i", FALSE)) {
710     lives_osc_check_arguments(arglen, vargs, "i", TRUE);
711     lives_osc_parse_int_argument(vargs, &fpsi);
712     fps = (float)fpsi;
713   } else {
714     if (!lives_osc_check_arguments(arglen, vargs, "f", TRUE)) return lives_osc_notify_failure();
715     lives_osc_parse_float_argument(vargs, &fps);
716   }
717 
718   if (LIVES_IS_PLAYING) lives_spin_button_set_value(LIVES_SPIN_BUTTON(mainw->spinbutton_pb_fps),
719         (double)(fps)*mainw->files[mainw->playing_file]->fps);
720   return lives_osc_notify_success(NULL);
721 }
722 
723 
lives_osc_cb_bgset_fps_ratio(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)724 boolean lives_osc_cb_bgset_fps_ratio(void *context, int arglen, const void *vargs, OSCTimeTag when,
725                                      NetworkReturnAddressPtr ra) {
726   int fpsi;
727   float fps;
728   if (mainw->multitrack) return lives_osc_notify_failure();
729 
730   if (!IS_VALID_CLIP(mainw->blend_file) || mainw->blend_file == mainw->current_file) return lives_osc_notify_failure();
731 
732   if (lives_osc_check_arguments(arglen, vargs, "i", FALSE)) {
733     lives_osc_check_arguments(arglen, vargs, "i", TRUE);
734     lives_osc_parse_int_argument(vargs, &fpsi);
735     fps = (float)fpsi;
736   } else {
737     if (!lives_osc_check_arguments(arglen, vargs, "f", TRUE)) return lives_osc_notify_failure();
738     lives_osc_parse_float_argument(vargs, &fps);
739   }
740 
741   mainw->files[mainw->blend_file]->pb_fps = mainw->files[mainw->blend_file]->fps * (double)fps;
742   return lives_osc_notify_success(NULL);
743 }
744 
745 
lives_osc_cb_fx_reset(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)746 boolean lives_osc_cb_fx_reset(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
747   if (!mainw->osc_block) rte_keys_reset();
748   return lives_osc_notify_success(NULL);
749 }
750 
751 
lives_osc_cb_fx_map_clear(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)752 boolean lives_osc_cb_fx_map_clear(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
753   if (!mainw->osc_block) on_clear_all_clicked(NULL, NULL);
754   return lives_osc_notify_success(NULL);
755 }
756 
757 
lives_osc_cb_fx_map(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)758 boolean lives_osc_cb_fx_map(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
759   int effect_key;
760   char effect_name[OSC_STRING_SIZE];
761 
762   if (!lives_osc_check_arguments(arglen, vargs, "is", TRUE)) return lives_osc_notify_failure();
763   lives_osc_parse_int_argument(vargs, &effect_key);
764   lives_osc_parse_string_argument(vargs, effect_name);
765   if (effect_key < 1 || effect_key >= prefs->rte_keys_virtual) return lives_osc_notify_failure();
766   if (!mainw->osc_block) {
767     weed_add_effectkey(effect_key, effect_name, FALSE); // allow partial matches
768     return lives_osc_notify_success(NULL);
769   }
770   return lives_osc_notify_failure();
771 }
772 
773 
lives_osc_cb_fx_unmap(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)774 boolean lives_osc_cb_fx_unmap(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
775   int effect_key;
776   int mode;
777 
778   if (!lives_osc_check_arguments(arglen, vargs, "ii", TRUE)) return lives_osc_notify_failure();
779   lives_osc_parse_int_argument(vargs, &effect_key);
780   lives_osc_parse_int_argument(vargs, &mode);
781   mode--;
782   if (!mainw->osc_block && rte_keymode_valid(effect_key, mode, TRUE)) {
783     int idx = effect_key * rte_getmodespk() + mode;
784     on_clear_clicked(NULL, LIVES_INT_TO_POINTER(idx));
785     return lives_osc_notify_success(NULL);
786   }
787   return lives_osc_notify_failure();
788 }
789 
790 
osc_fx_on(int effect_key)791 static boolean osc_fx_on(int effect_key) {
792   int count;
793   int grab = mainw->last_grabbable_effect;
794 
795   weed_plant_t *filter = rte_keymode_get_filter(effect_key, rte_key_getmode(effect_key));
796 
797   if (!filter) return lives_osc_notify_failure();
798   count = enabled_in_channels(filter, FALSE);
799   if (!LIVES_IS_PLAYING && via_shortcut && count != 0) return lives_osc_notify_failure(); // is no generator
800 
801   if (!LIVES_IS_PLAYING && count == 0) {
802     if (mainw->preview || (!mainw->multitrack && mainw->event_list) || mainw->is_processing ||
803         mainw->multitrack) return lives_osc_notify_failure();
804     mainw->error = FALSE;
805     lives_timer_add_simple(0, osc_init_generator, LIVES_INT_TO_POINTER(effect_key));
806     return TRUE;
807   } else {
808     rte_key_toggle(effect_key);
809     mainw->last_grabbable_effect = grab;
810   }
811   return lives_osc_notify_success(NULL);
812 }
813 
814 
lives_osc_cb_fx_enable(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)815 boolean lives_osc_cb_fx_enable(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
816   // if via_shortcut and not playing, we ignore unless a generator starts (which starts playback)
817   int effect_key;
818 
819   if (mainw->multitrack) return lives_osc_notify_failure();
820   if (!lives_osc_check_arguments(arglen, vargs, "i", TRUE)) return lives_osc_notify_failure();
821   lives_osc_parse_int_argument(vargs, &effect_key);
822   if (effect_key < 1 || effect_key >= prefs->rte_keys_virtual) return lives_osc_notify_failure();
823 
824   if (!mainw->osc_block) {
825     if (!(mainw->rte & (GU641 << (effect_key - 1)))) {
826       return osc_fx_on(effect_key);
827     }
828   } else return lives_osc_notify_failure();
829 
830   return lives_osc_notify_success(NULL);
831 }
832 
833 
lives_osc_cb_fx_disable(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)834 boolean lives_osc_cb_fx_disable(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
835   int effect_key;
836   if (mainw->multitrack) return lives_osc_notify_failure();
837   if (!lives_osc_check_arguments(arglen, vargs, "i", TRUE)) return lives_osc_notify_failure();
838   lives_osc_parse_int_argument(vargs, &effect_key);
839   if (effect_key < 1 || effect_key >= prefs->rte_keys_virtual) return lives_osc_notify_failure();
840   if (mainw->rte & (GU641 << (effect_key - 1))) {
841     if (!mainw->osc_block) {
842       rte_key_toggle(effect_key);
843       return lives_osc_notify_success(NULL);
844     }
845   }
846   return lives_osc_notify_failure();
847 }
848 
849 
lives_osc_cb_fx_toggle(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)850 boolean lives_osc_cb_fx_toggle(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
851   int effect_key;
852 
853   if (mainw->multitrack) return lives_osc_notify_failure();
854   if (!lives_osc_check_arguments(arglen, vargs, "i", TRUE)) return lives_osc_notify_failure();
855   lives_osc_parse_int_argument(vargs, &effect_key);
856   if (effect_key < 1 || effect_key >= prefs->rte_keys_virtual) return lives_osc_notify_failure();
857 
858   if (!(mainw->rte & (GU641 << (effect_key - 1)))) {
859     return osc_fx_on(effect_key);
860   }
861 
862   if (!mainw->osc_block) rte_key_toggle(effect_key);
863 
864   return lives_osc_notify_success(NULL);
865 }
866 
867 // *_set will allow setting of invalid clips - in this case nothing happens
868 //*_select will index only valid clips
869 
870 
lives_osc_cb_fgclip_set(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)871 boolean lives_osc_cb_fgclip_set(void *context, int arglen, const void *vargs, OSCTimeTag when,	NetworkReturnAddressPtr ra) {
872   // switch fg clip
873 
874   int clip;
875   if (mainw->current_file < 1 || (mainw->preview || (mainw->event_list && (!mainw->record || !LIVES_IS_PLAYING))) ||
876       mainw->is_processing ||
877       mainw->multitrack) return lives_osc_notify_failure();
878 
879   if (!lives_osc_check_arguments(arglen, vargs, "i", TRUE)) return lives_osc_notify_failure();
880   lives_osc_parse_int_argument(vargs, &clip);
881 
882   if (clip > 0 && clip < MAX_FILES - 1) {
883     if (IS_NORMAL_CLIP(clip)) {
884       if (mainw->playing_file != 0) {
885         char *msg = lives_strdup_printf("%d", clip);
886         switch_clip(1, clip, FALSE);
887         lives_osc_notify_success(msg);
888         lives_free(msg);
889         return TRUE;
890       }
891     }
892   }
893   return lives_osc_notify_failure();
894 }
895 
896 
lives_osc_cb_bgclip_set(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)897 boolean lives_osc_cb_bgclip_set(void *context, int arglen, const void *vargs, OSCTimeTag when,	NetworkReturnAddressPtr ra) {
898   // switch bg clip
899 
900   int clip;
901   if (mainw->current_file < 1 || (mainw->preview || (mainw->event_list && (!mainw->record || !LIVES_IS_PLAYING))) ||
902       mainw->is_processing ||
903       mainw->multitrack) return lives_osc_notify_failure();
904 
905   if (!lives_osc_check_arguments(arglen, vargs, "i", TRUE)) return lives_osc_notify_failure();
906   lives_osc_parse_int_argument(vargs, &clip);
907 
908   if (clip > 0 && clip < MAX_FILES - 1) {
909     if (IS_NORMAL_CLIP(clip)) {
910       char *msg = lives_strdup_printf("%d", clip);
911       switch_clip(2, clip, FALSE);
912       lives_osc_notify_success(msg);
913       lives_free(msg);
914       return TRUE;
915     }
916   }
917   return lives_osc_notify_failure();
918 }
919 
920 
lives_osc_cb_fgclip_select(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)921 boolean lives_osc_cb_fgclip_select(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
922   // switch fg clip
923   int clip, i;
924   if (mainw->current_file < 1 || (mainw->preview || (mainw->event_list && (!mainw->record || !LIVES_IS_PLAYING))) ||
925       mainw->is_processing ||
926       mainw->multitrack) return lives_osc_notify_failure();
927 
928   if (!lives_osc_check_arguments(arglen, vargs, "i", TRUE)) return lives_osc_notify_failure();
929   lives_osc_parse_int_argument(vargs, &clip);
930 
931   if (clip < 1 || !mainw->cliplist) return lives_osc_notify_failure();
932 
933   if (mainw->scrap_file != -1 && clip >= mainw->scrap_file) clip++;
934   if (mainw->ascrap_file != -1 && clip >= mainw->ascrap_file) clip++;
935 
936   if (clip > lives_list_length(mainw->cliplist)) return lives_osc_notify_failure();
937 
938   i = LIVES_POINTER_TO_INT(lives_list_nth_data(mainw->cliplist, clip - 1));
939 
940   if (i == mainw->current_file) return lives_osc_notify_failure();
941   if (mainw->playing_file != 0) {
942     char *msg;
943     switch_clip(1, i, FALSE);
944     msg = lives_strdup_printf("%d", i);
945     lives_osc_notify_success(msg);
946     lives_free(msg);
947     return TRUE;
948   }
949   return lives_osc_notify_failure();
950 }
951 
952 
lives_osc_cb_bgclip_select(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)953 boolean lives_osc_cb_bgclip_select(void *context, int arglen, const void *vargs, OSCTimeTag when,	NetworkReturnAddressPtr ra) {
954   // switch bg clip
955   char *msg;
956   int clip, i;
957 
958   if (mainw->current_file < 1 || (mainw->preview || (mainw->event_list && (!mainw->record || !LIVES_IS_PLAYING))) ||
959       mainw->is_processing ||
960       mainw->multitrack) return lives_osc_notify_failure(); // etc
961 
962   if (!lives_osc_check_arguments(arglen, vargs, "i", TRUE)) return lives_osc_notify_failure();
963   lives_osc_parse_int_argument(vargs, &clip);
964 
965   if (clip < 1 || !mainw->cliplist) return lives_osc_notify_failure();
966 
967   if (mainw->scrap_file != -1 && clip >= mainw->scrap_file) clip++;
968 
969   if (mainw->ascrap_file != -1 && clip >= mainw->ascrap_file) clip++;
970 
971   if (clip > lives_list_length(mainw->cliplist)) return lives_osc_notify_failure();
972 
973   if (mainw->num_tr_applied < 1) return lives_osc_notify_failure();
974 
975   i = LIVES_POINTER_TO_INT(lives_list_nth_data(mainw->cliplist, clip - 1));
976 
977   if (i == mainw->blend_file) return lives_osc_notify_failure();
978 
979   switch_clip(2, i, FALSE);
980 
981   msg = lives_strdup_printf("%d", i);
982   lives_osc_notify_success(msg);
983   lives_free(msg);
984   return TRUE;
985 }
986 
987 
lives_osc_cb_clip_resample(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)988 boolean lives_osc_cb_clip_resample(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
989   int fps;
990   float fpsf;
991   double fpsd;
992 
993   if (LIVES_IS_PLAYING) return lives_osc_notify_failure();
994 
995   if (mainw->current_file < 1 || (mainw->preview || (!mainw->multitrack && mainw->event_list)) ||
996       mainw->is_processing ||
997       mainw->multitrack) return lives_osc_notify_failure();
998 
999   if (!lives_osc_check_arguments(arglen, vargs, "f", FALSE)) {
1000     if (!lives_osc_check_arguments(arglen, vargs, "i", TRUE)) return lives_osc_notify_failure();
1001     lives_osc_parse_int_argument(vargs, &fps);
1002     fpsd = (double)(fps * 1.);
1003   } else {
1004     lives_osc_check_arguments(arglen, vargs, "f", TRUE);
1005     lives_osc_parse_float_argument(vargs, &fpsf);
1006     fpsd = (double)fpsf;
1007   }
1008 
1009   if (fpsd < 1. && fpsd > FPS_MAX) return lives_osc_notify_failure();
1010 
1011   cfile->undo1_dbl = fpsd;
1012 
1013   on_resample_vid_ok(NULL, NULL);
1014 
1015   return lives_osc_notify_success(NULL);
1016 }
1017 
1018 
lives_osc_cb_clip_close(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)1019 boolean lives_osc_cb_clip_close(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
1020   int noaudio = 0;
1021   int clipno = mainw->current_file;
1022   int current_file = clipno;
1023 
1024   char *boolstr;
1025 
1026   if (LIVES_IS_PLAYING) return lives_osc_notify_failure();
1027 
1028   if (mainw->current_file < 1 || (mainw->preview || (!mainw->multitrack && mainw->event_list)) ||
1029       mainw->is_processing) return lives_osc_notify_failure();
1030 
1031   if (lives_osc_check_arguments(arglen, vargs, "i", FALSE)) {
1032     lives_osc_check_arguments(arglen, vargs, "i", TRUE);
1033     lives_osc_parse_int_argument(vargs, &noaudio);
1034   } else if (mainw->multitrack || !lives_osc_check_arguments(arglen, vargs, "", TRUE)) {
1035     return lives_osc_notify_failure();
1036   }
1037 
1038   boolstr = lives_strdup_printf("%d", noaudio);
1039   if (!strcmp(boolstr, get_omc_const("LIVES_TRUE"))) noaudio = TRUE;
1040   else {
1041     if (!strcmp(boolstr, get_omc_const("LIVES_FALSE"))) noaudio = FALSE;
1042     else {
1043       lives_free(boolstr);
1044       return lives_osc_notify_failure();
1045     }
1046   }
1047   lives_free(boolstr);
1048 
1049   if (!IS_VALID_CLIP(clipno) || (mainw->multitrack && clipno == mainw->multitrack->render_file))
1050     return lives_osc_notify_failure();
1051 
1052   if (clipno == current_file) current_file = -1;
1053 
1054   mainw->current_file = clipno;
1055 
1056   close_current_file(current_file);
1057   return lives_osc_notify_success(NULL);
1058 }
1059 
1060 
lives_osc_cb_clip_undo(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)1061 boolean lives_osc_cb_clip_undo(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
1062   int clipno = mainw->current_file;
1063   int current_file = clipno;
1064 
1065   if (LIVES_IS_PLAYING) return lives_osc_notify_failure();
1066 
1067   if (mainw->current_file < 1 || mainw->preview || mainw->event_list || mainw->is_processing ||
1068       mainw->multitrack) return lives_osc_notify_failure();
1069 
1070   if (lives_osc_check_arguments(arglen, vargs, "i", FALSE)) {
1071     lives_osc_check_arguments(arglen, vargs, "i", TRUE);
1072     lives_osc_parse_int_argument(vargs, &clipno);
1073   } else if (!lives_osc_check_arguments(arglen, vargs, "", TRUE)) {
1074     return lives_osc_notify_failure();
1075   }
1076 
1077   if (!IS_VALID_CLIP(clipno)) return lives_osc_notify_failure();
1078 
1079   if (!mainw->files[clipno]->undoable) return lives_osc_notify_failure();
1080 
1081   mainw->current_file = clipno;
1082 
1083   on_undo_activate(NULL, NULL);
1084 
1085   switch_to_file(mainw->current_file = 0, current_file);
1086 
1087   return lives_osc_notify_success(NULL);
1088 }
1089 
1090 
lives_osc_cb_clip_redo(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)1091 boolean lives_osc_cb_clip_redo(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
1092   int clipno = mainw->current_file;
1093   int current_file = clipno;
1094 
1095   if (LIVES_IS_PLAYING) return lives_osc_notify_failure();
1096 
1097   if (mainw->current_file < 1 || mainw->preview || mainw->event_list || mainw->is_processing ||
1098       mainw->multitrack) return lives_osc_notify_failure();
1099 
1100   if (lives_osc_check_arguments(arglen, vargs, "i", FALSE)) {
1101     lives_osc_check_arguments(arglen, vargs, "i", TRUE);
1102     lives_osc_parse_int_argument(vargs, &clipno);
1103   } else if (!lives_osc_check_arguments(arglen, vargs, "", TRUE)) {
1104     return lives_osc_notify_failure();
1105   }
1106 
1107   if (!IS_VALID_CLIP(clipno)) return lives_osc_notify_failure();
1108 
1109   if (!mainw->files[clipno]->redoable) return lives_osc_notify_failure();
1110 
1111   mainw->current_file = clipno;
1112 
1113   on_redo_activate(NULL, NULL);
1114 
1115   switch_to_file(mainw->current_file = 0, current_file);
1116 
1117   return lives_osc_notify_success(NULL);
1118 }
1119 
1120 
lives_osc_cb_fgclip_copy(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)1121 boolean lives_osc_cb_fgclip_copy(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
1122   int noaudio = 0;
1123   int clipno = mainw->current_file;
1124   int start, end, current_file = clipno;
1125   boolean ccpd;
1126 
1127   char *boolstr;
1128 
1129   if (LIVES_IS_PLAYING || mainw->multitrack) return lives_osc_notify_failure();
1130 
1131   if (mainw->current_file < 1 || (mainw->preview || (!mainw->multitrack && mainw->event_list)) ||
1132       mainw->is_processing) return lives_osc_notify_failure();
1133 
1134   if (lives_osc_check_arguments(arglen, vargs, "ii", FALSE)) {
1135     lives_osc_check_arguments(arglen, vargs, "ii", TRUE);
1136     lives_osc_parse_int_argument(vargs, &noaudio);
1137     lives_osc_parse_int_argument(vargs, &clipno);
1138   } else if (lives_osc_check_arguments(arglen, vargs, "i", FALSE)) {
1139     lives_osc_check_arguments(arglen, vargs, "i", TRUE);
1140     lives_osc_parse_int_argument(vargs, &noaudio);
1141   } else if (!lives_osc_check_arguments(arglen, vargs, "", TRUE)) {
1142     return lives_osc_notify_failure();
1143   }
1144 
1145   boolstr = lives_strdup_printf("%d", noaudio);
1146   if (!strcmp(boolstr, get_omc_const("LIVES_TRUE"))) noaudio = TRUE;
1147   else {
1148     if (!strcmp(boolstr, get_omc_const("LIVES_FALSE"))) noaudio = FALSE;
1149     else {
1150       lives_free(boolstr);
1151       return lives_osc_notify_failure();
1152     }
1153   }
1154   lives_free(boolstr);
1155 
1156   if (!IS_NORMAL_CLIP(clipno) || clipno == 0) return lives_osc_notify_failure();
1157 
1158   mainw->current_file = clipno;
1159   start = cfile->start;
1160   end = cfile->end;
1161 
1162   cfile->start = 1;
1163   cfile->end = cfile->frames;
1164 
1165   ccpd = mainw->ccpd_with_sound;
1166 
1167   mainw->ccpd_with_sound = !noaudio;
1168 
1169   on_copy_activate(NULL, NULL);
1170 
1171   mainw->ccpd_with_sound = ccpd;
1172 
1173   cfile->start = start;
1174   cfile->end = end;
1175 
1176   mainw->current_file = current_file;
1177 
1178   return lives_osc_notify_success(NULL);
1179 }
1180 
1181 
lives_osc_cb_fgclipsel_rteapply(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)1182 boolean lives_osc_cb_fgclipsel_rteapply(void *context, int arglen, const void *vargs, OSCTimeTag when,
1183                                         NetworkReturnAddressPtr ra) {
1184   int clipno = mainw->current_file;
1185   int current_file = clipno;
1186 
1187   if (LIVES_IS_PLAYING || mainw->multitrack) return lives_osc_notify_failure();
1188 
1189   if (mainw->current_file < 1 || (mainw->preview || (!mainw->multitrack && mainw->event_list)) ||
1190       mainw->is_processing) return lives_osc_notify_failure();
1191 
1192   if (lives_osc_check_arguments(arglen, vargs, "i", FALSE)) {
1193     lives_osc_check_arguments(arglen, vargs, "i", TRUE);
1194     lives_osc_parse_int_argument(vargs, &clipno);
1195   } else if (!lives_osc_check_arguments(arglen, vargs, "", TRUE)) {
1196     return lives_osc_notify_failure();
1197   }
1198 
1199   if (!IS_NORMAL_CLIP(clipno) || clipno == 0) return lives_osc_notify_failure();
1200 
1201   mainw->current_file = clipno;
1202 
1203   on_realfx_activate(NULL, &mainw->rendered_fx[0]);
1204 
1205   mainw->current_file = current_file;
1206 
1207   return lives_osc_notify_success(NULL);
1208 }
1209 
1210 
lives_osc_cb_fgclipsel_copy(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)1211 boolean lives_osc_cb_fgclipsel_copy(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
1212   int noaudio = 0;
1213   int clipno = mainw->current_file;
1214   int current_file = clipno;
1215   boolean ccpd;
1216 
1217   char *boolstr;
1218 
1219   if (LIVES_IS_PLAYING || mainw->multitrack) return lives_osc_notify_failure();
1220 
1221   if (mainw->current_file < 1 || (mainw->preview || (!mainw->multitrack && mainw->event_list)) ||
1222       mainw->is_processing) return lives_osc_notify_failure();
1223 
1224   if (lives_osc_check_arguments(arglen, vargs, "ii", FALSE)) {
1225     lives_osc_check_arguments(arglen, vargs, "ii", TRUE);
1226     lives_osc_parse_int_argument(vargs, &noaudio);
1227     lives_osc_parse_int_argument(vargs, &clipno);
1228   } else if (lives_osc_check_arguments(arglen, vargs, "i", FALSE)) {
1229     lives_osc_check_arguments(arglen, vargs, "i", TRUE);
1230     lives_osc_parse_int_argument(vargs, &noaudio);
1231   } else if (!lives_osc_check_arguments(arglen, vargs, "", TRUE)) {
1232     return lives_osc_notify_failure();
1233   }
1234 
1235   boolstr = lives_strdup_printf("%d", noaudio);
1236   if (!strcmp(boolstr, get_omc_const("LIVES_TRUE"))) noaudio = TRUE;
1237   else {
1238     if (!strcmp(boolstr, get_omc_const("LIVES_FALSE"))) noaudio = FALSE;
1239     else {
1240       lives_free(boolstr);
1241       return lives_osc_notify_failure();
1242     }
1243   }
1244   lives_free(boolstr);
1245 
1246   if (!IS_NORMAL_CLIP(clipno) || clipno == 0) return lives_osc_notify_failure();
1247 
1248   mainw->current_file = clipno;
1249 
1250   ccpd = mainw->ccpd_with_sound;
1251 
1252   mainw->ccpd_with_sound = !noaudio;
1253 
1254   on_copy_activate(NULL, NULL);
1255 
1256   mainw->ccpd_with_sound = ccpd;
1257 
1258   mainw->current_file = current_file;
1259 
1260   return lives_osc_notify_success(NULL);
1261 }
1262 
1263 
lives_osc_cb_fgclipsel_cut(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)1264 boolean lives_osc_cb_fgclipsel_cut(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
1265   int noaudio = 0;
1266   int clipno = mainw->current_file;
1267   int current_file = clipno;
1268   boolean ccpd;
1269 
1270   char *boolstr;
1271 
1272   if (LIVES_IS_PLAYING) return lives_osc_notify_failure();
1273   if (mainw->multitrack) return lives_osc_notify_failure();
1274 
1275   if (mainw->current_file < 1 || (mainw->preview || (!mainw->multitrack && mainw->event_list)) ||
1276       mainw->is_processing) return lives_osc_notify_failure();
1277 
1278   if (lives_osc_check_arguments(arglen, vargs, "ii", FALSE)) {
1279     lives_osc_check_arguments(arglen, vargs, "ii", TRUE);
1280     lives_osc_parse_int_argument(vargs, &noaudio);
1281     lives_osc_parse_int_argument(vargs, &clipno);
1282   } else if (lives_osc_check_arguments(arglen, vargs, "i", FALSE)) {
1283     lives_osc_check_arguments(arglen, vargs, "i", TRUE);
1284     lives_osc_parse_int_argument(vargs, &noaudio);
1285   } else if (!lives_osc_check_arguments(arglen, vargs, "", TRUE)) {
1286     return lives_osc_notify_failure();
1287   }
1288 
1289   boolstr = lives_strdup_printf("%d", noaudio);
1290   if (!strcmp(boolstr, get_omc_const("LIVES_TRUE"))) noaudio = TRUE;
1291   else {
1292     if (!strcmp(boolstr, get_omc_const("LIVES_FALSE"))) noaudio = FALSE;
1293     else {
1294       lives_free(boolstr);
1295       return lives_osc_notify_failure();
1296     }
1297   }
1298   lives_free(boolstr);
1299 
1300   if (!IS_NORMAL_CLIP(clipno) || clipno == 0) return lives_osc_notify_failure();
1301 
1302   mainw->current_file = clipno;
1303 
1304   ccpd = mainw->ccpd_with_sound;
1305 
1306   mainw->ccpd_with_sound = !noaudio;
1307 
1308   mainw->osc_auto = 1;
1309   on_cut_activate(NULL, NULL);
1310   mainw->osc_auto = 0;
1311 
1312   mainw->ccpd_with_sound = ccpd;
1313 
1314   mainw->current_file = current_file;
1315 
1316   return lives_osc_notify_success(NULL);
1317 }
1318 
1319 
lives_osc_cb_fgclipsel_delete(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)1320 boolean lives_osc_cb_fgclipsel_delete(void *context, int arglen, const void *vargs, OSCTimeTag when,
1321                                       NetworkReturnAddressPtr ra) {
1322   int noaudio = 0;
1323   int clipno = mainw->current_file;
1324   int current_file = clipno;
1325   boolean ccpd;
1326 
1327   char *boolstr;
1328 
1329   if (LIVES_IS_PLAYING) return lives_osc_notify_failure();
1330   if (mainw->multitrack) return lives_osc_notify_failure();
1331 
1332   if (mainw->current_file < 1 || (mainw->preview || (!mainw->multitrack && mainw->event_list)) ||
1333       mainw->is_processing) return lives_osc_notify_failure();
1334 
1335   if (lives_osc_check_arguments(arglen, vargs, "ii", FALSE)) {
1336     lives_osc_check_arguments(arglen, vargs, "ii", TRUE);
1337     lives_osc_parse_int_argument(vargs, &noaudio);
1338     lives_osc_parse_int_argument(vargs, &clipno);
1339   } else if (lives_osc_check_arguments(arglen, vargs, "i", FALSE)) {
1340     lives_osc_check_arguments(arglen, vargs, "i", TRUE);
1341     lives_osc_parse_int_argument(vargs, &noaudio);
1342   } else if (!lives_osc_check_arguments(arglen, vargs, "", TRUE)) {
1343     return lives_osc_notify_failure();
1344   }
1345 
1346   boolstr = lives_strdup_printf("%d", noaudio);
1347   if (!strcmp(boolstr, get_omc_const("LIVES_TRUE"))) noaudio = TRUE;
1348   else {
1349     if (!strcmp(boolstr, get_omc_const("LIVES_FALSE"))) noaudio = FALSE;
1350     else {
1351       lives_free(boolstr);
1352       return lives_osc_notify_failure();
1353     }
1354   }
1355   lives_free(boolstr);
1356 
1357   if (!IS_NORMAL_CLIP(clipno) || clipno == 0) return lives_osc_notify_failure();
1358 
1359   mainw->current_file = clipno;
1360 
1361   ccpd = mainw->ccpd_with_sound;
1362 
1363   mainw->ccpd_with_sound = !noaudio;
1364 
1365   mainw->osc_auto = 1;
1366   on_delete_activate(NULL, NULL);
1367   mainw->osc_auto = 0;
1368 
1369   mainw->ccpd_with_sound = ccpd;
1370 
1371   mainw->current_file = current_file;
1372 
1373   return lives_osc_notify_success(NULL);
1374 }
1375 
1376 
lives_osc_cb_clipbd_paste(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)1377 boolean lives_osc_cb_clipbd_paste(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
1378   int noaudio = 0;
1379   boolean ccpd;
1380   char *boolstr;
1381 
1382   if (LIVES_IS_PLAYING) return lives_osc_notify_failure();
1383   if (mainw->multitrack) return lives_osc_notify_failure();
1384 
1385   if (!clipboard) return lives_osc_notify_failure();
1386 
1387   if (mainw->current_file < 1 || (mainw->preview || (!mainw->multitrack && mainw->event_list)) ||
1388       mainw->is_processing) return lives_osc_notify_failure();
1389 
1390   if (lives_osc_check_arguments(arglen, vargs, "i", FALSE)) {
1391     lives_osc_check_arguments(arglen, vargs, "i", TRUE);
1392     lives_osc_parse_int_argument(vargs, &noaudio);
1393   } else if (!lives_osc_check_arguments(arglen, vargs, "", TRUE)) {
1394     return lives_osc_notify_failure();
1395   }
1396 
1397   boolstr = lives_strdup_printf("%d", noaudio);
1398   if (!strcmp(boolstr, get_omc_const("LIVES_TRUE"))) noaudio = TRUE;
1399   else {
1400     if (!strcmp(boolstr, get_omc_const("LIVES_FALSE"))) noaudio = FALSE;
1401     else {
1402       lives_free(boolstr);
1403       return lives_osc_notify_failure();
1404     }
1405   }
1406   lives_free(boolstr);
1407 
1408   ccpd = mainw->ccpd_with_sound;
1409 
1410   mainw->ccpd_with_sound = !noaudio;
1411 
1412   on_paste_as_new_activate(NULL, NULL);
1413 
1414   mainw->ccpd_with_sound = ccpd;
1415 
1416   return lives_osc_notify_success(NULL);
1417 }
1418 
1419 
lives_osc_cb_clipbd_insertb(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)1420 boolean lives_osc_cb_clipbd_insertb(void *context, int arglen, const void *vargs, OSCTimeTag when,	NetworkReturnAddressPtr ra) {
1421   int noaudio = 0;
1422   int times = 1;
1423   int clipno = mainw->current_file;
1424   int current_file = clipno;
1425 
1426   char *boolstr;
1427 
1428   if (LIVES_IS_PLAYING) return lives_osc_notify_failure();
1429   if (mainw->multitrack) return lives_osc_notify_failure();
1430 
1431   if (mainw->current_file < 1 || (mainw->preview || (!mainw->multitrack && mainw->event_list)) ||
1432       mainw->is_processing) return lives_osc_notify_failure();
1433 
1434   if (lives_osc_check_arguments(arglen, vargs, "iii", FALSE)) {
1435     lives_osc_check_arguments(arglen, vargs, "iii", TRUE);
1436     lives_osc_parse_int_argument(vargs, &noaudio);
1437     lives_osc_parse_int_argument(vargs, &times);
1438     lives_osc_parse_int_argument(vargs, &clipno);
1439   } else if (lives_osc_check_arguments(arglen, vargs, "ii", FALSE)) {
1440     lives_osc_check_arguments(arglen, vargs, "ii", TRUE);
1441     lives_osc_parse_int_argument(vargs, &noaudio);
1442     lives_osc_parse_int_argument(vargs, &times);
1443   } else if (lives_osc_check_arguments(arglen, vargs, "i", FALSE)) {
1444     lives_osc_check_arguments(arglen, vargs, "i", TRUE);
1445     lives_osc_parse_int_argument(vargs, &noaudio);
1446   } else if (!lives_osc_check_arguments(arglen, vargs, "", TRUE)) {
1447     return lives_osc_notify_failure();
1448   }
1449 
1450   boolstr = lives_strdup_printf("%d", noaudio);
1451   if (!strcmp(boolstr, get_omc_const("LIVES_TRUE"))) noaudio = TRUE;
1452   else {
1453     if (!strcmp(boolstr, get_omc_const("LIVES_FALSE"))) noaudio = FALSE;
1454     else {
1455       lives_free(boolstr);
1456       return lives_osc_notify_failure();
1457     }
1458   }
1459   lives_free(boolstr);
1460 
1461   if (!IS_NORMAL_CLIP(clipno) || clipno == 0) return lives_osc_notify_failure();
1462 
1463   if (times == 0 || times < -1) return lives_osc_notify_failure();
1464 
1465   mainw->current_file = clipno;
1466 
1467   mainw->insert_after = FALSE;
1468 
1469   if (clipboard->achans == 0 && cfile->achans == 0) noaudio = TRUE;
1470 
1471   mainw->fx1_bool = (times == -1); // fit to audio
1472   mainw->fx1_val = times;     // times to insert otherwise
1473   mainw->fx2_bool = !noaudio; // with audio
1474 
1475   on_insert_activate(NULL, NULL);
1476 
1477   mainw->current_file = current_file;
1478   return lives_osc_notify_success(NULL);
1479 }
1480 
1481 
lives_osc_cb_clipbd_inserta(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)1482 boolean lives_osc_cb_clipbd_inserta(void *context, int arglen, const void *vargs, OSCTimeTag when,	NetworkReturnAddressPtr ra) {
1483   int noaudio = 0;
1484   int times = 1;
1485   int clipno = mainw->current_file;
1486   int current_file = clipno;
1487 
1488   char *boolstr;
1489 
1490   if (LIVES_IS_PLAYING) return lives_osc_notify_failure();
1491   if (mainw->multitrack) return lives_osc_notify_failure();
1492 
1493   if (mainw->current_file < 1 || (mainw->preview || (!mainw->multitrack && mainw->event_list)) ||
1494       mainw->is_processing) return lives_osc_notify_failure();
1495 
1496   if (lives_osc_check_arguments(arglen, vargs, "iii", FALSE)) {
1497     lives_osc_check_arguments(arglen, vargs, "iii", TRUE);
1498     lives_osc_parse_int_argument(vargs, &noaudio);
1499     lives_osc_parse_int_argument(vargs, &times);
1500     lives_osc_parse_int_argument(vargs, &clipno);
1501   } else if (lives_osc_check_arguments(arglen, vargs, "ii", FALSE)) {
1502     lives_osc_check_arguments(arglen, vargs, "ii", TRUE);
1503     lives_osc_parse_int_argument(vargs, &noaudio);
1504     lives_osc_parse_int_argument(vargs, &times);
1505   } else if (lives_osc_check_arguments(arglen, vargs, "i", FALSE)) {
1506     lives_osc_check_arguments(arglen, vargs, "i", TRUE);
1507     lives_osc_parse_int_argument(vargs, &noaudio);
1508   } else if (!lives_osc_check_arguments(arglen, vargs, "", TRUE)) {
1509     return lives_osc_notify_failure();
1510   }
1511 
1512   boolstr = lives_strdup_printf("%d", noaudio);
1513   if (!strcmp(boolstr, get_omc_const("LIVES_TRUE"))) noaudio = TRUE;
1514   else {
1515     if (!strcmp(boolstr, get_omc_const("LIVES_FALSE"))) noaudio = FALSE;
1516     else {
1517       lives_free(boolstr);
1518       return lives_osc_notify_failure();
1519     }
1520   }
1521   lives_free(boolstr);
1522 
1523   if (!IS_NORMAL_CLIP(clipno) || clipno == 0) return lives_osc_notify_failure();
1524 
1525   if (times == 0 || times < -1) return lives_osc_notify_failure();
1526 
1527   mainw->current_file = clipno;
1528 
1529   mainw->insert_after = TRUE;
1530 
1531   if (clipboard->achans == 0 && cfile->achans == 0) noaudio = TRUE;
1532 
1533   mainw->fx1_bool = (times == -1); // fit to audio
1534   mainw->fx1_val = times;     // times to insert otherwise
1535   mainw->fx2_bool = !noaudio; // with audio
1536 
1537   mainw->fx1_start = 1;
1538   mainw->fx2_start = count_resampled_frames(clipboard->frames, clipboard->fps, cfile->fps);
1539 
1540   on_insert_activate(NULL, NULL);
1541 
1542   mainw->current_file = current_file;
1543 
1544   return lives_osc_notify_success(NULL);
1545 }
1546 
1547 
lives_osc_cb_fgclip_retrigger(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)1548 boolean lives_osc_cb_fgclip_retrigger(void *context, int arglen, const void *vargs, OSCTimeTag when,
1549                                       NetworkReturnAddressPtr ra) {
1550   // switch fg clip and reset framenumber
1551 
1552   if (mainw->playing_file < 1 || (mainw->preview || (mainw->event_list && !mainw->record)) ||
1553       mainw->is_processing) return lives_osc_notify_failure();
1554   if (mainw->multitrack) return lives_osc_notify_failure();
1555   if (!lives_osc_check_arguments(arglen, vargs, "i", TRUE)) return lives_osc_notify_failure();
1556 
1557   lives_osc_cb_fgclip_select(context, arglen, vargs, when, ra);
1558 
1559   if (cfile->pb_fps > 0. || (cfile->play_paused && cfile->freeze_fps > 0.)) cfile->frameno = cfile->last_frameno = 1;
1560   else cfile->frameno = cfile->last_frameno = cfile->frames;
1561 
1562 #ifdef RT_AUDIO
1563   if (prefs->audio_opts & AUDIO_OPTS_FOLLOW_FPS) {
1564     resync_audio(cfile->frameno);
1565   }
1566 #endif
1567   return lives_osc_notify_success(NULL);
1568 }
1569 
1570 
lives_osc_cb_bgclip_retrigger(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)1571 boolean lives_osc_cb_bgclip_retrigger(void *context, int arglen, const void *vargs, OSCTimeTag when,
1572                                       NetworkReturnAddressPtr ra) {
1573   // switch bg clip and reset framenumber
1574 
1575   if (mainw->playing_file < 1 || (mainw->preview || (mainw->event_list && !mainw->record)) ||
1576       mainw->is_processing) return lives_osc_notify_failure();
1577   if (mainw->multitrack) return lives_osc_notify_failure();
1578   if (!lives_osc_check_arguments(arglen, vargs, "i", TRUE)) return lives_osc_notify_failure();
1579 
1580   lives_osc_cb_bgclip_select(context, arglen, vargs, when, ra);
1581 
1582   if (!IS_VALID_CLIP(mainw->blend_file) || mainw->blend_file == mainw->current_file) return lives_osc_notify_failure();
1583 
1584   if (mainw->files[mainw->blend_file]->pb_fps > 0. || (mainw->files[mainw->blend_file]->play_paused &&
1585       mainw->files[mainw->blend_file]->freeze_fps > 0.))
1586     mainw->files[mainw->blend_file]->frameno = mainw->files[mainw->blend_file]->last_frameno = 1;
1587   else mainw->files[mainw->blend_file]->frameno = mainw->files[mainw->blend_file]->last_frameno =
1588           mainw->files[mainw->blend_file]->frames;
1589   return lives_osc_notify_success(NULL);
1590 }
1591 
1592 
lives_osc_cb_fgclip_select_next(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)1593 boolean lives_osc_cb_fgclip_select_next(void *context, int arglen, const void *vargs, OSCTimeTag when,
1594                                         NetworkReturnAddressPtr ra) {
1595   // switch fg clip
1596 
1597   if (mainw->current_file < 1 || (mainw->preview || (mainw->event_list && (!mainw->record || !LIVES_IS_PLAYING))) ||
1598       mainw->is_processing) return lives_osc_notify_failure(); // TODO
1599   if (mainw->multitrack) return lives_osc_notify_failure();
1600 
1601   nextclip_callback(NULL, NULL, 0, (LiVESXModifierType)0, LIVES_INT_TO_POINTER(1));
1602 
1603   if (!LIVES_IS_PLAYING && prefs->omc_noisy) {
1604     char *msg = lives_strdup_printf("%d", mainw->current_file);
1605     lives_osc_notify_success(msg);
1606     lives_free(msg);
1607     return TRUE;
1608   }
1609   return lives_osc_notify_failure();
1610 }
1611 
1612 
lives_osc_cb_bgclip_select_next(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)1613 boolean lives_osc_cb_bgclip_select_next(void *context, int arglen, const void *vargs, OSCTimeTag when,
1614                                         NetworkReturnAddressPtr ra) {
1615   // switch bg clip
1616 
1617   if (mainw->current_file < 1 || (mainw->preview || (mainw->event_list && (!mainw->record || !LIVES_IS_PLAYING))) ||
1618       mainw->is_processing) return lives_osc_notify_failure(); // TODO
1619   if (!IS_VALID_CLIP(mainw->blend_file)) return lives_osc_notify_failure();
1620   if (mainw->multitrack) return lives_osc_notify_failure();
1621 
1622   nextclip_callback(NULL, NULL, 0, (LiVESXModifierType)0, LIVES_INT_TO_POINTER(2));
1623 
1624   if (!LIVES_IS_PLAYING && prefs->omc_noisy) {
1625     char *msg = lives_strdup_printf("%d", mainw->blend_file);
1626     lives_osc_notify_success(msg);
1627     lives_free(msg);
1628     return TRUE;
1629   }
1630   return lives_osc_notify_failure();
1631 }
1632 
1633 
lives_osc_cb_fgclip_select_previous(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)1634 boolean lives_osc_cb_fgclip_select_previous(void *context, int arglen, const void *vargs, OSCTimeTag when,
1635     NetworkReturnAddressPtr ra) {
1636   // switch fg clip
1637 
1638   if (mainw->current_file < 1 || (mainw->preview || (mainw->event_list && (!mainw->record || !LIVES_IS_PLAYING))) ||
1639       mainw->is_processing) return lives_osc_notify_failure(); // TODO
1640   if (mainw->multitrack) return lives_osc_notify_failure();
1641 
1642   prevclip_callback(NULL, NULL, 0, (LiVESXModifierType)0, LIVES_INT_TO_POINTER(1));
1643 
1644   if (!LIVES_IS_PLAYING && prefs->omc_noisy) {
1645     char *msg = lives_strdup_printf("%d", mainw->current_file);
1646     lives_osc_notify_success(msg);
1647     lives_free(msg);
1648     return TRUE;
1649   }
1650   return lives_osc_notify_failure();
1651 }
1652 
1653 
lives_osc_cb_bgclip_select_previous(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)1654 boolean lives_osc_cb_bgclip_select_previous(void *context, int arglen, const void *vargs, OSCTimeTag when,
1655     NetworkReturnAddressPtr ra) {
1656   // switch bg clip
1657 
1658   if (mainw->current_file < 1 || (mainw->preview || (mainw->event_list && (!mainw->record || !LIVES_IS_PLAYING))) ||
1659       mainw->is_processing) return lives_osc_notify_failure(); // TODO
1660   if (mainw->multitrack) return lives_osc_notify_failure();
1661 
1662   if (!IS_VALID_CLIP(mainw->blend_file)) return lives_osc_notify_failure();
1663 
1664   prevclip_callback(NULL, NULL, 0, (LiVESXModifierType)0, LIVES_INT_TO_POINTER(2));
1665 
1666   if (!LIVES_IS_PLAYING) {
1667     char *msg = lives_strdup_printf("%d", mainw->blend_file);
1668     lives_osc_notify_success(msg);
1669     lives_free(msg);
1670     return TRUE;
1671   }
1672   return lives_osc_notify_failure();
1673 }
1674 
1675 
lives_osc_cb_quit(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)1676 boolean lives_osc_cb_quit(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
1677   mainw->only_close = mainw->no_exit = FALSE;
1678   mainw->leave_recovery = FALSE;
1679 
1680   if (mainw->was_set) {
1681     on_save_set_activate(NULL, mainw->set_name);
1682   } else mainw->leave_files = FALSE;
1683   lives_exit(0);
1684   return TRUE;
1685 }
1686 
1687 
lives_osc_cb_getname(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)1688 boolean lives_osc_cb_getname(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
1689   return lives_status_send(PACKAGE_NAME);
1690 }
1691 
1692 
lives_osc_cb_getversion(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)1693 boolean lives_osc_cb_getversion(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
1694   return lives_status_send(VERSION);
1695 }
1696 
1697 
lives_osc_cb_getstatus(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)1698 boolean lives_osc_cb_getstatus(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
1699   if (mainw->go_away) return lives_status_send(get_omc_const("LIVES_STATUS_NOTREADY"));
1700   if (LIVES_IS_PLAYING) return lives_status_send(get_omc_const("LIVES_STATUS_PLAYING"));
1701   if (mainw->is_processing) return lives_status_send(get_omc_const("LIVES_STATUS_PROCESSING"));
1702   if ((mainw->preview || (!mainw->multitrack && mainw->event_list && (!mainw->record ||
1703                           !LIVES_IS_PLAYING)))) return lives_status_send(get_omc_const("LIVES_STATUS_PREVIEW"));
1704   return lives_status_send(get_omc_const("LIVES_STATUS_READY"));
1705 }
1706 
1707 
lives_osc_cb_getconst(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)1708 boolean lives_osc_cb_getconst(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
1709   const char *retval;
1710   char cname[OSC_STRING_SIZE];
1711 
1712   if (!lives_osc_check_arguments(arglen, vargs, "s", TRUE)) return lives_osc_notify_failure();
1713   lives_osc_parse_string_argument(vargs, cname);
1714   retval = get_omc_const(cname);
1715   return lives_status_send(retval);
1716 }
1717 
1718 
lives_osc_cb_open_status_socket(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)1719 boolean lives_osc_cb_open_status_socket(void *context, int arglen, const void *vargs, OSCTimeTag when,
1720                                         NetworkReturnAddressPtr ra) {
1721   char host[OSC_STRING_SIZE];
1722   int port;
1723 
1724   if (!lives_osc_check_arguments(arglen, vargs, "si", FALSE)) {
1725     if (!lives_osc_check_arguments(arglen, vargs, "i", TRUE)) return lives_osc_notify_failure();
1726     lives_snprintf(host, OSC_STRING_SIZE, "localhost");
1727   } else {
1728     lives_osc_check_arguments(arglen, vargs, "si", TRUE);
1729     lives_osc_parse_string_argument(vargs, host);
1730   }
1731   lives_osc_parse_int_argument(vargs, &port);
1732 
1733   if (status_socket) {
1734     LIVES_INFO("OMC status socket already opened");
1735     return lives_osc_notify_failure();
1736   }
1737 
1738   if (!(status_socket = OpenHTMSocket(host, port, TRUE))) {
1739     LIVES_WARN("Unable to open status socket !");
1740     return lives_osc_notify_failure();
1741   }
1742 
1743   return lives_osc_notify_success(NULL);
1744 }
1745 
1746 
lives_osc_cb_open_notify_socket(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)1747 boolean lives_osc_cb_open_notify_socket(void *context, int arglen, const void *vargs, OSCTimeTag when,
1748                                         NetworkReturnAddressPtr ra) {
1749   char host[OSC_STRING_SIZE];
1750   int port;
1751 
1752   if (!lives_osc_check_arguments(arglen, vargs, "si", FALSE)) {
1753     if (!lives_osc_check_arguments(arglen, vargs, "i", TRUE)) return lives_osc_notify_failure();
1754     lives_snprintf(host, OSC_STRING_SIZE, "localhost");
1755   } else {
1756     lives_osc_check_arguments(arglen, vargs, "si", TRUE);
1757     lives_osc_parse_string_argument(vargs, host);
1758   }
1759   lives_osc_parse_int_argument(vargs, &port);
1760 
1761   if (notify_socket) {
1762     LIVES_INFO("OMC notify socket already opened");
1763     return lives_osc_notify_failure();
1764   }
1765 
1766   prefs->omc_noisy = FALSE; // default for confirms is OFF
1767   if (!(notify_socket = OpenHTMSocket(host, port, TRUE))) {
1768     LIVES_WARN("Unable to open notify socket !");
1769     return lives_osc_notify_failure();
1770   }
1771   return lives_osc_notify_success(NULL);
1772 }
1773 
1774 
lives_osc_cb_close_status_socket(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)1775 boolean lives_osc_cb_close_status_socket(void *context, int arglen, const void *vargs, OSCTimeTag when,
1776     NetworkReturnAddressPtr ra) {
1777   lives_osc_close_status_socket();
1778   return lives_osc_notify_success(NULL);
1779 }
1780 
1781 
lives_osc_cb_notify_c(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)1782 boolean lives_osc_cb_notify_c(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
1783   int state;
1784   char *boolstr;
1785 
1786   if (!lives_osc_check_arguments(arglen, vargs, "i", TRUE)) return lives_osc_notify_failure();
1787   lives_osc_parse_int_argument(vargs, &state);
1788   boolstr = lives_strdup_printf("%d", state);
1789   if (!strcmp(boolstr, get_omc_const("LIVES_TRUE"))) state = TRUE;
1790   else {
1791     if (!strcmp(boolstr, get_omc_const("LIVES_FALSE"))) state = FALSE;
1792     else {
1793       lives_free(boolstr);
1794       return lives_osc_notify_failure();
1795     }
1796   }
1797   lives_free(boolstr);
1798   prefs->omc_noisy = state;
1799   return lives_osc_notify_success(NULL);
1800 }
1801 
1802 
lives_osc_cb_notify_e(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)1803 boolean lives_osc_cb_notify_e(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
1804   int state;
1805   char *boolstr;
1806 
1807   if (!lives_osc_check_arguments(arglen, vargs, "i", TRUE)) return lives_osc_notify_failure();
1808   lives_osc_parse_int_argument(vargs, &state);
1809   boolstr = lives_strdup_printf("%d", state);
1810   if (!strcmp(boolstr, get_omc_const("LIVES_TRUE"))) state = TRUE;
1811   else {
1812     if (!strcmp(boolstr, get_omc_const("LIVES_FALSE"))) state = FALSE;
1813     else {
1814       lives_free(boolstr);
1815       return lives_osc_notify_failure();
1816     }
1817   }
1818   lives_free(boolstr);
1819   prefs->omc_events = state;
1820   return lives_osc_notify_success(NULL);
1821 }
1822 
1823 
lives_osc_cb_clip_count(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)1824 boolean lives_osc_cb_clip_count(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
1825   char *tmp;
1826 
1827   lives_status_send((tmp = lives_strdup_printf("%d", mainw->clips_available)));
1828   lives_free(tmp);
1829   return TRUE;
1830 }
1831 
1832 
lives_osc_cb_clip_goto(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)1833 boolean lives_osc_cb_clip_goto(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
1834   int frame;
1835   if (mainw->current_file < 1 || (mainw->preview || (mainw->event_list && (!mainw->record || !LIVES_IS_PLAYING))) ||
1836       mainw->playing_file < 1 ||
1837       mainw->is_processing) return lives_osc_notify_failure();
1838   if (mainw->multitrack) return lives_osc_notify_failure();
1839 
1840   if (!lives_osc_check_arguments(arglen, vargs, "i", TRUE)) return lives_osc_notify_failure();
1841   lives_osc_parse_int_argument(vargs, &frame);
1842 
1843   if (frame < 1 || frame > cfile->frames || !CURRENT_CLIP_IS_NORMAL) return lives_osc_notify_failure();
1844 
1845   cfile->last_frameno = cfile->frameno = frame;
1846 
1847 #ifdef RT_AUDIO
1848   if (prefs->audio_opts & AUDIO_OPTS_FOLLOW_FPS) {
1849     resync_audio(frame);
1850   }
1851 #endif
1852   return lives_osc_notify_success(NULL);
1853 }
1854 
1855 
lives_osc_cb_clip_getframe(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)1856 boolean lives_osc_cb_clip_getframe(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
1857   char *tmp;
1858   if (mainw->current_file < 1 || (mainw->preview || (!mainw->multitrack && mainw->event_list && !mainw->record)) ||
1859       mainw->playing_file < 1) return lives_status_send("0");
1860   else {
1861     lives_status_send((tmp = lives_strdup_printf("%d", mainw->actual_frame)));
1862     lives_free(tmp);
1863   }
1864   return TRUE;
1865 }
1866 
1867 
lives_osc_cb_clip_getfps(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)1868 boolean lives_osc_cb_clip_getfps(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
1869   char *tmp;
1870 
1871   if (mainw->current_file < 1) return lives_osc_notify_failure();
1872 
1873   if (mainw->current_file < 0) lives_status_send((tmp = lives_strdup_printf("%.3f", 0.)));
1874   else if ((mainw->preview || (!mainw->multitrack && mainw->event_list && !mainw->record)) ||
1875            mainw->playing_file < 1) lives_status_send((tmp = lives_strdup_printf("%.3f", cfile->fps)));
1876   else lives_status_send((tmp = lives_strdup_printf("%.3f", cfile->pb_fps)));
1877   lives_free(tmp);
1878   return TRUE;
1879 }
1880 
1881 
lives_osc_cb_clip_get_ifps(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)1882 boolean lives_osc_cb_clip_get_ifps(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
1883   char *tmp;
1884   lives_clip_t *sfile;
1885   int clip = mainw->current_file;
1886 
1887   if (lives_osc_check_arguments(arglen, vargs, "i", FALSE)) {
1888     lives_osc_check_arguments(arglen, vargs, "i", TRUE);
1889     lives_osc_parse_int_argument(vargs, &clip);
1890   }
1891 
1892   if (!IS_VALID_CLIP(clip)) return lives_osc_notify_failure();
1893 
1894   sfile = mainw->files[clip];
1895   if ((mainw->preview || (!mainw->multitrack && mainw->event_list && !mainw->record)) ||
1896       mainw->playing_file < 1) lives_status_send((tmp = lives_strdup_printf("%.3f", sfile->fps)));
1897   else lives_status_send((tmp = lives_strdup_printf("%.3f", sfile->pb_fps)));
1898   lives_free(tmp);
1899   return TRUE;
1900 }
1901 
1902 
lives_osc_cb_get_fps_ratio(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)1903 boolean lives_osc_cb_get_fps_ratio(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
1904   char *tmp;
1905 
1906   if (mainw->current_file < 1) return lives_osc_notify_failure();
1907 
1908   if (mainw->current_file < 0) lives_status_send((tmp = lives_strdup_printf("%.4f", 0.)));
1909   else if ((mainw->preview || (!mainw->multitrack && mainw->event_list && !mainw->record)) ||
1910            mainw->playing_file < 1) lives_status_send((tmp = lives_strdup_printf("%.4f", 1.)));
1911   else lives_status_send((tmp = lives_strdup_printf("%.4f", cfile->pb_fps / cfile->fps)));
1912   lives_free(tmp);
1913   return TRUE;
1914 }
1915 
1916 
lives_osc_cb_bgget_fps_ratio(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)1917 boolean lives_osc_cb_bgget_fps_ratio(void *context, int arglen, const void *vargs, OSCTimeTag when,
1918                                      NetworkReturnAddressPtr ra) {
1919   char *tmp;
1920 
1921   if (mainw->current_file < 1) return lives_osc_notify_failure();
1922 
1923   if (!CURRENT_CLIP_IS_VALID || !IS_VALID_CLIP(mainw->blend_file))
1924     lives_status_send((tmp = lives_strdup_printf("%.4f", 0.)));
1925   else if ((mainw->preview || (!mainw->multitrack && mainw->event_list && !mainw->record)) ||
1926            mainw->playing_file < 1) lives_status_send((tmp = lives_strdup_printf("%.4f", 1.)));
1927   else lives_status_send((tmp = lives_strdup_printf("%.4f", mainw->files[mainw->blend_file]->pb_fps /
1928                                   mainw->files[mainw->blend_file]->fps)));
1929   lives_free(tmp);
1930   return TRUE;
1931 }
1932 
1933 
lives_osc_cb_bgclip_getframe(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)1934 boolean lives_osc_cb_bgclip_getframe(void *context, int arglen, const void *vargs, OSCTimeTag when,
1935                                      NetworkReturnAddressPtr ra) {
1936   char *tmp;
1937 
1938   if (mainw->current_file < 1 || (mainw->preview || (!mainw->multitrack && mainw->event_list && !mainw->record)) ||
1939       mainw->playing_file < 1 || !IS_VALID_CLIP(mainw->blend_file)) return lives_status_send("0");
1940   else {
1941     lives_status_send((tmp = lives_strdup_printf("%d", mainw->files[mainw->blend_file]->frameno)));
1942     lives_free(tmp);
1943   }
1944   return TRUE;
1945 }
1946 
1947 
lives_osc_cb_bgclip_getfps(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)1948 boolean lives_osc_cb_bgclip_getfps(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
1949   char *tmp;
1950 
1951   if (mainw->current_file < 1) return lives_osc_notify_failure();
1952   if (!IS_VALID_CLIP(mainw->blend_file))lives_status_send((tmp = lives_strdup_printf("%.3f", 0.)));
1953   else if ((mainw->preview || (!mainw->multitrack && mainw->event_list && !mainw->record)) ||
1954            mainw->playing_file < 1) lives_status_send((tmp = lives_strdup_printf("%.3f", mainw->files[mainw->blend_file]->fps)));
1955   else lives_status_send((tmp = lives_strdup_printf("%.3f", mainw->files[mainw->blend_file]->pb_fps)));
1956   lives_free(tmp);
1957   return TRUE;
1958 }
1959 
1960 
lives_osc_cb_get_amute(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)1961 boolean lives_osc_cb_get_amute(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
1962   if (!is_realtime_aplayer(prefs->audio_player)) {
1963     return lives_status_send(get_omc_const("LIVES_FALSE"));
1964   }
1965   if (!mainw->mute) return lives_status_send(get_omc_const("LIVES_FALSE"));
1966   else return lives_status_send(get_omc_const("LIVES_TRUE"));
1967 }
1968 
1969 
lives_osc_cb_set_amute(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)1970 boolean lives_osc_cb_set_amute(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
1971   int mute;
1972   char *boolstr;
1973 
1974   if (!is_realtime_aplayer(prefs->audio_player)) {
1975     return lives_osc_notify_failure();
1976   }
1977 
1978   if (lives_osc_check_arguments(arglen, vargs, "i", FALSE)) {
1979     lives_osc_check_arguments(arglen, vargs, "i", TRUE);
1980     lives_osc_parse_int_argument(vargs, &mute);
1981     boolstr = lives_strdup_printf("%d", mute);
1982     if (!strcmp(boolstr, get_omc_const("LIVES_TRUE"))) mute = TRUE;
1983     else {
1984       if (!strcmp(boolstr, get_omc_const("LIVES_FALSE"))) mute = FALSE;
1985       else {
1986         lives_free(boolstr);
1987         return lives_osc_notify_failure();
1988       }
1989     }
1990     lives_free(boolstr);
1991   } else return lives_osc_notify_failure();
1992 
1993   if ((mute && !mainw->mute) || (!mute && mainw->mute))
1994     lives_check_menu_item_set_active(LIVES_CHECK_MENU_ITEM(mainw->mute_audio), !mainw->mute);
1995 
1996   return lives_osc_notify_success(NULL);
1997 }
1998 
1999 
lives_osc_cb_set_avol(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)2000 boolean lives_osc_cb_set_avol(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
2001   float vol;
2002 
2003   if (lives_osc_check_arguments(arglen, vargs, "f", TRUE)) {
2004     lives_osc_parse_float_argument(vargs, &vol);
2005   } else return lives_osc_notify_failure();
2006 
2007   if (vol < 0. || vol > 1.) return lives_osc_notify_failure();
2008 
2009   pref_factory_float(PREF_MASTER_VOLUME, vol, TRUE);
2010 
2011   return lives_osc_notify_success(NULL);
2012 }
2013 
2014 
lives_osc_cb_get_avol(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)2015 boolean lives_osc_cb_get_avol(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
2016   char *tmp;
2017 
2018   if (!is_realtime_aplayer(prefs->audio_player)) {
2019     tmp = lives_strdup("100.00");
2020     lives_status_send(tmp);
2021     lives_free(tmp);
2022     return TRUE;
2023   }
2024 
2025   tmp = lives_strdup_printf("%.2f", future_prefs->volume);
2026   lives_status_send(tmp);
2027   lives_free(tmp);
2028 
2029   return TRUE;
2030 }
2031 
2032 
lives_osc_cb_getmode(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)2033 boolean lives_osc_cb_getmode(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
2034   if (mainw->multitrack) return lives_status_send(get_omc_const("LIVES_MODE_MULTITRACK"));
2035   else return lives_status_send(get_omc_const("LIVES_MODE_CLIPEDIT"));
2036 }
2037 
2038 
lives_osc_cb_setmode(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)2039 boolean lives_osc_cb_setmode(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
2040   char *modes;
2041   int mode;
2042   int cliped = atoi(get_omc_const("LIVES_MODE_CLIPEDIT")); // 0
2043   int mt = atoi(get_omc_const("LIVES_MODE_MULTITRACK")); // 1
2044 
2045   if ((mainw->preview || (!mainw->multitrack && mainw->event_list)) || mainw->is_processing ||
2046       LIVES_IS_PLAYING) return lives_osc_notify_failure();
2047 
2048   if (!lives_osc_check_arguments(arglen, vargs, "i", TRUE)) return lives_osc_notify_failure();
2049 
2050   lives_osc_parse_int_argument(vargs, &mode);
2051 
2052   if (mode != cliped && mode != mt) return lives_osc_notify_failure();
2053 
2054   // these two will also send a status changed message
2055   if (mode == mt && !mainw->multitrack) on_multitrack_activate(NULL, NULL);
2056   else if (mode == cliped && mainw->multitrack) multitrack_delete(mainw->multitrack, FALSE);
2057 
2058   modes = lives_strdup_printf("%d", mode);
2059   lives_osc_notify_success(modes);
2060   lives_free(modes);
2061   return TRUE;
2062 }
2063 
2064 
lives_osc_cb_clearlay(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)2065 boolean lives_osc_cb_clearlay(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
2066   if (LIVES_IS_PLAYING || (mainw->preview || (mainw->event_list && !mainw->record)) || mainw->is_processing ||
2067       !mainw->multitrack) return lives_osc_notify_failure();
2068   wipe_layout(mainw->multitrack);
2069   return lives_osc_notify_success(NULL);
2070 }
2071 
2072 
lives_osc_cb_blockcount(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)2073 boolean lives_osc_cb_blockcount(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
2074   char *tmp;
2075   int nblocks;
2076   int track;
2077   if (!mainw->multitrack) return lives_osc_notify_failure();
2078 
2079   if (lives_osc_check_arguments(arglen, vargs, "i", FALSE)) {
2080     lives_osc_check_arguments(arglen, vargs, "i", TRUE);
2081     lives_osc_parse_int_argument(vargs, &track);
2082   } else if (lives_osc_check_arguments(arglen, vargs, "", TRUE)) {
2083     track = mainw->multitrack->current_track;
2084   } else return lives_osc_notify_failure();
2085 
2086   nblocks = mt_get_block_count(mainw->multitrack, track);
2087 
2088   tmp = lives_strdup_printf("%d", nblocks);
2089   lives_status_send(tmp);
2090   lives_free(tmp);
2091   return TRUE;
2092 }
2093 
2094 
lives_osc_cb_blockinsert(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)2095 boolean lives_osc_cb_blockinsert(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
2096   int ins_audio, oins_audio;
2097   int ign_ins_sel, oign_ins_sel;
2098 
2099   int clip;
2100 
2101   char *tmp;
2102   char *boolstr;
2103 
2104   if (LIVES_IS_PLAYING || (mainw->preview || (!mainw->multitrack && mainw->event_list)) || mainw->is_processing ||
2105       !mainw->multitrack) return lives_osc_notify_failure();
2106 
2107   oins_audio = ins_audio = mainw->multitrack->opts.insert_audio;
2108   oign_ins_sel = ign_ins_sel = mainw->multitrack->opts.ign_ins_sel;
2109 
2110   if (!ign_ins_sel) ign_ins_sel = 0;
2111   else ign_ins_sel = 1;
2112 
2113   if (!ins_audio) ins_audio = 0;
2114   else ins_audio = 1;
2115 
2116   if (lives_osc_check_arguments(arglen, vargs, "iii", FALSE)) {
2117     lives_osc_check_arguments(arglen, vargs, "iii", TRUE);
2118     lives_osc_parse_int_argument(vargs, &clip);
2119     lives_osc_parse_int_argument(vargs, &ign_ins_sel);
2120     lives_osc_parse_int_argument(vargs, &ins_audio);
2121   }
2122   if (lives_osc_check_arguments(arglen, vargs, "ii", FALSE)) {
2123     lives_osc_check_arguments(arglen, vargs, "ii", TRUE);
2124     lives_osc_parse_int_argument(vargs, &clip);
2125     lives_osc_parse_int_argument(vargs, &ign_ins_sel);
2126   } else if (lives_osc_check_arguments(arglen, vargs, "i", TRUE)) {
2127     lives_osc_parse_int_argument(vargs, &clip);
2128   } else return lives_osc_notify_failure();
2129 
2130   if (!IS_VALID_CLIP(clip) || clip == mainw->current_file || clip == mainw->scrap_file ||
2131       clip == mainw->ascrap_file)
2132     return lives_osc_notify_failure();
2133 
2134   boolstr = lives_strdup_printf("%d", ins_audio);
2135   if (!strcmp(boolstr, get_omc_const("LIVES_TRUE"))) ins_audio = TRUE;
2136   else {
2137     if (!strcmp(boolstr, get_omc_const("LIVES_FALSE"))) ins_audio = FALSE;
2138     else {
2139       lives_free(boolstr);
2140       return lives_osc_notify_failure();
2141     }
2142   }
2143   lives_free(boolstr);
2144 
2145   boolstr = lives_strdup_printf("%d", ign_ins_sel);
2146   if (!strcmp(boolstr, get_omc_const("LIVES_TRUE"))) ign_ins_sel = TRUE;
2147   else {
2148     if (!strcmp(boolstr, get_omc_const("LIVES_FALSE"))) ign_ins_sel = FALSE;
2149     else {
2150       lives_free(boolstr);
2151       return lives_osc_notify_failure();
2152     }
2153   }
2154   lives_free(boolstr);
2155 
2156   mainw->multitrack->clip_selected = clip - 1;
2157   mt_clip_select(mainw->multitrack, TRUE);
2158 
2159   mainw->multitrack->opts.insert_audio = ins_audio;
2160   mainw->multitrack->opts.ign_ins_sel = ign_ins_sel;
2161 
2162   multitrack_insert(NULL, mainw->multitrack);
2163 
2164   mainw->multitrack->opts.insert_audio = oins_audio;
2165   mainw->multitrack->opts.ign_ins_sel = oign_ins_sel;
2166 
2167   tmp = lives_strdup_printf("%lu", mt_get_last_block_uid(mainw->multitrack));
2168 
2169   lives_osc_notify_success(tmp);
2170   lives_free(tmp);
2171   return TRUE;
2172 }
2173 
2174 
lives_osc_cb_mtctimeset(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)2175 boolean lives_osc_cb_mtctimeset(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
2176   float time;
2177   char *msg;
2178 
2179   if (LIVES_IS_PLAYING || (mainw->preview || (!mainw->multitrack && mainw->event_list)) || mainw->is_processing ||
2180       !mainw->multitrack) return lives_osc_notify_failure();
2181 
2182   if (lives_osc_check_arguments(arglen, vargs, "f", TRUE)) {
2183     lives_osc_parse_float_argument(vargs, &time);
2184   } else return lives_osc_notify_failure();
2185 
2186   if (time < 0.) return lives_osc_notify_failure();
2187 
2188   time = q_dbl(time, mainw->multitrack->fps) / TICKS_PER_SECOND_DBL;
2189   mt_tl_move(mainw->multitrack, time);
2190 
2191   msg = lives_strdup_printf("%.8f", lives_ruler_get_value(LIVES_RULER(mainw->multitrack->timeline)));
2192   lives_osc_notify_success(msg);
2193   lives_free(msg);
2194   return TRUE;
2195 }
2196 
2197 
lives_osc_cb_mtctimeget(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)2198 boolean lives_osc_cb_mtctimeget(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
2199   char *msg;
2200 
2201   if (!mainw->multitrack) return lives_osc_notify_failure();
2202 
2203   msg = lives_strdup_printf("%.8f", lives_ruler_get_value(LIVES_RULER(mainw->multitrack->timeline)));
2204   lives_status_send(msg);
2205   lives_free(msg);
2206   return TRUE;
2207 }
2208 
2209 
lives_osc_cb_mtctrackset(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)2210 boolean lives_osc_cb_mtctrackset(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
2211   int track;
2212   char *msg;
2213 
2214   if (LIVES_IS_PLAYING || (mainw->preview || (!mainw->multitrack && mainw->event_list)) || mainw->is_processing ||
2215       !mainw->multitrack) return lives_osc_notify_failure();
2216 
2217   if (lives_osc_check_arguments(arglen, vargs, "i", TRUE)) {
2218     lives_osc_parse_int_argument(vargs, &track);
2219   } else return lives_osc_notify_failure();
2220 
2221   if (mt_track_is_video(mainw->multitrack, track) || mt_track_is_audio(mainw->multitrack, track)) {
2222     mainw->multitrack->current_track = track;
2223     track_select(mainw->multitrack);
2224     msg = lives_strdup_printf("%d", track);
2225     lives_osc_notify_success(msg);
2226     lives_free(msg);
2227     return TRUE;
2228   } else return lives_osc_notify_failure();
2229 }
2230 
2231 
lives_osc_cb_mtctrackget(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)2232 boolean lives_osc_cb_mtctrackget(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
2233   char *msg;
2234   if (!mainw->multitrack) return lives_osc_notify_failure();
2235 
2236   msg = lives_strdup_printf("%d", mainw->multitrack->current_track);
2237   lives_status_send(msg);
2238   lives_free(msg);
2239   return TRUE;
2240 }
2241 
2242 
lives_osc_cb_blockstget(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)2243 boolean lives_osc_cb_blockstget(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
2244   int track;
2245   int nblock;
2246   double sttime;
2247   char *tmp;
2248   if (!mainw->multitrack) return lives_osc_notify_failure();
2249 
2250   if (lives_osc_check_arguments(arglen, vargs, "ii", FALSE)) {
2251     lives_osc_check_arguments(arglen, vargs, "ii", TRUE);
2252     lives_osc_parse_int_argument(vargs, &track);
2253     lives_osc_parse_int_argument(vargs, &nblock);
2254   } else if (lives_osc_check_arguments(arglen, vargs, "i", TRUE)) {
2255     track = mainw->multitrack->current_track;
2256     lives_osc_parse_int_argument(vargs, &nblock);
2257   } else return lives_osc_notify_failure();
2258 
2259   if (mt_track_is_video(mainw->multitrack, track) || mt_track_is_audio(mainw->multitrack, track)) {
2260     sttime = mt_get_block_sttime(mainw->multitrack, track, nblock);
2261     if (sttime < 0.) return lives_osc_notify_failure();
2262     tmp = lives_strdup_printf("%.8f", sttime);
2263     lives_status_send(tmp);
2264     lives_free(tmp);
2265     return TRUE;
2266   }
2267   return lives_osc_notify_failure(); ///< invalid track
2268 }
2269 
2270 
lives_osc_cb_blockenget(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)2271 boolean lives_osc_cb_blockenget(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
2272   int track;
2273   int nblock;
2274   double entime;
2275   char *tmp;
2276   if (!mainw->multitrack) return lives_osc_notify_failure();
2277 
2278   if (lives_osc_check_arguments(arglen, vargs, "ii", FALSE)) {
2279     lives_osc_check_arguments(arglen, vargs, "ii", TRUE);
2280     lives_osc_parse_int_argument(vargs, &track);
2281     lives_osc_parse_int_argument(vargs, &nblock);
2282   } else if (lives_osc_check_arguments(arglen, vargs, "i", TRUE)) {
2283     track = mainw->multitrack->current_track;
2284     lives_osc_parse_int_argument(vargs, &nblock);
2285   } else return lives_osc_notify_failure();
2286 
2287   if (mt_track_is_video(mainw->multitrack, track) || mt_track_is_audio(mainw->multitrack, track)) {
2288     entime = mt_get_block_entime(mainw->multitrack, track, nblock);
2289     if (entime < 0.) return lives_osc_notify_failure();
2290     tmp = lives_strdup_printf("%.8f", entime);
2291     lives_status_send(tmp);
2292     lives_free(tmp);
2293     return TRUE;
2294   }
2295   return lives_osc_notify_failure(); ///< invalid track
2296 }
2297 
2298 
lives_osc_cb_get_playtime(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)2299 boolean lives_osc_cb_get_playtime(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
2300   char *tmp;
2301 
2302   if (mainw->current_file < 1 || (mainw->preview || (!mainw->multitrack && mainw->event_list && !mainw->record)) ||
2303       mainw->playing_file < 1) return lives_osc_notify_failure();
2304 
2305   lives_status_send((tmp = lives_strdup_printf("%.8f", (double)mainw->currticks / TICKS_PER_SECOND_DBL)));
2306   lives_free(tmp);
2307   return TRUE;
2308 }
2309 
2310 
lives_osc_cb_bgclip_goto(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)2311 boolean lives_osc_cb_bgclip_goto(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
2312   int frame;
2313   if (mainw->current_file < 1 || (mainw->preview || (mainw->event_list && !mainw->record)) || mainw->playing_file < 1 ||
2314       mainw->is_processing) return lives_osc_notify_failure();
2315   if (mainw->multitrack) return lives_osc_notify_failure();
2316 
2317   if (!IS_VALID_CLIP(mainw->blend_file)) return lives_osc_notify_failure();
2318 
2319   if (!lives_osc_check_arguments(arglen, vargs, "i", TRUE)) return lives_osc_notify_failure();
2320   lives_osc_parse_int_argument(vargs, &frame);
2321 
2322   if (frame < 1 || frame > mainw->files[mainw->blend_file]->frames ||
2323       !IS_NORMAL_CLIP(mainw->blend_file)) return lives_osc_notify_failure();
2324 
2325   mainw->files[mainw->blend_file]->last_frameno = mainw->files[mainw->blend_file]->frameno = frame;
2326   return lives_osc_notify_success(NULL);
2327 }
2328 
2329 
lives_osc_cb_clip_get_current(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)2330 boolean lives_osc_cb_clip_get_current(void *context, int arglen, const void *vargs, OSCTimeTag when,
2331                                       NetworkReturnAddressPtr ra) {
2332   char *tmp;
2333   lives_status_send((tmp = lives_strdup_printf("%d", mainw->current_file < 0 ? 0 : mainw->current_file)));
2334   lives_free(tmp);
2335   return TRUE;
2336 }
2337 
2338 
lives_osc_cb_bgclip_get_current(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)2339 boolean lives_osc_cb_bgclip_get_current(void *context, int arglen, const void *vargs, OSCTimeTag when,
2340                                         NetworkReturnAddressPtr ra) {
2341   char *tmp;
2342 
2343   if (mainw->multitrack) return lives_osc_notify_failure();
2344   lives_status_send((tmp = lives_strdup_printf("%d", mainw->blend_file < 0 ? 0 : mainw->blend_file)));
2345   lives_free(tmp);
2346   return TRUE;
2347 }
2348 
2349 
lives_osc_cb_clip_set_start(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)2350 boolean lives_osc_cb_clip_set_start(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
2351   char *msg;
2352 
2353   int current_file = mainw->current_file;
2354   int clip = current_file;
2355   int frame;
2356 
2357   boolean selwidth_locked = mainw->selwidth_locked;
2358 
2359   lives_clip_t *sfile;
2360 
2361   if (mainw->current_file < 1 || (mainw->preview || (mainw->event_list && (!mainw->record || !LIVES_IS_PLAYING))) ||
2362       mainw->is_processing) return lives_osc_notify_failure();
2363   if (mainw->multitrack) return lives_osc_notify_failure();
2364 
2365   if (lives_osc_check_arguments(arglen, vargs, "ii", FALSE)) {
2366     lives_osc_check_arguments(arglen, vargs, "ii", TRUE);
2367     lives_osc_parse_int_argument(vargs, &frame);
2368     lives_osc_parse_int_argument(vargs, &clip);
2369   } else if (lives_osc_check_arguments(arglen, vargs, "i", TRUE)) {
2370     lives_osc_parse_int_argument(vargs, &frame);
2371   } else return lives_osc_notify_failure();
2372 
2373   if (frame < 1 || !IS_NORMAL_CLIP(clip)) return lives_osc_notify_failure();
2374 
2375   sfile = mainw->files[clip];
2376 
2377   if (frame > sfile->frames) frame = sfile->frames;
2378 
2379   mainw->selwidth_locked = FALSE;
2380   if (clip == mainw->current_file) lives_spin_button_set_value(LIVES_SPIN_BUTTON(mainw->spinbutton_start), frame);
2381   else {
2382     if (sfile->end < frame) sfile->end = frame;
2383     sfile->start = frame;
2384   }
2385   mainw->selwidth_locked = selwidth_locked;
2386 
2387   msg = lives_strdup_printf("%d", frame);
2388   lives_osc_notify_success(msg);
2389   lives_free(msg);
2390 
2391   return TRUE;
2392 }
2393 
2394 
lives_osc_cb_clip_get_start(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)2395 boolean lives_osc_cb_clip_get_start(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
2396   int current_file = mainw->current_file;
2397   int clip = current_file;
2398   char *tmp;
2399 
2400   lives_clip_t *sfile;
2401 
2402   if (mainw->current_file < 1) return lives_osc_notify_failure();
2403   if (mainw->multitrack) return lives_osc_notify_failure();
2404 
2405   if (lives_osc_check_arguments(arglen, vargs, "i", FALSE)) {
2406     lives_osc_check_arguments(arglen, vargs, "i", TRUE);
2407     lives_osc_parse_int_argument(vargs, &clip);
2408   }
2409 
2410   if (!IS_VALID_CLIP(clip)) return lives_osc_notify_failure();
2411 
2412   sfile = mainw->files[clip];
2413 
2414   lives_status_send((tmp = lives_strdup_printf("%d", sfile->start)));
2415   lives_free(tmp);
2416   return TRUE;
2417 }
2418 
2419 
lives_osc_cb_clip_set_end(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)2420 boolean lives_osc_cb_clip_set_end(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
2421   char *msg;
2422 
2423   int current_file = mainw->current_file;
2424   int clip = current_file;
2425   int frame;
2426 
2427   boolean selwidth_locked = mainw->selwidth_locked;
2428 
2429   lives_clip_t *sfile;
2430 
2431   if (mainw->current_file < 1 || (mainw->preview || (mainw->event_list && (!mainw->record || !LIVES_IS_PLAYING))) ||
2432       mainw->is_processing) return lives_osc_notify_failure();
2433   if (mainw->multitrack) return lives_osc_notify_failure();
2434 
2435   if (lives_osc_check_arguments(arglen, vargs, "ii", FALSE)) {
2436     lives_osc_check_arguments(arglen, vargs, "ii", TRUE);
2437     lives_osc_parse_int_argument(vargs, &frame);
2438     lives_osc_parse_int_argument(vargs, &clip);
2439   } else if (lives_osc_check_arguments(arglen, vargs, "i", TRUE)) {
2440     lives_osc_parse_int_argument(vargs, &frame);
2441   } else return lives_osc_notify_failure();
2442 
2443   if (frame < 1 || !IS_NORMAL_CLIP(clip)) return lives_osc_notify_failure();
2444 
2445   sfile = mainw->files[clip];
2446 
2447   if (frame > sfile->frames) frame = sfile->frames;
2448 
2449   mainw->selwidth_locked = FALSE;
2450   if (clip == mainw->current_file) lives_spin_button_set_value(LIVES_SPIN_BUTTON(mainw->spinbutton_end), frame);
2451   else {
2452     if (sfile->start > frame) sfile->start = frame;
2453     sfile->end = frame;
2454   }
2455   mainw->selwidth_locked = selwidth_locked;
2456 
2457   msg = lives_strdup_printf("%d", frame);
2458   lives_osc_notify_success(msg);
2459   lives_free(msg);
2460 
2461   return TRUE;
2462 }
2463 
2464 
lives_osc_cb_clip_get_end(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)2465 boolean lives_osc_cb_clip_get_end(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
2466   int current_file = mainw->current_file;
2467   int clip = current_file;
2468   char *tmp;
2469 
2470   lives_clip_t *sfile;
2471 
2472   if (mainw->current_file < 1) return lives_osc_notify_failure();
2473   if (mainw->multitrack) return lives_osc_notify_failure();
2474 
2475   if (lives_osc_check_arguments(arglen, vargs, "i", FALSE)) {
2476     lives_osc_check_arguments(arglen, vargs, "i", TRUE);
2477     lives_osc_parse_int_argument(vargs, &clip);
2478   }
2479 
2480   if (!IS_VALID_CLIP(clip)) return lives_osc_notify_failure();
2481 
2482   sfile = mainw->files[clip];
2483 
2484   lives_status_send((tmp = lives_strdup_printf("%d", sfile->end)));
2485   lives_free(tmp);
2486   return TRUE;
2487 }
2488 
2489 
lives_osc_cb_clip_get_size(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)2490 boolean lives_osc_cb_clip_get_size(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
2491   int current_file = mainw->current_file;
2492   int clip = current_file;
2493   char *tmp;
2494 
2495   lives_clip_t *sfile;
2496 
2497   if (mainw->current_file < 1) return lives_osc_notify_failure();
2498 
2499   if (lives_osc_check_arguments(arglen, vargs, "i", FALSE)) {
2500     lives_osc_check_arguments(arglen, vargs, "i", TRUE);
2501     lives_osc_parse_int_argument(vargs, &clip);
2502   }
2503 
2504   if (!IS_VALID_CLIP(clip)) return lives_osc_notify_failure();
2505 
2506   sfile = mainw->files[clip];
2507 
2508   lives_status_send((tmp = lives_strdup_printf("%d|%d", sfile->hsize, sfile->vsize)));
2509   lives_free(tmp);
2510   return TRUE;
2511 }
2512 
2513 
lives_osc_cb_clip_get_name(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)2514 boolean lives_osc_cb_clip_get_name(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
2515   int current_file = mainw->current_file;
2516   int clip = current_file;
2517 
2518   lives_clip_t *sfile;
2519 
2520   if (mainw->current_file < 1) return lives_osc_notify_failure();
2521 
2522   if (lives_osc_check_arguments(arglen, vargs, "i", FALSE)) {
2523     lives_osc_check_arguments(arglen, vargs, "i", TRUE);
2524     lives_osc_parse_int_argument(vargs, &clip);
2525   } else if (mainw->multitrack) return lives_osc_notify_failure();
2526 
2527   if (!IS_VALID_CLIP(clip)) return lives_osc_notify_failure();
2528 
2529   sfile = mainw->files[clip];
2530 
2531   return lives_status_send(sfile->name);
2532 }
2533 
2534 
lives_osc_cb_clip_set_name(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)2535 boolean lives_osc_cb_clip_set_name(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
2536   int current_file = mainw->current_file;
2537   int clip = current_file;
2538   char name[OSC_STRING_SIZE];
2539 
2540   if (mainw->current_file < 1 || (mainw->preview || (!mainw->multitrack && mainw->event_list && (!mainw->record ||
2541                                   !LIVES_IS_PLAYING))) ||
2542       mainw->is_processing) return lives_osc_notify_failure();
2543 
2544   if (lives_osc_check_arguments(arglen, vargs, "si", FALSE)) {
2545     lives_osc_check_arguments(arglen, vargs, "si", TRUE);
2546     lives_osc_parse_string_argument(vargs, name);
2547     lives_osc_parse_int_argument(vargs, &clip);
2548   } else if (lives_osc_check_arguments(arglen, vargs, "s", TRUE)) {
2549     if (mainw->multitrack) return lives_osc_notify_failure();
2550     lives_osc_parse_string_argument(vargs, name);
2551   } else return lives_osc_notify_failure();
2552 
2553   if (!IS_VALID_CLIP(clip)) return lives_osc_notify_failure();
2554 
2555   mainw->current_file = clip;
2556   on_rename_clip_name(NULL, (livespointer)name);
2557 
2558   if (clip == current_file) set_main_title(name, 0);
2559   else mainw->current_file = current_file;
2560 
2561   return lives_osc_notify_success(name);
2562 }
2563 
2564 
lives_osc_cb_clip_get_frames(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)2565 boolean lives_osc_cb_clip_get_frames(void *context, int arglen, const void *vargs, OSCTimeTag when,
2566                                      NetworkReturnAddressPtr ra) {
2567   int current_file = mainw->current_file;
2568   int clip = current_file;
2569   char *tmp;
2570 
2571   lives_clip_t *sfile;
2572 
2573   if (mainw->current_file < 1) return lives_osc_notify_failure();
2574 
2575   if (lives_osc_check_arguments(arglen, vargs, "i", FALSE)) {
2576     lives_osc_check_arguments(arglen, vargs, "i", TRUE);
2577     lives_osc_parse_int_argument(vargs, &clip);
2578   } else if (mainw->multitrack) return lives_osc_notify_failure();
2579 
2580   if (!IS_VALID_CLIP(clip)) return lives_osc_notify_failure();
2581 
2582   sfile = mainw->files[clip];
2583 
2584   lives_status_send((tmp = lives_strdup_printf("%d", sfile->frames)));
2585   lives_free(tmp);
2586   return TRUE;
2587 }
2588 
2589 
lives_osc_cb_clip_save_frame(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)2590 boolean lives_osc_cb_clip_save_frame(void *context, int arglen, const void *vargs, OSCTimeTag when,
2591                                      NetworkReturnAddressPtr ra) {
2592   int current_file = mainw->current_file;
2593   int clip = current_file;
2594   int frame, width = -1, height = -1;
2595   char fname[OSC_STRING_SIZE];
2596   boolean retval;
2597 
2598   lives_clip_t *sfile;
2599 
2600   if (mainw->current_file < 1) return lives_osc_notify_failure();
2601   if (mainw->multitrack) return lives_osc_notify_failure();
2602 
2603   if (!lives_osc_check_arguments(arglen, vargs, "is", FALSE)) {
2604     if (!lives_osc_check_arguments(arglen, vargs, "iis", FALSE)) {
2605       if (!lives_osc_check_arguments(arglen, vargs, "isii", FALSE)) {
2606         if (!lives_osc_check_arguments(arglen, vargs, "iisii", TRUE)) {
2607           return lives_osc_notify_failure();
2608         }
2609         lives_osc_parse_int_argument(vargs, &frame);
2610         lives_osc_parse_int_argument(vargs, &clip);
2611         lives_osc_parse_string_argument(vargs, fname);
2612         lives_osc_parse_int_argument(vargs, &width);
2613         lives_osc_parse_int_argument(vargs, &height);
2614       } else {
2615         lives_osc_check_arguments(arglen, vargs, "isii", TRUE);
2616         if (mainw->multitrack) return lives_osc_notify_failure();
2617         lives_osc_parse_int_argument(vargs, &frame);
2618         lives_osc_parse_string_argument(vargs, fname);
2619         lives_osc_parse_int_argument(vargs, &width);
2620         lives_osc_parse_int_argument(vargs, &height);
2621       }
2622     } else {
2623       lives_osc_check_arguments(arglen, vargs, "iis", TRUE);
2624       lives_osc_parse_int_argument(vargs, &frame);
2625       lives_osc_parse_int_argument(vargs, &clip);
2626       lives_osc_parse_string_argument(vargs, fname);
2627     }
2628   } else {
2629     if (mainw->multitrack) return lives_osc_notify_failure();
2630     lives_osc_check_arguments(arglen, vargs, "is", TRUE);
2631     lives_osc_parse_int_argument(vargs, &frame);
2632     lives_osc_parse_string_argument(vargs, fname);
2633   }
2634 
2635   if (frame < 1 || !IS_NORMAL_CLIP(clip)) return lives_osc_notify_failure();
2636 
2637   sfile = mainw->files[clip];
2638 
2639   if (frame > sfile->frames) return lives_osc_notify_failure();
2640 
2641   retval = save_frame_inner(clip, frame, fname, width, height, TRUE);
2642 
2643   if (retval) return lives_osc_notify_success(NULL);
2644   else return lives_osc_notify_failure();
2645 }
2646 
2647 
lives_osc_cb_clip_select_all(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)2648 boolean lives_osc_cb_clip_select_all(void *context, int arglen, const void *vargs, OSCTimeTag when,
2649                                      NetworkReturnAddressPtr ra) {
2650   boolean selwidth_locked = mainw->selwidth_locked;
2651 
2652   if (mainw->current_file < 1 || (mainw->preview || (!mainw->multitrack && mainw->event_list && (!mainw->record ||
2653                                   !LIVES_IS_PLAYING))) ||
2654       mainw->is_processing) return lives_osc_notify_failure();
2655   if (!CURRENT_CLIP_IS_NORMAL || !CURRENT_CLIP_HAS_VIDEO) return lives_osc_notify_failure();
2656 
2657   mainw->selwidth_locked = FALSE;
2658   on_select_all_activate(NULL, NULL);
2659   mainw->selwidth_locked = selwidth_locked;
2660 
2661   return lives_osc_notify_success(NULL);
2662 }
2663 
2664 
lives_osc_cb_clip_isvalid(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)2665 boolean lives_osc_cb_clip_isvalid(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
2666   int clip;
2667 
2668   if (!lives_osc_check_arguments(arglen, vargs, "i", TRUE)) return lives_osc_notify_failure();
2669   lives_osc_parse_int_argument(vargs, &clip);
2670 
2671   if (IS_VALID_CLIP(clip) && !(mainw->multitrack &&
2672                                clip == mainw->multitrack->render_file) &&
2673       clip != mainw->scrap_file)
2674     return lives_status_send(get_omc_const("LIVES_TRUE"));
2675   else return lives_status_send(get_omc_const("LIVES_FALSE"));
2676 }
2677 
2678 
lives_osc_cb_rte_count(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)2679 boolean lives_osc_cb_rte_count(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
2680   // count realtime effects - (only those assigned to keys for now)
2681   char *tmp;
2682   lives_status_send((tmp = lives_strdup_printf("%d", prefs->rte_keys_virtual)));
2683   lives_free(tmp);
2684   return TRUE;
2685 }
2686 
2687 
lives_osc_cb_rteuser_count(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)2688 boolean lives_osc_cb_rteuser_count(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
2689   // count realtime effects
2690   char *tmp;
2691   lives_status_send((tmp = lives_strdup_printf("%d", FX_MAX)));
2692   lives_free(tmp);
2693   return TRUE;
2694 }
2695 
2696 
lives_osc_cb_fssepwin_enable(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)2697 boolean lives_osc_cb_fssepwin_enable(void *context, int arglen, const void *vargs, OSCTimeTag when,
2698                                      NetworkReturnAddressPtr ra) {
2699   if (!mainw->sep_win) {
2700     on_sepwin_pressed(NULL, NULL);
2701   }
2702 
2703   if (!mainw->fs) {
2704     on_full_screen_pressed(NULL, NULL);
2705   }
2706   return lives_osc_notify_success(NULL);
2707 }
2708 
2709 
lives_osc_cb_fssepwin_disable(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)2710 boolean lives_osc_cb_fssepwin_disable(void *context, int arglen, const void *vargs, OSCTimeTag when,
2711                                       NetworkReturnAddressPtr ra) {
2712   if (mainw->fs) {
2713     on_full_screen_pressed(NULL, NULL);
2714   }
2715   if (mainw->sep_win) {
2716     on_sepwin_pressed(NULL, NULL);
2717   }
2718   return lives_osc_notify_success(NULL);
2719 }
2720 
2721 
lives_osc_cb_op_fps_set(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)2722 boolean lives_osc_cb_op_fps_set(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
2723   int fps;
2724   float fpsf;
2725   double fpsd;
2726   char *msg;
2727 
2728   if (mainw->fixed_fpsd > 0.) return lives_osc_notify_failure();
2729   if (!lives_osc_check_arguments(arglen, vargs, "f", FALSE)) {
2730     if (!lives_osc_check_arguments(arglen, vargs, "i", TRUE)) return lives_osc_notify_failure();
2731     lives_osc_parse_int_argument(vargs, &fps);
2732     fpsd = (double)(fps * 1.);
2733   } else {
2734     lives_osc_check_arguments(arglen, vargs, "f", TRUE);
2735     lives_osc_parse_float_argument(vargs, &fpsf);
2736     fpsd = (double)fpsf;
2737   }
2738   if (fpsd > 0. && fpsd <= FPS_MAX) {
2739     mainw->fixed_fpsd = fpsd;
2740     d_print(_("Syncing to external framerate of %.8f frames per second.\n"), fpsd);
2741   } else {
2742     if (fpsd == 0.) mainw->fixed_fpsd = -1.; ///< 0. to release
2743     else return lives_osc_notify_failure();
2744   }
2745   msg = lives_strdup_printf("%.3f", fpsd);
2746   lives_osc_notify_success(msg);
2747   lives_free(msg);
2748   return TRUE;
2749 }
2750 
2751 
lives_osc_cb_pref_set_audio_source(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)2752 boolean lives_osc_cb_pref_set_audio_source(void *context, int arglen, const void *vargs, OSCTimeTag when,
2753     NetworkReturnAddressPtr ra) {
2754   int val;
2755 
2756   if (!lives_osc_check_arguments(arglen, vargs, "i", TRUE)) return lives_osc_notify_failure();
2757   lives_osc_parse_int_argument(vargs, &val);
2758   if (val != AUDIO_SRC_INT && val != AUDIO_SRC_EXT) return lives_osc_notify_failure();
2759   pref_factory_bool(PREF_REC_EXT_AUDIO, val == AUDIO_SRC_EXT, FALSE);
2760   return lives_osc_notify_success(NULL);
2761 }
2762 
2763 
lives_osc_cb_pref_get_audio_source(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)2764 boolean lives_osc_cb_pref_get_audio_source(void *context, int arglen, const void *vargs, OSCTimeTag when,
2765     NetworkReturnAddressPtr ra) {
2766   if (prefs->audio_src == AUDIO_SRC_EXT) return lives_status_send(get_omc_const("LIVES_AUDIO_SOURCE_EXTERNAL"));
2767   return lives_status_send(get_omc_const("LIVES_AUDIO_SOURCE_INTERNAL"));
2768 }
2769 
2770 
lives_osc_cb_freeze(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)2771 boolean lives_osc_cb_freeze(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
2772   if (mainw->playing_file < 1) return lives_osc_notify_failure();
2773 
2774   if (!mainw->osc_block) {
2775     freeze_callback(NULL, NULL, 0, (LiVESXModifierType)0, NULL);
2776   }
2777   return lives_osc_notify_success(NULL);
2778 }
2779 
2780 
lives_osc_cb_op_nodrope(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)2781 boolean lives_osc_cb_op_nodrope(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
2782   prefs->noframedrop = TRUE;
2783   return lives_osc_notify_success(NULL);
2784 }
2785 
2786 
lives_osc_cb_op_nodropd(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)2787 boolean lives_osc_cb_op_nodropd(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
2788   prefs->noframedrop = FALSE;
2789   return lives_osc_notify_success(NULL);
2790 }
2791 
2792 
lives_osc_cb_fx_getname(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)2793 boolean lives_osc_cb_fx_getname(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
2794   char *retval;
2795   int fidx;
2796 
2797   if (lives_osc_check_arguments(arglen, vargs, "i", FALSE)) {
2798     lives_osc_check_arguments(arglen, vargs, "i", TRUE);
2799     lives_osc_parse_int_argument(vargs, &fidx);
2800   } else return lives_osc_notify_failure();
2801 
2802   retval = make_weed_hashname(fidx, FALSE, FALSE, 0, FALSE);
2803 
2804   lives_status_send(retval);
2805 
2806   lives_free(retval);
2807 
2808   return TRUE;
2809 }
2810 
2811 
lives_osc_cb_clip_encodeas(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)2812 boolean lives_osc_cb_clip_encodeas(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
2813   char fname[OSC_STRING_SIZE];
2814 
2815   if (LIVES_IS_PLAYING || mainw->current_file < 1) return lives_osc_notify_failure();
2816 
2817   if (mainw->preview || mainw->event_list || mainw->is_processing ||
2818       mainw->multitrack) return lives_osc_notify_failure();
2819 
2820   if (!cfile || cfile->opening) return lives_osc_notify_failure();
2821 
2822   mainw->osc_enc_width = mainw->osc_enc_height = 0;
2823   mainw->osc_enc_fps = 0.;
2824 
2825   if (!lives_osc_check_arguments(arglen, vargs, "siif", FALSE)) {
2826     if (!lives_osc_check_arguments(arglen, vargs, "sii", FALSE)) {
2827       if (!lives_osc_check_arguments(arglen, vargs, "sf", FALSE)) {
2828         if (!lives_osc_check_arguments(arglen, vargs, "s", TRUE))
2829           return lives_osc_notify_failure();
2830         lives_osc_parse_string_argument(vargs, fname);
2831       }
2832       lives_osc_check_arguments(arglen, vargs, "sf", TRUE);
2833       lives_osc_parse_string_argument(vargs, fname);
2834       lives_osc_parse_float_argument(vargs, &mainw->osc_enc_fps);
2835     } else {
2836       lives_osc_check_arguments(arglen, vargs, "sii", TRUE);
2837       lives_osc_parse_string_argument(vargs, fname);
2838       lives_osc_parse_int_argument(vargs, &mainw->osc_enc_width);
2839       lives_osc_parse_int_argument(vargs, &mainw->osc_enc_height);
2840     }
2841   } else {
2842     lives_osc_check_arguments(arglen, vargs, "siif", TRUE);
2843     lives_osc_parse_string_argument(vargs, fname);
2844     lives_osc_parse_int_argument(vargs, &mainw->osc_enc_width);
2845     lives_osc_parse_int_argument(vargs, &mainw->osc_enc_height);
2846     lives_osc_parse_float_argument(vargs, &mainw->osc_enc_fps);
2847   }
2848 
2849   if (cfile->frames == 0) {
2850     // TODO
2851     on_export_audio_activate(NULL, NULL);
2852     return lives_osc_notify_success(NULL);
2853   }
2854 
2855   mainw->osc_auto = 1;
2856   save_file(mainw->current_file, 1, cfile->frames, fname);
2857   mainw->osc_auto = 0;
2858   return lives_osc_notify_success(NULL);
2859 }
2860 
2861 
lives_osc_cb_rte_setmode(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)2862 boolean lives_osc_cb_rte_setmode(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
2863   int effect_key;
2864   int mode;
2865 
2866   if (!lives_osc_check_arguments(arglen, vargs, "ii", TRUE)) return lives_osc_notify_failure();
2867   lives_osc_parse_int_argument(vargs, &effect_key);
2868   lives_osc_parse_int_argument(vargs, &mode);
2869   if (effect_key < 1 || effect_key >= FX_KEYS_MAX_VIRTUAL || mode < 1 ||
2870       mode > rte_getmodespk()) return lives_osc_notify_failure();
2871   if (!mainw->osc_block) rte_key_setmode(effect_key, mode - 1);
2872 
2873   return lives_osc_notify_success(NULL);
2874 }
2875 
2876 
lives_osc_cb_rte_nextmode(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)2877 boolean lives_osc_cb_rte_nextmode(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
2878   int effect_key;
2879 
2880   if (!lives_osc_check_arguments(arglen, vargs, "i", TRUE)) return lives_osc_notify_failure();
2881   lives_osc_parse_int_argument(vargs, &effect_key);
2882   if (effect_key < 1 || effect_key >= FX_KEYS_MAX_VIRTUAL) return lives_osc_notify_failure();
2883   if (!mainw->osc_block) rte_key_setmode(effect_key, -1);
2884 
2885   return lives_osc_notify_success(NULL);
2886 }
2887 
2888 
lives_osc_cb_rte_prevmode(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)2889 boolean lives_osc_cb_rte_prevmode(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
2890   int effect_key;
2891 
2892   if (!lives_osc_check_arguments(arglen, vargs, "i", TRUE)) return lives_osc_notify_failure();
2893   lives_osc_parse_int_argument(vargs, &effect_key);
2894   if (effect_key < 1 || effect_key >= FX_KEYS_MAX_VIRTUAL) return lives_osc_notify_failure();
2895   if (!mainw->osc_block) rte_key_setmode(effect_key, -2);
2896 
2897   return lives_osc_notify_success(NULL);
2898 }
2899 
2900 
2901 ///////////////////////////////////////////////////////////////
2902 
setfx(weed_plant_t * plant,weed_plant_t * tparam,int pnum,int nargs,const void * vargs,int skip)2903 static boolean setfx(weed_plant_t *plant, weed_plant_t *tparam, int pnum, int nargs, const void *vargs, int skip) {
2904   // set value of "value" leaf for tparam, or "host_default" for a template
2905   // set it to vargs (length nargs)
2906 
2907   weed_plant_t *ptmpl, *inst = NULL;
2908 
2909   float valuef;
2910 
2911   int valuei;
2912   int i;
2913   int ptype, cspace = -1;
2914   int x = 0;
2915   //int copyto = -1;
2916   int defargs;
2917   int maxi_r = 255, maxi_g = 255, maxi_b = 255, maxi_a = 255, mini_r = 0, mini_g = 0, mini_b = 0, mini_a = 0, mini, maxi;
2918   int key = -1;
2919 
2920   double maxd_r = 1., maxd_g = 1., maxd_b = 1., maxd_a = 1., mind_r = 0., mind_g = 0., mind_b = 0., mind_a = 0., mind, maxd;
2921   char values[OSC_STRING_SIZE];
2922   const char *pattern;
2923 
2924   if (nargs <= 0) return FALSE; // must set at least one value
2925 
2926   if (WEED_PLANT_IS_FILTER_CLASS(plant)) {
2927     ptmpl = tparam;
2928   } else {
2929     ptmpl = weed_get_plantptr_value(tparam, WEED_LEAF_TEMPLATE, NULL);
2930     inst = plant;
2931     if (weed_plant_has_leaf(inst, WEED_LEAF_HOST_KEY)) key = weed_get_int_value(inst, WEED_LEAF_HOST_KEY, NULL);
2932   }
2933 
2934   ptype = weed_paramtmpl_get_type(ptmpl);
2935   if (ptype == WEED_PARAM_COLOR) cspace = weed_get_int_value(ptmpl, WEED_LEAF_COLORSPACE, NULL);
2936 
2937   if (!(weed_parameter_has_variable_elements_strict(inst, ptmpl))) {
2938     if (nargs > (defargs = weed_leaf_num_elements(ptmpl, WEED_LEAF_DEFAULT))) {
2939       if (!(ptype == WEED_PARAM_COLOR && defargs == 1 && ((cspace == WEED_COLORSPACE_RGB && (nargs % 3 == 0)) ||
2940             (cspace == WEED_COLORSPACE_RGBA &&
2941              !(nargs & 3)))))
2942         // error: parameter does not have variable elements, and the user sent too many values
2943         return FALSE;
2944     }
2945   }
2946 
2947   pattern = (char *)vargs + skip; // skip comma,int,(int)
2948 
2949   switch (ptype) {
2950   case WEED_PARAM_INTEGER: {
2951     int *valuesi = (int *)lives_malloc(nargs * sizint);
2952 
2953     while (pattern[x] != 0) {
2954       if (pattern[x] == 'f') {
2955         // we wanted an int but we got a float
2956         //so we will round to the nearest value
2957         lives_osc_parse_float_argument(vargs, &valuef);
2958         valuesi[x] = myround(valuef);
2959       } else if (pattern[x] == 'i') {
2960         lives_osc_parse_int_argument(vargs, &valuesi[x]);
2961       } else {
2962         lives_free(valuesi);
2963         return FALSE;
2964       }
2965       mini = weed_get_int_value(ptmpl, WEED_LEAF_MIN, NULL);
2966       maxi = weed_get_int_value(ptmpl, WEED_LEAF_MAX, NULL);
2967 
2968       if (valuesi[x] < mini) valuesi[x] = mini;
2969       if (valuesi[x] > maxi) valuesi[x] = maxi;
2970       x++;
2971     }
2972 
2973     if (inst) {
2974       if (!filter_mutex_trylock(key)) {
2975         //copyto = set_copy_to(inst, pnum, FALSE);
2976         if (mainw->record && !mainw->record_paused && LIVES_IS_PLAYING && (prefs->rec_opts & REC_EFFECTS)) {
2977           // if we are recording, add this change to our event_list
2978           rec_param_change(inst, pnum);
2979           //if (copyto != -1) rec_param_change(inst, copyto);
2980         }
2981         weed_set_int_array(tparam, WEED_LEAF_VALUE, nargs, valuesi);
2982         //set_copy_to(inst, pnum, TRUE);
2983 
2984         if (mainw->record && !mainw->record_paused && LIVES_IS_PLAYING && (prefs->rec_opts & REC_EFFECTS)) {
2985           // if we are recording, add this change to our event_list
2986           rec_param_change(inst, pnum);
2987           //if (copyto != -1) rec_param_change(inst, copyto);
2988         }
2989         filter_mutex_unlock(key);
2990       }
2991     } else {
2992       weed_set_int_array(tparam, WEED_LEAF_HOST_DEFAULT, nargs, valuesi);
2993     }
2994 
2995     lives_free(valuesi);
2996 
2997     break;
2998   }
2999 
3000   case WEED_PARAM_SWITCH: {
3001     int group = 0;
3002     int *valuesb = (int *)lives_malloc(nargs * sizint);
3003 
3004     while (pattern[x] != 0) {
3005       if (pattern[x] == 'i') {
3006         lives_osc_parse_int_argument(vargs, &valuesb[x]);
3007       } else {
3008         lives_free(valuesb);
3009         return FALSE;
3010       }
3011       valuesb[x] = !!valuesb[x];
3012       x++;
3013     }
3014 
3015     if (weed_plant_has_leaf(ptmpl, WEED_LEAF_GROUP))
3016       group = weed_get_int_value(ptmpl, WEED_LEAF_GROUP, NULL);
3017 
3018     if (group != 0 && valuesb[0] == WEED_FALSE) goto grpinvalid;
3019 
3020     if (inst) {
3021       if (!filter_mutex_trylock(key)) {
3022         weed_set_boolean_array(tparam, WEED_LEAF_VALUE, nargs, valuesb);
3023         //copyto = set_copy_to(inst, pnum, TRUE);
3024         if (mainw->record && !mainw->record_paused && LIVES_IS_PLAYING && (prefs->rec_opts & REC_EFFECTS)) {
3025           // if we are recording, add this change to our event_list
3026           rec_param_change(inst, pnum);
3027           //if (copyto != -1) rec_param_change(inst, copyto);
3028         }
3029         filter_mutex_unlock(key);
3030       }
3031 
3032       if (group != 0) {
3033         // set all other values in group to WEED_FALSE
3034         weed_plant_t *filter = weed_instance_get_filter(inst, FALSE), *xtparam;
3035         int nparams = num_in_params(filter, FALSE, TRUE);
3036 
3037         for (pnum = 0; pnum < nparams; pnum++) {
3038           xtparam = weed_inst_in_param(inst, pnum, FALSE, TRUE);
3039 
3040           if (xtparam != tparam) {
3041             ptmpl = weed_param_get_template(xtparam);
3042             ptype = weed_paramtmpl_get_type(ptmpl);
3043             if (ptype == WEED_PARAM_SWITCH) {
3044               int xgroup = 0;
3045 
3046               if (weed_plant_has_leaf(ptmpl, WEED_LEAF_GROUP))
3047                 xgroup = weed_get_int_value(ptmpl, WEED_LEAF_GROUP, NULL);
3048 
3049               if (xgroup == group) {
3050                 if (!filter_mutex_trylock(key)) {
3051                   weed_set_boolean_value(xtparam, WEED_LEAF_VALUE, WEED_FALSE);
3052                   //copyto = set_copy_to(inst, pnum, TRUE);
3053                   if (mainw->record && !mainw->record_paused && LIVES_IS_PLAYING && (prefs->rec_opts & REC_EFFECTS)) {
3054                     // if we are recording, add this change to our event_list
3055                     rec_param_change(inst, pnum);
3056                     //if (copyto != -1) rec_param_change(inst, copyto);
3057                   }
3058                     filter_mutex_unlock(key);
3059 		  // *INDENT-OFF*
3060 }}}}}}
3061 // *INDENT-ON*
3062     } else {
3063       weed_set_boolean_array(tparam, WEED_LEAF_HOST_DEFAULT, nargs, valuesb);
3064 
3065       if (group != 0) {
3066         // set all other values in group to WEED_FALSE
3067         weed_plant_t *filter = plant, *xtparam;
3068         int nparams = num_in_params(filter, FALSE, TRUE);
3069 
3070         for (pnum = 0; pnum < nparams; pnum++) {
3071           xtparam = weed_filter_in_paramtmpl(inst, pnum, TRUE);
3072 
3073           if (xtparam != tparam) {
3074             ptype = weed_paramtmpl_get_type(xtparam);
3075             if (ptype == WEED_PARAM_SWITCH) {
3076               int xgroup = 0;
3077 
3078               if (weed_plant_has_leaf(ptmpl, WEED_LEAF_GROUP))
3079                 xgroup = weed_get_int_value(ptmpl, WEED_LEAF_GROUP, NULL);
3080 
3081               if (xgroup == group) {
3082                   weed_set_boolean_value(tparam, WEED_LEAF_HOST_DEFAULT, WEED_FALSE);
3083 		// *INDENT-OFF*
3084 }}}}}}
3085 // *INDENT-ON*
3086 
3087 grpinvalid:
3088 
3089     lives_free(valuesb);
3090 
3091     break;
3092   }
3093 
3094   case WEED_PARAM_FLOAT: {
3095     double *valuesd = (double *)lives_malloc(nargs * sizdbl);
3096 
3097     while (pattern[x] != 0) {
3098       if (pattern[x] == 'i') {
3099         // we wanted an float but we got an int
3100         //so we will convert
3101         lives_osc_parse_int_argument(vargs, &valuei);
3102         valuesd[x] = (double)(valuei);
3103       } else if (pattern[x] == 'f') {
3104         lives_osc_parse_float_argument(vargs, &valuef);
3105         valuesd[x] = (double)(valuef);
3106       } else {
3107         lives_free(valuesd);
3108         return FALSE;
3109       }
3110       mind = weed_get_double_value(ptmpl, WEED_LEAF_MIN, NULL);
3111       maxd = weed_get_double_value(ptmpl, WEED_LEAF_MAX, NULL);
3112 
3113       if (valuesd[x] < mind) valuesd[x] = mind;
3114       if (valuesd[x] > maxd) valuesd[x] = maxd;
3115       x++;
3116     }
3117 
3118     if (inst) {
3119       //copyto = set_copy_to(inst, pnum, FALSE);
3120 
3121       if (mainw->record && !mainw->record_paused && LIVES_IS_PLAYING && (prefs->rec_opts & REC_EFFECTS)) {
3122         // if we are recording, add this change to our event_list
3123         rec_param_change(inst, pnum);
3124         //if (copyto != -1) rec_param_change(inst, copyto);
3125       }
3126       if (!filter_mutex_trylock(key)) {
3127         weed_set_double_array(tparam, WEED_LEAF_VALUE, nargs, valuesd);
3128         //set_copy_to(inst, pnum, TRUE);
3129 
3130         if (mainw->record && !mainw->record_paused && LIVES_IS_PLAYING && (prefs->rec_opts & REC_EFFECTS)) {
3131           // if we are recording, add this change to our event_list
3132           rec_param_change(inst, pnum);
3133           //if (copyto != -1) rec_param_change(inst, copyto);
3134         }
3135         filter_mutex_unlock(key);
3136       }
3137     } else {
3138       weed_set_double_array(tparam, WEED_LEAF_HOST_DEFAULT, nargs, valuesd);
3139     }
3140 
3141     lives_free(valuesd);
3142 
3143     break;
3144   }
3145 
3146   case WEED_PARAM_TEXT: {
3147     char **valuess = (char **)lives_malloc(nargs * sizeof(char *));
3148 
3149     while (pattern[x] != 0) {
3150       if (pattern[x] == 'i') {
3151         // we wanted a string but we got an int
3152         //so we will convert
3153         lives_osc_parse_int_argument(vargs, &valuei);
3154         valuess[x] = lives_strdup_printf("%d", valuei);
3155       } else if (pattern[x] == 'f') {
3156         // we wanted a string but we got a float
3157         //so we will convert
3158         lives_osc_parse_float_argument(vargs, &valuef);
3159         valuess[x] = lives_strdup_printf("%f", valuef);
3160       } else if (pattern[x] == 's') {
3161         lives_osc_parse_string_argument(vargs, values);
3162         valuess[x] = lives_strdup(values);
3163       } else {
3164         for (i = 0; i < x; i++) lives_free(valuess[i]);
3165         lives_free(valuess);
3166         return FALSE;
3167       }
3168 
3169       x++;
3170     }
3171 
3172     if (inst) {
3173       if (!filter_mutex_trylock(key)) {
3174         weed_set_string_array(tparam, WEED_LEAF_VALUE, nargs, valuess);
3175         //copyto = set_copy_to(inst, pnum, TRUE);
3176 
3177         if (mainw->record && !mainw->record_paused && LIVES_IS_PLAYING && (prefs->rec_opts & REC_EFFECTS)) {
3178           // if we are recording, add this change to our event_list
3179           rec_param_change(inst, pnum);
3180           //if (copyto != -1) rec_param_change(inst, copyto);
3181         }
3182         filter_mutex_unlock(key);
3183       }
3184     } else {
3185       weed_set_string_array(tparam, WEED_LEAF_HOST_DEFAULT, nargs, valuess);
3186     }
3187 
3188     for (i = 0; i < x; i++) lives_free(valuess[i]);
3189     lives_free(valuess);
3190 
3191     break;
3192   }
3193 
3194   // COLOR is the most complicated, as we can have 3-values (RGB) or 4-values (RGBA), and we can have
3195   // an int or a float type. Also min and max can have 1,n or N values.
3196 
3197   case WEED_PARAM_COLOR:
3198     switch (cspace) {
3199     case WEED_COLORSPACE_RGB:
3200       if (nargs % 3 != 0) return FALSE; //nargs must be a multiple of 3
3201 
3202       if (weed_leaf_seed_type(ptmpl, WEED_LEAF_DEFAULT) == WEED_SEED_INT) {
3203         // RGB, int type
3204         int *valuesi = (int *)lives_malloc(nargs * sizint);
3205         int nmins = weed_leaf_num_elements(ptmpl, WEED_LEAF_MIN);
3206         int nmaxs = weed_leaf_num_elements(ptmpl, WEED_LEAF_MAX);
3207         int *minis = NULL, *maxis = NULL;
3208 
3209         // get min and max values - 3 possibilities: 1 value, 3 values or N values
3210 
3211         if (nmins == 1) {
3212           mini_r = mini_g = mini_b = weed_get_int_value(ptmpl, WEED_LEAF_MIN, NULL);
3213         } else {
3214           minis = weed_get_int_array(ptmpl, WEED_LEAF_MIN, NULL);
3215           if (nmins == 3) {
3216             mini_r = minis[0];
3217             mini_g = minis[1];
3218             mini_b = minis[2];
3219             lives_free(minis);
3220           }
3221         }
3222 
3223         if (nmaxs == 1) {
3224           maxi_r = maxi_g = maxi_b = weed_get_int_value(ptmpl, WEED_LEAF_MAX, NULL);
3225         } else {
3226           maxis = weed_get_int_array(ptmpl, WEED_LEAF_MAX, NULL);
3227           if (nmaxs == 3) {
3228             maxi_r = maxis[0];
3229             maxi_g = maxis[1];
3230             maxi_b = maxis[2];
3231             lives_free(maxis);
3232           }
3233         }
3234 
3235         // read vals from OSC message
3236         while (pattern[x] != 0) {
3237           // get next 3 values
3238           for (i = 0; i < 3; i++) {
3239             if (pattern[x + i] == 'f') {
3240               // we wanted int but we got floats
3241               lives_osc_parse_float_argument(vargs, &valuef);
3242               valuesi[x + i] = myround(valuef);
3243             } else {
3244               lives_osc_parse_int_argument(vargs, &valuesi[x + i]);
3245             }
3246           }
3247 
3248           if (nmins <= 3) {
3249             if (valuesi[x] < mini_r) valuesi[x] = mini_r;
3250             if (valuesi[x + 1] < mini_g) valuesi[x + 1] = mini_g;
3251             if (valuesi[x + 2] < mini_b) valuesi[x + 2] = mini_b;
3252           } else {
3253             if (valuesi[x] < minis[x])   valuesi[x] = minis[x];
3254             if (valuesi[x + 1] < minis[x + 1]) valuesi[x + 1] = minis[x + 1];
3255             if (valuesi[x + 2] < minis[x + 2]) valuesi[x + 2] = minis[x + 2];
3256           }
3257 
3258           if (nmaxs <= 3) {
3259             if (valuesi[x] > maxi_r) valuesi[x] = maxi_r;
3260             if (valuesi[x + 1] > maxi_g) valuesi[x + 1] = maxi_g;
3261             if (valuesi[x + 2] > maxi_b) valuesi[x + 2] = maxi_b;
3262           } else {
3263             if (valuesi[x] > maxis[x + i])   valuesi[x] = maxis[x + i];
3264             if (valuesi[x + 1] > maxis[x + 1]) valuesi[x + 1] = maxis[x + 1];
3265             if (valuesi[x + 2] > maxis[x + 2]) valuesi[x + 2] = maxis[x + 2];
3266           }
3267           x += 3;
3268         }
3269 
3270         if (inst) {
3271           if (!filter_mutex_trylock(key)) {
3272             //copyto = set_copy_to(inst, pnum, FALSE);
3273 
3274             if (mainw->record && !mainw->record_paused && LIVES_IS_PLAYING && (prefs->rec_opts & REC_EFFECTS)) {
3275               // if we are recording, add this change to our event_list
3276               rec_param_change(inst, pnum);
3277               //if (copyto != -1) rec_param_change(inst, copyto);
3278             }
3279 
3280             weed_set_int_array(tparam, WEED_LEAF_VALUE, nargs, valuesi);
3281             //set_copy_to(inst, pnum, TRUE);
3282 
3283             if (mainw->record && !mainw->record_paused && LIVES_IS_PLAYING && (prefs->rec_opts & REC_EFFECTS)) {
3284               // if we are recording, add this change to our event_list
3285               rec_param_change(inst, pnum);
3286               //if (copyto != -1) rec_param_change(inst, copyto);
3287             }
3288             filter_mutex_unlock(key);
3289           }
3290         } else {
3291           weed_set_int_array(tparam, WEED_LEAF_HOST_DEFAULT, nargs, valuesi);
3292         }
3293 
3294         lives_free(valuesi);
3295 
3296         if (nmins > 3) lives_free(minis);
3297         if (nmaxs > 3) lives_free(maxis);
3298       } else {
3299         // RGB, float type
3300         double *valuesd = (double *)lives_malloc(nargs * sizeof(double));
3301         int nmins = weed_leaf_num_elements(ptmpl, WEED_LEAF_MIN);
3302         int nmaxs = weed_leaf_num_elements(ptmpl, WEED_LEAF_MAX);
3303         double *minds = NULL, *maxds = NULL;
3304         // get min and max values - 3 possibilities: 1 value, 3 values or N values
3305 
3306         if (nmins == 1) {
3307           mind_r = mind_g = mind_b = weed_get_double_value(ptmpl, WEED_LEAF_MIN, NULL);
3308         } else {
3309           minds = weed_get_double_array(ptmpl, WEED_LEAF_MIN, NULL);
3310           if (nmins == 3) {
3311             mind_r = minds[0];
3312             mind_g = minds[1];
3313             mind_b = minds[2];
3314             lives_free(minds);
3315           }
3316         }
3317 
3318         if (nmaxs == 1) {
3319           maxd_r = maxd_g = maxd_b = weed_get_double_value(ptmpl, WEED_LEAF_MAX, NULL);
3320         } else {
3321           maxds = weed_get_double_array(ptmpl, WEED_LEAF_MAX, NULL);
3322           if (nmaxs == 3) {
3323             maxd_r = maxds[0];
3324             maxd_g = maxds[1];
3325             maxd_b = maxds[2];
3326             lives_free(maxds);
3327           }
3328         }
3329 
3330         // read vals from OSC message
3331         while (pattern[x] != 0) {
3332           // get next 3 values
3333           for (i = 0; i < 3; i++) {
3334             if (pattern[x + i] == 'i') {
3335               // we wanted float but we got floats
3336               lives_osc_parse_int_argument(vargs, &valuei);
3337               valuesd[x + i] = (double)valuei;
3338             } else {
3339               lives_osc_parse_float_argument(vargs, &valuef);
3340               valuesd[x + i] = (double)valuef;
3341             }
3342           }
3343 
3344           if (nmins <= 3) {
3345             if (valuesd[x] < mind_r) valuesd[x] = mind_r;
3346             if (valuesd[x + 1] < mind_g) valuesd[x + 1] = mind_g;
3347             if (valuesd[x + 2] < mind_b) valuesd[x + 2] = mind_b;
3348           } else {
3349             if (valuesd[x] < minds[x])   valuesd[x] = minds[x];
3350             if (valuesd[x + 1] < minds[x + 1]) valuesd[x + 1] = minds[x + 1];
3351             if (valuesd[x + 2] < minds[x + 2]) valuesd[x + 2] = minds[x + 2];
3352           }
3353 
3354           if (nmaxs <= 3) {
3355             if (valuesd[x] > maxd_r) valuesd[x] = maxd_r;
3356             if (valuesd[x + 1] > maxd_g) valuesd[x + 1] = maxd_g;
3357             if (valuesd[x + 2] > maxd_b) valuesd[x + 2] = maxd_b;
3358           } else {
3359             if (valuesd[x] > maxds[x])   valuesd[x] = maxds[x];
3360             if (valuesd[x + 1] > maxds[x + 1]) valuesd[x + 1] = maxds[x + 1];
3361             if (valuesd[x + 2] > maxds[x + 2]) valuesd[x + 2] = maxds[x + 2];
3362           }
3363           x += 3;
3364         }
3365 
3366         if (inst) {
3367           if (!filter_mutex_trylock(key)) {
3368             //copyto = set_copy_to(inst, pnum, FALSE);
3369 
3370             if (mainw->record && !mainw->record_paused && LIVES_IS_PLAYING && (prefs->rec_opts & REC_EFFECTS)) {
3371               // if we are recording, add this change to our event_list
3372               rec_param_change(inst, pnum);
3373               //if (copyto != -1) rec_param_change(inst, copyto);
3374             }
3375 
3376             weed_set_double_array(tparam, WEED_LEAF_VALUE, nargs, valuesd);
3377             //set_copy_to(inst, pnum, TRUE);
3378 
3379             if (mainw->record && !mainw->record_paused && LIVES_IS_PLAYING && (prefs->rec_opts & REC_EFFECTS)) {
3380               // if we are recording, add this change to our event_list
3381               rec_param_change(inst, pnum);
3382               //if (copyto != -1) rec_param_change(inst, copyto);
3383             }
3384             filter_mutex_unlock(key);
3385           }
3386         } else {
3387           weed_set_double_array(tparam, WEED_LEAF_HOST_DEFAULT, nargs, valuesd);
3388         }
3389 
3390         lives_free(valuesd);
3391 
3392         if (nmins > 3) lives_free(minds);
3393         if (nmaxs > 3) lives_free(maxds);
3394       }
3395 
3396       break;
3397 
3398     // RGBA colorspace
3399 
3400     case WEED_COLORSPACE_RGBA:
3401       if (nargs & 3) return FALSE; //nargs must be a multiple of 4
3402 
3403       if (weed_leaf_seed_type(ptmpl, WEED_LEAF_DEFAULT) == WEED_SEED_INT) {
3404         // RGBA, int type
3405         int *valuesi = (int *)lives_malloc(nargs * sizint);
3406         int nmins = weed_leaf_num_elements(ptmpl, WEED_LEAF_MIN);
3407         int nmaxs = weed_leaf_num_elements(ptmpl, WEED_LEAF_MAX);
3408         int *minis = NULL, *maxis = NULL;
3409 
3410         // get min and max values - 3 possibilities: 1 value, 4 values or N values
3411 
3412         if (nmins == 1) {
3413           mini_r = mini_g = mini_b = mini_a = weed_get_int_value(ptmpl, WEED_LEAF_MIN, NULL);
3414         } else {
3415           minis = weed_get_int_array(ptmpl, WEED_LEAF_MIN, NULL);
3416           if (nmins == 4) {
3417             mini_r = minis[0];
3418             mini_g = minis[1];
3419             mini_b = minis[2];
3420             mini_a = minis[3];
3421             lives_free(minis);
3422           }
3423         }
3424 
3425         if (nmaxs == 1) {
3426           maxi_r = maxi_g = maxi_b = maxi_a = weed_get_int_value(ptmpl, WEED_LEAF_MAX, NULL);
3427         } else {
3428           maxis = weed_get_int_array(ptmpl, WEED_LEAF_MAX, NULL);
3429           if (nmaxs == 4) {
3430             maxi_r = maxis[0];
3431             maxi_g = maxis[1];
3432             maxi_b = maxis[2];
3433             maxi_a = maxis[3];
3434             lives_free(maxis);
3435           }
3436         }
3437 
3438         // read vals from OSC message
3439         while (pattern[x] != 0) {
3440           // get next 4 values
3441           for (i = 0; i < 4; i++) {
3442             if (pattern[x] == 'f') {
3443               // we wanted int but we got floats
3444               lives_osc_parse_float_argument(vargs, &valuef);
3445               valuesi[x + i] = myround(valuef);
3446             } else {
3447               lives_osc_parse_int_argument(vargs, &valuesi[x + i]);
3448             }
3449           }
3450 
3451           if (nmins <= 3) {
3452             if (valuesi[x] < mini_r) valuesi[x] = mini_r;
3453             if (valuesi[x + 1] < mini_g) valuesi[x + 1] = mini_g;
3454             if (valuesi[x + 2] < mini_b) valuesi[x + 2] = mini_b;
3455             if (valuesi[x + 3] < mini_a) valuesi[x + 3] = mini_a;
3456           } else {
3457             if (valuesi[x] < minis[x])   valuesi[x] = minis[x];
3458             if (valuesi[x + 1] < minis[x + 1]) valuesi[x + 1] = minis[x + 1];
3459             if (valuesi[x + 2] < minis[x + 2]) valuesi[x + 2] = minis[x + 2];
3460             if (valuesi[x + 3] < minis[x + 3]) valuesi[x + 3] = minis[x + 3];
3461           }
3462 
3463           if (nmaxs <= 4) {
3464             if (valuesi[x] > maxi_r) valuesi[x] = maxi_r;
3465             if (valuesi[x + 1] > maxi_g) valuesi[x + 1] = maxi_g;
3466             if (valuesi[x + 2] > maxi_b) valuesi[x + 2] = maxi_b;
3467             if (valuesi[x + 3] > maxi_a) valuesi[x + 3] = maxi_a;
3468           } else {
3469             if (valuesi[x] > maxis[x])   valuesi[x] = maxis[x];
3470             if (valuesi[x + 1] > maxis[x + 1]) valuesi[x + 1] = maxis[x + 1];
3471             if (valuesi[x + 2] > maxis[x + 2]) valuesi[x + 2] = maxis[x + 2];
3472             if (valuesi[x + 3] > maxis[x + 3]) valuesi[x + 3] = maxis[x + 3];
3473           }
3474           x += 4;
3475         }
3476 
3477         if (inst) {
3478           if (!filter_mutex_trylock(key)) {
3479             //copyto = set_copy_to(inst, pnum, FALSE);
3480 
3481             if (mainw->record && !mainw->record_paused && LIVES_IS_PLAYING && (prefs->rec_opts & REC_EFFECTS)) {
3482               // if we are recording, add this change to our event_list
3483               rec_param_change(inst, pnum);
3484               //if (copyto != -1) rec_param_change(inst, copyto);
3485             }
3486 
3487             weed_set_int_array(tparam, WEED_LEAF_VALUE, nargs, valuesi);
3488             //set_copy_to(inst, pnum, TRUE);
3489 
3490             if (mainw->record && !mainw->record_paused && LIVES_IS_PLAYING && (prefs->rec_opts & REC_EFFECTS)) {
3491               // if we are recording, add this change to our event_list
3492               rec_param_change(inst, pnum);
3493               //if (copyto != -1) rec_param_change(inst, copyto);
3494             }
3495             filter_mutex_unlock(key);
3496           }
3497         } else {
3498           weed_set_int_array(tparam, WEED_LEAF_HOST_DEFAULT, nargs, valuesi);
3499         }
3500 
3501         lives_free(valuesi);
3502 
3503         if (nmins > 4) lives_free(minis);
3504         if (nmaxs > 4) lives_free(maxis);
3505 
3506       } else {
3507         // RGBA, float type
3508         double *valuesd = (double *)lives_malloc(nargs * sizdbl);
3509         int nmins = weed_leaf_num_elements(ptmpl, WEED_LEAF_MIN);
3510         int nmaxs = weed_leaf_num_elements(ptmpl, WEED_LEAF_MAX);
3511         double *minds = NULL, *maxds = NULL;
3512 
3513         // get min and max values - 3 possibilities: 1 value, 3 values or N values
3514 
3515         if (nmins == 1) {
3516           mind_r = mind_g = mind_b = mind_a = weed_get_double_value(ptmpl, WEED_LEAF_MIN, NULL);
3517         } else {
3518           minds = weed_get_double_array(ptmpl, WEED_LEAF_MIN, NULL);
3519           if (nmins == 4) {
3520             mind_r = minds[0];
3521             mind_g = minds[1];
3522             mind_b = minds[2];
3523             mind_a = minds[3];
3524             lives_free(minds);
3525           }
3526         }
3527 
3528         if (nmaxs == 1) {
3529           maxd_r = maxd_g = maxd_b = mind_a = weed_get_double_value(ptmpl, WEED_LEAF_MAX, NULL);
3530         } else {
3531           maxds = weed_get_double_array(ptmpl, WEED_LEAF_MAX, NULL);
3532           if (nmaxs == 4) {
3533             maxd_r = maxds[0];
3534             maxd_g = maxds[1];
3535             maxd_b = maxds[2];
3536             maxd_a = maxds[3];
3537             lives_free(maxds);
3538           }
3539         }
3540 
3541         // read vals from OSC message
3542         while (pattern[x] != 0) {
3543           // get next 4 values
3544           for (i = 0; i < 4; i++) {
3545             if (pattern[x] == 'i') {
3546               // we wanted float but we got floats
3547               lives_osc_parse_int_argument(vargs, &valuei);
3548               valuesd[x + i] = (double)valuei;
3549             } else {
3550               lives_osc_parse_float_argument(vargs, &valuef);
3551               valuesd[x + i] = (double)valuef;
3552             }
3553           }
3554 
3555           if (nmins <= 4) {
3556             if (valuesd[x] < mind_r) valuesd[x] = mind_r;
3557             if (valuesd[x + 1] < mind_g) valuesd[x + 1] = mind_g;
3558             if (valuesd[x + 2] < mind_b) valuesd[x + 2] = mind_b;
3559             if (valuesd[x + 3] < mind_a) valuesd[x + 3] = mind_a;
3560           } else {
3561             if (valuesd[x] < minds[x])   valuesd[x] = minds[x];
3562             if (valuesd[x + 1] < minds[x + 1]) valuesd[x + 1] = minds[x + 1];
3563             if (valuesd[x + 2] < minds[x + 2]) valuesd[x + 2] = minds[x + 2];
3564             if (valuesd[x + 3] < minds[x + 3]) valuesd[x + 3] = minds[x + 3];
3565           }
3566 
3567           if (nmaxs <= 4) {
3568             if (valuesd[x] > maxd_r) valuesd[x] = maxd_r;
3569             if (valuesd[x + 1] > maxd_g) valuesd[x + 1] = maxd_g;
3570             if (valuesd[x + 2] > maxd_b) valuesd[x + 2] = maxd_b;
3571             if (valuesd[x + 3] > maxd_a) valuesd[x + 3] = maxd_a;
3572           } else {
3573             if (valuesd[x] > maxds[x])   valuesd[x] = maxds[x];
3574             if (valuesd[x + 1] > maxds[x + 1]) valuesd[x + 1] = maxds[x + 1];
3575             if (valuesd[x + 2] > maxds[x + 2]) valuesd[x + 2] = maxds[x + 2];
3576             if (valuesd[x + 3] > maxds[x + 3]) valuesd[x + 3] = maxds[x + 3];
3577           }
3578           x += 4;
3579         }
3580 
3581         if (inst) {
3582           if (!filter_mutex_trylock(key)) {
3583             //copyto = set_copy_to(inst, pnum, FALSE);
3584 
3585             if (mainw->record && !mainw->record_paused && LIVES_IS_PLAYING && (prefs->rec_opts & REC_EFFECTS)) {
3586               // if we are recording, add this change to our event_list
3587               rec_param_change(inst, pnum);
3588               //if (copyto != -1) rec_param_change(inst, copyto);
3589             }
3590 
3591             weed_set_double_array(tparam, WEED_LEAF_VALUE, nargs, valuesd);
3592             //set_copy_to(inst, pnum, TRUE);
3593 
3594             if (mainw->record && !mainw->record_paused && LIVES_IS_PLAYING && (prefs->rec_opts & REC_EFFECTS)) {
3595               // if we are recording, add this change to our event_list
3596               rec_param_change(inst, pnum);
3597               //if (copyto != -1) rec_param_change(inst, copyto);
3598             }
3599             filter_mutex_unlock(key);
3600           }
3601         } else {
3602           weed_set_double_array(tparam, WEED_LEAF_HOST_DEFAULT, nargs, valuesd);
3603         }
3604 
3605         lives_free(valuesd);
3606 
3607         if (nmins > 4) lives_free(minds);
3608         if (nmaxs > 4) lives_free(maxds);
3609       }
3610 
3611       break;
3612 
3613     default:
3614       // invalid colorspace
3615       return FALSE;
3616     }
3617 
3618   default:
3619     // invalid param type
3620     return FALSE;
3621   }
3622 
3623   return TRUE;
3624 }
3625 
3626 
lives_osc_cb_rte_getparamtype(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)3627 boolean lives_osc_cb_rte_getparamtype(void *context, int arglen, const void *vargs, OSCTimeTag when,
3628                                       NetworkReturnAddressPtr ra) {
3629   weed_plant_t *filter;
3630   weed_plant_t *ptmpl;
3631   int ptype;
3632   int nparams = 0;
3633   int effect_key, mode, pnum;
3634 
3635   const char *retval;
3636 
3637   // TODO - handle compound fx
3638 
3639   if (!lives_osc_check_arguments(arglen, vargs, "iii", FALSE)) {
3640     if (!lives_osc_check_arguments(arglen, vargs, "ii", TRUE)) return lives_osc_notify_failure();
3641     lives_osc_parse_int_argument(vargs, &effect_key);
3642     lives_osc_parse_int_argument(vargs, &pnum);
3643     mode = rte_key_getmode(effect_key);
3644   } else {
3645     lives_osc_check_arguments(arglen, vargs, "iii", TRUE);
3646     lives_osc_parse_int_argument(vargs, &effect_key);
3647     lives_osc_parse_int_argument(vargs, &mode);
3648     lives_osc_parse_int_argument(vargs, &pnum);
3649     if (mode < 1 || mode > rte_key_getmaxmode(effect_key) + 1) return lives_osc_notify_failure();
3650     mode--;
3651   }
3652 
3653   if (effect_key < 1 || effect_key > FX_MAX) return lives_osc_notify_failure();
3654   //g_print("key %d pnum %d",effect_key,pnum);
3655 
3656   filter = rte_keymode_get_filter(effect_key, mode);
3657   if (!filter) return lives_osc_notify_failure();
3658 
3659   nparams = num_in_params(filter, FALSE, TRUE);
3660   if (nparams == 0) return lives_osc_notify_failure();
3661   if (pnum < 0 || pnum >= nparams) return lives_osc_notify_failure();
3662 
3663   ptmpl = weed_filter_in_paramtmpl(filter, pnum, TRUE);
3664   ptype = weed_paramtmpl_get_type(ptmpl);
3665 
3666   switch (ptype) {
3667   case WEED_PARAM_INTEGER:
3668     retval = get_omc_const("LIVES_PARAM_TYPE_INT");
3669     break;
3670   case WEED_PARAM_FLOAT:
3671     retval = get_omc_const("LIVES_PARAM_TYPE_FLOAT");
3672     break;
3673   case WEED_PARAM_TEXT:
3674     retval = get_omc_const("LIVES_PARAM_TYPE_STRING");
3675     break;
3676   case WEED_PARAM_SWITCH:
3677     retval = get_omc_const("LIVES_PARAM_TYPE_BOOL");
3678     break;
3679   case WEED_PARAM_COLOR:
3680     retval = get_omc_const("LIVES_PARAM_TYPE_COLOR");
3681     break;
3682   default:
3683     return lives_osc_notify_failure();
3684   }
3685 
3686   return lives_status_send(retval);
3687 }
3688 
3689 
lives_osc_cb_rte_getoparamtype(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)3690 boolean lives_osc_cb_rte_getoparamtype(void *context, int arglen, const void *vargs, OSCTimeTag when,
3691                                        NetworkReturnAddressPtr ra) {
3692   weed_plant_t *filter;
3693   weed_plant_t **out_ptmpls;
3694   weed_plant_t *ptmpl;
3695   int ptype;
3696   int nparams = 0;
3697   int effect_key, mode, pnum;
3698 
3699   const char *retval;
3700 
3701   if (!lives_osc_check_arguments(arglen, vargs, "iii", FALSE)) {
3702     if (!lives_osc_check_arguments(arglen, vargs, "ii", TRUE)) return lives_osc_notify_failure();
3703     lives_osc_parse_int_argument(vargs, &effect_key);
3704     lives_osc_parse_int_argument(vargs, &pnum);
3705     mode = rte_key_getmode(effect_key);
3706   } else {
3707     lives_osc_check_arguments(arglen, vargs, "iii", TRUE);
3708     lives_osc_parse_int_argument(vargs, &effect_key);
3709     lives_osc_parse_int_argument(vargs, &mode);
3710     lives_osc_parse_int_argument(vargs, &pnum);
3711     if (mode < 1 || mode > rte_key_getmaxmode(effect_key) + 1) return lives_osc_notify_failure();
3712     mode--;
3713   }
3714 
3715   if (effect_key < 1 || effect_key > FX_MAX) return lives_osc_notify_failure();
3716   //g_print("key %d pnum %d",effect_key,pnum);
3717 
3718   filter = rte_keymode_get_filter(effect_key, mode);
3719   if (!filter) return lives_osc_notify_failure();
3720 
3721   if (!weed_plant_has_leaf(filter, WEED_LEAF_OUT_PARAMETER_TEMPLATES)) return lives_osc_notify_failure();
3722   nparams = weed_leaf_num_elements(filter, WEED_LEAF_OUT_PARAMETER_TEMPLATES);
3723   if (pnum < 0 || pnum >= nparams) return lives_osc_notify_failure();
3724 
3725   out_ptmpls = weed_get_plantptr_array(filter, WEED_LEAF_OUT_PARAMETER_TEMPLATES, NULL);
3726 
3727   ptmpl = out_ptmpls[pnum];
3728   ptype = weed_paramtmpl_get_type(ptmpl);
3729   lives_free(out_ptmpls);
3730 
3731   switch (ptype) {
3732   case WEED_PARAM_INTEGER:
3733     retval = get_omc_const("LIVES_PARAM_TYPE_INT");
3734     break;
3735   case WEED_PARAM_FLOAT:
3736     retval = get_omc_const("LIVES_PARAM_TYPE_FLOAT");
3737     break;
3738   case WEED_PARAM_TEXT:
3739     retval = get_omc_const("LIVES_PARAM_TYPE_STRING");
3740     break;
3741   case WEED_PARAM_SWITCH:
3742     retval = get_omc_const("LIVES_PARAM_TYPE_BOOL");
3743     break;
3744   case WEED_PARAM_COLOR:
3745     retval = get_omc_const("LIVES_PARAM_TYPE_COLOR");
3746     break;
3747   default:
3748     return lives_osc_notify_failure();
3749   }
3750 
3751   return lives_status_send(retval);
3752 }
3753 
3754 
lives_osc_cb_rte_getpparamtype(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)3755 boolean lives_osc_cb_rte_getpparamtype(void *context, int arglen, const void *vargs, OSCTimeTag when,
3756                                        NetworkReturnAddressPtr ra) {
3757   // playback plugin params
3758   weed_plant_t *ptmpl, *param;
3759   int ptype;
3760   int pnum;
3761 
3762   const char *retval;
3763 
3764   if (!mainw->vpp || mainw->vpp->num_play_params == 0) return lives_osc_notify_failure();
3765 
3766   if (!lives_osc_check_arguments(arglen, vargs, "i", TRUE)) return lives_osc_notify_failure();
3767 
3768   lives_osc_parse_int_argument(vargs, &pnum);
3769 
3770   if (pnum < 0 || pnum >= mainw->vpp->num_play_params) return lives_osc_notify_failure();
3771 
3772   param = (weed_plant_t *)pp_get_param(mainw->vpp->play_params, pnum);
3773 
3774   ptmpl = weed_param_get_template(param);
3775 
3776   ptype = weed_param_get_type(ptmpl);
3777 
3778   switch (ptype) {
3779   case WEED_PARAM_INTEGER:
3780     retval = get_omc_const("LIVES_PARAM_TYPE_INT");
3781     break;
3782   case WEED_PARAM_FLOAT:
3783     retval = get_omc_const("LIVES_PARAM_TYPE_FLOAT");
3784     break;
3785   case WEED_PARAM_TEXT:
3786     retval = get_omc_const("LIVES_PARAM_TYPE_STRING");
3787     break;
3788   case WEED_PARAM_SWITCH:
3789     retval = get_omc_const("LIVES_PARAM_TYPE_BOOL");
3790     break;
3791   case WEED_PARAM_COLOR:
3792     retval = get_omc_const("LIVES_PARAM_TYPE_COLOR");
3793     break;
3794   default:
3795     return lives_osc_notify_failure();
3796   }
3797 
3798   return lives_status_send(retval);
3799 }
3800 
3801 
lives_osc_cb_rte_getnparamtype(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)3802 boolean lives_osc_cb_rte_getnparamtype(void *context, int arglen, const void *vargs, OSCTimeTag when,
3803                                        NetworkReturnAddressPtr ra) {
3804   weed_plant_t *filter;
3805   weed_plant_t **in_ptmpls;
3806   weed_plant_t *ptmpl;
3807   int ptype;
3808   int effect_key, pnum, i;
3809 
3810   const char *retval;
3811 
3812   if (!lives_osc_check_arguments(arglen, vargs, "ii", TRUE)) return lives_osc_notify_failure();
3813 
3814   lives_osc_parse_int_argument(vargs, &effect_key);
3815   lives_osc_parse_int_argument(vargs, &pnum);
3816 
3817   if (effect_key < 1 || effect_key > FX_MAX) return lives_osc_notify_failure();
3818   //g_print("key %d pnum %d",effect_key,pnum);
3819 
3820   filter = rte_keymode_get_filter(effect_key, rte_key_getmode(effect_key));
3821   if (!filter) return lives_osc_notify_failure();
3822   if (!weed_plant_has_leaf(filter, WEED_LEAF_IN_PARAMETER_TEMPLATES)) return lives_osc_notify_failure();
3823   i = get_nth_simple_param(filter, pnum);
3824   if (i == -1) return lives_osc_notify_failure();
3825   in_ptmpls = weed_get_plantptr_array(filter, WEED_LEAF_IN_PARAMETER_TEMPLATES, NULL);
3826   ptmpl = in_ptmpls[i];
3827 
3828   ptype = weed_param_get_type(ptmpl);
3829   lives_free(in_ptmpls);
3830 
3831   switch (ptype) {
3832   case WEED_PARAM_INTEGER:
3833     retval = get_omc_const("LIVES_PARAM_TYPE_INT");
3834     break;
3835   case WEED_PARAM_FLOAT:
3836     retval = get_omc_const("LIVES_PARAM_TYPE_FLOAT");
3837     break;
3838   default:
3839     return lives_osc_notify_failure();
3840   }
3841 
3842   return lives_status_send(retval);
3843 }
3844 
3845 
lives_osc_cb_rte_getparamcspace(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)3846 boolean lives_osc_cb_rte_getparamcspace(void *context, int arglen, const void *vargs, OSCTimeTag when,
3847                                         NetworkReturnAddressPtr ra) {
3848   weed_plant_t *filter;
3849   weed_plant_t *ptmpl;
3850   int ptype;
3851   int nparams;
3852   int effect_key, mode;
3853   int pnum, cspace;
3854   int stype;
3855 
3856   const char *retval;
3857 
3858   if (!lives_osc_check_arguments(arglen, vargs, "iii", FALSE)) {
3859     if (!lives_osc_check_arguments(arglen, vargs, "ii", TRUE)) return lives_osc_notify_failure();
3860     lives_osc_parse_int_argument(vargs, &effect_key);
3861     lives_osc_parse_int_argument(vargs, &pnum);
3862     mode = rte_key_getmode(effect_key);
3863   } else {
3864     lives_osc_check_arguments(arglen, vargs, "iii", TRUE);
3865     lives_osc_parse_int_argument(vargs, &effect_key);
3866     lives_osc_parse_int_argument(vargs, &mode);
3867     lives_osc_parse_int_argument(vargs, &pnum);
3868     if (mode < 1 || mode > rte_key_getmaxmode(effect_key) + 1) return lives_osc_notify_failure();
3869     mode--;
3870   }
3871 
3872   if (effect_key < 1 || effect_key > FX_MAX) return lives_osc_notify_failure();
3873   //g_print("key %d pnum %d",effect_key,pnum);
3874 
3875   filter = rte_keymode_get_filter(effect_key, mode);
3876   if (!filter) return lives_osc_notify_failure();
3877 
3878   nparams = num_in_params(filter, FALSE, TRUE);
3879   if (nparams == 0) return lives_osc_notify_failure();
3880   if (pnum < 0 || pnum >= nparams) return lives_osc_notify_failure();
3881 
3882   ptmpl = weed_filter_in_paramtmpl(filter, pnum, TRUE);
3883 
3884   ptype = weed_paramtmpl_get_type(ptmpl);
3885 
3886   if (ptype != WEED_PARAM_COLOR) {
3887     return lives_osc_notify_failure();
3888   }
3889   cspace = weed_get_int_value(ptmpl, WEED_LEAF_COLORSPACE, NULL);
3890 
3891   stype = weed_leaf_seed_type(ptmpl, WEED_LEAF_DEFAULT);
3892 
3893   if (cspace == WEED_COLORSPACE_RGB) {
3894     if (stype == WEED_SEED_INT) retval = get_omc_const("LIVES_COLORSPACE_RGB_INT");
3895     else retval = get_omc_const("LIVES_COLORSPACE_RGB_FLOAT");
3896   } else {
3897     if (stype == WEED_SEED_INT) retval = get_omc_const("LIVES_COLORSPACE_RGBA_INT");
3898     else retval = get_omc_const("LIVES_COLORSPACE_RGBA_FLOAT");
3899   }
3900 
3901   return lives_status_send(retval);
3902 }
3903 
3904 
lives_osc_cb_rte_getparamgrp(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)3905 boolean lives_osc_cb_rte_getparamgrp(void *context, int arglen, const void *vargs, OSCTimeTag when,
3906                                      NetworkReturnAddressPtr ra) {
3907   weed_plant_t *filter;
3908   weed_plant_t *ptmpl;
3909   int ptype;
3910   int nparams;
3911   int effect_key, mode, pnum, grp;
3912 
3913   char *retval;
3914 
3915   if (!lives_osc_check_arguments(arglen, vargs, "iii", FALSE)) {
3916     if (!lives_osc_check_arguments(arglen, vargs, "ii", TRUE)) return lives_osc_notify_failure();
3917     lives_osc_parse_int_argument(vargs, &effect_key);
3918     lives_osc_parse_int_argument(vargs, &pnum);
3919     mode = rte_key_getmode(effect_key);
3920   } else {
3921     lives_osc_check_arguments(arglen, vargs, "iii", TRUE);
3922     lives_osc_parse_int_argument(vargs, &effect_key);
3923     lives_osc_parse_int_argument(vargs, &mode);
3924     lives_osc_parse_int_argument(vargs, &pnum);
3925     if (mode < 1 || mode > rte_key_getmaxmode(effect_key) + 1) return lives_osc_notify_failure();
3926     mode--;
3927   }
3928 
3929   if (effect_key < 1 || effect_key > FX_MAX) return lives_osc_notify_failure();
3930   //g_print("key %d pnum %d",effect_key,pnum);
3931 
3932   filter = rte_keymode_get_filter(effect_key, mode);
3933   if (!filter) return lives_osc_notify_failure();
3934 
3935   nparams = num_in_params(filter, FALSE, TRUE);
3936   if (nparams == 0) return lives_osc_notify_failure();
3937   if (pnum < 0 || pnum >= nparams) return lives_osc_notify_failure();
3938 
3939   ptmpl = weed_filter_in_paramtmpl(filter, pnum, TRUE);
3940 
3941   ptype = weed_paramtmpl_get_type(ptmpl);
3942 
3943   if (ptype != WEED_PARAM_SWITCH) {
3944     return lives_osc_notify_failure();
3945   }
3946   grp = weed_get_int_value(ptmpl, WEED_LEAF_GROUP, NULL);
3947 
3948   retval = lives_strdup_printf("%d", grp);
3949 
3950   lives_status_send(retval);
3951   lives_free(retval);
3952 
3953   return TRUE;
3954 }
3955 
3956 
lives_osc_cb_rte_getoparamcspace(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)3957 boolean lives_osc_cb_rte_getoparamcspace(void *context, int arglen, const void *vargs, OSCTimeTag when,
3958     NetworkReturnAddressPtr ra) {
3959   weed_plant_t *filter;
3960   weed_plant_t **out_ptmpls;
3961   weed_plant_t *ptmpl;
3962   int ptype;
3963   int nparams;
3964   int effect_key, mode, pnum, cspace;
3965   int stype;
3966 
3967   const char *retval;
3968 
3969   if (!lives_osc_check_arguments(arglen, vargs, "iii", FALSE)) {
3970     if (!lives_osc_check_arguments(arglen, vargs, "ii", TRUE)) return lives_osc_notify_failure();
3971     lives_osc_parse_int_argument(vargs, &effect_key);
3972     lives_osc_parse_int_argument(vargs, &pnum);
3973     mode = rte_key_getmode(effect_key);
3974   } else {
3975     lives_osc_check_arguments(arglen, vargs, "iii", TRUE);
3976     lives_osc_parse_int_argument(vargs, &effect_key);
3977     lives_osc_parse_int_argument(vargs, &mode);
3978     lives_osc_parse_int_argument(vargs, &pnum);
3979     if (mode < 1 || mode > rte_key_getmaxmode(effect_key) + 1) return lives_osc_notify_failure();
3980     mode--;
3981   }
3982 
3983   if (effect_key < 1 || effect_key > FX_MAX) return lives_osc_notify_failure();
3984   //g_print("key %d pnum %d",effect_key,pnum);
3985 
3986   filter = rte_keymode_get_filter(effect_key, mode);
3987   if (!filter) return lives_osc_notify_failure();
3988 
3989   if (pnum < 0) return lives_osc_notify_failure();
3990 
3991   out_ptmpls = weed_get_plantptr_array_counted(filter, WEED_LEAF_OUT_PARAMETER_TEMPLATES, &nparams);
3992   if (pnum >= nparams) return lives_osc_notify_failure();
3993 
3994   ptmpl = out_ptmpls[pnum];
3995   if (!ptmpl) return lives_osc_notify_failure();
3996 
3997   ptype = weed_paramtmpl_get_type(ptmpl);
3998 
3999   if (ptype != WEED_PARAM_COLOR) {
4000     return lives_osc_notify_failure();
4001   }
4002   cspace = weed_get_int_value(ptmpl, WEED_LEAF_COLORSPACE, NULL);
4003 
4004   stype = weed_leaf_seed_type(ptmpl, WEED_LEAF_DEFAULT);
4005 
4006   if (cspace == WEED_COLORSPACE_RGB) {
4007     if (stype == WEED_SEED_INT) retval = get_omc_const("LIVES_COLORSPACE_RGB_INT");
4008     else retval = get_omc_const("LIVES_COLORSPACE_RGB_FLOAT");
4009   } else {
4010     if (stype == WEED_SEED_INT) retval = get_omc_const("LIVES_COLORSPACE_RGBA_INT");
4011     else retval = get_omc_const("LIVES_COLORSPACE_RGBA_FLOAT");
4012   }
4013 
4014   lives_status_send(retval);
4015   lives_free(out_ptmpls);
4016   return TRUE;
4017 }
4018 
4019 
lives_osc_cb_rte_getpparamcspace(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)4020 boolean lives_osc_cb_rte_getpparamcspace(void *context, int arglen, const void *vargs, OSCTimeTag when,
4021     NetworkReturnAddressPtr ra) {
4022   // playback plugin params
4023   weed_plant_t *ptmpl, *param;
4024   int ptype;
4025   int pnum, cspace;
4026   int stype;
4027 
4028   const char *retval;
4029 
4030   if (!mainw->vpp || mainw->vpp->num_play_params == 0) return lives_osc_notify_failure();
4031 
4032   if (!lives_osc_check_arguments(arglen, vargs, "i", TRUE)) return lives_osc_notify_failure();
4033   lives_osc_parse_int_argument(vargs, &pnum);
4034 
4035   if (pnum < 0 || pnum >= mainw->vpp->num_play_params) return lives_osc_notify_failure();
4036 
4037   param = (weed_plant_t *)pp_get_param(mainw->vpp->play_params, pnum);
4038 
4039   ptype = weed_param_get_type(param);
4040 
4041   if (ptype != WEED_PARAM_COLOR) {
4042     return lives_osc_notify_failure();
4043   }
4044   ptmpl = weed_param_get_template(param);
4045   cspace = weed_get_int_value(ptmpl, WEED_LEAF_COLORSPACE, NULL);
4046   stype = weed_leaf_seed_type(ptmpl, WEED_LEAF_DEFAULT);
4047 
4048   if (cspace == WEED_COLORSPACE_RGB) {
4049     if (stype == WEED_SEED_INT) retval = get_omc_const("LIVES_COLORSPACE_RGB_INT");
4050     else retval = get_omc_const("LIVES_COLORSPACE_RGB_FLOAT");
4051   } else {
4052     if (stype == WEED_SEED_INT) retval = get_omc_const("LIVES_COLORSPACE_RGBA_INT");
4053     else retval = get_omc_const("LIVES_COLORSPACE_RGBA_FLOAT");
4054   }
4055 
4056   return lives_status_send(retval);
4057 }
4058 
4059 
lives_osc_cb_rte_getparamflags(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)4060 boolean lives_osc_cb_rte_getparamflags(void *context, int arglen, const void *vargs, OSCTimeTag when,
4061                                        NetworkReturnAddressPtr ra) {
4062   weed_plant_t *filter;
4063   weed_plant_t *ptmpl;
4064   int nparams;
4065   int effect_key;
4066   int mode;
4067   int pnum, flags = 0;
4068 
4069   char *retval;
4070 
4071   if (!lives_osc_check_arguments(arglen, vargs, "iii", FALSE)) {
4072     if (!lives_osc_check_arguments(arglen, vargs, "ii", TRUE)) return lives_osc_notify_failure();
4073     lives_osc_parse_int_argument(vargs, &effect_key);
4074     lives_osc_parse_int_argument(vargs, &pnum);
4075     mode = rte_key_getmode(effect_key);
4076   } else {
4077     lives_osc_check_arguments(arglen, vargs, "iii", TRUE);
4078     lives_osc_parse_int_argument(vargs, &effect_key);
4079     lives_osc_parse_int_argument(vargs, &mode);
4080     lives_osc_parse_int_argument(vargs, &pnum);
4081     if (mode < 1 || mode > rte_key_getmaxmode(effect_key) + 1) return lives_osc_notify_failure();
4082     mode--;
4083   }
4084 
4085   if (effect_key < 1 || effect_key > FX_MAX) return lives_osc_notify_failure();
4086   //g_print("key %d pnum %d",effect_key,pnum);
4087 
4088   filter = rte_keymode_get_filter(effect_key, mode);
4089   if (!filter) return lives_osc_notify_failure();
4090 
4091   nparams = num_in_params(filter, FALSE, TRUE);
4092   if (nparams == 0) return lives_osc_notify_failure();
4093   if (pnum < 0 || pnum >= nparams) return lives_osc_notify_failure();
4094 
4095   ptmpl = weed_filter_in_paramtmpl(filter, pnum, TRUE);
4096 
4097   if (weed_plant_has_leaf(ptmpl, WEED_LEAF_FLAGS))
4098     flags = weed_get_int_value(ptmpl, WEED_LEAF_FLAGS, NULL);
4099 
4100   retval = lives_strdup_printf("%d", flags);
4101   lives_status_send(retval);
4102   lives_free(retval);
4103   return TRUE;
4104 }
4105 
4106 
lives_osc_cb_rte_getpparamflags(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)4107 boolean lives_osc_cb_rte_getpparamflags(void *context, int arglen, const void *vargs, OSCTimeTag when,
4108                                         NetworkReturnAddressPtr ra) {
4109   weed_plant_t *ptmpl, *param;
4110   int pnum, flags = 0;
4111 
4112   char *retval;
4113 
4114   if (!mainw->ext_playback || !mainw->vpp->play_params) return lives_osc_notify_failure();
4115 
4116   if (!lives_osc_check_arguments(arglen, vargs, "i", TRUE)) return lives_osc_notify_failure();
4117 
4118   lives_osc_parse_int_argument(vargs, &pnum);
4119 
4120   if (pnum < 0 || pnum >= mainw->vpp->num_play_params) return lives_osc_notify_failure();
4121 
4122   param = (weed_plant_t *)pp_get_param(mainw->vpp->play_params, pnum);
4123 
4124   ptmpl = weed_get_plantptr_value(param, WEED_LEAF_TEMPLATE, NULL);
4125 
4126   if (weed_plant_has_leaf(ptmpl, WEED_LEAF_FLAGS))
4127     flags = weed_get_int_value(ptmpl, WEED_LEAF_FLAGS, NULL);
4128 
4129   retval = lives_strdup_printf("%d", flags);
4130   lives_status_send(retval);
4131   lives_free(retval);
4132   return TRUE;
4133 }
4134 
4135 
lives_osc_cb_rte_getparamname(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)4136 boolean lives_osc_cb_rte_getparamname(void *context, int arglen, const void *vargs, OSCTimeTag when,
4137                                       NetworkReturnAddressPtr ra) {
4138   weed_plant_t *filter;
4139   weed_plant_t *ptmpl;
4140   int nparams;
4141   int effect_key;
4142   int mode;
4143   int pnum;
4144 
4145   char *retval;
4146 
4147   if (!lives_osc_check_arguments(arglen, vargs, "iii", FALSE)) {
4148     if (!lives_osc_check_arguments(arglen, vargs, "ii", TRUE)) return lives_osc_notify_failure();
4149     lives_osc_parse_int_argument(vargs, &effect_key);
4150     lives_osc_parse_int_argument(vargs, &pnum);
4151     mode = rte_key_getmode(effect_key);
4152   } else {
4153     lives_osc_check_arguments(arglen, vargs, "iii", TRUE);
4154     lives_osc_parse_int_argument(vargs, &effect_key);
4155     lives_osc_parse_int_argument(vargs, &mode);
4156     lives_osc_parse_int_argument(vargs, &pnum);
4157     if (mode < 1 || mode > rte_key_getmaxmode(effect_key) + 1) return lives_osc_notify_failure();
4158     mode--;
4159   }
4160 
4161   if (effect_key < 1 || effect_key > FX_MAX) return lives_osc_notify_failure();
4162   //g_print("key %d pnum %d",effect_key,pnum);
4163 
4164   filter = rte_keymode_get_filter(effect_key, mode);
4165   if (!filter) return lives_osc_notify_failure();
4166 
4167   nparams = num_in_params(filter, FALSE, TRUE);
4168   if (nparams == 0) return lives_osc_notify_failure();
4169   if (pnum < 0 || pnum >= nparams) return lives_osc_notify_failure();
4170 
4171   ptmpl = weed_filter_in_paramtmpl(filter, pnum, TRUE);
4172 
4173   retval = weed_get_string_value(ptmpl, WEED_LEAF_NAME, NULL);
4174 
4175   lives_status_send(retval);
4176 
4177   lives_free(retval);
4178   return TRUE;
4179 }
4180 
4181 
lives_osc_cb_pgui_countchoices(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)4182 boolean lives_osc_cb_pgui_countchoices(void *context, int arglen, const void *vargs, OSCTimeTag when,
4183                                        NetworkReturnAddressPtr ra) {
4184   // TODO: for a running instance, the value may differ from the filter_class
4185   weed_plant_t *filter;
4186   weed_plant_t *ptmpl;
4187 
4188   int nparams;
4189   int effect_key;
4190   int mode;
4191   int pnum;
4192   int val = 0;
4193 
4194   char *retval;
4195 
4196   if (!lives_osc_check_arguments(arglen, vargs, "iii", FALSE)) {
4197     if (!lives_osc_check_arguments(arglen, vargs, "ii", TRUE)) return lives_osc_notify_failure();
4198     lives_osc_parse_int_argument(vargs, &effect_key);
4199     lives_osc_parse_int_argument(vargs, &pnum);
4200     mode = rte_key_getmode(effect_key);
4201   } else {
4202     lives_osc_check_arguments(arglen, vargs, "iii", TRUE);
4203     lives_osc_parse_int_argument(vargs, &effect_key);
4204     lives_osc_parse_int_argument(vargs, &mode);
4205     lives_osc_parse_int_argument(vargs, &pnum);
4206     if (mode < 1 || mode > rte_key_getmaxmode(effect_key) + 1) return lives_osc_notify_failure();
4207     mode--;
4208   }
4209 
4210   if (effect_key < 1 || effect_key > FX_MAX) return lives_osc_notify_failure();
4211   //g_print("key %d pnum %d",effect_key,pnum);
4212 
4213   filter = rte_keymode_get_filter(effect_key, mode);
4214   if (!filter) return lives_osc_notify_failure();
4215 
4216   nparams = num_in_params(filter, FALSE, TRUE);
4217   if (nparams == 0) return lives_osc_notify_failure();
4218   if (pnum < 0 || pnum >= nparams) return lives_osc_notify_failure();
4219 
4220   ptmpl = weed_filter_in_paramtmpl(filter, pnum, TRUE);
4221 
4222   if (weed_plant_has_leaf(ptmpl, WEED_LEAF_CHOICES))
4223     val = weed_leaf_num_elements(ptmpl, WEED_LEAF_CHOICES);
4224 
4225   retval = lives_strdup_printf("%d", val);
4226 
4227   lives_status_send(retval);
4228 
4229   lives_free(retval);
4230   return TRUE;
4231 }
4232 
4233 
lives_osc_cb_pgui_getchoice(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)4234 boolean lives_osc_cb_pgui_getchoice(void *context, int arglen, const void *vargs, OSCTimeTag when,
4235                                     NetworkReturnAddressPtr ra) {
4236   weed_plant_t *filter;
4237   weed_plant_t *ptmpl;
4238 
4239   boolean ret = FALSE;
4240 
4241   int nparams;
4242   int effect_key;
4243   int mode;
4244   int pnum;
4245   int cc;
4246 
4247   char *retval = lives_strdup("");
4248 
4249   if (!lives_osc_check_arguments(arglen, vargs, "iiii", FALSE)) {
4250     if (!lives_osc_check_arguments(arglen, vargs, "iii", TRUE)) return lives_osc_notify_failure();
4251     lives_osc_parse_int_argument(vargs, &effect_key);
4252     lives_osc_parse_int_argument(vargs, &pnum);
4253     lives_osc_parse_int_argument(vargs, &cc);
4254     mode = rte_key_getmode(effect_key);
4255   } else {
4256     lives_osc_check_arguments(arglen, vargs, "iiii", TRUE);
4257     lives_osc_parse_int_argument(vargs, &effect_key);
4258     lives_osc_parse_int_argument(vargs, &mode);
4259     lives_osc_parse_int_argument(vargs, &pnum);
4260     lives_osc_parse_int_argument(vargs, &cc);
4261     if (mode < 1 || mode > rte_key_getmaxmode(effect_key) + 1) return lives_osc_notify_failure();
4262     mode--;
4263   }
4264 
4265   if (effect_key < 1 || effect_key > FX_MAX) return lives_osc_notify_failure();
4266   //g_print("key %d pnum %d",effect_key,pnum);
4267 
4268   filter = rte_keymode_get_filter(effect_key, mode);
4269   if (!filter) return lives_osc_notify_failure();
4270 
4271   nparams = num_in_params(filter, FALSE, TRUE);
4272   if (nparams == 0) return lives_osc_notify_failure();
4273   if (pnum < 0 || pnum >= nparams) return lives_osc_notify_failure();
4274 
4275   ptmpl = weed_filter_in_paramtmpl(filter, pnum, TRUE);
4276 
4277   if (weed_plant_has_leaf(ptmpl, WEED_LEAF_CHOICES)) {
4278     int nc = weed_leaf_num_elements(ptmpl, WEED_LEAF_CHOICES);
4279     if (cc < nc) {
4280       char **choices = weed_get_string_array(ptmpl, WEED_LEAF_CHOICES, NULL);
4281       register int i;
4282       for (i = 0; i < nc; i++) {
4283         if (i == cc) {
4284           lives_free(retval);
4285           retval = choices[i];
4286           ret = TRUE;
4287         } else lives_free(choices[i]);
4288       }
4289       lives_free(choices);
4290     }
4291   }
4292 
4293   lives_status_send(retval);
4294   lives_free(retval);
4295 
4296   return ret;
4297 }
4298 
4299 
lives_osc_cb_rte_getoparamname(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)4300 boolean lives_osc_cb_rte_getoparamname(void *context, int arglen, const void *vargs, OSCTimeTag when,
4301                                        NetworkReturnAddressPtr ra) {
4302   weed_plant_t *filter;
4303   weed_plant_t **out_ptmpls;
4304   weed_plant_t *ptmpl;
4305 
4306   int nparams;
4307   int effect_key;
4308   int mode;
4309   int pnum;
4310 
4311   char *retval;
4312 
4313   if (!lives_osc_check_arguments(arglen, vargs, "iii", FALSE)) {
4314     if (!lives_osc_check_arguments(arglen, vargs, "ii", TRUE)) return lives_osc_notify_failure();
4315     lives_osc_parse_int_argument(vargs, &effect_key);
4316     lives_osc_parse_int_argument(vargs, &pnum);
4317     mode = rte_key_getmode(effect_key);
4318   } else {
4319     lives_osc_check_arguments(arglen, vargs, "iii", TRUE);
4320     lives_osc_parse_int_argument(vargs, &effect_key);
4321     lives_osc_parse_int_argument(vargs, &mode);
4322     lives_osc_parse_int_argument(vargs, &pnum);
4323     if (mode < 1 || mode > rte_key_getmaxmode(effect_key) + 1) return lives_osc_notify_failure();
4324     mode--;
4325   }
4326 
4327   if (effect_key < 1 || effect_key > FX_MAX) return lives_osc_notify_failure();
4328   //g_print("key %d pnum %d",effect_key,pnum);
4329 
4330   filter = rte_keymode_get_filter(effect_key, mode);
4331   if (!filter) return lives_osc_notify_failure();
4332   if (!weed_plant_has_leaf(filter, WEED_LEAF_OUT_PARAMETER_TEMPLATES)) return lives_osc_notify_failure();
4333 
4334   nparams = weed_leaf_num_elements(filter, WEED_LEAF_OUT_PARAMETER_TEMPLATES);
4335   if (pnum < 0 || pnum >= nparams) return lives_osc_notify_failure();
4336 
4337   out_ptmpls = weed_get_plantptr_array(filter, WEED_LEAF_OUT_PARAMETER_TEMPLATES, NULL);
4338   ptmpl = out_ptmpls[pnum];
4339 
4340   retval = weed_get_string_value(ptmpl, WEED_LEAF_NAME, NULL);
4341 
4342   lives_status_send(retval);
4343 
4344   lives_free(retval);
4345   lives_free(out_ptmpls);
4346   return TRUE;
4347 }
4348 
4349 
lives_osc_cb_rte_getpparamname(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)4350 boolean lives_osc_cb_rte_getpparamname(void *context, int arglen, const void *vargs, OSCTimeTag when,
4351                                        NetworkReturnAddressPtr ra) {
4352   weed_plant_t *ptmpl, *param;
4353   int pnum;
4354 
4355   char *retval;
4356 
4357   if (!mainw->ext_playback || !mainw->vpp->play_params) return lives_osc_notify_failure();
4358 
4359   if (!lives_osc_check_arguments(arglen, vargs, "i", TRUE)) return lives_osc_notify_failure();
4360 
4361   lives_osc_parse_int_argument(vargs, &pnum);
4362 
4363   if (pnum < 0 || pnum >= mainw->vpp->num_play_params) return lives_osc_notify_failure();
4364 
4365   param = (weed_plant_t *)pp_get_param(mainw->vpp->play_params, pnum);
4366 
4367   ptmpl = weed_get_plantptr_value(param, WEED_LEAF_TEMPLATE, NULL);
4368 
4369   retval = weed_get_string_value(ptmpl, WEED_LEAF_NAME, NULL);
4370 
4371   lives_status_send(retval);
4372 
4373   lives_free(retval);
4374   return TRUE;
4375 }
4376 
4377 
lives_osc_cb_rte_getnparamname(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)4378 boolean lives_osc_cb_rte_getnparamname(void *context, int arglen, const void *vargs, OSCTimeTag when,
4379                                        NetworkReturnAddressPtr ra) {
4380   weed_plant_t *filter;
4381   weed_plant_t **in_ptmpls;
4382   weed_plant_t *ptmpl;
4383   int effect_key;
4384   int pnum, i;
4385 
4386   char *retval;
4387 
4388   if (!lives_osc_check_arguments(arglen, vargs, "ii", TRUE)) return lives_osc_notify_failure();
4389 
4390   lives_osc_parse_int_argument(vargs, &effect_key);
4391   lives_osc_parse_int_argument(vargs, &pnum);
4392 
4393   if (effect_key < 1 || effect_key > FX_MAX) return lives_osc_notify_failure();
4394   //g_print("key %d pnum %d",effect_key,pnum);
4395 
4396   filter = rte_keymode_get_filter(effect_key, rte_key_getmode(effect_key));
4397   if (!filter) return lives_osc_notify_failure();
4398   if (!weed_plant_has_leaf(filter, WEED_LEAF_IN_PARAMETER_TEMPLATES)) return lives_osc_notify_failure();
4399 
4400   i = get_nth_simple_param(filter, pnum);
4401   if (i == -1) return lives_osc_notify_failure();
4402 
4403   in_ptmpls = weed_get_plantptr_array(filter, WEED_LEAF_IN_PARAMETER_TEMPLATES, NULL);
4404   ptmpl = in_ptmpls[i];
4405 
4406   retval = weed_get_string_value(ptmpl, WEED_LEAF_NAME, NULL);
4407 
4408   lives_status_send(retval);
4409 
4410   lives_free(in_ptmpls);
4411   lives_free(retval);
4412   return TRUE;
4413 }
4414 
4415 
lives_osc_cb_rte_setparam(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)4416 boolean lives_osc_cb_rte_setparam(void *context, int arglen, const void *vargs, OSCTimeTag when,
4417                                   NetworkReturnAddressPtr ra) {
4418   weed_plant_t *inst, *filter;
4419   weed_plant_t *tparam;
4420   int nparams;
4421 
4422   int effect_key;
4423   int pnum, nargs;
4424 
4425   if (!lives_osc_check_arguments(arglen, vargs, "ii", TRUE)) return lives_osc_notify_failure();
4426 
4427   nargs = lives_osc_get_num_arguments(vargs);
4428   if (nargs < 3) return lives_osc_notify_failure();
4429 
4430   osc_header_len = pad4(nargs + 1); // add comma
4431 
4432   lives_osc_parse_int_argument(vargs, &effect_key);
4433   lives_osc_parse_int_argument(vargs, &pnum);
4434 
4435   if (effect_key < 1 || effect_key > FX_MAX) return lives_osc_notify_failure();
4436   //g_print("key %d pnum %d",effect_key,pnum);
4437 
4438   filter = rte_keymode_get_filter(effect_key, rte_key_getmode(effect_key));
4439   inst = rte_keymode_get_instance(effect_key, rte_key_getmode(effect_key));
4440 
4441   if (!inst) return lives_osc_notify_failure();
4442 
4443   nparams = num_in_params(filter, FALSE, TRUE);
4444   if (pnum < 0 || pnum >= nparams) {
4445     weed_instance_unref(inst);
4446     return lives_osc_notify_failure();
4447   }
4448 
4449   tparam = weed_inst_in_param(inst, pnum, FALSE, TRUE);
4450 
4451   if (!mainw->osc_block) {
4452     if (!setfx(inst, tparam, pnum, nargs - 2, vargs, 3)) {
4453       weed_instance_unref(inst);
4454       return lives_osc_notify_failure();
4455     }
4456   } else {
4457     weed_instance_unref(inst);
4458     return lives_osc_notify_failure();
4459   }
4460 
4461   weed_instance_unref(inst);
4462 
4463   if (fx_dialog[1]) {
4464     lives_rfx_t *rfx = fx_dialog[1]->rfx;
4465     if (!rfx->is_template) {
4466       int keyw = fx_dialog[1]->key;
4467       int modew = fx_dialog[1]->mode;
4468       if (keyw == effect_key && modew == rte_key_getmode(effect_key))
4469         mainw->vrfx_update = rfx;
4470     }
4471   }
4472 
4473   if (mainw->ce_thumbs) ce_thumbs_register_rfx_change(effect_key, rte_key_getmode(effect_key));
4474 
4475   return lives_osc_notify_success(NULL);
4476 }
4477 
4478 
lives_osc_cb_rte_setparamdef(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)4479 boolean lives_osc_cb_rte_setparamdef(void *context, int arglen, const void *vargs, OSCTimeTag when,
4480                                      NetworkReturnAddressPtr ra) {
4481   weed_plant_t *filter;
4482   weed_plant_t *tptmpl;
4483   int nparams;
4484 
4485   int effect_key;
4486   int mode;
4487   int pnum, nargs, skip;
4488 
4489   nargs = lives_osc_get_num_arguments(vargs);
4490 
4491   if (!lives_osc_check_arguments(arglen, vargs, "iii", FALSE)) {
4492     if (!lives_osc_check_arguments(arglen, vargs, "ii", TRUE)) return lives_osc_notify_failure();
4493     if (nargs < 3) return lives_osc_notify_failure();
4494     osc_header_len = pad4(nargs + 1); // add comma
4495     lives_osc_parse_int_argument(vargs, &effect_key);
4496     lives_osc_parse_int_argument(vargs, &pnum);
4497     mode = rte_key_getmode(effect_key);
4498     skip = 3;
4499   } else {
4500     if (nargs < 4) return lives_osc_notify_failure();
4501     lives_osc_check_arguments(arglen, vargs, "iii", TRUE);
4502     osc_header_len = pad4(nargs + 1); // add comma
4503     lives_osc_parse_int_argument(vargs, &effect_key);
4504     lives_osc_parse_int_argument(vargs, &mode);
4505     if (mode < 1 || mode > rte_key_getmaxmode(effect_key) + 1) return lives_osc_notify_failure();
4506     lives_osc_parse_int_argument(vargs, &pnum);
4507     skip = 4;
4508   }
4509 
4510   if (effect_key < 1 || effect_key > FX_MAX) return lives_osc_notify_failure();
4511   //g_print("key %d pnum %d",effect_key,pnum);
4512 
4513   filter = rte_keymode_get_filter(effect_key, mode);
4514 
4515   if (!filter) return lives_osc_notify_failure();
4516 
4517   nparams = num_in_params(filter, FALSE, TRUE);
4518   if (nparams == 0) return lives_osc_notify_failure();
4519   if (pnum < 0 || pnum >= nparams) return lives_osc_notify_failure();
4520 
4521   tptmpl = weed_filter_in_paramtmpl(filter, pnum, TRUE);
4522 
4523   if (!setfx(filter, tptmpl, pnum, nargs - 2, vargs, skip)) {
4524     return lives_osc_notify_failure();
4525   }
4526 
4527   return lives_osc_notify_success(NULL);
4528 }
4529 
4530 
lives_osc_cb_rte_setpparam(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)4531 boolean lives_osc_cb_rte_setpparam(void *context, int arglen, const void *vargs, OSCTimeTag when,
4532                                    NetworkReturnAddressPtr ra) {
4533   // set playback plugin param
4534   weed_plant_t *param;
4535   int pnum, nargs;
4536 
4537   if (!mainw->ext_playback || !mainw->vpp->play_params) return lives_osc_notify_failure();
4538 
4539   if (!lives_osc_check_arguments(arglen, vargs, "i", TRUE)) return lives_osc_notify_failure();
4540 
4541   nargs = lives_osc_get_num_arguments(vargs);
4542   if (nargs < 2) return lives_osc_notify_failure();
4543 
4544   osc_header_len = pad4(nargs + 1); // add comma
4545 
4546   lives_osc_parse_int_argument(vargs, &pnum);
4547 
4548   if (pnum < 0 || pnum >= mainw->vpp->num_play_params) return lives_osc_notify_failure();
4549 
4550   param = (weed_plant_t *)pp_get_param(mainw->vpp->play_params, pnum);
4551 
4552   if (!mainw->osc_block) {
4553     if (!setfx(NULL, param, pnum, nargs - 1, vargs, 2)) return lives_osc_notify_failure();
4554   } else return lives_osc_notify_failure();
4555 
4556   return lives_osc_notify_success(NULL);
4557 }
4558 
4559 
lives_osc_cb_rte_setnparam(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)4560 boolean lives_osc_cb_rte_setnparam(void *context, int arglen, const void *vargs, OSCTimeTag when,
4561                                    NetworkReturnAddressPtr ra) {
4562   int effect_key;
4563   int pnum, i, nargs;
4564   int error;
4565 
4566   // pick pnum which is numeric single valued, non-reinit
4567   // i.e. simple numeric parameter
4568 
4569   weed_plant_t *inst, *param;
4570   weed_plant_t **in_params;
4571 
4572   if (!lives_osc_check_arguments(arglen, vargs, "ii", TRUE)) return lives_osc_notify_failure();
4573 
4574   nargs = lives_osc_get_num_arguments(vargs);
4575   if (nargs < 3) return lives_osc_notify_failure();
4576 
4577   osc_header_len = pad4(nargs + 1); // add comma
4578 
4579   lives_osc_parse_int_argument(vargs, &effect_key);
4580   lives_osc_parse_int_argument(vargs, &pnum);
4581 
4582   if (effect_key < 1 || effect_key > FX_MAX) return lives_osc_notify_failure();
4583   //g_print("key %d pnum %d",effect_key,pnum);
4584 
4585   inst = rte_keymode_get_instance(effect_key, rte_key_getmode(effect_key));
4586   if (!inst) return lives_osc_notify_failure();
4587 
4588   in_params = weed_get_plantptr_array(inst, WEED_LEAF_IN_PARAMETERS, &error);
4589 
4590   i = get_nth_simple_param(inst, pnum);
4591 
4592   param = in_params[i];
4593 
4594   if (i != -1 && !mainw->osc_block) {
4595     if (!setfx(inst, param, pnum, nargs - 2, vargs, 3)) {
4596       weed_instance_unref(inst);
4597       return lives_osc_notify_failure();
4598     }
4599   } else {
4600     weed_instance_unref(inst);
4601     return lives_osc_notify_failure();
4602   }
4603   weed_instance_unref(inst);
4604   return lives_osc_notify_success(NULL);
4605 }
4606 
4607 
lives_osc_cb_rte_setnparamdef(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)4608 boolean lives_osc_cb_rte_setnparamdef(void *context, int arglen, const void *vargs, OSCTimeTag when,
4609                                       NetworkReturnAddressPtr ra) {
4610   weed_plant_t *filter;
4611   weed_plant_t *tptmpl;
4612   int nparams;
4613 
4614   int effect_key;
4615   int mode;
4616   int pnum, nargs, skip;
4617 
4618   nargs = lives_osc_get_num_arguments(vargs);
4619 
4620   if (!lives_osc_check_arguments(arglen, vargs, "iii", FALSE)) {
4621     if (!lives_osc_check_arguments(arglen, vargs, "ii", TRUE)) return lives_osc_notify_failure();
4622     if (nargs < 3) return lives_osc_notify_failure();
4623     osc_header_len = pad4(nargs + 1); // add comma
4624     lives_osc_parse_int_argument(vargs, &effect_key);
4625     lives_osc_parse_int_argument(vargs, &pnum);
4626     mode = rte_key_getmode(effect_key);
4627     skip = 3;
4628   } else {
4629     if (nargs < 4) return lives_osc_notify_failure();
4630     lives_osc_check_arguments(arglen, vargs, "iii", TRUE);
4631     osc_header_len = pad4(nargs + 1); // add comma
4632     lives_osc_parse_int_argument(vargs, &effect_key);
4633     lives_osc_parse_int_argument(vargs, &mode);
4634     if (mode < 1 || mode > rte_key_getmaxmode(effect_key) + 1) return lives_osc_notify_failure();
4635     lives_osc_parse_int_argument(vargs, &pnum);
4636     skip = 4;
4637   }
4638 
4639   if (effect_key < 1 || effect_key > FX_MAX) return lives_osc_notify_failure();
4640   //g_print("key %d pnum %d",effect_key,pnum);
4641 
4642   filter = rte_keymode_get_filter(effect_key, mode);
4643 
4644   if (!filter) return lives_osc_notify_failure();
4645 
4646   nparams = num_in_params(filter, FALSE, TRUE);
4647   if (nparams == 0) return lives_osc_notify_failure();
4648   if (pnum < 0 || pnum >= nparams) return lives_osc_notify_failure();
4649 
4650   tptmpl = weed_filter_in_paramtmpl(filter, pnum, TRUE);
4651 
4652   if (!setfx(filter, tptmpl, pnum, nargs - 2, vargs, skip)) {
4653     return lives_osc_notify_failure();
4654   }
4655 
4656   return lives_osc_notify_success(NULL);
4657 }
4658 
4659 
lives_osc_cb_rte_paramcount(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)4660 boolean lives_osc_cb_rte_paramcount(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
4661   int effect_key, mode;
4662 
4663   int count = 0;
4664   weed_plant_t *filter;
4665   char *msg;
4666 
4667   if (!lives_osc_check_arguments(arglen, vargs, "ii", FALSE)) {
4668     if (!lives_osc_check_arguments(arglen, vargs, "i", TRUE)) return lives_osc_notify_failure();
4669     lives_osc_parse_int_argument(vargs, &effect_key);
4670     mode = rte_key_getmode(effect_key);
4671   } else {
4672     lives_osc_check_arguments(arglen, vargs, "ii", TRUE);
4673     lives_osc_parse_int_argument(vargs, &effect_key);
4674     lives_osc_parse_int_argument(vargs, &mode);
4675     if (mode < 1 || mode > rte_key_getmaxmode(effect_key) + 1) return lives_osc_notify_failure();
4676     mode--;
4677   }
4678 
4679   if (effect_key < 1 || effect_key > FX_MAX) return lives_osc_notify_failure();
4680   //g_print("key %d pnum %d",effect_key,pnum);
4681 
4682   filter = rte_keymode_get_filter(effect_key, mode);
4683   if (!filter) return lives_osc_notify_failure();
4684 
4685   count = num_in_params(filter, FALSE, TRUE);
4686 
4687   msg = lives_strdup_printf("%d", count);
4688   lives_status_send(msg);
4689   lives_free(msg);
4690   return TRUE;
4691 }
4692 
4693 
lives_osc_cb_rte_oparamcount(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)4694 boolean lives_osc_cb_rte_oparamcount(void *context, int arglen, const void *vargs, OSCTimeTag when,
4695                                      NetworkReturnAddressPtr ra) {
4696   int effect_key, mode;
4697   int count = 0;
4698   weed_plant_t *filter;
4699   char *msg;
4700 
4701   if (!lives_osc_check_arguments(arglen, vargs, "ii", FALSE)) {
4702     if (!lives_osc_check_arguments(arglen, vargs, "i", TRUE)) return lives_osc_notify_failure();
4703     lives_osc_parse_int_argument(vargs, &effect_key);
4704     mode = rte_key_getmode(effect_key);
4705   } else {
4706     lives_osc_check_arguments(arglen, vargs, "ii", TRUE);
4707     lives_osc_parse_int_argument(vargs, &effect_key);
4708     lives_osc_parse_int_argument(vargs, &mode);
4709     if (mode < 1 || mode > rte_key_getmaxmode(effect_key) + 1) return lives_osc_notify_failure();
4710     mode--;
4711   }
4712 
4713   if (effect_key < 1 || effect_key > FX_MAX) return lives_osc_notify_failure();
4714   //g_print("key %d pnum %d",effect_key,pnum);
4715 
4716   filter = rte_keymode_get_filter(effect_key, mode);
4717   if (!filter) return lives_osc_notify_failure();
4718 
4719   if (weed_plant_has_leaf(filter, WEED_LEAF_OUT_PARAMETER_TEMPLATES)) {
4720     count = weed_leaf_num_elements(filter, WEED_LEAF_OUT_PARAMETER_TEMPLATES);
4721   }
4722 
4723   msg = lives_strdup_printf("%d", count);
4724   lives_status_send(msg);
4725   lives_free(msg);
4726   return TRUE;
4727 }
4728 
4729 
lives_osc_cb_rte_getinpal(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)4730 boolean lives_osc_cb_rte_getinpal(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
4731   weed_plant_t **ctmpls, *template;
4732   weed_plant_t *filter, *inst, *ctmpl, *chan = NULL;
4733   int filter_flags;
4734   int effect_key, mode, cnum, count;
4735   char *msg;
4736 
4737   if (!lives_osc_check_arguments(arglen, vargs, "iii", FALSE)) {
4738     if (!lives_osc_check_arguments(arglen, vargs, "ii", TRUE)) return lives_osc_notify_failure();
4739     lives_osc_parse_int_argument(vargs, &effect_key);
4740     lives_osc_parse_int_argument(vargs, &cnum);
4741     mode = rte_key_getmode(effect_key);
4742   } else {
4743     lives_osc_check_arguments(arglen, vargs, "iii", TRUE);
4744     lives_osc_parse_int_argument(vargs, &effect_key);
4745     lives_osc_parse_int_argument(vargs, &mode);
4746     if (mode < 1 || mode > rte_key_getmaxmode(effect_key) + 1) return lives_osc_notify_failure();
4747     lives_osc_parse_int_argument(vargs, &cnum);
4748     mode--;
4749   }
4750 
4751   if (effect_key < 1 || effect_key > FX_MAX) return lives_osc_notify_failure();
4752   //g_print("key %d pnum %d",effect_key,pnum);
4753 
4754   inst = rte_keymode_get_instance(effect_key, mode);
4755   filter = rte_keymode_get_filter(effect_key, mode);
4756   if (!filter) return lives_osc_notify_failure();
4757 
4758   if (inst) {
4759     chan = get_enabled_channel(inst, cnum, TRUE);
4760     ctmpl = weed_get_plantptr_value(chan, WEED_LEAF_TEMPLATE, NULL);
4761   } else {
4762     if (!weed_plant_has_leaf(filter, WEED_LEAF_IN_CHANNEL_TEMPLATES)) return lives_osc_notify_failure();
4763     count = weed_leaf_num_elements(filter, WEED_LEAF_IN_CHANNEL_TEMPLATES);
4764     if (cnum >= count) return lives_osc_notify_failure();
4765     ctmpls = weed_get_plantptr_array(filter, WEED_LEAF_IN_CHANNEL_TEMPLATES, NULL);
4766     ctmpl = ctmpls[cnum];
4767     lives_free(ctmpls);
4768   }
4769 
4770   if (weed_plant_has_leaf(ctmpl, WEED_LEAF_IS_AUDIO)) {
4771     weed_instance_unref(inst);
4772     msg = lives_strdup_printf("%d", WEED_PALETTE_END);
4773     lives_status_send(msg);
4774     lives_free(msg);
4775     return TRUE;
4776   }
4777 
4778   if (inst) {
4779     weed_instance_unref(inst);
4780     msg = lives_strdup_printf("%d", weed_get_int_value(chan, WEED_LEAF_CURRENT_PALETTE, NULL));
4781     lives_status_send(msg);
4782     lives_free(msg);
4783     return TRUE;
4784   }
4785 
4786   filter_flags = weed_get_int_value(filter, WEED_LEAF_FLAGS, NULL);
4787   if ((filter_flags & WEED_FILTER_PALETTES_MAY_VARY) && weed_plant_has_leaf(ctmpl, WEED_LEAF_PALETTE_LIST)) {
4788     template = ctmpl;;
4789   } else template = filter;
4790   msg = lives_osc_format_result(template, WEED_LEAF_PALETTE_LIST, 0, -1);
4791   lives_status_send(msg);
4792   lives_free(msg);
4793   return TRUE;
4794 }
4795 
4796 
lives_osc_cb_rte_getoutpal(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)4797 boolean lives_osc_cb_rte_getoutpal(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
4798   weed_plant_t **ctmpls, *template;
4799   weed_plant_t *filter, *inst, *ctmpl, *chan = NULL;
4800   int effect_key, mode, cnum, count, filter_flags;
4801   char *msg;
4802 
4803   if (!lives_osc_check_arguments(arglen, vargs, "iii", FALSE)) {
4804     if (!lives_osc_check_arguments(arglen, vargs, "ii", TRUE)) return lives_osc_notify_failure();
4805     lives_osc_parse_int_argument(vargs, &effect_key);
4806     lives_osc_parse_int_argument(vargs, &cnum);
4807     mode = rte_key_getmode(effect_key);
4808   } else {
4809     lives_osc_check_arguments(arglen, vargs, "iii", TRUE);
4810     lives_osc_parse_int_argument(vargs, &effect_key);
4811     lives_osc_parse_int_argument(vargs, &mode);
4812     if (mode < 1 || mode > rte_key_getmaxmode(effect_key) + 1) return lives_osc_notify_failure();
4813     lives_osc_parse_int_argument(vargs, &cnum);
4814     mode--;
4815   }
4816 
4817   if (effect_key < 1 || effect_key > FX_MAX) return lives_osc_notify_failure();
4818   //g_print("key %d pnum %d",effect_key,pnum);
4819 
4820   inst = rte_keymode_get_instance(effect_key, mode);
4821   filter = rte_keymode_get_filter(effect_key, mode);
4822   if (!filter) return lives_osc_notify_failure();
4823 
4824   if (inst) {
4825     chan = get_enabled_channel(inst, cnum, FALSE);
4826     ctmpl = weed_get_plantptr_value(chan, WEED_LEAF_TEMPLATE, NULL);
4827   } else {
4828     if (!weed_plant_has_leaf(filter, WEED_LEAF_OUT_CHANNEL_TEMPLATES)) return lives_osc_notify_failure();
4829     count = weed_leaf_num_elements(filter, WEED_LEAF_OUT_CHANNEL_TEMPLATES);
4830     if (cnum >= count) return lives_osc_notify_failure();
4831     ctmpls = weed_get_plantptr_array(filter, WEED_LEAF_OUT_CHANNEL_TEMPLATES, NULL);
4832     ctmpl = ctmpls[cnum];
4833     lives_free(ctmpls);
4834   }
4835 
4836   if (weed_plant_has_leaf(ctmpl, WEED_LEAF_IS_AUDIO)) {
4837     weed_instance_unref(inst);
4838     msg = lives_strdup_printf("%d", WEED_PALETTE_END);
4839     lives_status_send(msg);
4840     lives_free(msg);
4841     return TRUE;
4842   }
4843 
4844   if (inst) {
4845     weed_instance_unref(inst);
4846     msg = lives_strdup_printf("%d", weed_get_int_value(chan, WEED_LEAF_CURRENT_PALETTE, NULL));
4847     lives_status_send(msg);
4848     lives_free(msg);
4849     return TRUE;
4850   }
4851   filter_flags = weed_get_int_value(filter, WEED_LEAF_FLAGS, NULL);
4852 
4853   if ((filter_flags & WEED_FILTER_PALETTES_MAY_VARY) && weed_plant_has_leaf(ctmpl, WEED_LEAF_PALETTE_LIST)) {
4854     template = ctmpl;;
4855   } else template = filter;
4856   msg = lives_osc_format_result(template, WEED_LEAF_PALETTE_LIST, 0, -1);
4857   lives_status_send(msg);
4858   lives_free(msg);
4859   return TRUE;
4860 }
4861 
4862 
lives_osc_cb_rte_pparamcount(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)4863 boolean lives_osc_cb_rte_pparamcount(void *context, int arglen, const void *vargs, OSCTimeTag when,
4864                                      NetworkReturnAddressPtr ra) {
4865   // return num playback plugin params
4866   int count = 0;
4867   char *msg;
4868 
4869   if (!mainw->vpp) {
4870     return lives_status_send("0");
4871   }
4872 
4873   count = mainw->vpp->num_play_params;
4874 
4875   msg = lives_strdup_printf("%d", count);
4876   lives_status_send(msg);
4877   lives_free(msg);
4878   return TRUE;
4879 }
4880 
4881 
lives_osc_cb_rte_nparamcount(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)4882 boolean lives_osc_cb_rte_nparamcount(void *context, int arglen, const void *vargs, OSCTimeTag when,
4883                                      NetworkReturnAddressPtr ra) {
4884   int effect_key;
4885   int count = -1, i;
4886 
4887   // return number of numeric single valued, non-reinit
4888   // i.e. simple numeric parameters
4889 
4890   weed_plant_t *filter;
4891 
4892   char *msg;
4893 
4894   if (!lives_osc_check_arguments(arglen, vargs, "i", TRUE)) return lives_osc_notify_failure();
4895   lives_osc_parse_int_argument(vargs, &effect_key);
4896 
4897   if (effect_key < 1 || effect_key > FX_MAX) return lives_osc_notify_failure();
4898   //g_print("key %d pnum %d",effect_key,pnum);
4899 
4900   filter = rte_keymode_get_filter(effect_key, rte_key_getmode(effect_key));
4901   if (!filter) return lives_osc_notify_failure();
4902 
4903   do {
4904     i = get_nth_simple_param(filter, ++count);
4905   } while (i != -1);
4906 
4907   msg = lives_strdup_printf("%d", count);
4908   lives_status_send(msg);
4909   lives_free(msg);
4910   return TRUE;
4911 }
4912 
4913 
lives_osc_cb_rte_getnchannels(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)4914 boolean lives_osc_cb_rte_getnchannels(void *context, int arglen, const void *vargs, OSCTimeTag when,
4915                                       NetworkReturnAddressPtr ra) {
4916   int effect_key, mode;
4917   int count;
4918 
4919   weed_plant_t *plant;
4920 
4921   char *msg;
4922 
4923   if (!lives_osc_check_arguments(arglen, vargs, "ii", FALSE)) {
4924     if (!lives_osc_check_arguments(arglen, vargs, "i", TRUE)) return lives_osc_notify_failure();
4925     lives_osc_parse_int_argument(vargs, &effect_key);
4926     mode = rte_key_getmode(effect_key);
4927   } else {
4928     lives_osc_check_arguments(arglen, vargs, "ii", TRUE);
4929     lives_osc_parse_int_argument(vargs, &effect_key);
4930     lives_osc_parse_int_argument(vargs, &mode);
4931     if (mode < 0 || mode > rte_key_getmaxmode(effect_key) + 1) return lives_osc_notify_failure();
4932     mode--;
4933   }
4934 
4935   if (effect_key < 1 || effect_key > FX_MAX) return lives_osc_notify_failure();
4936   plant = rte_keymode_get_instance(effect_key, mode);
4937   if (!plant) plant = rte_keymode_get_filter(effect_key, mode);
4938   if (!plant) return lives_osc_notify_failure();
4939 
4940   count = enabled_in_channels(plant, FALSE);
4941   if (WEED_PLANT_IS_FILTER_INSTANCE(plant)) weed_instance_unref(plant);
4942 
4943   msg = lives_strdup_printf("%d", count);
4944   lives_status_send(msg);
4945   lives_free(msg);
4946   return TRUE;
4947 }
4948 
4949 
lives_osc_cb_rte_getnochannels(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)4950 boolean lives_osc_cb_rte_getnochannels(void *context, int arglen, const void *vargs, OSCTimeTag when,
4951                                        NetworkReturnAddressPtr ra) {
4952   int effect_key;
4953   int count;
4954 
4955   weed_plant_t *plant, *orig_plant;
4956 
4957   char *msg;
4958 
4959   if (!lives_osc_check_arguments(arglen, vargs, "i", TRUE)) return lives_osc_notify_failure();
4960   lives_osc_parse_int_argument(vargs, &effect_key);
4961 
4962   if (effect_key < 1 || effect_key > FX_MAX) return lives_osc_notify_failure();
4963   //g_print("key %d pnum %d",effect_key,pnum);
4964   orig_plant = plant = rte_keymode_get_instance(effect_key, rte_key_getmode(effect_key));
4965 
4966   // handle compound fx
4967   if (plant) while (weed_plant_has_leaf(plant, WEED_LEAF_HOST_NEXT_INSTANCE)) plant = weed_get_plantptr_value(plant,
4968           WEED_LEAF_HOST_NEXT_INSTANCE, NULL);
4969   else plant = rte_keymode_get_filter(effect_key, rte_key_getmode(effect_key));
4970   if (plant) return lives_osc_notify_failure();
4971 
4972   count = enabled_out_channels(plant, FALSE);
4973   if (WEED_PLANT_IS_FILTER_INSTANCE(orig_plant)) weed_instance_unref(orig_plant);
4974 
4975   msg = lives_strdup_printf("%d", count);
4976   lives_status_send(msg);
4977   lives_free(msg);
4978   return TRUE;
4979 }
4980 
4981 
lives_osc_cb_rte_getparammin(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)4982 boolean lives_osc_cb_rte_getparammin(void *context, int arglen, const void *vargs, OSCTimeTag when,
4983                                      NetworkReturnAddressPtr ra) {
4984   int effect_key;
4985   int mode;
4986   int pnum;
4987 
4988   int nparams;
4989   weed_plant_t *filter;
4990   weed_plant_t *ptmpl;
4991 
4992   char *msg;
4993 
4994   if (!lives_osc_check_arguments(arglen, vargs, "iii", FALSE)) {
4995     if (!lives_osc_check_arguments(arglen, vargs, "ii", TRUE)) return lives_osc_notify_failure();
4996     lives_osc_parse_int_argument(vargs, &effect_key);
4997     lives_osc_parse_int_argument(vargs, &pnum);
4998     mode = rte_key_getmode(effect_key);
4999   } else {
5000     lives_osc_check_arguments(arglen, vargs, "iii", TRUE);
5001     lives_osc_parse_int_argument(vargs, &effect_key);
5002     lives_osc_parse_int_argument(vargs, &mode);
5003     lives_osc_parse_int_argument(vargs, &pnum);
5004     if (mode < 1 || mode > rte_key_getmaxmode(effect_key) + 1) return lives_osc_notify_failure();
5005     mode--;
5006   }
5007 
5008   if (effect_key < 1 || effect_key > FX_MAX) return lives_osc_notify_failure();
5009   //g_print("key %d pnum %d",effect_key,pnum);
5010 
5011   filter = rte_keymode_get_filter(effect_key, mode);
5012   if (!filter) return lives_osc_notify_failure();
5013 
5014   nparams = num_in_params(filter, FALSE, TRUE);
5015   if (nparams == 0) return lives_osc_notify_failure();
5016   if (pnum < 0 || pnum >= nparams) return lives_osc_notify_failure();
5017 
5018   ptmpl = weed_filter_in_paramtmpl(filter, pnum, TRUE);
5019 
5020   if (!weed_plant_has_leaf(ptmpl, WEED_LEAF_MIN)) {
5021     return lives_osc_notify_failure();
5022   }
5023 
5024   msg = lives_osc_format_result(ptmpl, WEED_LEAF_MIN, 0, -1);
5025 
5026   lives_status_send(msg);
5027   lives_free(msg);
5028   return TRUE;
5029 }
5030 
5031 
lives_osc_cb_rte_getoparammin(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)5032 boolean lives_osc_cb_rte_getoparammin(void *context, int arglen, const void *vargs, OSCTimeTag when,
5033                                       NetworkReturnAddressPtr ra) {
5034   int effect_key;
5035   int mode;
5036   int pnum;
5037 
5038   int error, nparams;
5039   weed_plant_t *filter;
5040   weed_plant_t **out_ptmpls;
5041   weed_plant_t *ptmpl;
5042 
5043   char *msg;
5044 
5045   if (!lives_osc_check_arguments(arglen, vargs, "iii", FALSE)) {
5046     if (!lives_osc_check_arguments(arglen, vargs, "ii", TRUE)) return lives_osc_notify_failure();
5047     lives_osc_parse_int_argument(vargs, &effect_key);
5048     lives_osc_parse_int_argument(vargs, &pnum);
5049     mode = rte_key_getmode(effect_key);
5050   } else {
5051     lives_osc_check_arguments(arglen, vargs, "iii", TRUE);
5052     lives_osc_parse_int_argument(vargs, &effect_key);
5053     lives_osc_parse_int_argument(vargs, &mode);
5054     lives_osc_parse_int_argument(vargs, &pnum);
5055     if (mode < 1 || mode > rte_key_getmaxmode(effect_key) + 1) return lives_osc_notify_failure();
5056     mode--;
5057   }
5058 
5059   if (effect_key < 1 || effect_key > FX_MAX) return lives_osc_notify_failure();
5060   //g_print("key %d pnum %d",effect_key,pnum);
5061 
5062   filter = rte_keymode_get_filter(effect_key, mode);
5063   if (!filter) return lives_osc_notify_failure();
5064 
5065   if (!weed_plant_has_leaf(filter, WEED_LEAF_OUT_PARAMETER_TEMPLATES)) return lives_osc_notify_failure();
5066 
5067   nparams = weed_leaf_num_elements(filter, WEED_LEAF_OUT_PARAMETER_TEMPLATES);
5068   if (pnum < 0 || pnum >= nparams) return lives_osc_notify_failure();
5069 
5070   out_ptmpls = weed_get_plantptr_array(filter, WEED_LEAF_OUT_PARAMETER_TEMPLATES, &error);
5071 
5072   ptmpl = out_ptmpls[pnum];
5073 
5074   if (!weed_plant_has_leaf(ptmpl, WEED_LEAF_MIN)) {
5075     lives_free(out_ptmpls);
5076     return lives_osc_notify_failure();
5077   }
5078 
5079   msg = lives_osc_format_result(ptmpl, WEED_LEAF_MIN, 0, -1);
5080 
5081   lives_status_send(msg);
5082   lives_free(msg);
5083   lives_free(out_ptmpls);
5084   return TRUE;
5085 }
5086 
5087 
lives_osc_cb_rte_getohasparammin(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)5088 boolean lives_osc_cb_rte_getohasparammin(void *context, int arglen, const void *vargs, OSCTimeTag when,
5089     NetworkReturnAddressPtr ra) {
5090   int effect_key;
5091   int mode;
5092   int pnum;
5093 
5094   int error, nparams;
5095   weed_plant_t *filter;
5096   weed_plant_t **out_ptmpls;
5097   weed_plant_t *ptmpl;
5098 
5099   if (!lives_osc_check_arguments(arglen, vargs, "iii", FALSE)) {
5100     if (!lives_osc_check_arguments(arglen, vargs, "ii", TRUE)) return lives_osc_notify_failure();
5101     lives_osc_parse_int_argument(vargs, &effect_key);
5102     lives_osc_parse_int_argument(vargs, &pnum);
5103     mode = rte_key_getmode(effect_key);
5104   } else {
5105     lives_osc_check_arguments(arglen, vargs, "iii", TRUE);
5106     lives_osc_parse_int_argument(vargs, &effect_key);
5107     lives_osc_parse_int_argument(vargs, &mode);
5108     lives_osc_parse_int_argument(vargs, &pnum);
5109     if (mode < 1 || mode > rte_key_getmaxmode(effect_key) + 1) return lives_osc_notify_failure();
5110     mode--;
5111   }
5112 
5113   if (effect_key < 1 || effect_key > FX_MAX) return lives_osc_notify_failure();
5114   //g_print("key %d pnum %d",effect_key,pnum);
5115 
5116   filter = rte_keymode_get_filter(effect_key, mode);
5117   if (!filter) return lives_osc_notify_failure();
5118 
5119   if (!weed_plant_has_leaf(filter, WEED_LEAF_OUT_PARAMETER_TEMPLATES)) return lives_osc_notify_failure();
5120 
5121   nparams = weed_leaf_num_elements(filter, WEED_LEAF_OUT_PARAMETER_TEMPLATES);
5122   if (pnum < 0 || pnum >= nparams) return lives_osc_notify_failure();
5123 
5124   out_ptmpls = weed_get_plantptr_array(filter, WEED_LEAF_OUT_PARAMETER_TEMPLATES, &error);
5125 
5126   ptmpl = out_ptmpls[pnum];
5127   lives_free(out_ptmpls);
5128 
5129   if (!weed_plant_has_leaf(ptmpl, WEED_LEAF_MIN)) return lives_status_send(get_omc_const("LIVES_FALSE"));
5130   else return lives_status_send(get_omc_const("LIVES_TRUE"));
5131 }
5132 
5133 
lives_osc_cb_rte_getpparammin(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)5134 boolean lives_osc_cb_rte_getpparammin(void *context, int arglen, const void *vargs, OSCTimeTag when,
5135                                       NetworkReturnAddressPtr ra) {
5136   int pnum;
5137 
5138   int error;
5139   weed_plant_t *ptmpl, *param;
5140 
5141   char *msg;
5142 
5143   if (!mainw->ext_playback || !mainw->vpp->play_params) return lives_osc_notify_failure();
5144 
5145   if (!lives_osc_check_arguments(arglen, vargs, "i", TRUE)) return lives_osc_notify_failure();
5146   lives_osc_parse_int_argument(vargs, &pnum);
5147 
5148   if (pnum < 0 || pnum >= mainw->vpp->num_play_params) return lives_osc_notify_failure();
5149 
5150   param = (weed_plant_t *)pp_get_param(mainw->vpp->play_params, pnum);
5151 
5152   ptmpl = weed_get_plantptr_value(param, WEED_LEAF_TEMPLATE, &error);
5153 
5154   if (!weed_plant_has_leaf(ptmpl, WEED_LEAF_MIN)) {
5155     return lives_osc_notify_failure();
5156   }
5157 
5158   msg = lives_osc_format_result(ptmpl, WEED_LEAF_MIN, 0, -1);
5159 
5160   lives_status_send(msg);
5161   lives_free(msg);
5162   return TRUE;
5163 }
5164 
5165 
lives_osc_cb_rte_getparammax(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)5166 boolean lives_osc_cb_rte_getparammax(void *context, int arglen, const void *vargs, OSCTimeTag when,
5167                                      NetworkReturnAddressPtr ra) {
5168   int effect_key;
5169   int mode;
5170   int pnum;
5171 
5172   int nparams;
5173   weed_plant_t *filter;
5174   weed_plant_t *ptmpl;
5175 
5176   char *msg;
5177 
5178   if (!lives_osc_check_arguments(arglen, vargs, "iii", FALSE)) {
5179     if (!lives_osc_check_arguments(arglen, vargs, "ii", TRUE)) return lives_osc_notify_failure();
5180     lives_osc_parse_int_argument(vargs, &effect_key);
5181     lives_osc_parse_int_argument(vargs, &pnum);
5182     mode = rte_key_getmode(effect_key);
5183   } else {
5184     lives_osc_check_arguments(arglen, vargs, "iii", TRUE);
5185     lives_osc_parse_int_argument(vargs, &effect_key);
5186     lives_osc_parse_int_argument(vargs, &mode);
5187     lives_osc_parse_int_argument(vargs, &pnum);
5188     if (mode < 1 || mode > rte_key_getmaxmode(effect_key) + 1) return lives_osc_notify_failure();
5189     mode--;
5190   }
5191 
5192   if (effect_key < 1 || effect_key > FX_MAX) return lives_osc_notify_failure();
5193   //g_print("key %d pnum %d",effect_key,pnum);
5194 
5195   filter = rte_keymode_get_filter(effect_key, mode);
5196   if (!filter) return lives_osc_notify_failure();
5197 
5198   nparams = num_in_params(filter, FALSE, TRUE);
5199   if (nparams == 0) return lives_osc_notify_failure();
5200   if (pnum < 0 || pnum >= nparams) return lives_osc_notify_failure();
5201 
5202   ptmpl = weed_filter_in_paramtmpl(filter, pnum, TRUE);
5203 
5204   if (!weed_plant_has_leaf(ptmpl, WEED_LEAF_MAX)) {
5205     return lives_osc_notify_failure();
5206   }
5207 
5208   msg = lives_osc_format_result(ptmpl, WEED_LEAF_MAX, 0, -1);
5209 
5210   lives_status_send(msg);
5211   lives_free(msg);
5212   return TRUE;
5213 }
5214 
5215 
lives_osc_cb_rte_getoparammax(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)5216 boolean lives_osc_cb_rte_getoparammax(void *context, int arglen, const void *vargs, OSCTimeTag when,
5217                                       NetworkReturnAddressPtr ra) {
5218   int effect_key;
5219   int mode;
5220   int pnum;
5221 
5222   int error, nparams;
5223   weed_plant_t *filter;
5224   weed_plant_t **out_ptmpls;
5225   weed_plant_t *ptmpl;
5226 
5227   char *msg;
5228 
5229   if (!lives_osc_check_arguments(arglen, vargs, "iii", FALSE)) {
5230     if (!lives_osc_check_arguments(arglen, vargs, "ii", TRUE)) return lives_osc_notify_failure();
5231     lives_osc_parse_int_argument(vargs, &effect_key);
5232     lives_osc_parse_int_argument(vargs, &pnum);
5233     mode = rte_key_getmode(effect_key);
5234   } else {
5235     lives_osc_check_arguments(arglen, vargs, "iii", TRUE);
5236     lives_osc_parse_int_argument(vargs, &effect_key);
5237     lives_osc_parse_int_argument(vargs, &mode);
5238     lives_osc_parse_int_argument(vargs, &pnum);
5239     if (mode < 1 || mode > rte_key_getmaxmode(effect_key) + 1) return lives_osc_notify_failure();
5240     mode--;
5241   }
5242 
5243   if (effect_key < 1 || effect_key > FX_MAX) return lives_osc_notify_failure();
5244   //g_print("key %d pnum %d",effect_key,pnum);
5245 
5246   filter = rte_keymode_get_filter(effect_key, mode);
5247   if (!filter) return lives_osc_notify_failure();
5248 
5249   if (!weed_plant_has_leaf(filter, WEED_LEAF_OUT_PARAMETER_TEMPLATES)) return lives_osc_notify_failure();
5250   nparams = weed_leaf_num_elements(filter, WEED_LEAF_OUT_PARAMETER_TEMPLATES);
5251   if (pnum < 0 || pnum >= nparams) return lives_osc_notify_failure();
5252 
5253   out_ptmpls = weed_get_plantptr_array(filter, WEED_LEAF_OUT_PARAMETER_TEMPLATES, &error);
5254 
5255   ptmpl = out_ptmpls[pnum];
5256 
5257   if (!weed_plant_has_leaf(ptmpl, WEED_LEAF_MAX)) {
5258     lives_free(out_ptmpls);
5259     return lives_osc_notify_failure();
5260   }
5261 
5262   msg = lives_osc_format_result(ptmpl, WEED_LEAF_MAX, 0, -1);
5263 
5264   lives_status_send(msg);
5265   lives_free(msg);
5266   lives_free(out_ptmpls);
5267   return TRUE;
5268 }
5269 
5270 
lives_osc_cb_rte_getohasparammax(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)5271 boolean lives_osc_cb_rte_getohasparammax(void *context, int arglen, const void *vargs, OSCTimeTag when,
5272     NetworkReturnAddressPtr ra) {
5273   int effect_key;
5274   int mode;
5275   int pnum;
5276 
5277   int error, nparams;
5278   weed_plant_t *filter;
5279   weed_plant_t **out_ptmpls;
5280   weed_plant_t *ptmpl;
5281 
5282   if (!lives_osc_check_arguments(arglen, vargs, "iii", FALSE)) {
5283     if (!lives_osc_check_arguments(arglen, vargs, "ii", TRUE)) return lives_osc_notify_failure();
5284     lives_osc_parse_int_argument(vargs, &effect_key);
5285     lives_osc_parse_int_argument(vargs, &pnum);
5286     mode = rte_key_getmode(effect_key);
5287   } else {
5288     lives_osc_check_arguments(arglen, vargs, "iii", TRUE);
5289     lives_osc_parse_int_argument(vargs, &effect_key);
5290     lives_osc_parse_int_argument(vargs, &mode);
5291     lives_osc_parse_int_argument(vargs, &pnum);
5292     if (mode < 1 || mode > rte_key_getmaxmode(effect_key) + 1) return lives_osc_notify_failure();
5293     mode--;
5294   }
5295 
5296   if (effect_key < 1 || effect_key > FX_MAX) return lives_osc_notify_failure();
5297   //g_print("key %d pnum %d",effect_key,pnum);
5298 
5299   filter = rte_keymode_get_filter(effect_key, mode);
5300   if (!filter) return lives_osc_notify_failure();
5301 
5302   if (!weed_plant_has_leaf(filter, WEED_LEAF_OUT_PARAMETER_TEMPLATES)) return lives_osc_notify_failure();
5303   nparams = weed_leaf_num_elements(filter, WEED_LEAF_OUT_PARAMETER_TEMPLATES);
5304   if (pnum < 0 || pnum >= nparams) return lives_osc_notify_failure();
5305 
5306   out_ptmpls = weed_get_plantptr_array(filter, WEED_LEAF_OUT_PARAMETER_TEMPLATES, &error);
5307 
5308   ptmpl = out_ptmpls[pnum];
5309   lives_free(out_ptmpls);
5310 
5311   if (!weed_plant_has_leaf(ptmpl, WEED_LEAF_MAX)) return lives_status_send(get_omc_const("LIVES_FALSE"));
5312   else return lives_status_send(get_omc_const("LIVES_TRUE"));
5313 }
5314 
5315 
lives_osc_cb_rte_getpparammax(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)5316 boolean lives_osc_cb_rte_getpparammax(void *context, int arglen, const void *vargs, OSCTimeTag when,
5317                                       NetworkReturnAddressPtr ra) {
5318   // playback plugin param max
5319 
5320   int pnum;
5321 
5322   int error;
5323   weed_plant_t *ptmpl, *param;
5324 
5325   char *msg;
5326 
5327   if (!mainw->ext_playback || !mainw->vpp->play_params) return lives_osc_notify_failure();
5328 
5329   if (!lives_osc_check_arguments(arglen, vargs, "i", TRUE)) return lives_osc_notify_failure();
5330   lives_osc_parse_int_argument(vargs, &pnum);
5331 
5332   if (pnum < 0 || pnum >= mainw->vpp->num_play_params) return lives_osc_notify_failure();
5333 
5334   param = (weed_plant_t *)pp_get_param(mainw->vpp->play_params, pnum);
5335 
5336   ptmpl = weed_get_plantptr_value(param, WEED_LEAF_TEMPLATE, &error);
5337 
5338   if (!weed_plant_has_leaf(ptmpl, WEED_LEAF_MAX)) {
5339     return lives_osc_notify_failure();
5340   }
5341 
5342   msg = lives_osc_format_result(ptmpl, WEED_LEAF_MAX, 0, -1);
5343 
5344   lives_status_send(msg);
5345   lives_free(msg);
5346 
5347   return TRUE;
5348 }
5349 
5350 
lives_osc_cb_rte_getparamdef(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)5351 boolean lives_osc_cb_rte_getparamdef(void *context, int arglen, const void *vargs, OSCTimeTag when,
5352                                      NetworkReturnAddressPtr ra) {
5353   int effect_key;
5354   int mode;
5355   int pnum, nvals;
5356 
5357   int nparams;
5358   weed_plant_t *filter;
5359   weed_plant_t *ptmpl;
5360 
5361   char *msg;
5362 
5363   if (!lives_osc_check_arguments(arglen, vargs, "iii", FALSE)) {
5364     if (!lives_osc_check_arguments(arglen, vargs, "ii", TRUE)) return lives_osc_notify_failure();
5365     lives_osc_parse_int_argument(vargs, &effect_key);
5366     lives_osc_parse_int_argument(vargs, &pnum);
5367     mode = rte_key_getmode(effect_key);
5368   } else {
5369     lives_osc_check_arguments(arglen, vargs, "iii", TRUE);
5370     lives_osc_parse_int_argument(vargs, &effect_key);
5371     lives_osc_parse_int_argument(vargs, &mode);
5372     lives_osc_parse_int_argument(vargs, &pnum);
5373     if (mode < 1 || mode > rte_key_getmaxmode(effect_key) + 1) return lives_osc_notify_failure();
5374     mode--;
5375   }
5376 
5377   if (effect_key < 1 || effect_key > FX_MAX) return lives_osc_notify_failure();
5378   //g_print("key %d pnum %d",effect_key,pnum);
5379 
5380   filter = rte_keymode_get_filter(effect_key, mode);
5381   if (!filter) return lives_osc_notify_failure();
5382 
5383   nparams = num_in_params(filter, FALSE, TRUE);
5384   if (nparams == 0) return lives_osc_notify_failure();
5385   if (pnum < 0 || pnum >= nparams) return lives_osc_notify_failure();
5386 
5387   ptmpl = weed_filter_in_paramtmpl(filter, pnum, TRUE);
5388 
5389   if (weed_plant_has_leaf(ptmpl, WEED_LEAF_HOST_DEFAULT)) {
5390     msg = lives_osc_format_result(ptmpl, WEED_LEAF_HOST_DEFAULT, 0, -1);
5391   } else {
5392     nvals = weed_leaf_num_elements(ptmpl, WEED_LEAF_DEFAULT);
5393     if (nvals > 0)
5394       msg = lives_osc_format_result(ptmpl, WEED_LEAF_DEFAULT, 0, nvals);
5395     else {
5396       // default can have 0 values if param has variable elements; in this case we use WEED_LEAF_NEW_DEFAULT
5397       msg = lives_osc_format_result(ptmpl, WEED_LEAF_NEW_DEFAULT, 0, -1);
5398     }
5399   }
5400 
5401   lives_status_send(msg);
5402   lives_free(msg);
5403 
5404   return TRUE;
5405 }
5406 
5407 
lives_osc_cb_rte_getoparamdef(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)5408 boolean lives_osc_cb_rte_getoparamdef(void *context, int arglen, const void *vargs, OSCTimeTag when,
5409                                       NetworkReturnAddressPtr ra) {
5410   int effect_key;
5411   int mode;
5412   int pnum, nvals;
5413 
5414   int error, nparams;
5415   weed_plant_t *filter;
5416   weed_plant_t **out_ptmpls;
5417   weed_plant_t *ptmpl;
5418 
5419   char *msg;
5420 
5421   if (!lives_osc_check_arguments(arglen, vargs, "iii", FALSE)) {
5422     if (!lives_osc_check_arguments(arglen, vargs, "ii", TRUE)) return lives_osc_notify_failure();
5423     lives_osc_parse_int_argument(vargs, &effect_key);
5424     lives_osc_parse_int_argument(vargs, &pnum);
5425     mode = rte_key_getmode(effect_key);
5426   } else {
5427     lives_osc_check_arguments(arglen, vargs, "iii", TRUE);
5428     lives_osc_parse_int_argument(vargs, &effect_key);
5429     lives_osc_parse_int_argument(vargs, &mode);
5430     lives_osc_parse_int_argument(vargs, &pnum);
5431     if (mode < 1 || mode > rte_key_getmaxmode(effect_key) + 1) return lives_osc_notify_failure();
5432     mode--;
5433   }
5434 
5435   if (effect_key < 1 || effect_key > FX_MAX) return lives_osc_notify_failure();
5436   //g_print("key %d pnum %d",effect_key,pnum);
5437 
5438   filter = rte_keymode_get_filter(effect_key, mode);
5439   if (!filter) return lives_osc_notify_failure();
5440 
5441   if (!weed_plant_has_leaf(filter, WEED_LEAF_OUT_PARAMETER_TEMPLATES)) return lives_osc_notify_failure();
5442   nparams = weed_leaf_num_elements(filter, WEED_LEAF_OUT_PARAMETER_TEMPLATES);
5443   if (pnum < 0 || pnum >= nparams) return lives_osc_notify_failure();
5444 
5445   out_ptmpls = weed_get_plantptr_array(filter, WEED_LEAF_OUT_PARAMETER_TEMPLATES, &error);
5446 
5447   ptmpl = out_ptmpls[pnum];
5448 
5449   if (weed_plant_has_leaf(ptmpl, WEED_LEAF_HOST_DEFAULT)) {
5450     msg = lives_osc_format_result(ptmpl, WEED_LEAF_HOST_DEFAULT, 0, -1);
5451   } else {
5452     if (!weed_plant_has_leaf(ptmpl, WEED_LEAF_DEFAULT)) {
5453       lives_free(out_ptmpls);
5454       return lives_osc_notify_failure();
5455     }
5456 
5457     nvals = weed_leaf_num_elements(ptmpl, WEED_LEAF_DEFAULT);
5458     if (nvals > 0)
5459       msg = lives_osc_format_result(ptmpl, WEED_LEAF_DEFAULT, 0, nvals);
5460     else {
5461       // default can have 0 values if param has variable elements; in this case we use WEED_LEAF_NEW_DEFAULT
5462       msg = lives_osc_format_result(ptmpl, WEED_LEAF_NEW_DEFAULT, 0, -1);
5463     }
5464   }
5465 
5466   lives_status_send(msg);
5467   lives_free(msg);
5468   lives_free(out_ptmpls);
5469 
5470   return TRUE;
5471 }
5472 
5473 
lives_osc_cb_rte_gethasparamdef(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)5474 boolean lives_osc_cb_rte_gethasparamdef(void *context, int arglen, const void *vargs, OSCTimeTag when,
5475                                         NetworkReturnAddressPtr ra) {
5476   int effect_key;
5477   int mode;
5478   int pnum;
5479 
5480   int nparams;
5481   weed_plant_t *filter;
5482   weed_plant_t *ptmpl;
5483 
5484   if (!lives_osc_check_arguments(arglen, vargs, "iii", FALSE)) {
5485     if (!lives_osc_check_arguments(arglen, vargs, "ii", TRUE)) return lives_osc_notify_failure();
5486     lives_osc_parse_int_argument(vargs, &effect_key);
5487     lives_osc_parse_int_argument(vargs, &pnum);
5488     mode = rte_key_getmode(effect_key);
5489   } else {
5490     lives_osc_check_arguments(arglen, vargs, "iii", TRUE);
5491     lives_osc_parse_int_argument(vargs, &effect_key);
5492     lives_osc_parse_int_argument(vargs, &mode);
5493     lives_osc_parse_int_argument(vargs, &pnum);
5494     if (mode < 1 || mode > rte_key_getmaxmode(effect_key) + 1) return lives_osc_notify_failure();
5495     mode--;
5496   }
5497 
5498   if (effect_key < 1 || effect_key > FX_MAX) return lives_osc_notify_failure();
5499   //g_print("key %d pnum %d",effect_key,pnum);
5500 
5501   filter = rte_keymode_get_filter(effect_key, mode);
5502   if (!filter) return lives_osc_notify_failure();
5503 
5504   nparams = num_in_params(filter, FALSE, TRUE);
5505   if (nparams == 0) return lives_osc_notify_failure();
5506   if (pnum < 0 || pnum >= nparams) return lives_osc_notify_failure();
5507 
5508   ptmpl = weed_filter_in_paramtmpl(filter, pnum, TRUE);
5509 
5510   if (weed_plant_has_leaf(ptmpl, WEED_LEAF_HOST_DEFAULT)) {
5511     if (weed_leaf_num_elements(ptmpl, WEED_LEAF_HOST_DEFAULT) == 0) return lives_status_send(get_omc_const("LIVES_FALSE"));
5512     return lives_status_send(get_omc_const("LIVES_DEFAULT_OVERRIDDEN"));
5513   }
5514   if (!weed_plant_has_leaf(ptmpl, WEED_LEAF_DEFAULT) ||
5515       weed_leaf_num_elements(ptmpl, WEED_LEAF_DEFAULT) == 0) return lives_status_send(get_omc_const("LIVES_FALSE"));
5516   else return lives_status_send(get_omc_const("LIVES_TRUE"));
5517 }
5518 
5519 
lives_osc_cb_rte_getohasparamdef(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)5520 boolean lives_osc_cb_rte_getohasparamdef(void *context, int arglen, const void *vargs, OSCTimeTag when,
5521     NetworkReturnAddressPtr ra) {
5522   int effect_key;
5523   int mode;
5524   int pnum;
5525 
5526   int error, nparams;
5527   weed_plant_t *filter;
5528   weed_plant_t **out_ptmpls;
5529   weed_plant_t *ptmpl;
5530 
5531   if (!lives_osc_check_arguments(arglen, vargs, "iii", FALSE)) {
5532     if (!lives_osc_check_arguments(arglen, vargs, "ii", TRUE)) return lives_osc_notify_failure();
5533     lives_osc_parse_int_argument(vargs, &effect_key);
5534     lives_osc_parse_int_argument(vargs, &pnum);
5535     mode = rte_key_getmode(effect_key);
5536   } else {
5537     lives_osc_check_arguments(arglen, vargs, "iii", TRUE);
5538     lives_osc_parse_int_argument(vargs, &effect_key);
5539     lives_osc_parse_int_argument(vargs, &mode);
5540     lives_osc_parse_int_argument(vargs, &pnum);
5541     if (mode < 1 || mode > rte_key_getmaxmode(effect_key) + 1) return lives_osc_notify_failure();
5542     mode--;
5543   }
5544 
5545   if (effect_key < 1 || effect_key > FX_MAX) return lives_osc_notify_failure();
5546   //g_print("key %d pnum %d",effect_key,pnum);
5547 
5548   filter = rte_keymode_get_filter(effect_key, mode);
5549   if (!filter) return lives_osc_notify_failure();
5550 
5551   if (!weed_plant_has_leaf(filter, WEED_LEAF_OUT_PARAMETER_TEMPLATES)) return lives_osc_notify_failure();
5552   nparams = weed_leaf_num_elements(filter, WEED_LEAF_OUT_PARAMETER_TEMPLATES);
5553   if (pnum < 0 || pnum >= nparams) return lives_osc_notify_failure();
5554 
5555   out_ptmpls = weed_get_plantptr_array(filter, WEED_LEAF_OUT_PARAMETER_TEMPLATES, &error);
5556 
5557   ptmpl = out_ptmpls[pnum];
5558   lives_free(out_ptmpls);
5559 
5560   if (!weed_plant_has_leaf(ptmpl, WEED_LEAF_HOST_DEFAULT) &&
5561       !weed_plant_has_leaf(ptmpl, WEED_LEAF_DEFAULT)) return lives_status_send(get_omc_const("LIVES_FALSE"));
5562   else return lives_status_send(get_omc_const("LIVES_TRUE"));
5563 }
5564 
5565 
lives_osc_cb_rte_getpparamdef(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)5566 boolean lives_osc_cb_rte_getpparamdef(void *context, int arglen, const void *vargs, OSCTimeTag when,
5567                                       NetworkReturnAddressPtr ra) {
5568   // default for playback plugin param
5569 
5570   int pnum, nvals;
5571 
5572   int error;
5573   weed_plant_t *param;
5574   weed_plant_t *ptmpl;
5575 
5576   char *msg;
5577 
5578   if (!mainw->ext_playback || !mainw->vpp->play_params) return lives_osc_notify_failure();
5579 
5580   if (!lives_osc_check_arguments(arglen, vargs, "i", TRUE)) return lives_osc_notify_failure();
5581 
5582   lives_osc_parse_int_argument(vargs, &pnum);
5583 
5584   if (pnum < 0 || pnum >= mainw->vpp->num_play_params) return lives_osc_notify_failure();
5585 
5586   param = (weed_plant_t *)pp_get_param(mainw->vpp->play_params, pnum);
5587 
5588   ptmpl = weed_get_plantptr_value(param, WEED_LEAF_TEMPLATE, &error);
5589 
5590   nvals = weed_leaf_num_elements(ptmpl, WEED_LEAF_DEFAULT);
5591   if (nvals > 0)
5592     msg = lives_osc_format_result(ptmpl, WEED_LEAF_DEFAULT, 0, nvals);
5593   else {
5594     // default can have 0 values if param has variable elements; in this case we use WEED_LEAF_NEW_DEFAULT
5595     msg = lives_osc_format_result(ptmpl, WEED_LEAF_NEW_DEFAULT, 0, -1);
5596   }
5597 
5598   lives_status_send(msg);
5599   lives_free(msg);
5600 
5601   return TRUE;
5602 }
5603 
5604 
lives_osc_cb_rte_getparamval(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)5605 boolean lives_osc_cb_rte_getparamval(void *context, int arglen, const void *vargs, OSCTimeTag when,
5606                                      NetworkReturnAddressPtr ra) {
5607   int effect_key;
5608   int pnum, st = 0, end = 1, ptype, cspace;
5609 
5610   int error, nparams;
5611   weed_plant_t *inst, *filter;
5612   weed_plant_t *param, *ptmpl;
5613   char *msg;
5614 
5615   if (lives_osc_check_arguments(arglen, vargs, "ii", FALSE)) {
5616     lives_osc_check_arguments(arglen, vargs, "ii", TRUE);
5617     lives_osc_parse_int_argument(vargs, &effect_key);
5618     lives_osc_parse_int_argument(vargs, &pnum);
5619   } else {
5620     if (!lives_osc_check_arguments(arglen, vargs, "iii", TRUE)) return lives_osc_notify_failure();
5621     lives_osc_parse_int_argument(vargs, &effect_key);
5622     lives_osc_parse_int_argument(vargs, &pnum);
5623     lives_osc_parse_int_argument(vargs, &st);
5624     end = st + 1;
5625   }
5626 
5627   if (effect_key < 1 || effect_key > FX_MAX) return lives_osc_notify_failure();
5628   //g_print("key %d pnum %d",effect_key,pnum);
5629 
5630   filter = rte_keymode_get_filter(effect_key, rte_key_getmode(effect_key));
5631   if (!filter) return lives_osc_notify_failure();
5632 
5633   filter = rte_keymode_get_filter(effect_key, rte_key_getmode(effect_key));
5634   inst = rte_keymode_get_instance(effect_key, rte_key_getmode(effect_key));
5635 
5636   if (!inst) return lives_osc_notify_failure();
5637 
5638   nparams = num_in_params(filter, FALSE, TRUE);
5639   if (nparams == 0) {
5640     weed_instance_unref(inst);
5641     return lives_osc_notify_failure();
5642   }
5643   if (pnum < 0 || pnum >= nparams) {
5644     weed_instance_unref(inst);
5645     return lives_osc_notify_failure();
5646   }
5647 
5648   param = weed_inst_in_param(inst, pnum, FALSE, TRUE);
5649   ptmpl = weed_get_plantptr_value(param, WEED_LEAF_TEMPLATE, &error);
5650 
5651   ptype = weed_paramtmpl_get_type(ptmpl);
5652   if (ptype == WEED_PARAM_COLOR) {
5653     int valsize = 4;
5654     cspace = weed_get_int_value(ptmpl, WEED_LEAF_COLORSPACE, &error);
5655     if (cspace == WEED_COLORSPACE_RGB) valsize = 3;
5656     st *= valsize;
5657     end = st + valsize;
5658   }
5659 
5660   if (end > weed_leaf_num_elements(param, WEED_LEAF_VALUE)) {
5661     weed_instance_unref(inst);
5662     return lives_osc_notify_failure();
5663   }
5664 
5665   msg = lives_osc_format_result(param, WEED_LEAF_VALUE, st, end);
5666 
5667   weed_instance_unref(inst);
5668   lives_status_send(msg);
5669   lives_free(msg);
5670 
5671   return TRUE;
5672 }
5673 
5674 
lives_osc_cb_rte_getoparamval(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)5675 boolean lives_osc_cb_rte_getoparamval(void *context, int arglen, const void *vargs, OSCTimeTag when,
5676                                       NetworkReturnAddressPtr ra) {
5677   int effect_key;
5678   int pnum, st = 0, end = 1, ptype, cspace;
5679 
5680   int error, nparams;
5681   weed_plant_t *inst, *filter;
5682   weed_plant_t **out_params, **out_ptmpls;
5683   weed_plant_t *param, *ptmpl;
5684   char *msg;
5685 
5686   if (lives_osc_check_arguments(arglen, vargs, "ii", FALSE)) {
5687     lives_osc_check_arguments(arglen, vargs, "ii", TRUE);
5688     lives_osc_parse_int_argument(vargs, &effect_key);
5689     lives_osc_parse_int_argument(vargs, &pnum);
5690   } else {
5691     if (!lives_osc_check_arguments(arglen, vargs, "iii", TRUE)) return lives_osc_notify_failure();
5692     lives_osc_parse_int_argument(vargs, &effect_key);
5693     lives_osc_parse_int_argument(vargs, &pnum);
5694     lives_osc_parse_int_argument(vargs, &st);
5695     end = st + 1;
5696   }
5697 
5698   if (effect_key < 1 || effect_key > FX_MAX) return lives_osc_notify_failure();
5699   //g_print("key %d pnum %d",effect_key,pnum);
5700 
5701   filter = rte_keymode_get_filter(effect_key, rte_key_getmode(effect_key));
5702   if (!filter) return lives_osc_notify_failure();
5703 
5704   if (!weed_plant_has_leaf(filter, WEED_LEAF_OUT_PARAMETER_TEMPLATES)) return lives_osc_notify_failure();
5705   nparams = weed_leaf_num_elements(filter, WEED_LEAF_OUT_PARAMETER_TEMPLATES);
5706   if (pnum < 0 || pnum >= nparams) return lives_osc_notify_failure();
5707 
5708   inst = rte_keymode_get_instance(effect_key, rte_key_getmode(effect_key));
5709   if (!inst) return lives_osc_notify_failure();
5710 
5711   out_ptmpls = weed_get_plantptr_array(filter, WEED_LEAF_OUT_PARAMETER_TEMPLATES, &error);
5712 
5713   ptmpl = out_ptmpls[pnum];
5714 
5715   out_params = weed_get_plantptr_array(inst, WEED_LEAF_OUT_PARAMETERS, &error);
5716 
5717   param = out_params[pnum];
5718 
5719   lives_free(out_ptmpls);
5720   lives_free(out_params);
5721 
5722   ptype = weed_paramtmpl_get_type(ptmpl);
5723   if (ptype == WEED_PARAM_COLOR) {
5724     int valsize = 4;
5725     cspace = weed_get_int_value(ptmpl, WEED_LEAF_COLORSPACE, &error);
5726     if (cspace == WEED_COLORSPACE_RGB) valsize = 3;
5727     st *= valsize;
5728     end = st + valsize;
5729   }
5730 
5731   if (end > weed_leaf_num_elements(param, WEED_LEAF_VALUE)) {
5732     weed_instance_unref(inst);
5733     return lives_osc_notify_failure();
5734   }
5735 
5736   if (!filter_mutex_trylock(effect_key - 1)) {
5737     msg = lives_osc_format_result(param, WEED_LEAF_VALUE, st, end);
5738     weed_instance_unref(inst);
5739     filter_mutex_unlock(effect_key - 1);
5740     lives_status_send(msg);
5741     lives_free(msg);
5742   } else {
5743     weed_instance_unref(inst);
5744     return lives_osc_notify_failure();
5745   }
5746   weed_instance_unref(inst);
5747   return TRUE;
5748 }
5749 
5750 
lives_osc_cb_rte_getpparamval(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)5751 boolean lives_osc_cb_rte_getpparamval(void *context, int arglen, const void *vargs, OSCTimeTag when,
5752                                       NetworkReturnAddressPtr ra) {
5753   // playback plugin param value
5754   int pnum, st = 0, end = 1, ptype, cspace;
5755 
5756   int error;
5757   weed_plant_t *param, *ptmpl;
5758   char *msg;
5759 
5760   if (!mainw->ext_playback || !mainw->vpp->play_params) return lives_osc_notify_failure();
5761 
5762   if (lives_osc_check_arguments(arglen, vargs, "i", FALSE)) {
5763     lives_osc_check_arguments(arglen, vargs, "i", TRUE);
5764     lives_osc_parse_int_argument(vargs, &pnum);
5765   } else {
5766     if (!lives_osc_check_arguments(arglen, vargs, "ii", TRUE)) return lives_osc_notify_failure();
5767     lives_osc_parse_int_argument(vargs, &pnum);
5768     lives_osc_parse_int_argument(vargs, &st);
5769     end = st + 1;
5770   }
5771 
5772   param = (weed_plant_t *)pp_get_param(mainw->vpp->play_params, pnum);
5773 
5774   ptmpl = weed_get_plantptr_value(param, WEED_LEAF_TEMPLATE, &error);
5775 
5776   ptype = weed_paramtmpl_get_type(ptmpl);
5777   if (ptype == WEED_PARAM_COLOR) {
5778     int valsize = 4;
5779     cspace = weed_get_int_value(ptmpl, WEED_LEAF_COLORSPACE, &error);
5780     if (cspace == WEED_COLORSPACE_RGB) valsize = 3;
5781     st *= valsize;
5782     end = st + valsize;
5783   }
5784 
5785   if (end > weed_leaf_num_elements(param, WEED_LEAF_VALUE)) return lives_osc_notify_failure();
5786 
5787   msg = lives_osc_format_result(param, WEED_LEAF_VALUE, st, end);
5788 
5789   lives_status_send(msg);
5790   lives_free(msg);
5791 
5792   return TRUE;
5793 }
5794 
5795 
lives_osc_cb_rte_getnparam(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)5796 boolean lives_osc_cb_rte_getnparam(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
5797   int effect_key;
5798   int pnum, i;
5799 
5800   // pick pnum which is numeric single valued, non-reinit
5801   // i.e. simple numeric parameter
5802 
5803   weed_plant_t *filter;
5804   weed_plant_t **in_ptmpls;
5805   weed_plant_t *ptmpl;
5806   int ptype;
5807 
5808   int vali;
5809   double vald;
5810 
5811   char *msg;
5812 
5813   if (!lives_osc_check_arguments(arglen, vargs, "ii", TRUE)) return lives_osc_notify_failure();
5814 
5815   lives_osc_parse_int_argument(vargs, &effect_key);
5816   lives_osc_parse_int_argument(vargs, &pnum);
5817 
5818   if (effect_key < 1 || effect_key > FX_MAX) return lives_osc_notify_failure();
5819   //g_print("key %d pnum %d",effect_key,pnum);
5820 
5821   filter = rte_keymode_get_filter(effect_key, rte_key_getmode(effect_key));
5822   if (!filter) return lives_osc_notify_failure();
5823 
5824   i = get_nth_simple_param(filter, pnum);
5825 
5826   if (i == -1) return lives_osc_notify_failure();
5827 
5828   in_ptmpls = weed_get_plantptr_array(filter, WEED_LEAF_IN_PARAMETER_TEMPLATES, NULL);
5829 
5830   ptmpl = in_ptmpls[i];
5831   ptype = weed_paramtmpl_get_type(ptmpl);
5832 
5833   if (ptype == WEED_PARAM_INTEGER) {
5834     vali = weed_get_int_value(ptmpl, WEED_LEAF_VALUE, NULL);
5835     msg = lives_strdup_printf("%d", vali);
5836   } else {
5837     vald = weed_get_double_value(ptmpl, WEED_LEAF_VALUE, NULL);
5838     msg = lives_strdup_printf("%f", vald);
5839   }
5840   lives_status_send(msg);
5841   lives_free(msg);
5842   lives_free(in_ptmpls);
5843 
5844   return TRUE;
5845 }
5846 
5847 
lives_osc_cb_rte_getnparammin(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)5848 boolean lives_osc_cb_rte_getnparammin(void *context, int arglen, const void *vargs, OSCTimeTag when,
5849                                       NetworkReturnAddressPtr ra) {
5850   int effect_key;
5851   int pnum, i;
5852 
5853   // pick pnum which is numeric single valued, non-reinit
5854   // i.e. simple numeric parameter
5855 
5856   weed_plant_t *filter;
5857   weed_plant_t **in_ptmpls;
5858   weed_plant_t *ptmpl;
5859   int ptype;
5860 
5861   int vali;
5862   double vald;
5863 
5864   char *msg;
5865 
5866   if (!lives_osc_check_arguments(arglen, vargs, "ii", TRUE)) return lives_osc_notify_failure();
5867 
5868   lives_osc_parse_int_argument(vargs, &effect_key);
5869   lives_osc_parse_int_argument(vargs, &pnum);
5870 
5871   if (effect_key < 1 || effect_key > FX_MAX) return lives_osc_notify_failure();
5872   //g_print("key %d pnum %d",effect_key,pnum);
5873 
5874   filter = rte_keymode_get_filter(effect_key, rte_key_getmode(effect_key));
5875   if (!filter) return lives_osc_notify_failure();
5876 
5877   i = get_nth_simple_param(filter, pnum);
5878 
5879   if (i == -1) return lives_osc_notify_failure();
5880 
5881   in_ptmpls = weed_get_plantptr_array(filter, WEED_LEAF_IN_PARAMETER_TEMPLATES, NULL);
5882 
5883   ptmpl = in_ptmpls[i];
5884   ptype = weed_paramtmpl_get_type(ptmpl);
5885 
5886   if (ptype == WEED_PARAM_INTEGER) {
5887     vali = weed_get_int_value(ptmpl, WEED_LEAF_MIN, NULL);
5888     msg = lives_strdup_printf("%d", vali);
5889   } else {
5890     vald = weed_get_double_value(ptmpl, WEED_LEAF_MIN, NULL);
5891     msg = lives_strdup_printf("%f", vald);
5892   }
5893   lives_status_send(msg);
5894   lives_free(msg);
5895   lives_free(in_ptmpls);
5896 
5897   return TRUE;
5898 }
5899 
5900 
lives_osc_cb_rte_getnparammax(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)5901 boolean lives_osc_cb_rte_getnparammax(void *context, int arglen, const void *vargs, OSCTimeTag when,
5902                                       NetworkReturnAddressPtr ra) {
5903   int effect_key;
5904   int pnum, i;
5905 
5906   // pick pnum which is numeric single valued, non-reinit
5907   // i.e. simple numeric parameter
5908 
5909   weed_plant_t *filter;
5910   weed_plant_t **in_ptmpls;
5911   weed_plant_t *ptmpl;
5912   int ptype;
5913 
5914   int vali;
5915   double vald;
5916 
5917   char *msg;
5918 
5919   if (!lives_osc_check_arguments(arglen, vargs, "ii", TRUE)) return lives_osc_notify_failure();
5920 
5921   lives_osc_parse_int_argument(vargs, &effect_key);
5922   lives_osc_parse_int_argument(vargs, &pnum);
5923 
5924   if (effect_key < 1 || effect_key > FX_MAX) return lives_osc_notify_failure();
5925   //g_print("key %d pnum %d",effect_key,pnum);
5926 
5927   filter = rte_keymode_get_filter(effect_key, rte_key_getmode(effect_key));
5928   if (!filter) return lives_osc_notify_failure();
5929 
5930   i = get_nth_simple_param(filter, pnum);
5931 
5932   if (i == -1) return lives_osc_notify_failure();
5933 
5934   in_ptmpls = weed_get_plantptr_array(filter, WEED_LEAF_IN_PARAMETER_TEMPLATES, NULL);
5935 
5936   ptmpl = in_ptmpls[i];
5937   ptype = weed_paramtmpl_get_type(ptmpl);
5938 
5939   if (ptype == WEED_PARAM_INTEGER) {
5940     vali = weed_get_int_value(ptmpl, WEED_LEAF_MAX, NULL);
5941     msg = lives_strdup_printf("%d", vali);
5942   } else {
5943     vald = weed_get_double_value(ptmpl, WEED_LEAF_MAX, NULL);
5944     msg = lives_strdup_printf("%f", vald);
5945   }
5946   lives_status_send(msg);
5947   lives_free(msg);
5948   lives_free(in_ptmpls);
5949   return TRUE;
5950 }
5951 
5952 
lives_osc_cb_rte_getnparamdef(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)5953 boolean lives_osc_cb_rte_getnparamdef(void *context, int arglen, const void *vargs, OSCTimeTag when,
5954                                       NetworkReturnAddressPtr ra) {
5955   int effect_key;
5956   int pnum, i;
5957 
5958   // pick pnum which is numeric single valued, non-reinit
5959   // i.e. simple numeric parameter
5960 
5961   weed_plant_t *filter;
5962   weed_plant_t **in_ptmpls;
5963   weed_plant_t *ptmpl;
5964   int ptype;
5965 
5966   int vali;
5967   double vald;
5968 
5969   char *msg;
5970 
5971   if (!lives_osc_check_arguments(arglen, vargs, "ii", TRUE)) return lives_osc_notify_failure();
5972 
5973   lives_osc_parse_int_argument(vargs, &effect_key);
5974   lives_osc_parse_int_argument(vargs, &pnum);
5975 
5976   if (effect_key < 1 || effect_key > FX_MAX) return lives_osc_notify_failure();
5977   //g_print("key %d pnum %d",effect_key,pnum);
5978 
5979   filter = rte_keymode_get_filter(effect_key, rte_key_getmode(effect_key));
5980   if (!filter) return lives_osc_notify_failure();
5981 
5982   i = get_nth_simple_param(filter, pnum);
5983 
5984   if (i == -1) return lives_osc_notify_failure();
5985 
5986   in_ptmpls = weed_get_plantptr_array(filter, WEED_LEAF_IN_PARAMETER_TEMPLATES, NULL);
5987 
5988   ptmpl = in_ptmpls[i];
5989   ptype = weed_paramtmpl_get_type(ptmpl);
5990 
5991   if (ptype == WEED_PARAM_INTEGER) {
5992     if (!weed_plant_has_leaf(ptmpl, WEED_LEAF_HOST_DEFAULT)) vali = weed_get_int_value(ptmpl, WEED_LEAF_DEFAULT, NULL);
5993     else vali = weed_get_int_value(ptmpl, WEED_LEAF_HOST_DEFAULT, NULL);
5994     msg = lives_strdup_printf("%d", vali);
5995   } else {
5996     if (!weed_plant_has_leaf(ptmpl, WEED_LEAF_HOST_DEFAULT)) vald = weed_get_double_value(ptmpl, WEED_LEAF_DEFAULT, NULL);
5997     else vald = weed_get_double_value(ptmpl, WEED_LEAF_HOST_DEFAULT, NULL);
5998     msg = lives_strdup_printf("%f", vald);
5999   }
6000 
6001   lives_status_send(msg);
6002   lives_free(msg);
6003   lives_free(in_ptmpls);
6004   return TRUE;
6005 }
6006 
6007 
lives_osc_cb_rte_getnparamtrans(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)6008 boolean lives_osc_cb_rte_getnparamtrans(void *context, int arglen, const void *vargs, OSCTimeTag when,
6009                                         NetworkReturnAddressPtr ra) {
6010   // check if nparam is the transition parameter
6011   weed_plant_t *filter;
6012 
6013   int effect_key;
6014   int pnum;
6015   int nparams;
6016 
6017   if (!lives_osc_check_arguments(arglen, vargs, "ii", TRUE)) return lives_osc_notify_failure();
6018 
6019   lives_osc_parse_int_argument(vargs, &effect_key);
6020   lives_osc_parse_int_argument(vargs, &pnum);
6021 
6022   if (effect_key < 1 || effect_key > FX_MAX) return lives_osc_notify_failure();
6023   //g_print("key %d pnum %d",effect_key,pnum);
6024 
6025   filter = rte_keymode_get_filter(effect_key, rte_key_getmode(effect_key));
6026   if (!filter) return lives_osc_notify_failure();
6027 
6028   nparams = num_in_params(filter, FALSE, TRUE);
6029   if (pnum < 0 || pnum >= nparams) return lives_osc_notify_failure();
6030 
6031   if (pnum == get_transition_param(filter, TRUE)) return lives_status_send(get_omc_const("LIVES_TRUE"));
6032   return lives_status_send(get_omc_const("LIVES_FALSE"));
6033 }
6034 
6035 
lives_osc_cb_rte_getparamtrans(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)6036 boolean lives_osc_cb_rte_getparamtrans(void *context, int arglen, const void *vargs, OSCTimeTag when,
6037                                        NetworkReturnAddressPtr ra) {
6038   // check if param is the transition parameter
6039   weed_plant_t *filter;
6040   weed_plant_t *ptmpl;
6041 
6042   int effect_key;
6043   int mode;
6044   int pnum;
6045   int nparams;
6046 
6047   if (!lives_osc_check_arguments(arglen, vargs, "iii", FALSE)) {
6048     if (!lives_osc_check_arguments(arglen, vargs, "ii", TRUE)) return lives_osc_notify_failure();
6049     lives_osc_parse_int_argument(vargs, &effect_key);
6050     lives_osc_parse_int_argument(vargs, &pnum);
6051     mode = rte_key_getmode(effect_key);
6052   } else {
6053     lives_osc_check_arguments(arglen, vargs, "iii", TRUE);
6054     lives_osc_parse_int_argument(vargs, &effect_key);
6055     lives_osc_parse_int_argument(vargs, &mode);
6056     lives_osc_parse_int_argument(vargs, &pnum);
6057     if (mode < 1 || mode > rte_key_getmaxmode(effect_key) + 1) return lives_osc_notify_failure();
6058     mode--;
6059   }
6060 
6061   if (effect_key < 1 || effect_key > FX_MAX) return lives_osc_notify_failure();
6062   //g_print("key %d pnum %d",effect_key,pnum);
6063 
6064   filter = rte_keymode_get_filter(effect_key, mode);
6065   if (!filter) return lives_osc_notify_failure();
6066 
6067   nparams = num_in_params(filter, FALSE, TRUE);
6068   if (nparams == 0) return lives_osc_notify_failure();
6069   if (pnum < 0 || pnum >= nparams) return lives_osc_notify_failure();
6070 
6071   ptmpl = weed_filter_in_paramtmpl(filter, pnum, TRUE);
6072 
6073   if (weed_plant_has_leaf(ptmpl, WEED_LEAF_IS_TRANSITION) &&
6074       weed_get_boolean_value(ptmpl, WEED_LEAF_IS_TRANSITION, NULL) == WEED_TRUE)
6075     return lives_status_send(get_omc_const("LIVES_TRUE"));
6076   return lives_status_send(get_omc_const("LIVES_FALSE"));
6077 }
6078 
6079 
lives_osc_cb_rte_getmode(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)6080 boolean lives_osc_cb_rte_getmode(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
6081   char *tmp;
6082 
6083   int effect_key;
6084 
6085   if (!lives_osc_check_arguments(arglen, vargs, "i", TRUE)) return lives_osc_notify_failure();
6086   lives_osc_parse_int_argument(vargs, &effect_key);
6087 
6088   if (effect_key < 1 || effect_key > FX_MAX) {
6089     return lives_status_send("0");
6090   }
6091 
6092   lives_status_send((tmp = lives_strdup_printf("%d", rte_key_getmode(effect_key) + 1)));
6093   lives_free(tmp);
6094   return TRUE;
6095 }
6096 
6097 
lives_osc_cb_rte_getstate(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)6098 boolean lives_osc_cb_rte_getstate(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
6099   weed_plant_t *inst;
6100   int effect_key;
6101 
6102   if (!lives_osc_check_arguments(arglen, vargs, "i", TRUE)) return lives_osc_notify_failure();
6103   lives_osc_parse_int_argument(vargs, &effect_key);
6104 
6105   if (effect_key < 1 || effect_key > FX_KEYS_MAX_VIRTUAL) {
6106     return lives_status_send(get_omc_const("LIVES_FALSE"));
6107   }
6108   if ((inst = rte_keymode_get_instance(effect_key,
6109                                        rte_key_getmode(effect_key))) == NULL)
6110     return lives_status_send(get_omc_const("LIVES_FALSE"));
6111   weed_instance_unref(inst);
6112   return lives_status_send(get_omc_const("LIVES_TRUE"));
6113 }
6114 
6115 
lives_osc_cb_rte_get_keyfxname(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)6116 boolean lives_osc_cb_rte_get_keyfxname(void *context, int arglen, const void *vargs, OSCTimeTag when,
6117                                        NetworkReturnAddressPtr ra) {
6118   int effect_key;
6119   int mode;
6120   char *tmp;
6121 
6122   if (!lives_osc_check_arguments(arglen, vargs, "ii", TRUE)) return lives_osc_notify_failure();
6123   lives_osc_parse_int_argument(vargs, &effect_key);
6124   lives_osc_parse_int_argument(vargs, &mode);
6125   if (effect_key < 1 || effect_key > FX_MAX || mode < 1 || mode > rte_getmodespk()) return lives_osc_notify_failure();
6126   lives_status_send((tmp = lives_strdup_printf("%s", rte_keymode_get_filter_name(effect_key, mode - 1, FALSE))));
6127   lives_free(tmp);
6128   return TRUE;
6129 }
6130 
6131 
lives_osc_cb_rte_getmodespk(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)6132 boolean lives_osc_cb_rte_getmodespk(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
6133   int effect_key;
6134   char *tmp;
6135 
6136   if (!lives_osc_check_arguments(arglen, vargs, "i", FALSE)) {
6137     if (lives_osc_check_arguments(arglen, vargs, "", TRUE)) {
6138       lives_status_send((tmp = lives_strdup_printf("%d", rte_getmodespk())));
6139       lives_free(tmp);
6140       return TRUE;
6141     }
6142     return lives_osc_notify_failure();
6143   }
6144 
6145   lives_osc_check_arguments(arglen, vargs, "i", TRUE);
6146   lives_osc_parse_int_argument(vargs, &effect_key);
6147 
6148   if (effect_key > FX_KEYS_MAX_VIRTUAL || effect_key < 1) {
6149     return lives_status_send("0");
6150   }
6151 
6152   lives_status_send((tmp = lives_strdup_printf("%d", rte_key_getmaxmode(effect_key) + 1)));
6153   lives_free(tmp);
6154 
6155   return TRUE;
6156 }
6157 
6158 
lives_osc_cb_rte_addpconnection(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)6159 boolean lives_osc_cb_rte_addpconnection(void *context, int arglen, const void *vargs, OSCTimeTag when,
6160                                         NetworkReturnAddressPtr ra) {
6161   weed_plant_t *ofilter, *ifilter;
6162 
6163   int key0, mode0, pnum0;
6164   int key1, mode1, pnum1;
6165   int autoscale;
6166 
6167   if (!lives_osc_check_arguments(arglen, vargs, "iiiiiii", TRUE)) return lives_osc_notify_failure();
6168   lives_osc_parse_int_argument(vargs, &key0);
6169   lives_osc_parse_int_argument(vargs, &mode0);
6170   lives_osc_parse_int_argument(vargs, &pnum0);
6171 
6172   lives_osc_parse_int_argument(vargs, &autoscale);
6173 
6174   lives_osc_parse_int_argument(vargs, &key1);
6175   lives_osc_parse_int_argument(vargs, &mode1);
6176   lives_osc_parse_int_argument(vargs, &pnum1);
6177 
6178   if (key0 < 1 || key0 >= FX_KEYS_MAX_VIRTUAL || mode0 < 1 || mode0 > rte_getmodespk()) return lives_osc_notify_failure();
6179   if (key1 < -2 || key1 == 0 || key1 >= FX_KEYS_MAX_VIRTUAL || mode1 < 1 || (key1 >= 0 &&
6180       mode1 > rte_getmodespk())) return lives_osc_notify_failure();
6181 
6182   if (key0 == key1) return lives_osc_notify_failure();
6183 
6184   if (autoscale != TRUE && autoscale != FALSE) return lives_osc_notify_failure();
6185 
6186   mode0--;
6187   mode1--;
6188 
6189   ofilter = rte_keymode_get_filter(key0, mode0);
6190   if (!ofilter) return lives_osc_notify_failure();
6191 
6192   if (pnum0 >= num_out_params(ofilter)) return lives_osc_notify_failure();
6193 
6194   if (key1 == -1) {
6195     // connecting to the playback plugin
6196     if (mode1 > 1 || !mainw->vpp || pnum1 >= mainw->vpp->num_play_params) return lives_osc_notify_failure();
6197   } else if (key1 == -2) {
6198     // connecting to subtitler
6199     if (mode1 > 1 || pnum1 > 0) return lives_osc_notify_failure();
6200   } else {
6201     ifilter = rte_keymode_get_filter(key1, mode1);
6202     if (!ifilter) return lives_osc_notify_failure();
6203 
6204     if (pnum1 >= num_in_params(ifilter, FALSE, TRUE)) return lives_osc_notify_failure();
6205   }
6206 
6207   if (pnum0 < -EXTRA_PARAMS_OUT || pnum1 < -EXTRA_PARAMS_IN) return lives_osc_notify_failure();
6208 
6209   if (pconx_check_connection(ofilter, pnum0, key1, mode1, pnum1, FALSE, NULL, NULL, NULL, NULL,
6210                              NULL)) return lives_osc_notify_failure();
6211 
6212   key0--;
6213   key1--;
6214 
6215   pconx_add_connection(key0, mode0, pnum0, key1, mode1, pnum1, autoscale);
6216   return lives_osc_notify_success(NULL);
6217 }
6218 
6219 
lives_osc_cb_rte_delpconnection(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)6220 boolean lives_osc_cb_rte_delpconnection(void *context, int arglen, const void *vargs, OSCTimeTag when,
6221                                         NetworkReturnAddressPtr ra) {
6222   int key0, mode0, pnum0;
6223   int key1, mode1, pnum1;
6224 
6225   if (!lives_osc_check_arguments(arglen, vargs, "iiiiii", TRUE)) return lives_osc_notify_failure();
6226   lives_osc_parse_int_argument(vargs, &key0);
6227   lives_osc_parse_int_argument(vargs, &mode0);
6228   lives_osc_parse_int_argument(vargs, &pnum0);
6229   lives_osc_parse_int_argument(vargs, &key1);
6230   lives_osc_parse_int_argument(vargs, &mode1);
6231   lives_osc_parse_int_argument(vargs, &pnum1);
6232 
6233   if (key0 < 0 || key0 >= FX_KEYS_MAX_VIRTUAL || mode0 < 1 || mode0 > rte_getmodespk()) return lives_osc_notify_failure();
6234   if (key1 < -2 || key1 >= FX_KEYS_MAX_VIRTUAL || mode1 < 1 || mode1 > rte_getmodespk()) return lives_osc_notify_failure();
6235 
6236   if (pnum0 < -EXTRA_PARAMS_OUT || pnum1 < -EXTRA_PARAMS_IN) return lives_osc_notify_failure();
6237 
6238   pconx_delete(key0 == 0 ? FX_DATA_WILDCARD : key0 - 1, key0 == 0 ? FX_DATA_WILDCARD : --mode0,
6239                key0 == 0 ? FX_DATA_WILDCARD : pnum0, key1 == 0 ? FX_DATA_WILDCARD : key1 - 1,
6240                key1 == 0 ? FX_DATA_WILDCARD : --mode1, key1 == 0 ? FX_DATA_WILDCARD : pnum1);
6241   return lives_osc_notify_success(NULL);
6242 }
6243 
6244 
lives_osc_cb_rte_listpconnection(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)6245 boolean lives_osc_cb_rte_listpconnection(void *context, int arglen, const void *vargs, OSCTimeTag when,
6246     NetworkReturnAddressPtr ra) {
6247   int okey, omode, opnum;
6248   char *msg;
6249 
6250   if (!lives_osc_check_arguments(arglen, vargs, "iii", TRUE)) return lives_osc_notify_failure();
6251   lives_osc_parse_int_argument(vargs, &okey);
6252   lives_osc_parse_int_argument(vargs, &omode);
6253   lives_osc_parse_int_argument(vargs, &opnum);
6254 
6255   if (okey < 1 || okey >= FX_KEYS_MAX_VIRTUAL || omode < 1 || omode > rte_getmodespk()) return lives_osc_notify_failure();
6256 
6257   msg = pconx_list(okey, omode, opnum);
6258 
6259   if (!*msg) {
6260     lives_free(msg);
6261     msg = lives_strdup("0 0 0 0");
6262   }
6263 
6264   lives_status_send(msg);
6265   lives_free(msg);
6266   return TRUE;
6267 }
6268 
6269 
lives_osc_cb_rte_addcconnection(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)6270 boolean lives_osc_cb_rte_addcconnection(void *context, int arglen, const void *vargs, OSCTimeTag when,
6271                                         NetworkReturnAddressPtr ra) {
6272   int key0, mode0, cnum0;
6273   int key1, mode1, cnum1;
6274   weed_plant_t *filter;
6275 
6276   if (!lives_osc_check_arguments(arglen, vargs, "iiiiii", TRUE)) return lives_osc_notify_failure();
6277   lives_osc_parse_int_argument(vargs, &key0);
6278   lives_osc_parse_int_argument(vargs, &mode0);
6279   lives_osc_parse_int_argument(vargs, &cnum0);
6280   lives_osc_parse_int_argument(vargs, &key1);
6281   lives_osc_parse_int_argument(vargs, &mode1);
6282   lives_osc_parse_int_argument(vargs, &cnum1);
6283 
6284   if (key0 < 1 || key0 >= FX_KEYS_MAX_VIRTUAL || mode0 < 1 || mode0 > rte_getmodespk()) return lives_osc_notify_failure();
6285   if (key1 < -1 || key1 == 0 || key1 >= FX_KEYS_MAX_VIRTUAL || mode1 < 1 ||
6286       mode1 > rte_getmodespk()) return lives_osc_notify_failure();
6287 
6288   if (key0 == key1) return lives_osc_notify_failure();
6289 
6290   mode0--;
6291   mode1--;
6292 
6293   filter = rte_keymode_get_filter(key0, mode0);
6294   if (!filter) return lives_osc_notify_failure();
6295 
6296   if (cnum0 >= enabled_out_channels(filter, FALSE)) return lives_osc_notify_failure();
6297 
6298   if (key1 == -1) {
6299     // connecting to the playback plugin
6300     if (mode1 > 1 || !mainw->vpp || cnum1 >= mainw->vpp->num_alpha_chans) return lives_osc_notify_failure();
6301   } else {
6302     filter = rte_keymode_get_filter(key1, mode1);
6303     if (!filter) return lives_osc_notify_failure();
6304 
6305     if (cnum1 >= enabled_in_channels(filter, FALSE)) return lives_osc_notify_failure();
6306   }
6307 
6308   if (cconx_check_connection(key1, mode1, cnum1, FALSE, NULL, NULL, NULL, NULL, NULL)) return lives_osc_notify_failure();
6309 
6310   key0--;
6311   key1--;
6312 
6313   cconx_add_connection(key0, mode0, cnum0, key1, mode1, cnum1);
6314   return lives_osc_notify_success(NULL);
6315 }
6316 
6317 
lives_osc_cb_rte_delcconnection(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)6318 boolean lives_osc_cb_rte_delcconnection(void *context, int arglen, const void *vargs, OSCTimeTag when,
6319                                         NetworkReturnAddressPtr ra) {
6320   int key0, mode0, cnum0;
6321   int key1, mode1, cnum1;
6322 
6323   if (!lives_osc_check_arguments(arglen, vargs, "iiiiii", TRUE)) return lives_osc_notify_failure();
6324   lives_osc_parse_int_argument(vargs, &key0);
6325   lives_osc_parse_int_argument(vargs, &mode0);
6326   lives_osc_parse_int_argument(vargs, &cnum0);
6327   lives_osc_parse_int_argument(vargs, &key1);
6328   lives_osc_parse_int_argument(vargs, &mode1);
6329   lives_osc_parse_int_argument(vargs, &cnum1);
6330 
6331   if (key0 < 0 || key0 >= FX_KEYS_MAX_VIRTUAL || mode0 < 1 || mode0 > rte_getmodespk()) return lives_osc_notify_failure();
6332   if (key1 < -2 || key1 >= FX_KEYS_MAX_VIRTUAL || mode1 < 1 || mode1 > rte_getmodespk()) return lives_osc_notify_failure();
6333 
6334   cconx_delete(key0 == 0 ? FX_DATA_WILDCARD : --key0, --mode0, cnum0, key1 == 0 ? FX_DATA_WILDCARD : --key1, --mode1, cnum1);
6335 
6336   return lives_osc_notify_success(NULL);
6337 }
6338 
6339 
lives_osc_cb_rte_listcconnection(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)6340 boolean lives_osc_cb_rte_listcconnection(void *context, int arglen, const void *vargs, OSCTimeTag when,
6341     NetworkReturnAddressPtr ra) {
6342   int okey, omode, ocnum;
6343   char *msg;
6344 
6345   if (!lives_osc_check_arguments(arglen, vargs, "iii", TRUE)) return lives_osc_notify_failure();
6346   lives_osc_parse_int_argument(vargs, &okey);
6347   lives_osc_parse_int_argument(vargs, &omode);
6348   lives_osc_parse_int_argument(vargs, &ocnum);
6349 
6350   if (okey < 1 || okey >= FX_KEYS_MAX_VIRTUAL || omode < 1 || omode > rte_getmodespk()) return lives_osc_notify_failure();
6351 
6352   msg = cconx_list(okey, omode, ocnum);
6353 
6354   if (!*msg) {
6355     lives_free(msg);
6356     msg = lives_strdup("0 0 0");
6357   }
6358 
6359   lives_status_send(msg);
6360   lives_free(msg);
6361   return TRUE;
6362 }
6363 
6364 
lives_osc_cb_swap(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)6365 boolean lives_osc_cb_swap(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
6366   if (mainw->multitrack) return lives_osc_notify_failure();
6367   swap_fg_bg_callback(NULL, NULL, 0, (LiVESXModifierType)0, NULL);
6368   return lives_osc_notify_success(NULL);
6369 }
6370 
6371 
lives_osc_record_start(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)6372 boolean lives_osc_record_start(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
6373   if (mainw->multitrack) return lives_osc_notify_failure();
6374   record_toggle_callback(NULL, NULL, 0, (LiVESXModifierType)0, LIVES_INT_TO_POINTER((int)TRUE));
6375   return lives_osc_notify_success(NULL);
6376   // TODO - send record start and record stop events
6377 }
6378 
6379 
lives_osc_record_stop(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)6380 boolean lives_osc_record_stop(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
6381   if (mainw->multitrack) return lives_osc_notify_failure();
6382   record_toggle_callback(NULL, NULL, 0, (LiVESXModifierType)0, LIVES_INT_TO_POINTER((int)FALSE));
6383   return lives_osc_notify_success(NULL);
6384 }
6385 
6386 
lives_osc_record_toggle(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)6387 boolean lives_osc_record_toggle(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
6388   if (mainw->multitrack) return lives_osc_notify_failure();
6389   record_toggle_callback(NULL, NULL, 0, (LiVESXModifierType)0, LIVES_INT_TO_POINTER(!mainw->record));
6390   return lives_osc_notify_success(NULL);
6391 }
6392 
6393 
lives_osc_cb_ping(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)6394 boolean lives_osc_cb_ping(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
6395   //g_print("send pong\n");
6396   return lives_status_send("pong");
6397 }
6398 
6399 
lives_osc_cb_getsetname(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)6400 boolean lives_osc_cb_getsetname(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
6401   return lives_status_send(mainw->set_name);
6402 }
6403 
6404 
lives_osc_cb_open_file(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)6405 boolean lives_osc_cb_open_file(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
6406   char filename[OSC_STRING_SIZE];
6407   float starttime = 0.;
6408   int numframes = 0; // all frames by default
6409 
6410   int type = 0;
6411 
6412   if ((mainw->preview || (!mainw->multitrack && mainw->event_list)) || mainw->is_processing ||
6413       mainw->multitrack) return lives_osc_notify_failure();
6414 
6415   if (LIVES_IS_PLAYING) return lives_osc_notify_failure();
6416 
6417   if (!lives_osc_check_arguments(arglen, vargs, "sfi", FALSE)) {
6418     type++;
6419     if (!lives_osc_check_arguments(arglen, vargs, "sf", FALSE)) {
6420       type++;
6421       if (!lives_osc_check_arguments(arglen, vargs, "s", TRUE)) return lives_osc_notify_failure();
6422     } else lives_osc_check_arguments(arglen, vargs, "sf", TRUE);
6423   } else lives_osc_check_arguments(arglen, vargs, "sfi", TRUE);
6424 
6425   lives_osc_parse_string_argument(vargs, filename);
6426   if (type < 2) {
6427     lives_osc_parse_float_argument(vargs, &starttime);
6428     if (type < 1) {
6429       lives_osc_parse_int_argument(vargs, &numframes);
6430     }
6431   }
6432   deduce_file(filename, starttime, numframes);
6433   return lives_osc_notify_success(NULL);
6434 }
6435 
6436 
lives_osc_cb_open_unicap(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)6437 boolean lives_osc_cb_open_unicap(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
6438 #ifdef HAVE_UNICAP
6439   char devname[OSC_STRING_SIZE];
6440   int deint = FALSE;
6441 
6442   char *boolstr;
6443 
6444   if ((mainw->preview || (!mainw->multitrack && mainw->event_list)) || mainw->is_processing ||
6445       mainw->multitrack) return lives_osc_notify_failure();
6446 
6447   if (!lives_osc_check_arguments(arglen, vargs, "si", FALSE)) {
6448     if (lives_osc_check_arguments(arglen, vargs, "s", FALSE)) {
6449       lives_osc_parse_string_argument(vargs, devname);
6450     } else return lives_osc_notify_failure();
6451   } else {
6452     lives_osc_parse_string_argument(vargs, devname);
6453     lives_osc_parse_int_argument(vargs, &deint);
6454     boolstr = lives_strdup_printf("%d", deint);
6455     if (!strcmp(boolstr, get_omc_const("LIVES_TRUE"))) deint = TRUE;
6456     else {
6457       if (!strcmp(boolstr, get_omc_const("LIVES_FALSE"))) deint = FALSE;
6458       else {
6459         lives_free(boolstr);
6460         return lives_osc_notify_failure();
6461       }
6462     }
6463     lives_free(boolstr);
6464   }
6465 
6466   mainw->open_deint = deint;
6467 
6468   on_open_vdev_activate(NULL, (livespointer)devname);
6469 
6470   return lives_osc_notify_success(NULL);
6471 
6472 #endif
6473 
6474   return lives_osc_notify_failure();
6475 }
6476 
6477 
lives_osc_cb_new_audio(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)6478 boolean lives_osc_cb_new_audio(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
6479   char filename[OSC_STRING_SIZE];
6480 
6481   if ((mainw->preview || (!mainw->multitrack && mainw->event_list)) || mainw->is_processing ||
6482       mainw->multitrack) return lives_osc_notify_failure();
6483 
6484   if (LIVES_IS_PLAYING) return lives_osc_notify_failure();
6485 
6486   if (!CURRENT_CLIP_HAS_VIDEO || cfile->opening) return lives_osc_notify_failure();
6487 
6488   if (!lives_osc_check_arguments(arglen, vargs, "s", TRUE)) return lives_osc_notify_failure();
6489 
6490   lives_osc_parse_string_argument(vargs, filename);
6491   on_open_new_audio_clicked(NULL, filename);
6492   return lives_osc_notify_success(NULL);
6493 }
6494 
6495 
lives_osc_cb_loadset(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)6496 boolean lives_osc_cb_loadset(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
6497   char setname[OSC_STRING_SIZE];
6498 
6499   char *tmp;
6500 
6501   if ((mainw->preview || (!mainw->multitrack && mainw->event_list)) || mainw->is_processing ||
6502       mainw->multitrack) return lives_osc_notify_failure();
6503 
6504   if (LIVES_IS_PLAYING) return lives_osc_notify_failure();
6505 
6506   if (*mainw->set_name) return lives_osc_notify_failure();
6507 
6508   if (!lives_osc_check_arguments(arglen, vargs, "s", TRUE)) {
6509     return lives_osc_notify_failure();
6510   }
6511   lives_osc_parse_string_argument(vargs, setname);
6512 
6513   mainw->osc_auto = 1;
6514   if (!is_legal_set_name((tmp = U82F(setname)), TRUE, TRUE)) {
6515     mainw->osc_auto = 0;
6516     lives_free(tmp);
6517     return lives_osc_notify_failure();
6518   }
6519   mainw->osc_auto = 0;
6520 
6521   lives_free(tmp);
6522 
6523   reload_set(setname);
6524   return lives_osc_notify_success(NULL);
6525 }
6526 
6527 
lives_osc_cb_saveset(void * context,int arglen,const void * vargs,OSCTimeTag when,NetworkReturnAddressPtr ra)6528 boolean lives_osc_cb_saveset(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra) {
6529   boolean ret;
6530   int force_append = FALSE;
6531   char setname[OSC_STRING_SIZE];
6532 
6533   char *tmp;
6534   char *boolstr;
6535 
6536   // setname should be in filesystem encoding
6537 
6538   lives_memset(setname, 0, 1);
6539 
6540   if ((mainw->preview || (!mainw->multitrack && mainw->event_list)) || mainw->is_processing ||
6541       mainw->multitrack) return lives_osc_notify_failure();
6542 
6543   if (LIVES_IS_PLAYING) return lives_osc_notify_failure();
6544 
6545   if (!lives_osc_check_arguments(arglen, vargs, "s", TRUE)) {
6546     if (!lives_osc_check_arguments(arglen, vargs, "si", TRUE)) {
6547       if (!lives_osc_check_arguments(arglen, vargs, "", TRUE)) {
6548         return lives_osc_notify_failure();
6549       }
6550     } else {
6551       lives_osc_parse_string_argument(vargs, setname);
6552       lives_osc_parse_int_argument(vargs, &force_append);
6553       boolstr = lives_strdup_printf("%d", force_append);
6554       if (!strcmp(boolstr, get_omc_const("LIVES_TRUE"))) force_append = TRUE;
6555       else {
6556         if (!strcmp(boolstr, get_omc_const("LIVES_FALSE"))) force_append = FALSE;
6557         else {
6558           lives_free(boolstr);
6559           return lives_osc_notify_failure();
6560         }
6561       }
6562       lives_free(boolstr);
6563     }
6564   } else {
6565     lives_osc_parse_string_argument(vargs, setname);
6566   }
6567 
6568   if (!*setname) {
6569     mainw->only_close = TRUE;
6570     ret = on_save_set_activate(NULL, NULL);
6571     mainw->only_close = FALSE;
6572     if (ret) return lives_osc_notify_success(NULL);
6573     else return lives_osc_notify_failure();
6574   }
6575 
6576   if (is_legal_set_name((tmp = U82F(setname)), TRUE, FALSE)) {
6577     mainw->only_close = TRUE;
6578     if (force_append) mainw->osc_auto = 2;
6579     else mainw->osc_auto = 1;
6580     ret = on_save_set_activate(NULL, setname);
6581     mainw->osc_auto = 0;
6582     mainw->only_close = FALSE;
6583     lives_free(tmp);
6584     if (ret) return lives_osc_notify_success(NULL);
6585     else return lives_osc_notify_failure();
6586   }
6587 
6588   lives_free(tmp);
6589 
6590   return lives_osc_notify_failure();
6591 }
6592 
6593 typedef void (*osc_cb)(void *context, int arglen, const void *vargs, OSCTimeTag when, NetworkReturnAddressPtr ra);
6594 
6595 static struct {
6596   char	 *descr;
6597   char	 *name;
6598   void (*cb)(void *ctx, int len, const void *vargs, OSCTimeTag when,	NetworkReturnAddressPtr ra);
6599   int		 leave; // leaf
6600 } osc_methods[] = {
6601   { "/record/enable",		"enable",	(osc_cb)lives_osc_record_start,			3	},
6602   { "/record/disable",	"disable",	(osc_cb)lives_osc_record_stop,			3	},
6603   { "/record/toggle",	        "toggle",	(osc_cb)lives_osc_record_toggle,			3	},
6604   { "/video/play",		"play",	(osc_cb)lives_osc_cb_play,			5	},
6605   { "/video/selection/play",		"play",	(osc_cb)lives_osc_cb_playsel,			46	},
6606   { "/video/play/forwards",		"forwards",	(osc_cb)lives_osc_cb_play_forward,			36	},
6607   { "/video/play/backwards",		"backwards",	(osc_cb)lives_osc_cb_play_backward,			36	},
6608   { "/video/play/faster",		"faster",	(osc_cb)lives_osc_cb_play_faster,			36	},
6609   { "/clip/foreground/fps/faster",		"faster",	(osc_cb)lives_osc_cb_play_faster,			61	},
6610   { "/clip/foreground/fps/get",		"get",	(osc_cb)lives_osc_cb_clip_getfps,			61	},
6611   { "/clip/background/fps/faster",		"faster",	(osc_cb)lives_osc_cb_bgplay_faster,			63	},
6612   { "/clip/background/fps/get",		"get",	(osc_cb)lives_osc_cb_bgclip_getfps,			63	},
6613   { "/video/play/slower",		"slower",	(osc_cb)lives_osc_cb_play_slower,			36	},
6614   { "/clip/foreground/fps/slower",		"slower",	(osc_cb)lives_osc_cb_play_slower,			61	},
6615   { "/clip/background/fps/slower",		"slower",	(osc_cb)lives_osc_cb_bgplay_slower,			63	},
6616   { "/video/play/reset",		"reset",	(osc_cb)lives_osc_cb_play_reset,			36	},
6617   { "/video/play/parameter/count",		"set",	(osc_cb)lives_osc_cb_rte_pparamcount,			140	},
6618   { "/video/play/parameter/value/set",		"set",	(osc_cb)lives_osc_cb_rte_setpparam,			140	},
6619   { "/video/play/parameter/flags/get",		"get",	(osc_cb)lives_osc_cb_rte_getpparamflags,        141	},
6620   { "/video/play/parameter/min/get",		"get",	(osc_cb)lives_osc_cb_rte_getpparammin,		        142	},
6621   { "/video/play/parameter/max/get",		"get",	(osc_cb)lives_osc_cb_rte_getpparammax,		        143	},
6622   { "/video/play/parameter/type/get",		"get",	(osc_cb)lives_osc_cb_rte_getpparamtype,		        144	},
6623   { "/video/play/parameter/name/get",		"get",	(osc_cb)lives_osc_cb_rte_getpparamname,		        145	},
6624   { "/video/play/parameter/colorspace/get",		"get",	(osc_cb)lives_osc_cb_rte_getpparamcspace,      	        146	},
6625   { "/video/play/parameter/default/get",		"get",	(osc_cb)lives_osc_cb_rte_getpparamdef,		        147	},
6626   { "/video/play/parameter/value/get",		"get",	(osc_cb)lives_osc_cb_rte_getpparamval,		        140	},
6627   { "/clip/foreground/fps/reset",		"reset",	(osc_cb)lives_osc_cb_play_reset,			61	},
6628   { "/clip/background/fps/reset",		"reset",	(osc_cb)lives_osc_cb_bgplay_reset,			63	},
6629   { "/video/stop",		"stop", (osc_cb)lives_osc_cb_stop,				5	},
6630   { "/video/fps/set",	       "set",	(osc_cb)lives_osc_cb_set_fps,			40	},
6631   { "/video/fps/get",	       "get",	(osc_cb)lives_osc_cb_clip_getfps,			40	},
6632   { "/video/loop/set",	       "set",	(osc_cb)lives_osc_cb_set_loop,			38	},
6633   { "/video/loop/get",	       "get",	(osc_cb)lives_osc_cb_get_loop,			38	},
6634   { "/video/pingpong/set",	       "set",	(osc_cb)lives_osc_cb_set_pingpong,			39	},
6635   { "/video/pingpong/get",	       "get",	(osc_cb)lives_osc_cb_get_pingpong,			39	},
6636   { "/lives/mode/set",	       "set",	(osc_cb)lives_osc_cb_setmode,			103	},
6637   { "/lives/mode/get",	       "get",	(osc_cb)lives_osc_cb_getmode,			103	},
6638   { "/video/fps/ratio/set",	       "set",	(osc_cb)lives_osc_cb_set_fps_ratio,			65	},
6639   { "/video/fps/ratio/get",	       "get",	(osc_cb)lives_osc_cb_get_fps_ratio,			65	},
6640   { "/video/play/time/get",	       "get",	(osc_cb)lives_osc_cb_get_playtime,			67	},
6641   { "/audio/mute/get",	       "get",	(osc_cb)lives_osc_cb_get_amute,			300	},
6642   { "/audio/mute/set",	       "set",	(osc_cb)lives_osc_cb_set_amute,			300	},
6643   { "/audio/volume/get",	       "get",	(osc_cb)lives_osc_cb_get_avol,			301	},
6644   { "/audio/volume/set",	       "set",	(osc_cb)lives_osc_cb_set_avol,			301	},
6645   { "/audio/source/get",	       "get",	(osc_cb)lives_osc_cb_pref_get_audio_source,			302	},
6646   { "/audio/source/set",	       "set",	(osc_cb)lives_osc_cb_pref_set_audio_source,			302	},
6647   { "/clip/foreground/fps/set",	"set",	(osc_cb)lives_osc_cb_set_fps,			61	},
6648   { "/clip/background/fps/set",	"set",	(osc_cb)lives_osc_cb_bgset_fps,			63	},
6649   { "/clip/foreground/fps/ratio/set",	"set",	(osc_cb)lives_osc_cb_set_fps_ratio,			64	},
6650   { "/clip/foreground/fps/ratio/get",	"get",	(osc_cb)lives_osc_cb_get_fps_ratio,			64	},
6651   { "/clip/background/fps/ratio/set",	"set",	(osc_cb)lives_osc_cb_bgset_fps_ratio,			66	},
6652   { "/clip/background/fps/ratio/get",	"get",	(osc_cb)lives_osc_cb_bgget_fps_ratio,			66	},
6653   { "/video/play/reverse",		"reverse",	(osc_cb)lives_osc_cb_play_reverse,		36	},
6654   { "/clip/foreground/fps/reverse",	"reverse",	(osc_cb)lives_osc_cb_play_reverse,		61	},
6655   { "/clip/background/fps/reverse",	"reverse",	(osc_cb)lives_osc_cb_bgplay_reverse,		63	},
6656   { "/video/freeze/toggle",		"toggle", (osc_cb)lives_osc_cb_freeze,		37	},
6657   { "/effects/realtime/name/get",		"get",	(osc_cb)lives_osc_cb_fx_getname,			115	},
6658   { "/effect_key/map",		"map",	(osc_cb)lives_osc_cb_fx_map,			25	},
6659   { "/effect_key/unmap",		"unmap",	(osc_cb)lives_osc_cb_fx_unmap,			25	},
6660   { "/effect_key/map/clear",		"clear",	(osc_cb)lives_osc_cb_fx_map_clear,			32	},
6661   { "/effect_key/reset",		"reset",	(osc_cb)lives_osc_cb_fx_reset,			25	},
6662   { "/effect_key/enable",		"enable",	(osc_cb)lives_osc_cb_fx_enable,		        25	},
6663   { "/effect_key/disable",		"disable",	(osc_cb)lives_osc_cb_fx_disable,		        25	},
6664   { "/effect_key/toggle",		"toggle",	(osc_cb)lives_osc_cb_fx_toggle,		        25	},
6665   { "/effect_key/count",		"count",	(osc_cb)lives_osc_cb_rte_count,		        25	},
6666   { "/effect_key/parameter/value/set",		"set",	(osc_cb)lives_osc_cb_rte_setparam,		        42	},
6667   { "/effect_key/parameter/type/get",		"get",	(osc_cb)lives_osc_cb_rte_getparamtype,		        68	},
6668   { "/effect_key/outparameter/type/get",		"get",	(osc_cb)lives_osc_cb_rte_getoparamtype,		        153	},
6669   { "/effect_key/nparameter/type/get",		"get",	(osc_cb)lives_osc_cb_rte_getnparamtype,		        116	},
6670   { "/effect_key/parameter/name/get",		"get",	(osc_cb)lives_osc_cb_rte_getparamname,		        71	},
6671   { "/effect_key/outparameter/name/get",		"get",	(osc_cb)lives_osc_cb_rte_getoparamname,		        152	},
6672   { "/effect_key/nparameter/name/get",		"get",	(osc_cb)lives_osc_cb_rte_getnparamname,		        72	},
6673   { "/effect_key/parameter/colorspace/get",		"get",	(osc_cb)lives_osc_cb_rte_getparamcspace,		        73	},
6674   { "/effect_key/outparameter/colorspace/get",		"get",	(osc_cb)lives_osc_cb_rte_getoparamcspace,		        154	},
6675   { "/effect_key/parameter/flags/get",		"get",	(osc_cb)lives_osc_cb_rte_getparamflags,		        74	},
6676   { "/effect_key/parameter/min/get",		"get",	(osc_cb)lives_osc_cb_rte_getparammin,		        75	},
6677   { "/effect_key/parameter/max/get",		"get",	(osc_cb)lives_osc_cb_rte_getparammax,		        76	},
6678   { "/effect_key/parameter/default/get",		"get",	(osc_cb)lives_osc_cb_rte_getparamdef,		        77	},
6679   { "/effect_key/parameter/default/set",		"set",	(osc_cb)lives_osc_cb_rte_setparamdef,		        77	},
6680   { "/effect_key/parameter/group/get",		"get",	(osc_cb)lives_osc_cb_rte_getparamgrp,		        78	},
6681   { "/effect_key/parameter/gui/choices/count",	"count",	(osc_cb)lives_osc_cb_pgui_countchoices,		        181	},
6682   { "/effect_key/parameter/gui/choices/get",	"get", (osc_cb)lives_osc_cb_pgui_getchoice,		        181	},
6683   { "/effect_key/outparameter/min/get",		"get",	(osc_cb)lives_osc_cb_rte_getoparammin,		        156	},
6684   { "/effect_key/outparameter/max/get",		"get",	(osc_cb)lives_osc_cb_rte_getoparammax,		        157	},
6685   { "/effect_key/outparameter/default/get",		"get",	(osc_cb)lives_osc_cb_rte_getoparamdef,		        158	},
6686   { "/effect_key/outparameter/has_min",		"has_min",	(osc_cb)lives_osc_cb_rte_getohasparammin,		        150	},
6687   { "/effect_key/outparameter/has_max",		"has_max",	(osc_cb)lives_osc_cb_rte_getohasparammax,		        150	},
6688   { "/effect_key/outparameter/has_default",		"has_default",	(osc_cb)lives_osc_cb_rte_getohasparamdef,		        150	},
6689   { "/effect_key/parameter/has_default",		"has_default",	(osc_cb)lives_osc_cb_rte_gethasparamdef,		        41	},
6690   { "/effect_key/parameter/value/get",		"get",	(osc_cb)lives_osc_cb_rte_getparamval,		        42	},
6691   { "/effect_key/outparameter/value/get",		"get",	(osc_cb)lives_osc_cb_rte_getoparamval,		        155	},
6692   { "/effect_key/nparameter/count",		"count",	(osc_cb)lives_osc_cb_rte_nparamcount,		        91	},
6693   { "/effect_key/parameter/count",		"count",	(osc_cb)lives_osc_cb_rte_paramcount,		        41	},
6694   { "/effect_key/outparameter/count",		"count",	(osc_cb)lives_osc_cb_rte_oparamcount,		        150	},
6695   { "/effect_key/nparameter/value/set",		"set",	(osc_cb)lives_osc_cb_rte_setnparam,		        92	},
6696   { "/effect_key/nparameter/value/get",		"get",	(osc_cb)lives_osc_cb_rte_getnparam,		        92	},
6697   { "/effect_key/nparameter/min/get",		"get",	(osc_cb)lives_osc_cb_rte_getnparammin,		        93	},
6698   { "/effect_key/nparameter/max/get",		"get",	(osc_cb)lives_osc_cb_rte_getnparammax,		        94	},
6699   { "/effect_key/nparameter/default/get",		"get",	(osc_cb)lives_osc_cb_rte_getnparamdef,		        95	},
6700   { "/effect_key/nparameter/default/set",		"set",	(osc_cb)lives_osc_cb_rte_setnparamdef,		        95	},
6701   { "/effect_key/nparameter/is_transition",		"is_transition",	(osc_cb)lives_osc_cb_rte_getnparamtrans,		        91	},
6702   { "/effect_key/parameter/is_transition",		"is_transition",	(osc_cb)lives_osc_cb_rte_getparamtrans,		        41	},
6703   { "/effect_key/inchannel/active/count",		"count",	(osc_cb)lives_osc_cb_rte_getnchannels,		        131	},
6704   { "/effect_key/inchannel/palette/get",		"get",	(osc_cb)lives_osc_cb_rte_getinpal,		        132	},
6705   { "/effect_key/outchannel/active/count",		"count",	(osc_cb)lives_osc_cb_rte_getnochannels,		        171	},
6706   { "/effect_key/outchannel/palette/get",		"get",	(osc_cb)lives_osc_cb_rte_getoutpal,		        162	},
6707   { "/effect_key/mode/set",		"set",	(osc_cb)lives_osc_cb_rte_setmode,		        43	},
6708   { "/effect_key/mode/get",		"get",	(osc_cb)lives_osc_cb_rte_getmode,		        43	},
6709   { "/effect_key/mode/next",		"next",	(osc_cb)lives_osc_cb_rte_nextmode,		        43	},
6710   { "/effect_key/mode/previous",	"previous",	(osc_cb)lives_osc_cb_rte_prevmode,		        43	},
6711   { "/effect_key/name/get",		"get",	(osc_cb)lives_osc_cb_rte_get_keyfxname,		        44	},
6712   { "/effect_key/maxmode/get",		"get",	(osc_cb)lives_osc_cb_rte_getmodespk,		        45	},
6713   { "/effect_key/state/get",		"get",	(osc_cb)lives_osc_cb_rte_getstate,		        56	},
6714   { "/effect_key/outparameter/connection/add",		"add",	(osc_cb)lives_osc_cb_rte_addpconnection,		        151	},
6715   { "/effect_key/outparameter/connection/delete",		"delete",	(osc_cb)lives_osc_cb_rte_delpconnection,		        151	},
6716   { "/effect_key/outparameter/connection/list",		"list",	(osc_cb)lives_osc_cb_rte_listpconnection,		        151	},
6717   { "/effect_key/outchannel/connection/add",		        "add",	(osc_cb)lives_osc_cb_rte_addcconnection,		        161	},
6718   { "/effect_key/outchannel/connection/delete",		"delete",	(osc_cb)lives_osc_cb_rte_delcconnection,		        161	},
6719   { "/effect_key/outchannel/connection/list",		"list",	(osc_cb)lives_osc_cb_rte_listcconnection,		        161	},
6720   { "/clip/encode_as",		"encode_as",	(osc_cb)lives_osc_cb_clip_encodeas,			1	},
6721   { "/clip/select",		"select",	(osc_cb)lives_osc_cb_fgclip_select,			1	},
6722   { "/clip/close",		"close",	(osc_cb)lives_osc_cb_clip_close,	  		        1	},
6723   { "/clip/copy",		"copy",	(osc_cb)lives_osc_cb_fgclip_copy,	  		        1	},
6724   { "/clip/undo",		"undo",	(osc_cb)lives_osc_cb_clip_undo,	  		        1	},
6725   { "/clip/redo",		"redo",	(osc_cb)lives_osc_cb_clip_redo,	  		        1	},
6726   { "/clip/selection/copy",		"copy",	(osc_cb)lives_osc_cb_fgclipsel_copy,	  		        55	},
6727   { "/clip/selection/cut",		"cut",	(osc_cb)lives_osc_cb_fgclipsel_cut,	  		        55	},
6728   { "/clip/selection/delete",		"delete",	(osc_cb)lives_osc_cb_fgclipsel_delete,	  		        55	},
6729   { "/clip/selection/rte_apply",		"rte_apply",	(osc_cb)lives_osc_cb_fgclipsel_rteapply,	  		        55	},
6730   { "/clipboard/paste",		"paste",	(osc_cb)lives_osc_cb_clipbd_paste,			70	},
6731   { "/clipboard/insert_before",		"insert_before",	(osc_cb)lives_osc_cb_clipbd_insertb,			70	},
6732   { "/clipboard/insert_after",		"insert_after",	(osc_cb)lives_osc_cb_clipbd_inserta,			70	},
6733   { "/clip/retrigger",		"retrigger",	(osc_cb)lives_osc_cb_fgclip_retrigger,			1	},
6734   { "/clip/resample",		        "resample",	(osc_cb)lives_osc_cb_clip_resample,			1	},
6735   { "/clip/select/next",		"next",	(osc_cb)lives_osc_cb_fgclip_select_next,			54	},
6736   { "/clip/select/previous",		"previous",	(osc_cb)lives_osc_cb_fgclip_select_previous,			54	},
6737   { "/clip/foreground/select",		"select",	(osc_cb)lives_osc_cb_fgclip_select,			47	},
6738   { "/clip/background/select",		"select",	(osc_cb)lives_osc_cb_bgclip_select,			48	},
6739   { "/clip/foreground/retrigger",		"retrigger",	(osc_cb)lives_osc_cb_fgclip_retrigger,			47	},
6740   { "/clip/background/retrigger",		"retrigger",	(osc_cb)lives_osc_cb_bgclip_retrigger,			48	},
6741   { "/clip/foreground/set",		"set",	(osc_cb)lives_osc_cb_fgclip_set,			47	},
6742   { "/clip/background/set",		"set",	(osc_cb)lives_osc_cb_bgclip_set,			48	},
6743   { "/clip/foreground/get",		"get",	(osc_cb)lives_osc_cb_clip_get_current,			47	},
6744   { "/clip/background/get",		"get",	(osc_cb)lives_osc_cb_bgclip_get_current,			48	},
6745   { "/clip/foreground/next",		"next",	(osc_cb)lives_osc_cb_fgclip_select_next,			47	},
6746   { "/clip/background/next",		"next",	(osc_cb)lives_osc_cb_bgclip_select_next,			48	},
6747   { "/clip/foreground/previous",		"previous",	(osc_cb)lives_osc_cb_fgclip_select_previous,			47	},
6748   { "/clip/background/previous",		"previous",	(osc_cb)lives_osc_cb_bgclip_select_previous,			48	},
6749   { "/lives/quit",	         "quit", (osc_cb)lives_osc_cb_quit,			21	},
6750   { "/lives/version/get",	         "get", (osc_cb)lives_osc_cb_getversion,			24	},
6751   { "/lives/status/get",	         "get", (osc_cb)lives_osc_cb_getstatus,			122	},
6752   { "/lives/constant/value/get",	         "get", (osc_cb)lives_osc_cb_getconst,			121	},
6753   { "/app/quit",	         "quit", (osc_cb)lives_osc_cb_quit,			22	},
6754   { "/app/name",	         "name", (osc_cb)lives_osc_cb_getname,			22	},
6755   { "/app/name/get",	         "get", (osc_cb)lives_osc_cb_getname,			23	},
6756   { "/app/version/get",	         "get", (osc_cb)lives_osc_cb_getversion,			125	},
6757   { "/quit",	         "quit", (osc_cb)lives_osc_cb_quit,			2	},
6758   { "/reply_to",	         "reply_to", (osc_cb)lives_osc_cb_open_status_socket,			2	},
6759   { "/lives/open_status_socket",	         "open_status_socket", (osc_cb)lives_osc_cb_open_status_socket,			21	},
6760   { "/app/open_status_socket",	         "open_status_socket", (osc_cb)lives_osc_cb_open_status_socket,			22	},
6761   { "/app/ping",	         "ping", (osc_cb)lives_osc_cb_ping,			22	},
6762   { "/lives/ping",	         "ping", (osc_cb)lives_osc_cb_ping,			21	},
6763   { "/ping",	         "ping", (osc_cb)lives_osc_cb_ping,			2	},
6764   { "/notify_to",	         "notify_to", (osc_cb)lives_osc_cb_open_notify_socket,			2	},
6765   { "/lives/open_notify_socket",	         "open_notify_socket", (osc_cb)lives_osc_cb_open_notify_socket,			21	},
6766   { "/notify/confirmations/set",	         "set", (osc_cb)lives_osc_cb_notify_c,			101	},
6767   { "/notify/events/set",	         "set", (osc_cb)lives_osc_cb_notify_e,			102	},
6768   { "/clip/count",	         "count", (osc_cb)lives_osc_cb_clip_count,			1  },
6769   { "/clip/goto",	         "goto", (osc_cb)lives_osc_cb_clip_goto,			1	},
6770   { "/clip/foreground/frame/set",	         "set", (osc_cb)lives_osc_cb_clip_goto,			60	},
6771   { "/clip/foreground/frame/get",	         "get", (osc_cb)lives_osc_cb_clip_getframe,			60	},
6772   { "/clip/background/frame/set",	         "set", (osc_cb)lives_osc_cb_bgclip_goto,			62	},
6773   { "/clip/background/frame/get",	         "get", (osc_cb)lives_osc_cb_bgclip_getframe,			62	},
6774   { "/clip/is_valid/get",	         "get", (osc_cb)lives_osc_cb_clip_isvalid,			49	},
6775   { "/clip/frame/count",	         "count", (osc_cb)lives_osc_cb_clip_get_frames,			57	},
6776   { "/clip/frame/save_as_image",	         "save_as_image", (osc_cb)lives_osc_cb_clip_save_frame,			57	},
6777   { "/clip/select_all",	         "select_all", (osc_cb)lives_osc_cb_clip_select_all,			1	},
6778   { "/clip/start/set",	 "set", (osc_cb)lives_osc_cb_clip_set_start,			50	},
6779   { "/clip/start/get",	 "get", (osc_cb)lives_osc_cb_clip_get_start,			50	},
6780   { "/clip/end/set",	 "set", (osc_cb)lives_osc_cb_clip_set_end,			51	},
6781   { "/clip/end/get",	 "get", (osc_cb)lives_osc_cb_clip_get_end,			51	},
6782   { "/clip/size/get",	 "get", (osc_cb)lives_osc_cb_clip_get_size,			58	},
6783   { "/clip/name/get",	 "get", (osc_cb)lives_osc_cb_clip_get_name,			59	},
6784   { "/clip/name/set",	 "set", (osc_cb)lives_osc_cb_clip_set_name,			59	},
6785   { "/clip/fps/get",	 "get", (osc_cb)lives_osc_cb_clip_get_ifps,			113	},
6786   { "/clip/open/file",	 "file", (osc_cb)lives_osc_cb_open_file,			33	},
6787   { "/clip/open/unicap",	 "unicap", (osc_cb)lives_osc_cb_open_unicap,			33	},
6788   { "/clip/audio/new",	 "new", (osc_cb)lives_osc_cb_new_audio,			108	},
6789   { "/output/fullscreen/enable",		"enable",	(osc_cb)lives_osc_cb_fssepwin_enable,		28	},
6790   { "/output/fullscreen/disable",		"disable",	(osc_cb)lives_osc_cb_fssepwin_disable,       	28	},
6791   { "/output/fps/set",		"set",	(osc_cb)lives_osc_cb_op_fps_set,       	52	},
6792   { "/output/nodrop/enable",		"enable",	(osc_cb)lives_osc_cb_op_nodrope,       	30	},
6793   { "/output/nodrop/disable",		"disable",	(osc_cb)lives_osc_cb_op_nodropd,       	30	},
6794   { "/clip/foreground/background/swap",		"swap",	(osc_cb)lives_osc_cb_swap,       	53	},
6795   { "/clipset/load",		"load",	(osc_cb)lives_osc_cb_loadset,       	35	},
6796   { "/clipset/save",		"save",	(osc_cb)lives_osc_cb_saveset,       	35	},
6797   { "/clipset/name/get",		"get",	(osc_cb)lives_osc_cb_getsetname,       	135	},
6798   { "/layout/clear",		"clear",	(osc_cb)lives_osc_cb_clearlay,       	104	},
6799   { "/block/count",		"count",	(osc_cb)lives_osc_cb_blockcount,       	105	},
6800   { "/block/insert",		"insert",	(osc_cb)lives_osc_cb_blockinsert,       	105	},
6801   { "/block/start/time/get",		"get",	(osc_cb)lives_osc_cb_blockstget,       	111	},
6802   { "/block/end/time/get",		"get",	(osc_cb)lives_osc_cb_blockenget,       	112	},
6803   { "/mt/time/get",		"get",	(osc_cb)lives_osc_cb_mtctimeget,       	201	},
6804   { "/mt/time/set",		"set",	(osc_cb)lives_osc_cb_mtctimeset,       	201	},
6805   { "/mt/ctrack/get",		"get",	(osc_cb)lives_osc_cb_mtctrackget,       	201	},
6806   { "/mt/ctrack/set",		"set",	(osc_cb)lives_osc_cb_mtctrackset,       	201	},
6807   { "/test",		"",	(osc_cb)lives_osc_cb_test,       	500	},
6808 
6809   { NULL,					NULL,		NULL,							0	},
6810 };
6811 
6812 static struct {
6813   char *comment; // leaf comment
6814   char *name;  // leaf name
6815   int  leave; // leaf number
6816   int  att;  // attached to parent number
6817   int  it; // ???
6818 } osc_cont[] = {
6819   {	"/",	 	"",	                 2, -1, 0   	},
6820   {	"/video/",	 	"video",	 5, -1, 0   	},
6821   {	"/video/selection/",	 	"selection",	 46, 5, 0   	},
6822   {	"/video/fps/",	 	"fps",	 40, 5, 0   	},
6823   {	"/video/fps/ratio/",	 	"ratio",	 65, 40, 0   	},
6824   {	"/video/play/ start video playback",	 	"play",	         36, 5, 0   	},
6825   {	"/video/play/time",	 	"time",	         67, 36, 0   	},
6826   {	"/video/play/parameter",	 	"parameter",	         69, 36, 0   	},
6827   {	"/video/play/parameter/value",	 	"value",	         140, 69, 0   	},
6828   {	"/video/play/parameter/flags",	 	"flags",	         141, 69, 0   	},
6829   {	"/video/play/parameter/min",	 	"min",	         142, 69, 0   	},
6830   {	"/video/play/parameter/max",	 	"max",	         143, 69, 0   	},
6831   {	"/video/play/parameter/type",	 	"type",	         144, 69, 0   	},
6832   {	"/video/play/parameter/name",	 	"name",	         145, 69, 0   	},
6833   {	"/video/play/parameter/colorspace",	"colorspace",	 146, 69, 0   	},
6834   {	"/video/play/parameter/default",	"default",	 147, 69, 0   	},
6835   {	"/video/freeze/",	"freeze",        37, 5, 0   	},
6836   {	"/video/loop/",	"loop",        38, 5, 0   	},
6837   {	"/video/pingpong/",	"pingpong",        39, 5, 0   	},
6838   {	"/audio/",	 	"audio",	 6, -1, 0   	},
6839   {	"/audio/mute",	 	"mute",	 300, 6, 0   	},
6840   {	"/audio/volume",	 	"volume",	 301, 6, 0   	},
6841   {	"/audio/source",	 	"source",	 302, 6, 0   	},
6842   {	"/clip/", 		"clip",		 1, -1, 0	},
6843   {	"/clip/fps/", 		"fps",		 113, 1, 0	},
6844   {	"/clip/foreground/", 	"foreground",    47, 1, 0	},
6845   {	"/clip/foreground/valid/", 	"valid",    80, 1, 0	},
6846   {	"/clip/foreground/background/",  "background",    53, 47, 0	},
6847   {	"/clip/foreground/frame/",  "frame",    60, 47, 0	},
6848   {	"/clip/foreground/fps/",  "fps",    61, 47, 0	},
6849   {	"/clip/foreground/fps/ratio/",  "ratio",    64, 61, 0	},
6850   {	"/clip/background/", 	"background",    48, 1, 0	},
6851   {	"/clip/background/valid/", 	"valid",    81, 1, 0	},
6852   {	"/clip/background/frame/",  "frame",    62, 48, 0	},
6853   {	"/clip/background/fps/",  "fps",    63, 48, 0	},
6854   {	"/clip/background/fps/ratio/",  "ratio",    66, 63, 0	},
6855   {	"/clip/is_valid/", 	"is_valid",      49, 1, 0	},
6856   {	"/clip/frame/", 	"frame",      57, 1, 0	},
6857   {	"/clip/start/", 	"start",         50, 1, 0	},
6858   {	"/clip/end/", 	        "end",           51, 1, 0	},
6859   {	"/clip/select/", 	        "select",           54, 1, 0	},
6860   {	"/clip/selection/", 	        "selection",           55, 1, 0	},
6861   {	"/clip/size/", 	        "size",           58, 1, 0	},
6862   {	"/clip/name/", 	        "name",           59, 1, 0	},
6863   {	"/clip/audio/", 	"audio",           108, 1, 0	},
6864   {	"/clipboard/", 		"clipboard",		 70, -1, 0	},
6865   {	"/record/", 		"record",	 3, -1, 0	},
6866   {	"/effect/", 		"effects",	 4, -1, 0	},
6867   {	"/effect/realtime/", 		"realtime",	 114, 4, 0	},
6868   {	"/effect/realtime/name/", 		"name",	 115, 114, 0	},
6869   {	"/effect_key/", 		"effect_key",	 25, -1, 0	},
6870   {	"/effect_key/inchannel/", 	"inchannel",	 130, 25, 0	},
6871   {	"/effect_key/inchannel/active/", 	"active",	 131, 130, 0	},
6872   {	"/effect_key/inchannel/palette/", 	"palette",	 132, 130, 0	},
6873   {	"/effect_key/parameter/", 	"parameter",	 41, 25, 0	},
6874   {	"/effect_key/parameter/value/", "value",	 42, 41, 0	},
6875   {	"/effect_key/parameter/type/", "type",	 68, 41, 0	},
6876   {	"/effect_key/parameter/name/", "name",	 71, 41, 0	},
6877   {	"/effect_key/parameter/colorspace/", "colorspace",	 73, 41, 0	},
6878   {	"/effect_key/parameter/flags/", "flags",	 74, 41, 0	},
6879   {	"/effect_key/parameter/min/", "min",	 75, 41, 0	},
6880   {	"/effect_key/parameter/max/", "max",	 76, 41, 0	},
6881   {	"/effect_key/parameter/default/", "default",	 77, 41, 0	},
6882   {	"/effect_key/parameter/group/", "group",	 78, 41, 0	},
6883   {	"/effect_key/parameter/gui/", "gui",	 180, 41, 0	},
6884   {	"/effect_key/parameter/gui/choices", "choices",	 181, 180, 0	},
6885   {	"/effect_key/nparameter/", 	"nparameter",	 91, 25, 0	},
6886   {	"/effect_key/nparameter/name/", "name",	 72, 91, 0	},
6887   {	"/effect_key/nparameter/value/", "value",	 92, 91, 0	},
6888   {	"/effect_key/nparameter/type/", "type",	 116, 91, 0	},
6889   {	"/effect_key/nparameter/min/", "min",	 93, 91, 0	},
6890   {	"/effect_key/nparameter/max/", "max",	 94, 91, 0	},
6891   {	"/effect_key/nparameter/default/", "default",	 95, 91, 0	},
6892   {	"/effect_key/map/", 		"map",	 32, 25, 0	},
6893   {	"/effect_key/mode/", 		"mode",	 43, 25, 0	},
6894   {	"/effect_key/name/", 		"name",	 44, 25, 0	},
6895   {	"/effect_key/maxmode/", 	"maxmode",	 45, 25, 0	},
6896   {	"/effect_key/state/", 	"state",	 56, 25, 0	},
6897   {	"/effect_key/outchannel/", 	"outchannel",	 160, 25, 0	},
6898   {	"/effect_key/outchannel/connection/", 	"connection",	 161, 160, 0	},
6899   {	"/effect_key/outchannel/palette/", 	"palette",	 162, 160, 0	},
6900   {	"/effect_key/outchannel/active/", 	"active",	 171, 160, 0	},
6901   {	"/effect_key/outparameter/", 	"outparameter",	 150, 25, 0	},
6902   {	"/effect_key/outparameter/connection/", 	"connection",	 151, 150, 0	},
6903   {	"/effect_key/outparameter/name/", 	"name",	 152, 150, 0	},
6904   {	"/effect_key/outparameter/type/", 	"type",	 153, 150, 0	},
6905   {	"/effect_key/outparameter/colorspace/", 	"colorspace",	 154, 150, 0	},
6906   {	"/effect_key/outparameter/value/", 	"value",	 155, 150, 0	},
6907   {	"/effect_key/outparameter/min/", 	"min",	 156, 150, 0	},
6908   {	"/effect_key/outparameter/max/", 	"max",	 157, 150, 0	},
6909   {	"/effect_key/outparameter/default/", 	"default",	 158, 150, 0	},
6910   {	"/lives/", 		"lives",	 21, -1, 0	},
6911   {	"/lives/version/", 		"version",	 24, 21, 0	},
6912   {	"/lives/mode/", 		"mode",	 103, 21, 0	},
6913   {	"/lives/status/", 		"status",	 122, 21, 0	},
6914   {	"/lives/constant/", 		"constant",	 120, 21, 0	},
6915   {	"/lives/constant/value/", 		"value",	 121, 120, 0	},
6916   {	"/clipset/", 		"clipset",	 35, -1, 0	},
6917   {	"/clipset/name/", 		"name",	 135, 35, 0	},
6918   {	"/app/", 		"app",	         22, -1, 0	},
6919   {	"/app/name/", 		"name",	         23, 22, 0	},
6920   {	"/app/version/", 		"version",	         125, 22, 0	},
6921   {	"/output/", 	"output",	 27, -1, 0	},
6922   {	"/output/fullscreen/", 	"fullscreen",	 28, 27, 0	},
6923   {	"/output/fps/", 	        "fps",	 52, 27, 0	},
6924   {	"/output/nodrop/", 	"nodrop",	 30, 27, 0	},
6925   {	"/clip/open/",   		"open",		 33, 1, 0	},
6926   {	"/notify/",   		"notify",		 100, -1, 0	},
6927   {	"/notify/confirmations/",   		"confirmations",		 101, 100, 0	},
6928   {	"/notify/events/",   		"events",		 102, 100, 0	},
6929   {	"/layout/",   		"layout",		 104, -1, 0	},
6930   {	"/block/",   		"block",		 105, -1, 0	},
6931   {	"/block/start/",   		"start",		 106, 105, 0	},
6932   {	"/block/start/time/",   		"time",		 111, 106, 0	},
6933   {	"/block/end/",   		"end",		 107, 105, 0	},
6934   {	"/block/end/time/",   		"time",		 112, 107, 0	},
6935   {	"/mt/",   		"mt",		 200, -1, 0	},
6936   {	"/mt/ctime/",   		"ctime",		 201, 200, 0	},
6937   {	"/mt/ctrack/",   		"ctrack",		 202, 200, 0	},
6938   {	"/test/",   		"test",		 500, -1, 0	},
6939   {	NULL,			NULL,		0, -1, 0		},
6940 };
6941 
6942 
lives_osc_build_cont(lives_osc * o)6943 int lives_osc_build_cont(lives_osc * o) {
6944   /* Create containers /video , /clip, /chain and /tag */
6945   register int i;
6946   for (i = 0; osc_cont[i].name ; i++) {
6947     if (osc_cont[i].it == 0) {
6948       o->cqinfo.comment = osc_cont[i].comment;
6949 
6950       // add a container to a leaf
6951       if ((o->leaves[osc_cont[i].leave] =
6952              OSCNewContainer(osc_cont[i].name,
6953                              (osc_cont[i].att == -1 ? o->container : o->leaves[osc_cont[i].att]),
6954                              &(o->cqinfo))) == 0) {
6955         if (osc_cont[i].att == - 1) {
6956           lives_printerr("Cannot create container %d (%s) \n",
6957                          i, osc_cont[i].name);
6958           return 0;
6959         } else {
6960           lives_printerr("Cannot add branch %s to  container %d)\n",
6961                          osc_cont[i].name, osc_cont[i].att);
6962           return 0;
6963         }
6964       }
6965     } else {
6966       char name[50];
6967       char comment[50];
6968       int n = osc_cont[i].it;
6969       int base = osc_cont[i].leave;
6970       register int j;
6971 
6972       for (j = 0; j < n ; j++) {
6973         sprintf(name, "N%d", j);
6974         sprintf(comment, "<%d>", j);
6975         lives_printerr("Try cont.%d  '%s', %d %d\n", j, name,
6976                        base + j, base);
6977         o->cqinfo.comment = comment;
6978         if ((o->leaves[base + j] = OSCNewContainer(name,
6979                                    o->leaves[osc_cont[i].att],
6980                                    &(o->cqinfo))) == 0) {
6981           lives_printerr("Cannot auto numerate container %s \n",
6982                          osc_cont[i].name);
6983           return 0;
6984 
6985         }
6986       }
6987     }
6988   }
6989   return 1;
6990 }
6991 
6992 
lives_osc_attach_methods(lives_osc * o)6993 int lives_osc_attach_methods(lives_osc * o) {
6994   int i;
6995 
6996   for (i = 0; osc_methods[i].name ; i++) {
6997     o->ris.description = osc_methods[i].descr;
6998     OSCNewMethod(osc_methods[i].name,
6999                  o->leaves[osc_methods[i].leave],
7000                  osc_methods[i].cb,
7001                  NULL, // this is the context which is reurned but it seems to be unused
7002                  & (o->ris));
7003   }
7004   return 1;
7005 }
7006 
7007 
7008 /* initialization, setup a UDP socket and invoke OSC magic */
lives_osc_allocate(int port_id)7009 lives_osc *lives_osc_allocate(int port_id) {
7010   lives_osc *o;
7011 
7012   if (!livesOSC) {
7013     o = (lives_osc *)lives_malloc(sizeof(lives_osc));
7014     //o->osc_args = (osc_arg*)lives_malloc(50 * sizeof(*o->osc_args));
7015     o->osc_args = NULL;
7016     o->rt.InitTimeMemoryAllocator = lives_osc_malloc;
7017     o->rt.RealTimeMemoryAllocator = lives_osc_malloc;
7018     o->rt.receiveBufferSize = 1024;
7019     o->rt.numReceiveBuffers = 100;
7020     o->rt.numQueuedObjects = 100;
7021     o->rt.numCallbackListNodes = 200;
7022     o->leaves = (OSCcontainer *) lives_malloc(sizeof(OSCcontainer) * 1000);
7023     o->t.initNumContainers = 1000;
7024     o->t.initNumMethods = 2000;
7025     o->t.InitTimeMemoryAllocator = lives_osc_malloc;
7026     o->t.RealTimeMemoryAllocator = lives_osc_malloc;
7027 
7028     if (!OSCInitReceive(&(o->rt))) {
7029       d_print(_("Cannot initialize OSC receiver\n"));
7030       return NULL;
7031     }
7032     o->packet = OSCAllocPacketBuffer();
7033 
7034     /* Top level container / */
7035     o->container = OSCInitAddressSpace(&(o->t));
7036 
7037     OSCInitContainerQueryResponseInfo(&(o->cqinfo));
7038     o->cqinfo.comment = "Video commands";
7039 
7040     if (!lives_osc_build_cont(o))
7041       return NULL;
7042 
7043     OSCInitMethodQueryResponseInfo(&(o->ris));
7044 
7045     if (!lives_osc_attach_methods(o))
7046       return NULL;
7047   } else o = livesOSC;
7048 
7049   if (port_id > 0) {
7050     if (NetworkStartUDPServer(o->packet, port_id) != TRUE) {
7051       d_print(_("WARNING: Cannot start OSC server at UDP port %d\n"), port_id);
7052     } else {
7053       d_print(_("Started OSC server at UDP port %d\n"), port_id);
7054     }
7055   }
7056 
7057   return o;
7058 }
7059 
7060 
lives_osc_dump(void)7061 void lives_osc_dump(void) {OSCPrintWholeAddressSpace();}
7062 
7063 // CALL THIS PERIODICALLY, will read all queued messages and call callbacks
7064 
7065 /* get a packet */
lives_osc_get_packet(lives_osc * o)7066 static int lives_osc_get_packet(lives_osc * o) {
7067   //OSCTimeTag tag;
7068 
7069   /* see if there is something to read , this is effectivly NetworkPacketWaiting */
7070   // if(ioctl( o->sockfd, FIONREAD, &bytes,0 ) == -1) return 0;
7071   // if(bytes==0) return 0;
7072   if (NetworkPacketWaiting(o->packet)) {
7073     /* yes, receive packet from UDP */
7074     if (NetworkReceivePacket(o->packet)) {
7075       /* OSC must accept this packet (OSC will auto-invoke it, see source !) */
7076       OSCAcceptPacket(o->packet);
7077 
7078 #ifdef DEBUG_OSC
7079       g_print("got osc msg %s\n", OSCPacketBufferGetBuffer((OSCPacketBuffer)o->packet));
7080 #endif
7081       /* Is this really productive ? */
7082       OSCBeProductiveWhileWaiting();
7083       // here we call the callbacks
7084 
7085       /* tell caller we had 1 packet */
7086       return 1;
7087     }
7088   }
7089   return 0;
7090 }
7091 
7092 
oscbuf_to_packet(OSCbuf * obuf,OSCPacketBuffer packet)7093 static void oscbuf_to_packet(OSCbuf * obuf, OSCPacketBuffer packet) {
7094   int *psize = OSCPacketBufferGetSize(packet);
7095   int bufsize = OSC_packetSize(obuf);
7096 
7097   if (bufsize > 100) {
7098     LIVES_ERROR("error, OSC msglen > 100 !");
7099   }
7100 
7101   lives_memcpy(OSCPacketBufferGetBuffer(packet), OSC_getPacket(obuf), bufsize);
7102   *psize = bufsize;
7103 }
7104 
7105 
lives_osc_act(OSCbuf * obuf)7106 boolean lives_osc_act(OSCbuf * obuf) {
7107   // this is a shortcut route to make LiVES carry out the OSC message in msg
7108 
7109   OSCPacketBuffer packet;
7110 
7111   if (!livesOSC) lives_osc_init(0);
7112 
7113   packet = livesOSC->packet;
7114 
7115   oscbuf_to_packet(obuf, packet);
7116 
7117   OSCAcceptPacket(packet);
7118 
7119   via_shortcut = TRUE;
7120   OSCBeProductiveWhileWaiting();
7121   via_shortcut = FALSE;
7122 
7123   return TRUE;
7124 }
7125 
7126 
lives_osc_free(lives_osc * c)7127 void lives_osc_free(lives_osc * c) {
7128   if (!c) return;
7129   if (c->leaves) free(c->leaves);
7130   if (c) free(c);
7131   c = NULL;
7132 }
7133 
7134 
7135 ////////////////////////////// API public functions /////////////////////
7136 
lives_osc_init(uint32_t udp_port)7137 boolean lives_osc_init(uint32_t udp_port) {
7138   if (livesOSC && udp_port != 0) {
7139     /*  OSCPacketBuffer packet=livesOSC->packet;
7140       if (shutdown (packet->returnAddr->sockfd,SHUT_RDWR)) {
7141       d_print( lives_strdup_printf (_("Cannot shut down OSC/UDP server\n"));
7142       }
7143     */
7144     if (NetworkStartUDPServer(livesOSC->packet, udp_port) != TRUE) {
7145       d_print(_("Cannot start OSC/UDP server at port %d \n"), udp_port);
7146     }
7147   } else {
7148     livesOSC = lives_osc_allocate(udp_port);
7149     if (!livesOSC) return FALSE;
7150     status_socket = NULL;
7151     notify_socket = NULL;
7152   }
7153   return TRUE;
7154 }
7155 
7156 
lives_osc_poll(livespointer data)7157 boolean lives_osc_poll(livespointer data) {
7158   // data is always NULL
7159   // must return TRUE
7160   if (!mainw->osc_block && livesOSC) lives_osc_get_packet(livesOSC);
7161   return TRUE;
7162 }
7163 
7164 
lives_osc_end(void)7165 void lives_osc_end(void) {
7166   if (notify_socket) {
7167     lives_osc_notify(LIVES_OSC_NOTIFY_QUIT, "");
7168     lives_osc_close_notify_socket();
7169   }
7170   if (status_socket) {
7171     lives_osc_close_status_socket();
7172   }
7173 
7174   if (livesOSC) lives_osc_free(livesOSC);
7175   livesOSC = NULL;
7176 }
7177 
7178 #endif
7179