git-svn-id: svn://db.shs.com.ru/pip@256 12ceb7fc-bf1f-11e4-8940-5bc7170c53b5

This commit is contained in:
2016-09-07 08:07:36 +00:00
parent d321b01f10
commit 10a8742995
4 changed files with 189 additions and 109 deletions

View File

@@ -23,6 +23,7 @@
# include <wincon.h>
# include <winuser.h>
#else
# include "piprocess.h"
# include <csignal>
# include <pty.h>
# include <fcntl.h>
@@ -48,6 +49,9 @@ struct PITerminalAuxData {
};
#else
# define BUFFER_SIZE 4096
enum DECType {
CKM = 1
};
#endif
@@ -62,11 +66,13 @@ PRIVATE_DEFINITION_START(PITerminal)
PIString shell;
PIByteArray read_buf, tmp_buf;
PIScreenTypes::CellFormat cur_format;
int term_type;
int fd, cur_x, cur_y;
int save_cur_x, save_cur_y;
pid_t pid;
PIString esc_seq;
bool is_esc_seq, last_read;
PIMap<int, bool> DEC;
termios desc;
#endif
PRIVATE_DEFINITION_END(PITerminal)
@@ -131,9 +137,9 @@ void PITerminal::write(PIKbdListener::SpecialKey k, PIKbdListener::KeyModifiers
PIByteArray ba;
#ifdef WINDOWS
switch (k) {
case PIKbdListener::Tab: ba << uchar('\t'); break;
case PIKbdListener::Tab: ba << uchar('\t'); break;
case PIKbdListener::Return: ba << uchar('\r') << uchar('\n'); break;
case PIKbdListener::Space: ba << uchar(' '); break;
case PIKbdListener::Space: ba << uchar(' '); break;
default: break;
}
//piCout << "write" << ba.size();
@@ -146,35 +152,57 @@ void PITerminal::write(PIKbdListener::SpecialKey k, PIKbdListener::KeyModifiers
writePipe(PRIVATE->pipe, msg);
}
#else
int term = PRIVATE->term_type;
int flags = 0;
switch (k) {
case PIKbdListener::Tab: ba << uchar('\t'); break;
case PIKbdListener::Return: ba << uchar('\n'); break;
case PIKbdListener::Esc: ba << uchar('\e'); break;
case PIKbdListener::Space: ba << uchar(' '); break;
case PIKbdListener::Space: ba << uchar(' '); break;
case PIKbdListener::Backspace: ba << uchar(0x7f); break;
case PIKbdListener::UpArrow: ba << uchar('\e') << uchar('[') /*<< uchar('1')*/ << uchar('A'); break;
case PIKbdListener::DownArrow: ba << uchar('\e') << uchar('[') /*<< uchar('1')*/ << uchar('B'); break;
case PIKbdListener::RightArrow: ba << uchar('\e') << uchar('[') /*<< uchar('1')*/ << uchar('C'); break;
case PIKbdListener::LeftArrow: ba << uchar('\e') << uchar('[') /*<< uchar('1')*/ << uchar('D'); break;
case PIKbdListener::Home: break;
case PIKbdListener::End: break;
case PIKbdListener::PageUp: ba << uchar('\e') << uchar('[') << uchar('5') << uchar('~'); break;
case PIKbdListener::PageDown: ba << uchar('\e') << uchar('[') << uchar('6') << uchar('~'); break;
case PIKbdListener::Insert: ba << uchar('\e') << uchar('[') << uchar('2') << uchar('~'); break;
case PIKbdListener::Delete: ba << uchar('\e') << uchar('[') << uchar('3') << uchar('~'); break;
case PIKbdListener::F1: break;
case PIKbdListener::F2: break;
case PIKbdListener::F3: break;
case PIKbdListener::F4: break;
case PIKbdListener::F5: break;
case PIKbdListener::F6: break;
case PIKbdListener::F7: break;
case PIKbdListener::F8: break;
case PIKbdListener::F9: break;
case PIKbdListener::F10: break;
case PIKbdListener::F11: break;
case PIKbdListener::F12: break;
default: break;
case PIKbdListener::UpArrow:
case PIKbdListener::DownArrow:
case PIKbdListener::RightArrow:
case PIKbdListener::LeftArrow: if (PRIVATE->DEC.value(CKM, false)) flags = 1;
/*case PIKbdListener::Home: //break;
case PIKbdListener::End: //break;
case PIKbdListener::PageUp: //ba << uchar('\e') << uchar('[') << uchar('5') << uchar('~'); break;
case PIKbdListener::PageDown: //ba << uchar('\e') << uchar('[') << uchar('6') << uchar('~'); break;
case PIKbdListener::Insert: //ba << uchar('\e') << uchar('[') << uchar('2') << uchar('~'); break;
case PIKbdListener::Delete: //ba << uchar('\e') << uchar('[') << uchar('3') << uchar('~'); break;
case PIKbdListener::F1: //break;
case PIKbdListener::F2: //break;
case PIKbdListener::F3: //break;
case PIKbdListener::F4: //break;
case PIKbdListener::F5: //break;
case PIKbdListener::F6: //break;
case PIKbdListener::F7: //break;
case PIKbdListener::F8: //break;
case PIKbdListener::F9: //break;
case PIKbdListener::F10: //break;
case PIKbdListener::F11: //break;
case PIKbdListener::F12: //break;
*/
default: {
//piCout << flags;
int mod = 0;
if (m[PIKbdListener::Shift]) m |= 1;
if (m[PIKbdListener::Alt]) m |= 2;
if (m[PIKbdListener::Ctrl]) m |= 4;
for (int i = 0; ; ++i) {
const PIKbdListener::EscSeq & e(PIKbdListener::esc_seq[i]);
if (!e.seq) break;
//piCout << "search" << rc[1] << esc_seq[i].seq;
if (e.key == k && e.mod == m) {
if (((e.vt & term) == term) || (((e.flags & flags) == flags) && (flags != 0))) {
//piCout << "found key" << PIString(e.seq).replaceAll("\e", "\\e");
PIByteArray d = ("\e" + PIString(e.seq)).toByteArray();
write(d);
break;
}
}
}
} break;
}
//piCout << "write" << ba.size();
if (!ba.isEmpty()) write(ba);
@@ -188,7 +216,11 @@ void PITerminal::write(PIKbdListener::KeyEvent ke) {
if (isSpecialKey(ke.key)) write((PIKbdListener::SpecialKey)ke.key, ke.modifiers);
else {
PIByteArray ba;
#ifdef WINDOWS
ba << uchar(PIChar(ke.key).toConcole1Byte());
#else
ba = PIString(PIChar(ke.key)).toUTF8();
#endif
write(ba);
}
}
@@ -196,7 +228,6 @@ void PITerminal::write(PIKbdListener::KeyEvent ke) {
PIVector<PIVector<PIScreenTypes::Cell> > PITerminal::content() {
readConsole();
getCursor(cursor_x, cursor_y);
PIVector<PIVector<PIScreenTypes::Cell> > ret = cells;
if (cursor_blink && cursor_visible)
if (cursor_x >= 0 && cursor_x < size_x)
@@ -253,6 +284,7 @@ void PITerminal::initPrivate() {
PRIVATE->fd = PRIVATE->cur_x = PRIVATE->cur_y = 0;
PRIVATE->save_cur_x = PRIVATE->save_cur_y = 0;
PRIVATE->pid = 0;
PRIVATE->term_type = 0;
PRIVATE->is_esc_seq = false;
PRIVATE->last_read = true;
PRIVATE->esc_seq.clear();
@@ -311,12 +343,10 @@ uchar PITerminal::invertColor(uchar c) {
void PITerminal::run() {
getCursor(cursor_x, cursor_y);
if (cursor_tm.elapsed_m() >= 500) {
cursor_tm.reset();
cursor_blink = !cursor_blink;
if (cursor_blink) {
getCursor(cursor_x, cursor_y);
}
}
#ifndef WINDOWS
if (PRIVATE->fd == 0) return;
@@ -326,7 +356,7 @@ void PITerminal::run() {
if (readed > 0) {
PRIVATE->last_read = true;
//piCoutObj << "readed" << readed << PIString(PRIVATE->tmp_buf.resized(readed)).replaceAll("\e", "\\e");
piCoutObj << "readed" << readed << (PRIVATE->tmp_buf.resized(readed));
//piCoutObj << "readed" << readed << (PRIVATE->tmp_buf.resized(readed));
PRIVATE->read_buf.append(PRIVATE->tmp_buf.resized(readed));
for (;;) {
int ind = -1;
@@ -340,7 +370,11 @@ void PITerminal::run() {
parseInput(PIString((const char *)PRIVATE->read_buf.data(), ind));
PRIVATE->read_buf.remove(0, ind);
}
if (PRIVATE->read_buf.size_s() >= BUFFER_SIZE) {
bool parse = PRIVATE->read_buf.size_s() >= BUFFER_SIZE;
if (PRIVATE->read_buf.size_s() == 1)
if (PRIVATE->read_buf[0] < 0x80)
parse = true;
if (parse) {
parseInput(PIString(PRIVATE->read_buf));
PRIVATE->read_buf.clear();
}
@@ -414,12 +448,19 @@ bool PITerminal::isCompleteEscSeq(const PIString & es) {
void PITerminal::applyEscSeq(PIString es) {
piCoutObj << es;
//piCoutObj << es;
if (es.size_s() < 2) return;
if (es[1] == '?' && es.size_s() >= 2) { // cursor
PIString c = es.mid(2);
if (c == "25l") cursor_visible = false;
if (c == "25h") cursor_visible = true;
if (es[1] == '?' && es.size_s() >= 2) {
char a = es.takeRight(1)[0].toAscii();
bool val = false;
if (a == 'l') val = false;
if (a == 'h') val = true;
int dec = es.mid(2).toInt();
//piCoutObj << "DEC" << dec << val;
switch (dec) {
case 25: cursor_visible = val; break;
default: PRIVATE->DEC[dec] = val; break;
}
}
PIScreenTypes::Cell def_cell = PIScreenTypes::Cell(' ', PRIVATE->cur_format);
if (es[0] == '[') { // CSI
@@ -590,6 +631,13 @@ void PITerminal::moveCursor(int dx, int dy) {
cells[y].fill(PIScreenTypes::Cell());
}
}
int PITerminal::termType(const PIString & t) {
if (t == "xterm") return PIKbdListener::vt_xterm;
else if (t == "linux") return PIKbdListener::vt_linux;
return PIKbdListener::vt_none;
}
#endif
@@ -665,6 +713,13 @@ bool PITerminal::initialize() {
winsize ws;
ws.ws_col = dsize_x;
ws.ws_row = dsize_y;
PIStringList env = PIProcess::currentEnvironment();
piForeachC (PIString & e, env)
if (e.startsWith("TERM=")) {
PRIVATE->term_type = termType(e.mid(5).trim().toLowerCase());
//piCout << PRIVATE->term_type;
piBreak;
}
pid_t fr = forkpty(&(PRIVATE->fd), pty, 0, &ws);
//piCoutObj << fr << PRIVATE->fd << pty;
if (fr == 0) {