forked from RealDeuce/EtherTerm
/
screenBuffer.cpp
209 lines (187 loc) · 5.93 KB
/
screenBuffer.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
// EtherTerm SVN: $Id$
// Source: $HeadURL$
// $LastChangedDate$
// $LastChangedRevision$
// $LastChangedBy$
#include "screenBuffer.hpp"
#include "renderer.hpp"
#include <iostream>
ScreenBuffer::ScreenBuffer() :
position(0),
x_position(1),
y_position(1),
characters_per_line(80)
{
//Set the default size of the vector screen buffer
//Then Fill each element with defaults
screenBuffer.reserve(TERM_HEIGHT * TERM_WIDTH);
screenBuffer.resize(TERM_HEIGHT * TERM_WIDTH);
}
ScreenBuffer::~ScreenBuffer()
{
// Clear
std::vector<myScreen>().swap(screenBuffer);
std::cout << "ScreenBuffer Released" << std::endl;
}
// Screen Buffer Vector Constructors
ScreenBuffer::myScreen::myScreen() :
foreground({0, 0, 0, 0}),
background({0, 0, 0, 0})
{ }
ScreenBuffer::myScreen::myScreen(
std::string sequence,
SDL_Color fg, SDL_Color bg) :
characterSequence(sequence),
foreground(fg),
background(bg)
{ }
/**
* handle screen buffer, Keeps track of all data
* Plotted through the ANSI Parser so we can pull
* Text and or redraw screens at anytime.
*/
void ScreenBuffer::setScreenBuffer(unsigned char mySequence)
{
// Keep track of the longest line in buffer for Centering screen.
// NOT IN USE CURRENTLY
//if (x_position > max_x_position)
// max_x_position = x_position;
std::string sequence;
sequence = (signed)mySequence;
sequenceBuffer.characterSequence = sequence;
sequence.erase();
sequenceBuffer.foreground = TheRenderer::Instance()->m_currentFGColor;
sequenceBuffer.background = TheRenderer::Instance()->m_currentBGColor;
// Setup current position in the screen buffer. 1 based for 0 based.
position = ((y_position-1) * characters_per_line) + (x_position-1);
// Add Sequence to Screen Buffer
try
{
if((unsigned)position < screenBuffer.size())
screenBuffer.at(position) = sequenceBuffer;
else
{
std::cout << "Xposition: " << x_position-1 << std::endl;
}
}
catch(std::exception &e)
{
std::cout << "Exception setScreenBuffer: " << e.what() << std::endl;
std::cout << "Server sent data that exceeds screen dimensions." << std::endl;
}
// Clear for next sequences.
sequenceBuffer.characterSequence.erase();
}
/*
* Moves the Screen Buffer Up a line to match the internal SDL_Surface
*/
void ScreenBuffer::scrollScreenBuffer()
{
//*** IMPORTANT (WIP), must add check for region scrolling only!
//TheTerminal::Instance()->scrollRegionActive &&
// y_position > TheTerminal::Instance()->bottomMargin))
// Theory, Erase Line at Top margin, then add a new line bottom margin
// To move it back down. That way only the middle is scrolled up.
// This remove the top line to scroll the screen up
// And follow the SDL Surface! later on add history for scroll back.
try
{
screenBuffer.erase(
screenBuffer.begin(), screenBuffer.begin() + characters_per_line);
}
catch(std::exception &e)
{
std::cout << "Exception scrollScreenBuffer: " << e.what() << std::endl;
}
// Readd The last Line back to the buffer.
screenBuffer.resize(TERM_HEIGHT * TERM_WIDTH);
}
/*
* Clear Range of Screen Buffer for Erase Sequences.
*/
void ScreenBuffer::clearScreenBufferRange(int start, int end)
{
int startPosition = ((y_position-1) * characters_per_line) + (start);
int endPosition = startPosition + (end - start);
//std::cout << "start " << start << " end " << end
// << std::endl;
//std::cout << "startPosition " << startPosition << " endPosition " << endPosition
// << std::endl;
// Clear out entire line.
for(int i = startPosition; i < endPosition; i++)
{
try
{
screenBuffer[i].characterSequence.erase();
}
catch(std::exception &e)
{
std::cout << "Exception clearScreenBufferRange: "
<< e.what() << std::endl;
}
}
// Debugging
//getScreenBufferText();
}
/*
* When the Screen/Surface is cleared, we also clear the buffer
*/
void ScreenBuffer::clearScreenBuffer()
{
// Allocate the Size
screenBuffer.clear();
screenBuffer.resize(TERM_HEIGHT * TERM_WIDTH);
}
// Debug to console.
void ScreenBuffer::getScreenBufferText()
{
//std::cout << "* getScreenBufferText" << std::endl; // Start Fresh line.
for(auto &it : screenBuffer)
{
if(it.characterSequence != "")
std::cout << it.characterSequence << std::flush;
else
std::cout << " " << std::flush;
}
}
/*
* Gets Coordinates from the screen already translated to
* Screen Buffer Positions, Now we pull the position and throw the
* Text data into the Clipboard.
*/
void ScreenBuffer::bufferToClipboard(int startx, int starty, int numChar, int numRows)
{
std::string textBuffer = "";
int startPosition = (starty * characters_per_line) + startx;
int endPosition = startPosition + numChar;
// Loop the Number of Rows to Grab
for(int ot = 0; ot < numRows; ot++)
{
// Grab each line per Row.
for(int it = startPosition; it < endPosition; it++)
{
try
{
if(screenBuffer[it].characterSequence != "")
{
textBuffer += screenBuffer[it].characterSequence;
}
else
{
textBuffer += " ";
}
}
catch(std::exception &e)
{
std::cout << "Exception bufferToClipboard: " << e.what() << std::endl;
}
}
// Add Newline at the end of each row.
textBuffer += "\r\n";
// Reset start/end position to next Row.
startPosition += characters_per_line;
endPosition += characters_per_line;
}
// Copy Resulting text to the Clipboard.
SDL_SetClipboardText(textBuffer.c_str());
}