changeset 16430:1766d8655006

Merge in Dan's changes
author Jordi Gutiérrez Hermoso <jordigh@octave.org>
date Thu, 04 Apr 2013 09:28:47 -0400
parents 586972e3ea7a (current diff) f016a5342e19 (diff)
children 5982d469f79b
files libgui/src/octave-adapter/octave-event-listener.h libgui/src/octave-adapter/octave-link.cc libgui/src/octave-adapter/octave-link.h libgui/src/octave-adapter/octave-main-thread.cc libgui/src/octave-adapter/octave-main-thread.h libinterp/corefcn/__execute_edit_hook__.cc
diffstat 23 files changed, 326 insertions(+), 1189 deletions(-) [+]
line wrap: on
line diff
--- a/libgui/qterminal/libqterminal/unix/SelfListener.cpp
+++ b/libgui/qterminal/libqterminal/unix/SelfListener.cpp
@@ -23,7 +23,7 @@
 }
 
 void SelfListener::run() {
-    char buf[4096];
+    char buf[4096 + 1];
     int len;
     bool running = true;
     while(running) {
--- a/libgui/src/main-window.cc
+++ b/libgui/src/main-window.cc
@@ -42,7 +42,6 @@
 #include "file-editor.h"
 #endif
 #include "main-window.h"
-#include "octave-link.h"
 #include "settings-dialog.h"
 
 #include "builtins.h"
@@ -60,7 +59,6 @@
 {
   // We have to set up all our windows, before we finally launch octave.
   construct ();
-  octave_link::launch_octave ();
 }
 
 main_window::~main_window ()
@@ -72,6 +70,9 @@
   if (_octave_qt_event_listener)
     delete _octave_qt_event_listener;
 
+  octave_link::connect_link (0);
+  delete _octave_qt_link;
+
 #ifdef HAVE_QSCINTILLA
   if (_file_editor)
     delete _file_editor;
@@ -494,39 +495,6 @@
 }
 
 void
-main_window::handle_insert_debugger_pointer_request (const QString& file, int line)
-{
-#ifdef HAVE_QSCINTILLA
-  _file_editor->handle_insert_debugger_pointer_request (file, line);
-#endif
-}
-
-void
-main_window::handle_delete_debugger_pointer_request (const QString& file, int line)
-{
-#ifdef HAVE_QSCINTILLA
-  _file_editor->handle_delete_debugger_pointer_request (file, line);
-#endif
-}
-
-void
-main_window::handle_update_dbstop_marker_request (bool insert,
-                                                  const QString& file, int line)
-{
-#ifdef HAVE_QSCINTILLA
-  _file_editor->handle_update_dbstop_marker_request (insert, file, line);
-#endif
-}
-
-void
-main_window::handle_edit_file_request (const QString& file)
-{
-#ifdef HAVE_QSCINTILLA
-  _file_editor->handle_edit_file_request (file);
-#endif
-}
-
-void
 main_window::debug_continue ()
 {
   octave_link::post_event (this, &main_window::debug_continue_callback);
@@ -1165,7 +1133,6 @@
   setStatusBar (_status_bar);
 
   _octave_qt_event_listener = new octave_qt_event_listener ();
-  octave_link::register_event_listener (_octave_qt_event_listener);
 
   connect (_octave_qt_event_listener,
            SIGNAL (current_directory_has_changed_signal (QString)),
@@ -1192,23 +1159,33 @@
            this,
            SLOT (handle_quit_debug_mode ()));
 
-  connect (_octave_qt_event_listener,
-           SIGNAL (insert_debugger_pointer_signal (const QString&, int)), this,
+  // FIXME -- is it possible to eliminate the event_listenter?
+
+  _octave_qt_link = new octave_qt_link ();
+
+  connect (_octave_qt_link,
+           SIGNAL (update_dbstop_marker_signal (bool, const QString&, int)),
+           _file_editor,
+           SLOT (handle_update_dbstop_marker_request (bool, const QString&, int)));
+
+  connect (_octave_qt_link,
+           SIGNAL (edit_file_signal (const QString&)),
+           _file_editor,
+           SLOT (handle_edit_file_request (const QString&)));
+
+  connect (_octave_qt_link,
+           SIGNAL (insert_debugger_pointer_signal (const QString&, int)),
+           _file_editor,
            SLOT (handle_insert_debugger_pointer_request (const QString&, int)));
 
-  connect (_octave_qt_event_listener,
-           SIGNAL (delete_debugger_pointer_signal (const QString&, int)), this,
+  connect (_octave_qt_link,
+           SIGNAL (delete_debugger_pointer_signal (const QString&, int)),
+           _file_editor,
            SLOT (handle_delete_debugger_pointer_request (const QString&, int)));
 
-  connect (_octave_qt_event_listener,
-           SIGNAL (update_dbstop_marker_signal (bool, const QString&, int)),
-           this,
-           SLOT (handle_update_dbstop_marker_request (bool, const QString&, int)));
+  octave_link::connect_link (_octave_qt_link);
 
-  connect (_octave_qt_event_listener,
-           SIGNAL (edit_file_signal (const QString&)),
-           this,
-           SLOT (handle_edit_file_request(const QString&)));
+  octave_link::register_event_listener (_octave_qt_event_listener);
 }
 
 void
--- a/libgui/src/main-window.h
+++ b/libgui/src/main-window.h
@@ -50,6 +50,7 @@
 #include "terminal-dockwidget.h"
 #include "documentation-dockwidget.h"
 #include "octave-qt-event-listener.h"
+#include "octave-qt-link.h"
 
 /**
  * \class MainWindow
@@ -107,10 +108,6 @@
 
   void handle_entered_debug_mode ();
   void handle_quit_debug_mode ();
-  void handle_insert_debugger_pointer_request (const QString& file, int line);
-  void handle_delete_debugger_pointer_request (const QString& file, int line);
-  void handle_update_dbstop_marker_request (bool insert, const QString& file, int line);
-  void handle_edit_file_request (const QString& file);
   void debug_continue ();
   void debug_step_into ();
   void debug_step_over ();
@@ -178,6 +175,8 @@
 
   octave_qt_event_listener *_octave_qt_event_listener;
 
+  octave_qt_link *_octave_qt_link;
+
   // Flag for closing whole application
   bool                      _closing;
 };
--- a/libgui/src/module.mk
+++ b/libgui/src/module.mk
@@ -71,14 +71,15 @@
   src/moc-files-dockwidget.cc \
   src/moc-history-dockwidget.cc \
   src/moc-main-window.cc \
+  src/moc-octave-main-thread.cc \
   src/moc-octave-qt-event-listener.cc \
+  src/moc-octave-qt-link.cc \
   src/moc-settings-dialog.cc \
   src/moc-terminal-dockwidget.cc \
   src/moc-color-picker.cc \
   src/moc-welcome-wizard.cc \
   src/moc-workspace-model.cc \
   src/moc-workspace-view.cc \
-  src/octave-adapter/moc-octave-main-thread.cc \
   src/qtinfo/moc-parser.cc \
   src/qtinfo/moc-webinfo.cc \
   src/moc-octave-dock-widget.cc
@@ -104,11 +105,10 @@
   src/m-editor/find-dialog.h \
   src/m-editor/lexer-octave-gui.h \
   src/main-window.h \
-  src/octave-adapter/octave-event-listener.h \
-  src/octave-adapter/octave-link.h \
-  src/octave-adapter/octave-main-thread.h \
   src/octave-gui.h \
+  src/octave-main-thread.h \
   src/octave-qt-event-listener.h \
+  src/octave-qt-link.h \
   src/qtinfo/parser.h \
   src/qtinfo/webinfo.h \
   src/resource-manager.h \
@@ -129,10 +129,10 @@
   src/m-editor/find-dialog.cc \
   src/m-editor/lexer-octave-gui.cc \
   src/main-window.cc \
-  src/octave-adapter/octave-link.cc \
-  src/octave-adapter/octave-main-thread.cc \
   src/octave-gui.cc \
+  src/octave-main-thread.cc \
   src/octave-qt-event-listener.cc \
+  src/octave-qt-link.cc \
   src/qtinfo/parser.cc \
   src/qtinfo/webinfo.cc \
   src/resource-manager.cc \
@@ -153,7 +153,6 @@
   -I$(srcdir)/qterminal/libqterminal \
   -Isrc -I$(srcdir)/src \
   -I$(srcdir)/src/m-editor \
-  -I$(srcdir)/src/octave-adapter \
   -I$(srcdir)/src/qtinfo \
   -I$(top_srcdir)/liboctave/cruft/misc \
   -I$(top_srcdir)/liboctave/array \
--- a/libgui/src/octave-gui.cc
+++ b/libgui/src/octave-gui.cc
@@ -80,7 +80,7 @@
 int
 octave_start_gui (int argc, char *argv[])
 {
-  dissociate_terminal ();
+  // dissociate_terminal ();
 
   QApplication application (argc, argv);
 
rename from libgui/src/octave-adapter/octave-main-thread.cc
rename to libgui/src/octave-main-thread.cc
--- a/libgui/src/octave-adapter/octave-main-thread.cc
+++ b/libgui/src/octave-main-thread.cc
@@ -35,76 +35,6 @@
 #include "octave-main-thread.h"
 #include "octave-link.h"
 
-static octave_value_list
-pre_input_event_hook_fcn (const octave_value_list&, int)
-{
-  octave_value_list retval;
-
-  octave_link::pre_input_event_hook_fcn ();
-
-  return retval;
-}
-
-static octave_value_list
-post_input_event_hook_fcn (const octave_value_list&, int)
-{
-  octave_value_list retval;
-
-  octave_link::post_input_event_hook_fcn ();
-
-  return retval;
-}
-
-static octave_value_list
-enter_debugger_event_hook_fcn (const octave_value_list& args, int)
-{
-  octave_value_list retval;
-
-  octave_link::enter_debugger_event_hook_fcn (args);
-
-  return retval;
-}
-
-static octave_value_list
-exit_debugger_event_hook_fcn (const octave_value_list& args, int)
-{
-  octave_value_list retval;
-
-  octave_link::exit_debugger_event_hook_fcn (args);
-
-  return retval;
-}
-
-static octave_value_list
-dbstop_hook_fcn (const octave_value_list& args, int)
-{
-  octave_value_list retval;
-
-  octave_link::update_breakpoint_hook_fcn (true, args);
-
-  return retval;
-}
-
-static octave_value_list
-dbclear_hook_fcn (const octave_value_list& args, int)
-{
-  octave_value_list retval;
-
-  octave_link::update_breakpoint_hook_fcn (false, args);
-
-  return retval;
-}
-
-static octave_value_list
-edit_hook_fcn (const octave_value_list& args, int)
-{
-  octave_value_list retval;
-
-  octave_link::edit_file (args);
-
-  return retval;
-}
-
 octave_main_thread::octave_main_thread () : QThread ()
 {
 }
@@ -120,34 +50,6 @@
   octave_initialize_interpreter (octave_cmdline_argc, octave_cmdline_argv,
                                  octave_embedded);
 
-  octave_value pre_fcn (new octave_builtin (pre_input_event_hook_fcn));
-  octave_value pre_fcn_handle (new octave_fcn_handle (pre_fcn));
-  Fadd_pre_input_event_hook (pre_fcn_handle);
-
-  octave_value post_fcn (new octave_builtin (post_input_event_hook_fcn));
-  octave_value post_fcn_handle (new octave_fcn_handle (post_fcn));
-  Fadd_post_input_event_hook (post_fcn_handle);
-
-  octave_value enter_debugger_fcn (new octave_builtin (enter_debugger_event_hook_fcn));
-  octave_value enter_debugger_fcn_handle (new octave_fcn_handle (enter_debugger_fcn));
-  Fadd_enter_debugger_event_hook (enter_debugger_fcn_handle);
-
-  octave_value exit_debugger_fcn (new octave_builtin (exit_debugger_event_hook_fcn));
-  octave_value exit_debugger_fcn_handle (new octave_fcn_handle (exit_debugger_fcn));
-  Fadd_exit_debugger_event_hook (exit_debugger_fcn_handle);
-
-  octave_value dbstop_fcn (new octave_builtin (dbstop_hook_fcn));
-  octave_value dbstop_fcn_handle (new octave_fcn_handle (dbstop_fcn));
-  Fadd_dbstop_hook (dbstop_fcn_handle);
-
-  octave_value dbclear_fcn (new octave_builtin (dbclear_hook_fcn));
-  octave_value dbclear_fcn_handle (new octave_fcn_handle (dbclear_fcn));
-  Fadd_dbclear_hook (dbclear_fcn_handle);
-
-  octave_value edit_fcn (new octave_builtin (edit_hook_fcn));
-  octave_value edit_fcn_handle (new octave_fcn_handle (edit_fcn));
-  Fadd_edit_hook (edit_fcn_handle);
-
   // Prime the history list.
   octave_link::update_history ();
 
rename from libgui/src/octave-adapter/octave-main-thread.h
rename to libgui/src/octave-main-thread.h
--- a/libgui/src/octave-qt-event-listener.cc
+++ b/libgui/src/octave-qt-event-listener.cc
@@ -54,35 +54,6 @@
 }
 
 void
-octave_qt_event_listener::insert_debugger_pointer (const std::string& file,
-                                                   int line)
-{
-  emit insert_debugger_pointer_signal (QString::fromStdString (file), line);
-}
-
-void
-octave_qt_event_listener::delete_debugger_pointer (const std::string& file,
-                                                   int line)
-{
-  emit delete_debugger_pointer_signal (QString::fromStdString (file), line);
-}
-
-void
-octave_qt_event_listener::update_dbstop_marker (bool insert,
-                                                const std::string& file,
-                                                int line)
-{
-  emit update_dbstop_marker_signal (insert, QString::fromStdString (file),
-                                    line);
-}
-
-void
-octave_qt_event_listener::edit_file (const std::string& file)
-{
-  emit edit_file_signal (QString::fromStdString (file));
-}
-
-void
 octave_qt_event_listener::about_to_exit ()
 {
   qApp->quit ();
--- a/libgui/src/octave-qt-event-listener.h
+++ b/libgui/src/octave-qt-event-listener.h
@@ -37,10 +37,6 @@
   void current_directory_has_changed (const std::string& directory);
   void update_workspace (void);
   void update_history (void);
-  void insert_debugger_pointer (const std::string& file, int line);
-  void delete_debugger_pointer (const std::string& file, int line);
-  void update_dbstop_marker (bool insert, const std::string& file, int line);
-  void edit_file (const std::string& file);
   void about_to_exit ();
 
   void entered_debug_mode ();
@@ -50,10 +46,6 @@
   void current_directory_has_changed_signal (const QString& directory);
   void update_workspace_signal (void);
   void update_history_signal (void);
-  void insert_debugger_pointer_signal (const QString& file, int line);
-  void delete_debugger_pointer_signal (const QString& file, int line);
-  void update_dbstop_marker_signal (bool insert, const QString& file, int line);
-  void edit_file_signal (const QString& file);
   void entered_debug_mode_signal ();
   void quit_debug_mode_signal ();
 };
new file mode 100644
--- /dev/null
+++ b/libgui/src/octave-qt-link.cc
@@ -0,0 +1,109 @@
+/*
+
+Copyright (C) 2013 John W. Eaton
+Copyright (C) 2011-2012 Jacob Dawid
+Copyright (C) 2011-2012 John P. Swensen
+
+This file is part of Octave.
+
+Octave 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 3 of the License, or (at your
+option) any later version.
+
+Octave 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 Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "octave-qt-link.h"
+
+octave_qt_link::octave_qt_link (void)
+  : octave_link (), main_thread (new octave_main_thread)
+{
+  // Start the first one.
+  main_thread->start ();
+}
+
+void
+octave_qt_link::do_update_workspace (void)
+{
+  if (event_listener)
+    {
+      event_listener->update_workspace ();
+
+      do_process_events ();
+    }
+}
+
+void
+octave_qt_link::do_update_history (void)
+{
+  if (event_listener)
+    {
+      event_listener->update_history ();
+
+      do_process_events ();
+    }
+}
+
+void
+octave_qt_link::do_pre_input_event (void)
+{
+  do_update_workspace ();
+}
+
+void
+octave_qt_link::do_post_input_event (void)
+{
+  do_update_history ();
+}
+
+void
+octave_qt_link::do_enter_debugger_event (const std::string& file, int line)
+{
+  do_insert_debugger_pointer (file, line);
+}
+
+void
+octave_qt_link::do_exit_debugger_event (const std::string& file, int line)
+{
+  do_delete_debugger_pointer (file, line);
+}
+
+void
+octave_qt_link::do_update_breakpoint (bool insert,
+                                      const std::string& file, int line)
+{
+  emit update_dbstop_marker_signal (insert, QString::fromStdString (file), line);
+}
+
+bool
+octave_qt_link::do_edit_file (const std::string& file)
+{
+  emit edit_file_signal (QString::fromStdString (file));
+
+  return true;
+}
+
+void
+octave_qt_link::do_insert_debugger_pointer (const std::string& file, int line)
+{
+  emit insert_debugger_pointer_signal (QString::fromStdString (file), line);
+}
+
+void
+octave_qt_link::do_delete_debugger_pointer (const std::string& file, int line)
+{
+  emit delete_debugger_pointer_signal (QString::fromStdString (file), line);
+}
new file mode 100644
--- /dev/null
+++ b/libgui/src/octave-qt-link.h
@@ -0,0 +1,94 @@
+/*
+
+Copyright (C) 2013 John W. Eaton
+Copyright (C) 2011-2012 Jacob Dawid
+Copyright (C) 2011-2012 John P. Swensen
+
+This file is part of Octave.
+
+Octave 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 3 of the License, or (at your
+option) any later version.
+
+Octave 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 Octave; see the file COPYING.  If not, see
+<http://www.gnu.org/licenses/>.
+
+*/
+
+#ifndef OCTAVE_QT_LINK_H
+#define OCTAVE_QT_LINK_H
+
+#include <string>
+
+#include <QObject>
+#include <QString>
+
+#include "octave-link.h"
+#include "octave-main-thread.h"
+
+// \class OctaveLink
+// \brief Provides threadsafe access to octave.
+// \author Jacob Dawid
+//
+// This class is a wrapper around octave and provides thread safety by
+// buffering access operations to octave and executing them in the
+// readline event hook, which lives in the octave thread.
+
+class octave_qt_link : public QObject, public octave_link
+{
+  Q_OBJECT
+
+public:
+
+  octave_qt_link (void);
+
+  ~octave_qt_link (void) { }
+
+  void do_update_workspace (void);
+
+  void do_update_history (void);
+
+  void do_pre_input_event (void);
+  void do_post_input_event (void);
+
+  void do_enter_debugger_event (const std::string& file, int line);
+  void do_exit_debugger_event (const std::string& file, int line);
+
+  void do_update_breakpoint (bool insert, const std::string& file, int line);
+
+  bool do_edit_file (const std::string& file);
+
+private:
+
+  // No copying!
+
+  octave_qt_link (const octave_qt_link&);
+
+  octave_qt_link& operator = (const octave_qt_link&);
+
+  void do_insert_debugger_pointer (const std::string& file, int line);
+
+  void do_delete_debugger_pointer (const std::string& file, int line);
+
+  // Thread running octave_main.
+  octave_main_thread *main_thread;
+
+signals:
+
+  void update_dbstop_marker_signal (bool insert, const QString& file, int line);
+
+  void edit_file_signal (const QString& file);
+
+  void insert_debugger_pointer_signal (const QString&, int);
+
+  void delete_debugger_pointer_signal (const QString&, int);
+};
+
+#endif
deleted file mode 100644
--- a/libinterp/corefcn/__execute_edit_hook__.cc
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
-
-Copyright (C) 2013 John W. Eaton
-
-This file is part of Octave.
-
-Octave 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 3 of the License, or (at
-your option) any later version.
-
-Octave 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 Octave; see the file COPYING.  If not, see
-<http://www.gnu.org/licenses/>.
-
-*/
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "defun.h"
-#include "error.h"
-#include "defun.h"
-#include "hook-fcn.h"
-#include "oct-obj.h"
-
-static hook_function_list edit_hook_functions;
-
-DEFUN (add_edit_hook, args, ,
-  "-*- texinfo -*-\n\
-@deftypefn  {Built-in Function} {@var{id} =} add_edit_hook (@var{fcn})\n\
-@deftypefnx {Built-in Function} {@var{id} =} add_edit_hook (@var{fcn}, @var{data})\n\
-Add the named function or function handle @var{fcn} to the list of functions to call\n\
-to handle editing files.  The function should have the form\n\
-\n\
-@example\n\
-@var{fcn} (@var{file}, @var{data})\n\
-@end example\n\
-\n\
-If @var{data} is omitted, Octave calls the function without one argument.\n\
-\n\
-The returned identifier may be used to remove the function handle from\n\
-the list of input hook functions.\n\
-@seealso{remove_edit_hook}\n\
-@end deftypefn")
-{
-  octave_value retval;
-
-  int nargin = args.length ();
-
-  if (nargin == 1 || nargin == 2)
-    {
-      octave_value user_data;
-
-      if (nargin == 2)
-        user_data = args(1);
-
-      hook_function hook_fcn (args(0), user_data);
-
-      if (! error_state)
-        {
-          edit_hook_functions.insert (hook_fcn.id (), hook_fcn);
-
-          retval = hook_fcn.id ();
-        }
-      else
-        error ("add_edit_hook: expecting string as first arg");
-    }
-  else
-    print_usage ();
-
-  return retval;
-}
-
-DEFUN (remove_edit_hook, args, ,
-  "-*- texinfo -*-\n\
-@deftypefn {Built-in Function} {} remove_edit_hook (@var{name})\n\
-@deftypefnx {Built-in Function} {} remove_input_event_hook (@var{fcn_id})\n\
-Remove the named function or function handle with the given identifier\n\
-from the list of functions to call to handle editing files.\n\
-@seealso{add_edit_hook}\n\
-@end deftypefn")
-{
-  octave_value_list retval;
-
-  int nargin = args.length ();
-
-  if (nargin == 1 || nargin == 2)
-    {
-      std::string hook_fcn_id = args(0).string_value ();
-
-      bool warn = (nargin < 2);
-
-      if (! error_state)
-        {
-          hook_function_list::iterator p
-            = edit_hook_functions.find (hook_fcn_id);
-
-          if (p != edit_hook_functions.end ())
-            edit_hook_functions.erase (p);
-          else if (warn)
-            warning ("remove_edit_hook: %s not found in list",
-                     hook_fcn_id.c_str ());
-        }
-      else
-        error ("remove_edit_hook: argument not valid as a hook function name or id");
-    }
-  else
-    print_usage ();
-
-  return retval;
-}
-
-DEFUN (__execute_edit_hook__, args, ,
-  "-*- texinfo -*-\n\
-@deftypefn {Built-in Function} {@var{status} =} __execute_edit_hook__ (@var{file})\n\
-Undocumented internal function.\n\
-@end deftypefn")
-{
-  octave_value retval;
-
-  if (edit_hook_functions.empty ())
-    retval = false;
-  else
-    {
-      edit_hook_functions.run (args);
-
-      retval = true;
-    }
-
-  return retval;
-}
-
-/*
-## No test needed for internal helper function.
-%!assert (1)
-*/
--- a/libinterp/corefcn/module.mk
+++ b/libinterp/corefcn/module.mk
@@ -27,7 +27,6 @@
 COREFCN_SRC = \
   corefcn/__contourc__.cc \
   corefcn/__dispatch__.cc \
-  corefcn/__execute_edit_hook__.cc \
   corefcn/__lin_interpn__.cc \
   corefcn/__pchip_deriv__.cc \
   corefcn/__qp__.cc \
--- a/libinterp/interp-core/ls-mat5.cc
+++ b/libinterp/interp-core/ls-mat5.cc
@@ -82,6 +82,7 @@
 #endif
 
 #define PAD(l) (((l) > 0 && (l) <= 4) ? 4 : (((l)+7)/8)*8)
+#define INT8(l) ((l) == miINT8 || (l) == miUINT8 || (l) == miUTF8)
 
 
 // The subsystem data block
@@ -674,7 +675,7 @@
       dims(1) = 1;
     }
 
-  if (read_mat5_tag (is, swap, type, len) || type != miINT8)
+  if (read_mat5_tag (is, swap, type, len) || !INT8(type))
     {
       error ("load: invalid array name subelement");
       goto early_read_error;
@@ -1059,7 +1060,7 @@
           {
             int32_t fn_type;
             int32_t fn_len;
-            if (read_mat5_tag (is, swap, fn_type, fn_len) || fn_type != miINT8)
+            if (read_mat5_tag (is, swap, fn_type, fn_len) || !INT8(fn_type))
               {
                 error ("load: invalid field name subelement");
                 goto data_read_error;
@@ -1120,7 +1121,7 @@
       {
         isclass = true;
 
-        if (read_mat5_tag (is, swap, type, len) || type != miINT8)
+        if (read_mat5_tag (is, swap, type, len) || !INT8(type))
           {
             error ("load: invalid class name");
             goto skip_ahead;
@@ -1170,7 +1171,7 @@
 
         // field name subelement.  The length of this subelement tells
         // us how many fields there are.
-        if (read_mat5_tag (is, swap, fn_type, fn_len) || fn_type != miINT8)
+        if (read_mat5_tag (is, swap, fn_type, fn_len) || !INT8(fn_type))
           {
             error ("load: invalid field name subelement");
             goto data_read_error;
--- a/libinterp/interp-core/module.mk
+++ b/libinterp/interp-core/module.mk
@@ -35,6 +35,7 @@
   interp-core/mex.h \
   interp-core/mexproto.h \
   interp-core/mxarray.in.h \
+  interp-core/octave-event-listener.h \
   interp-core/oct-errno.h \
   interp-core/oct-fstrm.h \
   interp-core/oct-hdf5.h \
rename from libgui/src/octave-adapter/octave-event-listener.h
rename to libinterp/interp-core/octave-event-listener.h
--- a/libgui/src/octave-adapter/octave-event-listener.h
+++ b/libinterp/interp-core/octave-event-listener.h
@@ -40,17 +40,6 @@
     virtual void
     update_history (void) = 0;
 
-    virtual void
-    insert_debugger_pointer (const std::string& file, int line) = 0;
-
-    virtual void
-    delete_debugger_pointer (const std::string& file, int line) = 0;
-
-    virtual void
-    update_dbstop_marker (bool insert, const std::string& file, int line) = 0;
-
-    virtual void edit_file (const std::string& file) = 0;
-
     virtual void about_to_exit () = 0;
 
     virtual void entered_debug_mode () = 0;
--- a/libinterp/interpfcn/debug.cc
+++ b/libinterp/interpfcn/debug.cc
@@ -37,9 +37,9 @@
 #include "defun.h"
 #include "error.h"
 #include "help.h"
-#include "hook-fcn.h"
 #include "input.h"
 #include "pager.h"
+#include "octave-link.h"
 #include "oct-obj.h"
 #include "utils.h"
 #include "parse.h"
@@ -186,17 +186,6 @@
   return dbg_fcn;
 }
 
-octave_value
-location_info (const std::string& fname, int line)
-{
-  octave_scalar_map location_info_map;
-
-  location_info_map.setfield ("file", fname);
-  location_info_map.setfield ("line", line);
-
-  return octave_value (location_info_map);
-}
-
 static void
 parse_dbfunction_params (const char *who, const octave_value_list& args,
                          std::string& symbol_name, bp_table::intmap& lines)
@@ -285,201 +274,6 @@
   return retval;
 }
 
-static hook_function_list dbstop_hook_functions;
-static hook_function_list dbclear_hook_functions;
-
-DEFUN (add_dbstop_hook, args, ,
-  "-*- texinfo -*-\n\
-@deftypefn  {Built-in Function} {@var{id} =} add_dbstop_hook (@var{fcn})\n\
-@deftypefnx {Built-in Function} {@var{id} =} add_dbstop_hook (@var{fcn}, @var{data})\n\
-Add the named function or function handle @var{fcn} to the list of\n\
-functions to call when a debugger breakpoint is set.  The function\n\
-should have the form\n\
-\n\
-@example\n\
-@var{fcn} (@var{location}, @var{data})\n\
-@end example\n\
-\n\
-in which @var{location} is a structure containing the following elements:\n\
-\n\
-@table @code\n\
-@item file\n\
-The name of the file where the breakpoint is located.\n\
-@item line\n\
-The line number corresponding to the breakpoint.\n\
-@end table\n\
-\n\
-If @var{data} is omitted when the hook function is added, the hook\n\
-function is called with a single argument.\n\
-\n\
-The returned identifier may be used to remove the function handle from\n\
-the list of input hook functions.\n\
-@seealso{remove_dbstop_hook}\n\
-@end deftypefn")
-{
-  octave_value retval;
-
-  int nargin = args.length ();
-
-  if (nargin == 1 || nargin == 2)
-    {
-      octave_value user_data;
-
-      if (nargin == 2)
-        user_data = args(1);
-
-      hook_function hook_fcn (args(0), user_data);
-
-      if (! error_state)
-        {
-          dbstop_hook_functions.insert (hook_fcn.id (), hook_fcn);
-
-          retval = hook_fcn.id ();
-        }
-      else
-        error ("add_dbstop_hook: expecting string as first arg");
-    }
-  else
-    print_usage ();
-
-  return retval;
-}
-
-DEFUN (remove_dbstop_hook, args, ,
-  "-*- texinfo -*-\n\
-@deftypefn {Built-in Function} {} remove_dbstop_hook (@var{name})\n\
-@deftypefnx {Built-in Function} {} remove_dbstop_hook (@var{fcn_id})\n\
-Remove the named function or function handle with the given identifier\n\
-from the list of functions to call when a debugger breakpoint is set.\n\
-@seealso{add_dbstop_hook}\n\
-@end deftypefn")
-{
-  octave_value_list retval;
-
-  int nargin = args.length ();
-
-  if (nargin == 1 || nargin == 2)
-    {
-      std::string hook_fcn_id = args(0).string_value ();
-
-      bool warn = (nargin < 2);
-
-      if (! error_state)
-        {
-          hook_function_list::iterator p
-            = dbstop_hook_functions.find (hook_fcn_id);
-
-          if (p != dbstop_hook_functions.end ())
-            dbstop_hook_functions.erase (p);
-          else if (warn)
-            warning ("remove_dbstop_hook: %s not found in list",
-                     hook_fcn_id.c_str ());
-        }
-      else
-        error ("remove_dbstop_hook: argument not valid as a hook function name or id");
-    }
-  else
-    print_usage ();
-
-  return retval;
-}
-
-DEFUN (add_dbclear_hook, args, ,
-  "-*- texinfo -*-\n\
-@deftypefn  {Built-in Function} {@var{id} =} add_dbclear_hook (@var{fcn})\n\
-@deftypefnx {Built-in Function} {@var{id} =} add_dbclear_hook (@var{fcn}, @var{data})\n\
-Add the named function or function handle @var{fcn} to the list of\n\
-functions to call when a debugger breakpoint is cleared.  The function\n\
-should have the form\n\
-\n\
-@example\n\
-@var{fcn} (@var{location}, @var{data})\n\
-@end example\n\
-\n\
-in which @var{location} is a structure containing the following elements:\n\
-\n\
-@table @code\n\
-@item file\n\
-The name of the file where the breakpoint is located.\n\
-@item line\n\
-The line number corresponding to the breakpoint.\n\
-@end table\n\
-\n\
-If @var{data} is omitted when the hook function is added, the hook\n\
-function is called with a single argument.\n\
-\n\
-The returned identifier may be used to remove the function handle from\n\
-the list of input hook functions.\n\
-@seealso{remove_dbclear_hook}\n\
-@end deftypefn")
-{
-  octave_value retval;
-
-  int nargin = args.length ();
-
-  if (nargin == 1 || nargin == 2)
-    {
-      octave_value user_data;
-
-      if (nargin == 2)
-        user_data = args(1);
-
-      hook_function hook_fcn (args(0), user_data);
-
-      if (! error_state)
-        {
-          dbclear_hook_functions.insert (hook_fcn.id (), hook_fcn);
-
-          retval = hook_fcn.id ();
-        }
-      else
-        error ("add_dbclear_hook: expecting string as first arg");
-    }
-  else
-    print_usage ();
-
-  return retval;
-}
-
-DEFUN (remove_dbclear_hook, args, ,
-  "-*- texinfo -*-\n\
-@deftypefn {Built-in Function} {} remove_dbclear_hook (@var{name})\n\
-@deftypefnx {Built-in Function} {} remove_dbclear_hook (@var{fcn_id})\n\
-Remove the named function or function handle with the given identifier\n\
-from the list of functions to call when a debugger breakpoint is cleared.\n\
-@seealso{add_dbclear_hook}\n\
-@end deftypefn")
-{
-  octave_value_list retval;
-
-  int nargin = args.length ();
-
-  if (nargin == 1 || nargin == 2)
-    {
-      std::string hook_fcn_id = args(0).string_value ();
-
-      bool warn = (nargin < 2);
-
-      if (! error_state)
-        {
-          hook_function_list::iterator p
-            = dbclear_hook_functions.find (hook_fcn_id);
-
-          if (p != dbclear_hook_functions.end ())
-            dbclear_hook_functions.erase (p);
-          else if (warn)
-            warning ("remove_dbclear_hook: %s not found in list",
-                     hook_fcn_id.c_str ());
-        }
-      else
-        error ("remove_dbclear_hook: argument not valid as a hook function name or id");
-    }
-  else
-    print_usage ();
-
-  return retval;
-}
-
 bp_table::intmap
 bp_table::do_add_breakpoint (const std::string& fname,
                              const bp_table::intmap& line)
@@ -513,8 +307,7 @@
                       std::string file = dbg_fcn->fcn_file_name ();
 
                       if (! file.empty ())
-                        dbstop_hook_functions.run
-                          (location_info (file, retval[i]));
+                        octave_link::update_breakpoint (true, file, retval[i]);
                     }
                 }
             }
@@ -569,8 +362,7 @@
                           cmds->delete_breakpoint (lineno);
 
                           if (! file.empty ())
-                            dbclear_hook_functions.run
-                              (location_info (file, lineno));
+                            octave_link::update_breakpoint (false, file, lineno);
                         }
                     }
 
@@ -619,7 +411,7 @@
               retval[i] = lineno;
 
               if (! file.empty ())
-                dbclear_hook_functions.run (location_info (file, lineno));
+                octave_link::update_breakpoint (false, file, lineno);
             }
 
           bp_set_iterator it = bp_set.find (fname);
