void CScreenDevice::ClearDisplayEnd (void) { ClearLineEnd (); unsigned nPosY = m_nCursorY + m_CharGen.GetCharHeight (); unsigned nOffset = nPosY * m_nPitch; TScreenColor *pBuffer = m_pBuffer + nOffset; unsigned nSize = m_nSize / sizeof (TScreenColor) - nOffset; while (nSize--) { *pBuffer++ = BLACK_COLOR; } }
void CScreenDevice::Write (char chChar) { switch (m_nState) { case ScreenStateStart: switch (chChar) { case '\b': CursorLeft (); break; case '\t': Tabulator (); break; case '\n': NewLine (); break; case '\r': CarriageReturn (); break; case '\x1b': m_nState = ScreenStateEscape; break; default: DisplayChar (chChar); break; } break; case ScreenStateEscape: switch (chChar) { case 'M': ReverseScroll (); m_nState = ScreenStateStart; break; case '[': m_nState = ScreenStateBracket; break; default: m_nState = ScreenStateStart; break; } break; case ScreenStateBracket: switch (chChar) { case '?': m_nState = ScreenStateQuestionMark; break; case 'A': CursorUp (); m_nState = ScreenStateStart; break; case 'B': CursorDown (); m_nState = ScreenStateStart; break; case 'C': CursorRight (); m_nState = ScreenStateStart; break; case 'H': CursorHome (); m_nState = ScreenStateStart; break; case 'J': ClearDisplayEnd (); m_nState = ScreenStateStart; break; case 'K': ClearLineEnd (); m_nState = ScreenStateStart; break; case 'L': InsertLines (1); m_nState = ScreenStateStart; break; case 'M': DeleteLines (1); m_nState = ScreenStateStart; break; case 'P': DeleteChars (1); m_nState = ScreenStateStart; break; default: if ('0' <= chChar && chChar <= '9') { m_nParam1 = chChar - '0'; m_nState = ScreenStateNumber1; } else { m_nState = ScreenStateStart; } break; } break; case ScreenStateNumber1: switch (chChar) { case ';': m_nState = ScreenStateSemicolon; break; case 'L': InsertLines (m_nParam1); m_nState = ScreenStateStart; break; case 'M': DeleteLines (m_nParam1); m_nState = ScreenStateStart; break; case 'P': DeleteChars (m_nParam1); m_nState = ScreenStateStart; break; case 'X': EraseChars (m_nParam1); m_nState = ScreenStateStart; break; case 'h': case 'l': if (m_nParam1 == 4) { InsertMode (chChar == 'h'); } m_nState = ScreenStateStart; break; case 'm': SetStandoutMode (m_nParam1); m_nState = ScreenStateStart; break; default: if ('0' <= chChar && chChar <= '9') { m_nParam1 *= 10; m_nParam1 += chChar - '0'; if (m_nParam1 > 99) { m_nState = ScreenStateStart; } } else { m_nState = ScreenStateStart; } break; } break; case ScreenStateSemicolon: if ('0' <= chChar && chChar <= '9') { m_nParam2 = chChar - '0'; m_nState = ScreenStateNumber2; } else { m_nState = ScreenStateStart; } break; case ScreenStateQuestionMark: if ('0' <= chChar && chChar <= '9') { m_nParam1 = chChar - '0'; m_nState = ScreenStateNumber3; } else { m_nState = ScreenStateStart; } break; case ScreenStateNumber2: switch (chChar) { case 'H': CursorMove (m_nParam1, m_nParam2); m_nState = ScreenStateStart; break; case 'r': SetScrollRegion (m_nParam1, m_nParam2); m_nState = ScreenStateStart; break; default: if ('0' <= chChar && chChar <= '9') { m_nParam2 *= 10; m_nParam2 += chChar - '0'; if (m_nParam2 > 199) { m_nState = ScreenStateStart; } } else { m_nState = ScreenStateStart; } break; } break; case ScreenStateNumber3: switch (chChar) { case 'h': case 'l': if (m_nParam1 == 25) { SetCursorMode (chChar == 'h'); } m_nState = ScreenStateStart; break; default: if ('0' <= chChar && chChar <= '9') { m_nParam1 *= 10; m_nParam1 += chChar - '0'; if (m_nParam1 > 99) { m_nState = ScreenStateStart; } } else { m_nState = ScreenStateStart; } break; } break; default: m_nState = ScreenStateStart; break; } }
/*! * \brief Read a line. * * This functions offers some editing capabilities and is typically * used for text input by human users. * * Line editing can be done by entering any of the following control * characters: * * - \ref EDIT_KEY_RESTORE Restores initial default line (default ESC) * - \ref EDIT_KEY_REMOVE Deletes character on the left of the cursor (default CTRL-H) * - \ref EDIT_KEY_HOME Moves cursor to the beginning of the line (default Ctrl-A). * - \ref EDIT_KEY_END Moves cursor to the beginning of the line (default CTRL-E) * - \ref EDIT_KEY_LEFT Moves cursor one character to the left (default CTRL-B) * - \ref EDIT_KEY_RIGHT Moves cursor one character to the right (default CTRL-F) * - \ref EDIT_KEY_UP Walks up the list of previously entered lines (default CTRL-R) * - \ref EDIT_KEY_DOWN Walks down the list of previously entered lines (default CTRL-V) * * Note, that these commands may be modified by the currently registered * remapping routine. * * \param el Pointer to an \ref EDLINE structure, obtained by a * previous call to \ref EdLineOpen. * \param buf Pointer to the buffer that receives the text line. * If it contains a string on entry, this will be used * as the default value. * \param siz Number of bytes available in the buffer. The maximum * length of the text string is 1 less, so the string * is always properly terminated. * * \return Number of characters or -1 on errors. * * \todo Hidden entry for password input. */ int EdLineRead(EDLINE *el, char *buf, int siz) { int ch; int cpos; int i; #ifndef EDIT_DISABLE_HISTORY int ipos; int hidx = 0; int refresh = 0; #endif /* Make sure that the string is terminated. */ buf[siz - 1] = '\0'; #ifndef EDIT_DISABLE_HISTORY EditHistorySet(el->el_hist, 0, buf); #endif PrintString(el, buf); cpos = strlen(buf); for (;;) { ch = (*el->el_get)(el->el_iparm); if (ch == EOF) { return -1; } ch = (*el->el_map)(ch, &el->el_seq); if (ch == EDIT_KEY_ENTER) { break; } /* Backspace removes the character in front of the cursor. */ if (ch == EDIT_KEY_REMOVE) { if (cpos) { cpos--; for (i = cpos; i < siz - 1; i++) { buf[i] = buf[i + 1]; } if (el->el_mode & EDIT_MODE_ECHO) { (*el->el_put)(el->el_oparm, EDIT_CHAR_BACKSPACE); } PrintString(el, &buf[cpos]); (*el->el_put)(el->el_oparm, EDIT_CHAR_SPACE); PrintCharacter(el, EDIT_CHAR_BACKSPACE, strlen(buf) + 1 - cpos); } } #ifndef EDIT_DISABLE_HISTORY else if (ch == EDIT_KEY_RESTORE) { hidx = 0; refresh = 1; } else if (ch == EDIT_KEY_UP) { if (EditHistoryGet(el->el_hist, hidx + 1, NULL, 0) >= 0) { hidx++; refresh = 1; } } else if (ch == EDIT_KEY_DOWN) { if (hidx > 0) { hidx--; refresh = 1; } } #endif else if (ch == EDIT_KEY_RIGHT) { if (cpos < strlen(buf)) { if (el->el_mode & EDIT_MODE_ECHO) { (*el->el_put)(el->el_oparm, buf[cpos]); } cpos++; } } else if (ch == EDIT_KEY_LEFT) { if (cpos) { if (el->el_mode & EDIT_MODE_ECHO) { (*el->el_put)(el->el_oparm, EDIT_CHAR_BACKSPACE); } cpos--; } } else if (ch == EDIT_KEY_HOME) { PrintCharacter(el, EDIT_CHAR_BACKSPACE, cpos); cpos = 0; } else if (ch == EDIT_KEY_END) { PrintString(el, &buf[cpos]); cpos = strlen(buf); } /* Normal character, insert at cursor position if buffer is not full. */ else if (isprint(ch) && strlen(buf) < siz - 1) { for (i = siz - 1; i > cpos; i--) { buf[i] = buf[i - 1]; } buf[cpos++] = ch; if (el->el_mode & EDIT_MODE_ECHO) { (*el->el_put)(el->el_oparm, ch); } PrintString(el, &buf[cpos]); PrintCharacter(el, EDIT_CHAR_BACKSPACE, strlen(buf) - cpos); } else { /* Beep on buffer overflow. */ (*el->el_put)(el->el_oparm, EDIT_CHAR_ALARM); } #ifndef EDIT_DISABLE_HISTORY if (refresh && (el->el_mode & EDIT_MODE_HISTORY) != 0) { refresh = 0; PrintCharacter(el, EDIT_CHAR_BACKSPACE, cpos); ipos = strlen(buf); EditHistoryGet(el->el_hist, hidx, buf, siz); cpos = strlen(buf); PrintString(el, buf); ClearLineEnd(el, ipos - cpos); } #endif } PrintString(el, EDIT_STR_EOL); #ifndef EDIT_DISABLE_HISTORY EditHistoryInsert(el->el_hist, 1, buf); #endif return strlen(buf); }