1 /******************************************************************************
2 * recordMyDesktop *
3 *******************************************************************************
4 * *
5 * Copyright (C) 2006,2007,2008 John Varouhakis *
6 * *
7 * *
8 * This program is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU General Public License as published by *
10 * the Free Software Foundation; either version 2 of the License, or *
11 * (at your option) any later version. *
12 * *
13 * This program is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU General Public License for more details. *
17 * *
18 * You should have received a copy of the GNU General Public License *
19 * along with this program; if not, write to the Free Software *
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
21 * *
22 * *
23 * *
24 * For further information contact me at johnvarouhakis@gmail.com *
25 ******************************************************************************/
26
27 #include "config.h"
28 #include "rmd_parseargs.h"
29
30 #include "rmd_types.h"
31
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35
36
PrintConfig(void)37 static void PrintConfig(void) {
38 fprintf(stderr,"\nrecordMyDesktop was compiled with"
39 " the following options:\n\n");
40 #ifdef HAVE_LIBJACK
41 fprintf(stdout,"Jack\t\t\t:Enabled\n");
42 #else
43 fprintf(stdout,"Jack\t\t\t:Disabled\n");
44 #endif
45 #ifdef HAVE_LIBASOUND
46 fprintf(stdout,"Default Audio Backend\t:ALSA\n");
47 #else
48 fprintf(stdout,"Default Audio Backend\t:OSS\n");
49 #endif
50 fprintf(stderr,"\n\n");
51 }
52
53 /**
54 * Still has backwards compatible options like -this, but --this is
55 * what is documented.
56 */
ParseArgs(int argc,char ** argv,ProgArgs * arg_return)57 boolean ParseArgs(int argc, char **argv, ProgArgs *arg_return) {
58 int i;
59 char *usage="\nUsage:\n"
60 "\trecordmydesktop [OPTIONS]^filename\n\n\n"
61
62 "General Options:\n"
63 "\t-h or --help\t\tPrint this help and exit.\n"
64 "\t--version\t\tPrint program version and exit.\n"
65 "\t--print-config\t\tPrint info about options "
66 "selected during compilation and exit.\n\n"
67
68 "Image Options:\n"
69 "\t--windowid id_of_window\tid of window to be recorded.\n"
70 "\t--display DISPLAY\tDisplay to connect to.\n"
71 "\t-x X\t\t\tOffset in x direction.\n"
72 "\t-y Y\t\t\tOffset in y direction.\n"
73 "\t--width N\t\tWidth of recorded window.\n"
74 "\t--height N\t\tHeight of recorded window.\n\n"
75
76 "\t--dummy-cursor color\tColor of the dummy cursor [black|white]\n"
77 "\t--no-cursor\t\tDisable drawing of the cursor.\n"
78 "\t--no-shared\t\tDisable usage of"
79 " MIT-shared memory extension(Not Recommended!).\n"
80
81 "\t--full-shots\t\tTake full screenshot at every frame(Not recomended!).\n"
82 "\t--quick-subsampling\tDo subsampling"
83 " of the chroma planes by discarding,not averaging.\n"
84
85 "\t--fps N(number>0.0)\tA positive number denoting desired framerate.\n\n"
86
87 "Sound Options:\n"
88 "\t--channels N\t\t\tA positive number denoting"
89 " desired sound channels in recording.\n"
90
91 "\t--freq N\t\t\t\tA positive number denoting desired sound frequency.\n"
92 "\t--buffer-size N\t\t\tA positive number denoting the desired"
93 " sound buffer size (in frames,when using ALSA or OSS)\n"
94 "\t--ring-buffer-size N\t\tA float number denoting the desired"
95 " ring buffer size (in seconds,when using JACK only).\n"
96
97 "\t--device SOUND_DEVICE\t\tSound device(default "
98 DEFAULT_AUDIO_DEVICE
99 ").\n"
100 "\t--use-jack port1 port2... portn\tRecord audio from the specified\n"
101 "\t\t\t\t\tlist of space-separated jack ports.\n"
102 "\t--no-sound\t\t\tDo not record sound.\n\n"
103
104 "Encoding Options\n"
105 "\t--on-the-fly-encoding\tEncode the audio-video data, while recording.\n"
106 "\t--v_quality n\t\tA number from 0 to 63 for"
107 " desired encoded video quality(default 63).\n"
108
109 "\t--v_bitrate n\t\tA number from 0 to 2000000"
110 " for desired encoded video bitrate(default 0).\n"
111
112 "\t--s_quality n\t\tDesired audio quality(-1 to 10).\n\n"
113
114 "Misc Options:\n"
115 "\t--rescue path_to_data\tEncode data from a previous, crashed, session.\n"
116 "\t--no-wm-check\t\tDo not try to detect"
117 " the window manager(and set options according to it)\n"
118
119 "\t--pause-shortcut MOD+KEY\tShortcut that will be used for (un)pausing"
120 "(default Control+Mod1+p).\n"
121 "\t--stop-shortcut MOD+KEY\tShortcut that will be used to stop the "
122 "recording (default Control+Mod1+s).\n"
123
124 "\t--compress-cache\tImage data are cached with light compression.\n"
125 "\t--workdir DIR\t\tLocation where a temporary directory"
126 " will be created to hold project files(default $HOME).\n"
127
128 "\t--delay n[H|h|M|m]\tNumber of secs(default),minutes or hours"
129 " before capture starts(number can be float)\n"
130
131 "\t--overwrite\t\tIf there is already a file with the same name,"
132 " delete it\n"
133
134 "\t\t\t\t(default is to add a number postfix to the new one).\n"
135 "\t-o filename\t\tName of recorded video(default out.ogv).\n"
136 "\n\tIf no other options are specified, filename can be given "
137 "without the -o switch.\n\n\n";
138
139 if(argc==2){
140 if(argv[1][0]!='-'){
141 free(arg_return->filename);
142 arg_return->filename=malloc(strlen(argv[1])+1);
143 strcpy(arg_return->filename,argv[1]);
144 return TRUE;
145 }
146 }
147 for(i=1;i<argc;i++){
148 if (strcmp(argv[i], "--delay") == 0 ||
149 strcmp(argv[i], "-delay") == 0) {
150 if(i+1<argc){
151 float num=atof(argv[i+1]);
152 if(num>0.0){
153 int k;
154 for(k=0;k<strlen(argv[i+1]);k++){
155 if((argv[i+1][k]=='M')||(argv[i+1][k]=='m')){
156 num*=60.0;
157 break;
158 }
159 else if((argv[i+1][k]=='H')||(argv[i+1][k]=='h')){
160 num*=3600.0;
161 break;
162 }
163 }
164 arg_return->delay=(int)num;
165 }
166 else{
167 fprintf(stderr,"Argument Usage: --delay n[H|h|M|m]\n"
168 "where n is a float number\n");
169 return FALSE;
170 }
171 }
172 else{
173 fprintf(stderr,"Argument Usage: --delay n[H|h|M|m]\n"
174 "where n is a float number\n");
175 return FALSE;
176 }
177 i++;
178 }
179 else if (strcmp(argv[i], "--windowid") == 0 ||
180 strcmp(argv[i], "-windowid") == 0) {
181 if(i+1<argc){
182 Window num=strtod(argv[i+1],NULL);
183 if(num>0)
184 arg_return->windowid=num;
185 else{
186 fprintf(stderr,"Argument Usage:"
187 " --windowid id_of_window(number)\n");
188 return FALSE;
189 }
190 }
191 else{
192 fprintf(stderr,"Argument Usage:"
193 " --windowid id_of_window(number)\n");
194 return FALSE;
195 }
196 i++;
197 }
198 else if (strcmp(argv[i], "--display") == 0 ||
199 strcmp(argv[i], "-display") == 0) {
200 if(i+1<argc){
201 if(arg_return->display!=NULL)
202 free(arg_return->display);
203 arg_return->display=malloc(strlen(argv[i+1])+1);
204 strcpy(arg_return->display,argv[i+1]);
205 }
206 else{
207 fprintf(stderr,"Argument Usage: --display DISPLAY\n");
208 return FALSE;
209 }
210 i++;
211 }
212 else if(!strcmp(argv[i],"-x")){
213 if(i+1<argc){
214 int num=atoi(argv[i+1]);
215 if(num>0)
216 arg_return->x=num;
217 else{
218 fprintf(stderr,"Argument Usage: -x X(number>0)\n");
219 return FALSE;
220 }
221 }
222 else{
223 fprintf(stderr,"Argument Usage: -x X(number>0)\n");
224 return FALSE;
225 }
226 i++;
227 }
228 else if(!strcmp(argv[i],"-y")){
229 if(i+1<argc){
230 int num=atoi(argv[i+1]);
231 if(num>0)
232 arg_return->y=num;
233 else{
234 fprintf(stderr,"Argument Usage: -y Y(number>0)\n");
235 return FALSE;
236 }
237 }
238 else{
239 fprintf(stderr,"Argument Usage: -y Y(number>0)\n");
240 return FALSE;
241 }
242 i++;
243 }
244 else if (strcmp(argv[i], "--width") == 0 ||
245 strcmp(argv[i], "-width") == 0) {
246 if(i+1<argc){
247 int num=atoi(argv[i+1]);
248 if(num>0)
249 arg_return->width=num;
250 else{
251 fprintf(stderr,"Argument Usage: --width N(number>0)\n");
252 return FALSE;
253 }
254 }
255 else{
256 fprintf(stderr,"Argument Usage: --width N(number>0)\n");
257 return FALSE;
258 }
259 i++;
260 }
261 else if (strcmp(argv[i], "--height") == 0 ||
262 strcmp(argv[i], "-height") == 0) {
263 if(i+1<argc){
264 int num=atoi(argv[i+1]);
265 if(num>0)
266 arg_return->height=num;
267 else{
268 fprintf(stderr,"Argument Usage: --height N(number>0)\n");
269 return FALSE;
270 }
271 }
272 else{
273 fprintf(stderr,"Argument Usage: --height N(number>0)\n");
274 return FALSE;
275 }
276 i++;
277 }
278 else if(!strcmp(argv[i],"-o")){
279 if(i+1<argc){
280 free(arg_return->filename);
281 arg_return->filename=malloc(strlen(argv[i+1])+1);
282 strcpy(arg_return->filename,argv[i+1]);
283 }
284 else{
285 fprintf(stderr,"Argument Usage: -o filename\n");
286 return FALSE;
287 }
288 i++;
289 }
290 else if (strcmp(argv[i], "--fps") == 0 ||
291 strcmp(argv[i], "-fps") == 0) {
292 if(i+1<argc){
293 float num=atof(argv[i+1]);
294 if(num>0.0)
295 arg_return->fps=num;
296 else{
297 fprintf(stderr,"Argument Usage: --fps N(number>0)\n");
298 return FALSE;
299 }
300 }
301 else{
302 fprintf(stderr,"Argument Usage: --fps N(number>0)\n");
303 return FALSE;
304 }
305 i++;
306 }
307 else if (strcmp(argv[i], "--v_quality") == 0 ||
308 strcmp(argv[i], "-v_quality") == 0) {
309 if(i+1<argc){
310 int num=atoi(argv[i+1]);
311 if((num>=0)&&(num<64))
312 arg_return->v_quality=num;
313 else{
314 fprintf(stderr,"Argument Usage:"
315 " --v_quality n(number 0-63)\n");
316 return FALSE;
317 }
318 }
319 else{
320 fprintf(stderr,"Argument Usage:"
321 " --v_quality n(number 0-63)\n");
322 return FALSE;
323 }
324 i++;
325 }
326 else if (strcmp(argv[i], "--v_bitrate") == 0 ||
327 strcmp(argv[i], "-v_bitrate") == 0) {
328 if(i+1<argc){
329 int num=atoi(argv[i+1]);
330 if((num>=0)&&(num<=2000000))
331 arg_return->v_bitrate=num;
332 else{
333 fprintf(stderr,"Argument Usage:"
334 " --v_bitrate n(number 0-2000000)\n");
335 return FALSE;
336 }
337 }
338 else{
339 fprintf(stderr,"Argument Usage:"
340 " --v_bitrate n(number 0-2000000)\n");
341 return FALSE;
342 }
343 i++;
344 }
345 else if (strcmp(argv[i], "--dummy-cursor") == 0 ||
346 strcmp(argv[i], "-dummy-cursor") == 0) {
347 if(i+1<argc){
348 if(!strcmp(argv[i+1],"white"))
349 arg_return->cursor_color=0;
350 else if(!strcmp(argv[i+1],"black"))
351 arg_return->cursor_color=1;
352 else{
353 fprintf(stderr,"Argument Usage:"
354 " --dummy-cursor [black|white]\n");
355 return FALSE;
356 }
357 arg_return->have_dummy_cursor=1;
358 arg_return->xfixes_cursor=0;
359 }
360 else{
361 fprintf(stderr,"Argument Usage:"
362 " --dummy-cursor [black|white]\n");
363 return FALSE;
364 }
365 i++;
366 }
367 else if(!strcmp(argv[i],"--no-cursor"))
368 arg_return->xfixes_cursor=0;
369 else if (strcmp(argv[i], "--freq") == 0 ||
370 strcmp(argv[i], "-freq") == 0) {
371 if(i+1<argc){
372 int num=atoi(argv[i+1]);
373 if(num>0)
374 arg_return->frequency=num;
375 else{
376 fprintf(stderr,"Argument Usage: --freq N(number>0)\n");
377 return FALSE;
378 }
379 }
380 else{
381 fprintf(stderr,"Argument Usage: --freq N(number>0)\n");
382 return FALSE;
383 }
384 i++;
385 }
386 else if (strcmp(argv[i], "--channels") == 0 ||
387 strcmp(argv[i], "-channels") == 0) {
388 if(i+1<argc){
389 int num=atoi(argv[i+1]);
390 if(num>0)
391 arg_return->channels=num;
392 else{
393 fprintf(stderr,"Argument Usage: --channels N(number>0)\n");
394 return FALSE;
395 }
396 }
397 else{
398 fprintf(stderr,"Argument Usage: --channels N(number>0)\n");
399 return FALSE;
400 }
401 i++;
402 }
403 else if (strcmp(argv[i], "--s_quality") == 0 ||
404 strcmp(argv[i], "-s_quality") == 0) {
405 if(i+1<argc){
406 int num=atoi(argv[i+1]);
407 if((num>=-1)&&(num<=10))
408 arg_return->s_quality=num;
409 else{
410 fprintf(stderr,"Argument Usage:"
411 " --s_quality n(number -1 to 10)\n");
412 return FALSE;
413 }
414 }
415 else{
416 fprintf(stderr,"Argument Usage:"
417 " --s_quality n(number -1 to 10)\n");
418 return FALSE;
419 }
420 i++;
421 }
422 else if (strcmp(argv[i], "--device") == 0 ||
423 strcmp(argv[i], "-device") == 0) {
424 if(i+1<argc){
425 free(arg_return->device);
426 arg_return->device=malloc(strlen(argv[i+1])+1);
427 strcpy(arg_return->device,argv[i+1]);
428 }
429 else{
430 fprintf(stderr,"Argument Usage: -device SOUND_DEVICE\n");
431 return FALSE;
432 }
433 i++;
434 }
435 else if (strcmp(argv[i], "--workdir") == 0 ||
436 strcmp(argv[i], "-workdir") == 0) {
437 if(i+1<argc){
438 free(arg_return->workdir);
439 arg_return->workdir=malloc(strlen(argv[i+1])+1);
440 strcpy(arg_return->workdir,argv[i+1]);
441 }
442 else{
443 fprintf(stderr,"Argument Usage: --workdir DIR\n");
444 return FALSE;
445 }
446 i++;
447 }
448 else if (strcmp(argv[i], "--pause-shortcut") == 0 ||
449 strcmp(argv[i], "-pause-shortcut") == 0) {
450 if(i+1<argc){
451 free(arg_return->pause_shortcut);
452 arg_return->pause_shortcut=malloc(strlen(argv[i+1])+1);
453 strcpy(arg_return->pause_shortcut,argv[i+1]);
454 }
455 else{
456 fprintf(stderr,"Argument Usage: --pause-shortcut MOD+KEY\n");
457 return FALSE;
458 }
459 i++;
460 }
461 else if (strcmp(argv[i], "--stop-shortcut") == 0 ||
462 strcmp(argv[i], "-stop-shortcut") == 0) {
463 if(i+1<argc){
464 free(arg_return->stop_shortcut);
465 arg_return->stop_shortcut=malloc(strlen(argv[i+1])+1);
466 strcpy(arg_return->stop_shortcut,argv[i+1]);
467 }
468 else{
469 fprintf(stderr,"Argument Usage: --stop-shortcut MOD+KEY\n");
470 return FALSE;
471 }
472 i++;
473 }
474 else if (strcmp(argv[i], "--buffer-size") == 0 ||
475 strcmp(argv[i], "-buffer-size") == 0) {
476 if(i+1<argc){
477 int num=atoi(argv[i+1]);
478 if(num>0)
479 arg_return->buffsize=num;
480 else{
481 fprintf(stderr,"Argument Usage:"
482 " --buffer-size N(number>0)\n");
483 return FALSE;
484 }
485 }
486 else{
487 fprintf(stderr,"Argument Usage: --buffer-size N(number>0)\n");
488 return FALSE;
489 }
490 i++;
491 }
492 else if (strcmp(argv[i], "--use-jack") == 0 ||
493 strcmp(argv[i], "-use-jack") == 0) {
494 if(i+1<argc){
495 #ifdef HAVE_LIBJACK
496 int k=i+1;
497 arg_return->jack_nports=0;
498 while((k<argc)&&(argv[k][0]!='-')){
499 arg_return->jack_nports++;
500 k++;
501 }
502 if(arg_return->jack_nports>0){
503 arg_return->jack_port_names=malloc(sizeof(char*)*
504 arg_return->jack_nports);
505 for(k=i+1;k<i+1+arg_return->jack_nports;k++){
506 arg_return->jack_port_names[k-i-1]=
507 malloc(strlen(argv[k])+1);
508 strcpy(arg_return->jack_port_names[k-i-1],
509 argv[k]);
510 }
511 i+=arg_return->jack_nports;
512 arg_return->use_jack=1;
513 }
514 else{
515 fprintf(stderr,"Argument Usage: --use-jack port1"
516 " port2... portn\n");
517 return FALSE;
518 }
519 #else
520 fprintf(stderr,"recordMyDesktop is not compiled"
521 " with Jack support!\n");
522 return FALSE;
523 #endif
524 }
525 else{
526 fprintf(stderr,"Argument Usage: --use-jack port1"
527 " port2... portn\n");
528 return FALSE;
529 }
530 }
531 else if (strcmp(argv[i], "--ring-buffer-size") == 0 ||
532 strcmp(argv[i], "-ring-buffer-size") == 0) {
533 if(i+1<argc){
534 float num=atof(argv[i+1]);
535 if(num>0.0)
536 arg_return->jack_ringbuffer_secs=num;
537 else{
538 fprintf(stderr,"Argument Usage: --ring-buffer-size"
539 " N(floating point number>0.0)\n");
540 return FALSE;
541 }
542 }
543 else{
544 fprintf(stderr,"Argument Usage: --ring-buffer-size"
545 " N(floating point number>0.0)\n");
546 return FALSE;
547 }
548 i++;
549 }
550 else if (strcmp(argv[i], "--rescue") == 0 ||
551 strcmp(argv[i], "-rescue") == 0) {
552 if(i+1<argc){
553 arg_return->rescue_path = argv[i + 1];
554 }
555 else{
556 fprintf(stderr,"Argument Usage: --rescue path_to_data\n");
557 return FALSE;
558 }
559 i++;
560 }
561 else if(!strcmp(argv[i],"--no-sound"))
562 arg_return->nosound=1;
563 else if(!strcmp(argv[i],"--no-shared")){
564 arg_return->noshared=1;
565 }
566 else if(!strcmp(argv[i],"--full-shots")){
567 arg_return->full_shots=1;
568 }
569 else if(!strcmp(argv[i],"--no-frame")){
570 arg_return->noframe=1;
571 }
572 else if(!strcmp(argv[i],"--follow-mouse")){
573 arg_return->full_shots=1;
574 arg_return->follow_mouse=1;
575 }
576 else if(!strcmp(argv[i],"--no-encode"))
577 arg_return->no_encode=1;
578 else if(!strcmp(argv[i],"--quick-subsampling")){
579 arg_return->no_quick_subsample=0;
580 }
581 else if(!strcmp(argv[i],"--on-the-fly-encoding")){
582 arg_return->encOnTheFly=1;
583 }
584 else if(!strcmp(argv[i],"--overwrite"))
585 arg_return->overwrite=1;
586 else if(!strcmp(argv[i],"--no-wm-check"))
587 arg_return->nowmcheck=1;
588 else if(!strcmp(argv[i],"--compress-cache")){
589 arg_return->zerocompression=0;
590 }
591 else if(!strcmp(argv[i],"--help")||!strcmp(argv[i],"-h")){
592 fprintf(stderr,"%s",usage);
593 exit(0);
594 }
595 else if(!strcmp(argv[i],"--version")){
596 fprintf(stderr,"recordMyDesktop v%s\n\n",VERSION);
597 exit(0);
598 }
599 else if(!strcmp(argv[i],"--print-config")){
600 PrintConfig();
601 exit(0);
602 }
603 else{
604 fprintf(stderr,"\n\tError parsing arguments.\n\t"
605 "Type --help or -h for usage.\n\n");
606 return FALSE;
607 }
608 }
609
610 return TRUE;
611 }
612