diff --git a/main.cpp b/main.cpp index 786e4f4b..6e7d03f5 100644 --- a/main.cpp +++ b/main.cpp @@ -31,9 +31,9 @@ public: T dot(VC a) {T res = T(); for (uint i=0; i > c = term->content(); - d->fillRect(x, y, x + width, y + height, c); + d->fillRect(x_, y_, x_ + width_, y_ + height_, c); } bool keyEvent(PIKbdListener::KeyEvent key) { //piCout << "key"; @@ -67,7 +67,7 @@ private: int main (int argc, char * argv[]) { PIScreen screen; PITerminal term; - TerminalTile tt(&term); + TileTerminal tt(&term); screen.rootTile()->addTile(&tt); tt.setFocus(); screen.enableExitCapture(); diff --git a/src/auxiliary/piterminal/main.cpp b/src/auxiliary/piterminal/main.cpp index 69150b7d..2459086a 100644 --- a/src/auxiliary/piterminal/main.cpp +++ b/src/auxiliary/piterminal/main.cpp @@ -199,8 +199,8 @@ public: void getCursor(int & x, int & y) { GetConsoleScreenBufferInfo(console, &sbi); - x = sbi.dwCursorPosition.X + sbi.srWindow.Left; - y = sbi.dwCursorPosition.Y + sbi.srWindow.Top; + x = sbi.dwCursorPosition.X - sbi.srWindow.Left; + y = sbi.dwCursorPosition.Y - sbi.srWindow.Top; } diff --git a/src/console/piscreen.cpp b/src/console/piscreen.cpp index 8f595ce6..c3354743 100644 --- a/src/console/piscreen.cpp +++ b/src/console/piscreen.cpp @@ -472,8 +472,8 @@ void PIScreen::begin() { void PIScreen::run() { console.prepare(); - root.width = drawer_.width = console.width; - root.height = drawer_.height = console.height; + root.width_ = drawer_.width = console.width; + root.height_ = drawer_.height = console.height; root.layout(); root.drawEventInternal(&drawer_); if (tile_dialog) { @@ -481,12 +481,12 @@ void PIScreen::run() { tile_dialog->sizeHint(sw, sh); sw = piClampi(sw, tile_dialog->minimumWidth, tile_dialog->maximumWidth); sh = piClampi(sh, tile_dialog->minimumHeight, tile_dialog->maximumHeight); - tile_dialog->x = (console.width - sw) / 2; - tile_dialog->y = (console.height - sh) / 2; - tile_dialog->width = sw; - tile_dialog->height = sh; + tile_dialog->x_ = (console.width - sw) / 2; + tile_dialog->y_ = (console.height - sh) / 2; + tile_dialog->width_ = sw; + tile_dialog->height_ = sh; tile_dialog->layout(); - int dx = tile_dialog->x - 1, dy = tile_dialog->y - 1, dw = tile_dialog->width, dh = tile_dialog->height; + int dx = tile_dialog->x_ - 1, dy = tile_dialog->y_ - 1, dw = tile_dialog->width_, dh = tile_dialog->height_; drawer_.drawFrame(dx, dy, dx + dw + 1, dy + dh + 1, (Color)tile_dialog->back_format.color_char, (Color)tile_dialog->back_format.color_back, (CharFlags)tile_dialog->back_format.flags); tile_dialog->drawEventInternal(&drawer_); diff --git a/src/console/piscreentile.cpp b/src/console/piscreentile.cpp index bc103072..c0e697cd 100644 --- a/src/console/piscreentile.cpp +++ b/src/console/piscreentile.cpp @@ -29,7 +29,7 @@ PIScreenTile::PIScreenTile(const PIString & n, Direction d, SizePolicy p): PIObj size_policy = p; focus_flags = 0; screen = 0; - minimumWidth = minimumHeight = x = y = width = height = pw = ph = 0; + minimumWidth = minimumHeight = x_ = y_ = width_ = height_ = pw = ph = 0; maximumWidth = maximumHeight = 65535; marginLeft = marginRight = marginTop = marginBottom = spacing = 0; parent = 0; @@ -121,7 +121,7 @@ void PIScreenTile::drawEventInternal(PIScreenDrawer * d) { //d->clearRect(x, y, x + width, y + height); return; } - d->fillRect(x, y, x + width, y + height, back_symbol, (Color)back_format.color_char, (Color)back_format.color_back, back_format.flags); + d->fillRect(x_, y_, x_ + width_, y_ + height_, back_symbol, (Color)back_format.color_char, (Color)back_format.color_back, back_format.flags); drawEvent(d); piForeach (PIScreenTile * t, tiles) t->drawEventInternal(d); @@ -155,8 +155,8 @@ void PIScreenTile::sizeHint(int & w, int & h) const { void PIScreenTile::layout() { if (tiles.isEmpty() || !visible) return; int as(0), ts(0), ts2(0), ecnt(0), pcnt(0); - ts = (direction == Horizontal) ? (width - marginLeft - marginRight) : (height - marginTop - marginBottom); - ts2 = (direction != Horizontal) ? (width - marginLeft - marginRight) : (height - marginTop - marginBottom); + ts = (direction == Horizontal) ? (width_ - marginLeft - marginRight) : (height_ - marginTop - marginBottom); + ts2 = (direction != Horizontal) ? (width_ - marginLeft - marginRight) : (height_ - marginTop - marginBottom); ts -= spacing * (tiles.size_s() - 1); PIVector hints(tiles.size_s()); PIVector asizes(tiles.size_s()); @@ -218,25 +218,25 @@ void PIScreenTile::layout() { } } } - int cx = x + marginLeft, cy = y + marginTop; + int cx = x_ + marginLeft, cy = y_ + marginTop; for (int i = 0; i < tiles.size_s(); ++i) { PIScreenTile * t(tiles[i]); if (!t->visible) continue; - t->x = cx; - t->y = cy; + t->x_ = cx; + t->y_ = cy; if (direction == Horizontal) { - t->width = hints[i]; - t->height = ts2; + t->width_ = hints[i]; + t->height_ = ts2; cx += hints[i] + spacing; } else { - t->width = ts2; - t->height = hints[i]; + t->width_ = ts2; + t->height_ = hints[i]; cy += hints[i] + spacing; } - if (t->pw != t->width || t->ph != t->height) - t->resizeEvent(t->width, t->height); - t->pw = t->width; - t->ph = t->height; + if (t->pw != t->width_ || t->ph != t->height_) + t->resizeEvent(t->width_, t->height_); + t->pw = t->width_; + t->ph = t->height_; t->layout(); } } diff --git a/src/console/piscreentile.h b/src/console/piscreentile.h index e7c879e6..29421fe5 100644 --- a/src/console/piscreentile.h +++ b/src/console/piscreentile.h @@ -46,6 +46,11 @@ public: bool hasFocus() const {return has_focus;} void setMargins(int m) {marginLeft = marginRight = marginTop = marginBottom = m;} void setMargins(int l, int r, int t, int b) {marginLeft = l; marginRight = r; marginTop = t; marginBottom = b;} + + int x() const {return x_;} + int y() const {return y_;} + int width() const {return width_;} + int height() const {return height_;} PIScreenTypes::Direction direction; PIScreenTypes::SizePolicy size_policy; @@ -81,7 +86,7 @@ protected: PIVector tiles; PIScreenTile * parent; PIScreenTypes::PIScreenBase * screen; - int x, y, width, height; + int x_, y_, width_, height_; bool has_focus; private: diff --git a/src/console/piscreentiles.cpp b/src/console/piscreentiles.cpp index cb64cefd..c2152052 100644 --- a/src/console/piscreentiles.cpp +++ b/src/console/piscreentiles.cpp @@ -48,11 +48,11 @@ void TileSimple::drawEvent(PIScreenDrawer * d) { Row & r(content[i]); int rx = 0; switch (alignment) { - case Left: rx = x; break; - case Center: rx = x + (width - r.first.size_s()) / 2; break; - case Right: rx = x + width - r.first.size_s(); break; + case Left: rx = x_; break; + case Center: rx = x_ + (width_ - r.first.size_s()) / 2; break; + case Right: rx = x_ + width_ - r.first.size_s(); break; }; - d->drawText(rx, y + i, r.first, (Color)r.second.color_char, (Color)r.second.color_back, r.second.flags); + d->drawText(rx, y_ + i, r.first, (Color)r.second.color_char, (Color)r.second.color_back, r.second.flags); } } @@ -77,23 +77,23 @@ void TileList::sizeHint(int & w, int & h) const { void TileList::drawEvent(PIScreenDrawer * d) { vert_line = d->artChar(PIScreenDrawer::LineVertical); - lhei = height - 2; + lhei = height_ - 2; //int osp = piMini(3, lhei / 4); int is = piClampi(offset, 0, piMaxi(0, content.size_s() - 1)), ie = piClampi(offset + lhei, 0, content.size_s()); - if (is > 0) d->drawText(x, y, PIString(" /\\ ").repeat(width / 4), Green, Default, Bold); + if (is > 0) d->drawText(x_, y_, PIString(" /\\ ").repeat(width_ / 4), Green, Default, Bold); //piCout << is << ie << offset << lhei << content.size_s(); for (int i = is; i < ie; ++i) { Row & r(content[i]); bool sel = i == cur && has_focus; if (sel) { - int cy = y + i - is + 1; - d->drawLine(x, cy, x + width - 2, cy, ' ', Default, Blue); + int cy = y_ + i - is + 1; + d->drawLine(x_, cy, x_ + width_ - 2, cy, ' ', Default, Blue); } int rx(0); switch (alignment) { - case Left: rx = x; break; - case Center: rx = x + (width - 1 - r.first.size_s()) / 2; break; - case Right: rx = x + width - 1 - r.first.size_s(); break; + case Left: rx = x_; break; + case Center: rx = x_ + (width_ - 1 - r.first.size_s()) / 2; break; + case Right: rx = x_ + width_ - 1 - r.first.size_s(); break; }; CharFlags cf = r.second.flags; Color cc = (Color)r.second.color_char; @@ -101,18 +101,18 @@ void TileList::drawEvent(PIScreenDrawer * d) { cf |= Bold; cc = Yellow; } - d->drawText(rx, y + i - is + 1, r.first, cc, sel ? Blue : Default, cf); + d->drawText(rx, y_ + i - is + 1, r.first, cc, sel ? Blue : Default, cf); } - int cx = x + width - 1; - d->drawLine(cx, y + 1, cx, y + height - 2, vert_line, Green); + int cx = x_ + width_ - 1; + d->drawLine(cx, y_ + 1, cx, y_ + height_ - 2, vert_line, Green); if (content.size_s() > 1) - d->drawPixel(cx, y + piRound(float(cur) / (content.size_s() - 1) * (lhei - 1)) + 1, ' ', Green, Green); - if (ie < content.size_s()) d->drawText(x, y + height - 1, PIString(" \\/ ").repeat(width / 4), Green, Default, Bold); + d->drawPixel(cx, y_ + piRound(float(cur) / (content.size_s() - 1) * (lhei - 1)) + 1, ' ', Green, Green); + if (ie < content.size_s()) d->drawText(x_, y_ + height_ - 1, PIString(" \\/ ").repeat(width_ / 4), Green, Default, Bold); } bool TileList::keyEvent(PIKbdListener::KeyEvent key) { - lhei = height - 2; + lhei = height_ - 2; int oo(0), osp = piMini(3, lhei / 4); switch (key.key) { case PIKbdListener::PageUp: @@ -216,10 +216,10 @@ void TileButton::drawEvent(PIScreenDrawer * d) { Color cb = has_focus ? Blue : Cyan; Color ct = has_focus ? White : Black; int ff = has_focus ? Bold : 0; - d->fillRect(x, y, x + width, y + 1, ' ', Default, cb); - d->drawText(x, y, "[", ct, Transparent, ff); - d->drawText(x + (width - text.size_s()) / 2, y, text, ct, Transparent, ff); - d->drawText(x + width - 1, y, "]", ct, Transparent, ff); + d->fillRect(x_, y_, x_ + width_, y_ + 1, ' ', Default, cb); + d->drawText(x_, y_, "[", ct, Transparent, ff); + d->drawText(x_ + (width_ - text.size_s()) / 2, y_, text, ct, Transparent, ff); + d->drawText(x_ + width_ - 1, y_, "]", ct, Transparent, ff); } @@ -259,12 +259,12 @@ void TileButtons::sizeHint(int & w, int & h) const { void TileButtons::drawEvent(PIScreenDrawer * d) { - int cx = x, cy = y, shw, shh; + int cx = x_, cy = y_, shw, shh; sizeHint(shw, shh); int dx = 0; switch (alignment) { - case PIScreenTypes::Center: dx = (width - shw) / 2; break; - case PIScreenTypes::Right: dx = width - shw; break; + case PIScreenTypes::Center: dx = (width_ - shw) / 2; break; + case PIScreenTypes::Right: dx = width_ - shw; break; default: break; } if (direction == PIScreenTypes::Horizontal) @@ -281,7 +281,7 @@ void TileButtons::drawEvent(PIScreenDrawer * d) { Button & b(content[i]); int cw = b.first.size_s() + 2, xo(0); if (direction == Vertical) { - cw = width - 2; + cw = width_ - 2; xo = (cw - b.first.size_s()) / 2 - 1; } d->fillRect(cx, cy, cx + cw + 2, cy + 1, ' ', Default, cb); @@ -337,9 +337,9 @@ void TileCheck::drawEvent(PIScreenDrawer * d) { int ff = has_focus ? Bold : 0; PIString cs("[ ]"); if (toggled) cs[1] = '*'; - d->fillRect(x, y, x + width, y + 1, ' ', Default, cb); - d->drawText(x, y, cs, ct, Transparent, ff); - d->drawText(x + 4, y, text, ct, Transparent, ff); + d->fillRect(x_, y_, x_ + width_, y_ + 1, ' ', Default, cb); + d->drawText(x_, y_, cs, ct, Transparent, ff); + d->drawText(x_ + 4, y_, text, ct, Transparent, ff); } @@ -371,17 +371,17 @@ void TileProgress::sizeHint(int & w, int & h) const { void TileProgress::drawEvent(PIScreenDrawer * d) { int v = maximum == 0. ? 0 : piClampd(piRoundd(value / maximum * 100.), 0, 100); PIString s = prefix + PIString::fromNumber(piRoundd(value)) + suffix; - int w = piRoundd(v / 100. * width), sx = (width - s.size_s()) / 2; - d->fillRect(x, y, x + width, y + 1, ' ', Default, Cyan); - d->fillRect(x, y, x + w, y + 1, ' ', Default, Blue); + int w = piRoundd(v / 100. * width_), sx = (width_ - s.size_s()) / 2; + d->fillRect(x_, y_, x_ + width_, y_ + 1, ' ', Default, Cyan); + d->fillRect(x_, y_, x_ + w, y_ + 1, ' ', Default, Blue); if (w < sx) - d->drawText(x + sx, y, s, Black, Transparent); + d->drawText(x_ + sx, y_, s, Black, Transparent); else if (w >= sx + s.size_s()) - d->drawText(x + sx, y, s, White, Transparent); + d->drawText(x_ + sx, y_, s, White, Transparent); else { int fw = w - sx; - d->drawText(x + sx, y, s.left(fw), White, Transparent); - d->drawText(x + sx + fw, y, s.cutLeft(fw), Black, Transparent); + d->drawText(x_ + sx, y_, s.left(fw), White, Transparent); + d->drawText(x_ + sx + fw, y_, s.cutLeft(fw), Black, Transparent); } } @@ -443,12 +443,12 @@ void TileInput::sizeHint(int & w, int & h) const { void TileInput::drawEvent(PIScreenDrawer * d) { - PIString ps = text.mid(offset, width - 2); - d->drawText(x + 1, y, ps, (Color)format.color_char, Transparent, (CharFlags)format.flags); + PIString ps = text.mid(offset, width_ - 2); + d->drawText(x_ + 1, y_, ps, (Color)format.color_char, Transparent, (CharFlags)format.flags); if (offset > 0) - d->drawText(x, y, "<", Green, Black, Bold); - if (text.size_s() - offset >= width - 2) - d->drawText(x + width - 1, y, ">", Green, Black, Bold); + d->drawText(x_, y_, "<", Green, Black, Bold); + if (text.size_s() - offset >= width_ - 2) + d->drawText(x_ + width_ - 1, y_, ">", Green, Black, Bold); if (!has_focus) return; Color cb = (Color)format.color_char, cc = (Color)format.color_back; if (tm_blink.elapsed_m() >= 650) { @@ -456,12 +456,12 @@ void TileInput::drawEvent(PIScreenDrawer * d) { inv = !inv; } if (inv) piSwap(cb, cc); - d->drawText(x + 1 + cur - offset, y, text.mid(cur, 1).expandLeftTo(1, ' '), cc, cb, (CharFlags)format.flags); + d->drawText(x_ + 1 + cur - offset, y_, text.mid(cur, 1).expandLeftTo(1, ' '), cc, cb, (CharFlags)format.flags); } bool TileInput::keyEvent(PIKbdListener::KeyEvent key) { - int lwid = piMaxi(0, width - 2); + int lwid = piMaxi(0, width_ - 2); int oo(0), osp = piMini(3, lwid / 4); lwid--; switch (key.key) { diff --git a/src/console/piterminal.cpp b/src/console/piterminal.cpp index 995aeddd..4d74afd6 100644 --- a/src/console/piterminal.cpp +++ b/src/console/piterminal.cpp @@ -124,6 +124,16 @@ void PITerminal::write(PIKbdListener::SpecialKey k, PIKbdListener::KeyModifiers } +void PITerminal::write(PIKbdListener::KeyEvent ke) { + if (isSpecialKey(ke.key)) write((PIKbdListener::SpecialKey)ke.key, ke.modifiers); + else { + PIByteArray ba; + ba << uchar(PIChar(ke.key).toConcole1Byte()); + write(ba); + } +} + + PIVector > PITerminal::content() { readConsole(); return cells; diff --git a/src/console/piterminal.h b/src/console/piterminal.h index fdadbed3..2ba1df4d 100644 --- a/src/console/piterminal.h +++ b/src/console/piterminal.h @@ -44,6 +44,7 @@ public: void write(const PIByteArray & d); void write(PIKbdListener::SpecialKey k, PIKbdListener::KeyModifiers m); + void write(PIKbdListener::KeyEvent ke); PIVector > content(); static bool isSpecialKey(int k); diff --git a/src/thread/pitimer.h b/src/thread/pitimer.h index fdcf5e1b..3eb1b449 100755 --- a/src/thread/pitimer.h +++ b/src/thread/pitimer.h @@ -271,7 +271,7 @@ public: /** \fn void tickEvent(void * data, int delimiter) * \brief Raise on timer tick * \details \b Data can be set with function \a setData(void * data) or from constructor. - * \b Delimiter if frequency delimiter, 1 for main loop. */ + * \b Delimiter is frequency delimiter, 1 for main loop. */ //! \} diff --git a/utils/system_daemon/daemon.cpp b/utils/system_daemon/daemon.cpp index 4ad78cca..4738d0f2 100644 --- a/utils/system_daemon/daemon.cpp +++ b/utils/system_daemon/daemon.cpp @@ -9,21 +9,65 @@ extern PIScreen * screen; Daemon::Remote::Remote(const PIString & n): PIThread() { setName(n); + term = 0; ft.setName(n); ft.setPacketSize(3984); CONNECTU(&ft, sendRequest, this, ftSendRequest) CONNECTU(&ft, receiveFilesFinished, this, ftReceived) CONNECTU(&ft, sendFilesFinished, this, ftSended) + CONNECTU(&term_timer, tickEvent, this, termTimerTick) dir_my = PIDir::current(); } Daemon::Remote::~Remote() { + shellClose(); ft.stop(); stop(true); } +void Daemon::Remote::shellOpen() { + if (term) return; + term = new PITerminal(); + term->initialize(); + term_timer.start(40); +} + + +void Daemon::Remote::shellClose() { + if (!term) return; + //piCoutObj << "shellClose ..."; + term_timer.stop(); + term_timer.waitForFinish(100); + term->destroy(); + delete term; + term = 0; + //piCoutObj << "shellClose ok"; +} + + +void Daemon::Remote::shellResize(int w, int h) { + if (!term) return; + term->resize(w, h); +} + + +void Daemon::Remote::shellKeySend(PIKbdListener::KeyEvent k) { + if (!term) return; + term->write(k); +} + + +void Daemon::Remote::termTimerTick() { + if (!term) return; + PIVector > cells = term->content(); + PIByteArray ba; + ba << int(ShellContent) << cells; + sendRequest(name(), ba); +} + + void Daemon::Remote::startAction(Daemon::PacketType a, const PIString & dir, const PIStringList & fl) { _fl = fl; if (!dir.isEmpty()) @@ -209,7 +253,8 @@ void Daemon::TileFileProgress::tileEvent(PIScreenTile * t, TileEvent e) { Daemon::Daemon(): inited__(false), PIPeer(pisd_prefix + PISystemInfo::instance()->hostname + "_" + PIString(rand() % 100)) { // setName("Daemon"); dtimer.setName("__S__Daemon_timer"); - mode = offset = cur = height = 0; + mode = rmNone; + offset = cur = height = 0; CONNECTU(screen, keyPressed, this, keyEvent) CONNECTU(&dtimer, tickEvent, this, timerEvent) CONNECTU(&fm, tileKey, this, fmKeyEvent) @@ -251,13 +296,21 @@ Daemon::Daemon(): inited__(false), PIPeer(pisd_prefix + PISystemInfo::instance() tile_fm->hide(); tile_file_progress = new TileFileProgress(); - + + tile_shell = new TileTerminal("shell"); + tile_shell->hide(); + CONNECTU(tile_shell, resizeRequest, this, shResizeRequest) + CONNECTU(tile_shell, keyPressed, this, shKeyEvent) + CONNECTU(tile_shell, closeRequest, this, requestCloseShell) + CONNECTU(tile_shell, closeRequest, this, escPressed) + tile_root->addTile(tile_header); tile_root->addTile(list_daemons); tile_root->addTile(list_actions); tile_root->addTile(tile_info); tile_root->addTile(tile_fm); + tile_root->addTile(tile_shell); CONNECTU(screen, tileEvent, this, tileEvent) reinit(); @@ -266,9 +319,12 @@ Daemon::Daemon(): inited__(false), PIPeer(pisd_prefix + PISystemInfo::instance() Daemon::~Daemon() { + requestCloseShell(); PIVector rl = remotes.values(); - piForeach (Remote * r, rl) + piForeach (Remote * r, rl) { + r->shellClose(); delete r; + } remotes.clear(); } @@ -278,6 +334,40 @@ PIScreenTile * Daemon::tile() const { } +void Daemon::escPressed() { + if (mode == rmNone) + menuRequest(); + else { + if (mode > rmSelectMode) { + mode = rmSelectMode; + screen->lock(); + tile_info->content.clear(); + screen->unlock(); + showActionList(); + } else + disconnect(); + } +} + + +void Daemon::shResizeRequest() { + Remote * r = remotes.value(conn_name, 0); + if (!r) return; + PIByteArray ba; + ba << int(ShellResizeRequest) << int(tile_shell->width()) << int(tile_shell->height()); + send(conn_name, ba); +} + + +void Daemon::shKeyEvent(PIKbdListener::KeyEvent k) { + Remote * r = remotes.value(conn_name, 0); + if (!r) return; + PIByteArray ba; + ba << int(ShellKeyEvent) << k; + send(conn_name, ba); +} + + void Daemon::localSend(const PIString & p_name, const PIByteArray & data) { //piCoutObj << "localSend" << localft.stateString(); PIByteArray h; h << int(FileTransfer); @@ -292,6 +382,7 @@ void Daemon::hideAll() { tile_info->hide(); list_daemons->hide(); tile_fm->hide(); + tile_shell->hide(); } @@ -344,12 +435,20 @@ void Daemon::tileEvent(PIScreenTile * t, TileEvent e) { if (e.type == TileList::RowPressed) { PIMutexLocker ml(remote_mutex); switch (e.data.toInt()) { - case 0: mode = 2; showTile(tile_info, "Information"); break; + case 0: + mode = rmInformation; + showTile(tile_info, "Information"); + break; case 1: - mode = 3; + mode = rmFileManager; showTile(tile_fm, "File manager"); requestChDir("."); break; + case 2: + mode = rmShell; + showTile(tile_shell, "Shell"); + requestOpenShell(); + break; default: break; } } @@ -363,18 +462,7 @@ void Daemon::keyEvent(PIKbdListener::KeyEvent key) { if (screen->dialogTile()) return; switch (key.key) { case PIKbdListener::Esc: - if (mode == 0) - menuRequest(); - else { - if (mode > 1) { - mode = 1; - screen->lock(); - tile_info->content.clear(); - screen->unlock(); - showActionList(); - } else - disconnect(); - } + escPressed(); break; default: break; } @@ -478,7 +566,7 @@ void Daemon::timerEvent(void * _d, int delim) { piForeachC (PIString & i, available_daemons) list_daemons->content << TileList::Row(i, CellFormat()); screen->unlock(); - if (delim == 5 && mode == 2) { + if (delim == 5 && mode == rmInformation) { if (conn_name.isEmpty()) return; PIByteArray ba; ba << int(RequestHostInfo); send(conn_name, ba); @@ -502,13 +590,13 @@ PIStringList Daemon::availableDaemons() { void Daemon::connectToDaemon(const PIString & dn) { if (dn.isEmpty()) return; conn_name = pisd_prefix + dn; - mode = 1; + mode = rmSelectMode; } void Daemon::disconnect() { conn_name.clear(); - mode = 0; + mode = rmNone; showMainList(); } @@ -547,6 +635,7 @@ void Daemon::peerDisconnected(const PIString & p_name) { PIMutexLocker ml(remote_mutex); Remote * dt = remotes.value(p_name, 0); if (!dt) return; + dt->shellClose(); if (tile_file_progress->ft == &(dt->ft)) { tile_file_progress->close(false); } @@ -615,7 +704,7 @@ void Daemon::dataReceived(const PIString & from, const PIByteArray & data) { Remote * r = remotes.value(from); PIString dir; int type; ba >> type; -// piCout << "rec from " << from << type << r; + //piCout << "rec from " << from << type << r; switch (type) { case RequestHostInfo: makeMyHostInfo(); @@ -689,6 +778,32 @@ void Daemon::dataReceived(const PIString & from, const PIByteArray & data) { r->cryptFiles(files); } break; + case ShellOpen: + if (!r) return; + r->shellOpen(); + break; + case ShellClose: + if (!r) return; + r->shellClose(); + break; + case ShellContent: { + if (!r) return; + PIVector > cells; + ba >> cells; + tile_shell->setContent(cells); + } break; + case ShellResizeRequest: { + if (!r) return; + int w, h; + ba >> w >> h; + r->shellResize(w, h); + } break; + case ShellKeyEvent: { + if (!r) return; + PIKbdListener::KeyEvent k; + ba >> k; + r->shellKeySend(k); + } break; }; if (!rba.isEmpty()) send(from, rba); } @@ -703,6 +818,24 @@ void Daemon::sendDirToRemote(Remote * r) { } +void Daemon::requestOpenShell() { + Remote * r = remotes.value(conn_name, 0); + if (!r) return; + PIByteArray ba; + ba << int(ShellOpen); + send(conn_name, ba); +} + + +void Daemon::requestCloseShell() { + Remote * r = remotes.value(conn_name, 0); + if (!r) return; + PIByteArray ba; + ba << int(ShellClose); + send(conn_name, ba); +} + + void Daemon::makeMyHostInfo() { info_my.execCommand = PISystemInfo::instance()->execCommand; info_my.hostname = PISystemInfo::instance()->hostname; diff --git a/utils/system_daemon/daemon.h b/utils/system_daemon/daemon.h index 308c60fa..41eb33bf 100644 --- a/utils/system_daemon/daemon.h +++ b/utils/system_daemon/daemon.h @@ -7,6 +7,8 @@ #include "pidatatransfer.h" #include "pifiletransfer.h" #include "file_manager.h" +#include "terminal_tile.h" +#include "piterminal.h" extern PISystemMonitor sys_mon; @@ -42,7 +44,7 @@ public: void showMainList() {showTile(list_daemons, "Select daemon");} void showActionList() {showTile(list_actions, "Select action");} - void showLocalFilemanager() {mode = 3; showTile(tile_fm, "File manager");} + void showLocalFilemanager() {mode = rmFileManager; showTile(tile_fm, "File manager");} PIStringList availableDaemons(); void connectToDaemon(const PIString & dn); @@ -73,9 +75,23 @@ private: MkDir, CryptFiles, - FileTransfer = 30 + FileTransfer = 30, + + ShellOpen = 40, + ShellClose, + ShellContent, + ShellResizeRequest, + ShellKeyEvent }; + + enum RemoteMode { + rmNone, + rmSelectMode, + rmInformation, + rmFileManager, + rmShell + }; class Remote: public PIThread { PIOBJECT_SUBCLASS(Remote, PIThread) @@ -87,6 +103,10 @@ private: void updateDir() {startAction(Daemon::RequestChangeDir, PIString(), PIStringList());} void makeDir(const PIString & dir) {startAction(Daemon::MkDir, dir, PIStringList() << "");} void cryptFiles(const PIStringList & fl) {startAction(Daemon::CryptFiles, PIString(), fl);} + void shellOpen(); + void shellClose(); + void shellResize(int w, int h); + void shellKeySend(PIKbdListener::KeyEvent k); EVENT_HANDLER1(void, ftSendRequest, PIByteArray &, data) {PIByteArray h; h << int(FileTransfer); data.insert(0, h); sendRequest(name(), data);} EVENT_HANDLER1(void, ftReceived, bool, ok) {receiveFinished(name(), ok);} EVENT_HANDLER1(void, ftSended, bool, ok) {sendFinished(name(), ok);} @@ -96,6 +116,7 @@ private: EVENT2(sendFinished, const PIString & , p_name, bool, ok) EVENT2(changeDirFinished, const PIString & , p_name, const PIString & , dir) EVENT_HANDLER1(void, received, PIByteArray & , data) {ft.received(data);} + EVENT_HANDLER(void, termTimerTick); void startAction(PacketType a, const PIString & dir, const PIStringList & fl); void run(); @@ -105,6 +126,8 @@ private: PIFileTransfer ft; PIStringList _fl; PacketType action; + PITimer term_timer; + PITerminal * term; private: void updateDirEntries(); @@ -134,11 +157,16 @@ private: EVENT_HANDLER2(void, sendRequest, const PIString &, p_name, const PIByteArray &, data) {send(p_name, data);} EVENT_HANDLER1(void, fmKeyEvent, PIKbdListener::KeyEvent, key); EVENT_HANDLER3(void, fmActionRequest, bool, remote_tile, FileManager::Action, type, PIVariant, data); + EVENT_HANDLER (void, shResizeRequest); + EVENT_HANDLER1(void, shKeyEvent, PIKbdListener::KeyEvent, k); EVENT_HANDLER2(void, timerEvent, void * , _d, int, delim); EVENT_HANDLER2(void, filesReceived, const PIString & , p_name, bool, ok); EVENT_HANDLER2(void, dirChanged, const PIString & , p_name, const PIString & , dir); EVENT_HANDLER2(void, closeFileDialog, const PIString & , p_name, bool, ok); EVENT_HANDLER2(void, localSend, const PIString & , p_name, const PIByteArray &, data); + EVENT_HANDLER (void, escPressed); + EVENT_HANDLER (void, requestOpenShell); + EVENT_HANDLER (void, requestCloseShell); EVENT(menuRequest) void hideAll(); void showTile(PIScreenTile * t, const PIString & header = PIString()); @@ -163,9 +191,11 @@ private: TileSimple * tile_info, * tile_header; TileList * list_daemons, * list_actions; TileFileProgress * tile_file_progress; + TileTerminal * tile_shell; PIFileTransfer localft; Remote * _self; - int mode, offset, cur, height; + RemoteMode mode; + int offset, cur, height; bool inited__; }; diff --git a/utils/system_daemon/file_manager.cpp b/utils/system_daemon/file_manager.cpp index 8dfbb8ab..da3a9a20 100644 --- a/utils/system_daemon/file_manager.cpp +++ b/utils/system_daemon/file_manager.cpp @@ -201,9 +201,9 @@ void FileManager::TileDir::buildNames() { scol = scol.expandRightTo(9, ' ') + "| " + e.time_modification.toString("dd.MM hh:mm:ss") + " | " + e.perm_user.toString() + " " + e.perm_group.toString() + " " + e.perm_other.toString(); fcol = t + e.name(); - if (fcol.size_s() >= width - 2 - scol.size_s()) - fcol = fcol.left(width - 5 - scol.size_s()) + "..."; - fcol.expandRightTo(width - 1 - scol.size_s(), ' '); + if (fcol.size_s() >= width_ - 2 - scol.size_s()) + fcol = fcol.left(width_ - 5 - scol.size_s()) + "..."; + fcol.expandRightTo(width_ - 1 - scol.size_s(), ' '); content << Row(fcol + scol, CellFormat(cc, Transparent, cf)); } unlock(); diff --git a/utils/system_daemon/terminal_tile.cpp b/utils/system_daemon/terminal_tile.cpp new file mode 100644 index 00000000..85522afd --- /dev/null +++ b/utils/system_daemon/terminal_tile.cpp @@ -0,0 +1,44 @@ +#include "terminal_tile.h" +#include "piscreendrawer.h" + + +TileTerminal::TileTerminal(const PIString & n): PIScreenTile(n) { + focus_flags = PIScreenTypes::CanHasFocus; + size_policy = PIScreenTypes::Expanding; + lastp[0] = lastp[1] = lastp[2] = 0; +} + + +void TileTerminal::drawEvent(PIScreenDrawer * d) { + //piCout << "draw" << visible; + //PIVector > c = term->content(); + d->fillRect(x_, y_, x_ + width_, y_ + height_, cells); +} + + +bool TileTerminal::keyEvent(PIKbdListener::KeyEvent key) { + lastp[0] = lastp[1]; + lastp[1] = lastp[2]; + lastp[2] = char(key.key); + if (lastp[0] == '\e' && lastp[1] == '~' && lastp[2] == '.') { + closeRequest(); + return true; + } + //piCout << "key"; + /*if (!term) return false; + if (PITerminal::isSpecialKey(key.key)) term->write((PIKbdListener::SpecialKey)key.key, key.modifiers); + else { + PIByteArray ba; + ba << PIChar(key.key).toConcole1Byte(); + term->write(ba); + }*/ + keyPressed(key); + return true; +} + + +void TileTerminal::resizeEvent(int w, int h) { + /*if (!term) return; + term->resize(w, h);*/ + resizeRequest(); +} diff --git a/utils/system_daemon/terminal_tile.h b/utils/system_daemon/terminal_tile.h new file mode 100644 index 00000000..0d97c497 --- /dev/null +++ b/utils/system_daemon/terminal_tile.h @@ -0,0 +1,30 @@ +#ifndef TERMINAL_TILE_H +#define TERMINAL_TILE_H + +#include "piscreentile.h" +#include "pikbdlistener.h" + + +class TileTerminal: public PIScreenTile { + PIOBJECT_SUBCLASS(TileTerminal, PIScreenTile) +public: + TileTerminal(const PIString & n); + + void setContent(const PIVector > & c) {cells = c;} + + EVENT(resizeRequest) + EVENT1(keyPressed, PIKbdListener::KeyEvent, k) + EVENT(closeRequest) + +private: + void drawEvent(PIScreenDrawer * d); + bool keyEvent(PIKbdListener::KeyEvent key); + void resizeEvent(int w, int h); + + PIVector > cells; + char lastp[3]; + +}; + + +#endif // TERMINAL_TILE_H