├── Doxyfile ├── Makefile ├── README.txt ├── TerminalWx.cbp ├── TestApp.cpp ├── TestApp.h ├── TestMain.cpp ├── TestMain.h ├── lgpl-2.0.txt ├── licence3.txt ├── src ├── GTerm │ ├── actions.cpp │ ├── gterm.cpp │ ├── gterm.hpp │ ├── keytrans.cpp │ ├── states.cpp │ ├── utils.cpp │ └── vt52_states.cpp ├── taTelnet │ ├── wxterm.cpp │ └── wxterm.h ├── terminalinputevent.cpp ├── terminalinputevent.h ├── terminalwx.cpp └── terminalwx.h └── wxsmith └── Testframe.wxs /Makefile: -------------------------------------------------------------------------------- 1 | #------------------------------------------------------------------------------# 2 | # This makefile was generated by 'cbp2make' tool rev.147 # 3 | #------------------------------------------------------------------------------# 4 | 5 | 6 | WORKDIR = `pwd` 7 | 8 | CC = gcc 9 | CXX = g++ 10 | AR = ar 11 | LD = g++ 12 | WINDRES = windres 13 | 14 | INC = 15 | CFLAGS = `wx-config --cflags` -Wall 16 | RESINC = 17 | LIBDIR = 18 | LIB = 19 | LDFLAGS = `wx-config --libs` 20 | 21 | INC_DEBUG = $(INC) 22 | CFLAGS_DEBUG = $(CFLAGS) -g 23 | RESINC_DEBUG = $(RESINC) 24 | RCFLAGS_DEBUG = $(RCFLAGS) 25 | LIBDIR_DEBUG = $(LIBDIR) 26 | LIB_DEBUG = $(LIB) 27 | LDFLAGS_DEBUG = $(LDFLAGS) 28 | OBJDIR_DEBUG = obj/Debug 29 | DEP_DEBUG = 30 | OUT_DEBUG = bin/Debug/TestApp 31 | 32 | INC_RELEASE = $(INC) 33 | CFLAGS_RELEASE = $(CFLAGS) -O2 34 | RESINC_RELEASE = $(RESINC) 35 | RCFLAGS_RELEASE = $(RCFLAGS) 36 | LIBDIR_RELEASE = $(LIBDIR) 37 | LIB_RELEASE = $(LIB) 38 | LDFLAGS_RELEASE = -s $(LDFLAGS) 39 | OBJDIR_RELEASE = obj/Release 40 | DEP_RELEASE = 41 | OUT_RELEASE = bin/Release/TestApp 42 | 43 | OBJ_DEBUG = $(OBJDIR_DEBUG)/src/GTerm/states.o $(OBJDIR_DEBUG)/src/terminalwx.o $(OBJDIR_DEBUG)/src/terminalinputevent.o $(OBJDIR_DEBUG)/src/taTelnet/wxterm.o $(OBJDIR_DEBUG)/src/GTerm/vt52_states.o $(OBJDIR_DEBUG)/src/GTerm/utils.o $(OBJDIR_DEBUG)/TestApp.o $(OBJDIR_DEBUG)/src/GTerm/keytrans.o $(OBJDIR_DEBUG)/src/GTerm/gterm.o $(OBJDIR_DEBUG)/src/GTerm/actions.o $(OBJDIR_DEBUG)/TestMain.o 44 | 45 | OBJ_RELEASE = $(OBJDIR_RELEASE)/src/GTerm/states.o $(OBJDIR_RELEASE)/src/terminalwx.o $(OBJDIR_RELEASE)/src/terminalinputevent.o $(OBJDIR_RELEASE)/src/taTelnet/wxterm.o $(OBJDIR_RELEASE)/src/GTerm/vt52_states.o $(OBJDIR_RELEASE)/src/GTerm/utils.o $(OBJDIR_RELEASE)/TestApp.o $(OBJDIR_RELEASE)/src/GTerm/keytrans.o $(OBJDIR_RELEASE)/src/GTerm/gterm.o $(OBJDIR_RELEASE)/src/GTerm/actions.o $(OBJDIR_RELEASE)/TestMain.o 46 | 47 | all: debug release 48 | 49 | clean: clean_debug clean_release 50 | 51 | before_debug: 52 | test -d bin/Debug || mkdir -p bin/Debug 53 | test -d $(OBJDIR_DEBUG)/src/GTerm || mkdir -p $(OBJDIR_DEBUG)/src/GTerm 54 | test -d $(OBJDIR_DEBUG)/src || mkdir -p $(OBJDIR_DEBUG)/src 55 | test -d $(OBJDIR_DEBUG)/src/taTelnet || mkdir -p $(OBJDIR_DEBUG)/src/taTelnet 56 | test -d $(OBJDIR_DEBUG) || mkdir -p $(OBJDIR_DEBUG) 57 | 58 | after_debug: 59 | 60 | debug: before_debug out_debug after_debug 61 | 62 | out_debug: before_debug $(OBJ_DEBUG) $(DEP_DEBUG) 63 | $(LD) $(LIBDIR_DEBUG) -o $(OUT_DEBUG) $(OBJ_DEBUG) $(LDFLAGS_DEBUG) $(LIB_DEBUG) 64 | 65 | $(OBJDIR_DEBUG)/src/GTerm/states.o: src/GTerm/states.cpp 66 | $(CXX) $(CFLAGS_DEBUG) $(INC_DEBUG) -c src/GTerm/states.cpp -o $(OBJDIR_DEBUG)/src/GTerm/states.o 67 | 68 | $(OBJDIR_DEBUG)/src/terminalwx.o: src/terminalwx.cpp 69 | $(CXX) $(CFLAGS_DEBUG) $(INC_DEBUG) -c src/terminalwx.cpp -o $(OBJDIR_DEBUG)/src/terminalwx.o 70 | 71 | $(OBJDIR_DEBUG)/src/terminalinputevent.o: src/terminalinputevent.cpp 72 | $(CXX) $(CFLAGS_DEBUG) $(INC_DEBUG) -c src/terminalinputevent.cpp -o $(OBJDIR_DEBUG)/src/terminalinputevent.o 73 | 74 | $(OBJDIR_DEBUG)/src/taTelnet/wxterm.o: src/taTelnet/wxterm.cpp 75 | $(CXX) $(CFLAGS_DEBUG) $(INC_DEBUG) -c src/taTelnet/wxterm.cpp -o $(OBJDIR_DEBUG)/src/taTelnet/wxterm.o 76 | 77 | $(OBJDIR_DEBUG)/src/GTerm/vt52_states.o: src/GTerm/vt52_states.cpp 78 | $(CXX) $(CFLAGS_DEBUG) $(INC_DEBUG) -c src/GTerm/vt52_states.cpp -o $(OBJDIR_DEBUG)/src/GTerm/vt52_states.o 79 | 80 | $(OBJDIR_DEBUG)/src/GTerm/utils.o: src/GTerm/utils.cpp 81 | $(CXX) $(CFLAGS_DEBUG) $(INC_DEBUG) -c src/GTerm/utils.cpp -o $(OBJDIR_DEBUG)/src/GTerm/utils.o 82 | 83 | $(OBJDIR_DEBUG)/TestApp.o: TestApp.cpp 84 | $(CXX) $(CFLAGS_DEBUG) $(INC_DEBUG) -c TestApp.cpp -o $(OBJDIR_DEBUG)/TestApp.o 85 | 86 | $(OBJDIR_DEBUG)/src/GTerm/keytrans.o: src/GTerm/keytrans.cpp 87 | $(CXX) $(CFLAGS_DEBUG) $(INC_DEBUG) -c src/GTerm/keytrans.cpp -o $(OBJDIR_DEBUG)/src/GTerm/keytrans.o 88 | 89 | $(OBJDIR_DEBUG)/src/GTerm/gterm.o: src/GTerm/gterm.cpp 90 | $(CXX) $(CFLAGS_DEBUG) $(INC_DEBUG) -c src/GTerm/gterm.cpp -o $(OBJDIR_DEBUG)/src/GTerm/gterm.o 91 | 92 | $(OBJDIR_DEBUG)/src/GTerm/actions.o: src/GTerm/actions.cpp 93 | $(CXX) $(CFLAGS_DEBUG) $(INC_DEBUG) -c src/GTerm/actions.cpp -o $(OBJDIR_DEBUG)/src/GTerm/actions.o 94 | 95 | $(OBJDIR_DEBUG)/TestMain.o: TestMain.cpp 96 | $(CXX) $(CFLAGS_DEBUG) $(INC_DEBUG) -c TestMain.cpp -o $(OBJDIR_DEBUG)/TestMain.o 97 | 98 | clean_debug: 99 | rm -f $(OBJ_DEBUG) $(OUT_DEBUG) 100 | rm -rf bin/Debug 101 | rm -rf $(OBJDIR_DEBUG)/src/GTerm 102 | rm -rf $(OBJDIR_DEBUG)/src 103 | rm -rf $(OBJDIR_DEBUG)/src/taTelnet 104 | rm -rf $(OBJDIR_DEBUG) 105 | 106 | before_release: 107 | test -d bin/Release || mkdir -p bin/Release 108 | test -d $(OBJDIR_RELEASE)/src/GTerm || mkdir -p $(OBJDIR_RELEASE)/src/GTerm 109 | test -d $(OBJDIR_RELEASE)/src || mkdir -p $(OBJDIR_RELEASE)/src 110 | test -d $(OBJDIR_RELEASE)/src/taTelnet || mkdir -p $(OBJDIR_RELEASE)/src/taTelnet 111 | test -d $(OBJDIR_RELEASE) || mkdir -p $(OBJDIR_RELEASE) 112 | 113 | after_release: 114 | 115 | release: before_release out_release after_release 116 | 117 | out_release: before_release $(OBJ_RELEASE) $(DEP_RELEASE) 118 | $(LD) $(LIBDIR_RELEASE) -o $(OUT_RELEASE) $(OBJ_RELEASE) $(LDFLAGS_RELEASE) $(LIB_RELEASE) 119 | 120 | $(OBJDIR_RELEASE)/src/GTerm/states.o: src/GTerm/states.cpp 121 | $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c src/GTerm/states.cpp -o $(OBJDIR_RELEASE)/src/GTerm/states.o 122 | 123 | $(OBJDIR_RELEASE)/src/terminalwx.o: src/terminalwx.cpp 124 | $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c src/terminalwx.cpp -o $(OBJDIR_RELEASE)/src/terminalwx.o 125 | 126 | $(OBJDIR_RELEASE)/src/terminalinputevent.o: src/terminalinputevent.cpp 127 | $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c src/terminalinputevent.cpp -o $(OBJDIR_RELEASE)/src/terminalinputevent.o 128 | 129 | $(OBJDIR_RELEASE)/src/taTelnet/wxterm.o: src/taTelnet/wxterm.cpp 130 | $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c src/taTelnet/wxterm.cpp -o $(OBJDIR_RELEASE)/src/taTelnet/wxterm.o 131 | 132 | $(OBJDIR_RELEASE)/src/GTerm/vt52_states.o: src/GTerm/vt52_states.cpp 133 | $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c src/GTerm/vt52_states.cpp -o $(OBJDIR_RELEASE)/src/GTerm/vt52_states.o 134 | 135 | $(OBJDIR_RELEASE)/src/GTerm/utils.o: src/GTerm/utils.cpp 136 | $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c src/GTerm/utils.cpp -o $(OBJDIR_RELEASE)/src/GTerm/utils.o 137 | 138 | $(OBJDIR_RELEASE)/TestApp.o: TestApp.cpp 139 | $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c TestApp.cpp -o $(OBJDIR_RELEASE)/TestApp.o 140 | 141 | $(OBJDIR_RELEASE)/src/GTerm/keytrans.o: src/GTerm/keytrans.cpp 142 | $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c src/GTerm/keytrans.cpp -o $(OBJDIR_RELEASE)/src/GTerm/keytrans.o 143 | 144 | $(OBJDIR_RELEASE)/src/GTerm/gterm.o: src/GTerm/gterm.cpp 145 | $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c src/GTerm/gterm.cpp -o $(OBJDIR_RELEASE)/src/GTerm/gterm.o 146 | 147 | $(OBJDIR_RELEASE)/src/GTerm/actions.o: src/GTerm/actions.cpp 148 | $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c src/GTerm/actions.cpp -o $(OBJDIR_RELEASE)/src/GTerm/actions.o 149 | 150 | $(OBJDIR_RELEASE)/TestMain.o: TestMain.cpp 151 | $(CXX) $(CFLAGS_RELEASE) $(INC_RELEASE) -c TestMain.cpp -o $(OBJDIR_RELEASE)/TestMain.o 152 | 153 | clean_release: 154 | rm -f $(OBJ_RELEASE) $(OUT_RELEASE) 155 | rm -rf bin/Release 156 | rm -rf $(OBJDIR_RELEASE)/src/GTerm 157 | rm -rf $(OBJDIR_RELEASE)/src 158 | rm -rf $(OBJDIR_RELEASE)/src/taTelnet 159 | rm -rf $(OBJDIR_RELEASE) 160 | 161 | .PHONY: before_debug after_debug clean_debug before_release after_release clean_release 162 | 163 | -------------------------------------------------------------------------------- /README.txt: -------------------------------------------------------------------------------- 1 | This is a wxWidgets Terminal widget conveniently packaged for you. 2 | 3 | For doxygen documentation, see: http://jeremysalwen.github.com/TerminalWx/ 4 | 5 | TerminalWx is taken (with modifications) from the Chameleon IDE (Mark 6 | Erikson), which itself took (with modifications) from taTelnet (Derry 7 | Bryson), which itself took (with modifications) from GTerm (Timothy 8 | Miller). So this code has a bit of history ;). All credit to those 9 | before me, the amount I've contributed is relatively nothing. 10 | 11 | It is offered under the terms of the wxWindows License Version 3.1, 12 | which is basically the LGPL version 2+ with an exception for the 13 | requirement to distribute the source code with binaries. (see 14 | license3.txt for details of the license). 15 | 16 | Dependencies 17 | ----- 18 | 19 | You will need wxgtk version 2.9 or later. 20 | You will also need libwxsmith to compile the test application. 21 | 22 | -------------------------------------------------------------------------------- /TerminalWx.cbp: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 70 | 71 | -------------------------------------------------------------------------------- /TestApp.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | TerminalWx - A wxWidgets terminal widget 3 | Copyright (C) 2012-2013 Jeremy Salwen 4 | 5 | License: wxWindows License Version 3.1 (See the file license3.txt) 6 | 7 | */ 8 | 9 | #include "TestApp.h" 10 | 11 | //(*AppHeaders 12 | #include "TestMain.h" 13 | #include 14 | //*) 15 | 16 | IMPLEMENT_APP(TestApp); 17 | 18 | bool TestApp::OnInit() 19 | { 20 | //(*AppInitialize 21 | bool wxsOK = true; 22 | wxInitAllImageHandlers(); 23 | if ( wxsOK ) 24 | { 25 | TerminalWxFrame* Frame = new TerminalWxFrame(0); 26 | Frame->Show(); 27 | SetTopWindow(Frame); 28 | } 29 | //*) 30 | return wxsOK; 31 | 32 | } 33 | -------------------------------------------------------------------------------- /TestApp.h: -------------------------------------------------------------------------------- 1 | /* 2 | TerminalWx - A wxWidgets terminal widget 3 | Copyright (C) 2012-2013 Jeremy Salwen 4 | 5 | License: wxWindows License Version 3.1 (See the file license3.txt) 6 | 7 | */ 8 | 9 | #ifndef TESTAPP_H 10 | #define TESTAPP_H 11 | 12 | #include 13 | 14 | class TestApp : public wxApp 15 | { 16 | public: 17 | virtual bool OnInit(); 18 | }; 19 | 20 | #endif // TESTAPP_H 21 | -------------------------------------------------------------------------------- /TestMain.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | TerminalWx - A wxWidgets terminal widget 3 | Copyright (C) 2012-2013 Jeremy Salwen 4 | 5 | License: wxWindows License Version 3.1 (See the file license3.txt) 6 | 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | #include "TestMain.h" 15 | #include "src/terminalinputevent.h" 16 | 17 | //(*InternalHeaders(TerminalWxFrame) 18 | #include 19 | #include 20 | //*) 21 | 22 | //helper functions 23 | enum wxbuildinfoformat { 24 | short_f, long_f }; 25 | 26 | wxString wxbuildinfo(wxbuildinfoformat format) 27 | { 28 | wxString wxbuild(wxVERSION_STRING); 29 | 30 | if (format == long_f ) 31 | { 32 | #if defined(__WXMSW__) 33 | wxbuild << _T("-Windows"); 34 | #elif defined(__UNIX__) 35 | wxbuild << _T("-Linux"); 36 | #endif 37 | 38 | #if wxUSE_UNICODE 39 | wxbuild << _T("-Unicode build"); 40 | #else 41 | wxbuild << _T("-ANSI build"); 42 | #endif // wxUSE_UNICODE 43 | } 44 | 45 | return wxbuild; 46 | } 47 | 48 | //(*IdInit(TerminalWxFrame) 49 | const long TerminalWxFrame::ID_TERM = wxNewId(); 50 | const long TerminalWxFrame::idMenuQuit = wxNewId(); 51 | const long TerminalWxFrame::idMenuAbout = wxNewId(); 52 | const long TerminalWxFrame::ID_STATUSBAR1 = wxNewId(); 53 | //*) 54 | 55 | BEGIN_EVENT_TABLE(TerminalWxFrame,wxFrame) 56 | //(*EventTable(TerminalWxFrame) 57 | //*) 58 | END_EVENT_TABLE() 59 | 60 | TerminalWxFrame::TerminalWxFrame(wxWindow* parent,wxWindowID id) 61 | { 62 | //(*Initialize(TerminalWxFrame) 63 | wxMenuItem* MenuItem2; 64 | wxMenuItem* MenuItem1; 65 | wxMenu* Menu1; 66 | wxMenuBar* MenuBar1; 67 | wxMenu* Menu2; 68 | 69 | Create(parent, id, _("Test TerminalWx App"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_STYLE, _T("id")); 70 | Term1 = new TerminalWx(this,ID_TERM,wxPoint(72,56),80,24,_T("ID_TERM")); 71 | MenuBar1 = new wxMenuBar(); 72 | Menu1 = new wxMenu(); 73 | MenuItem1 = new wxMenuItem(Menu1, idMenuQuit, _("Quit\tAlt-F4"), _("Quit the application"), wxITEM_NORMAL); 74 | Menu1->Append(MenuItem1); 75 | MenuBar1->Append(Menu1, _("&File")); 76 | Menu2 = new wxMenu(); 77 | MenuItem2 = new wxMenuItem(Menu2, idMenuAbout, _("About\tF1"), _("Show info about this application"), wxITEM_NORMAL); 78 | Menu2->Append(MenuItem2); 79 | MenuBar1->Append(Menu2, _("Help")); 80 | SetMenuBar(MenuBar1); 81 | StatusBar1 = new wxStatusBar(this, ID_STATUSBAR1, 0, _T("ID_STATUSBAR1")); 82 | int __wxStatusBarWidths_1[1] = { -1 }; 83 | int __wxStatusBarStyles_1[1] = { wxSB_NORMAL }; 84 | StatusBar1->SetFieldsCount(1,__wxStatusBarWidths_1); 85 | StatusBar1->SetStatusStyles(1,__wxStatusBarStyles_1); 86 | SetStatusBar(StatusBar1); 87 | 88 | Connect(idMenuQuit,wxEVT_COMMAND_MENU_SELECTED,(wxObjectEventFunction)&TerminalWxFrame::OnQuit); 89 | Connect(idMenuAbout,wxEVT_COMMAND_MENU_SELECTED,(wxObjectEventFunction)&TerminalWxFrame::OnAbout); 90 | Connect(wxID_ANY,wxEVT_CLOSE_WINDOW,(wxObjectEventFunction)&TerminalWxFrame::OnClose); 91 | //*) 92 | } 93 | 94 | TerminalWxFrame::~TerminalWxFrame() 95 | { 96 | //(*Destroy(TerminalWxFrame) 97 | //*) 98 | } 99 | 100 | void TerminalWxFrame::OnQuit(wxCommandEvent& event) 101 | { 102 | Close(); 103 | } 104 | 105 | void TerminalWxFrame::OnAbout(wxCommandEvent& event) 106 | { 107 | wxString msg = wxbuildinfo(long_f); 108 | wxMessageBox(msg, _("Welcome to...")); 109 | 110 | Term1->DisplayCharsUnsafe(msg); 111 | } 112 | 113 | void TerminalWxFrame::OnClose(wxCloseEvent& event) 114 | { 115 | Destroy(); 116 | } 117 | -------------------------------------------------------------------------------- /TestMain.h: -------------------------------------------------------------------------------- 1 | /* 2 | TerminalWx - A wxWidgets terminal widget 3 | Copyright (C) 2012-2013 Jeremy Salwen 4 | 5 | License: wxWindows License Version 3.1 (See the file license3.txt) 6 | 7 | */ 8 | 9 | #ifndef TESTMAIN_H 10 | #define TESTMAIN_H 11 | 12 | //(*Headers(TerminalWxFrame) 13 | #include 14 | #include 15 | #include 16 | //*) 17 | 18 | #include 19 | #include 20 | 21 | #include "src/terminalwx.h" 22 | 23 | class TerminalWxFrame: public wxFrame 24 | { 25 | public: 26 | 27 | TerminalWxFrame(wxWindow* parent,wxWindowID id = -1); 28 | virtual ~TerminalWxFrame(); 29 | 30 | private: 31 | 32 | //(*Handlers(TerminalWxFrame) 33 | void OnQuit(wxCommandEvent& event); 34 | void OnAbout(wxCommandEvent& event); 35 | void OnClose(wxCloseEvent& event); 36 | void OnCustom1Paint(wxPaintEvent& event); 37 | //*) 38 | 39 | //(*Identifiers(TerminalWxFrame) 40 | static const long ID_TERM; 41 | static const long idMenuQuit; 42 | static const long idMenuAbout; 43 | static const long ID_STATUSBAR1; 44 | //*) 45 | 46 | //(*Declarations(TerminalWxFrame) 47 | wxStatusBar* StatusBar1; 48 | TerminalWx* Term1; 49 | //*) 50 | 51 | DECLARE_EVENT_TABLE() 52 | }; 53 | 54 | #endif // TERMINALWXMAIN_H 55 | -------------------------------------------------------------------------------- /lgpl-2.0.txt: -------------------------------------------------------------------------------- 1 | GNU LIBRARY GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1991 Free Software Foundation, Inc. 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | [This is the first released version of the library GPL. It is 10 | numbered 2 because it goes with version 2 of the ordinary GPL.] 11 | 12 | Preamble 13 | 14 | The licenses for most software are designed to take away your 15 | freedom to share and change it. By contrast, the GNU General Public 16 | Licenses are intended to guarantee your freedom to share and change 17 | free software--to make sure the software is free for all its users. 18 | 19 | This license, the Library General Public License, applies to some 20 | specially designated Free Software Foundation software, and to any 21 | other libraries whose authors decide to use it. You can use it for 22 | your libraries, too. 23 | 24 | When we speak of free software, we are referring to freedom, not 25 | price. Our General Public Licenses are designed to make sure that you 26 | have the freedom to distribute copies of free software (and charge for 27 | this service if you wish), that you receive source code or can get it 28 | if you want it, that you can change the software or use pieces of it 29 | in new free programs; and that you know you can do these things. 30 | 31 | To protect your rights, we need to make restrictions that forbid 32 | anyone to deny you these rights or to ask you to surrender the rights. 33 | These restrictions translate to certain responsibilities for you if 34 | you distribute copies of the library, or if you modify it. 35 | 36 | For example, if you distribute copies of the library, whether gratis 37 | or for a fee, you must give the recipients all the rights that we gave 38 | you. You must make sure that they, too, receive or can get the source 39 | code. If you link a program with the library, you must provide 40 | complete object files to the recipients so that they can relink them 41 | with the library, after making changes to the library and recompiling 42 | it. And you must show them these terms so they know their rights. 43 | 44 | Our method of protecting your rights has two steps: (1) copyright 45 | the library, and (2) offer you this license which gives you legal 46 | permission to copy, distribute and/or modify the library. 47 | 48 | Also, for each distributor's protection, we want to make certain 49 | that everyone understands that there is no warranty for this free 50 | library. If the library is modified by someone else and passed on, we 51 | want its recipients to know that what they have is not the original 52 | version, so that any problems introduced by others will not reflect on 53 | the original authors' reputations. 54 | 55 | Finally, any free program is threatened constantly by software 56 | patents. We wish to avoid the danger that companies distributing free 57 | software will individually obtain patent licenses, thus in effect 58 | transforming the program into proprietary software. To prevent this, 59 | we have made it clear that any patent must be licensed for everyone's 60 | free use or not licensed at all. 61 | 62 | Most GNU software, including some libraries, is covered by the ordinary 63 | GNU General Public License, which was designed for utility programs. This 64 | license, the GNU Library General Public License, applies to certain 65 | designated libraries. This license is quite different from the ordinary 66 | one; be sure to read it in full, and don't assume that anything in it is 67 | the same as in the ordinary license. 68 | 69 | The reason we have a separate public license for some libraries is that 70 | they blur the distinction we usually make between modifying or adding to a 71 | program and simply using it. Linking a program with a library, without 72 | changing the library, is in some sense simply using the library, and is 73 | analogous to running a utility program or application program. However, in 74 | a textual and legal sense, the linked executable is a combined work, a 75 | derivative of the original library, and the ordinary General Public License 76 | treats it as such. 77 | 78 | Because of this blurred distinction, using the ordinary General 79 | Public License for libraries did not effectively promote software 80 | sharing, because most developers did not use the libraries. We 81 | concluded that weaker conditions might promote sharing better. 82 | 83 | However, unrestricted linking of non-free programs would deprive the 84 | users of those programs of all benefit from the free status of the 85 | libraries themselves. This Library General Public License is intended to 86 | permit developers of non-free programs to use free libraries, while 87 | preserving your freedom as a user of such programs to change the free 88 | libraries that are incorporated in them. (We have not seen how to achieve 89 | this as regards changes in header files, but we have achieved it as regards 90 | changes in the actual functions of the Library.) The hope is that this 91 | will lead to faster development of free libraries. 92 | 93 | The precise terms and conditions for copying, distribution and 94 | modification follow. Pay close attention to the difference between a 95 | "work based on the library" and a "work that uses the library". The 96 | former contains code derived from the library, while the latter only 97 | works together with the library. 98 | 99 | Note that it is possible for a library to be covered by the ordinary 100 | General Public License rather than by this special one. 101 | 102 | GNU LIBRARY GENERAL PUBLIC LICENSE 103 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 104 | 105 | 0. This License Agreement applies to any software library which 106 | contains a notice placed by the copyright holder or other authorized 107 | party saying it may be distributed under the terms of this Library 108 | General Public License (also called "this License"). Each licensee is 109 | addressed as "you". 110 | 111 | A "library" means a collection of software functions and/or data 112 | prepared so as to be conveniently linked with application programs 113 | (which use some of those functions and data) to form executables. 114 | 115 | The "Library", below, refers to any such software library or work 116 | which has been distributed under these terms. A "work based on the 117 | Library" means either the Library or any derivative work under 118 | copyright law: that is to say, a work containing the Library or a 119 | portion of it, either verbatim or with modifications and/or translated 120 | straightforwardly into another language. (Hereinafter, translation is 121 | included without limitation in the term "modification".) 122 | 123 | "Source code" for a work means the preferred form of the work for 124 | making modifications to it. For a library, complete source code means 125 | all the source code for all modules it contains, plus any associated 126 | interface definition files, plus the scripts used to control compilation 127 | and installation of the library. 128 | 129 | Activities other than copying, distribution and modification are not 130 | covered by this License; they are outside its scope. The act of 131 | running a program using the Library is not restricted, and output from 132 | such a program is covered only if its contents constitute a work based 133 | on the Library (independent of the use of the Library in a tool for 134 | writing it). Whether that is true depends on what the Library does 135 | and what the program that uses the Library does. 136 | 137 | 1. You may copy and distribute verbatim copies of the Library's 138 | complete source code as you receive it, in any medium, provided that 139 | you conspicuously and appropriately publish on each copy an 140 | appropriate copyright notice and disclaimer of warranty; keep intact 141 | all the notices that refer to this License and to the absence of any 142 | warranty; and distribute a copy of this License along with the 143 | Library. 144 | 145 | You may charge a fee for the physical act of transferring a copy, 146 | and you may at your option offer warranty protection in exchange for a 147 | fee. 148 | 149 | 2. You may modify your copy or copies of the Library or any portion 150 | of it, thus forming a work based on the Library, and copy and 151 | distribute such modifications or work under the terms of Section 1 152 | above, provided that you also meet all of these conditions: 153 | 154 | a) The modified work must itself be a software library. 155 | 156 | b) You must cause the files modified to carry prominent notices 157 | stating that you changed the files and the date of any change. 158 | 159 | c) You must cause the whole of the work to be licensed at no 160 | charge to all third parties under the terms of this License. 161 | 162 | d) If a facility in the modified Library refers to a function or a 163 | table of data to be supplied by an application program that uses 164 | the facility, other than as an argument passed when the facility 165 | is invoked, then you must make a good faith effort to ensure that, 166 | in the event an application does not supply such function or 167 | table, the facility still operates, and performs whatever part of 168 | its purpose remains meaningful. 169 | 170 | (For example, a function in a library to compute square roots has 171 | a purpose that is entirely well-defined independent of the 172 | application. Therefore, Subsection 2d requires that any 173 | application-supplied function or table used by this function must 174 | be optional: if the application does not supply it, the square 175 | root function must still compute square roots.) 176 | 177 | These requirements apply to the modified work as a whole. If 178 | identifiable sections of that work are not derived from the Library, 179 | and can be reasonably considered independent and separate works in 180 | themselves, then this License, and its terms, do not apply to those 181 | sections when you distribute them as separate works. But when you 182 | distribute the same sections as part of a whole which is a work based 183 | on the Library, the distribution of the whole must be on the terms of 184 | this License, whose permissions for other licensees extend to the 185 | entire whole, and thus to each and every part regardless of who wrote 186 | it. 187 | 188 | Thus, it is not the intent of this section to claim rights or contest 189 | your rights to work written entirely by you; rather, the intent is to 190 | exercise the right to control the distribution of derivative or 191 | collective works based on the Library. 192 | 193 | In addition, mere aggregation of another work not based on the Library 194 | with the Library (or with a work based on the Library) on a volume of 195 | a storage or distribution medium does not bring the other work under 196 | the scope of this License. 197 | 198 | 3. You may opt to apply the terms of the ordinary GNU General Public 199 | License instead of this License to a given copy of the Library. To do 200 | this, you must alter all the notices that refer to this License, so 201 | that they refer to the ordinary GNU General Public License, version 2, 202 | instead of to this License. (If a newer version than version 2 of the 203 | ordinary GNU General Public License has appeared, then you can specify 204 | that version instead if you wish.) Do not make any other change in 205 | these notices. 206 | 207 | Once this change is made in a given copy, it is irreversible for 208 | that copy, so the ordinary GNU General Public License applies to all 209 | subsequent copies and derivative works made from that copy. 210 | 211 | This option is useful when you wish to copy part of the code of 212 | the Library into a program that is not a library. 213 | 214 | 4. You may copy and distribute the Library (or a portion or 215 | derivative of it, under Section 2) in object code or executable form 216 | under the terms of Sections 1 and 2 above provided that you accompany 217 | it with the complete corresponding machine-readable source code, which 218 | must be distributed under the terms of Sections 1 and 2 above on a 219 | medium customarily used for software interchange. 220 | 221 | If distribution of object code is made by offering access to copy 222 | from a designated place, then offering equivalent access to copy the 223 | source code from the same place satisfies the requirement to 224 | distribute the source code, even though third parties are not 225 | compelled to copy the source along with the object code. 226 | 227 | 5. A program that contains no derivative of any portion of the 228 | Library, but is designed to work with the Library by being compiled or 229 | linked with it, is called a "work that uses the Library". Such a 230 | work, in isolation, is not a derivative work of the Library, and 231 | therefore falls outside the scope of this License. 232 | 233 | However, linking a "work that uses the Library" with the Library 234 | creates an executable that is a derivative of the Library (because it 235 | contains portions of the Library), rather than a "work that uses the 236 | library". The executable is therefore covered by this License. 237 | Section 6 states terms for distribution of such executables. 238 | 239 | When a "work that uses the Library" uses material from a header file 240 | that is part of the Library, the object code for the work may be a 241 | derivative work of the Library even though the source code is not. 242 | Whether this is true is especially significant if the work can be 243 | linked without the Library, or if the work is itself a library. The 244 | threshold for this to be true is not precisely defined by law. 245 | 246 | If such an object file uses only numerical parameters, data 247 | structure layouts and accessors, and small macros and small inline 248 | functions (ten lines or less in length), then the use of the object 249 | file is unrestricted, regardless of whether it is legally a derivative 250 | work. (Executables containing this object code plus portions of the 251 | Library will still fall under Section 6.) 252 | 253 | Otherwise, if the work is a derivative of the Library, you may 254 | distribute the object code for the work under the terms of Section 6. 255 | Any executables containing that work also fall under Section 6, 256 | whether or not they are linked directly with the Library itself. 257 | 258 | 6. As an exception to the Sections above, you may also compile or 259 | link a "work that uses the Library" with the Library to produce a 260 | work containing portions of the Library, and distribute that work 261 | under terms of your choice, provided that the terms permit 262 | modification of the work for the customer's own use and reverse 263 | engineering for debugging such modifications. 264 | 265 | You must give prominent notice with each copy of the work that the 266 | Library is used in it and that the Library and its use are covered by 267 | this License. You must supply a copy of this License. If the work 268 | during execution displays copyright notices, you must include the 269 | copyright notice for the Library among them, as well as a reference 270 | directing the user to the copy of this License. Also, you must do one 271 | of these things: 272 | 273 | a) Accompany the work with the complete corresponding 274 | machine-readable source code for the Library including whatever 275 | changes were used in the work (which must be distributed under 276 | Sections 1 and 2 above); and, if the work is an executable linked 277 | with the Library, with the complete machine-readable "work that 278 | uses the Library", as object code and/or source code, so that the 279 | user can modify the Library and then relink to produce a modified 280 | executable containing the modified Library. (It is understood 281 | that the user who changes the contents of definitions files in the 282 | Library will not necessarily be able to recompile the application 283 | to use the modified definitions.) 284 | 285 | b) Accompany the work with a written offer, valid for at 286 | least three years, to give the same user the materials 287 | specified in Subsection 6a, above, for a charge no more 288 | than the cost of performing this distribution. 289 | 290 | c) If distribution of the work is made by offering access to copy 291 | from a designated place, offer equivalent access to copy the above 292 | specified materials from the same place. 293 | 294 | d) Verify that the user has already received a copy of these 295 | materials or that you have already sent this user a copy. 296 | 297 | For an executable, the required form of the "work that uses the 298 | Library" must include any data and utility programs needed for 299 | reproducing the executable from it. However, as a special exception, 300 | the source code distributed need not include anything that is normally 301 | distributed (in either source or binary form) with the major 302 | components (compiler, kernel, and so on) of the operating system on 303 | which the executable runs, unless that component itself accompanies 304 | the executable. 305 | 306 | It may happen that this requirement contradicts the license 307 | restrictions of other proprietary libraries that do not normally 308 | accompany the operating system. Such a contradiction means you cannot 309 | use both them and the Library together in an executable that you 310 | distribute. 311 | 312 | 7. You may place library facilities that are a work based on the 313 | Library side-by-side in a single library together with other library 314 | facilities not covered by this License, and distribute such a combined 315 | library, provided that the separate distribution of the work based on 316 | the Library and of the other library facilities is otherwise 317 | permitted, and provided that you do these two things: 318 | 319 | a) Accompany the combined library with a copy of the same work 320 | based on the Library, uncombined with any other library 321 | facilities. This must be distributed under the terms of the 322 | Sections above. 323 | 324 | b) Give prominent notice with the combined library of the fact 325 | that part of it is a work based on the Library, and explaining 326 | where to find the accompanying uncombined form of the same work. 327 | 328 | 8. You may not copy, modify, sublicense, link with, or distribute 329 | the Library except as expressly provided under this License. Any 330 | attempt otherwise to copy, modify, sublicense, link with, or 331 | distribute the Library is void, and will automatically terminate your 332 | rights under this License. However, parties who have received copies, 333 | or rights, from you under this License will not have their licenses 334 | terminated so long as such parties remain in full compliance. 335 | 336 | 9. You are not required to accept this License, since you have not 337 | signed it. However, nothing else grants you permission to modify or 338 | distribute the Library or its derivative works. These actions are 339 | prohibited by law if you do not accept this License. Therefore, by 340 | modifying or distributing the Library (or any work based on the 341 | Library), you indicate your acceptance of this License to do so, and 342 | all its terms and conditions for copying, distributing or modifying 343 | the Library or works based on it. 344 | 345 | 10. Each time you redistribute the Library (or any work based on the 346 | Library), the recipient automatically receives a license from the 347 | original licensor to copy, distribute, link with or modify the Library 348 | subject to these terms and conditions. You may not impose any further 349 | restrictions on the recipients' exercise of the rights granted herein. 350 | You are not responsible for enforcing compliance by third parties to 351 | this License. 352 | 353 | 11. If, as a consequence of a court judgment or allegation of patent 354 | infringement or for any other reason (not limited to patent issues), 355 | conditions are imposed on you (whether by court order, agreement or 356 | otherwise) that contradict the conditions of this License, they do not 357 | excuse you from the conditions of this License. If you cannot 358 | distribute so as to satisfy simultaneously your obligations under this 359 | License and any other pertinent obligations, then as a consequence you 360 | may not distribute the Library at all. For example, if a patent 361 | license would not permit royalty-free redistribution of the Library by 362 | all those who receive copies directly or indirectly through you, then 363 | the only way you could satisfy both it and this License would be to 364 | refrain entirely from distribution of the Library. 365 | 366 | If any portion of this section is held invalid or unenforceable under any 367 | particular circumstance, the balance of the section is intended to apply, 368 | and the section as a whole is intended to apply in other circumstances. 369 | 370 | It is not the purpose of this section to induce you to infringe any 371 | patents or other property right claims or to contest validity of any 372 | such claims; this section has the sole purpose of protecting the 373 | integrity of the free software distribution system which is 374 | implemented by public license practices. Many people have made 375 | generous contributions to the wide range of software distributed 376 | through that system in reliance on consistent application of that 377 | system; it is up to the author/donor to decide if he or she is willing 378 | to distribute software through any other system and a licensee cannot 379 | impose that choice. 380 | 381 | This section is intended to make thoroughly clear what is believed to 382 | be a consequence of the rest of this License. 383 | 384 | 12. If the distribution and/or use of the Library is restricted in 385 | certain countries either by patents or by copyrighted interfaces, the 386 | original copyright holder who places the Library under this License may add 387 | an explicit geographical distribution limitation excluding those countries, 388 | so that distribution is permitted only in or among countries not thus 389 | excluded. In such case, this License incorporates the limitation as if 390 | written in the body of this License. 391 | 392 | 13. The Free Software Foundation may publish revised and/or new 393 | versions of the Library General Public License from time to time. 394 | Such new versions will be similar in spirit to the present version, 395 | but may differ in detail to address new problems or concerns. 396 | 397 | Each version is given a distinguishing version number. If the Library 398 | specifies a version number of this License which applies to it and 399 | "any later version", you have the option of following the terms and 400 | conditions either of that version or of any later version published by 401 | the Free Software Foundation. If the Library does not specify a 402 | license version number, you may choose any version ever published by 403 | the Free Software Foundation. 404 | 405 | 14. If you wish to incorporate parts of the Library into other free 406 | programs whose distribution conditions are incompatible with these, 407 | write to the author to ask for permission. For software which is 408 | copyrighted by the Free Software Foundation, write to the Free 409 | Software Foundation; we sometimes make exceptions for this. Our 410 | decision will be guided by the two goals of preserving the free status 411 | of all derivatives of our free software and of promoting the sharing 412 | and reuse of software generally. 413 | 414 | NO WARRANTY 415 | 416 | 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO 417 | WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. 418 | EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR 419 | OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY 420 | KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE 421 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 422 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE 423 | LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME 424 | THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 425 | 426 | 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN 427 | WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY 428 | AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU 429 | FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR 430 | CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE 431 | LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING 432 | RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A 433 | FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF 434 | SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 435 | DAMAGES. 436 | 437 | END OF TERMS AND CONDITIONS 438 | 439 | How to Apply These Terms to Your New Libraries 440 | 441 | If you develop a new library, and you want it to be of the greatest 442 | possible use to the public, we recommend making it free software that 443 | everyone can redistribute and change. You can do so by permitting 444 | redistribution under these terms (or, alternatively, under the terms of the 445 | ordinary General Public License). 446 | 447 | To apply these terms, attach the following notices to the library. It is 448 | safest to attach them to the start of each source file to most effectively 449 | convey the exclusion of warranty; and each file should have at least the 450 | "copyright" line and a pointer to where the full notice is found. 451 | 452 | 453 | Copyright (C) 454 | 455 | This library is free software; you can redistribute it and/or 456 | modify it under the terms of the GNU Library General Public 457 | License as published by the Free Software Foundation; either 458 | version 2 of the License, or (at your option) any later version. 459 | 460 | This library is distributed in the hope that it will be useful, 461 | but WITHOUT ANY WARRANTY; without even the implied warranty of 462 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 463 | Library General Public License for more details. 464 | 465 | You should have received a copy of the GNU Library General Public 466 | License along with this library; if not, write to the Free Software 467 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 468 | 469 | Also add information on how to contact you by electronic and paper mail. 470 | 471 | You should also get your employer (if you work as a programmer) or your 472 | school, if any, to sign a "copyright disclaimer" for the library, if 473 | necessary. Here is a sample; alter the names: 474 | 475 | Yoyodyne, Inc., hereby disclaims all copyright interest in the 476 | library `Frob' (a library for tweaking knobs) written by James Random Hacker. 477 | 478 | , 1 April 1990 479 | Ty Coon, President of Vice 480 | 481 | That's all there is to it! 482 | -------------------------------------------------------------------------------- /licence3.txt: -------------------------------------------------------------------------------- 1 | wxWindows Library Licence, Version 3.1 2 | ====================================== 3 | 4 | Copyright (C) 1998-2005 Julian Smart, Robert Roebling et al 5 | 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this licence document, but changing it is not allowed. 8 | 9 | WXWINDOWS LIBRARY LICENCE 10 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 11 | 12 | This library is free software; you can redistribute it and/or modify it 13 | under the terms of the GNU Library General Public Licence as published by 14 | the Free Software Foundation; either version 2 of the Licence, or (at 15 | your option) any later version. 16 | 17 | This library is distributed in the hope that it will be useful, but 18 | WITHOUT ANY WARRANTY; without even the implied warranty of 19 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library 20 | General Public Licence for more details. 21 | 22 | You should have received a copy of the GNU Library General Public Licence 23 | along with this software, usually in a file named COPYING.LIB. If not, 24 | write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, 25 | Boston, MA 02111-1307 USA. 26 | 27 | EXCEPTION NOTICE 28 | 29 | 1. As a special exception, the copyright holders of this library give 30 | permission for additional uses of the text contained in this release of 31 | the library as licenced under the wxWindows Library Licence, applying 32 | either version 3.1 of the Licence, or (at your option) any later version of 33 | the Licence as published by the copyright holders of version 34 | 3.1 of the Licence document. 35 | 36 | 2. The exception is that you may use, copy, link, modify and distribute 37 | under your own terms, binary object code versions of works based 38 | on the Library. 39 | 40 | 3. If you copy code from files distributed under the terms of the GNU 41 | General Public Licence or the GNU Library General Public Licence into a 42 | copy of this library, as this licence permits, the exception does not 43 | apply to the code that you add in this way. To avoid misleading anyone as 44 | to the status of such modified files, you must delete this exception 45 | notice from such code and/or adjust the licensing conditions notice 46 | accordingly. 47 | 48 | 4. If you write modifications of your own for this library, it is your 49 | choice whether to permit this exception to apply to your modifications. 50 | If you do not wish that, you must delete the exception notice from such 51 | code and/or adjust the licensing conditions notice accordingly. 52 | 53 | 54 | -------------------------------------------------------------------------------- /src/GTerm/actions.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | TerminalWx - A wxWidgets terminal widget 3 | Copyright (C) 1999 Timothy Miller 4 | 2004 Mark Erikson 5 | 2012-2013 Jeremy Salwen 6 | 7 | License: wxWindows License Version 3.1 (See the file license3.txt) 8 | 9 | */ 10 | 11 | #include "gterm.hpp" 12 | 13 | 14 | // For efficiency, this grabs all printing characters from buffer, up to 15 | // the end of the line or end of buffer 16 | void GTerm::normal_input() 17 | { 18 | int n, n_taken, i, c, y; 19 | #if 0 20 | char str[100]; 21 | #endif 22 | 23 | #define IS_CTRL_CHAR(c) ((c)<32 || (c) ==127) 24 | 25 | if (IS_CTRL_CHAR(*input_data)) return; 26 | 27 | if (cursor_x >= width) { 28 | if (mode_flags & NOEOLWRAP) { 29 | cursor_x = width-1; 30 | } else { 31 | next_line(); 32 | } 33 | } 34 | 35 | n = 0; 36 | if (mode_flags & NOEOLWRAP) { 37 | while (!IS_CTRL_CHAR(input_data[n]) && n=width) n = width-cursor_x; 40 | } else { 41 | while (!IS_CTRL_CHAR(input_data[n]) && n=cursor_x+n; i--) { 59 | text[y+i] = text[y+i-n]; 60 | color[y+i] = color[y+i-n]; 61 | } 62 | 63 | c = calc_color(fg_color, bg_color, mode_flags); 64 | for (i=0; i0) move_cursor(cursor_x-1, cursor_y); 114 | if (mode_flags & DESTRUCTBS) { 115 | clear_area(cursor_x, cursor_y, cursor_x, cursor_y); 116 | } 117 | } 118 | 119 | void GTerm::bell() 120 | { 121 | Bell(); 122 | } 123 | 124 | void GTerm::clear_param() 125 | { 126 | nparam = 0; 127 | memset(param, 0, sizeof(param)); 128 | q_mode = 0; 129 | got_param = 0; 130 | } 131 | 132 | void GTerm::keypad_numeric() { clear_mode_flag(KEYAPPMODE); } 133 | void GTerm::keypad_application() { set_mode_flag(KEYAPPMODE); } 134 | 135 | void GTerm::save_cursor() 136 | { 137 | save_attrib = mode_flags; 138 | save_x = cursor_x; 139 | save_y = cursor_y; 140 | } 141 | 142 | void GTerm::restore_cursor() 143 | { 144 | mode_flags = (mode_flags & ~15) | (save_attrib & 15); 145 | move_cursor(save_x, save_y); 146 | } 147 | 148 | void GTerm::set_tab() 149 | { 150 | tab_stops[cursor_x] = 1; 151 | } 152 | 153 | void GTerm::index_down() 154 | { 155 | lf(); 156 | } 157 | 158 | void GTerm::next_line() 159 | { 160 | lf(); cr(); 161 | } 162 | 163 | void GTerm::index_up() 164 | { 165 | if (cursor_y > scroll_top) { 166 | move_cursor(cursor_x, cursor_y-1); 167 | } else { 168 | scroll_region(scroll_top, scroll_bot, -1); 169 | } 170 | } 171 | 172 | void GTerm::reset() 173 | { 174 | int i; 175 | 176 | pending_scroll = 0; 177 | bg_color = 0; 178 | fg_color = 7; 179 | scroll_top = 0; 180 | scroll_bot = height-1; 181 | for (i=0; i=width) x = width-1; 234 | move_cursor(x, cursor_y); 235 | } 236 | 237 | void GTerm::cursor_up() 238 | { 239 | int n, y; 240 | n = param[0]; if (n<1) n = 1; 241 | y = cursor_y-n; if (y<0) y = 0; 242 | move_cursor(cursor_x, y); 243 | } 244 | 245 | void GTerm::cursor_down() 246 | { 247 | int n, y; 248 | n = param[0]; if (n<1) n = 1; 249 | y = cursor_y+n; if (y>=height) y = height-1; 250 | move_cursor(cursor_x, y); 251 | } 252 | 253 | void GTerm::cursor_position() 254 | { 255 | int x, y; 256 | x = param[1]; if (x<1) x=1; 257 | y = param[0]; if (y<1) y=1; 258 | if (mode_flags & CURSORRELATIVE) { 259 | move_cursor(x-1, y-1+scroll_top); 260 | } else { 261 | move_cursor(x-1, y-1); 262 | } 263 | } 264 | 265 | void GTerm::device_attrib() 266 | { 267 | char *str = "\033[?1;2c"; 268 | ProcessOutput(strlen(str), (unsigned char *)str); 269 | } 270 | 271 | void GTerm::delete_char() 272 | { 273 | int n, mx; 274 | n = param[0]; if (n<1) n = 1; 275 | mx = width-cursor_x; 276 | if (n>=mx) { 277 | clear_area(cursor_x, cursor_y, width-1, cursor_y); 278 | } else { 279 | shift_text(cursor_y, cursor_x, width-1, -n); 280 | } 281 | } 282 | 283 | void GTerm::set_mode() // h 284 | { 285 | switch (param[0] + 1000*q_mode) { 286 | case 1007: clear_mode_flag(NOEOLWRAP); break; 287 | case 1001: set_mode_flag(CURSORAPPMODE); break; 288 | case 1006: set_mode_flag(CURSORRELATIVE); break; 289 | case 4: set_mode_flag(INSERT); break; 290 | case 1003: RequestSizeChange(132, height); break; 291 | case 20: set_mode_flag(NEWLINE); break; 292 | case 12: clear_mode_flag(LOCALECHO); break; 293 | case 1025: 294 | clear_mode_flag(CURSORINVISIBLE); 295 | move_cursor(cursor_x, cursor_y); 296 | break; 297 | } 298 | } 299 | 300 | void GTerm::clear_mode() // l 301 | { 302 | switch (param[0] + 1000*q_mode) { 303 | case 1007: set_mode_flag(NOEOLWRAP); break; 304 | case 1001: clear_mode_flag(CURSORAPPMODE); break; 305 | case 1006: clear_mode_flag(CURSORRELATIVE); break; 306 | case 4: clear_mode_flag(INSERT); break; 307 | case 1003: RequestSizeChange(80, height); break; 308 | case 20: clear_mode_flag(NEWLINE); break; 309 | case 1002: current_state = vt52_normal_state; break; 310 | case 12: set_mode_flag(LOCALECHO); break; 311 | case 1025: 312 | set_mode_flag(CURSORINVISIBLE); break; 313 | move_cursor(cursor_x, cursor_y); 314 | break; 315 | } 316 | } 317 | 318 | void GTerm::request_param() 319 | { 320 | char str[40]; 321 | sprintf(str, "\033[%d;1;1;120;120;1;0x", param[0]+2); 322 | ProcessOutput(strlen(str), (unsigned char *)str); 323 | } 324 | 325 | void GTerm::set_margins() 326 | { 327 | int t, b; 328 | 329 | t = param[0]; 330 | if (t<1) t = 1; 331 | b = param[1]; 332 | if (b<1) b = height; 333 | 334 | if (pending_scroll) update_changes(); 335 | 336 | scroll_top = t-1; 337 | scroll_bot = b-1; 338 | if (cursor_y < scroll_top) move_cursor(cursor_x, scroll_top); 339 | if (cursor_y > scroll_bot) move_cursor(cursor_x, scroll_bot); 340 | } 341 | 342 | void GTerm::delete_line() 343 | { 344 | int n, mx; 345 | n = param[0]; if (n<1) n = 1; 346 | mx = scroll_bot-cursor_y+1; 347 | if (n>=mx) { 348 | clear_area(0, cursor_y, width-1, scroll_bot); 349 | } else { 350 | scroll_region(cursor_y, scroll_bot, n); 351 | } 352 | } 353 | 354 | void GTerm::status_report() 355 | { 356 | char str[20]; 357 | if (param[0] == 5) { 358 | char *str = "\033[0n"; 359 | ProcessOutput(strlen(str), (unsigned char *)str); 360 | } else if (param[0] == 6) { 361 | sprintf(str, "\033[%d;%dR", cursor_y+1, cursor_x+1); 362 | ProcessOutput(strlen(str), (unsigned char *)str); 363 | } 364 | } 365 | 366 | void GTerm::erase_display() 367 | { 368 | switch (param[0]) { 369 | case 0: 370 | clear_area(cursor_x, cursor_y, width-1, cursor_y); 371 | if (cursor_y0) 377 | clear_area(0, 0, width-1, cursor_y-1); 378 | break; 379 | case 2: 380 | clear_area(0, 0, width-1, height-1); 381 | break; 382 | } 383 | } 384 | 385 | void GTerm::erase_line() 386 | { 387 | switch (param[0]) { 388 | case 0: 389 | clear_area(cursor_x, cursor_y, width-1, cursor_y); 390 | break; 391 | case 1: 392 | clear_area(0, cursor_y, cursor_x, cursor_y); 393 | break; 394 | case 2: 395 | clear_area(0, cursor_y, width-1, cursor_y); 396 | break; 397 | } 398 | } 399 | 400 | void GTerm::insert_line() 401 | { 402 | int n, mx; 403 | n = param[0]; if (n<1) n = 1; 404 | mx = scroll_bot-cursor_y+1; 405 | if (n>=mx) { 406 | clear_area(0, cursor_y, width-1, scroll_bot); 407 | } else { 408 | scroll_region(cursor_y, scroll_bot, -n); 409 | } 410 | } 411 | 412 | void GTerm::set_colors() 413 | { 414 | int n; 415 | 416 | if (!nparam && param[0] == 0) { 417 | clear_mode_flag(15); 418 | fg_color = 7; 419 | bg_color = 0; 420 | return; 421 | } 422 | 423 | for (n=0; n<=nparam; n++) { 424 | if (param[n]/10 == 4) { 425 | bg_color = param[n]%10; 426 | } else if (param[n]/10 == 3) { 427 | fg_color = param[n]%10; 428 | } else switch (param[n]) { 429 | case 0: 430 | clear_mode_flag(15); 431 | fg_color = 7; 432 | bg_color = 0; 433 | break; 434 | case 1: 435 | set_mode_flag(BOLD); 436 | break; 437 | case 4: 438 | set_mode_flag(UNDERLINE); 439 | break; 440 | case 5: 441 | set_mode_flag(BLINK); 442 | break; 443 | case 7: 444 | set_mode_flag(INVERSE); 445 | break; 446 | } 447 | } 448 | } 449 | 450 | void GTerm::clear_tab() 451 | { 452 | if (param[0] == 3) { 453 | memset(tab_stops, 0, sizeof(tab_stops)); 454 | } else if (param[0] == 0) { 455 | tab_stops[cursor_x] = 0; 456 | } 457 | } 458 | 459 | void GTerm::insert_char() 460 | { 461 | int n, mx; 462 | n = param[0]; if (n<1) n = 1; 463 | mx = width-cursor_x; 464 | if (n>=mx) { 465 | clear_area(cursor_x, cursor_y, width-1, cursor_y); 466 | } else { 467 | shift_text(cursor_y, cursor_x, width-1, n); 468 | } 469 | } 470 | 471 | void GTerm::screen_align() 472 | { 473 | int y, yp, x, c; 474 | 475 | c = calc_color(7, 0, 0); 476 | for (y=0; ymx) n = mx; 492 | clear_area(cursor_x, cursor_y, cursor_x+n-1, cursor_y); 493 | } 494 | 495 | void GTerm::vt52_cursory() 496 | { 497 | // store y coordinate 498 | param[0] = (*input_data) - 32; 499 | if (param[0]<0) param[0] = 0; 500 | if (param[0]>=height) param[0] = height-1; 501 | } 502 | 503 | void GTerm::vt52_cursorx() 504 | { 505 | int x; 506 | x = (*input_data)-32; 507 | if (x<0) x = 0; 508 | if (x>=width) x = width-1; 509 | move_cursor(x, param[0]); 510 | } 511 | 512 | void GTerm::vt52_ident() 513 | { 514 | char *str = "\033/Z"; 515 | ProcessOutput(strlen(str), (unsigned char *)str); 516 | } 517 | 518 | 519 | #ifdef GTERM_PC 520 | 521 | void GTerm::pc_begin(void) 522 | { 523 | //printf("pc_begin...\n"); 524 | set_mode_flag(PC); 525 | //printf("pc_begin: mode_flags = %x\n", mode_flags); 526 | ProcessOutput((unsigned int)strlen(pc_machinename) + 1, (unsigned char *)pc_machinename); 527 | pc_oldWidth = Width(); 528 | pc_oldHeight = Height(); 529 | ResizeTerminal(80, 25); 530 | update_changes(); 531 | } 532 | 533 | void GTerm::pc_end(void) 534 | { 535 | // printf("pc_end...\n"); 536 | clear_mode_flag(PC); 537 | ResizeTerminal(pc_oldWidth, pc_oldHeight); 538 | update_changes(); 539 | } 540 | 541 | void GTerm::pc_cmd(void) 542 | { 543 | pc_curcmd = *input_data; 544 | //printf("pc_cmd: pc_curcmd = %d...\n", pc_curcmd); 545 | pc_argcount = 0; 546 | switch(pc_curcmd) 547 | { 548 | case GTERM_PC_CMD_CURONOFF : // 549 | pc_numargs = 1; 550 | break; 551 | 552 | case GTERM_PC_CMD_MOVECURSOR : // 553 | pc_numargs = 2; 554 | break; 555 | 556 | case GTERM_PC_CMD_PUTTEXT : // 557 | pc_numargs = 4; 558 | break; 559 | 560 | case GTERM_PC_CMD_WRITE : // 561 | pc_numargs = 4; 562 | break; 563 | 564 | case GTERM_PC_CMD_MOVETEXT : // 565 | pc_numargs = 6; 566 | break; 567 | 568 | case GTERM_PC_CMD_BEEP : 569 | Bell(); 570 | break; 571 | 572 | case GTERM_PC_CMD_SELECTPRINTER : 573 | pc_numargs = 1; 574 | break; 575 | 576 | case GTERM_PC_CMD_PRINTCHAR : 577 | pc_numargs = 1; 578 | break; 579 | 580 | case GTERM_PC_CMD_PRINTCHARS : 581 | pc_numargs = 2; 582 | break; 583 | 584 | default : 585 | current_state = pc_cmd_state; 586 | break; 587 | } 588 | } 589 | 590 | void GTerm::pc_arg(void) 591 | { 592 | int 593 | i, 594 | yp, 595 | yp2; 596 | 597 | //printf("pc_arg: pc_curcmd = %d...\n", pc_curcmd); 598 | 599 | pc_args[pc_argcount++] = *input_data; 600 | if(pc_argcount == pc_numargs) 601 | { 602 | switch(pc_curcmd) 603 | { 604 | case GTERM_PC_CMD_CURONOFF : 605 | //printf("pc_arg: curonoff got %d\n", *input_data); 606 | if(*input_data) 607 | clear_mode_flag(CURSORINVISIBLE); 608 | else 609 | set_mode_flag(CURSORINVISIBLE); 610 | current_state = pc_cmd_state; 611 | changed_line(cursor_y, cursor_x, cursor_x); 612 | break; 613 | 614 | case GTERM_PC_CMD_MOVECURSOR : 615 | //printf("pc_arg: movecursor (%d, %d)\n", pc_args[0], pc_args[1]); 616 | move_cursor(pc_args[0], pc_args[1]); 617 | current_state = pc_cmd_state; 618 | break; 619 | 620 | case GTERM_PC_CMD_PUTTEXT : 621 | //printf("pc_arg: puttext got %d, %d, %d, %d\n", pc_args[0], pc_args[1], pc_args[2], pc_args[3]); 622 | pc_numdata = pc_args[2] * pc_args[3] * 2; 623 | pc_datacount = 0; 624 | pc_curx = pc_args[0]; 625 | pc_cury = pc_args[1]; 626 | if(pc_numdata) 627 | current_state = pc_data_state; 628 | else 629 | current_state = pc_cmd_state; 630 | break; 631 | 632 | case GTERM_PC_CMD_WRITE : 633 | //printf("pc_arg: write got %d, %d, %d, %d\n", pc_args[0], pc_args[1], pc_args[2], pc_args[3]); 634 | pc_numdata = pc_args[2]; 635 | pc_datacount = 0; 636 | pc_curx = pc_args[0]; 637 | pc_cury = pc_args[1]; 638 | if(pc_numdata) 639 | current_state = pc_data_state; 640 | else 641 | current_state = pc_cmd_state; 642 | break; 643 | 644 | case GTERM_PC_CMD_MOVETEXT : // 645 | if(pc_args[1] < pc_args[5]) 646 | { 647 | for(i = 0; i < pc_args[3]; i++) 648 | { 649 | yp = linenumbers[pc_args[1] + i] * MAXWIDTH; 650 | yp2 = linenumbers[pc_args[5] + i] * MAXWIDTH; 651 | memmove(&text[yp2 + pc_args[4]], &text[yp + pc_args[0]], pc_args[2]); 652 | memmove(&color[yp2 + pc_args[4]], &color[yp + pc_args[0]], pc_args[2]); 653 | changed_line(pc_args[5] + i, pc_args[4], pc_args[4] + pc_args[2] - 1); 654 | } 655 | } 656 | else 657 | { 658 | for(i = pc_args[3] - 1; i >= 0; i--) 659 | { 660 | yp = linenumbers[pc_args[1] + i] * MAXWIDTH; 661 | yp2 = linenumbers[pc_args[5] + i] * MAXWIDTH; 662 | memmove(&text[yp2 + pc_args[4]], &text[yp + pc_args[0]], pc_args[2]); 663 | memmove(&color[yp2 + pc_args[4]], &color[yp + pc_args[0]], pc_args[2]); 664 | changed_line(pc_args[5] + i, pc_args[4], pc_args[4] + pc_args[2] - 1); 665 | } 666 | } 667 | current_state = pc_cmd_state; 668 | break; 669 | 670 | case GTERM_PC_CMD_SELECTPRINTER : 671 | pc_numdata = pc_args[0]; 672 | pc_datacount = 0; 673 | memset(pc_printername, 0, sizeof(pc_printername)); 674 | if(pc_numdata) 675 | current_state = pc_data_state; 676 | else 677 | { 678 | SelectPrinter(""); 679 | current_state = pc_cmd_state; 680 | } 681 | break; 682 | 683 | case GTERM_PC_CMD_PRINTCHAR : 684 | PrintChars(1, &pc_args[0]); 685 | current_state = pc_cmd_state; 686 | break; 687 | 688 | case GTERM_PC_CMD_PRINTCHARS : 689 | pc_numdata = (pc_args[0] << 8) + pc_args[1]; 690 | pc_datacount = 0; 691 | if(pc_numdata) 692 | current_state = pc_data_state; 693 | else 694 | current_state = pc_cmd_state; 695 | break; 696 | } 697 | } 698 | } 699 | 700 | void GTerm::pc_data(void) 701 | { 702 | int 703 | yp; 704 | 705 | //printf("pc_data: pc_curcmd = %d, pc_datacount = %d, pc_numdata = %d, pc_curx = %d, pc_cur_y = %d...\n", pc_curcmd, pc_datacount, pc_numdata, pc_curx, pc_cury); 706 | switch(pc_curcmd) 707 | { 708 | case GTERM_PC_CMD_PUTTEXT : 709 | yp = linenumbers[pc_cury] * MAXWIDTH; 710 | if(!(pc_datacount & 1)) 711 | { 712 | //printf("pc_data: got char %d\n", *input_data); 713 | text[yp + pc_curx] = *input_data; 714 | } 715 | else 716 | { 717 | //printf("pc_data: got attr %d\n", *input_data); 718 | color[yp + pc_curx] = *input_data << 4; 719 | } 720 | if(pc_datacount & 1) 721 | { 722 | changed_line(pc_cury, pc_args[0], pc_curx); 723 | pc_curx++; 724 | if(pc_curx == pc_args[0] + pc_args[2]) 725 | { 726 | pc_curx = pc_args[0]; 727 | pc_cury++; 728 | } 729 | } 730 | break; 731 | 732 | case GTERM_PC_CMD_WRITE : 733 | yp = linenumbers[pc_cury] * MAXWIDTH; 734 | text[yp + pc_curx] = *input_data; 735 | color[yp + pc_curx] = (unsigned short)pc_args[3] << 4; 736 | changed_line(pc_cury, pc_args[0], pc_curx); 737 | pc_curx++; 738 | break; 739 | 740 | case GTERM_PC_CMD_SELECTPRINTER : 741 | if(pc_datacount < GTERM_PC_MAXPRINTERNAME - 1) 742 | pc_printername[pc_datacount] = *input_data; 743 | if(pc_datacount == pc_numdata - 1) 744 | SelectPrinter(pc_printername); 745 | break; 746 | 747 | case GTERM_PC_CMD_PRINTCHARS : 748 | PrintChars(1, input_data); 749 | break; 750 | } 751 | 752 | pc_datacount++; 753 | if(pc_datacount == pc_numdata) 754 | current_state = pc_cmd_state; 755 | } 756 | 757 | #endif // GTERM_PC 758 | -------------------------------------------------------------------------------- /src/GTerm/gterm.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | TerminalWx - A wxWidgets terminal widget 3 | Copyright (C) 1999 Timothy Miller 4 | 2004 Mark Erikson 5 | 2012-2013 Jeremy Salwen 6 | 7 | License: wxWindows License Version 3.1 (See the file license3.txt) 8 | 9 | */ 10 | 11 | #ifdef __GNUG__ 12 | #pragma implementation "gterm.hpp" 13 | #endif 14 | 15 | #include "gterm.hpp" 16 | #include 17 | 18 | using namespace std; 19 | 20 | void GTerm::Update() 21 | { 22 | update_changes(); 23 | } 24 | 25 | void GTerm::ProcessInput(int len, unsigned char *data) 26 | { 27 | //printf("ProcessInput called...\n"); 28 | int i; 29 | StateOption *last_state; 30 | 31 | data_len = len; 32 | input_data = data; 33 | 34 | while (data_len) { 35 | //printf("ProcessInput() processing %d...\n", *input_data); 36 | i = 0; 37 | while (current_state[i].byte != -1 && 38 | current_state[i].byte != *input_data) i++; 39 | 40 | // action must be allowed to redirect state change 41 | last_state = current_state+i; 42 | current_state = last_state->next_state; 43 | if (last_state->action) 44 | (this->*(last_state->action))(); 45 | input_data++; 46 | data_len--; 47 | } 48 | 49 | if (!(mode_flags & DEFERUPDATE) || 50 | (pending_scroll > scroll_bot-scroll_top)) update_changes(); 51 | } 52 | 53 | void GTerm::Reset() 54 | { 55 | reset(); 56 | } 57 | 58 | void GTerm::ExposeArea(int x, int y, int w, int h) 59 | { 60 | int i; 61 | for (i=0; i= height) scroll_top = 0; 74 | cx = min(width-1, cursor_x); 75 | cy = min(height-1, cursor_y); 76 | move_cursor(cx, cy); 77 | } 78 | 79 | GTerm::GTerm(int w, int h) : width(w), height(h) 80 | { 81 | int i; 82 | 83 | doing_update = 0; 84 | 85 | // could make this dynamic 86 | text = new unsigned char[MAXWIDTH*MAXHEIGHT]; 87 | color = new unsigned short[MAXWIDTH*MAXHEIGHT]; 88 | 89 | for (i=0; i= 0 && x < Width() && y >= 0 && y < Height()) 133 | return color[(linenumbers[y] * MAXWIDTH) + x] & SELECTED; 134 | return 0; 135 | } 136 | 137 | void 138 | GTerm::Select(int x, int y, int select) 139 | { 140 | if(color && x >= 0 && x < Width() && y >= 0 && y < Height()) 141 | { 142 | if(select) 143 | color[(linenumbers[y] * MAXWIDTH) + x] |= SELECTED; 144 | else 145 | color[(linenumbers[y] * MAXWIDTH) + x] &= ~SELECTED; 146 | changed_line(y, x, x); 147 | // update_changes(); 148 | } 149 | } 150 | 151 | unsigned char 152 | GTerm::GetChar(int x, int y) 153 | { 154 | if(text && x >= 0 && x < Width() && y >= 0 && y < Height()) 155 | return text[(linenumbers[y] * MAXWIDTH) + x]; 156 | 157 | return 0; 158 | } 159 | 160 | 161 | 162 | -------------------------------------------------------------------------------- /src/GTerm/gterm.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | TerminalWx - A wxWidgets terminal widget 3 | Copyright (C) 1999 Timothy Miller 4 | 2004 Mark Erikson 5 | 2012-2013 Jeremy Salwen 6 | 7 | License: wxWindows License Version 3.1 (See the file license3.txt) 8 | 9 | */ 10 | 11 | #ifndef INCLUDED_GTERM_H 12 | #define INCLUDED_GTERM_H 13 | 14 | #ifdef __GNUG__ 15 | #pragma interface 16 | #endif 17 | 18 | #include 19 | #include 20 | #include 21 | 22 | #define MAXWIDTH 200 23 | #define MAXHEIGHT 100 24 | 25 | 26 | #define GTERM_PC 27 | 28 | 29 | class GTerm; 30 | typedef void (GTerm::*StateFunc)(); 31 | 32 | struct StateOption { 33 | int byte; // char value to look for; -1==end/default 34 | StateFunc action; 35 | StateOption *next_state; 36 | }; 37 | 38 | class GTerm { 39 | public: 40 | // mode flags 41 | enum 42 | { 43 | BOLD=0x1, 44 | BLINK=0x2, 45 | UNDERLINE=0x4, 46 | INVERSE=0x8, 47 | NOEOLWRAP=0x10, 48 | CURSORAPPMODE=0x20, 49 | CURSORRELATIVE=0x40, 50 | NEWLINE=0x80, 51 | INSERT=0x100, 52 | KEYAPPMODE=0x200, 53 | DEFERUPDATE=0x400, 54 | DESTRUCTBS=0x800, 55 | TEXTONLY=0x1000, 56 | LOCALECHO=0x2000, 57 | CURSORINVISIBLE=0x4000, 58 | #ifdef GTERM_PC 59 | // ,PC=0x10000 60 | PC=0x8000, 61 | #endif // GTERM_PC 62 | SELECTED=0x8000 // flag to indicate a char is selected 63 | } MODES; 64 | 65 | private: 66 | // terminal info 67 | int width, height, scroll_top, scroll_bot; 68 | unsigned char *text; 69 | unsigned short *color; 70 | short linenumbers[MAXHEIGHT]; // text at text[linenumbers[y]*MAXWIDTH] 71 | unsigned char dirty_startx[MAXHEIGHT], dirty_endx[MAXHEIGHT]; 72 | int pending_scroll; // >0 means scroll up 73 | int doing_update; 74 | 75 | // terminal state 76 | int cursor_x, cursor_y; 77 | int save_x, save_y, save_attrib; 78 | int fg_color, bg_color; 79 | int mode_flags; 80 | char tab_stops[MAXWIDTH]; 81 | StateOption *current_state; 82 | static StateOption normal_state[], esc_state[], bracket_state[]; 83 | static StateOption cset_shiftin_state[], cset_shiftout_state[]; 84 | static StateOption hash_state[]; 85 | static StateOption vt52_normal_state[], vt52_esc_state[]; 86 | static StateOption vt52_cursory_state[], vt52_cursorx_state[]; 87 | 88 | public: 89 | // keycode translation 90 | enum 91 | { 92 | KEY_NULL = 0, 93 | KEY_BACK = 1000, 94 | KEY_TAB, 95 | KEY_RETURN, 96 | KEY_ESCAPE, 97 | KEY_SPACE, 98 | KEY_LEFT, 99 | KEY_UP, 100 | KEY_RIGHT, 101 | KEY_DOWN, 102 | KEY_NUMPAD_LEFT, 103 | KEY_NUMPAD_UP, 104 | KEY_NUMPAD_RIGHT, 105 | KEY_NUMPAD_DOWN, 106 | KEY_DIVIDE, 107 | KEY_NUMPAD_DIVIDE, 108 | KEY_MULTIPLY, 109 | KEY_NUMPAD_MULTIPLY, 110 | KEY_SUBTRACT, 111 | KEY_NUMPAD_SUBTRACT, 112 | KEY_ADD, 113 | KEY_NUMPAD_ADD, 114 | KEY_HOME, 115 | KEY_NUMPAD_HOME, 116 | KEY_END, 117 | KEY_NUMPAD_END, 118 | KEY_PAGEUP, 119 | KEY_NUMPAD_PAGEUP, 120 | KEY_PAGEDOWN, 121 | KEY_NUMPAD_PAGEDOWN, 122 | KEY_INSERT, 123 | KEY_NUMPAD_INSERT, 124 | KEY_DELETE, 125 | KEY_NUMPAD_DELETE, 126 | KEY_ENTER, 127 | KEY_NUMPAD_ENTER, 128 | KEY_NEXT, 129 | KEY_PRIOR, 130 | KEY_NUMPAD0, 131 | KEY_NUMPAD1, 132 | KEY_NUMPAD2, 133 | KEY_NUMPAD3, 134 | KEY_NUMPAD4, 135 | KEY_NUMPAD5, 136 | KEY_NUMPAD6, 137 | KEY_NUMPAD7, 138 | KEY_NUMPAD8, 139 | KEY_NUMPAD9, 140 | KEY_NUMPAD_BEGIN, 141 | KEY_NUMPAD_DECIMAL, 142 | KEY_F1, 143 | KEY_F2, 144 | KEY_F3, 145 | KEY_F4, 146 | KEY_F5, 147 | KEY_F6, 148 | KEY_F7, 149 | KEY_F8, 150 | KEY_F9, 151 | KEY_F10, 152 | KEY_F11, 153 | KEY_F12 154 | } KEYCODE; 155 | 156 | private: 157 | typedef struct 158 | { 159 | int 160 | keyCode; 161 | 162 | char 163 | *seq; 164 | } VTKeySeq; 165 | 166 | static VTKeySeq cursor_keys[]; 167 | static VTKeySeq cursor_app_keys[]; 168 | static VTKeySeq keypad_keys[]; 169 | static VTKeySeq keypad_app_keys[]; 170 | static VTKeySeq other_keys[]; 171 | 172 | #ifdef GTERM_PC 173 | typedef struct 174 | { 175 | int 176 | keyCode; 177 | 178 | unsigned short 179 | normSeq, 180 | shiftSeq, 181 | ctrlSeq, 182 | altSeq; 183 | } PCKeySeq; 184 | 185 | static PCKeySeq pc_keys[]; 186 | #endif // GTERM_PC 187 | 188 | VTKeySeq *translate_vt_keycode(int keyCode, VTKeySeq *table); 189 | #ifdef GTERM_PC 190 | unsigned short translate_pc_keycode(int KeyCode, int shift, int ctrl, int alt); 191 | #endif // GTERM_PC 192 | 193 | #ifdef GTERM_PC 194 | 195 | #define GTERM_PC_MAXARGS 10 196 | 197 | #define GTERM_PC_CMD_EXIT 0 // end console mode 198 | #define GTERM_PC_CMD_CURONOFF 1 // cursor on/off 199 | #define GTERM_PC_CMD_MOVECURSOR 2 // move cursor to x,y 200 | #define GTERM_PC_CMD_PUTTEXT 3 // put text 201 | #define GTERM_PC_CMD_WRITE 4 // write text 202 | #define GTERM_PC_CMD_MOVETEXT 5 // move text 203 | #define GTERM_PC_CMD_BEEP 6 // beep 204 | #define GTERM_PC_CMD_SELECTPRINTER 7 // select printer 205 | #define GTERM_PC_CMD_PRINTCHAR 8 // print a single character 206 | #define GTERM_PC_CMD_PRINTCHARS 9 // prints multiple characters 207 | 208 | #define GTERM_PC_MAXPRINTERNAME 100 209 | 210 | int pc_cury; 211 | int pc_curx; 212 | int pc_state; 213 | int pc_curcmd; 214 | int pc_numargs; 215 | int pc_argcount; 216 | int pc_numdata; 217 | int pc_datacount; 218 | int pc_oldWidth; 219 | int pc_oldHeight; 220 | unsigned char pc_args[GTERM_PC_MAXARGS]; 221 | char *pc_machinename; 222 | char pc_printername[GTERM_PC_MAXPRINTERNAME]; 223 | 224 | // 225 | // Define state tables 226 | // 227 | static StateOption pc_cmd_state[]; 228 | static StateOption pc_arg_state[]; 229 | static StateOption pc_data_state[]; 230 | 231 | // 232 | // Define actions 233 | // 234 | void pc_begin(void); 235 | void pc_end(void); 236 | void pc_cmd(void); 237 | void pc_arg(void); 238 | void pc_data(void); 239 | 240 | #endif // GTERM_PC 241 | 242 | // utility functions 243 | void update_changes(); 244 | void scroll_region(int start_y, int end_y, int num); // does clear 245 | void shift_text(int y, int start_x, int end_x, int num); // ditto 246 | void clear_area(int start_x, int start_y, int end_x, int end_y); 247 | void changed_line(int y, int start_x, int end_x); 248 | void move_cursor(int x, int y); 249 | int calc_color(int fg, int bg, int flags); 250 | 251 | // action parameters 252 | int nparam, param[30]; 253 | unsigned char *input_data; 254 | int data_len, q_mode, got_param, quote_mode; 255 | 256 | // terminal actions 257 | void normal_input(); 258 | void set_q_mode(); 259 | void set_quote_mode(); 260 | void clear_param(); 261 | void param_digit(); 262 | void next_param(); 263 | 264 | // non-printing characters 265 | void cr(), lf(), ff(), bell(), tab(), bs(); 266 | 267 | // escape sequence actions 268 | void keypad_numeric(); 269 | void keypad_application(); 270 | void save_cursor(); 271 | void restore_cursor(); 272 | void set_tab(); 273 | void index_down(); 274 | void index_up(); 275 | void next_line(); 276 | void reset(); 277 | 278 | void cursor_left(); 279 | void cursor_down(); 280 | void cursor_right(); 281 | void cursor_up(); 282 | void cursor_position(); 283 | void device_attrib(); 284 | void delete_char(); 285 | void set_mode(); 286 | void clear_mode(); 287 | void request_param(); 288 | void set_margins(); 289 | void delete_line(); 290 | void status_report(); 291 | void erase_display(); 292 | void erase_line(); 293 | void insert_line(); 294 | void set_colors(); 295 | void clear_tab(); 296 | void insert_char(); 297 | void screen_align(); 298 | void erase_char(); 299 | 300 | // vt52 stuff 301 | void vt52_cursory(); 302 | void vt52_cursorx(); 303 | void vt52_ident(); 304 | 305 | public: 306 | GTerm(int w, int h); 307 | virtual ~GTerm(); 308 | 309 | // function to control terminal 310 | virtual void ProcessInput(int len, unsigned char *data); 311 | virtual void ProcessOutput(int len, unsigned char *data) { SendBack(len, (char *)data); } 312 | virtual void ResizeTerminal(int width, int height); 313 | int Width() { return width; } 314 | int Height() { return height; } 315 | virtual void Update(); 316 | virtual void ExposeArea(int x, int y, int w, int h); 317 | virtual void Reset(); 318 | 319 | int GetMode() { return mode_flags; } 320 | void SetMode(int mode) { mode_flags = mode; } 321 | void set_mode_flag(int flag); 322 | void clear_mode_flag(int flag); 323 | 324 | // manditory child-supplied functions 325 | virtual void DrawText(int fg_color, int bg_color, int flags, 326 | int x, int y, int len, unsigned char *string) = 0; 327 | virtual void DrawCursor(int fg_color, int bg_color, int flags, 328 | int x, int y, unsigned char c) = 0; 329 | 330 | // optional child-supplied functions 331 | virtual void MoveChars(int sx, int sy, int dx, int dy, int w, int h) { } 332 | virtual void ClearChars(int bg_color, int x, int y, int w, int h) { } 333 | virtual void SendBack(int len, char *data) { } 334 | virtual void SendBack(char *data) { SendBack(strlen(data), data); } 335 | virtual void ModeChange(int state) { } 336 | virtual void Bell() { } 337 | virtual void RequestSizeChange(int w, int h) { } 338 | 339 | virtual int TranslateKeyCode(int keycode, int *len, char *data, 340 | int shift = 0, int ctrl = 0, int alt = 0); 341 | 342 | #ifdef GTERM_PC 343 | virtual void SelectPrinter(char *PrinterName) {} 344 | virtual void PrintChars(int len, unsigned char *data) {} 345 | 346 | void SetMachineName(char *machinename); 347 | char *GetMachineName(void) { return pc_machinename; } 348 | #endif // GTERM_PC 349 | 350 | virtual int IsSelected(int x, int y); 351 | virtual void Select(int x, int y, int select); 352 | virtual unsigned char GetChar(int x, int y); 353 | }; 354 | 355 | #endif 356 | -------------------------------------------------------------------------------- /src/GTerm/keytrans.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | TerminalWx - A wxWidgets terminal widget 3 | Copyright (C) 1999 Derry Bryson 4 | 2004 Mark Erikson 5 | 2012-2013 Jeremy Salwen 6 | 7 | License: wxWindows License Version 3.1 (See the file license3.txt) 8 | 9 | */ 10 | 11 | 12 | #include "gterm.hpp" 13 | #include 14 | 15 | // 16 | // Keycode translation tables 17 | // 18 | GTerm::VTKeySeq GTerm::cursor_keys[] = 19 | { 20 | { KEY_LEFT, "\033[D" }, 21 | { KEY_UP, "\033[A" }, 22 | { KEY_RIGHT, "\033[C" }, 23 | { KEY_DOWN, "\033[B" }, 24 | { KEY_NUMPAD_LEFT, "\033[D" }, 25 | { KEY_NUMPAD_UP, "\033[A" }, 26 | { KEY_NUMPAD_RIGHT, "\033[C" }, 27 | { KEY_NUMPAD_DOWN, "\033[B" }, 28 | { KEY_NULL, 0 } 29 | }; 30 | 31 | GTerm::VTKeySeq GTerm::cursor_app_keys[] = 32 | { 33 | { KEY_LEFT, "\033OD" }, 34 | { KEY_UP, "\033OA" }, 35 | { KEY_RIGHT, "\033OC" }, 36 | { KEY_DOWN, "\033OB" }, 37 | { KEY_NUMPAD_LEFT, "\033OD" }, 38 | { KEY_NUMPAD_UP, "\033OA" }, 39 | { KEY_NUMPAD_RIGHT, "\033OC" }, 40 | { KEY_NUMPAD_DOWN, "\033OB" }, 41 | { KEY_NULL, 0 } 42 | }; 43 | 44 | GTerm::VTKeySeq GTerm::keypad_keys[] = 45 | { 46 | { KEY_NUMPAD_DIVIDE, "/" }, 47 | { KEY_NUMPAD_MULTIPLY, "*" }, 48 | { KEY_NUMPAD_SUBTRACT, "-" }, 49 | { KEY_NUMPAD_HOME, "\033[\000" }, 50 | { KEY_NUMPAD7, "7" }, 51 | { KEY_NUMPAD8, "8" }, 52 | { KEY_NUMPAD_PAGEUP, "\033[5~" }, 53 | { KEY_NUMPAD9, "9" }, 54 | { KEY_NUMPAD_ADD, "+" }, 55 | { KEY_NUMPAD4, "4" }, 56 | { KEY_NUMPAD_BEGIN, "\033[s" }, 57 | { KEY_NUMPAD5, "5" }, 58 | { KEY_NUMPAD6, "6" }, 59 | { KEY_NUMPAD_END, "\033[e" }, 60 | { KEY_NUMPAD1, "1" }, 61 | { KEY_NUMPAD2, "2" }, 62 | { KEY_NUMPAD_PAGEDOWN, "\033[6~" }, 63 | { KEY_NUMPAD3, "3" }, 64 | { KEY_NUMPAD_INSERT, "\033[2~" }, 65 | { KEY_NUMPAD0, "0" }, 66 | { KEY_NUMPAD_DELETE, "\033[3~" }, 67 | { KEY_NUMPAD_DECIMAL, "." }, 68 | { KEY_NUMPAD_ENTER, "\r" }, 69 | { KEY_NULL, 0 } 70 | }; 71 | 72 | GTerm::VTKeySeq GTerm::keypad_app_keys[] = 73 | { 74 | { KEY_NUMPAD_DIVIDE, "\033Oo" }, 75 | { KEY_NUMPAD_MULTIPLY, "\033Oj" }, 76 | { KEY_NUMPAD_SUBTRACT, "\033Om" }, 77 | { KEY_NUMPAD_HOME, "\033[\000" }, 78 | { KEY_NUMPAD7, "\033Ow" }, 79 | { KEY_NUMPAD8, "\033Ox" }, 80 | { KEY_NUMPAD_PAGEUP, "\033[5~" }, 81 | { KEY_NUMPAD9, "\033Oy" }, 82 | { KEY_NUMPAD_ADD, "\033Ok" }, 83 | { KEY_NUMPAD4, "\033Ot" }, 84 | { KEY_NUMPAD_BEGIN, "\033[s" }, 85 | { KEY_NUMPAD5, "\033Ou" }, 86 | { KEY_NUMPAD6, "\033Ov" }, 87 | { KEY_NUMPAD_END, "\033[e" }, 88 | { KEY_NUMPAD1, "\033Oq" }, 89 | { KEY_NUMPAD2, "\033Or" }, 90 | { KEY_NUMPAD_PAGEDOWN, "\033[6~" }, 91 | { KEY_NUMPAD3, "\033Os" }, 92 | { KEY_NUMPAD_INSERT, "\033[2~" }, 93 | { KEY_NUMPAD0, "\033Op" }, 94 | { KEY_NUMPAD_DELETE, "\033[3~" }, 95 | { KEY_NUMPAD_DECIMAL, "\033On" }, 96 | { KEY_NUMPAD_ENTER, "\033OM" }, 97 | { KEY_NULL, 0 } 98 | }; 99 | 100 | GTerm::VTKeySeq GTerm::other_keys[] = 101 | { 102 | { KEY_HOME, "\033[\000" }, 103 | { KEY_PAGEUP, "\033[5~" }, 104 | { KEY_PRIOR, "\033[5~" }, 105 | { KEY_PAGEDOWN, "\033[6~"}, 106 | { KEY_NEXT, "\033[6~" }, 107 | { KEY_END, "\033[e" }, 108 | { KEY_INSERT, "\033[2~" }, 109 | { KEY_F1, "\033[11~" }, 110 | { KEY_F2, "\033[12~" }, 111 | { KEY_F3, "\033[13~" }, 112 | { KEY_F4, "\033[14~" }, 113 | { KEY_F5, "\033[15~" }, 114 | { KEY_F6, "\033[17~" }, 115 | { KEY_F7, "\033[18~" }, 116 | { KEY_F8, "\033[19~" }, 117 | { KEY_F9, "\033[20~" }, 118 | { KEY_F10, "\033[21~" }, 119 | { KEY_F11, "\033[23~" }, 120 | { KEY_F12, "\033[24~" }, 121 | { KEY_RETURN, "\r" }, 122 | { KEY_SPACE, " " }, 123 | { KEY_BACK, "\x8" }, 124 | { KEY_ESCAPE, "\x1b" }, 125 | { KEY_TAB, "\x9" }, 126 | { KEY_DELETE, "\x7f" }, 127 | { KEY_NULL, 0 } 128 | }; 129 | 130 | #ifdef GTERM_PC 131 | GTerm::PCKeySeq GTerm::pc_keys[] = 132 | { 133 | { '0', 0x0030, 0x0029, 0x0000, 0x8100 }, 134 | { '1', 0x0031, 0x0021, 0x0000, 0x7800 }, 135 | { '2', 0x0032, 0x0040, 0x0000, 0x7900 }, 136 | { '3', 0x0033, 0x0023, 0x0000, 0x7a00 }, 137 | { '4', 0x0034, 0x0024, 0x0000, 0x7b00 }, 138 | { '5', 0x0035, 0x0025, 0x0000, 0x7c00 }, 139 | { '6', 0x0036, 0x005e, 0x0000, 0x7d00 }, 140 | { '7', 0x0037, 0x0026, 0x0000, 0x7e00 }, 141 | { '8', 0x0038, 0x002a, 0x0000, 0x7f00 }, 142 | { '9', 0x0039, 0x0028, 0x0000, 0x8000 }, 143 | 144 | { ')', 0x0030, 0x0029, 0x0000, 0x8100 }, 145 | { '!', 0x0031, 0x0021, 0x0000, 0x7800 }, 146 | { '@', 0x0032, 0x0040, 0x0000, 0x7900 }, 147 | { '#', 0x0033, 0x0023, 0x0000, 0x7a00 }, 148 | { '$', 0x0034, 0x0024, 0x0000, 0x7b00 }, 149 | { '%', 0x0035, 0x0025, 0x0000, 0x7c00 }, 150 | { '^', 0x0036, 0x005e, 0x0000, 0x7d00 }, 151 | { '&', 0x0037, 0x0026, 0x0000, 0x7e00 }, 152 | { '*', 0x0038, 0x002a, 0x0000, 0x7f00 }, 153 | { '(', 0x0039, 0x0028, 0x0000, 0x8000 }, 154 | 155 | { 'a', 0x0061, 0x0041, 0x0001, 0x1e00 }, 156 | { 'b', 0x0062, 0x0042, 0x0002, 0x3000 }, 157 | { 'c', 0x0063, 0x0043, 0x0003, 0x2e00 }, 158 | { 'd', 0x0064, 0x0044, 0x0004, 0x2000 }, 159 | { 'e', 0x0065, 0x0045, 0x0005, 0x1200 }, 160 | { 'f', 0x0066, 0x0046, 0x0006, 0x2100 }, 161 | { 'g', 0x0067, 0x0047, 0x0007, 0x2200 }, 162 | { 'h', 0x0068, 0x0048, 0x0008, 0x2300 }, 163 | { 'i', 0x0069, 0x0049, 0x0009, 0x1700 }, 164 | { 'j', 0x006a, 0x004a, 0x000a, 0x2400 }, 165 | { 'k', 0x006b, 0x004b, 0x000b, 0x2500 }, 166 | { 'l', 0x006c, 0x004c, 0x000c, 0x2600 }, 167 | { 'm', 0x006d, 0x004d, 0x000d, 0x3200 }, 168 | { 'n', 0x006e, 0x004e, 0x000e, 0x3100 }, 169 | { 'o', 0x006f, 0x004f, 0x000f, 0x1800 }, 170 | { 'p', 0x0070, 0x0050, 0x0010, 0x1900 }, 171 | { 'q', 0x0071, 0x0051, 0xff91, 0x1000 }, 172 | { 'r', 0x0072, 0x0052, 0x0012, 0x1300 }, 173 | { 's', 0x0073, 0x0053, 0xff93, 0x1f00 }, 174 | { 't', 0x0074, 0x0054, 0x0014, 0x1400 }, 175 | { 'u', 0x0075, 0x0055, 0x0015, 0x1600 }, 176 | { 'v', 0x0076, 0x0056, 0x0016, 0x2f00 }, 177 | { 'w', 0x0077, 0x0057, 0x0017, 0x1100 }, 178 | { 'x', 0x0078, 0x0058, 0x0018, 0x2d00 }, 179 | { 'y', 0x0079, 0x0059, 0x0019, 0x1500 }, 180 | { 'z', 0x007a, 0x005a, 0x001a, 0x2c00 }, 181 | 182 | { '`', 0x0060, 0x007e, 0x0000, 0x0000 }, 183 | { '~', 0x0060, 0x007e, 0x0000, 0x0000 }, 184 | { '-', 0x002d, 0x005f, 0x0000, 0x0000 }, 185 | { '_', 0x002d, 0x005f, 0x0000, 0x0000 }, 186 | { '=', 0x003d, 0x002b, 0x0000, 0x0000 }, 187 | { '+', 0x003d, 0x002b, 0x0000, 0x0000 }, 188 | { ',', 0x002c, 0x003c, 0x0000, 0x0000 }, 189 | { '<', 0x002c, 0x003c, 0x0000, 0x0000 }, 190 | { '.', 0x002e, 0x003e, 0x0000, 0x0000 }, 191 | { '>', 0x002e, 0x003e, 0x0000, 0x0000 }, 192 | { ';', 0x003b, 0x003a, 0x0000, 0x0000 }, 193 | { ':', 0x003b, 0x003a, 0x0000, 0x0000 }, 194 | { '\'', 0x002c, 0x0022, 0x0000, 0x0000 }, 195 | { '"', 0x002c, 0x0022, 0x0000, 0x0000 }, 196 | { '[', 0x005b, 0x007b, 0x0000, 0x0000 }, 197 | { '{', 0x005b, 0x007b, 0x0000, 0x0000 }, 198 | { ']', 0x005d, 0x007d, 0x0000, 0x0000 }, 199 | { '}', 0x005d, 0x007d, 0x0000, 0x0000 }, 200 | { '\\', 0x005c, 0x007c, 0x0000, 0x0000 }, 201 | { '|', 0x005c, 0x007c, 0x0000, 0x0000 }, 202 | { '/', 0x002f, 0x003f, 0x0000, 0x0000 }, 203 | { '?', 0x002f, 0x003f, 0x0000, 0x0000 }, 204 | 205 | { KEY_BACK, 0x0008, 0x0008, 0x007f, 0x0000 }, 206 | { KEY_TAB, 0x0009, 0x0f00, 0x0000, 0x0000 }, 207 | { KEY_RETURN, 0x000d, 0x000d, 0x000a, 0x0000 }, 208 | { KEY_ESCAPE, 0x001b, 0x001b, 0x001b, 0x0000 }, 209 | { KEY_SPACE, 0x0020, 0x0020, 0x0000, 0x0000 }, 210 | { KEY_LEFT, 0x4b00, 0x0034, 0x7300, 0xb200 }, 211 | { KEY_UP, 0x4800, 0x0038, 0xa000, 0xaf00 }, 212 | { KEY_RIGHT, 0x4d00, 0x0036, 0x7400, 0xb400 }, 213 | { KEY_DOWN, 0x5000, 0x0032, 0xa400, 0xb700 }, 214 | { KEY_NUMPAD_LEFT, 0x4b00, 0x0034, 0x7300, 0xb200 }, 215 | { KEY_NUMPAD_UP, 0x4800, 0x0038, 0xa000, 0xaf00 }, 216 | { KEY_NUMPAD_RIGHT, 0x4d00, 0x0036, 0x7400, 0xb400 }, 217 | { KEY_NUMPAD_DOWN, 0x5000, 0x0032, 0xa400, 0xb700 }, 218 | { KEY_DIVIDE, 0x002f, 0x002f, 0x0000, 0x0000 }, 219 | { KEY_MULTIPLY, 0x0038, 0x0038, 0x0000, 0x7f00 }, 220 | { KEY_SUBTRACT, 0x002d, 0x002d, 0x0000, 0x0000 }, 221 | { KEY_ADD, 0x003d, 0x003d, 0x0000, 0x0000 }, 222 | { KEY_HOME, 0x4700, 0x0037, 0x7700, 0xae00 }, 223 | { KEY_END, 0x4f00, 0x0031, 0x7500, 0xb600 }, 224 | { KEY_PAGEUP, 0x4900, 0x0039, 0x8400, 0xb000 }, 225 | { KEY_PAGEDOWN, 0x5100, 0x0033, 0x7600, 0xb800 }, 226 | { KEY_INSERT, 0x5200, 0x0030, 0xa500, 0xb900 }, 227 | { KEY_DELETE, 0x5300, 0x002e, 0xa600, 0xba00 }, 228 | { KEY_ENTER, 0x000d, 0x000d, 0x000a, 0x0000 }, 229 | { KEY_NEXT, 0x5100, 0x0033, 0x7600, 0xb800 }, 230 | { KEY_PRIOR, 0x4900, 0x0039, 0x8400, 0xb000 }, 231 | 232 | { KEY_NUMPAD0, 0x0030, 0x0029, 0x0000, 0x8100 }, 233 | { KEY_NUMPAD1, 0x0031, 0x0021, 0x0000, 0x7800 }, 234 | { KEY_NUMPAD2, 0x0032, 0x0040, 0x0000, 0x7900 }, 235 | { KEY_NUMPAD3, 0x0033, 0x0023, 0x0000, 0x7a00 }, 236 | { KEY_NUMPAD4, 0x0034, 0x0024, 0x0000, 0x7b00 }, 237 | { KEY_NUMPAD5, 0x0035, 0x0025, 0x0000, 0x7c00 }, 238 | { KEY_NUMPAD6, 0x0036, 0x005e, 0x0000, 0x7d00 }, 239 | { KEY_NUMPAD7, 0x0037, 0x0026, 0x0000, 0x7e00 }, 240 | { KEY_NUMPAD8, 0x0038, 0x002a, 0x0000, 0x7f00 }, 241 | { KEY_NUMPAD9, 0x0039, 0x0028, 0x0000, 0x8000 }, 242 | 243 | { KEY_F1, 0x3b00, 0x5400, 0x5e00, 0x6800 }, 244 | { KEY_F2, 0x3c00, 0x5500, 0x5f00, 0x6900 }, 245 | { KEY_F3, 0x3d00, 0x5600, 0x6000, 0x6a00 }, 246 | { KEY_F4, 0x3e00, 0x5700, 0x6100, 0x6b00 }, 247 | { KEY_F5, 0x3f00, 0x5800, 0x6200, 0x6c00 }, 248 | { KEY_F6, 0x4000, 0x5900, 0x6300, 0x6d00 }, 249 | { KEY_F7, 0x4100, 0x5a00, 0x6400, 0x6e00 }, 250 | { KEY_F8, 0x4200, 0x5b00, 0x6500, 0x6f00 }, 251 | { KEY_F9, 0x4300, 0x5c00, 0x6600, 0x7000 }, 252 | { KEY_F10, 0x4400, 0x5d00, 0x6700, 0x7100 }, 253 | { KEY_F11, 0x0000, 0x0000, 0x0000, 0x0000 }, 254 | { KEY_F12, 0x0000, 0x0000, 0x0000, 0x0000 }, 255 | { KEY_NULL, 0, 0, 0, 0 } 256 | }; 257 | #endif // GTERM_PC 258 | 259 | GTerm::VTKeySeq * 260 | GTerm::translate_vt_keycode(int keyCode, VTKeySeq *table) 261 | { 262 | while(table->keyCode != KEY_NULL) 263 | { 264 | if(table->keyCode == keyCode) 265 | return table; 266 | table++; 267 | } 268 | return 0; 269 | } 270 | 271 | #ifdef GTERM_PC 272 | unsigned short 273 | GTerm::translate_pc_keycode(int keyCode, int shift, int ctrl, int alt) 274 | { 275 | int 276 | i; 277 | 278 | if(keyCode < 1000) 279 | { 280 | if(isupper(keyCode)) 281 | { 282 | if(!alt) 283 | shift = 1; 284 | keyCode = tolower(keyCode); 285 | } 286 | 287 | if(iscntrl(keyCode)) 288 | { 289 | ctrl = 1; 290 | keyCode = keyCode + 'a' - 1; 291 | } 292 | } 293 | 294 | //printf("looking for %d...", keyCode); 295 | for(i = 0; pc_keys[i].keyCode; i++) 296 | { 297 | if(keyCode == pc_keys[i].keyCode) 298 | { 299 | //printf("found!\n"); 300 | if(shift) 301 | return pc_keys[i].shiftSeq; 302 | if(ctrl) 303 | return pc_keys[i].ctrlSeq; 304 | if(alt) 305 | return pc_keys[i].altSeq; 306 | return pc_keys[i].normSeq; 307 | } 308 | } 309 | //printf("not found!\n"); 310 | return 0; 311 | } 312 | #endif // GTERM_PC 313 | 314 | int 315 | GTerm::TranslateKeyCode(int keyCode, int *len, char *data, int shift, 316 | int ctrl, int alt) 317 | { 318 | int 319 | mode = GetMode(); 320 | 321 | #ifdef GTERM_PC 322 | unsigned short 323 | pcKeySeq; 324 | #endif // GTERM_PC 325 | 326 | VTKeySeq 327 | *keySeq; 328 | 329 | //printf("keycode = %d, shift = %d, ctrl = %d, alt = %d\n", keyCode, shift, ctrl, alt); 330 | //printf("GTerm::TranslateKeyCode(): mode = %x\n", mode); 331 | #ifdef GTERM_PC 332 | if(mode & PC) 333 | { 334 | pcKeySeq = translate_pc_keycode(keyCode, shift, ctrl, alt); 335 | if(pcKeySeq) 336 | { 337 | //printf("keySeq = %x\n", pcKeySeq); 338 | *(unsigned char *)data++ = pcKeySeq >> 8; 339 | *(unsigned char *)data = pcKeySeq & 0xff; 340 | *len = 2; 341 | return 1; 342 | } 343 | return 0; 344 | } 345 | else 346 | { 347 | #endif // GTERM_PC 348 | //printf("mode = %x\n", mode); 349 | if(mode & KEYAPPMODE) 350 | { 351 | //printf("KEYAPPMODE\n"); 352 | keySeq = translate_vt_keycode(keyCode, keypad_app_keys); 353 | } 354 | else 355 | keySeq = translate_vt_keycode(keyCode, keypad_keys); 356 | 357 | if(!keySeq) 358 | { 359 | if(mode & CURSORAPPMODE) 360 | { 361 | //printf("CURSORAPPMODE\n"); 362 | keySeq = translate_vt_keycode(keyCode, cursor_app_keys); 363 | //printf("keySeq = %08x\n", keySeq); 364 | } 365 | else 366 | keySeq = translate_vt_keycode(keyCode, cursor_keys); 367 | } 368 | 369 | if(!keySeq) 370 | keySeq = translate_vt_keycode(keyCode, other_keys); 371 | 372 | if(keySeq) 373 | { 374 | *len = strlen(keySeq->seq); 375 | strcpy(data, keySeq->seq); 376 | return 1; 377 | } 378 | return 0; 379 | #ifdef GTERM_PC 380 | } 381 | #endif // GTERM_PC 382 | } 383 | -------------------------------------------------------------------------------- /src/GTerm/states.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | TerminalWx - A wxWidgets terminal widget 3 | Copyright (C) 1999 Timothy Miller 4 | 2004 Mark Erikson 5 | 2012-2013 Jeremy Salwen 6 | 7 | License: wxWindows License Version 3.1 (See the file license3.txt) 8 | 9 | */ 10 | 11 | 12 | /* GRG: Added a lot of GTerm:: prefixes to correctly form pointers 13 | * to functions in all the tables. Example: &cr -> >erm::cr 14 | */ 15 | 16 | #include "gterm.hpp" 17 | 18 | // state machine transition tables 19 | StateOption GTerm::normal_state[] = { 20 | { 13, >erm::cr, normal_state }, 21 | { 10, >erm::lf, normal_state }, 22 | { 12, >erm::ff, normal_state }, 23 | { 9, >erm::tab, normal_state }, 24 | { 8, >erm::bs, normal_state }, 25 | { 7, >erm::bell, normal_state }, 26 | { 27, 0, esc_state }, 27 | { -1, >erm::normal_input, normal_state} }; 28 | 29 | StateOption GTerm::esc_state[] = { 30 | { '[', >erm::clear_param, bracket_state }, 31 | { '>', >erm::keypad_numeric, normal_state }, 32 | { '=', >erm::keypad_application, normal_state }, 33 | { '7', >erm::save_cursor, normal_state }, 34 | { '8', >erm::restore_cursor, normal_state }, 35 | { 'H', >erm::set_tab, normal_state }, 36 | { 'D', >erm::index_down, normal_state }, 37 | { 'M', >erm::index_up, normal_state }, 38 | { 'E', >erm::next_line, normal_state }, 39 | { 'c', >erm::reset, normal_state }, 40 | { '(', 0, cset_shiftin_state }, 41 | { ')', 0, cset_shiftout_state }, 42 | { '#', 0, hash_state }, 43 | #ifdef GTERM_PC 44 | { '!', >erm::pc_begin, pc_cmd_state }, 45 | #endif 46 | 47 | { 13, >erm::cr, esc_state }, // standard VT100 wants 48 | { 10, >erm::lf, esc_state }, // cursor controls in 49 | { 12, >erm::ff, esc_state }, // the middle of ESC 50 | { 9, >erm::tab, esc_state }, // sequences 51 | { 8, >erm::bs, esc_state }, 52 | { 7, >erm::bell, esc_state }, 53 | { -1, 0, normal_state} }; 54 | 55 | // Should but cursor control characters in these groups as well. 56 | // Maybe later. 57 | 58 | StateOption GTerm::cset_shiftin_state[] = { 59 | { 'A', 0, normal_state }, // should set UK characters 60 | { '0', 0, normal_state }, // should set Business Gfx 61 | { -1, 0, normal_state }, // default to ASCII 62 | }; 63 | 64 | StateOption GTerm::cset_shiftout_state[] = { 65 | { 'A', 0, normal_state }, // should set UK characters 66 | { '0', 0, normal_state }, // should set Business Gfx 67 | { -1, 0, normal_state }, // default to ASCII 68 | }; 69 | 70 | StateOption GTerm::hash_state[] = { 71 | { '8', >erm::screen_align, normal_state }, 72 | { -1, 0, normal_state} }; 73 | 74 | StateOption GTerm::bracket_state[] = { 75 | { '?', >erm::set_q_mode, bracket_state }, 76 | { '"', >erm::set_quote_mode, bracket_state }, 77 | { '0', >erm::param_digit, bracket_state }, 78 | { '1', >erm::param_digit, bracket_state }, 79 | { '2', >erm::param_digit, bracket_state }, 80 | { '3', >erm::param_digit, bracket_state }, 81 | { '4', >erm::param_digit, bracket_state }, 82 | { '5', >erm::param_digit, bracket_state }, 83 | { '6', >erm::param_digit, bracket_state }, 84 | { '7', >erm::param_digit, bracket_state }, 85 | { '8', >erm::param_digit, bracket_state }, 86 | { '9', >erm::param_digit, bracket_state }, 87 | { ';', >erm::next_param, bracket_state }, 88 | { 'D', >erm::cursor_left, normal_state }, 89 | { 'B', >erm::cursor_down, normal_state }, 90 | { 'C', >erm::cursor_right, normal_state }, 91 | { 'A', >erm::cursor_up, normal_state }, 92 | { 'H', >erm::cursor_position, normal_state }, 93 | { 'f', >erm::cursor_position, normal_state }, 94 | { 'c', >erm::device_attrib, normal_state }, 95 | { 'P', >erm::delete_char, normal_state }, 96 | { 'h', >erm::set_mode, normal_state }, 97 | { 'l', >erm::clear_mode, normal_state }, 98 | { 's', >erm::save_cursor, normal_state }, 99 | { 'u', >erm::restore_cursor, normal_state }, 100 | { 'x', >erm::request_param, normal_state }, 101 | { 'r', >erm::set_margins, normal_state }, 102 | { 'M', >erm::delete_line, normal_state }, 103 | { 'n', >erm::status_report, normal_state }, 104 | { 'J', >erm::erase_display, normal_state }, 105 | { 'K', >erm::erase_line, normal_state }, 106 | { 'L', >erm::insert_line, normal_state }, 107 | { 'm', >erm::set_colors, normal_state }, 108 | { 'g', >erm::clear_tab, normal_state }, 109 | { '@', >erm::insert_char, normal_state }, 110 | { 'X', >erm::erase_char, normal_state }, 111 | { 'p', 0, normal_state }, // something to do with levels 112 | 113 | { 13, >erm::cr, bracket_state },// standard VT100 wants 114 | { 10, >erm::lf, bracket_state },// cursor controls in 115 | { 12, >erm::ff, bracket_state },// the middle of ESC 116 | { 9, >erm::tab, bracket_state },// sequences 117 | { 8, >erm::bs, bracket_state }, 118 | { 7, >erm::bell, bracket_state }, 119 | { -1, 0, normal_state} }; 120 | 121 | #ifdef GTERM_PC 122 | 123 | StateOption GTerm::pc_cmd_state[] = 124 | { 125 | { GTERM_PC_CMD_CURONOFF, >erm::pc_cmd, pc_arg_state }, 126 | { GTERM_PC_CMD_MOVECURSOR, >erm::pc_cmd, pc_arg_state }, 127 | { GTERM_PC_CMD_PUTTEXT, >erm::pc_cmd, pc_arg_state }, 128 | { GTERM_PC_CMD_WRITE, >erm::pc_cmd, pc_arg_state }, 129 | { GTERM_PC_CMD_MOVETEXT, >erm::pc_cmd, pc_arg_state }, 130 | { GTERM_PC_CMD_EXIT, >erm::pc_end, normal_state }, 131 | { GTERM_PC_CMD_BEEP, >erm::pc_cmd, pc_cmd_state }, 132 | { GTERM_PC_CMD_SELECTPRINTER, >erm::pc_cmd, pc_arg_state }, 133 | { GTERM_PC_CMD_PRINTCHAR, >erm::pc_cmd, pc_arg_state }, 134 | { GTERM_PC_CMD_PRINTCHARS, >erm::pc_cmd, pc_arg_state }, 135 | { -1, >erm::pc_cmd, pc_cmd_state } 136 | }; 137 | 138 | StateOption GTerm::pc_arg_state[] = 139 | { 140 | { -1, >erm::pc_arg, pc_arg_state } 141 | }; 142 | 143 | StateOption GTerm::pc_data_state[] = 144 | { 145 | { -1, >erm::pc_data, pc_data_state } 146 | }; 147 | 148 | #endif // GTERM_PC 149 | -------------------------------------------------------------------------------- /src/GTerm/utils.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | TerminalWx - A wxWidgets terminal widget 3 | Copyright (C) 1999 Timothy Miller 4 | 2004 Mark Erikson 5 | 2012-2013 Jeremy Salwen 6 | 7 | License: wxWindows License Version 3.1 (See the file license3.txt) 8 | 9 | */ 10 | 11 | 12 | #include "gterm.hpp" 13 | //#include 14 | 15 | int GTerm::calc_color(int fg, int bg, int flags) 16 | { 17 | return (flags & 15) | (fg << 4) | (bg << 8); 18 | } 19 | 20 | void GTerm::update_changes() 21 | { 22 | int yp, start_x, mx; 23 | int blank, c, x, y; 24 | 25 | // prevent recursion for scrolls which cause exposures 26 | if (doing_update) return; 27 | doing_update = 1; 28 | 29 | // first perform scroll-copy 30 | mx = scroll_bot-scroll_top+1; 31 | if (!(mode_flags & TEXTONLY) && pending_scroll && 32 | pending_scroll=MAXWIDTH) continue; 46 | yp = linenumbers[y]*MAXWIDTH; 47 | 48 | blank = !(mode_flags & TEXTONLY); 49 | start_x = dirty_startx[y]; 50 | c = color[yp+start_x]; 51 | for (x=start_x; x<=dirty_endx[y]; x++) { 52 | if (text[yp+x]!=32 && text[yp+x]) blank = 0; 53 | if (c != color[yp+x]) { 54 | if (!blank) { 55 | if(mode_flags & PC) 56 | DrawText((c>>4)&0xf, (c>>8)&0xf, c/*&15*/, start_x, 57 | y, x-start_x, text+yp+start_x); 58 | else 59 | DrawText((c>>4)&7, (c>>8)&7, c/*&15*/, start_x, 60 | y, x-start_x, text+yp+start_x); 61 | } else { 62 | ClearChars((c>>8)&7, start_x, y, x-start_x, 1); 63 | } 64 | start_x = x; 65 | c = color[yp+x]; 66 | blank = !(mode_flags & TEXTONLY); 67 | if (text[yp+x]!=32 && text[yp+x]) blank = 0; 68 | } 69 | } 70 | if (!blank) { 71 | if(mode_flags & PC) 72 | DrawText((c>>4)&0xf, (c>>8)&0xf, c/*&15*/, start_x, 73 | y, x-start_x, text+yp+start_x); 74 | else 75 | DrawText((c>>4)&7, (c>>8)&7, c/*&15*/, start_x, 76 | y, x-start_x, text+yp+start_x); 77 | } else { 78 | ClearChars((c>>8)&7, start_x, y, x-start_x, 1); 79 | } 80 | 81 | dirty_endx[y] = 0; 82 | dirty_startx[y] = MAXWIDTH; 83 | } 84 | 85 | if (!(mode_flags & CURSORINVISIBLE)) { 86 | x = cursor_x; 87 | if (x>=width) x = width-1; 88 | yp = linenumbers[cursor_y]*MAXWIDTH+x; 89 | c = color[yp]; 90 | if(mode_flags & PC) 91 | DrawCursor((c>>4)&0xf, (c>>8)&0xf, c&15, x, cursor_y, text[yp]); 92 | else 93 | DrawCursor((c>>4)&7, (c>>8)&7, c&15, x, cursor_y, text[yp]); 94 | } 95 | 96 | doing_update = 0; 97 | } 98 | 99 | void GTerm::scroll_region(int start_y, int end_y, int num) 100 | { 101 | int y, takey, fast_scroll, mx, clr, x, yp, c; 102 | short temp[MAXHEIGHT]; 103 | unsigned char temp_sx[MAXHEIGHT], temp_ex[MAXHEIGHT]; 104 | 105 | if (!num) return; 106 | mx = end_y-start_y+1; 107 | if (num > mx) num = mx; 108 | if (-num > mx) num = -mx; 109 | 110 | fast_scroll = (start_y == scroll_top && end_y == scroll_bot && 111 | !(mode_flags & TEXTONLY)); 112 | 113 | if (fast_scroll) pending_scroll += num; 114 | 115 | memcpy(temp, linenumbers, sizeof(linenumbers)); 116 | if (fast_scroll) { 117 | memcpy(temp_sx, dirty_startx, sizeof(dirty_startx)); 118 | memcpy(temp_ex, dirty_endx, sizeof(dirty_endx)); 119 | } 120 | 121 | c = calc_color(fg_color, bg_color, mode_flags); 122 | 123 | // move the lines by renumbering where they point to 124 | if (numend_y); 127 | if (takeyend_y) takey = start_y-1+(takey-end_y); 129 | 130 | linenumbers[y] = temp[takey]; 131 | if (!fast_scroll || clr) { 132 | dirty_startx[y] = 0; 133 | dirty_endx[y] = width-1; 134 | } else { 135 | dirty_startx[y] = temp_sx[takey]; 136 | dirty_endx[y] = temp_ex[takey]; 137 | } 138 | if (clr) { 139 | yp = linenumbers[y]*MAXWIDTH; 140 | memset(text+yp, 32, width); 141 | for (x=0; xmx) num = mx; 158 | if (-num>mx) num = -mx; 159 | 160 | if (num start_x) dirty_startx[y] = start_x; 205 | if (dirty_endx[y] < end_x) dirty_endx[y] = end_x; 206 | } 207 | 208 | void GTerm::move_cursor(int x, int y) 209 | { 210 | if (cursor_x>=width) cursor_x = width-1; 211 | changed_line(cursor_y, cursor_x, cursor_x); 212 | cursor_x = x; 213 | cursor_y = y; 214 | } 215 | 216 | void GTerm::set_mode_flag(int flag) 217 | { 218 | mode_flags |= flag; 219 | ModeChange(mode_flags); 220 | } 221 | 222 | void GTerm::clear_mode_flag(int flag) 223 | { 224 | mode_flags &= ~flag; 225 | ModeChange(mode_flags); 226 | } 227 | 228 | -------------------------------------------------------------------------------- /src/GTerm/vt52_states.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | TerminalWx - A wxWidgets terminal widget 3 | Copyright (C) 1999 Timothy Miller 4 | 2004 Mark Erikson 5 | 2012-2013 Jeremy Salwen 6 | 7 | License: wxWindows License Version 3.1 (See the file license3.txt) 8 | 9 | */ 10 | 11 | /* GRG: Added a lot of GTerm:: prefixes to correctly form pointers 12 | * to functions in all the tables. Example: &cr -> >erm::cr 13 | */ 14 | 15 | #include "gterm.hpp" 16 | 17 | // I'm certain that this set is incomplete, but I got these from reverse- 18 | // engineering a VT100 verification test program. 19 | 20 | 21 | // state machine transition tables 22 | StateOption GTerm::vt52_normal_state[] = { 23 | { 13, >erm::cr, vt52_normal_state }, 24 | { 10, >erm::lf, vt52_normal_state }, 25 | { 12, >erm::ff, vt52_normal_state }, 26 | { 9, >erm::tab, vt52_normal_state }, 27 | { 8, >erm::bs, vt52_normal_state }, 28 | { 7, >erm::bell, vt52_normal_state }, 29 | { 27, >erm::clear_param, vt52_esc_state }, 30 | { -1, >erm::normal_input, vt52_normal_state } }; 31 | 32 | StateOption GTerm::vt52_esc_state[] = { 33 | { 'D', >erm::cursor_left, vt52_normal_state }, 34 | { 'B', >erm::cursor_down, vt52_normal_state }, 35 | { 'C', >erm::cursor_right, vt52_normal_state }, 36 | { 'A', >erm::cursor_up, vt52_normal_state }, 37 | { 'Y', 0, vt52_cursory_state }, 38 | { 'J', >erm::erase_display, vt52_normal_state }, 39 | { 'K', >erm::erase_line, vt52_normal_state }, 40 | { 'H', >erm::cursor_position, vt52_normal_state }, 41 | { 'I', >erm::index_up, vt52_normal_state }, 42 | { 'F', 0, vt52_normal_state }, // graphics mode 43 | { 'G', 0, vt52_normal_state }, // ASCII mode 44 | { 'Z', >erm::vt52_ident, vt52_normal_state }, // identify 45 | { '<', 0, normal_state }, 46 | { -1, 0, vt52_normal_state }}; 47 | 48 | StateOption GTerm::vt52_cursory_state[] = { 49 | { -1, >erm::vt52_cursory, vt52_cursorx_state } }; 50 | 51 | StateOption GTerm::vt52_cursorx_state[] = { 52 | { -1, >erm::vt52_cursorx, vt52_normal_state } }; 53 | 54 | -------------------------------------------------------------------------------- /src/taTelnet/wxterm.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | taTelnet - A cross-platform telnet program. 3 | Copyright (c) 2000 Derry Bryson 4 | 2004 Mark Erikson 5 | 2012-2013 Jeremy Salwen 6 | 7 | License: wxWindows License Version 3.1 (See the file license3.txt) 8 | 9 | */ 10 | 11 | #ifdef __GNUG__ 12 | #pragma implementation "wxterm.h" 13 | #endif 14 | 15 | // For compilers that support precompilation, includes "wx/wx.h". 16 | #include "wx/wxprec.h" 17 | 18 | #ifdef __BORLANDC__ 19 | #pragma hdrstop 20 | #endif 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | #include 34 | 35 | #include "../GTerm/gterm.hpp" 36 | #include "wxterm.h" 37 | 38 | 39 | 40 | #define CURSOR_BLINK_DEFAULT_TIMEOUT 300 41 | #define CURSOR_BLINK_MAX_TIMEOUT 2000 42 | 43 | /* 44 | ** Keycode translation tables 45 | */ 46 | wxTerm::TermKeyMap wxTerm::keyMapTable[] = 47 | { 48 | { WXK_BACK, GTerm::KEY_BACK }, 49 | { WXK_TAB, GTerm::KEY_TAB }, 50 | { WXK_RETURN, GTerm::KEY_RETURN }, 51 | { WXK_ESCAPE, GTerm::KEY_ESCAPE }, 52 | { WXK_SPACE, GTerm::KEY_SPACE }, 53 | { WXK_LEFT, GTerm::KEY_LEFT }, 54 | { WXK_UP, GTerm::KEY_UP }, 55 | { WXK_RIGHT, GTerm::KEY_RIGHT }, 56 | { WXK_DOWN, GTerm::KEY_DOWN }, 57 | // { WXK_DIVIDE, GTerm::KEY_DIVIDE }, 58 | // { WXK_MULTIPLY, GTerm::KEY_MULTIPLY }, 59 | // { WXK_SUBTRACT, GTerm::KEY_SUBTRACT }, 60 | // { WXK_ADD, GTerm::KEY_ADD }, 61 | { WXK_HOME, GTerm::KEY_HOME }, 62 | { WXK_END, GTerm::KEY_END }, 63 | { WXK_PAGEUP, GTerm::KEY_PAGEUP }, 64 | { WXK_PAGEDOWN, GTerm::KEY_PAGEDOWN }, 65 | { WXK_INSERT, GTerm::KEY_INSERT }, 66 | { WXK_DELETE, GTerm::KEY_DELETE }, 67 | // { WXK_NEXT, GTerm::KEY_NEXT }, 68 | // { WXK_PRIOR, GTerm::KEY_PRIOR }, 69 | // { WXK_NUMPAD0, GTerm::KEY_NUMPAD0 }, 70 | // { WXK_NUMPAD1, GTerm::KEY_NUMPAD1 }, 71 | // { WXK_NUMPAD2, GTerm::KEY_NUMPAD2 }, 72 | // { WXK_NUMPAD3, GTerm::KEY_NUMPAD3 }, 73 | // { WXK_NUMPAD4, GTerm::KEY_NUMPAD4 }, 74 | // { WXK_NUMPAD5, GTerm::KEY_NUMPAD5 }, 75 | // { WXK_NUMPAD6, GTerm::KEY_NUMPAD6 }, 76 | // { WXK_NUMPAD7, GTerm::KEY_NUMPAD7 }, 77 | // { WXK_NUMPAD8, GTerm::KEY_NUMPAD8 }, 78 | // { WXK_NUMPAD9, GTerm::KEY_NUMPAD9 }, 79 | // { WXK_DECIMAL, GTerm::KEY_NUMPAD_DECIMAL }, 80 | { WXK_F1, GTerm::KEY_F1 }, 81 | { WXK_F2, GTerm::KEY_F2 }, 82 | { WXK_F3, GTerm::KEY_F3 }, 83 | { WXK_F4, GTerm::KEY_F4 }, 84 | { WXK_F5, GTerm::KEY_F5 }, 85 | { WXK_F6, GTerm::KEY_F6 }, 86 | { WXK_F7, GTerm::KEY_F7 }, 87 | { WXK_F8, GTerm::KEY_F8 }, 88 | { WXK_F9, GTerm::KEY_F9 }, 89 | { WXK_F10, GTerm::KEY_F10 }, 90 | { WXK_F11, GTerm::KEY_F11 }, 91 | { WXK_F12, GTerm::KEY_F12 }, 92 | { (wxKeyCode)0, GTerm::KEY_NULL } 93 | }; 94 | 95 | static unsigned char 96 | xCharMap[] = 97 | { 98 | 0, // 0 99 | 1, // 1 100 | 2, // 2 101 | 3, // 3 102 | 1, // 4 103 | 5, // 5 104 | 6, // 6 105 | 7, // 7 106 | 8, // 8 107 | 9, // 9 108 | 10, // 10 109 | 11, // 11 110 | 12, // 12 111 | 13, // 13 112 | 14, // 14 113 | 15, // 15 114 | 62, // 16 115 | 60, // 17 116 | 18, // 18 117 | 19, // 19 118 | 20, // 20 119 | 21, // 21 120 | 22, // 22 121 | 23, // 23 122 | 24, // 24 123 | 25, // 25 124 | 26, // 26 125 | 27, // 27 126 | 28, // 28 127 | 29, // 29 128 | 94, // 30 129 | 31, // 31 130 | 32, // 32 131 | 33, // 33 132 | 34, // 34 133 | 35, // 35 134 | 36, // 36 135 | 37, // 37 136 | 38, // 38 137 | 39, // 39 138 | 40, // 40 139 | 41, // 41 140 | 42, // 42 141 | 43, // 43 142 | 44, // 44 143 | 45, // 45 144 | 46, // 46 145 | 47, // 47 146 | 48, // 48 147 | 49, // 49 148 | 50, // 50 149 | 51, // 51 150 | 52, // 52 151 | 53, // 53 152 | 54, // 54 153 | 55, // 55 154 | 56, // 56 155 | 57, // 57 156 | 58, // 58 157 | 59, // 59 158 | 60, // 60 159 | 61, // 61 160 | 62, // 62 161 | 63, // 63 162 | 64, // 64 163 | 65, // 65 164 | 66, // 66 165 | 67, // 67 166 | 68, // 68 167 | 69, // 69 168 | 70, // 70 169 | 71, // 71 170 | 72, // 72 171 | 73, // 73 172 | 74, // 74 173 | 75, // 75 174 | 76, // 76 175 | 77, // 77 176 | 78, // 78 177 | 79, // 79 178 | 80, // 80 179 | 81, // 81 180 | 82, // 82 181 | 83, // 83 182 | 84, // 84 183 | 85, // 85 184 | 86, // 86 185 | 87, // 87 186 | 88, // 88 187 | 89, // 89 188 | 90, // 90 189 | 91, // 91 190 | 92, // 92 191 | 93, // 93 192 | 94, // 94 193 | 95, // 95 194 | 96, // 96 195 | 97, // 97 196 | 98, // 98 197 | 99, // 99 198 | 100, // 100 199 | 101, // 101 200 | 102, // 102 201 | 103, // 103 202 | 104, // 104 203 | 105, // 105 204 | 106, // 106 205 | 107, // 107 206 | 108, // 108 207 | 109, // 109 208 | 110, // 110 209 | 111, // 111 210 | 112, // 112 211 | 113, // 113 212 | 114, // 114 213 | 115, // 115 214 | 116, // 116 215 | 117, // 117 216 | 118, // 118 217 | 119, // 119 218 | 120, // 120 219 | 121, // 121 220 | 122, // 122 221 | 123, // 123 222 | 124, // 124 223 | 125, // 125 224 | 126, // 126 225 | 127, // 127 226 | 128, // 128 227 | 129, // 129 228 | 130, // 130 229 | 131, // 131 230 | 132, // 132 231 | 133, // 133 232 | 134, // 134 233 | 135, // 135 234 | 136, // 136 235 | 137, // 137 236 | 138, // 138 237 | 139, // 139 238 | 140, // 140 239 | 141, // 141 240 | 142, // 142 241 | 143, // 143 242 | 144, // 144 243 | 145, // 145 244 | 146, // 146 245 | 147, // 147 246 | 148, // 148 247 | 149, // 149 248 | 150, // 150 249 | 151, // 151 250 | 152, // 152 251 | 153, // 153 252 | 154, // 154 253 | 155, // 155 254 | 156, // 156 255 | 157, // 157 256 | 158, // 158 257 | 159, // 159 258 | 160, // 160 259 | 161, // 161 260 | 162, // 162 261 | 163, // 163 262 | 164, // 164 263 | 165, // 165 264 | 166, // 166 265 | 167, // 167 266 | 168, // 168 267 | 169, // 169 268 | 170, // 170 269 | 171, // 171 270 | 172, // 172 271 | 173, // 173 272 | 174, // 174 273 | 175, // 175 274 | 2, // 176 275 | 2, // 177 276 | 2, // 178 277 | 25, // 179 278 | 22, // 180 279 | 22, // 181 280 | 22, // 182 281 | 12, // 183 282 | 12, // 184 283 | 22, // 185 284 | 25, // 186 285 | 12, // 187 286 | 11, // 188 287 | 11, // 189 288 | 11, // 190 289 | 12, // 191 290 | 14, // 192 291 | 23, // 193 292 | 24, // 194 293 | 21, // 195 294 | 18, // 196 295 | 15, // 197 296 | 21, // 198 297 | 21, // 199 298 | 14, // 200 299 | 13, // 201 300 | 23, // 202 301 | 24, // 203 302 | 21, // 204 303 | 18, // 205 304 | 15, // 206 305 | 23, // 207 306 | 23, // 208 307 | 24, // 209 308 | 24, // 210 309 | 14, // 211 310 | 14, // 212 311 | 13, // 213 312 | 13, // 214 313 | 15, // 215 314 | 15, // 216 315 | 11, // 217 316 | 13, // 218 317 | 0, // 219 318 | 220, // 220 319 | 221, // 221 320 | 222, // 222 321 | 223, // 223 322 | 224, // 224 323 | 225, // 225 324 | 226, // 226 325 | 227, // 227 326 | 228, // 228 327 | 229, // 229 328 | 230, // 230 329 | 231, // 231 330 | 232, // 232 331 | 233, // 233 332 | 234, // 234 333 | 235, // 235 334 | 236, // 236 335 | 237, // 237 336 | 238, // 238 337 | 239, // 239 338 | 240, // 240 339 | 241, // 241 340 | 242, // 242 341 | 243, // 243 342 | 244, // 244 343 | 245, // 245 344 | 246, // 246 345 | 247, // 247 346 | 248, // 248 347 | 249, // 249 348 | 250, // 250 349 | 251, // 251 350 | 252, // 252 351 | 253, // 253 352 | 254, // 254 353 | 255 // 255 354 | }; 355 | 356 | BEGIN_EVENT_TABLE(wxTerm, wxWindow) 357 | EVT_PAINT (wxTerm::OnPaint) 358 | EVT_CHAR (wxTerm::OnChar) 359 | EVT_LEFT_DOWN (wxTerm::OnLeftDown) 360 | EVT_LEFT_UP (wxTerm::OnLeftUp) 361 | EVT_MOTION (wxTerm::OnMouseMove) 362 | EVT_TIMER (-1, wxTerm::OnTimer) 363 | #if 0 364 | EVT_KEY_DOWN(wxTerm::OnKeyDown) 365 | #endif 366 | 367 | EVT_SIZE (wxTerm::OnSize) 368 | EVT_SET_FOCUS (wxTerm::OnGainFocus) 369 | EVT_KILL_FOCUS (wxTerm::OnLoseFocus) 370 | END_EVENT_TABLE() 371 | 372 | wxTerm::wxTerm(wxWindow* parent, wxWindowID id, 373 | const wxPoint& pos, 374 | int width, int height, 375 | const wxString& name) : 376 | wxWindow(parent, id, pos, wxSize(-1, -1), wxWANTS_CHARS, name), 377 | GTerm(width, height) 378 | { 379 | int 380 | i; 381 | 382 | m_inUpdateSize = false; 383 | m_init = 1; 384 | 385 | m_curDC = 0; 386 | 387 | m_charsInLine = width; 388 | m_linesDisplayed = height; 389 | 390 | m_selecting = FALSE; 391 | m_selx1 = m_sely1 = m_selx2 = m_sely2 = 0; 392 | m_marking = FALSE; 393 | m_curX = -1; 394 | m_curY = -1; 395 | m_curBlinkRate = CURSOR_BLINK_DEFAULT_TIMEOUT; 396 | m_timer.SetOwner(this); 397 | if(m_curBlinkRate) 398 | m_timer.Start(m_curBlinkRate); 399 | 400 | m_boldStyle = COLOR; 401 | 402 | GetDefVTColors(m_vt_colors); 403 | GetDefPCColors(m_pc_colors); 404 | 405 | m_colors = m_vt_colors; 406 | 407 | SetBackgroundColour(m_colors[0]); 408 | 409 | for(i = 0; i < 16; i++) 410 | m_vt_colorPens[i] = wxPen(m_vt_colors[i], 1, wxSOLID); 411 | 412 | for(i = 0; i < 16; i++) 413 | m_pc_colorPens[i] = wxPen(m_pc_colors[i], 1, wxSOLID); 414 | 415 | m_colorPens = m_vt_colorPens; 416 | 417 | m_width = width; 418 | m_height = height; 419 | 420 | m_printerFN = 0; 421 | m_printerName = 0; 422 | 423 | 424 | 425 | m_normalFont = GetFont(); 426 | m_underlinedFont = GetFont(); 427 | m_underlinedFont.SetUnderlined(TRUE); 428 | m_boldFont = GetFont(); 429 | m_boldFont.SetWeight(wxBOLD); 430 | m_boldUnderlinedFont = m_boldFont; 431 | m_boldUnderlinedFont.SetUnderlined(TRUE); 432 | 433 | m_bitmap = 0; 434 | 435 | 436 | //ResizeTerminal(width, height); 437 | 438 | 439 | //SetVirtualSize(m_charWidth * 80, m_charHeight * 100); 440 | //SetScrollRate(m_charWidth, m_charHeight); 441 | 442 | m_init = 0; 443 | 444 | SetCursor(wxCursor(wxCURSOR_IBEAM)); 445 | 446 | wxFont monospacedFont(10, wxMODERN, wxNORMAL, wxNORMAL, false, "Courier New"); 447 | 448 | SetFont(monospacedFont); 449 | 450 | // 10pt Courier New is 8 pixels wide and 16 pixels high... set up 451 | // a default client size to match 452 | SetClientSize(m_charsInLine * 8, m_linesDisplayed * 16); 453 | UpdateSize(); 454 | } 455 | 456 | wxTerm::~wxTerm() 457 | { 458 | if(m_bitmap) 459 | { 460 | m_memDC.SelectObject(wxNullBitmap); 461 | delete m_bitmap; 462 | } 463 | } 464 | 465 | ////////////////////////////////////////////////////////////////////////////// 466 | /// public SetBoldStyle 467 | /// Sets the bold style for the terminal 468 | /// 469 | /// @param boldStyle wxTerm::BOLDSTYLE & The style to be used 470 | /// 471 | /// @return void 472 | /// 473 | /// @author Derry Bryson @date 04-22-2004 474 | ////////////////////////////////////////////////////////////////////////////// 475 | void 476 | wxTerm::SetBoldStyle(wxTerm::BOLDSTYLE boldStyle) 477 | { 478 | // wxColour colors[16]; 479 | 480 | if(boldStyle == DEFAULT) 481 | boldStyle = COLOR; 482 | 483 | m_boldStyle = boldStyle; 484 | // GetDefVTColors(colors, m_boldStyle); 485 | // SetVTColors(colors); 486 | Refresh(); 487 | } 488 | 489 | ////////////////////////////////////////////////////////////////////////////// 490 | /// public SetFont 491 | /// Sets the font for the terminal 492 | /// 493 | /// @param font const wxFont & The font to be used 494 | /// 495 | /// @return bool Unused (returns true) 496 | /// 497 | /// @author Derry Bryson @date 04-22-2004 498 | ////////////////////////////////////////////////////////////////////////////// 499 | bool 500 | wxTerm::SetFont(const wxFont& font) 501 | { 502 | m_init = 1; 503 | 504 | wxWindow::SetFont(font); 505 | m_normalFont = font; 506 | m_underlinedFont = font; 507 | m_underlinedFont.SetUnderlined(TRUE); 508 | m_boldFont = GetFont(); 509 | m_boldFont.SetWeight(wxBOLD); 510 | m_boldUnderlinedFont = m_boldFont; 511 | m_boldUnderlinedFont.SetUnderlined(TRUE); 512 | m_init = 0; 513 | 514 | ResizeTerminal(m_width, m_height); 515 | Refresh(); 516 | 517 | return TRUE; 518 | } 519 | 520 | ////////////////////////////////////////////////////////////////////////////// 521 | /// public GetDfVTColors 522 | /// Gets the colors for a VT100 terminal 523 | /// 524 | /// @param colors wxColour [] The colors that need to be assigned to 525 | /// @param boldStyle wxTerm::BOLDSTYLE The bold style used in the terminal 526 | /// 527 | /// @return void 528 | /// 529 | /// @author Derry Bryson @date 04-22-2004 530 | ////////////////////////////////////////////////////////////////////////////// 531 | void 532 | wxTerm::GetDefVTColors(wxColour colors[16], wxTerm::BOLDSTYLE boldStyle) 533 | { 534 | if(boldStyle == DEFAULT) 535 | boldStyle = m_boldStyle; 536 | 537 | if(boldStyle != COLOR) 538 | { 539 | colors[0] = wxColour(0, 0, 0); // black 540 | colors[1] = wxColour(255, 0, 0); // red 541 | colors[2] = wxColour(0, 255, 0); // green 542 | colors[3] = wxColour(255, 0, 255); // yellow 543 | colors[4] = wxColour(0, 0, 255); // blue 544 | colors[5] = wxColour(255, 255, 0); // magenta 545 | colors[6] = wxColour(0, 255, 255); // cyan 546 | colors[7] = wxColour(255, 255, 255); // white 547 | colors[8] = wxColour(0, 0, 0); // black 548 | colors[9] = wxColour(255, 0, 0); // red 549 | colors[10] = wxColour(0, 255, 0); // green 550 | colors[11] = wxColour(255, 0, 255); // yellow 551 | colors[12] = wxColour(0, 0, 255); // blue 552 | colors[13] = wxColour(255, 255, 0); // magenta 553 | colors[14] = wxColour(0, 255, 255); // cyan 554 | colors[15] = wxColour(255, 255, 255); // white 555 | } 556 | else 557 | { 558 | colors[0] = wxColour(0, 0, 0); // black 559 | colors[1] = wxColour(170, 0, 0); // red 560 | colors[2] = wxColour(0, 170, 0); // green 561 | colors[3] = wxColour(170, 0, 170); // yellow 562 | colors[4] = wxColour(0, 0, 170); // blue 563 | colors[5] = wxColour(170, 170, 0); // magenta 564 | colors[6] = wxColour(0, 170, 170); // cyan 565 | colors[7] = wxColour(192, 192, 192); // white 566 | // colors[7] = wxColour(170, 170, 170); // white 567 | #if 0 568 | colors[8] = wxColour(85, 85, 85); // bold black 569 | colors[9] = wxColour(255, 85, 85); // bold red 570 | colors[10] = wxColour(85, 255, 85); // bold green 571 | colors[11] = wxColour(255, 85, 255); // bold yellow 572 | colors[12] = wxColour(85, 85, 255); // bold blue 573 | colors[13] = wxColour(255, 255, 85); // bold magenta 574 | colors[14] = wxColour(85, 255, 255); // bold cyan 575 | colors[15] = wxColour(255, 255, 255); // bold white 576 | #else 577 | colors[8] = wxColour(85, 85, 85); // bold black 578 | colors[9] = wxColour(255, 0, 0); // bold red 579 | colors[10] = wxColour(0, 255, 0); // bold green 580 | colors[11] = wxColour(255, 0, 255); // bold yellow 581 | colors[12] = wxColour(0, 0, 255); // bold blue 582 | colors[13] = wxColour(255, 255, 0); // bold magenta 583 | colors[14] = wxColour(0, 255, 255); // bold cyan 584 | colors[15] = wxColour(255, 255, 255); // bold white 585 | #endif 586 | } 587 | } 588 | 589 | ////////////////////////////////////////////////////////////////////////////// 590 | /// public GetVTColors 591 | /// Retrieves a copy of the VT100 colors 592 | /// 593 | /// @param colors wxColour [] An array to be filled with the VT100 colors 594 | /// 595 | /// @return void 596 | /// 597 | /// @author Derry Bryson @date 04-22-2004 598 | ////////////////////////////////////////////////////////////////////////////// 599 | void 600 | wxTerm::GetVTColors(wxColour colors[16]) 601 | { 602 | int 603 | i; 604 | 605 | for(i = 0; i < 16; i++) 606 | colors[i] = m_vt_colors[i]; 607 | } 608 | 609 | ////////////////////////////////////////////////////////////////////////////// 610 | /// public SetVTColors 611 | /// Sets the VT100 colors 612 | /// 613 | /// @param colors wxColour [] The new colors to be used 614 | /// 615 | /// @return void 616 | /// 617 | /// @author Derry Bryson @date 04-22-2004 618 | ////////////////////////////////////////////////////////////////////////////// 619 | void 620 | wxTerm::SetVTColors(wxColour colors[16]) 621 | { 622 | int 623 | i; 624 | 625 | m_init = 1; 626 | for(i = 0; i < 16; i++) 627 | m_vt_colors[i] = colors[i]; 628 | 629 | if(!(GetMode() & PC)) 630 | SetBackgroundColour(m_vt_colors[0]); 631 | 632 | for(i = 0; i < 16; i++) 633 | m_vt_colorPens[i] = wxPen(m_vt_colors[i], 1, wxSOLID); 634 | m_init = 0; 635 | 636 | Refresh(); 637 | } 638 | 639 | ////////////////////////////////////////////////////////////////////////////// 640 | /// public GetDefPCColors 641 | /// Gets the default PC colors 642 | /// 643 | /// @param colors wxColour [] Filled with the colors to be used 644 | /// 645 | /// @return void 646 | /// 647 | /// @author Derry Bryson @date 04-22-2004 648 | ////////////////////////////////////////////////////////////////////////////// 649 | void 650 | wxTerm::GetDefPCColors(wxColour colors[16]) 651 | { 652 | #if 0 653 | /* 654 | ** These colors need tweaking. I'm sure they are not correct. 655 | */ 656 | colors[0] = wxColour(0, 0, 0); // black 657 | colors[1] = wxColour(0, 0, 128); // blue 658 | colors[2] = wxColour(0, 128, 0); // green 659 | colors[3] = wxColour(0, 128, 128); // cyan 660 | colors[4] = wxColour(128, 0, 0); // red 661 | colors[5] = wxColour(128, 0, 128); // magenta 662 | colors[6] = wxColour(128, 128, 0); // brown 663 | colors[7] = wxColour(128, 128, 128); // white 664 | colors[8] = wxColour(64, 64, 64); // gray 665 | colors[9] = wxColour(0, 0, 255); // lt blue 666 | colors[10] = wxColour(0, 255, 0); // lt green 667 | colors[11] = wxColour(0, 255, 255); // lt cyan 668 | colors[12] = wxColour(255, 0, 0); // lt red 669 | colors[13] = wxColour(255, 0, 255); // lt magenta 670 | colors[14] = wxColour(255, 255, 0); // yellow 671 | colors[15] = wxColour(255, 255, 255); // white 672 | #else 673 | /* 674 | ** These are much better 675 | */ 676 | colors[0] = wxColour(0, 0, 0); // black 677 | colors[1] = wxColour(0, 0, 170); // blue 678 | colors[2] = wxColour(0, 170, 0); // green 679 | colors[3] = wxColour(0, 170, 170); // cyan 680 | colors[4] = wxColour(170, 0, 0); // red 681 | colors[5] = wxColour(170, 0, 170); // magenta 682 | colors[6] = wxColour(170, 170, 0); // brown 683 | colors[7] = wxColour(170, 170, 170); // white 684 | #if 0 685 | colors[8] = wxColour(85, 85, 85); // gray 686 | colors[9] = wxColour(85, 85, 255); // lt blue 687 | colors[10] = wxColour(85, 255, 85); // lt green 688 | colors[11] = wxColour(85, 255, 255); // lt cyan 689 | colors[12] = wxColour(255, 85, 85); // lt red 690 | colors[13] = wxColour(255, 85, 255); // lt magenta 691 | colors[14] = wxColour(255, 255, 85); // yellow 692 | colors[15] = wxColour(255, 255, 255); // white 693 | #else 694 | colors[8] = wxColour(50, 50, 50); // gray 695 | colors[9] = wxColour(0, 0, 255); // lt blue 696 | colors[10] = wxColour(0, 255, 0); // lt green 697 | colors[11] = wxColour(0, 255, 255); // lt cyan 698 | colors[12] = wxColour(255, 0, 0); // lt red 699 | colors[13] = wxColour(255, 0, 255); // lt magenta 700 | colors[14] = wxColour(255, 255, 0); // yellow 701 | colors[15] = wxColour(255, 255, 255); // white 702 | #endif 703 | #endif 704 | } 705 | 706 | ////////////////////////////////////////////////////////////////////////////// 707 | /// public GetPCColors 708 | /// Retrieves the PC colors 709 | /// 710 | /// @param colors wxColour [] Filled with the PC colors 711 | /// 712 | /// @return void 713 | /// 714 | /// @author Derry Bryson @date 04-22-2004 715 | ////////////////////////////////////////////////////////////////////////////// 716 | void 717 | wxTerm::GetPCColors(wxColour colors[16]) 718 | { 719 | int 720 | i; 721 | 722 | for(i = 0; i < 16; i++) 723 | colors[i] = m_pc_colors[i]; 724 | } 725 | 726 | ////////////////////////////////////////////////////////////////////////////// 727 | /// public SetPCColors 728 | /// Sets the PC colors 729 | /// 730 | /// @param colors wxColour [] The new colors to be used 731 | /// 732 | /// @return void 733 | /// 734 | /// @author Derry Bryson @date 04-22-2004 735 | ////////////////////////////////////////////////////////////////////////////// 736 | void 737 | wxTerm::SetPCColors(wxColour colors[16]) 738 | { 739 | int 740 | i; 741 | 742 | m_init = 1; 743 | for(i = 0; i < 16; i++) 744 | m_pc_colors[i] = colors[i]; 745 | 746 | if(GetMode() & PC) 747 | SetBackgroundColour(m_pc_colors[0]); 748 | 749 | for(i = 0; i < 16; i++) 750 | m_pc_colorPens[i] = wxPen(m_pc_colors[i], 1, wxSOLID); 751 | m_init = 0; 752 | 753 | Refresh(); 754 | } 755 | 756 | ////////////////////////////////////////////////////////////////////////////// 757 | /// public SetCursorBlinkRate 758 | /// Sets how often the cursor blinks 759 | /// 760 | /// @param rate int How many milliseconds between blinks 761 | /// 762 | /// @return void 763 | /// 764 | /// @author Derry Bryson @date 04-22-2004 765 | ////////////////////////////////////////////////////////////////////////////// 766 | void 767 | wxTerm::SetCursorBlinkRate(int rate) 768 | { 769 | if(rate < 0 || rate > CURSOR_BLINK_MAX_TIMEOUT) 770 | return; 771 | 772 | m_init = 1; 773 | if(rate != m_curBlinkRate) 774 | { 775 | m_curBlinkRate = rate; 776 | if(!m_curBlinkRate) 777 | m_timer.Stop(); 778 | else 779 | m_timer.Start(m_curBlinkRate); 780 | } 781 | m_init = 0; 782 | } 783 | 784 | ////////////////////////////////////////////////////////////////////////////// 785 | /// private OnChar 786 | /// Handles user keyboard input and begins processing the server's response 787 | /// 788 | /// @param event wxKeyEvent & The generated key event 789 | /// 790 | /// @return void 791 | /// 792 | /// @author Derry Bryson @date 04-22-2004 793 | ////////////////////////////////////////////////////////////////////////////// 794 | void 795 | wxTerm::OnChar(wxKeyEvent& event) 796 | { 797 | if(!(GetMode() & PC) && event.AltDown()) 798 | event.Skip(); 799 | else 800 | { 801 | 802 | int 803 | rc, 804 | keyCode = 0, 805 | len; 806 | 807 | unsigned char 808 | buf[10]; 809 | 810 | /* 811 | ** Map control characters 812 | */ 813 | if(event.ControlDown()) 814 | { 815 | if(event.GetKeyCode() >= 'a' && event.GetKeyCode() <= 'z') 816 | keyCode = event.GetKeyCode() - 'a' + 1; 817 | else if(event.GetKeyCode() >= '[' && event.GetKeyCode() <= '_') 818 | keyCode = event.GetKeyCode() - '[' + 0x1b; 819 | else if(event.GetKeyCode() == '6') 820 | keyCode = 0x1e; 821 | else if(event.GetKeyCode() == '-') 822 | keyCode = 0x1f; 823 | } 824 | 825 | if(!keyCode && !(keyCode = MapKeyCode((int)event.GetKeyCode()))) 826 | { 827 | /* 828 | ** If the keycode wasn't mapped in the table and it is a special 829 | ** key, then we just ignore it. 830 | */ 831 | if(event.GetKeyCode() >= WXK_START) 832 | { 833 | event.Skip(); 834 | return; 835 | } 836 | /* 837 | ** Otherwise, it must just be an ascii character 838 | */ 839 | keyCode = (int)event.GetKeyCode(); 840 | } 841 | 842 | if(GetMode() & PC) 843 | rc = TranslateKeyCode(keyCode, &len, (char *)buf, event.ShiftDown(), 844 | event.ControlDown(), event.AltDown()); 845 | else 846 | rc = TranslateKeyCode(keyCode, &len, (char *)buf); 847 | 848 | if(rc) 849 | { 850 | if((GetMode() & NEWLINE) && !(GetMode() & PC) && (buf[len - 1] == 10)) 851 | { 852 | buf[len - 1] = 13; 853 | buf[len] = 10; 854 | len++; 855 | } 856 | ProcessOutput(len, buf); 857 | if((GetMode() & LOCALECHO) && !(GetMode() & PC)) 858 | ProcessInput(len, buf); 859 | } 860 | else if(!(GetMode() & PC)) 861 | { 862 | if((GetMode() & NEWLINE) && !(GetMode() & PC) && (keyCode == 10)) 863 | { 864 | len = 2; 865 | buf[0] = 13; 866 | buf[1] = keyCode; 867 | } 868 | else 869 | { 870 | len = 1; 871 | buf[0] = keyCode; 872 | } 873 | ProcessOutput(len, buf); 874 | if((GetMode() & LOCALECHO) && !(GetMode() & PC)) 875 | ProcessInput(len, buf); 876 | } 877 | else 878 | event.Skip(); 879 | } 880 | } 881 | 882 | ////////////////////////////////////////////////////////////////////////////// 883 | /// private OnKeyDown 884 | /// Appears to be unused 885 | /// 886 | /// @param event wxKeyEvent & The generated key event 887 | /// 888 | /// @return void 889 | /// 890 | /// @author Derry Bryson @date 04-22-2004 891 | ////////////////////////////////////////////////////////////////////////////// 892 | void 893 | wxTerm::OnKeyDown(wxKeyEvent& event) 894 | { 895 | if(!(GetMode() & PC) && event.AltDown()) 896 | event.Skip(); 897 | else if(event.AltDown()) 898 | { 899 | // wxLogMessage("OnKeyDown() got KeyCode = %d", event.KeyCode()); 900 | // if(event.KeyCode() != 309) 901 | // OnChar(event); 902 | } 903 | else 904 | event.Skip(); 905 | } 906 | 907 | ////////////////////////////////////////////////////////////////////////////// 908 | /// private OnPaint 909 | /// Redraws the terminal widget 910 | /// 911 | /// @param event wxPaintEvent & The generated paint event 912 | /// 913 | /// @return void 914 | /// 915 | /// @author Derry Bryson @date 04-22-2004 916 | ////////////////////////////////////////////////////////////////////////////// 917 | void 918 | wxTerm::OnPaint(wxPaintEvent& WXUNUSED(event)) 919 | { 920 | wxPaintDC 921 | dc(this); 922 | 923 | m_curDC = &dc; 924 | ExposeArea(0, 0, m_width, m_height); 925 | m_curDC = 0; 926 | } 927 | 928 | ////////////////////////////////////////////////////////////////////////////// 929 | /// private OnLeftDown 930 | /// Begins selection of terminal text 931 | /// 932 | /// @param event wxMouseEvent & The generated mouse event 933 | /// 934 | /// @return void 935 | /// 936 | /// @author Derry Bryson @date 04-22-2004 937 | ////////////////////////////////////////////////////////////////////////////// 938 | void 939 | wxTerm::OnLeftDown(wxMouseEvent& event) 940 | { 941 | SetFocus(); 942 | 943 | ClearSelection(); 944 | m_selx1 = m_selx2 = event.GetX() / m_charWidth; 945 | m_sely1 = m_sely2 = event.GetY() / m_charHeight; 946 | m_selecting = TRUE; 947 | CaptureMouse(); 948 | 949 | } 950 | 951 | ////////////////////////////////////////////////////////////////////////////// 952 | /// private OnLeftUp 953 | /// Ends text selection 954 | /// 955 | /// @param event wxMouseEvent & The generated mouse event 956 | /// 957 | /// @return void 958 | /// 959 | /// @author Derry Bryson @date 04-22-2004 960 | ////////////////////////////////////////////////////////////////////////////// 961 | void 962 | wxTerm::OnLeftUp(wxMouseEvent& event) 963 | { 964 | 965 | m_selecting = FALSE; 966 | if(GetCapture() == this) 967 | { 968 | ReleaseMouse(); 969 | } 970 | 971 | } 972 | 973 | ////////////////////////////////////////////////////////////////////////////// 974 | /// private OnMouseMove 975 | /// Changes the selection if the mouse button is down 976 | /// 977 | /// @param event wxMouseEvent & The generated mouse event 978 | /// 979 | /// @return void 980 | /// 981 | /// @author Derry Bryson @date 04-22-2004 982 | ////////////////////////////////////////////////////////////////////////////// 983 | void 984 | wxTerm::OnMouseMove(wxMouseEvent& event) 985 | { 986 | 987 | if(m_selecting) 988 | { 989 | m_selx2 = event.GetX() / m_charWidth; 990 | if(m_selx2 >= Width()) 991 | m_selx2 = Width() - 1; 992 | m_sely2 = event.GetY() / m_charHeight; 993 | if(m_sely2 >= Height()) 994 | m_sely2 = Height() - 1; 995 | 996 | MarkSelection(); 997 | } 998 | } 999 | 1000 | ////////////////////////////////////////////////////////////////////////////// 1001 | /// public ClearSelection 1002 | /// De-selects all selected text 1003 | /// 1004 | /// @return void 1005 | /// 1006 | /// @author Derry Bryson @date 04-22-2004 1007 | ////////////////////////////////////////////////////////////////////////////// 1008 | void 1009 | wxTerm::ClearSelection() 1010 | { 1011 | int 1012 | x, 1013 | y; 1014 | 1015 | wxClientDC 1016 | *dc = 0; 1017 | 1018 | m_selx1 = m_sely1 = m_selx2 = m_sely2 = 0; 1019 | 1020 | if(!m_curDC) 1021 | { 1022 | dc = new wxClientDC(this); 1023 | m_curDC = dc; 1024 | } 1025 | 1026 | for(y = 0; y < Height(); y++) 1027 | for(x = 0; x < Width(); x++) 1028 | Select(x, y, 0); 1029 | 1030 | if(dc) 1031 | { 1032 | this->wxWindow::Update(); 1033 | 1034 | m_curDC = 0; 1035 | delete dc; 1036 | } 1037 | } 1038 | 1039 | ////////////////////////////////////////////////////////////////////////////// 1040 | /// private MarkSelection 1041 | /// Does _something_ as far as selecting text, but not really sure... used for SelectAll, I think 1042 | /// 1043 | /// @return void 1044 | /// 1045 | /// @author Derry Bryson @date 04-22-2004 1046 | ////////////////////////////////////////////////////////////////////////////// 1047 | void 1048 | wxTerm::MarkSelection() 1049 | { 1050 | int 1051 | x, 1052 | y; 1053 | 1054 | wxClientDC 1055 | *dc = 0; 1056 | 1057 | m_marking = TRUE; 1058 | 1059 | if(!m_curDC) 1060 | { 1061 | dc = new wxClientDC(this); 1062 | m_curDC = dc; 1063 | } 1064 | 1065 | for(y = 0; y < Height(); y++) 1066 | for(x = 0; x < Width(); x++) 1067 | Select(x, y, 0); 1068 | 1069 | if(m_sely1 == m_sely2) 1070 | { 1071 | if(m_selx1 >= m_selx2) 1072 | for(x = m_selx1; x <= m_selx2; x++) 1073 | Select(x, m_sely1, 1); 1074 | else 1075 | for(x = m_selx2; x >= m_selx1; x--) 1076 | Select(x, m_sely1, 1); 1077 | } 1078 | else if(m_sely1 < m_sely2) 1079 | { 1080 | for(x = m_selx1; x < Width(); x++) 1081 | Select(x, m_sely1, 1); 1082 | 1083 | for(y = m_sely1 + 1; y < m_sely2; y++) 1084 | for(x = 0; x < Width(); x++) 1085 | Select(x, y, 1); 1086 | 1087 | for(x = 0; x <= m_selx2; x++) 1088 | Select(x, m_sely2, 1); 1089 | } 1090 | else 1091 | { 1092 | for(x = 0; x <= m_selx1; x++) 1093 | Select(x, m_sely1, 1); 1094 | 1095 | for(y = m_sely2 + 1; y < m_sely1; y++) 1096 | for(x = 0; x < Width(); x++) 1097 | Select(x, y, 1); 1098 | 1099 | for(x = m_selx2; x < Width(); x++) 1100 | Select(x, m_sely2, 1); 1101 | } 1102 | 1103 | this->wxWindow::Update(); 1104 | 1105 | if(dc) 1106 | { 1107 | m_curDC = 0; 1108 | delete dc; 1109 | } 1110 | 1111 | m_marking = FALSE; 1112 | } 1113 | 1114 | ////////////////////////////////////////////////////////////////////////////// 1115 | /// public HasSelection 1116 | /// Checks if any text is selected 1117 | /// 1118 | /// @return bool Whether or not there's any text selected 1119 | /// 1120 | /// @author Derry Bryson @date 04-22-2004 1121 | ////////////////////////////////////////////////////////////////////////////// 1122 | bool 1123 | wxTerm::HasSelection() 1124 | { 1125 | return(m_selx1 != m_selx2 || m_sely1 != m_sely2); 1126 | } 1127 | 1128 | wxString 1129 | ////////////////////////////////////////////////////////////////////////////// 1130 | /// public GetSelection 1131 | /// Returns the selected text 1132 | /// 1133 | /// @return wxString The selected text 1134 | /// 1135 | /// @author Derry Bryson @date 04-22-2004 1136 | ////////////////////////////////////////////////////////////////////////////// 1137 | wxTerm::GetSelection() 1138 | { 1139 | int 1140 | x1, 1141 | y1, 1142 | x2, 1143 | y2; 1144 | 1145 | wxString 1146 | sel; 1147 | 1148 | if(m_sely1 <= m_sely2) 1149 | { 1150 | x1 = m_selx1; 1151 | y1 = m_sely1; 1152 | x2 = m_selx2; 1153 | y2 = m_sely2; 1154 | } 1155 | else 1156 | { 1157 | x1 = m_selx2; 1158 | y1 = m_sely2; 1159 | x2 = m_selx1; 1160 | y2 = m_sely1; 1161 | } 1162 | 1163 | while(x1 != x2 || y1 != y2) 1164 | { 1165 | if(GetChar(x1, y1)) 1166 | sel.Append(GetChar(x1, y1)); 1167 | 1168 | x1++; 1169 | if(x1 == Width()) 1170 | { 1171 | sel.Append('\n'); 1172 | x1 = 0; 1173 | y1++; 1174 | } 1175 | } 1176 | if(GetChar(x1, y1)) 1177 | sel.Append(GetChar(x1, y1)); 1178 | 1179 | return sel; 1180 | } 1181 | 1182 | ////////////////////////////////////////////////////////////////////////////// 1183 | /// public SelectAll 1184 | /// Selects the whole terminal 1185 | /// 1186 | /// @return void 1187 | /// 1188 | /// @author Derry Bryson @date 04-22-2004 1189 | ////////////////////////////////////////////////////////////////////////////// 1190 | void 1191 | wxTerm::SelectAll() 1192 | { 1193 | m_selx1 = 0; 1194 | m_sely1 = 0; 1195 | m_selx2 = Width() - 1; 1196 | m_sely2 = Height() - 1; 1197 | MarkSelection(); 1198 | } 1199 | 1200 | /* 1201 | ** GTerm stuff 1202 | */ 1203 | ////////////////////////////////////////////////////////////////////////////// 1204 | /// public virtual DrawText 1205 | /// Responsible for actually drawing the terminal text on the widget. This virtual 1206 | /// function is called from GTerm::update_changes. 1207 | /// 1208 | /// @param fg_color int The index of the foreground color 1209 | /// @param bg_color int The index of the background color 1210 | /// @param flags int Modifiers for drawing the text 1211 | /// @param x int The x position in character cells 1212 | /// @param y int The y position in character cells 1213 | /// @param len int The number of characters to draw 1214 | /// @param string unsigned char * The characters to draw 1215 | /// 1216 | /// @return void 1217 | /// 1218 | /// @author Derry Bryson @date 04-22-2004 1219 | ////////////////////////////////////////////////////////////////////////////// 1220 | void 1221 | wxTerm::DrawText(int fg_color, int bg_color, int flags, 1222 | int x, int y, int len, unsigned char *string) 1223 | { 1224 | int 1225 | t; 1226 | 1227 | if(flags & BOLD && m_boldStyle == COLOR) 1228 | fg_color = (fg_color % 8) + 8; 1229 | 1230 | if(flags & SELECTED) 1231 | { 1232 | fg_color = 0; 1233 | bg_color = 15; 1234 | } 1235 | 1236 | if(flags & INVERSE) 1237 | { 1238 | t = fg_color; 1239 | fg_color = bg_color; 1240 | bg_color = t; 1241 | } 1242 | 1243 | if(!m_curDC) 1244 | return; 1245 | 1246 | #if defined(__WXGTK__) || defined(__WXMOTIF__) 1247 | int 1248 | i; 1249 | 1250 | for(i = 0; string[i]; i++) 1251 | string[i] = xCharMap[string[i]]; 1252 | #endif 1253 | 1254 | wxString 1255 | str(string, len); 1256 | 1257 | if(m_boldStyle != FONT) 1258 | { 1259 | if(flags & UNDERLINE) 1260 | m_curDC->SetFont(m_underlinedFont); 1261 | else 1262 | m_curDC->SetFont(m_normalFont); 1263 | } 1264 | else 1265 | { 1266 | if(flags & BOLD) 1267 | { 1268 | if(flags & UNDERLINE) 1269 | m_curDC->SetFont(m_boldUnderlinedFont); 1270 | else 1271 | m_curDC->SetFont(m_boldFont); 1272 | } 1273 | else 1274 | { 1275 | if(flags & UNDERLINE) 1276 | m_curDC->SetFont(m_underlinedFont); 1277 | else 1278 | m_curDC->SetFont(m_normalFont); 1279 | } 1280 | } 1281 | 1282 | x = x * m_charWidth; 1283 | y = y * m_charHeight; 1284 | m_curDC->SetBackgroundMode(wxSOLID); 1285 | m_curDC->SetTextBackground(m_colors[bg_color]); 1286 | m_curDC->SetTextForeground(m_colors[fg_color]); 1287 | m_curDC->DrawText(str, x, y); 1288 | if(flags & BOLD && m_boldStyle == OVERSTRIKE) 1289 | { 1290 | m_curDC->SetBackgroundMode(wxTRANSPARENT); 1291 | m_curDC->DrawText(str, x + 1, y); 1292 | } 1293 | } 1294 | 1295 | ////////////////////////////////////////////////////////////////////////////// 1296 | /// private DoDrawCursor 1297 | /// Does the actual work of drawing the cursor 1298 | /// 1299 | /// @param fg_color int The index of the foreground color 1300 | /// @param bg_color int The index of the background color 1301 | /// @param flags int Modifier flags 1302 | /// @param x int The x position of the cursor, in characters 1303 | /// @param y int The y position of the cursor, in characters 1304 | /// @param c unsigned char The character the cursor is over 1305 | /// 1306 | /// @return void 1307 | /// 1308 | /// @author Derry Bryson @date 04-22-2004 1309 | ////////////////////////////////////////////////////////////////////////////// 1310 | void 1311 | wxTerm::DoDrawCursor(int fg_color, int bg_color, int flags, 1312 | int x, int y, unsigned char c) 1313 | { 1314 | 1315 | if(flags & BOLD && m_boldStyle == COLOR) 1316 | fg_color = (fg_color % 8) + 8; 1317 | 1318 | if(flags & INVERSE) 1319 | { 1320 | int t = fg_color; 1321 | fg_color = bg_color; 1322 | bg_color = t; 1323 | } 1324 | 1325 | if(!m_curDC) 1326 | return; 1327 | 1328 | #if defined(__WXGTK__) || defined(__WXMOTIF__) 1329 | c = xCharMap[c]; 1330 | #endif 1331 | 1332 | wxString 1333 | str((char)c); 1334 | 1335 | if(m_boldStyle != FONT) 1336 | { 1337 | if(flags & UNDERLINE) 1338 | m_curDC->SetFont(m_underlinedFont); 1339 | else 1340 | m_curDC->SetFont(m_normalFont); 1341 | } 1342 | else 1343 | { 1344 | if(flags & BOLD) 1345 | { 1346 | if(flags & UNDERLINE) 1347 | m_curDC->SetFont(m_boldUnderlinedFont); 1348 | else 1349 | m_curDC->SetFont(m_boldFont); 1350 | } 1351 | else 1352 | { 1353 | if(flags & UNDERLINE) 1354 | m_curDC->SetFont(m_underlinedFont); 1355 | else 1356 | m_curDC->SetFont(m_normalFont); 1357 | } 1358 | } 1359 | 1360 | x = x * m_charWidth; 1361 | y = y * m_charHeight; 1362 | m_curDC->SetBackgroundMode(wxSOLID); 1363 | m_curDC->SetTextBackground(m_colors[fg_color]); 1364 | m_curDC->SetTextForeground(m_colors[bg_color]); 1365 | m_curDC->DrawText(str, x, y); 1366 | if(flags & BOLD && m_boldStyle == OVERSTRIKE) 1367 | m_curDC->DrawText(str, x + 1, y); 1368 | } 1369 | 1370 | ////////////////////////////////////////////////////////////////////////////// 1371 | /// public virtual DrawCursor 1372 | /// Draws the cursor on the terminal widget. This virtual function is called 1373 | /// from GTerm::update_changes. 1374 | /// 1375 | /// @param fg_color int The index of the foreground color 1376 | /// @param bg_color int The index of the background color 1377 | /// @param flags int Modifiers for drawing the cursor 1378 | /// @param x int The x position in character cells 1379 | /// @param y int The y position in character cells 1380 | /// @param c unsigned char The character that underlies the cursor 1381 | /// 1382 | /// @return void 1383 | /// 1384 | /// @author Derry Bryson @date 04-22-2004 1385 | ////////////////////////////////////////////////////////////////////////////// 1386 | void 1387 | wxTerm::DrawCursor(int fg_color, int bg_color, int flags, 1388 | int x, int y, unsigned char c) 1389 | { 1390 | m_curX = x; 1391 | m_curY = y; 1392 | m_curFG = fg_color; 1393 | m_curBG = bg_color, 1394 | m_curFlags = flags; 1395 | m_curChar = c; 1396 | 1397 | 1398 | 1399 | if(m_timer.IsRunning()) 1400 | m_timer.Stop(); 1401 | DoDrawCursor(fg_color, bg_color, flags, x, y, c); 1402 | if(m_curBlinkRate) 1403 | { 1404 | m_timer.Start(m_curBlinkRate); 1405 | m_curState = 1; 1406 | } 1407 | } 1408 | 1409 | ////////////////////////////////////////////////////////////////////////////// 1410 | /// private OnTimer 1411 | /// Blinks the cursor each time it goes off 1412 | /// 1413 | /// @param event wxTimerEvent & The generated timer event 1414 | /// 1415 | /// @return void 1416 | /// 1417 | /// @author Derry Bryson @date 04-22-2004 1418 | ////////////////////////////////////////////////////////////////////////////// 1419 | void 1420 | wxTerm::OnTimer(wxTimerEvent& WXUNUSED(event)) 1421 | { 1422 | wxClientDC 1423 | *dc = 0; 1424 | 1425 | if(m_init) 1426 | return; 1427 | 1428 | if(m_curX == -1 || m_curY == -1) 1429 | return; 1430 | 1431 | if(GetMode() & CURSORINVISIBLE) 1432 | { 1433 | //wxLogDebug("Skipping cursor"); 1434 | return; 1435 | } 1436 | //wxLogDebug("Drawing cursor"); 1437 | if(!m_curDC) 1438 | { 1439 | dc = new wxClientDC(this); 1440 | m_curDC = dc; 1441 | } 1442 | 1443 | if(m_curBlinkRate) 1444 | { 1445 | m_curState++; 1446 | if(m_curState & 1 && m_curX != -1 && m_curY != -1) 1447 | DoDrawCursor(m_curFG, m_curBG, m_curFlags, m_curX, m_curY, m_curChar); 1448 | else 1449 | DoDrawCursor(m_curBG, m_curFG, m_curFlags, m_curX, m_curY, m_curChar); 1450 | } 1451 | 1452 | if(dc) 1453 | { 1454 | delete dc; 1455 | m_curDC = 0; 1456 | } 1457 | } 1458 | 1459 | ////////////////////////////////////////////////////////////////////////////// 1460 | /// public virtual MoveChars 1461 | /// Moves characters on the screen. This virtual function is called from 1462 | /// GTerm::update_changes. 1463 | /// 1464 | /// @param sx int The starting x position, in character cells 1465 | /// @param sy int The starting y position, in character cells 1466 | /// @param dx int The number of character cells to shift in the x direction 1467 | /// @param dy int The number of character cells to shift in the y direction 1468 | /// @param w int The width in characters of the area to be moved 1469 | /// @param h int The height in characters of the area to be moved 1470 | /// 1471 | /// @return void 1472 | /// 1473 | /// @author Derry Bryson @date 04-22-2004 1474 | ////////////////////////////////////////////////////////////////////////////// 1475 | void 1476 | wxTerm::MoveChars(int sx, int sy, int dx, int dy, int w, int h) 1477 | { 1478 | if(!m_marking) 1479 | ClearSelection(); 1480 | 1481 | sx = sx * m_charWidth; 1482 | sy = sy * m_charHeight; 1483 | dx = dx * m_charWidth; 1484 | dy = dy * m_charHeight; 1485 | w = w * m_charWidth; 1486 | h = h * m_charHeight; 1487 | 1488 | m_memDC.Blit(0, 0, w, h, m_curDC, sx, sy); 1489 | m_curDC->Blit(dx, dy, w, h, &m_memDC, 0, 0); 1490 | } 1491 | 1492 | ////////////////////////////////////////////////////////////////////////////// 1493 | /// public virtual ClearChars 1494 | /// Clears a section of characters from the screen. This virtual function 1495 | /// is called from GTerm::update_changes. 1496 | /// 1497 | /// @param bg_color int The background color to replace the characters with 1498 | /// @param x int The starting x position, in characters 1499 | /// @param y int The starting y position, in characters 1500 | /// @param w int The width of the area to be cleared, in characters 1501 | /// @param h int The height of the area to be cleared, in characters 1502 | /// 1503 | /// @return void 1504 | /// 1505 | /// @author Derry Bryson @date 04-22-2004 1506 | ////////////////////////////////////////////////////////////////////////////// 1507 | void 1508 | wxTerm::ClearChars(int bg_color, int x, int y, int w, int h) 1509 | { 1510 | if(!m_marking) 1511 | ClearSelection(); 1512 | 1513 | x = x * m_charWidth; 1514 | y = y * m_charHeight; 1515 | w = w * m_charWidth; 1516 | h = h * m_charHeight; 1517 | 1518 | bool deleteDC = false; 1519 | if(!m_curDC) 1520 | { 1521 | m_curDC = new wxClientDC(this); 1522 | deleteDC = true; 1523 | } 1524 | m_curDC->SetPen(m_colorPens[bg_color]); 1525 | m_curDC->SetBrush(wxBrush(m_colors[bg_color], wxSOLID)); 1526 | m_curDC->DrawRectangle(x, y, w /* + 1*/, h /*+ 1*/); 1527 | 1528 | if(deleteDC) 1529 | { 1530 | delete m_curDC; 1531 | m_curDC = 0; 1532 | } 1533 | } 1534 | 1535 | ////////////////////////////////////////////////////////////////////////////// 1536 | /// public virtual ModeChange 1537 | /// Changes the drawing mode between VT100 and PC 1538 | /// 1539 | /// @param state int The new state 1540 | /// 1541 | /// @return void 1542 | /// 1543 | /// @author Derry Bryson @date 04-22-2004 1544 | ////////////////////////////////////////////////////////////////////////////// 1545 | void 1546 | wxTerm::ModeChange(int state) 1547 | { 1548 | ClearSelection(); 1549 | 1550 | if(state & GTerm::PC) 1551 | { 1552 | m_colors = m_pc_colors; 1553 | m_colorPens = m_pc_colorPens; 1554 | } 1555 | else 1556 | { 1557 | m_colors = m_vt_colors; 1558 | m_colorPens = m_vt_colorPens; 1559 | } 1560 | GTerm/*lnet*/::ModeChange(state); 1561 | } 1562 | 1563 | ////////////////////////////////////////////////////////////////////////////// 1564 | /// public virtual Bell 1565 | /// Rings the system bell 1566 | /// 1567 | /// @return void 1568 | /// 1569 | /// @author Derry Bryson @date 04-22-2004 1570 | ////////////////////////////////////////////////////////////////////////////// 1571 | void 1572 | wxTerm::Bell() 1573 | { 1574 | wxBell(); 1575 | } 1576 | 1577 | ////////////////////////////////////////////////////////////////////////////// 1578 | /// public UpdateSize 1579 | /// Updates the terminal's size in characters after it has been resized on the screen. 1580 | /// 1581 | /// @return void 1582 | /// 1583 | /// @author Mark Erikson @date 04-22-2004 1584 | ////////////////////////////////////////////////////////////////////////////// 1585 | void wxTerm::UpdateSize() 1586 | { 1587 | // prevent any nasty recursion 1588 | if(m_inUpdateSize) 1589 | { 1590 | return; 1591 | } 1592 | 1593 | m_inUpdateSize = true; 1594 | int charWidth, charHeight; 1595 | 1596 | wxClientDC* dc = new wxClientDC(this); 1597 | 1598 | if(!m_curDC) 1599 | { 1600 | m_curDC = dc; 1601 | } 1602 | 1603 | dc->SetFont(m_normalFont); 1604 | dc->GetTextExtent("M", &charWidth, &charHeight); 1605 | wxSize currentClientSize = GetClientSize(); 1606 | int numCharsInLine = currentClientSize.GetX() / charWidth; 1607 | int numLinesShown = currentClientSize.GetY() / charHeight; 1608 | 1609 | 1610 | 1611 | if( (numCharsInLine != m_charsInLine) || (numLinesShown != m_linesDisplayed)) 1612 | { 1613 | wxString message; 1614 | 1615 | // FINALLY! Finally killed the memory leak! The problem is that somehow a size event 1616 | // was generating negative numbers for these values, which led to weird things happening. 1617 | if( (numCharsInLine > 0) && (numLinesShown > 0)) 1618 | { 1619 | m_charsInLine = numCharsInLine; 1620 | m_linesDisplayed = numLinesShown; 1621 | // tell the GTerm core to resize itself 1622 | ResizeTerminal(numCharsInLine, numLinesShown); 1623 | 1624 | UpdateRemoteSize(m_charsInLine, m_linesDisplayed); 1625 | /* 1626 | wxString remoteResizeCommand = wxString::Format("stty rows %d cols %d", m_linesDisplayed, m_charsInLine); 1627 | wxLogDebug("Resizing terminal: %s", remoteResizeCommand); 1628 | wxStringBuffer tempBuffer(remoteResizeCommand, 256); 1629 | SendBack(tempBuffer); 1630 | */ 1631 | } 1632 | } 1633 | 1634 | m_inUpdateSize = false; 1635 | 1636 | if(dc) 1637 | { 1638 | delete dc; 1639 | m_curDC = 0; 1640 | } 1641 | } 1642 | 1643 | ////////////////////////////////////////////////////////////////////////////// 1644 | /// public virtual ResizeTerminal 1645 | /// GetEventHandler()->ProcessEvent(e); 1712 | } 1713 | } 1714 | 1715 | ////////////////////////////////////////////////////////////////////////////// 1716 | /// public virtual RequestSizeChange 1717 | /// A virtual function, used by GTerm to update the size 1718 | /// 1719 | /// @param w int The new width in characters 1720 | /// @param h int The new height in characters 1721 | /// 1722 | /// @return void 1723 | /// 1724 | /// @author Derry Bryson @date 04-22-2004 1725 | ////////////////////////////////////////////////////////////////////////////// 1726 | void 1727 | wxTerm::RequestSizeChange(int w, int h) 1728 | { 1729 | ResizeTerminal(w, h); 1730 | } 1731 | 1732 | ////////////////////////////////////////////////////////////////////////////// 1733 | /// public virtual ProcessInput 1734 | /// Processes text received from the server 1735 | /// 1736 | /// @param len int The number of characters received 1737 | /// @param data unsigned char * The received text 1738 | /// 1739 | /// @return void 1740 | /// 1741 | /// @remarks This function is *not* safe to call from anywhere but 1742 | /// @remarks the main wxwidgets event loop, as it draws 1743 | /// 1744 | /// @author Derry Bryson @date 04-22-2004 1745 | ////////////////////////////////////////////////////////////////////////////// 1746 | void 1747 | wxTerm::ProcessInput(int len, unsigned char *data) 1748 | { 1749 | wxClientDC 1750 | dc(this); 1751 | 1752 | ClearSelection(); 1753 | m_curDC = &dc; 1754 | GTerm::ProcessInput(len, data); 1755 | m_curDC = 0; 1756 | } 1757 | 1758 | ////////////////////////////////////////////////////////////////////////////// 1759 | /// private MapKeyCode 1760 | /// Converts from WXWidgets special keycodes to VT100 1761 | /// special keycodes. 1762 | /// 1763 | /// 1764 | /// @param keyCode int The keycode to check 1765 | /// 1766 | /// @return int The returned keycode 1767 | /// 1768 | /// @author Derry Bryson @date 04-22-2004 1769 | ////////////////////////////////////////////////////////////////////////////// 1770 | int 1771 | wxTerm::MapKeyCode(int keyCode) 1772 | { 1773 | int 1774 | i; 1775 | 1776 | for(i = 0; keyMapTable[i].keyCode; i++) 1777 | if(keyMapTable[i].keyCode == keyCode) 1778 | return keyMapTable[i].VTKeyCode; 1779 | return 0; 1780 | } 1781 | 1782 | ////////////////////////////////////////////////////////////////////////////// 1783 | /// public virtual SelectPrinter 1784 | /// Selects the printer to be used 1785 | /// 1786 | /// @param PrinterName char * The text of the printer name 1787 | /// 1788 | /// @return void 1789 | /// 1790 | /// @author Derry Bryson @date 04-22-2004 1791 | ////////////////////////////////////////////////////////////////////////////// 1792 | void 1793 | wxTerm::SelectPrinter(char *PrinterName) 1794 | { 1795 | if(m_printerFN) 1796 | { 1797 | if(m_printerName[0] == '#') 1798 | fclose(m_printerFN); 1799 | else 1800 | #if defined(__WXGTK__) || defined(__WXMOTIF__) 1801 | pclose(m_printerFN); 1802 | #endif 1803 | #if defined(__WXMSW__) 1804 | fclose(m_printerFN); 1805 | #endif 1806 | 1807 | m_printerFN = 0; 1808 | } 1809 | 1810 | if(m_printerName) 1811 | { 1812 | free(m_printerName); 1813 | m_printerName = 0; 1814 | } 1815 | 1816 | if(strlen(PrinterName)) 1817 | { 1818 | m_printerName = strdup(PrinterName); 1819 | } 1820 | } 1821 | 1822 | ////////////////////////////////////////////////////////////////////////////// 1823 | /// public virtual PrintChars 1824 | /// Prints stuff to the currently selected printer 1825 | /// 1826 | /// @param len int The number of characters 1827 | /// @param data unsigned char * The text 1828 | /// 1829 | /// @return void 1830 | /// 1831 | /// @author Derry Bryson @date 04-22-2004 1832 | ////////////////////////////////////////////////////////////////////////////// 1833 | void 1834 | wxTerm::PrintChars(int len, unsigned char *data) 1835 | { 1836 | char 1837 | pname[100]; 1838 | 1839 | if(!m_printerFN) 1840 | { 1841 | if(!m_printerName) 1842 | return; 1843 | 1844 | if(m_printerName[0] == '#') 1845 | { 1846 | #if defined(__WXGTK__) || defined(__WXMOTIF__) 1847 | sprintf(pname, "/dev/lp%d", m_printerName[1] - '0'); 1848 | #endif 1849 | #if defined(__WXMSW__) 1850 | sprintf(pname, "lpt%d", m_printerName[1] - '0' + 1); 1851 | #endif 1852 | m_printerFN = fopen(pname, "wb"); 1853 | } 1854 | else 1855 | { 1856 | #if defined(__WXGTK__) || defined(__WXMOTIF__) 1857 | sprintf(pname, "lpr -P%s", m_printerName); 1858 | m_printerFN = popen(pname, "w"); 1859 | #endif 1860 | #if defined(__WXMSW__) 1861 | m_printerFN = fopen(m_printerName, "wb"); 1862 | #endif 1863 | } 1864 | } 1865 | 1866 | if(m_printerFN) 1867 | { 1868 | fwrite(data, len, 1, m_printerFN); 1869 | } 1870 | } 1871 | 1872 | 1873 | ////////////////////////////////////////////////////////////////////////////// 1874 | /// private OnGainFocus 1875 | /// Enables the cursor 1876 | /// 1877 | /// @param event wxFocusEvent & The generated focus event 1878 | /// 1879 | /// @return void 1880 | /// 1881 | /// @author Mark Erikson @date 04-22-2004 1882 | ////////////////////////////////////////////////////////////////////////////// 1883 | void wxTerm::OnGainFocus(wxFocusEvent &event) 1884 | { 1885 | this->clear_mode_flag(CURSORINVISIBLE); 1886 | wxLogDebug("TerminalWx Gained focus"); 1887 | GTerm::Update(); 1888 | } 1889 | 1890 | ////////////////////////////////////////////////////////////////////////////// 1891 | /// private OnLoseFocus 1892 | /// Disables the cursor 1893 | /// 1894 | /// @param event wxFocusEvent & The generated focus event 1895 | /// 1896 | /// @return void 1897 | /// 1898 | /// @author Mark Erikson @date 04-22-2004 1899 | ////////////////////////////////////////////////////////////////////////////// 1900 | void wxTerm::OnLoseFocus(wxFocusEvent &event) 1901 | { 1902 | this->set_mode_flag(CURSORINVISIBLE); 1903 | wxLogDebug("TerminalWx Lost focus"); 1904 | GTerm::Update(); 1905 | } 1906 | 1907 | ////////////////////////////////////////////////////////////////////////////// 1908 | /// private OnSize 1909 | /// Lets the terminal resize the text whenever the window is resized 1910 | /// 1911 | /// @param event wxSizeEvent & The generated size event 1912 | /// 1913 | /// @return void 1914 | /// 1915 | /// @author Mark Erikson @date 04-22-2004 1916 | ////////////////////////////////////////////////////////////////////////////// 1917 | void wxTerm::OnSize(wxSizeEvent &event) 1918 | { 1919 | UpdateSize(); 1920 | } 1921 | 1922 | void wxTerm::UpdateRemoteSize(int width, int height) 1923 | { 1924 | 1925 | } 1926 | -------------------------------------------------------------------------------- /src/taTelnet/wxterm.h: -------------------------------------------------------------------------------- 1 | /* 2 | taTelnet - A cross-platform telnet program. 3 | Copyright (c) 2000 Derry Bryson 4 | 2004 Mark Erikson 5 | 2012-2013 Jeremy Salwen 6 | 7 | License: wxWindows License Version 3.1 (See the file license3.txt) 8 | 9 | */ 10 | 11 | 12 | #ifndef INCLUDE_WXTERM 13 | #define INCLUDE_WXTERM 14 | 15 | #ifdef __GNUG__ 16 | #pragma interface 17 | #endif 18 | 19 | #include "../GTerm/gterm.hpp" 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | #define wxEVT_COMMAND_TERM_RESIZE wxEVT_USER_FIRST + 1000 30 | #define wxEVT_COMMAND_TERM_NEXT wxEVT_USER_FIRST + 1001 31 | 32 | #define EVT_TERM_RESIZE(id, fn) { wxEVT_COMMAND_TERM_RESIZE, id, -1, (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) &fn, (wxObject *)NULL }, 33 | 34 | class wxTerm : public wxWindow, public GTerm 35 | { 36 | int 37 | m_charWidth, 38 | m_charHeight, 39 | m_init, 40 | m_width, 41 | m_height, 42 | m_selx1, 43 | m_sely1, 44 | m_selx2, 45 | m_sely2, 46 | m_curX, 47 | m_curY, 48 | m_curFG, 49 | m_curBG, 50 | m_curFlags, 51 | m_curState, 52 | m_curBlinkRate; 53 | 54 | int m_charsInLine; 55 | int m_linesDisplayed; 56 | 57 | unsigned char 58 | m_curChar; 59 | 60 | bool 61 | m_selecting, 62 | m_marking; 63 | 64 | bool m_inUpdateSize; 65 | 66 | wxColour 67 | m_vt_colors[16], 68 | m_pc_colors[16], 69 | *m_colors; 70 | 71 | wxPen 72 | m_vt_colorPens[16], 73 | m_pc_colorPens[16], 74 | *m_colorPens; 75 | 76 | wxFont 77 | m_normalFont, 78 | m_underlinedFont, 79 | m_boldFont, 80 | m_boldUnderlinedFont; 81 | 82 | wxDC 83 | *m_curDC; 84 | 85 | wxMemoryDC 86 | m_memDC; 87 | 88 | wxBitmap 89 | *m_bitmap; 90 | 91 | FILE 92 | *m_printerFN; 93 | 94 | char 95 | *m_printerName; 96 | 97 | wxTimer 98 | m_timer; 99 | 100 | public: 101 | enum BOLDSTYLE 102 | { 103 | DEFAULT = -1, 104 | COLOR = 0, 105 | OVERSTRIKE = 1, 106 | FONT = 2 107 | }; 108 | 109 | private: 110 | BOLDSTYLE 111 | m_boldStyle; 112 | 113 | typedef struct 114 | { 115 | wxKeyCode 116 | keyCode; 117 | 118 | int 119 | VTKeyCode; 120 | } TermKeyMap; 121 | 122 | static TermKeyMap keyMapTable[]; 123 | 124 | public: 125 | wxTerm(wxWindow* parent, wxWindowID id, 126 | const wxPoint& pos = wxDefaultPosition, 127 | int width = 80, int height = 24, 128 | const wxString& name = "wxTerm"); 129 | 130 | virtual ~wxTerm(); 131 | 132 | bool SetFont(const wxFont& font); 133 | 134 | void GetDefVTColors(wxColor colors[16], wxTerm::BOLDSTYLE boldStyle = wxTerm::DEFAULT); 135 | void GetVTColors(wxColour colors[16]); 136 | void SetVTColors(wxColour colors[16]); 137 | void GetDefPCColors(wxColour colors[16]); 138 | void GetPCColors(wxColour colors[16]); 139 | void SetPCColors(wxColour colors[16]); 140 | int GetCursorBlinkRate() { return m_curBlinkRate; } 141 | void SetCursorBlinkRate(int rate); 142 | 143 | void SetBoldStyle(wxTerm::BOLDSTYLE boldStyle); 144 | wxTerm::BOLDSTYLE GetBoldStyle(void) { return m_boldStyle; } 145 | 146 | void ScrollTerminal(int numLines, bool scrollUp = true); 147 | 148 | void ClearSelection(); 149 | bool HasSelection(); 150 | wxString GetSelection(); 151 | void SelectAll(); 152 | 153 | void UpdateSize(); 154 | //void UpdateSize(int &termheight, int &linesReceived); 155 | //void UpdateSize(wxSizeEvent &event); 156 | 157 | /* 158 | ** GTerm stuff 159 | */ 160 | virtual void DrawText(int fg_color, int bg_color, int flags, 161 | int x, int y, int len, unsigned char *string); 162 | virtual void DrawCursor(int fg_color, int bg_color, int flags, 163 | int x, int y, unsigned char c); 164 | 165 | virtual void MoveChars(int sx, int sy, int dx, int dy, int w, int h); 166 | virtual void ClearChars(int bg_color, int x, int y, int w, int h); 167 | // virtual void SendBack(int len, char *data); 168 | virtual void ModeChange(int state); 169 | virtual void Bell(); 170 | virtual void ResizeTerminal(int w, int h); 171 | virtual void RequestSizeChange(int w, int h); 172 | 173 | virtual void ProcessInput(int len, unsigned char *data); 174 | // virtual void ProcessOutput(int len, unsigned char *data); 175 | 176 | virtual void SelectPrinter(char *PrinterName); 177 | virtual void PrintChars(int len, unsigned char *data); 178 | 179 | virtual void UpdateRemoteSize(int width, int height); 180 | int GetTermWidth(){return m_charsInLine;} 181 | int GetTermHeight(){return m_linesDisplayed;} 182 | 183 | private: 184 | int MapKeyCode(int keyCode); 185 | void MarkSelection(); 186 | void DoDrawCursor(int fg_color, int bg_color, int flags, 187 | int x, int y, unsigned char c); 188 | 189 | void OnChar(wxKeyEvent& event); 190 | void OnKeyDown(wxKeyEvent& event); 191 | void OnPaint(wxPaintEvent& event); 192 | void OnLeftDown(wxMouseEvent& event); 193 | void OnLeftUp(wxMouseEvent& event); 194 | void OnMouseMove(wxMouseEvent& event); 195 | void OnTimer(wxTimerEvent& event); 196 | void OnSize(wxSizeEvent &event); 197 | 198 | void OnGainFocus(wxFocusEvent &event); 199 | void OnLoseFocus(wxFocusEvent &event); 200 | 201 | //private wxScrollBar* m_scrollbar; 202 | 203 | DECLARE_EVENT_TABLE() 204 | }; 205 | 206 | #endif /* INCLUDE_WXTERM */ 207 | -------------------------------------------------------------------------------- /src/terminalinputevent.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | TerminalWx - A wxWidgets terminal widget 3 | Copyright (C) 2004 Mark Erikson 4 | 2012-2013 Jeremy Salwen 5 | 6 | License: wxWindows License Version 3.1 (See the file license3.txt) 7 | 8 | */ 9 | 10 | #include "terminalinputevent.h" 11 | 12 | 13 | DEFINE_EVENT_TYPE(chEVT_TERMINAL_INPUT) 14 | 15 | TerminalInputEvent::TerminalInputEvent(wxString str) 16 | : wxEvent(0, chEVT_TERMINAL_INPUT),m_string(str) 17 | { 18 | // 19 | } 20 | 21 | TerminalInputEvent::TerminalInputEvent(const TerminalInputEvent& otherEvent) 22 | : wxEvent(otherEvent) 23 | { 24 | this->SetString(otherEvent.GetString()); 25 | } 26 | -------------------------------------------------------------------------------- /src/terminalinputevent.h: -------------------------------------------------------------------------------- 1 | /* 2 | TerminalWx - A wxWidgets terminal widget 3 | Copyright (C) 2004 Mark Erikson 4 | 2012-2013 Jeremy Salwen 5 | 6 | License: wxWindows License Version 3.1 (See the file license3.txt) 7 | 8 | */ 9 | #ifndef __TERMINAL_INPUT_EVENT__H__ 10 | #define __TERMINAL_INPUT_EVENT__H__ 11 | 12 | #include 13 | #include 14 | 15 | // ------------------------------------------------------------------- 16 | // ProcessEvent 17 | // ------------------------------------------------------------------- 18 | DECLARE_EVENT_TYPE(chEVT_TERMINAL_INPUT, wxID_ANY) 19 | 20 | 21 | class TerminalInputEvent : public wxEvent 22 | { 23 | public: 24 | TerminalInputEvent(wxString str); 25 | TerminalInputEvent(const TerminalInputEvent& event); 26 | 27 | void SetString(wxString s) { m_string = s; } 28 | 29 | wxString GetString() const { return m_string; } 30 | 31 | virtual wxEvent *Clone() const { return new TerminalInputEvent(*this); } 32 | 33 | private: 34 | wxString m_string; 35 | 36 | }; 37 | 38 | typedef void (wxEvtHandler::*TerminalInputEventFunction)(TerminalInputEvent&); 39 | 40 | 41 | #define EVT_TERMINAL_INPUT(fn) \ 42 | DECLARE_EVENT_TABLE_ENTRY( \ 43 | chEVT_TERMINAL_INPUT, wxID_ANY, wxID_ANY, \ 44 | (wxObjectEventFunction)(wxEventFunction)(TerminalInputEventFunction)&fn, \ 45 | (wxObject *) NULL), 46 | 47 | 48 | #endif // __TERMINAL_INPUT_EVENT__H__ 49 | -------------------------------------------------------------------------------- /src/terminalwx.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | TerminalWx - A wxWidgets terminal widget 3 | Copyright (C) 2012-2013 Jeremy Salwen 4 | 5 | License: wxWindows License Version 3.1 (See the file license3.txt) 6 | 7 | */ 8 | 9 | #include "terminalwx.h" 10 | 11 | #include 12 | /** 13 | Constructor for the terminal widget. 14 | 15 | @param width The width of the terminal in characters 16 | @param height The height of the terminal in character 17 | 18 | @param name 19 | The terminal name, which is not displayed but stored 20 | internally, and might be changed by VT commands. 21 | 22 | */ 23 | TerminalWx::TerminalWx(wxWindow* parent, wxWindowID id, 24 | const wxPoint& pos, 25 | int width, int height, 26 | const wxString& name): wxTerm(parent,id,pos,width,height,name) 27 | { 28 | //ctor 29 | } 30 | /** 31 | Called whenever the user has input additional text. 32 | By default it does nothing. 33 | */ 34 | void TerminalWx::OnUserInput(wxString input) { 35 | wxLogDebug("GotInput! %s",input); 36 | //By default do nothing. 37 | } 38 | 39 | void TerminalWx::SendBack(int len,char* data) { 40 | OnUserInput(wxString(data,len)); 41 | } 42 | void TerminalWx::SendBack(char* data) { 43 | OnUserInput(wxString(data)); 44 | } 45 | /** 46 | * Processes characters sent from the backend. 47 | * 48 | * This function is thread safe and can be called from any thread at any time. 49 | * 50 | */ 51 | void TerminalWx::DisplayChars(const wxString& str) { 52 | this->QueueEvent(new TerminalInputEvent(str)); 53 | } 54 | 55 | /** 56 | * Processes characters sent from the backend 57 | * 58 | * This function is not thread safe and can *only* 59 | * safely be called from the main event loop 60 | */ 61 | void TerminalWx::DisplayCharsUnsafe(const wxString& str) { 62 | ProcessInput(str.length(),(unsigned char*)const_cast((const char*)str.mb_str())); 63 | } 64 | 65 | void TerminalWx::OnTerminalInput(TerminalInputEvent& evt) { 66 | DisplayCharsUnsafe(evt.GetString()); 67 | } 68 | 69 | TerminalWx::~TerminalWx() 70 | { 71 | //dtor 72 | } 73 | 74 | 75 | wxBEGIN_EVENT_TABLE(TerminalWx, wxTerm) 76 | 77 | EVT_TERMINAL_INPUT(TerminalWx::OnTerminalInput) 78 | 79 | wxEND_EVENT_TABLE() 80 | -------------------------------------------------------------------------------- /src/terminalwx.h: -------------------------------------------------------------------------------- 1 | /* 2 | TerminalWx - A wxWidgets terminal widget 3 | Copyright (C) 2012-2013 Jeremy Salwen 4 | 5 | License: wxWindows License Version 3.1 (See the file license3.txt) 6 | 7 | */ 8 | 9 | #ifndef TERMINALWX_H 10 | #define TERMINALWX_H 11 | 12 | #include "taTelnet/wxterm.h" 13 | #include "terminalinputevent.h" 14 | 15 | /*! \mainpage TerminalWx 16 | * 17 | * \section intro_sec Introduction 18 | * 19 | * TerminalWx is a fully VT100 compatible virtual terminal widget for wxWindows 20 | * 21 | * The code is almost entirely from the Chameleon IDE by Mark Erikson, 22 | * taTelnet by Derry Bryson, and GTerm by Timothy Miller. 23 | * 24 | * \section install_sec Use 25 | * 26 | * The public API for TerminalWx is the class TerminalWx. 27 | * It is a wxWindow. Simply add it to your gui as you would any other widget. 28 | * 29 | * 30 | */ 31 | 32 | 33 | /** 34 | * Terminal Widget 35 | * 36 | * To handle user input to the terminal, inherit this 37 | * class and override the OnUserInput 38 | * 39 | * To make the widget display new characters sent from your backend, 40 | * use DisplayChars (or you may use DisplayCharsUnsafe, if you are 41 | * calling from within the main event loop. 42 | */ 43 | class TerminalWx : public wxTerm 44 | { 45 | public: 46 | TerminalWx(wxWindow* parent, wxWindowID id, 47 | const wxPoint& pos = wxDefaultPosition, 48 | int width = 80, int height = 24, 49 | const wxString& name = "TerminalWx"); 50 | virtual ~TerminalWx(); 51 | virtual void OnUserInput(wxString); 52 | virtual void DisplayChars(const wxString& text); 53 | virtual void DisplayCharsUnsafe(const wxString& text); 54 | protected: 55 | private: 56 | void OnTerminalInput(TerminalInputEvent&); 57 | virtual void SendBack(int len, char* data); 58 | virtual void SendBack(char* data); 59 | DECLARE_EVENT_TABLE() 60 | }; 61 | 62 | #endif // TERMINALWX_H 63 | -------------------------------------------------------------------------------- /wxsmith/Testframe.wxs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Test TerminalWx App 5 | 6 | 7 | $(THIS) = new $(CLASS)($(PARENT),$(ID),$(POS),80,24,$(NAME)); 8 | 9 | 72,56 10 | 11 | 12 | 13 | 14 | 15 | 16 | Alt-F4 17 | Quit the application 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | F1 26 | Show info about this application 27 | 28 | 29 | 30 | 31 | 32 | 1 33 | -1 34 | wxSB_NORMAL 35 | 36 | 37 | 38 | --------------------------------------------------------------------------------