27 #define XTERM_BOLD 0x1 28 #define XTERM_UNDERLINE 0x2 29 #define XTERM_INVERSE 0x4 30 #define XTERM_BRIGHTFG 0x8 31 #define XTERM_BRIGHTBG 0x10 32 #define XTERM_BORDER 0x20 33 #define XTERM_ITALIC 0x40 48 #define USE_FRAMEBUFFER_LINES 1 50 #include "environment.h" 52 #include "pedigree/native/config/Config.h" 53 #include "pedigree/native/graphics/Graphics.h" 55 #include <cairo/cairo.h> 59 extern uint32_t g_Colours[];
60 extern uint32_t g_BrightColours[];
62 uint8_t g_DefaultFg = 7;
63 uint8_t g_DefaultBg = 0;
65 bool g_FontsPrecached =
false;
67 static void getXtermColorFromDb(
const char *colorName, uint8_t &color)
75 sQuery +=
"select r from 'colour_scheme' where name='";
85 klog(LOG_ALERT,
"TUI: Error looking up '%s' colour.", colorName);
91 LOG_ALERT,
"TUI: Error looking up '%s' colour: %s\n", colorName,
98 color = pResult->
getNum(0,
"r");
107 size_t offsetLeft,
size_t offsetTop,
Terminal *pT,
class Widget *pWidget,
109 : m_ActiveBuffer(0), m_Cmd(), m_OsCtl(), m_bChangingState(false),
110 m_bContainedBracket(false), m_bContainedParen(false),
111 m_bIsOsControl(false), m_Flags(0), m_Modes(0), m_TabStops(0), m_SavedX(0),
112 m_SavedY(0), m_pT(pT), m_bFbMode(false), m_pWidget(pWidget), m_pTui(pTui)
114 setFonts(pNormalFont, pBoldFont);
116 size_t width = nWidth / m_pNormalFont->getWidth();
117 size_t height = nHeight / m_pNormalFont->getHeight();
119 m_pWindows[0] =
new Window(
120 height, width, pFramebuffer, 1000, offsetLeft, offsetTop, nWidth,
this);
121 m_pWindows[1] =
new Window(
122 height, width, pFramebuffer, 1000, offsetLeft, offsetTop, nWidth,
this);
124 getXtermColorFromDb(
"xterm-bg", g_DefaultBg);
125 getXtermColorFromDb(
"xterm-fg", g_DefaultFg);
128 m_TabStops =
new char[getStride()];
129 memset(m_TabStops, 0, getStride());
130 for (
size_t i = 0; i < getStride(); i += 8)
139 m_Cmd.has_param =
false;
141 m_OsCtl.cur_param = 0;
142 m_OsCtl.has_param =
false;
148 delete m_pWindows[0];
149 delete m_pWindows[1];
154 if (key & Keyboard::Special)
157 uint32_t utf32 = key & ~0UL;
158 char *str =
reinterpret_cast<char *
>(&utf32);
159 if (!strncmp(str,
"left", 4))
161 m_pT->addToQueue(
'\e');
162 if ((m_Modes & AnsiVt52) == AnsiVt52)
164 if (m_Modes & CursorKey)
165 m_pT->addToQueue(
'O');
167 m_pT->addToQueue(
'[');
169 m_pT->addToQueue(
'D');
171 if (!strncmp(str,
"righ", 4))
173 m_pT->addToQueue(
'\e');
174 if ((m_Modes & AnsiVt52) == AnsiVt52)
176 if (m_Modes & CursorKey)
177 m_pT->addToQueue(
'O');
179 m_pT->addToQueue(
'[');
181 m_pT->addToQueue(
'C');
183 if (!strncmp(str,
"up", 2))
185 m_pT->addToQueue(
'\e');
186 if ((m_Modes & AnsiVt52) == AnsiVt52)
188 if (m_Modes & CursorKey)
189 m_pT->addToQueue(
'O');
191 m_pT->addToQueue(
'[');
193 m_pT->addToQueue(
'A');
195 if (!strncmp(str,
"down", 4))
197 m_pT->addToQueue(
'\e');
198 if ((m_Modes & AnsiVt52) == AnsiVt52)
200 if (m_Modes & CursorKey)
201 m_pT->addToQueue(
'O');
203 m_pT->addToQueue(
'[');
205 m_pT->addToQueue(
'B');
208 else if (key & Keyboard::Alt)
211 m_pT->addToQueue(
'\e');
212 m_pT->addToQueue(key & 0x7F);
214 else if (key ==
'\n' || key ==
'\r')
216 m_pT->addToQueue(
'\r');
217 if (m_Modes & LineFeedNewLine)
218 m_pT->addToQueue(
'\n');
222 uint32_t utf32 = key & 0xFFFFFFFF;
229 buf[0] = utf32 & 0x7F;
232 else if (utf32 <= 0x7FF)
234 buf[0] = 0xC0 | ((utf32 >> 6) & 0x1F);
235 buf[1] = 0x80 | (utf32 & 0x3F);
238 else if (utf32 <= 0xFFFF)
240 buf[0] = 0xE0 | ((utf32 >> 12) & 0x0F);
241 buf[1] = 0x80 | ((utf32 >> 6) & 0x3F);
242 buf[2] = 0x80 | (utf32 & 0x3F);
245 else if (utf32 <= 0x10FFFF)
247 buf[0] = 0xE0 | ((utf32 >> 18) & 0x07);
248 buf[1] = 0x80 | ((utf32 >> 12) & 0x3F);
249 buf[2] = 0x80 | ((utf32 >> 6) & 0x3F);
250 buf[3] = 0x80 | (utf32 & 0x3F);
255 for (
size_t i = 0; i < nbuf; i++)
256 m_pT->addToQueue(buf[i]);
259 m_pT->addToQueue(0,
true);
262 bool Xterm::setFlagsForUtf32(uint32_t utf32)
264 size_t oldFlags = m_Flags;
288 m_Flags |= LeftRound;
292 m_Flags |= RightRound;
296 m_Flags |= LeftSquare;
300 m_Flags |= RightSquare;
304 m_Flags |= Underscore;
328 m_Flags |= Backslash;
336 m_Flags |= Apostrophe;
351 return oldFlags != m_Flags;
356 #ifdef XTERM_DEBUG_EXTRA 357 klog(LOG_INFO,
"XTerm::write(%c/%x)", (
char) utf32, utf32);
361 if (m_Flags & Vt52SetCursorWaitY)
363 m_Cmd.params[0] = (char) utf32 - 32;
364 m_Flags &= ~Vt52SetCursorWaitY;
365 m_Flags |= Vt52SetCursorWaitX;
368 else if (m_Flags & Vt52SetCursorWaitX)
370 m_Cmd.params[1] = (char) utf32 - 32;
371 m_pWindows[m_ActiveBuffer]->setCursor(
372 m_Cmd.params[1], m_Cmd.params[0], rect);
384 const char *answerback =
"\e[1;2c";
387 m_pT->addToQueue(*answerback);
392 m_pWindows[m_ActiveBuffer]->backspace(rect);
398 if (m_Modes & LineFeedNewLine)
399 m_pWindows[m_ActiveBuffer]->cursorDownAndLeftToMargin(rect);
401 m_pWindows[m_ActiveBuffer]->cursorDown(1, rect);
405 m_pWindows[m_ActiveBuffer]->cursorTab(rect);
409 m_pWindows[m_ActiveBuffer]->cursorLeftToMargin(rect);
421 m_Cmd.has_param =
false;
424 sizeof(m_Cmd.params[0]) * XTERM_MAX_PARAMS);
426 m_OsCtl.cur_param = 0;
427 m_OsCtl.has_param =
false;
428 for (
size_t i = 0; i < XTERM_MAX_PARAMS; ++i)
430 m_OsCtl.params[i] =
"";
436 if (m_pWindows[m_ActiveBuffer]->getLineRenderMode())
480 m_pWindows[m_ActiveBuffer]->addChar(utf32, rect);
485 (m_Flags & (Escape | LeftSquare | RightSquare | Underscore)) ==
486 (Escape | LeftSquare))
488 setFlagsForUtf32(utf32);
494 m_pWindows[m_ActiveBuffer]->backspace(rect);
499 if (m_Modes & LineFeedNewLine)
500 m_pWindows[m_ActiveBuffer]->cursorLeftToMargin(rect);
501 m_pWindows[m_ActiveBuffer]->cursorDown(1, rect);
505 m_pWindows[m_ActiveBuffer]->cursorLeftToMargin(rect);
518 m_Cmd.params[m_Cmd.cur_param] =
519 m_Cmd.params[m_Cmd.cur_param] * 10 + (utf32 -
'0');
520 m_Cmd.has_param =
true;
529 m_pWindows[m_ActiveBuffer]->insertCharacters(
530 m_Cmd.params[0] ? m_Cmd.params[0] : 1, rect);
535 if (m_Cmd.has_param && m_Cmd.params[0])
536 m_pWindows[m_ActiveBuffer]->cursorUpWithinMargin(
537 m_Cmd.params[0], rect);
539 m_pWindows[m_ActiveBuffer]->cursorUpWithinMargin(1, rect);
544 if (m_Cmd.has_param && m_Cmd.params[0])
545 m_pWindows[m_ActiveBuffer]->cursorDownWithinMargin(
546 m_Cmd.params[0], rect);
548 m_pWindows[m_ActiveBuffer]->cursorDownWithinMargin(1, rect);
553 if (m_Cmd.has_param && m_Cmd.params[0])
554 m_pWindows[m_ActiveBuffer]->cursorRightWithinMargin(
555 m_Cmd.params[0], rect);
557 m_pWindows[m_ActiveBuffer]->cursorRightWithinMargin(
563 if (m_Cmd.has_param && m_Cmd.params[0])
564 m_pWindows[m_ActiveBuffer]->cursorLeftWithinMargin(
565 m_Cmd.params[0], rect);
567 m_pWindows[m_ActiveBuffer]->cursorLeftWithinMargin(1, rect);
572 m_pWindows[m_ActiveBuffer]->cursorLeftToMargin(rect);
573 m_pWindows[m_ActiveBuffer]->cursorDown(
574 m_Cmd.params[0] ? m_Cmd.params[0] : 1, rect);
579 m_pWindows[m_ActiveBuffer]->cursorLeftToMargin(rect);
580 m_pWindows[m_ActiveBuffer]->cursorUp(
581 m_Cmd.params[0] ? m_Cmd.params[0] : 1, rect);
587 m_pWindows[m_ActiveBuffer]->setCursorX(
588 (m_Cmd.params[0]) ? m_Cmd.params[0] - 1 : 0, rect);
597 size_t x = (m_Cmd.params[1]) ? m_Cmd.params[1] - 1 : 0;
598 size_t y = (m_Cmd.params[0]) ? m_Cmd.params[0] - 1 : 0;
599 if (m_Modes & Origin)
601 m_pWindows[m_ActiveBuffer]->setCursorRelOrigin(
606 m_pWindows[m_ActiveBuffer]->setCursor(x, y, rect);
611 if (m_Modes & Origin)
613 m_pWindows[m_ActiveBuffer]->cursorToOrigin();
617 m_pWindows[m_ActiveBuffer]->setCursor(0, 0, rect);
625 if (!m_Cmd.params[0])
628 for (
int n = 0; n < m_Cmd.params[0]; ++n)
630 m_pWindows[m_ActiveBuffer]->cursorTab(rect);
636 switch (m_Cmd.params[0])
639 m_pWindows[m_ActiveBuffer]->eraseDown(rect);
642 m_pWindows[m_ActiveBuffer]->eraseUp(rect);
645 m_pWindows[m_ActiveBuffer]->eraseScreen(rect);
652 switch (m_Cmd.params[0])
655 m_pWindows[m_ActiveBuffer]->eraseEOL(rect);
658 m_pWindows[m_ActiveBuffer]->eraseSOL(rect);
661 m_pWindows[m_ActiveBuffer]->eraseLine(rect);
668 m_pWindows[m_ActiveBuffer]->insertLines(
669 m_Cmd.params[0] ? m_Cmd.params[0] : 1, rect);
674 m_pWindows[m_ActiveBuffer]->deleteLines(
675 m_Cmd.params[0] ? m_Cmd.params[0] : 1, rect);
680 m_pWindows[m_ActiveBuffer]->deleteCharacters(
681 (m_Cmd.params[0]) ? m_Cmd.params[0] : 1, rect);
687 size_t nScrollLines = (m_Cmd.params[0]) ? m_Cmd.params[0] : 1;
688 m_pWindows[m_ActiveBuffer]->scrollDown(nScrollLines, rect);
694 if (m_Flags & RightAngle)
698 else if (m_Cmd.cur_param > 1)
702 "XTERM: highlight mouse tracking is not supported.");
706 size_t nScrollLines =
707 (m_Cmd.params[0]) ? m_Cmd.params[0] : 1;
708 m_pWindows[m_ActiveBuffer]->scrollUp(nScrollLines, rect);
714 m_pWindows[m_ActiveBuffer]->eraseChars(
715 (m_Cmd.params[0]) ? m_Cmd.params[0] - 1 : 1, rect);
720 if (!m_Cmd.params[0])
723 for (
int n = 0; n < m_Cmd.params[0]; ++n)
725 m_pWindows[m_ActiveBuffer]->cursorTabBack(rect);
734 LOG_INFO,
"XTERM: Device Attributes command with " 735 "non-zero parameter");
737 else if (m_Flags & RightAngle)
740 const char *attribs =
"\e[?85;95;0c";
743 m_pT->addToQueue(*attribs);
750 const char *attribs =
"\e[?1;2c";
753 m_pT->addToQueue(*attribs);
762 m_pWindows[m_ActiveBuffer]->setCursorY(
763 (m_Cmd.params[0]) ? m_Cmd.params[0] - 1 : 0, rect);
769 m_pWindows[m_ActiveBuffer]->cursorDown(
770 (m_Cmd.params[0]) ? m_Cmd.params[0] - 1 : 1, rect);
775 if ((!m_Cmd.has_param) || (m_Cmd.params[0] == 0))
776 m_pWindows[m_ActiveBuffer]->clearTabStop();
777 else if (m_Cmd.has_param && (m_Cmd.params[0] == 3))
778 m_pWindows[m_ActiveBuffer]->clearAllTabStops();
785 size_t modesToChange = 0;
787 if (m_Flags & Question)
790 for (
int i = 0; i <= m_Cmd.cur_param; ++i)
792 switch (m_Cmd.params[i])
795 modesToChange |= CursorKey;
798 modesToChange |= AnsiVt52;
804 modesToChange |= Scrolling;
807 modesToChange |= Screen;
810 modesToChange |= Origin;
813 modesToChange |= AutoWrap;
816 modesToChange |= AutoRepeat;
820 klog(LOG_INFO,
"(Dis)Allowing 80->132 mode.");
823 klog(LOG_INFO,
"Reverse-wraparound mode.");
826 modesToChange |= AppKeypad;
829 modesToChange |= Margin;
835 m_SavedX = m_pWindows[m_ActiveBuffer]
837 m_SavedY = m_pWindows[m_ActiveBuffer]
842 m_pWindows[m_ActiveBuffer]->setCursor(
843 m_SavedX, m_SavedY, rect);
848 if (m_Cmd.params[i] != 1048)
850 m_ActiveBuffer = (utf32 ==
'h') ? 1 : 0;
851 if ((utf32 ==
'h') &&
852 (m_Cmd.params[i] == 1049))
855 m_pWindows[m_ActiveBuffer]->eraseScreen(
861 m_pWindows[m_ActiveBuffer]->renderAll(
862 rect, m_pWindows[0]);
869 "XTERM: unknown DEC Private Mode %d",
877 for (
int i = 0; i <= m_Cmd.cur_param; ++i)
879 switch (m_Cmd.params[i])
882 modesToChange |= Insert;
885 modesToChange |= LineFeedNewLine;
889 LOG_INFO,
"XTERM: unknown standard mode %d",
898 m_Modes |= modesToChange;
902 m_Modes &= ~(modesToChange);
906 if (modesToChange & Origin)
908 if (m_Modes & Origin)
911 m_pWindows[m_ActiveBuffer]->cursorToOrigin();
916 m_pWindows[m_ActiveBuffer]->setCursor(0, 0, rect);
920 if (modesToChange &
Column)
923 if (m_Modes & Column)
925 m_pWindows[m_ActiveBuffer]->setMargins(0, XTERM_WIDE);
929 m_pWindows[m_ActiveBuffer]->setMargins(
933 m_pWindows[m_ActiveBuffer]->eraseScreen(rect);
934 m_pWindows[m_ActiveBuffer]->setScrollRegion(-1, -1);
937 m_pWindows[m_ActiveBuffer]->setCursor(0, 0, rect);
940 if (modesToChange & Screen)
951 for (
int i = 0; i < m_Cmd.cur_param + 1; i++)
953 switch (m_Cmd.params[i])
958 m_pWindows[m_ActiveBuffer]->setFlags(0);
959 m_pWindows[m_ActiveBuffer]->setForeColour(
961 m_pWindows[m_ActiveBuffer]->setBackColour(
969 m_pWindows[m_ActiveBuffer]->getFlags();
970 if (!(flags & XTERM_BOLD))
973 m_pWindows[m_ActiveBuffer]->setFlags(flags);
981 m_pWindows[m_ActiveBuffer]->getFlags();
982 if (!(flags & XTERM_ITALIC))
984 flags |= XTERM_ITALIC;
985 m_pWindows[m_ActiveBuffer]->setFlags(flags);
993 m_pWindows[m_ActiveBuffer]->getFlags();
994 if (!(flags & XTERM_UNDERLINE))
996 flags |= XTERM_UNDERLINE;
997 m_pWindows[m_ActiveBuffer]->setFlags(flags);
1005 m_pWindows[m_ActiveBuffer]->getFlags();
1006 if (flags & XTERM_INVERSE)
1007 flags &= ~XTERM_INVERSE;
1009 flags |= XTERM_INVERSE;
1010 m_pWindows[m_ActiveBuffer]->setFlags(flags);
1016 m_pWindows[m_ActiveBuffer]->getFlags();
1017 flags &= ~XTERM_ITALIC;
1018 m_pWindows[m_ActiveBuffer]->setFlags(flags);
1024 m_pWindows[m_ActiveBuffer]->getFlags();
1025 flags &= ~XTERM_ITALIC;
1026 m_pWindows[m_ActiveBuffer]->setFlags(flags);
1032 m_pWindows[m_ActiveBuffer]->getFlags();
1033 flags &= ~XTERM_UNDERLINE;
1034 m_pWindows[m_ActiveBuffer]->setFlags(flags);
1040 m_pWindows[m_ActiveBuffer]->getFlags();
1041 flags &= ~XTERM_INVERSE;
1042 m_pWindows[m_ActiveBuffer]->setFlags(flags);
1054 m_pWindows[m_ActiveBuffer]->setForeColour(
1055 m_Cmd.params[i] - 30);
1059 if (m_Cmd.params[i + 1] == 5)
1061 m_pWindows[m_ActiveBuffer]->setForeColour(
1062 m_Cmd.params[i + 2]);
1067 m_pWindows[m_ActiveBuffer]->setForeColour(
1079 m_pWindows[m_ActiveBuffer]->setBackColour(
1080 m_Cmd.params[i] - 40);
1084 if (m_Cmd.params[i + 1] == 5)
1086 m_pWindows[m_ActiveBuffer]->setBackColour(
1087 m_Cmd.params[i + 2]);
1092 m_pWindows[m_ActiveBuffer]->setForeColour(
1100 "XTERM: unknown character attribute %d",
1110 if ((m_Flags & RightAngle) == 0)
1113 switch (m_Cmd.params[0])
1118 const char *status =
"\e[0n";
1121 m_pT->addToQueue(*status);
1130 m_pWindows[m_ActiveBuffer]->getCursorX() + 1;
1132 m_pWindows[m_ActiveBuffer]->getCursorY() + 1;
1134 if (m_Modes & Origin)
1136 reportX = m_pWindows[m_ActiveBuffer]
1137 ->getCursorXRelOrigin() +
1139 reportY = m_pWindows[m_ActiveBuffer]
1140 ->getCursorYRelOrigin() +
1146 sprintf(buf,
"\e[%zd;%zdR", reportY, reportX);
1147 const char *p = (
const char *) buf;
1150 m_pT->addToQueue(*p);
1159 "XTERM: unknown device status request %d",
1174 if (m_Flags & Space)
1183 if ((m_Flags & Question) == 0)
1185 if (m_Cmd.has_param)
1187 m_pWindows[m_ActiveBuffer]->setScrollRegion(
1188 m_Cmd.params[0] - 1, m_Cmd.params[1] - 1);
1192 m_pWindows[m_ActiveBuffer]->setScrollRegion(-1, -1);
1195 if (m_Modes & Origin)
1197 m_pWindows[m_ActiveBuffer]->cursorToOrigin();
1201 m_pWindows[m_ActiveBuffer]->setCursor(0, 0, rect);
1208 if (!m_Cmd.has_param)
1210 if ((m_Modes & Margin) == 0)
1212 m_SavedX = m_pWindows[m_ActiveBuffer]->getCursorX();
1213 m_SavedY = m_pWindows[m_ActiveBuffer]->getCursorY();
1216 else if (m_Modes & Margin)
1219 m_pWindows[m_ActiveBuffer]->setMargins(
1220 (m_Cmd.params[0]) ? m_Cmd.params[0] - 1 : ~0,
1221 (m_Cmd.params[1]) ? m_Cmd.params[1] - 1 : ~0);
1227 if ((m_Flags & Space) == 0)
1229 m_pWindows[m_ActiveBuffer]->setCursor(
1230 m_SavedX, m_SavedY, rect);
1236 if ((m_Flags & Asterisk) == 0)
1238 if (m_Cmd.params[0] <= 1)
1240 const char *termparams = 0;
1241 if (m_Cmd.params[0] == 1)
1242 termparams =
"\e[3;1;1;120;120;1;0x";
1244 termparams =
"\e[2;1;1;120;120;1;0x";
1248 m_pT->addToQueue(*termparams);
1261 (m_Flags & (Escape | LeftSquare | RightSquare | Underscore)) == Escape)
1263 bool seenFlag = setFlagsForUtf32(utf32);
1269 m_pWindows[m_ActiveBuffer]->backspace(rect);
1273 if (m_Flags & LeftRound)
1276 m_pWindows[m_ActiveBuffer]->setLineRenderMode(
true);
1282 klog(LOG_ALERT,
"XTERM: double-height lines not supported");
1287 klog(LOG_ALERT,
"XTERM: double-height lines not supported");
1297 klog(LOG_ALERT,
"XTERM: double-width lines not supported");
1302 m_SavedX = m_pWindows[m_ActiveBuffer]->getCursorX();
1303 m_SavedY = m_pWindows[m_ActiveBuffer]->getCursorY();
1315 m_pWindows[m_ActiveBuffer]->setMargins(0, XTERM_WIDE);
1319 m_pWindows[m_ActiveBuffer]->setMargins(
1322 m_pWindows[m_ActiveBuffer]->setScrollRegion(-1, -1);
1325 m_pWindows[m_ActiveBuffer]->fillChar(
'E', rect);
1328 m_pWindows[m_ActiveBuffer]->setCursor(0, 0, rect);
1332 m_pWindows[m_ActiveBuffer]->setCursor(
1333 m_SavedX, m_SavedY, rect);
1339 m_Modes |= AnsiVt52;
1349 m_pWindows[m_ActiveBuffer]->cursorUpWithinMargin(1, rect);
1354 if (m_Flags & LeftRound)
1357 m_pWindows[m_ActiveBuffer]->setLineRenderMode(
false);
1361 m_pWindows[m_ActiveBuffer]->cursorDownWithinMargin(1, rect);
1367 m_pWindows[m_ActiveBuffer]->cursorRightWithinMargin(1, rect);
1372 if (m_Modes & AnsiVt52)
1374 m_pWindows[m_ActiveBuffer]->cursorDown(1, rect);
1378 m_pWindows[m_ActiveBuffer]->cursorLeftWithinMargin(1, rect);
1384 m_pWindows[m_ActiveBuffer]->cursorDownAndLeftToMargin(rect);
1402 if (m_Modes & AnsiVt52)
1405 m_pWindows[m_ActiveBuffer]->setTabStop();
1410 m_pWindows[m_ActiveBuffer]->setCursor(0, 0, rect);
1416 if (!(m_Modes & AnsiVt52))
1419 m_pWindows[m_ActiveBuffer]->cursorUp(1, rect);
1425 if (!(m_Modes & AnsiVt52))
1427 m_pWindows[m_ActiveBuffer]->eraseDown(rect);
1433 if (!(m_Modes & AnsiVt52))
1435 m_pWindows[m_ActiveBuffer]->eraseEOL(rect);
1441 if ((m_Modes & AnsiVt52) && !(m_Flags & Space))
1444 m_pWindows[m_ActiveBuffer]->cursorUp(1, rect);
1456 if (!(m_Modes & AnsiVt52))
1459 m_Flags |= Vt52SetCursorWaitY;
1470 const char *answerback = 0;
1471 if (m_Modes & AnsiVt52)
1472 answerback =
"\e[1;2c";
1474 answerback =
"\e/Z";
1478 m_pT->addToQueue(*answerback);
1488 klog(LOG_INFO,
"XTERM: unknown ESCAPE control '%c'", utf32);
1495 (m_Flags & (Escape | LeftSquare | RightSquare | Underscore)) ==
1496 (Escape | RightSquare))
1502 if (!m_OsCtl.has_param)
1506 "XTERM: not enough parameters for OS control");
1510 if (m_OsCtl.params[0] ==
"0" || m_OsCtl.params[0] ==
"1" ||
1511 m_OsCtl.params[0] ==
"2")
1515 m_pWidget->setTitle(m_OsCtl.params[1]);
1521 LOG_INFO,
"XTERM: unhandled OS control '%s'",
1522 m_OsCtl.params[0].c_str());
1530 m_OsCtl.cur_param++;
1536 m_OsCtl.params[m_OsCtl.cur_param] +=
1537 static_cast<char>(utf32);
1543 (m_Flags & (Escape | LeftSquare | RightSquare | Underscore)) ==
1544 (Escape | Underscore))
1551 m_pT->addToQueue(0,
true);
1556 m_pWindows[m_ActiveBuffer]->renderAll(rect, m_pWindows[m_ActiveBuffer]);
1559 Xterm::Window::Window(
1561 size_t nMaxScrollback,
size_t offsetLeft,
size_t offsetTop,
size_t fbWidth,
1563 : m_pBuffer(0), m_BufferLength(0), m_pFramebuffer(pFb), m_FbWidth(fbWidth),
1564 m_Width(nCols), m_Height(nRows), m_Stride(XTERM_MIN_WIDTH),
1565 m_OffsetLeft(offsetLeft), m_OffsetTop(offsetTop),
1566 m_nMaxScrollback(nMaxScrollback), m_CursorX(0), m_CursorY(0),
1567 m_ScrollStart(0), m_ScrollEnd(nRows - 1), m_pInsert(0), m_pView(0),
1568 m_Fg(g_DefaultFg), m_Bg(g_DefaultBg), m_Flags(0), m_bCursorFilled(
true),
1569 m_bLineRender(
false), m_pParentXterm(parent)
1572 klog(LOG_INFO,
"Xterm::Window::Window() dimensions %zdx%zd", nCols, nRows);
1575 if (m_Width > m_Stride)
1579 m_pBuffer =
reinterpret_cast<TermChar *
>(
1580 malloc(m_Stride * m_Height *
sizeof(TermChar)));
1582 m_BufferLength = m_Stride * m_Height;
1589 for (
size_t i = 0; i < m_Stride * m_Height; i++)
1590 m_pBuffer[i] = blank;
1592 if (m_pParentXterm->m_pCairo)
1594 cairo_save(m_pParentXterm->m_pCairo);
1595 cairo_set_operator(m_pParentXterm->m_pCairo, CAIRO_OPERATOR_SOURCE);
1597 cairo_set_source_rgba(
1598 m_pParentXterm->m_pCairo, ((g_Colours[m_Bg] >> 16) & 0xFF) / 256.0,
1599 ((g_Colours[m_Bg] >> 8) & 0xFF) / 256.0,
1600 ((g_Colours[m_Bg]) & 0xFF) / 256.0, 0.8);
1603 m_pParentXterm->m_pCairo, m_OffsetLeft, m_OffsetTop,
1604 nCols * m_pParentXterm->m_pNormalFont->getWidth(),
1605 nRows * m_pParentXterm->m_pNormalFont->getHeight());
1606 cairo_fill(m_pParentXterm->m_pCairo);
1608 cairo_restore(m_pParentXterm->m_pCairo);
1611 m_pInsert = m_pView = m_pBuffer;
1614 m_RightMargin = m_Width;
1617 Xterm::Window::~Window()
1625 klog(LOG_INFO,
"Xterm::Window::showCursor");
1628 render(rect, m_bCursorFilled ? XTERM_INVERSE : XTERM_BORDER);
1634 klog(LOG_INFO,
"Xterm::Window::hideCursor");
1640 void Xterm::Window::resize(
size_t nWidth,
size_t nHeight,
bool bActive)
1643 klog(LOG_INFO,
"Xterm::Window::resize(%zd, %zd)", nWidth, nHeight);
1648 size_t cols = nWidth / m_pParentXterm->m_pNormalFont->getWidth();
1649 size_t rows = nHeight / m_pParentXterm->m_pNormalFont->getHeight();
1652 klog(LOG_INFO,
" -> cols %zd, %zd", nWidth, nHeight);
1655 if (bActive && m_Bg && m_pParentXterm->m_pCairo)
1658 if ((m_pParentXterm->getModes() & Screen) && (bg == g_DefaultBg))
1663 cairo_save(m_pParentXterm->m_pCairo);
1664 cairo_set_source_rgba(
1665 m_pParentXterm->m_pCairo, ((g_Colours[bg] >> 16) & 0xFF) / 256.0,
1666 ((g_Colours[bg] >> 8) & 0xFF) / 256.0,
1667 ((g_Colours[bg]) & 0xFF) / 256.0, 1.0);
1670 m_pParentXterm->m_pCairo, m_OffsetLeft, m_OffsetTop, nWidth,
1672 cairo_fill(m_pParentXterm->m_pCairo);
1674 cairo_restore(m_pParentXterm->m_pCairo);
1677 size_t previousStride = m_Stride;
1679 if (m_Stride < XTERM_MIN_WIDTH)
1680 m_Stride = XTERM_MIN_WIDTH;
1682 if (cols > m_Stride)
1685 TermChar *newBuf =
reinterpret_cast<TermChar *
>(
1686 malloc(m_Stride * rows *
sizeof(TermChar)));
1693 for (
size_t i = 0; i < m_Stride * rows; i++)
1696 for (
size_t r = 0; r < m_Height; r++)
1700 for (
size_t c = 0; c < m_Stride; c++)
1705 newBuf[r * m_Stride + c] = m_pInsert[r * previousStride + c];
1711 m_pInsert = m_pView = m_pBuffer = newBuf;
1712 m_BufferLength = rows * m_Stride;
1714 if (m_RightMargin > (ssize_t) cols)
1715 m_RightMargin = cols;
1716 if (m_LeftMargin > (ssize_t) cols)
1717 m_LeftMargin = cols;
1719 m_FbWidth = cols * m_pParentXterm->m_pNormalFont->getWidth();
1723 m_ScrollEnd = rows - 1;
1724 if (m_CursorX >= m_RightMargin)
1725 m_CursorX = m_RightMargin - 1;
1726 if (m_CursorY > m_ScrollEnd)
1727 m_CursorY = m_ScrollEnd;
1730 delete[] m_pParentXterm->m_TabStops;
1731 m_pParentXterm->m_TabStops =
new char[m_Stride];
1732 memset(m_pParentXterm->m_TabStops, 0, m_Stride);
1733 for (
size_t i = 0; i < m_Stride; i += 8)
1735 m_pParentXterm->m_TabStops[i] =
'|';
1739 void Xterm::Window::setScrollRegion(
int start,
int end)
1747 klog(LOG_INFO,
"Xterm::Window::setScrollRegion(%d, %d)", start, end);
1750 m_ScrollStart = start;
1753 if (m_ScrollStart > m_ScrollEnd)
1755 size_t tmp = m_ScrollStart;
1756 m_ScrollStart = m_ScrollEnd;
1760 if (m_ScrollStart >= (ssize_t) m_Height)
1761 m_ScrollStart = m_Height - 1;
1762 if (m_ScrollEnd >= (ssize_t) m_Height)
1763 m_ScrollEnd = m_Height - 1;
1766 void Xterm::Window::setForeColour(uint8_t fgColour)
1771 void Xterm::Window::setBackColour(uint8_t bgColour)
1776 void Xterm::Window::setFlags(uint8_t flags)
1781 uint8_t Xterm::Window::getFlags()
1786 void Xterm::Window::setMargins(
size_t left,
size_t right)
1789 klog(LOG_INFO,
"Xterm::Window::setMargins(%zd, %zd)", left, right);
1792 if (left > m_Stride)
1794 if (right > m_Stride)
1797 m_LeftMargin = left;
1798 m_RightMargin = right;
1803 TermChar *pOld = (pPrevious) ? pPrevious->m_pInsert : 0;
1804 TermChar *pNew = m_pInsert;
1808 for (
size_t y = 0; y < m_Height; y++)
1810 for (
size_t x = 0; x < m_Width; --x)
1812 if ((!pOld) || (pOld[y * m_Stride + x] != pNew[y * m_Stride + x]) ||
1813 (m_pParentXterm->getModes() !=
1814 pPrevious->m_pParentXterm->getModes()))
1816 render(rect, 0, x, y);
1822 void Xterm::Window::renderArea(
1834 for (
size_t cy = y; cy < (y + h); ++cy)
1836 for (
size_t cx = x; cx < (x + w); ++cx)
1838 render(rect, 0, cx, cy);
1843 void Xterm::Window::setChar(uint32_t utf32,
size_t x,
size_t y)
1850 TermChar *c = &m_pInsert[y * m_Stride + x];
1865 return m_pInsert[y * m_Stride + x];
1871 klog(LOG_INFO,
"Xterm::Window::cursorDown(%zd)", n);
1881 klog(LOG_INFO,
"Xterm::Window::cursorUp(%zd)", n);
1888 void Xterm::Window::cursorUpWithinMargin(
size_t n,
DirtyRectangle &rect)
1891 klog(LOG_INFO,
"Xterm::Window::cursorUpWithinMargin(%zd)", n);
1895 if (m_CursorY < m_ScrollStart)
1896 m_CursorY = m_ScrollStart;
1899 void Xterm::Window::cursorLeftWithinMargin(
size_t n,
DirtyRectangle &)
1902 klog(LOG_INFO,
"Xterm::Window::cursorLeftWithinMargin(%zd)", n);
1907 if (m_CursorX < m_LeftMargin)
1908 m_CursorX = m_LeftMargin;
1911 void Xterm::Window::cursorRightWithinMargin(
size_t n,
DirtyRectangle &)
1914 klog(LOG_INFO,
"Xterm::Window::cursorRightWithinMargin(%zd)", n);
1919 if (m_CursorX >= m_RightMargin)
1920 m_CursorX = m_RightMargin - 1;
1923 void Xterm::Window::cursorDownWithinMargin(
size_t n,
DirtyRectangle &)
1926 klog(LOG_INFO,
"Xterm::Window::cursorDownWithinMargin(%zd)", n);
1931 if (m_CursorY > m_ScrollEnd)
1932 m_CursorY = m_ScrollEnd;
1938 klog(LOG_INFO,
"Xterm::Window::backspace()");
1941 if (m_CursorX == m_RightMargin)
1944 if (m_CursorX > m_LeftMargin)
1948 void Xterm::Window::render(
1955 if (x > m_Width || y > m_Height)
1960 TermChar c = m_pView[y * m_Stride + x];
1964 uint32_t fg = g_Colours[c.fore];
1965 if (c.flags & XTERM_BRIGHTFG)
1966 fg = g_BrightColours[c.fore];
1967 uint32_t bg = g_Colours[c.back];
1968 if (c.flags & XTERM_BRIGHTBG)
1969 bg = g_BrightColours[c.back];
1971 if (c.flags & XTERM_INVERSE)
1978 if (m_pParentXterm->getModes() & Screen)
1981 if (c.fore == g_DefaultFg && c.back == g_DefaultBg)
1989 uint32_t utf32 = c.utf32;
1993 (x * m_pParentXterm->m_pNormalFont->getWidth()) + m_OffsetLeft,
1994 (y * m_pParentXterm->m_pNormalFont->getHeight()) + m_OffsetTop);
1996 ((x + 1) * m_pParentXterm->m_pNormalFont->getWidth()) + m_OffsetLeft,
1997 ((y + 1) * m_pParentXterm->m_pNormalFont->getHeight()) + m_OffsetTop);
1999 Font *pFont = m_pParentXterm->m_pNormalFont;
2000 bool bBold = (c.flags & XTERM_BOLD) == XTERM_BOLD;
2001 bool bItalic = (c.flags & XTERM_ITALIC) == XTERM_ITALIC;
2002 bool bUnderline = (c.flags & XTERM_UNDERLINE) == XTERM_UNDERLINE;
2005 m_pFramebuffer, utf32, (x * pFont->getWidth()) + m_OffsetLeft,
2006 (y * pFont->getHeight()) + m_OffsetTop, fg, bg,
true, bBold, bItalic,
2009 if (c.flags & XTERM_BORDER)
2012 cairo_save(m_pParentXterm->m_pCairo);
2013 cairo_set_operator(m_pParentXterm->m_pCairo, CAIRO_OPERATOR_SOURCE);
2015 cairo_set_line_width(m_pParentXterm->m_pCairo, 1.0);
2016 cairo_set_line_join(m_pParentXterm->m_pCairo, CAIRO_LINE_JOIN_MITER);
2017 cairo_set_antialias(m_pParentXterm->m_pCairo, CAIRO_ANTIALIAS_NONE);
2019 cairo_set_source_rgba(
2020 m_pParentXterm->m_pCairo, ((fg >> 16) & 0xFF) / 256.0,
2021 ((fg >> 8) & 0xFF) / 256.0, (fg & 0xFF) / 256.0, 0.8);
2024 m_pParentXterm->m_pCairo,
2025 (x * pFont->getWidth()) + m_OffsetLeft + 1,
2026 (y * pFont->getHeight()) + m_OffsetTop + 1, pFont->getWidth() - 2,
2027 pFont->getHeight() - 2);
2028 cairo_stroke(m_pParentXterm->m_pCairo);
2030 cairo_restore(m_pParentXterm->m_pCairo);
2034 void Xterm::Window::scrollRegionUp(
size_t numRows,
DirtyRectangle &rect)
2037 klog(LOG_INFO,
"Xterm::Window::scrollRegionUp(%zd)", numRows);
2040 size_t targetY = m_ScrollStart;
2041 size_t sourceY = m_ScrollStart + numRows;
2043 size_t movedRows = (m_ScrollEnd + 1) - sourceY;
2044 size_t blankFrom = (m_ScrollEnd + 1) - numRows;
2045 size_t blankLength = (m_ScrollEnd + 1) - blankFrom;
2051 m_OffsetTop + (targetY + m_pParentXterm->m_pNormalFont->getHeight()));
2053 m_OffsetLeft + m_FbWidth,
2054 m_OffsetTop + ((blankFrom + blankLength) *
2055 m_pParentXterm->m_pNormalFont->getHeight()));
2056 m_pParentXterm->m_pTui->redraw(rect);
2059 cairo_save(m_pParentXterm->m_pCairo);
2061 cairo_set_operator(m_pParentXterm->m_pCairo, CAIRO_OPERATOR_SOURCE);
2065 m_pParentXterm->m_pCairo, m_OffsetLeft,
2066 m_OffsetTop + (targetY * m_pParentXterm->m_pNormalFont->getHeight()),
2067 m_FbWidth - m_OffsetLeft,
2068 movedRows * m_pParentXterm->m_pNormalFont->getHeight());
2070 cairo_push_group(m_pParentXterm->m_pCairo);
2071 cairo_set_source_surface(
2072 m_pParentXterm->m_pCairo, m_pParentXterm->m_pCairoSurface, 0,
2073 -((
double) (numRows * m_pParentXterm->m_pNormalFont->getHeight())));
2074 cairo_fill_preserve(m_pParentXterm->m_pCairo);
2075 cairo_pop_group_to_source(m_pParentXterm->m_pCairo);
2080 if ((m_pParentXterm->getModes() & Screen) && (bg == g_DefaultBg))
2085 cairo_set_source_rgba(
2086 m_pParentXterm->m_pCairo, ((g_Colours[bg] >> 16) & 0xFF) / 256.0,
2087 ((g_Colours[bg] >> 8) & 0xFF) / 256.0, ((g_Colours[bg]) & 0xFF) / 256.0,
2092 m_pParentXterm->m_pCairo, m_OffsetLeft,
2093 m_OffsetTop + (blankFrom * m_pParentXterm->m_pNormalFont->getHeight()),
2094 m_FbWidth - m_OffsetLeft,
2095 blankLength * m_pParentXterm->m_pNormalFont->getHeight());
2098 cairo_restore(m_pParentXterm->m_pCairo);
2102 m_OffsetTop + (targetY + m_pParentXterm->m_pNormalFont->getHeight()));
2104 m_FbWidth, m_OffsetTop + ((blankFrom + blankLength) *
2105 m_pParentXterm->m_pNormalFont->getHeight()));
2108 &m_pInsert[targetY * m_Stride], &m_pInsert[sourceY * m_Stride],
2109 movedRows * m_Stride *
sizeof(TermChar));
2116 for (
size_t i = blankFrom * m_Stride;
2117 i < (blankFrom + blankLength) * m_Stride; i++)
2118 m_pInsert[i] = blank;
2120 renderArea(rect, 0, targetY, m_Width, movedRows + blankLength);
2123 void Xterm::Window::scrollRegionDown(
size_t numRows,
DirtyRectangle &rect)
2126 klog(LOG_INFO,
"Xterm::Window::scrollRegionDown(%zd)", numRows);
2129 size_t targetY = m_ScrollStart + numRows;
2130 size_t sourceY = m_ScrollStart;
2132 size_t movedRows = (m_ScrollEnd + 1) - targetY;
2133 size_t blankFrom = sourceY;
2134 size_t blankLength = numRows;
2140 m_OffsetTop + (sourceY + m_pParentXterm->m_pNormalFont->getHeight()));
2142 m_OffsetLeft + m_FbWidth,
2143 m_OffsetTop + (movedRows * m_pParentXterm->m_pNormalFont->getHeight()));
2144 m_pParentXterm->m_pTui->redraw(rect);
2147 cairo_save(m_pParentXterm->m_pCairo);
2149 cairo_set_operator(m_pParentXterm->m_pCairo, CAIRO_OPERATOR_SOURCE);
2153 m_pParentXterm->m_pCairo, m_OffsetLeft,
2154 m_OffsetTop + (targetY * m_pParentXterm->m_pNormalFont->getHeight()),
2155 m_FbWidth - m_OffsetLeft,
2156 movedRows * m_pParentXterm->m_pNormalFont->getHeight());
2158 cairo_push_group(m_pParentXterm->m_pCairo);
2159 cairo_set_source_surface(
2160 m_pParentXterm->m_pCairo, m_pParentXterm->m_pCairoSurface, 0,
2161 (
double) (numRows * m_pParentXterm->m_pNormalFont->getHeight()));
2162 cairo_fill_preserve(m_pParentXterm->m_pCairo);
2163 cairo_pop_group_to_source(m_pParentXterm->m_pCairo);
2168 if ((m_pParentXterm->getModes() & Screen) && (bg == g_DefaultBg))
2173 cairo_set_source_rgba(
2174 m_pParentXterm->m_pCairo, ((g_Colours[bg] >> 16) & 0xFF) / 256.0,
2175 ((g_Colours[bg] >> 8) & 0xFF) / 256.0, ((g_Colours[bg]) & 0xFF) / 256.0,
2180 m_pParentXterm->m_pCairo, m_OffsetLeft,
2181 m_OffsetTop + (blankFrom * m_pParentXterm->m_pNormalFont->getHeight()),
2182 m_FbWidth - m_OffsetLeft,
2183 blankLength * m_pParentXterm->m_pNormalFont->getHeight());
2186 cairo_restore(m_pParentXterm->m_pCairo);
2190 m_OffsetTop + (targetY + m_pParentXterm->m_pNormalFont->getHeight()));
2192 m_FbWidth, m_OffsetTop + ((blankFrom + blankLength) *
2193 m_pParentXterm->m_pNormalFont->getHeight()));
2196 &m_pInsert[targetY * m_Stride], &m_pInsert[sourceY * m_Stride],
2197 movedRows * m_Stride *
sizeof(TermChar));
2204 for (
size_t i = blankFrom * m_Stride;
2205 i < (blankFrom + blankLength) * m_Stride; i++)
2206 m_pInsert[i] = blank;
2208 renderArea(rect, 0, blankFrom, m_Width, movedRows + blankLength);
2211 void Xterm::Window::setCursorRelOrigin(
size_t x,
size_t y,
DirtyRectangle &rect)
2214 klog(LOG_INFO,
"Xterm::Window::setCursorRelOrigin(%zd, %zd)", x, y);
2219 setCursor(x, y, rect);
2222 void Xterm::Window::setCursor(
size_t x,
size_t y,
DirtyRectangle &rect)
2225 klog(LOG_INFO,
"Xterm::Window::setCursor(%zd, %zd)", x, y);
2235 klog(LOG_INFO,
"Xterm::Window::setCursorX(%zd)", x);
2238 setCursor(x, m_CursorY, rect);
2243 klog(LOG_INFO,
"Xterm::Window::setCursorY(%zd)", y);
2246 setCursor(m_CursorX, y, rect);
2249 ssize_t Xterm::Window::getCursorX()
const 2253 ssize_t Xterm::Window::getCursorY()
const 2260 if ((m_CursorX > m_LeftMargin) && (m_CursorX <= m_RightMargin))
2261 return m_CursorX - m_LeftMargin;
2266 ssize_t Xterm::Window::getCursorYRelOrigin()
const 2268 if ((m_CursorY > m_ScrollStart) && (m_CursorY <= m_ScrollEnd))
2269 return m_CursorY - m_ScrollStart;
2274 void Xterm::Window::cursorToOrigin()
2277 klog(LOG_INFO,
"Xterm::Window::cursorToOrigin()");
2280 m_CursorX = m_LeftMargin;
2281 m_CursorY = m_ScrollStart;
2287 klog(LOG_INFO,
"Xterm::Window::cursorLeft()");
2290 if (m_CursorX > m_LeftMargin)
2294 void Xterm::Window::cursorLeftNum(
size_t n,
DirtyRectangle &rect)
2297 klog(LOG_INFO,
"Xterm::Window::cursorLeftNum(%zd)", n);
2302 if (m_CursorX < m_LeftMargin)
2303 m_CursorX = m_LeftMargin;
2306 void Xterm::Window::cursorDownAndLeftToMargin(
DirtyRectangle &rect)
2309 klog(LOG_INFO,
"Xterm::Window::cursorDownAndLeftToMargin()");
2312 cursorDown(1, rect);
2313 m_CursorX = m_LeftMargin;
2319 klog(LOG_INFO,
"Xterm::Window::cursorLeftToMargin()");
2322 m_CursorX = m_LeftMargin;
2328 klog(LOG_INFO,
"Xterm::Window::cursorTab()");
2331 bool tabStopFound =
false;
2332 for (ssize_t x = (m_CursorX + 1); x < m_RightMargin; ++x)
2334 if (m_pParentXterm->m_TabStops[x] != 0)
2337 tabStopFound =
true;
2344 m_CursorX = m_RightMargin - 1;
2346 else if (m_CursorX >= m_RightMargin)
2347 m_CursorX = m_RightMargin - 1;
2353 klog(LOG_INFO,
"Xterm::Window::cursorTabBack()");
2356 bool tabStopFound =
false;
2357 for (ssize_t x = (m_CursorX - 1); x >= 0; --x)
2359 if (m_pParentXterm->m_TabStops[x] != 0)
2362 tabStopFound =
true;
2369 m_CursorX = m_LeftMargin;
2371 else if (m_CursorX < m_LeftMargin)
2372 m_CursorX = m_LeftMargin;
2375 void Xterm::Window::fillChar(uint32_t utf32,
DirtyRectangle &rect)
2378 klog(LOG_INFO,
"Xterm::Window::fillChar(%c)", (
char) utf32);
2381 for (ssize_t y = m_ScrollStart; y < m_ScrollEnd; ++y)
2383 for (ssize_t x = m_LeftMargin; x < m_RightMargin; ++x)
2385 setChar(utf32, x, y);
2390 rect, m_LeftMargin, m_ScrollStart, m_RightMargin - m_LeftMargin,
2391 m_ScrollEnd - m_ScrollStart);
2394 void Xterm::Window::addChar(uint32_t utf32,
DirtyRectangle &rect)
2396 #ifdef XTERM_DEBUG_EXTRA 2398 LOG_INFO,
"Xterm::Window::addChar(%c) [@ %zd, %zd]", (
char) utf32,
2399 m_CursorX, m_CursorY);
2406 if (m_CursorX >= (ssize_t) m_Stride)
2409 if (m_pParentXterm->getModes() & Insert)
2412 insertCharacters(1, rect);
2416 setChar(utf32, m_CursorX, m_CursorY);
2417 if (getChar() != tc)
2427 klog(LOG_INFO,
"Xterm::Window::scrollUp(%zd)", n);
2430 scrollRegionDown(n, rect);
2436 klog(LOG_INFO,
"Xterm::Window::scrollDown(%zd)", n);
2439 scrollRegionUp(n, rect);
2445 klog(LOG_INFO,
"Xterm::Window::eraseScreen()");
2448 cairo_save(m_pParentXterm->m_pCairo);
2449 cairo_set_operator(m_pParentXterm->m_pCairo, CAIRO_OPERATOR_SOURCE);
2452 if ((m_pParentXterm->getModes() & Screen) && (bg == g_DefaultBg))
2457 cairo_set_source_rgba(
2458 m_pParentXterm->m_pCairo, ((g_Colours[bg] >> 16) & 0xFF) / 256.0,
2459 ((g_Colours[bg] >> 8) & 0xFF) / 256.0, ((g_Colours[bg]) & 0xFF) / 256.0,
2463 m_pParentXterm->m_pCairo, 0, 0, m_FbWidth,
2464 m_Height * m_pParentXterm->m_pNormalFont->getHeight());
2467 cairo_restore(m_pParentXterm->m_pCairo);
2474 rect.point(m_OffsetLeft, m_OffsetTop);
2476 m_OffsetLeft + m_FbWidth,
2477 m_OffsetTop + (m_Height * m_pParentXterm->m_pNormalFont->getHeight()));
2479 for (
size_t row = 0; row < m_Height; row++)
2481 for (
size_t col = 0; col < m_Width; col++)
2483 setChar(
' ', col, row);
2493 klog(LOG_INFO,
"Xterm::Window::eraseEOL()");
2496 size_t l = (m_CursorX * m_pParentXterm->m_pNormalFont->getWidth());
2498 cairo_save(m_pParentXterm->m_pCairo);
2499 cairo_set_operator(m_pParentXterm->m_pCairo, CAIRO_OPERATOR_SOURCE);
2502 if ((m_pParentXterm->getModes() & Screen) && (bg == g_DefaultBg))
2507 cairo_set_source_rgba(
2508 m_pParentXterm->m_pCairo, ((g_Colours[bg] >> 16) & 0xFF) / 256.0,
2509 ((g_Colours[bg] >> 8) & 0xFF) / 256.0, ((g_Colours[bg]) & 0xFF) / 256.0,
2513 m_pParentXterm->m_pCairo, m_OffsetLeft + l,
2514 m_OffsetTop + (m_CursorY * m_pParentXterm->m_pNormalFont->getHeight()),
2515 m_FbWidth - l, m_pParentXterm->m_pNormalFont->getHeight());
2518 cairo_restore(m_pParentXterm->m_pCairo);
2528 m_OffsetTop + (m_CursorY * m_pParentXterm->m_pNormalFont->getHeight()));
2530 m_OffsetLeft + m_FbWidth,
2532 ((m_CursorY + 1) * m_pParentXterm->m_pNormalFont->getHeight()));
2534 size_t row = m_CursorY;
2535 for (
size_t col = m_CursorX; col < m_Width; col++)
2537 setChar(
' ', col, row);
2540 renderArea(rect, m_CursorX, m_CursorY, m_Width, 1);
2546 klog(LOG_INFO,
"Xterm::Window::eraseSOL()");
2549 cairo_save(m_pParentXterm->m_pCairo);
2550 cairo_set_operator(m_pParentXterm->m_pCairo, CAIRO_OPERATOR_SOURCE);
2553 if ((m_pParentXterm->getModes() & Screen) && (bg == g_DefaultBg))
2558 cairo_set_source_rgba(
2559 m_pParentXterm->m_pCairo, ((g_Colours[bg] >> 16) & 0xFF) / 256.0,
2560 ((g_Colours[bg] >> 8) & 0xFF) / 256.0, ((g_Colours[bg]) & 0xFF) / 256.0,
2564 m_pParentXterm->m_pCairo, m_OffsetLeft,
2565 m_OffsetTop + (m_CursorY * m_pParentXterm->m_pNormalFont->getHeight()),
2566 (m_CursorX + 1) * m_pParentXterm->m_pNormalFont->getWidth(),
2567 m_pParentXterm->m_pNormalFont->getHeight());
2570 cairo_restore(m_pParentXterm->m_pCairo);
2574 m_OffsetTop + (m_CursorY * m_pParentXterm->m_pNormalFont->getHeight()));
2577 ((m_CursorX + 1) * m_pParentXterm->m_pNormalFont->getWidth()),
2579 ((m_CursorY + 1) * m_pParentXterm->m_pNormalFont->getHeight()));
2581 size_t row = m_CursorY;
2582 for (ssize_t col = 0; col <= m_CursorX; col++)
2584 setChar(
' ', col, row);
2587 renderArea(rect, 0, m_CursorY, m_CursorX, 1);
2593 klog(LOG_INFO,
"Xterm::Window::eraseLine()");
2596 cairo_save(m_pParentXterm->m_pCairo);
2597 cairo_set_operator(m_pParentXterm->m_pCairo, CAIRO_OPERATOR_SOURCE);
2600 if ((m_pParentXterm->getModes() & Screen) && (bg == g_DefaultBg))
2605 cairo_set_source_rgba(
2606 m_pParentXterm->m_pCairo, ((g_Colours[bg] >> 16) & 0xFF) / 256.0,
2607 ((g_Colours[bg] >> 8) & 0xFF) / 256.0, ((g_Colours[bg]) & 0xFF) / 256.0,
2611 m_pParentXterm->m_pCairo, m_OffsetLeft,
2612 m_OffsetTop + (m_CursorY * m_pParentXterm->m_pNormalFont->getHeight()),
2613 m_FbWidth - m_OffsetLeft, m_pParentXterm->m_pNormalFont->getHeight());
2616 cairo_restore(m_pParentXterm->m_pCairo);
2620 m_OffsetTop + (m_CursorY * m_pParentXterm->m_pNormalFont->getHeight()));
2622 m_OffsetLeft + m_FbWidth,
2624 ((m_CursorY + 1) * m_pParentXterm->m_pNormalFont->getHeight()));
2626 size_t row = m_CursorY;
2627 for (
size_t col = 0; col < m_Width; col++)
2629 setChar(
' ', col, row);
2632 renderArea(rect, 0, m_CursorY, m_Width, 1);
2638 klog(LOG_INFO,
"Xterm::Window::eraseChars(%zd)", n);
2642 size_t left = (m_CursorX * m_pParentXterm->m_pNormalFont->getWidth());
2643 if ((m_CursorX + (ssize_t) n) > m_RightMargin)
2644 n = m_RightMargin - m_CursorX;
2645 size_t width = n * m_pParentXterm->m_pNormalFont->getWidth();
2647 cairo_save(m_pParentXterm->m_pCairo);
2648 cairo_set_operator(m_pParentXterm->m_pCairo, CAIRO_OPERATOR_SOURCE);
2651 if ((m_pParentXterm->getModes() & Screen) && (bg == g_DefaultBg))
2656 cairo_set_source_rgba(
2657 m_pParentXterm->m_pCairo, ((g_Colours[bg] >> 16) & 0xFF) / 256.0,
2658 ((g_Colours[bg] >> 8) & 0xFF) / 256.0, ((g_Colours[bg]) & 0xFF) / 256.0,
2662 m_pParentXterm->m_pCairo, left,
2663 m_CursorY * m_pParentXterm->m_pNormalFont->getHeight(), width,
2664 m_pParentXterm->m_pNormalFont->getHeight());
2667 cairo_restore(m_pParentXterm->m_pCairo);
2676 m_OffsetTop + (m_CursorY * m_pParentXterm->m_pNormalFont->getHeight()));
2678 m_OffsetLeft + width,
2680 ((m_CursorY + 1) * m_pParentXterm->m_pNormalFont->getHeight()));
2682 size_t row = m_CursorY;
2683 for (
size_t col = m_CursorX; col < (m_CursorX + n); col++)
2685 setChar(
' ', col, row);
2688 renderArea(rect, m_CursorX, m_CursorY, n, 1);
2694 klog(LOG_INFO,
"Xterm::Window::eraseUp()");
2701 cairo_save(m_pParentXterm->m_pCairo);
2702 cairo_set_operator(m_pParentXterm->m_pCairo, CAIRO_OPERATOR_SOURCE);
2705 if ((m_pParentXterm->getModes() & Screen) && (bg == g_DefaultBg))
2710 cairo_set_source_rgba(
2711 m_pParentXterm->m_pCairo, ((g_Colours[bg] >> 16) & 0xFF) / 256.0,
2712 ((g_Colours[bg] >> 8) & 0xFF) / 256.0, ((g_Colours[bg]) & 0xFF) / 256.0,
2716 m_pParentXterm->m_pCairo, m_OffsetLeft, m_OffsetTop, m_FbWidth,
2717 m_pParentXterm->m_pNormalFont->getHeight() * m_CursorY);
2720 cairo_restore(m_pParentXterm->m_pCairo);
2726 rect.point(m_OffsetLeft, m_OffsetTop);
2728 m_OffsetLeft + m_FbWidth,
2730 ((m_CursorY + 1) * m_pParentXterm->m_pNormalFont->getHeight()));
2732 for (ssize_t row = 0; row < m_CursorY; row++)
2734 for (
size_t col = 0; col < m_Width; col++)
2736 setChar(
' ', col, row);
2740 renderArea(rect, 0, 0, m_Width, m_CursorY);
2746 klog(LOG_INFO,
"Xterm::Window::eraseDown()");
2753 size_t eraseStart = m_CursorY + 1;
2755 size_t top = eraseStart * m_pParentXterm->m_pNormalFont->getHeight();
2757 cairo_save(m_pParentXterm->m_pCairo);
2758 cairo_set_operator(m_pParentXterm->m_pCairo, CAIRO_OPERATOR_SOURCE);
2761 if ((m_pParentXterm->getModes() & Screen) && (bg == g_DefaultBg))
2766 cairo_set_source_rgba(
2767 m_pParentXterm->m_pCairo, ((g_Colours[bg] >> 16) & 0xFF) / 256.0,
2768 ((g_Colours[bg] >> 8) & 0xFF) / 256.0, ((g_Colours[bg]) & 0xFF) / 256.0,
2772 m_pParentXterm->m_pCairo, m_OffsetLeft, m_OffsetTop + top, m_FbWidth,
2773 m_pParentXterm->m_pNormalFont->getHeight() * (m_Height - eraseStart));
2776 cairo_restore(m_pParentXterm->m_pCairo);
2782 rect.point(m_OffsetLeft, top + m_OffsetTop);
2784 m_OffsetLeft + m_FbWidth,
2786 ((m_Height - eraseStart) *
2787 m_pParentXterm->m_pNormalFont->getHeight()));
2789 for (
size_t row = eraseStart; row < m_Height; row++)
2791 for (
size_t col = 0; col < m_Width; col++)
2793 setChar(
' ', col, row);
2797 renderArea(rect, 0, eraseStart, m_Width, m_Height - eraseStart);
2803 klog(LOG_INFO,
"Xterm::Window::deleteCharacters(%zd)", n);
2807 ssize_t deleteStart = m_CursorX;
2810 ssize_t deleteEnd = deleteStart + n;
2811 if (deleteEnd > m_RightMargin)
2812 deleteEnd = m_RightMargin;
2815 ssize_t numChars = m_RightMargin - deleteEnd;
2820 &m_pInsert[(m_CursorY * m_Stride) + deleteStart],
2821 &m_pInsert[(m_CursorY * m_Stride) + deleteEnd],
2827 (m_RightMargin - n) * m_pParentXterm->m_pNormalFont->getWidth();
2828 size_t top = m_CursorY * m_pParentXterm->m_pNormalFont->getHeight();
2830 cairo_save(m_pParentXterm->m_pCairo);
2831 cairo_set_operator(m_pParentXterm->m_pCairo, CAIRO_OPERATOR_SOURCE);
2834 if ((m_pParentXterm->getModes() & Screen) && (bg == g_DefaultBg))
2839 cairo_set_source_rgba(
2840 m_pParentXterm->m_pCairo, ((g_Colours[bg] >> 16) & 0xFF) / 256.0,
2841 ((g_Colours[bg] >> 8) & 0xFF) / 256.0, ((g_Colours[bg]) & 0xFF) / 256.0,
2845 m_pParentXterm->m_pCairo, m_OffsetLeft + left, m_OffsetTop + top,
2846 n * m_pParentXterm->m_pNormalFont->getWidth(),
2847 m_pParentXterm->m_pNormalFont->getHeight());
2850 cairo_restore(m_pParentXterm->m_pCairo);
2853 ssize_t row = m_CursorY, col = 0;
2854 for (col = (m_RightMargin - n); col < m_RightMargin; col++)
2856 setChar(
' ', col, row);
2858 for (col = deleteStart; col < m_RightMargin; col++)
2860 render(rect, 0, col, row);
2863 renderArea(rect, deleteStart, m_CursorY, m_RightMargin - deleteStart, 1);
2869 klog(LOG_INFO,
"Xterm::Window::insertCharacters(%zd)", n);
2873 ssize_t insertStart = m_CursorX;
2876 ssize_t insertEnd = insertStart + n;
2879 ssize_t numChars = m_RightMargin - insertEnd;
2883 &m_pInsert[(m_CursorY * m_Stride) + insertEnd],
2884 &m_pInsert[(m_CursorY * m_Stride) + insertStart],
2889 size_t left = insertStart * m_pParentXterm->m_pNormalFont->getWidth();
2890 size_t top = m_CursorY * m_pParentXterm->m_pNormalFont->getHeight();
2892 cairo_save(m_pParentXterm->m_pCairo);
2893 cairo_set_operator(m_pParentXterm->m_pCairo, CAIRO_OPERATOR_SOURCE);
2896 if ((m_pParentXterm->getModes() & Screen) && (bg == g_DefaultBg))
2901 cairo_set_source_rgba(
2902 m_pParentXterm->m_pCairo, ((g_Colours[bg] >> 16) & 0xFF) / 256.0,
2903 ((g_Colours[bg] >> 8) & 0xFF) / 256.0, ((g_Colours[bg]) & 0xFF) / 256.0,
2907 m_pParentXterm->m_pCairo, m_OffsetLeft + left, m_OffsetTop + top,
2908 n * m_pParentXterm->m_pNormalFont->getWidth(),
2909 m_pParentXterm->m_pNormalFont->getHeight());
2912 cairo_restore(m_pParentXterm->m_pCairo);
2914 rect.point(m_OffsetLeft + left, m_OffsetTop + top);
2916 m_OffsetLeft + left + (n * m_pParentXterm->m_pNormalFont->getWidth()),
2917 m_OffsetTop + top + m_pParentXterm->m_pNormalFont->getHeight());
2920 ssize_t row = m_CursorY, col = 0;
2921 for (col = insertStart; col < insertEnd; col++)
2923 setChar(
' ', col, row);
2927 for (col = insertStart; col < m_RightMargin; col++)
2929 render(rect, 0, col, row);
2932 renderArea(rect, insertStart, m_CursorY, m_RightMargin - insertStart, 1);
2938 klog(LOG_INFO,
"Xterm::Window::insertLines(%zd)", n);
2941 if (m_CursorY + (ssize_t) n >= m_ScrollEnd)
2942 n = m_ScrollEnd - m_CursorY;
2947 scrollRegionDown(n, rect);
2953 klog(LOG_INFO,
"Xterm::Window::deleteLines(%zd)", n);
2956 if (m_CursorY + (ssize_t) n >= m_ScrollEnd)
2957 n = m_ScrollEnd - m_CursorY;
2960 scrollRegionUp(n, rect);
2963 void Xterm::Window::lineRender(uint32_t utf32,
DirtyRectangle &rect)
2965 klog(LOG_NOTICE,
"line render: %c", utf32);
2967 size_t left = m_OffsetLeft +
2968 (m_LeftMargin * m_pParentXterm->m_pNormalFont->getWidth()) +
2969 (m_CursorX * m_pParentXterm->m_pNormalFont->getWidth());
2970 size_t top = m_OffsetTop +
2971 (m_ScrollStart * m_pParentXterm->m_pNormalFont->getHeight()) +
2972 (m_CursorY * m_pParentXterm->m_pNormalFont->getHeight());
2975 if (m_CursorX < m_RightMargin)
2978 size_t fullWidth = m_pParentXterm->m_pNormalFont->getWidth();
2979 size_t fullHeight = m_pParentXterm->m_pNormalFont->getHeight();
2981 size_t halfWidth = (fullWidth / 2) + 1;
2982 size_t halfHeight = (fullHeight / 2) + 1;
2986 if ((m_pParentXterm->getModes() & Screen) && (bg == g_DefaultBg) &&
2987 (fg == g_DefaultFg))
2993 uint32_t bgColourInt = g_Colours[bg];
2994 uint32_t fgColourInt = g_Colours[fg];
2996 cairo_save(m_pParentXterm->m_pCairo);
2997 cairo_set_operator(m_pParentXterm->m_pCairo, CAIRO_OPERATOR_SOURCE);
2999 cairo_set_source_rgba(
3000 m_pParentXterm->m_pCairo, ((bgColourInt >> 16) & 0xFF) / 256.0,
3001 ((bgColourInt >> 8) & 0xFF) / 256.0, (bgColourInt & 0xFF) / 256.0, 0.8);
3003 cairo_rectangle(m_pParentXterm->m_pCairo, left, top, fullWidth, fullHeight);
3004 cairo_fill(m_pParentXterm->m_pCairo);
3006 cairo_set_source_rgba(
3007 m_pParentXterm->m_pCairo, ((fgColourInt >> 16) & 0xFF) / 256.0,
3008 ((fgColourInt >> 8) & 0xFF) / 256.0, (fgColourInt & 0xFF) / 256.0, 1.0);
3013 rect.point(m_OffsetLeft + left, m_OffsetTop + top);
3014 rect.point(m_OffsetLeft + left + fullWidth, m_OffsetTop + top + fullHeight);
3016 switch (utf32 & 0xFF)
3022 cairo_move_to(m_pParentXterm->m_pCairo, left, top + halfHeight);
3024 m_pParentXterm->m_pCairo, left + halfWidth, top + halfHeight);
3025 cairo_stroke(m_pParentXterm->m_pCairo);
3031 cairo_move_to(m_pParentXterm->m_pCairo, left + halfWidth, top);
3033 m_pParentXterm->m_pCairo, left + halfWidth, top + halfHeight);
3034 cairo_stroke(m_pParentXterm->m_pCairo);
3043 cairo_move_to(m_pParentXterm->m_pCairo, left, top + halfHeight);
3045 m_pParentXterm->m_pCairo, left + halfWidth, top + halfHeight);
3046 cairo_stroke(m_pParentXterm->m_pCairo);
3053 m_pParentXterm->m_pCairo, left + halfWidth, top + halfHeight);
3055 m_pParentXterm->m_pCairo, left + halfWidth, top + fullHeight);
3056 cairo_stroke(m_pParentXterm->m_pCairo);
3067 m_pParentXterm->m_pCairo, left + halfWidth, top + halfHeight);
3069 m_pParentXterm->m_pCairo, left + fullWidth, top + halfHeight);
3070 cairo_stroke(m_pParentXterm->m_pCairo);
3078 m_pParentXterm->m_pCairo, left + halfWidth, top + halfHeight);
3080 m_pParentXterm->m_pCairo, left + halfWidth, top + fullHeight);
3081 cairo_stroke(m_pParentXterm->m_pCairo);
3091 cairo_move_to(m_pParentXterm->m_pCairo, left + halfWidth, top);
3093 m_pParentXterm->m_pCairo, left + halfWidth, top + halfHeight);
3094 cairo_stroke(m_pParentXterm->m_pCairo);
3101 m_pParentXterm->m_pCairo, left + halfWidth, top + halfHeight);
3103 m_pParentXterm->m_pCairo, left + fullWidth, top + halfHeight);
3104 cairo_stroke(m_pParentXterm->m_pCairo);
3114 cairo_move_to(m_pParentXterm->m_pCairo, left, top + halfHeight);
3116 m_pParentXterm->m_pCairo, left + fullWidth, top + halfHeight);
3117 cairo_stroke(m_pParentXterm->m_pCairo);
3123 cairo_move_to(m_pParentXterm->m_pCairo, left + halfWidth, top);
3125 m_pParentXterm->m_pCairo, left + halfWidth, top + fullHeight);
3126 cairo_stroke(m_pParentXterm->m_pCairo);
3135 cairo_move_to(m_pParentXterm->m_pCairo, left, top + halfHeight);
3137 m_pParentXterm->m_pCairo, left + fullWidth, top + halfHeight);
3138 cairo_stroke(m_pParentXterm->m_pCairo);
3145 cairo_move_to(m_pParentXterm->m_pCairo, left + halfWidth, top);
3147 m_pParentXterm->m_pCairo, left + halfWidth, top + fullHeight);
3148 cairo_stroke(m_pParentXterm->m_pCairo);
3153 m_pParentXterm->m_pCairo, left + halfWidth, top + halfHeight);
3155 m_pParentXterm->m_pCairo, left + fullWidth, top + halfHeight);
3156 cairo_stroke(m_pParentXterm->m_pCairo);
3166 cairo_move_to(m_pParentXterm->m_pCairo, left + halfWidth, top);
3168 m_pParentXterm->m_pCairo, left + halfWidth, top + fullHeight);
3169 cairo_stroke(m_pParentXterm->m_pCairo);
3175 cairo_move_to(m_pParentXterm->m_pCairo, left, top + halfHeight);
3177 m_pParentXterm->m_pCairo, left + halfWidth, top + halfHeight);
3178 cairo_stroke(m_pParentXterm->m_pCairo);
3187 cairo_move_to(m_pParentXterm->m_pCairo, left, top + halfHeight);
3189 m_pParentXterm->m_pCairo, left + fullWidth, top + halfHeight);
3190 cairo_stroke(m_pParentXterm->m_pCairo);
3196 cairo_move_to(m_pParentXterm->m_pCairo, left + halfWidth, top);
3198 m_pParentXterm->m_pCairo, left + halfWidth, top + halfHeight);
3199 cairo_stroke(m_pParentXterm->m_pCairo);
3208 cairo_move_to(m_pParentXterm->m_pCairo, left, top + halfHeight);
3210 m_pParentXterm->m_pCairo, left + fullWidth, top + halfHeight);
3211 cairo_stroke(m_pParentXterm->m_pCairo);
3218 m_pParentXterm->m_pCairo, left + halfWidth, top + halfHeight);
3220 m_pParentXterm->m_pCairo, left + halfWidth, top + fullHeight);
3221 cairo_stroke(m_pParentXterm->m_pCairo);
3231 cairo_move_to(m_pParentXterm->m_pCairo, left + halfWidth, top);
3233 m_pParentXterm->m_pCairo, left + halfWidth, top + fullHeight);
3234 cairo_stroke(m_pParentXterm->m_pCairo);
3243 cairo_restore(m_pParentXterm->m_pCairo);
3248 if (m_CursorX >= m_RightMargin)
3252 if (m_pParentXterm->getModes() & AutoWrap)
3254 m_CursorX = m_LeftMargin;
3261 m_CursorX = m_RightMargin - 1;
3270 if (m_CursorY < m_ScrollStart)
3273 size_t numRows = (m_ScrollStart - m_CursorY);
3274 scrollRegionDown(numRows, rect);
3275 m_CursorY = m_ScrollStart;
3277 else if (m_CursorY > m_ScrollEnd)
3280 size_t numRows = (m_CursorY - m_ScrollEnd);
3281 scrollRegionUp(numRows, rect);
3282 m_CursorY = m_ScrollEnd;
3289 klog(LOG_INFO,
"Xterm::Window::invert()");
3293 for (
size_t y = 0; y < m_Height; y++)
3295 for (
size_t x = 0; x < m_Width; x++)
3297 TermChar *pChar = &m_pView[(y * m_Stride) + x];
3298 if ((pChar->fore == g_DefaultFg) && (pChar->back == g_DefaultBg))
3300 uint8_t fore = pChar->fore;
3301 pChar->fore = pChar->back;
3308 renderAll(rect,
this);
3314 klog(LOG_INFO,
"Xterm::Window::setTabStop() [@%zd]", m_CursorX);
3317 m_pParentXterm->m_TabStops[m_CursorX] =
'|';
3323 klog(LOG_INFO,
"Xterm::Window::clearTabStop() [@%zd]", m_CursorX);
3326 m_pParentXterm->m_TabStops[m_CursorX] = 0;
3332 klog(LOG_INFO,
"Xterm::Window::clearAllTabStops()");
3335 memset(m_pParentXterm->m_TabStops, 0, m_Stride);
void processKey(uint64_t key)
void write(uint32_t utf32, DirtyRectangle &rect)
void eraseLine(DirtyRectangle &rect)
ssize_t getCursorXRelOrigin() const
void renderAll(DirtyRectangle &rect)
void insertLines(size_t n, DirtyRectangle &rect)
void eraseScreen(DirtyRectangle &rect)
void eraseDown(DirtyRectangle &rect)
void insertCharacters(size_t n, DirtyRectangle &rect)
void eraseChars(size_t n, DirtyRectangle &rect)
size_t getNum(size_t row, size_t col)
Returns the value in column 'col' of the result, in number form.
Result * query(const char *sql)
void eraseUp(DirtyRectangle &rect)
void eraseEOL(DirtyRectangle &rect)
bool succeeded()
Returns true if the result is valid, false if there was an error.
void deleteLines(size_t n, DirtyRectangle &rect)
void eraseSOL(DirtyRectangle &rect)
void checkScroll(DirtyRectangle &rect)
void deleteCharacters(size_t n, DirtyRectangle &rect)
std::string errorMessage(size_t buffSz=256)
Returns the error message.
void checkWrap(DirtyRectangle &rect)