Hi,

As per Andreas's off-bugtracker request, let me send a skeleton patch.
It compiles but sure doesn't run correctly; but at least shows which
are the bits that need to be addressed by someone familiar with
synaptic and C++.  Please make sure to review every line of the patch
and address all the comments mentioned within.

In increasing order of importance:

- Minor changes around the scrollbar and font handling; I don't think
anything could've gone wrong here

- No more vtereaper, the API changed here a little bit.  Previously it
was a global reaper object, so you'd need to know the PID and compare.
Now it's a signal connected to a VteTerminal instance, and I believe
there can only be one child per terminal at a time (or even if vte
allows more, I guess no reasonable app does this), so I hope verifying
and comparing the PID is not necessary anymore. Please double check if
I'm correct here.

- The big piece is spawning a process for the terminal, and here my
patch is definitely incomplete as it'd require more thorough
understanding of the code:

-- argv needs to be populated with the command to be launched
-- the possible pty flags and spawn should be carefully revised
-- I _think_ that whatever happened so far between the
vte_whatever_fork() and the exec() [now I replaced vte_whatever_fork()
by vte_whatever_spawn(), but I haven't traced down where the exec()
happens], which I believe is probably what DoInstallPostFork() does,
needs to be moved into the child_setup method of vte_whatever_spawn().
It's going to be a bit of refactoring.

