Skip to content

Commit

Permalink
Backport keyPress() from FingerTerm, tweaked. Fixes #17
Browse files Browse the repository at this point in the history
  • Loading branch information
direc85 committed Sep 30, 2023
1 parent 37588b2 commit f2dd78c
Showing 1 changed file with 142 additions and 67 deletions.
209 changes: 142 additions & 67 deletions src/terminal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -181,91 +181,166 @@ void Terminal::putString(QString str, bool unEscape)

void Terminal::keyPress(int key, unsigned int modifiers)
{
QChar c(key);
QString toWrite;

resetBackBufferScrollPos();

if (c.isLetter()) {
c = ((modifiers & Qt::ShiftModifier) != 0) ? c.toUpper() : c.toLower();
}
// physical sticky shift generates key=0, mod=Qt::ShiftModifier, sticky alt: key=0, mod=0
if (key == 0 && (modifiers == Qt::ShiftModifier || modifiers == Qt::NoModifier))
return;

QString toWrite;
if (key > 0xFFFF) {
int modcode = (modifiers & Qt::ShiftModifier ? 1 : 0) |
(modifiers & Qt::AltModifier ? 2 : 0) |
(modifiers & Qt::ControlModifier ? 4 : 0);

if (modcode == 0) {
QString fmt;
char cursorModif='[';
if(iAppCursorKeys)
cursorModif = 'O';

switch (key)
{
case Qt::Key_Up: fmt = QString("%2%1A").arg(cursorModif); break;
case Qt::Key_Down: fmt = QString("%2%1B").arg(cursorModif); break;
case Qt::Key_Right: fmt = QString("%2%1C").arg(cursorModif); break;
case Qt::Key_Left: fmt = QString("%2%1D").arg(cursorModif); break;
case Qt::Key_PageUp: fmt = "%1[5~"; break;
case Qt::Key_PageDown: fmt = "%1[6~"; break;
case Qt::Key_Home: fmt = "%1OH"; break;
case Qt::Key_End: fmt = "%1OF"; break;
case Qt::Key_Insert: fmt = "%1[2~"; break;
case Qt::Key_Delete: fmt = "%1[3~"; break;

case Qt::Key_F1: fmt = "%1OP"; break;
case Qt::Key_F2: fmt = "%1OQ"; break;
case Qt::Key_F3: fmt = "%1OR"; break;
case Qt::Key_F4: fmt = "%1OS"; break;
case Qt::Key_F5: fmt = "%1[15~"; break;
case Qt::Key_F6: fmt = "%1[17~"; break;
case Qt::Key_F7: fmt = "%1[18~"; break;
case Qt::Key_F8: fmt = "%1[19~"; break;
case Qt::Key_F9: fmt = "%1[20~"; break;
case Qt::Key_F10: fmt = "%1[21~"; break;
case Qt::Key_F11: fmt = "%1[23~"; break;
case Qt::Key_F12: fmt = "%1[24~"; break;
}

if (!fmt.isEmpty())
toWrite += fmt.arg(ch_ESC);

} else {
QString fmt;
char modChar = '1' + modcode;
switch (key) {
case Qt::Key_Up: fmt = "%1[1;%2A"; break;
case Qt::Key_Down: fmt = "%1[1;%2B"; break;
case Qt::Key_Right: fmt = "%1[1;%2C"; break;
case Qt::Key_Left: fmt = "%1[1;%2D"; break;
case Qt::Key_PageUp: fmt = "%1[5;%2~"; break;
case Qt::Key_PageDown: fmt = "%1[6;%2~"; break;
case Qt::Key_Home: fmt = "%1[1;%2H"; break;
case Qt::Key_End: fmt = "%1[1;%2F"; break;
case Qt::Key_Insert: fmt = "%1[2;%2~"; break;
case Qt::Key_Delete: fmt = "%1[3;%2~"; break;

case Qt::Key_F1: fmt = "%1[1;%2P"; break;
case Qt::Key_F2: fmt = "%1[1;%2Q"; break;
case Qt::Key_F3: fmt = "%1[1;%2R"; break;
case Qt::Key_F4: fmt = "%1[1;%2S"; break;
case Qt::Key_F5: fmt = "%1[15;%2~"; break;
case Qt::Key_F6: fmt = "%1[17;%2~"; break;
case Qt::Key_F7: fmt = "%1[18;%2~"; break;
case Qt::Key_F8: fmt = "%1[19;%2~"; break;
case Qt::Key_F9: fmt = "%1[20;%2~"; break;
case Qt::Key_F10: fmt = "%1[21;%2~"; break;
case Qt::Key_F11: fmt = "%1[23;%2~"; break;
case Qt::Key_F12: fmt = "%1[24;%2~"; break;
}

if(key <= 0xFF || (key >= 0x410 && key <= 0x44F)) {
if(modifiers & Qt::AltModifier)
toWrite.append(ch_ESC);
if (!fmt.isEmpty())
toWrite += fmt.arg(ch_ESC).arg(modChar);

if (modifiers & Qt::ControlModifier) {
char asciiVal = c.toLatin1();
}

if (asciiVal >= 0x41 && asciiVal <= 0x5f) {
// Turn uppercase characters into their control code equivalent
toWrite.append(asciiVal - 0x40);
} else if (asciiVal >= 0x61) {
// Turn lowercase characters into their control code equivalent
toWrite.append(asciiVal - 0x60);
if( key==Qt::Key_Enter || key==Qt::Key_Return ) {
if ( (modifiers & (Qt::ShiftModifier | Qt::ControlModifier)) ==
(Qt::ShiftModifier | Qt::ControlModifier) )
toWrite += QChar(0x9E);
else if (modifiers & Qt::ControlModifier)
toWrite += QChar(0x1E); // ^^
else if (modifiers & Qt::ShiftModifier)
toWrite += "\n";
else if(iNewLineMode)
toWrite += "\r\n";
else
toWrite += "\r";
}
if( key==Qt::Key_Backspace ) {
if ( (modifiers & (Qt::ShiftModifier | Qt::ControlModifier)) ==
(Qt::ShiftModifier | Qt::ControlModifier) )
toWrite += QChar(0x9F);
else if (modifiers & Qt::ControlModifier)
toWrite += QChar(0x1F); // ^_
else
toWrite += "\x7F";
}
if( key==Qt::Key_Tab || key==Qt::Key_Backtab ) {
if ( key == Qt::Key_Backtab ) modifiers |= Qt::ShiftModifier;
if (modifiers & Qt::ControlModifier) {
char modChar = '5' + (modifiers & Qt::ShiftModifier ? 1 : 0);
toWrite += QString("%1[1;%2I").arg(ch_ESC).arg(modChar);
} else if (modifiers & Qt::ShiftModifier) {
toWrite += QString("%1[Z").arg(ch_ESC);
} else {
qWarning() << "Ctrl+" << c << " does not translate into a control code";
toWrite += "\t";
}
} else {
toWrite.append(c);
}

if(iPtyIFace)
iPtyIFace->writeTerm(toWrite);
if( key==Qt::Key_Escape ) {
if (modifiers & Qt::ShiftModifier)
toWrite += QChar(0x9B);
else
toWrite += QString(1,ch_ESC);
}

if (!toWrite.isEmpty()) {
if(iPtyIFace)
iPtyIFace->writeTerm(toWrite);
} else {
qDebug() << "unknown special key: " << key;
}
return;
}

char cursorModif='[';
if(iAppCursorKeys)
cursorModif = 'O';

if( key==Qt::Key_Up )
toWrite += QString("%1%2A").arg(ch_ESC).arg(cursorModif).toLatin1();
if( key==Qt::Key_Down )
toWrite += QString("%1%2B").arg(ch_ESC).arg(cursorModif).toLatin1();
if( key==Qt::Key_Right )
toWrite += QString("%1%2C").arg(ch_ESC).arg(cursorModif).toLatin1();
if( key==Qt::Key_Left )
toWrite += QString("%1%2D").arg(ch_ESC).arg(cursorModif).toLatin1();

if( key==Qt::Key_Enter || key==Qt::Key_Return ) {
if(iNewLineMode)
toWrite += "\r\n";
else
toWrite += "\r";
QChar c(key);

if (c.isLetter()) {
c = ((modifiers & Qt::ShiftModifier) != 0) ? c.toUpper() : c.toLower();
}
if( key==Qt::Key_Backspace )
toWrite += "\x7F";
if( key==Qt::Key_Tab )
toWrite = "\t";

if( key==Qt::Key_PageUp )
toWrite += QString("%1[5~").arg(ch_ESC).toLatin1();
if( key==Qt::Key_PageDown )
toWrite += QString("%1[6~").arg(ch_ESC).toLatin1();
if( key==Qt::Key_Home )
toWrite += QString("%1OH").arg(ch_ESC).toLatin1();
if( key==Qt::Key_End )
toWrite += QString("%1OF").arg(ch_ESC).toLatin1();
if( key==Qt::Key_Delete )
toWrite += QString("%1[3~").arg(ch_ESC).toLatin1();
if( key==Qt::Key_Escape )
toWrite += QString(1,ch_ESC);
if (key >= 0x01000030 && key <= 0x0100003b) {
// For some reason, function key escape sequence codes skip a few numbers..?
// See e.g. https://invisible-island.net/xterm/xterm-function-keys.html
int f_seq = key-0x1000025;
if(f_seq > 21)
f_seq = f_seq + 2;
else if(f_seq > 15)
f_seq = f_seq + 1;

toWrite += (QString("%1[").arg(ch_ESC) + QString::number(f_seq) + QString("~")).toLatin1();

if((modifiers & Qt::AltModifier) != 0) {
toWrite.append(ch_ESC);
}

if(iPtyIFace)
if ((modifiers & Qt::ControlModifier) != 0) {
char asciiVal = c.toUpper().toLatin1();

if (asciiVal >= 0x41 && asciiVal <= 0x5f) {
// Turn uppercase characters into their control code equivalent
toWrite.append(asciiVal - 0x40);
} else {
qWarning() << "Ctrl+" << c << " does not translate into a control code";
}
} else {
toWrite.append(c);
}

if (iPtyIFace) {
iPtyIFace->writeTerm(toWrite);
}
return;
}

void Terminal::insertInBuffer(const QString& chars)
Expand Down

0 comments on commit f2dd78c

Please sign in to comment.