--- a/libinterp/interpfcn/debug.h
+++ b/libinterp/interpfcn/debug.h
@@ -131,6 +131,4 @@
 
 extern std::string get_file_line (const std::string& fname, size_t line);
 
-extern octave_value location_info (const std::string& fname, int line);
-
 #endif
--- a/libinterp/interpfcn/input.cc
+++ b/libinterp/interpfcn/input.cc
@@ -53,6 +53,7 @@
 #include "input.h"
 #include "lex.h"
 #include "load-path.h"
+#include "octave-link.h"
 #include "oct-map.h"
 #include "oct-hist.h"
 #include "toplev.h"
@@ -122,11 +123,7 @@
 // The filemarker used to separate filenames from subfunction names
 char Vfilemarker = '>';
 
-static hook_function_list pre_input_event_hook_functions;
 static hook_function_list input_event_hook_functions;
-static hook_function_list post_input_event_hook_functions;
-static hook_function_list enter_debugger_event_hook_functions;
-static hook_function_list exit_debugger_event_hook_functions;
 
 // For octave_quit.
 void
@@ -215,7 +212,7 @@
   // printing the prompt.
 
   if (interactive || forced_interactive)
-    pre_input_event_hook_functions.run ();
+    octave_link::pre_input_event ();
 
   bool history_skip_auto_repeated_debugging_command = false;
 
