commit 45157b354d2ced651a52c8759bc0c7d84423c700 Author: ramon Date: Mon Oct 19 09:47:15 2009 +0000 Resstructuración de trunk. git-svn-id: https://opengnsys.es/svn/trunk@390 a21b9725-9963-47de-94b9-378ad31fedc9 diff --git a/qtermwidget/AUTHORS b/qtermwidget/AUTHORS new file mode 100644 index 0000000..bfa5fa3 --- /dev/null +++ b/qtermwidget/AUTHORS @@ -0,0 +1 @@ +e_k@users.sourceforge.net \ No newline at end of file diff --git a/qtermwidget/COPYING b/qtermwidget/COPYING new file mode 100644 index 0000000..5b6e7c6 --- /dev/null +++ b/qtermwidget/COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/qtermwidget/README b/qtermwidget/README new file mode 100644 index 0000000..5d7c147 --- /dev/null +++ b/qtermwidget/README @@ -0,0 +1,28 @@ +This is a external source gotten it from: + +http://www.qt-apps.org/content/show.php/QTermWidget?content=82832 + +Only library and headers needed. Compile with QtEmbedded-4.5.1. + +********************************************************************************** +QTermWidget +version 0.1.0 + +QTermWidget is an opensource project based on KDE4 Konsole application. +The main goal of this project is to provide unicode-enabled, embeddable +QT widget for using as a built-in console (or terminal emulation widget). + +Of course I`m aware about embedding abilities of original Konsole, +but once I had Qt without KDE, and it was a serious obstacle. +I decided not to rely on a chance. I cannot find any interesting related project, +so I had to write it. + +The original Konsole`s code was rewritten entirely with QT4 only; also I have to +include in the project some parts of code from kde core library. All code dealing +with user interface parts and session managers was removed (maybe later I bring it +back somehow), and the result is quite useful, I suppose. + +This library was compiled and tested on three linux systems, +based on 2.4.32, 2.6.20, 2.6.23 kernels, x86 and amd64. +Please inform about its behaviour on other systems. + diff --git a/qtermwidget/includes/BlockArray.h b/qtermwidget/includes/BlockArray.h new file mode 100644 index 0000000..ca47388 --- /dev/null +++ b/qtermwidget/includes/BlockArray.h @@ -0,0 +1,125 @@ +/* + This file is part of Konsole, an X terminal. + Copyright (C) 2000 by Stephan Kulow + + Rewritten for QT4 by e_k , Copyright (C)2008 + + 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. +*/ + +#ifndef BLOCKARRAY_H +#define BLOCKARRAY_H + +#include + +//#error Do not use in KDE 2.1 + +#define BlockSize (1 << 12) +#define ENTRIES ((BlockSize - sizeof(size_t) ) / sizeof(unsigned char)) + +namespace Konsole +{ + +struct Block { + Block() { size = 0; } + unsigned char data[ENTRIES]; + size_t size; +}; + +// /////////////////////////////////////////////////////// + +class BlockArray { +public: + /** + * Creates a history file for holding + * maximal size blocks. If more blocks + * are requested, then it drops earlier + * added ones. + */ + BlockArray(); + + /// destructor + ~BlockArray(); + + /** + * adds the Block at the end of history. + * This may drop other blocks. + * + * The ownership on the block is transfered. + * An unique index number is returned for accessing + * it later (if not yet dropped then) + * + * Note, that the block may be dropped completely + * if history is turned off. + */ + size_t append(Block *block); + + /** + * gets the block at the index. Function may return + * 0 if the block isn't available any more. + * + * The returned block is strictly readonly as only + * maped in memory - and will be invalid on the next + * operation on this class. + */ + const Block *at(size_t index); + + /** + * reorders blocks as needed. If newsize is null, + * the history is emptied completely. The indices + * returned on append won't change their semantic, + * but they may not be valid after this call. + */ + bool setHistorySize(size_t newsize); + + size_t newBlock(); + + Block *lastBlock() const; + + /** + * Convenient function to set the size in KBytes + * instead of blocks + */ + bool setSize(size_t newsize); + + size_t len() const { return length; } + + bool has(size_t index) const; + + size_t getCurrent() const { return current; } + +private: + void unmap(); + void increaseBuffer(); + void decreaseBuffer(size_t newsize); + + size_t size; + // current always shows to the last inserted block + size_t current; + size_t index; + + Block *lastmap; + size_t lastmap_index; + Block *lastblock; + + int ion; + size_t length; + +}; + +} + +#endif diff --git a/qtermwidget/includes/Character.h b/qtermwidget/includes/Character.h new file mode 100644 index 0000000..0978ce5 --- /dev/null +++ b/qtermwidget/includes/Character.h @@ -0,0 +1,210 @@ +/* + This file is part of Konsole, KDE's terminal. + + Copyright (C) 2007 by Robert Knight + Copyright (C) 1997,1998 by Lars Doelle + + Rewritten for QT4 by e_k , Copyright (C)2008 + + 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. +*/ + +#ifndef CHARACTER_H +#define CHARACTER_H + +// Qt +#include + +// Local +#include "CharacterColor.h" + +namespace Konsole +{ + +typedef unsigned char LineProperty; + +static const int LINE_DEFAULT = 0; +static const int LINE_WRAPPED = (1 << 0); +static const int LINE_DOUBLEWIDTH = (1 << 1); +static const int LINE_DOUBLEHEIGHT = (1 << 2); + +#define DEFAULT_RENDITION 0 +#define RE_BOLD (1 << 0) +#define RE_BLINK (1 << 1) +#define RE_UNDERLINE (1 << 2) +#define RE_REVERSE (1 << 3) // Screen only +#define RE_INTENSIVE (1 << 3) // Widget only +#define RE_CURSOR (1 << 4) +#define RE_EXTENDED_CHAR (1 << 5) + +/** + * A single character in the terminal which consists of a unicode character + * value, foreground and background colors and a set of rendition attributes + * which specify how it should be drawn. + */ +class Character +{ +public: + /** + * Constructs a new character. + * + * @param _c The unicode character value of this character. + * @param _f The foreground color used to draw the character. + * @param _b The color used to draw the character's background. + * @param _r A set of rendition flags which specify how this character is to be drawn. + */ + inline Character(quint16 _c = ' ', + CharacterColor _f = CharacterColor(COLOR_SPACE_DEFAULT,DEFAULT_FORE_COLOR), + CharacterColor _b = CharacterColor(COLOR_SPACE_DEFAULT,DEFAULT_BACK_COLOR), + quint8 _r = DEFAULT_RENDITION) + : character(_c), rendition(_r), foregroundColor(_f), backgroundColor(_b) {} + + union + { + /** The unicode character value for this character. */ + quint16 character; + /** + * Experimental addition which allows a single Character instance to contain more than + * one unicode character. + * + * charSequence is a hash code which can be used to look up the unicode + * character sequence in the ExtendedCharTable used to create the sequence. + */ + quint16 charSequence; + }; + + /** A combination of RENDITION flags which specify options for drawing the character. */ + quint8 rendition; + + /** The foreground color used to draw this character. */ + CharacterColor foregroundColor; + /** The color used to draw this character's background. */ + CharacterColor backgroundColor; + + /** + * Returns true if this character has a transparent background when + * it is drawn with the specified @p palette. + */ + bool isTransparent(const ColorEntry* palette) const; + /** + * Returns true if this character should always be drawn in bold when + * it is drawn with the specified @p palette, independent of whether + * or not the character has the RE_BOLD rendition flag. + */ + bool isBold(const ColorEntry* base) const; + + /** + * Compares two characters and returns true if they have the same unicode character value, + * rendition and colors. + */ + friend bool operator == (const Character& a, const Character& b); + /** + * Compares two characters and returns true if they have different unicode character values, + * renditions or colors. + */ + friend bool operator != (const Character& a, const Character& b); +}; + +inline bool operator == (const Character& a, const Character& b) +{ + return a.character == b.character && + a.rendition == b.rendition && + a.foregroundColor == b.foregroundColor && + a.backgroundColor == b.backgroundColor; +} + +inline bool operator != (const Character& a, const Character& b) +{ + return a.character != b.character || + a.rendition != b.rendition || + a.foregroundColor != b.foregroundColor || + a.backgroundColor != b.backgroundColor; +} + +inline bool Character::isTransparent(const ColorEntry* base) const +{ + return ((backgroundColor._colorSpace == COLOR_SPACE_DEFAULT) && + base[backgroundColor._u+0+(backgroundColor._v?BASE_COLORS:0)].transparent) + || ((backgroundColor._colorSpace == COLOR_SPACE_SYSTEM) && + base[backgroundColor._u+2+(backgroundColor._v?BASE_COLORS:0)].transparent); +} + +inline bool Character::isBold(const ColorEntry* base) const +{ + return ((backgroundColor._colorSpace == COLOR_SPACE_DEFAULT) && + base[backgroundColor._u+0+(backgroundColor._v?BASE_COLORS:0)].bold) + || ((backgroundColor._colorSpace == COLOR_SPACE_SYSTEM) && + base[backgroundColor._u+2+(backgroundColor._v?BASE_COLORS:0)].bold); +} + +extern unsigned short vt100_graphics[32]; + + +/** + * A table which stores sequences of unicode characters, referenced + * by hash keys. The hash key itself is the same size as a unicode + * character ( ushort ) so that it can occupy the same space in + * a structure. + */ +class ExtendedCharTable +{ +public: + /** Constructs a new character table. */ + ExtendedCharTable(); + ~ExtendedCharTable(); + + /** + * Adds a sequences of unicode characters to the table and returns + * a hash code which can be used later to look up the sequence + * using lookupExtendedChar() + * + * If the same sequence already exists in the table, the hash + * of the existing sequence will be returned. + * + * @param unicodePoints An array of unicode character points + * @param length Length of @p unicodePoints + */ + ushort createExtendedChar(ushort* unicodePoints , ushort length); + /** + * Looks up and returns a pointer to a sequence of unicode characters + * which was added to the table using createExtendedChar(). + * + * @param hash The hash key returned by createExtendedChar() + * @param length This variable is set to the length of the + * character sequence. + * + * @return A unicode character sequence of size @p length. + */ + ushort* lookupExtendedChar(ushort hash , ushort& length) const; + + /** The global ExtendedCharTable instance. */ + static ExtendedCharTable instance; +private: + // calculates the hash key of a sequence of unicode points of size 'length' + ushort extendedCharHash(ushort* unicodePoints , ushort length) const; + // tests whether the entry in the table specified by 'hash' matches the + // character sequence 'unicodePoints' of size 'length' + bool extendedCharMatch(ushort hash , ushort* unicodePoints , ushort length) const; + // internal, maps hash keys to character sequence buffers. The first ushort + // in each value is the length of the buffer, followed by the ushorts in the buffer + // themselves. + QHash extendedCharTable; +}; + +} + +#endif // CHARACTER_H + diff --git a/qtermwidget/includes/CharacterColor.h b/qtermwidget/includes/CharacterColor.h new file mode 100644 index 0000000..1b86674 --- /dev/null +++ b/qtermwidget/includes/CharacterColor.h @@ -0,0 +1,301 @@ +/* + This file is part of Konsole, KDE's terminal. + + Copyright (C) 2007 by Robert Knight + Copyright (C) 1997,1998 by Lars Doelle + + Rewritten for QT4 by e_k , Copyright (C)2008 + + 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. +*/ + +#ifndef CHARACTERCOLOR_H +#define CHARACTERCOLOR_H + +// Qt +#include + +namespace Konsole +{ + +/** + * An entry in a terminal display's color palette. + * + * A color palette is an array of 16 ColorEntry instances which map + * system color indexes (from 0 to 15) into actual colors. + * + * Each entry can be set as bold, in which case any text + * drawn using the color should be drawn in bold. + * + * Each entry can also be transparent, in which case the terminal + * display should avoid drawing the background for any characters + * using the entry as a background. + */ +class ColorEntry +{ +public: + /** + * Constructs a new color palette entry. + * + * @param c The color value for this entry. + * @param tr Specifies that the color should be transparent when used as a background color. + * @param b Specifies that text drawn with this color should be bold. + */ + ColorEntry(QColor c, bool tr, bool b) : color(c), transparent(tr), bold(b) {} + + /** + * Constructs a new color palette entry with an undefined color, and + * with the transparent and bold flags set to false. + */ + ColorEntry() : transparent(false), bold(false) {} + + /** + * Sets the color, transparency and boldness of this color to those of @p rhs. + */ + void operator=(const ColorEntry& rhs) + { + color = rhs.color; + transparent = rhs.transparent; + bold = rhs.bold; + } + + /** The color value of this entry for display. */ + QColor color; + + /** + * If true character backgrounds using this color should be transparent. + * This is not applicable when the color is used to render text. + */ + bool transparent; + /** + * If true characters drawn using this color should be bold. + * This is not applicable when the color is used to draw a character's background. + */ + bool bold; +}; + + +// Attributed Character Representations /////////////////////////////// + +// Colors + +#define BASE_COLORS (2+8) +#define INTENSITIES 2 +#define TABLE_COLORS (INTENSITIES*BASE_COLORS) + +#define DEFAULT_FORE_COLOR 0 +#define DEFAULT_BACK_COLOR 1 + +//a standard set of colors using black text on a white background. +//defined in TerminalDisplay.cpp + +static const ColorEntry base_color_table[TABLE_COLORS] = +// The following are almost IBM standard color codes, with some slight +// gamma correction for the dim colors to compensate for bright X screens. +// It contains the 8 ansiterm/xterm colors in 2 intensities. +{ + // Fixme: could add faint colors here, also. + // normal + ColorEntry(QColor(0x00,0x00,0x00), 0, 0 ), ColorEntry( QColor(0xB2,0xB2,0xB2), 1, 0 ), // Dfore, Dback + ColorEntry(QColor(0x00,0x00,0x00), 0, 0 ), ColorEntry( QColor(0xB2,0x18,0x18), 0, 0 ), // Black, Red + ColorEntry(QColor(0x18,0xB2,0x18), 0, 0 ), ColorEntry( QColor(0xB2,0x68,0x18), 0, 0 ), // Green, Yellow + ColorEntry(QColor(0x18,0x18,0xB2), 0, 0 ), ColorEntry( QColor(0xB2,0x18,0xB2), 0, 0 ), // Blue, Magenta + ColorEntry(QColor(0x18,0xB2,0xB2), 0, 0 ), ColorEntry( QColor(0xB2,0xB2,0xB2), 0, 0 ), // Cyan, White + // intensiv + ColorEntry(QColor(0x00,0x00,0x00), 0, 1 ), ColorEntry( QColor(0xFF,0xFF,0xFF), 1, 0 ), + ColorEntry(QColor(0x68,0x68,0x68), 0, 0 ), ColorEntry( QColor(0xFF,0x54,0x54), 0, 0 ), + ColorEntry(QColor(0x54,0xFF,0x54), 0, 0 ), ColorEntry( QColor(0xFF,0xFF,0x54), 0, 0 ), + ColorEntry(QColor(0x54,0x54,0xFF), 0, 0 ), ColorEntry( QColor(0xFF,0x54,0xFF), 0, 0 ), + ColorEntry(QColor(0x54,0xFF,0xFF), 0, 0 ), ColorEntry( QColor(0xFF,0xFF,0xFF), 0, 0 ) +}; + +/* CharacterColor is a union of the various color spaces. + + Assignment is as follows: + + Type - Space - Values + + 0 - Undefined - u: 0, v:0 w:0 + 1 - Default - u: 0..1 v:intense w:0 + 2 - System - u: 0..7 v:intense w:0 + 3 - Index(256) - u: 16..255 v:0 w:0 + 4 - RGB - u: 0..255 v:0..256 w:0..256 + + Default colour space has two separate colours, namely + default foreground and default background colour. +*/ + +#define COLOR_SPACE_UNDEFINED 0 +#define COLOR_SPACE_DEFAULT 1 +#define COLOR_SPACE_SYSTEM 2 +#define COLOR_SPACE_256 3 +#define COLOR_SPACE_RGB 4 + +/** + * Describes the color of a single character in the terminal. + */ +class CharacterColor +{ + friend class Character; + +public: + /** Constructs a new CharacterColor whoose color and color space are undefined. */ + CharacterColor() + : _colorSpace(COLOR_SPACE_UNDEFINED), + _u(0), + _v(0), + _w(0) + {} + + /** + * Constructs a new CharacterColor using the specified @p colorSpace and with + * color value @p co + * + * The meaning of @p co depends on the @p colorSpace used. + * + * TODO : Document how @p co relates to @p colorSpace + * + * TODO : Add documentation about available color spaces. + */ + CharacterColor(quint8 colorSpace, int co) + : _colorSpace(colorSpace), + _u(0), + _v(0), + _w(0) + { + switch (colorSpace) + { + case COLOR_SPACE_DEFAULT: + _u = co & 1; + break; + case COLOR_SPACE_SYSTEM: + _u = co & 7; + _v = (co >> 3) & 1; + break; + case COLOR_SPACE_256: + _u = co & 255; + break; + case COLOR_SPACE_RGB: + _u = co >> 16; + _v = co >> 8; + _w = co; + break; + default: + _colorSpace = COLOR_SPACE_UNDEFINED; + } + } + + /** + * Returns true if this character color entry is valid. + */ + bool isValid() + { + return _colorSpace != COLOR_SPACE_UNDEFINED; + } + + /** + * Toggles the value of this color between a normal system color and the corresponding intensive + * system color. + * + * This is only applicable if the color is using the COLOR_SPACE_DEFAULT or COLOR_SPACE_SYSTEM + * color spaces. + */ + void toggleIntensive(); + + /** + * Returns the color within the specified color @palette + * + * The @p palette is only used if this color is one of the 16 system colors, otherwise + * it is ignored. + */ + QColor color(const ColorEntry* palette) const; + + /** + * Compares two colors and returns true if they represent the same color value and + * use the same color space. + */ + friend bool operator == (const CharacterColor& a, const CharacterColor& b); + /** + * Compares two colors and returns true if they represent different color values + * or use different color spaces. + */ + friend bool operator != (const CharacterColor& a, const CharacterColor& b); + +private: + quint8 _colorSpace; + + // bytes storing the character color + quint8 _u; + quint8 _v; + quint8 _w; +}; + +inline bool operator == (const CharacterColor& a, const CharacterColor& b) +{ + return *reinterpret_cast(&a._colorSpace) == + *reinterpret_cast(&b._colorSpace); +} + +inline bool operator != (const CharacterColor& a, const CharacterColor& b) +{ + return *reinterpret_cast(&a._colorSpace) != + *reinterpret_cast(&b._colorSpace); +} + +inline const QColor color256(quint8 u, const ColorEntry* base) +{ + // 0.. 16: system colors + if (u < 8) return base[u+2 ].color; u -= 8; + if (u < 8) return base[u+2+BASE_COLORS].color; u -= 8; + + // 16..231: 6x6x6 rgb color cube + if (u < 216) return QColor(255*((u/36)%6)/5, + 255*((u/ 6)%6)/5, + 255*((u/ 1)%6)/5); u -= 216; + + // 232..255: gray, leaving out black and white + int gray = u*10+8; return QColor(gray,gray,gray); +} + +inline QColor CharacterColor::color(const ColorEntry* base) const +{ + switch (_colorSpace) + { + case COLOR_SPACE_DEFAULT: return base[_u+0+(_v?BASE_COLORS:0)].color; + case COLOR_SPACE_SYSTEM: return base[_u+2+(_v?BASE_COLORS:0)].color; + case COLOR_SPACE_256: return color256(_u,base); + case COLOR_SPACE_RGB: return QColor(_u,_v,_w); + case COLOR_SPACE_UNDEFINED: return QColor(); + } + + Q_ASSERT(false); // invalid color space + + return QColor(); +} + +inline void CharacterColor::toggleIntensive() +{ + if (_colorSpace == COLOR_SPACE_SYSTEM || _colorSpace == COLOR_SPACE_DEFAULT) + { + _v = !_v; + } +} + + +} + +#endif // CHARACTERCOLOR_H + diff --git a/qtermwidget/includes/ColorTables.h b/qtermwidget/includes/ColorTables.h new file mode 100644 index 0000000..321d6db --- /dev/null +++ b/qtermwidget/includes/ColorTables.h @@ -0,0 +1,58 @@ +#ifndef _COLOR_TABLE_H +#define _COLOR_TABLE_H + +#include "CharacterColor.h" + +using namespace Konsole; + +static const ColorEntry whiteonblack_color_table[TABLE_COLORS] = +{ + // normal + ColorEntry(QColor(0xFF,0xFF,0xFF), 0, 0 ), ColorEntry( QColor(0x00,0x00,0x00), 1, 0 ), // Dfore, Dback + ColorEntry(QColor(0x00,0x00,0x00), 0, 0 ), ColorEntry( QColor(0xB2,0x18,0x18), 0, 0 ), // Black, Red + ColorEntry(QColor(0x18,0xB2,0x18), 0, 0 ), ColorEntry( QColor(0xB2,0x68,0x18), 0, 0 ), // Green, Yellow + ColorEntry(QColor(0x18,0x18,0xB2), 0, 0 ), ColorEntry( QColor(0xB2,0x18,0xB2), 0, 0 ), // Blue, Magenta + ColorEntry(QColor(0x18,0xB2,0xB2), 0, 0 ), ColorEntry( QColor(0xB2,0xB2,0xB2), 0, 0 ), // Cyan, White + // intensiv + ColorEntry(QColor(0x00,0x00,0x00), 0, 1 ), ColorEntry( QColor(0xFF,0xFF,0xFF), 1, 0 ), + ColorEntry(QColor(0x68,0x68,0x68), 0, 0 ), ColorEntry( QColor(0xFF,0x54,0x54), 0, 0 ), + ColorEntry(QColor(0x54,0xFF,0x54), 0, 0 ), ColorEntry( QColor(0xFF,0xFF,0x54), 0, 0 ), + ColorEntry(QColor(0x54,0x54,0xFF), 0, 0 ), ColorEntry( QColor(0xFF,0x54,0xFF), 0, 0 ), + ColorEntry(QColor(0x54,0xFF,0xFF), 0, 0 ), ColorEntry( QColor(0xFF,0xFF,0xFF), 0, 0 ) +}; + +static const ColorEntry greenonblack_color_table[TABLE_COLORS] = +{ + ColorEntry(QColor( 24, 240, 24), 0, 0), ColorEntry(QColor( 0, 0, 0), 1, 0), + ColorEntry(QColor( 0, 0, 0), 0, 0), ColorEntry(QColor( 178, 24, 24), 0, 0), + ColorEntry(QColor( 24, 178, 24), 0, 0), ColorEntry(QColor( 178, 104, 24), 0, 0), + ColorEntry(QColor( 24, 24, 178), 0, 0), ColorEntry(QColor( 178, 24, 178), 0, 0), + ColorEntry(QColor( 24, 178, 178), 0, 0), ColorEntry(QColor( 178, 178, 178), 0, 0), + // intensive colors + ColorEntry(QColor( 24, 240, 24), 0, 1 ), ColorEntry(QColor( 0, 0, 0), 1, 0 ), + ColorEntry(QColor( 104, 104, 104), 0, 0 ), ColorEntry(QColor( 255, 84, 84), 0, 0 ), + ColorEntry(QColor( 84, 255, 84), 0, 0 ), ColorEntry(QColor( 255, 255, 84), 0, 0 ), + ColorEntry(QColor( 84, 84, 255), 0, 0 ), ColorEntry(QColor( 255, 84, 255), 0, 0 ), + ColorEntry(QColor( 84, 255, 255), 0, 0 ), ColorEntry(QColor( 255, 255, 255), 0, 0 ) +}; + +static const ColorEntry blackonlightyellow_color_table[TABLE_COLORS] = +{ + ColorEntry(QColor( 0, 0, 0), 0, 0), ColorEntry(QColor( 255, 255, 221), 1, 0), + ColorEntry(QColor( 0, 0, 0), 0, 0), ColorEntry(QColor( 178, 24, 24), 0, 0), + ColorEntry(QColor( 24, 178, 24), 0, 0), ColorEntry(QColor( 178, 104, 24), 0, 0), + ColorEntry(QColor( 24, 24, 178), 0, 0), ColorEntry(QColor( 178, 24, 178), 0, 0), + ColorEntry(QColor( 24, 178, 178), 0, 0), ColorEntry(QColor( 178, 178, 178), 0, 0), + ColorEntry(QColor( 0, 0, 0), 0, 1), ColorEntry(QColor( 255, 255, 221), 1, 0), + ColorEntry(QColor(104, 104, 104), 0, 0), ColorEntry(QColor( 255, 84, 84), 0, 0), + ColorEntry(QColor( 84, 255, 84), 0, 0), ColorEntry(QColor( 255, 255, 84), 0, 0), + ColorEntry(QColor( 84, 84, 255), 0, 0), ColorEntry(QColor( 255, 84, 255), 0, 0), + ColorEntry(QColor( 84, 255, 255), 0, 0), ColorEntry(QColor( 255, 255, 255), 0, 0) +}; + + + + + +#endif + diff --git a/qtermwidget/includes/DefaultTranslatorText.h b/qtermwidget/includes/DefaultTranslatorText.h new file mode 100644 index 0000000..e47417c --- /dev/null +++ b/qtermwidget/includes/DefaultTranslatorText.h @@ -0,0 +1,2 @@ +"keyboard \"Fallback Key Translator\"\n" +"key Tab : \"\\t\" \0" diff --git a/qtermwidget/includes/Emulation.h b/qtermwidget/includes/Emulation.h new file mode 100644 index 0000000..2782df7 --- /dev/null +++ b/qtermwidget/includes/Emulation.h @@ -0,0 +1,465 @@ +/* + This file is part of Konsole, an X terminal. + + Copyright (C) 2007 by Robert Knight + Copyright (C) 1997,1998 by Lars Doelle + + Rewritten for QT4 by e_k , Copyright (C)2008 + + 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. +*/ + +#ifndef EMULATION_H +#define EMULATION_H + +// System +#include + +// Qt +#include +//#include +#include +#include +#include + + +namespace Konsole +{ + +class KeyboardTranslator; +class HistoryType; +class Screen; +class ScreenWindow; +class TerminalCharacterDecoder; + +/** + * This enum describes the available states which + * the terminal emulation may be set to. + * + * These are the values used by Emulation::stateChanged() + */ +enum +{ + /** The emulation is currently receiving user input. */ + NOTIFYNORMAL=0, + /** + * The terminal program has triggered a bell event + * to get the user's attention. + */ + NOTIFYBELL=1, + /** + * The emulation is currently receiving data from its + * terminal input. + */ + NOTIFYACTIVITY=2, + + // unused here? + NOTIFYSILENCE=3 +}; + +/** + * Base class for terminal emulation back-ends. + * + * The back-end is responsible for decoding an incoming character stream and + * producing an output image of characters. + * + * When input from the terminal is received, the receiveData() slot should be called with + * the data which has arrived. The emulation will process the data and update the + * screen image accordingly. The codec used to decode the incoming character stream + * into the unicode characters used internally can be specified using setCodec() + * + * The size of the screen image can be specified by calling setImageSize() with the + * desired number of lines and columns. When new lines are added, old content + * is moved into a history store, which can be set by calling setHistory(). + * + * The screen image can be accessed by creating a ScreenWindow onto this emulation + * by calling createWindow(). Screen windows provide access to a section of the + * output. Each screen window covers the same number of lines and columns as the + * image size returned by imageSize(). The screen window can be moved up and down + * and provides transparent access to both the current on-screen image and the + * previous output. The screen windows emit an outputChanged signal + * when the section of the image they are looking at changes. + * Graphical views can then render the contents of a screen window, listening for notifications + * of output changes from the screen window which they are associated with and updating + * accordingly. + * + * The emulation also is also responsible for converting input from the connected views such + * as keypresses and mouse activity into a character string which can be sent + * to the terminal program. Key presses can be processed by calling the sendKeyEvent() slot, + * while mouse events can be processed using the sendMouseEvent() slot. When the character + * stream has been produced, the emulation will emit a sendData() signal with a pointer + * to the character buffer. This data should be fed to the standard input of the terminal + * process. The translation of key presses into an output character stream is performed + * using a lookup in a set of key bindings which map key sequences to output + * character sequences. The name of the key bindings set used can be specified using + * setKeyBindings() + * + * The emulation maintains certain state information which changes depending on the + * input received. The emulation can be reset back to its starting state by calling + * reset(). + * + * The emulation also maintains an activity state, which specifies whether + * terminal is currently active ( when data is received ), normal + * ( when the terminal is idle or receiving user input ) or trying + * to alert the user ( also known as a "Bell" event ). The stateSet() signal + * is emitted whenever the activity state is set. This can be used to determine + * how long the emulation has been active/idle for and also respond to + * a 'bell' event in different ways. + */ +class Emulation : public QObject +{ +Q_OBJECT + +public: + + /** Constructs a new terminal emulation */ + Emulation(); + ~Emulation(); + + /** + * Creates a new window onto the output from this emulation. The contents + * of the window are then rendered by views which are set to use this window using the + * TerminalDisplay::setScreenWindow() method. + */ + ScreenWindow* createWindow(); + + /** Returns the size of the screen image which the emulation produces */ + QSize imageSize(); + + /** + * Returns the total number of lines, including those stored in the history. + */ + int lineCount(); + + + /** + * Sets the history store used by this emulation. When new lines + * are added to the output, older lines at the top of the screen are transferred to a history + * store. + * + * The number of lines which are kept and the storage location depend on the + * type of store. + */ + void setHistory(const HistoryType&); + /** Returns the history store used by this emulation. See setHistory() */ + const HistoryType& history(); + /** Clears the history scroll. */ + void clearHistory(); + + /** + * Copies the output history from @p startLine to @p endLine + * into @p stream, using @p decoder to convert the terminal + * characters into text. + * + * @param decoder A decoder which converts lines of terminal characters with + * appearance attributes into output text. PlainTextDecoder is the most commonly + * used decoder. + * @param startLine The first + */ + virtual void writeToStream(TerminalCharacterDecoder* decoder,int startLine,int endLine); + + + /** Returns the codec used to decode incoming characters. See setCodec() */ + const QTextCodec* codec() { return _codec; } + /** Sets the codec used to decode incoming characters. */ + void setCodec(const QTextCodec*); + + /** + * Convenience method. + * Returns true if the current codec used to decode incoming + * characters is UTF-8 + */ + bool utf8() { Q_ASSERT(_codec); return _codec->mibEnum() == 106; } + + + /** TODO Document me */ + virtual char getErase() const; + + /** + * Sets the key bindings used to key events + * ( received through sendKeyEvent() ) into character + * streams to send to the terminal. + */ + void setKeyBindings(const QString& name); + /** + * Returns the name of the emulation's current key bindings. + * See setKeyBindings() + */ + QString keyBindings(); + + /** + * Copies the current image into the history and clears the screen. + */ + virtual void clearEntireScreen() =0; + + /** Resets the state of the terminal. */ + virtual void reset() =0; + + /** + * Returns true if the active terminal program wants + * mouse input events. + * + * The programUsesMouseChanged() signal is emitted when this + * changes. + */ + bool programUsesMouse() const; + +public slots: + + /** Change the size of the emulation's image */ + virtual void setImageSize(int lines, int columns); + + /** + * Interprets a sequence of characters and sends the result to the terminal. + * This is equivalent to calling sendKeyEvent() for each character in @p text in succession. + */ + virtual void sendText(const QString& text) = 0; + + /** + * Interprets a key press event and emits the sendData() signal with + * the resulting character stream. + */ + virtual void sendKeyEvent(QKeyEvent*); + + /** + * Converts information about a mouse event into an xterm-compatible escape + * sequence and emits the character sequence via sendData() + */ + virtual void sendMouseEvent(int buttons, int column, int line, int eventType); + + /** + * Sends a string of characters to the foreground terminal process. + * + * @param string The characters to send. + * @param length Length of @p string or if set to a negative value, @p string will + * be treated as a null-terminated string and its length will be determined automatically. + */ + virtual void sendString(const char* string, int length = -1) = 0; + + /** + * Processes an incoming stream of characters. receiveData() decodes the incoming + * character buffer using the current codec(), and then calls receiveChar() for + * each unicode character in the resulting buffer. + * + * receiveData() also starts a timer which causes the outputChanged() signal + * to be emitted when it expires. The timer allows multiple updates in quick + * succession to be buffered into a single outputChanged() signal emission. + * + * @param buffer A string of characters received from the terminal program. + * @param len The length of @p buffer + */ + void receiveData(const char* buffer,int len); + +signals: + + /** + * Emitted when a buffer of data is ready to send to the + * standard input of the terminal. + * + * @param data The buffer of data ready to be sent + * @paran len The length of @p data in bytes + */ + void sendData(const char* data,int len); + + /** + * Requests that sending of input to the emulation + * from the terminal process be suspended or resumed. + * + * @param suspend If true, requests that sending of + * input from the terminal process' stdout be + * suspended. Otherwise requests that sending of + * input be resumed. + */ + void lockPtyRequest(bool suspend); + + /** + * Requests that the pty used by the terminal process + * be set to UTF 8 mode. + * + * TODO: More documentation + */ + void useUtf8Request(bool); + + /** + * Emitted when the activity state of the emulation is set. + * + * @param state The new activity state, one of NOTIFYNORMAL, NOTIFYACTIVITY + * or NOTIFYBELL + */ + void stateSet(int state); + + /** TODO Document me */ + void zmodemDetected(); + + + /** + * Requests that the color of the text used + * to represent the tabs associated with this + * emulation be changed. This is a Konsole-specific + * extension from pre-KDE 4 times. + * + * TODO: Document how the parameter works. + */ + void changeTabTextColorRequest(int color); + + /** + * This is emitted when the program running in the shell indicates whether or + * not it is interested in mouse events. + * + * @param usesMouse This will be true if the program wants to be informed about + * mouse events or false otherwise. + */ + void programUsesMouseChanged(bool usesMouse); + + /** + * Emitted when the contents of the screen image change. + * The emulation buffers the updates from successive image changes, + * and only emits outputChanged() at sensible intervals when + * there is a lot of terminal activity. + * + * Normally there is no need for objects other than the screen windows + * created with createWindow() to listen for this signal. + * + * ScreenWindow objects created using createWindow() will emit their + * own outputChanged() signal in response to this signal. + */ + void outputChanged(); + + /** + * Emitted when the program running in the terminal wishes to update the + * session's title. This also allows terminal programs to customize other + * aspects of the terminal emulation display. + * + * This signal is emitted when the escape sequence "\033]ARG;VALUE\007" + * is received in the input string, where ARG is a number specifying what + * should change and VALUE is a string specifying the new value. + * + * TODO: The name of this method is not very accurate since this method + * is used to perform a whole range of tasks besides just setting + * the user-title of the session. + * + * @param title Specifies what to change. + *
    + *
  • 0 - Set window icon text and session title to @p newTitle
  • + *
  • 1 - Set window icon text to @p newTitle
  • + *
  • 2 - Set session title to @p newTitle
  • + *
  • 11 - Set the session's default background color to @p newTitle, + * where @p newTitle can be an HTML-style string (#RRGGBB) or a named + * color (eg 'red', 'blue'). + * See http://doc.trolltech.com/4.2/qcolor.html#setNamedColor for more + * details. + *
  • + *
  • 31 - Supposedly treats @p newTitle as a URL and opens it (NOT IMPLEMENTED)
  • + *
  • 32 - Sets the icon associated with the session. @p newTitle is the name + * of the icon to use, which can be the name of any icon in the current KDE icon + * theme (eg: 'konsole', 'kate', 'folder_home')
  • + *
