--- /dev/null
+// $Id$
+//
+// Copyright (C) 2009
+// Fraunhofer Institute for Open Communication Systems (FOKUS)
+// Competence Center NETwork research (NET), St. Augustin, GERMANY
+// Stefan Bund <g0dil@berlios.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+/** \file
+ \brief Terminal public header */
+
+#ifndef HH_SENF_Utils_Termlib_AbstractTerminal_
+#define HH_SENF_Utils_Termlib_AbstractTerminal_ 1
+
+// Custom includes
+#include <string>
+
+//#include "AbstractTerminal.mpp"
+///////////////////////////////hh.p////////////////////////////////////////
+
+namespace senf {
+namespace term {
+
+ struct AbstractTerminal
+ {
+ struct Callbacks {
+ virtual ~Callbacks() {}
+ virtual void cb_init() = 0;
+ virtual void cb_charReceived(char ch) = 0;
+ virtual void cb_windowSizeChanged() = 0;
+ };
+
+ virtual ~AbstractTerminal() {}
+
+ virtual void setCallbacks(Callbacks & cb) = 0;
+
+ virtual std::string terminalType() = 0;
+ virtual unsigned width() = 0;
+ virtual unsigned height() = 0;
+
+ virtual void write(char ch) = 0;
+ };
+
+}}
+
+///////////////////////////////hh.e////////////////////////////////////////
+//#include "AbstractTerminal.cci"
+//#include "AbstractTerminal.ct"
+//#include "AbstractTerminal.cti"
+#endif
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// comment-column: 40
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// End:
--- /dev/null
+// $Id$
+//
+// Copyright (C) 2009
+// Fraunhofer Institute for Open Communication Systems (FOKUS)
+// Competence Center NETwork research (NET), St. Augustin, GERMANY
+// Stefan Bund <g0dil@berlios.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+/** \file
+ \brief Editor non-inline non-template implementation */
+
+#include "Editor.hh"
+//#include "Editor.ih"
+
+// Custom includes
+#include <senf/Utils/membind.hh>
+#include <senf/Scheduler/Scheduler.hh>
+
+//#include "Editor.mpp"
+#define prefix_
+///////////////////////////////cc.p////////////////////////////////////////
+
+prefix_ senf::term::BaseEditor::BaseEditor(AbstractTerminal & terminal)
+ : terminal_ (&terminal),
+ keyTimeout_ (senf::ClockService::milliseconds(DEFAULT_KEY_TIMEOUT_MS)),
+ timer_ ("senf::term::BaseEditor::keySequenceTimeout",
+ senf::membind(&BaseEditor::keySequenceTimeout, this)),
+ column_ (0u)
+{
+ terminal_->setCallbacks(*this);
+}
+
+prefix_ void senf::term::BaseEditor::newline()
+{
+ write("\r\n");
+ write(tifo_.getString(Terminfo::properties::ClrEol));
+ column_ = 0;
+}
+
+prefix_ void senf::term::BaseEditor::toColumn(unsigned c)
+{
+ if (c >= width())
+ c = width();
+ if (c > column_) {
+ if (tifo_.hasProperty(Terminfo::properties::ParmRightCursor)) {
+ write(tifo_.formatString(Terminfo::properties::ParmRightCursor, c - column_));
+ column_ = c;
+ }
+ else {
+ char const * cuf1 (tifo_.getString(Terminfo::properties::CursorRight));
+ while (c > column_) {
+ write(cuf1);
+ ++column_;
+ }
+ }
+ }
+ else if (c < column_) {
+ if (tifo_.hasProperty(Terminfo::properties::ParmLeftCursor)) {
+ write(tifo_.formatString(Terminfo::properties::ParmLeftCursor, column_ - c));
+ column_ = c;
+ }
+ else {
+ char const * cub1 (tifo_.getString(Terminfo::properties::CursorRight));
+ while (c < column_) {
+ write(cub1);
+ --column_;
+ }
+ }
+ }
+}
+
+prefix_ void senf::term::BaseEditor::insertChar(char ch)
+{
+ if (column_+1 >= width())
+ return;
+ if (tifo_.hasProperty(Terminfo::properties::InsertCharacter))
+ write(tifo_.getString(Terminfo::properties::InsertCharacter));
+ else
+ write(tifo_.formatString(Terminfo::properties::ParmIch, 1));
+ write(ch);
+ ++ column_;
+}
+
+prefix_ void senf::term::BaseEditor::overwriteChar(char ch)
+{
+ write(ch);
+ ++ column_;
+}
+
+prefix_ void senf::term::BaseEditor::deleteChar()
+{
+ if (tifo_.hasProperty(Terminfo::properties::DeleteCharacter))
+ write(tifo_.getString(Terminfo::properties::DeleteCharacter));
+ else
+ write(tifo_.formatString(Terminfo::properties::ParmDch, 1));
+}
+
+prefix_ unsigned senf::term::BaseEditor::currentColumn()
+ const
+{
+ return column_;
+}
+
+prefix_ void senf::term::BaseEditor::cb_init()
+{
+ tifo_.load(terminal_->terminalType());
+ keyParser_.load(tifo_);
+ if (tifo_.hasProperty(Terminfo::properties::KeypadXmit))
+ write(tifo_.getString(Terminfo::properties::KeypadXmit));
+}
+
+prefix_ void senf::term::BaseEditor::cb_charReceived(char c)
+{
+ inputBuffer_ += c;
+ timer_.timeout(senf::scheduler::eventTime() + keyTimeout_);
+ processKeys();
+}
+
+prefix_ void senf::term::BaseEditor::cb_windowSizeChanged()
+{
+ if (column_ >= width())
+ column_ = width()-1;
+}
+
+prefix_ void senf::term::BaseEditor::keySequenceTimeout()
+{
+ while (!inputBuffer_.empty()) {
+ processKeys();
+ v_keyReceived(keycode_t(inputBuffer_[0]));
+ inputBuffer_.erase(0, 1);
+ }
+}
+
+prefix_ void senf::term::BaseEditor::processKeys()
+{
+ do {
+ std::pair<senf::term::KeyParser::keycode_t, std::string::size_type> result
+ (keyParser_.lookup(inputBuffer_));
+ if (result.first == senf::term::KeyParser::Incomplete)
+ return;
+ v_keyReceived(result.first);
+ inputBuffer_.erase(0, result.second);
+ } while (! inputBuffer_.empty());
+ timer_.disable();
+}
+
+prefix_ unsigned senf::term::BaseEditor::width()
+{
+ return terminal_->width();
+}
+
+prefix_ void senf::term::BaseEditor::write(char ch)
+{
+ terminal_->write(ch);
+}
+
+prefix_ void senf::term::BaseEditor::write(std::string const & s)
+{
+ for (std::string::const_iterator i (s.begin()); i != s.end(); ++i)
+ write(*i);
+}
+
+///////////////////////////////cc.e////////////////////////////////////////
+#undef prefix_
+//#include "Editor.mpp"
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// comment-column: 40
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// End:
--- /dev/null
+// $Id$
+//
+// Copyright (C) 2009
+// Fraunhofer Institute for Open Communication Systems (FOKUS)
+// Competence Center NETwork research (NET), St. Augustin, GERMANY
+// Stefan Bund <g0dil@berlios.de>
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 2 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the
+// Free Software Foundation, Inc.,
+// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+/** \file
+ \brief Editor public header */
+
+#ifndef HH_SENF_Utils_Termlib_Editor_
+#define HH_SENF_Utils_Termlib_Editor_ 1
+
+// Custom includes
+#include <senf/Scheduler/ClockService.hh>
+#include <senf/Scheduler/TimerEvent.hh>
+#include "AbstractTerminal.hh"
+#include "Terminfo.hh"
+
+//#include "Editor.mpp"
+///////////////////////////////hh.p////////////////////////////////////////
+
+namespace senf {
+namespace term {
+
+ class BaseEditor
+ : public AbstractTerminal::Callbacks
+ {
+ public:
+ typedef KeyParser::keycode_t keycode_t;
+
+ static unsigned const DEFAULT_KEY_TIMEOUT_MS = 500u;
+
+ explicit BaseEditor(AbstractTerminal & terminal);
+
+ void newline(); ///< Move to beginning of a new, empty line
+ void toColumn(unsigned c); ///< Move cursor to column \p c
+ void insertChar(char ch); ///< Insert \p ch at current column, shifting text right
+ void overwriteChar(char ch); ///< Write \p ch at current column
+ void deleteChar(); ///< Delete a character a current column
+
+ unsigned currentColumn() const; ///< Return number of current column
+
+ private:
+ virtual void v_keyReceived(keycode_t key) = 0;
+
+ virtual void cb_init();
+ virtual void cb_charReceived(char c);
+ virtual void cb_windowSizeChanged();
+
+ void keySequenceTimeout();
+ void processKeys();
+
+ unsigned width();
+ void write(char ch);
+ void write(std::string const & s);
+
+ AbstractTerminal * terminal_;
+ Terminfo tifo_;
+ KeyParser keyParser_;
+ std::string inputBuffer_;
+ ClockService::clock_type keyTimeout_;
+ scheduler::TimerEvent timer_;
+ unsigned column_;
+ };
+
+}}
+
+///////////////////////////////hh.e////////////////////////////////////////
+//#include "Editor.cci"
+//#include "Editor.ct"
+//#include "Editor.cti"
+#endif
+
+\f
+// Local Variables:
+// mode: c++
+// fill-column: 100
+// comment-column: 40
+// c-file-style: "senf"
+// indent-tabs-mode: nil
+// ispell-local-dictionary: "american"
+// compile-command: "scons -u test"
+// End:
//#include "TelnetTerminal.ih"
// Custom includes
-#include <senf/Utils/membind.hh>
//#include "TelnetTerminal.mpp"
#define prefix_
///////////////////////////////cc.p////////////////////////////////////////
prefix_ senf::term::TelnetTerminal::TelnetTerminal()
- : keyTimeout_ (senf::ClockService::milliseconds(DEFAULT_KEY_TIMEOUT_MS)),
- timer_ ("senf::term::TelnetTerminal::keySequenceTimeout",
- senf::membind(&TelnetTerminal::keySequenceTimeout, this))
{
requestPeerOption(telnetopt::SUPPRESS_GO_AHEAD);
requestLocalOption(telnetopt::SUPPRESS_GO_AHEAD);
requestLocalOption(telnetopt::ECHO);
}
-prefix_ void senf::term::TelnetTerminal::v_setupComplete()
+prefix_ void senf::term::TelnetTerminal::setCallbacks(AbstractTerminal::Callbacks & cb)
+{
+ callbacks_ = &cb;
+}
+
+prefix_ std::string senf::term::TelnetTerminal::terminalType()
+{
+ return telnethandler::TerminalType::terminalType();
+}
+
+prefix_ unsigned senf::term::TelnetTerminal::width()
{
- tifo_.load(terminalType());
- keyParser_.load(tifo_);
+ return telnethandler::NAWS::width();
}
-prefix_ void senf::term::TelnetTerminal::v_charReceived(char c)
+prefix_ unsigned senf::term::TelnetTerminal::height()
+{
+ return telnethandler::NAWS::height();
+}
+
+prefix_ void senf::term::TelnetTerminal::write(char ch)
+{
+ BaseTelnetProtocol::write(ch);
+}
+
+prefix_ void senf::term::TelnetTerminal::v_setupComplete()
{
- inputBuffer_ += c;
- timer_.timeout(senf::scheduler::eventTime() + keyTimeout_);
- processKeys();
+ callbacks_->cb_init();
}
-prefix_ void senf::term::TelnetTerminal::keySequenceTimeout()
+prefix_ void senf::term::TelnetTerminal::v_charReceived(char ch)
{
- while (!inputBuffer_.empty()) {
- processKeys();
- v_keyReceived(keycode_t(inputBuffer_[0]));
- inputBuffer_.erase(0, 1);
- }
+ callbacks_->cb_charReceived(ch);
}
-prefix_ void senf::term::TelnetTerminal::processKeys()
+prefix_ void senf::term::TelnetTerminal::v_windowSizeChanged()
{
- do {
- std::pair<senf::term::KeyParser::keycode_t, std::string::size_type> result
- (keyParser_.lookup(inputBuffer_));
- if (result.first == senf::term::KeyParser::Incomplete)
- return;
- v_keyReceived(result.first);
- inputBuffer_.erase(0, result.second);
- } while (! inputBuffer_.empty());
- timer_.disable();
+ callbacks_->cb_windowSizeChanged();
}
///////////////////////////////cc.e////////////////////////////////////////
#define HH_SENF_Utils_Termlib_TelnetTerminal_ 1
// Custom includes
-#include <senf/Scheduler/TimerEvent.hh>
-#include <senf/Scheduler/ClockService.hh>
#include "Telnet.hh"
-#include "Terminfo.hh"
+#include "AbstractTerminal.hh"
//#include "TelnetTerminal.mpp"
///////////////////////////////hh.p////////////////////////////////////////
class TelnetTerminal
: public telnethandler::TerminalType,
- public telnethandler::NAWS
+ public telnethandler::NAWS,
+ public AbstractTerminal
{
public:
- typedef KeyParser::keycode_t keycode_t;
-
- static unsigned const DEFAULT_KEY_TIMEOUT_MS = 500u;
-
TelnetTerminal();
- protected:
- virtual void v_setupComplete();
+ virtual void setCallbacks(AbstractTerminal::Callbacks & cb);
+ virtual std::string terminalType();
+ virtual unsigned width();
+ virtual unsigned height();
+ virtual void write(char ch);
private:
- virtual void v_keyReceived(keycode_t key) = 0;
-
- virtual void v_charReceived(char c);
- void keySequenceTimeout();
- void processKeys();
+ virtual void v_setupComplete();
+ virtual void v_charReceived(char ch);
+ virtual void v_windowSizeChanged();
- senf::term::Terminfo tifo_;
- senf::term::KeyParser keyParser_;
- std::string inputBuffer_;
- senf::ClockService::clock_type keyTimeout_;
- senf::scheduler::TimerEvent timer_;
+ AbstractTerminal::Callbacks * callbacks_;
};
+
}}
///////////////////////////////hh.e////////////////////////////////////////
return strings_[p];
}
+prefix_ bool senf::term::Terminfo::hasProperty(properties::Boolean p)
+ const
+{
+ return getFlag(p);
+}
+
+prefix_ bool senf::term::Terminfo::hasProperty(properties::Numeric p)
+ const
+{
+ return getNumber(p) != NoValue;
+}
+
+prefix_ bool senf::term::Terminfo::hasProperty(properties::String p)
+ const
+{
+ return getString(p) != 0;
+}
+
+namespace {
+
+ struct Stack
+ {
+ std::vector<senf::term::Terminfo::number_t> stack;
+
+ void push(senf::term::Terminfo::number_t v)
+ {
+ stack.push_back(v);
+ }
+
+ senf::term::Terminfo::number_t pop()
+ {
+ if (stack.empty())
+ return 0;
+ else {
+ senf::term::Terminfo::number_t v (stack.back());
+ stack.pop_back();
+ return v;
+ }
+ }
+
+ senf::term::Terminfo::number_t popNonzero()
+ {
+ senf::term::Terminfo::number_t v (pop());
+ return v ? v : 1;
+ }
+ };
+
+}
+
+// The following code is taken directly from utio. As far as I understand it is buggy
+// and/or only partially implements the string format language. But seems to be enough for
+// all the common terminal types ...
+prefix_ std::string senf::term::Terminfo::formatString(properties::String p,
+ number_t arg1, number_t arg2,
+ number_t arg3, number_t arg4,
+ number_t arg5, number_t arg6,
+ number_t arg7, number_t arg8,
+ number_t arg9)
+ const
+{
+ char const * fmt_p (getString(p));
+ if (! fmt_p)
+ return "";
+
+ std::string const prgstr (fmt_p);
+ Stack stack;
+ bool bCondValue (false);
+ std::string result;
+
+ for (std::string::const_iterator i (prgstr.begin()); i != prgstr.end(); ++i) {
+ if (*i != '%') {
+ result += *i;
+ continue;
+ }
+ int width = 0, base = 0;
+ switch (*++i) {
+ case '%': result += *i; break;
+ case 'i': ++arg1; ++arg2; break;
+ case 'c': result += char(stack.pop()); break;
+ case 'x': base = 16; continue;
+ case '0': if (!base) base = 8;
+ case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8':
+ case '9': if (!base) base = 10;
+ width = width * base + (*i - '0');
+ continue;
+ case '\\': base = 0;
+ case '{': continue;
+ case '\'': if (*(i - 1) == '%') {
+ if (*(i + 1) != '\\')
+ width = *++i;
+ continue;
+ }
+ case '}': stack.push(width); break;
+ // Binary operands are in infix (reversed) order
+ case '+': stack.push(stack.pop() + stack.pop()); break;
+ case '-': stack.push(-stack.pop() + stack.pop()); break;
+ case '*': stack.push(stack.pop() * stack.pop()); break;
+ case '/': stack.push(stack.pop() / stack.popNonzero()); break;
+ case 'm': stack.push(stack.pop() % stack.popNonzero()); break;
+ case '|': stack.push(stack.pop() | stack.pop()); break;
+ case '&': stack.push(stack.pop() & stack.pop()); break;
+ case '^': stack.push(stack.pop() ^ stack.pop()); break;
+ case '>': stack.push(stack.pop() < stack.pop()); break;
+ case '<': stack.push(stack.pop() > stack.pop()); break;
+ case '=': stack.push(stack.pop() == stack.pop()); break;
+ case 'A': stack.push(stack.pop() && stack.pop()); break;
+ case 'O': stack.push(stack.pop() || stack.pop()); break;
+ case '!': stack.push(!stack.pop()); break;
+ case '~': stack.push(~stack.pop()); break;
+ case 't': bCondValue = stack.pop();
+ case 'e': if ((bCondValue = !bCondValue)) // this also supports elsif
+ --(i = prgstr.begin() + std::min (prgstr.find ("%e", i-prgstr.begin()),
+ prgstr.find ("%;", i-prgstr.begin())));
+ case '?':
+ case ';': break;
+ case 'p':
+ switch (*++i) {
+ case '1': stack.push(arg1); break;
+ case '2': stack.push(arg2); break;
+ case '3': stack.push(arg3); break;
+ case '4': stack.push(arg4); break;
+ case '5': stack.push(arg5); break;
+ case '6': stack.push(arg6); break;
+ case '7': stack.push(arg7); break;
+ case '8': stack.push(arg8); break;
+ case '9': stack.push(arg9); break;
+ }
+ break;
+ case 'd': {
+ number_t n = stack.pop();
+ const std::string::size_type iSize = result.size();
+ do {
+ result += std::string::value_type('0' + (n % 10));
+ } while ((n /= 10) || --width > 0);
+ reverse (result.begin() + iSize, result.end());
+ break; }
+ }
+ }
+
+ return result;
+}
+
prefix_ void senf::term::Terminfo::dump(std::ostream & os)
const
{
///////////////////////////////////////////////////////////////////////////
// Types
- enum Color {
- Black, Red, Green, Brown, Blue, Magenta, Cyan, LightGray, DarkGray, LightRed,
- LightGreen, Yellow, LightBlue, Pink, LightCyan, White,
- Preserve, LastColor = Preserve };
-
- enum Attribute {
- Standout, Underline, Reverse, Blink, HalfBright, Bold, Invisible, Protect, AltCharset,
- Italic, Substript, Superscript, LastAttribute };
-
enum { NoValue = -1 };
struct properties
bool getFlag(properties::Boolean p) const;
number_t getNumber(properties::Numeric p) const;
string_t getString(properties::String p) const;
+ bool hasProperty(properties::Boolean p) const;
+ bool hasProperty(properties::Numeric p ) const;
+ bool hasProperty(properties::String p ) const;
+ std::string formatString(properties::String p,
+ number_t arg1=NoValue, number_t arg2=NoValue,
+ number_t arg3=NoValue, number_t arg4=NoValue,
+ number_t arg5=NoValue, number_t arg6=NoValue,
+ number_t arg7=NoValue, number_t arg8=NoValue,
+ number_t arg9=NoValue) const;
+
+ ///////////////////////////////////////////////////////////////////////////
void dump(std::ostream & os) const;
Pair(senf::term::KeyParser::keycode_t('b'), 1u) );
BOOST_CHECK_EQUAL( kp.lookup(""),
Pair(senf::term::KeyParser::keycode_t('\0'), 0u) );
+
+ BOOST_CHECK_EQUAL( ifo.formatString(senf::term::Terminfo::properties::CursorAddress,
+ 9, 12),
+ "\e[10;13H" );
}
///////////////////////////////cc.e////////////////////////////////////////
// Custom includes
#include <boost/bind.hpp>
-#include "TelnetTerminal.hh"
#include "../../Scheduler/Scheduler.hh"
#include "../Logger.hh"
#include "../../Socket/Protocols/INet.hh"
+#include "TelnetTerminal.hh"
+#include "Editor.hh"
//#include "telnetServer.mpp"
#define prefix_
namespace {
- class MyTelnet : public senf::term::TelnetTerminal
+ class MyEditor
+ : public senf::term::BaseEditor
{
public:
- explicit MyTelnet(Handle handle) : senf::term::BaseTelnetProtocol(handle) {}
-
+ MyEditor(senf::term::AbstractTerminal & terminal)
+ : BaseEditor(terminal) {}
+
private:
virtual void v_keyReceived(keycode_t key)
{
SENF_LOG(("Key " << senf::term::KeyParser::describe(key)));
+ if (key >= ' ' && key < 256)
+ insertChar(key);
+ else
+ switch (key) {
+ case '\r':
+ newline();
+ break;
+ case senf::term::KeyParser::Left:
+ {
+ unsigned c (currentColumn());
+ if (c > 0)
+ toColumn(c-1);
+ break;
+ }
+ case senf::term::KeyParser::Backspace:
+ {
+ unsigned c (currentColumn());
+ if (c > 0) {
+ toColumn(c-1);
+ deleteChar();
+ }
+ break;
+ }
+ case senf::term::KeyParser::Delete:
+ deleteChar();
+ break;
+ }
}
+ };
+
+ class MyTelnet
+ : public senf::term::TelnetTerminal
+ {
+ public:
+ explicit MyTelnet(Handle handle)
+ : senf::term::BaseTelnetProtocol(handle),
+ editor_(*this) {}
+
virtual void v_eof()
{
SENF_LOG(("EOF"));
delete this;
}
- virtual void v_setupComplete()
- {
- TelnetTerminal::v_setupComplete();
- SENF_LOG(("Terminal type is '" << terminalType() << "', window size is "
- << width() << "x" << height()));
- }
-
- virtual void v_windowSizeChanged()
- {
- SENF_LOG(("New window size: " << width() << "x" << height()));
- }
+ private:
+ MyEditor editor_;
};
typedef senf::TCPv4ServerSocketHandle ServerHandle;
def SetupForSENF(env):
env.Append( LIBS = [ 'senf', 'readline', 'rt', '$BOOSTREGEXLIB',
- '$BOOSTIOSTREAMSLIB', '$BOOSTSIGNALSLIB' ],
+ '$BOOSTIOSTREAMSLIB', '$BOOSTSIGNALSLIB',
+ '$BOOSTFSLIB' ],
BOOSTREGEXLIB = 'boost_regex',
BOOSTIOSTREAMSLIB = 'boost_iostreams',
BOOSTSIGNALSLIB = 'boost_signals',
+ BOOSTFSLIB = 'boost_filesystem',
CXXFLAGS = [ '-Wno-long-long',
'${"$CXXFLAGS_"+(final and "final" or "debug")}',
'${profile and ("-g","-pg") or None}' ],