Revision 459020569c003547b0066547ea17dffc49bddc62 authored by chou86_e on 26 February 2008, 00:54:26 UTC, committed by chou86_e on 26 February 2008, 00:54:26 UTC
added externs to top of .c files added hooks for disable/enable scrolling (doesn't work yet) fixed resize issues fixed lcleartext finding bottommost location to scroll to git-svn-id: https://svn.code.sf.net/p/ucblogo/code@71 fc4ef4ee-df3e-0410-84de-fb01f5d6c4f7
1 parent 7fd9e7c
wxTerminal.cpp
/* This file implements the logo frame, which is the main frame that
contains the terminal, turtle graphics and the editor.
*/
#include <iostream>
#ifdef __GNUG__
#pragma implementation "wxTerminal.h"
#endif
// For compilers that support precompilation, includes "wx/wx.h".
#include "wx/wxprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
// for all others, include the necessary headers (this file is usually all you
// need because it includes almost all "standard" wxWindows headers
#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
#include <wx/timer.h>
extern std::string pathString;
#include <wx/stdpaths.h>
#include <ctype.h>
extern unsigned char *cmdHistory[];
extern unsigned char **hist_inptr, **hist_outptr;
extern int readingInstruction;
#include <wx/print.h>
#include "LogoFrame.h"
#include "wxGlobals.h"
#include <wx/clipbrd.h>
#include <wx/html/htmprint.h>
#include <wx/print.h>
#include <wx/printdlg.h>
#include "wxTurtleGraphics.h"
#include "config.h"
#include "TextEditor.h"
#include "wxTerminal.h" /* must come after wxTurtleGraphics.h */
#ifdef __WXMAC__
#include <Carbon/Carbon.h>
#endif
using namespace std;
// ----------------------------------------------------------------------------
// Globals
// ----------------------------------------------------------------------------
// This is for the input for terminal-like behavior
unsigned char inputBuffer [8000];
// How far into the inputBuffer we are
int input_index = 0;
// if logo is in character mode
int logo_char_mode;
// the terminal DC
wxFont old_font;
wxTextAttr old_style;
// when edit is called in logo
TextEditor * editWindow;
// the turtle graphics we are using
TurtleCanvas * turtleGraphics;
// this contains the previous 3 window
wxBoxSizer *topsizer;
LogoFrame *logoFrame;
LogoEventManager *logoEventManager;
// used to calculate where the cursor should be
int cur_x = 0, cur_y = 0;
int first = 1;
int last_logo_x = 0, last_logo_y = 0;
int last_user_x = 0, last_user_y = 0;
bool cursor_moved = 0;
// the menu
wxMenuBar* menuBar;
extern "C" void wxTextScreen();
char *argv[2] = {"UCBLogo", 0};
// This is for stopping logo asynchronously
#ifdef SIG_TAKES_ARG
extern "C" RETSIGTYPE logo_stop(int);
extern "C" RETSIGTYPE logo_pause(int);
#else
extern "C" RETSIGTYPE logo_stop();
extern "C" RETSIGTYPE logo_pause();
#endif
#ifdef MULTITHREAD
extern void wxLogoWakeup();
#endif
int logo_stop_flag = 0;
int logo_pause_flag = 0;
int movedCursor = 0;
// this is a static reference to the main terminal
wxTerminal *wxTerminal::terminal;
// ----------------------------------------------------------------------------
// constants
// ----------------------------------------------------------------------------
enum
{
Menu_File = 200,
Menu_File_Save,
Menu_File_Load,
Menu_File_Page_Setup,
Menu_File_Print_Text,
Menu_File_Print_Text_Prev,
Menu_File_Print_Turtle,
Menu_File_Print_Turtle_Prev,
Menu_File_Quit,
Menu_Edit = 300,
Menu_Edit_Copy,
Menu_Edit_Paste,
Menu_Logo = 400,
Menu_Logo_Stop,
Menu_Logo_Pause,
Menu_Font = 500,
Menu_Font_Inc,
Menu_Font_Dec,
Menu_Help = 600,
Menu_Help_Man,
Edit_Menu_File = 700,
Edit_Menu_File_Close_Accept,
Edit_Menu_File_Close_Reject,
Edit_Menu_File_Page_Setup,
Edit_Menu_File_Print_Text,
Edit_Menu_Edit = 800,
Edit_Menu_Edit_Copy,
Edit_Menu_Edit_Paste,
Edit_Menu_Edit_Cut,
Edit_Menu_Edit_Find,
Edit_Menu_Edit_Find_Next
};
// ----------------------------------------------------------------------------
// LogoApplication class
// ----------------------------------------------------------------------------
bool LogoApplication::OnInit()
{
logoFrame = new LogoFrame
("Berkeley Logo",
50, 50, 900, 500);
logoFrame->Show(TRUE);
#ifndef MULTITHREAD
#ifndef __WXMAC__
m_mainLoop = new wxEventLoop();
#endif
logoEventManager = new LogoEventManager(this);
#endif
SetTopWindow(logoFrame);
return TRUE;
}
#ifndef MULTITHREAD
extern "C" int start (int, char **);
int LogoApplication::OnRun()
{
#ifndef __WXMAC__
wxEventLoop::SetActive(m_mainLoop);
#endif
SetExitOnFrameDelete(true);
#ifndef __WXMAC__ /* needed for wxWidgets 2.6 */
wxSetWorkingDirectory(wxStandardPaths::Get().GetDocumentsDir());
#endif
// fix the working directory in mac
#ifdef __WXMAC__
char path[1024];
CFBundleRef mainBundle = CFBundleGetMainBundle();
assert( mainBundle );
CFURLRef mainBundleURL = CFBundleCopyBundleURL( mainBundle);
assert( mainBundleURL);
CFStringRef cfStringRef = CFURLCopyFileSystemPath( mainBundleURL, kCFURLPOSIXPathStyle);
assert( cfStringRef);
CFStringGetCString( cfStringRef, path, 1024, kCFStringEncodingASCII);
CFRelease( mainBundleURL);
CFRelease( cfStringRef);
//std::string pathString(path);
pathString = path;
pathString+="/Contents/Resources/";
// chdir(pathString.c_str());
#endif
start(1, argv);
return 0;
}
#endif
int LogoApplication::OnExit() {
return 0;
}
// ----------------------------------------------------------------------------
// LogoEventManager class
// ----------------------------------------------------------------------------
#ifndef MULTITHREAD
LogoEventManager::LogoEventManager(LogoApplication *logoApp)
{
m_logoApp = logoApp;
}
void LogoEventManager::ProcessAnEvent(int force_yield)
{
if( m_logoApp->Pending() ) {
m_logoApp->Dispatch();
}
else {
if(force_yield) {
m_logoApp->Yield(TRUE);
}
else {
static int foo = 500; // carefully tuned fudge factor
if (--foo == 0) {
m_logoApp->Yield(TRUE);
foo = 500;
}
}
}
}
void LogoEventManager::ProcessAllEvents()
{
while( m_logoApp->Pending() ) {
m_logoApp->Dispatch();
}
m_logoApp->Yield(TRUE);
}
#endif
// ----------------------------------------------------------------------------
// LogoFrame class
// ----------------------------------------------------------------------------
BEGIN_EVENT_TABLE (LogoFrame, wxFrame)
EVT_MENU(Menu_File_Save, LogoFrame::OnSave)
EVT_MENU(Menu_File_Load, LogoFrame::OnLoad)
EVT_MENU(Menu_File_Page_Setup, TurtleCanvas::OnPageSetup)
EVT_MENU(Menu_File_Print_Text, LogoFrame::OnPrintText)
EVT_MENU(Menu_File_Print_Text_Prev, LogoFrame::OnPrintTextPrev)
EVT_MENU(Menu_File_Print_Turtle, TurtleCanvas::PrintTurtleWindow)
EVT_MENU(Menu_File_Print_Turtle_Prev, TurtleCanvas::TurtlePrintPreview)
EVT_MENU(Menu_File_Quit, LogoFrame::OnQuit)
EVT_MENU(Menu_Edit_Copy, LogoFrame::DoCopy)
EVT_MENU(Menu_Edit_Paste, LogoFrame::DoPaste)
EVT_MENU(Menu_Logo_Pause, LogoFrame::DoPause)
EVT_MENU(Menu_Logo_Stop, LogoFrame::DoStop)
EVT_MENU(Menu_Font_Inc, LogoFrame::OnIncreaseFont)
EVT_MENU(Menu_Font_Dec, LogoFrame::OnDecreaseFont)
EVT_MENU(Edit_Menu_File_Close_Accept, LogoFrame::OnEditCloseAccept)
EVT_MENU(Edit_Menu_File_Close_Reject, LogoFrame::OnEditCloseReject)
EVT_MENU(Edit_Menu_File_Page_Setup, TurtleCanvas::OnPageSetup)
EVT_MENU(Edit_Menu_File_Print_Text, LogoFrame::OnEditPrint)
EVT_MENU(Edit_Menu_Edit_Copy, LogoFrame::OnEditCopy)
EVT_MENU(Edit_Menu_Edit_Cut, LogoFrame::OnEditCut)
EVT_MENU(Edit_Menu_Edit_Paste, LogoFrame::OnEditPaste)
EVT_MENU(Edit_Menu_Edit_Find, LogoFrame::OnEditFind)
EVT_MENU(Edit_Menu_Edit_Find_Next, LogoFrame::OnEditFindNext)
EVT_CLOSE(LogoFrame::OnCloseWindow)
END_EVENT_TABLE()
#include "ucblogo.xpm"
LogoFrame::LogoFrame (const wxChar *title,
int xpos, int ypos,
int width, int height)
: wxFrame( (wxFrame *) NULL, -1, title,
wxPoint(xpos, ypos),
wxSize(width, height)) {
// the topsizer allows different resizeable segments in the main frame (i.e. for
// turtle graphics and the terminal displaying simultaneously)
SetMinSize(wxSize(100, 100));
SetIcon(wxIcon(ucblogo));
logoFrame = this;
topsizer = new wxBoxSizer( wxVERTICAL );
wxTerminal::terminal = new wxTerminal (this, -1, wxPoint(-1, -1), 82, 25, wxString(""));
turtleGraphics = new TurtleCanvas( this );
wxFont f(18, wxFONTFAMILY_TELETYPE, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL,
false, wxString(""));
editWindow = new TextEditor( this, -1, "", wxDefaultPosition, wxSize(100,60), wxTE_MULTILINE, f);
wxTerminal::terminal->isEditFile=0;
topsizer->Add(
editWindow,
1, // make vertically stretchable
wxEXPAND | // make horizontally stretchable
wxALL, // and make border all around
2 );
topsizer->Add(
turtleGraphics,
4, // make vertically stretchable
wxEXPAND | // make horizontally stretchable
wxALL, // and make border all around
2 );
topsizer->Add(
wxTerminal::terminal,
1, // make vertically stretchable
wxEXPAND | // make horizontally stretchable
wxALL, // and make border all around
2 );
topsizer->Show(wxTerminal::terminal, 1);
topsizer->Show(turtleGraphics, 0);
topsizer->Show(editWindow, 0);
SetSizer( topsizer );
SetAutoLayout(true);
//topsizer->Fit(this);
//topsizer->SetSizeHints(this);
wxTerminal::terminal->SetFocus();
SetUpMenu();
wxSleep(1);
#ifdef MULTITHREAD
init_Logo_Interpreter (1, argv );
#endif
}
void LogoFrame::OnCloseWindow(wxCloseEvent& event)
{
extern int wx_leave_mainloop;
logo_stop_flag = 1;
wx_leave_mainloop++;
Destroy();
}
void LogoFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
{
Close(TRUE);
}
void LogoFrame::SetUpMenu(){
int i;
if(!menuBar)
menuBar = new wxMenuBar( wxMB_DOCKABLE );
else
for(i=menuBar->GetMenuCount()-1;i>=0;i--)
delete menuBar->Remove(i);
wxMenu *fileMenu = new wxMenu;
fileMenu->Append( Menu_File_Save, _T("Save Logo Session \tCtrl-S"));
fileMenu->Append( Menu_File_Load, _T("Load Logo Session \tCtrl-O"));
fileMenu->AppendSeparator();
fileMenu->Append( Menu_File_Page_Setup, _T("Page Setup"));
fileMenu->Append( Menu_File_Print_Text, _T("Print Text Window"));
fileMenu->Append( Menu_File_Print_Text_Prev, _T("Print Preview Text Window"));
fileMenu->Append( Menu_File_Print_Turtle, _T("Print Turtle Graphics"));
fileMenu->Append( Menu_File_Print_Turtle_Prev, _T("Turtle Graphics Print Preview"));
fileMenu->AppendSeparator();
fileMenu->Append(Menu_File_Quit, _T("Quit UCBLogo \tCtrl-Q"));
wxMenu *editMenu = new wxMenu;
menuBar->Append(fileMenu, _T("&File"));
menuBar->Append(editMenu, _T("&Edit"));
wxMenu *logoMenu = new wxMenu;
#ifdef __WXMSW__
editMenu->Append(Menu_Edit_Copy, _T("Copy \tCtrl-C"));
editMenu->Append(Menu_Edit_Paste, _T("Paste \tCtrl-V"));
logoMenu->Append(Menu_Logo_Pause, _T("Pause \tCtrl-P"));
logoMenu->Append(Menu_Logo_Stop, _T("Stop \tCtrl-S"));
#else
editMenu->Append(Menu_Edit_Copy, _T("Copy \tCtrl-C"));
editMenu->Append(Menu_Edit_Paste, _T("Paste \tCtrl-V"));
logoMenu->Append(Menu_Logo_Pause, _T("Pause \tAlt-P"));
logoMenu->Append(Menu_Logo_Stop, _T("Stop \tAlt-S"));
#endif
menuBar->Append(logoMenu, _T("&Logo"));
wxMenu *fontMenu = new wxMenu;
fontMenu->Append(Menu_Font_Inc, _T("Increase Font Size \tCtrl-+"));
fontMenu->Append(Menu_Font_Dec, _T("Decrease Font Size \tCtrl--"));
menuBar->Append(fontMenu, _T("&Font"));
/*wxMenu *helpMenu = new wxMenu;
helpMenu->Append(Menu_Help_Man, _T("Browse Online Manual"));
menuBar->Append(helpMenu, _T("&Help"));*/
SetMenuBar(menuBar);
}
void LogoFrame::DoCopy(wxCommandEvent& WXUNUSED(event)){
wxTerminal::terminal->DoCopy();
}
void LogoFrame::DoPaste(wxCommandEvent& WXUNUSED(event)){
wxTerminal::terminal->DoPaste();
}
extern "C" void new_line(FILE *);
int firstloadsave = 1;
void doSave(char * name, int length);
void doLoad(char * name, int length);
void LogoFrame::OnSave(wxCommandEvent& WXUNUSED(event)) {
wxFileDialog dialog(this,
_T("Save Logo Workspace"),
(firstloadsave ?
#ifdef __WXMAC__ /* needed for wxWidgets 2.6 */
*wxEmptyString :
#else
wxStandardPaths::Get().GetDocumentsDir() :
#endif
*wxEmptyString),
wxEmptyString,
// "Logo workspaces(*.lg)|All files(*.*)",
"*.*",
#ifdef __WXMAC__ /* needed for wxWidgets 2.6 */
wxSAVE|wxOVERWRITE_PROMPT|wxCHANGE_DIR);
#else
#if 0
(
#endif
wxFD_SAVE|wxFD_OVERWRITE_PROMPT|wxFD_CHANGE_DIR);
#endif
dialog.SetFilterIndex(1);
if (dialog.ShowModal() == wxID_OK)
{
doSave((char *)dialog.GetPath().c_str(),
dialog.GetPath().length());
new_line(stdout);
}
firstloadsave = 0;
}
void LogoFrame::OnLoad(wxCommandEvent& WXUNUSED(event)){
wxFileDialog dialog
(
this,
_T("Load Logo Workspace"),
(firstloadsave ?
#ifdef __WXMAC__ /* needed for wxWidgets 2.6 */
*wxEmptyString :
#else
wxStandardPaths::Get().GetDocumentsDir() :
#endif
*wxEmptyString),
wxEmptyString,
// "Logo workspaces(*.lg)|All files(*.*)",
"*",
#ifdef __WXMAC__ /* needed for wxWidgets 2.6 */
wxOPEN|wxFILE_MUST_EXIST|wxCHANGE_DIR);
#else
#if 0
(
#endif
wxFD_OPEN|wxFD_FILE_MUST_EXIST|wxFD_CHANGE_DIR);
#endif
if (dialog.ShowModal() == wxID_OK) {
doLoad((char *)dialog.GetPath().c_str(),
dialog.GetPath().length());
new_line(stdout);
}
firstloadsave = 0;
}
void LogoFrame::OnPrintText(wxCommandEvent& WXUNUSED(event)){
wxHtmlEasyPrinting *htmlPrinter=wxTerminal::terminal->htmlPrinter;
if(!htmlPrinter){
htmlPrinter = new wxHtmlEasyPrinting();
int fontsizes[] = { 6, 8, 12, 14, 16, 20, 24 };
htmlPrinter->SetFonts("Courier","Courier", fontsizes);
}
wxString *textString = wxTerminal::terminal->get_text();
htmlPrinter->PrintText(*textString);
delete textString;
}
void LogoFrame::OnPrintTextPrev(wxCommandEvent& WXUNUSED(event)){
wxHtmlEasyPrinting *htmlPrinter=wxTerminal::terminal->htmlPrinter;
if(!htmlPrinter){
htmlPrinter = new wxHtmlEasyPrinting();
int fontsizes[] = { 6, 8, 12, 14, 16, 20, 24 };
htmlPrinter->SetFonts("Courier","Courier", fontsizes);
}
wxString *textString = wxTerminal::terminal->get_text();
htmlPrinter->PreviewText(*textString,wxString(""));
}
void LogoFrame::OnIncreaseFont(wxCommandEvent& WXUNUSED(event)){
int expected;
// get original size and number of characters per row and column
int width, height, numCharX, numCharY, m_charWidth, m_charHeight;
int m_lineHeight;
wxClientDC dc(wxTerminal::terminal);
dc.GetMultiLineTextExtent("M", &m_charWidth, &m_charHeight,
&m_lineHeight);
GetSize(&width, &height);
numCharX = width/m_charWidth;
numCharY = height/m_lineHeight;
wxdprintf("m_charWidth: %d, m_charHeight: %d, width: %d, height: %d, numCharX: %d, numCharY: %d\n", m_charWidth, m_charHeight, width, height, numCharX, numCharY);
wxFont font = wxTerminal::terminal->GetFont();
expected = font.GetPointSize()+1;
// see that we have the font we are trying to use
while(font.GetPointSize() != expected && expected <= 24){
expected++;
font.SetPointSize(expected);
}
wxTerminal::terminal->SetFont(font);
editWindow->SetFont(font);
wxSizeEvent event;
if(wxTerminal::terminal->IsShown())
wxTerminal::terminal->OnSize(event);
// resize the frame according to the new font size
int new_m_charWidth, new_m_charHeight, new_m_lineHeight;
wxClientDC newdc(wxTerminal::terminal);
newdc.GetMultiLineTextExtent("M", &new_m_charWidth,
&new_m_charHeight, &new_m_lineHeight);
if (new_m_charWidth != m_charWidth ||
new_m_lineHeight != m_lineHeight) {
SetSize(numCharX*new_m_charWidth, numCharY*new_m_lineHeight);
}
//GetSize(&width, &height);
//printf("new m_charWidth: %d, new m_charHeight: %d, new width: %d, new height: %d\n", new_m_charWidth, new_m_charHeight, width, height);
Layout();
}
void LogoFrame::OnDecreaseFont(wxCommandEvent& WXUNUSED(event)){
int expected;
// get original size and number of characters per row and column
int width, height, numCharX, numCharY, m_charWidth, m_charHeight;
wxClientDC dc(wxTerminal::terminal);
dc.GetTextExtent("M", &m_charWidth, &m_charHeight);
GetSize(&width, &height);
numCharX = width/m_charWidth;
numCharY = height/m_charHeight;
//printf("m_charWidth: %d, m_charHeight: %d, width: %d, height: %d, numCharX: %d, numCharY: %d\n", m_charWidth, m_charHeight, width, height, numCharX, numCharY);
wxFont font = wxTerminal::terminal->GetFont();
expected = font.GetPointSize()-1;
// see that we have the font we are trying to use
while(font.GetPointSize() != expected && expected >= 6){
expected--;
font.SetPointSize(expected);
}
wxTerminal::terminal->SetFont(font);
editWindow->SetFont(font);
wxSizeEvent event;
wxTerminal::terminal->OnSize(event);
// resize the frame according to the new font size
int new_m_charWidth, new_m_charHeight;
wxClientDC newdc(wxTerminal::terminal);
newdc.GetTextExtent("M", &new_m_charWidth, &new_m_charHeight);
if (new_m_charWidth != m_charWidth || new_m_charHeight != m_charHeight) {
SetSize(numCharX*new_m_charWidth, numCharY*new_m_charHeight);
wxdprintf("resized window?");
}
//GetSize(&width, &height);
//printf("new m_charWidth: %d, new m_charHeight: %d, new width: %d, new height: %d\n", new_m_charWidth, new_m_charHeight, width, height);
Layout();
}
void LogoFrame::DoStop(wxCommandEvent& WXUNUSED(event)){
logo_stop_flag = 1;
#ifdef MULTITHREAD
wxLogoWakeup();
#endif
}
void LogoFrame::DoPause(wxCommandEvent& WXUNUSED(event)){
logo_pause_flag = 1;
#ifdef MULTITHREAD
wxLogoWakeup();
#endif
}
void LogoFrame::OnEditCloseAccept(wxCommandEvent& WXUNUSED(event)){
editWindow->OnCloseAccept();
}
void LogoFrame::OnEditCloseReject(wxCommandEvent& WXUNUSED(event)){
editWindow->OnCloseReject();
}
void LogoFrame::OnEditPrint(wxCommandEvent& WXUNUSED(event)){
editWindow->DoPrint();
}
void LogoFrame::OnEditCopy(wxCommandEvent& WXUNUSED(event)){
editWindow->DoCopy();
}
void LogoFrame::OnEditCut(wxCommandEvent& WXUNUSED(event)){
editWindow->DoCut();
}
void LogoFrame::OnEditPaste(wxCommandEvent& WXUNUSED(event)){
editWindow->Paste();
}
void LogoFrame::OnEditFind(wxCommandEvent& WXUNUSED(event)){
editWindow->OnFind();
}
void LogoFrame::OnEditFindNext(wxCommandEvent& WXUNUSED(event)){
editWindow->OnFindNext();
}
void LogoFrame::OnEditSave(wxCommandEvent& WXUNUSED(event)){
editWindow->OnSave();
}
void LogoFrame::SetUpEditMenu(){
int i;
for(i=menuBar->GetMenuCount()-1;i>=0;i--)
delete menuBar->Remove(i);
wxMenu *fileMenu = new wxMenu;
fileMenu->Append( Edit_Menu_File_Close_Accept, _T("Close and Accept Changes \tCtrl-Q"));
fileMenu->Append( Edit_Menu_File_Close_Reject, _T("Close and Revert Changes \tCtrl-R"));
fileMenu->AppendSeparator();
fileMenu->Append( Edit_Menu_File_Page_Setup, _T("Page Setup"));
fileMenu->Append( Edit_Menu_File_Print_Text, _T("Print... \tCtrl-P"));
wxMenu *editMenu = new wxMenu;
menuBar->Append(fileMenu, _T("&File"));
menuBar->Append(editMenu, _T("&Edit"));
editMenu->Append(Edit_Menu_Edit_Cut, _T("Cut \tCtrl-X"));
editMenu->Append(Edit_Menu_Edit_Copy, _T("Copy \tCtrl-C"));
editMenu->Append(Edit_Menu_Edit_Paste, _T("Paste \tCtrl-V"));
editMenu->AppendSeparator();
editMenu->Append(Edit_Menu_Edit_Find, _T("Find... \tCtrl-F"));
editMenu->Append(Edit_Menu_Edit_Find_Next, _T("Find Next \tCtrl-G"));
wxMenu *fontMenu = new wxMenu;
fontMenu->Append(Menu_Font_Inc, _T("Increase Font Size \tCtrl-+"));
fontMenu->Append(Menu_Font_Dec, _T("Decrease Font Size \tCtrl--"));
menuBar->Append(fontMenu, _T("&Font"));
logoFrame->SetMenuBar(menuBar);
}
// ----------------------------------------------------------------------------
// wxTerminal
// ----------------------------------------------------------------------------
BEGIN_DECLARE_EVENT_TYPES()
DECLARE_EVENT_TYPE(wxEVT_MY_CUSTOM_COMMAND, 7777)
END_DECLARE_EVENT_TYPES()
DEFINE_EVENT_TYPE(wxEVT_MY_CUSTOM_COMMAND)
#define EVT_MY_CUSTOM_COMMAND(id, fn) \
DECLARE_EVENT_TABLE_ENTRY( \
wxEVT_MY_CUSTOM_COMMAND, id, -1, \
(wxObjectEventFunction)(wxEventFunction)(wxCommandEventFunction)&fn, \
(wxObject *) NULL \
),
BEGIN_DECLARE_EVENT_TYPES()
DECLARE_EVENT_TYPE(wxEVT_TERM_CUSTOM_COMMAND, 7777)
END_DECLARE_EVENT_TYPES()
DEFINE_EVENT_TYPE(wxEVT_TERM_CUSTOM_COMMAND)
#define wxEVT_TERM_CUSTOM_COMMAND(id, fn) \
DECLARE_EVENT_TABLE_ENTRY( \
wxEVT_TERM_CUSTOM_COMMAND, id, -1, \
(wxObjectEventFunction)(wxEventFunction)(wxCommandEventFunction)&fn, \
(wxObject *) NULL \
),
BEGIN_EVENT_TABLE(wxTerminal, wxWindow)
EVT_PAINT(wxTerminal::OnPaint)
EVT_CHAR(wxTerminal::OnChar)
EVT_LEFT_DOWN(wxTerminal::OnLeftDown)
EVT_LEFT_UP(wxTerminal::OnLeftUp)
EVT_MOTION(wxTerminal::OnMouseMove)
EVT_MY_CUSTOM_COMMAND(-1, wxTerminal::printText)
EVT_SIZE(wxTerminal::OnSize)
EVT_KILL_FOCUS(wxTerminal::LoseFocus)
END_EVENT_TABLE()
wxCommandEvent * haveInputEvent = new wxCommandEvent(wxEVT_MY_CUSTOM_COMMAND);
wxTerminal::wxTerminal(wxWindow* parent, wxWindowID id,
const wxPoint& pos,
int width, int height,
const wxString& name) :
wxScrolledWindow(parent, id, pos, wxSize(-1, -1), wxWANTS_CHARS|wxVSCROLL, name)
// wxScrolledWindow(parent, id, pos, wxSize(-1, -1), wxWANTS_CHARS, name)
{
//allocating char structures.
term_chars = (wxterm_char_buffer *) malloc(sizeof(wxterm_char_buffer));
memset(term_chars, '\0', sizeof(wxterm_char_buffer));
term_lines = (wxterm_line_buffer *) malloc(sizeof(wxterm_line_buffer));
memset(term_lines, 0, sizeof(wxterm_line_buffer));
term_chars->next = 0;
term_lines->next = 0;
//initializations
curr_line_pos.buf = term_lines;
curr_line_pos.offset = 0;
line_of(curr_line_pos).buf = term_chars;
line_of(curr_line_pos).offset = 0;
curr_char_pos.buf = term_chars;
curr_char_pos.offset = 0;
//curr_char_pos line_length not used!
m_currMode = 0;
y_max = 0;
x_max = m_width;
// start us out not in char mode
logo_char_mode = 0;
// For printing the text
htmlPrinter = 0;
// set_mode_flag(DESTRUCTBS);
wxTerminal::terminal = this;
int
i;
m_selecting = FALSE;
m_selx1 = m_sely1 = m_selx2 = m_sely2 = 0;
m_seloldx1 = m_seloldy1= m_seloldx2 = m_seloldy2 = 0;
m_marking = FALSE;
m_curX = -1;
m_curY = -1;
// m_boldStyle = FONT;
GetDefVTColors(m_vt_colors);
m_colors = m_vt_colors;
m_curFG = 15;
m_curBG = 0;
SetBackgroundColour(m_colors[0]);
SetMinSize(wxSize(50, 50));
for(i = 0; i < 16; i++)
m_vt_colorPens[i] = wxPen(m_vt_colors[i], 1, wxSOLID);
m_colorPens = m_vt_colorPens;
m_width = width;
m_height = height;
m_printerFN = 0;
m_printerName = 0;
wxFont f(18, wxFONTFAMILY_TELETYPE, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL,
false, "Courier");
SetFont(f);
wxClientDC
dc(this);
dc.GetTextExtent("M", &m_charWidth, &m_charHeight);
m_charWidth--;
m_vscroll_enabled = TRUE;
// int x, y;
//GetSize(&x, &y);
// parent->SetSize(-1,-1, m_charWidth * width, m_charHeight * height + 1);
// SetScrollbars(m_charWidth, m_charHeight, 0, 30);
//SetScrollRate(0, m_charHeight);
//SetVirtualSize(m_charWidth * width, 2 * m_charHeight); //1 row (nothing displayed yet)
// ResizeTerminal(width, height);
}
wxTerminal::~wxTerminal()
{
//clean up the buffers
}
void wxTerminal::deferUpdate(int flag) {
if (flag)
set_mode_flag(DEFERUPDATE);
else
clear_mode_flag(DEFERUPDATE);
}
void wxTerminal::set_mode_flag(int flag) {
m_currMode |= flag;
}
void wxTerminal::clear_mode_flag(int flag) {
m_currMode &= ~flag;
}
bool
wxTerminal::SetFont(const wxFont& font)
{
wxWindow::SetFont(font);
m_normalFont = font;
m_underlinedFont = font;
m_underlinedFont.SetUnderlined(TRUE);
m_boldFont = GetFont();
m_boldFont.SetWeight(wxBOLD);
m_boldUnderlinedFont = m_boldFont;
m_boldUnderlinedFont.SetUnderlined(TRUE);
wxClientDC
dc(this);
dc.GetTextExtent("M", &m_charWidth, &m_charHeight);
m_charWidth--;
ResizeTerminal(m_width, m_height);
Refresh();
return TRUE;
}
void
wxTerminal::GetDefVTColors(wxColour colors[16] /*, wxTerminal::BOLDSTYLE boldStyle*/)
{
colors[0] = wxColour(0, 0, 0); // black
colors[1] = wxColour(255, 0, 0); // red
colors[2] = wxColour(0, 255, 0); // green
colors[3] = wxColour(255, 0, 255); // yellow
colors[4] = wxColour(0, 0, 255); // blue
colors[5] = wxColour(255, 255, 0); // magenta
colors[6] = wxColour(0, 255, 255); // cyan
colors[7] = wxColour(255, 255, 255); // white
colors[8] = wxColour(0, 0, 0); // black
colors[9] = wxColour(255, 0, 0); // red
colors[10] = wxColour(0, 255, 0); // green
colors[11] = wxColour(255, 0, 255); // yellow
colors[12] = wxColour(0, 0, 255); // blue
colors[13] = wxColour(255, 255, 0); // magenta
colors[14] = wxColour(0, 255, 255); // cyan
colors[15] = wxColour(255, 255, 255); // white
}
void wxTerminal::printText (wxCommandEvent& event){
set_mode_flag(BOLD);
#ifdef MULTITHREAD
out_mut.Lock();
#endif
if (event.GetClientData() != NULL) {
int * temp = (int *)event.GetClientData();
this->setCursor(temp[0], temp[1]);
free (temp);
movedCursor = 1;
#ifdef MULTITHREAD
buff_full_cond.Broadcast();
out_mut.Unlock();
#endif
return;
}
if (out_buff_index_public == 0) {
alreadyAlerted = 0;
#ifdef MULTITHREAD
buff_full_cond.Broadcast();
out_mut.Unlock();
#endif
clear_mode_flag(BOLD);
return;
}
alreadyAlerted = 0;
wxClientDC
dc(this);
if(input_index != 0){
// set the cursor in the proper place
setCursor(last_logo_x, last_logo_y);
// scroll_region(last_logo_y, last_logo_y + 1, -1);
cursor_moved = 1;
}
if (out_buff_index_public != 0) {
ClearSelection();
PassInputToTerminal(out_buff_index_public, (unsigned char *)out_buff_public);
out_buff_index_public = 0;
}
#ifdef MULTITHREAD
buff_full_cond.Broadcast();
out_mut.Unlock();
#endif
last_logo_x = cursor_x;
last_logo_y = cursor_y;
if(cursor_moved){
int x_changed, y_changed;
x_changed = input_index % x_max;
y_changed = input_index / x_max;
setCursor(last_logo_x, last_logo_y);
// Because scrolling trouble occurs
ClearSelection();
PassInputToTerminal(input_index, (unsigned char *)inputBuffer);
cursor_moved = 0;
}
}
/*
PassInputToInterp() takes all characters in the input buffer and hands
them off to the logo interpreter
*/
void wxTerminal::PassInputToInterp() {
int i;
#ifdef MULTITHREAD
in_mut.Lock();
#endif
if(logo_char_mode){
buff[buff_index++] = inputBuffer[--input_index];
input_index = 0;
#ifdef MULTITHREAD
read_buff.Broadcast();
#endif
}
else {
buff[buff_index++] = '\n';
for (i = input_index -1;i >= 0; i --) {
buff[buff_index++] = inputBuffer[i];
}
input_index = 0;
#ifdef MULTITHREAD
read_buff.Broadcast();
#endif
// sent to logo, so the text is locked
last_logo_x = cursor_x;
last_logo_y = cursor_y;
}
#ifdef MULTITHREAD
in_mut.Unlock();
#endif
}
void wxTerminal::DoCopy(){
if (wxTheClipboard->Open())
{
// This data objects are held by the clipboard,
// so do not delete them in the app.
wxTheClipboard->SetData( new wxTextDataObject(GetSelection()) );
wxTheClipboard->Close();
}
}
void wxTerminal::DoPaste(){
if (wxTheClipboard->Open())
{
if (wxTheClipboard->IsSupported( wxDF_TEXT ))
{
wxTextDataObject data;
wxTheClipboard->GetData( data );
wxString s = data.GetText();
unsigned int i;
char chars[2];
int len;
char prev = ' ';
for (i = 0; i < s.Length(); i++){
len = 1;
chars[0] = s.GetChar(i);
if (prev == ' ' && chars[0] == ' ')
continue;
prev = chars[0];
inputBuffer[input_index++] = s.GetChar(i);
if(chars[0] == 10){
chars[0] = 10;
chars[1] = 13;
len = 2;
}
ClearSelection();
PassInputToTerminal(len, (unsigned char *)chars);
}
}
wxTheClipboard->Close();
}
}
void wxTerminal::LoseFocus (wxFocusEvent & event){
}
int wxTerminal::currentPosition () {
// Gives the length of the characters up to the cursor
int ret = 0;
if (cursor_y - last_logo_y >= 2) {
ret = (cursor_y - last_logo_y - 1) * m_width + (m_width - last_logo_x) + cursor_x;
}
else if (cursor_y - last_logo_y == 1) {
ret = (m_width - last_logo_x) + cursor_x;
}
else
ret = cursor_x - last_logo_x;
// fprintf(stderr, "currentposition: %d \n", ret);
return ret;
}
/*
OnChar is called each time the user types a character
in the main terminal window
*/
void
wxTerminal::OnChar(wxKeyEvent& event)
{
ClearSelection();
static int xval;
static int yval;
int
keyCode = 0,
len;
unsigned char
buf[10];
keyCode = (int)event.GetKeyCode();
if(logo_char_mode){
if (keyCode == WXK_RETURN) {
keyCode = '\n';
}
else if (keyCode == WXK_BACK) {
keyCode = 8;
}
else if (keyCode >= WXK_START) {
/* ignore it */
return; //not sure about this (evan)
}
else {
}
//also not sure about this (evan)
if (event.ControlDown()) keyCode -= 0140;
if (event.AltDown()) keyCode += 0200;
inputBuffer[input_index++] = keyCode;
PassInputToInterp();
}
else if (keyCode == WXK_RETURN) {
// for the new terminal:
int currentPos = currentPosition();
#if 1
if(currentPos < input_index) {
int new_x = cursor_x + (input_index - currentPos);
int new_y = cursor_y;
while(new_x > x_max) {
new_y++;
new_x -= x_max;
}
setCursor(new_x, new_y);
}
#else
//old method:
while(currentPosition() < input_index) {
if(max(last_logo_x, cursor_x + 1) >= x_max) {
setCursor(0, max(cursor_y,last_logo_y) + 1);
}
else {
setCursor(max(last_logo_x, cursor_x + 1), max(cursor_y,last_logo_y));
}
}
#endif
buf[0] = 10;
buf[1] = 13;
len = 2;
PassInputToTerminal(len, buf);
PassInputToInterp();
}
else if (keyCode == WXK_BACK) {
// fprintf(stderr, "onchar backspace\n");
if (input_index == 0)
return;
int currentPos = currentPosition();
if (currentPos == 0)
return;
// fprintf(stderr, "cpos %d, inputidx %d\n", currentPos, input_index);
int i;
if (cursor_x == 0) { // need to go back to the prev line
setCursor(m_width, cursor_y - 1);
}
for (i = currentPos; i < input_index; i++) {
inputBuffer[i-1] = inputBuffer[i];
}
input_index--;
currentPos--;
inputBuffer[input_index] = ' ';
cur_x = cursor_x, cur_y = cursor_y;
setCursor(cur_x - 1, cur_y);
set_mode_flag(CURSORINVISIBLE);
PassInputToTerminal(input_index - currentPos + 1, // 1 for the space
(unsigned char *)inputBuffer + currentPos);
clear_mode_flag(CURSORINVISIBLE);
setCursor(cur_x - 1, cur_y);
}
else if (keyCode == WXK_UP) { // up
xval = last_logo_x;
yval = last_logo_y;
if (readingInstruction) {
int i;
setCursor(xval, yval);
if (input_index != 0) { // we have to swipe what is already there
for (i = 0; i < input_index; i++) {
inputBuffer[i] = ' ';
}
PassInputToTerminal(input_index, (unsigned char *)inputBuffer);
}
setCursor(xval, yval);
// Now get a history entry
if (--hist_outptr < cmdHistory) {
hist_outptr = &cmdHistory[HIST_MAX-1];
}
if (*hist_outptr == 0) {
wxBell();
hist_outptr++;
}
else {
PassInputToTerminal(strlen((const char *)*hist_outptr), *hist_outptr);
for (i = 0; (*hist_outptr)[i]; i++)
inputBuffer[i] = (*hist_outptr)[i];
input_index = i;
}
}
}
else if (keyCode == WXK_DOWN) { // down
xval = last_logo_x;
yval = last_logo_y;
if (readingInstruction) {
int i;
setCursor(xval, yval);
if (input_index != 0) { // we have to swipe what is already there
for (i = 0; i < input_index; i++) {
inputBuffer[i] = ' ';
}
PassInputToTerminal(input_index, (unsigned char *)inputBuffer);
}
setCursor(xval, yval);
if (*hist_outptr != 0) {
hist_outptr++;
}
if (hist_outptr >= &cmdHistory[HIST_MAX]) {
hist_outptr = cmdHistory;
}
if (*hist_outptr == 0) {
wxBell();
} else {
PassInputToTerminal(strlen((const char *)*hist_outptr),
*hist_outptr);
for (i = 0; (*hist_outptr)[i]; i++)
inputBuffer[i] = (*hist_outptr)[i];
input_index = i;
}
}}
else if (keyCode == WXK_LEFT) { // left
// cursor_x, cursor_y. make sure it doesn't go past cursor_x
if (cursor_x - 1 < 0)
setCursor(x_max, max(cursor_y,last_logo_y) - 1);
int xval;
if (last_logo_y == cursor_y && cursor_x - 1 < last_logo_x)
xval = last_logo_x;
else
xval = cursor_x - 1;
setCursor( xval, max(cursor_y,last_logo_y));
}
else if (keyCode == WXK_RIGHT) { // right
int currentPos = currentPosition();
if (currentPos >= input_index)
return;
if (max(last_logo_x, cursor_x + 1) >= x_max)
setCursor(0, max(cursor_y,last_logo_y) + 1);
else
setCursor(max(last_logo_x, cursor_x + 1), max(cursor_y,last_logo_y));
}
else if (keyCode == WXK_TAB) { // tab
//do nothing for now. could be tab completion later.
}
else if (keyCode >= WXK_START) {
/* ignore it */
}
else {
buf[0] = keyCode;
len = 1;
int doInsert = 0;
int currentPos = currentPosition();
if (currentPos < input_index ) { // we are in the middle of input
doInsert = 1;
int i;
for (i = input_index; i >= currentPos + 1; i--) {
inputBuffer[i] = inputBuffer[i - 1];
}
inputBuffer[currentPos] = keyCode;
input_index++;
}
else
inputBuffer[input_index++] = keyCode;
if (doInsert) {
// I can't get insert to work quite right ???
// So I guess this will do
// Use the global ones so it will be decremented if this scrolls
cur_x = cursor_x; cur_y = cursor_y;
set_mode_flag(CURSORINVISIBLE);
PassInputToTerminal(input_index - currentPos,
(unsigned char *)(inputBuffer + currentPos));
clear_mode_flag(CURSORINVISIBLE);
if (cur_x == m_width)
setCursor(1, cur_y + 1);
else
setCursor(cur_x+1, cur_y);
}
else {
PassInputToTerminal(len, buf);
}
}
}
void wxTerminal::setCursor (int x, int y, bool fromLogo) {
wxClientDC dc (this);
#ifdef MULTITHREAD
in_mut.Lock();
#endif
if(fromLogo) {
if(x < 0 || x > m_width ||
y < 0 || y > m_height) {
return;
}
GetViewStart(&cursor_x,&cursor_y);
if(!m_vscroll_enabled) {
cursor_x = x;
cursor_y = m_vscroll_pos;
}
cursor_x = x;
cursor_y += y;
fprintf(stderr, "wxsetcursor from logo: set to %d %d\n", cursor_x, cursor_y);
}
else {
cursor_x = x;
cursor_y = y;
}
// fprintf(stderr, "setcursor : set to %d %d\n", cursor_x, cursor_y);
int want_x, want_y;
want_x = cursor_x;
want_y = cursor_y;
if(cursor_y < 0) {
fprintf(stderr, "cursor_y < 0 in setcursor. BAD \n");
}
cursor_y = min(cursor_y,y_max);
curr_line_pos = GetLinePosition(cursor_y);
curr_char_pos = line_of(curr_line_pos);
if(cursor_y < want_y ||
cursor_x > curr_char_pos.line_length) {
cursor_x = curr_char_pos.line_length;
}
curr_char_pos.offset = curr_char_pos.offset + cursor_x;
adjust_charpos(curr_char_pos);
if(fromLogo &&
(cursor_x != want_x ||
cursor_y != want_y)) {
//advance one character
// inc_charpos(curr_char_pos);
//cursor_x++;
if(cursor_x > x_max) {
cursor_x = 0;
cursor_y++;
inc_linepos(curr_line_pos);
}
// fprintf(stderr, "padding with spaces... cxcy %d %d, wxwy %d %d\n", cursor_x, cursor_y, want_x, want_y);
unsigned char space = ' ';
unsigned char newline = '\n';
int oldmode = m_currMode & DEFERUPDATE;
set_mode_flag(DEFERUPDATE);
while(cursor_y != want_y) {
PassInputToTerminal(1,&newline);
}
while(cursor_x != want_x) {
PassInputToTerminal(1,&space);
}
clear_mode_flag(DEFERUPDATE);
m_currMode |= oldmode;
}
// fprintf(stderr, "CURSOR CHANGE: (%d, %d), charoffset: %d\n", x,y,curr_char_pos.offset);
if(!(m_currMode & DEFERUPDATE)) {
Scroll(-1, cursor_y/* - min(m_height, y_max)+1*/);
Refresh();
}
#ifdef MULTITHREAD
in_mut.Unlock();
#endif
}
void wxTerminal::OnSize(wxSizeEvent& event) {
int x, y;
GetSize(&x, &y);
if (m_width == x / m_charWidth && m_height == y / m_charHeight)
return;
x = x / m_charWidth;
y = y / m_charHeight;
if (x < 1)
x = 1;
if (y < 1)
y = 1;
ResizeTerminal(x,y);
Refresh();
}
wxMemoryDC * currentMemDC = NULL;
wxBitmap * currentBitmap = NULL;
int oldWidth = -1;
int oldHeight = -1;
void wxTerminal::OnDraw(wxDC& dc)
{
//DebugOutputBuffer();
wxRect rectUpdate = GetUpdateRegion().GetBox();
CalcUnscrolledPosition(rectUpdate.x, rectUpdate.y,
&rectUpdate.x, &rectUpdate.y);
int lineFrom = rectUpdate.y / m_charHeight;
int lineTo = rectUpdate.GetBottom() / m_charHeight;
if(!m_vscroll_enabled) {
lineFrom += m_vscroll_pos;
lineTo += m_vscroll_pos;
fprintf(stderr, "OnDraw: lines %d to %d\n", lineFrom, lineTo);
}
if ( lineTo > y_max)
lineTo = y_max;
//find the position!
wxterm_linepos tlpos;
tlpos.buf = term_lines;
wxterm_charpos tline;
tlpos.offset = lineFrom;
adjust_linepos(tlpos);
for ( int line = lineFrom; line <= lineTo; line++ )
{
tline = line_of(tlpos);
// fprintf(stderr, "off %d length %d ", tlpos.offset, tline.line_length);
for ( int col = 0; col < tline.line_length; col++ ) {
DrawText(dc, m_curFG, m_curBG, mode_of(tline), col, line, 1, &char_of(tline));
inc_charpos(tline);
}
inc_linepos(tlpos);
}
//draw cursor if visible
if(lineFrom <= cursor_y && cursor_y <= lineTo &&
!(m_currMode & CURSORINVISIBLE)) {
int c_x = cursor_x;
int c_y = cursor_y;
if(!m_vscroll_enabled) {
c_y = c_y - m_vscroll_pos;
}
dc.Blit( c_x*m_charWidth, c_y*m_charHeight, m_charWidth, m_charHeight, &dc, c_x*m_charWidth, c_y*m_charHeight, wxINVERT);
}
}
void
wxTerminal::OnLeftDown(wxMouseEvent& event)
{
m_selecting = TRUE;
int tmpx = m_selx2, tmpy = m_sely2;
m_selx2 = m_selx1;
m_sely2 = m_sely1;
m_seloldx2 = tmpx;
m_seloldy2 = tmpy;
MarkSelection();
m_seloldx1 = m_selx1;
m_seloldx2 = m_selx2;
m_seloldy1 = m_sely1;
m_seloldy2 = m_sely2;
tmpx = event.GetX();
tmpy = event.GetY();
CalcUnscrolledPosition(tmpx,tmpy,&tmpx,&tmpy);
if(!m_vscroll_enabled) {
tmpy += m_vscroll_pos * m_charWidth;
}
tmpx = tmpx / m_charWidth;
if(tmpx > x_max)
// tmpx = m_width - 1;
tmpx = x_max;
tmpy = tmpy / m_charHeight;
if(tmpy >= y_max)
//tmpy = m_height - 1;
tmpy = y_max;
m_selx1 = m_selx2 = tmpx;
m_sely1 = m_sely2 = tmpy;
// fprintf(stderr, "LeftDown: mouseunscrolledpos: %d, %d", tmpx, tmpy);
m_selecting = TRUE;
event.Skip(); //let native handler reset focus
}
void
wxTerminal::OnLeftUp(wxMouseEvent& event)
{
if ((m_sely2 != m_sely1 || m_selx2 != m_selx1))
{
if (wxTheClipboard->Open() ) {
// This data objects are held by the clipboard,
// so do not delete them in the app.
wxTheClipboard->SetData( new wxTextDataObject(GetSelection()) );
wxTheClipboard->Close();
}
}
m_selecting = FALSE;
if (HasCapture()) {
// uncapture mouse
ReleaseMouse();
}
}
void
wxTerminal::OnMouseMove(wxMouseEvent& event)
{
if(m_selecting)
{
int tmpx, tmpy;
tmpx = event.GetX();
tmpy = event.GetY();
CalcUnscrolledPosition(tmpx,tmpy,&tmpx,&tmpy);
if(!m_vscroll_enabled) {
tmpy += m_vscroll_pos * m_charWidth;
}
tmpx = tmpx / m_charWidth;
if(tmpx > x_max)
// tmpx = m_width - 1;
tmpx = x_max;
tmpy = tmpy / m_charHeight;
if(tmpy >= y_max)
//tmpy = m_height - 1;
tmpy = y_max;
// fprintf(stderr, "MouseMove: mouseunscrolledpos: %d, %d", tmpx, tmpy);
if ((m_sely2 > m_sely1 || (m_sely2 == m_sely1 && m_selx2 > m_selx1)) &&
((tmpy < m_sely1) || (tmpy == m_sely1 && tmpx < m_selx1))) {
int x = m_selx2, y = m_sely2;
m_selx2 = m_selx1;
m_sely2 = m_sely1;
m_seloldx2 = x;
m_seloldy2 = y;
MarkSelection();
}
m_seloldx1 = m_selx1;
m_seloldx2 = m_selx2;
m_seloldy1 = m_sely1;
m_seloldy2 = m_sely2;
m_selx2 = tmpx;
m_sely2 = tmpy;
// fprintf(stderr, "x1y1x2y2 (%d,%d) (%d,%d)\n", m_selx1, m_sely1, m_selx2, m_sely2);
MarkSelection();
if(!HasCapture()) {
CaptureMouse();
}
}
}
void
wxTerminal::ClearSelection()
{
if (m_sely2 != m_sely1 || m_selx2 != m_selx1) {
m_sely2 = m_sely1;
m_selx2 = m_selx1;
MarkSelection();
}
}
void
wxTerminal::InvertScrolledArea(wxDC &dc, int t_x, int t_y, int w, int h) {
if(!m_vscroll_enabled) {
t_y -= m_vscroll_pos * m_charWidth;
}
CalcScrolledPosition(t_x,t_y,&t_x,&t_y);
dc.Blit( t_x, t_y, w, h, &dc, t_x, t_y, wxINVERT);
}
void
wxTerminal::MarkSelection() {
static int prev = 0;
wxClientDC dc(this);
m_marking = TRUE;
int pixx2 = m_selx2 * m_charWidth, pixy2 = m_sely2 * m_charHeight,
pixoldx2 = m_seloldx2 * m_charWidth, pixoldy2 = m_seloldy2 * m_charHeight;
if ((m_sely2 > m_sely1 || (m_sely2 == m_sely1 && m_selx2 > m_selx1)) ||
((m_sely2 == m_sely1 && m_selx2 == m_selx1) && !prev)) {
prev = 0;
if(m_seloldy2 == m_sely2)
{
if(m_selx2 > m_seloldx2) {
//dc.Blit( pixoldx2, pixoldy2, pixx2 - pixoldx2, m_charHeight, &dc, pixoldx2, pixoldy2, wxINVERT);
InvertScrolledArea(dc, pixoldx2, pixoldy2, pixx2 - pixoldx2, m_charHeight);
}
else {
//dc.Blit( pixx2, pixy2,pixoldx2 - pixx2, m_charHeight, &dc, pixx2, pixy2, wxINVERT);
InvertScrolledArea(dc, pixx2, pixy2,pixoldx2 - pixx2, m_charHeight);
}
}
else if(m_seloldy2 < m_sely2)
{
//dc.Blit( pixoldx2, pixoldy2, (x_max * m_charWidth) - pixoldx2, m_charHeight, &dc, pixoldx2, pixoldy2, wxINVERT);
InvertScrolledArea(dc, pixoldx2, pixoldy2, (x_max * m_charWidth) - pixoldx2, m_charHeight);
//dc.Blit( 0, (m_seloldy2 + 1) * m_charHeight,(x_max * m_charWidth), pixy2 - ((m_seloldy2 + 1) * m_charHeight), &dc,0, (m_seloldy2 + 1) * m_charHeight, wxINVERT);
InvertScrolledArea(dc, 0, (m_seloldy2 + 1) * m_charHeight,(x_max * m_charWidth), pixy2 - ((m_seloldy2 + 1) * m_charHeight));
//dc.Blit( 0, pixy2, pixx2, m_charHeight, &dc, 0, pixy2, wxINVERT);
InvertScrolledArea(dc, 0, pixy2, pixx2, m_charHeight);
}
else
{
//dc.Blit( 0, pixoldy2, pixoldx2, m_charHeight, &dc, 0, pixoldy2, wxINVERT);
InvertScrolledArea(dc, 0, pixoldy2, pixoldx2, m_charHeight);
// dc.Blit( 0, (m_sely2 + 1) * m_charHeight, (x_max * m_charWidth), pixoldy2 - ((m_sely2 + 1) * m_charHeight), &dc,0, (m_sely2 + 1) * m_charHeight, wxINVERT);
InvertScrolledArea(dc, 0, (m_sely2 + 1) * m_charHeight, (x_max * m_charWidth), pixoldy2 - ((m_sely2 + 1) * m_charHeight));
//dc.Blit( pixx2 /*+ m_charWidth*/, pixy2, (x_max * m_charWidth)-(pixx2 /*+ m_charWidth*/), m_charHeight, &dc, pixx2 /*+ m_charWidth*/, pixy2, wxINVERT);
InvertScrolledArea(dc, pixx2 /*+ m_charWidth*/, pixy2, (x_max * m_charWidth)-(pixx2 /*+ m_charWidth*/), m_charHeight);
}
} else {
prev = 1;
if(m_seloldy2 == m_sely2)
{
if(m_selx2 <= m_seloldx2)
//dc.Blit( pixx2, pixy2, pixoldx2 - pixx2 , m_charHeight, &dc, pixx2, pixy2, wxINVERT);
InvertScrolledArea(dc, pixx2, pixy2, pixoldx2 - pixx2 , m_charHeight);
else
//dc.Blit( pixoldx2, pixoldy2,pixx2 - pixoldx2, m_charHeight, &dc, pixoldx2, pixoldy2, wxINVERT);
InvertScrolledArea(dc, pixoldx2, pixoldy2,pixx2 - pixoldx2, m_charHeight);
}
else if(m_seloldy2 > m_sely2)
{
// dc.Blit( pixx2, pixy2, (x_max * m_charWidth) - pixx2, m_charHeight, &dc, pixx2, pixy2, wxINVERT);
InvertScrolledArea(dc, pixx2, pixy2, (x_max * m_charWidth) - pixx2, m_charHeight);
// dc.Blit( 0, (m_sely2 + 1) * m_charHeight,(x_max * m_charWidth), pixoldy2 - ((m_sely2 + 1) * m_charHeight), &dc,0, (m_sely2 + 1) * m_charHeight, wxINVERT);
InvertScrolledArea(dc, 0, (m_sely2 + 1) * m_charHeight,(x_max * m_charWidth), pixoldy2 - ((m_sely2 + 1) * m_charHeight));
//dc.Blit( 0, pixoldy2, pixoldx2, m_charHeight, &dc, 0, pixoldy2, wxINVERT);
InvertScrolledArea(dc, 0, pixoldy2, pixoldx2, m_charHeight);
}
else
{
//dc.Blit( 0, pixy2, pixx2, m_charHeight, &dc, 0, pixy2, wxINVERT);
InvertScrolledArea(dc, 0, pixy2, pixx2, m_charHeight);
//dc.Blit( 0, (m_seloldy2 + 1) * m_charHeight,(x_max * m_charWidth), pixy2 - ((m_seloldy2 + 1) * m_charHeight), &dc,0, (m_seloldy2 + 1) * m_charHeight, wxINVERT);
InvertScrolledArea(dc, 0, (m_seloldy2 + 1) * m_charHeight,(x_max * m_charWidth), pixy2 - ((m_seloldy2 + 1) * m_charHeight));
//dc.Blit( pixoldx2, pixoldy2, (x_max * m_charWidth)-(pixoldx2 ) , m_charHeight, &dc, pixoldx2, pixoldy2, wxINVERT);
InvertScrolledArea(dc, pixoldx2, pixoldy2, (x_max * m_charWidth)-(pixoldx2 ) , m_charHeight);
}
}
dc.SetLogicalFunction(wxCOPY);
wxWindow::Update();
m_marking = FALSE;
}
bool
wxTerminal::HasSelection()
{
return(m_selx1 != m_selx2 || m_sely1 != m_sely2);
}
/*
* Gets characters from x1,y1 up to , but not including x2,y2
*/
wxString
wxTerminal::GetChars(int x1, int y1, int x2, int y2)
{
// fprintf(stderr, "getchars: x1y1 x2y2 %d,%d -> %d,%d\n", x1,y1,x2,y2);
int tx,ty;
if(y1 > y2 ||
(y1 == y2 && x1 > x2)) {
tx = x1;
ty = y1;
x1 = x2;
y1 = y2;
x2 = tx;
y2 = ty;
}
wxString ret;
//invalid means offset < -1.
if(0 < y1 && y1 > y_max) {
return ret;
}
wxterm_charpos a = GetCharPosition(0,y1);
a.offset = a.offset + min(x1, a.line_length - 1);
adjust_charpos(a);
wxterm_charpos b = GetCharPosition(0,min(y2, y_max));
b.offset = b.offset + min(x2, b.line_length);
adjust_charpos(b);
while(a.buf != b.buf) {
// size 10, offset 5, copy 10-5=5 chars... yup
ret.Append((wxChar*)a.buf->cbuf+a.offset, WXTERM_CB_SIZE-a.offset);
if(a.buf->next) {
a.offset = 0;
a.buf = a.buf->next;
}
else {
//bad
fprintf(stderr, "BAD (getchars)\n");
}
}
// fprintf(stderr, "off1 off2 %d %d\n", a.offset, b.offset);
ret.Append((wxChar*)a.buf->cbuf+a.offset, b.offset - a.offset);
return ret;
}
wxString
wxTerminal::GetSelection()
{
return GetChars(m_selx1,m_sely1,m_selx2,m_sely2);
}
void
wxTerminal::SelectAll()
{
m_selx1 = 0;
m_sely1 = 0;
m_selx2 = x_max;
m_sely2 = y_max;
MarkSelection();
}
wxterm_linepos wxTerminal::GetLinePosition(int y)
{
wxterm_linepos lpos;
lpos.buf = term_lines;
lpos.offset = y;
adjust_linepos(lpos);
return lpos;
}
wxterm_charpos wxTerminal::GetCharPosition(int x, int y)
{
// fprintf(stderr, "getcharpos: x,y: %d,%d", x, y);
wxterm_charpos ret = line_of(GetLinePosition(y));
if(x > ret.line_length) {
fprintf(stderr, "invalid longer than linelength: %d\n", ret.line_length);
}
ret.offset = ret.offset + x;
adjust_charpos(ret);
return ret;
}
void
wxTerminal::DrawText(wxDC& dc, int fg_color, int bg_color, int flags,
int x, int y, int len, unsigned char *string)
{
// fprintf(stderr, "indrawtext x: %d, y: %d, , fgc: %d, bgc: %d, flags: %d, c: %c\n", x,y,fg_color, bg_color, flags,string[0]);
// fprintf(stderr, "cw: %d, ch: %d\n", m_charWidth, m_charHeight);
// int t;
if(flags & SELECTED)
{
fg_color = 0;
bg_color = 15;
}
wxString
str(string, len);
if(flags & BOLD)
{
if(flags & UNDERLINE)
dc.SetFont(m_boldUnderlinedFont);
else
dc.SetFont(m_boldFont);
}
else
{
if(flags & UNDERLINE)
dc.SetFont(m_underlinedFont);
else
dc.SetFont(m_normalFont);
}
int coord_x, coord_y;
dc.SetBackgroundMode(wxSOLID);
dc.SetTextBackground(m_colors[bg_color]);
dc.SetTextForeground(m_colors[fg_color]);
coord_y = y * m_charHeight;
coord_x = x * (m_charWidth);
for(unsigned int i = 0; i < str.Length(); i++, coord_x+=m_charWidth){
dc.DrawText(str.Mid(i, 1), coord_x, coord_y);
// if(flags & BOLD && m_boldStyle == OVERSTRIKE)
// dc.DrawText(str, x + 1, y);
if(flags & INVERSE) {
dc.Blit( coord_x, coord_y, m_charWidth, m_charHeight, &dc, coord_x, coord_y, wxINVERT);
}
}
}
void
wxTerminal::Bell()
{
wxBell();
}
void
wxTerminal::RenumberLines(int new_width)
{
//m_width is the OLD WIDTH at this point of the code.
wxterm_linepos l_pos;
l_pos.buf = term_lines;
l_pos.offset = 0;
wxterm_charpos c_pos = (wxterm_charpos) { term_chars, 0, 0 };
wxterm_charpos last_logo_pos = GetCharPosition(last_logo_x,last_logo_y);
// fprintf(stderr, "lastlogopos buf %d off %d\n", (int)last_logo_pos.buf, last_logo_pos.offset);
//IMPORTANT:
// * line_number stores the current line we're looking at,
// * c_pos.line_length is how far into the current line we are
// * c_pos.offset is the offset into the BUFFER
int line_number = 0;
//run until see '\0'
int next_line = 0; // flag to say "mark next line".
// fprintf(stderr, "renumber: buf: %d, off: %d \n", curr_char_pos.buf, curr_char_pos.offset);
while(char_of(c_pos) != '\0') {
//fprintf(stderr, "renumber: current buf: %d, current off: %d \n", c_pos.buf, c_pos.offset);
if(c_pos.buf == curr_char_pos.buf && c_pos.offset == curr_char_pos.offset) {
//fprintf(stderr, "changed cursor position\n");
cursor_x = c_pos.line_length;
cursor_y = line_number;
curr_line_pos = l_pos;
}
if(c_pos.buf == last_logo_pos.buf && c_pos.offset == last_logo_pos.offset) {
//fprintf(stderr, "changed lastlogo position\n");
last_logo_x = c_pos.line_length;
last_logo_y = line_number;
}
if(char_of(c_pos) == '\n') {
next_line = 1;
}
else {
c_pos.line_length++;
if(c_pos.line_length == new_width) {
next_line = 1;
}
}
inc_charpos(c_pos);
if(next_line) {
// fprintf(stderr, "resizing... nextline\n");
line_of(l_pos).line_length = c_pos.line_length;
inc_linepos(l_pos);
line_of(l_pos).buf = c_pos.buf;
line_of(l_pos).offset = c_pos.offset;
c_pos.line_length = 0;
next_line = 0;
line_number++;
}
}
if(c_pos.buf == curr_char_pos.buf && c_pos.offset == curr_char_pos.offset) {
// fprintf(stderr, "changed cursor position\n");
cursor_x = c_pos.line_length;
cursor_y = line_number;
curr_line_pos = l_pos;
}
if(c_pos.buf == last_logo_pos.buf && c_pos.offset == last_logo_pos.offset) {
// fprintf(stderr, "changed lastlogo position\n");
last_logo_x = c_pos.line_length;
last_logo_y = line_number;
}
line_of(l_pos).line_length = c_pos.line_length;
y_max = line_number;
//sanity check on variables
//fprintf(stderr, "cursor %d %d\n", cursor_x, cursor_y);
//fprintf(stderr, "lastlogopos xy %d %d\n", last_logo_x, last_logo_y);
}
void
wxTerminal::ResizeTerminal(int width, int height)
{
/*
** Set terminal size
*/
if(width != m_width) {
//need to renumber the lines
RenumberLines(width);
m_width = width;
x_max = m_width;
}
m_height = height;
//reset virtual size
SetScrollRate(0, m_charHeight);
SetVirtualSize(x_max*m_charWidth,(y_max+1)*m_charHeight);
}
void wxTerminal::DebugOutputBuffer() {
//debugging
wxterm_linepos lpos;
lpos.buf = term_lines;
lpos.offset = 0;
wxterm_charpos pos_1 = line_of(lpos);
fprintf(stderr, "WXTERMINAL STATS: \n width: %d, height: %d, \n x_max: %d, y_max: %d \n cursor_x: %d, cursor_y: %d \n last_logo_x : %d, last_logo_y: %d \ncurr_charpos buf %d offset %d \ncurr_line buf %d offset %d\n", m_width, m_height, x_max, y_max,cursor_x, cursor_y, last_logo_x, last_logo_y,(int)curr_char_pos.buf, curr_char_pos.offset, (int)curr_line_pos.buf, curr_line_pos.offset);
fprintf(stderr, "WXTERMINAL CHARACTER BUFFER\n###############\n");
while(char_of(pos_1) != '\0') {
if(char_of(pos_1) == '\n') {
fprintf(stderr, "\\n\n");
}
else {
fprintf(stderr,"%c", char_of(pos_1));
}
inc_charpos(pos_1);
}
fprintf(stderr, "|");
fprintf(stderr, "\n#############\n");
fprintf(stderr, "WXTERMINAL LINE BUFFER\n##############\n");
for(int i = 0; i <= y_max; i++) {
fprintf(stderr, "LINE %d: buf: %d, offset: %d, len: %d\n", i,(int)line_of(lpos).buf, line_of(lpos).offset, line_of(lpos).line_length);
inc_linepos(lpos);
}
fprintf(stderr, "\n#############\n\n");
}
void wxTerminal::InsertChar(char c)
{
// fprintf(stderr, "inserting char: '%c' at offset %d\n", c, curr_char_pos.offset);
// fprintf(stderr, "test: %d\n", x_max);
//insert a character at current location
//if there is a newline at the current location and we're not inserting one
if(char_of(curr_char_pos) == '\n' &&
c != '\n') {
// check case if we're about to insert the last character of the line
if(line_of(curr_line_pos).line_length < m_width - 1) {
// fprintf(stderr, "here1\n");
//have to add characters to current line,
//bump characters up.
wxterm_linepos lpos = curr_line_pos;
wxterm_charpos pos_1 = curr_char_pos;
wxterm_charpos pos_2 = pos_1;
inc_charpos(pos_2);
// Method of relocating characters:
// need two variables, S = save, G = grab
//
// save 1,
// S1 G
// 12345678
//
// grab 2, place 1, save 2
//
// S2 G2
// _1345678
//
// grab 3, place 2, save 3...
//
// S3 G3
// _1245678
//
// etc...
// ends when next position to grab is '\0'
// (allocate buffer when necesary)
// grab 8, place 7, save 8
// place 8 in that last position
unsigned char save_char, save_mode;
unsigned char grab_char, grab_mode;
save_char = char_of(pos_1);
save_mode = mode_of(pos_1);
while(char_of(pos_2) != '\0') {
grab_char = char_of(pos_2);
grab_mode = mode_of(pos_2);
char_of(pos_2) = save_char;
mode_of(pos_2) = save_mode;
save_char = grab_char;
save_mode = grab_mode;
inc_charpos(pos_1);
inc_charpos(pos_2);
}
//insert "save" into pos2
char_of(pos_2) = save_char;
mode_of(pos_2) = save_mode;
//now bump all the lines up.
//look at the current line number (cursor_y)
// go until y_max, and adjust position of all lines +1
inc_linepos(lpos);
for(int lnum = cursor_y+1; lnum <= y_max; lnum++) {
inc_charpos(line_of(lpos));
inc_linepos(lpos);
}
}
}
char_of(curr_char_pos) = c;
mode_of(curr_char_pos) = m_currMode;
inc_charpos(curr_char_pos);
}
void wxTerminal::NextLine() {
// fprintf(stderr, "nextline!\n");
//points next line position to current char position, and increments line offset.
inc_linepos(curr_line_pos);
line_of(curr_line_pos).buf = curr_char_pos.buf;
line_of(curr_line_pos).offset = curr_char_pos.offset;
//line_of(curr_line_pos).line_length = 0;
cursor_y++;
if(cursor_y > y_max) {
y_max = cursor_y;
int x,y;
GetVirtualSize(&x,&y);
SetVirtualSize(max(x,x_max*m_charWidth),max(y,(y_max+1)*m_charHeight));
// fprintf(stderr, "increasing virtual area\n");
}
cursor_x = 0;
}
void
wxTerminal::PassInputToTerminal(int len, unsigned char *data)
{
// fprintf(stderr, "pitt: input received: len %d, string %s\n", len, data);
//fprintf(stderr, "PItT before:\n");
//DebugOutputBuffer();
int i;
int numspaces, j;
wxterm_linepos lpos;
wxterm_charpos pos_1, pos_2;
int new_line_length;
for(i = 0; i < len; i++) {
switch(data[i]) {
case TOGGLE_STANDOUT: // char 17
//enter/exit standout mode , ignore character
m_currMode ^= INVERSE;
break;
case '\t':
// formula is: (8 - (cursorpos%8)) spaces
numspaces = (8 - (cursor_x % 8));
if(numspaces == 0) {
numspaces = 8;
}
for(j = 0; j < numspaces; j++) {
InsertChar(' ');
cursor_x++;
if(cursor_x > line_of(curr_line_pos).line_length) {
line_of(curr_line_pos).line_length = cursor_x;
}
if(cursor_x == x_max) {
NextLine();
}
}
break;
case '\r':
case '\n':
new_line_length = cursor_x;
InsertChar('\n');
if(i + 1 < len &&
((data[i] == '\r' && data[i+1] == '\n') || //LF+CR
(data[i] == '\n' && data[i+1] == '\r'))) { //CR+LF
i++;
}
if(new_line_length < line_of(curr_line_pos).line_length &&
cursor_y < y_max) {
//shift all the characters down.
//current position is after the newline.
lpos = curr_line_pos;
inc_linepos(lpos);
pos_1 = curr_char_pos;
pos_2 = line_of(lpos);
while(char_of(pos_1) != '\0') {
if(char_of(pos_2) != '\0' &&
pos_2.buf == line_of(lpos).buf &&
pos_2.offset == line_of(lpos).offset) {
line_of(lpos).buf = pos_1.buf;
line_of(lpos).offset = pos_1.offset;
inc_linepos(lpos);
}
char_of(pos_1) = char_of(pos_2);
mode_of(pos_1) = mode_of(pos_2);
inc_charpos(pos_1);
inc_charpos(pos_2);
}
}
//check if line_length is -1 TODO
// fprintf(stderr, "new length: %d\n", new_line_length);
line_of(curr_line_pos).line_length = new_line_length;
NextLine();
break;
default:
InsertChar(data[i]);
cursor_x++;
if(cursor_x > line_of(curr_line_pos).line_length) {
line_of(curr_line_pos).line_length = cursor_x;
}
if(cursor_x == x_max) {
NextLine();
}
break;
}
}
// last_user_x = cursor_x;
// last_user_y = cursor_y;
if(!(m_currMode & DEFERUPDATE)) {
Scroll(-1, cursor_y/* - min(m_height, y_max)+1*/);
//Scroll(-1,y_max-min(m_height, y_max)+1);
//fprintf(stderr, "PItT after:\n");
//DebugOutputBuffer();
Refresh();
}
// fprintf(stderr, "end pitt\n");
}
wxString * wxTerminal::get_text()
{
// int i;
wxString *outputString = new wxString();
outputString->Clear();
outputString->Append("<HTML>\n");
outputString->Append("<BODY>\n");
outputString->Append("<FONT SIZE=2>\n");
wxString txt = GetChars(0,0,x_max,y_max);
txt.Replace("\n","<BR>\n");
outputString->Append(txt);
/*
wxterm_linepos tlpos = term_lines;
for(i=0;i<ymax;i++){
outputString->append(textString->Mid(linenumbers[i]*MAXWIDTH),MAXWIDTH);
outputString->append("<BR>");
}*/
outputString->Append("<\\FONT>");
outputString->Append("<\\BODY>");
outputString->Append("<\\HTML>");
// delete textString;
return outputString;
}
void
wxTerminal::SelectPrinter(char *PrinterName)
{
if(m_printerFN)
{
if(m_printerName[0] == '#')
fclose(m_printerFN);
else
#if defined(__WXMSW__)
fclose(m_printerFN);
#else
pclose(m_printerFN);
#endif
m_printerFN = 0;
}
if(m_printerName)
{
free(m_printerName);
m_printerName = 0;
}
if(strlen(PrinterName))
{
m_printerName = strdup(PrinterName);
}
}
void
wxTerminal::PrintChars(int len, unsigned char *data)
{
char
pname[100];
if(!m_printerFN)
{
if(!m_printerName)
return;
if(m_printerName[0] == '#')
{
#if defined(__WXMSW__)
sprintf(pname, "lpt%d", m_printerName[1] - '0' + 1);
#else
sprintf(pname, "/dev/lp%d", m_printerName[1] - '0');
#endif
m_printerFN = fopen(pname, "wb");
}
else
{
#if defined(__WXMSW__)
m_printerFN = fopen(m_printerName, "wb");
#else
sprintf(pname, "lpr -P%s", m_printerName);
m_printerFN = popen(pname, "w");
#endif
}
}
if(m_printerFN)
{
fwrite(data, len, 1, m_printerFN);
}
}
// ----------------------------------------------------------------------------
// Functions called from the interpreter thread
// ----------------------------------------------------------------------------
extern "C" void setCharMode(int mode){
logo_char_mode = mode;
}
extern "C" void wxClearText() {
#ifdef MULTITHREAD
out_mut.Lock();
#endif
// wxTerminal::terminal->Reset();
//idea here.. increase the size of the terminal, and set the thumb position to the bottom
//TODO
wxTerminal::terminal->ClearScreen();
out_buff_index_public = 0;
out_buff_index_private = 0;
#ifdef MULTITHREAD
out_mut.Unlock();
#endif
}
void wxTerminal::ClearScreen() {
if(y_max > 0) {
int x,y;
GetVirtualSize(&x,&y);
SetVirtualSize(max(x,x_max*m_charWidth),max(y,(y_max+1+m_height)*m_charHeight));
Scroll(-1,y_max);
int vx,vy;
GetViewStart(&vx,&vy);
setCursor(0,y_max + 1 - vy, TRUE);
Refresh();
}
}
void wxTerminal::EnableScrolling(bool want_scrolling) {
return;
//the following doesn't work yet.
#if 0
if(want_scrolling) {
if(!m_vscroll_enabled) {
SetVirtualSize(x_max*m_charWidth,(y_max+1)*m_charHeight);
m_vscroll_enabled = TRUE;
}
}
else {
if(m_vscroll_enabled) {
int x;
GetViewStart(&x, &m_vscroll_pos);
m_vscroll_enabled = FALSE;
SetVirtualSize(m_width*m_charWidth, m_height*m_charHeight);
}
}
#endif
}
extern "C" void flushFile(FILE * stream, int);
extern "C" void wxSetCursor(int x, int y){
#ifndef MULTITHREAD
//just call wxTerminal::setCursor with a special flag.
fprintf(stderr, "Setting scroll off\n");
wxTerminal::terminal->EnableScrolling(FALSE);
flushFile(stdout, 0);
wxTerminal::terminal->setCursor(x,y,TRUE);
#else
int * data = (int *)malloc(2 * sizeof(int));
data[0] = x;
data[1] = y;
wxCommandEvent event(wxEVT_MY_CUSTOM_COMMAND);
event.SetClientData((void *)data);
flushFile(stdout, 0);
out_mut.Lock();
movedCursor = 0;
out_mut.Unlock();
wxPostEvent(wxTerminal::terminal,event);
out_mut.Lock();
if (!movedCursor) {
buff_full_cond.Wait();
}
movedCursor = 0;
out_mut.Unlock();
#endif
}
extern "C" void wx_enable_scrolling() {
wxTerminal::terminal->EnableScrolling(TRUE);
}
extern "C" int check_wx_stop(int force_yield) {
#ifndef MULTITHREAD
logoEventManager->ProcessAnEvent(force_yield);
#endif
if (logo_stop_flag) {
logo_stop_flag = 0;
#ifdef SIG_TAKES_ARG
logo_stop(0);
#else
logo_stop();
#endif
return 1;
}
if (logo_pause_flag) {
logo_pause_flag = 0;
#ifdef SIG_TAKES_ARG
logo_pause(0);
#else
logo_pause();
#endif
return 0;
}
return 0;
}
extern "C" int internal_check(){
if (logo_stop_flag) {
logo_stop_flag = 0;
#ifdef SIG_TAKES_ARG
logo_stop(0);
#else
logo_stop();
#endif
return 1;
}
if (logo_pause_flag) {
logo_pause_flag = 0;
#ifdef SIG_TAKES_ARG
logo_pause(0);
#else
logo_pause();
#endif
return 1;
}
return 0;
}
extern "C" int getTermInfo(int type){
switch (type){
case X_COORD:
return wxTerminal::terminal->x_coord;
break;
case Y_COORD:
return wxTerminal::terminal->y_coord;
break;
case X_MAX:
//return wxTerminal::terminal->x_max;
return wxTerminal::terminal->m_width;
break;
case Y_MAX:
//return wxTerminal::terminal->y_max;
return wxTerminal::terminal->m_height;
break;
case EDIT_STATE:
return editWindow->stateFlag;
break;
default:
return -1;
}
return -1;
}
extern "C" void setTermInfo(int type, int val){
switch (type){
case X_COORD:
wxTerminal::terminal->x_coord=val;
break;
case Y_COORD:
wxTerminal::terminal->y_coord=val;
break;
case X_MAX:
return;
//wxTerminal::terminal->x_max=val;
break;
case Y_MAX:
return;
//wxTerminal::terminal->y_max=val;
break;
case EDIT_STATE:
editWindow->stateFlag=val;
break;
}
}
extern "C" void doClose() {
extern int wx_leave_mainloop;
if(!wx_leave_mainloop) {
logoFrame->Close(TRUE);
}
}
![swh spinner](/static/img/swh-spinner.gif)
Computing file changes ...