~ubuntu-branches/ubuntu/wily/qgis/wily

« back to all changes in this revision

Viewing changes to src/plugins/grass/qtermwidget/Pty.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Johan Van de Wauw
  • Date: 2010-07-11 20:23:24 UTC
  • mfrom: (3.1.4 squeeze)
  • Revision ID: james.westby@ubuntu.com-20100711202324-5ktghxa7hracohmr
Tags: 1.4.0+12730-3ubuntu1
* Merge from Debian unstable (LP: #540941).
* Fix compilation issues with QT 4.7
* Add build-depends on libqt4-webkit-dev 

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
    This file is part of Konsole, an X terminal.
 
3
    Copyright (C) 1997,1998 by Lars Doelle <lars.doelle@on-line.de>
 
4
 
 
5
    Rewritten for QT4 by e_k <e_k at users.sourceforge.net>, Copyright (C)2008
 
6
 
 
7
    This program is free software; you can redistribute it and/or modify
 
8
    it under the terms of the GNU General Public License as published by
 
9
    the Free Software Foundation; either version 2 of the License, or
 
10
    (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., 51 Franklin Street, Fifth Floor, Boston, MA
 
20
    02110-1301  USA.
 
21
*/
 
22
 
 
23
// Own
 
24
#include "Pty.h"
 
25
 
 
26
// System
 
27
#include <sys/types.h>
 
28
#include <sys/stat.h>
 
29
#include <unistd.h>
 
30
#include <errno.h>
 
31
#include <termios.h>
 
32
 
 
33
// Qt
 
34
#include <QtCore>
 
35
 
 
36
// KDE
 
37
//#include <KStandardDirs>
 
38
//#include <KLocale>
 
39
//#include <KDebug>
 
40
#include "kpty.h"
 
41
 
 
42
using namespace Konsole;
 
43
 
 
44
void Pty::donePty()
 
45
{
 
46
  emit done( exitStatus() );
 
47
}
 
48
 
 
49
void Pty::setWindowSize( int lines, int cols )
 
50
{
 
51
  _windowColumns = cols;
 
52
  _windowLines = lines;
 
53
 
 
54
  if ( pty()->masterFd() >= 0 )
 
55
    pty()->setWinSize( lines, cols );
 
56
}
 
57
QSize Pty::windowSize() const
 
58
{
 
59
  return QSize( _windowColumns, _windowLines );
 
60
}
 
61
 
 
62
void Pty::setXonXoff( bool enable )
 
63
{
 
64
  _xonXoff = enable;
 
65
 
 
66
  if ( pty()->masterFd() >= 0 )
 
67
  {
 
68
    struct ::termios ttmode;
 
69
    pty()->tcGetAttr( &ttmode );
 
70
    if ( !enable )
 
71
      ttmode.c_iflag &= ~( IXOFF | IXON );
 
72
    else
 
73
      ttmode.c_iflag |= ( IXOFF | IXON );
 
74
    if ( !pty()->tcSetAttr( &ttmode ) )
 
75
      qWarning( "Unable to set terminal attributes." );
 
76
  }
 
77
}
 
78
 
 
79
void Pty::setUtf8Mode( bool enable )
 
80
{
 
81
#ifdef IUTF8 // XXX not a reasonable place to check it.
 
82
  _utf8 = enable;
 
83
 
 
84
  if ( pty()->masterFd() >= 0 )
 
85
  {
 
86
    struct ::termios ttmode;
 
87
    pty()->tcGetAttr( &ttmode );
 
88
    if ( !enable )
 
89
      ttmode.c_iflag &= ~IUTF8;
 
90
    else
 
91
      ttmode.c_iflag |= IUTF8;
 
92
    if ( !pty()->tcSetAttr( &ttmode ) )
 
93
      qWarning( "Unable to set terminal attributes." );
 
94
  }
 
95
#endif
 
96
}
 
97
 
 
98
void Pty::setErase( char erase )
 
99
{
 
100
  _eraseChar = erase;
 
101
 
 
102
  if ( pty()->masterFd() >= 0 )
 
103
  {
 
104
    struct ::termios ttmode;
 
105
 
 
106
    pty()->tcGetAttr( &ttmode );
 
107
 
 
108
    ttmode.c_cc[VERASE] = erase;
 
109
 
 
110
    if ( !pty()->tcSetAttr( &ttmode ) )
 
111
      qWarning( "Unable to set terminal attributes." );
 
112
  }
 
113
}
 
114
 
 
115
char Pty::erase() const
 
116
{
 
117
  if ( pty()->masterFd() >= 0 )
 
118
  {
 
119
    qDebug() << "Getting erase char";
 
120
    struct ::termios ttyAttributes;
 
121
    pty()->tcGetAttr( &ttyAttributes );
 
122
    return ttyAttributes.c_cc[VERASE];
 
123
  }
 
124
 
 
125
  return _eraseChar;
 
126
}
 
127
 
 
128
void Pty::addEnvironmentVariables( const QStringList& environment )
 
129
{
 
130
  QListIterator<QString> iter( environment );
 
131
  while ( iter.hasNext() )
 
132
  {
 
133
    QString pair = iter.next();
 
134
 
 
135
    // split on the first '=' character
 
136
    int pos = pair.indexOf( '=' );
 
137
 
 
138
    if ( pos >= 0 )
 
139
    {
 
140
      QString variable = pair.left( pos );
 
141
      QString value = pair.mid( pos + 1 );
 
142
 
 
143
      //kDebug() << "Setting environment pair" << variable <<
 
144
      //    " set to " << value;
 
145
 
 
146
      setEnvironment( variable, value );
 
147
    }
 
148
  }
 
149
}
 
150
 
 
151
int Pty::start( const QString& program,
 
152
                const QStringList& programArguments,
 
153
                const QStringList& environment,
 
154
                ulong winid,
 
155
                bool addToUtmp
 
156
//               const QString& dbusService,
 
157
//               const QString& dbusSession)
 
158
              )
 
159
{
 
160
  clearArguments();
 
161
 
 
162
  setBinaryExecutable( program.toLatin1() );
 
163
 
 
164
  addEnvironmentVariables( environment );
 
165
 
 
166
  QStringListIterator it( programArguments );
 
167
  while ( it.hasNext() )
 
168
    arguments.append( it.next().toUtf8() );
 
169
 
 
170
//  if ( !dbusService.isEmpty() )
 
171
//     setEnvironment("KONSOLE_DBUS_SERVICE",dbusService);
 
172
//  if ( !dbusSession.isEmpty() )
 
173
//     setEnvironment("KONSOLE_DBUS_SESSION", dbusSession);
 
174
 
 
175
  setEnvironment( "WINDOWID", QString::number( winid ) );
 
176
 
 
177
  // unless the LANGUAGE environment variable has been set explicitly
 
178
  // set it to a null string
 
179
  // this fixes the problem where KCatalog sets the LANGUAGE environment
 
180
  // variable during the application's startup to something which
 
181
  // differs from LANG,LC_* etc. and causes programs run from
 
182
  // the terminal to display mesages in the wrong language
 
183
  //
 
184
  // this can happen if LANG contains a language which KDE
 
185
  // does not have a translation for
 
186
  //
 
187
  // BR:149300
 
188
  if ( !environment.contains( "LANGUAGE" ) )
 
189
    setEnvironment( "LANGUAGE", QString() );
 
190
 
 
191
  setUsePty( All, addToUtmp );
 
192
 
 
193
  pty()->open();
 
194
 
 
195
  struct ::termios ttmode;
 
196
  pty()->tcGetAttr( &ttmode );
 
197
  if ( !_xonXoff )
 
198
    ttmode.c_iflag &= ~( IXOFF | IXON );
 
199
  else
 
200
    ttmode.c_iflag |= ( IXOFF | IXON );
 
201
#ifdef IUTF8 // XXX not a reasonable place to check it.
 
202
  if ( !_utf8 )
 
203
    ttmode.c_iflag &= ~IUTF8;
 
204
  else
 
205
    ttmode.c_iflag |= IUTF8;
 
206
#endif
 
207
 
 
208
  if ( _eraseChar != 0 )
 
209
    ttmode.c_cc[VERASE] = _eraseChar;
 
210
 
 
211
  if ( !pty()->tcSetAttr( &ttmode ) )
 
212
    qWarning( "Unable to set terminal attributes." );
 
213
 
 
214
  pty()->setWinSize( _windowLines, _windowColumns );
 
215
 
 
216
  if ( K3Process::start( NotifyOnExit, ( Communication )( Stdin | Stdout ) ) == false )
 
217
    return -1;
 
218
 
 
219
  resume(); // Start...
 
220
  return 0;
 
221
 
 
222
}
 
223
 
 
224
void Pty::setWriteable( bool writeable )
 
225
{
 
226
  struct stat sbuf;
 
227
  stat( pty()->ttyName(), &sbuf );
 
228
  if ( writeable )
 
229
    chmod( pty()->ttyName(), sbuf.st_mode | S_IWGRP );
 
230
  else
 
231
    chmod( pty()->ttyName(), sbuf.st_mode & ~( S_IWGRP | S_IWOTH ) );
 
232
}
 
233
 
 
234
Pty::Pty()
 
235
    : _bufferFull( false ),
 
236
    _windowColumns( 0 ),
 
237
    _windowLines( 0 ),
 
238
    _eraseChar( 0 ),
 
239
    _xonXoff( true ),
 
240
    _utf8( true )
 
241
{
 
242
  connect( this, SIGNAL( receivedStdout( K3Process *, char *, int ) ),
 
243
           this, SLOT( dataReceived( K3Process *, char *, int ) ) );
 
244
  connect( this, SIGNAL( processExited( K3Process * ) ),
 
245
           this, SLOT( donePty() ) );
 
246
  connect( this, SIGNAL( wroteStdin( K3Process * ) ),
 
247
           this, SLOT( writeReady() ) );
 
248
  _pty = new KPty;
 
249
 
 
250
  setUsePty( All, false ); // utmp will be overridden later
 
251
}
 
252
 
 
253
Pty::~Pty()
 
254
{
 
255
  delete _pty;
 
256
}
 
257
 
 
258
void Pty::writeReady()
 
259
{
 
260
  _pendingSendJobs.erase( _pendingSendJobs.begin() );
 
261
  _bufferFull = false;
 
262
  doSendJobs();
 
263
}
 
264
 
 
265
void Pty::doSendJobs()
 
266
{
 
267
  if ( _pendingSendJobs.isEmpty() )
 
268
  {
 
269
    emit bufferEmpty();
 
270
    return;
 
271
  }
 
272
 
 
273
  SendJob& job = _pendingSendJobs.first();
 
274
 
 
275
 
 
276
  if ( !writeStdin( job.data(), job.length() ) )
 
277
  {
 
278
    qWarning( "Pty::doSendJobs - Could not send input data to terminal process." );
 
279
    return;
 
280
  }
 
281
  _bufferFull = true;
 
282
}
 
283
 
 
284
void Pty::appendSendJob( const char* s, int len )
 
285
{
 
286
  _pendingSendJobs.append( SendJob( s, len ) );
 
287
}
 
288
 
 
289
void Pty::sendData( const char* s, int len )
 
290
{
 
291
  appendSendJob( s, len );
 
292
  if ( !_bufferFull )
 
293
    doSendJobs();
 
294
}
 
295
 
 
296
void Pty::dataReceived( K3Process *, char *buf, int len )
 
297
{
 
298
  emit receivedData( buf, len );
 
299
}
 
300
 
 
301
void Pty::lockPty( bool lock )
 
302
{
 
303
  if ( lock )
 
304
    suspend();
 
305
  else
 
306
    resume();
 
307
}
 
308
 
 
309
int Pty::foregroundProcessGroup() const
 
310
{
 
311
  int pid = tcgetpgrp( pty()->masterFd() );
 
312
 
 
313
  if ( pid != -1 )
 
314
  {
 
315
    return pid;
 
316
  }
 
317
 
 
318
  return 0;
 
319
}
 
320
 
 
321
//#include "moc_Pty.cpp"