1
0
mirror of https://github.com/taigrr/arduinolibs synced 2025-01-18 04:33:12 -08:00

Make terminal writes more atomic

This commit is contained in:
Rhys Weatherley 2016-03-09 19:38:00 +10:00
parent 9e6f6cfb2d
commit 6392661663

View File

@ -305,13 +305,22 @@ size_t Terminal::write(const uint8_t *buffer, size_t size)
*/ */
void Terminal::writeProgMem(const char *str) void Terminal::writeProgMem(const char *str)
{ {
uint8_t buffer[16];
uint8_t posn;
uint8_t ch; uint8_t ch;
if (!_stream) if (!_stream || !str)
return; return;
posn = 0;
while ((ch = pgm_read_byte((const uint8_t *)str)) != 0) { while ((ch = pgm_read_byte((const uint8_t *)str)) != 0) {
_stream->write(ch); buffer[posn++] = ch;
if (posn == sizeof(buffer)) {
_stream->write(buffer, posn);
posn = 0;
}
++str; ++str;
} }
if (posn != 0)
_stream->write(buffer, posn);
} }
/** /**
@ -818,6 +827,25 @@ void Terminal::clearToEOL()
writeProgMem(escape); writeProgMem(escape);
} }
// Writes a decimal number to a buffer.
static void writeNumber(uint8_t *buf, uint8_t &posn, int value)
{
int divisor = 10000;
bool haveDigits = false;
while (divisor >= 1) {
int digit = value / divisor;
if (digit || haveDigits) {
buf[posn++] = '0' + digit;
haveDigits = true;
}
value %= divisor;
divisor /= 10;
}
if (!haveDigits) {
buf[posn++] = '0';
}
}
/** /**
* \brief Moves the cursor to a specific location in the window. * \brief Moves the cursor to a specific location in the window.
* *
@ -830,6 +858,8 @@ void Terminal::cursorMove(int x, int y)
{ {
if (!_stream) if (!_stream)
return; return;
// Range check the arguments.
if (x < 0) if (x < 0)
x = 0; x = 0;
else if (x >= ncols) else if (x >= ncols)
@ -838,12 +868,17 @@ void Terminal::cursorMove(int x, int y)
y = 0; y = 0;
else if (y >= nrows) else if (y >= nrows)
y = nrows - 1; y = nrows - 1;
_stream->write((uint8_t)0x1B);
_stream->write((uint8_t)'['); // Format the command "ESC[row;colH" and send it.
_stream->print(y + 1); uint8_t buffer[16];
_stream->write((uint8_t)';'); uint8_t posn = 0;
_stream->print(x + 1); buffer[posn++] = 0x1B;
_stream->write((uint8_t)'H'); buffer[posn++] = '[';
writeNumber(buffer, posn, y + 1);
buffer[posn++] = ';';
writeNumber(buffer, posn, x + 1);
buffer[posn++] = 'H';
_stream->write(buffer, posn);
} }
/** /**
@ -1133,17 +1168,20 @@ void Terminal::color(Color fg)
uint8_t bold = (fg & 0x08) ? 1 : 0; uint8_t bold = (fg & 0x08) ? 1 : 0;
if (!_stream) if (!_stream)
return; return;
_stream->write((uint8_t)0x1B); uint8_t buffer[16];
_stream->write((uint8_t)'['); uint8_t posn = 0;
_stream->write((uint8_t)'0'); // reset all attributes first buffer[posn++] = 0x1B;
_stream->write((uint8_t)';'); buffer[posn++] = '[';
_stream->write((uint8_t)'3'); buffer[posn++] = '0'; // reset all attributes first
_stream->write((uint8_t)('0' + code)); buffer[posn++] = ';';
buffer[posn++] = '3';
buffer[posn++] = '0' + code;
if (bold) { if (bold) {
_stream->write((uint8_t)';'); buffer[posn++] = ';';
_stream->write((uint8_t)'1'); buffer[posn++] = '1';
} }
_stream->write((uint8_t)'m'); buffer[posn++] = 'm';
_stream->write(buffer, posn);
} }
/** /**
@ -1163,20 +1201,23 @@ void Terminal::color(Color fg, Color bg)
uint8_t codebg = (bg & 0x07); uint8_t codebg = (bg & 0x07);
if (!_stream) if (!_stream)
return; return;
_stream->write((uint8_t)0x1B); uint8_t buffer[16];
_stream->write((uint8_t)'['); uint8_t posn = 0;
_stream->write((uint8_t)'0'); // reset all attributes first buffer[posn++] = 0x1B;
_stream->write((uint8_t)';'); buffer[posn++] = '[';
_stream->write((uint8_t)'3'); buffer[posn++] = '0'; // reset all attributes first
_stream->write((uint8_t)('0' + codefg)); buffer[posn++] = ';';
buffer[posn++] = '3';
buffer[posn++] = '0' + codefg;
if (boldfg) { if (boldfg) {
_stream->write((uint8_t)';'); buffer[posn++] = ';';
_stream->write((uint8_t)'1'); buffer[posn++] = '1';
} }
_stream->write((uint8_t)';'); buffer[posn++] = ';';
_stream->write((uint8_t)'4'); buffer[posn++] = '4';
_stream->write((uint8_t)('0' + codebg)); buffer[posn++] = '0' + codebg;
_stream->write((uint8_t)'m'); buffer[posn++] = 'm';
_stream->write(buffer, posn);
} }
/** /**