void Telnet::handleStateSubNegIac(uchar c) { if (c == SE) { if (_sbOption == TELOPT_TTYPE && _sbBuffer->size() == 1 && _sbBuffer->at(0) == TELQUAL_SEND) { QByteArray bs; bs.append(IAC); bs.append(SB); bs.append(TELOPT_TTYPE); bs.append(static_cast<char>(TELQUAL_IS)); bs.append("vt100"); bs.append(IAC); bs.append(SE); emit hasBytesToSend(bs); } _state = TOP_LEVEL; _sbBuffer->clear(); } else { _sbBuffer->append(c); _state = SUBNEGOT; } }
void Telnet::handleStateSeenDo(uchar c) { QByteArray bs; switch (c) { case TELOPT_NAWS: sendCommand(WILL, c); bs.append(IAC); bs.append(SB); bs.append(TELOPT_NAWS); bs.append('\x0'); bs.append('\x50'); bs.append('\x0'); bs.append('\x18'); bs.append(IAC); bs.append(SE); emit hasBytesToSend(bs); break; case TELOPT_TTYPE: case TELOPT_BINARY: sendCommand(WILL, c); break; default: sendCommand(WONT, c); break; } _state = TOP_LEVEL; }
void Telnet::sendCommand(uchar cmd, uchar option) { QByteArray data; data.append(IAC); data.append(cmd); data.append(option); emit hasBytesToSend(data); }
void View::popInsertBuffer() { Q_D(View); emit hasBytesToSend(QByteArray(1, d->insertBuffer.dequeue())); if (d->insertBuffer.isEmpty()) d->insertTimer->stop(); }
void View::insertText(const QString &string, uint delayMs) { Q_D(View); QByteArray bytes; foreach (const QChar &rc, string) { if (rc < '\x7f') { uchar b = rc.unicode() % 0x100; if (b == '\n') b = '\r'; if (!delayMs) bytes.append(b); else d->insertBuffer.enqueue(b); } else { ushort code; switch (d->terminal->connection()->site()->encoding()) { case BBS::EncodingBig5: code = YL::U2B[rc.unicode()]; break; case BBS::EncodingGBK: code = YL::U2G[rc.unicode()]; break; default: code = 0; break; } uchar bu = code / 0x100; uchar bl = code % 0x100; if (!delayMs) { bytes.append(bu); bytes.append(bl); } else { d->insertBuffer.enqueue(bu); d->insertBuffer.enqueue(bl); } } } if (!delayMs) { if (!bytes.isEmpty()) emit hasBytesToSend(bytes); } else { if (!d->insertBuffer.isEmpty()) d->insertTimer->start(delayMs); } }
void Telnet::sendBytes(QByteArray bytes) { if (bytes.isEmpty()) return; switch (_socket->state()) { case QAbstractSocket::UnconnectedState: case QAbstractSocket::HostLookupState: case QAbstractSocket::ConnectingState: case QAbstractSocket::ClosingState: return; default: break; } qint64 sz = _socket->write(bytes); if (sz == bytes.size()) return; else if (sz <= 0) emit hasBytesToSend(bytes); else emit hasBytesToSend(bytes.mid(sz)); // restart from want we left off }
void View::setTerminal(Connection::Terminal *terminal) { Q_D(View); if (d->terminal == terminal) return; if (d->terminal) { disconnect(d->terminal); delete d->terminal; } d->terminal = terminal; if (!d->terminal) return; d->terminal->setParent(this); d->terminal->setView(this); connect(d->terminal, SIGNAL(dataProcessed()), SLOT(updateScreen())); d->terminal->connection()->connect(this, SIGNAL(hasBytesToSend(QByteArray)), SLOT(sendBytes(QByteArray))); connect(d->terminal, SIGNAL(shouldExtendTop(int,int)), SLOT(extendTop(int,int))); connect(d->terminal, SIGNAL(shouldExtendBottom(int,int)), SLOT(extendBottom(int,int))); }