+ * @param newTitle Specifies the new title + */ + + void titleChanged(int title,const QString& newTitle); + + /** + * Emitted when the program running in the terminal changes the + * screen size. + */ + void imageSizeChanged(int lineCount , int columnCount); + + /** + * Emitted when the terminal program requests to change various properties + * of the terminal display. + * + * A profile change command occurs when a special escape sequence, followed + * by a string containing a series of name and value pairs is received. + * This string can be parsed using a ProfileCommandParser instance. + * + * @param text A string expected to contain a series of key and value pairs in + * the form: name=value;name2=value2 ... + */ + void profileChangeCommandReceived(const QString& text); + +protected: + virtual void setMode (int mode) = 0; + virtual void resetMode(int mode) = 0; + + /** + * Processes an incoming character. See receiveData() + * @p ch A unicode character code. + */ + virtual void receiveChar(int ch); + + /** + * Sets the active screen. The terminal has two screens, primary and alternate. + * The primary screen is used by default. When certain interactive programs such + * as Vim are run, they trigger a switch to the alternate screen. + * + * @param index 0 to switch to the primary screen, or 1 to switch to the alternate screen + */ + void setScreen(int index); + + enum EmulationCodec + { + LocaleCodec = 0, + Utf8Codec = 1 + }; + void setCodec(EmulationCodec codec); // codec number, 0 = locale, 1=utf8 + + + QList _windows; + + Screen* _currentScreen; // pointer to the screen which is currently active, + // this is one of the elements in the screen[] array + + Screen* _screen[2]; // 0 = primary screen ( used by most programs, including the shell + // scrollbars are enabled in this mode ) + // 1 = alternate ( used by vi , emacs etc. + // scrollbars are not enabled in this mode ) + + + //decodes an incoming C-style character stream into a unicode QString using + //the current text codec. (this allows for rendering of non-ASCII characters in text files etc.) + const QTextCodec* _codec; + QTextDecoder* _decoder; + + const KeyboardTranslator* _keyTranslator; // the keyboard layout + +protected slots: + /** + * Schedules an update of attached views. + * Repeated calls to bufferedUpdate() in close succession will result in only a single update, + * much like the Qt buffered update of widgets. + */ + void bufferedUpdate(); + +private slots: + + // triggered by timer, causes the emulation to send an updated screen image to each + // view + void showBulk(); + + void usesMouseChanged(bool usesMouse); + +private: + + bool _usesMouse; + QTimer _bulkTimer1; + QTimer _bulkTimer2; + +}; + +} + +#endif // ifndef EMULATION_H diff --git a/qtermwidget/includes/ExtendedDefaultTranslator.h b/qtermwidget/includes/ExtendedDefaultTranslator.h new file mode 100644 index 0000000..6403c72 --- /dev/null +++ b/qtermwidget/includes/ExtendedDefaultTranslator.h @@ -0,0 +1,74 @@ +"keyboard \"Default (XFree 4)\"" +"key Escape : \"\\E\"" +"key Tab -Shift : \"\\t\"\n" +"key Tab +Shift+Ansi : \"\\E[Z\"\n" +"key Tab +Shift-Ansi : \"\\t\"\n" +"key Backtab +Ansi : \"\\E[Z\"\n" +"key Backtab -Ansi : \"\\t\"\n" +"key Return-Shift-NewLine : \"\\r\"\n" +"key Return-Shift+NewLine : \"\\r\\n\"\n" +"key Return+Shift : \"\\EOM\"\n" +"key Backspace : \"\\x7f\"\n" +"key Up -Shift-Ansi : \"\\EA\"\n" +"key Down -Shift-Ansi : \"\\EB\"\n" +"key Right-Shift-Ansi : \"\\EC\"\n" +"key Left -Shift-Ansi : \"\\ED\"\n" +"key Up -Shift-AnyMod+Ansi+AppCuKeys : \"\\EOA\"\n" +"key Down -Shift-AnyMod+Ansi+AppCuKeys : \"\\EOB\"\n" +"key Right -Shift-AnyMod+Ansi+AppCuKeys : \"\\EOC\"\n" +"key Left -Shift-AnyMod+Ansi+AppCuKeys : \"\\EOD\"\n" +"key Up -Shift-AnyMod+Ansi-AppCuKeys : \"\\E[A\"\n" +"key Down -Shift-AnyMod+Ansi-AppCuKeys : \"\\E[B\"\n" +"key Right -Shift-AnyMod+Ansi-AppCuKeys : \"\\E[C\"\n" +"key Left -Shift-AnyMod+Ansi-AppCuKeys : \"\\E[D\"\n" +"key Up -Shift+AnyMod+Ansi : \"\\E[1;*A\"\n" +"key Down -Shift+AnyMod+Ansi : \"\\E[1;*B\"\n" +"key Right -Shift+AnyMod+Ansi : \"\\E[1;*C\"\n" +"key Left -Shift+AnyMod+Ansi : \"\\E[1;*D\"\n" +"key Enter+NewLine : \"\\r\\n\"\n" +"key Enter-NewLine : \"\\r\"\n" +"key Home -AnyMod -AppCuKeys : \"\\E[H\" \n" +"key End -AnyMod -AppCuKeys : \"\\E[F\" \n" +"key Home -AnyMod +AppCuKeys : \"\\EOH\" \n" +"key End -AnyMod +AppCuKeys : \"\\EOF\" \n" +"key Home +AnyMod : \"\\E[1;*H\"\n" +"key End +AnyMod : \"\\E[1;*F\"\n" +"key Insert -AnyMod : \"\\E[2~\"\n" +"key Delete -AnyMod : \"\\E[3~\"\n" +"key Insert +AnyMod : \"\\E[2;*~\"\n" +"key Delete +AnyMod : \"\\E[3;*~\"\n" +"key Prior -Shift-AnyMod : \"\\E[5~\"\n" +"key Next -Shift-AnyMod : \"\\E[6~\"\n" +"key Prior -Shift+AnyMod : \"\\E[5;*~\"\n" +"key Next -Shift+AnyMod : \"\\E[6;*~\"\n" +"key F1 -AnyMod : \"\\EOP\"\n" +"key F2 -AnyMod : \"\\EOQ\"\n" +"key F3 -AnyMod : \"\\EOR\"\n" +"key F4 -AnyMod : \"\\EOS\"\n" +"key F5 -AnyMod : \"\\E[15~\"\n" +"key F6 -AnyMod : \"\\E[17~\"\n" +"key F7 -AnyMod : \"\\E[18~\"\n" +"key F8 -AnyMod : \"\\E[19~\"\n" +"key F9 -AnyMod : \"\\E[20~\"\n" +"key F10 -AnyMod : \"\\E[21~\"\n" +"key F11 -AnyMod : \"\\E[23~\"\n" +"key F12 -AnyMod : \"\\E[24~\"\n" +"key F1 +AnyMod : \"\\EO*P\"\n" +"key F2 +AnyMod : \"\\EO*Q\"\n" +"key F3 +AnyMod : \"\\EO*R\"\n" +"key F4 +AnyMod : \"\\EO*S\"\n" +"key F5 +AnyMod : \"\\E[15;*~\"\n" +"key F6 +AnyMod : \"\\E[17;*~\"\n" +"key F7 +AnyMod : \"\\E[18;*~\"\n" +"key F8 +AnyMod : \"\\E[19;*~\"\n" +"key F9 +AnyMod : \"\\E[20;*~\"\n" +"key F10 +AnyMod : \"\\E[21;*~\"\n" +"key F11 +AnyMod : \"\\E[23;*~\"\n" +"key F12 +AnyMod : \"\\E[24;*~\"\n" +"key Space +Control : \"\\x00\"\n" +"key Up +Shift-AppScreen : scrollLineUp\n" +"key Prior +Shift-AppScreen : scrollPageUp\n" +"key Down +Shift-AppScreen : scrollLineDown\n" +"key Next +Shift-AppScreen : scrollPageDown\n" +"key ScrollLock : scrollLock\n" +"\0" diff --git a/qtermwidget/includes/Filter.h b/qtermwidget/includes/Filter.h new file mode 100644 index 0000000..06ea5e3 --- /dev/null +++ b/qtermwidget/includes/Filter.h @@ -0,0 +1,383 @@ +/* + Copyright (C) 2007 by Robert Knight + + Rewritten for QT4 by e_k , Copyright (C)2008 + + 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. +*/ + +#ifndef FILTER_H +#define FILTER_H + +// Qt +#include +#include +#include +#include +#include +#include + +// Local +#include "Character.h" + +namespace Konsole +{ + +/** + * A filter processes blocks of text looking for certain patterns (such as URLs or keywords from a list) + * and marks the areas which match the filter's patterns as 'hotspots'. + * + * Each hotspot has a type identifier associated with it ( such as a link or a highlighted section ), + * and an action. When the user performs some activity such as a mouse-click in a hotspot area ( the exact + * action will depend on what is displaying the block of text which the filter is processing ), the hotspot's + * activate() method should be called. Depending on the type of hotspot this will trigger a suitable response. + * + * For example, if a hotspot represents a URL then a suitable action would be opening that URL in a web browser. + * Hotspots may have more than one action, in which case the list of actions can be obtained using the + * actions() method. + * + * Different subclasses of filter will return different types of hotspot. + * Subclasses must reimplement the process() method to examine a block of text and identify sections of interest. + * When processing the text they should create instances of Filter::HotSpot subclasses for sections of interest + * and add them to the filter's list of hotspots using addHotSpot() + */ +class Filter +{ +public: + /** + * Represents an area of text which matched the pattern a particular filter has been looking for. + * + * Each hotspot has a type identifier associated with it ( such as a link or a highlighted section ), + * and an action. When the user performs some activity such as a mouse-click in a hotspot area ( the exact + * action will depend on what is displaying the block of text which the filter is processing ), the hotspot's + * activate() method should be called. Depending on the type of hotspot this will trigger a suitable response. + * + * For example, if a hotspot represents a URL then a suitable action would be opening that URL in a web browser. + * Hotspots may have more than one action, in which case the list of actions can be obtained using the + * actions() method. These actions may then be displayed in a popup menu or toolbar for example. + */ + class HotSpot + { + public: + /** + * Constructs a new hotspot which covers the area from (@p startLine,@p startColumn) to (@p endLine,@p endColumn) + * in a block of text. + */ + HotSpot(int startLine , int startColumn , int endLine , int endColumn); + virtual ~HotSpot(); + + enum Type + { + // the type of the hotspot is not specified + NotSpecified, + // this hotspot represents a clickable link + Link, + // this hotspot represents a marker + Marker + }; + + /** Returns the line when the hotspot area starts */ + int startLine() const; + /** Returns the line where the hotspot area ends */ + int endLine() const; + /** Returns the column on startLine() where the hotspot area starts */ + int startColumn() const; + /** Returns the column on endLine() where the hotspot area ends */ + int endColumn() const; + /** + * Returns the type of the hotspot. This is usually used as a hint for views on how to represent + * the hotspot graphically. eg. Link hotspots are typically underlined when the user mouses over them + */ + Type type() const; + /** + * Causes the an action associated with a hotspot to be triggered. + * + * @param object The object which caused the hotspot to be triggered. This is + * typically null ( in which case the default action should be performed ) or + * one of the objects from the actions() list. In which case the associated + * action should be performed. + */ + virtual void activate(QObject* object = 0) = 0; + /** + * Returns a list of actions associated with the hotspot which can be used in a + * menu or toolbar + */ + virtual QList actions(); + + /** + * Returns the text of a tooltip to be shown when the mouse moves over the hotspot, or + * an empty string if there is no tooltip associated with this hotspot. + * + * The default implementation returns an empty string. + */ + virtual QString tooltip() const; + + protected: + /** Sets the type of a hotspot. This should only be set once */ + void setType(Type type); + + private: + int _startLine; + int _startColumn; + int _endLine; + int _endColumn; + Type _type; + + }; + + /** Constructs a new filter. */ + Filter(); + virtual ~Filter(); + + /** Causes the filter to process the block of text currently in its internal buffer */ + virtual void process() = 0; + + /** + * Empties the filters internal buffer and resets the line count back to 0. + * All hotspots are deleted. + */ + void reset(); + + /** Adds a new line of text to the filter and increments the line count */ + //void addLine(const QString& string); + + /** Returns the hotspot which covers the given @p line and @p column, or 0 if no hotspot covers that area */ + HotSpot* hotSpotAt(int line , int column) const; + + /** Returns the list of hotspots identified by the filter */ + QList hotSpots() const; + + /** Returns the list of hotspots identified by the filter which occur on a given line */ + QList hotSpotsAtLine(int line) const; + + /** + * TODO: Document me + */ + void setBuffer(const QString* buffer , const QList* linePositions); + +protected: + /** Adds a new hotspot to the list */ + void addHotSpot(HotSpot*); + /** Returns the internal buffer */ + const QString* buffer(); + /** Converts a character position within buffer() to a line and column */ + void getLineColumn(int position , int& startLine , int& startColumn); + +private: + QMultiHash _hotspots; + QList _hotspotList; + + const QList* _linePositions; + const QString* _buffer; +}; + +/** + * A filter which searches for sections of text matching a regular expression and creates a new RegExpFilter::HotSpot + * instance for them. + * + * Subclasses can reimplement newHotSpot() to return custom hotspot types when matches for the regular expression + * are found. + */ +class RegExpFilter : public Filter +{ +public: + /** + * Type of hotspot created by RegExpFilter. The capturedTexts() method can be used to find the text + * matched by the filter's regular expression. + */ + class HotSpot : public Filter::HotSpot + { + public: + HotSpot(int startLine, int startColumn, int endLine , int endColumn); + virtual void activate(QObject* object = 0); + + /** Sets the captured texts associated with this hotspot */ + void setCapturedTexts(const QStringList& texts); + /** Returns the texts found by the filter when matching the filter's regular expression */ + QStringList capturedTexts() const; + private: + QStringList _capturedTexts; + }; + + /** Constructs a new regular expression filter */ + RegExpFilter(); + + /** + * Sets the regular expression which the filter searches for in blocks of text. + * + * Regular expressions which match the empty string are treated as not matching + * anything. + */ + void setRegExp(const QRegExp& text); + /** Returns the regular expression which the filter searches for in blocks of text */ + QRegExp regExp() const; + + /** + * Reimplemented to search the filter's text buffer for text matching regExp() + * + * If regexp matches the empty string, then process() will return immediately + * without finding results. + */ + virtual void process(); + +protected: + /** + * Called when a match for the regular expression is encountered. Subclasses should reimplement this + * to return custom hotspot types + */ + virtual RegExpFilter::HotSpot* newHotSpot(int startLine,int startColumn, + int endLine,int endColumn); + +private: + QRegExp _searchText; +}; + +class FilterObject; + +/** A filter which matches URLs in blocks of text */ +class UrlFilter : public RegExpFilter +{ +public: + /** + * Hotspot type created by UrlFilter instances. The activate() method opens a web browser + * at the given URL when called. + */ + class HotSpot : public RegExpFilter::HotSpot + { + public: + HotSpot(int startLine,int startColumn,int endLine,int endColumn); + virtual ~HotSpot(); + + virtual QList actions(); + + /** + * Open a web browser at the current URL. The url itself can be determined using + * the capturedTexts() method. + */ + virtual void activate(QObject* object = 0); + + virtual QString tooltip() const; + private: + enum UrlType + { + StandardUrl, + Email, + Unknown + }; + UrlType urlType() const; + + FilterObject* _urlObject; + }; + + UrlFilter(); + +protected: + virtual RegExpFilter::HotSpot* newHotSpot(int,int,int,int); + +private: + + static const QRegExp FullUrlRegExp; + static const QRegExp EmailAddressRegExp; + + // combined OR of FullUrlRegExp and EmailAddressRegExp + static const QRegExp CompleteUrlRegExp; +}; + +class FilterObject : public QObject +{ +Q_OBJECT +public: + FilterObject(Filter::HotSpot* filter) : _filter(filter) {} +private slots: + void activated(); +private: + Filter::HotSpot* _filter; +}; + +/** + * A chain which allows a group of filters to be processed as one. + * The chain owns the filters added to it and deletes them when the chain itself is destroyed. + * + * Use addFilter() to add a new filter to the chain. + * When new text to be filtered arrives, use addLine() to add each additional + * line of text which needs to be processed and then after adding the last line, use + * process() to cause each filter in the chain to process the text. + * + * After processing a block of text, the reset() method can be used to set the filter chain's + * internal cursor back to the first line. + * + * The hotSpotAt() method will return the first hotspot which covers a given position. + * + * The hotSpots() and hotSpotsAtLine() method return all of the hotspots in the text and on + * a given line respectively. + */ +class FilterChain : protected QList +{ +public: + virtual ~FilterChain(); + + /** Adds a new filter to the chain. The chain will delete this filter when it is destroyed */ + void addFilter(Filter* filter); + /** Removes a filter from the chain. The chain will no longer delete the filter when destroyed */ + void removeFilter(Filter* filter); + /** Returns true if the chain contains @p filter */ + bool containsFilter(Filter* filter); + /** Removes all filters from the chain */ + void clear(); + + /** Resets each filter in the chain */ + void reset(); + /** + * Processes each filter in the chain + */ + void process(); + + /** Sets the buffer for each filter in the chain to process. */ + void setBuffer(const QString* buffer , const QList* linePositions); + + /** Returns the first hotspot which occurs at @p line, @p column or 0 if no hotspot was found */ + Filter::HotSpot* hotSpotAt(int line , int column) const; + /** Returns a list of all the hotspots in all the chain's filters */ + QList hotSpots() const; + /** Returns a list of all hotspots at the given line in all the chain's filters */ + QList hotSpotsAtLine(int line) const; + +}; + +/** A filter chain which processes character images from terminal displays */ +class TerminalImageFilterChain : public FilterChain +{ +public: + TerminalImageFilterChain(); + virtual ~TerminalImageFilterChain(); + + /** + * Set the current terminal image to @p image. + * + * @param image The terminal image + * @param lines The number of lines in the terminal image + * @param columns The number of columns in the terminal image + */ + void setImage(const Character* const image , int lines , int columns, + const QVector& lineProperties); + +private: + QString* _buffer; + QList* _linePositions; +}; + +} +#endif //FILTER_H diff --git a/qtermwidget/includes/History.h b/qtermwidget/includes/History.h new file mode 100644 index 0000000..a26a367 --- /dev/null +++ b/qtermwidget/includes/History.h @@ -0,0 +1,344 @@ +/* + This file is part of Konsole, an X terminal. + Copyright (C) 1997,1998 by Lars Doelle + + Rewritten for QT4 by e_k , Copyright (C)2008 + + 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. +*/ + +#ifndef TEHISTORY_H +#define TEHISTORY_H + +// Qt +#include +#include +#include + +// Konsole +#include "BlockArray.h" +#include "Character.h" + +namespace Konsole +{ + +#if 1 +/* + An extendable tmpfile(1) based buffer. +*/ + +class HistoryFile +{ +public: + HistoryFile(); + virtual ~HistoryFile(); + + virtual void add(const unsigned char* bytes, int len); + virtual void get(unsigned char* bytes, int len, int loc); + virtual int len(); + + //mmaps the file in read-only mode + void map(); + //un-mmaps the file + void unmap(); + //returns true if the file is mmap'ed + bool isMapped(); + + +private: + int ion; + int length; + QTemporaryFile tmpFile; + + //pointer to start of mmap'ed file data, or 0 if the file is not mmap'ed + char* fileMap; + + //incremented whenver 'add' is called and decremented whenever + //'get' is called. + //this is used to detect when a large number of lines are being read and processed from the history + //and automatically mmap the file for better performance (saves the overhead of many lseek-read calls). + int readWriteBalance; + + //when readWriteBalance goes below this threshold, the file will be mmap'ed automatically + static const int MAP_THRESHOLD = -1000; +}; +#endif + +////////////////////////////////////////////////////////////////////// + +////////////////////////////////////////////////////////////////////// +// Abstract base class for file and buffer versions +////////////////////////////////////////////////////////////////////// +class HistoryType; + +class HistoryScroll +{ +public: + HistoryScroll(HistoryType*); + virtual ~HistoryScroll(); + + virtual bool hasScroll(); + + // access to history + virtual int getLines() = 0; + virtual int getLineLen(int lineno) = 0; + virtual void getCells(int lineno, int colno, int count, Character res[]) = 0; + virtual bool isWrappedLine(int lineno) = 0; + + // backward compatibility (obsolete) + Character getCell(int lineno, int colno) { Character res; getCells(lineno,colno,1,&res); return res; } + + // adding lines. + virtual void addCells(const Character a[], int count) = 0; + // convenience method - this is virtual so that subclasses can take advantage + // of QVector's implicit copying + virtual void addCellsVector(const QVector& cells) + { + addCells(cells.data(),cells.size()); + } + + virtual void addLine(bool previousWrapped=false) = 0; + + // + // FIXME: Passing around constant references to HistoryType instances + // is very unsafe, because those references will no longer + // be valid if the history scroll is deleted. + // + const HistoryType& getType() { return *m_histType; } + +protected: + HistoryType* m_histType; + +}; + +#if 1 + +////////////////////////////////////////////////////////////////////// +// File-based history (e.g. file log, no limitation in length) +////////////////////////////////////////////////////////////////////// + +class HistoryScrollFile : public HistoryScroll +{ +public: + HistoryScrollFile(const QString &logFileName); + virtual ~HistoryScrollFile(); + + virtual int getLines(); + virtual int getLineLen(int lineno); + virtual void getCells(int lineno, int colno, int count, Character res[]); + virtual bool isWrappedLine(int lineno); + + virtual void addCells(const Character a[], int count); + virtual void addLine(bool previousWrapped=false); + +private: + int startOfLine(int lineno); + + QString m_logFileName; + HistoryFile index; // lines Row(int) + HistoryFile cells; // text Row(Character) + HistoryFile lineflags; // flags Row(unsigned char) +}; + + +////////////////////////////////////////////////////////////////////// +// Buffer-based history (limited to a fixed nb of lines) +////////////////////////////////////////////////////////////////////// +class HistoryScrollBuffer : public HistoryScroll +{ +public: + typedef QVector HistoryLine; + + HistoryScrollBuffer(unsigned int maxNbLines = 1000); + virtual ~HistoryScrollBuffer(); + + virtual int getLines(); + virtual int getLineLen(int lineno); + virtual void getCells(int lineno, int colno, int count, Character res[]); + virtual bool isWrappedLine(int lineno); + + virtual void addCells(const Character a[], int count); + virtual void addCellsVector(const QVector& cells); + virtual void addLine(bool previousWrapped=false); + + void setMaxNbLines(unsigned int nbLines); + unsigned int maxNbLines() { return _maxLineCount; } + + +private: + int bufferIndex(int lineNumber); + + HistoryLine* _historyBuffer; + QBitArray _wrappedLine; + int _maxLineCount; + int _usedLines; + int _head; + + //QVector m_histBuffer; + //QBitArray m_wrappedLine; + //unsigned int m_maxNbLines; + //unsigned int m_nbLines; + //unsigned int m_arrayIndex; + //bool m_buffFilled; +}; + +/*class HistoryScrollBufferV2 : public HistoryScroll +{ +public: + virtual int getLines(); + virtual int getLineLen(int lineno); + virtual void getCells(int lineno, int colno, int count, Character res[]); + virtual bool isWrappedLine(int lineno); + + virtual void addCells(const Character a[], int count); + virtual void addCells(const QVector& cells); + virtual void addLine(bool previousWrapped=false); + +};*/ + +#endif + +////////////////////////////////////////////////////////////////////// +// Nothing-based history (no history :-) +////////////////////////////////////////////////////////////////////// +class HistoryScrollNone : public HistoryScroll +{ +public: + HistoryScrollNone(); + virtual ~HistoryScrollNone(); + + virtual bool hasScroll(); + + virtual int getLines(); + virtual int getLineLen(int lineno); + virtual void getCells(int lineno, int colno, int count, Character res[]); + virtual bool isWrappedLine(int lineno); + + virtual void addCells(const Character a[], int count); + virtual void addLine(bool previousWrapped=false); +}; + +////////////////////////////////////////////////////////////////////// +// BlockArray-based history +////////////////////////////////////////////////////////////////////// +class HistoryScrollBlockArray : public HistoryScroll +{ +public: + HistoryScrollBlockArray(size_t size); + virtual ~HistoryScrollBlockArray(); + + virtual int getLines(); + virtual int getLineLen(int lineno); + virtual void getCells(int lineno, int colno, int count, Character res[]); + virtual bool isWrappedLine(int lineno); + + virtual void addCells(const Character a[], int count); + virtual void addLine(bool previousWrapped=false); + +protected: + BlockArray m_blockArray; + QHash m_lineLengths; +}; + +////////////////////////////////////////////////////////////////////// +// History type +////////////////////////////////////////////////////////////////////// + +class HistoryType +{ +public: + HistoryType(); + virtual ~HistoryType(); + + /** + * Returns true if the history is enabled ( can store lines of output ) + * or false otherwise. + */ + virtual bool isEnabled() const = 0; + /** + * Returns true if the history size is unlimited. + */ + bool isUnlimited() const { return maximumLineCount() == 0; } + /** + * Returns the maximum number of lines which this history type + * can store or 0 if the history can store an unlimited number of lines. + */ + virtual int maximumLineCount() const = 0; + + virtual HistoryScroll* scroll(HistoryScroll *) const = 0; +}; + +class HistoryTypeNone : public HistoryType +{ +public: + HistoryTypeNone(); + + virtual bool isEnabled() const; + virtual int maximumLineCount() const; + + virtual HistoryScroll* scroll(HistoryScroll *) const; +}; + +class HistoryTypeBlockArray : public HistoryType +{ +public: + HistoryTypeBlockArray(size_t size); + + virtual bool isEnabled() const; + virtual int maximumLineCount() const; + + virtual HistoryScroll* scroll(HistoryScroll *) const; + +protected: + size_t m_size; +}; + +#if 1 +class HistoryTypeFile : public HistoryType +{ +public: + HistoryTypeFile(const QString& fileName=QString()); + + virtual bool isEnabled() const; + virtual const QString& getFileName() const; + virtual int maximumLineCount() const; + + virtual HistoryScroll* scroll(HistoryScroll *) const; + +protected: + QString m_fileName; +}; + + +class HistoryTypeBuffer : public HistoryType +{ +public: + HistoryTypeBuffer(unsigned int nbLines); + + virtual bool isEnabled() const; + virtual int maximumLineCount() const; + + virtual HistoryScroll* scroll(HistoryScroll *) const; + +protected: + unsigned int m_nbLines; +}; + +#endif + +} + +#endif // TEHISTORY_H diff --git a/qtermwidget/includes/KeyboardTranslator.h b/qtermwidget/includes/KeyboardTranslator.h new file mode 100644 index 0000000..e0082ae --- /dev/null +++ b/qtermwidget/includes/KeyboardTranslator.h @@ -0,0 +1,657 @@ +/* + This source file is part of Konsole, a terminal emulator. + + Copyright (C) 2007 by Robert Knight + + Rewritten for QT4 by e_k , Copyright (C)2008 + + 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. +*/ + +#ifndef KEYBOARDTRANSLATOR_H +#define KEYBOARDTRANSLATOR_H + +// Qt +#include +#include +#include +#include +#include +#include + +typedef void (*CleanUpFunction)(); + +/** + * @internal + * + * Helper class for K_GLOBAL_STATIC to clean up the object on library unload or application + * shutdown. + */ +class CleanUpGlobalStatic +{ + public: + CleanUpFunction func; + + inline ~CleanUpGlobalStatic() { func(); } +}; + + +//these directives are taken from the heart of kdecore + +# define K_GLOBAL_STATIC_STRUCT_NAME(NAME) + +#if QT_VERSION < 0x040400 +# define Q_BASIC_ATOMIC_INITIALIZER Q_ATOMIC_INIT +# define testAndSetOrdered testAndSet +#endif + +#define K_GLOBAL_STATIC(TYPE, NAME) K_GLOBAL_STATIC_WITH_ARGS(TYPE, NAME, ()) + +#define K_GLOBAL_STATIC_WITH_ARGS(TYPE, NAME, ARGS) \ +static QBasicAtomicPointer _k_static_##NAME = Q_BASIC_ATOMIC_INITIALIZER(0); \ +static bool _k_static_##NAME##_destroyed; \ +static struct K_GLOBAL_STATIC_STRUCT_NAME(NAME) \ +{ \ + bool isDestroyed() \ + { \ + return _k_static_##NAME##_destroyed; \ + } \ + inline operator TYPE*() \ + { \ + return operator->(); \ + } \ + inline TYPE *operator->() \ + { \ + if (!_k_static_##NAME) { \ + if (isDestroyed()) { \ + qFatal("Fatal Error: Accessed global static '%s *%s()' after destruction. " \ + "Defined at %s:%d", #TYPE, #NAME, __FILE__, __LINE__); \ + } \ + TYPE *x = new TYPE ARGS; \ + if (!_k_static_##NAME.testAndSetOrdered(0, x) \ + && _k_static_##NAME != x ) { \ + delete x; \ + } else { \ + static CleanUpGlobalStatic cleanUpObject = { destroy }; \ + } \ + } \ + return _k_static_##NAME; \ + } \ + inline TYPE &operator*() \ + { \ + return *operator->(); \ + } \ + static void destroy() \ + { \ + _k_static_##NAME##_destroyed = true; \ + TYPE *x = _k_static_##NAME; \ + _k_static_##NAME = 0; \ + delete x; \ + } \ +} NAME; + + + + + +class QIODevice; +class QTextStream; + +namespace Konsole +{ + +/** + * A convertor which maps between key sequences pressed by the user and the + * character strings which should be sent to the terminal and commands + * which should be invoked when those character sequences are pressed. + * + * Konsole supports multiple keyboard translators, allowing the user to + * specify the character sequences which are sent to the terminal + * when particular key sequences are pressed. + * + * A key sequence is defined as a key code, associated keyboard modifiers + * (Shift,Ctrl,Alt,Meta etc.) and state flags which indicate the state + * which the terminal must be in for the key sequence to apply. + */ +class KeyboardTranslator +{ +public: + /** + * The meaning of a particular key sequence may depend upon the state which + * the terminal emulation is in. Therefore findEntry() may return a different + * Entry depending upon the state flags supplied. + * + * This enum describes the states which may be associated with with a particular + * entry in the keyboard translation entry. + */ + enum State + { + /** Indicates that no special state is active */ + NoState = 0, + /** + * TODO More documentation + */ + NewLineState = 1, + /** + * Indicates that the terminal is in 'Ansi' mode. + * TODO: More documentation + */ + AnsiState = 2, + /** + * TODO More documentation + */ + CursorKeysState = 4, + /** + * Indicates that the alternate screen ( typically used by interactive programs + * such as screen or vim ) is active + */ + AlternateScreenState = 8, + /** Indicates that any of the modifier keys is active. */ + AnyModifierState = 16 + }; + Q_DECLARE_FLAGS(States,State) + + /** + * This enum describes commands which are associated with particular key sequences. + */ + enum Command + { + /** Indicates that no command is associated with this command sequence */ + NoCommand = 0, + /** TODO Document me */ + SendCommand = 1, + /** Scroll the terminal display up one page */ + ScrollPageUpCommand = 2, + /** Scroll the terminal display down one page */ + ScrollPageDownCommand = 4, + /** Scroll the terminal display up one line */ + ScrollLineUpCommand = 8, + /** Scroll the terminal display down one line */ + ScrollLineDownCommand = 16, + /** Toggles scroll lock mode */ + ScrollLockCommand = 32, + /** Echos the operating system specific erase character. */ + EraseCommand = 64 + }; + Q_DECLARE_FLAGS(Commands,Command) + + /** + * Represents an association between a key sequence pressed by the user + * and the character sequence and commands associated with it for a particular + * KeyboardTranslator. + */ + class Entry + { + public: + /** + * Constructs a new entry for a keyboard translator. + */ + Entry(); + + /** + * Returns true if this entry is null. + * This is true for newly constructed entries which have no properties set. + */ + bool isNull() const; + + /** Returns the commands associated with this entry */ + Command command() const; + /** Sets the command associated with this entry. */ + void setCommand(Command command); + + /** + * Returns the character sequence associated with this entry, optionally replacing + * wildcard '*' characters with numbers to indicate the keyboard modifiers being pressed. + * + * TODO: The numbers used to replace '*' characters are taken from the Konsole/KDE 3 code. + * Document them. + * + * @param expandWildCards Specifies whether wild cards (occurrences of the '*' character) in + * the entry should be replaced with a number to indicate the modifier keys being pressed. + * + * @param modifiers The keyboard modifiers being pressed. + */ + QByteArray text(bool expandWildCards = false, + Qt::KeyboardModifiers modifiers = Qt::NoModifier) const; + + /** Sets the character sequence associated with this entry */ + void setText(const QByteArray& text); + + /** + * Returns the character sequence associated with this entry, + * with any non-printable characters replaced with escape sequences. + * + * eg. \\E for Escape, \\t for tab, \\n for new line. + * + * @param expandWildCards See text() + * @param modifiers See text() + */ + QByteArray escapedText(bool expandWildCards = false, + Qt::KeyboardModifiers modifiers = Qt::NoModifier) const; + + /** Returns the character code ( from the Qt::Key enum ) associated with this entry */ + int keyCode() const; + /** Sets the character code associated with this entry */ + void setKeyCode(int keyCode); + + /** + * Returns a bitwise-OR of the enabled keyboard modifiers associated with this entry. + * If a modifier is set in modifierMask() but not in modifiers(), this means that the entry + * only matches when that modifier is NOT pressed. + * + * If a modifier is not set in modifierMask() then the entry matches whether the modifier + * is pressed or not. + */ + Qt::KeyboardModifiers modifiers() const; + + /** Returns the keyboard modifiers which are valid in this entry. See modifiers() */ + Qt::KeyboardModifiers modifierMask() const; + + /** See modifiers() */ + void setModifiers( Qt::KeyboardModifiers modifiers ); + /** See modifierMask() and modifiers() */ + void setModifierMask( Qt::KeyboardModifiers modifiers ); + + /** + * Returns a bitwise-OR of the enabled state flags associated with this entry. + * If flag is set in stateMask() but not in state(), this means that the entry only + * matches when the terminal is NOT in that state. + * + * If a state is not set in stateMask() then the entry matches whether the terminal + * is in that state or not. + */ + States state() const; + + /** Returns the state flags which are valid in this entry. See state() */ + States stateMask() const; + + /** See state() */ + void setState( States state ); + /** See stateMask() */ + void setStateMask( States mask ); + + /** + * Returns the key code and modifiers associated with this entry + * as a QKeySequence + */ + //QKeySequence keySequence() const; + + /** + * Returns this entry's conditions ( ie. its key code, modifier and state criteria ) + * as a string. + */ + QString conditionToString() const; + + /** + * Returns this entry's result ( ie. its command or character sequence ) + * as a string. + * + * @param expandWildCards See text() + * @param modifiers See text() + */ + QString resultToString(bool expandWildCards = false, + Qt::KeyboardModifiers modifiers = Qt::NoModifier) const; + + /** + * Returns true if this entry matches the given key sequence, specified + * as a combination of @p keyCode , @p modifiers and @p state. + */ + bool matches( int keyCode , + Qt::KeyboardModifiers modifiers , + States flags ) const; + + bool operator==(const Entry& rhs) const; + + private: + void insertModifier( QString& item , int modifier ) const; + void insertState( QString& item , int state ) const; + QByteArray unescape(const QByteArray& text) const; + + int _keyCode; + Qt::KeyboardModifiers _modifiers; + Qt::KeyboardModifiers _modifierMask; + States _state; + States _stateMask; + + Command _command; + QByteArray _text; + }; + + /** Constructs a new keyboard translator with the given @p name */ + KeyboardTranslator(const QString& name); + + //KeyboardTranslator(const KeyboardTranslator& other); + + /** Returns the name of this keyboard translator */ + QString name() const; + + /** Sets the name of this keyboard translator */ + void setName(const QString& name); + + /** Returns the descriptive name of this keyboard translator */ + QString description() const; + + /** Sets the descriptive name of this keyboard translator */ + void setDescription(const QString& description); + + /** + * Looks for an entry in this keyboard translator which matches the given + * key code, keyboard modifiers and state flags. + * + * Returns the matching entry if found or a null Entry otherwise ( ie. + * entry.isNull() will return true ) + * + * @param keyCode A key code from the Qt::Key enum + * @param modifiers A combination of modifiers + * @param state Optional flags which specify the current state of the terminal + */ + Entry findEntry(int keyCode , + Qt::KeyboardModifiers modifiers , + States state = NoState) const; + + /** + * Adds an entry to this keyboard translator's table. Entries can be looked up according + * to their key sequence using findEntry() + */ + void addEntry(const Entry& entry); + + /** + * Replaces an entry in the translator. If the @p existing entry is null, + * then this is equivalent to calling addEntry(@p replacement) + */ + void replaceEntry(const Entry& existing , const Entry& replacement); + + /** + * Removes an entry from the table. + */ + void removeEntry(const Entry& entry); + + /** Returns a list of all entries in the translator. */ + QList entries() const; + +private: + + QHash _entries; // entries in this keyboard translation, + // entries are indexed according to + // their keycode + QString _name; + QString _description; +}; +Q_DECLARE_OPERATORS_FOR_FLAGS(KeyboardTranslator::States) +Q_DECLARE_OPERATORS_FOR_FLAGS(KeyboardTranslator::Commands) + +/** + * Parses the contents of a Keyboard Translator (.keytab) file and + * returns the entries found in it. + * + * Usage example: + * + * @code + * QFile source( "/path/to/keytab" ); + * source.open( QIODevice::ReadOnly ); + * + * KeyboardTranslator* translator = new KeyboardTranslator( "name-of-translator" ); + * + * KeyboardTranslatorReader reader(source); + * while ( reader.hasNextEntry() ) + * translator->addEntry(reader.nextEntry()); + * + * source.close(); + * + * if ( !reader.parseError() ) + * { + * // parsing succeeded, do something with the translator + * } + * else + * { + * // parsing failed + * } + * @endcode + */ +class KeyboardTranslatorReader +{ +public: + /** Constructs a new reader which parses the given @p source */ + KeyboardTranslatorReader( QIODevice* source ); + + /** + * Returns the description text. + * TODO: More documentation + */ + QString description() const; + + /** Returns true if there is another entry in the source stream */ + bool hasNextEntry(); + /** Returns the next entry found in the source stream */ + KeyboardTranslator::Entry nextEntry(); + + /** + * Returns true if an error occurred whilst parsing the input or + * false if no error occurred. + */ + bool parseError(); + + /** + * Parses a condition and result string for a translator entry + * and produces a keyboard translator entry. + * + * The condition and result strings are in the same format as in + */ + static KeyboardTranslator::Entry createEntry( const QString& condition , + const QString& result ); +private: + struct Token + { + enum Type + { + TitleKeyword, + TitleText, + KeyKeyword, + KeySequence, + Command, + OutputText + }; + Type type; + QString text; + }; + QList tokenize(const QString&); + void readNext(); + bool decodeSequence(const QString& , + int& keyCode, + Qt::KeyboardModifiers& modifiers, + Qt::KeyboardModifiers& modifierMask, + KeyboardTranslator::States& state, + KeyboardTranslator::States& stateFlags); + + static bool parseAsModifier(const QString& item , Qt::KeyboardModifier& modifier); + static bool parseAsStateFlag(const QString& item , KeyboardTranslator::State& state); + static bool parseAsKeyCode(const QString& item , int& keyCode); + static bool parseAsCommand(const QString& text , KeyboardTranslator::Command& command); + + QIODevice* _source; + QString _description; + KeyboardTranslator::Entry _nextEntry; + bool _hasNext; +}; + +/** Writes a keyboard translation to disk. */ +class KeyboardTranslatorWriter +{ +public: + /** + * Constructs a new writer which saves data into @p destination. + * The caller is responsible for closing the device when writing is complete. + */ + KeyboardTranslatorWriter(QIODevice* destination); + ~KeyboardTranslatorWriter(); + + /** + * Writes the header for the keyboard translator. + * @param description Description of the keyboard translator. + */ + void writeHeader( const QString& description ); + /** Writes a translator entry. */ + void writeEntry( const KeyboardTranslator::Entry& entry ); + +private: + QIODevice* _destination; + QTextStream* _writer; +}; + +/** + * Manages the keyboard translations available for use by terminal sessions, + * see KeyboardTranslator. + */ +class KeyboardTranslatorManager +{ +public: + /** + * Constructs a new KeyboardTranslatorManager and loads the list of + * available keyboard translations. + * + * The keyboard translations themselves are not loaded until they are + * first requested via a call to findTranslator() + */ + KeyboardTranslatorManager(); + ~KeyboardTranslatorManager(); + + /** + * Adds a new translator. If a translator with the same name + * already exists, it will be replaced by the new translator. + * + * TODO: More documentation. + */ + void addTranslator(KeyboardTranslator* translator); + + /** + * Deletes a translator. Returns true on successful deletion or false otherwise. + * + * TODO: More documentation + */ + bool deleteTranslator(const QString& name); + + /** Returns the default translator for Konsole. */ + const KeyboardTranslator* defaultTranslator(); + + /** + * Returns the keyboard translator with the given name or 0 if no translator + * with that name exists. + * + * The first time that a translator with a particular name is requested, + * the on-disk .keyboard file is loaded and parsed. + */ + const KeyboardTranslator* findTranslator(const QString& name); + /** + * Returns a list of the names of available keyboard translators. + * + * The first time this is called, a search for available + * translators is started. + */ + QList allTranslators(); + + /** Returns the global KeyboardTranslatorManager instance. */ + static KeyboardTranslatorManager* instance(); + +private: + static const char* defaultTranslatorText; + + void findTranslators(); // locate the available translators + KeyboardTranslator* loadTranslator(const QString& name); // loads the translator + // with the given name + KeyboardTranslator* loadTranslator(QIODevice* device,const QString& name); + + bool saveTranslator(const KeyboardTranslator* translator); + QString findTranslatorPath(const QString& name); + + QHash _translators; // maps translator-name -> KeyboardTranslator + // instance + bool _haveLoadedAll; +}; + +inline int KeyboardTranslator::Entry::keyCode() const { return _keyCode; } +inline void KeyboardTranslator::Entry::setKeyCode(int keyCode) { _keyCode = keyCode; } + +inline void KeyboardTranslator::Entry::setModifiers( Qt::KeyboardModifiers modifier ) +{ + _modifiers = modifier; +} +inline Qt::KeyboardModifiers KeyboardTranslator::Entry::modifiers() const { return _modifiers; } + +inline void KeyboardTranslator::Entry::setModifierMask( Qt::KeyboardModifiers mask ) +{ + _modifierMask = mask; +} +inline Qt::KeyboardModifiers KeyboardTranslator::Entry::modifierMask() const { return _modifierMask; } + +inline bool KeyboardTranslator::Entry::isNull() const +{ + return ( *this == Entry() ); +} + +inline void KeyboardTranslator::Entry::setCommand( Command command ) +{ + _command = command; +} +inline KeyboardTranslator::Command KeyboardTranslator::Entry::command() const { return _command; } + +inline void KeyboardTranslator::Entry::setText( const QByteArray& text ) +{ + _text = unescape(text); +} +inline int oneOrZero(int value) +{ + return value ? 1 : 0; +} +inline QByteArray KeyboardTranslator::Entry::text(bool expandWildCards,Qt::KeyboardModifiers modifiers) const +{ + QByteArray expandedText = _text; + + if (expandWildCards) + { + int modifierValue = 1; + modifierValue += oneOrZero(modifiers & Qt::ShiftModifier); + modifierValue += oneOrZero(modifiers & Qt::AltModifier) << 1; + modifierValue += oneOrZero(modifiers & Qt::ControlModifier) << 2; + + for (int i=0;i<_text.length();i++) + { + if (expandedText[i] == '*') + expandedText[i] = '0' + modifierValue; + } + } + + return expandedText; +} + +inline void KeyboardTranslator::Entry::setState( States state ) +{ + _state = state; +} +inline KeyboardTranslator::States KeyboardTranslator::Entry::state() const { return _state; } + +inline void KeyboardTranslator::Entry::setStateMask( States stateMask ) +{ + _stateMask = stateMask; +} +inline KeyboardTranslator::States KeyboardTranslator::Entry::stateMask() const { return _stateMask; } + +} + +Q_DECLARE_METATYPE(Konsole::KeyboardTranslator::Entry) +Q_DECLARE_METATYPE(const Konsole::KeyboardTranslator*) + +#endif // KEYBOARDTRANSLATOR_H + diff --git a/qtermwidget/includes/LineFont.h b/qtermwidget/includes/LineFont.h new file mode 100644 index 0000000..9b64143 --- /dev/null +++ b/qtermwidget/includes/LineFont.h @@ -0,0 +1,21 @@ +// WARNING: Autogenerated by "fontembedder ./linefont.src". +// You probably do not want to hand-edit this! + +static const quint32 LineChars[] = { + 0x00007c00, 0x000fffe0, 0x00421084, 0x00e739ce, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00427000, 0x004e7380, 0x00e77800, 0x00ef7bc0, + 0x00421c00, 0x00439ce0, 0x00e73c00, 0x00e7bde0, 0x00007084, 0x000e7384, 0x000079ce, 0x000f7bce, + 0x00001c84, 0x00039ce4, 0x00003dce, 0x0007bdee, 0x00427084, 0x004e7384, 0x004279ce, 0x00e77884, + 0x00e779ce, 0x004f7bce, 0x00ef7bc4, 0x00ef7bce, 0x00421c84, 0x00439ce4, 0x00423dce, 0x00e73c84, + 0x00e73dce, 0x0047bdee, 0x00e7bde4, 0x00e7bdee, 0x00427c00, 0x0043fce0, 0x004e7f80, 0x004fffe0, + 0x004fffe0, 0x00e7fde0, 0x006f7fc0, 0x00efffe0, 0x00007c84, 0x0003fce4, 0x000e7f84, 0x000fffe4, + 0x00007dce, 0x0007fdee, 0x000f7fce, 0x000fffee, 0x00427c84, 0x0043fce4, 0x004e7f84, 0x004fffe4, + 0x00427dce, 0x00e77c84, 0x00e77dce, 0x0047fdee, 0x004e7fce, 0x00e7fde4, 0x00ef7f84, 0x004fffee, + 0x00efffe4, 0x00e7fdee, 0x00ef7fce, 0x00efffee, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x000f83e0, 0x00a5294a, 0x004e1380, 0x00a57800, 0x00ad0bc0, 0x004390e0, 0x00a53c00, 0x00a5a1e0, + 0x000e1384, 0x0000794a, 0x000f0b4a, 0x000390e4, 0x00003d4a, 0x0007a16a, 0x004e1384, 0x00a5694a, + 0x00ad2b4a, 0x004390e4, 0x00a52d4a, 0x00a5a16a, 0x004f83e0, 0x00a57c00, 0x00ad83e0, 0x000f83e4, + 0x00007d4a, 0x000f836a, 0x004f93e4, 0x00a57d4a, 0x00ad836a, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00001c00, 0x00001084, 0x00007000, 0x00421000, + 0x00039ce0, 0x000039ce, 0x000e7380, 0x00e73800, 0x000e7f80, 0x00e73884, 0x0003fce0, 0x004239ce +}; diff --git a/qtermwidget/includes/LineFont.src b/qtermwidget/includes/LineFont.src new file mode 100644 index 0000000..6835253 --- /dev/null +++ b/qtermwidget/includes/LineFont.src @@ -0,0 +1,786 @@ +#2500: single horizontal line +2500 + + +----- + + + +#2501: triple horizontal line +2501 + +----- +----- +----- + + +#2502: single vertical line +2502 + | + | + | + | + | + +#2503: triple vertical line +2503 + ||| + ||| + ||| + ||| + ||| + +#2504-250B are dashed - not handled + +#250C: top-left corner (lines on bottom + right) +250C + + + .-- + | + | + +#250D: as above, but top line triple-width +250D + + .-- + .-- + |-- + | + +#250E: now the vert line triple-width +250E + + + ..-- + ||| + ||| + +#250F: and now both lines triple-width +250F + + .___ + |.-- + ||._ + ||| + +#2510: top-right corner +2510 + + +--. + | + | + +2511 + +==. +==. +==| + | + +2512 + + +==.. + ||| + ||| + +2513 + +===. +==.| +=.|| + ||| + +#2514: bottom-left corner +2514 + | + | + .== + + + +2515 + | + |== + |== + === + + + +2516 + ||| + ||| + |.== + + + +2517 + ||| + ||.= + |.== + .=== + + +#2518: bottm-right corner +2518 + | + | +==. + + + +2519 + | +==| +==| +=== + + + +251A + ||| + ||| +==== + + + +251B + ||| +=.|| +==.| +===. + + +#251C: Join of vertical line and one from the right +251C + | + | + |== + | + | + +251D + | + |== + |== + |== + | + +251E + ||| + ||| + ||== + | + | + +251F + | + | + ||== + ||| + ||| + + +2520 + ||| + ||| + ||== + ||| + ||| + +2521 + ||| + |||= + ||== + .|== + | + +2522 + | + .|== + ||== + |||= + ||| + +2523 + ||| + ||.= + ||== + ||.= + ||| + +#2524: Join of vertical line and one from the left +2524 + | + | +==| + | + | + +2525 + | +==| +==| +==| + | + +2526 + ||| + ||| +==+| + | + | + +2527 + | + | +==+| + ||| + ||| + +2528 + ||| + ||| +==+| + ||| + ||| + +2529 + ||| +=+|| +==+| +===+ + | + +252A + | +=+|| +==+| +===+ + ||| + +252B + ||| +=+|| +==+| +=+|| + ||| + +#252C: horizontal line joined to from below +252C + + +===== + | + | + +252D + +=== +==|== +==| + | + +252E + + === +==|== + |== + | + +252F + +==+== +==|== +==|== + | + +2530 + +===== +===== +==|== + | + +2531 + +===| +==||= +=||| + ||| + +2532 + + |=== +=||== + ||== + || + +2533 + +===== +==|== +=+|+= + ||| + +#2534: bottom line, connected to from top +2534 + | + | +===== + + + +2535 + | +==| +===== +=== + + +2536 + | + |== +===== + === + + +2537 + | +==|== +===== +===== + + +2538 + ||| + ||| +===== + + + +2539 + ||| +==|| +===== +===| + + + +253A + ||| + ||== +=|=== + |=== + + +253B + ||| +==|== +===== +===== + + +#253C: vertical + horizontal lines intersecting +253C + | + | +===== + | + | + +253D + | +==| +===== +==| + | + +253E + | + |== +===== + |== + | + +253F + | +==|== +===== +==|== + | + +2540 + ||| + ||| +===== + | + | + +2541 + | + | +===== + ||| + ||| + +2542 + ||| + ||| +===== + ||| + ||| + +2543 + ||| +=||| +===== +==|+ + | + +2544 + ||| + ||== +===== + |== + | + +2545 + | +==|+ +===== +=||| + ||| + +2546 + | + |== +===== + ||== + ||| + +2547 + ||| +=|||= +===== +=|||= + | + +2548 + | +=|||= +===== +=|||= + ||| + +2549 + ||| +=||| +===== +=||| + ||| + +254A + ||| + |||= +===== + |||= + ||| + +254B + ||| +=|||= +===== +=|||= + ||| + +#254C-254F are dashed +2550 + +_____ + +_____ + + +2551 + | | + | | + | | + | | + | | + +2552 + + |-- + | + |-- + | + +2553 + + + ---- + | | + | | + +2554 + + +--- + | + + +- + | | + +2555 + +--+ + | +--+ + | + +2556 + + +-+-+ + | | + | | + +2557 + +---+ + | +-+ | + | | + +2558 + | + +-- + | + +-- + +2559 + | | + | | + +-+- + + + +255A + | | + | +- + | + +--- + + +255B + | +--+ + | +--+ + + +255C + | | + | | +-+-+ + + +255D + | | +-+ | + | +---+ + + +255E + | + +-- + | + +-- + | + +255F + | | + | | + | +- + | | + | | + +2560 + | | + | +- + | | + | +- + | | + +2561 + | +--+ + | +--+ + | + +2562 + | | + | | +-+ + + | | + | | + +2563 + | | +-+ | + | +-+ | + | | + +2564 + +----- + +--+-- + | + +2565 + + +-+-+- + | | + | | + +2566 + +----- + +-+ +- + | | + +2567 + | +--+-- + +----- + + +2568 + | | + | | +-+-+- + + + +2569 + | | +-+ +- + +----- + + +256A + | +--+-- + | +--+-- + | + +256B + | | + | | +-+-+- + | | + | | + +256C + | | +-+ +- + +-+ +- + | | + +#256F-2570 are curly, +#2571-2573 are slashes and X + +2574 + + +___ + + + +2575 + | + | + | + + + +2576 + + + ___ + + + +2577 + + + | + | + | + +2578 + +___ +___ +___ + + +2579 + ||| + ||| + ||| + + + +257A + + ___ + ___ + ___ + + +257B + + + ||| + ||| + ||| + +257C + + ___ +_____ + ___ + + +257D + | + | + ||| + ||| + ||| + +257E + +___ +_____ +___ + + +257F + ||| + ||| + ||| + | + | diff --git a/qtermwidget/includes/Pty.h b/qtermwidget/includes/Pty.h new file mode 100644 index 0000000..f3e9432 --- /dev/null +++ b/qtermwidget/includes/Pty.h @@ -0,0 +1,243 @@ +/* + This file is part of Konsole, KDE's terminal emulator. + + Copyright (C) 2007 by Robert Knight + Copyright (C) 1997,1998 by Lars Doelle + + Rewritten for QT4 by e_k , Copyright (C)2008 + + 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. +*/ + +#ifndef PTY_H +#define PTY_H + +// Qt +#include +#include +#include +#include + +#include "k3process.h" + + +namespace Konsole +{ + +/** + * The Pty class is used to start the terminal process, + * send data to it, receive data from it and manipulate + * various properties of the pseudo-teletype interface + * used to communicate with the process. + * + * To use this class, construct an instance and connect + * to the sendData slot and receivedData signal to + * send data to or receive data from the process. + * + * To start the terminal process, call the start() method + * with the program name and appropriate arguments. + */ +class Pty: public K3Process +{ +Q_OBJECT + + public: + + /** + * Constructs a new Pty. + * + * Connect to the sendData() slot and receivedData() signal to prepare + * for sending and receiving data from the terminal process. + * + * To start the terminal process, call the run() method with the + * name of the program to start and appropriate arguments. + */ + Pty(); + ~Pty(); + + /** + * Starts the terminal process. + * + * Returns 0 if the process was started successfully or non-zero + * otherwise. + * + * @param program Path to the program to start + * @param arguments Arguments to pass to the program being started + * @param environment A list of key=value pairs which will be added + * to the environment for the new process. At the very least this + * should include an assignment for the TERM environment variable. + * @param winid Specifies the value of the WINDOWID environment variable + * in the process's environment. + * @param addToUtmp Specifies whether a utmp entry should be created for + * the pty used. See K3Process::setUsePty() + * @param dbusService Specifies the value of the KONSOLE_DBUS_SERVICE + * environment variable in the process's environment. + * @param dbusSession Specifies the value of the KONSOLE_DBUS_SESSION + * environment variable in the process's environment. + */ + int start( const QString& program, + const QStringList& arguments, + const QStringList& environment, + ulong winid, + bool addToUtmp +// const QString& dbusService, +// const QString& dbusSession + ); + + /** TODO: Document me */ + void setWriteable(bool writeable); + + /** + * Enables or disables Xon/Xoff flow control. + */ + void setXonXoff(bool on); + + /** + * Sets the size of the window (in lines and columns of characters) + * used by this teletype. + */ + void setWindowSize(int lines, int cols); + + /** Returns the size of the window used by this teletype. See setWindowSize() */ + QSize windowSize() const; + + /** TODO Document me */ + void setErase(char erase); + + /** */ + char erase() const; + + /** + * Returns the process id of the teletype's current foreground + * process. This is the process which is currently reading + * input sent to the terminal via. sendData() + * + * If there is a problem reading the foreground process group, + * 0 will be returned. + */ + int foregroundProcessGroup() const; + + /** + * Returns whether the buffer used to send data to the + * terminal process is full. + */ + bool bufferFull() const { return _bufferFull; } + + + public slots: + + /** + * Put the pty into UTF-8 mode on systems which support it. + */ + void setUtf8Mode(bool on); + + /** + * Suspend or resume processing of data from the standard + * output of the terminal process. + * + * See K3Process::suspend() and K3Process::resume() + * + * @param lock If true, processing of output is suspended, + * otherwise processing is resumed. + */ + void lockPty(bool lock); + + /** + * Sends data to the process currently controlling the + * teletype ( whose id is returned by foregroundProcessGroup() ) + * + * @param buffer Pointer to the data to send. + * @param length Length of @p buffer. + */ + void sendData(const char* buffer, int length); + + signals: + + /** + * Emitted when the terminal process terminates. + * + * @param exitCode The status code which the process exited with. + */ + void done(int exitCode); + + /** + * Emitted when a new block of data is received from + * the teletype. + * + * @param buffer Pointer to the data received. + * @param length Length of @p buffer + */ + void receivedData(const char* buffer, int length); + + /** + * Emitted when the buffer used to send data to the terminal + * process becomes empty, i.e. all data has been sent. + */ + void bufferEmpty(); + + + private slots: + + // called when terminal process exits + void donePty(); + // called when data is received from the terminal process + void dataReceived(K3Process*, char* buffer, int length); + // sends the first enqueued buffer of data to the + // terminal process + void doSendJobs(); + // called when the terminal process is ready to + // receive more data + void writeReady(); + + private: + // takes a list of key=value pairs and adds them + // to the environment for the process + void addEnvironmentVariables(const QStringList& environment); + + // enqueues a buffer of data to be sent to the + // terminal process + void appendSendJob(const char* buffer, int length); + + // a buffer of data in the queue to be sent to the + // terminal process + class SendJob { + public: + SendJob() {} + SendJob(const char* b, int len) : buffer(len) + { + memcpy( buffer.data() , b , len ); + } + + const char* data() const { return buffer.constData(); } + int length() const { return buffer.size(); } + private: + QVector buffer; + }; + + QList _pendingSendJobs; + bool _bufferFull; + + int _windowColumns; + int _windowLines; + char _eraseChar; + bool _xonXoff; + bool _utf8; + KPty *_pty; +}; + +} + +#endif // PTY_H diff --git a/qtermwidget/includes/Screen.h b/qtermwidget/includes/Screen.h new file mode 100644 index 0000000..a4ad199 --- /dev/null +++ b/qtermwidget/includes/Screen.h @@ -0,0 +1,662 @@ +/* + This file is part of Konsole, KDE's terminal. + + Copyright (C) 2007 by Robert Knight + Copyright (C) 1997,1998 by Lars Doelle + + Rewritten for QT4 by e_k , Copyright (C)2008 + + 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. +*/ + +#ifndef SCREEN_H +#define SCREEN_H + +// Qt +#include +#include +#include + +// Konsole +#include "Character.h" +#include "History.h" + +#define MODE_Origin 0 +#define MODE_Wrap 1 +#define MODE_Insert 2 +#define MODE_Screen 3 +#define MODE_Cursor 4 +#define MODE_NewLine 5 +#define MODES_SCREEN 6 + +namespace Konsole +{ + +/*! +*/ +struct ScreenParm +{ + int mode[MODES_SCREEN]; +}; + +class TerminalCharacterDecoder; + +/** + \brief An image of characters with associated attributes. + + The terminal emulation ( Emulation ) receives a serial stream of + characters from the program currently running in the terminal. + From this stream it creates an image of characters which is ultimately + rendered by the display widget ( TerminalDisplay ). Some types of emulation + may have more than one screen image. + + getImage() is used to retrieve the currently visible image + which is then used by the display widget to draw the output from the + terminal. + + The number of lines of output history which are kept in addition to the current + screen image depends on the history scroll being used to store the output. + The scroll is specified using setScroll() + The output history can be retrieved using writeToStream() + + The screen image has a selection associated with it, specified using + setSelectionStart() and setSelectionEnd(). The selected text can be retrieved + using selectedText(). When getImage() is used to retrieve the the visible image, + characters which are part of the selection have their colours inverted. +*/ +class Screen +{ +public: + /** Construct a new screen image of size @p lines by @p columns. */ + Screen(int lines, int columns); + ~Screen(); + + // VT100/2 Operations + // Cursor Movement + + /** Move the cursor up by @p n lines. */ + void cursorUp (int n); + /** Move the cursor down by @p n lines. */ + void cursorDown (int n); + /** Move the cursor to the left by @p n columns. */ + void cursorLeft (int n); + /** Move the cursor to the right by @p n columns. */ + void cursorRight (int n); + /** Position the cursor on line @p y. */ + void setCursorY (int y); + /** Position the cursor at column @p x. */ + void setCursorX (int x); + /** Position the cursor at line @p y, column @p x. */ + void setCursorYX (int y, int x); + /** + * Sets the margins for scrolling the screen. + * + * @param topLine The top line of the new scrolling margin. + * @param bottomLine The bottom line of the new scrolling margin. + */ + void setMargins (int topLine , int bottomLine); + /** Returns the top line of the scrolling region. */ + int topMargin() const; + /** Returns the bottom line of the scrolling region. */ + int bottomMargin() const; + + /** + * Resets the scrolling margins back to the top and bottom lines + * of the screen. + */ + void setDefaultMargins(); + + /** + * Moves the cursor down one line, if the MODE_NewLine mode + * flag is enabled then the cursor is returned to the leftmost + * column first. + * + * Equivalent to NextLine() if the MODE_NewLine flag is set + * or index() otherwise. + */ + void NewLine (); + /** + * Moves the cursor down one line and positions it at the beginning + * of the line. + */ + void NextLine (); + + /** + * Move the cursor down one line. If the cursor is on the bottom + * line of the scrolling region (as returned by bottomMargin()) the + * scrolling region is scrolled up by one line instead. + */ + void index (); + /** + * Move the cursor up one line. If the cursor is on the top line + * of the scrolling region (as returned by topMargin()) the scrolling + * region is scrolled down by one line instead. + */ + void reverseIndex(); + + /** + * Scroll the scrolling region of the screen up by @p n lines. + * The scrolling region is initially the whole screen, but can be changed + * using setMargins() + */ + void scrollUp(int n); + /** + * Scroll the scrolling region of the screen down by @p n lines. + * The scrolling region is initially the whole screen, but can be changed + * using setMargins() + */ + void scrollDown(int n); + + /** + * Moves the cursor to the beginning of the current line. + * Equivalent to setCursorX(0) + */ + void Return (); + /** + * Moves the cursor one column to the left and erases the character + * at the new cursor position. + */ + void BackSpace (); + /** + * Moves the cursor @p n tab-stops to the right. + */ + void Tabulate (int n = 1); + /** + * Moves the cursor @p n tab-stops to the left. + */ + void backTabulate(int n); + + // Editing + + /** + * Erase @p n characters beginning from the current cursor position. + * This is equivalent to over-writing @p n characters starting with the current + * cursor position with spaces. + * If @p n is 0 then one character is erased. + */ + void eraseChars (int n); + /** + * Delete @p n characters beginning from the current cursor position. + * If @p n is 0 then one character is deleted. + */ + void deleteChars (int n); + /** + * Insert @p n blank characters beginning from the current cursor position. + * The position of the cursor is not altered. + * If @p n is 0 then one character is inserted. + */ + void insertChars (int n); + /** + * Removes @p n lines beginning from the current cursor position. + * The position of the cursor is not altered. + * If @p n is 0 then one line is removed. + */ + void deleteLines (int n); + /** + * Inserts @p lines beginning from the current cursor position. + * The position of the cursor is not altered. + * If @p n is 0 then one line is inserted. + */ + void insertLines (int n); + /** Clears all the tab stops. */ + void clearTabStops(); + /** Sets or removes a tab stop at the cursor's current column. */ + void changeTabStop(bool set); + + /** Resets (clears) the specified screen @p mode. */ + void resetMode (int mode); + /** Sets (enables) the specified screen @p mode. */ + void setMode (int mode); + /** + * Saves the state of the specified screen @p mode. It can be restored + * using restoreMode() + */ + void saveMode (int mode); + /** Restores the state of a screen @p mode saved by calling saveMode() */ + void restoreMode (int mode); + /** Returns whether the specified screen @p mode is enabled or not .*/ + bool getMode (int mode) const; + + /** + * Saves the current position and appearence (text color and style) of the cursor. + * It can be restored by calling restoreCursor() + */ + void saveCursor (); + /** Restores the position and appearence of the cursor. See saveCursor() */ + void restoreCursor(); + + /** Clear the whole screen, moving the current screen contents into the history first. */ + void clearEntireScreen(); + /** + * Clear the area of the screen from the current cursor position to the end of + * the screen. + */ + void clearToEndOfScreen(); + /** + * Clear the area of the screen from the current cursor position to the start + * of the screen. + */ + void clearToBeginOfScreen(); + /** Clears the whole of the line on which the cursor is currently positioned. */ + void clearEntireLine(); + /** Clears from the current cursor position to the end of the line. */ + void clearToEndOfLine(); + /** Clears from the current cursor position to the beginning of the line. */ + void clearToBeginOfLine(); + + /** Fills the entire screen with the letter 'E' */ + void helpAlign (); + + /** + * Enables the given @p rendition flag. Rendition flags control the appearence + * of characters on the screen. + * + * @see Character::rendition + */ + void setRendition (int rendition); + /** + * Disables the given @p rendition flag. Rendition flags control the appearence + * of characters on the screen. + * + * @see Character::rendition + */ + void resetRendition(int rendition); + + /** + * Sets the cursor's foreground color. + * @param space The color space used by the @p color argument + * @param color The new foreground color. The meaning of this depends on + * the color @p space used. + * + * @see CharacterColor + */ + void setForeColor (int space, int color); + /** + * Sets the cursor's background color. + * @param space The color space used by the @p color argumnet. + * @param color The new background color. The meaning of this depends on + * the color @p space used. + * + * @see CharacterColor + */ + void setBackColor (int space, int color); + /** + * Resets the cursor's color back to the default and sets the + * character's rendition flags back to the default settings. + */ + void setDefaultRendition(); + + /** Returns the column which the cursor is positioned at. */ + int getCursorX() const; + /** Returns the line which the cursor is positioned on. */ + int getCursorY() const; + + /** TODO Document me */ + void clear(); + /** + * Sets the position of the cursor to the 'home' position at the top-left + * corner of the screen (0,0) + */ + void home(); + /** + * Resets the state of the screen. This resets the various screen modes + * back to their default states. The cursor style and colors are reset + * (as if setDefaultRendition() had been called) + * + *
    + *
  • Line wrapping is enabled.
  • + *
  • Origin mode is disabled.
  • + *
  • Insert mode is disabled.
  • + *
  • Cursor mode is enabled. TODO Document me
  • + *
  • Screen mode is disabled. TODO Document me
  • + *
  • New line mode is disabled. TODO Document me
  • + *
