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