1 /* 2 This file is part of Konsole, an X terminal. 3 4 Copyright (C) 2007 by Robert Knight <robertknight@gmail.com> 5 Copyright (C) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> 6 7 Rewritten for QT4 by e_k <e_k at users.sourceforge.net>, Copyright (C)2008 8 9 This program is free software; you can redistribute it and/or modify 10 it under the terms of the GNU General Public License as published by 11 the Free Software Foundation; either version 2 of the License, or 12 (at your option) any later version. 13 14 This program is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU General Public License for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with this program; if not, write to the Free Software 21 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 22 02110-1301 USA. 23 */ 24 25 #ifndef SESSION_H 26 #define SESSION_H 27 28 #include <QProcess> 29 #include <QStringList> 30 #include <QWidget> 31 32 #include "History.h" 33 34 class KProcess; 35 36 namespace Konsole { 37 38 class Emulation; 39 class Pty; 40 class TerminalDisplay; 41 //class ZModemDialog; 42 43 /** 44 * Represents a terminal session consisting of a pseudo-teletype and a terminal emulation. 45 * The pseudo-teletype (or PTY) handles I/O between the terminal process and Konsole. 46 * The terminal emulation ( Emulation and subclasses ) processes the output stream from the 47 * PTY and produces a character image which is then shown on views connected to the session. 48 * 49 * Each Session can be connected to one or more views by using the addView() method. 50 * The attached views can then display output from the program running in the terminal 51 * or send input to the program in the terminal in the form of keypresses and mouse 52 * activity. 53 */ 54 class Session : public QObject { 55 Q_OBJECT 56 57 public: 58 Q_PROPERTY(QString name READ nameTitle) 59 Q_PROPERTY(int processId READ processId) 60 Q_PROPERTY(QString keyBindings READ keyBindings WRITE setKeyBindings) 61 Q_PROPERTY(QSize size READ size WRITE setSize) 62 63 /** 64 * Constructs a new session. 65 * 66 * To start the terminal process, call the run() method, 67 * after specifying the program and arguments 68 * using setProgram() and setArguments() 69 * 70 * If no program or arguments are specified explicitly, the Session 71 * falls back to using the program specified in the SHELL environment 72 * variable. 73 */ 74 Session(QObject* parent = 0); 75 ~Session() override; 76 77 /** 78 * Returns true if the session is currently running. This will be true 79 * after run() has been called successfully. 80 */ 81 bool isRunning() const; 82 83 /** 84 * Sets the profile associated with this session. 85 * 86 * \param profileKey A key which can be used to obtain the current 87 * profile settings from the SessionManager 88 */ 89 void setProfileKey(const QString & profileKey); 90 /** 91 * Returns the profile key associated with this session. 92 * This can be passed to the SessionManager to obtain the current 93 * profile settings. 94 */ 95 QString profileKey() const; 96 97 /** 98 * Adds a new view for this session. 99 * 100 * The viewing widget will display the output from the terminal and 101 * input from the viewing widget (key presses, mouse activity etc.) 102 * will be sent to the terminal. 103 * 104 * Views can be removed using removeView(). The session is automatically 105 * closed when the last view is removed. 106 */ 107 void addView(TerminalDisplay * widget); 108 /** 109 * Removes a view from this session. When the last view is removed, 110 * the session will be closed automatically. 111 * 112 * @p widget will no longer display output from or send input 113 * to the terminal 114 */ 115 void removeView(TerminalDisplay * widget); 116 117 /** 118 * Returns the views connected to this session 119 */ 120 QList<TerminalDisplay *> views() const; 121 122 /** 123 * Returns the terminal emulation instance being used to encode / decode 124 * characters to / from the process. 125 */ 126 Emulation * emulation() const; 127 128 /** 129 * Returns the environment of this session as a list of strings like 130 * VARIABLE=VALUE 131 */ 132 QStringList environment() const; 133 /** 134 * Sets the environment for this session. 135 * @p environment should be a list of strings like 136 * VARIABLE=VALUE 137 */ 138 void setEnvironment(const QStringList & environment); 139 140 /** Returns the unique ID for this session. */ 141 int sessionId() const; 142 143 /** 144 * Returns the session title set by the user (ie. the program running 145 * in the terminal), or an empty string if the user has not set a custom title 146 */ 147 QString userTitle() const; 148 149 /** 150 * This enum describes the contexts for which separate 151 * tab title formats may be specified. 152 */ 153 enum TabTitleContext { 154 /** Default tab title format */ 155 LocalTabTitle, 156 /** 157 * Tab title format used session currently contains 158 * a connection to a remote computer (via SSH) 159 */ 160 RemoteTabTitle 161 }; 162 /** 163 * Sets the format used by this session for tab titles. 164 * 165 * \param context The context whoose format should be set. 166 * \param format The tab title format. This may be a mixture 167 * of plain text and dynamic elements denoted by a '%' character 168 * followed by a letter (e.g., %d for directory). The dynamic 169 * elements available depend on the @p context 170 */ 171 void setTabTitleFormat(TabTitleContext context , const QString & format); 172 /** Returns the format used by this session for tab titles. */ 173 QString tabTitleFormat(TabTitleContext context) const; 174 175 176 /** Returns the arguments passed to the shell process when run() is called. */ 177 QStringList arguments() const; 178 /** Returns the program name of the shell process started when run() is called. */ 179 QString program() const; 180 181 /** 182 * Sets the command line arguments which the session's program will be passed when 183 * run() is called. 184 */ 185 void setArguments(const QStringList & arguments); 186 /** Sets the program to be executed when run() is called. */ 187 void setProgram(const QString & program); 188 189 /** Returns the session's current working directory. */ initialWorkingDirectory()190 QString initialWorkingDirectory() { 191 return _initialWorkingDir; 192 } 193 194 /** 195 * Sets the initial working directory for the session when it is run 196 * This has no effect once the session has been started. 197 */ 198 void setInitialWorkingDirectory( const QString & dir ); 199 200 /** 201 * Sets the type of history store used by this session. 202 * Lines of output produced by the terminal are added 203 * to the history store. The type of history store 204 * used affects the number of lines which can be 205 * remembered before they are lost and the storage 206 * (in memory, on-disk etc.) used. 207 */ 208 void setHistoryType(const HistoryType & type); 209 /** 210 * Returns the type of history store used by this session. 211 */ 212 const HistoryType & historyType() const; 213 /** 214 * Clears the history store used by this session. 215 */ 216 void clearHistory(); 217 218 /** 219 * Enables monitoring for activity in the session. 220 * This will cause notifySessionState() to be emitted 221 * with the NOTIFYACTIVITY state flag when output is 222 * received from the terminal. 223 */ 224 void setMonitorActivity(bool); 225 /** Returns true if monitoring for activity is enabled. */ 226 bool isMonitorActivity() const; 227 228 /** 229 * Enables monitoring for silence in the session. 230 * This will cause notifySessionState() to be emitted 231 * with the NOTIFYSILENCE state flag when output is not 232 * received from the terminal for a certain period of 233 * time, specified with setMonitorSilenceSeconds() 234 */ 235 void setMonitorSilence(bool); 236 /** 237 * Returns true if monitoring for inactivity (silence) 238 * in the session is enabled. 239 */ 240 bool isMonitorSilence() const; 241 /** See setMonitorSilence() */ 242 void setMonitorSilenceSeconds(int seconds); 243 244 /** 245 * Sets the key bindings used by this session. The bindings 246 * specify how input key sequences are translated into 247 * the character stream which is sent to the terminal. 248 * 249 * \param id The name of the key bindings to use. The 250 * names of available key bindings can be determined using the 251 * KeyboardTranslatorManager class. 252 */ 253 void setKeyBindings(const QString & id); 254 /** Returns the name of the key bindings used by this session. */ 255 QString keyBindings() const; 256 257 /** 258 * This enum describes the available title roles. 259 */ 260 enum TitleRole { 261 /** The name of the session. */ 262 NameRole, 263 /** The title of the session which is displayed in tabs etc. */ 264 DisplayedTitleRole 265 }; 266 267 /** Sets the session's title for the specified @p role to @p title. */ 268 void setTitle(TitleRole role , const QString & title); 269 /** Returns the session's title for the specified @p role. */ 270 QString title(TitleRole role) const; 271 /** Convenience method used to read the name property. Returns title(Session::NameRole). */ nameTitle()272 QString nameTitle() const { 273 return title(Session::NameRole); 274 } 275 276 /** Sets the name of the icon associated with this session. */ 277 void setIconName(const QString & iconName); 278 /** Returns the name of the icon associated with this session. */ 279 QString iconName() const; 280 281 /** Sets the text of the icon associated with this session. */ 282 void setIconText(const QString & iconText); 283 /** Returns the text of the icon associated with this session. */ 284 QString iconText() const; 285 286 /** Specifies whether a utmp entry should be created for the pty used by this session. */ 287 void setAddToUtmp(bool); 288 289 /** Sends the specified @p signal to the terminal process. */ 290 bool sendSignal(int signal); 291 292 /** 293 * Specifies whether to close the session automatically when the terminal 294 * process terminates. 295 */ setAutoClose(bool b)296 void setAutoClose(bool b) { 297 _autoClose = b; 298 } 299 300 /** 301 * Sets whether flow control is enabled for this terminal 302 * session. 303 */ 304 void setFlowControlEnabled(bool enabled); 305 306 /** Returns whether flow control is enabled for this terminal session. */ 307 bool flowControlEnabled() const; 308 309 /** 310 * Sends @p text to the current foreground terminal program. 311 */ 312 void sendText(const QString & text) const; 313 314 /** 315 * Returns the process id of the terminal process. 316 * This is the id used by the system API to refer to the process. 317 */ 318 int processId() const; 319 320 /** 321 * Returns the process id of the terminal's foreground process. 322 * This is initially the same as processId() but can change 323 * as the user starts other programs inside the terminal. 324 */ 325 int foregroundProcessId() const; 326 327 /** Returns the terminal session's window size in lines and columns. */ 328 QSize size(); 329 /** 330 * Emits a request to resize the session to accommodate 331 * the specified window size. 332 * 333 * \param size The size in lines and columns to request. 334 */ 335 void setSize(const QSize & size); 336 337 /** Sets the text codec used by this session's terminal emulation. */ 338 void setCodec(QTextCodec * codec); 339 340 /** 341 * Sets whether the session has a dark background or not. The session 342 * uses this information to set the COLORFGBG variable in the process's 343 * environment, which allows the programs running in the terminal to determine 344 * whether the background is light or dark and use appropriate colors by default. 345 * 346 * This has no effect once the session is running. 347 */ 348 void setDarkBackground(bool darkBackground); 349 /** 350 * Returns true if the session has a dark background. 351 * See setDarkBackground() 352 */ 353 bool hasDarkBackground() const; 354 355 /** 356 * Attempts to get the shell program to redraw the current display area. 357 * This can be used after clearing the screen, for example, to get the 358 * shell to redraw the prompt line. 359 */ 360 void refresh(); 361 362 // void startZModem(const QString &rz, const QString &dir, const QStringList &list); 363 // void cancelZModem(); 364 // bool isZModemBusy() { return _zmodemBusy; } 365 366 /** 367 * Returns a pty slave file descriptor. 368 * This can be used for display and control 369 * a remote terminal. 370 */ 371 int getPtySlaveFd() const; 372 373 public slots: 374 375 /** 376 * Starts the terminal session. 377 * 378 * This creates the terminal process and connects the teletype to it. 379 */ 380 void run(); 381 382 /** 383 * Starts the terminal session for "as is" PTY 384 * (without the direction a data to internal terminal process). 385 * It can be used for control or display a remote/external terminal. 386 */ 387 void runEmptyPTY(); 388 389 /** 390 * Closes the terminal session. This sends a hangup signal 391 * (SIGHUP) to the terminal process and causes the done(Session*) 392 * signal to be emitted. 393 */ 394 void close(); 395 396 /** 397 * Changes the session title or other customizable aspects of the terminal 398 * emulation display. For a list of what may be changed see the 399 * Emulation::titleChanged() signal. 400 */ 401 void setUserTitle( int, const QString & caption ); 402 403 signals: 404 405 /** Emitted when the terminal process starts. */ 406 void started(); 407 408 /** 409 * Emitted when the terminal process exits. 410 */ 411 void finished(); 412 413 /** 414 * Emitted when output is received from the terminal process. 415 */ 416 void receivedData( const QString & text ); 417 418 /** Emitted when the session's title has changed. */ 419 void titleChanged(); 420 421 /** Emitted when the session's profile has changed. */ 422 void profileChanged(const QString & profile); 423 424 /** 425 * Emitted when the activity state of this session changes. 426 * 427 * \param state The new state of the session. This may be one 428 * of NOTIFYNORMAL, NOTIFYSILENCE or NOTIFYACTIVITY 429 */ 430 void stateChanged(int state); 431 432 /** Emitted when a bell event occurs in the session. */ 433 void bellRequest( const QString & message ); 434 435 /** 436 * Requests that the color the text for any tabs associated with 437 * this session should be changed; 438 * 439 * TODO: Document what the parameter does 440 */ 441 void changeTabTextColorRequest(int); 442 443 /** 444 * Requests that the background color of views on this session 445 * should be changed. 446 */ 447 void changeBackgroundColorRequest(const QColor &); 448 449 /** TODO: Document me. */ 450 void openUrlRequest(const QString & url); 451 452 /** TODO: Document me. */ 453 // void zmodemDetected(); 454 455 /** 456 * Emitted when the terminal process requests a change 457 * in the size of the terminal window. 458 * 459 * \param size The requested window size in terms of lines and columns. 460 */ 461 void resizeRequest(const QSize & size); 462 463 /** 464 * Emitted when a profile change command is received from the terminal. 465 * 466 * \param text The text of the command. This is a string of the form 467 * "PropertyName=Value;PropertyName=Value ..." 468 */ 469 void profileChangeCommandReceived(const QString & text); 470 471 /** 472 * Emitted when the flow control state changes. 473 * 474 * \param enabled True if flow control is enabled or false otherwise. 475 */ 476 void flowControlEnabledChanged(bool enabled); 477 478 void silence(); 479 void activity(); 480 481 private slots: 482 void done(int, QProcess::ExitStatus ); 483 484 // void fireZModemDetected(); 485 486 void onReceiveBlock( const char * buffer, int len ); 487 void monitorTimerDone(); 488 489 void onViewSizeChange(int height, int width); 490 void onEmulationSizeChange(int lines , int columns); 491 492 void activityStateSet(int); 493 494 //automatically detach views from sessions when view is destroyed 495 void viewDestroyed(QObject * view); 496 497 // void zmodemReadStatus(); 498 // void zmodemReadAndSendBlock(); 499 // void zmodemRcvBlock(const char *data, int len); 500 // void zmodemFinished(); 501 502 private: 503 504 void updateTerminalSize(); 505 WId windowId() const; 506 507 int _uniqueIdentifier; 508 509 Pty *_shellProcess; 510 Emulation * _emulation; 511 512 QList<TerminalDisplay *> _views; 513 514 bool _monitorActivity; 515 bool _monitorSilence; 516 bool _notifiedActivity; 517 bool _masterMode; 518 bool _autoClose; 519 bool _wantedClose; 520 QTimer * _monitorTimer; 521 522 int _silenceSeconds; 523 524 QString _nameTitle; 525 QString _displayTitle; 526 QString _userTitle; 527 528 QString _localTabTitleFormat; 529 QString _remoteTabTitleFormat; 530 531 QString _iconName; 532 QString _iconText; // as set by: echo -en '\033]1;IconText\007 533 bool _addToUtmp; 534 bool _flowControl; 535 bool _fullScripting; 536 537 QString _program; 538 QStringList _arguments; 539 540 QStringList _environment; 541 int _sessionId; 542 543 QString _initialWorkingDir; 544 545 // ZModem 546 // bool _zmodemBusy; 547 // KProcess* _zmodemProc; 548 // ZModemDialog* _zmodemProgress; 549 550 // Color/Font Changes by ESC Sequences 551 552 QColor _modifiedBackground; // as set by: echo -en '\033]11;Color\007 553 554 QString _profileKey; 555 556 bool _hasDarkBackground; 557 558 static int lastSessionId; 559 560 int ptySlaveFd; 561 562 }; 563 564 /** 565 * Provides a group of sessions which is divided into master and slave sessions. 566 * Activity in master sessions can be propagated to all sessions within the group. 567 * The type of activity which is propagated and method of propagation is controlled 568 * by the masterMode() flags. 569 */ 570 class SessionGroup : public QObject { 571 Q_OBJECT 572 573 public: 574 /** Constructs an empty session group. */ 575 SessionGroup(); 576 /** Destroys the session group and removes all connections between master and slave sessions. */ 577 ~SessionGroup() override; 578 579 /** Adds a session to the group. */ 580 void addSession( Session * session ); 581 /** Removes a session from the group. */ 582 void removeSession( Session * session ); 583 584 /** Returns the list of sessions currently in the group. */ 585 QList<Session *> sessions() const; 586 587 /** 588 * Sets whether a particular session is a master within the group. 589 * Changes or activity in the group's master sessions may be propagated 590 * to all the sessions in the group, depending on the current masterMode() 591 * 592 * \param session The session whoose master status should be changed. 593 * \param master True to make this session a master or false otherwise 594 */ 595 void setMasterStatus( Session * session , bool master ); 596 /** Returns the master status of a session. See setMasterStatus() */ 597 bool masterStatus( Session * session ) const; 598 599 /** 600 * This enum describes the options for propagating certain activity or 601 * changes in the group's master sessions to all sessions in the group. 602 */ 603 enum MasterMode { 604 /** 605 * Any input key presses in the master sessions are sent to all 606 * sessions in the group. 607 */ 608 CopyInputToAll = 1 609 }; 610 611 /** 612 * Specifies which activity in the group's master sessions is propagated 613 * to all sessions in the group. 614 * 615 * \param mode A bitwise OR of MasterMode flags. 616 */ 617 void setMasterMode( int mode ); 618 /** 619 * Returns a bitwise OR of the active MasterMode flags for this group. 620 * See setMasterMode() 621 */ 622 int masterMode() const; 623 624 private: 625 void connectPair(Session * master , Session * other); 626 void disconnectPair(Session * master , Session * other); 627 void connectAll(bool connect); 628 QList<Session *> masters() const; 629 630 // maps sessions to their master status 631 QHash<Session *,bool> _sessions; 632 633 int _masterMode; 634 }; 635 636 } 637 638 #endif 639