+ * + * If @p clearScreen is true then the screen contents are erased entirely, + * otherwise they are unaltered. + */ + void reset(bool clearScreen = true); + + /** + * Displays a new character at the current cursor position. + * + * If the cursor is currently positioned at the right-edge of the screen and + * line wrapping is enabled then the character is added at the start of a new + * line below the current one. + * + * If the MODE_Insert screen mode is currently enabled then the character + * is inserted at the current cursor position, otherwise it will replace the + * character already at the current cursor position. + */ + void ShowCharacter(unsigned short c); + + // Do composition with last shown character FIXME: Not implemented yet for KDE 4 + void compose(const QString& compose); + + /** + * Resizes the image to a new fixed size of @p new_lines by @p new_columns. + * In the case that @p new_columns is smaller than the current number of columns, + * existing lines are not truncated. This prevents characters from being lost + * if the terminal display is resized smaller and then larger again. + * + * (note that in versions of Konsole prior to KDE 4, existing lines were + * truncated when making the screen image smaller) + */ + void resizeImage(int new_lines, int new_columns); + + /** + * Returns the current screen image. + * The result is an array of Characters of size [getLines()][getColumns()] which + * must be freed by the caller after use. + * + * @param dest Buffer to copy the characters into + * @param size Size of @p dest in Characters + * @param startLine Index of first line to copy + * @param endLine Index of last line to copy + */ + void getImage( Character* dest , int size , int startLine , int endLine ) const; + + /** + * Returns the additional attributes associated with lines in the image. + * The most important attribute is LINE_WRAPPED which specifies that the + * line is wrapped, + * other attributes control the size of characters in the line. + */ + QVector getLineProperties( int startLine , int endLine ) const; + + + /** Return the number of lines. */ + int getLines() { return lines; } + /** Return the number of columns. */ + int getColumns() { return columns; } + /** Return the number of lines in the history buffer. */ + int getHistLines (); + /** + * Sets the type of storage used to keep lines in the history. + * If @p copyPreviousScroll is true then the contents of the previous + * history buffer are copied into the new scroll. + */ + void setScroll(const HistoryType& , bool copyPreviousScroll = true); + /** Returns the type of storage used to keep lines in the history. */ + const HistoryType& getScroll(); + /** + * Returns true if this screen keeps lines that are scrolled off the screen + * in a history buffer. + */ + bool hasScroll(); + + /** + * Sets the start of the selection. + * + * @param column The column index of the first character in the selection. + * @param line The line index of the first character in the selection. + * @param columnmode True if the selection is in column mode. + */ + void setSelectionStart(const int column, const int line, const bool columnmode); + + /** + * Sets the end of the current selection. + * + * @param column The column index of the last character in the selection. + * @param line The line index of the last character in the selection. + */ + void setSelectionEnd(const int column, const int line); + + /** + * Retrieves the start of the selection or the cursor position if there + * is no selection. + */ + void getSelectionStart(int& column , int& line); + + /** + * Retrieves the end of the selection or the cursor position if there + * is no selection. + */ + void getSelectionEnd(int& column , int& line); + + /** Clears the current selection */ + void clearSelection(); + + void setBusySelecting(bool busy) { sel_busy = busy; } + + /** + * Returns true if the character at (@p column, @p line) is part of the + * current selection. + */ + bool isSelected(const int column,const int line) const; + + /** + * Convenience method. Returns the currently selected text. + * @param preserveLineBreaks Specifies whether new line characters should + * be inserted into the returned text at the end of each terminal line. + */ + QString selectedText(bool preserveLineBreaks); + + /** + * Copies part of the output to a stream. + * + * @param decoder A decoder which coverts terminal characters into text + * @param from The first line in the history to retrieve + * @param to The last line in the history to retrieve + */ + void writeToStream(TerminalCharacterDecoder* decoder, int from, int to); + + /** + * Sets the selection to line @p no in the history and returns + * the text of that line from the history buffer. + */ + QString getHistoryLine(int no); + + /** + * Copies the selected characters, set using @see setSelBeginXY and @see setSelExtentXY + * into a stream. + * + * @param decoder A decoder which converts terminal characters into text. + * PlainTextDecoder is the most commonly used decoder which coverts characters + * into plain text with no formatting. + * @param preserveLineBreaks Specifies whether new line characters should + * be inserted into the returned text at the end of each terminal line. + */ + void writeSelectionToStream(TerminalCharacterDecoder* decoder , bool + preserveLineBreaks = true); + + /** TODO Document me */ + void checkSelection(int from, int to); + + /** + * Sets or clears an attribute of the current line. + * + * @param property The attribute to set or clear + * Possible properties are: + * LINE_WRAPPED: Specifies that the line is wrapped. + * LINE_DOUBLEWIDTH: Specifies that the characters in the current line should be double the normal width. + * LINE_DOUBLEHEIGHT:Specifies that the characters in the current line should be double the normal height. + * Double-height lines are formed of two lines containing the same characters, + * with both having the LINE_DOUBLEHEIGHT attribute. This allows other parts of the + * code to work on the assumption that all lines are the same height. + * + * @param enable true to apply the attribute to the current line or false to remove it + */ + void setLineProperty(LineProperty property , bool enable); + + + /** + * Returns the number of lines that the image has been scrolled up or down by, + * since the last call to resetScrolledLines(). + * + * a positive return value indicates that the image has been scrolled up, + * a negative return value indicates that the image has been scrolled down. + */ + int scrolledLines() const; + + /** + * Returns the region of the image which was last scrolled. + * + * This is the area of the image from the top margin to the + * bottom margin when the last scroll occurred. + */ + QRect lastScrolledRegion() const; + + /** + * Resets the count of the number of lines that the image has been scrolled up or down by, + * see scrolledLines() + */ + void resetScrolledLines(); + + /** + * Returns the number of lines of output which have been + * dropped from the history since the last call + * to resetDroppedLines() + * + * If the history is not unlimited then it will drop + * the oldest lines of output if new lines are added when + * it is full. + */ + int droppedLines() const; + + /** + * Resets the count of the number of lines dropped from + * the history. + */ + void resetDroppedLines(); + + /** + * Fills the buffer @p dest with @p count instances of the default (ie. blank) + * Character style. + */ + static void fillWithDefaultChar(Character* dest, int count); + +private: + + //copies a line of text from the screen or history into a stream using a + //specified character decoder + //line - the line number to copy, from 0 (the earliest line in the history) up to + // hist->getLines() + lines - 1 + //start - the first column on the line to copy + //count - the number of characters on the line to copy + //decoder - a decoder which coverts terminal characters (an Character array) into text + //appendNewLine - if true a new line character (\n) is appended to the end of the line + void copyLineToStream(int line, + int start, + int count, + TerminalCharacterDecoder* decoder, + bool appendNewLine, + bool preserveLineBreaks); + + //fills a section of the screen image with the character 'c' + //the parameters are specified as offsets from the start of the screen image. + //the loc(x,y) macro can be used to generate these values from a column,line pair. + void clearImage(int loca, int loce, char c); + + //move screen image between 'sourceBegin' and 'sourceEnd' to 'dest'. + //the parameters are specified as offsets from the start of the screen image. + //the loc(x,y) macro can be used to generate these values from a column,line pair. + void moveImage(int dest, int sourceBegin, int sourceEnd); + + void scrollUp(int from, int i); + void scrollDown(int from, int i); + + void addHistLine(); + + void initTabStops(); + + void effectiveRendition(); + void reverseRendition(Character& p) const; + + bool isSelectionValid() const; + + // copies 'count' lines from the screen buffer into 'dest', + // starting from 'startLine', where 0 is the first line in the screen buffer + void copyFromScreen(Character* dest, int startLine, int count) const; + // copies 'count' lines from the history buffer into 'dest', + // starting from 'startLine', where 0 is the first line in the history + void copyFromHistory(Character* dest, int startLine, int count) const; + + + // screen image ---------------- + int lines; + int columns; + + typedef QVector ImageLine; // [0..columns] + ImageLine* screenLines; // [lines] + + int _scrolledLines; + QRect _lastScrolledRegion; + + int _droppedLines; + + QVarLengthArray lineProperties; + + // history buffer --------------- + HistoryScroll *hist; + + // cursor location + int cuX; + int cuY; + + // cursor color and rendition info + CharacterColor cu_fg; // foreground + CharacterColor cu_bg; // background + quint8 cu_re; // rendition + + // margins ---------------- + int tmargin; // top margin + int bmargin; // bottom margin + + // states ---------------- + ScreenParm currParm; + + // ---------------------------- + + bool* tabstops; + + // selection ------------------- + int sel_begin; // The first location selected. + int sel_TL; // TopLeft Location. + int sel_BR; // Bottom Right Location. + bool sel_busy; // Busy making a selection. + bool columnmode; // Column selection mode + + // effective colors and rendition ------------ + CharacterColor ef_fg; // These are derived from + CharacterColor ef_bg; // the cu_* variables above + quint8 ef_re; // to speed up operation + + // + // save cursor, rendition & states ------------ + // + + // cursor location + int sa_cuX; + int sa_cuY; + + // rendition info + quint8 sa_cu_re; + CharacterColor sa_cu_fg; + CharacterColor sa_cu_bg; + + // last position where we added a character + int lastPos; + + // modes + ScreenParm saveParm; + + static Character defaultChar; +}; + +} + +#endif // SCREEN_H diff --git a/qtermwidget/includes/ScreenWindow.h b/qtermwidget/includes/ScreenWindow.h new file mode 100644 index 0000000..d2955ab --- /dev/null +++ b/qtermwidget/includes/ScreenWindow.h @@ -0,0 +1,256 @@ +/* + Copyright (C) 2007 by Robert Knight + + Rewritten for QT4 by e_k , Copyright (C)2008 + + 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. +*/ + +#ifndef SCREENWINDOW_H +#define SCREENWINDOW_H + +// Qt +#include +#include +#include + +// Konsole +#include "Character.h" + +namespace Konsole +{ + +class Screen; + +/** + * Provides a window onto a section of a terminal screen. + * This window can then be rendered by a terminal display widget ( TerminalDisplay ). + * + * To use the screen window, create a new ScreenWindow() instance and associated it with + * a terminal screen using setScreen(). + * Use the scrollTo() method to scroll the window up and down on the screen. + * Call the getImage() method to retrieve the character image which is currently visible in the window. + * + * setTrackOutput() controls whether the window moves to the bottom of the associated screen when new + * lines are added to it. + * + * Whenever the output from the underlying screen is changed, the notifyOutputChanged() slot should + * be called. This in turn will update the window's position and emit the outputChanged() signal + * if necessary. + */ +class ScreenWindow : public QObject +{ +Q_OBJECT + +public: + /** + * Constructs a new screen window with the given parent. + * A screen must be specified by calling setScreen() before calling getImage() or getLineProperties(). + * + * You should not call this constructor directly, instead use the Emulation::createWindow() method + * to create a window on the emulation which you wish to view. This allows the emulation + * to notify the window when the associated screen has changed and synchronize selection updates + * between all views on a session. + */ + ScreenWindow(QObject* parent = 0); + virtual ~ScreenWindow(); + + /** Sets the screen which this window looks onto */ + void setScreen(Screen* screen); + /** Returns the screen which this window looks onto */ + Screen* screen() const; + + /** + * Returns the image of characters which are currently visible through this window + * onto the screen. + * + * The buffer is managed by the ScreenWindow instance and does not need to be + * deleted by the caller. + */ + Character* getImage(); + + /** + * Returns the line attributes associated with the lines of characters which + * are currently visible through this window + */ + QVector getLineProperties(); + + /** + * Returns the number of lines which the region of the window + * specified by scrollRegion() has been scrolled by since the last call + * to resetScrollCount(). scrollRegion() is in most cases the + * whole window, but will be a smaller area in, for example, applications + * which provide split-screen facilities. + * + * This is not guaranteed to be accurate, but allows views to optimise + * rendering by reducing the amount of costly text rendering that + * needs to be done when the output is scrolled. + */ + int scrollCount() const; + + /** + * Resets the count of scrolled lines returned by scrollCount() + */ + void resetScrollCount(); + + /** + * Returns the area of the window which was last scrolled, this is + * usually the whole window area. + * + * Like scrollCount(), this is not guaranteed to be accurate, + * but allows views to optimise rendering. + */ + QRect scrollRegion() const; + + /** + * Sets the start of the selection to the given @p line and @p column within + * the window. + */ + void setSelectionStart( int column , int line , bool columnMode ); + /** + * Sets the end of the selection to the given @p line and @p column within + * the window. + */ + void setSelectionEnd( int column , int line ); + /** + * Retrieves the start of the selection within the window. + */ + void getSelectionStart( int& column , int& line ); + /** + * Retrieves the end of the selection within the window. + */ + void getSelectionEnd( int& column , int& line ); + /** + * Returns true if the character at @p line , @p column is part of the selection. + */ + bool isSelected( int column , int line ); + /** + * Clears the current selection + */ + void clearSelection(); + + /** Sets the number of lines in the window */ + void setWindowLines(int lines); + /** Returns the number of lines in the window */ + int windowLines() const; + /** Returns the number of columns in the window */ + int windowColumns() const; + + /** Returns the total number of lines in the screen */ + int lineCount() const; + /** Returns the total number of columns in the screen */ + int columnCount() const; + + /** Returns the index of the line which is currently at the top of this window */ + int currentLine() const; + + /** + * Returns the position of the cursor + * within the window. + */ + QPoint cursorPosition() const; + + /** + * Convenience method. Returns true if the window is currently at the bottom + * of the screen. + */ + bool atEndOfOutput() const; + + /** Scrolls the window so that @p line is at the top of the window */ + void scrollTo( int line ); + + enum RelativeScrollMode + { + ScrollLines, + ScrollPages + }; + + /** + * Scrolls the window relative to its current position on the screen. + * + * @param mode Specifies whether @p amount refers to the number of lines or the number + * of pages to scroll. + * @param amount The number of lines or pages ( depending on @p mode ) to scroll by. If + * this number is positive, the view is scrolled down. If this number is negative, the view + * is scrolled up. + */ + void scrollBy( RelativeScrollMode mode , int amount ); + + /** + * Specifies whether the window should automatically move to the bottom + * of the screen when new output is added. + * + * If this is set to true, the window will be moved to the bottom of the associated screen ( see + * screen() ) when the notifyOutputChanged() method is called. + */ + void setTrackOutput(bool trackOutput); + /** + * Returns whether the window automatically moves to the bottom of the screen as + * new output is added. See setTrackOutput() + */ + bool trackOutput() const; + + /** + * Returns the text which is currently selected. + * + * @param preserveLineBreaks See Screen::selectedText() + */ + QString selectedText( bool preserveLineBreaks ) const; + +public slots: + /** + * Notifies the window that the contents of the associated terminal screen have changed. + * This moves the window to the bottom of the screen if trackOutput() is true and causes + * the outputChanged() signal to be emitted. + */ + void notifyOutputChanged(); + +signals: + /** + * Emitted when the contents of the associated terminal screen ( see screen() ) changes. + */ + void outputChanged(); + + /** + * Emitted when the screen window is scrolled to a different position. + * + * @param line The line which is now at the top of the window. + */ + void scrolled(int line); + + /** + * Emitted when the selection is changed. + */ + void selectionChanged(); + +private: + int endWindowLine() const; + void fillUnusedArea(); + + Screen* _screen; // see setScreen() , screen() + Character* _windowBuffer; + int _windowBufferSize; + bool _bufferNeedsUpdate; + + int _windowLines; + int _currentLine; // see scrollTo() , currentLine() + bool _trackOutput; // see setTrackOutput() , trackOutput() + int _scrollCount; // count of lines which the window has been scrolled by since + // the last call to resetScrollCount() +}; + +} +#endif // SCREENWINDOW_H diff --git a/qtermwidget/includes/Session.h b/qtermwidget/includes/Session.h new file mode 100644 index 0000000..7b2ae25 --- /dev/null +++ b/qtermwidget/includes/Session.h @@ -0,0 +1,621 @@ +/* + This file is part of Konsole, an X terminal. + + Copyright (C) 2007 by Robert Knight + Copyright (C) 1997,1998 by Lars Doelle + + Rewritten for QT4 by e_k , Copyright (C)2008 + + 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. +*/ + +#ifndef SESSION_H +#define SESSION_H + +// Qt +#include +#include +#include + +// Konsole +#include "History.h" + +class KProcess; + +namespace Konsole +{ + +class Emulation; +class Pty; +class TerminalDisplay; +//class ZModemDialog; + +/** + * 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. + * 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. + * + * Each Session can be connected to one or more views by using the addView() method. + * 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. + */ +class Session : public QObject +{ +Q_OBJECT + +public: + Q_PROPERTY(QString name READ nameTitle) + Q_PROPERTY(int processId READ processId) + Q_PROPERTY(QString keyBindings READ keyBindings WRITE setKeyBindings) + Q_PROPERTY(QSize size READ size WRITE setSize) + + /** + * Constructs a new session. + * + * To start the terminal process, call the run() method, + * after specifying the program and arguments + * using setProgram() and setArguments() + * + * If no program or arguments are specified explicitly, the Session + * falls back to using the program specified in the SHELL environment + * variable. + */ + Session(); + ~Session(); + + /** + * Returns true if the session is currently running. This will be true + * after run() has been called successfully. + */ + bool isRunning() const; + + /** + * Sets the profile associated with this session. + * + * @param profileKey A key which can be used to obtain the current + * profile settings from the SessionManager + */ + void setProfileKey(const QString& profileKey); + /** + * Returns the profile key associated with this session. + * This can be passed to the SessionManager to obtain the current + * profile settings. + */ + QString profileKey() const; + + /** + * 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.) + * will be sent to the terminal. + * + * Views can be removed using removeView(). The session is automatically + * closed when the last view is removed. + */ + void addView(TerminalDisplay* widget); + /** + * Removes a view from this session. When the last view is removed, + * the session will be closed automatically. + * + * @p widget will no longer display output from or send input + * to the terminal + */ + void removeView(TerminalDisplay* widget); + + /** + * Returns the views connected to this session + */ + QList views() const; + + /** + * Returns the terminal emulation instance being used to encode / decode + * characters to / from the process. + */ + Emulation* emulation() const; + + /** + * Returns the environment of this session as a list of strings like + * VARIABLE=VALUE + */ + QStringList environment() const; + /** + * Sets the environment for this session. + * @p environment should be a list of strings like + * VARIABLE=VALUE + */ + void setEnvironment(const QStringList& environment); + + /** Returns the unique ID for this session. */ + int sessionId() const; + + /** + * Return the session title set by the user (ie. the program running + * in the terminal), or an empty string if the user has not set a custom title + */ + QString userTitle() const; + + /** + * This enum describes the contexts for which separate + * tab title formats may be specified. + */ + enum TabTitleContext + { + /** Default tab title format */ + LocalTabTitle, + /** + * Tab title format used session currently contains + * a connection to a remote computer (via SSH) + */ + RemoteTabTitle + }; + /** + * Sets the format used by this session for tab titles. + * + * @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 + * elements available depend on the @p context + */ + void setTabTitleFormat(TabTitleContext context , const QString& format); + /** Returns the format used by this session for tab titles. */ + QString tabTitleFormat(TabTitleContext context) const; + + + /** 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; + + /** + * 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); + + /** Returns the session's current working directory. */ + QString initialWorkingDirectory() { return _initialWorkingDir; } + + /** + * Sets the initial working directory for the session when it is run + * This has no effect once the session has been started. + */ + void setInitialWorkingDirectory( const QString& dir ); + + /** + * 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 + * (in memory, on-disk etc.) used. + */ + 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. + */ + void clearHistory(); + + /** + * Enables monitoring for activity in the session. + * This will cause notifySessionState() to be emitted + * with the NOTIFYACTIVITY state flag when output is + * received from the terminal. + */ + void setMonitorActivity(bool); + /** Returns true if monitoring for activity is enabled. */ + bool isMonitorActivity() const; + + /** + * 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() + */ + void setMonitorSilence(bool); + /** + * Returns true if monitoring for inactivity (silence) + * in the session is enabled. + */ + bool isMonitorSilence() const; + /** See setMonitorSilence() */ + void setMonitorSilenceSeconds(int seconds); + + /** + * Sets the key bindings used by this session. The bindings + * specify how input key sequences are translated into + * the character stream which is sent to the terminal. + * + * @param id The name of the key bindings to use. The + * names of available key bindings can be determined using the + * KeyboardTranslatorManager class. + */ + void setKeyBindings(const QString& id); + /** Returns the name of the key bindings used by this session. */ + QString keyBindings() const; + + /** + * 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); } + + /** 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; + + /** Sets the text of the icon associated with this session. */ + void setIconText(const QString& iconText); + /** Returns the text of the icon associated with this session. */ + QString iconText() const; + + /** Specifies whether a utmp entry should be created for the pty used by this session. */ + void setAddToUtmp(bool); + + /** Sends the specified @p signal to the terminal process. */ + bool sendSignal(int signal); + + /** + * Specifies whether to close the session automatically when the terminal + * process terminates. + */ + void setAutoClose(bool b) { _autoClose = b; } + + /** + * Sets whether flow control is enabled for this terminal + * session. + */ + void setFlowControlEnabled(bool enabled); + + /** Returns whether flow control is enabled for this terminal session. */ + bool flowControlEnabled() const; + + /** + * Sends @p text to the current foreground terminal program. + */ + void sendText(const QString& text) const; + + /** + * Returns the process id of the terminal process. + * This is the id used by the system API to refer to the process. + */ + int processId() const; + + /** + * Returns the process id of the terminal's foreground process. + * This is initially the same as processId() but can change + * as the user starts other programs inside the terminal. + */ + int foregroundProcessId() const; + + /** Returns the terminal session's window size in lines and columns. */ + QSize size(); + /** + * Emits a request to resize the session to accommodate + * the specified window size. + * + * @param size The size in lines and columns to request. + */ + void setSize(const QSize& size); + + /** Sets the text codec used by this session's terminal emulation. */ + void setCodec(QTextCodec* codec); + + /** + * 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. + * + * This has no effect once the session is running. + */ + void setDarkBackground(bool darkBackground); + /** + * Returns true if the session has a dark background. + * See setDarkBackground() + */ + bool hasDarkBackground() const; + + /** + * 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 + * shell to redraw the prompt line. + */ + void refresh(); + +// void startZModem(const QString &rz, const QString &dir, const QStringList &list); +// void cancelZModem(); +// bool isZModemBusy() { return _zmodemBusy; } + +public slots: + + /** + * Starts the terminal session. + * + * This creates the terminal process and connects the teletype to it. + */ + void run(); + + /** + * Closes the terminal session. This sends a hangup signal + * (SIGHUP) to the terminal process and causes the done(Session*) + * signal to be emitted. + */ + void close(); + + /** + * 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. + */ + void setUserTitle( int, const QString &caption ); + +signals: + + /** Emitted when the terminal process starts. */ + void started(); + + /** + * Emitted when the terminal process exits. + */ + void finished(); + + /** + * Emitted when output is received from the terminal process. + */ + void receivedData( const QString& text ); + + /** Emitted when the session's title has changed. */ + void titleChanged(); + + /** Emitted when the session's profile has changed. */ + void profileChanged(const QString& profile); + + /** + * 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 + */ + void stateChanged(int state); + + /** Emitted when a bell event occurs in the session. */ + void bellRequest( const QString& message ); + + /** + * Requests that the color the text for any tabs associated with + * this session should be changed; + * + * TODO: Document what the parameter does + */ + void changeTabTextColorRequest(int); + + /** + * Requests that the background color of views on this session + * should be changed. + */ + void changeBackgroundColorRequest(const QColor&); + + /** TODO: Document me. */ + void openUrlRequest(const QString& url); + + /** TODO: Document me. */ +// void zmodemDetected(); + + /** + * Emitted when the terminal process requests a change + * in the size of the terminal window. + * + * @param size The requested window size in terms of lines and columns. + */ + void resizeRequest(const QSize& size); + + /** + * Emitted when a profile change command is received from the terminal. + * + * @param text The text of the command. This is a string of the form + * "PropertyName=Value;PropertyName=Value ..." + */ + void profileChangeCommandReceived(const QString& text); + + /** + * Emitted when the flow control state changes. + * + * @param enabled True if flow control is enabled or false otherwise. + */ + void flowControlEnabledChanged(bool enabled); + +private slots: + void done(int); + +// void fireZModemDetected(); + + void onReceiveBlock( const char* buffer, int len ); + void monitorTimerDone(); + + void onViewSizeChange(int height, int width); + void onEmulationSizeChange(int lines , int columns); + + void activityStateSet(int); + + //automatically detach views from sessions when view is destroyed + void viewDestroyed(QObject* view); + +// void zmodemReadStatus(); +// void zmodemReadAndSendBlock(); +// void zmodemRcvBlock(const char *data, int len); +// void zmodemFinished(); + +private: + + void updateTerminalSize(); + WId windowId() const; + + int _uniqueIdentifier; + + Pty* _shellProcess; + Emulation* _emulation; + + QList _views; + + bool _monitorActivity; + bool _monitorSilence; + bool _notifiedActivity; + bool _masterMode; + bool _autoClose; + bool _wantedClose; + QTimer* _monitorTimer; + + int _silenceSeconds; + + QString _nameTitle; + QString _displayTitle; + QString _userTitle; + + QString _localTabTitleFormat; + QString _remoteTabTitleFormat; + + QString _iconName; + QString _iconText; // as set by: echo -en '\033]1;IconText\007 + bool _addToUtmp; + bool _flowControl; + bool _fullScripting; + + QString _program; + QStringList _arguments; + + QStringList _environment; + int _sessionId; + + QString _initialWorkingDir; + + // ZModem +// bool _zmodemBusy; +// KProcess* _zmodemProc; +// ZModemDialog* _zmodemProgress; + + // Color/Font Changes by ESC Sequences + + QColor _modifiedBackground; // as set by: echo -en '\033]11;Color\007 + + QString _profileKey; + + bool _hasDarkBackground; + + static int lastSessionId; + +}; + +/** + * 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 + * by the masterMode() flags. + */ +class SessionGroup : public QObject +{ +Q_OBJECT + +public: + /** Constructs an empty session group. */ + SessionGroup(); + /** 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 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 ); + /** Returns the master status of a session. See setMasterStatus() */ + bool masterStatus( Session* session ) const; + + /** + * This enum describes the options for propagating certain activity or + * changes in the group's master sessions to all sessions in the group. + */ + enum MasterMode + { + /** + * Any input key presses in the master sessions are sent to all + * sessions in the group. + */ + CopyInputToAll = 1 + }; + + /** + * 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 ); + /** + * Returns a bitwise OR of the active MasterMode flags for this group. + * See setMasterMode() + */ + int masterMode() const; + +private: + void connectPair(Session* master , Session* other); + void disconnectPair(Session* master , Session* other); + void connectAll(bool connect); + QList masters() const; + + // maps sessions to their master status + QHash _sessions; + + int _masterMode; +}; + +} + +#endif diff --git a/qtermwidget/includes/ShellCommand.h b/qtermwidget/includes/ShellCommand.h new file mode 100644 index 0000000..44e0db8 --- /dev/null +++ b/qtermwidget/includes/ShellCommand.h @@ -0,0 +1,94 @@ +/* + Copyright (C) 2007 by Robert Knight + + Rewritten for QT4 by e_k , Copyright (C)2008 + + 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. +*/ + +#ifndef SHELLCOMMAND_H +#define SHELLCOMMAND_H + +// Qt +#include + +namespace Konsole +{ + +/** + * A class to parse and extract information about shell commands. + * + * ShellCommand can be used to: + * + *
    + *
  • Take a command-line (eg "/bin/sh -c /path/to/my/script") and split it + * into its component parts (eg. the command "/bin/sh" and the arguments + * "-c","/path/to/my/script") + *
  • + *
  • Take a command and a list of arguments and combine them to + * form a complete command line. + *
  • + *
  • Determine whether the binary specified by a command exists in the + * user's PATH. + *
  • + *
  • Determine whether a command-line specifies the execution of + * another command as the root user using su/sudo etc. + *
  • + *
