git-svn-id: svn://db.shs.com.ru/pip@256 12ceb7fc-bf1f-11e4-8940-5bc7170c53b5
This commit is contained in:
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user