2 * vm_console_widget.cpp
4 * Created on: Oct 4, 2012
8 #include "vm_console_widget.h"
11 #include <QMessageBox>
12 #include <QVBoxLayout>
15 VmConsoleWidget::VmConsoleWidget(QWidget* parent) :
16 QWidget(parent), mCols(100), mRows(25), mTermProcess(0) {
21 VmConsoleWidget::~VmConsoleWidget() {
25 bool VmConsoleWidget::tryTerminate() {
26 if (mTermProcess == NULL) {
30 if (mTermProcess != NULL && mTermProcess->state() == QProcess::Running) {
31 mTermProcess->terminate();
32 bool xwindow_closed = mTermProcess->waitForFinished();
34 return xwindow_closed;
36 } else if (mVncView != NULL) {
37 mVncServer->terminate();
38 bool vncserver_exited = mVncServer->waitForFinished();
41 return vncserver_exited;
47 void VmConsoleWidget::mainWindowClosing() {
51 void VmConsoleWidget::closeEvent(QCloseEvent* e) {
53 qDebug() << "Warning: could not terminate process...there could be a leak";
55 qDebug() << "Process terminated";
60 void VmConsoleWidget::resizeEvent(QResizeEvent* re) {
61 QWidget::resizeEvent(re);
63 if (mTermProcess == NULL)
66 // Search for xterm window and update its size
67 Display *dsp = XOpenDisplay(NULL);
70 bool childFound = false;
71 while (!childFound && mTermProcess->state() == QProcess::Running) {
72 Window root, parent, *children;
74 XQueryTree(dsp, wnd, &root, &parent, &children, &numwin);
75 childFound = (children != NULL);
78 XResizeWindow(dsp, *children, width(), height());
86 bool VmConsoleWidget::isRunning() {
87 if (mTermProcess == NULL) {
91 // FIXME: This function is currently very unreliable
92 // The QProcess->state() function should return the correct
93 // state of the process but it is currently not working as expected
94 // Debugging with GDB also does not reveal the problem
95 // Maybe the way this method is being called is incorrect
96 return (mTermProcess->state() == QProcess::Running) ? true : false;
99 bool VmConsoleWidget::start(int mode, QString devfile, QString streamName) {
100 qDebug() << "VmConsoleWidget : start() [" << streamName << "]";
102 // Start VM in correct mode
103 if (mode == VmConsoleWidget::STREAM) {
104 mVmMode = "v3_stream";
105 } else if (mode == VmConsoleWidget::CONSOLE) {
106 mVmMode = "v3_cons_sc";
108 mVmMode = "v3_vncclient";
111 qDebug() << "Vm Mode: " << mVmMode;
112 qDebug() << "Vm dev file: " << devfile;
116 if (streamName.compare("") != 0) {
117 // This is v3_stream mode
118 args << "-sb" << "-geometry" << QString("%1x%2").arg(mCols).arg(mRows) << "-j"
119 << "-into" << QString::number(winId()) << "-e" << mVmMode << devfile << streamName;
121 // Start the xterm process
122 qDebug() << "Starting terminal with arguments '" << args.join(" ");
123 mTermProcess = new QProcess();
125 // Connect signals and slots
126 connect(mTermProcess, SIGNAL(finished(int, QProcess::ExitStatus)), this,
127 SLOT(termProcessExited(int, QProcess::ExitStatus)));
129 connect(mTermProcess, SIGNAL(error(QProcess::ProcessError)), this,
130 SLOT(errorMessage(QProcess::ProcessError)));
132 mTermProcess->start("/usr/bin/xterm", args);
135 // This is non-stream mode
137 if (mVmMode.compare("v3_cons_sc") == 0) {
139 args << "-sb" << "-geometry" << QString("%1x%2").arg(mCols).arg(mRows) << "-j"
140 << "-into" << QString::number(winId()) << "-e" << mVmMode << devfile;
143 qDebug() << "Starting terminal with arguments '" << args.join(" ");
144 mTermProcess = new QProcess();
146 // Connect signals and slots
147 connect(mTermProcess, SIGNAL(finished(int, QProcess::ExitStatus)), this,
148 SLOT(termProcessExited(int, QProcess::ExitStatus)));
150 connect(mTermProcess, SIGNAL(error(QProcess::ProcessError)), this,
151 SLOT(errorMessage(QProcess::ProcessError)));
153 mTermProcess->start("/usr/bin/xterm", args);
157 mVncServer = new QProcess();
158 mVncServer->setProcessChannelMode(QProcess::MergedChannels);
160 connect(mVncServer, SIGNAL(finished(int, QProcess::ExitStatus)), this,
161 SLOT(termProcessExited(int, QProcess::ExitStatus)));
163 connect(mVncServer, SIGNAL(error(QProcess::ProcessError)), this,
164 SLOT(errorMessage(QProcess::ProcessError)));
167 args << "--port=5951" << "--password=test123" << devfile;
168 qDebug() << "arguments: " << args.join(" ");
169 mVncServer->start("v3_vncserver", args);
171 if (!mVncServer->waitForFinished()) {
172 qDebug() << "Error with VNC server";
174 msg.setText("Error with VNC server!");
175 msg.setStandardButtons(QMessageBox::Ok);
176 msg.setIcon(QMessageBox::Critical);
181 //args << "-sb" << "-geometry" << QString("%1x%2").arg(mCols).arg(mRows) << "-j"
182 // << "-into" << QString::number(winId()) << "-e" << "vncviewer localhost:5951";
184 QVBoxLayout* vncBox = new QVBoxLayout();
185 mVncView = new VncView(this, QUrl("vnc://localhost:5951"), KConfigGroup());
186 //mVncView = new VncView(this, QUrl("vnc://localhost:5901"), KConfigGroup());
187 vncBox->addWidget(mVncView);
188 this->setLayout(vncBox);
195 // Flag to indicate success and failure
198 if (mVmMode.compare("v3_vncclient") == 0) {
205 // This is v3_stream or v3_cons_sc mode
206 if (mTermProcess != NULL && mTermProcess->waitForStarted()) {
208 qDebug() << "Process started";
211 qDebug() << "Process did not start";
215 /* Wait for the xterm window to be opened and resize it
216 * to our own widget size.
218 Display *dsp = XOpenDisplay(NULL);
219 Window wnd = winId();
221 bool childFound = false;
222 while (!childFound && mTermProcess->state() == QProcess::Running) {
223 Window root, parent, *children;
225 XQueryTree(dsp, wnd, &root, &parent, &children, &numwin);
226 childFound = (children != NULL);
229 XResizeWindow(dsp, *children, width(), height());
240 qDebug() << (success == -1 ? "Starting the process failed"
241 : "Process started, but exited before opening a terminal");
247 status = (success == 0);
253 void VmConsoleWidget::termProcessExited(int a, QProcess::ExitStatus b) {
254 qDebug() << "Term Process Exited: " << a << " : " << b;
256 if (mTermProcess != NULL) {
260 if (mVncServer != NULL) {
270 void VmConsoleWidget::errorMessage(QProcess::ProcessError err) {
271 qDebug() << "Process error: " << err;