+ */ +class ShellCommand +{ +public: + /** + * Constructs a ShellCommand from a command line. + * + * @param fullCommand The command line to parse. + */ + ShellCommand(const QString& fullCommand); + /** + * Constructs a ShellCommand with the specified @p command and @p arguments. + */ + ShellCommand(const QString& command , const QStringList& arguments); + + /** Returns the command. */ + QString command() const; + /** Returns the arguments. */ + QStringList arguments() const; + + /** + * Returns the full command line. + */ + QString fullCommand() const; + + /** Returns true if this is a root command. */ + bool isRootCommand() const; + /** Returns true if the program specified by @p command() exists. */ + bool isAvailable() const; + + /** Expands environment variables in @p text .*/ + static QString expand(const QString& text); + + /** Expands environment variables in each string in @p list. */ + static QStringList expand(const QStringList& items); + +private: + QStringList _arguments; +}; + +} + +#endif // SHELLCOMMAND_H + diff --git a/qtermwidget/includes/TerminalCharacterDecoder.h b/qtermwidget/includes/TerminalCharacterDecoder.h new file mode 100644 index 0000000..5d97fc3 --- /dev/null +++ b/qtermwidget/includes/TerminalCharacterDecoder.h @@ -0,0 +1,139 @@ +/* + This file is part of Konsole, an X terminal. + + Copyright (C) 2006-7 by Robert Knight + + Rewritten for QT4 by e_k , Copyright (C)2008 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser 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 Lesser 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. +*/ + +#ifndef TERMINAL_CHARACTER_DECODER_H +#define TERMINAL_CHARACTER_DECODER_H + +#include "Character.h" + +class QTextStream; + +namespace Konsole +{ + +/** + * Base class for terminal character decoders + * + * The decoder converts lines of terminal characters which consist of a unicode character, foreground + * and background colours and other appearance-related properties into text strings. + * + * Derived classes may produce either plain text with no other colour or appearance information, or + * they may produce text which incorporates these additional properties. + */ +class TerminalCharacterDecoder +{ +public: + virtual ~TerminalCharacterDecoder() {} + + /** Begin decoding characters. The resulting text is appended to @p output. */ + virtual void begin(QTextStream* output) = 0; + /** End decoding. */ + virtual void end() = 0; + + /** + * Converts a line of terminal characters with associated properties into a text string + * and writes the string into an output QTextStream. + * + * @param characters An array of characters of length @p count. + * @param properties Additional properties which affect all characters in the line + * @param output The output stream which receives the decoded text + */ + virtual void decodeLine(const Character* const characters, + int count, + LineProperty properties) = 0; +}; + +/** + * A terminal character decoder which produces plain text, ignoring colours and other appearance-related + * properties of the original characters. + */ +class PlainTextDecoder : public TerminalCharacterDecoder +{ +public: + PlainTextDecoder(); + + /** + * Set whether trailing whitespace at the end of lines should be included + * in the output. + * Defaults to true. + */ + void setTrailingWhitespace(bool enable); + /** + * Returns whether trailing whitespace at the end of lines is included + * in the output. + */ + bool trailingWhitespace() const; + + virtual void begin(QTextStream* output); + virtual void end(); + + virtual void decodeLine(const Character* const characters, + int count, + LineProperty properties); + + +private: + QTextStream* _output; + bool _includeTrailingWhitespace; +}; + +/** + * A terminal character decoder which produces pretty HTML markup + */ +class HTMLDecoder : public TerminalCharacterDecoder +{ +public: + /** + * Constructs an HTML decoder using a default black-on-white color scheme. + */ + HTMLDecoder(); + + /** + * Sets the colour table which the decoder uses to produce the HTML colour codes in its + * output + */ + void setColorTable( const ColorEntry* table ); + + virtual void decodeLine(const Character* const characters, + int count, + LineProperty properties); + + virtual void begin(QTextStream* output); + virtual void end(); + +private: + void openSpan(QString& text , const QString& style); + void closeSpan(QString& text); + + QTextStream* _output; + const ColorEntry* _colorTable; + bool _innerSpanOpen; + quint8 _lastRendition; + CharacterColor _lastForeColor; + CharacterColor _lastBackColor; + +}; + +} + +#endif diff --git a/qtermwidget/includes/TerminalDisplay.h b/qtermwidget/includes/TerminalDisplay.h new file mode 100644 index 0000000..6b3c6d8 --- /dev/null +++ b/qtermwidget/includes/TerminalDisplay.h @@ -0,0 +1,754 @@ +/* + Copyright (C) 2007 by Robert Knight + Copyright (C) 1997,1998 by Lars Doelle + + Rewritten for QT4 by e_k , Copyright (C)2008 + + 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. +*/ + +#ifndef TERMINALDISPLAY_H +#define TERMINALDISPLAY_H + +// Qt +#include +#include +#include + +// Konsole +#include "Filter.h" +#include "Character.h" +#include "ColorTables.h" + +class QDrag; +class QDragEnterEvent; +class QDropEvent; +class QLabel; +class QTimer; +class QEvent; +class QFrame; +class QGridLayout; +class QKeyEvent; +class QScrollBar; +class QShowEvent; +class QHideEvent; +class QWidget; + +//class KMenu; + +namespace Konsole +{ + +extern unsigned short vt100_graphics[32]; + +class ScreenWindow; + +/** + * A widget which displays output from a terminal emulation and sends input keypresses and mouse activity + * to the terminal. + * + * When the terminal emulation receives new output from the program running in the terminal, + * it will update the display by calling updateImage(). + * + * TODO More documentation + */ +class TerminalDisplay : public QWidget +{ + Q_OBJECT + +public: + /** Constructs a new terminal display widget with the specified parent. */ + TerminalDisplay(QWidget *parent=0); + virtual ~TerminalDisplay(); + + /** Returns the terminal color palette used by the display. */ + const ColorEntry* colorTable() const; + /** Sets the terminal color palette used by the display. */ + void setColorTable(const ColorEntry table[]); + /** + * Sets the seed used to generate random colors for the display + * (in color schemes that support them). + */ + void setRandomSeed(uint seed); + /** + * Returns the seed used to generate random colors for the display + * (in color schemes that support them). + */ + uint randomSeed() const; + + /** Sets the opacity of the terminal display. */ + void setOpacity(qreal opacity); + + /** + * This enum describes the location where the scroll bar is positioned in the display widget. + */ + enum ScrollBarPosition + { + /** Do not show the scroll bar. */ + NoScrollBar=0, + /** Show the scroll bar on the left side of the display. */ + ScrollBarLeft=1, + /** Show the scroll bar on the right side of the display. */ + ScrollBarRight=2 + }; + /** + * Specifies whether the terminal display has a vertical scroll bar, and if so whether it + * is shown on the left or right side of the display. + */ + void setScrollBarPosition(ScrollBarPosition position); + + /** + * Sets the current position and range of the display's scroll bar. + * + * @param cursor The position of the scroll bar's thumb. + * @param lines The maximum value of the scroll bar. + */ + void setScroll(int cursor, int lines); + + /** + * Returns the display's filter chain. When the image for the display is updated, + * the text is passed through each filter in the chain. Each filter can define + * hotspots which correspond to certain strings (such as URLs or particular words). + * Depending on the type of the hotspots created by the filter ( returned by Filter::Hotspot::type() ) + * the view will draw visual cues such as underlines on mouse-over for links or translucent + * rectangles for markers. + * + * To add a new filter to the view, call: + * viewWidget->filterChain()->addFilter( filterObject ); + */ + FilterChain* filterChain() const; + + /** + * Updates the filters in the display's filter chain. This will cause + * the hotspots to be updated to match the current image. + * + * WARNING: This function can be expensive depending on the + * image size and number of filters in the filterChain() + * + * TODO - This API does not really allow efficient usage. Revise it so + * that the processing can be done in a better way. + * + * eg: + * - Area of interest may be known ( eg. mouse cursor hovering + * over an area ) + */ + void processFilters(); + + /** + * Returns a list of menu actions created by the filters for the content + * at the given @p position. + */ + QList filterActions(const QPoint& position); + + /** Returns true if the cursor is set to blink or false otherwise. */ + bool blinkingCursor() { return _hasBlinkingCursor; } + /** Specifies whether or not the cursor blinks. */ + void setBlinkingCursor(bool blink); + + void setCtrlDrag(bool enable) { _ctrlDrag=enable; } + bool ctrlDrag() { return _ctrlDrag; } + + /** + * This enum describes the methods for selecting text when + * the user triple-clicks within the display. + */ + enum TripleClickMode + { + /** Select the whole line underneath the cursor. */ + SelectWholeLine, + /** Select from the current cursor position to the end of the line. */ + SelectForwardsFromCursor + }; + /** Sets how the text is selected when the user triple clicks within the display. */ + void setTripleClickMode(TripleClickMode mode) { _tripleClickMode = mode; } + /** See setTripleClickSelectionMode() */ + TripleClickMode tripleClickMode() { return _tripleClickMode; } + + void setLineSpacing(uint); + uint lineSpacing() const; + + void emitSelection(bool useXselection,bool appendReturn); + + /** + * This enum describes the available shapes for the keyboard cursor. + * See setKeyboardCursorShape() + */ + enum KeyboardCursorShape + { + /** A rectangular block which covers the entire area of the cursor character. */ + BlockCursor, + /** + * A single flat line which occupies the space at the bottom of the cursor + * character's area. + */ + UnderlineCursor, + /** + * An cursor shaped like the capital letter 'I', similar to the IBeam + * cursor used in Qt/KDE text editors. + */ + IBeamCursor + }; + /** + * Sets the shape of the keyboard cursor. This is the cursor drawn + * at the position in the terminal where keyboard input will appear. + * + * In addition the terminal display widget also has a cursor for + * the mouse pointer, which can be set using the QWidget::setCursor() + * method. + * + * Defaults to BlockCursor + */ + void setKeyboardCursorShape(KeyboardCursorShape shape); + /** + * Returns the shape of the keyboard cursor. See setKeyboardCursorShape() + */ + KeyboardCursorShape keyboardCursorShape() const; + + /** + * Sets the color used to draw the keyboard cursor. + * + * The keyboard cursor defaults to using the foreground color of the character + * underneath it. + * + * @param useForegroundColor If true, the cursor color will change to match + * the foreground color of the character underneath it as it is moved, in this + * case, the @p color parameter is ignored and the color of the character + * under the cursor is inverted to ensure that it is still readable. + * @param color The color to use to draw the cursor. This is only taken into + * account if @p useForegroundColor is false. + */ + void setKeyboardCursorColor(bool useForegroundColor , const QColor& color); + + /** + * Returns the color of the keyboard cursor, or an invalid color if the keyboard + * cursor color is set to change according to the foreground color of the character + * underneath it. + */ + QColor keyboardCursorColor() const; + + /** + * Returns the number of lines of text which can be displayed in the widget. + * + * This will depend upon the height of the widget and the current font. + * See fontHeight() + */ + int lines() { return _lines; } + /** + * Returns the number of characters of text which can be displayed on + * each line in the widget. + * + * This will depend upon the width of the widget and the current font. + * See fontWidth() + */ + int columns() { return _columns; } + + /** + * Returns the height of the characters in the font used to draw the text in the display. + */ + int fontHeight() { return _fontHeight; } + /** + * Returns the width of the characters in the display. + * This assumes the use of a fixed-width font. + */ + int fontWidth() { return _fontWidth; } + + void setSize(int cols, int lins); + void setFixedSize(int cols, int lins); + + // reimplemented + QSize sizeHint() const; + + /** + * Sets which characters, in addition to letters and numbers, + * are regarded as being part of a word for the purposes + * of selecting words in the display by double clicking on them. + * + * The word boundaries occur at the first and last characters which + * are either a letter, number, or a character in @p wc + * + * @param wc An array of characters which are to be considered parts + * of a word ( in addition to letters and numbers ). + */ + void setWordCharacters(const QString& wc); + /** + * Returns the characters which are considered part of a word for the + * purpose of selecting words in the display with the mouse. + * + * @see setWordCharacters() + */ + QString wordCharacters() { return _wordCharacters; } + + /** + * Sets the type of effect used to alert the user when a 'bell' occurs in the + * terminal session. + * + * The terminal session can trigger the bell effect by calling bell() with + * the alert message. + */ + void setBellMode(int mode); + /** + * Returns the type of effect used to alert the user when a 'bell' occurs in + * the terminal session. + * + * See setBellMode() + */ + int bellMode() { return _bellMode; } + + /** + * This enum describes the different types of sounds and visual effects which + * can be used to alert the user when a 'bell' occurs in the terminal + * session. + */ + enum BellMode + { + /** A system beep. */ + SystemBeepBell=0, + /** + * KDE notification. This may play a sound, show a passive popup + * or perform some other action depending on the user's settings. + */ + NotifyBell=1, + /** A silent, visual bell (eg. inverting the display's colors briefly) */ + VisualBell=2, + /** No bell effects */ + NoBell=3 + }; + + void setSelection(const QString &t); + + /** + * Reimplemented. Has no effect. Use setVTFont() to change the font + * used to draw characters in the display. + */ + virtual void setFont(const QFont &); + + /** Returns the font used to draw characters in the display */ + QFont getVTFont() { return font(); } + + /** + * Sets the font used to draw the display. Has no effect if @p font + * is larger than the size of the display itself. + */ + void setVTFont(const QFont& font); + + /** + * Specified whether anti-aliasing of text in the terminal display + * is enabled or not. Defaults to enabled. + */ + static void setAntialias( bool antialias ) { _antialiasText = antialias; } + /** + * Returns true if anti-aliasing of text in the terminal is enabled. + */ + static bool antialias() { return _antialiasText; } + + /** + * Sets whether or not the current height and width of the + * terminal in lines and columns is displayed whilst the widget + * is being resized. + */ + void setTerminalSizeHint(bool on) { _terminalSizeHint=on; } + /** + * Returns whether or not the current height and width of + * the terminal in lines and columns is displayed whilst the widget + * is being resized. + */ + bool terminalSizeHint() { return _terminalSizeHint; } + /** + * Sets whether the terminal size display is shown briefly + * after the widget is first shown. + * + * See setTerminalSizeHint() , isTerminalSizeHint() + */ + void setTerminalSizeStartup(bool on) { _terminalSizeStartup=on; } + + void setBidiEnabled(bool set) { _bidiEnabled=set; } + bool isBidiEnabled() { return _bidiEnabled; } + + /** + * Sets the terminal screen section which is displayed in this widget. + * When updateImage() is called, the display fetches the latest character image from the + * the associated terminal screen window. + * + * In terms of the model-view paradigm, the ScreenWindow is the model which is rendered + * by the TerminalDisplay. + */ + void setScreenWindow( ScreenWindow* window ); + /** Returns the terminal screen section which is displayed in this widget. See setScreenWindow() */ + ScreenWindow* screenWindow() const; + + static bool HAVE_TRANSPARENCY; + +public slots: + + /** + * Causes the terminal display to fetch the latest character image from the associated + * terminal screen ( see setScreenWindow() ) and redraw the display. + */ + void updateImage(); + /** + * Causes the terminal display to fetch the latest line status flags from the + * associated terminal screen ( see setScreenWindow() ). + */ + void updateLineProperties(); + + /** Copies the selected text to the clipboard. */ + void copyClipboard(); + /** + * Pastes the content of the clipboard into the + * display. + */ + void pasteClipboard(); + /** + * Pastes the content of the selection into the + * display. + */ + void pasteSelection(); + + /** + * Changes whether the flow control warning box should be shown when the flow control + * stop key (Ctrl+S) are pressed. + */ + void setFlowControlWarningEnabled(bool enabled); + + /** + * Causes the widget to display or hide a message informing the user that terminal + * output has been suspended (by using the flow control key combination Ctrl+S) + * + * @param suspended True if terminal output has been suspended and the warning message should + * be shown or false to indicate that terminal output has been resumed and that + * the warning message should disappear. + */ + void outputSuspended(bool suspended); + + /** + * Sets whether the program whoose output is being displayed in the view + * is interested in mouse events. + * + * If this is set to true, mouse signals will be emitted by the view when the user clicks, drags + * or otherwise moves the mouse inside the view. + * The user interaction needed to create selections will also change, and the user will be required + * to hold down the shift key to create a selection or perform other mouse activities inside the + * view area - since the program running in the terminal is being allowed to handle normal mouse + * events itself. + * + * @param usesMouse Set to true if the program running in the terminal is interested in mouse events + * or false otherwise. + */ + void setUsesMouse(bool usesMouse); + + /** See setUsesMouse() */ + bool usesMouse() const; + + /** + * Shows a notification that a bell event has occurred in the terminal. + * TODO: More documentation here + */ + void bell(const QString& message); + +signals: + + /** + * Emitted when the user presses a key whilst the terminal widget has focus. + */ + void keyPressedSignal(QKeyEvent *e); + + /** + * Emitted when the user presses the suspend or resume flow control key combinations + * + * @param suspend true if the user pressed Ctrl+S (the suspend output key combination) or + * false if the user pressed Ctrl+Q (the resume output key combination) + */ + void flowControlKeyPressed(bool suspend); + + /** + * A mouse event occurred. + * @param button The mouse button (0 for left button, 1 for middle button, 2 for right button, 3 for release) + * @param column The character column where the event occurred + * @param line The character row where the event occurred + * @param eventType The type of event. 0 for a mouse press / release or 1 for mouse motion + */ + void mouseSignal(int button, int column, int line, int eventType); + void changedFontMetricSignal(int height, int width); + void changedContentSizeSignal(int height, int width); + + /** + * Emitted when the user right clicks on the display, or right-clicks with the Shift + * key held down if usesMouse() is true. + * + * This can be used to display a context menu. + */ + void configureRequest( TerminalDisplay*, int state, const QPoint& position ); + + void isBusySelecting(bool); + void sendStringToEmu(const char*); + +protected: + virtual bool event( QEvent * ); + + virtual void paintEvent( QPaintEvent * ); + + virtual void showEvent(QShowEvent*); + virtual void hideEvent(QHideEvent*); + virtual void resizeEvent(QResizeEvent*); + + virtual void fontChange(const QFont &font); + + virtual void keyPressEvent(QKeyEvent* event); + virtual void mouseDoubleClickEvent(QMouseEvent* ev); + virtual void mousePressEvent( QMouseEvent* ); + virtual void mouseReleaseEvent( QMouseEvent* ); + virtual void mouseMoveEvent( QMouseEvent* ); + virtual void extendSelection( const QPoint& pos ); + virtual void wheelEvent( QWheelEvent* ); + + virtual bool focusNextPrevChild( bool next ); + + // drag and drop + virtual void dragEnterEvent(QDragEnterEvent* event); + virtual void dropEvent(QDropEvent* event); + void doDrag(); + enum DragState { diNone, diPending, diDragging }; + + struct _dragInfo { + DragState state; + QPoint start; + QDrag *dragObject; + } dragInfo; + + virtual int charClass(quint16) const; + + void clearImage(); + + void mouseTripleClickEvent(QMouseEvent* ev); + + // reimplemented + virtual void inputMethodEvent ( QInputMethodEvent* event ); + virtual QVariant inputMethodQuery( Qt::InputMethodQuery query ) const; + +protected slots: + + void scrollBarPositionChanged(int value); + void blinkEvent(); + void blinkCursorEvent(); + + //Renables bell noises and visuals. Used to disable further bells for a short period of time + //after emitting the first in a sequence of bell events. + void enableBell(); + +private slots: + + void swapColorTable(); + void tripleClickTimeout(); // resets possibleTripleClick + +private: + + // -- Drawing helpers -- + + // divides the part of the display specified by 'rect' into + // fragments according to their colors and styles and calls + // drawTextFragment() to draw the fragments + void drawContents(QPainter &paint, const QRect &rect); + // draws a section of text, all the text in this section + // has a common color and style + void drawTextFragment(QPainter& painter, const QRect& rect, + const QString& text, const Character* style); + // draws the background for a text fragment + // if useOpacitySetting is true then the color's alpha value will be set to + // the display's transparency (set with setOpacity()), otherwise the background + // will be drawn fully opaque + void drawBackground(QPainter& painter, const QRect& rect, const QColor& color, + bool useOpacitySetting); + // draws the cursor character + void drawCursor(QPainter& painter, const QRect& rect , const QColor& foregroundColor, + const QColor& backgroundColor , bool& invertColors); + // draws the characters or line graphics in a text fragment + void drawCharacters(QPainter& painter, const QRect& rect, const QString& text, + const Character* style, bool invertCharacterColor); + // draws a string of line graphics + void drawLineCharString(QPainter& painter, int x, int y, + const QString& str, const Character* attributes); + + // draws the preedit string for input methods + void drawInputMethodPreeditString(QPainter& painter , const QRect& rect); + + // -- + + // maps an area in the character image to an area on the widget + QRect imageToWidget(const QRect& imageArea) const; + + // maps a point on the widget to the position ( ie. line and column ) + // of the character at that point. + void getCharacterPosition(const QPoint& widgetPoint,int& line,int& column) const; + + // the area where the preedit string for input methods will be draw + QRect preeditRect() const; + + // shows a notification window in the middle of the widget indicating the terminal's + // current size in columns and lines + void showResizeNotification(); + + // scrolls the image by a number of lines. + // 'lines' may be positive ( to scroll the image down ) + // or negative ( to scroll the image up ) + // 'region' is the part of the image to scroll - currently only + // the top, bottom and height of 'region' are taken into account, + // the left and right are ignored. + void scrollImage(int lines , const QRect& region); + + void calcGeometry(); + void propagateSize(); + void updateImageSize(); + void makeImage(); + + void paintFilters(QPainter& painter); + + // returns a region covering all of the areas of the widget which contain + // a hotspot + QRegion hotSpotRegion() const; + + // returns the position of the cursor in columns and lines + QPoint cursorPosition() const; + + // the window onto the terminal screen which this display + // is currently showing. + QPointer _screenWindow; + + bool _allowBell; + + QGridLayout* _gridLayout; + + bool _fixedFont; // has fixed pitch + int _fontHeight; // height + int _fontWidth; // width + int _fontAscent; // ascend + + int _leftMargin; // offset + int _topMargin; // offset + + int _lines; // the number of lines that can be displayed in the widget + int _columns; // the number of columns that can be displayed in the widget + + int _usedLines; // the number of lines that are actually being used, this will be less + // than 'lines' if the character image provided with setImage() is smaller + // than the maximum image size which can be displayed + + int _usedColumns; // the number of columns that are actually being used, this will be less + // than 'columns' if the character image provided with setImage() is smaller + // than the maximum image size which can be displayed + + int _contentHeight; + int _contentWidth; + Character* _image; // [lines][columns] + // only the area [usedLines][usedColumns] in the image contains valid data + + int _imageSize; + QVector _lineProperties; + + ColorEntry _colorTable[TABLE_COLORS]; + uint _randomSeed; + + bool _resizing; + bool _terminalSizeHint; + bool _terminalSizeStartup; + bool _bidiEnabled; + bool _mouseMarks; + + QPoint _iPntSel; // initial selection point + QPoint _pntSel; // current selection point + QPoint _tripleSelBegin; // help avoid flicker + int _actSel; // selection state + bool _wordSelectionMode; + bool _lineSelectionMode; + bool _preserveLineBreaks; + bool _columnSelectionMode; + + QClipboard* _clipboard; + QScrollBar* _scrollBar; + ScrollBarPosition _scrollbarLocation; + QString _wordCharacters; + int _bellMode; + + bool _blinking; // hide text in paintEvent + bool _hasBlinker; // has characters to blink + bool _cursorBlinking; // hide cursor in paintEvent + bool _hasBlinkingCursor; // has blinking cursor enabled + bool _ctrlDrag; // require Ctrl key for drag + TripleClickMode _tripleClickMode; + bool _isFixedSize; //Columns / lines are locked. + QTimer* _blinkTimer; // active when hasBlinker + QTimer* _blinkCursorTimer; // active when hasBlinkingCursor + +// KMenu* _drop; + QString _dropText; + int _dndFileCount; + + bool _possibleTripleClick; // is set in mouseDoubleClickEvent and deleted + // after QApplication::doubleClickInterval() delay + + + QLabel* _resizeWidget; + QTimer* _resizeTimer; + + bool _flowControlWarningEnabled; + + //widgets related to the warning message that appears when the user presses Ctrl+S to suspend + //terminal output - informing them what has happened and how to resume output + QLabel* _outputSuspendedLabel; + + uint _lineSpacing; + + bool _colorsInverted; // true during visual bell + + QSize _size; + + QRgb _blendColor; + + // list of filters currently applied to the display. used for links and + // search highlight + TerminalImageFilterChain* _filterChain; + QRect _mouseOverHotspotArea; + + KeyboardCursorShape _cursorShape; + + // custom cursor color. if this is invalid then the foreground + // color of the character under the cursor is used + QColor _cursorColor; + + + struct InputMethodData + { + QString preeditString; + QRect previousPreeditRect; + }; + InputMethodData _inputMethodData; + + static bool _antialiasText; // do we antialias or not + + //the delay in milliseconds between redrawing blinking text + static const int BLINK_DELAY = 500; + static const int DEFAULT_LEFT_MARGIN = 1; + static const int DEFAULT_TOP_MARGIN = 1; + +public: + static void setTransparencyEnabled(bool enable) + { + HAVE_TRANSPARENCY = enable; + } +}; + +} + +#endif // TERMINALDISPLAY_H diff --git a/qtermwidget/includes/Vt102Emulation.h b/qtermwidget/includes/Vt102Emulation.h new file mode 100644 index 0000000..4554c1b --- /dev/null +++ b/qtermwidget/includes/Vt102Emulation.h @@ -0,0 +1,192 @@ +/* + This file is part of Konsole, an X terminal. + + Copyright (C) 2007 by Robert Knight + Copyright (C) 1997,1998 by Lars Doelle + + Rewritten for QT4 by e_k , Copyright (C)2008 + + 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. +*/ + +#ifndef VT102EMULATION_H +#define VT102EMULATION_H + +// Standard Library +#include + +// Qt +#include +#include +#include + +// Konsole +#include "Emulation.h" +#include "Screen.h" + +#define MODE_AppScreen (MODES_SCREEN+0) +#define MODE_AppCuKeys (MODES_SCREEN+1) +#define MODE_AppKeyPad (MODES_SCREEN+2) +#define MODE_Mouse1000 (MODES_SCREEN+3) +#define MODE_Mouse1001 (MODES_SCREEN+4) +#define MODE_Mouse1002 (MODES_SCREEN+5) +#define MODE_Mouse1003 (MODES_SCREEN+6) +#define MODE_Ansi (MODES_SCREEN+7) +#define MODE_total (MODES_SCREEN+8) + +namespace Konsole +{ + +struct DECpar +{ + bool mode[MODE_total]; +}; + +struct CharCodes +{ + // coding info + char charset[4]; // + int cu_cs; // actual charset. + bool graphic; // Some VT100 tricks + bool pound ; // Some VT100 tricks + bool sa_graphic; // saved graphic + bool sa_pound; // saved pound +}; + +/** + * Provides an xterm compatible terminal emulation based on the DEC VT102 terminal. + * A full description of this terminal can be found at http://vt100.net/docs/vt102-ug/ + * + * In addition, various additional xterm escape sequences are supported to provide + * features such as mouse input handling. + * See http://rtfm.etla.org/xterm/ctlseq.html for a description of xterm's escape + * sequences. + * + */ +class Vt102Emulation : public Emulation +{ +Q_OBJECT + +public: + + /** Constructs a new emulation */ + Vt102Emulation(); + ~Vt102Emulation(); + + // reimplemented + virtual void clearEntireScreen(); + virtual void reset(); + + // reimplemented + virtual char getErase() const; + +public slots: + + // reimplemented + virtual void sendString(const char*,int length = -1); + virtual void sendText(const QString& text); + virtual void sendKeyEvent(QKeyEvent*); + virtual void sendMouseEvent( int buttons, int column, int line , int eventType ); + +protected: + // reimplemented + virtual void setMode (int mode); + virtual void resetMode (int mode); + + // reimplemented + virtual void receiveChar(int cc); + + +private slots: + + //causes changeTitle() to be emitted for each (int,QString) pair in pendingTitleUpdates + //used to buffer multiple title updates + void updateTitle(); + + +private: + unsigned short applyCharset(unsigned short c); + void setCharset(int n, int cs); + void useCharset(int n); + void setAndUseCharset(int n, int cs); + void saveCursor(); + void restoreCursor(); + void resetCharset(int scrno); + + void setMargins(int top, int bottom); + //set margins for all screens back to their defaults + void setDefaultMargins(); + + // returns true if 'mode' is set or false otherwise + bool getMode (int mode); + // saves the current boolean value of 'mode' + void saveMode (int mode); + // restores the boolean value of 'mode' + void restoreMode(int mode); + // resets all modes + void resetModes(); + + void resetToken(); +#define MAXPBUF 80 + void pushToToken(int cc); + int pbuf[MAXPBUF]; //FIXME: overflow? + int ppos; +#define MAXARGS 15 + void addDigit(int dig); + void addArgument(); + int argv[MAXARGS]; + int argc; + void initTokenizer(); + int tbl[256]; + + void scan_buffer_report(); //FIXME: rename + void ReportErrorToken(); //FIXME: rename + + void tau(int code, int p, int q); + void XtermHack(); + + void reportTerminalType(); + void reportSecondaryAttributes(); + void reportStatus(); + void reportAnswerBack(); + void reportCursorPosition(); + void reportTerminalParms(int p); + + void onScrollLock(); + void scrollLock(const bool lock); + + // clears the screen and resizes it to the specified + // number of columns + void clearScreenAndSetColumns(int columnCount); + + CharCodes _charset[2]; + + DECpar _currParm; + DECpar _saveParm; + + //hash table and timer for buffering calls to the session instance + //to update the name of the session + //or window title. + //these calls occur when certain escape sequences are seen in the + //output from the terminal + QHash _pendingTitleUpdates; + QTimer* _titleUpdateTimer; + +}; + +} + +#endif // VT102EMULATION_H diff --git a/qtermwidget/includes/default.keytab b/qtermwidget/includes/default.keytab new file mode 100644 index 0000000..f84293d --- /dev/null +++ b/qtermwidget/includes/default.keytab @@ -0,0 +1,128 @@ +# [README.default.Keytab] Buildin Keyboard Table +# +# To customize your keyboard, copy this file to something +# ending with .keytab and change it to meet you needs. +# Please read the README.KeyTab and the README.keyboard +# in this case. +# +# -------------------------------------------------------------- + +keyboard "Default (XFree 4)" + +# -------------------------------------------------------------- +# +# Note that this particular table is a "risc" version made to +# ease customization without bothering with obsolete details. +# See VT100.keytab for the more hairy stuff. +# +# -------------------------------------------------------------- + +# common keys + +key Escape : "\E" + +key Tab -Shift : "\t" +key Tab +Shift+Ansi : "\E[Z" +key Tab +Shift-Ansi : "\t" +key Backtab +Ansi : "\E[Z" +key Backtab -Ansi : "\t" + +key Return-Shift-NewLine : "\r" +key Return-Shift+NewLine : "\r\n" + +key Return+Shift : "\EOM" + +# Backspace and Delete codes are preserving CTRL-H. + +key Backspace : "\x7f" + +# Arrow keys in VT52 mode +# shift up/down are reserved for scrolling. +# shift left/right are reserved for switching between tabs (this is hardcoded). + +key Up -Shift-Ansi : "\EA" +key Down -Shift-Ansi : "\EB" +key Right-Shift-Ansi : "\EC" +key Left -Shift-Ansi : "\ED" + +# Arrow keys in ANSI mode with Application - and Normal Cursor Mode) + +key Up -Shift-AnyMod+Ansi+AppCuKeys : "\EOA" +key Down -Shift-AnyMod+Ansi+AppCuKeys : "\EOB" +key Right -Shift-AnyMod+Ansi+AppCuKeys : "\EOC" +key Left -Shift-AnyMod+Ansi+AppCuKeys : "\EOD" + +key Up -Shift-AnyMod+Ansi-AppCuKeys : "\E[A" +key Down -Shift-AnyMod+Ansi-AppCuKeys : "\E[B" +key Right -Shift-AnyMod+Ansi-AppCuKeys : "\E[C" +key Left -Shift-AnyMod+Ansi-AppCuKeys : "\E[D" + +key Up -Shift+AnyMod+Ansi : "\E[1;*A" +key Down -Shift+AnyMod+Ansi : "\E[1;*B" +key Right -Shift+AnyMod+Ansi : "\E[1;*C" +key Left -Shift+AnyMod+Ansi : "\E[1;*D" + +# other grey PC keys + +key Enter+NewLine : "\r\n" +key Enter-NewLine : "\r" + +key Home -AnyMod -AppCuKeys : "\E[H" +key End -AnyMod -AppCuKeys : "\E[F" +key Home -AnyMod +AppCuKeys : "\EOH" +key End -AnyMod +AppCuKeys : "\EOF" +key Home +AnyMod : "\E[1;*H" +key End +AnyMod : "\E[1;*F" + +key Insert -AnyMod : "\E[2~" +key Delete -AnyMod : "\E[3~" +key Insert +AnyMod : "\E[2;*~" +key Delete +AnyMod : "\E[3;*~" + +key Prior -Shift-AnyMod : "\E[5~" +key Next -Shift-AnyMod : "\E[6~" +key Prior -Shift+AnyMod : "\E[5;*~" +key Next -Shift+AnyMod : "\E[6;*~" + +# Function keys +key F1 -AnyMod : "\EOP" +key F2 -AnyMod : "\EOQ" +key F3 -AnyMod : "\EOR" +key F4 -AnyMod : "\EOS" +key F5 -AnyMod : "\E[15~" +key F6 -AnyMod : "\E[17~" +key F7 -AnyMod : "\E[18~" +key F8 -AnyMod : "\E[19~" +key F9 -AnyMod : "\E[20~" +key F10 -AnyMod : "\E[21~" +key F11 -AnyMod : "\E[23~" +key F12 -AnyMod : "\E[24~" + +key F1 +AnyMod : "\EO*P" +key F2 +AnyMod : "\EO*Q" +key F3 +AnyMod : "\EO*R" +key F4 +AnyMod : "\EO*S" +key F5 +AnyMod : "\E[15;*~" +key F6 +AnyMod : "\E[17;*~" +key F7 +AnyMod : "\E[18;*~" +key F8 +AnyMod : "\E[19;*~" +key F9 +AnyMod : "\E[20;*~" +key F10 +AnyMod : "\E[21;*~" +key F11 +AnyMod : "\E[23;*~" +key F12 +AnyMod : "\E[24;*~" + +# Work around dead keys + +key Space +Control : "\x00" + +# Some keys are used by konsole to cause operations. +# The scroll* operations refer to the history buffer. + +key Up +Shift-AppScreen : scrollLineUp +key Prior +Shift-AppScreen : scrollPageUp +key Down +Shift-AppScreen : scrollLineDown +key Next +Shift-AppScreen : scrollPageDown + +key ScrollLock : scrollLock + +# keypad characters are not offered differently by Qt. diff --git a/qtermwidget/includes/k3process.h b/qtermwidget/includes/k3process.h new file mode 100644 index 0000000..f8388ea --- /dev/null +++ b/qtermwidget/includes/k3process.h @@ -0,0 +1,890 @@ +/* This file is part of the KDE libraries + Copyright (C) 1997 Christian Czezakte (e9025461@student.tuwien.ac.at) + + Rewritten for QT4 by e_k , Copyright (C)2008 + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef K3PROCESS_H +#define K3PROCESS_H + +#include + +#include // for pid_t +#include +#include +#include + +class QSocketNotifier; +class K3ProcessPrivate; +class KPty; + +/** + * @obsolete Use KProcess and KPtyProcess instead. + * + * Child process invocation, monitoring and control. + * This class works only in the application's main thread. + * + * General usage and features:\n + * + * This class allows a KDE application to start child processes without having + * to worry about UN*X signal handling issues and zombie process reaping. + * + * @see K3ProcIO + * + * Basically, this class distinguishes three different ways of running + * child processes: + * + * @li DontCare -- The child process is invoked and both the child + * process and the parent process continue concurrently. + * + * The process is started in an own session (see setsid(2)). + * + * @li NotifyOnExit -- The child process is invoked and both the + * child and the parent process run concurrently. + * + * When the child process exits, the K3Process instance + * corresponding to it emits the Qt signal processExited(). + * Since this signal is @em not emitted from within a UN*X + * signal handler, arbitrary function calls can be made. + * + * Be aware: When the K3Process object gets destructed, the child + * process will be killed if it is still running! + * This means in particular, that it usually makes no sense to use + * a K3Process on the stack with NotifyOnExit. + * + * @li OwnGroup -- like NotifyOnExit, but the child process is started + * in an own process group (and an own session, FWIW). The behavior of + * kill() changes to killing the whole process group - this makes + * this mode useful for implementing primitive job management. It can be + * used to work around broken wrapper scripts that don't propagate signals + * to the "real" program. However, use this with care, as you disturb the + * shell's job management if your program is started from the command line. + * + * @li Block -- The child process starts and the parent process + * is suspended until the child process exits. (@em Really not recommended + * for programs with a GUI.) + * In this mode the parent can read the child's output, but can't send it any + * input. + * + * K3Process also provides several functions for determining the exit status + * and the pid of the child process it represents. + * + * Furthermore it is possible to supply command-line arguments to the process + * in a clean fashion (no null-terminated stringlists and such...) + * + * A small usage example: + * \code + * K3Process *proc = new K3Process; + * + * *proc << "my_executable"; + * *proc << "These" << "are" << "the" << "command" << "line" << "args"; + * QApplication::connect(proc, SIGNAL(processExited(K3Process *)), + * pointer_to_my_object, SLOT(my_objects_slot(K3Process *))); + * proc->start(); + * \endcode + * + * This will start "my_executable" with the commandline arguments "These"... + * + * When the child process exits, the slot will be invoked. + * + * Communication with the child process:\n + * + * K3Process supports communication with the child process through + * stdin/stdout/stderr. + * + * The following functions are provided for getting data from the child + * process or sending data to the child's stdin (For more information, + * have a look at the documentation of each function): + * + * @li writeStdin() + * -- Transmit data to the child process' stdin. When all data was sent, the + * signal wroteStdin() is emitted. + * + * @li When data arrives at stdout or stderr, the signal receivedStdout() + * resp. receivedStderr() is emitted. + * + * @li You can shut down individual communication channels with + * closeStdin(), closeStdout(), and closeStderr(), resp. + * + * @author Christian Czezatke e9025461@student.tuwien.ac.at + * + **/ +class K3Process : public QObject +{ + Q_OBJECT + +public: + + /** + * Modes in which the communication channels can be opened. + * + * If communication for more than one channel is required, + * the values should be or'ed together, for example to get + * communication with stdout as well as with stdin, you would + * specify @p Stdin | @p Stdout + * + */ + enum CommunicationFlag { + NoCommunication = 0, /**< No communication with the process. */ + Stdin = 1, /**< Connect to write to the process with writeStdin(). */ + Stdout = 2, /**< Connect to read from the process' output. */ + Stderr = 4, /**< Connect to read from the process' stderr. */ + AllOutput = 6, /**< Connects to all output channels. */ + All = 7, /**< Connects to all channels. */ + NoRead = 8, /**< If specified with Stdout, no data is actually read from stdout, + * only the signal receivedStdout(int fd, int &len) is emitted. */ + CTtyOnly = NoRead, /**< Tells setUsePty() to create a PTY for the process + * and make it the process' controlling TTY, but does not + * redirect any I/O channel to the PTY. */ + MergedStderr = 16 /**< If specified with Stdout, the process' stderr will be + * redirected onto the same file handle as its stdout, i.e., + * all error output will be signalled with receivedStdout(). + * Don't specify Stderr if you specify MergedStderr. */ + }; + + Q_DECLARE_FLAGS(Communication, CommunicationFlag) + + /** + * Run-modes for a child process. + */ + enum RunMode { + /** + * The application does not receive notifications from the subprocess when + * it is finished or aborted. + */ + DontCare, + /** + * The application is notified when the subprocess dies. + */ + NotifyOnExit, + /** + * The application is suspended until the started process is finished. + */ + Block, + /** + * Same as NotifyOnExit, but the process is run in an own session, + * just like with DontCare. + */ + OwnGroup + }; + + /** + * Constructor + */ + explicit K3Process( QObject* parent=0L ); + + /** + *Destructor: + * + * If the process is running when the destructor for this class + * is called, the child process is killed with a SIGKILL, but + * only if the run mode is not of type @p DontCare. + * Processes started as @p DontCare keep running anyway. + */ + virtual ~K3Process(); + + /** + * Sets the executable and the command line argument list for this process. + * + * For example, doing an "ls -l /usr/local/bin" can be achieved by: + * \code + * K3Process p; + * ... + * p << "ls" << "-l" << "/usr/local/bin" + * \endcode + * + * @param arg the argument to add + * @return a reference to this K3Process + **/ + K3Process &operator<<(const QString& arg); + /** + * Similar to previous method, takes a char *, supposed to be in locale 8 bit already. + */ + K3Process &operator<<(const char * arg); + /** + * Similar to previous method, takes a QByteArray, supposed to be in locale 8 bit already. + * @param arg the argument to add + * @return a reference to this K3Process + */ + K3Process &operator<<(const QByteArray & arg); + + /** + * Sets the executable and the command line argument list for this process, + * in a single method call, or add a list of arguments. + * @param args the arguments to add + * @return a reference to this K3Process + **/ + K3Process &operator<<(const QStringList& args); + + /** + * Clear a command line argument list that has been set by using + * operator<<. + */ + void clearArguments(); + + /** + * Starts the process. + * For a detailed description of the + * various run modes and communication semantics, have a look at the + * general description of the K3Process class. Note that if you use + * setUsePty( Stdout | Stderr, \ ), you cannot use Stdout | Stderr + * here - instead, use Stdout only to receive the mixed output. + * + * The following problems could cause this function to + * return false: + * + * @li The process is already running. + * @li The command line argument list is empty. + * @li The the @p comm parameter is incompatible with the selected pty usage. + * @li The starting of the process failed (could not fork). + * @li The executable was not found. + * + * @param runmode The Run-mode for the process. + * @param comm Specifies which communication channels should be + * established to the child process (stdin/stdout/stderr). By default, + * no communication takes place and the respective communication + * signals will never get emitted. + * + * @return true on success, false on error + * (see above for error conditions) + **/ + virtual bool start(RunMode runmode = NotifyOnExit, + Communication comm = NoCommunication); + + /** + * Stop the process (by sending it a signal). + * + * @param signo The signal to send. The default is SIGTERM. + * @return true if the signal was delivered successfully. + */ + virtual bool kill(int signo = SIGTERM); + + /** + * Checks whether the process is running. + * @return true if the process is (still) considered to be running + */ + bool isRunning() const; + + /** Returns the process id of the process. + * + * If it is called after + * the process has exited, it returns the process id of the last + * child process that was created by this instance of K3Process. + * + * Calling it before any child process has been started by this + * K3Process instance causes pid() to return 0. + * @return the pid of the process or 0 if no process has been started yet. + **/ + pid_t pid() const; + + /** + * Suspend processing of data from stdout of the child process. + */ + void suspend(); + + /** + * Resume processing of data from stdout of the child process. + */ + void resume(); + + /** + * Suspend execution of the current thread until the child process dies + * or the timeout hits. This function is not recommended for programs + * with a GUI. + * @param timeout timeout in seconds. -1 means wait indefinitely. + * @return true if the process exited, false if the timeout hit. + */ + bool wait(int timeout = -1); + + /** + * Checks whether the process exited cleanly. + * + * @return true if the process has already finished and has exited + * "voluntarily", ie: it has not been killed by a signal. + */ + bool normalExit() const; + + /** + * Checks whether the process was killed by a signal. + * + * @return true if the process has already finished and has not exited + * "voluntarily", ie: it has been killed by a signal. + */ + bool signalled() const; + + /** + * Checks whether a killed process dumped core. + * + * @return true if signalled() returns true and the process + * dumped core. Note that on systems that don't define the + * WCOREDUMP macro, the return value is always false. + */ + bool coreDumped() const; + + /** + * Returns the exit status of the process. + * + * @return the exit status of the process. Note that this value + * is not valid if normalExit() returns false. + */ + int exitStatus() const; + + /** + * Returns the signal the process was killed by. + * + * @return the signal number that caused the process to exit. + * Note that this value is not valid if signalled() returns false. + */ + int exitSignal() const; + + /** + * Transmit data to the child process' stdin. + * + * This function may return false in the following cases: + * + * @li The process is not currently running. + * This implies that you cannot use this function in Block mode. + * + * @li Communication to stdin has not been requested in the start() call. + * + * @li Transmission of data to the child process by a previous call to + * writeStdin() is still in progress. + * + * Please note that the data is sent to the client asynchronously, + * so when this function returns, the data might not have been + * processed by the child process. + * That means that you must not free @p buffer or call writeStdin() + * again until either a wroteStdin() signal indicates that the + * data has been sent or a processExited() signal shows that + * the child process is no longer alive. + * + * If all the data has been sent to the client, the signal + * wroteStdin() will be emitted. + * + * This function does not work when the process is start()ed in Block mode. + * + * @param buffer the buffer to write + * @param buflen the length of the buffer + * @return false if an error has occurred + **/ + bool writeStdin(const char *buffer, int buflen); + + /** + * Shuts down the Stdin communication link. If no pty is used, this + * causes "EOF" to be indicated on the child's stdin file descriptor. + * + * @return false if no Stdin communication link exists (any more). + */ + bool closeStdin(); + + /** + * Shuts down the Stdout communication link. If no pty is used, any further + * attempts by the child to write to its stdout file descriptor will cause + * it to receive a SIGPIPE. + * + * @return false if no Stdout communication link exists (any more). + */ + bool closeStdout(); + + /** + * Shuts down the Stderr communication link. If no pty is used, any further + * attempts by the child to write to its stderr file descriptor will cause + * it to receive a SIGPIPE. + * + * @return false if no Stderr communication link exists (any more). + */ + bool closeStderr(); + + /** + * Deletes the optional utmp entry and closes the pty. + * + * Make sure to shut down any communication links that are using the pty + * before calling this function. + * + * @return false if the pty is not open (any more). + */ + bool closePty(); + + /** + * @brief Close stdin, stdout, stderr and the pty + * + * This is the same that calling all close* functions in a row: + * @see closeStdin, @see closeStdout, @see closeStderr and @see closePty + */ + void closeAll(); + + /** + * Lets you see what your arguments are for debugging. + * @return the list of arguments + */ + const QList &args() /* const */ { return arguments; } + + /** + * Controls whether the started process should drop any + * setuid/setgid privileges or whether it should keep them. + * Note that this function is mostly a dummy, as the KDE libraries + * currently refuse to run with setuid/setgid privileges. + * + * The default is false: drop privileges + * @param keepPrivileges true to keep the privileges + */ + void setRunPrivileged(bool keepPrivileges); + + /** + * Returns whether the started process will drop any + * setuid/setgid privileges or whether it will keep them. + * @return true if the process runs privileged + */ + bool runPrivileged() const; + + /** + * Adds the variable @p name to the process' environment. + * This function must be called before starting the process. + * @param name the name of the environment variable + * @param value the new value for the environment variable + */ + void setEnvironment(const QString &name, const QString &value); + + /** + * Changes the current working directory (CWD) of the process + * to be started. + * This function must be called before starting the process. + * @param dir the new directory + */ + void setWorkingDirectory(const QString &dir); + + /** + * Specify whether to start the command via a shell or directly. + * The default is to start the command directly. + * If @p useShell is true @p shell will be used as shell, or + * if shell is empty, /bin/sh will be used. + * + * When using a shell, the caller should make sure that all filenames etc. + * are properly quoted when passed as argument. + * @see quote() + * @param useShell true if the command should be started via a shell + * @param shell the path to the shell that will execute the process, or + * 0 to use /bin/sh. Use getenv("SHELL") to use the user's + * default shell, but note that doing so is usually a bad idea + * for shell compatibility reasons. + */ + void setUseShell(bool useShell, const char *shell = 0); + + /** + * This function can be used to quote an argument string such that + * the shell processes it properly. This is e. g. necessary for + * user-provided file names which may contain spaces or quotes. + * It also prevents expansion of wild cards and environment variables. + * @param arg the argument to quote + * @return the quoted argument + */ + static QString quote(const QString &arg); + + /** + * Detaches K3Process from child process. All communication is closed. + * No exit notification is emitted any more for the child process. + * Deleting the K3Process will no longer kill the child process. + * Note that the current process remains the parent process of the + * child process. + */ + void detach(); + + /** + * Specify whether to create a pty (pseudo-terminal) for running the + * command. + * This function should be called before starting the process. + * + * @param comm for which stdio handles to use a pty. Note that it is not + * allowed to specify Stdout and Stderr at the same time both here and to + * start (there is only one pty, so they cannot be distinguished). + * @param addUtmp true if a utmp entry should be created for the pty + */ + void setUsePty(Communication comm, bool addUtmp); + + /** + * Obtains the pty object used by this process. The return value is + * valid only after setUsePty() was used with a non-zero argument. + * The pty is open only while the process is running. + * @return a pointer to the pty object + */ + KPty *pty() const; + + /** + * More or less intuitive constants for use with setPriority(). + */ + enum { PrioLowest = 20, PrioLow = 10, PrioLower = 5, PrioNormal = 0, + PrioHigher = -5, PrioHigh = -10, PrioHighest = -19 }; + + /** + * Sets the scheduling priority of the process. + * @param prio the new priority in the range -20 (high) to 19 (low). + * @return false on error; see setpriority(2) for possible reasons. + */ + bool setPriority(int prio); + +Q_SIGNALS: + /** + * Emitted after the process has terminated when + * the process was run in the @p NotifyOnExit (==default option to + * start() ) or the Block mode. + * @param proc a pointer to the process that has exited + **/ + void processExited(K3Process *proc); + + + /** + * Emitted, when output from the child process has + * been received on stdout. + * + * To actually get this signal, the Stdout communication link + * has to be turned on in start(). + * + * @param proc a pointer to the process that has received the output + * @param buffer The data received. + * @param buflen The number of bytes that are available. + * + * You should copy the information contained in @p buffer to your private + * data structures before returning from the slot. + * Example: + * \code + * QString myBuf = QLatin1String(buffer, buflen); + * \endcode + **/ + void receivedStdout(K3Process *proc, char *buffer, int buflen); + + /** + * Emitted when output from the child process has + * been received on stdout. + * + * To actually get this signal, the Stdout communication link + * has to be turned on in start() and the + * NoRead flag must have been passed. + * + * You will need to explicitly call resume() after your call to start() + * to begin processing data from the child process' stdout. This is + * to ensure that this signal is not emitted when no one is connected + * to it, otherwise this signal will not be emitted. + * + * The data still has to be read from file descriptor @p fd. + * @param fd the file descriptor that provides the data + * @param len the number of bytes that have been read from @p fd must + * be written here + **/ + void receivedStdout(int fd, int &len); // KDE4: change, broken API + + + /** + * Emitted, when output from the child process has + * been received on stderr. + * + * To actually get this signal, the Stderr communication link + * has to be turned on in start(). + * + * You should copy the information contained in @p buffer to your private + * data structures before returning from the slot. + * + * @param proc a pointer to the process that has received the data + * @param buffer The data received. + * @param buflen The number of bytes that are available. + **/ + void receivedStderr(K3Process *proc, char *buffer, int buflen); + + /** + * Emitted after all the data that has been + * specified by a prior call to writeStdin() has actually been + * written to the child process. + * @param proc a pointer to the process + **/ + void wroteStdin(K3Process *proc); + + +protected Q_SLOTS: + + /** + * This slot gets activated when data from the child's stdout arrives. + * It usually calls childOutput(). + * @param fdno the file descriptor for the output + */ + void slotChildOutput(int fdno); + + /** + * This slot gets activated when data from the child's stderr arrives. + * It usually calls childError(). + * @param fdno the file descriptor for the output + */ + void slotChildError(int fdno); + + /** + * Called when another bulk of data can be sent to the child's + * stdin. If there is no more data to be sent to stdin currently + * available, this function must disable the QSocketNotifier innot. + * @param dummy ignore this argument + */ + void slotSendData(int dummy); // KDE 4: remove dummy + +protected: + + /** + * Sets up the environment according to the data passed via + * setEnvironment() + */ + void setupEnvironment(); + + /** + * The list of the process' command line arguments. The first entry + * in this list is the executable itself. + */ + QList arguments; + /** + * How to run the process (Block, NotifyOnExit, DontCare). You should + * not modify this data member directly from derived classes. + */ + RunMode run_mode; + /** + * true if the process is currently running. You should not + * modify this data member directly from derived classes. Please use + * isRunning() for reading the value of this data member since it + * will probably be made private in later versions of K3Process. + */ + bool runs; + + /** + * The PID of the currently running process. + * You should not modify this data member in derived classes. + * Please use pid() instead of directly accessing this + * member since it will probably be made private in + * later versions of K3Process. + */ + pid_t pid_; + + /** + * The process' exit status as returned by waitpid(). You should not + * modify the value of this data member from derived classes. You should + * rather use exitStatus() than accessing this data member directly + * since it will probably be made private in further versions of + * K3Process. + */ + int status; + + + /** + * If false, the child process' effective uid & gid will be reset to the + * real values. + * @see setRunPrivileged() + */ + bool keepPrivs; + + /** + * This function is called from start() right before a fork() takes + * place. According to the @p comm parameter this function has to initialize + * the in, out and err data members of K3Process. + * + * This function should return 1 if setting the needed communication channels + * was successful. + * + * The default implementation is to create UNIX STREAM sockets for the + * communication, but you could reimplement this function to establish a + * TCP/IP communication for network communication, for example. + */ + virtual int setupCommunication(Communication comm); + + /** + * Called right after a (successful) fork() on the parent side. This function + * will usually do some communications cleanup, like closing in[0], + * out[1] and out[1]. + * + * Furthermore, it must also create the QSocketNotifiers innot, + * outnot and errnot and connect their Qt signals to the respective + * K3Process slots. + * + * For a more detailed explanation, it is best to have a look at the default + * implementation in kprocess.cpp. + */ + virtual int commSetupDoneP(); + + /** + * Called right after a (successful) fork(), but before an exec() on the child + * process' side. It usually duplicates the in[0], out[1] and + * err[1] file handles to the respective standard I/O handles. + */ + virtual int commSetupDoneC(); + + + /** + * Immediately called after a successfully started process in NotifyOnExit + * mode has exited. This function normally calls commClose() + * and emits the processExited() signal. + * @param state the exit code of the process as returned by waitpid() + */ + virtual void processHasExited(int state); + + /** + * Cleans up the communication links to the child after it has exited. + * This function should act upon the values of pid() and runs. + * See the kprocess.cpp source for details. + * @li If pid() returns zero, the communication links should be closed + * only. + * @li if pid() returns non-zero and runs is false, all data + * immediately available from the communication links should be processed + * before closing them. + * @li if pid() returns non-zero and runs is true, the communication + * links should be monitored for data until the file handle returned by + * K3ProcessController::theKProcessController->notifierFd() becomes ready + * for reading - when it triggers, runs should be reset to false, and + * the function should be immediately left without closing anything. + * + * The previous semantics of this function are forward-compatible, but should + * be avoided, as they are prone to race conditions and can cause K3Process + * (and thus the whole program) to lock up under certain circumstances. At the + * end the function closes the communication links in any case. Additionally + * @li if runs is true, the communication links are monitored for data + * until all of them have returned EOF. Note that if any system function is + * interrupted (errno == EINTR) the polling loop should be aborted. + * @li if runs is false, all data immediately available from the + * communication links is processed. + */ + virtual void commClose(); + + /* KDE 4 - commClose will be changed to perform cleanup only in all cases * + * If @p notfd is -1, all data immediately available from the + * communication links should be processed. + * If @p notfd is not -1, the communication links should be monitored + * for data until the file handle @p notfd becomes ready for reading. + */ +// virtual void commDrain(int notfd); + + /** + * Specify the actual executable that should be started (first argument to execve) + * Normally the the first argument is the executable but you can + * override that with this function. + */ + void setBinaryExecutable(const char *filename); + + /** + * The socket descriptors for stdout. + */ + int out[2]; + /** + * The socket descriptors for stdin. + */ + int in[2]; + /** + * The socket descriptors for stderr. + */ + int err[2]; + + /** + * The socket notifier for in[1]. + */ + QSocketNotifier *innot; + /** + * The socket notifier for out[0]. + */ + QSocketNotifier *outnot; + /** + * The socket notifier for err[0]. + */ + QSocketNotifier *errnot; + + /** + * Lists the communication links that are activated for the child + * process. Should not be modified from derived classes. + */ + Communication communication; + + /** + * Called by slotChildOutput() this function copies data arriving from + * the child process' stdout to the respective buffer and emits the signal + * receivedStdout(). + */ + int childOutput(int fdno); + + /** + * Called by slotChildError() this function copies data arriving from + * the child process' stderr to the respective buffer and emits the signal + * receivedStderr(). + */ + int childError(int fdno); + + /** + * The buffer holding the data that has to be sent to the child + */ + const char *input_data; + /** + * The number of bytes already transmitted + */ + int input_sent; + /** + * The total length of input_data + */ + int input_total; + + /** + * K3ProcessController is a friend of K3Process because it has to have + * access to various data members. + */ + friend class K3ProcessController; + +private: + K3ProcessPrivate* const d; +}; + +Q_DECLARE_OPERATORS_FOR_FLAGS(K3Process::Communication) + +class K3ShellProcessPrivate; + +/** +* @obsolete +* +* Use K3Process and K3Process::setUseShell(true) instead. +* +* @short A class derived from K3Process to start child +* processes through a shell. +* @author Christian Czezatke +*/ +class K3ShellProcess : public K3Process +{ + Q_OBJECT + +public: + + /** + * Constructor + * + * If no shellname is specified, the user's default shell is used. + */ + explicit K3ShellProcess(const char *shellname=0); + + /** + * Destructor. + */ + ~K3ShellProcess(); + + virtual bool start(RunMode runmode = NotifyOnExit, + Communication comm = NoCommunication); + + static QString quote(const QString &arg); + +private: + K3ShellProcessPrivate* const d; +}; + + + +#endif + diff --git a/qtermwidget/includes/k3processcontroller.h b/qtermwidget/includes/k3processcontroller.h new file mode 100644 index 0000000..c077af2 --- /dev/null +++ b/qtermwidget/includes/k3processcontroller.h @@ -0,0 +1,137 @@ +/* This file is part of the KDE libraries + Copyright (C) 1997 Christian Czezakte (e9025461@student.tuwien.ac.at) + + Rewritten for QT4 by e_k , Copyright (C)2008 + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef K3PROCCTRL_H +#define K3PROCCTRL_H + +#include +#include + + +/** + * @short Used internally by K3Process + * @internal + * @author Christian Czezatke + * + * A class for internal use by K3Process only. -- Exactly one instance + * of this class is created by KApplication. + * + * This class takes care of the actual (UN*X) signal handling. + */ +class K3ProcessController : public QObject +{ + Q_OBJECT + +public: + /** + * Create an instance if none exists yet. + * Called by KApplication::KApplication() + */ + static void ref(); + + /** + * Destroy the instance if one exists and it is not referenced any more. + * Called by KApplication::~KApplication() + */ + static void deref(); + + /** + * Only a single instance of this class is allowed at a time. + * This method provides access to that instance. + */ + static K3ProcessController *instance(); + + /** + * Automatically called upon SIGCHLD. Never call it directly. + * If your application (or some library it uses) redirects SIGCHLD, + * the new signal handler (and only it) should call the old handler + * returned by sigaction(). + * @internal + */ + static void theSigCHLDHandler(int signal); // KDE4: private + + /** + * Wait for any process to exit and handle their exit without + * starting an event loop. + * This function may cause K3Process to emit any of its signals. + * + * @param timeout the timeout in seconds. -1 means no timeout. + * @return true if a process exited, false + * if no process exited within @p timeout seconds. + */ + bool waitForProcessExit(int timeout); + + /** + * Call this function to defer processing of the data that became available + * on notifierFd(). + */ + void unscheduleCheck(); + + /** + * This function @em must be called at some point after calling + * unscheduleCheck(). + */ + void rescheduleCheck(); + + /* + * Obtain the file descriptor K3ProcessController uses to get notified + * about process exits. select() or poll() on it if you create a custom + * event loop that needs to act upon SIGCHLD. + * @return the file descriptor of the reading end of the notification pipe + */ + int notifierFd() const; + + /** + * @internal + */ + void addKProcess( K3Process* ); + /** + * @internal + */ + void removeKProcess( K3Process* ); + /** + * @internal + */ + void addProcess( int pid ); + +private Q_SLOTS: + void slotDoHousekeeping(); + +private: + friend class I_just_love_gcc; + + static void setupHandlers(); + static void resetHandlers(); + + // Disallow instantiation + K3ProcessController(); + ~K3ProcessController(); + + // Disallow assignment and copy-construction + K3ProcessController( const K3ProcessController& ); + K3ProcessController& operator= ( const K3ProcessController& ); + + class Private; + Private * const d; +}; + +#endif + diff --git a/qtermwidget/includes/konsole_wcwidth.h b/qtermwidget/includes/konsole_wcwidth.h new file mode 100644 index 0000000..6f4e46a --- /dev/null +++ b/qtermwidget/includes/konsole_wcwidth.h @@ -0,0 +1,24 @@ +/* $XFree86: xc/programs/xterm/wcwidth.h,v 1.2 2001/06/18 19:09:27 dickey Exp $ */ + +/* Markus Kuhn -- 2001-01-12 -- public domain */ +/* Adaptions for KDE by Waldo Bastian */ +/* + Rewritten for QT4 by e_k +*/ + + +#ifndef _KONSOLE_WCWIDTH_H_ +#define _KONSOLE_WCWIDTH_H_ + +// Qt +#include +#include + +int konsole_wcwidth(quint16 ucs); +#if 0 +int konsole_wcwidth_cjk(Q_UINT16 ucs); +#endif + +int string_width( const QString &txt ); + +#endif diff --git a/qtermwidget/includes/kpty.h b/qtermwidget/includes/kpty.h new file mode 100644 index 0000000..8286834 --- /dev/null +++ b/qtermwidget/includes/kpty.h @@ -0,0 +1,188 @@ +/* This file is part of the KDE libraries + + Copyright (C) 2003,2007 Oswald Buddenhagen + + Rewritten for QT4 by e_k , Copyright (C)2008 + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef kpty_h +#define kpty_h + +#include + +struct KPtyPrivate; +struct termios; + +/** + * Provides primitives for opening & closing a pseudo TTY pair, assigning the + * controlling TTY, utmp registration and setting various terminal attributes. + */ +class KPty { + Q_DECLARE_PRIVATE(KPty) + +public: + + /** + * Constructor + */ + KPty(); + + /** + * Destructor: + * + * If the pty is still open, it will be closed. Note, however, that + * an utmp registration is @em not undone. + */ + ~KPty(); + + /** + * Create a pty master/slave pair. + * + * @return true if a pty pair was successfully opened + */ + bool open(); + + /** + * Close the pty master/slave pair. + */ + void close(); + + /** + * Close the pty slave descriptor. + * + * When creating the pty, KPty also opens the slave and keeps it open. + * Consequently the master will never receive an EOF notification. + * Usually this is the desired behavior, as a closed pty slave can be + * reopened any time - unlike a pipe or socket. However, in some cases + * pipe-alike behavior might be desired. + * + * After this function was called, slaveFd() and setCTty() cannot be + * used. + */ + void closeSlave(); + + /** + * Creates a new session and process group and makes this pty the + * controlling tty. + */ + void setCTty(); + + /** + * Creates an utmp entry for the tty. + * This function must be called after calling setCTty and + * making this pty the stdin. + * @param user the user to be logged on + * @param remotehost the host from which the login is coming. This is + * @em not the local host. For remote logins it should be the hostname + * of the client. For local logins from inside an X session it should + * be the name of the X display. Otherwise it should be empty. + */ + void login(const char *user = 0, const char *remotehost = 0); + + /** + * Removes the utmp entry for this tty. + */ + void logout(); + + /** + * Wrapper around tcgetattr(3). + * + * This function can be used only while the PTY is open. + * You will need an #include <termios.h> to do anything useful + * with it. + * + * @param ttmode a pointer to a termios structure. + * Note: when declaring ttmode, @c struct @c ::termios must be used - + * without the '::' some version of HP-UX thinks, this declares + * the struct in your class, in your method. + * @return @c true on success, false otherwise + */ + bool tcGetAttr(struct ::termios *ttmode) const; + + /** + * Wrapper around tcsetattr(3) with mode TCSANOW. + * + * This function can be used only while the PTY is open. + * + * @param ttmode a pointer to a termios structure. + * @return @c true on success, false otherwise. Note that success means + * that @em at @em least @em one attribute could be set. + */ + bool tcSetAttr(struct ::termios *ttmode); + + /** + * Change the logical (screen) size of the pty. + * The default is 24 lines by 80 columns. + * + * This function can be used only while the PTY is open. + * + * @param lines the number of rows + * @param columns the number of columns + * @return @c true on success, false otherwise + */ + bool setWinSize(int lines, int columns); + + /** + * Set whether the pty should echo input. + * + * Echo is on by default. + * If the output of automatically fed (non-interactive) PTY clients + * needs to be parsed, disabling echo often makes it much simpler. + * + * This function can be used only while the PTY is open. + * + * @param echo true if input should be echoed. + * @return @c true on success, false otherwise + */ + bool setEcho(bool echo); + + /** + * @return the name of the slave pty device. + * + * This function should be called only while the pty is open. + */ + const char *ttyName() const; + + /** + * @return the file descriptor of the master pty + * + * This function should be called only while the pty is open. + */ + int masterFd() const; + + /** + * @return the file descriptor of the slave pty + * + * This function should be called only while the pty slave is open. + */ + int slaveFd() const; + +protected: + /** + * @internal + */ + KPty(KPtyPrivate *d); + + /** + * @internal + */ + KPtyPrivate * const d_ptr; +}; + +#endif + diff --git a/qtermwidget/includes/kpty_p.h b/qtermwidget/includes/kpty_p.h new file mode 100644 index 0000000..1702b44 --- /dev/null +++ b/qtermwidget/includes/kpty_p.h @@ -0,0 +1,44 @@ +/* This file is part of the KDE libraries + + Copyright (C) 2003,2007 Oswald Buddenhagen + + Rewritten for QT4 by e_k , Copyright (C)2008 + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef kpty_p_h +#define kpty_p_h + +#include "kpty.h" + +#include + +struct KPtyPrivate { + Q_DECLARE_PUBLIC(KPty) + + KPtyPrivate(); + bool chownpty(bool grant); + + int masterFd; + int slaveFd; + + QByteArray ttyName; + + KPty *q_ptr; +}; + +#endif diff --git a/qtermwidget/includes/qtermwidget.h b/qtermwidget/includes/qtermwidget.h new file mode 100644 index 0000000..1a11c4d --- /dev/null +++ b/qtermwidget/includes/qtermwidget.h @@ -0,0 +1,108 @@ +/* Copyright (C) 2008 e_k (e_k@users.sourceforge.net) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + + +#ifndef _Q_TERM_WIDGET +#define _Q_TERM_WIDGET + +#include + +struct TermWidgetImpl; + +enum COLOR_SCHEME { COLOR_SCHEME_WHITE_ON_BLACK = 1, + COLOR_SCHEME_GREEN_ON_BLACK, + COLOR_SCHEME_BLACK_ON_LIGHT_YELLOW }; + +class QTermWidget : public QWidget +{ + Q_OBJECT +public: + + enum ScrollBarPosition + { + /** Do not show the scroll bar. */ + NoScrollBar=0, + /** Show the scroll bar on the left side of the display. */ + ScrollBarLeft=1, + /** Show the scroll bar on the right side of the display. */ + ScrollBarRight=2 + }; + + + //Creation of widget + QTermWidget(int startnow = 1, //start shell programm immediatelly + QWidget *parent = 0); + ~QTermWidget(); + + //start shell program if it was not started in constructor + void startShellProgram(); + + //look-n-feel, if you don`t like defaults + + // Terminal font + // Default is application font with family Monospace, size 10 + void setTerminalFont(QFont &font); + + // Shell program, default is /bin/bash + void setShellProgram(QString &progname); + + // Shell program args, default is none + void setArgs(QStringList &args); + + //Text codec, default is UTF-8 + void setTextCodec(QTextCodec *codec); + + //Color scheme, default is white on black + void setColorScheme(int scheme); + + //set size + void setSize(int h, int v); + + // History size for scrolling + void setHistorySize(int lines); //infinite if lines < 0 + + // Presence of scrollbar + void setScrollBarPosition(ScrollBarPosition); + + // Send some text to terminal + void sendText(QString &text); + +signals: + void finished(); + +protected: + virtual void resizeEvent(QResizeEvent *); + +protected slots: + void sessionFinished(); + +private: + void init(); + TermWidgetImpl *m_impl; +}; + + +//Maybe useful, maybe not + +#ifdef __cplusplus +extern "C" +#endif +void *createTermWidget(int startnow, void *parent); + +#endif + diff --git a/qtermwidget/lib/libqtermwidget.a b/qtermwidget/lib/libqtermwidget.a new file mode 100644 index 0000000..48052b5 Binary files /dev/null and b/qtermwidget/lib/libqtermwidget.a differ diff --git a/qtermwidget/lib/libqtermwidget_d.a b/qtermwidget/lib/libqtermwidget_d.a new file mode 100644 index 0000000..ab31e1b Binary files /dev/null and b/qtermwidget/lib/libqtermwidget_d.a differ diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..d1873ce --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,17 @@ +#include +#include +#include "mainwindow.h" + +int main(int argc, char *argv[]) +{ + if(argc<=1) + { + printf("Usage: %s http://siteweb.com/\n",argv[0]); + return -1; + } + + QApplication a(argc, argv); + MainWindow w; + w.show(); + return a.exec(); +} diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp new file mode 100644 index 0000000..3db6778 --- /dev/null +++ b/src/mainwindow.cpp @@ -0,0 +1,279 @@ +#include "mainwindow.h" +#include "mainwindow.moc" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define BUFFERSIZE 2048 + +#define CURRENT_TIME() QDateTime::currentDateTime().toString("dd/MM/yy hh:mm:ss") + +MainWindow::MainWindow(QWidget *parent) + : QMainWindow(parent),web(new QWebView()),text(new QTextEdit()), + process(new QProcess(this)), + logfile(NULL),logstream(NULL) +{ + // Graphic + //layout->addWidget(web); + //layout->addWidget(text); + //setLayout(layout); + setCentralWidget(web); + + dock=new QDockWidget(this); + dock->setAllowedAreas(Qt::BottomDockWidgetArea); + dock->setFeatures(QDockWidget::NoDockWidgetFeatures); + dock->setWidget(text); + addDockWidget(Qt::BottomDockWidgetArea,dock); + + + /* + QTermWidget *console = new QTermWidget(); + + QFont font = QApplication::font(); + font.setFamily("Terminus"); + font.setPointSize(12); + + console->setTerminalFont(font); + + //console->setColorScheme(COLOR_SCHEME_BLACK_ON_LIGHT_YELLOW); + console->setScrollBarPosition(QTermWidget::ScrollBarRight); + + mainWindow->setCentralWidget(console); + mainWindow->resize(802, 610); + + QObject::connect(console, SIGNAL(finished()), mainWindow, SLOT(close())); + */ + //showFullScreen(); + + text->setReadOnly(true); + + web->page()->setLinkDelegationPolicy(QWebPage::DelegateAllLinks); + + // Web signals + connect(web->page(),SIGNAL(linkClicked(const QUrl&)),this, + SLOT(slotLinkHandle(const QUrl&))); + connect(web,SIGNAL(loadStarted()),this,SLOT(slotWebLoadStarted())); + connect(web,SIGNAL(loadFinished(bool)),this,SLOT(slotWebLoadFinished(bool))); + connect(web,SIGNAL(loadProgress(int)),this,SLOT(slotWebLoadProgress(int))); + + QStringList arguments=QCoreApplication::arguments(); + web->load(QUrl(arguments[1])); + + + // Process signals + connect(process,SIGNAL(started()),this,SLOT(slotProcessStarted())); + connect(process,SIGNAL(finished(int,QProcess::ExitStatus)), + this,SLOT(slotProcessFinished(int,QProcess::ExitStatus))); + + connect(process,SIGNAL(error(QProcess::ProcessError)), + this,SLOT(slotProcessError(QProcess::ProcessError))); + + connect(process,SIGNAL(readyReadStandardOutput()),this,SLOT(slotProcessOutput())); + connect(process,SIGNAL(readyReadStandardError()), + this,SLOT(slotProcessErrorOutput())); + + // Set tittle + setWindowTitle(tr("OpenGNSys Browser")); + + if(!readEnvironmentValues()) + text->insertPlainText(tr("Any environment variable/s didn't be setted\n")); + + if(env.contains("OGLOGFILE") && env["OGLOGFILE"]!="") + { + logfile=new QFile(env["OGLOGFILE"]); + if(!logfile->open(QIODevice::WriteOnly | QIODevice::Text | + QIODevice::Append)) + { + text->insertPlainText(tr("The log file couldn't be opened: ")+logfile->fileName()); + delete logfile; + logfile=NULL; + } + else + logstream=new QTextStream(logfile); + } +} + +MainWindow::~MainWindow() +{ + if(logfile) + { + logfile->close(); + delete logfile; + } + if(logstream) + delete logstream; +} + +void MainWindow::slotLinkHandle(const QUrl &url) +{ + QString string = url.toString(); + qDebug() << string; + // Si es un link del tipo PROTOCOL lo ejecutamos + if(string.startsWith(PROTOCOL)) + { + string=string.remove(0,QString(PROTOCOL).length()); + QStringList list=string.split(" ",QString::SkipEmptyParts); + QString command=list.takeFirst(); + process->setReadChannel(QProcess::StandardOutput); + // Le ponemos el mismo entorno que tiene el browser ahora mismo + process->setEnvironment(QProcess::systemEnvironment()); + process->start(command,list); + } + else + { + qDebug() << "Load URL: " << url <load(url); + } +} + +void MainWindow::slotWebLoadStarted() +{ + qDebug()<<"Empieza la carga de la web"; +} + +void MainWindow::slotWebLoadProgress(int progress) +{ + qDebug()<<"Progress "<page()->totalBytes() == 0) + { + qDebug()<<"Error accediendo a la web"; + QMessageBox msgBox; + msgBox.setText(tr("The web page couldn't load. What do you want to do?")); + + QPushButton *reloadButton = msgBox.addButton(tr("Reload"), QMessageBox::ActionRole); + msgBox.addButton(QMessageBox::Abort); + + msgBox.exec(); + + if (msgBox.clickedButton() == reloadButton) + { + web->reload(); + } + else + { + close(); + } + } + else + qDebug()<<"Descarga finalizada satisfactoriamente"; +} + +void MainWindow::slotProcessStarted() +{ + qDebug()<<"Proceso inicializado"<setReadChannel(QProcess::StandardOutput); + char buf[BUFFERSIZE]; + while((process->readLine(buf,BUFFERSIZE) > 0)) + { + text->insertPlainText(buf); + /* + QString str=""; + str+=buf; + str+=""; + text->insertHtml(str); + */ + output<setReadChannel(QProcess::StandardError); + char buf[BUFFERSIZE]; + while((process->readLine(buf,BUFFERSIZE) > 0)) + { + text->insertPlainText(buf); + errors< +#include +#include +#include + +class QWebView; +class QTextEdit; +class QVBoxLayout; +class QProcess; +class QStringList; +class QString; +class QUrl; +class QFile; +class QTextStream; +class QDockWidget; + +class MainWindow : public QMainWindow +{ + Q_OBJECT + + public: + MainWindow(QWidget *parent = 0); + ~MainWindow(); + + public slots: + // Funcion que maneja los links + void slotLinkHandle(const QUrl& url); + void slotWebLoadStarted(); + void slotWebLoadFinished(bool ok); + void slotWebLoadProgress(int progress); + + // Funciones que manejan cada vez que el proceso hace algo + void slotProcessStarted(); + void slotProcessFinished(int code,QProcess::ExitStatus status); + void slotProcessError(QProcess::ProcessError error); + void slotProcessOutput(); + void slotProcessErrorOutput(); + + //Functions + protected: + int readEnvironmentValues(); + + + protected: + QWebView *web; + QTextEdit *text; + QDockWidget *dock; + + QProcess *process; + QStringList output; + QStringList errors; + + QMap env; + QFile *logfile; + QTextStream *logstream; +}; + +#endif // MAINWINDOW_H