f54edcec0b904d6bb38b65187af9e0fea35d8684
[goodguy/history.git] / cinelerra-5.1 / cinelerra / main.C
1 /*
2  * CINELERRA
3  * Copyright (C) 2010 Adam Williams <broadcast at earthling dot net>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  *
19  */
20
21 #include "arraylist.h"
22 #include "batchrender.h"
23 #include "bcsignals.h"
24 #include "edl.h"
25 #include "file.h"
26 #include "filexml.h"
27 #include "filesystem.h"
28 #include "language.h"
29 #include "langinfo.h"
30 #include "loadfile.inc"
31 #include "mainmenu.h"
32 #include "mutex.h"
33 #include "mwindow.h"
34 #include "mwindowgui.h"
35 #include "pluginserver.h"
36 #include "preferences.h"
37 #include "renderfarmclient.h"
38 #include "versioninfo.h"
39
40 #include <locale.h>
41 #include <stdlib.h>
42 #include <string.h>
43
44 enum
45 {
46         DO_GUI,
47         DO_DEAMON,
48         DO_DEAMON_FG,
49         DO_BRENDER,
50         DO_USAGE,
51         DO_BATCHRENDER
52 };
53
54 #include "thread.h"
55
56
57 class CommandLineThread : public Thread
58 {
59 public:
60         CommandLineThread(ArrayList<char*> *filenames,
61                 MWindow *mwindow)
62         {
63                 this->filenames = filenames;
64                 this->mwindow = mwindow;
65         }
66
67
68         ~CommandLineThread()
69         {
70         }
71
72         void run()
73         {
74 //PRINT_TRACE
75                 mwindow->gui->lock_window("main");
76 //PRINT_TRACE
77                 mwindow->load_filenames(filenames, LOADMODE_REPLACE);
78 //PRINT_TRACE
79                 if(filenames->size() == 1)
80                         mwindow->gui->mainmenu->add_load(filenames->get(0));
81 //PRINT_TRACE
82                 mwindow->gui->unlock_window();
83 //PRINT_TRACE
84         }
85
86         MWindow *mwindow;
87         ArrayList<char*> *filenames;
88 };
89
90
91 int main(int argc, char *argv[])
92 {
93 // handle command line arguments first
94         srand(time(0));
95         ArrayList<char*> filenames;
96         FileSystem fs;
97
98
99         int operation = DO_GUI;
100         int deamon_port = DEAMON_PORT;
101         char deamon_path[BCTEXTLEN];
102         char config_path[BCTEXTLEN];
103         char batch_path[BCTEXTLEN];
104         int nice_value = 20;
105         config_path[0] = 0;
106         batch_path[0] = 0;
107         deamon_path[0] = 0;
108         EDL::id_lock = new Mutex("EDL::id_lock");
109
110         File::init_cin_path();
111         const char *locale_path = File::get_locale_path();
112         const char *cin = File::get_cin();
113
114         bindtextdomain(cin, locale_path);
115         textdomain(cin);
116         setlocale(LC_MESSAGES, "");
117
118 #ifdef X_HAVE_UTF8_STRING
119         char *loc = setlocale(LC_CTYPE, "");
120         if( loc ) {
121                 strcpy(BC_Resources::encoding, nl_langinfo(CODESET));
122                 BC_Resources::locale_utf8 = !strcmp(BC_Resources::encoding, "UTF-8");
123
124                 // Extract from locale language & region
125                 char locbuf[32], *p;
126                 locbuf[0] = 0;
127                 if((p = strchr(loc, '.')) != 0 && (p - loc) < (int)sizeof(locbuf)-1) {
128                         strncpy(locbuf, loc, p - loc);
129                         locbuf[p - loc] = 0;
130                 }
131                 else if(strlen(loc) < sizeof(locbuf)-1)
132                         strcpy(locbuf, loc);
133
134                 // Locale 'C' does not give useful language info - assume en
135                 if(!locbuf[0] || locbuf[0] == 'C')
136                         strcpy(locbuf, "en");
137
138                 if((p = strchr(locbuf, '_')) && p - locbuf < LEN_LANG) {
139                         *p++ = 0;
140                         strcpy(BC_Resources::language, locbuf);
141                         if(strlen(p) < LEN_LANG)
142                                 strcpy(BC_Resources::region, p);
143                 }
144                 else if(strlen(locbuf) < LEN_LANG)
145                         strcpy(BC_Resources::language, locbuf);
146         }
147         else
148                 printf(_(PROGRAM_NAME ": Could not set locale.\n"));
149 #else
150         setlocale(LC_CTYPE, "");
151 #endif
152         tzset();
153
154         int load_backup = 0;
155         int start_remote_control = 0;
156
157         for(int i = 1; i < argc; i++)
158         {
159                 if(!strcmp(argv[i], "-h"))
160                 {
161                         operation = DO_USAGE;
162                 }
163                 else
164                 if(!strcmp(argv[i], "-z"))
165                 {
166                         start_remote_control = 1;
167                 }
168                 else
169                 if(!strcmp(argv[i], "-r"))
170                 {
171                         operation = DO_BATCHRENDER;
172                         if(argc > i + 1)
173                         {
174                                 if(argv[i + 1][0] != '-')
175                                 {
176                                         strcpy(batch_path, argv[i + 1]);
177                                         i++;
178                                 }
179                         }
180                 }
181                 else
182                 if(!strcmp(argv[i], "-c"))
183                 {
184                         if(argc > i + 1)
185                         {
186                                 strcpy(config_path, argv[i + 1]);
187                                 i++;
188                         }
189                         else
190                         {
191                                 fprintf(stderr, _("%s: -c needs a filename.\n"), argv[0]);
192                         }
193                 }
194                 else
195                 if(!strcmp(argv[i], "-d") || !strcmp(argv[i], "-f"))
196                 {
197                         if(!strcmp(argv[i], "-d"))
198                                 operation = DO_DEAMON;
199                         else
200                                 operation = DO_DEAMON_FG;
201
202                         if(argc > i + 1)
203                         {
204                                 if(atol(argv[i + 1]) > 0)
205                                 {
206                                         deamon_port = atol(argv[i + 1]);
207                                         i++;
208                                 }
209                         }
210                 }
211                 else
212                 if(!strcmp(argv[i], "-b"))
213                 {
214                         operation = DO_BRENDER;
215                         if(i > argc - 2)
216                         {
217                                 fprintf(stderr, _("-b may not be used by the user.\n"));
218                                 exit(1);
219                         }
220                         else
221                                 strcpy(deamon_path, argv[i + 1]);
222                 }
223                 else
224                 if(!strcmp(argv[i], "-n"))
225                 {
226                         if(argc > i + 1)
227                         {
228                                 nice_value = atol(argv[i + 1]);
229                                 i++;
230                         }
231                 }
232                 else
233                 if(!strcmp(argv[i], "-x"))
234                 {
235                         load_backup = 1;
236                 }
237                 else
238                 {
239                         char *new_filename;
240                         new_filename = new char[BCTEXTLEN];
241                         strcpy(new_filename, argv[i]);
242                         fs.complete_path(new_filename);
243                         filenames.append(new_filename);
244                 }
245         }
246
247
248
249         if(operation == DO_GUI ||
250                 operation == DO_DEAMON ||
251                 operation == DO_DEAMON_FG ||
252                 operation == DO_USAGE ||
253                 operation == DO_BATCHRENDER) {
254
255                 fprintf(stderr, PROGRAM_NAME " " CINELERRA_VERSION);
256 #ifndef REPOMAINTXT
257 #define REPOMAINTXT ""
258 #endif
259 #ifndef COPYRIGHTTEXT1
260 #define COPYRIGHTTEXT1 ""
261 #endif
262 #ifndef COPYRIGHTTEXT2
263 #define COPYRIGHTTEXT2 ""
264 #endif
265 #ifndef COMPILEDATE
266 #define COMPILEDATE ""
267 #endif
268                 fprintf(stderr, REPOMAINTXT COPYRIGHTTEXT1 COPYRIGHTTEXT2 COMPILEDATE
269                         PROGRAM_NAME " is free software, covered by the GNU General Public License,\n"
270                         "and you are welcome to change it and/or distribute copies of it under\n"
271                         "certain conditions. There is absolutely no warranty for " PROGRAM_NAME ".\n\n");
272         }
273
274         switch(operation)
275         {
276                 case DO_USAGE:
277                         printf(_("\nUsage:\n"));
278                         printf(_("%s [-f] [-c configuration] [-d port] [-n nice] [-r batch file] [filenames]\n\n"), argv[0]);
279                         printf(_("-d = Run in the background as renderfarm client.  The port (400) is optional.\n"));
280                         printf(_("-f = Run in the foreground as renderfarm client.  Substitute for -d.\n"));
281                         printf(_("-n = Nice value if running as renderfarm client. (20)\n"));
282                         printf(_("-c = Configuration file to use instead of %s/%s.\n"),
283                                 File::get_config_path(), CONFIG_FILE);
284                         printf(_("-r = batch render the contents of the batch file (%s/%s) with no GUI.  batch file is optional.\n"),
285                                 File::get_config_path(), BATCH_PATH);
286                         printf(_("filenames = files to load\n\n\n"));
287                         exit(0);
288                         break;
289
290                 case DO_DEAMON:
291                 case DO_DEAMON_FG:
292                 {
293                         if(operation == DO_DEAMON)
294                         {
295                                 int pid = fork();
296
297                                 if(pid)
298                                 {
299 // Redhat 9 requires _exit instead of exit here.
300                                         _exit(0);
301                                 }
302                         }
303
304                         RenderFarmClient client(deamon_port,
305                                 0,
306                                 nice_value,
307                                 config_path);
308                         client.main_loop();
309                         break;
310                 }
311
312 // Same thing without detachment
313                 case DO_BRENDER:
314                 {
315                         RenderFarmClient client(0,
316                                 deamon_path,
317                                 20,
318                                 config_path);
319                         client.main_loop();
320                         break;
321                 }
322
323                 case DO_BATCHRENDER:
324                 {
325                         BatchRenderThread *thread = new BatchRenderThread;
326                         thread->start_rendering(config_path,
327                                 batch_path);
328                         break;
329                 }
330
331                 case DO_GUI:
332                 {
333                         int restart = 0, done = 0;
334                         while( !done ) {
335                                 BC_WindowBase::get_resources()->vframe_shm = 0;
336                                 MWindow mwindow;
337                                 mwindow.create_objects(1, !filenames.total, config_path);
338                                 CommandLineThread *thread  = 0;
339 //SET_TRACE
340 // load the initial files on seperate tracks
341 // use a new thread so it doesn't block the GUI
342                                 if( filenames.total ) {
343                                         thread  = new CommandLineThread(&filenames, &mwindow);
344                                         thread->start();
345 //PRINT_TRACE
346                                 }
347                                 if( load_backup ) {
348                                         load_backup = 0;
349                                         mwindow.gui->lock_window("main");
350                                         mwindow.load_backup();
351                                         mwindow.gui->unlock_window();
352                                 }
353                                 if( start_remote_control ) {
354                                         start_remote_control = 0;
355                                         mwindow.gui->remote_control->activate();
356                                 }
357 // run the program
358 //PRINT_TRACE
359                                 mwindow.start();
360                                 mwindow.run();
361 //PRINT_TRACE
362                                 restart = mwindow.restart();
363                                 if( restart ) {
364                                         mwindow.save_backup();
365                                         load_backup = 1;
366                                         start_remote_control =
367                                                 mwindow.gui->remote_control->is_active();
368                                 }
369                                 if( restart <= 0 )
370                                         done = 1;
371
372                                 mwindow.save_defaults();
373 //PRINT_TRACE
374                                 filenames.remove_all_objects();
375                                 delete thread;
376                         }
377
378                         if( restart < 0 ) {
379                                 char exe_path[BCTEXTLEN];
380                                 int len = readlink("/proc/self/exe", exe_path, sizeof(exe_path)-1);
381                                 if( len < 0 ) break;
382                                 exe_path[len] = 0;
383                                 char *av[4] = { 0, };  int ac = 0;
384                                 av[ac++] = exe_path;
385                                 if( load_backup ) av[ac++] = (char*) "-x";
386                                 if( start_remote_control ) av[ac++] = (char*) "-z";
387                                 av[ac++] = 0;
388                                 execv(exe_path, av);
389                         }
390                 }
391 //SET_TRACE
392 DISABLE_BUFFER
393                 break;
394         }
395
396         filenames.remove_all_objects();
397         delete EDL::id_lock;  EDL::id_lock = 0;
398
399         return 0;
400 }
401