New class FTermBuffer to buffer terminal outputs
This commit is contained in:
parent
b36fc80f51
commit
a998706e5e
|
@ -1,3 +1,7 @@
|
|||
2017-07-11 Markus Gans <guru.mail@muenster.de>
|
||||
* New class FTermBuffer to buffer terminal outputs
|
||||
* Add the possibility to print from the terminal buffer
|
||||
|
||||
2017-07-03 Markus Gans <guru.mail@muenster.de>
|
||||
* Use more static const variables where it makes sense
|
||||
|
||||
|
|
|
@ -43,6 +43,7 @@ libfinal_la_SOURCES = \
|
|||
fevent.cpp \
|
||||
foptiattr.cpp \
|
||||
foptimove.cpp \
|
||||
ftermbuffer.cpp \
|
||||
fapp.cpp \
|
||||
fwidget.cpp \
|
||||
fobject.cpp
|
||||
|
@ -81,6 +82,7 @@ finalcutinclude_HEADERS = \
|
|||
fpoint.h \
|
||||
foptiattr.h \
|
||||
foptimove.h \
|
||||
ftermbuffer.h \
|
||||
fprogressbar.h \
|
||||
fradiobutton.h \
|
||||
frect.h \
|
||||
|
|
|
@ -30,6 +30,7 @@ INCLUDE_HEADERS = \
|
|||
fobject.h \
|
||||
foptiattr.h \
|
||||
foptimove.h \
|
||||
ftermbuffer.h \
|
||||
fpoint.h \
|
||||
fprogressbar.h \
|
||||
fradiobutton.h \
|
||||
|
@ -91,6 +92,7 @@ OBJS = \
|
|||
fevent.o \
|
||||
foptiattr.o \
|
||||
foptimove.o \
|
||||
ftermbuffer.o \
|
||||
fapp.o \
|
||||
fwidget.o \
|
||||
fobject.o
|
||||
|
|
|
@ -30,6 +30,7 @@ INCLUDE_HEADERS = \
|
|||
fobject.h \
|
||||
foptiattr.h \
|
||||
foptimove.h \
|
||||
ftermbuffer.h \
|
||||
fpoint.h \
|
||||
fprogressbar.h \
|
||||
fradiobutton.h \
|
||||
|
@ -91,6 +92,7 @@ OBJS = \
|
|||
fevent.o \
|
||||
foptiattr.o \
|
||||
foptimove.o \
|
||||
ftermbuffer.o \
|
||||
fapp.o \
|
||||
fwidget.o \
|
||||
fobject.o
|
||||
|
|
|
@ -135,8 +135,8 @@ am_libfinal_la_OBJECTS = fstring.lo fpoint.lo frect.lo fscrollbar.lo \
|
|||
fmenuitem.lo fradiomenuitem.lo fcheckmenuitem.lo fmenulist.lo \
|
||||
fdialog.lo fscrollview.lo fwindow.lo fmessagebox.lo \
|
||||
ftooltip.lo ffiledialog.lo ftextview.lo fstatusbar.lo fterm.lo \
|
||||
fvterm.lo fevent.lo foptiattr.lo foptimove.lo fapp.lo \
|
||||
fwidget.lo fobject.lo
|
||||
fvterm.lo fevent.lo foptiattr.lo foptimove.lo ftermbuffer.lo \
|
||||
fapp.lo fwidget.lo fobject.lo
|
||||
libfinal_la_OBJECTS = $(am_libfinal_la_OBJECTS)
|
||||
AM_V_lt = $(am__v_lt_@AM_V@)
|
||||
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
|
||||
|
@ -409,6 +409,7 @@ libfinal_la_SOURCES = \
|
|||
fevent.cpp \
|
||||
foptiattr.cpp \
|
||||
foptimove.cpp \
|
||||
ftermbuffer.cpp \
|
||||
fapp.cpp \
|
||||
fwidget.cpp \
|
||||
fobject.cpp
|
||||
|
@ -445,6 +446,7 @@ finalcutinclude_HEADERS = \
|
|||
fpoint.h \
|
||||
foptiattr.h \
|
||||
foptimove.h \
|
||||
ftermbuffer.h \
|
||||
fprogressbar.h \
|
||||
fradiobutton.h \
|
||||
frect.h \
|
||||
|
@ -571,6 +573,7 @@ distclean-compile:
|
|||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fstring.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fswitch.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fterm.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ftermbuffer.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ftextview.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ftogglebutton.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ftooltip.Plo@am__quote@
|
||||
|
|
|
@ -0,0 +1,141 @@
|
|||
// File: ftermbuffer.cpp
|
||||
// Provides: class FTermBuffer
|
||||
|
||||
#include "ftermbuffer.h"
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// class FTermBuffer
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
// constructors and destructor
|
||||
//----------------------------------------------------------------------
|
||||
FTermBuffer::FTermBuffer()
|
||||
: data()
|
||||
{ }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
FTermBuffer::~FTermBuffer() // destructor
|
||||
{ }
|
||||
|
||||
|
||||
// public methods of FTermBuffer
|
||||
//----------------------------------------------------------------------
|
||||
int FTermBuffer::writef (const wchar_t* format, ...)
|
||||
{
|
||||
assert ( format != 0 );
|
||||
static const int buf_size = 1024;
|
||||
wchar_t buffer[buf_size];
|
||||
va_list args;
|
||||
|
||||
va_start (args, format);
|
||||
std::vswprintf (buffer, buf_size, format, args);
|
||||
va_end (args);
|
||||
|
||||
FString str(buffer);
|
||||
return write(str);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
int FTermBuffer::writef (const char* format, ...)
|
||||
{
|
||||
assert ( format != 0 );
|
||||
int len;
|
||||
char buf[512];
|
||||
char* buffer;
|
||||
va_list args;
|
||||
|
||||
buffer = buf;
|
||||
va_start (args, format);
|
||||
len = vsnprintf (buffer, sizeof(buf), format, args);
|
||||
va_end (args);
|
||||
|
||||
if ( len >= int(sizeof(buf)) )
|
||||
{
|
||||
buffer = new char[len+1]();
|
||||
va_start (args, format);
|
||||
vsnprintf (buffer, uLong(len+1), format, args);
|
||||
va_end (args);
|
||||
}
|
||||
|
||||
FString str(buffer);
|
||||
int ret = write(str);
|
||||
|
||||
if ( buffer != buf )
|
||||
delete[] buffer;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
int FTermBuffer::write (const std::wstring& s)
|
||||
{
|
||||
assert ( ! s.empty() );
|
||||
return write (FString(s));
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
int FTermBuffer::write (const wchar_t* s)
|
||||
{
|
||||
assert ( s != 0 );
|
||||
return write (FString(s));
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
int FTermBuffer::write (const char* s)
|
||||
{
|
||||
assert ( s != 0 );
|
||||
FString str(s);
|
||||
return write(str);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
int FTermBuffer::write (const std::string& s)
|
||||
{
|
||||
assert ( ! s.empty() );
|
||||
return write (FString(s));
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
int FTermBuffer::write (const FString& s)
|
||||
{
|
||||
assert ( ! s.isNull() );
|
||||
register int len = 0;
|
||||
const wchar_t* p = s.wc_str();
|
||||
|
||||
if ( p )
|
||||
{
|
||||
while ( *p )
|
||||
{
|
||||
char_data nc; // next character
|
||||
nc = FVTerm::getAttribute();
|
||||
nc.code = *p;
|
||||
nc.no_changes = false;
|
||||
nc.printed = false;
|
||||
|
||||
data.push_back(nc);
|
||||
|
||||
p++;
|
||||
len++;
|
||||
} // end of while
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
int FTermBuffer::write (register int c)
|
||||
{
|
||||
char_data nc; // next character
|
||||
nc = FVTerm::getAttribute();
|
||||
nc.code = c;
|
||||
nc.no_changes = false;
|
||||
nc.printed = false;
|
||||
|
||||
data.push_back(nc);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
// private methods of FTermBuffer
|
||||
//----------------------------------------------------------------------
|
|
@ -0,0 +1,112 @@
|
|||
// File: ftermbuffer.h
|
||||
// Provides: class FTermBuffer
|
||||
//
|
||||
// Standalone class
|
||||
// ════════════════
|
||||
//
|
||||
// ▕▔▔▔▔▔▔▔▔▔▔▔▔▔▏
|
||||
// ▕ FTermBuffer ▏
|
||||
// ▕▁▁▁▁▁▁▁▁▁▁▁▁▁▏
|
||||
|
||||
|
||||
#ifndef FTERMBUFFER_H
|
||||
#define FTERMBUFFER_H
|
||||
|
||||
#include <vector>
|
||||
#include <sstream> // std::stringstream
|
||||
|
||||
#include "fvterm.h"
|
||||
#include "fstring.h"
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// class FTermBuffer
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
#pragma pack(push)
|
||||
#pragma pack(1)
|
||||
|
||||
class FTermBuffer
|
||||
{
|
||||
public:
|
||||
// Typedef
|
||||
typedef FOptiAttr::char_data char_data;
|
||||
|
||||
// Constructor
|
||||
explicit FTermBuffer();
|
||||
|
||||
// Destructor
|
||||
virtual ~FTermBuffer();
|
||||
|
||||
// Overloaded operators
|
||||
template<class type> FTermBuffer& operator << (const type&);
|
||||
|
||||
// Accessors
|
||||
virtual const char* getClassName() const;
|
||||
int getLength() const;
|
||||
|
||||
// Inquiry
|
||||
bool isEmpty () const;
|
||||
|
||||
// Methods
|
||||
void clear();
|
||||
int writef (const wchar_t*, ...);
|
||||
int writef (const char*, ...)
|
||||
#if defined(__clang__)
|
||||
__attribute__((__format__ (__printf__, 2, 3)))
|
||||
#elif defined(__GNUC__)
|
||||
__attribute__ ((format (printf, 2, 3)))
|
||||
#endif
|
||||
;
|
||||
int write (const std::wstring&);
|
||||
int write (const wchar_t*);
|
||||
int write (const char*);
|
||||
int write (const std::string&);
|
||||
int write (const FString&);
|
||||
int write (int);
|
||||
FTermBuffer& write ();
|
||||
std::vector<char_data> getBuffer();
|
||||
|
||||
private:
|
||||
std::vector<char_data> data;
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
|
||||
// FTermBuffer inline functions
|
||||
//----------------------------------------------------------------------
|
||||
template<class type>
|
||||
inline FTermBuffer& FTermBuffer::operator << (const type& s)
|
||||
{
|
||||
std::ostringstream outstream;
|
||||
outstream << s;
|
||||
write (outstream.str());
|
||||
return *this;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline const char* FTermBuffer::getClassName() const
|
||||
{ return "FTermBuffer"; }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline int FTermBuffer::getLength() const
|
||||
{ return int(data.size()); }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline bool FTermBuffer::isEmpty() const
|
||||
{ return data.empty(); }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline void FTermBuffer::clear()
|
||||
{ data.clear(); }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline FTermBuffer& FTermBuffer::write()
|
||||
{ return *this; }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline std::vector<FTermBuffer::char_data> FTermBuffer::getBuffer()
|
||||
{ return data; }
|
||||
|
||||
#endif // FTERMBUFFER_H
|
136
src/fvterm.cpp
136
src/fvterm.cpp
|
@ -552,6 +552,142 @@ int FVTerm::print (term_area* area, const FString& s)
|
|||
return len;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
int FVTerm::print (const std::vector<char_data>& termString)
|
||||
{
|
||||
if ( termString.empty() )
|
||||
return 0;
|
||||
|
||||
term_area* area = getPrintArea();
|
||||
|
||||
if ( ! area )
|
||||
{
|
||||
if ( vdesktop )
|
||||
area = vdesktop;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
return print (area, termString);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
int FVTerm::print (term_area* area, const std::vector<char_data>& termString)
|
||||
{
|
||||
register int len = 0;
|
||||
std::vector<char_data>::const_iterator iter;
|
||||
iter = termString.begin();
|
||||
uInt tabstop = uInt(getTabstop());
|
||||
|
||||
if ( ! area )
|
||||
return -1;
|
||||
|
||||
if ( termString.empty() )
|
||||
return 0;
|
||||
else
|
||||
area->has_changes = true;
|
||||
|
||||
while ( iter != termString.end() )
|
||||
{
|
||||
int width, height, rsh, bsh;
|
||||
width = area->width;
|
||||
height = area->height;
|
||||
rsh = area->right_shadow;
|
||||
bsh = area->bottom_shadow;
|
||||
|
||||
switch ( (*iter).code )
|
||||
{
|
||||
case '\n':
|
||||
area->cursor_y++;
|
||||
|
||||
case '\r':
|
||||
area->cursor_x = 1;
|
||||
break;
|
||||
|
||||
case '\t':
|
||||
area->cursor_x = short ( uInt(area->cursor_x)
|
||||
+ tabstop
|
||||
- uInt(area->cursor_x)
|
||||
+ 1
|
||||
% tabstop );
|
||||
break;
|
||||
|
||||
case '\b':
|
||||
area->cursor_x--;
|
||||
break;
|
||||
|
||||
case '\a':
|
||||
beep();
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
int ax = area->cursor_x - 1;
|
||||
int ay = area->cursor_y - 1;
|
||||
|
||||
char_data nc = *iter; // next character
|
||||
|
||||
if ( area
|
||||
&& area->cursor_x > 0
|
||||
&& area->cursor_y > 0
|
||||
&& ax < area->width + area->right_shadow
|
||||
&& ay < area->height + area->bottom_shadow )
|
||||
{
|
||||
char_data* ac; // area character
|
||||
int line_len = area->width + area->right_shadow;
|
||||
ac = &area->text[ay * line_len + ax];
|
||||
|
||||
if ( *ac != nc ) // compare with an overloaded operator
|
||||
{
|
||||
if ( ( ! ac->transparent && nc.transparent )
|
||||
|| ( ! ac->trans_shadow && nc.trans_shadow )
|
||||
|| ( ! ac->inherit_bg && nc.inherit_bg ) )
|
||||
{
|
||||
// add one transparent character form line
|
||||
area->changes[ay].trans_count++;
|
||||
}
|
||||
else if ( ( ac->transparent && ! nc.transparent )
|
||||
|| ( ac->trans_shadow && ! nc.trans_shadow )
|
||||
|| ( ac->inherit_bg && ! nc.inherit_bg ) )
|
||||
{
|
||||
// remove one transparent character from line
|
||||
area->changes[ay].trans_count--;
|
||||
}
|
||||
|
||||
// copy character to area
|
||||
std::memcpy (ac, &nc, sizeof(nc));
|
||||
|
||||
if ( ax < short(area->changes[ay].xmin) )
|
||||
area->changes[ay].xmin = uInt(ax);
|
||||
|
||||
if ( ax > short(area->changes[ay].xmax) )
|
||||
area->changes[ay].xmax = uInt(ax);
|
||||
}
|
||||
}
|
||||
|
||||
area->cursor_x++;
|
||||
}
|
||||
}
|
||||
|
||||
if ( area->cursor_x > width + rsh )
|
||||
{
|
||||
area->cursor_x = 1;
|
||||
area->cursor_y++;
|
||||
}
|
||||
|
||||
if ( area->cursor_y > height + bsh )
|
||||
{
|
||||
area->cursor_y--;
|
||||
break;
|
||||
}
|
||||
|
||||
len++;
|
||||
++iter;
|
||||
} // end of while
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
int FVTerm::print (register int c)
|
||||
{
|
||||
|
|
|
@ -140,6 +140,7 @@ class FVTerm : public FObject, public FTerm
|
|||
static short getTermBackgroundColor();
|
||||
term_area* getVWin() const;
|
||||
FPoint getPrintCursor();
|
||||
static char_data getAttribute();
|
||||
|
||||
// Mutators
|
||||
static void setTermXY (register int, register int);
|
||||
|
@ -265,6 +266,8 @@ class FVTerm : public FObject, public FTerm
|
|||
int print (term_area*, const std::string&);
|
||||
int print (const FString&);
|
||||
int print (term_area*, const FString&);
|
||||
int print (const std::vector<char_data>&);
|
||||
int print (term_area*, const std::vector<char_data>&);
|
||||
int print (int);
|
||||
int print (term_area*, int);
|
||||
FVTerm& print();
|
||||
|
@ -443,6 +446,10 @@ inline short FVTerm::getTermBackgroundColor()
|
|||
inline FVTerm::term_area* FVTerm::getVWin() const
|
||||
{ return vwin; }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline FVTerm::char_data FVTerm::getAttribute()
|
||||
{ return next_attribute; }
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
inline bool FVTerm::hideCursor()
|
||||
{ return hideCursor(true); }
|
||||
|
|
Loading…
Reference in New Issue