diff libgui/src/octave-gui.cc @ 17778:b5d58667d32d

new main program wrapper to handle giving up controlling tty * octave-gui.cc (octave_cli_thread): New class, from QtHandles. (dissociate_terminal): Delete. (octave_start_gui): Third arg is now START_GUI instead of FORK. Don't call dissociate_terminal. If start_gui is false, use octave_cli_thread to start Octave within a QApplication context. * sighandlers.cc (gui_driver_sig_handler): Move to src/main.in.cc. (install_gui_driver_signal_handlers): Move to src/main.in.cc and rename to octave_set_signal_handler. * octave.cc (no_fork_option): Delete. (process_command_line): Don't handle NO_FORK_OPTION. (octave_fork_gui): Move to src/main.in.cc and rename to have_controlling_terminal. * options-usage.h (usage_string, octave_print_verbose_usage_and_exit): Delete --no-fork from text. (long_opts): Delete no-fork from list. (NO_FORK_OPTION): Delete. * run-octave.in: Set OCTAVE_BINDIR in environment before exec-ing Octave binary. * src/Makefile.am: Build octave-gui, octave-cli, and octave instead of octave-cli and octave. * main-gui.cc: Rename from main.cc. Call octave_start_gui and pass START_GUI as parameter. * main.in.cc: New file.
author John W. Eaton <jwe@octave.org>
date Sun, 27 Oct 2013 18:47:22 -0400
parents e4569ae06475
children 86c6ae5f969e
line wrap: on
line diff
--- a/libgui/src/octave-gui.cc	Sun Oct 27 08:40:54 2013 -0400
+++ b/libgui/src/octave-gui.cc	Sun Oct 27 18:47:22 2013 -0400
@@ -24,8 +24,9 @@
 #include <config.h>
 #endif
 
-#include <QtGui/QApplication>
+#include <QApplication>
 #include <QTextCodec>
+#include <QThread>
 #include <QTranslator>
 
 #include <iostream>
@@ -42,6 +43,7 @@
 #include "oct-syscalls.h"
 #include "syswait.h"
 
+#include "octave.h"
 #include "sighandlers.h"
 
 #include "welcome-wizard.h"
@@ -49,6 +51,37 @@
 #include "main-window.h"
 #include "octave-gui.h"
 
+// Allow the Octave interpreter to start as in CLI mode with a
+// QApplication context so that it can use Qt for things like plotting
+// and UI widgets.
+
+class octave_cli_thread : public QThread
+{
+public:
+
+  octave_cli_thread (int argc, char **argv)
+    : m_argc (argc), m_argv (argv), m_result (0) { }
+
+  int result (void) const { return m_result; }
+
+protected:
+
+  void run (void)
+  {
+    octave_initialize_interpreter (m_argc, m_argv, 0);
+
+    m_result = octave_execute_interpreter ();
+
+    QApplication::exit (m_result);
+  }
+
+private:
+
+  int m_argc;
+  char** m_argv;
+  int m_result;
+};
+
 
 // Custom message handler for filtering some messages from Qt.
 
@@ -78,104 +111,75 @@
      }
  }
 
-
-// Dissociate from the controlling terminal, if any.
+// If START_GUI is false, we still set up the QApplication so that we
+// can use Qt widgets for plot windows.
 
-static void
-dissociate_terminal (void)
+int
+octave_start_gui (int argc, char *argv[], bool start_gui)
 {
-#if ! (defined (__WIN32__) || defined (__APPLE__)) || defined (__CYGWIN__)
- 
-  pid_t pid = fork ();
+  qInstallMsgHandler (message_handler);
 
-  if (pid < 0)
+  QApplication application (argc, argv);
+
+  if (start_gui)
     {
-      std::cerr << "fork failed!" << std::endl;;
-      exit (1);
-    }
-  else if (pid == 0)
-    {
-      // Child.
+      // Set the codec for all strings
+      QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));
+
+      // install translators for the gui and qt text
+      QTranslator gui_tr, qt_tr, qsci_tr;
+      resource_manager::config_translators (&qt_tr,&qsci_tr,&gui_tr);
+      application.installTranslator (&qt_tr);
+      application.installTranslator (&qsci_tr);
+      application.installTranslator (&gui_tr);
+
+      while (true)
+        {
+          if (resource_manager::is_first_run ())
+            {
+              welcome_wizard welcomeWizard;
+              welcomeWizard.exec ();
+              resource_manager::reload_settings ();
+            }
+          else
+            {
+              // update network-settings
+              resource_manager::update_network_settings ();
 
-      if (setsid () < 0)
-        {
-          std::cerr << "setsid error" << std::endl;
-          exit (1);
+#if ! defined (__WIN32__) || defined (__CYGWIN__)
+              // If we were started from a launcher, TERM might not be
+              // defined, but we provide a terminal with xterm
+              // capabilities.
+
+              std::string term = octave_env::getenv ("TERM");
+
+              if (term.empty ())
+                octave_env::putenv ("TERM", "xterm");
+#else
+              std::string term = octave_env::getenv ("TERM");
+
+              if (term.empty ())
+                octave_env::putenv ("TERM", "cygwin");
+#endif
+
+              // create main window, read settings, and show window
+              main_window w;
+              w.read_settings ();  // get widget settings and window layout
+              w.focus_command_window ();
+              w.connect_visibility_changed (); // connect signals for changes in
+              // visibility not before w is shown
+              return application.exec ();
+            }
         }
     }
   else
     {
-      // Parent
-
-      install_gui_driver_signal_handlers (pid);
-
-      int status;
-
-      waitpid (pid, &status, 0);
-
-      exit (octave_wait::ifexited (status)
-            ? octave_wait::exitstatus (status) : 127);
-    }
-
-#endif
-}
+      octave_cli_thread main_thread (argc, argv);
 
-int
-octave_start_gui (int argc, char *argv[], bool fork)
-{
-  if (fork)
-    dissociate_terminal ();
-
-  qInstallMsgHandler (message_handler);
-
-  QApplication application (argc, argv);
-
-  // Set the codec for all strings
-  QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));
-
-  // install translators for the gui and qt text
-  QTranslator gui_tr, qt_tr, qsci_tr;
-  resource_manager::config_translators (&qt_tr,&qsci_tr,&gui_tr);
-  application.installTranslator (&qt_tr);
-  application.installTranslator (&qsci_tr);
-  application.installTranslator (&gui_tr);
+      application.setQuitOnLastWindowClosed (false);
 
-  while (true)
-    {
-      if (resource_manager::is_first_run ())
-        {
-          welcome_wizard welcomeWizard;
-          welcomeWizard.exec ();
-          resource_manager::reload_settings ();
-        }
-      else
-        {
-          // update network-settings
-          resource_manager::update_network_settings ();
-
-#if ! defined (__WIN32__) || defined (__CYGWIN__)
-          // If we were started from a launcher, TERM might not be
-          // defined, but we provide a terminal with xterm
-          // capabilities.
+      main_thread.start ();
 
-          std::string term = octave_env::getenv ("TERM");
-
-          if (term.empty ())
-            octave_env::putenv ("TERM", "xterm");
-#else
-          std::string term = octave_env::getenv ("TERM");
-
-          if (term.empty ())
-            octave_env::putenv ("TERM", "cygwin");
-#endif
-
-          // create main window, read settings, and show window
-          main_window w;
-          w.read_settings ();  // get widget settings and window layout
-          w.focus_command_window ();
-          w.connect_visibility_changed (); // connect signals for changes in
-                                           // visibility not before w is shown
-          return application.exec ();
-        }
+      return application.exec ();
     }
 }