source: projects/synaptic/trunk/gtk/rgterminstallprogress.cc @ 280

Revision 280, 6.9 KB checked in by yasumichi, 15 years ago (diff)

first import

Line 
1/* rgzvtinstallprogress.cc
2 *
3 * Copyright (c) 2002 Michael Vogt
4 *
5 * Author: Michael Vogt <mvo@debian.org>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of the
10 * License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
20 * USA
21 */
22
23
24
25#include "config.h"
26
27#ifdef HAVE_TERMINAL
28
29#include "i18n.h"
30
31#include "rgterminstallprogress.h"
32#include "rgmainwindow.h"
33#include "rguserdialog.h"
34#include "rconfiguration.h"
35#include "gsynaptic.h"
36
37#include <X11/Xlib.h>
38#include <iostream>
39#include <cerrno>
40#include <unistd.h>
41#include <sys/wait.h>
42#include <sys/types.h>
43#include <apt-pkg/error.h>
44#include <apt-pkg/configuration.h>
45#include <apt-pkg/pkgsystem.h>
46#include <cassert>
47
48#include <vte/vte.h>
49#include <vte/reaper.h>
50
51using namespace std;
52
53void RGTermInstallProgress::child_exited(VteReaper *vtereaper,
54                                        gint child_pid, gint ret, 
55                                        gpointer data)
56{
57   RGTermInstallProgress *me = (RGTermInstallProgress*)data;
58   if(child_pid == me->_child_id) {
59//        cout << "child exited" << endl;
60//        cout << "waitpid returned: " << WEXITSTATUS(ret) << endl;
61      me->res = (pkgPackageManager::OrderResult)WEXITSTATUS(ret);
62      me->child_has_exited=true;
63   }
64}
65
66void RGTermInstallProgress::startUpdate()
67{
68   child_has_exited=false;
69   VteReaper* reaper = vte_reaper_get();
70   g_signal_connect(G_OBJECT(reaper), "child-exited",
71                    G_CALLBACK(child_exited),
72                    this);
73 
74   // check if we run embedded
75   int id = _config->FindI("Volatile::PlugProgressInto", -1);
76   //cout << "Plug ID: " << id << endl;
77   if (id > 0) {
78      gtk_widget_hide(glade_xml_get_widget(_gladeXML, "window_zvtinstallprogress"));
79      GtkWidget *vbox = glade_xml_get_widget(_gladeXML, "vbox_terminstall_progress");
80      _sock =  gtk_plug_new(id);
81      gtk_widget_reparent(vbox, _sock);
82      gtk_widget_show(_sock);
83   } else {
84      show();
85   }
86
87   gtk_label_set_markup(GTK_LABEL(_statusL), _("<i>Running...</i>"));
88   gtk_widget_set_sensitive(_closeB, false);
89   RGFlushInterface();
90}
91
92void RGTermInstallProgress::finishUpdate()
93{
94   gtk_widget_set_sensitive(_closeB, true);
95   
96   RGFlushInterface();
97   _updateFinished = true;
98
99   _config->Set("Synaptic::closeZvt", 
100                gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(_closeOnF))
101                ? "true" : "false");
102   
103   if (!RWriteConfigFile(*_config)) {
104      _error->Error(_("An error occurred while saving configurations."));
105      RGUserDialog userDialog(this);
106      userDialog.showErrors();
107   }
108 
109   if(res == 0 &&(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(_closeOnF)) ||
110                  _config->FindB("Volatile::Non-Interactive", false))) {
111      hide();
112      return;
113   }
114
115   const char *msg = _(getResultStr(res));
116   vte_terminal_feed(VTE_TERMINAL(_term), utf8_to_locale(msg), strlen(msg));
117   gtk_label_set_markup(GTK_LABEL(_statusL), _("<i>Finished</i>"));
118   if(res == 0)
119      gtk_widget_grab_focus(GTK_WIDGET(_closeB));
120}
121
122void RGTermInstallProgress::stopShell(GtkWidget *self, void* data)
123{
124   RGTermInstallProgress *me = (RGTermInstallProgress*)data; 
125
126   if(!me->_updateFinished) {
127      gtk_label_set_markup(GTK_LABEL(me->_statusL), 
128                           _("<i>Can't close while running</i>"));
129      return;
130   } 
131
132   RGFlushInterface();
133   if(me->_sock != NULL) {
134      gtk_widget_destroy(me->_sock);
135   } else {
136      me->hide();
137   }
138}
139
140bool RGTermInstallProgress::close()
141{
142   stopShell(NULL, this);
143   return true;
144}
145
146gboolean RGTermInstallProgress::zvtFocus (GtkWidget *widget,
147                                         GdkEventButton *event,
148                                         gpointer user_data)
149{
150   //cout << "zvtFocus" << endl;
151   
152   gtk_widget_grab_focus(widget);
153   
154   return FALSE;
155}
156
157RGTermInstallProgress::RGTermInstallProgress(RGMainWindow *main) 
158   : RInstallProgress(), RGGladeWindow(main, "zvtinstallprogress"), _sock(NULL)
159{
160   setTitle(_("Applying Changes"));
161
162   GtkWidget *hbox = glade_xml_get_widget(_gladeXML, "hbox_terminal");
163   assert(hbox);
164
165   _term = vte_terminal_new();
166   GtkWidget *scrollbar = 
167      gtk_vscrollbar_new (GTK_ADJUSTMENT (VTE_TERMINAL(_term)->adjustment));
168   GTK_WIDGET_UNSET_FLAGS (scrollbar, GTK_CAN_FOCUS);
169   vte_terminal_set_scrollback_lines(VTE_TERMINAL(_term), 10000);
170   if(_config->FindB("Synaptic::useUserTerminalFont")) {
171      char *s =(char*)_config->Find("Synaptic::TerminalFontName").c_str();
172      vte_terminal_set_font_from_string(VTE_TERMINAL(_term), s);
173   } else {
174      vte_terminal_set_font_from_string(VTE_TERMINAL(_term), "monospace 10");
175   }
176
177   gtk_box_pack_start(GTK_BOX(hbox), _term, TRUE, TRUE, 0);
178   gtk_widget_show(_term);
179
180   gtk_box_pack_end(GTK_BOX(hbox), scrollbar, FALSE, FALSE, 0);
181   gtk_widget_show(scrollbar);
182
183   _closeOnF = glade_xml_get_widget(_gladeXML, "checkbutton_close_after_pm");
184   assert(_closeOnF);
185   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(_closeOnF), 
186                                _config->FindB("Synaptic::closeZvt", false));
187
188   _statusL = glade_xml_get_widget(_gladeXML, "label_status");
189   _closeB = glade_xml_get_widget(_gladeXML, "button_close");
190   gtk_signal_connect(GTK_OBJECT(_closeB), "clicked",
191                      (GtkSignalFunc)stopShell, this);
192
193   if(_config->FindB("Volatile::Non-Interactive", false)) 
194      gtk_widget_hide(_closeOnF);
195   
196}
197
198
199
200
201pkgPackageManager::OrderResult
202RGTermInstallProgress::start(RPackageManager *pm,
203                            int numPackages,
204                            int numPackagesTotal)
205{
206   //cout << "RGTermInstallProgress::start()" << endl;
207
208   void *dummy;
209   int open_max, ret = 250;
210
211   res = pm->DoInstallPreFork();
212   if (res == pkgPackageManager::Failed)
213      return res;
214
215   _child_id = vte_terminal_forkpty(VTE_TERMINAL(_term),NULL,NULL,false,false,false);
216   if (_child_id == -1) {
217      cerr << "Internal Error: impossible to fork children. Synaptics is going to stop. Please report." << endl;
218      cerr << "errorcode: " << errno << endl;
219      exit(1);
220   }
221
222   if (_child_id == 0) {
223
224      // we ignore sigpipe as it is thrown sporadic on
225      // debian, kernel 2.6 systems
226      struct sigaction new_act;
227      memset( &new_act, 0, sizeof( new_act ) );
228      new_act.sa_handler = SIG_IGN;
229      sigaction( SIGPIPE, &new_act, NULL);
230      res = pm->DoInstallPostFork();
231      _exit(res);
232   }
233
234   startUpdate();
235   // make sure that the child has really exited and we catched the
236   // return code
237   while(!child_has_exited)
238      updateInterface();
239
240   finishUpdate();
241
242   return res;
243}
244
245void RGTermInstallProgress::updateInterface()
246{   
247   if (gtk_events_pending()) {
248      while (gtk_events_pending()) gtk_main_iteration();
249   } else {
250      // 0.1 secs
251      usleep(10000);
252   }
253}
254
255
256#endif
257
258// vim:sts=3:sw=3
Note: See TracBrowser for help on using the repository browser.