mirror of
https://github.com/Swordfish90/cool-retro-term.git
synced 2025-04-18 16:50:47 +01:00
794 lines
32 KiB
C++
794 lines
32 KiB
C++
/**************************************************************************************************
|
|
* Copyright (c) 2012 Jørgen Lind
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
|
* associated documentation files (the "Software"), to deal in the Software without restriction,
|
|
* including without limitation the rights to use, copy, modify, merge, publish, distribute,
|
|
* sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
|
|
* furnished to do so, subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be included in all copies or
|
|
* substantial portions of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
|
|
* NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
|
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
|
|
* OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
*
|
|
***************************************************************************************************/
|
|
|
|
#include "parser.h"
|
|
|
|
#include "controll_chars.h"
|
|
#include "screen.h"
|
|
|
|
#include <QtCore/QDebug>
|
|
|
|
|
|
static bool yat_parser_debug = qEnvironmentVariableIsSet("YAT_PARSER_DEBUG");
|
|
|
|
Parser::Parser(Screen *screen)
|
|
: m_decode_state(PlainText)
|
|
, m_current_token_start(0)
|
|
, m_currrent_position(0)
|
|
, m_intermediate_char(QChar())
|
|
, m_parameters(10)
|
|
, m_screen(screen)
|
|
{
|
|
}
|
|
|
|
void Parser::addData(const QByteArray &data)
|
|
{
|
|
m_current_token_start = 0;
|
|
m_current_data = data;
|
|
for (m_currrent_position = 0; m_currrent_position < data.size(); m_currrent_position++) {
|
|
uchar character = data.at(m_currrent_position);
|
|
switch (m_decode_state) {
|
|
case PlainText:
|
|
//UTF-8
|
|
if (character > 127)
|
|
continue;
|
|
if (character < C0::C0_END ||
|
|
(character >= C1_8bit::C1_8bit_Start &&
|
|
character <= C1_8bit::C1_8bit_Stop)) {
|
|
if (m_currrent_position != m_current_token_start) {
|
|
m_screen->replaceAtCursor(QString::fromUtf8(data.mid(m_current_token_start,
|
|
m_currrent_position - m_current_token_start)));
|
|
tokenFinished();
|
|
m_current_token_start--;
|
|
}
|
|
m_decode_state = DecodeC0;
|
|
decodeC0(data.at(m_currrent_position));
|
|
}
|
|
break;
|
|
case DecodeC0:
|
|
decodeC0(character);
|
|
break;
|
|
case DecodeC1_7bit:
|
|
decodeC1_7bit(character);
|
|
break;
|
|
case DecodeCSI:
|
|
decodeCSI(character);
|
|
break;
|
|
case DecodeOSC:
|
|
decodeOSC(character);
|
|
break;
|
|
case DecodeOtherEscape:
|
|
decodeOtherEscape(character);
|
|
break;
|
|
}
|
|
|
|
}
|
|
if (m_decode_state == PlainText) {
|
|
QByteArray text = data.mid(m_current_token_start);
|
|
if (text.size()) {
|
|
m_screen->replaceAtCursor(QString::fromUtf8(text));
|
|
tokenFinished();
|
|
}
|
|
}
|
|
m_current_data = QByteArray();
|
|
}
|
|
|
|
void Parser::decodeC0(uchar character)
|
|
{
|
|
if (yat_parser_debug)
|
|
qDebug() << C0::C0(character);
|
|
switch (character) {
|
|
case C0::NUL:
|
|
case C0::SOH:
|
|
case C0::STX:
|
|
case C0::ETX:
|
|
case C0::EOT:
|
|
case C0::ENQ:
|
|
case C0::ACK:
|
|
qDebug() << "Unhandled" << C0::C0(character);
|
|
tokenFinished();
|
|
break;
|
|
case C0::BEL:
|
|
m_screen->scheduleFlash();
|
|
tokenFinished();
|
|
break;
|
|
case C0::BS:
|
|
m_screen->backspace();
|
|
tokenFinished();
|
|
break;
|
|
case C0::HT: {
|
|
int x = m_screen->cursorPosition().x();
|
|
int spaces = 8 - (x % 8);
|
|
m_screen->replaceAtCursor(QString(spaces,' '));
|
|
}
|
|
tokenFinished();
|
|
break;
|
|
case C0::LF:
|
|
m_screen->lineFeed();
|
|
tokenFinished();
|
|
break;
|
|
case C0::VT:
|
|
case C0::FF:
|
|
qDebug() << "Unhandled" << C0::C0(character);
|
|
tokenFinished();
|
|
break;
|
|
case C0::CR:
|
|
m_screen->moveCursorHome();
|
|
tokenFinished();
|
|
//next should be a linefeed;
|
|
break;
|
|
case C0::SOorLS1:
|
|
case C0::SIorLS0:
|
|
case C0::DLE:
|
|
case C0::DC1:
|
|
case C0::DC2:
|
|
case C0::DC3:
|
|
case C0::DC4:
|
|
case C0::NAK:
|
|
case C0::SYN:
|
|
case C0::ETB:
|
|
case C0::CAN:
|
|
case C0::EM:
|
|
case C0::SUB:
|
|
qDebug() << "Unhandled" << C0::C0(character);
|
|
tokenFinished();
|
|
break;
|
|
case C0::ESC:
|
|
m_decode_state = DecodeC1_7bit;
|
|
break;
|
|
case C0::IS4:
|
|
case C0::IS3:
|
|
case C0::IS2:
|
|
case C0::IS1:
|
|
default:
|
|
qDebug() << "Unhandled" << C0::C0(character);
|
|
tokenFinished();
|
|
break;
|
|
}
|
|
}
|
|
|
|
void Parser::decodeC1_7bit(uchar character)
|
|
{
|
|
if (yat_parser_debug)
|
|
qDebug() << C1_7bit::C1_7bit(character);
|
|
switch(character) {
|
|
case C1_7bit::CSI:
|
|
m_decode_state = DecodeCSI;
|
|
break;
|
|
case C1_7bit::OSC:
|
|
m_decode_state = DecodeOSC;
|
|
break;
|
|
case C1_7bit::RI:
|
|
m_screen->reverseLineFeed();
|
|
tokenFinished();
|
|
break;
|
|
case '%':
|
|
case '#':
|
|
case '(':
|
|
m_parameters.append(-character);
|
|
m_decode_state = DecodeOtherEscape;
|
|
break;
|
|
case '=':
|
|
qDebug() << "Application keypad";
|
|
tokenFinished();
|
|
break;
|
|
case '>':
|
|
qDebug() << "Normal keypad mode";
|
|
tokenFinished();
|
|
break;
|
|
default:
|
|
qDebug() << "Unhandled" << C1_7bit::C1_7bit(character);
|
|
tokenFinished();
|
|
}
|
|
}
|
|
|
|
void Parser::decodeParameters(uchar character)
|
|
{
|
|
switch (character) {
|
|
case 0x30:
|
|
case 0x31:
|
|
case 0x32:
|
|
case 0x33:
|
|
case 0x34:
|
|
case 0x35:
|
|
case 0x36:
|
|
case 0x37:
|
|
case 0x38:
|
|
case 0x39:
|
|
m_parameter_string.append(character);
|
|
break;
|
|
case 0x3a:
|
|
qDebug() << "Encountered special delimiter in parameterbyte";
|
|
break;
|
|
case 0x3b:
|
|
appendParameter();
|
|
break;
|
|
case 0x3c:
|
|
case 0x3d:
|
|
case 0x3e:
|
|
case 0x3f:
|
|
appendParameter();
|
|
m_parameters.append(-character);
|
|
break;
|
|
default:
|
|
//this is undefined for now
|
|
qDebug() << "Encountered undefined parameter byte";
|
|
break;
|
|
}
|
|
}
|
|
|
|
void Parser::decodeCSI(uchar character)
|
|
{
|
|
if (character >= 0x30 && character <= 0x3f) {
|
|
decodeParameters(character);
|
|
} else {
|
|
if (character >= 0x20 && character <= 0x2f) {
|
|
if (m_intermediate_char.unicode())
|
|
qDebug() << "Warning!: double intermediate bytes found in CSI";
|
|
m_intermediate_char = character;
|
|
} else if (character >= 0x40 && character <= 0x7d) {
|
|
if (m_intermediate_char.unicode()) {
|
|
if (yat_parser_debug)
|
|
qDebug() << FinalBytesSingleIntermediate::FinalBytesSingleIntermediate(character);
|
|
switch (character) {
|
|
case FinalBytesSingleIntermediate::SL:
|
|
case FinalBytesSingleIntermediate::SR:
|
|
case FinalBytesSingleIntermediate::GSM:
|
|
case FinalBytesSingleIntermediate::GSS:
|
|
case FinalBytesSingleIntermediate::FNT:
|
|
case FinalBytesSingleIntermediate::TSS:
|
|
case FinalBytesSingleIntermediate::JFY:
|
|
case FinalBytesSingleIntermediate::SPI:
|
|
case FinalBytesSingleIntermediate::QUAD:
|
|
case FinalBytesSingleIntermediate::SSU:
|
|
case FinalBytesSingleIntermediate::PFS:
|
|
case FinalBytesSingleIntermediate::SHS:
|
|
case FinalBytesSingleIntermediate::SVS:
|
|
case FinalBytesSingleIntermediate::IGS:
|
|
case FinalBytesSingleIntermediate::IDCS:
|
|
case FinalBytesSingleIntermediate::PPA:
|
|
case FinalBytesSingleIntermediate::PPR:
|
|
case FinalBytesSingleIntermediate::PPB:
|
|
case FinalBytesSingleIntermediate::SPD:
|
|
case FinalBytesSingleIntermediate::DTA:
|
|
case FinalBytesSingleIntermediate::SHL:
|
|
case FinalBytesSingleIntermediate::SLL:
|
|
case FinalBytesSingleIntermediate::FNK:
|
|
case FinalBytesSingleIntermediate::SPQR:
|
|
case FinalBytesSingleIntermediate::SEF:
|
|
case FinalBytesSingleIntermediate::PEC:
|
|
case FinalBytesSingleIntermediate::SSW:
|
|
case FinalBytesSingleIntermediate::SACS:
|
|
case FinalBytesSingleIntermediate::SAPV:
|
|
case FinalBytesSingleIntermediate::STAB:
|
|
case FinalBytesSingleIntermediate::GCC:
|
|
case FinalBytesSingleIntermediate::TATE:
|
|
case FinalBytesSingleIntermediate::TALE:
|
|
case FinalBytesSingleIntermediate::TAC:
|
|
case FinalBytesSingleIntermediate::TCC:
|
|
case FinalBytesSingleIntermediate::TSR:
|
|
case FinalBytesSingleIntermediate::SCO:
|
|
case FinalBytesSingleIntermediate::SRCS:
|
|
case FinalBytesSingleIntermediate::SCS:
|
|
case FinalBytesSingleIntermediate::SLS:
|
|
case FinalBytesSingleIntermediate::SCP:
|
|
default:
|
|
qDebug() << "unhandled CSI" << FinalBytesSingleIntermediate::FinalBytesSingleIntermediate(character);
|
|
tokenFinished();
|
|
break;
|
|
}
|
|
} else {
|
|
if (yat_parser_debug)
|
|
qDebug() << FinalBytesNoIntermediate::FinalBytesNoIntermediate(character);
|
|
switch (character) {
|
|
case FinalBytesNoIntermediate::ICH: {
|
|
appendParameter();
|
|
int n_chars = m_parameters.size() ? m_parameters.at(0) : 1;
|
|
qDebug() << "ICH WITH n_chars" << n_chars;
|
|
m_screen->insertEmptyCharsAtCursor(n_chars);
|
|
tokenFinished();
|
|
}
|
|
break;
|
|
case FinalBytesNoIntermediate::CUU: {
|
|
appendParameter();
|
|
Q_ASSERT(m_parameters.size() < 2);
|
|
int move_up = m_parameters.size() ? m_parameters.at(0) : 1;
|
|
m_screen->moveCursorUp(move_up);
|
|
tokenFinished();
|
|
}
|
|
break;
|
|
case FinalBytesNoIntermediate::CUD:
|
|
tokenFinished();
|
|
qDebug() << "unhandled CSI" << FinalBytesNoIntermediate::FinalBytesNoIntermediate(character);
|
|
break;
|
|
case FinalBytesNoIntermediate::CUF:{
|
|
appendParameter();
|
|
Q_ASSERT(m_parameters.size() < 2);
|
|
int move_right = m_parameters.size() ? m_parameters.at(0) : 1;
|
|
m_screen->moveCursorRight(move_right);
|
|
tokenFinished();
|
|
}
|
|
break;
|
|
case FinalBytesNoIntermediate::CUB:
|
|
case FinalBytesNoIntermediate::CNL:
|
|
case FinalBytesNoIntermediate::CPL:
|
|
qDebug() << "unhandled CSI" << FinalBytesNoIntermediate::FinalBytesNoIntermediate(character);
|
|
tokenFinished();
|
|
break;
|
|
case FinalBytesNoIntermediate::CHA: {
|
|
appendParameter();
|
|
Q_ASSERT(m_parameters.size() < 2);
|
|
int move_to_pos_on_line = m_parameters.size() ? m_parameters.at(0) : 1;
|
|
m_screen->moveCursorToCharacter(move_to_pos_on_line);
|
|
}
|
|
tokenFinished();
|
|
break;
|
|
case FinalBytesNoIntermediate::CUP:
|
|
appendParameter();
|
|
if (!m_parameters.size()) {
|
|
m_screen->moveCursorTop();
|
|
m_screen->moveCursorHome();
|
|
} else if (m_parameters.size() == 2){
|
|
m_screen->moveCursor(m_parameters.at(1), m_parameters.at(0));
|
|
} else {
|
|
qDebug() << "OHOHOHOH";
|
|
}
|
|
tokenFinished();
|
|
break;
|
|
case FinalBytesNoIntermediate::CHT:
|
|
tokenFinished();
|
|
qDebug() << "unhandled CSI" << FinalBytesNoIntermediate::FinalBytesNoIntermediate(character);
|
|
break;
|
|
case FinalBytesNoIntermediate::ED:
|
|
appendParameter();
|
|
if (!m_parameters.size()) {
|
|
m_screen->eraseFromCurrentLineToEndOfScreen();
|
|
} else {
|
|
switch (m_parameters.at(0)) {
|
|
case 1:
|
|
m_screen->eraseFromCurrentLineToBeginningOfScreen();
|
|
break;
|
|
case 2:
|
|
m_screen->eraseScreen();
|
|
break;
|
|
default:
|
|
qDebug() << "Invalid parameter value for FinalBytesNoIntermediate::ED";
|
|
}
|
|
}
|
|
|
|
tokenFinished();
|
|
break;
|
|
case FinalBytesNoIntermediate::EL:
|
|
appendParameter();
|
|
if (!m_parameters.size() || m_parameters.at(0) == 0) {
|
|
m_screen->eraseFromCursorPositionToEndOfLine();
|
|
} else if (m_parameters.at(0) == 1) {
|
|
m_screen->eraseToCursorPosition();
|
|
} else if (m_parameters.at(0) == 2) {
|
|
m_screen->eraseLine();
|
|
} else{
|
|
qDebug() << "Fault when processing FinalBytesNoIntermediate::EL";
|
|
}
|
|
tokenFinished();
|
|
break;
|
|
case FinalBytesNoIntermediate::IL: {
|
|
appendParameter();
|
|
int count = 1;
|
|
if (m_parameters.size()) {
|
|
count = m_parameters.at(0);
|
|
}
|
|
m_screen->insertLines(count);
|
|
tokenFinished();
|
|
}
|
|
break;
|
|
case FinalBytesNoIntermediate::DL: {
|
|
appendParameter();
|
|
int count = 1;
|
|
if (m_parameters.size()) {
|
|
count = m_parameters.at(0);
|
|
}
|
|
m_screen->deleteLines(count);
|
|
tokenFinished();
|
|
}
|
|
break;
|
|
case FinalBytesNoIntermediate::EF:
|
|
case FinalBytesNoIntermediate::EA:
|
|
qDebug() << "unhandled CSI" << FinalBytesNoIntermediate::FinalBytesNoIntermediate(character);
|
|
tokenFinished();
|
|
break;
|
|
case FinalBytesNoIntermediate::DCH:{
|
|
appendParameter();
|
|
Q_ASSERT(m_parameters.size() < 2);
|
|
int n_chars = m_parameters.size() ? m_parameters.at(0) : 1;
|
|
m_screen->deleteCharacters(n_chars);
|
|
}
|
|
tokenFinished();
|
|
break;
|
|
case FinalBytesNoIntermediate::SSE:
|
|
case FinalBytesNoIntermediate::CPR:
|
|
case FinalBytesNoIntermediate::SU:
|
|
case FinalBytesNoIntermediate::SD:
|
|
case FinalBytesNoIntermediate::NP:
|
|
case FinalBytesNoIntermediate::PP:
|
|
case FinalBytesNoIntermediate::CTC:
|
|
case FinalBytesNoIntermediate::ECH:
|
|
case FinalBytesNoIntermediate::CVT:
|
|
case FinalBytesNoIntermediate::CBT:
|
|
case FinalBytesNoIntermediate::SRS:
|
|
case FinalBytesNoIntermediate::PTX:
|
|
case FinalBytesNoIntermediate::SDS:
|
|
case FinalBytesNoIntermediate::SIMD:
|
|
case FinalBytesNoIntermediate::HPA:
|
|
case FinalBytesNoIntermediate::HPR:
|
|
case FinalBytesNoIntermediate::REP:
|
|
qDebug() << "unhandled CSI" << FinalBytesNoIntermediate::FinalBytesNoIntermediate(character);
|
|
tokenFinished();
|
|
break;
|
|
case FinalBytesNoIntermediate::DA:
|
|
appendParameter();
|
|
if (m_parameters.size()) {
|
|
switch (m_parameters.at(0)) {
|
|
case -'>':
|
|
m_screen->sendSecondaryDA();
|
|
break;
|
|
case -'?':
|
|
qDebug() << "WHAT!!!";
|
|
break; //ignore
|
|
case 0:
|
|
default:
|
|
m_screen->sendPrimaryDA();
|
|
}
|
|
} else {
|
|
m_screen->sendPrimaryDA();
|
|
}
|
|
tokenFinished();
|
|
break;
|
|
case FinalBytesNoIntermediate::VPA: {
|
|
appendParameter();
|
|
Q_ASSERT(m_parameters.size() < 2);
|
|
int move_to_line = m_parameters.size() ? m_parameters.at(0) : 1;
|
|
m_screen->moveCursorToLine(move_to_line);
|
|
}
|
|
tokenFinished();
|
|
break;
|
|
case FinalBytesNoIntermediate::VPR:
|
|
case FinalBytesNoIntermediate::HVP:
|
|
case FinalBytesNoIntermediate::TBC:
|
|
qDebug() << "unhandled CSI" << FinalBytesNoIntermediate::FinalBytesNoIntermediate(character);
|
|
tokenFinished();
|
|
break;
|
|
case FinalBytesNoIntermediate::SM:
|
|
appendParameter();
|
|
if (m_parameters.size() && m_parameters.at(0) == -'?') {
|
|
if (m_parameters.size() > 1) {
|
|
switch (m_parameters.at(1)) {
|
|
case 1:
|
|
m_screen->setApplicationCursorKeysMode(true);
|
|
break;
|
|
case 4:
|
|
qDebug() << "Insertion mode";
|
|
break;
|
|
case 7:
|
|
qDebug() << "MODE 7";
|
|
break;
|
|
case 12:
|
|
m_screen->setCursorBlinking(true);
|
|
break;
|
|
case 25:
|
|
m_screen->setCursorVisible(true);
|
|
break;
|
|
case 1034:
|
|
//I don't know what this sequence is
|
|
break;
|
|
case 1049:
|
|
m_screen->saveCursor();
|
|
m_screen->saveScreenData();
|
|
break;
|
|
default:
|
|
qDebug() << "unhandled CSI FinalBytesNoIntermediate::SM ? with parameter:" << m_parameters.at(1);
|
|
}
|
|
} else {
|
|
qDebug() << "unhandled CSI FinalBytesNoIntermediate::SM ?";
|
|
}
|
|
} else {
|
|
qDebug() << "unhandled CSI FinalBytesNoIntermediate::SM";
|
|
}
|
|
tokenFinished();
|
|
break;
|
|
case FinalBytesNoIntermediate::MC:
|
|
case FinalBytesNoIntermediate::HPB:
|
|
case FinalBytesNoIntermediate::VPB:
|
|
qDebug() << "unhandled CSI" << FinalBytesNoIntermediate::FinalBytesNoIntermediate(character);
|
|
tokenFinished();
|
|
break;
|
|
case FinalBytesNoIntermediate::RM:
|
|
appendParameter();
|
|
if (m_parameters.size()) {
|
|
switch(m_parameters.at(0)) {
|
|
case -'?':
|
|
if (m_parameters.size() > 1) {
|
|
switch(m_parameters.at(1)) {
|
|
case 1:
|
|
qDebug() << "Normal cursor keys";
|
|
break;
|
|
case 12:
|
|
m_screen->setCursorBlinking(false);
|
|
break;
|
|
case 25:
|
|
m_screen->setCursorVisible(false);
|
|
break;
|
|
case 1049:
|
|
m_screen->restoreCursor();
|
|
m_screen->restoreScreenData();
|
|
break;
|
|
default:
|
|
qDebug() << "unhandled CSI FinalBytesNoIntermediate::RM? with "
|
|
"parameter " << m_parameters.at(1);
|
|
}
|
|
} else {
|
|
qDebug() << "unhandled CSI FinalBytesNoIntermediate::RM";
|
|
}
|
|
break;
|
|
case 4:
|
|
m_screen->setInsertMode(Screen::Replace);
|
|
default:
|
|
qDebug() << "unhandled CSI FinalBytesNoIntermediate::RM";
|
|
break;
|
|
}
|
|
}
|
|
tokenFinished();
|
|
break;
|
|
case FinalBytesNoIntermediate::SGR: {
|
|
appendParameter();
|
|
|
|
if (!m_parameters.size())
|
|
m_parameters << 0;
|
|
|
|
for (int i = 0; i < m_parameters.size();i++) {
|
|
switch(m_parameters.at(i)) {
|
|
case 0:
|
|
// m_screen->setTextStyle(TextStyle::Normal);
|
|
m_screen->resetStyle();
|
|
break;
|
|
case 1:
|
|
m_screen->setTextStyle(TextStyle::Bold);
|
|
break;
|
|
case 5:
|
|
m_screen->setTextStyle(TextStyle::Blinking);
|
|
break;
|
|
case 7:
|
|
m_screen->setTextStyle(TextStyle::Inverse);
|
|
break;
|
|
case 8:
|
|
qDebug() << "SGR: Hidden text not supported";
|
|
break;
|
|
case 22:
|
|
m_screen->setTextStyle(TextStyle::Normal);
|
|
break;
|
|
case 24:
|
|
m_screen->setTextStyle(TextStyle::Underlined, false);
|
|
break;
|
|
case 25:
|
|
m_screen->setTextStyle(TextStyle::Blinking, false);
|
|
break;
|
|
case 27:
|
|
m_screen->setTextStyle(TextStyle::Inverse, false);
|
|
break;
|
|
case 28:
|
|
qDebug() << "SGR: Visible text is allways on";
|
|
break;
|
|
case 30:
|
|
case 31:
|
|
case 32:
|
|
case 33:
|
|
case 34:
|
|
case 35:
|
|
case 36:
|
|
case 37:
|
|
// case 38:
|
|
case 39:
|
|
case 40:
|
|
case 41:
|
|
case 42:
|
|
case 43:
|
|
case 44:
|
|
case 45:
|
|
case 46:
|
|
case 47:
|
|
// case 38:
|
|
case 49:
|
|
m_screen->setTextStyleColor(m_parameters.at(i));
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
|
qDebug() << "Unknown SGR" << m_parameters.at(i);
|
|
}
|
|
}
|
|
|
|
tokenFinished();
|
|
}
|
|
break;
|
|
case FinalBytesNoIntermediate::DSR:
|
|
qDebug() << "report";
|
|
case FinalBytesNoIntermediate::DAQ:
|
|
case FinalBytesNoIntermediate::Reserved0:
|
|
case FinalBytesNoIntermediate::Reserved1:
|
|
qDebug() << "Unhandeled CSI" << FinalBytesNoIntermediate::FinalBytesNoIntermediate(character);
|
|
tokenFinished();
|
|
break;
|
|
case FinalBytesNoIntermediate::Reserved2:
|
|
appendParameter();
|
|
if (m_parameters.size() == 2) {
|
|
if (m_parameters.at(0) >= 0) {
|
|
m_screen->setScrollArea(m_parameters.at(0),m_parameters.at(1));
|
|
} else {
|
|
qDebug() << "Unknown value for scrollRegion";
|
|
}
|
|
} else {
|
|
qDebug() << "Unknown parameterset for scrollRegion";
|
|
}
|
|
tokenFinished();
|
|
break;
|
|
case FinalBytesNoIntermediate::Reserved3:
|
|
case FinalBytesNoIntermediate::Reserved4:
|
|
case FinalBytesNoIntermediate::Reserved5:
|
|
case FinalBytesNoIntermediate::Reserved6:
|
|
case FinalBytesNoIntermediate::Reserved7:
|
|
case FinalBytesNoIntermediate::Reserved8:
|
|
case FinalBytesNoIntermediate::Reserved9:
|
|
case FinalBytesNoIntermediate::Reserveda:
|
|
case FinalBytesNoIntermediate::Reservedb:
|
|
case FinalBytesNoIntermediate::Reservedc:
|
|
case FinalBytesNoIntermediate::Reservedd:
|
|
case FinalBytesNoIntermediate::Reservede:
|
|
case FinalBytesNoIntermediate::Reservedf:
|
|
default:
|
|
qDebug() << "Unhandeled CSI" << FinalBytesNoIntermediate::FinalBytesNoIntermediate(character);
|
|
tokenFinished();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void Parser::decodeOSC(uchar character)
|
|
{
|
|
if (!m_parameters.size() &&
|
|
character >= 0x30 && character <= 0x3f) {
|
|
decodeParameters(character);
|
|
} else {
|
|
if (m_decode_osc_state == None) {
|
|
appendParameter();
|
|
if (m_parameters.size() != 1) {
|
|
tokenFinished();
|
|
return;
|
|
}
|
|
|
|
switch (m_parameters.at(0)) {
|
|
case 0:
|
|
m_decode_osc_state = ChangeWindowAndIconName;
|
|
break;
|
|
case 1:
|
|
m_decode_osc_state = ChangeIconTitle;
|
|
break;
|
|
case 2:
|
|
m_decode_osc_state = ChangeWindowTitle;
|
|
break;
|
|
default:
|
|
m_decode_osc_state = Unknown;
|
|
break;
|
|
}
|
|
} else {
|
|
if (character == 0x07) {
|
|
if (m_decode_osc_state == ChangeWindowAndIconName ||
|
|
m_decode_osc_state == ChangeWindowTitle) {
|
|
QString title = QString::fromUtf8(m_current_data.mid(m_current_token_start+4,
|
|
m_currrent_position - m_current_token_start -1));
|
|
m_screen->setTitle(title);
|
|
}
|
|
tokenFinished();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void Parser::decodeOtherEscape(uchar character)
|
|
{
|
|
Q_ASSERT(m_parameters.size());
|
|
switch(m_parameters.at(0)) {
|
|
case -'(':
|
|
switch(character) {
|
|
case 0:
|
|
m_screen->setCharacterMap("DEC Special Character and Line Drawing Set");
|
|
break;
|
|
case 'A':
|
|
m_screen->setCharacterMap("UK");
|
|
break;
|
|
case 'B':
|
|
m_screen->setCharacterMap("USASCII");
|
|
break;
|
|
case '4':
|
|
m_screen->setCharacterMap("Dutch");
|
|
break;
|
|
case 'C':
|
|
case '5':
|
|
m_screen->setCharacterMap("Finnish");
|
|
break;
|
|
case 'R':
|
|
m_screen->setCharacterMap("French");
|
|
break;
|
|
case 'Q':
|
|
m_screen->setCharacterMap("FrenchCanadian");
|
|
break;
|
|
case 'K':
|
|
m_screen->setCharacterMap("German");
|
|
break;
|
|
case 'Y':
|
|
m_screen->setCharacterMap("Italian");
|
|
break;
|
|
case 'E':
|
|
case '6':
|
|
m_screen->setCharacterMap("NorDan");
|
|
break;
|
|
case 'Z':
|
|
m_screen->setCharacterMap("Spanish");
|
|
break;
|
|
case 'H':
|
|
case '7':
|
|
m_screen->setCharacterMap("Sweedish");
|
|
break;
|
|
case '=':
|
|
m_screen->setCharacterMap("Swiss");
|
|
break;
|
|
default:
|
|
qDebug() << "Not supported Character set!";
|
|
}
|
|
break;
|
|
default:
|
|
qDebug() << "Other Escape sequence not recognized";
|
|
}
|
|
tokenFinished();
|
|
}
|
|
|
|
void Parser::tokenFinished()
|
|
{
|
|
m_decode_state = PlainText;
|
|
m_decode_osc_state = None;
|
|
|
|
m_parameters.clear();
|
|
m_parameter_string.clear();
|
|
|
|
m_current_token_start = m_currrent_position + 1;
|
|
m_intermediate_char = 0;
|
|
}
|
|
|
|
void Parser::appendParameter()
|
|
{
|
|
if (m_parameter_string.size()) {
|
|
m_parameters.append(m_parameter_string.toUShort());
|
|
m_parameter_string.clear();
|
|
}
|
|
}
|
|
|