Should you get stuck with these, I recommend to look at (apart from
vte's doc obviously) gnome-terminal's source code, as well as the two
small self-contained test programs (vteapp.c and app.vala) in vte's
source tree.

Good luck,

egmont
diff --git a/configure.in b/configure.in
index 4d802db..ef22639 100644
--- a/configure.in
+++ b/configure.in
@@ -47,7 +47,7 @@ dnl AC_SUBST(BUILD_wings)
 
 dnl we build for gtk3 by default now
 pkg_modules="gtk+-3.0 >= 2.91.0, pango >= 1.0.0, glib-2.0"
-vte_modules="vte-2.90"
+vte_modules="vte-2.91"
 
 PKG_CHECK_MODULES(GTK, [$pkg_modules])
 BUILD_gtk="gtk"	
diff --git a/gtk/rgdebinstallprogress.cc b/gtk/rgdebinstallprogress.cc
index a084860..155ed27 100644
--- a/gtk/rgdebinstallprogress.cc
+++ b/gtk/rgdebinstallprogress.cc
@@ -54,18 +54,19 @@
 
 #include "i18n.h"
 
-void RGDebInstallProgress::child_exited(VteReaper *vtereaper,
-					gint child_pid, gint ret, 
+void RGDebInstallProgress::child_exited(VteTerminal *vteterminal,
+					gint ret,
 					gpointer data)
 {
    RGDebInstallProgress *me = (RGDebInstallProgress*)data;
 
-   if(child_pid == me->_child_id) {
+// I _guess_ there's no point in checking the pid, since there can be one child per terminal
+//XXX   if(child_pid == me->_child_id) {
 //        cout << "correct child exited" << endl;
 //        cout << "waitpid returned: " << WEXITSTATUS(ret) << endl;
       me->res = (pkgPackageManager::OrderResult)WEXITSTATUS(ret);
       me->child_has_exited=true;
-   }
+//XXX   }
 }
 
 ssize_t
@@ -289,8 +290,7 @@ void RGDebInstallProgress::conffile(gchar *conffile, gchar *status)
 void RGDebInstallProgress::startUpdate()
 {
    child_has_exited=false;
-   VteReaper* reaper = vte_reaper_get();
-   g_signal_connect(G_OBJECT(reaper), "child-exited",
+   g_signal_connect(VTE_TERMINAL(_term), "child-exited",
 		    G_CALLBACK(child_exited),
 		    this);
 
@@ -341,8 +341,9 @@ void RGDebInstallProgress::expander_callback (GObject    *object,
    // this crap here is needed because VteTerminal does not like
    // it when run hidden. this workaround will scroll to the end of
    // the current buffer
+   // TODO is this still true as of libvte-2.91 ???
    gtk_widget_realize(GTK_WIDGET(me->_term));
-   GtkAdjustment *a = vte_terminal_get_adjustment(VTE_TERMINAL(me->_term));
+   GtkAdjustment *a = gtk_scrollable_get_vadjustment(GTK_SCROLLABLE(VTE_TERMINAL(me->_term)));
    gtk_adjustment_set_value(a, gtk_adjustment_get_upper(a) - gtk_adjustment_get_page_size(a));
    gtk_adjustment_value_changed(a);
 
@@ -401,15 +402,20 @@ RGDebInstallProgress::RGDebInstallProgress(RGMainWindow *main,
 
    _term = vte_terminal_new();
    vte_terminal_set_size(VTE_TERMINAL(_term),80,23);
-   GtkWidget *scrollbar = gtk_vscrollbar_new (vte_terminal_get_adjustment(VTE_TERMINAL(_term)));
+   GtkWidget *scrollbar = gtk_vscrollbar_new (gtk_scrollable_get_vadjustment(GTK_SCROLLABLE(VTE_TERMINAL(_term))));
    gtk_widget_set_can_focus (scrollbar, FALSE);
    vte_terminal_set_scrollback_lines(VTE_TERMINAL(_term), 10000);
+
+   char *s;
    if(_config->FindB("Synaptic::useUserTerminalFont")) {
-      char *s =(char*)_config->Find("Synaptic::TerminalFontName").c_str();
-      vte_terminal_set_font_from_string(VTE_TERMINAL(_term), s);
+      s =(char*)_config->Find("Synaptic::TerminalFontName").c_str();
    } else {
-      vte_terminal_set_font_from_string(VTE_TERMINAL(_term), "monospace 8");
+      s = "monospace 8";
    }
+   PangoFontDescription *fontdesc = pango_font_description_from_string(s);
+   vte_terminal_set_font(VTE_TERMINAL(_term), fontdesc);
+   pango_font_description_free(fontdesc);
+
    gtk_box_pack_start(GTK_BOX(GTK_WIDGET(gtk_builder_get_object(_builder,"hbox_vte"))), _term, TRUE, TRUE, 0);
    g_signal_connect(G_OBJECT(_term), "key-press-event", G_CALLBACK(key_press_event), this);
    g_signal_connect(G_OBJECT(_term), "button-press-event",
@@ -549,7 +555,7 @@ void RGDebInstallProgress::terminalAction(GtkWidget *terminal,
           vte_terminal_select_all(VTE_TERMINAL(terminal));
           break;
       case EDIT_SELECT_NONE:
-          vte_terminal_select_none(VTE_TERMINAL(terminal));
+          vte_terminal_unselect_all(VTE_TERMINAL(terminal));
           break;
    }
 }
@@ -670,6 +676,7 @@ pkgPackageManager::OrderResult RGDebInstallProgress::start(pkgPackageManager *pm
    void *dummy;
    pkgPackageManager::OrderResult res;
    int ret;
+   GError *err;
 
    res = pm->DoInstallPreFork();
    if (res == pkgPackageManager::Failed)
@@ -677,10 +684,20 @@ pkgPackageManager::OrderResult RGDebInstallProgress::start(pkgPackageManager *pm
 
    // we need to send the fds from the pipe over a socket because
    // the vte_terminal closes all our FDs 
-   _child_id = vte_terminal_forkpty(VTE_TERMINAL(_term),NULL,NULL,
-				    false,false,false);
-   if (_child_id < 0) {
-      cerr << "vte_terminal_forkpty() failed. " << strerror(errno) << endl;
+   if (!vte_terminal_spawn_sync(VTE_TERMINAL(_term),
+                                VTE_PTY_DEFAULT,  // ptyflags
+                                NULL,             // cwd
+                                NULL, /* XXX */   // command and args     <-- put the command to be launched here
+                                NULL,             // (additional?) env vars
+                                G_SPAWN_DEFAULT,  // spawn flags          <-- review this one also
+                                NULL, /* XXX */   // child setup          <-- I think the DoInstallPostFork stuff needs to come here
+                                NULL,             // data
+                                &_child_id,       // pid (out)
+                                NULL,             // cancellable
+                                &err)) {          // error (out)
+
+      // TODO: I guess the error code is in GError err rather than errno!
+      cerr << "vte_terminal_spawn_sync() failed. " << strerror(errno) << endl;
       res = pkgPackageManager::Failed;
       GtkWidget *dialog;
       dialog = gtk_message_dialog_new (GTK_WINDOW(window()),
@@ -694,7 +711,7 @@ pkgPackageManager::OrderResult RGDebInstallProgress::start(pkgPackageManager *pm
       gtk_widget_destroy(dialog);
       return res;
    }
-   else if (_child_id == 0) {
+   else {
       int fd[2];
       pipe(fd);
       ipc_send_fd(fd[0]); // send the read part of the pipe to the parent
diff --git a/gtk/rgdebinstallprogress.h b/gtk/rgdebinstallprogress.h
index af6dfcc..15c8c21 100644
--- a/gtk/rgdebinstallprogress.h
+++ b/gtk/rgdebinstallprogress.h
@@ -32,7 +32,7 @@
 #include "rggtkbuilderwindow.h"
 #include "rguserdialog.h"
 #include<map>
-#include <vte/reaper.h>
+#include <vte/vte.h>
 
 
 class RGMainWindow;
@@ -111,7 +111,7 @@ class RGDebInstallProgress:public RInstallProgress, public RGGtkBuilderWindow
    pid_t _child_id;
    pkgPackageManager::OrderResult res;
    bool child_has_exited;
-   static void child_exited(VteReaper *vtereaper,gint child_pid, gint ret,
+   static void child_exited(VteTerminal *vteterminal, gint ret,
 			    gpointer data);
    static void terminalAction(GtkWidget *terminal, TermAction action);
 
diff --git a/gtk/rgterminstallprogress.cc b/gtk/rgterminstallprogress.cc
index 45c8510..248c52d 100644
--- a/gtk/rgterminstallprogress.cc
+++ b/gtk/rgterminstallprogress.cc
@@ -1,4 +1,4 @@
-/* rgzvtinstallprogress.cc
+/* rgterminstallprogress.cc
  *
  * Copyright (c) 2002 Michael Vogt
  *
@@ -48,7 +48,6 @@
 #include <cstdlib>
 
 #include <vte/vte.h>
-#include <vte/reaper.h>
 
 #include <cstdlib>
 #include <cstring>
@@ -63,15 +62,20 @@ RGTermInstallProgress::RGTermInstallProgress(RGMainWindow *main)
 
    _term = vte_terminal_new();
    vte_terminal_set_size(VTE_TERMINAL(_term),80,23);
-   _scrollbar = gtk_vscrollbar_new (vte_terminal_get_adjustment(VTE_TERMINAL(_term)));
+   _scrollbar = gtk_vscrollbar_new (gtk_scrollable_get_vadjustment(GTK_SCROLLABLE(VTE_TERMINAL(_term))));
    gtk_widget_set_can_focus (_scrollbar, FALSE);
    vte_terminal_set_scrollback_lines(VTE_TERMINAL(_term), 10000);
+
+   char *s;
    if(_config->FindB("Synaptic::useUserTerminalFont")) {
       char *s =(char*)_config->Find("Synaptic::TerminalFontName").c_str();
-      vte_terminal_set_font_from_string(VTE_TERMINAL(_term), s);
    } else {
-      vte_terminal_set_font_from_string(VTE_TERMINAL(_term), "monospace 10");
+      s = "monospace 10";
    }
+   PangoFontDescription *fontdesc = pango_font_description_from_string(s);
+   vte_terminal_set_font(VTE_TERMINAL(_term), fontdesc);
+   pango_font_description_free(fontdesc);
+
    GtkWidget *box = GTK_WIDGET(gtk_builder_get_object(_builder,"hbox_vte"));
    gtk_box_pack_start(GTK_BOX(box), _term, TRUE, TRUE, 0);
    gtk_box_pack_end(GTK_BOX(box), _scrollbar, FALSE, FALSE, 0);
@@ -94,17 +98,18 @@ RGTermInstallProgress::RGTermInstallProgress(RGMainWindow *main)
 }
 
 
-void RGTermInstallProgress::child_exited(VteReaper *vtereaper,
-					gint child_pid, gint ret, 
+void RGTermInstallProgress::child_exited(VteTerminal *vteterminal,
+					gint ret,
 					gpointer data)
 {
    RGTermInstallProgress *me = (RGTermInstallProgress*)data;
-   if(child_pid == me->_child_id) {
+// I _guess_ there's no point in checking the pid, since there can be one child per terminal
+//   if(child_pid == me->_child_id) {
 //        cout << "child exited" << endl;
 //        cout << "waitpid returned: " << WEXITSTATUS(ret) << endl;
       me->res = (pkgPackageManager::OrderResult)WEXITSTATUS(ret);
       me->child_has_exited=true;
-   }
+//   }
 }
 
 void RGTermInstallProgress::startUpdate()
@@ -114,8 +119,7 @@ void RGTermInstallProgress::startUpdate()
    gtk_widget_show_all(win);
 
    child_has_exited=false;
-   VteReaper* reaper = vte_reaper_get();
-   g_signal_connect(G_OBJECT(reaper), "child-exited",
+   g_signal_connect(VTE_TERMINAL(_term), "child-exited",
 		    G_CALLBACK(child_exited),
 		    this);
  
@@ -220,19 +224,22 @@ RGTermInstallProgress::start(pkgPackageManager *pm,
 
    void *dummy;
    int open_max, ret = 250;
+   GError *err;
 
    res = pm->DoInstallPreFork();
    if (res == pkgPackageManager::Failed)
       return res;
 
-   _child_id = vte_terminal_forkpty(VTE_TERMINAL(_term),NULL,NULL,false,false,false);
-   if (_child_id == -1) {
+   if (!vte_terminal_spawn_sync(VTE_TERMINAL(_term),
+           // TODO copy from rgdebinstallprogress.cc
+           VTE_PTY_DEFAULT, NULL, NULL, NULL, G_SPAWN_DEFAULT, NULL, NULL, &_child_id, NULL, &err)) {
+
       cerr << "Internal Error: impossible to fork children. Synaptics is going to stop. Please report." << endl;
       cerr << "errorcode: " << errno << endl;
       exit(1);
    }
 
-   if (_child_id == 0) {
+   else {
 
       // we ignore sigpipe as it is thrown sporadic on
       // debian, kernel 2.6 systems
diff --git a/gtk/rgterminstallprogress.h b/gtk/rgterminstallprogress.h
index a474f2a..ad0e672 100644
--- a/gtk/rgterminstallprogress.h
+++ b/gtk/rgterminstallprogress.h
@@ -31,7 +31,6 @@
 #include "rgwindow.h"
 
 #include <vte/vte.h>
-#include <vte/reaper.h>
 
 class RGTermInstallProgress : public RInstallProgress, public RGGtkBuilderWindow {
   GtkWidget *_term;
@@ -46,7 +45,7 @@ class RGTermInstallProgress : public RInstallProgress, public RGGtkBuilderWindow
 
 protected:
   bool child_has_exited;
-  static void child_exited(VteReaper *vtereaper,gint child_pid, gint ret,
+  static void child_exited(VteTerminal *vteterminal, gint ret,
 			   gpointer data);
   virtual void startUpdate();
   virtual void updateInterface();

Reply via email to