Merge CV, ver=5.1; ops/methods from HV, and interface from CV where possible
[goodguy/history.git] / cinelerra-5.1 / cinelerra / main.C
diff --git a/cinelerra-5.1/cinelerra/main.C b/cinelerra-5.1/cinelerra/main.C
new file mode 100644 (file)
index 0000000..84a3cad
--- /dev/null
@@ -0,0 +1,432 @@
+/*
+ * CINELERRA
+ * Copyright (C) 2010 Adam Williams <broadcast at earthling dot net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#include "arraylist.h"
+#include "batchrender.h"
+#include "bcsignals.h"
+#include "edl.h"
+#include "file.inc"
+#include "filexml.h"
+#include "filesystem.h"
+#include "language.h"
+#include "langinfo.h"
+#include "loadfile.inc"
+#include "mainmenu.h"
+#include "mutex.h"
+#include "mwindow.h"
+#include "mwindowgui.h"
+#include "pluginserver.h"
+#include "preferences.h"
+#include "renderfarmclient.h"
+#include "versioninfo.h"
+
+#include <locale.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define PACKAGE "cinelerra"
+#define LOCALEDIR "/locale/"
+
+
+enum
+{
+       DO_GUI,
+       DO_DEAMON,
+       DO_DEAMON_FG,
+       DO_BRENDER,
+       DO_USAGE,
+       DO_BATCHRENDER
+};
+
+#include "thread.h"
+
+
+class CommandLineThread : public Thread
+{
+public:
+       CommandLineThread(ArrayList<char*> *filenames,
+               MWindow *mwindow)
+       {
+               this->filenames = filenames;
+               this->mwindow = mwindow;
+       }
+
+
+       ~CommandLineThread()
+       {
+       }
+
+       void run()
+       {
+//PRINT_TRACE
+               mwindow->gui->lock_window("main");
+//PRINT_TRACE
+               mwindow->load_filenames(filenames, LOADMODE_REPLACE);
+//PRINT_TRACE
+               if(filenames->size() == 1)
+                       mwindow->gui->mainmenu->add_load(filenames->get(0));
+//PRINT_TRACE
+               mwindow->gui->unlock_window();
+//PRINT_TRACE
+       }
+
+       MWindow *mwindow;
+       ArrayList<char*> *filenames;
+};
+
+
+int main(int argc, char *argv[])
+{
+// handle command line arguments first
+       srand(time(0));
+       ArrayList<char*> filenames;
+       FileSystem fs;
+
+
+       int operation = DO_GUI;
+       int deamon_port = DEAMON_PORT;
+       char deamon_path[BCTEXTLEN];
+       char config_path[BCTEXTLEN];
+       char batch_path[BCTEXTLEN];
+       char locale_path[BCTEXTLEN];
+       char exe_path[BCTEXTLEN];
+       char env_path[BCTEXTLEN];
+       int nice_value = 20;
+       config_path[0] = 0;
+       batch_path[0] = 0;
+       deamon_path[0] = 0;
+       EDL::id_lock = new Mutex("EDL::id_lock");
+
+       get_exe_path(exe_path);
+       snprintf(env_path, sizeof(env_path), "CINELERRA_PATH=%s", exe_path);
+       putenv(env_path);
+       sprintf(locale_path, "%s%s", exe_path, LOCALEDIR);
+
+// detect an UTF-8 locale and try to use a non-Unicode locale instead
+// <---Beginning of dirty hack
+// This hack will be removed as soon as Cinelerra is UTF-8 compliant
+//    char *s, *language;
+
+// Query user locale
+//    if ((s = getenv("LC_ALL"))  ||
+//             (s = getenv("LC_MESSAGES")) ||
+//             (s = getenv("LC_CTYPE")) ||
+//             (s = getenv ("LANG")))
+//    {
+// Test if user locale is set to Unicode
+//        if (strstr(s, ".UTF-8"))
+//        {
+// extract language  from language-charset@variant
+//          language = strtok (s, ".@");
+// set language as the default locale
+//          setenv("LANG", language, 1);
+//        }
+//    }
+// End of dirty hack --->
+
+       bindtextdomain (PACKAGE, locale_path);
+       textdomain (PACKAGE);
+       setlocale (LC_MESSAGES, "");
+#ifdef X_HAVE_UTF8_STRING
+       char *loc = setlocale(LC_CTYPE, "");
+       if( loc ) {
+               strcpy(BC_Resources::encoding, nl_langinfo(CODESET));
+               BC_Resources::locale_utf8 = !strcmp(BC_Resources::encoding, "UTF-8");
+
+               // Extract from locale language & region
+               char locbuf[32], *p;
+               locbuf[0] = 0;
+               if((p = strchr(loc, '.')) != 0 && (p - loc) < (int)sizeof(locbuf)-1) {
+                       strncpy(locbuf, loc, p - loc);
+                       locbuf[p - loc] = 0;
+               }
+               else if(strlen(loc) < sizeof(locbuf)-1)
+                       strcpy(locbuf, loc);
+
+                // Locale 'C' does not give useful language info - assume en
+               if(!locbuf[0] || locbuf[0] == 'C')
+                       strcpy(locbuf, "en");
+
+               if((p = strchr(locbuf, '_')) && p - locbuf < LEN_LANG) {
+                       *p++ = 0;
+                       strcpy(BC_Resources::language, locbuf);
+                       if(strlen(p) < LEN_LANG)
+                               strcpy(BC_Resources::region, p);
+               }
+               else if(strlen(locbuf) < LEN_LANG)
+                       strcpy(BC_Resources::language, locbuf);
+       }
+       else
+               printf(_(PROGRAM_NAME ": Could not set locale.\n"));
+#else
+        setlocale(LC_CTYPE, "");
+#endif
+       tzset();
+
+       int load_backup = 0;
+       int start_remote_control = 0;
+
+       for(int i = 1; i < argc; i++)
+       {
+               if(!strcmp(argv[i], "-h"))
+               {
+                       operation = DO_USAGE;
+               }
+               else
+               if(!strcmp(argv[i], "-z"))
+               {
+                       start_remote_control = 1;
+               }
+               else
+               if(!strcmp(argv[i], "-r"))
+               {
+                       operation = DO_BATCHRENDER;
+                       if(argc > i + 1)
+                       {
+                               if(argv[i + 1][0] != '-')
+                               {
+                                       strcpy(batch_path, argv[i + 1]);
+                                       i++;
+                               }
+                       }
+               }
+               else
+               if(!strcmp(argv[i], "-c"))
+               {
+                       if(argc > i + 1)
+                       {
+                               strcpy(config_path, argv[i + 1]);
+                               i++;
+                       }
+                       else
+                       {
+                               fprintf(stderr, _("%s: -c needs a filename.\n"), argv[0]);
+                       }
+               }
+               else
+               if(!strcmp(argv[i], "-d") || !strcmp(argv[i], "-f"))
+               {
+                       if(!strcmp(argv[i], "-d"))
+                               operation = DO_DEAMON;
+                       else
+                               operation = DO_DEAMON_FG;
+
+                       if(argc > i + 1)
+                       {
+                               if(atol(argv[i + 1]) > 0)
+                               {
+                                       deamon_port = atol(argv[i + 1]);
+                                       i++;
+                               }
+                       }
+               }
+               else
+               if(!strcmp(argv[i], "-b"))
+               {
+                       operation = DO_BRENDER;
+                       if(i > argc - 2)
+                       {
+                               fprintf(stderr, _("-b may not be used by the user.\n"));
+                               exit(1);
+                       }
+                       else
+                               strcpy(deamon_path, argv[i + 1]);
+               }
+               else
+               if(!strcmp(argv[i], "-n"))
+               {
+                       if(argc > i + 1)
+                       {
+                               nice_value = atol(argv[i + 1]);
+                               i++;
+                       }
+               }
+               else
+               if(!strcmp(argv[i], "-x"))
+               {
+                       load_backup = 1;
+               }
+               else
+               {
+                       char *new_filename;
+                       new_filename = new char[BCTEXTLEN];
+                       strcpy(new_filename, argv[i]);
+                       fs.complete_path(new_filename);
+                       filenames.append(new_filename);
+               }
+       }
+
+
+
+       if(operation == DO_GUI ||
+               operation == DO_DEAMON ||
+               operation == DO_DEAMON_FG ||
+               operation == DO_USAGE ||
+               operation == DO_BATCHRENDER) {
+
+               fprintf(stderr, PROGRAM_NAME " " CINELERRA_VERSION);
+#ifndef REPOMAINTXT
+#define REPOMAINTXT ""
+#endif
+#ifndef COPYRIGHTTEXT1
+#define COPYRIGHTTEXT1 ""
+#endif
+#ifndef COPYRIGHTTEXT2
+#define COPYRIGHTTEXT2 ""
+#endif
+#ifndef COMPILEDATE
+#define COMPILEDATE ""
+#endif
+               fprintf(stderr, REPOMAINTXT COPYRIGHTTEXT1 COPYRIGHTTEXT2 COMPILEDATE
+                       PROGRAM_NAME " is free software, covered by the GNU General Public License,\n"
+                       "and you are welcome to change it and/or distribute copies of it under\n"
+                       "certain conditions. There is absolutely no warranty for " PROGRAM_NAME ".\n\n");
+       }
+
+       switch(operation)
+       {
+               case DO_USAGE:
+                       printf(_("\nUsage:\n"));
+                       printf(_("%s [-f] [-c configuration] [-d port] [-n nice] [-r batch file] [filenames]\n\n"), argv[0]);
+                       printf(_("-d = Run in the background as renderfarm client.  The port (400) is optional.\n"));
+                       printf(_("-f = Run in the foreground as renderfarm client.  Substitute for -d.\n"));
+                       printf(_("-n = Nice value if running as renderfarm client. (20)\n"));
+                       printf(_("-c = Configuration file to use instead of %s%s.\n"),
+                               BCASTDIR,
+                               CONFIG_FILE);
+                       printf(_("-r = batch render the contents of the batch file (%s%s) with no GUI.  batch file is optional.\n"),
+                               BCASTDIR,
+                               BATCH_PATH);
+                       printf(_("filenames = files to load\n\n\n"));
+                       exit(0);
+                       break;
+
+               case DO_DEAMON:
+               case DO_DEAMON_FG:
+               {
+                       if(operation == DO_DEAMON)
+                       {
+                               int pid = fork();
+
+                               if(pid)
+                               {
+// Redhat 9 requires _exit instead of exit here.
+                                       _exit(0);
+                               }
+                       }
+
+                       RenderFarmClient client(deamon_port,
+                               0,
+                               nice_value,
+                               config_path);
+                       client.main_loop();
+                       break;
+               }
+
+// Same thing without detachment
+               case DO_BRENDER:
+               {
+                       RenderFarmClient client(0,
+                               deamon_path,
+                               20,
+                               config_path);
+                       client.main_loop();
+                       break;
+               }
+
+               case DO_BATCHRENDER:
+               {
+                       BatchRenderThread *thread = new BatchRenderThread;
+                       thread->start_rendering(config_path,
+                               batch_path);
+                       break;
+               }
+
+               case DO_GUI:
+               {
+                       int restart = 0, done = 0;
+                       while( !done ) {
+                               BC_WindowBase::get_resources()->vframe_shm = 0;
+                               MWindow mwindow;
+                               mwindow.create_objects(1, !filenames.total, config_path);
+                               CommandLineThread *thread  = 0;
+//SET_TRACE
+// load the initial files on seperate tracks
+// use a new thread so it doesn't block the GUI
+                               if( filenames.total ) {
+                                       thread  = new CommandLineThread(&filenames, &mwindow);
+                                       thread->start();
+//PRINT_TRACE
+                               }
+                               if( load_backup ) {
+                                       load_backup = 0;
+                                       mwindow.gui->lock_window("main");
+                                       mwindow.load_backup();
+                                       mwindow.gui->unlock_window();
+                               }
+                               if( start_remote_control ) {
+                                       start_remote_control = 0;
+                                       mwindow.gui->remote_control->activate();
+                               }
+// run the program
+//PRINT_TRACE
+                               mwindow.start();
+                               mwindow.run();
+//PRINT_TRACE
+                               restart = mwindow.restart();
+                               if( restart ) {
+                                       mwindow.save_backup();
+                                       load_backup = 1;
+                                       start_remote_control =
+                                               mwindow.gui->remote_control->is_active();
+                               }
+                               if( restart <= 0 )
+                                       done = 1;
+
+                               mwindow.save_defaults();
+//PRINT_TRACE
+                               filenames.remove_all_objects();
+                               delete thread;
+                       }
+
+                       if( restart < 0 ) {
+                               char exe_path[BCTEXTLEN];
+                               int len = readlink("/proc/self/exe", exe_path, sizeof(exe_path)-1);
+                               if( len < 0 ) break;
+                               exe_path[len] = 0;
+                               char *av[4] = { 0, };  int ac = 0;
+                               av[ac++] = exe_path;
+                               if( load_backup ) av[ac++] = (char*) "-x";
+                               if( start_remote_control ) av[ac++] = (char*) "-z";
+                               av[ac++] = 0;
+                               execv(exe_path, av);
+                       }
+               }
+//SET_TRACE
+DISABLE_BUFFER
+               break;
+       }
+
+       filenames.remove_all_objects();
+       delete EDL::id_lock;  EDL::id_lock = 0;
+
+       return 0;
+}
+