Session.h 20.5 KB
Newer Older
1 2
/*
    This file is part of Konsole, an X terminal.
3

4 5
    Copyright 2007-2008 by Robert Knight <robertknight@gmail.com>
    Copyright 1997,1998 by Lars Doelle <lars.doelle@on-line.de>
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21

    This program 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 2 of the License, or
    (at your option) any later version.

    This program 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 this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301  USA.
*/
22 23 24 25

#ifndef SESSION_H
#define SESSION_H

26
// Qt
Dirk Mueller's avatar
Dirk Mueller committed
27 28
#include <QtCore/QStringList>
#include <QtCore/QByteRef>
29

30
// KDE
31 32
#include <KApplication>
#include <KMainWindow>
33
#include "konsole_export.h"
34

35 36 37
// Konsole
#include "History.h"

38
class KProcess;
Robert Knight's avatar
 
Robert Knight committed
39
class KUrl;
Robert Knight's avatar
 
Robert Knight committed
40

41 42 43
namespace Konsole
{

44 45
class Emulation;
class Pty;
Robert Knight's avatar
 
Robert Knight committed
46
class ProcessInfo;
47 48
class TerminalDisplay;
class ZModemDialog;
Waldo Bastian's avatar
Waldo Bastian committed
49

Robert Knight's avatar
 
Robert Knight committed
50
/**
51 52
 * Represents a terminal session consisting of a pseudo-teletype and a terminal emulation.
 * The pseudo-teletype (or PTY) handles I/O between the terminal process and Konsole.
53 54
 * The terminal emulation ( Emulation and subclasses ) processes the output stream from the
 * PTY and produces a character image which is then shown on views connected to the session.
Robert Knight's avatar
 
Robert Knight committed
55
 *
56
 * Each Session can be connected to one or more views by using the addView() method.
Robert Knight's avatar
 
Robert Knight committed
57 58 59 60
 * The attached views can then display output from the program running in the terminal
 * or send input to the program in the terminal in the form of keypresses and mouse
 * activity.
 */
61
class KONSOLEPRIVATE_EXPORT Session : public QObject
62
{
63
Q_OBJECT
64 65

public:
66
  Q_PROPERTY(QString name READ nameTitle)
67
  Q_PROPERTY(int processId READ processId)
68
  Q_PROPERTY(QString keyBindings READ keyBindings WRITE setKeyBindings)
69
  Q_PROPERTY(QSize size READ size WRITE setSize)
70

71
  /**
72
   * Constructs a new session.
73
   *
74 75 76
   * To start the terminal process, call the run() method,
   * after specifying the program and arguments
   * using setProgram() and setArguments()
77 78
   *
   * If no program or arguments are specified explicitly, the Session
79
   * falls back to using the program specified in the SHELL environment
80
   * variable.
81
   */
82
  explicit Session(QObject* parent = 0);
83
  ~Session();
84

85 86
  /** 
   * Connect to an existing terminal.  When a new Session() is constructed it 
87
   * automatically searches for and opens a new teletype.  If you want to 
88 89 90 91 92
   * use an existing teletype (given its file descriptor) call this after
   * constructing the session.
   *
   * Calling openTeletype() while a session is running has no effect.
   *
93
   * @param masterFd The file descriptor of the pseudo-teletype master (See KPtyProcess::KPtyProcess())
94
   */
95
  void openTeletype(int masterFd);
96

97
  /**
98
   * Returns true if the session is currently running.  This will be true
99
   * after run() has been called successfully.
100
   */
101
  bool isRunning() const;
102

103 104 105 106 107
  /**
   * Adds a new view for this session.
   *
   * The viewing widget will display the output from the terminal and
   * input from the viewing widget (key presses, mouse activity etc.)
Robert Knight's avatar
 
Robert Knight committed
108
   * will be sent to the terminal.
109
   *
Robert Knight's avatar
Robert Knight committed
110 111
   * Views can be removed using removeView().  The session is automatically
   * closed when the last view is removed.
112
   */
113
  void addView(TerminalDisplay* widget);
114
  /**
115 116
   * Removes a view from this session.  When the last view is removed,
   * the session will be closed automatically.
117 118
   *
   * @p widget will no longer display output from or send input
119
   * to the terminal
120
   */
121
  void removeView(TerminalDisplay* widget);
122

123 124 125
  /**
   * Returns the views connected to this session
   */
126
  QList<TerminalDisplay*> views() const;
127

128
  /**
129
   * Returns the terminal emulation instance being used to encode / decode
130 131
   * characters to / from the process.
   */
132 133 134
  Emulation*  emulation() const;

  /**
Constantin Berzan's avatar
APIDOX  
Constantin Berzan committed
135 136
   * Returns the environment of this session as a list of strings like
   * VARIABLE=VALUE
137
   */
138
  QStringList environment() const;
139
  /**
Constantin Berzan's avatar
APIDOX  
Constantin Berzan committed
140 141 142
   * Sets the environment for this session.
   * @p environment should be a list of strings like
   * VARIABLE=VALUE
Robert Knight's avatar
 
Robert Knight committed
143
   */
144
  void setEnvironment(const QStringList& environment);
Robert Knight's avatar
 
Robert Knight committed
145

146
  /** Returns the unique ID for this session. */
147
  int sessionId() const;
148 149 150

  /**
   * Return the session title set by the user (ie. the program running
Robert Knight's avatar
 
Robert Knight committed
151
   * in the terminal), or an empty string if the user has not set a custom title
Robert Knight's avatar
Robert Knight committed
152 153
   */
  QString userTitle() const;
154 155

  /**
156 157 158
   * This enum describes the contexts for which separate
   * tab title formats may be specified.
   */
159 160
  enum TabTitleContext
  {
161
    /** Default tab title format */
162
    LocalTabTitle,
163
    /**
164 165 166
     * Tab title format used session currently contains
     * a connection to a remote computer (via SSH)
     */
167 168
    RemoteTabTitle
  };
169 170 171
  /**
   * Sets the format used by this session for tab titles.
   *
172 173 174 175
   * @param context The context whoose format should be set.
   * @param format The tab title format.  This may be a mixture
   * of plain text and dynamic elements denoted by a '%' character
   * followed by a letter.  (eg. %d for directory).  The dynamic
176
   * elements available depend on the @p context
177
   */
178
  void setTabTitleFormat(TabTitleContext context , const QString& format);
179
  /** Returns the format used by this session for tab titles. */
180
  QString tabTitleFormat(TabTitleContext context) const;
Robert Knight's avatar
Robert Knight committed
181

182 183 184 185 186

  /** Returns the arguments passed to the shell process when run() is called. */
  QStringList arguments() const;
  /** Returns the program name of the shell process started when run() is called. */
  QString program() const;
187

188
  /**
Robert Knight's avatar
 
Robert Knight committed
189 190 191 192 193 194 195
   * Sets the command line arguments which the session's program will be passed when
   * run() is called.
   */
  void setArguments(const QStringList& arguments);
  /** Sets the program to be executed when run() is called. */
  void setProgram(const QString& program);

196
  /** Returns the session's current working directory. */
197
  QString initialWorkingDirectory() { return _initialWorkingDir; }
198 199 200

  /**
   * Sets the initial working directory for the session when it is run
Robert Knight's avatar
 
Robert Knight committed
201 202
   * This has no effect once the session has been started.
   */
203
  void setInitialWorkingDirectory( const QString& dir );
204

Robert Knight's avatar
 
Robert Knight committed
205 206 207 208 209
  /**
   * Returns the current directory of the foreground process in the session
   */
  QString currentWorkingDirectory();

210 211 212 213 214 215
  /**
   * Sets the type of history store used by this session.
   * Lines of output produced by the terminal are added
   * to the history store.  The type of history store
   * used affects the number of lines which can be
   * remembered before they are lost and the storage
216 217
   * (in memory, on-disk etc.) used.
   */
218 219 220 221 222 223 224
  void setHistoryType(const HistoryType& type);
  /**
   * Returns the type of history store used by this session.
   */
  const HistoryType& historyType() const;
  /**
   * Clears the history store used by this session.
225
   */
226
  void clearHistory();
227

228
  /**
229 230
   * Enables monitoring for activity in the session.
   * This will cause notifySessionState() to be emitted
231 232
   * with the NOTIFYACTIVITY state flag when output is
   * received from the terminal.
233
   */
234
  void setMonitorActivity(bool);
235 236
  /** Returns true if monitoring for activity is enabled. */
  bool isMonitorActivity() const;
237

238 239 240 241 242 243 244
  /**
   * Enables monitoring for silence in the session.
   * This will cause notifySessionState() to be emitted
   * with the NOTIFYSILENCE state flag when output is not
   * received from the terminal for a certain period of
   * time, specified with setMonitorSilenceSeconds()
   */
245
  void setMonitorSilence(bool);
246
  /**
247 248 249 250 251
   * Returns true if monitoring for inactivity (silence)
   * in the session is enabled.
   */
  bool isMonitorSilence()  const;
  /** See setMonitorSilence() */
252
  void setMonitorSilenceSeconds(int seconds);
253

254 255
  /**
   * Sets the key bindings used by this session.  The bindings
256
   * specify how input key sequences are translated into
257 258 259
   * the character stream which is sent to the terminal.
   *
   * @param id The name of the key bindings to use.  The
260
   * names of available key bindings can be determined using the
261
   * KeyboardTranslatorManager class.
262
   */
263 264 265
  void setKeyBindings(const QString& id);
  /** Returns the name of the key bindings used by this session. */
  QString keyBindings() const;
266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283

  /**
   * This enum describes the available title roles.
   */
  enum TitleRole
  {
      /** The name of the session. */
      NameRole,
      /** The title of the session which is displayed in tabs etc. */
      DisplayedTitleRole
  };

  /** Sets the session's title for the specified @p role to @p title. */
  void setTitle(TitleRole role , const QString& title);
  /** Returns the session's title for the specified @p role. */
  QString title(TitleRole role) const;
  /** Convenience method used to read the name property.  Returns title(Session::NameRole). */
  QString nameTitle() const { return title(Session::NameRole); }
Robert Knight's avatar
 
Robert Knight committed
284 285
  /** Returns a title generated from tab format and process information. */
  QString getDynamicTitle();
286 287 288 289 290

  /** Sets the name of the icon associated with this session. */
  void setIconName(const QString& iconName);
  /** Returns the name of the icon associated with this session. */
  QString iconName() const;
291

Robert Knight's avatar
 
Robert Knight committed
292 293 294
  /** Return URL for the session. */
  KUrl getUrl();

Constantin Berzan's avatar
APIDOX  
Constantin Berzan committed
295
  /** Sets the text of the icon associated with this session. */
296
  void setIconText(const QString& iconText);
Constantin Berzan's avatar
APIDOX  
Constantin Berzan committed
297
  /** Returns the text of the icon associated with this session. */
298 299
  QString iconText() const;

Robert Knight's avatar
Robert Knight committed
300 301 302 303
  /** 
   * Specifies whether a utmp entry should be created for the pty used by this session.
   * If true, KPty::login() is called when the session is started.
   */
304
  void setAddToUtmp(bool);
305

Constantin Berzan's avatar
APIDOX  
Constantin Berzan committed
306 307 308 309
  /**
   * Specifies whether to close the session automatically when the terminal
   * process terminates.
   */
310
  void setAutoClose(bool b) { _autoClose = b; }
311

312 313 314 315 316
  /**
   * Sets whether flow control is enabled for this terminal
   * session.
   */
  void setFlowControlEnabled(bool enabled);
317

Robert Knight's avatar
 
Robert Knight committed
318 319 320
  /** Returns whether flow control is enabled for this terminal session. */
  bool flowControlEnabled() const;

321
  /**
322 323 324 325
   * Sends @p text to the current foreground terminal program.
   */
  void sendText(const QString& text) const;

326 327
  /**
   * Returns the process id of the terminal process.
328 329
   * This is the id used by the system API to refer to the process.
   */
330
  int processId() const;
331

332 333 334 335 336
  /**
   * Returns the foreground PID. Returns -1 if there is none.
   */
  int foregroundProcessId();

Robert Knight's avatar
 
Robert Knight committed
337
  /** Returns true if the user has started a program in the session. */
338
  bool isForegroundProcessActive();
Robert Knight's avatar
 
Robert Knight committed
339 340

  /** Returns the name of the current foreground process. */
341
  QString foregroundProcessName();
342

343
  /** Returns the terminal session's window size in lines and columns. */
Waldo Bastian's avatar
Waldo Bastian committed
344
  QSize size();
345
  /**
346
   * Emits a request to resize the session to accommodate
347 348 349 350
   * the specified window size.
   *
   * @param size The size in lines and columns to request.
   */
Robert Knight's avatar
Robert Knight committed
351
  void setSize(const QSize& size);
352

353 354 355
  /** Sets the text codec used by this session's terminal emulation. */
  void setCodec(QTextCodec* codec);

356
  /**
357 358 359 360 361
   * Sets whether the session has a dark background or not.  The session
   * uses this information to set the COLORFGBG variable in the process's
   * environment, which allows the programs running in the terminal to determine
   * whether the background is light or dark and use appropriate colors by default.
   *
362
   * This has no effect once the session is running.
363 364
   */
  void setDarkBackground(bool darkBackground);
365 366 367 368
  /**
   * Returns true if the session has a dark background.
   * See setDarkBackground()
   */
369 370
  bool hasDarkBackground() const;

371 372 373
  /**
   * Attempts to get the shell program to redraw the current display area.
   * This can be used after clearing the screen, for example, to get the
374 375 376 377
   * shell to redraw the prompt line.
   */
  void refresh();

378 379 380 381
  void startZModem(const QString &rz, const QString &dir, const QStringList &list);
  void cancelZModem();
  bool isZModemBusy() { return _zmodemBusy; }

382 383
 /** 
   * Possible values of the @p what parameter for setUserTitle()
384
   * See "Operating System Controls" section on http://rtfm.etla.org/xterm/ctlseq.html 
385 386 387
   */
  enum UserTitleChange
  {
388 389 390 391 392 393 394
      IconNameAndWindowTitle     = 0,
    IconName                 = 1,
    WindowTitle                = 2,
    TextColor                = 10,
    BackgroundColor            = 11,
    SessionName                = 30,
    ProfileChange            = 50     // this clashes with Xterm's font change command
395 396
  };

Robert Knight's avatar
 
Robert Knight committed
397 398 399 400
  // session management
  void saveSession(KConfigGroup& group);
  void restoreSession(KConfigGroup& group);

401
public slots:
402

403 404
  /**
   * Starts the terminal session.
405 406 407
   *
   * This creates the terminal process and connects the teletype to it.
   */
408
  void run();
409

410 411
  /**
   * Closes the terminal session.  This sends a hangup signal
412 413 414 415
   * (SIGHUP) to the terminal process and causes the finished()  
   * signal to be emitted.  If the process does not respond to the SIGHUP signal
   * then the terminal connection (the pty) is closed and Konsole waits for the 
   * process to exit.
416
   */
417
  void close();
418

Constantin Berzan's avatar
APIDOX  
Constantin Berzan committed
419 420 421 422
  /**
   * Changes the session title or other customizable aspects of the terminal
   * emulation display. For a list of what may be changed see the
   * Emulation::titleChanged() signal.
423 424 425
   *
   * @param what The feature being changed.  Value is one of UserTitleChange
   * @param caption The text part of the terminal command
Constantin Berzan's avatar
APIDOX  
Constantin Berzan committed
426
   */
427
  void setUserTitle( int what , const QString &caption );
428

429
signals:
430

431 432 433
  /** Emitted when the terminal process starts. */
  void started();

434
  /**
435 436 437
   * Emitted when the terminal process exits.
   */
  void finished();
438

439 440
  /**
   * Emitted when output is received from the terminal process.
441
   */
442
  void receivedData( const QString& text );
443

444
  /** Emitted when the session's title has changed. */
445
  void titleChanged();
446

447
  /**
448 449 450 451 452
   * Emitted when the activity state of this session changes.
   *
   * @param state The new state of the session.  This may be one
   * of NOTIFYNORMAL, NOTIFYSILENCE or NOTIFYACTIVITY
   */
453
  void stateChanged(int state);
454

Robert Knight's avatar
 
Robert Knight committed
455 456
  /** Emitted when a bell event occurs in the session. */
  void bellRequest( const QString& message );
457 458

  /**
459 460 461 462 463
   * Requests that the color the text for any tabs associated with
   * this session should be changed;
   *
   * TODO: Document what the parameter does
   */
464
  void changeTabTextColorRequest(int);
465 466 467 468 469

  /**
   * Requests that the background color of views on this session
   * should be changed.
   */
470
  void changeBackgroundColorRequest(const QColor&);
471 472 473 474 475
  /** 
   * Requests that the text color of views on this session should
   * be changed to @p color.
   */
  void changeForegroundColorRequest(const QColor&);
476

Robert Knight's avatar
 
Robert Knight committed
477
  /** TODO: Document me. */
478
  void openUrlRequest(const QString& url);
479

480 481
  /** TODO: Document me. */
  void zmodemDetected();
Laurent Montel's avatar
Laurent Montel committed
482

483 484
  /**
   * Emitted when the terminal process requests a change
485
   * in the size of the terminal window.
486 487 488
   *
   * @param size The requested window size in terms of lines and columns.
   */
489
  void resizeRequest(const QSize& size);
Robert Knight's avatar
 
Robert Knight committed
490

491 492
  /**
   * Emitted when a profile change command is received from the terminal.
493 494 495 496 497 498
   *
   * @param text The text of the command.  This is a string of the form
   * "PropertyName=Value;PropertyName=Value ..."
   */
  void profileChangeCommandReceived(const QString& text);

Robert Knight's avatar
 
Robert Knight committed
499 500 501 502 503 504 505
 /**
  * Emitted when the flow control state changes.
  *
  * @param enabled True if flow control is enabled or false otherwise.
  */
  void flowControlEnabledChanged(bool enabled);

506
private slots:
507
  void done(int);
508

509
  void fireZModemDetected();
510

511
  void onReceiveBlock( const char* buffer, int len );
512
  void monitorTimerDone();
513

514
  void onViewSizeChange(int height, int width);
515

516
  void activityStateSet(int);
517

518 519
  //automatically detach views from sessions when view is destroyed
  void viewDestroyed(QObject* view);
520

521 522
  void zmodemReadStatus();
  void zmodemReadAndSendBlock();
523
  void zmodemRcvBlock(const char *data, int len);
524
  void zmodemFinished();
525

Robert Knight's avatar
 
Robert Knight committed
526
  void updateFlowControlState(bool suspended);
527
  void updateWindowSize(int lines, int columns);
528 529
private:

530
  void updateTerminalSize();
531
  WId windowId() const;
532
  bool kill(int signal);
533 534 535 536 537 538 539
  // print a warning message in the terminal.  This is used
  // if the program fails to start, or if the shell exits in 
  // an unsuccessful manner
  void terminalWarning(const QString& message);
  // checks that the binary 'program' is available and can be executed
  // returns the binary name if available or an empty string otherwise
  QString checkProgram(const QString& program) const;
Robert Knight's avatar
 
Robert Knight committed
540 541 542 543
  ProcessInfo* getProcessInfo();
  void updateSessionProcessInfo();
  bool updateForegroundProcessInfo();
  ProcessInfo* updateWorkingDirectory();
544

545 546
  int            _uniqueIdentifier;

547
  Pty*          _shellProcess;
548
  Emulation*    _emulation;
549

550
  QList<TerminalDisplay*> _views;
551

552 553 554 555 556 557 558
  bool           _monitorActivity;
  bool           _monitorSilence;
  bool           _notifiedActivity;
  bool           _masterMode;
  bool           _autoClose;
  bool           _wantedClose;
  QTimer*        _monitorTimer;
559

560
  int            _silenceSeconds;
Laurent Montel's avatar
Laurent Montel committed
561

562 563
  QString        _nameTitle;
  QString        _displayTitle;
Robert Knight's avatar
Robert Knight committed
564
  QString        _userTitle;
565 566 567 568

  QString        _localTabTitleFormat;
  QString        _remoteTabTitleFormat;

569 570 571 572 573
  QString        _iconName;
  QString        _iconText; // as set by: echo -en '\033]1;IconText\007
  bool           _addToUtmp;
  bool           _flowControl;
  bool           _fullScripting;
574

575 576
  QString        _program;
  QStringList    _arguments;
577

578
  QStringList    _environment;
579
  int            _sessionId;
580

581
  QString        _initialWorkingDir;
Robert Knight's avatar
 
Robert Knight committed
582 583 584 585 586
  QString        _currentWorkingDir;

  ProcessInfo*   _sessionProcessInfo;
  ProcessInfo*   _foregroundProcessInfo;
  int            _foregroundPid;
Laurent Montel's avatar
Laurent Montel committed
587

Waldo Bastian's avatar
Waldo Bastian committed
588
  // ZModem
589
  bool           _zmodemBusy;
590
  KProcess*      _zmodemProc;
591
  ZModemDialog*  _zmodemProgress;
592 593 594

  // Color/Font Changes by ESC Sequences

595
  QColor         _modifiedBackground; // as set by: echo -en '\033]11;Color\007
596

597
  QString        _profileKey;
598

599 600
  bool _hasDarkBackground;

601
  static int lastSessionId;
602

603 604
};

605 606 607 608
/**
 * Provides a group of sessions which is divided into master and slave sessions.
 * Activity in master sessions can be propagated to all sessions within the group.
 * The type of activity which is propagated and method of propagation is controlled
609
 * by the masterMode() flags.
610 611 612 613 614 615 616
 */
class SessionGroup : public QObject
{
Q_OBJECT

public:
    /** Constructs an empty session group. */
617
    SessionGroup(QObject* parent);
618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637
    /** Destroys the session group and removes all connections between master and slave sessions. */
    ~SessionGroup();

