refactor the handling of the filename arg to make consistent
[melted] / src / melted / melted_unit_commands.c
1 /*
2 * melted_unit_commands.c
3 * Copyright (C) 2002-2009 Ushodaya Enterprises Limited
4 * Author: Dan Dennedy <dan@dennedy.org>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20
21 #ifdef HAVE_CONFIG_H
22 #include <config.h>
23 #endif
24
25 #include <sys/types.h>
26 #include <sys/stat.h>
27 #include <fcntl.h>
28 #include <unistd.h>
29 #include <string.h>
30 #include <stdlib.h>
31 #include <stdio.h>
32
33 #include "melted_unit.h"
34 #include "melted_commands.h"
35 #include "melted_log.h"
36
37
38 void get_fullname( command_argument cmd_arg, char *fullname, size_t len, char *filename )
39 {
40 char *service = strchr( filename, ':' );
41
42 if ( service != NULL )
43 {
44 service = filename;
45 filename = strchr( service, ':' );
46 *filename ++ = '\0';
47
48 if ( strlen( cmd_arg->root_dir ) && filename[0] == '/' )
49 filename++;
50
51 snprintf( fullname, len, "%s:%s%s", service, cmd_arg->root_dir, filename );
52 }
53 else
54 {
55 if ( strlen( cmd_arg->root_dir ) && filename[0] == '/' )
56 filename++;
57
58 snprintf( fullname, len, "%s%s", cmd_arg->root_dir, filename );
59 }
60 }
61
62 int melted_load( command_argument cmd_arg )
63 {
64 melted_unit unit = melted_get_unit(cmd_arg->unit);
65 char *filename = (char*) cmd_arg->argument;
66 char fullname[1024];
67 int flush = 1;
68
69 if ( filename[0] == '!' )
70 {
71 flush = 0;
72 filename ++;
73 }
74 get_fullname( cmd_arg, fullname, sizeof(fullname), filename );
75
76 if (unit == NULL)
77 return RESPONSE_INVALID_UNIT;
78 else
79 {
80 int32_t in = -1, out = -1;
81 if ( mvcp_tokeniser_count( cmd_arg->tokeniser ) == 5 )
82 {
83 in = atol( mvcp_tokeniser_get_string( cmd_arg->tokeniser, 3 ) );
84 out = atol( mvcp_tokeniser_get_string( cmd_arg->tokeniser, 4 ) );
85 }
86 if ( melted_unit_load( unit, fullname, in, out, flush ) != mvcp_ok )
87 return RESPONSE_BAD_FILE;
88 }
89 return RESPONSE_SUCCESS;
90 }
91
92 int melted_list( command_argument cmd_arg )
93 {
94 melted_unit unit = melted_get_unit( cmd_arg->unit );
95
96 if ( unit != NULL )
97 {
98 melted_unit_report_list( unit, cmd_arg->response );
99 return RESPONSE_SUCCESS;
100 }
101
102 return RESPONSE_INVALID_UNIT;
103 }
104
105 static int parse_clip( command_argument cmd_arg, int arg )
106 {
107 melted_unit unit = melted_get_unit(cmd_arg->unit);
108 int clip = melted_unit_get_current_clip( unit );
109
110 if ( mvcp_tokeniser_count( cmd_arg->tokeniser ) > arg )
111 {
112 char *token = mvcp_tokeniser_get_string( cmd_arg->tokeniser, arg );
113 if ( token[ 0 ] == '+' )
114 clip += atoi( token + 1 );
115 else if ( token[ 0 ] == '-' )
116 clip -= atoi( token + 1 );
117 else
118 clip = atoi( token );
119 }
120
121 return clip;
122 }
123
124 int melted_insert( command_argument cmd_arg )
125 {
126 melted_unit unit = melted_get_unit(cmd_arg->unit);
127 char *filename = (char*) cmd_arg->argument;
128 char fullname[1024];
129
130 get_fullname( cmd_arg, fullname, sizeof(fullname), filename );
131
132 if (unit == NULL)
133 return RESPONSE_INVALID_UNIT;
134 else
135 {
136 long in = -1, out = -1;
137 int index = parse_clip( cmd_arg, 3 );
138
139 if ( mvcp_tokeniser_count( cmd_arg->tokeniser ) == 6 )
140 {
141 in = atoi( mvcp_tokeniser_get_string( cmd_arg->tokeniser, 4 ) );
142 out = atoi( mvcp_tokeniser_get_string( cmd_arg->tokeniser, 5 ) );
143 }
144
145 switch( melted_unit_insert( unit, fullname, index, in, out ) )
146 {
147 case mvcp_ok:
148 return RESPONSE_SUCCESS;
149 default:
150 return RESPONSE_BAD_FILE;
151 }
152 }
153 return RESPONSE_SUCCESS;
154 }
155
156 int melted_remove( command_argument cmd_arg )
157 {
158 melted_unit unit = melted_get_unit(cmd_arg->unit);
159
160 if (unit == NULL)
161 return RESPONSE_INVALID_UNIT;
162 else
163 {
164 int index = parse_clip( cmd_arg, 2 );
165
166 if ( melted_unit_remove( unit, index ) != mvcp_ok )
167 return RESPONSE_BAD_FILE;
168 }
169 return RESPONSE_SUCCESS;
170 }
171
172 int melted_clean( command_argument cmd_arg )
173 {
174 melted_unit unit = melted_get_unit(cmd_arg->unit);
175
176 if (unit == NULL)
177 return RESPONSE_INVALID_UNIT;
178 else
179 {
180 if ( melted_unit_clean( unit ) != mvcp_ok )
181 return RESPONSE_BAD_FILE;
182 }
183 return RESPONSE_SUCCESS;
184 }
185
186 int melted_wipe( command_argument cmd_arg )
187 {
188 melted_unit unit = melted_get_unit(cmd_arg->unit);
189
190 if (unit == NULL)
191 return RESPONSE_INVALID_UNIT;
192 else
193 {
194 if ( melted_unit_wipe( unit ) != mvcp_ok )
195 return RESPONSE_BAD_FILE;
196 }
197 return RESPONSE_SUCCESS;
198 }
199
200 int melted_clear( command_argument cmd_arg )
201 {
202 melted_unit unit = melted_get_unit(cmd_arg->unit);
203
204 if (unit == NULL)
205 return RESPONSE_INVALID_UNIT;
206 else
207 {
208 if ( melted_unit_clear( unit ) != mvcp_ok )
209 return RESPONSE_BAD_FILE;
210 }
211 return RESPONSE_SUCCESS;
212 }
213
214 int melted_move( command_argument cmd_arg )
215 {
216 melted_unit unit = melted_get_unit(cmd_arg->unit);
217
218 if ( unit != NULL )
219 {
220 if ( mvcp_tokeniser_count( cmd_arg->tokeniser ) > 2 )
221 {
222 int src = parse_clip( cmd_arg, 2 );
223 int dest = parse_clip( cmd_arg, 3 );
224
225 if ( melted_unit_move( unit, src, dest ) != mvcp_ok )
226 return RESPONSE_BAD_FILE;
227 }
228 else
229 {
230 return RESPONSE_MISSING_ARG;
231 }
232 }
233 else
234 {
235 return RESPONSE_INVALID_UNIT;
236 }
237
238 return RESPONSE_SUCCESS;
239 }
240
241 int melted_append( command_argument cmd_arg )
242 {
243 melted_unit unit = melted_get_unit(cmd_arg->unit);
244 char *filename = (char*) cmd_arg->argument;
245 char fullname[1024];
246
247 get_fullname( cmd_arg, fullname, sizeof(fullname), filename );
248
249 if (unit == NULL)
250 return RESPONSE_INVALID_UNIT;
251 else
252 {
253 int32_t in = -1, out = -1;
254 if ( mvcp_tokeniser_count( cmd_arg->tokeniser ) == 5 )
255 {
256 in = atol( mvcp_tokeniser_get_string( cmd_arg->tokeniser, 3 ) );
257 out = atol( mvcp_tokeniser_get_string( cmd_arg->tokeniser, 4 ) );
258 }
259 switch ( melted_unit_append( unit, fullname, in, out ) )
260 {
261 case mvcp_ok:
262 return RESPONSE_SUCCESS;
263 default:
264 return RESPONSE_BAD_FILE;
265 }
266 }
267 return RESPONSE_SUCCESS;
268 }
269
270 int melted_push( command_argument cmd_arg, mlt_service service )
271 {
272 melted_unit unit = melted_get_unit(cmd_arg->unit);
273 if ( !unit )
274 return RESPONSE_INVALID_UNIT;
275 if ( service != NULL )
276 if ( melted_unit_append_service( unit, service ) == mvcp_ok )
277 return RESPONSE_SUCCESS;
278 return RESPONSE_BAD_FILE;
279 }
280
281 int melted_receive( command_argument cmd_arg, char *doc )
282 {
283 melted_unit unit = melted_get_unit(cmd_arg->unit);
284 if ( unit == NULL )
285 return RESPONSE_INVALID_UNIT;
286 else
287 {
288 // Get the consumer's profile
289 mlt_consumer consumer = mlt_properties_get_data( unit->properties, "consumer", NULL );
290 mlt_profile profile = mlt_service_profile( MLT_CONSUMER_SERVICE( consumer ) );
291 mlt_producer producer = mlt_factory_producer( profile, "xml-string", doc );
292 if ( producer != NULL )
293 {
294 if ( melted_unit_append_service( unit, MLT_PRODUCER_SERVICE( producer ) ) == mvcp_ok )
295 {
296 mlt_producer_close( producer );
297 return RESPONSE_SUCCESS;
298 }
299 mlt_producer_close( producer );
300 }
301 }
302 return RESPONSE_BAD_FILE;
303 }
304
305 int melted_play( command_argument cmd_arg )
306 {
307 melted_unit unit = melted_get_unit(cmd_arg->unit);
308
309 if ( unit == NULL )
310 {
311 return RESPONSE_INVALID_UNIT;
312 }
313 else
314 {
315 int speed = 1000;
316 if ( mvcp_tokeniser_count( cmd_arg->tokeniser ) == 3 )
317 speed = atoi( mvcp_tokeniser_get_string( cmd_arg->tokeniser, 2 ) );
318 melted_unit_play( unit, speed );
319 }
320
321 return RESPONSE_SUCCESS;
322 }
323
324 int melted_stop( command_argument cmd_arg )
325 {
326 melted_unit unit = melted_get_unit(cmd_arg->unit);
327 if ( unit == NULL )
328 return RESPONSE_INVALID_UNIT;
329 else
330 melted_unit_terminate( unit );
331 return RESPONSE_SUCCESS;
332 }
333
334 int melted_pause( command_argument cmd_arg )
335 {
336 melted_unit unit = melted_get_unit(cmd_arg->unit);
337 if ( unit == NULL )
338 return RESPONSE_INVALID_UNIT;
339 else
340 melted_unit_play( unit, 0 );
341 return RESPONSE_SUCCESS;
342 }
343
344 int melted_rewind( command_argument cmd_arg )
345 {
346 melted_unit unit = melted_get_unit(cmd_arg->unit);
347 if ( unit == NULL )
348 return RESPONSE_INVALID_UNIT;
349 else if ( melted_unit_has_terminated( unit ) )
350 melted_unit_change_position( unit, 0, 0 );
351 else
352 melted_unit_play( unit, -2000 );
353 return RESPONSE_SUCCESS;
354 }
355
356 int melted_step( command_argument cmd_arg )
357 {
358 melted_unit unit = melted_get_unit(cmd_arg->unit);
359
360 if (unit == NULL)
361 return RESPONSE_INVALID_UNIT;
362 else
363 {
364 melted_unit_play( unit, 0 );
365 melted_unit_step( unit, *(int*) cmd_arg->argument );
366 }
367 return RESPONSE_SUCCESS;
368 }
369
370 int melted_goto( command_argument cmd_arg )
371 {
372 melted_unit unit = melted_get_unit(cmd_arg->unit);
373 int clip = parse_clip( cmd_arg, 3 );
374
375 if (unit == NULL || melted_unit_is_offline(unit))
376 return RESPONSE_INVALID_UNIT;
377 else
378 melted_unit_change_position( unit, clip, *(int*) cmd_arg->argument );
379 return RESPONSE_SUCCESS;
380 }
381
382 int melted_ff( command_argument cmd_arg )
383 {
384 melted_unit unit = melted_get_unit(cmd_arg->unit);
385 if ( unit == NULL )
386 return RESPONSE_INVALID_UNIT;
387 else if ( melted_unit_has_terminated( unit ) )
388 melted_unit_change_position( unit, 0, 0 );
389 else
390 melted_unit_play( unit, 2000 );
391 return RESPONSE_SUCCESS;
392 }
393
394 int melted_set_in_point( command_argument cmd_arg )
395 {
396 melted_unit unit = melted_get_unit(cmd_arg->unit);
397 int clip = parse_clip( cmd_arg, 3 );
398
399 if ( unit == NULL )
400 return RESPONSE_INVALID_UNIT;
401 else
402 {
403 int position = *(int *) cmd_arg->argument;
404
405 switch( melted_unit_set_clip_in( unit, clip, position ) )
406 {
407 case -1:
408 return RESPONSE_BAD_FILE;
409 case -2:
410 return RESPONSE_OUT_OF_RANGE;
411 }
412 }
413 return RESPONSE_SUCCESS;
414 }
415
416 int melted_set_out_point( command_argument cmd_arg )
417 {
418 melted_unit unit = melted_get_unit(cmd_arg->unit);
419 int clip = parse_clip( cmd_arg, 3 );
420
421 if ( unit == NULL )
422 return RESPONSE_INVALID_UNIT;
423 else
424 {
425 int position = *(int *) cmd_arg->argument;
426
427 switch( melted_unit_set_clip_out( unit, clip, position ) )
428 {
429 case -1:
430 return RESPONSE_BAD_FILE;
431 case -2:
432 return RESPONSE_OUT_OF_RANGE;
433 }
434 }
435
436 return RESPONSE_SUCCESS;
437 }
438
439 int melted_get_unit_status( command_argument cmd_arg )
440 {
441 mvcp_status_t status;
442 int error = melted_unit_get_status( melted_get_unit( cmd_arg->unit ), &status );
443
444 if ( error == -1 )
445 return RESPONSE_INVALID_UNIT;
446 else
447 {
448 char text[ 10240 ];
449 mvcp_response_printf( cmd_arg->response, sizeof( text ), mvcp_status_serialise( &status, text, sizeof( text ) ) );
450 return RESPONSE_SUCCESS_1;
451 }
452 return 0;
453 }
454
455
456 int melted_set_unit_property( command_argument cmd_arg )
457 {
458 melted_unit unit = melted_get_unit(cmd_arg->unit);
459 char *name_value = (char*) cmd_arg->argument;
460 if (unit == NULL)
461 return RESPONSE_INVALID_UNIT;
462 else
463 melted_unit_set( unit, name_value );
464 return RESPONSE_SUCCESS;
465 }
466
467 int melted_get_unit_property( command_argument cmd_arg )
468 {
469 melted_unit unit = melted_get_unit(cmd_arg->unit);
470 char *name = (char*) cmd_arg->argument;
471 if (unit == NULL)
472 {
473 return RESPONSE_INVALID_UNIT;
474 }
475 else
476 {
477 char *value = melted_unit_get( unit, name );
478 if ( value != NULL )
479 mvcp_response_printf( cmd_arg->response, 1024, "%s\n", value );
480 }
481 return RESPONSE_SUCCESS;
482 }
483
484
485 int melted_transfer( command_argument cmd_arg )
486 {
487 melted_unit src_unit = melted_get_unit(cmd_arg->unit);
488 int dest_unit_id = -1;
489 char *string = (char*) cmd_arg->argument;
490 if ( string != NULL && ( string[ 0 ] == 'U' || string[ 0 ] == 'u' ) && strlen( string ) > 1 )
491 dest_unit_id = atoi( string + 1 );
492
493 if ( src_unit != NULL && dest_unit_id != -1 )
494 {
495 melted_unit dest_unit = melted_get_unit( dest_unit_id );
496 if ( dest_unit != NULL && !melted_unit_is_offline(dest_unit) && dest_unit != src_unit )
497 {
498 melted_unit_transfer( dest_unit, src_unit );
499 return RESPONSE_SUCCESS;
500 }
501 }
502 return RESPONSE_INVALID_UNIT;
503 }