21 #include "modules/system/vfs/File.h" 22 #include "pedigree/kernel/LockGuard.h" 23 #include "pedigree/kernel/Log.h" 24 #include "pedigree/kernel/machine/InputManager.h" 25 #include "pedigree/kernel/machine/Machine.h" 26 #include "pedigree/kernel/machine/Vga.h" 27 #include "pedigree/kernel/process/Mutex.h" 28 #include "pedigree/kernel/process/Thread.h" 29 #include "pedigree/kernel/processor/MemoryRegion.h" 30 #include "pedigree/kernel/processor/PhysicalMemoryManager.h" 31 #include "pedigree/kernel/processor/Processor.h" 32 #include "pedigree/kernel/processor/ProcessorInformation.h" 33 #include "pedigree/kernel/processor/VirtualAddressSpace.h" 34 #include "pedigree/kernel/processor/types.h" 35 #include "pedigree/kernel/time/Time.h" 36 #include "pedigree/kernel/utilities/Buffer.h" 37 #include "pedigree/kernel/utilities/StaticString.h" 38 #include "pedigree/kernel/utilities/String.h" 39 #include "pedigree/kernel/utilities/utility.h" 45 #define ALT_KEY (1ULL << 60) 46 #define SHIFT_KEY (1ULL << 61) 47 #define CTRL_KEY (1ULL << 62) 48 #define SPECIAL_KEY (1ULL << 63) 50 static int startFlipThread(
void *param);
53 :
File(str, 0, 0, 0, inode, pParentFS, 0, pParent), m_bInitialised(false),
54 m_bControlSeq(false), m_bBracket(false), m_bParenthesis(false),
55 m_bParams(false), m_bQuestionMark(false), m_CursorX(0), m_CursorY(0),
56 m_SavedCursorX(0), m_SavedCursorY(0), m_ScrollStart(0), m_ScrollEnd(0),
57 m_LeftMargin(0), m_RightMargin(0), m_CurrentParam(0), m_Params(),
59 m_Backbuffer(
"TextIO Backbuffer"), m_pFramebuffer(0), m_pBackbuffer(0),
60 m_pVga(0), m_TabStops(), m_OutBuffer(TEXTIO_BUFFER_SIZE), m_G0(
'B'),
61 m_G1(
'B'), m_bUtf8(false), m_nCharacter(0), m_nUtf8Handled(0),
62 m_bActive(false),
m_Lock(false), m_bOwnsConsole(false),
63 m_InputMode(
TextIO::Standard)
65 size_t backbufferSize =
66 BACKBUFFER_STRIDE * BACKBUFFER_ROWS *
sizeof(VgaCell);
67 size_t backbufferPages =
72 m_Backbuffer, backbufferPages, 0,
75 ERROR(
"TextIO: failed to allocate backbuffer!");
80 reinterpret_cast<VgaCell *
>(m_Backbuffer.virtualAddress());
86 setPermissionsOnly(FILE_GR | FILE_GW | FILE_UR | FILE_UW);
93 InputManager::MachineKey, inputCallback,
this);
109 m_bInitialised =
false;
111 m_bControlSeq =
false;
114 m_bQuestionMark =
false;
117 m_CursorX = m_CursorY = 0;
118 m_ScrollStart = m_ScrollEnd = 0;
119 m_LeftMargin = m_RightMargin = 0;
120 m_SavedCursorX = m_SavedCursorY = 0;
122 ByteSet(m_Params, 0,
sizeof(
size_t) * MAX_TEXTIO_PARAMS);
123 ByteSet(m_TabStops, 0, BACKBUFFER_STRIDE);
124 m_InputMode = Standard;
126 m_pVga = Machine::instance().
getVga(0);
130 m_pFramebuffer = *m_pVga;
131 if (m_pFramebuffer != 0)
139 m_pVga->getNumRows() * m_pVga->getNumCols() *
146 m_bInitialised =
true;
148 m_ScrollEnd = m_pVga->getNumRows() - 1;
150 m_RightMargin = m_pVga->getNumCols();
152 m_CurrentModes = AnsiVt52 | CharacterSetG0;
155 for (
size_t i = 0; i < BACKBUFFER_STRIDE; i += 8)
158 m_pVga->clearControl(Vga::Blink);
162 m_NextInterval = BLINK_OFF_PERIOD;
170 m_pFlipThread =
new Thread(parent, startFlipThread,
this);
171 m_pFlipThread->detach();
174 return m_bInitialised;
181 FATAL(
"TextIO misused: successfully call initialise() first.");
186 ERROR(
"TextIO: null string passed in.");
192 const char *orig = s;
193 while ((*s) && (len--))
196 uint8_t byte = *
reinterpret_cast<const uint8_t *
>(s);
199 if (m_nUtf8Handled >= 6)
202 m_nCharacter |= (byte & 0x3F) << m_nUtf8Handled;
211 if ((m_nUtf8Handled == 0) || ((byte & 0xC0) != 0x80))
213 if (m_nUtf8Handled > 0)
214 ERROR(
"TextIO: expected a continuation byte, but didn't " 224 if (((byte & 0xC0) != 0x80) && (s != orig))
231 if (m_nCharacter > 0x10FFFF)
233 ERROR(
"TextIO: invalid UTF8 sequence encountered.");
237 else if (m_nUtf8Handled < 6)
240 "TextIO: too many continuation bytes for a UTF8 sequence!");
246 else if ((byte & 0xC0) == 0xC0)
250 uint8_t thisByte = *
reinterpret_cast<const uint8_t *
>(s);
251 if ((thisByte & 0xF8) == 0xF0)
254 m_nCharacter = (thisByte & 0x7) << 18;
257 else if ((thisByte & 0xF0) == 0xE0)
260 m_nCharacter = (thisByte & 0xF) << 12;
263 else if ((thisByte & 0xE0) == 0xC0)
266 m_nCharacter = (thisByte & 0x1F) << 6;
271 ERROR(
"TextIO: invalid UTF8 leading byte (possible 5- or " 272 "6-byte sequence?)");
279 else if ((byte & 0x80) == 0x80)
282 "TextIO: invalid ASCII character " 283 << byte <<
" (not a UTF8 leading byte)");
290 if (m_bControlSeq && m_bBracket)
292 switch (m_nCharacter)
307 if (m_CurrentModes & LineFeedNewLine)
317 m_bQuestionMark =
true;
330 m_Params[m_CurrentParam] =
331 (m_Params[m_CurrentParam] * 10) + (m_nCharacter -
'0');
337 if (m_CurrentParam >= MAX_TEXTIO_PARAMS)
338 FATAL(
"TextIO: too many parameters!");
345 if (m_bParams && m_Params[0])
346 m_CursorY -= m_Params[0];
351 if (m_CursorY < m_ScrollStart)
352 m_CursorY = m_ScrollStart;
354 m_bControlSeq =
false;
359 if (m_bParams && m_Params[0])
360 m_CursorY += m_Params[0];
364 if (m_CursorY > m_ScrollEnd)
365 m_CursorY = m_ScrollEnd;
367 m_bControlSeq =
false;
372 if (m_bParams && m_Params[0])
373 m_CursorX += m_Params[0];
377 if (m_CursorX >= m_RightMargin)
378 m_CursorX = m_RightMargin - 1;
380 m_bControlSeq =
false;
387 if (m_bParams && m_Params[0])
388 m_CursorX -= m_Params[0];
393 if (m_CursorX < m_LeftMargin)
394 m_CursorX = m_LeftMargin;
396 m_bControlSeq =
false;
404 size_t xmove = m_Params[1] ? m_Params[1] - 1 : 0;
405 size_t ymove = m_Params[0] ? m_Params[0] - 1 : 0;
408 goHome(xmove, ymove);
416 m_bControlSeq =
false;
420 if ((!m_bParams) || (!m_Params[0]))
424 else if (m_Params[0] == 1)
428 else if (m_Params[0] == 2)
434 m_bControlSeq =
false;
438 if ((!m_bParams) || (!m_Params[0]))
442 else if (m_Params[0] == 1)
447 else if (m_Params[0] == 2)
452 m_bControlSeq =
false;
458 ERROR(
"TextIO: Device Attributes command with non-zero " 465 const char *attribs =
"\033[?1;2c";
467 const_cast<char *>(attribs), StringLength(attribs));
469 m_bControlSeq =
false;
475 if (m_Params[0] == 3)
477 ByteSet(m_TabStops, 0, BACKBUFFER_STRIDE);
482 m_TabStops[m_CursorX] = 0;
484 m_bControlSeq =
false;
490 int modesToChange = 0;
492 if (m_bQuestionMark & m_bParams)
494 for (
size_t i = 0; i <= m_CurrentParam; ++i)
499 modesToChange |= CursorKey;
502 modesToChange |= AnsiVt52;
508 modesToChange |= Scrolling;
511 modesToChange |= Screen;
514 modesToChange |= Origin;
517 modesToChange |= AutoWrap;
520 modesToChange |= AutoRepeat;
523 modesToChange |= Interlace;
527 "TextIO: unknown 'DEC Private Mode " 529 << m_Params[i] <<
"'");
536 for (
size_t i = 0; i <= m_CurrentParam; ++i)
541 modesToChange |= LineFeedNewLine;
545 "TextIO: unknown 'Set Mode' mode '" 546 << m_Params[i] <<
"'");
552 if (m_nCharacter ==
'h')
555 m_CurrentModes |= modesToChange;
558 if (modesToChange & Origin)
561 m_CursorX = m_LeftMargin;
562 m_CursorY = m_ScrollStart;
564 else if (modesToChange &
Column)
566 m_RightMargin = BACKBUFFER_COLS_WIDE;
574 m_ScrollEnd = BACKBUFFER_ROWS - 1;
584 m_CurrentModes &= ~(modesToChange);
587 if (modesToChange & Origin)
593 else if (modesToChange &
Column)
595 m_RightMargin = BACKBUFFER_COLS_NORMAL;
603 m_ScrollEnd = BACKBUFFER_ROWS - 1;
611 m_bControlSeq =
false;
616 for (
size_t i = 0; i <= m_CurrentParam; ++i)
624 m_CurrentModes &= ~(Inverse | Bright | Blink);
628 if (!(m_CurrentModes & Bright))
630 m_CurrentModes |= Bright;
635 if (m_CurrentModes & Bright)
637 m_CurrentModes &= ~Bright;
643 if (!(m_CurrentModes & Blink))
645 m_CurrentModes |= Blink;
650 if (!(m_CurrentModes & Inverse))
652 m_CurrentModes |= Inverse;
665 &m_Fore, m_Params[i] - 30,
666 m_CurrentModes & Bright);
669 if (m_Params[i + 1] == 5)
672 &m_Fore, m_Params[i + 2],
673 m_CurrentModes & Bright);
678 setColour(&m_Back, 7, m_CurrentModes & Bright);
689 setColour(&m_Back, m_Params[i] - 40);
692 if (m_Params[i + 1] == 5)
694 setColour(&m_Back, m_Params[i + 2]);
699 setColour(&m_Back, 0);
710 setColour(&m_Fore, m_Params[i] - 90,
true);
721 setColour(&m_Back, m_Params[i] - 100,
true);
726 "TextIO: unhandled 'Set Attribute Mode' " 728 <<
Dec << m_Params[i] <<
Hex <<
".");
732 m_bControlSeq =
false;
741 const char *status =
"\033[0n";
743 const_cast<char *>(status),
744 StringLength(status));
753 ssize_t reportX = m_CursorX + 1;
754 ssize_t reportY = m_CursorY + 1;
756 if (m_CurrentModes & Origin)
761 if ((reportX > m_LeftMargin) &&
762 (reportX <= m_RightMargin))
763 reportX -= m_LeftMargin;
764 if ((reportY > m_ScrollStart) &&
765 (reportY <= m_ScrollEnd))
766 reportY -= m_ScrollStart;
769 response.append(reportY);
770 response.append(
";");
771 response.append(reportX);
772 response.append(
"R");
775 static_cast<const char *>(response)),
781 "TextIO: unknown device status request " 782 <<
Dec << m_Params[0] <<
Hex <<
".");
785 m_bControlSeq =
false;
794 WARNING(
"TextIO: dropping command after seeing 'p' command " 795 "sequence terminator.");
796 m_bControlSeq =
false;
802 m_bControlSeq =
false;
808 m_ScrollStart = m_Params[0] - 1;
809 m_ScrollEnd = m_Params[1] - 1;
811 if (m_ScrollStart >= BACKBUFFER_ROWS)
812 m_ScrollStart = BACKBUFFER_ROWS - 1;
813 if (m_ScrollEnd >= BACKBUFFER_ROWS)
814 m_ScrollEnd = BACKBUFFER_ROWS - 1;
819 m_ScrollEnd = BACKBUFFER_ROWS - 1;
822 if (m_ScrollStart > m_ScrollEnd)
824 size_t tmp = m_ScrollStart;
825 m_ScrollStart = m_ScrollEnd;
831 m_bControlSeq =
false;
835 m_SavedCursorX = m_CursorX;
836 m_SavedCursorY = m_CursorY;
837 m_bControlSeq =
false;
841 m_CursorX = m_SavedCursorX;
842 m_CursorY = m_SavedCursorY;
843 m_bControlSeq =
false;
850 ERROR(
"TextIO: invalid 'sol' parameter for 'Request " 851 "Terminal Parameters'");
864 const char *termparms = 0;
866 termparms =
"\033[3;1;1;120;120;1;0x";
868 termparms =
"\033[2;1;1;120;120;1;0x";
870 const_cast<char *>(termparms),
871 StringLength(termparms));
873 m_bControlSeq =
false;
878 m_bControlSeq =
false;
883 "TextIO: unknown control sequence character '" 884 << m_nCharacter <<
"'!");
885 m_bControlSeq =
false;
889 else if (m_bControlSeq && (!m_bBracket) && (!m_bParenthesis))
891 switch (m_nCharacter)
898 if (m_CursorY > m_ScrollStart)
900 m_bControlSeq =
false;
904 if (m_CursorY < m_ScrollEnd)
906 m_bControlSeq =
false;
911 if (m_CursorX >= m_RightMargin)
912 m_CursorX = m_RightMargin - 1;
913 m_bControlSeq =
false;
917 if (m_CurrentModes & AnsiVt52)
925 if (m_CursorX > m_LeftMargin)
928 m_bControlSeq =
false;
935 m_bControlSeq =
false;
940 ERROR(
"TextIO: graphics mode is not implemented.");
941 m_bControlSeq =
false;
945 if (m_CurrentModes & AnsiVt52)
948 m_TabStops[m_CursorX] =
'|';
956 m_bControlSeq =
false;
965 m_bControlSeq =
false;
970 m_bControlSeq =
false;
975 m_bControlSeq =
false;
980 uint8_t row = (*(++s)) - 0x20;
981 uint8_t col = (*(++s)) - 0x20;
987 m_bControlSeq =
false;
992 const char *identifier = 0;
993 if (m_CurrentModes & AnsiVt52)
994 identifier =
"\033[?1;2c";
996 identifier =
"\033/Z";
998 const_cast<char *>(identifier),
999 StringLength(identifier));
1001 m_bControlSeq =
false;
1008 switch (m_nCharacter)
1018 "TextIO: unknown DEC command '" << m_nCharacter
1022 m_bControlSeq =
false;
1027 ERROR(
"TextIO: alternate keypad mode is not implemented.");
1028 m_bControlSeq =
false;
1032 m_CurrentModes |= AnsiVt52;
1033 m_bControlSeq =
false;
1038 ERROR(
"TextIO: alternate keypad mode is not implemented.");
1039 m_bControlSeq =
false;
1054 char curr = m_nCharacter;
1062 if ((next >=
'0' && next <=
'2') ||
1063 (next >=
'A' && next <=
'B'))
1069 else if (curr ==
')')
1072 WARNING(
"TextIO: only 'ESC(C' and 'ESC)C' are " 1073 "supported on a VT100.");
1075 m_bControlSeq =
false;
1080 m_SavedCursorX = m_CursorX;
1081 m_SavedCursorY = m_CursorY;
1082 m_bControlSeq =
false;
1086 m_CursorX = m_SavedCursorX;
1087 m_CursorY = m_SavedCursorY;
1088 m_bControlSeq =
false;
1094 m_bControlSeq =
false;
1099 "TextIO: unknown escape sequence character '" 1100 << m_nCharacter <<
"'!");
1101 m_bControlSeq =
false;
1107 if (m_nCharacter ==
'\033')
1109 m_bControlSeq =
true;
1112 m_bParenthesis =
false;
1113 m_bQuestionMark =
true;
1115 ByteSet(m_Params, 0,
sizeof(
size_t) * MAX_TEXTIO_PARAMS);
1119 switch (m_nCharacter)
1124 const char *answerback =
"\033[1;2c";
1126 const_cast<char *>(answerback),
1127 StringLength(answerback));
1142 if (m_CurrentModes & LineFeedNewLine)
1148 m_CurrentModes &= ~CharacterSetG0;
1149 m_CurrentModes |= CharacterSetG1;
1153 m_CurrentModes &= ~CharacterSetG1;
1154 m_CurrentModes |= CharacterSetG0;
1158 uint8_t c = translate(m_nCharacter);
1160 uint8_t characterSet = m_G0;
1161 if (m_CurrentModes & CharacterSetG1)
1162 characterSet = m_G1;
1164 if (characterSet >=
'0' && characterSet <=
'2')
1244 if (m_CursorX < BACKBUFFER_STRIDE)
1249 [(m_CursorY * BACKBUFFER_STRIDE) +
1251 pCell->character = c;
1252 pCell->fore = m_Fore;
1253 pCell->back = m_Back;
1254 pCell->flags = m_CurrentModes;
1260 "TextIO: X co-ordinate is beyond the end " 1261 "of a backbuffer line: " 1262 << m_CursorX <<
" vs " << BACKBUFFER_STRIDE
1271 if (m_CursorX < m_LeftMargin)
1273 WARNING(
"TextIO: X co-ordinate ended up befor the left margin.");
1274 m_CursorX = m_LeftMargin;
1284 m_pVga->moveCursor(m_CursorX, m_CursorY);
1291 if (m_OutBuffer.canRead(
false))
1295 void TextIO::setColour(TextIO::VgaColour *which,
size_t param,
bool bBright)
1300 *which = bBright ? DarkGrey : Black;
1303 *which = bBright ? LightRed : Red;
1306 *which = bBright ? LightGreen : Green;
1309 *which = bBright ? Yellow : Orange;
1312 *which = bBright ? LightBlue : Blue;
1315 *which = bBright ? LightMagenta : Magenta;
1318 *which = bBright ? LightCyan : Cyan;
1321 *which = bBright ? White : LightGrey;
1328 void TextIO::doBackspace()
1332 if (m_CursorX == m_RightMargin)
1336 if (m_CursorX > m_LeftMargin)
1340 void TextIO::doLinefeed()
1346 void TextIO::doCarriageReturn()
1348 m_CursorX = m_LeftMargin;
1351 void TextIO::doHorizontalTab()
1353 bool tabStopFound =
false;
1356 for (ssize_t x = (m_CursorX + 1); x < m_RightMargin; ++x)
1358 if (m_TabStops[x] != 0)
1361 tabStopFound =
true;
1369 m_CursorX = m_RightMargin - 1;
1371 else if (m_CursorX >= m_RightMargin)
1372 m_CursorX = m_RightMargin - 1;
1375 void TextIO::checkScroll()
1381 if (m_CursorY < m_ScrollStart)
1384 size_t numRows = (m_ScrollStart - m_CursorY);
1387 size_t sourceRow = m_ScrollStart;
1388 size_t destRow = m_ScrollStart + numRows;
1391 size_t sourceEnd = m_ScrollEnd + 1 - numRows;
1395 &m_pBackbuffer[destRow * BACKBUFFER_STRIDE],
1396 &m_pBackbuffer[sourceRow * BACKBUFFER_STRIDE],
1397 (sourceEnd - sourceRow) * BACKBUFFER_STRIDE *
sizeof(
VgaCell));
1400 for (
size_t i = 0; i < ((destRow - sourceRow) * BACKBUFFER_STRIDE); ++i)
1403 &m_pBackbuffer[(sourceRow * BACKBUFFER_STRIDE) + i];
1404 pCell->character =
' ';
1405 pCell->back = m_Back;
1406 pCell->fore = m_Fore;
1410 m_CursorY = m_ScrollStart;
1412 else if (m_CursorY > m_ScrollEnd)
1415 size_t numRows = (m_CursorY - m_ScrollEnd);
1419 size_t startOffset = m_ScrollStart * BACKBUFFER_STRIDE;
1422 size_t fromOffset = (m_ScrollStart + numRows) * BACKBUFFER_STRIDE;
1426 size_t movedRows = ((m_ScrollEnd + 1) * BACKBUFFER_STRIDE) - fromOffset;
1429 size_t blankFrom = (((m_ScrollEnd + 1) - numRows) * BACKBUFFER_STRIDE);
1432 size_t blankLength =
1433 ((m_ScrollEnd + 1) * BACKBUFFER_STRIDE) - blankFrom;
1436 &m_pBackbuffer[startOffset], &m_pBackbuffer[fromOffset],
1438 for (
size_t i = 0; i < blankLength; ++i)
1440 VgaCell *pCell = &m_pBackbuffer[blankFrom + i];
1441 pCell->character =
' ';
1442 pCell->back = m_Back;
1443 pCell->fore = m_Fore;
1447 m_CursorY = m_ScrollEnd;
1451 void TextIO::checkWrap()
1453 if (m_CursorX >= m_RightMargin)
1457 if (m_CurrentModes & AutoWrap)
1459 m_CursorX = m_LeftMargin;
1466 m_CursorX = m_RightMargin - 1;
1471 void TextIO::eraseSOS()
1479 for (ssize_t y = 0; y < m_CursorY; ++y)
1481 for (
size_t x = 0; x < BACKBUFFER_STRIDE; ++x)
1483 VgaCell *pCell = &m_pBackbuffer[(y * BACKBUFFER_STRIDE) + x];
1484 pCell->character =
' ';
1485 pCell->fore = m_Fore;
1486 pCell->back = m_Back;
1492 void TextIO::eraseEOS()
1500 for (
size_t y = m_CursorY + 1; y < BACKBUFFER_ROWS; ++y)
1502 for (
size_t x = 0; x < BACKBUFFER_STRIDE; ++x)
1504 VgaCell *pCell = &m_pBackbuffer[(y * BACKBUFFER_STRIDE) + x];
1505 pCell->character =
' ';
1506 pCell->back = m_Back;
1507 pCell->fore = m_Fore;
1513 void TextIO::eraseEOL()
1518 for (
size_t x = m_CursorX; x < BACKBUFFER_STRIDE; ++x)
1520 VgaCell *pCell = &m_pBackbuffer[(m_CursorY * BACKBUFFER_STRIDE) + x];
1521 pCell->character =
' ';
1522 pCell->back = m_Back;
1523 pCell->fore = m_Fore;
1528 void TextIO::eraseSOL()
1532 for (ssize_t x = 0; x <= m_CursorX; ++x)
1534 VgaCell *pCell = &m_pBackbuffer[(m_CursorY * BACKBUFFER_STRIDE) + x];
1535 pCell->character =
' ';
1536 pCell->fore = m_Fore;
1537 pCell->back = m_Back;
1542 void TextIO::eraseLine()
1546 for (
size_t x = 0; x < BACKBUFFER_STRIDE; ++x)
1548 VgaCell *pCell = &m_pBackbuffer[(m_CursorY * BACKBUFFER_STRIDE) + x];
1549 pCell->character =
' ';
1550 pCell->fore = m_Fore;
1551 pCell->back = m_Back;
1556 void TextIO::eraseScreen(uint8_t character)
1560 for (
size_t y = 0; y < BACKBUFFER_ROWS; ++y)
1562 for (
size_t x = 0; x < BACKBUFFER_STRIDE; ++x)
1564 VgaCell *pCell = &m_pBackbuffer[(y * BACKBUFFER_STRIDE) + x];
1565 pCell->character = character;
1566 pCell->fore = m_Fore;
1567 pCell->back = m_Back;
1573 void TextIO::goHome(ssize_t xmove, ssize_t ymove)
1576 if (m_CurrentModes & Origin)
1578 m_CursorX = m_LeftMargin + xmove;
1579 m_CursorY = m_ScrollStart + ymove;
1592 BACKBUFFER_STRIDE * BACKBUFFER_ROWS *
sizeof(
VgaCell));
1599 const VgaColour defaultBack = Black, defaultFore = LightGrey;
1613 size_t numRows = m_pVga->getNumRows();
1614 size_t numCols = m_pVga->getNumCols();
1616 for (
size_t y = 0; y < numRows; ++y)
1618 for (
size_t x = 0; x < numCols; ++x)
1620 VgaCell *pCell = &m_pBackbuffer[(y * BACKBUFFER_STRIDE) + x];
1623 if (pCell->flags & Blink)
1624 pCell->
hidden = hideState;
1629 VgaColour fore = pCell->fore;
1630 VgaColour back = pCell->back;
1633 if ((pCell->flags & Bright) && (fore < DarkGrey))
1634 fore = adjustColour(fore,
true);
1636 if (pCell->flags & Inverse)
1639 VgaColour tmp = fore;
1644 uint8_t attrib = (back << 4) | (fore & 0x0F);
1645 if (m_CurrentModes & Screen)
1648 if (pCell->fore == defaultFore && pCell->back == defaultBack)
1650 attrib = (fore << 4) | (back & 0x0F);
1655 (pCell->
hidden ?
' ' : pCell->character) | (attrib << 8);
1656 m_pFramebuffer[(y * numCols) + x] = front;
1662 uint64_t location, uint64_t size, uintptr_t buffer,
bool bCanBlock)
1664 return m_OutBuffer.read(reinterpret_cast<char *>(buffer), size, bCanBlock);
1668 uint64_t location, uint64_t size, uintptr_t buffer,
bool bCanBlock)
1670 writeStr(reinterpret_cast<const char *>(buffer), size);
1678 return m_OutBuffer.canWrite(timeout > 0) ? 1 : 0;
1682 return m_OutBuffer.canRead(timeout > 0) ? 1 : 0;
1686 void TextIO::flipThread()
1688 while (m_bInitialised)
1690 bool bBlinkOn = m_NextInterval != BLINK_ON_PERIOD;
1692 m_NextInterval = BLINK_ON_PERIOD;
1694 m_NextInterval = BLINK_OFF_PERIOD;
1697 flip(
true, !bBlinkOn);
1700 Time::delay(m_NextInterval * Time::Multiplier::Millisecond);
1967 if (codepoint <= 0xFF)
1968 return codepoint & 0xFF;
1973 static int startFlipThread(
void *param)
1997 if (!m_OutBuffer.canWrite(
false))
1999 WARNING(
"TextIO: output buffer is full, dropping keypress!");
2003 if (m_InputMode == Raw)
2005 if (in.type != InputManager::MachineKey)
2011 in.data.rawkey.scancode | (in.data.rawkey.keyUp ? 0x80 : 0);
2012 m_OutBuffer.write(reinterpret_cast<char *>(&buf),
sizeof(buf));
2024 uint64_t c = in.data.key.key;
2027 if (c & SPECIAL_KEY)
2029 uint32_t k = c & 0xFFFFFFFFULL;
2030 char *str =
reinterpret_cast<char *
>(&k);
2032 if (!StringCompareN(str,
"left", 4))
2036 else if (!StringCompareN(str,
"righ", 4))
2040 else if (!StringCompareN(str,
"up", 2))
2044 else if (!StringCompareN(str,
"down", 4))
2054 else if (c & CTRL_KEY)
2068 m_OutBuffer.write(
"\033[D", 3);
2071 m_OutBuffer.write(
"\033[C", 3);
2074 m_OutBuffer.write(
"\033[A", 3);
2077 m_OutBuffer.write(
"\033[B", 3);
2083 else if (c & ALT_KEY)
2087 char buf[2] = {
'\033',
static_cast<char>(c & 0xFF)};
2088 m_OutBuffer.write(buf, 2);
2096 m_OutBuffer.write(buf, nbuf);
2106 m_bOwnsConsole =
true;
2109 m_pVga->moveCursor(m_CursorX, m_CursorY);
2116 m_bOwnsConsole =
false;
2121 return m_bOwnsConsole;
static size_t getPageSize() PURE
static PhysicalMemoryManager & instance()
virtual int select(bool bWriting=false, int timeout=0)
virtual uint64_t writeBytewise(uint64_t location, uint64_t size, uintptr_t buffer, bool bCanBlock=true)
void writeStr(const char *s, size_t len)
void setMode(InputMode mode)
static ProcessorInformation & information()
virtual Vga * getVga(size_t n)=0
uint8_t translate(uint32_t codepoint)
void flip(bool timer=false, bool hideState=false)
static const size_t Write
static const size_t KernelMode
bool initialise(bool bClear=true)
virtual uint64_t readBytewise(uint64_t location, uint64_t size, uintptr_t buffer, bool bCanBlock=true)
virtual bool allocateRegion(MemoryRegion &Region, size_t cPages, size_t pageConstraints, size_t Flags, physical_uintptr_t start=-1)=0
static size_t Utf32ToUtf8(uint32_t utf32, char *utf8)
virtual bool setLargestTextMode()=0
InputMode getMode() const