New class FTermBuffer to buffer terminal outputs

This commit is contained in:
Markus Gans 2017-07-12 01:16:57 +02:00
parent b36fc80f51
commit a998706e5e
10 changed files with 412 additions and 3 deletions

View File

@ -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

View File

@ -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 \

View File

@ -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

View File

@ -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

View File

@ -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@

141
src/ftermbuffer.cpp Normal file
View File

@ -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
//----------------------------------------------------------------------

112
src/ftermbuffer.h Normal file
View File

@ -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

View File

@ -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)
{

View File

@ -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); }