@@ -271,7 +268,7 @@
   // list has been updated.
 
   if (interactive || forced_interactive)
-    post_input_event_hook_functions.run ();
+    octave_link::pre_input_event ();
 
   return retval;
 }
@@ -458,9 +455,9 @@
 }
 
 static void
-exit_debugger_cleanup (const octave_value& loc_info)
+exit_debugger_handler (const std::pair<std::string, int>& arg)
 {
-  exit_debugger_event_hook_functions.run (loc_info);
+  octave_link::exit_debugger_event (arg.first, arg.second);
 }
 
 static void
@@ -510,11 +507,10 @@
 
           if (have_file)
             {
-              octave_value loc_info = location_info (nm, curr_debug_line);
+              octave_link::enter_debugger_event (nm, curr_debug_line);
 
-              enter_debugger_event_hook_functions.run (loc_info);
-
-              frame.add_fcn (exit_debugger_cleanup, loc_info);
+              frame.add_fcn (exit_debugger_handler,
+                             std::pair<std::string, int> (nm, curr_debug_line));
 
               std::string line_buf
                 = get_file_line (nm, curr_debug_line);
@@ -1091,94 +1087,6 @@
   return retval;
 }
 
-DEFUN (add_pre_input_event_hook, args, ,
-  "-*- texinfo -*-\n\
-@deftypefn  {Built-in Function} {@var{id} =} add_pre_input_event_hook (@var{fcn})\n\
-@deftypefnx {Built-in Function} {@var{id} =} add_pre_input_event_hook (@var{fcn}, @var{data})\n\
-Add the named function or function handle @var{fcn} to the list of functions to call\n\
-immediately prior to prompting for interactive user input.  The\n\
-function should have the form\n\
-\n\
-@example\n\
-@var{fcn} (@var{data})\n\
-@end example\n\
-\n\
-If @var{data} is omitted, Octave calls the function without any\n\
-arguments.\n\
-\n\
-The returned identifier may be used to remove the function handle from\n\
-the list of input hook functions.\n\
-@seealso{remove_pre_input_event_hook}\n\
-@end deftypefn")
-{
-  octave_value retval;
-
-  int nargin = args.length ();
-
-  if (nargin == 1 || nargin == 2)
-    {
-      octave_value user_data;
-
-      if (nargin == 2)
-        user_data = args(1);
-
-      hook_function hook_fcn (args(0), user_data);
-
-      if (! error_state)
-        {
-          pre_input_event_hook_functions.insert (hook_fcn.id (), hook_fcn);
-
-          retval = hook_fcn.id ();
-        }
-      else
-        error ("add_pre_input_event_hook: expecting string as first arg");
-    }
-  else
-    print_usage ();
-
-  return retval;
-}
-
-DEFUN (remove_pre_input_event_hook, args, ,
-  "-*- texinfo -*-\n\
-@deftypefn {Built-in Function} {} remove_pre_input_event_hook (@var{name})\n\
-@deftypefnx {Built-in Function} {} remove_input_event_hook (@var{fcn_id})\n\
-Remove the named function or function handle with the given identifier\n\
-from the list of functions to call immediately prior to prompting for\n\
-interactive user input.\n\
-@seealso{add_pre_input_event_hook}\n\
-@end deftypefn")
-{
-  octave_value_list retval;
-
-  int nargin = args.length ();
-
-  if (nargin == 1 || nargin == 2)
-    {
-      std::string hook_fcn_id = args(0).string_value ();
-
-      bool warn = (nargin < 2);
-
-      if (! error_state)
-        {
-          hook_function_list::iterator p
-            = pre_input_event_hook_functions.find (hook_fcn_id);
-
-          if (p != pre_input_event_hook_functions.end ())
-            pre_input_event_hook_functions.erase (p);
-          else if (warn)
-            warning ("remove_pre_input_event_hook: %s not found in list",
-                     hook_fcn_id.c_str ());
-        }
-      else
-        error ("remove_pre_input_event_hook: argument not valid as a hook function name or id");
-    }
-  else
-    print_usage ();
-
-  return retval;
-}
- 
 static int
 internal_input_event_hook_fcn (void)
 {
@@ -1284,288 +1192,6 @@
   return retval;
 }
 