    /** Adds a session to the group. */
    void addSession( Session* session );
    /** Removes a session from the group. */
    void removeSession( Session* session );

    /** Returns the list of sessions currently in the group. */
    QList<Session*> sessions() const;

    /**
     * Sets whether a particular session is a master within the group.
     * Changes or activity in the group's master sessions may be propagated
     * to all the sessions in the group, depending on the current masterMode()
     *
     * @param session The session whoose master status should be changed.
     * @param master True to make this session a master or false otherwise
     */
    void setMasterStatus( Session* session , bool master );
638
    /** Returns the master status of a session.  See setMasterStatus() */
639 640
    bool masterStatus( Session* session ) const;

641 642
    /**
     * This enum describes the options for propagating certain activity or
643 644 645 646
     * changes in the group's master sessions to all sessions in the group.
     */
    enum MasterMode
    {
647 648
        /**
         * Any input key presses in the master sessions are sent to all
649 650 651 652 653
         * sessions in the group.
         */
        CopyInputToAll = 1
    };

654
    /**
655 656 657 658 659 660 661
     * Specifies which activity in the group's master sessions is propagated
     * to all sessions in the group.
     *
     * @param mode A bitwise OR of MasterMode flags.
     */
    void setMasterMode( int mode );
    /**
662
     * Returns a bitwise OR of the active MasterMode flags for this group.
663 664 665 666
     * See setMasterMode()
     */
    int masterMode() const;

667
private slots:
668
    void sessionFinished();
669

670 671 672 673 674 675 676 677 678 679 680 681
private:
    void connectPair(Session* master , Session* other);
    void disconnectPair(Session* master , Session* other);
    void connectAll(bool connect);
    QList<Session*> masters() const;

    // maps sessions to their master status
    QHash<Session*,bool> _sessions;

    int _masterMode;
};

Stephan Binner's avatar
Stephan Binner committed
682
}
683

684
#endif
Robert Knight's avatar
 
Robert Knight committed
685 686 687 688 689 690 691 692 693

/*
  Local Variables:
  mode: c++
  c-file-style: "stroustrup"
  indent-tabs-mode: nil
  tab-width: 4
  End:
*/