You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
846 lines
20 KiB
C++
846 lines
20 KiB
C++
/*
|
|
This file is part of Konsole, an X terminal.
|
|
Copyright (C) 1997,1998 by Lars Doelle <lars.doelle@on-line.de>
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
02110-1301 USA.
|
|
*/
|
|
|
|
#include "session.h"
|
|
#include "zmodem_dialog.h"
|
|
|
|
#include <kdebug.h>
|
|
#include <dcopclient.h>
|
|
#include <tdemessagebox.h>
|
|
#include <knotifyclient.h>
|
|
#include <tdelocale.h>
|
|
#include <kprocio.h>
|
|
#include <krun.h>
|
|
#include <kshell.h>
|
|
#include <kstandarddirs.h>
|
|
|
|
#include <stdlib.h>
|
|
#include <tqfile.h>
|
|
#include <tqdir.h>
|
|
#include <tqregexp.h>
|
|
#include <tqtextedit.h>
|
|
|
|
/*! \class TESession
|
|
|
|
Sessions are combinations of TEPTy and Emulations.
|
|
|
|
The stuff in here does not belong to the terminal emulation framework,
|
|
but to main.cpp. It serves it's duty by providing a single reference
|
|
to TEPTy/Emulation pairs. In fact, it is only there to demonstrate one
|
|
of the abilities of the framework - multible sessions.
|
|
*/
|
|
|
|
TESession::TESession(TEWidget* _te, const TQString &_term, ulong _winId, const TQString &_sessionId, const TQString &_initial_cwd)
|
|
: DCOPObject( _sessionId.latin1() )
|
|
, sh(0)
|
|
, connected(true)
|
|
, monitorActivity(false)
|
|
, monitorSilence(false)
|
|
, notifiedActivity(false)
|
|
, masterMode(false)
|
|
, autoClose(true)
|
|
, wantedClose(false)
|
|
, schema_no(0)
|
|
, font_no(3)
|
|
, silence_seconds(10)
|
|
, add_to_utmp(true)
|
|
, xon_xoff(false)
|
|
, pgm(TQString())
|
|
, args(TQStrList())
|
|
, sessionId(_sessionId)
|
|
, cwd("")
|
|
, initial_cwd(_initial_cwd)
|
|
, zmodemBusy(false)
|
|
, zmodemProc(0)
|
|
, zmodemProgress(0)
|
|
, encoding_no(0)
|
|
{
|
|
//kdDebug(1211)<<"TESession ctor() new TEPty"<<endl;
|
|
te = _te;
|
|
//kdDebug(1211)<<"TESession ctor() new TEmuVt102"<<endl;
|
|
em = new TEmuVt102(te);
|
|
font_h = te-> fontHeight();
|
|
font_w = te-> fontWidth();
|
|
TQObject::connect(te,TQT_SIGNAL(changedContentSizeSignal(int,int)),
|
|
this,TQT_SLOT(onContentSizeChange(int,int)));
|
|
TQObject::connect(te,TQT_SIGNAL(changedFontMetricSignal(int,int)),
|
|
this,TQT_SLOT(onFontMetricChange(int,int)));
|
|
|
|
term = _term;
|
|
winId = _winId;
|
|
iconName = "konsole";
|
|
|
|
setPty( new TEPty() );
|
|
|
|
connect( em, TQT_SIGNAL( changeTitle( int, const TQString & ) ),
|
|
this, TQT_SLOT( setUserTitle( int, const TQString & ) ) );
|
|
connect( em, TQT_SIGNAL( notifySessionState(int) ),
|
|
this, TQT_SLOT( notifySessionState(int) ) );
|
|
monitorTimer = new TQTimer(this);
|
|
connect(monitorTimer, TQT_SIGNAL(timeout()), this, TQT_SLOT(monitorTimerDone()));
|
|
|
|
connect( em, TQT_SIGNAL( zmodemDetected() ), this, TQT_SLOT(slotZModemDetected()));
|
|
|
|
connect( em, TQT_SIGNAL( changeTabTextColor( int ) ),
|
|
this, TQT_SLOT( changeTabTextColor( int ) ) );
|
|
|
|
//kdDebug(1211)<<"TESession ctor() done"<<endl;
|
|
}
|
|
|
|
void TESession::setPty(TEPty *_sh)
|
|
{
|
|
if ( sh ) {
|
|
delete sh;
|
|
}
|
|
sh = _sh;
|
|
connect( sh, TQT_SIGNAL( forkedChild() ),
|
|
this, TQT_SIGNAL( forkedChild() ));
|
|
|
|
//kdDebug(1211)<<"TESession ctor() sh->setSize()"<<endl;
|
|
sh->setSize(te->Lines(),te->Columns()); // not absolutely nessesary
|
|
sh->useUtf8(em->utf8());
|
|
//kdDebug(1211)<<"TESession ctor() connecting"<<endl;
|
|
connect( sh,TQT_SIGNAL(block_in(const char*,int)),this,TQT_SLOT(onRcvBlock(const char*,int)) );
|
|
|
|
connect( em,TQT_SIGNAL(sndBlock(const char*,int)),sh,TQT_SLOT(send_bytes(const char*,int)) );
|
|
connect( em,TQT_SIGNAL(lockPty(bool)),sh,TQT_SLOT(lockPty(bool)) );
|
|
connect( em,TQT_SIGNAL(useUtf8(bool)),sh,TQT_SLOT(useUtf8(bool)) );
|
|
|
|
connect( sh,TQT_SIGNAL(done(int)), this,TQT_SLOT(done(int)) );
|
|
|
|
if (!sh->error().isEmpty())
|
|
TQTimer::singleShot(0, this, TQT_SLOT(ptyError()));
|
|
}
|
|
|
|
void TESession::ptyError()
|
|
{
|
|
// FIXME: sh->error() is always empty
|
|
if ( sh->error().isEmpty() )
|
|
KMessageBox::error( te->topLevelWidget(),
|
|
i18n("Konsole is unable to open a PTY (pseudo teletype). It is likely that this is due to an incorrect configuration of the PTY devices. Konsole needs to have read/write access to the PTY devices."),
|
|
i18n("A Fatal Error Has Occurred") );
|
|
else
|
|
KMessageBox::error(te->topLevelWidget(), sh->error());
|
|
emit done(this);
|
|
}
|
|
|
|
void TESession::changeWidget(TEWidget* w)
|
|
{
|
|
TQObject::disconnect(te,TQT_SIGNAL(changedContentSizeSignal(int,int)),
|
|
this,TQT_SLOT(onContentSizeChange(int,int)));
|
|
TQObject::disconnect(te,TQT_SIGNAL(changedFontMetricSignal(int,int)),
|
|
this,TQT_SLOT(onFontMetricChange(int,int)));
|
|
te=w;
|
|
em->changeGUI(w);
|
|
font_h = te->fontHeight();
|
|
font_w = te->fontWidth();
|
|
sh->setSize(te->Lines(),te->Columns()); // not absolutely nessesary
|
|
|
|
te->setDefaultBackColor(modifiedBackground);
|
|
|
|
TQObject::connect(te,TQT_SIGNAL(changedContentSizeSignal(int,int)),
|
|
this,TQT_SLOT(onContentSizeChange(int,int)));
|
|
TQObject::connect(te,TQT_SIGNAL(changedFontMetricSignal(int,int)),
|
|
this,TQT_SLOT(onFontMetricChange(int,int)));
|
|
}
|
|
|
|
void TESession::setProgram( const TQString &_pgm, const TQStrList &_args )
|
|
{
|
|
pgm = _pgm;
|
|
args = _args;
|
|
}
|
|
|
|
void TESession::run()
|
|
{
|
|
// Upon a KPty error, there is no description on what that error was...
|
|
// Check to see if the given program is executable.
|
|
TQString exec = TQFile::encodeName(pgm);
|
|
exec = KRun::binaryName(exec, false);
|
|
exec = KShell::tildeExpand(exec);
|
|
TQString pexec = TDEGlobal::dirs()->findExe(exec);
|
|
if ( pexec.isEmpty() ) {
|
|
kdError()<<"can not execute "<<exec<<endl;
|
|
TQTimer::singleShot(1, this, TQT_SLOT(done()));
|
|
return;
|
|
}
|
|
|
|
TQString appId=kapp->dcopClient()->appId();
|
|
|
|
TQString cwd_save = TQDir::currentDirPath();
|
|
if (!initial_cwd.isEmpty())
|
|
TQDir::setCurrent(initial_cwd);
|
|
sh->setXonXoff(xon_xoff);
|
|
|
|
int result = sh->run(TQFile::encodeName(pgm), args, term.latin1(),
|
|
winId, add_to_utmp,
|
|
("DCOPRef("+appId+",konsole)").latin1(),
|
|
("DCOPRef("+appId+","+sessionId+")").latin1());
|
|
if (result < 0) { // Error in opening pseudo teletype
|
|
kdWarning()<<"Unable to open a pseudo teletype!"<<endl;
|
|
TQTimer::singleShot(0, this, TQT_SLOT(ptyError()));
|
|
}
|
|
sh->setErase(em->getErase());
|
|
|
|
if (!initial_cwd.isEmpty())
|
|
TQDir::setCurrent(cwd_save);
|
|
else
|
|
initial_cwd=cwd_save;
|
|
|
|
sh->setWriteable(false); // We are reachable via kwrited.
|
|
}
|
|
|
|
void TESession::changeTabTextColor( int color )
|
|
{
|
|
emit changeTabTextColor( this, color );
|
|
}
|
|
|
|
void TESession::setUserTitle( int what, const TQString &caption )
|
|
{
|
|
// (btw: what=0 changes title and icon, what=1 only icon, what=2 only title
|
|
if ((what == 0) || (what == 2))
|
|
userTitle = caption;
|
|
if ((what == 0) || (what == 1))
|
|
iconText = caption;
|
|
if (what == 11) {
|
|
TQString colorString = caption.section(';',0,0);
|
|
TQColor backColor = TQColor(colorString);
|
|
if (backColor.isValid()){// change color via \033]11;Color\007
|
|
if (backColor != modifiedBackground) {
|
|
modifiedBackground = backColor;
|
|
te->setDefaultBackColor(backColor);
|
|
}
|
|
}
|
|
}
|
|
if (what == 30)
|
|
renameSession(caption);
|
|
if (what == 31) {
|
|
cwd=caption;
|
|
cwd=cwd.replace( TQRegExp("^~"), TQDir::homeDirPath() );
|
|
emit openURLRequest(cwd);
|
|
}
|
|
if (what == 32) { // change icon via \033]32;Icon\007
|
|
iconName = caption;
|
|
te->update();
|
|
}
|
|
|
|
emit updateTitle(this);
|
|
}
|
|
|
|
TQString TESession::fullTitle() const
|
|
{
|
|
TQString res = title;
|
|
if ( !userTitle.isEmpty() )
|
|
res = userTitle + " - " + res;
|
|
return res;
|
|
}
|
|
|
|
void TESession::monitorTimerDone()
|
|
{
|
|
if (monitorSilence) {
|
|
KNotifyClient::event(winId, "Silence", i18n("Silence in session '%1'").arg(title));
|
|
emit notifySessionState(this,NOTIFYSILENCE);
|
|
}
|
|
notifiedActivity=false;
|
|
}
|
|
|
|
void TESession::notifySessionState(int state)
|
|
{
|
|
if (state==NOTIFYBELL) {
|
|
te->Bell(em->isConnected(),i18n("Bell in session '%1'").arg(title));
|
|
} else if (state==NOTIFYACTIVITY) {
|
|
if (monitorSilence) {
|
|
monitorTimer->start(silence_seconds*1000,true);
|
|
}
|
|
if (!monitorActivity)
|
|
return;
|
|
if (!notifiedActivity) {
|
|
KNotifyClient::event(winId, "Activity", i18n("Activity in session '%1'").arg(title));
|
|
notifiedActivity=true;
|
|
monitorTimer->start(silence_seconds*1000,true);
|
|
}
|
|
}
|
|
|
|
emit notifySessionState(this, state);
|
|
}
|
|
|
|
void TESession::onContentSizeChange(int height, int width)
|
|
{
|
|
// ensure that image is at least one line high by one column wide
|
|
const int columns = TQMAX( width/font_w , 1 );
|
|
const int lines = TQMAX( height/font_h , 1 );
|
|
|
|
em->onImageSizeChange( lines , columns );
|
|
sh->setSize( lines , columns );
|
|
}
|
|
|
|
void TESession::onFontMetricChange(int height, int width)
|
|
{
|
|
//kdDebug(1211)<<"TESession::onFontMetricChange " << height << " " << width << endl;
|
|
if (connected) {
|
|
font_h = height;
|
|
font_w = width;
|
|
}
|
|
}
|
|
|
|
bool TESession::sendSignal(int signal)
|
|
{
|
|
return sh->kill(signal);
|
|
}
|
|
|
|
bool TESession::closeSession()
|
|
{
|
|
autoClose = true;
|
|
wantedClose = true;
|
|
if (!sh->isRunning() || !sendSignal(SIGHUP))
|
|
{
|
|
// Forced close.
|
|
TQTimer::singleShot(1, this, TQT_SLOT(done()));
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void TESession::feedSession(const TQString &text)
|
|
{
|
|
emit disableMasterModeConnections();
|
|
setListenToKeyPress(true);
|
|
te->emitText(text);
|
|
setListenToKeyPress(false);
|
|
emit enableMasterModeConnections();
|
|
}
|
|
|
|
void TESession::sendSession(const TQString &text)
|
|
{
|
|
TQString newtext=text;
|
|
newtext.append("\r");
|
|
feedSession(newtext);
|
|
}
|
|
|
|
void TESession::renameSession(const TQString &name)
|
|
{
|
|
title=name;
|
|
emit renameSession(this,name);
|
|
}
|
|
|
|
TESession::~TESession()
|
|
{
|
|
//kdDebug(1211) << "disconnnecting..." << endl;
|
|
TQObject::disconnect( sh, TQT_SIGNAL( done(int) ),
|
|
this, TQT_SLOT( done(int) ) );
|
|
delete em;
|
|
delete sh;
|
|
|
|
delete zmodemProc;
|
|
}
|
|
|
|
void TESession::setConnect(bool c)
|
|
{
|
|
connected=c;
|
|
em->setConnect(c);
|
|
setListenToKeyPress(c);
|
|
}
|
|
|
|
void TESession::setListenToKeyPress(bool l)
|
|
{
|
|
em->setListenToKeyPress(l);
|
|
}
|
|
|
|
void TESession::done() {
|
|
emit processExited(sh);
|
|
emit done(this);
|
|
}
|
|
|
|
void TESession::done(int exitStatus)
|
|
{
|
|
if (!autoClose)
|
|
{
|
|
userTitle = i18n("<Finished>");
|
|
emit updateTitle(this);
|
|
return;
|
|
}
|
|
if (!wantedClose && (exitStatus || sh->signalled()))
|
|
{
|
|
if (sh->normalExit())
|
|
KNotifyClient::event(winId, "Finished", i18n("Session '%1' exited with status %2.").arg(title).arg(exitStatus));
|
|
else if (sh->signalled())
|
|
{
|
|
if (sh->coreDumped())
|
|
KNotifyClient::event(winId, "Finished", i18n("Session '%1' exited with signal %2 and dumped core.").arg(title).arg(sh->exitSignal()));
|
|
else
|
|
KNotifyClient::event(winId, "Finished", i18n("Session '%1' exited with signal %2.").arg(title).arg(sh->exitSignal()));
|
|
}
|
|
else
|
|
KNotifyClient::event(winId, "Finished", i18n("Session '%1' exited unexpectedly.").arg(title));
|
|
}
|
|
emit processExited(sh);
|
|
emit done(this);
|
|
}
|
|
|
|
void TESession::terminate()
|
|
{
|
|
delete this;
|
|
}
|
|
|
|
TEmulation* TESession::getEmulation()
|
|
{
|
|
return em;
|
|
}
|
|
|
|
// following interfaces might be misplaced ///
|
|
|
|
int TESession::schemaNo()
|
|
{
|
|
return schema_no;
|
|
}
|
|
|
|
int TESession::encodingNo()
|
|
{
|
|
return encoding_no;
|
|
}
|
|
|
|
int TESession::keymapNo()
|
|
{
|
|
return em->keymapNo();
|
|
}
|
|
|
|
TQString TESession::keymap()
|
|
{
|
|
return em->keymap();
|
|
}
|
|
|
|
int TESession::fontNo()
|
|
{
|
|
return font_no;
|
|
}
|
|
|
|
const TQString & TESession::Term()
|
|
{
|
|
return term;
|
|
}
|
|
|
|
const TQString & TESession::SessionId()
|
|
{
|
|
return sessionId;
|
|
}
|
|
|
|
void TESession::setSchemaNo(int sn)
|
|
{
|
|
schema_no = sn;
|
|
}
|
|
|
|
void TESession::setEncodingNo(int index)
|
|
{
|
|
encoding_no = index;
|
|
}
|
|
|
|
void TESession::setKeymapNo(int kn)
|
|
{
|
|
em->setKeymap(kn);
|
|
}
|
|
|
|
void TESession::setKeymap(const TQString &id)
|
|
{
|
|
em->setKeymap(id);
|
|
}
|
|
|
|
void TESession::setFontNo(int fn)
|
|
{
|
|
font_no = fn;
|
|
}
|
|
|
|
void TESession::setMetaAsAltMode(bool mode)
|
|
{
|
|
if (em)
|
|
em->setMetaKeyMode(mode);
|
|
}
|
|
|
|
void TESession::setTitle(const TQString& _title)
|
|
{
|
|
title = _title;
|
|
//kdDebug(1211)<<"Session setTitle " << title <<endl;
|
|
}
|
|
|
|
const TQString& TESession::Title()
|
|
{
|
|
return title;
|
|
}
|
|
|
|
void TESession::setIconName(const TQString& _iconName)
|
|
{
|
|
iconName = _iconName;
|
|
}
|
|
|
|
void TESession::setIconText(const TQString& _iconText)
|
|
{
|
|
iconText = _iconText;
|
|
//kdDebug(1211)<<"Session setIconText " << iconText <<endl;
|
|
}
|
|
|
|
const TQString& TESession::IconName()
|
|
{
|
|
return iconName;
|
|
}
|
|
|
|
const TQString& TESession::IconText()
|
|
{
|
|
return iconText;
|
|
}
|
|
|
|
bool TESession::testAndSetStateIconName (const TQString& newname)
|
|
{
|
|
if (newname != stateIconName)
|
|
{
|
|
stateIconName = newname;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void TESession::setHistory(const HistoryType &hType)
|
|
{
|
|
em->setHistory(hType);
|
|
}
|
|
|
|
const HistoryType& TESession::history()
|
|
{
|
|
return em->history();
|
|
}
|
|
|
|
void TESession::clearHistory()
|
|
{
|
|
if (history().isOn()) {
|
|
int histSize = history().getSize();
|
|
setHistory(HistoryTypeNone());
|
|
if (histSize)
|
|
setHistory(HistoryTypeBuffer(histSize));
|
|
else
|
|
setHistory(HistoryTypeFile());
|
|
}
|
|
}
|
|
|
|
TQStrList TESession::getArgs()
|
|
{
|
|
return args;
|
|
}
|
|
|
|
TQString TESession::getPgm()
|
|
{
|
|
return pgm;
|
|
}
|
|
|
|
TQString TESession::getCwd()
|
|
{
|
|
#ifdef HAVE_PROC_CWD
|
|
if (cwd.isEmpty()) {
|
|
TQFileInfo Cwd(TQString("/proc/%1/cwd").arg(sh->pid()));
|
|
if(Cwd.isSymLink())
|
|
return Cwd.readLink();
|
|
}
|
|
#endif /* HAVE_PROC_CWD */
|
|
return cwd;
|
|
}
|
|
|
|
bool TESession::isMonitorActivity() { return monitorActivity; }
|
|
bool TESession::isMonitorSilence() { return monitorSilence; }
|
|
bool TESession::isMasterMode() { return masterMode; }
|
|
|
|
void TESession::setMonitorActivity(bool _monitor)
|
|
{
|
|
monitorActivity=_monitor;
|
|
notifiedActivity=false;
|
|
}
|
|
|
|
void TESession::setMonitorSilence(bool _monitor)
|
|
{
|
|
if (monitorSilence==_monitor)
|
|
return;
|
|
|
|
monitorSilence=_monitor;
|
|
if (monitorSilence)
|
|
monitorTimer->start(silence_seconds*1000,true);
|
|
else
|
|
monitorTimer->stop();
|
|
}
|
|
|
|
void TESession::setMonitorSilenceSeconds(int seconds)
|
|
{
|
|
silence_seconds=seconds;
|
|
if (monitorSilence) {
|
|
monitorTimer->start(silence_seconds*1000,true);
|
|
}
|
|
}
|
|
|
|
void TESession::setMasterMode(bool _master)
|
|
{
|
|
masterMode=_master;
|
|
}
|
|
|
|
void TESession::setAddToUtmp(bool set)
|
|
{
|
|
add_to_utmp = set;
|
|
}
|
|
|
|
void TESession::setXonXoff(bool set)
|
|
{
|
|
xon_xoff = set;
|
|
}
|
|
|
|
void TESession::slotZModemDetected()
|
|
{
|
|
if (!zmodemBusy)
|
|
{
|
|
TQTimer::singleShot(10, this, TQT_SLOT(emitZModemDetected()));
|
|
zmodemBusy = true;
|
|
}
|
|
}
|
|
|
|
void TESession::emitZModemDetected()
|
|
{
|
|
emit zmodemDetected(this);
|
|
}
|
|
|
|
void TESession::cancelZModem()
|
|
{
|
|
sh->send_bytes("\030\030\030\030", 4); // Abort
|
|
zmodemBusy = false;
|
|
}
|
|
|
|
void TESession::startZModem(const TQString &zmodem, const TQString &dir, const TQStringList &list)
|
|
{
|
|
zmodemBusy = true;
|
|
zmodemProc = new KProcIO;
|
|
|
|
(*zmodemProc) << zmodem << "-v";
|
|
for(TQStringList::ConstIterator it = list.begin();
|
|
it != list.end();
|
|
++it)
|
|
{
|
|
(*zmodemProc) << (*it);
|
|
}
|
|
|
|
if (!dir.isEmpty())
|
|
zmodemProc->setWorkingDirectory(dir);
|
|
zmodemProc->start(KProcIO::NotifyOnExit, false);
|
|
|
|
// Override the read-processing of KProcIO
|
|
disconnect(zmodemProc,TQT_SIGNAL (receivedStdout (TDEProcess *, char *, int)), 0, 0);
|
|
connect(zmodemProc,TQT_SIGNAL (receivedStdout (TDEProcess *, char *, int)),
|
|
this, TQT_SLOT(zmodemSendBlock(TDEProcess *, char *, int)));
|
|
connect(zmodemProc,TQT_SIGNAL (receivedStderr (TDEProcess *, char *, int)),
|
|
this, TQT_SLOT(zmodemStatus(TDEProcess *, char *, int)));
|
|
connect(zmodemProc,TQT_SIGNAL (processExited(TDEProcess *)),
|
|
this, TQT_SLOT(zmodemDone()));
|
|
|
|
disconnect( sh,TQT_SIGNAL(block_in(const char*,int)), this, TQT_SLOT(onRcvBlock(const char*,int)) );
|
|
connect( sh,TQT_SIGNAL(block_in(const char*,int)), this, TQT_SLOT(zmodemRcvBlock(const char*,int)) );
|
|
connect( sh,TQT_SIGNAL(buffer_empty()), this, TQT_SLOT(zmodemContinue()));
|
|
|
|
zmodemProgress = new ZModemDialog(te->topLevelWidget(), false,
|
|
i18n("ZModem Progress"));
|
|
|
|
connect(zmodemProgress, TQT_SIGNAL(user1Clicked()),
|
|
this, TQT_SLOT(zmodemDone()));
|
|
|
|
zmodemProgress->show();
|
|
}
|
|
|
|
void TESession::zmodemSendBlock(TDEProcess *, char *data, int len)
|
|
{
|
|
sh->send_bytes(data, len);
|
|
// tqWarning("<-- %d bytes", len);
|
|
if (sh->buffer_full())
|
|
{
|
|
zmodemProc->suspend();
|
|
// tqWarning("ZModem suspend");
|
|
}
|
|
}
|
|
|
|
void TESession::zmodemContinue()
|
|
{
|
|
zmodemProc->resume();
|
|
// tqWarning("ZModem resume");
|
|
}
|
|
|
|
void TESession::zmodemStatus(TDEProcess *, char *data, int len)
|
|
{
|
|
TQCString msg(data, len+1);
|
|
while(!msg.isEmpty())
|
|
{
|
|
int i = msg.find('\015');
|
|
int j = msg.find('\012');
|
|
TQCString txt;
|
|
if ((i != -1) && ((j == -1) || (i < j)))
|
|
{
|
|
msg = msg.mid(i+1);
|
|
}
|
|
else if (j != -1)
|
|
{
|
|
txt = msg.left(j);
|
|
msg = msg.mid(j+1);
|
|
}
|
|
else
|
|
{
|
|
txt = msg;
|
|
msg.truncate(0);
|
|
}
|
|
if (!txt.isEmpty())
|
|
zmodemProgress->addProgressText(TQString::fromLocal8Bit(txt));
|
|
}
|
|
}
|
|
|
|
void TESession::zmodemRcvBlock(const char *data, int len)
|
|
{
|
|
TQByteArray ba;
|
|
ba.duplicate(data, len);
|
|
zmodemProc->writeStdin(ba);
|
|
// tqWarning("--> %d bytes", len);
|
|
}
|
|
|
|
void TESession::zmodemDone()
|
|
{
|
|
if (zmodemProc)
|
|
{
|
|
delete zmodemProc;
|
|
zmodemProc = 0;
|
|
zmodemBusy = false;
|
|
|
|
disconnect( sh,TQT_SIGNAL(block_in(const char*,int)), this ,TQT_SLOT(zmodemRcvBlock(const char*,int)) );
|
|
disconnect( sh,TQT_SIGNAL(buffer_empty()), this, TQT_SLOT(zmodemContinue()));
|
|
connect( sh,TQT_SIGNAL(block_in(const char*,int)), this, TQT_SLOT(onRcvBlock(const char*,int)) );
|
|
|
|
sh->send_bytes("\030\030\030\030", 4); // Abort
|
|
sh->send_bytes("\001\013\n", 3); // Try to get prompt back
|
|
zmodemProgress->done();
|
|
}
|
|
}
|
|
|
|
|
|
bool TESession::processDynamic(const TQCString &fun, const TQByteArray &data, TQCString& replyType, TQByteArray &replyData)
|
|
{
|
|
if (fullScripting)
|
|
{
|
|
if (fun == "feedSession(TQString)")
|
|
{
|
|
TQString arg0;
|
|
TQDataStream arg( data, IO_ReadOnly );
|
|
arg >> arg0;
|
|
feedSession(arg0);
|
|
replyType = "void";
|
|
return true;
|
|
}
|
|
else if (fun == "sendSession(TQString)")
|
|
{
|
|
TQString arg0;
|
|
TQDataStream arg( data, IO_ReadOnly );
|
|
arg >> arg0;
|
|
sendSession(arg0);
|
|
replyType = "void";
|
|
return true;
|
|
}
|
|
}
|
|
return SessionIface::processDynamic(fun, data, replyType, replyData);
|
|
|
|
}
|
|
|
|
QCStringList TESession::functionsDynamic()
|
|
{
|
|
QCStringList funcs = SessionIface::functionsDynamic();
|
|
if (fullScripting)
|
|
{
|
|
funcs << "void feedSession(TQString text)";
|
|
funcs << "void sendSession(TQString text)";
|
|
}
|
|
return funcs;
|
|
}
|
|
|
|
|
|
void TESession::onRcvBlock( const char* buf, int len )
|
|
{
|
|
em->onRcvBlock( buf, len );
|
|
emit receivedData( TQString::fromLatin1( buf, len ) );
|
|
}
|
|
|
|
void TESession::print( TQPainter &paint, bool friendly, bool exact )
|
|
{
|
|
te->print(paint, friendly, exact);
|
|
}
|
|
|
|
TQString TESession::schema()
|
|
{
|
|
TQString currentSchema;
|
|
emit getSessionSchema(this, currentSchema);
|
|
return currentSchema;
|
|
}
|
|
|
|
void TESession::setSchema(const TQString &schema)
|
|
{
|
|
emit setSessionSchema(this, schema);
|
|
}
|
|
|
|
TQString TESession::font()
|
|
{
|
|
return te->getVTFont().toString();
|
|
}
|
|
|
|
void TESession::setFont(const TQString &font)
|
|
{
|
|
TQFont tmp;
|
|
if (tmp.fromString(font))
|
|
te->setVTFont(tmp);
|
|
else
|
|
kdWarning()<<"unknown font: "<<font<<endl;
|
|
}
|
|
|
|
TQString TESession::encoding()
|
|
{
|
|
return em->codec()->name();
|
|
}
|
|
|
|
void TESession::setEncoding(const TQString &encoding)
|
|
{
|
|
emit setSessionEncoding(this, encoding);
|
|
}
|
|
|
|
TQString TESession::keytab()
|
|
{
|
|
return keymap();
|
|
}
|
|
|
|
void TESession::setKeytab(const TQString &keytab)
|
|
{
|
|
setKeymap(keytab);
|
|
emit updateSessionKeytab(this, keytab);
|
|
emit updateSessionConfig(this);
|
|
}
|
|
|
|
TQSize TESession::size()
|
|
{
|
|
return em->imageSize();
|
|
}
|
|
|
|
void TESession::setSize(TQSize size)
|
|
{
|
|
if ((size.width() <= 1) || (size.height() <= 1))
|
|
return;
|
|
|
|
emit resizeSession(this, size);
|
|
}
|
|
|
|
#include "session.moc"
|