update internationalization data
[goodguy/history.git] / cinelerra-5.0 / 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 "filexml.h"
26 #include "fileserver.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
39 #include <locale.h>
40 #include <stdlib.h>
41 #include <string.h>
42
43 #define PACKAGE "cinelerra"
44 #define LOCALEDIR "/locale/"
45
46
47 enum
48 {
49         DO_GUI,
50         DO_DEAMON,
51         DO_DEAMON_FG,
52         DO_BRENDER,
53         DO_USAGE,
54         DO_BATCHRENDER
55 };
56
57 #include "thread.h"
58
59
60 class CommandLineThread : public Thread
61 {
62 public:
63         CommandLineThread(ArrayList<char*> *filenames,
64                 MWindow *mwindow)
65         {
66                 this->filenames = filenames;
67                 this->mwindow = mwindow;
68         }
69
70
71         ~CommandLineThread()
72         {
73         }
74
75         void run()
76         {
77 //PRINT_TRACE
78                 mwindow->gui->lock_window("main");
79 //PRINT_TRACE
80                 mwindow->load_filenames(filenames, LOADMODE_REPLACE);
81 //PRINT_TRACE
82                 if(filenames->size() == 1)
83                         mwindow->gui->mainmenu->add_load(filenames->get(0));
84 //PRINT_TRACE
85                 mwindow->gui->unlock_window();
86 //PRINT_TRACE
87         }
88
89         MWindow *mwindow;
90         ArrayList<char*> *filenames;
91 };
92
93
94 void get_exe_path(char *result)
95 {
96 // Get executable path
97         pid_t pid = getpid();
98         char proc_path[BCTEXTLEN];
99         int len = 0;
100         result[0] = 0;
101         sprintf(proc_path, "/proc/%d/exe", pid);
102         if((len = readlink(proc_path, result, BCTEXTLEN)) >= 0)
103         {
104                 result[len] = 0;
105 //printf("Preferences::Preferences %d %s\n", __LINE__, result);
106                 char *ptr = strrchr(result, '/');
107                 if(ptr) *ptr = 0;
108         }
109
110 }
111
112
113 int main(int argc, char *argv[])
114 {
115 // handle command line arguments first
116         srand(time(0));
117         ArrayList<char*> filenames;
118         FileSystem fs;
119
120
121         int operation = DO_GUI;
122         int deamon_port = DEAMON_PORT;
123         char deamon_path[BCTEXTLEN];
124         char config_path[BCTEXTLEN];
125         char batch_path[BCTEXTLEN];
126         char locale_path[BCTEXTLEN];
127         char exe_path[BCTEXTLEN];
128         int nice_value = 20;
129         int start_remote_control = 0;
130         config_path[0] = 0;
131         batch_path[0] = 0;
132         deamon_path[0] = 0;
133         EDL::id_lock = new Mutex("EDL::id_lock");
134
135
136         get_exe_path(exe_path);
137         sprintf(locale_path, "%s%s", exe_path, LOCALEDIR);
138
139
140 // detect an UTF-8 locale and try to use a non-Unicode locale instead
141 // <---Beginning of dirty hack
142 // This hack will be removed as soon as Cinelerra is UTF-8 compliant
143 //    char *s, *language;
144
145 // Query user locale
146 //    if ((s = getenv("LC_ALL"))  ||
147 //              (s = getenv("LC_MESSAGES")) ||
148 //              (s = getenv("LC_CTYPE")) ||
149 //              (s = getenv ("LANG")))
150 //    {
151 // Test if user locale is set to Unicode
152 //        if (strstr(s, ".UTF-8"))
153 //        {
154 // extract language  from language-charset@variant
155 //          language = strtok (s, ".@");
156 // set language as the default locale
157 //          setenv("LANG", language, 1);
158 //        }
159 //    }
160 // End of dirty hack --->
161
162         bindtextdomain (PACKAGE, locale_path);
163         textdomain (PACKAGE);
164         setlocale (LC_MESSAGES, "");
165 #ifdef X_HAVE_UTF8_STRING
166         char *loc = setlocale(LC_CTYPE, "");
167         if( loc ) {
168                 strcpy(BC_Resources::encoding, nl_langinfo(CODESET));
169                 BC_Resources::locale_utf8 = !strcmp(BC_Resources::encoding, "UTF-8");
170
171                 // Extract from locale language & region
172                 char locbuf[32], *p;
173                 locbuf[0] = 0;
174                 if((p = strchr(loc, '.')) != 0 && (p - loc) < (int)sizeof(locbuf)-1) {
175                         strncpy(locbuf, loc, p - loc);
176                         locbuf[p - loc] = 0;
177                 }
178                 else if(strlen(loc) < sizeof(locbuf)-1)
179                         strcpy(locbuf, loc);
180
181                 // Locale 'C' does not give useful language info - assume en
182                 if(!locbuf[0] || locbuf[0] == 'C')
183                         strcpy(locbuf, "en");
184
185                 if((p = strchr(locbuf, '_')) && p - locbuf < LEN_LANG) {
186                         *p++ = 0;
187                         strcpy(BC_Resources::language, locbuf);
188                         if(strlen(p) < LEN_LANG)
189                                 strcpy(BC_Resources::region, p);
190                 }
191                 else if(strlen(locbuf) < LEN_LANG)
192                         strcpy(BC_Resources::language, locbuf);
193         }
194         else
195                 printf(_(PROGRAM_NAME ": Could not set locale.\n"));
196 #else
197         setlocale(LC_CTYPE, "");
198 #endif
199         tzset();
200
201
202
203
204
205
206         for(int i = 1; i < argc; i++)
207         {
208                 if(!strcmp(argv[i], "-h"))
209                 {
210                         operation = DO_USAGE;
211                 }
212                 else
213                 if(!strcmp(argv[i], "-z"))
214                 {
215                         start_remote_control = 1;
216                 }
217                 else
218                 if(!strcmp(argv[i], "-r"))
219                 {
220                         operation = DO_BATCHRENDER;
221                         if(argc > i + 1)
222                         {
223                                 if(argv[i + 1][0] != '-')
224                                 {
225                                         strcpy(batch_path, argv[i + 1]);
226                                         i++;
227                                 }
228                         }
229                 }
230                 else
231                 if(!strcmp(argv[i], "-c"))
232                 {
233                         if(argc > i + 1)
234                         {
235                                 strcpy(config_path, argv[i + 1]);
236                                 i++;
237                         }
238                         else
239                         {
240                                 fprintf(stderr, _("%s: -c needs a filename.\n"), argv[0]);
241                         }
242                 }
243                 else
244                 if(!strcmp(argv[i], "-d") || !strcmp(argv[i], "-f"))
245                 {
246                         if(!strcmp(argv[i], "-d"))
247                                 operation = DO_DEAMON;
248                         else
249                                 operation = DO_DEAMON_FG;
250
251                         if(argc > i + 1)
252                         {
253                                 if(atol(argv[i + 1]) > 0)
254                                 {
255                                         deamon_port = atol(argv[i + 1]);
256                                         i++;
257                                 }
258                         }
259                 }
260                 else
261                 if(!strcmp(argv[i], "-b"))
262                 {
263                         operation = DO_BRENDER;
264                         if(i > argc - 2)
265                         {
266                                 fprintf(stderr, _("-b may not be used by the user.\n"));
267                                 exit(1);
268                         }
269                         else
270                                 strcpy(deamon_path, argv[i + 1]);
271                 }
272                 else
273                 if(!strcmp(argv[i], "-n"))
274                 {
275                         if(argc > i + 1)
276                         {
277                                 nice_value = atol(argv[i + 1]);
278                                 i++;
279                         }
280                 }
281                 else
282                 {
283                         char *new_filename;
284                         new_filename = new char[BCTEXTLEN];
285                         strcpy(new_filename, argv[i]);
286             fs.complete_path(new_filename);
287
288                         filenames.append(new_filename);
289                 }
290         }
291
292
293
294
295         if(operation == DO_GUI ||
296                 operation == DO_DEAMON ||
297                 operation == DO_DEAMON_FG ||
298                 operation == DO_USAGE ||
299                 operation == DO_BATCHRENDER)
300         fprintf(stderr,
301                 _(PROGRAM_NAME " " CINELERRA_VERSION " " "(C)%d Adam Williams\n\n"
302                 PROGRAM_NAME " is free software, covered by the GNU General Public License,\n"
303                 "and you are welcome to change it and/or distribute copies of it under\n"
304                 "certain conditions. There is absolutely no warranty for " PROGRAM_NAME ".\n"),
305                 COPYRIGHT_DATE);
306
307
308
309
310
311         switch(operation)
312         {
313                 case DO_USAGE:
314                         printf(_("\nUsage:\n"));
315                         printf(_("%s [-f] [-c configuration] [-d port] [-n nice] [-r batch file] [filenames]\n\n"), argv[0]);
316                         printf(_("-d = Run in the background as renderfarm client.  The port (400) is optional.\n"));
317                         printf(_("-f = Run in the foreground as renderfarm client.  Substitute for -d.\n"));
318                         printf(_("-n = Nice value if running as renderfarm client. (20)\n"));
319                         printf(_("-c = Configuration file to use instead of %s%s.\n"),
320                                 BCASTDIR,
321                                 CONFIG_FILE);
322                         printf(_("-r = batch render the contents of the batch file (%s%s) with no GUI.  batch file is optional.\n"),
323                                 BCASTDIR,
324                                 BATCH_PATH);
325                         printf(_("filenames = files to load\n\n\n"));
326                         exit(0);
327                         break;
328
329                 case DO_DEAMON:
330                 case DO_DEAMON_FG:
331                 {
332                         if(operation == DO_DEAMON)
333                         {
334                                 int pid = fork();
335
336                                 if(pid)
337                                 {
338 // Redhat 9 requires _exit instead of exit here.
339                                         _exit(0);
340                                 }
341                         }
342
343                         RenderFarmClient client(deamon_port,
344                                 0,
345                                 nice_value,
346                                 config_path);
347                         client.main_loop();
348                         break;
349                 }
350
351 // Same thing without detachment
352                 case DO_BRENDER:
353                 {
354                         RenderFarmClient client(0,
355                                 deamon_path,
356                                 20,
357                                 config_path);
358                         client.main_loop();
359                         break;
360                 }
361
362                 case DO_BATCHRENDER:
363                 {
364                         BatchRenderThread *thread = new BatchRenderThread;
365                         thread->start_rendering(config_path,
366                                 batch_path);
367                         delete MWindow::file_server;
368                         break;
369                 }
370
371                 case DO_GUI:
372                 {
373                         int done = 0;
374                         int load_backup = 0;
375                         while( !done ) {
376                                 BC_WindowBase::get_resources()->vframe_shm = 0;
377                                 MWindow mwindow;
378                                 mwindow.create_objects(1, !filenames.total, config_path);
379 //SET_TRACE
380 // load the initial files on seperate tracks
381 // use a new thread so it doesn't block the GUI
382                                 if(filenames.total)
383                                 {
384 //PRINT_TRACE
385                                 CommandLineThread *thread  = new CommandLineThread(&filenames, &mwindow);
386 //PRINT_TRACE
387                                 thread->start();
388 //PRINT_TRACE
389 // thread is not deleted
390                                 }
391                                 if( load_backup ) {
392                                         load_backup = 0;
393                                         mwindow.gui->lock_window("main");
394                                         mwindow.load_backup();
395                                         mwindow.gui->unlock_window();
396                                 }
397                                 if( start_remote_control ) {
398                                         start_remote_control = 0;
399                                         mwindow.gui->remote_control->activate();
400                                 }
401 // run the program
402 //PRINT_TRACE
403                                 mwindow.start();
404                                 mwindow.run();
405 //PRINT_TRACE
406                                 if( mwindow.reload() )
407                                         start_remote_control =
408                                                 mwindow.gui->remote_control->is_active();
409                                 else
410                                         done = 1;
411                                 if( !done ) {
412                                         mwindow.save_backup();
413                                         load_backup = 1;
414                                 }
415
416                                 mwindow.save_defaults();
417 //PRINT_TRACE
418                                 filenames.remove_all_objects();
419                         }
420 //SET_TRACE
421 DISABLE_BUFFER
422                         break;
423                 }
424         }
425
426         return 0;
427 }
428