-DEFUN (add_post_input_event_hook, args, ,
-  "-*- texinfo -*-\n\
-@deftypefn  {Built-in Function} {@var{id} =} add_post_input_event_hook (@var{fcn})\n\
-@deftypefnx {Built-in Function} {@var{id} =} add_post_input_event_hook (@var{fcn}, @var{data})\n\
-Add the named function or function handle @var{fcn} to the list of functions to call\n\
-immediately after accepting interactive user input.  The function\n\
-should have the form\n\
-\n\
-@example\n\
-@var{fcn} (@var{data})\n\
-@end example\n\
-\n\
-If @var{data} is omitted, Octave calls the function without any\n\
-arguments.\n\
-\n\
-The returned identifier may be used to remove the function handle from\n\
-the list of input hook functions.\n\
-@seealso{remove_post_input_event_hook}\n\
-@end deftypefn")
-{
-  octave_value retval;
-
-  int nargin = args.length ();
-
-  if (nargin == 1 || nargin == 2)
-    {
-      octave_value user_data;
-
-      if (nargin == 2)
-        user_data = args(1);
-
-      hook_function hook_fcn (args(0), user_data);
-
-      if (! error_state)
-        {
-          post_input_event_hook_functions.insert (hook_fcn.id (), hook_fcn);
-
-          retval = hook_fcn.id ();
-        }
-      else
-        error ("add_post_input_event_hook: expecting string as first arg");
-    }
-  else
-    print_usage ();
-
-  return retval;
-}
-
-DEFUN (remove_post_input_event_hook, args, ,
-  "-*- texinfo -*-\n\
-@deftypefn {Built-in Function} {} remove_post_input_event_hook (@var{name})\n\
-@deftypefnx {Built-in Function} {} remove_post_input_event_hook (@var{fcn_id})\n\
-Remove the named function or function handle with the given identifier\n\
-from the list of functions to call immediately after accepting\n\
-interactive user input.\n\
-@seealso{add_post_input_event_hook}\n\
-@end deftypefn")
-{
-  octave_value_list retval;
-
-  int nargin = args.length ();
-
-  if (nargin == 1 || nargin == 2)
-    {
-      std::string hook_fcn_id = args(0).string_value ();
-
-      bool warn = (nargin < 2);
-
-      if (! error_state)
-        {
-          hook_function_list::iterator p
-            = post_input_event_hook_functions.find (hook_fcn_id);
-
-          if (p != post_input_event_hook_functions.end ())
-            post_input_event_hook_functions.erase (p);
-          else if (warn)
-            warning ("remove_post_input_event_hook: %s not found in list",
-                     hook_fcn_id.c_str ());
-        }
-      else
-        error ("remove_post_input_event_hook: argument not valid as a hook function name or id");
-    }
-  else
-    print_usage ();
-
-  return retval;
-}
-
-DEFUN (add_enter_debugger_event_hook, args, ,
-  "-*- texinfo -*-\n\
-@deftypefn  {Built-in Function} {@var{id} =} add_enter_debugger_event_hook (@var{fcn})\n\
-@deftypefnx {Built-in Function} {@var{id} =} add_enter_debugger_event_hook (@var{fcn}, @var{data})\n\
-Add the named function or function handle @var{fcn} to the list of\n\
-functions to call when a debugger breakpoint is reached.  The function\n\
-should have the form\n\
-\n\
-@example\n\
-@var{fcn} (@var{location}, @var{data})\n\
-@end example\n\
-\n\
-in which @var{location} is a structure containing the following elements:\n\
-\n\
-@table @code\n\
-@item file\n\
-The name of the file where the breakpoint is located.\n\
-@item line\n\
-The line number corresponding to the breakpoint.\n\
-@end table\n\
-\n\
-If @var{data} is omitted when the hook function is added, the hook\n\
-function is called with a single argument.\n\
-\n\
-The returned identifier may be used to remove the function handle from\n\
-the list of input hook functions.\n\
-@seealso{remove_enter_debugger_event_hook}\n\
-@end deftypefn")
-{
-  octave_value retval;
-
-  int nargin = args.length ();
-
-  if (nargin == 1 || nargin == 2)
-    {
-      octave_value user_data;
-
-      if (nargin == 2)
-        user_data = args(1);
-
-      hook_function hook_fcn (args(0), user_data);
-
-      if (! error_state)
-        {
-          enter_debugger_event_hook_functions.insert (hook_fcn.id (), hook_fcn);
-
-          retval = hook_fcn.id ();
-        }
-      else
-        error ("add_enter_debugger_event_hook: expecting string as first arg");
-    }
-  else
-    print_usage ();
-
-  return retval;
-}
-
-DEFUN (remove_enter_debugger_event_hook, args, ,
-  "-*- texinfo -*-\n\
-@deftypefn {Built-in Function} {} remove_enter_debugger_event_hook (@var{name})\n\
-@deftypefnx {Built-in Function} {} remove_enter_debugger_event_hook (@var{fcn_id})\n\
-Remove the named function or function handle with the given identifier\n\
-from the list of functions to call immediately after accepting\n\
-interactive user input.\n\
-@seealso{add_enter_debugger_event_hook}\n\
-@end deftypefn")
-{
-  octave_value_list retval;
-
-  int nargin = args.length ();
-
-  if (nargin == 1 || nargin == 2)
-    {
-      std::string hook_fcn_id = args(0).string_value ();
-
-      bool warn = (nargin < 2);
-
-      if (! error_state)
-        {
-          hook_function_list::iterator p
-            = enter_debugger_event_hook_functions.find (hook_fcn_id);
-
-          if (p != enter_debugger_event_hook_functions.end ())
-            enter_debugger_event_hook_functions.erase (p);
-          else if (warn)
-            warning ("remove_enter_debugger_event_hook: %s not found in list",
-                     hook_fcn_id.c_str ());
-        }
-      else
-        error ("remove_enter_debugger_event_hook: argument not valid as a hook function name or id");
-    }
-  else
-    print_usage ();
-
-  return retval;
-}
-
-DEFUN (add_exit_debugger_event_hook, args, ,
-  "-*- texinfo -*-\n\
-@deftypefn  {Built-in Function} {@var{id} =} add_exit_debugger_event_hook (@var{fcn})\n\
-@deftypefnx {Built-in Function} {@var{id} =} add_exit_debugger_event_hook (@var{fcn}, @var{data})\n\
-Add the named function or function handle @var{fcn} to the list of\n\
-functions to call when continuing execution after a debugger breakpoint.\n\
-The function should have the form\n\
-\n\
-@example\n\
-@var{fcn} (@var{location}, @var{data})\n\
-@end example\n\
-\n\
-in which @var{location} is a structure containing the following elements:\n\
-\n\
-@table @code\n\
-@item file\n\
-The name of the file where the breakpoint is located.\n\
-@item line\n\
-The line number corresponding to the breakpoint.\n\
-@end table\n\
-\n\
-If @var{data} is omitted when the hook function is added, the hook\n\
-function is called with a single argument.\n\
-\n\
-The returned identifier may be used to remove the function handle from\n\
-the list of input hook functions.\n\
-@seealso{remove_exit_debugger_event_hook}\n\
-@end deftypefn")
-{
-  octave_value retval;
-
-  int nargin = args.length ();
-
-  if (nargin == 1 || nargin == 2)
-    {
-      octave_value user_data;
-
-      if (nargin == 2)
-        user_data = args(1);
-
-      hook_function hook_fcn (args(0), user_data);
-
-      if (! error_state)
-        {
-          exit_debugger_event_hook_functions.insert (hook_fcn.id (), hook_fcn);
-
-          retval = hook_fcn.id ();
-        }
-      else
-        error ("add_exit_debugger_event_hook: expecting string as first arg");
-    }
-  else
-    print_usage ();
-
-  return retval;
-}
-
-DEFUN (remove_exit_debugger_event_hook, args, ,
-  "-*- texinfo -*-\n\
-@deftypefn {Built-in Function} {} remove_exit_debugger_event_hook (@var{name})\n\
-@deftypefnx {Built-in Function} {} remove_exit_debugger_event_hook (@var{fcn_id})\n\
-Remove the named function or function handle with the given identifier\n\
-from the list of functions to call immediately after accepting\n\
-interactive user input.\n\
-@seealso{add_exit_debugger_event_hook}\n\
-@end deftypefn")
-{
-  octave_value_list retval;
-
-  int nargin = args.length ();
-
-  if (nargin == 1 || nargin == 2)
-    {
-      std::string hook_fcn_id = args(0).string_value ();
-
-      bool warn = (nargin < 2);
-
-      if (! error_state)
-        {
-          hook_function_list::iterator p
-            = exit_debugger_event_hook_functions.find (hook_fcn_id);
-
-          if (p != exit_debugger_event_hook_functions.end ())
-            exit_debugger_event_hook_functions.erase (p);
-          else if (warn)
-            warning ("remove_exit_debugger_event_hook: %s not found in list",
-                     hook_fcn_id.c_str ());
-        }
-      else
-        error ("remove_exit_debugger_event_hook: argument not valid as a hook function name or id");
-    }
-  else
-    print_usage ();
-
-  return retval;
-}
-
 DEFUN (PS1, args, nargout,
   "-*- texinfo -*-\n\
 @deftypefn  {Built-in Function} {@var{val} =} PS1 ()\n\
--- a/libinterp/interpfcn/module.mk
+++ b/libinterp/interpfcn/module.mk
@@ -16,6 +16,7 @@
   interpfcn/load-path.h \
   interpfcn/load-save.h \
   interpfcn/ls-oct-ascii.h \
+  interpfcn/octave-link.h \
   interpfcn/oct-hist.h \
   interpfcn/pager.h \
   interpfcn/pr-output.h \
@@ -42,6 +43,7 @@
   interpfcn/load-path.cc \
   interpfcn/load-save.cc \
   interpfcn/ls-oct-ascii.cc \
+  interpfcn/octave-link.cc \
   interpfcn/oct-hist.cc \
   interpfcn/pager.cc \
   interpfcn/pr-output.cc \
rename from libgui/src/octave-adapter/octave-link.cc
rename to libinterp/interpfcn/octave-link.cc
--- a/libgui/src/octave-adapter/octave-link.cc
+++ b/libinterp/interpfcn/octave-link.cc
@@ -1,5 +1,6 @@
 /*
 
+Copyright (C) 2013 John W. Eaton
 Copyright (C) 2011-2012 Jacob Dawid
 Copyright (C) 2011-2012 John P. Swensen
 
@@ -26,6 +27,7 @@
 #endif
 
 #include "cmd-edit.h"
+#include "defun.h"
 #include "oct-env.h"
 #include "oct-mutex.h"
 #include "singleton-cleanup.h"
@@ -56,20 +58,23 @@
 octave_link::octave_link (void)
   : event_listener (0), event_queue_mutex (new octave_mutex ()),
     gui_event_queue (), last_cwd (), debugging (false)
-{ }
-
-void
-octave_link::do_launch_octave (void)
 {
-  // Create both threads.
-  main_thread = new octave_main_thread ();
-
   command_editor::add_event_hook (octave_readline_hook);
 
   octave_exit = octave_exit_hook;
+}
 
-  // Start the first one.
-  main_thread->start ();
+// OBJ should be an object of a class that is derived from the base
+// class octave_link, or 0 to disconnect the link.  It is the
+// responsibility of the caller to delete obj.
+
+void
+octave_link::connect_link (octave_link* obj)
+{
+  if (obj && instance)
+    ::error ("octave_link is already linked!");
+  else
+    instance = obj;
 }
 
 void
@@ -134,196 +139,28 @@
   return last_cwd;
 }
 
-void
-octave_link::do_update_workspace (void)
-{
-  if (event_listener)
-    {
-      event_listener->update_workspace ();
-
-      do_process_events ();
-    }
-}
-
-void
-octave_link::do_update_history (void)
-{
-  if (event_listener)
-    {
-      event_listener->update_history ();
-
-      do_process_events ();
-    }
-}
-
-void
-octave_link::do_insert_debugger_pointer (const octave_value_list& args)
-{
-  if (event_listener)
-    {
-      if (args.length () == 1)
-        {
-          octave_scalar_map m = args(0).scalar_map_value ();
-
-          if (! error_state)
-            {
-              octave_value ov_file = m.getfield ("file");
-              octave_value ov_line = m.getfield ("line");
-
-              std::string file = ov_file.string_value ();
-              int line = ov_line.int_value ();
-
-              if (! error_state)
-                {
-                  event_listener->insert_debugger_pointer (file, line);
-
-                  do_process_events ();
-                }
-              else
-                ::error ("invalid struct in debug pointer callback");
-            }
-          else
-            ::error ("expecting struct in debug pointer callback");
-        }
-      else
-        ::error ("invalid call to debug pointer callback");
-    }
-}
-
-void
-octave_link::do_delete_debugger_pointer (const octave_value_list& args)
-{
-  if (event_listener)
-    {
-      if (args.length () == 1)
-        {
-          octave_scalar_map m = args(0).scalar_map_value ();
-
-          if (! error_state)
-            {
-              octave_value ov_file = m.getfield ("file");
-              octave_value ov_line = m.getfield ("line");
-
-              std::string file = ov_file.string_value ();
-              int line = ov_line.int_value ();
-
-              if (! error_state)
-                {
-                  event_listener->delete_debugger_pointer (file, line);
-
-                  do_process_events ();
-                }
-              else
-                ::error ("invalid struct in debug pointer callback");
-            }
-          else
-            ::error ("expecting struct in debug pointer callback");
-        }
-      else
-        ::error ("invalid call to debug pointer callback");
-    }
-}
-
-void
-octave_link::do_pre_input_event_hook_fcn (void)
-{
-  do_update_workspace ();
-}
-
-void
-octave_link::do_post_input_event_hook_fcn (void)
-{
-  do_update_history ();
-}
-
-void
-octave_link::do_enter_debugger_event_hook_fcn (const octave_value_list& args)
-{
-  do_insert_debugger_pointer (args);
-}
-
-void
-octave_link::do_exit_debugger_event_hook_fcn (const octave_value_list& args)
-{
-  do_delete_debugger_pointer (args);
-}
-
-void
-octave_link::do_update_breakpoint_hook_fcn
-  (bool insert, const octave_value_list& args)
-{
-  if (event_listener)
-    {
-      if (args.length () == 1)
-        {
-          octave_scalar_map m = args(0).scalar_map_value ();
-
-          if (! error_state)
-            {
-              octave_value ov_file = m.getfield ("file");
-              octave_value ov_line = m.getfield ("line");
-
-              std::string file = ov_file.string_value ();
-              int line = ov_line.int_value ();
-
-              if (! error_state)
-                {
-                  event_listener->update_dbstop_marker (insert, file, line);
-
-                  do_process_events ();
-                }
-              else
-                ::error ("invalid struct in dbstop marker callback");
-            }
-          else
-            ::error ("expecting struct in dbstop marker callback");
-        }
-      else
-        ::error ("invalid call to dbstop marker callback");
-    }
-}
-
-void
-octave_link::do_edit_file (const octave_value_list& args)
-{
-  if (event_listener)
-    {
-      if (args.length () == 1)
-        {
-          std::string file = args(0).string_value ();
-
-          if (! error_state)
-            {
-              event_listener->edit_file (file);
-              do_process_events ();
-
-            }
-          else
-            ::error ("expecting file name in edit file callback");
-        }
-      else
-        ::error ("invalid call to edit file callback");
-    }
-}
-
 bool
 octave_link::instance_ok (void)
 {
-  bool retval = true;
-
-  if (! instance)
-    {
-      instance = new octave_link ();
+  return instance != 0;
+}
 
-      if (instance)
-        singleton_cleanup_list::add (cleanup_instance);
-    }
+DEFUN (__octave_link_edit_file__, args, ,
+  "-*- texinfo -*-\n\
+@deftypefn {Built-in Function} {} __octave_link_edit_file__ (@var{file})\n\
+Undocumented internal function.\n\
+@end deftypefn")
+{
+  octave_value retval;
 
-  if (! instance)
+  if (args.length () == 1)
     {
-      ::error ("unable to create octave_link object!");
+      std::string file = args(0).string_value ();
 
-      retval = false;
+      if (! error_state)
+        retval = octave_link::edit_file (file);
+      else
+        error ("expecting file name as argument");
     }
 
   return retval;
rename from libgui/src/octave-adapter/octave-link.h
rename to libinterp/interpfcn/octave-link.h
--- a/libgui/src/octave-adapter/octave-link.h
+++ b/libinterp/interpfcn/octave-link.h
@@ -1,5 +1,6 @@
 /*
 
+Copyright (C) 2013 John W. Eaton
 Copyright (C) 2011-2012 Jacob Dawid
 Copyright (C) 2011-2012 John P. Swensen
 
@@ -21,19 +22,15 @@
 
 */
 
-#ifndef OCTAVELINK_H
-#define OCTAVELINK_H
+#if !defined (octave_link_h)
+#define octave_link_h 1
 
 #include <string>
 
-class octave_mutex;
-
-#include "oct-obj.h"
+#include "event-queue.h"
+#include "octave-event-listener.h"
 
-#include "event-queue.h"
-
-#include "octave-main-thread.h"
-#include "octave-event-listener.h"
+class octave_mutex;
 
 // \class OctaveLink
 // \brief Provides threadsafe access to octave.
@@ -51,13 +48,7 @@
 
 public:
 
-  ~octave_link (void) { }
-
-  static void launch_octave (void)
-  {
-    if (instance_ok ())
-      instance->do_launch_octave ();
-  }
+  virtual ~octave_link (void) { }
 
   static void register_event_listener (octave_event_listener *el)
   {
@@ -134,44 +125,45 @@
       instance->do_update_history ();
   }
 
-  static void pre_input_event_hook_fcn (void)
+  static void pre_input_event (void)
   {
     if (instance_ok ())
-      instance->do_pre_input_event_hook_fcn ();
+      instance->do_pre_input_event ();
   }
 
-  static void post_input_event_hook_fcn (void)
+  static void post_input_event (void)
   {
     if (instance_ok ())
-      instance->do_post_input_event_hook_fcn ();
+      instance->do_post_input_event ();
   }
 
-  static void enter_debugger_event_hook_fcn (const octave_value_list& args)
+  static void enter_debugger_event (const std::string& file, int line)
   {
     if (instance_ok ())
-      instance->do_enter_debugger_event_hook_fcn (args);
+      instance->do_enter_debugger_event (file, line);
   }
 
-  static void exit_debugger_event_hook_fcn (const octave_value_list& args)
+  static void exit_debugger_event (const std::string& file, int line)
   {
     if (instance_ok ())
-      instance->do_exit_debugger_event_hook_fcn (args);
+      instance->do_exit_debugger_event (file, line);
   }
 
   static void
-  update_breakpoint_hook_fcn (bool insert, const octave_value_list& args)
+  update_breakpoint (bool insert, const std::string& file, int line)
   {
     if (instance_ok ())
-      instance->do_update_breakpoint_hook_fcn (insert, args);
+      instance->do_update_breakpoint (insert, file, line);
   }
 
-  static void
-  edit_file (const octave_value_list& args)
+  static bool
+  edit_file (const std::string& file)
   {
-    if (instance_ok ())
-      instance->do_edit_file (args);
+    return instance_ok () ? instance->do_edit_file (file) : false;
   }
 
+  static void connect_link (octave_link *);
+
 private:
 
   static octave_link *instance;
@@ -186,10 +178,9 @@
 
   static bool instance_ok (void);
 
-  octave_event_listener *event_listener;
+protected:
 
-  // Thread running octave_main.
-  octave_main_thread *main_thread;
+  octave_event_listener *event_listener;
 
   // Semaphore to lock access to the event queue.
   octave_mutex *event_queue_mutex;
@@ -202,7 +193,6 @@
 
   bool debugging;
 
-  void do_launch_octave (void);
   void do_register_event_listener (octave_event_listener *oel);
 
   void do_generate_events (void);
@@ -232,19 +222,21 @@
   void do_finished_readline_hook (void) { }
 
   std::string do_last_working_directory (void);
-  void do_update_workspace (void);
-  void do_update_history (void);
-  void do_insert_debugger_pointer (const octave_value_list& args);
-  void do_delete_debugger_pointer (const octave_value_list& args);
+
+  virtual void do_update_workspace (void) = 0;
+
+  virtual void do_update_history (void) = 0;
+
+  virtual void do_pre_input_event (void) = 0;
+  virtual void do_post_input_event (void) = 0;
 
-  void do_pre_input_event_hook_fcn (void);
-  void do_post_input_event_hook_fcn (void);
-  void do_enter_debugger_event_hook_fcn (const octave_value_list& args);
-  void do_exit_debugger_event_hook_fcn (const octave_value_list& args);
-  void do_update_breakpoint_hook_fcn (bool insert,
-                                      const octave_value_list& args);
+  virtual void do_enter_debugger_event (const std::string& file, int line) = 0;
+  virtual void do_exit_debugger_event (const std::string& file, int line) = 0;
 
-  void do_edit_file (const octave_value_list& args);
+  virtual void do_update_breakpoint (bool insert,
+                                     const std::string& file, int line) = 0;
+
+  virtual bool do_edit_file (const std::string& file) = 0;
 };
 
 #endif // OCTAVELINK_H
--- a/scripts/miscellaneous/edit.m
+++ b/scripts/miscellaneous/edit.m
@@ -563,7 +563,7 @@
   ## Give the hook function a chance.  If that fails, fall back
   ## on running an editor with the system function.
 
-  status = __execute_edit_hook__ (file);
+  status = __octave_link_edit_file__ (file);
 
   if (! status)
     system (sprintf (undo_string_escapes (editor),