File indexing completed on 2025-01-19 04:23:30

0001 /*
0002     This file is part of Konsole, an X terminal.
0003 
0004     Copyright (C) 2007 by Robert Knight <robertknight@gmail.com>
0005     Copyright (C) 1997,1998 by Lars Doelle <lars.doelle@on-line.de>
0006 
0007     Rewritten for QT4 by e_k <e_k at users.sourceforge.net>, Copyright (C)2008
0008 
0009     This program is free software; you can redistribute it and/or modify
0010     it under the terms of the GNU General Public License as published by
0011     the Free Software Foundation; either version 2 of the License, or
0012     (at your option) any later version.
0013 
0014     This program is distributed in the hope that it will be useful,
0015     but WITHOUT ANY WARRANTY; without even the implied warranty of
0016     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0017     GNU General Public License for more details.
0018 
0019     You should have received a copy of the GNU General Public License
0020     along with this program; if not, write to the Free Software
0021     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
0022     02110-1301  USA.
0023 */
0024 
0025 #ifndef SESSION_H
0026 #define SESSION_H
0027 
0028 #include <QStringList>
0029 #include <QWidget>
0030 
0031 #include "Emulation.h"
0032 #include "History.h"
0033 #include "ProcessInfo.h"
0034 
0035 class KProcess;
0036 
0037 namespace Konsole {
0038 
0039 class Emulation;
0040 class Pty;
0041 class TerminalDisplay;
0042 //class ZModemDialog;
0043 
0044 /**
0045  * Represents a terminal session consisting of a pseudo-teletype and a terminal emulation.
0046  * The pseudo-teletype (or PTY) handles I/O between the terminal process and Konsole.
0047  * The terminal emulation ( Emulation and subclasses ) processes the output stream from the
0048  * PTY and produces a character image which is then shown on views connected to the session.
0049  *
0050  * Each Session can be connected to one or more views by using the addView() method.
0051  * The attached views can then display output from the program running in the terminal
0052  * or send input to the program in the terminal in the form of keypresses and mouse
0053  * activity.
0054  */
0055 class Session : public QObject {
0056     Q_OBJECT
0057 
0058 public:
0059     Q_PROPERTY(QString name READ nameTitle)
0060     Q_PROPERTY(int processId READ processId)
0061     Q_PROPERTY(QString keyBindings READ keyBindings WRITE setKeyBindings)
0062     Q_PROPERTY(QSize size READ size WRITE setSize)
0063 
0064     /**
0065      * Constructs a new session.
0066      *
0067      * To start the terminal process, call the run() method,
0068      * after specifying the program and arguments
0069      * using setProgram() and setArguments()
0070      *
0071      * If no program or arguments are specified explicitly, the Session
0072      * falls back to using the program specified in the SHELL environment
0073      * variable.
0074      */
0075     Session(QObject* parent = 0);
0076     virtual ~Session();
0077 
0078     /**
0079      * Returns true if the session is currently running.  This will be true
0080      * after run() has been called successfully.
0081      */
0082     bool isRunning() const;
0083 
0084     /**
0085      * Sets the profile associated with this session.
0086      *
0087      * @param profileKey A key which can be used to obtain the current
0088      * profile settings from the SessionManager
0089      */
0090     void setProfileKey(const QString & profileKey);
0091     /**
0092      * Returns the profile key associated with this session.
0093      * This can be passed to the SessionManager to obtain the current
0094      * profile settings.
0095      */
0096     QString profileKey() const;
0097 
0098     /**
0099      * Adds a new view for this session.
0100      *
0101      * The viewing widget will display the output from the terminal and
0102      * input from the viewing widget (key presses, mouse activity etc.)
0103      * will be sent to the terminal.
0104      *
0105      * Views can be removed using removeView().  The session is automatically
0106      * closed when the last view is removed.
0107      */
0108     void addView(TerminalDisplay * widget);
0109     /**
0110      * Removes a view from this session.  When the last view is removed,
0111      * the session will be closed automatically.
0112      *
0113      * @p widget will no longer display output from or send input
0114      * to the terminal
0115      */
0116     void removeView(TerminalDisplay * widget);
0117 
0118     /**
0119      * Returns the views connected to this session
0120      */
0121     QList<TerminalDisplay *> views() const;
0122 
0123     /**
0124      * Returns the terminal emulation instance being used to encode / decode
0125      * characters to / from the process.
0126      */
0127     Emulation * emulation() const;
0128 
0129     /**
0130      * Returns the environment of this session as a list of strings like
0131      * VARIABLE=VALUE
0132      */
0133     QStringList environment() const;
0134     /**
0135      * Sets the environment for this session.
0136      * @p environment should be a list of strings like
0137      * VARIABLE=VALUE
0138      */
0139     void setEnvironment(const QStringList & environment);
0140 
0141     /** Returns the unique ID for this session. */
0142     int sessionId() const;
0143 
0144     /**
0145      * Return the session title set by the user (ie. the program running
0146      * in the terminal), or an empty string if the user has not set a custom title
0147      */
0148     QString userTitle() const;
0149 
0150     /**
0151      * This enum describes the contexts for which separate
0152      * tab title formats may be specified.
0153      */
0154     enum TabTitleContext {
0155         /** Default tab title format */
0156         LocalTabTitle,
0157         /**
0158          * Tab title format used session currently contains
0159          * a connection to a remote computer (via SSH)
0160          */
0161         RemoteTabTitle
0162     };
0163     /**
0164      * Sets the format used by this session for tab titles.
0165      *
0166      * @param context The context whoose format should be set.
0167      * @param format The tab title format.  This may be a mixture
0168      * of plain text and dynamic elements denoted by a '%' character
0169      * followed by a letter.  (eg. %d for directory).  The dynamic
0170      * elements available depend on the @p context
0171      */
0172     void setTabTitleFormat(TabTitleContext context , const QString & format);
0173     /** Returns the format used by this session for tab titles. */
0174     QString tabTitleFormat(TabTitleContext context) const;
0175 
0176 
0177     /** Returns the arguments passed to the shell process when run() is called. */
0178     QStringList arguments() const;
0179     /** Returns the program name of the shell process started when run() is called. */
0180     QString program() const;
0181 
0182     /**
0183      * Sets the command line arguments which the session's program will be passed when
0184      * run() is called.
0185      */
0186     void setArguments(const QStringList & arguments);
0187     /** Sets the program to be executed when run() is called. */
0188     void setProgram(const QString & program);
0189 
0190     /** Returns the session's current working directory. */
0191     QString initialWorkingDirectory() {
0192         return _initialWorkingDir;
0193     }
0194 
0195     /**
0196      * Sets the initial working directory for the session when it is run
0197      * This has no effect once the session has been started.
0198      */
0199     void setInitialWorkingDirectory( const QString & dir );
0200 
0201     /**
0202      * Sets the type of history store used by this session.
0203      * Lines of output produced by the terminal are added
0204      * to the history store.  The type of history store
0205      * used affects the number of lines which can be
0206      * remembered before they are lost and the storage
0207      * (in memory, on-disk etc.) used.
0208      */
0209     void setHistoryType(const HistoryType & type);
0210     /**
0211      * Returns the type of history store used by this session.
0212      */
0213     const HistoryType & historyType() const;
0214     /**
0215      * Clears the history store used by this session.
0216      */
0217     void clearHistory();
0218 
0219     /**
0220      * Enables monitoring for activity in the session.
0221      * This will cause notifySessionState() to be emitted
0222      * with the NOTIFYACTIVITY state flag when output is
0223      * received from the terminal.
0224      */
0225     void setMonitorActivity(bool);
0226     /** Returns true if monitoring for activity is enabled. */
0227     bool isMonitorActivity() const;
0228 
0229     /**
0230      * Enables monitoring for silence in the session.
0231      * This will cause notifySessionState() to be emitted
0232      * with the NOTIFYSILENCE state flag when output is not
0233      * received from the terminal for a certain period of
0234      * time, specified with setMonitorSilenceSeconds()
0235      */
0236     void setMonitorSilence(bool);
0237     /**
0238      * Returns true if monitoring for inactivity (silence)
0239      * in the session is enabled.
0240      */
0241     bool isMonitorSilence()  const;
0242     /** See setMonitorSilence() */
0243     void setMonitorSilenceSeconds(int seconds);
0244 
0245     /**
0246      * Sets the key bindings used by this session.  The bindings
0247      * specify how input key sequences are translated into
0248      * the character stream which is sent to the terminal.
0249      *
0250      * @param id The name of the key bindings to use.  The
0251      * names of available key bindings can be determined using the
0252      * KeyboardTranslatorManager class.
0253      */
0254     void setKeyBindings(const QString & id);
0255     /** Returns the name of the key bindings used by this session. */
0256     QString keyBindings() const;
0257 
0258     /**
0259      * This enum describes the available title roles.
0260      */
0261     enum TitleRole {
0262         /** The name of the session. */
0263         NameRole,
0264         /** The title of the session which is displayed in tabs etc. */
0265         DisplayedTitleRole
0266     };
0267 
0268     /** Sets the session's title for the specified @p role to @p title. */
0269     void setTitle(TitleRole role , const QString & title);
0270     /** Returns the session's title for the specified @p role. */
0271     QString title(TitleRole role) const;
0272     /** Convenience method used to read the name property.  Returns title(Session::NameRole). */
0273     QString nameTitle() const {
0274         return title(Session::NameRole);
0275     }
0276 
0277     /** Sets the name of the icon associated with this session. */
0278     void setIconName(const QString & iconName);
0279     /** Returns the name of the icon associated with this session. */
0280     QString iconName() const;
0281 
0282     /** Sets the text of the icon associated with this session. */
0283     void setIconText(const QString & iconText);
0284     /** Returns the text of the icon associated with this session. */
0285     QString iconText() const;
0286 
0287     /** Flag if the title/icon was changed by user/shell. */
0288     bool isTitleChanged() const;
0289 
0290     /** Specifies whether a utmp entry should be created for the pty used by this session. */
0291     void setAddToUtmp(bool);
0292 
0293     /** Sends the specified @p signal to the terminal process. */
0294     bool sendSignal(int signal);
0295 
0296     /**
0297      * Specifies whether to close the session automatically when the terminal
0298      * process terminates.
0299      */
0300     void setAutoClose(bool b) {
0301         _autoClose = b;
0302     }
0303 
0304     /**
0305      * Sets whether flow control is enabled for this terminal
0306      * session.
0307      */
0308     void setFlowControlEnabled(bool enabled);
0309 
0310     /** Returns whether flow control is enabled for this terminal session. */
0311     bool flowControlEnabled() const;
0312 
0313     /**
0314      * Sends @p text to the current foreground terminal program.
0315      */
0316     void sendText(const QString & text) const;
0317 
0318     /**
0319      * Returns the process id of the terminal process.
0320      * This is the id used by the system API to refer to the process.
0321      */
0322     int processId() const;
0323 
0324     /**
0325      * Returns the process id of the terminal's foreground process.
0326      * This is initially the same as processId() but can change
0327      * as the user starts other programs inside the terminal.
0328      */
0329     int foregroundProcessId() const;
0330 
0331     /**
0332      * Returns the name of the terminal's foreground process.
0333      */
0334     QString foregroundProcessName();
0335 
0336     /**
0337      * Returns the current working directory of the process.
0338      */
0339     QString currentDir();
0340 
0341     /** Returns the terminal session's window size in lines and columns. */
0342     QSize size();
0343     /**
0344      * Emits a request to resize the session to accommodate
0345      * the specified window size.
0346      *
0347      * @param size The size in lines and columns to request.
0348      */
0349     void setSize(const QSize & size);
0350 
0351     /** Sets the text codec used by this session's terminal emulation. */
0352     void setCodec(QTextCodec * codec);
0353 
0354     /**
0355      * Sets whether the session has a dark background or not.  The session
0356      * uses this information to set the COLORFGBG variable in the process's
0357      * environment, which allows the programs running in the terminal to determine
0358      * whether the background is light or dark and use appropriate colors by default.
0359      *
0360      * This has no effect once the session is running.
0361      */
0362     void setDarkBackground(bool darkBackground);
0363     /**
0364      * Returns true if the session has a dark background.
0365      * See setDarkBackground()
0366      */
0367     bool hasDarkBackground() const;
0368 
0369     /**
0370      * Attempts to get the shell program to redraw the current display area.
0371      * This can be used after clearing the screen, for example, to get the
0372      * shell to redraw the prompt line.
0373      */
0374     void refresh();
0375 
0376 //  void startZModem(const QString &rz, const QString &dir, const QStringList &list);
0377 //  void cancelZModem();
0378 //  bool isZModemBusy() { return _zmodemBusy; }
0379 
0380     /**
0381      * Returns a pty slave file descriptor.
0382      * This can be used for display and control
0383      * a remote terminal.
0384      */
0385     int getPtySlaveFd() const;
0386 
0387 public Q_SLOTS:
0388 
0389     /**
0390      * Starts the terminal session.
0391      *
0392      * This creates the terminal process and connects the teletype to it.
0393      */
0394     void run();
0395 
0396     /**
0397      * Starts the terminal session for "as is" PTY
0398      * (without the direction a data to internal terminal process).
0399      * It can be used for control or display a remote/external terminal.
0400      */
0401     void runEmptyPTY();
0402 
0403     /**
0404      * Closes the terminal session.  This sends a hangup signal
0405      * (SIGHUP) to the terminal process and causes the done(Session*)
0406      * signal to be emitted.
0407      */
0408     void close();
0409 
0410     /**
0411      * Changes the session title or other customizable aspects of the terminal
0412      * emulation display. For a list of what may be changed see the
0413      * Emulation::titleChanged() signal.
0414      */
0415     void setUserTitle( int, const QString & caption );    
0416 
0417 Q_SIGNALS:
0418 
0419     /** Emitted when the terminal process starts. */
0420     void started();
0421 
0422     /**
0423      * Emitted when the terminal process exits.
0424      */
0425     void finished();
0426 
0427     /**
0428      * Emitted when output is received from the terminal process.
0429      */
0430     void receivedData( const QString & text );
0431 
0432     /** Emitted when the session's title has changed. */
0433     void titleChanged();
0434 
0435     /** Emitted when the session's profile has changed. */
0436     void profileChanged(const QString & profile);
0437 
0438     /**
0439      * Emitted when the activity state of this session changes.
0440      *
0441      * @param state The new state of the session.  This may be one
0442      * of NOTIFYNORMAL, NOTIFYSILENCE or NOTIFYACTIVITY
0443      */
0444     void stateChanged(int state);
0445 
0446     /** Emitted when a bell event occurs in the session. */
0447     void bellRequest( const QString & message );
0448 
0449     /**
0450      * Requests that the color the text for any tabs associated with
0451      * this session should be changed;
0452      *
0453      * TODO: Document what the parameter does
0454      */
0455     void changeTabTextColorRequest(int);
0456 
0457     /**
0458      * Requests that the background color of views on this session
0459      * should be changed.
0460      */
0461     void changeBackgroundColorRequest(const QColor &);
0462 
0463     /** TODO: Document me. */
0464     void openUrlRequest(const QString & url);
0465 
0466     /** TODO: Document me. */
0467 //  void zmodemDetected();
0468 
0469     /**
0470      * Emitted when the terminal process requests a change
0471      * in the size of the terminal window.
0472      *
0473      * @param size The requested window size in terms of lines and columns.
0474      */
0475     void resizeRequest(const QSize & size);
0476 
0477     /**
0478      * Emitted when a profile change command is received from the terminal.
0479      *
0480      * @param text The text of the command.  This is a string of the form
0481      * "PropertyName=Value;PropertyName=Value ..."
0482      */
0483     void profileChangeCommandReceived(const QString & text);
0484 
0485     /**
0486      * Emitted when the flow control state changes.
0487      *
0488      * @param enabled True if flow control is enabled or false otherwise.
0489      */
0490     void flowControlEnabledChanged(bool enabled);
0491 
0492     /**
0493      * Broker for Emulation::cursorChanged() signal
0494      */
0495     void cursorChanged(Emulation::KeyboardCursorShape cursorShape, bool blinkingCursorEnabled);
0496 
0497     void silence();
0498     void activity();
0499 
0500 private Q_SLOTS:
0501     void done(int);
0502 
0503 //  void fireZModemDetected();
0504 
0505     void onReceiveBlock( const char * buffer, int len );
0506     void monitorTimerDone();
0507 
0508     void onViewSizeChange(int height, int width);
0509     void onEmulationSizeChange(QSize);
0510 
0511     void activityStateSet(int);
0512 
0513     //automatically detach views from sessions when view is destroyed
0514     void viewDestroyed(QObject * view);
0515 
0516 //  void zmodemReadStatus();
0517 //  void zmodemReadAndSendBlock();
0518 //  void zmodemRcvBlock(const char *data, int len);
0519 //  void zmodemFinished();
0520 
0521 private:
0522 
0523     void updateTerminalSize();
0524     bool updateForegroundProcessInfo();
0525     WId windowId() const;
0526 
0527     QString validDirectory(const QString &dir) const;
0528 
0529     int            _uniqueIdentifier;
0530 
0531     Pty     *_shellProcess;
0532     Emulation  *  _emulation;
0533 
0534     QList<TerminalDisplay *> _views;
0535 
0536     bool           _monitorActivity;
0537     bool           _monitorSilence;
0538     bool           _notifiedActivity;
0539     bool           _masterMode;
0540     bool           _autoClose;
0541     bool           _wantedClose;
0542     QTimer    *    _monitorTimer;
0543 
0544     int            _silenceSeconds;
0545 
0546     QString        _nameTitle;
0547     QString        _displayTitle;
0548     QString        _userTitle;
0549 
0550     QString        _localTabTitleFormat;
0551     QString        _remoteTabTitleFormat;
0552 
0553     QString        _iconName;
0554     QString        _iconText; // as set by: echo -en '\033]1;IconText\007
0555     bool           _isTitleChanged; ///< flag if the title/icon was changed by user
0556     bool           _addToUtmp;
0557     bool           _flowControl;
0558     bool           _fullScripting;
0559 
0560     QString        _program;
0561     QStringList    _arguments;
0562 
0563     QStringList    _environment;
0564     int            _sessionId;
0565 
0566     QString        _initialWorkingDir;
0567 
0568     // ZModem
0569 //  bool           _zmodemBusy;
0570 //  KProcess*      _zmodemProc;
0571 //  ZModemDialog*  _zmodemProgress;
0572 
0573     // Color/Font Changes by ESC Sequences
0574 
0575     QColor         _modifiedBackground; // as set by: echo -en '\033]11;Color\007
0576 
0577     QString        _profileKey;
0578 
0579     bool _hasDarkBackground;
0580 
0581     ProcessInfo *_foregroundProcessInfo;
0582     int _foregroundPid;
0583     static int lastSessionId;
0584     int ptySlaveFd;
0585 };
0586 
0587 /**
0588  * Provides a group of sessions which is divided into master and slave sessions.
0589  * Activity in master sessions can be propagated to all sessions within the group.
0590  * The type of activity which is propagated and method of propagation is controlled
0591  * by the masterMode() flags.
0592  */
0593 class SessionGroup : public QObject {
0594     Q_OBJECT
0595 
0596 public:
0597     /** Constructs an empty session group. */
0598     SessionGroup();
0599     /** Destroys the session group and removes all connections between master and slave sessions. */
0600     ~SessionGroup();
0601 
0602     /** Adds a session to the group. */
0603     void addSession( Session * session );
0604     /** Removes a session from the group. */
0605     void removeSession( Session * session );
0606 
0607     /** Returns the list of sessions currently in the group. */
0608     QList<Session *> sessions() const;
0609 
0610     /**
0611      * Sets whether a particular session is a master within the group.
0612      * Changes or activity in the group's master sessions may be propagated
0613      * to all the sessions in the group, depending on the current masterMode()
0614      *
0615      * @param session The session whoose master status should be changed.
0616      * @param master True to make this session a master or false otherwise
0617      */
0618     void setMasterStatus( Session * session , bool master );
0619     /** Returns the master status of a session.  See setMasterStatus() */
0620     bool masterStatus( Session * session ) const;
0621 
0622     /**
0623      * This enum describes the options for propagating certain activity or
0624      * changes in the group's master sessions to all sessions in the group.
0625      */
0626     enum MasterMode {
0627         /**
0628          * Any input key presses in the master sessions are sent to all
0629          * sessions in the group.
0630          */
0631         CopyInputToAll = 1
0632     };
0633 
0634     /**
0635      * Specifies which activity in the group's master sessions is propagated
0636      * to all sessions in the group.
0637      *
0638      * @param mode A bitwise OR of MasterMode flags.
0639      */
0640     void setMasterMode( int mode );
0641     /**
0642      * Returns a bitwise OR of the active MasterMode flags for this group.
0643      * See setMasterMode()
0644      */
0645     int masterMode() const;
0646 
0647 private:
0648     void connectPair(Session * master , Session * other);
0649     void disconnectPair(Session * master , Session * other);
0650     void connectAll(bool connect);
0651     QList<Session *> masters() const;
0652 
0653     // maps sessions to their master status
0654     QHash<Session *,bool> _sessions;
0655 
0656     int _masterMode;
0657 };
0658 
0659 }
0660 
0661 #endif