-rw-r--r-- | noncore/apps/opie-console/MyPty.cpp | 27 | ||||
-rw-r--r-- | noncore/apps/opie-console/MyPty.h | 6 | ||||
-rw-r--r-- | noncore/apps/opie-console/PLANS | 2 | ||||
-rw-r--r-- | noncore/apps/opie-console/consoleconfigwidget.cpp | 95 | ||||
-rw-r--r-- | noncore/apps/opie-console/consoleconfigwidget.h | 34 | ||||
-rw-r--r-- | noncore/apps/opie-console/default.cpp | 9 | ||||
-rw-r--r-- | noncore/apps/opie-console/opie-console.pro | 6 |
7 files changed, 162 insertions, 17 deletions
diff --git a/noncore/apps/opie-console/MyPty.cpp b/noncore/apps/opie-console/MyPty.cpp index 534f79a..b0f0275 100644 --- a/noncore/apps/opie-console/MyPty.cpp +++ b/noncore/apps/opie-console/MyPty.cpp @@ -97,247 +97,254 @@ actual size of the window. */ void MyPty::setSize(int lines, int columns) { qWarning("setting size"); struct winsize wsize; wsize.ws_row = (unsigned short)lines; wsize.ws_col = (unsigned short)columns; if(m_fd < 0) return; ioctl(m_fd,TIOCSWINSZ,(char *)&wsize); } void MyPty::donePty() { // This is code from the Qt DumbTerminal example ::close(m_fd); if (m_cpid) { kill(m_cpid, SIGHUP); //waitpid(m_cpid, &status, 0); delete m_sn_e; delete m_sn_r; m_sn_e = 0l; m_sn_r = 0l; } m_cpid = 0; m_fd = -1; // emit done(status); } const char* MyPty::deviceName() { return m_ttynam; } void MyPty::error() { // This is code from the Qt DumbTerminal example donePty(); } void MyPty::start() { - char* cmd = "/bin/sh"; - - if ( QFile::exists( "/bin/bash" ) ) { - cmd = "/bin/bash"; - } - QStrList lis; - int r =run(cmd, lis, 0, 0); + int r =run(m_cmd.latin1(), lis, 0, 0); r = r; } /*! start the client program. */ int MyPty::run(const char* cmd, QStrList &, const char*, int) { // This is code from the Qt DumbTerminal example m_cpid = fork(); if ( !m_cpid ) { // child - exec shell on tty for (int sig = 1; sig < NSIG; sig++) signal(sig,SIG_DFL); int ttyfd = ::open(m_ttynam, O_RDWR); dup2(ttyfd, STDIN_FILENO); dup2(ttyfd, STDOUT_FILENO); dup2(ttyfd, STDERR_FILENO); // should be done with tty, so close it ::close(ttyfd); static struct termios ttmode; if ( setsid() < 0 ) perror( "failed to set process group" ); #if defined (TIOCSCTTY) // grabbed from APUE by Stevens ioctl(STDIN_FILENO, TIOCSCTTY, 0); #endif tcgetattr( STDIN_FILENO, &ttmode ); ttmode.c_cc[VINTR] = 3; ttmode.c_cc[VERASE] = 8; tcsetattr( STDIN_FILENO, TCSANOW, &ttmode ); setenv("TERM",m_term,1); setenv("COLORTERM","0",1); - + EnvironmentMap::Iterator it; + for (it = m_env.begin(); it != m_env.end(); it++) { + setenv(it.key().latin1(), it.data().latin1(), 1); + } if (getuid() == 0) { char msg[] = "WARNING: You are running this shell as root!\n"; write(ttyfd, msg, sizeof(msg)); } execl(cmd, cmd, 0); donePty(); exit(-1); } // parent - continue as a widget delete m_sn_r; m_sn_r = new QSocketNotifier(m_fd,QSocketNotifier::Read,this); delete m_sn_e; m_sn_e = new QSocketNotifier(m_fd,QSocketNotifier::Exception,this); connect(m_sn_r,SIGNAL(activated(int)),this,SLOT(readPty())); connect(m_sn_e,SIGNAL(activated(int)),this,SLOT(error())); return 0; } int MyPty::openPty() { // This is code from the Qt DumbTerminal example int ptyfd = -1; #ifdef HAVE_OPENPTY int ttyfd; if ( openpty(&ptyfd,&ttyfd,ttynam,0,0) ) ptyfd = -1; else close(ttyfd); // we open the ttynam ourselves. #else for (const char* c0 = "pqrstuvwxyzabcde"; ptyfd < 0 && *c0 != 0; c0++) { for (const char* c1 = "0123456789abcdef"; ptyfd < 0 && *c1 != 0; c1++) { sprintf(m_ptynam,"/dev/pty%c%c",*c0,*c1); sprintf(m_ttynam,"/dev/tty%c%c",*c0,*c1); if ((ptyfd = ::open(m_ptynam,O_RDWR)) >= 0) { if (geteuid() != 0 && !access(m_ttynam,R_OK|W_OK) == 0) { ::close(ptyfd); ptyfd = -1; } } } } #endif if ( ptyfd < 0 ) { // qApp->exit(1); return -1; } return ptyfd; } /*! Create an instance. */ MyPty::MyPty(const Profile& prof) : m_cpid(0) { int term = prof.readNumEntry("Terminal", Profile::VT100 ); switch( term ) { default: case Profile::VT100: case Profile::VT102: m_term = "vt100"; break; case Profile::Linux: m_term = "linux"; break; case Profile::XTerm: m_term = "xterm"; break; } m_sn_e = 0l; m_sn_r = 0l; m_fd = openPty(); ProcCtl* ctl = ProcCtl::self(); Q_UNUSED(ctl); + reload(prof); } /*! Destructor. Note that the related client program is not killed (yet) when a instance is deleted. */ MyPty::~MyPty() { donePty(); } QString MyPty::identifier()const { return QString::fromLatin1("term"); } QString MyPty::name()const{ return identifier(); } bool MyPty::open() { if (m_fd < 0) m_fd = openPty(); start(); return true; } void MyPty::close() { donePty(); m_fd = openPty(); } -void MyPty::reload( const Profile& ) { - +void MyPty::reload( const Profile& prof) { + m_env.clear(); + m_cmd = prof.readEntry("Command", "/bin/bash"); + int envcount = prof.readNumEntry("EnvVars", 0); + for (int i=0; i<envcount; i++) { + QString name = prof.readEntry("Env_Name_" + QString::number(i), ""); + QString value = prof.readEntry("Env_Value_" + QString::number(i), ""); + if (!(name.isEmpty() || value.isEmpty())) { + m_env.insert(name, value); + } + } } /*! sends len bytes through the line */ void MyPty::send(const QByteArray& ar) { #ifdef VERBOSE_DEBUG // verbose debug printf("sending bytes:\n"); for (uint i = 0; i < ar.count(); i++) printf("%c", ar[i]); printf("\n"); #endif ::write(m_fd, ar.data(), ar.count()); } /*! indicates that a block of data is received */ void MyPty::readPty() { QByteArray buf(4096); int len = ::read( m_fd, buf.data(), 4096 ); if (len == -1 || len == 0) { donePty(); return; } if (len < 0) return; buf.resize(len); emit received(buf); #ifdef VERBOSE_DEBUG // verbose debug printf("read bytes:\n"); for (uint i = 0; i < buf.count(); i++) printf("%c", buf[i]); printf("\n"); #endif } QBitArray MyPty::supports()const { QBitArray ar(3); //autoconnect ar[0] = 1; // diff --git a/noncore/apps/opie-console/MyPty.h b/noncore/apps/opie-console/MyPty.h index 7561ca3..b292ce4 100644 --- a/noncore/apps/opie-console/MyPty.h +++ b/noncore/apps/opie-console/MyPty.h @@ -1,100 +1,106 @@ /* -------------------------------------------------------------------------- */ /* */ /* [MyPty.h] Pseudo Terminal Device */ /* */ /* -------------------------------------------------------------------------- */ /* */ /* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */ /* */ /* This file is part of Konsole - an X terminal for KDE */ /* */ /* -------------------------------------------------------------------------- */ /* */ /* Ported Konsole to Qt/Embedded */ /* */ /* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */ /* */ /* -------------------------------------------------------------------------- */ /*! \file */ #ifndef MY_PTY_H #define MY_PTY_H #include <qobject.h> +#include <qlist.h> #include <qstrlist.h> #include "io_layer.h" +typedef QMap<QString, QString> EnvironmentMap; + class Profile; class QSocketNotifier; class MyPty : public IOLayer { Q_OBJECT public: MyPty(const Profile&); ~MyPty(); QString identifier()const; QString name()const; QBitArray supports()const; public slots: /*! having a `run' separate from the constructor allows to make the necessary connections to the signals and slots of the instance before starting the execution of the client. */ void start(); int run(const char* pgm, QStrList & args , const char* term, int addutmp); bool open(); void close(); void reload( const Profile& ); void setSize(int lines, int columns); void error(); bool isConnected() { return true; }; signals: /*! emitted when the client program terminates. \param status the wait(2) status code of the terminated client program. */ void done(int status); /*! emitted when a new block of data comes in. \param s - the data \param len - the length of the block */ void received(const QByteArray&); public slots: void send(const QByteArray& ); private: const char* deviceName(); protected slots: void readPty(); void donePty(); private: int openPty(); private: char m_ptynam[16]; // "/dev/ptyxx" | "/dev/ptmx" char m_ttynam[16]; // "/dev/ttyxx" | "/dev/pts/########..." int m_fd; int m_cpid; QSocketNotifier* m_sn_e; QSocketNotifier* m_sn_r; char* m_term; + + QString m_cmd; + EnvironmentMap m_env; }; #endif diff --git a/noncore/apps/opie-console/PLANS b/noncore/apps/opie-console/PLANS index 8e0bee4..a7c7578 100644 --- a/noncore/apps/opie-console/PLANS +++ b/noncore/apps/opie-console/PLANS @@ -1,55 +1,55 @@ From a UNIX point of view we want to do something like minicom with a better GUI. It should feature some terminal emulation vt100/102, ansi, filetransfer via {x,y,z}modem, and some sort of session management. Besides this requirement we would like to be able to execute 'scripts' in a session. A script would just write to the TEmulation and then be sent via an IOlayer. We want a modular architecture which might support plugins in the future should we have a general opie-console setting dialog where you configure general things like where the tabs are, the profiles, and the default keyboard? (Almost) DONE: Framework Serial IOLayer Saving and Restoring Profiles ConfigDialog Framework IOLayer Profile->Session and MainWidget FilesendingLayer ( Z/Y Modem tested X does not work at all ) Fullscreen Modem - Josef Keys - hash + Scripting - wazlaf TASKS in progress: Keys - hash - Scripting - wazlaf Session->Profile - hash => why is this needed? you can not change any settings after you start the session, so all you would do is create a duplicate of the profile used to open the current session. maybe needed later when you can change settings while the session is running (colors, fonts...) zecke => think of that. You try to hook up with a New Device neither know anything.... speed flow and such stuff you start to experiment and it starts to work now you want to save the session hash => got it. OPEN tasks: Receiving ( copy &n paste from filetransfer.cpp ) POSTPONED UNTIL LATER: Irda ConfigWidget BT ConfigWidget IRDA-Layer Bluetooth-Layer diff --git a/noncore/apps/opie-console/consoleconfigwidget.cpp b/noncore/apps/opie-console/consoleconfigwidget.cpp new file mode 100644 index 0000000..70e2e78 --- a/dev/null +++ b/noncore/apps/opie-console/consoleconfigwidget.cpp @@ -0,0 +1,95 @@ +#include <qlabel.h> +#include <qlayout.h> +#include <qcombobox.h> +#include <qlineedit.h> +#include <qpushbutton.h> +#include <qlistview.h> +#include <qhbox.h> +#include <qregexp.h> +#include <stdio.h> + +#include "consoleconfigwidget.h" + +ConsoleConfigWidget::ConsoleConfigWidget( const QString& name, QWidget* parent, + const char* na ) + : ProfileDialogConnectionWidget( name, parent, na ) { + m_lay = new QVBoxLayout( this ); + QLabel *label = new QLabel(tr("Command to execute"), this); + m_lay->addWidget(label); + m_cmd = new QLineEdit(this); + m_lay->addWidget(m_cmd); + label = new QLabel(tr("Environment Variables"), this); + m_lay->addWidget(label); + m_env = new QListView(this); + m_env->addColumn(tr("Name")); + m_env->addColumn(tr("Value")); + m_lay->addWidget(m_env); + + QHBox *hbox = new QHBox(this); + label = new QLabel(tr("Name :"), hbox); + m_name = new QLineEdit(hbox); + m_lay->addWidget(hbox); + + hbox = new QHBox(this); + label = new QLabel(tr("Value :"), hbox); + m_value = new QLineEdit(hbox); + m_lay->addWidget(hbox); + + hbox = new QHBox(this); + hbox->setSpacing(10); + m_remove = new QPushButton(tr("Remove"), hbox); + connect(m_remove, SIGNAL(clicked()), this, SLOT(slotRemove())); + m_add = new QPushButton(tr("Add"), hbox); + connect(m_add, SIGNAL(clicked()), this, SLOT(slotAdd())); + m_lay->addWidget(hbox); +} + +void ConsoleConfigWidget::slotAdd() { + if (!(m_name->text().isEmpty() || m_value->text().isEmpty())) { + QListViewItem *item = new QListViewItem(m_env); + item->setText(0, m_name->text()); + item->setText(1, m_value->text()); + m_env->insertItem(item); + } +} + +void ConsoleConfigWidget::slotRemove() { + QListViewItem *item = m_env->currentItem(); + if (item) { + m_env->takeItem(item); + } +} + +ConsoleConfigWidget::~ConsoleConfigWidget() { +} + +void ConsoleConfigWidget::load( const Profile& prof ) { + m_cmd->setText(prof.readEntry("Command", "/bin/bash")); + int envcount = prof.readNumEntry("EnvVars", 0); + for (int i=0; i<envcount; i++) { + QString name = prof.readEntry("Env_Name_" + QString::number(i), ""); + QString value = prof.readEntry("Env_Value_" + QString::number(i), ""); + if (!(name.isEmpty() || value.isEmpty())) { + QListViewItem *item = new QListViewItem(m_env); + item->setText(0, name); + item->setText(1, value); + m_env->insertItem(item); + } + } +} + +void ConsoleConfigWidget::save( Profile& prof ) { + prof.writeEntry( "Command", m_cmd->text()); + QListViewItem *item = m_env->firstChild(); + int counter = 0; + while (item) { + QString name = item->text(0); + QString value = item->text(1); + prof.writeEntry("Env_Name_" + QString::number(counter), name); + prof.writeEntry("Env_Value_" + QString::number(counter), value); + item = item->nextSibling(); + counter++; + } + prof.writeEntry("EnvVars", QString::number(counter)); +} + diff --git a/noncore/apps/opie-console/consoleconfigwidget.h b/noncore/apps/opie-console/consoleconfigwidget.h new file mode 100644 index 0000000..c980cb4 --- a/dev/null +++ b/noncore/apps/opie-console/consoleconfigwidget.h @@ -0,0 +1,34 @@ +#ifndef OPIE_CONSOLE_CONFIG_WIDGET_H +#define OPIE_CONSOLE_CONFIG_WIDGET_H + +#include "profiledialogwidget.h" + +class QVBoxLayout; +class QLineEdit; +class QListView; +class QPushButton; + +class ConsoleConfigWidget : public ProfileDialogConnectionWidget { + Q_OBJECT +public: + ConsoleConfigWidget( const QString& name, QWidget* parent, const char* name = 0l ); + ~ConsoleConfigWidget(); + + void load( const Profile& ); + void save( Profile& ); + +protected slots: + void slotAdd(); + void slotRemove(); +private: + QVBoxLayout *m_lay; + QLineEdit *m_cmd; + QLineEdit *m_name; + QLineEdit *m_value; + QListView *m_env; + QPushButton *m_add; + QPushButton *m_remove; +}; + + +#endif diff --git a/noncore/apps/opie-console/default.cpp b/noncore/apps/opie-console/default.cpp index 5d82c6a..b060139 100644 --- a/noncore/apps/opie-console/default.cpp +++ b/noncore/apps/opie-console/default.cpp @@ -1,121 +1,122 @@ #include "io_serial.h" #include "io_irda.h" #include "io_bt.h" #include "io_modem.h" #include "filetransfer.h" #include "filereceive.h" #include "serialconfigwidget.h" #include "irdaconfigwidget.h" #include "btconfigwidget.h" #include "modemconfigwidget.h" #include "terminalwidget.h" #include "function_keyboard.h" +#include "consoleconfigwidget.h" #include "MyPty.h" #include "default.h" extern "C" { // FILE Transfer Stuff FileTransferLayer* newSZTransfer(IOLayer* lay) { return new FileTransfer( FileTransfer::SZ, lay ); } FileTransferLayer* newSYTransfer(IOLayer* lay) { return new FileTransfer( FileTransfer::SY, lay ); } FileTransferLayer* newSXTransfer(IOLayer* lay) { return new FileTransfer(FileTransfer ::SX, lay ); } // FILE Transfer Receive Stuff ReceiveLayer* newSZReceive(IOLayer* lay) { return new FileReceive( FileReceive::SZ, lay ); } ReceiveLayer* newSYReceive(IOLayer* lay) { return new FileReceive( FileReceive::SY, lay ); } ReceiveLayer* newSXReceive(IOLayer* lay) { return new FileReceive(FileReceive::SX, lay ); } // Layer stuff IOLayer* newSerialLayer( const Profile& prof) { return new IOSerial( prof ); } IOLayer* newBTLayer( const Profile& prof ) { return new IOBt( prof ); } IOLayer* newIrDaLayer( const Profile& prof ) { return new IOIrda( prof ); } IOLayer* newModemLayer( const Profile& prof ) { return new IOModem( prof ); } IOLayer* newConsole( const Profile& prof ) { return new MyPty( prof ); } // Connection Widgets ProfileDialogWidget* newSerialWidget( const QString& str, QWidget* wid ) { return new SerialConfigWidget( str, wid ); } ProfileDialogWidget* newIrDaWidget( const QString& str, QWidget* wid ) { return new IrdaConfigWidget( str, wid ); } ProfileDialogWidget* newModemWidget( const QString& str, QWidget* wid ) { return new ModemConfigWidget(str, wid ); } ProfileDialogWidget* newBTWidget( const QString& str, QWidget* wid ) { return new BTConfigWidget(str, wid ); } - ProfileDialogWidget* newConsoleWid( const QString& , QWidget* ) { - return 0l; + ProfileDialogWidget* newConsoleWid( const QString& str, QWidget* wid ) { + return new ConsoleConfigWidget(str, wid ); } // Terminal Widget(s) ProfileDialogWidget* newTerminalWidget(const QString& na, QWidget* wid) { return new TerminalWidget(na, wid,0 ); } // Function Keyboard Widget ProfileDialogWidget* newKeyboardWidget(const QString& na, QWidget *wid) { return new FunctionKeyboardConfig(na, wid); } /* // VT Emulations EmulationLayer* newVT102( WidgetLayer* wid ) { return new Vt102Emulation( wid ); } */ }; Default::Default( MetaFactory* fact ) { fact->addFileTransferLayer( "SZ", QObject::tr("Z-Modem"), newSZTransfer ); fact->addFileTransferLayer( "SY", QObject::tr("Y-Modem"), newSYTransfer ); fact->addFileTransferLayer( "SX", QObject::tr("X-Modem"), newSXTransfer ); fact->addReceiveLayer( "SZ", QObject::tr("Z-Modem"), newSZReceive ); fact->addReceiveLayer( "SY", QObject::tr("Y-Modem"), newSYReceive ); fact->addReceiveLayer( "SX", QObject::tr("X-Modem"), newSXReceive ); fact->addIOLayerFactory( "serial", QObject::tr("Serial"), newSerialLayer ); // fact->addIOLayerFactory( "irda", QObject::tr("Infrared"), newIrDaLayer ); // fact->addIOLayerFactory( "bt", QObject::tr("Bluetooth"), newBTLayer ); fact->addIOLayerFactory( "modem", QObject::tr("Modem"), newModemLayer ); - fact->addIOLayerFactory( "console", QObject::tr("local Console"), newConsole ); + fact->addIOLayerFactory( "console", QObject::tr("Local Console"), newConsole ); fact->addConnectionWidgetFactory( "serial", QObject::tr("Serial"), newSerialWidget ); // fact->addConnectionWidgetFactory( "irda", QObject::tr("Infrared"), newIrDaWidget ); fact->addConnectionWidgetFactory( "modem", QObject::tr("Modem"), newModemWidget ); // fact->addConnectionWidgetFactory( "bt", QObject::tr("Bluetooth"), newBTWidget ); - fact->addConnectionWidgetFactory( "console", QObject::tr("local Console"), newConsoleWid ); + fact->addConnectionWidgetFactory( "console", QObject::tr("Local Console"), newConsoleWid ); fact->addTerminalWidgetFactory( "default", QObject::tr("Default Terminal"), newTerminalWidget ); fact->addKeyboardWidgetFactory( "defaultKeys", QObject::tr("Default Keyboard"), newKeyboardWidget ); // fact->addEmulationLayer( "default", QObject::tr("Default Terminal"), newVT102 ); } Default::~Default() { } diff --git a/noncore/apps/opie-console/opie-console.pro b/noncore/apps/opie-console/opie-console.pro index f5737d4..e3f92f0 100644 --- a/noncore/apps/opie-console/opie-console.pro +++ b/noncore/apps/opie-console/opie-console.pro @@ -1,70 +1,72 @@ TEMPLATE = app #CONFIG = qt warn_on release CONFIG = qt debug DESTDIR = $(OPIEDIR)/bin HEADERS = io_layer.h io_serial.h io_irda.h io_bt.h io_modem.h \ file_layer.h filetransfer.h \ metafactory.h \ session.h \ mainwindow.h \ profile.h \ profileconfig.h \ profilemanager.h \ configwidget.h \ tabwidget.h \ configdialog.h \ keytrans.h \ transferdialog.h \ profiledialogwidget.h \ profileeditordialog.h \ default.h \ iolayerbase.h \ serialconfigwidget.h irdaconfigwidget.h \ btconfigwidget.h modemconfigwidget.h \ atconfigdialog.h dialdialog.h \ procctl.h \ function_keyboard.h \ receive_layer.h filereceive.h \ script.h \ dialer.h \ terminalwidget.h \ emulation_handler.h TECommon.h \ TEHistroy.h TEScreen.h TEWidget.h \ - TEmuVt102.h TEmulation.h MyPty.h + TEmuVt102.h TEmulation.h MyPty.h \ + consoleconfigwidget.h SOURCES = io_layer.cpp io_serial.cpp io_irda.cpp io_bt.cpp io_modem.cpp \ file_layer.cpp filetransfer.cpp \ main.cpp \ metafactory.cpp \ session.cpp \ mainwindow.cpp \ profile.cpp \ profileconfig.cpp \ profilemanager.cpp \ tabwidget.cpp \ configdialog.cpp \ keytrans.cpp \ transferdialog.cpp \ profiledialogwidget.cpp \ profileeditordialog.cpp \ iolayerbase.cpp \ serialconfigwidget.cpp irdaconfigwidget.cpp \ btconfigwidget.cpp modemconfigwidget.cpp \ atconfigdialog.cpp dialdialog.cpp \ default.cpp procctl.cpp \ function_keyboard.cpp \ receive_layer.cpp filereceive.cpp \ script.cpp \ dialer.cpp \ terminalwidget.cpp \ emulation_handler.cpp TEHistory.cpp \ TEScreen.cpp TEWidget.cpp \ - TEmuVt102.cpp TEmulation.cpp MyPty.cpp + TEmuVt102.cpp TEmulation.cpp MyPty.cpp \ + consoleconfigwidget.cpp INTERFACES = configurebase.ui editbase.ui INCLUDEPATH += $(OPIEDIR)/include DEPENDPATH += $(OPIEDIR)/include LIBS += -lqpe -lopie TARGET = opie-console |