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

@@ -45,78 +45,78 @@ PIKbdListener * PIKbdListener::_object = 0;
#ifndef WINDOWS
struct EscSeq {
const char * seq;
int key;
int mod;
// 1 - shift
// 2 - alt
// 4 - ctrl
};
// unix
const EscSeq esc_seq[] = {
{"[1A", PIKbdListener::UpArrow, 0},
{"[A", PIKbdListener::UpArrow, 0},
{"OA", PIKbdListener::UpArrow, 4},
{"[1B", PIKbdListener::DownArrow, 0},
{"[B", PIKbdListener::DownArrow, 0},
{"OB", PIKbdListener::DownArrow, 4},
{"[1C", PIKbdListener::RightArrow, 0},
{"[C", PIKbdListener::RightArrow, 0},
{"OC", PIKbdListener::RightArrow, 4},
{"[1D", PIKbdListener::LeftArrow, 0},
{"[D", PIKbdListener::LeftArrow, 0},
{"OD", PIKbdListener::LeftArrow, 0},
{"[H", PIKbdListener::Home, 0},
{"[1H", PIKbdListener::Home, 0},
{"[1~", PIKbdListener::Home, 0},
{"[F", PIKbdListener::End, 0},
{"[1F", PIKbdListener::End, 0},
{"[4~", PIKbdListener::End, 0},
{"[2~", PIKbdListener::Insert, 0},
{"[3~", PIKbdListener::Delete, 0},
{"[5~", PIKbdListener::PageUp, 0},
{"[6~", PIKbdListener::PageDown, 0},
{"[Z", PIKbdListener::Tab, 1},
{"OP", PIKbdListener::F1, 0},
{"[[A", PIKbdListener::F1, 0},
{"[11~", PIKbdListener::F1, 0},
{"OQ", PIKbdListener::F2, 0},
{"[[B", PIKbdListener::F2, 0},
{"[12~", PIKbdListener::F2, 0},
{"OR", PIKbdListener::F3, 0},
{"[[C", PIKbdListener::F3, 0},
{"[13~", PIKbdListener::F3, 0},
{"[25~", PIKbdListener::F3, 1},
{"OS", PIKbdListener::F4, 0},
{"[[D", PIKbdListener::F4, 0},
{"[14~", PIKbdListener::F4, 0},
{"[26~", PIKbdListener::F4, 1},
{"[[E", PIKbdListener::F5, 0},
{"OT", PIKbdListener::F5, 0},
{"[15~", PIKbdListener::F5, 0},
{"[28~", PIKbdListener::F5, 1},
{"OU", PIKbdListener::F6, 0},
{"[17~", PIKbdListener::F6, 0},
{"[29~", PIKbdListener::F6, 1},
{"OV", PIKbdListener::F7, 0},
{"[18~", PIKbdListener::F7, 0},
{"[31~", PIKbdListener::F7, 1},
{"OW", PIKbdListener::F8, 0},
{"[19~", PIKbdListener::F8, 0},
{"[32~", PIKbdListener::F8, 1},
{"OX", PIKbdListener::F9, 0},
{"[20~", PIKbdListener::F9, 0},
{"[33~", PIKbdListener::F9, 1},
{"OY", PIKbdListener::F10, 0},
{"[21~", PIKbdListener::F10, 0},
{"[34~", PIKbdListener::F10, 1},
{"OZ", PIKbdListener::F11, 0},
{"[23~", PIKbdListener::F11, 0},
{"O[", PIKbdListener::F12, 0},
{"[24~", PIKbdListener::F12, 0},
const PIKbdListener::EscSeq PIKbdListener::esc_seq[] = {
{"OA", PIKbdListener::UpArrow, 0, 0 , 1 },
{"OA", PIKbdListener::UpArrow, 4, 0 , 0 },
{"[1A", PIKbdListener::UpArrow, 0, 0 , 0 },
{"[A", PIKbdListener::UpArrow, 0, vt_all , 0 },
{"OB", PIKbdListener::DownArrow, 0, 0 , 1 },
{"OB", PIKbdListener::DownArrow, 4, 0 , 0 },
{"[1B", PIKbdListener::DownArrow, 0, 0 , 0 },
{"[B", PIKbdListener::DownArrow, 0, vt_all , 0 },
{"OC", PIKbdListener::RightArrow, 0, 0 , 1 },
{"OC", PIKbdListener::RightArrow, 4, 0 , 0 },
{"[1C", PIKbdListener::RightArrow, 0, 0 , 0 },
{"[C", PIKbdListener::RightArrow, 0, vt_all , 0 },
{"OD", PIKbdListener::LeftArrow, 0, 0 , 1 },
{"OD", PIKbdListener::LeftArrow, 4, 0 , 0 },
{"[1D", PIKbdListener::LeftArrow, 0, 0 , 0 },
{"[D", PIKbdListener::LeftArrow, 0, vt_all , 0 },
{"[H", PIKbdListener::Home, 0, vt_xterm , 0 },
{"[1H", PIKbdListener::Home, 0, 0 , 0 },
{"OH", PIKbdListener::Home, 0, 0 , 1 },
{"[1~", PIKbdListener::Home, 0, vt_linux , 0 },
{"[F", PIKbdListener::End, 0, vt_xterm , 0 },
{"[1F", PIKbdListener::End, 0, 0 , 0 },
{"OF", PIKbdListener::End, 0, 0 , 1 },
{"[4~", PIKbdListener::End, 0, vt_linux , 0 },
{"[2~", PIKbdListener::Insert, 0, vt_all , 0 },
{"[3~", PIKbdListener::Delete, 0, vt_all , 0 },
{"[5~", PIKbdListener::PageUp, 0, vt_all , 0 },
{"[6~", PIKbdListener::PageDown, 0, vt_all , 0 },
{"[Z", PIKbdListener::Tab, 1, vt_xterm , 0 },
{"OP", PIKbdListener::F1, 0, vt_xterm , 0 },
{"[[A", PIKbdListener::F1, 0, vt_linux , 0 },
{"[11~", PIKbdListener::F1, 0, 0 , 0 },
{"[25~", PIKbdListener::F1, 1, vt_linux , 0 },
{"OQ", PIKbdListener::F2, 0, vt_xterm , 0 },
{"[[B", PIKbdListener::F2, 0, vt_linux , 0 },
{"[12~", PIKbdListener::F2, 0, 0 , 0 },
{"[26~", PIKbdListener::F2, 1, vt_linux , 0 },
{"OR", PIKbdListener::F3, 0, vt_xterm , 0 },
{"[[C", PIKbdListener::F3, 0, vt_linux , 0 },
{"[13~", PIKbdListener::F3, 0, 0 , 0 },
{"[28~", PIKbdListener::F3, 1, vt_linux , 0 },
{"OS", PIKbdListener::F4, 0, vt_xterm , 0 },
{"[[D", PIKbdListener::F4, 0, vt_linux , 0 },
{"[14~", PIKbdListener::F4, 0, 0 , 0 },
{"[29~", PIKbdListener::F4, 1, vt_linux , 0 },
{"[[E", PIKbdListener::F5, 0, vt_linux , 0 },
{"OT", PIKbdListener::F5, 0, 0 , 0 },
{"[15~", PIKbdListener::F5, 0, vt_xterm , 0 },
{"[31~", PIKbdListener::F5, 1, vt_linux , 0 },
{"OU", PIKbdListener::F6, 0, 0 , 0 },
{"[17~", PIKbdListener::F6, 0, vt_all , 0 },
{"[32~", PIKbdListener::F6, 1, vt_linux , 0 },
{"OV", PIKbdListener::F7, 0, 0 , 0 },
{"[18~", PIKbdListener::F7, 0, vt_all , 0 },
{"[33~", PIKbdListener::F7, 1, vt_linux , 0 },
{"OW", PIKbdListener::F8, 0, 0 , 0 },
{"[19~", PIKbdListener::F8, 0, vt_all , 0 },
{"[34~", PIKbdListener::F8, 1, vt_linux , 0 },
{"OX", PIKbdListener::F9, 0, 0 , 0 },
{"[20~", PIKbdListener::F9, 0, vt_all , 0 },
{"[35~", PIKbdListener::F9, 1, vt_linux , 0 },
{"OY", PIKbdListener::F10, 0, 0 , 0 },
{"[21~", PIKbdListener::F10, 0, vt_all , 0 },
{"[36~", PIKbdListener::F10, 1, vt_linux , 0 },
{"OZ", PIKbdListener::F11, 0, 0 , 0 },
{"[23~", PIKbdListener::F11, 0, vt_all , 0 },
{"O[", PIKbdListener::F12, 0, 0 , 0 },
{"[24~", PIKbdListener::F12, 0, vt_all , 0 },
// End
{0, 0, 0},
{0, 0, 0, 0, 0},
};
#endif
@@ -242,8 +242,8 @@ void PIKbdListener::readKeyboard() {
#else
tcsetattr(0, TCSANOW, &PRIVATE->tterm);
ret = read(0, rc, 8);
/*piCout << NewLine << "read" << ret;
for (int i = 0; i < ret; ++i)
//piCout << "key" << PIString(rc).replaceAll("\e", "\\e");
/*for (int i = 0; i < ret; ++i)
cout << std::hex << int(((uchar * )&rc)[i]) << ' ';
cout << endl;
for (int i = 0; i < ret; ++i)
@@ -288,6 +288,7 @@ void PIKbdListener::readKeyboard() {
}
for (int i = 0; ; ++i) {
if (!esc_seq[i].seq) break;
//piCout << "search" << rc[1] << esc_seq[i].seq;
if (strcmp(esc_seq[i].seq, &(rc[1])) == 0) {
ke.key = esc_seq[i].key;
mod |= esc_seq[i].mod;

View File

@@ -32,6 +32,7 @@ class PIP_EXPORT PIKbdListener: public PIThread
{
PIOBJECT_SUBCLASS(PIKbdListener, PIThread)
friend class PIConsole;
friend class PITerminal;
public:
//! Special keyboard keys
@@ -152,6 +153,28 @@ private:
void run() {readKeyboard();}
void end();
#ifndef WINDOWS
struct EscSeq {
const char * seq;
int key;
int mod;
int vt;
int flags;
// 1 - shift
// 2 - alt
// 4 - ctrl
};
enum VTType {
vt_none,
vt_xterm = 0x1,
vt_linux = 0x2,
vt_all = 0xFF
};
static const EscSeq esc_seq[];
#endif
PRIVATE_DECLARATION
#ifdef WINDOWS
DWORD

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) {

View File

@@ -61,6 +61,7 @@ private:
bool isCompleteEscSeq(const PIString & es);
void applyEscSeq(PIString es);
void moveCursor(int dx, int dy);
int termType(const PIString & t);
#endif
PRIVATE_DECLARATION