-rw-r--r-- | noncore/apps/opie-console/MyPty.cpp | 1 | ||||
-rw-r--r-- | noncore/apps/opie-console/TEmulation.cpp | 1 | ||||
-rw-r--r-- | noncore/apps/opie-console/io_layer.h | 2 | ||||
-rw-r--r-- | noncore/apps/opie-console/mainwindow.cpp | 5 | ||||
-rw-r--r-- | noncore/apps/opie-console/session.cpp | 2 |
5 files changed, 9 insertions, 2 deletions
diff --git a/noncore/apps/opie-console/MyPty.cpp b/noncore/apps/opie-console/MyPty.cpp index a2373bf..6b0d6f2 100644 --- a/noncore/apps/opie-console/MyPty.cpp +++ b/noncore/apps/opie-console/MyPty.cpp @@ -1,326 +1,327 @@ /* -------------------------------------------------------------------------- */ /* */ /* [MyPty.C] 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> */ /* */ /* -------------------------------------------------------------------------- */ /* If you're compiling konsole on non-Linux platforms and find problems that you can track down to this file, please have a look into ../README.ports, too. */ /*! \file */ /*! \class TEPty \brief Ptys provide a pseudo terminal connection to a program. Although closely related to pipes, these pseudo terminal connections have some ability, that makes it nessesary to uses them. Most importent, they know about changing screen sizes and UNIX job control. Within the terminal emulation framework, this class represents the host side of the terminal together with the connecting serial line. One can create many instances of this class within a program. As a side effect of using this class, a signal(2) handler is installed on SIGCHLD. \par FIXME [NOTE: much of the technical stuff below will be replaced by forkpty.] publish the SIGCHLD signal if not related to an instance. clearify TEPty::done vs. TEPty::~TEPty semantics. check if pty is restartable via run after done. \par Pseudo terminals Pseudo terminals are a unique feature of UNIX, and always come in form of pairs of devices (/dev/ptyXX and /dev/ttyXX), which are connected to each other by the operating system. One may think of them as two serial devices linked by a null-modem cable. Being based on devices the number of simultanous instances of this class is (globally) limited by the number of those device pairs, which is 256. Another technic are UNIX 98 PTY's. These are supported also, and prefered over the (obsolete) predecessor. There's a sinister ioctl(2), signal(2) and job control stuff nessesary to make everything work as it should. */ #include <qapplication.h> #include <qsocketnotifier.h> #include <qstring.h> #include <stdlib.h> #include <stdio.h> #include <signal.h> #include <fcntl.h> #include <unistd.h> #include <termios.h> #include <sys/types.h> #include <sys/ioctl.h> #include <sys/wait.h> #ifdef HAVE_OPENPTY #include <pty.h> #endif #include "procctl.h" #include "MyPty.h" #undef VERBOSE_DEBUG /* -------------------------------------------------------------------------- */ /*! Informs the client program about the 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 int status = 0; ::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"; QStrList lis; int r =run(cmd, 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","vt100",1); setenv("COLORTERM","0",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&) : m_cpid(0) { m_sn_e = 0l; m_sn_r = 0l; m_fd = openPty(); ProcCtl* ctl = ProcCtl::self(); } /*! 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& ) { } /*! 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; // ar[1] = 0; ar[2] = 0; return ar; } diff --git a/noncore/apps/opie-console/TEmulation.cpp b/noncore/apps/opie-console/TEmulation.cpp index 6f3ad32..7a0c624 100644 --- a/noncore/apps/opie-console/TEmulation.cpp +++ b/noncore/apps/opie-console/TEmulation.cpp @@ -1,363 +1,364 @@ /* -------------------------------------------------------------------------- */ /* */ /* [TEmulation.cpp] Terminal Emulation Decoder */ /* */ /* -------------------------------------------------------------------------- */ /* */ /* 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> */ /* */ /* -------------------------------------------------------------------------- */ /*! \class TEmulation \brief Mediator between TEWidget and TEScreen. This class is responsible to scan the escapes sequences of the terminal emulation and to map it to their corresponding semantic complements. Thus this module knows mainly about decoding escapes sequences and is a stateless device w.r.t. the semantics. It is also responsible to refresh the TEWidget by certain rules. \sa TEWidget \sa TEScreen \par A note on refreshing Although the modifications to the current screen image could immediately be propagated via `TEWidget' to the graphical surface, we have chosen another way here. The reason for doing so is twofold. First, experiments show that directly displaying the operation results in slowing down the overall performance of emulations. Displaying individual characters using X11 creates a lot of overhead. Second, by using the following refreshing method, the screen operations can be completely separated from the displaying. This greatly simplifies the programmer's task of coding and maintaining the screen operations, since one need not worry about differential modifications on the display affecting the operation of concern. We use a refreshing algorithm here that has been adoped from rxvt/kvt. By this, refreshing is driven by a timer, which is (re)started whenever a new bunch of data to be interpreted by the emulation arives at `onRcvBlock'. As soon as no more data arrive for `BULK_TIMEOUT' milliseconds, we trigger refresh. This rule suits both bulk display operation as done by curses as well as individual characters typed. (BULK_TIMEOUT < 1000 / max characters received from keyboard per second). Additionally, we trigger refreshing by newlines comming in to make visual snapshots of lists as produced by `cat', `ls' and likely programs, thereby producing the illusion of a permanent and immediate display operation. As a sort of catch-all needed for cases where none of the above conditions catch, the screen refresh is also triggered by a count of incoming bulks (`bulk_incnt'). */ /* FIXME - evtl. the bulk operations could be made more transparent. */ #include "TEmulation.h" #include "TEWidget.h" #include "TEScreen.h" #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <qkeycode.h> /* ------------------------------------------------------------------------- */ /* */ /* TEmulation */ /* */ /* ------------------------------------------------------------------------- */ #define CNTL(c) ((c)-'@') /*! */ TEmulation::TEmulation(TEWidget* gui) : decoder((QTextDecoder*)NULL) { this->gui = gui; screen[0] = new TEScreen(gui->Lines(),gui->Columns()); screen[1] = new TEScreen(gui->Lines(),gui->Columns()); scr = screen[0]; bulk_nlcnt = 0; // reset bulk newline counter bulk_incnt = 0; // reset bulk counter connected = FALSE; QObject::connect(&bulk_timer, SIGNAL(timeout()), this, SLOT(showBulk()) ); QObject::connect(gui,SIGNAL(changedImageSizeSignal(int,int)), this,SLOT(onImageSizeChange(int,int))); QObject::connect(gui,SIGNAL(changedHistoryCursor(int)), this,SLOT(onHistoryCursorChange(int))); QObject::connect(gui,SIGNAL(keyPressedSignal(QKeyEvent*)), this,SLOT(onKeyPress(QKeyEvent*))); QObject::connect(gui,SIGNAL(beginSelectionSignal(const int,const int)), this,SLOT(onSelectionBegin(const int,const int)) ); QObject::connect(gui,SIGNAL(extendSelectionSignal(const int,const int)), this,SLOT(onSelectionExtend(const int,const int)) ); QObject::connect(gui,SIGNAL(endSelectionSignal(const BOOL)), this,SLOT(setSelection(const BOOL)) ); QObject::connect(gui,SIGNAL(clearSelectionSignal()), this,SLOT(clearSelection()) ); } /*! */ TEmulation::~TEmulation() { delete screen[0]; delete screen[1]; bulk_timer.stop(); } /*! change between primary and alternate screen */ void TEmulation::setScreen(int n) { scr = screen[n&1]; } void TEmulation::setHistory(bool on) { screen[0]->setScroll(on); if (!connected) return; showBulk(); } bool TEmulation::history() { return screen[0]->hasScroll(); } void TEmulation::setCodec(int c) { //FIXME: check whether we have to free codec codec = c ? QTextCodec::codecForName("utf8") : QTextCodec::codecForLocale(); if (decoder) delete decoder; decoder = codec->makeDecoder(); } void TEmulation::setKeytrans(int no) { keytrans = KeyTrans::find(no); } void TEmulation::setKeytrans(const char * no) { keytrans = KeyTrans::find(no); } // Interpreting Codes --------------------------------------------------------- /* This section deals with decoding the incoming character stream. Decoding means here, that the stream is first seperated into `tokens' which are then mapped to a `meaning' provided as operations by the `Screen' class. */ /*! */ void TEmulation::onRcvChar(int c) // process application unicode input to terminal // this is a trivial scanner { c &= 0xff; switch (c) { case '\b' : scr->BackSpace(); break; case '\t' : scr->Tabulate(); break; case '\n' : scr->NewLine(); break; case '\r' : scr->Return(); break; case 0x07 : gui->Bell(); break; default : scr->ShowCharacter(c); break; }; } /* ------------------------------------------------------------------------- */ /* */ /* Keyboard Handling */ /* */ /* ------------------------------------------------------------------------- */ /*! */ void TEmulation::onKeyPress( QKeyEvent* ev ) { + qWarning("onKeyPress,...."); if (!connected) return; // someone else gets the keys if (scr->getHistCursor() != scr->getHistLines()); scr->setHistCursor(scr->getHistLines()); if (!ev->text().isEmpty()) { // A block of text // Note that the text is proper unicode. // We should do a conversion here, but since this // routine will never be used, we simply emit plain ascii. emit sndBlock(ev->text().ascii(),ev->text().length()); } else if (ev->ascii()>0) { unsigned char c[1]; c[0] = ev->ascii(); emit sndBlock((char*)c,1); } } // Unblocking, Byte to Unicode translation --------------------------------- -- /* We are doing code conversion from locale to unicode first. */ void TEmulation::onRcvBlock(const char *s, int len) { bulkStart(); bulk_incnt += 1; for (int i = 0; i < len; i++) { QString result = decoder->toUnicode(&s[i],1); int reslen = result.length(); for (int j = 0; j < reslen; j++) onRcvChar(result[j].unicode()); if (s[i] == '\n') bulkNewline(); } bulkEnd(); } // Selection --------------------------------------------------------------- -- void TEmulation::onSelectionBegin(const int x, const int y) { if (!connected) return; scr->setSelBeginXY(x,y); showBulk(); } void TEmulation::onSelectionExtend(const int x, const int y) { if (!connected) return; scr->setSelExtentXY(x,y); showBulk(); } void TEmulation::setSelection(const BOOL preserve_line_breaks) { if (!connected) return; QString t = scr->getSelText(preserve_line_breaks); if (!t.isNull()) gui->setSelection(t); } void TEmulation::clearSelection() { if (!connected) return; scr->clearSelection(); showBulk(); } // Refreshing -------------------------------------------------------------- -- #define BULK_TIMEOUT 20 /*! called when \n comes in. Evtl. triggers showBulk at endBulk */ void TEmulation::bulkNewline() { bulk_nlcnt += 1; bulk_incnt = 0; // reset bulk counter since `nl' rule applies } /*! */ void TEmulation::showBulk() { bulk_nlcnt = 0; // reset bulk newline counter bulk_incnt = 0; // reset bulk counter if (connected) { ca* image = scr->getCookedImage(); // get the image gui->setImage(image, scr->getLines(), scr->getColumns()); // actual refresh free(image); //FIXME: check that we do not trigger other draw event here. gui->setScroll(scr->getHistCursor(),scr->getHistLines()); } } void TEmulation::bulkStart() { if (bulk_timer.isActive()) bulk_timer.stop(); } void TEmulation::bulkEnd() { if ( bulk_nlcnt > gui->Lines() || bulk_incnt > 20 ) showBulk(); // resets bulk_??cnt to 0, too. else bulk_timer.start(BULK_TIMEOUT,TRUE); } void TEmulation::setConnect(bool c) { connected = c; if ( connected) { onImageSizeChange(gui->Lines(), gui->Columns()); showBulk(); } else { scr->clearSelection(); } } // --------------------------------------------------------------------------- /*! triggered by image size change of the TEWidget `gui'. This event is simply propagated to the attached screens and to the related serial line. */ void TEmulation::onImageSizeChange(int lines, int columns) { if (!connected) return; screen[0]->resizeImage(lines,columns); screen[1]->resizeImage(lines,columns); showBulk(); emit ImageSizeChanged(lines,columns); // propagate event to serial line } void TEmulation::onHistoryCursorChange(int cursor) { if (!connected) return; scr->setHistCursor(cursor); showBulk(); } void TEmulation::setColumns(int columns) { //FIXME: this goes strange ways. // Can we put this straight or explain it at least? emit changeColumns(columns); } diff --git a/noncore/apps/opie-console/io_layer.h b/noncore/apps/opie-console/io_layer.h index d5f7eab..97a1e1c 100644 --- a/noncore/apps/opie-console/io_layer.h +++ b/noncore/apps/opie-console/io_layer.h @@ -1,126 +1,126 @@ #ifndef OPIE_IO_LAYER_H #define OPIE_IO_LAYER_H #include <qbitarray.h> #include <qobject.h> #include <qpe/config.h> #include "profile.h" /** * This is the base class for IO Layers * It will used to sent and recv data( QByteArray ) * it */ class IOLayer : public QObject { Q_OBJECT public: enum Error { NoError = -1, Refuse = 0, CouldNotOpen =1, ClosedUnexpected =2, ClosedError =3, Terminate = 4 /* add more errors here */ }; enum Feature { AutoConnect = 0, TransferFile =1, Close =2 }; /** * a small c'tor */ IOLayer(); /** * create an IOLayer instance from a config file * the currently set group stores the profile/session * information */ IOLayer( const Profile& ); /** * destructor */ virtual ~IOLayer(); /** * a small internal identifier */ virtual QString identifier() const = 0; /** * a short name */ virtual QString name() const = 0; /** * a file descriptor which opens * the device for io but does not * do any ioctling on it... * and it'll stop listening to the before opened * device */ virtual int rawIO()const; /** * will close the rawIO stuff * and will listen to it's data again... */ virtual void closeRawIO(int); /** * What does the IOLayer support? * Bits are related to features */ virtual QBitArray supports()const = 0; virtual bool isConnected() = 0; signals: /** * received input as QCString */ virtual void received( const QByteArray& ); /** * an error occured * int for the error number * and QString for a text */ virtual void error( int, const QString& ); virtual void closed(); public slots: /** * send a QCString to the device */ virtual void send( const QByteArray& ) = 0; /** * bool open */ virtual bool open() = 0; /** * close the io */ virtual void close() = 0; /** * closes and reloads the settings */ virtual void reload( const Profile& ) = 0; /** * set the size * needed for pty */ - virtual void setSize(int rows, int cols ); + virtual void setSize(int lines, int cols ); }; #endif diff --git a/noncore/apps/opie-console/mainwindow.cpp b/noncore/apps/opie-console/mainwindow.cpp index 0c89620..a7541f0 100644 --- a/noncore/apps/opie-console/mainwindow.cpp +++ b/noncore/apps/opie-console/mainwindow.cpp @@ -1,512 +1,515 @@ #include <assert.h> #include <qaction.h> #include <qmenubar.h> #include <qlabel.h> #include <qpopupmenu.h> #include <qtoolbar.h> #include <qmessagebox.h> #include <qpushbutton.h> #include <qwhatsthis.h> #include <qpe/resource.h> #include <opie/ofiledialog.h> #include "keytrans.h" #include "profileeditordialog.h" #include "configdialog.h" #include "default.h" #include "metafactory.h" #include "profile.h" #include "profilemanager.h" #include "mainwindow.h" #include "tabwidget.h" #include "transferdialog.h" #include "function_keyboard.h" #include "emulation_handler.h" #include "script.h" #include "quick_button.h" MainWindow::MainWindow(QWidget *parent, const char *name, WFlags) : QMainWindow(parent, name, WStyle_ContextHelp) { KeyTrans::loadAll(); for (int i = 0; i < KeyTrans::count(); i++ ) { KeyTrans* s = KeyTrans::find(i ); assert( s ); } m_factory = new MetaFactory(); Default def(m_factory); m_sessions.setAutoDelete( TRUE ); m_curSession = 0; m_manager = new ProfileManager( m_factory ); m_manager->load(); initUI(); populateProfiles(); } void MainWindow::initUI() { setToolBarsMovable( FALSE ); /* tool bar for the menu */ m_tool = new QToolBar( this ); m_tool->setHorizontalStretchable( TRUE ); m_bar = new QMenuBar( m_tool ); m_console = new QPopupMenu( this ); m_scripts = new QPopupMenu( this ); m_sessionsPop= new QPopupMenu( this ); //m_settings = new QPopupMenu( this ); /* add a toolbar for icons */ m_icons = new QToolBar(this); /* * the settings action */ m_setProfiles = new QAction(tr("Configure Profiles"), Resource::loadPixmap( "SettingsIcon" ), QString::null, 0, this, 0); // m_setProfiles->addTo( m_settings ); m_setProfiles->addTo( m_icons ); m_setProfiles->addTo( m_console ); connect( m_setProfiles, SIGNAL(activated() ), this, SLOT(slotConfigure() ) ); - + m_console->insertSeparator(); /* * new Action for new sessions */ QAction* a = new QAction(tr("New Connection"), Resource::loadPixmap( "new" ), QString::null, 0, this, 0); a->addTo( m_console ); a->addTo( m_icons ); connect(a, SIGNAL(activated() ), this, SLOT(slotNew() ) ); /* * connect action */ m_connect = new QAction(); m_connect->setText( tr("Connect") ); m_connect->addTo( m_console ); connect(m_connect, SIGNAL(activated() ), this, SLOT(slotConnect() ) ); /* * disconnect action */ m_disconnect = new QAction(); m_disconnect->setText( tr("Disconnect") ); m_disconnect->addTo( m_console ); connect(m_disconnect, SIGNAL(activated() ), this, SLOT(slotDisconnect() ) ); + m_console->insertSeparator(); + m_transfer = new QAction(); m_transfer->setText( tr("Transfer file...") ); m_transfer->addTo( m_console ); connect(m_transfer, SIGNAL(activated() ), this, SLOT(slotTransfer() ) ); /* * fullscreen */ m_isFullscreen = false; m_fullscreen = new QAction( tr("Full screen"), Resource::loadPixmap( "fullscreen" ) , QString::null, 0, this, 0); m_fullscreen->addTo( m_console ); m_fullscreen->addTo( m_icons ); connect( m_fullscreen, SIGNAL( activated() ), this, SLOT( slotFullscreen() ) ); + m_console->insertSeparator(); /* * terminate action */ m_terminate = new QAction(); m_terminate->setText( tr("Terminate") ); m_terminate->addTo( m_console ); connect(m_terminate, SIGNAL(activated() ), this, SLOT(slotTerminate() ) ); m_closewindow = new QAction(); m_closewindow->setText( tr("Close Window") ); m_closewindow->addTo( m_console ); connect( m_closewindow, SIGNAL(activated() ), this, SLOT(slotClose() ) ); /* * script actions */ m_recordScript = new QAction(tr("Record Script"), QString::null, 0, this, 0); m_recordScript->addTo(m_scripts); connect(m_recordScript, SIGNAL(activated()), this, SLOT(slotRecordScript())); m_saveScript = new QAction(tr("Save Script"), QString::null, 0, this, 0); m_saveScript->addTo(m_scripts); connect(m_saveScript, SIGNAL(activated()), this, SLOT(slotSaveScript())); m_runScript = new QAction(tr("Run Script"), QString::null, 0, this, 0); m_runScript->addTo(m_scripts); connect(m_runScript, SIGNAL(activated()), this, SLOT(slotRunScript())); /* * action that open/closes the keyboard */ m_openKeys = new QAction (tr("Open Keyboard..."), Resource::loadPixmap( "console/keyboard_icon.png" ), QString::null, 0, this, 0); m_openKeys->setToggleAction(true); connect (m_openKeys, SIGNAL(toggled(bool)), this, SLOT(slotOpenKeb(bool))); m_openKeys->addTo(m_icons); /* * action that open/closes the keyboard */ m_openButtons = new QAction ( tr( "Open Buttons..." ), Resource::loadPixmap( "down" ), QString::null, 0, this, 0 ); m_openButtons->setToggleAction( true ); connect ( m_openButtons, SIGNAL( toggled( bool ) ), this, SLOT( slotOpenButtons( bool ) ) ); m_openButtons->addTo( m_icons ); /* insert the submenu */ m_console->insertItem(tr("New from Profile"), m_sessionsPop, -1, 0); /* insert the connection menu */ m_bar->insertItem( tr("Connection"), m_console ); /* the scripts menu */ m_bar->insertItem( tr("Scripts"), m_scripts ); /* the settings menu */ // m_bar->insertItem( tr("Settings"), m_settings ); /* and the keyboard */ m_keyBar = new QToolBar(this); addToolBar( m_keyBar, "Keyboard", QMainWindow::Top, TRUE ); m_keyBar->setHorizontalStretchable( TRUE ); m_keyBar->hide(); m_kb = new FunctionKeyboard(m_keyBar); connect(m_kb, SIGNAL(keyPressed(ushort, ushort, bool, bool, bool)), this, SLOT(slotKeyReceived(ushort, ushort, bool, bool, bool))); m_buttonBar = new QToolBar( this ); addToolBar( m_buttonBar, "Buttons", QMainWindow::Top, TRUE ); m_buttonBar->setHorizontalStretchable( TRUE ); m_buttonBar->hide(); m_qb = new QuickButton( m_buttonBar ); connect( m_qb, SIGNAL( keyPressed( ushort, ushort, bool, bool, bool) ), this, SLOT( slotKeyReceived( ushort, ushort, bool, bool, bool) ) ); m_connect->setEnabled( false ); m_disconnect->setEnabled( false ); m_terminate->setEnabled( false ); m_transfer->setEnabled( false ); m_recordScript->setEnabled( false ); m_saveScript->setEnabled( false ); m_runScript->setEnabled( false ); m_fullscreen->setEnabled( false ); m_closewindow->setEnabled( false ); /* * connect to the menu activation */ connect( m_sessionsPop, SIGNAL(activated( int ) ), this, SLOT(slotProfile( int ) ) ); m_consoleWindow = new TabWidget( this, "blah"); connect(m_consoleWindow, SIGNAL(activated(Session*) ), this, SLOT(slotSessionChanged(Session*) ) ); setCentralWidget( m_consoleWindow ); } ProfileManager* MainWindow::manager() { return m_manager; } TabWidget* MainWindow::tabWidget() { return m_consoleWindow; } void MainWindow::populateProfiles() { m_sessionsPop->clear(); Profile::ValueList list = manager()->all(); for (Profile::ValueList::Iterator it = list.begin(); it != list.end(); ++it ) { m_sessionsPop->insertItem( (*it).name() ); } } MainWindow::~MainWindow() { delete m_factory; manager()->save(); } MetaFactory* MainWindow::factory() { return m_factory; } Session* MainWindow::currentSession() { return m_curSession; } QList<Session> MainWindow::sessions() { return m_sessions; } void MainWindow::slotNew() { ProfileEditorDialog dlg(factory() ); dlg.showMaximized(); int ret = dlg.exec(); if ( ret == QDialog::Accepted ) { create( dlg.profile() ); } } void MainWindow::slotRecordScript() { /* if (currentSession()) { currentSession()->emulationLayer()->startRecording(); } */ } void MainWindow::slotSaveScript() { /* if (currentSession() && currentSession()->emulationLayer()->isRecording()) { MimeTypes types; QStringList script; script << "text/plain"; types.insert("Script", script); QString filename = OFileDialog::getSaveFileName(2, "/", QString::null, types); if (!filename.isEmpty()) { currentSession()->emulationLayer()->script()->saveTo(filename); currentSession()->emulationLayer()->clearScript(); } } */ } void MainWindow::slotRunScript() { /* if (currentSession()) { MimeTypes types; QStringList script; script << "text/plain"; types.insert("Script", script); QString filename = OFileDialog::getOpenFileName(2, "/", QString::null, types); if (!filename.isEmpty()) { Script script(DocLnk(filename).file()); currentSession()->emulationLayer()->runScript(&script); } } */ } void MainWindow::slotConnect() { if ( currentSession() ) { bool ret = currentSession()->layer()->open(); if(!ret) QMessageBox::warning(currentSession()->widgetStack(), QObject::tr("Failed"), QObject::tr("Connecting failed for this session.")); else { m_connect->setEnabled( false ); m_disconnect->setEnabled( true ); } } } void MainWindow::slotDisconnect() { if ( currentSession() ) { currentSession()->layer()->close(); m_connect->setEnabled( true ); m_disconnect->setEnabled( false ); } } void MainWindow::slotTerminate() { if ( currentSession() ) currentSession()->layer()->close(); slotClose(); /* FIXME move to the next session */ } void MainWindow::slotConfigure() { ConfigDialog conf( manager()->all(), factory() ); conf.showMaximized(); int ret = conf.exec(); if ( QDialog::Accepted == ret ) { manager()->setProfiles( conf.list() ); manager()->save(); populateProfiles(); } } /* * we will remove * this window from the tabwidget * remove it from the list * delete it * and set the currentSession() */ void MainWindow::slotClose() { if (!currentSession() ) return; Session* ses = currentSession(); qWarning("removing! currentSession %s", currentSession()->name().latin1() ); /* set to NULL to be safe, if its needed slotSessionChanged resets it automatically */ m_curSession = NULL; tabWidget()->remove( /*currentSession()*/ses ); /*it's autodelete */ m_sessions.remove( ses ); qWarning("after remove!!"); if (!currentSession() ) { m_connect->setEnabled( false ); m_disconnect->setEnabled( false ); m_terminate->setEnabled( false ); m_transfer->setEnabled( false ); m_recordScript->setEnabled( false ); m_saveScript->setEnabled( false ); m_runScript->setEnabled( false ); m_fullscreen->setEnabled( false ); m_closewindow->setEnabled( false ); } } /* * We will get the name * Then the profile * and then we will make a profile */ void MainWindow::slotProfile( int id) { Profile prof = manager()->profile( m_sessionsPop->text( id) ); create( prof ); } void MainWindow::create( const Profile& prof ) { Session *ses = manager()->fromProfile( prof, tabWidget() ); if((!ses) || (!ses->layer()) || (!ses->widgetStack())) { QMessageBox::warning(this, QObject::tr("Session failed"), QObject::tr("<qt>Cannot open session: Not all components were found.</qt>")); //if(ses) delete ses; return; } m_sessions.append( ses ); tabWidget()->add( ses ); m_curSession = ses; // dicide if its a local term ( then no connction and no tranfer), maybe make a wrapper method out of it m_connect->setEnabled( true ); m_disconnect->setEnabled( false ); m_terminate->setEnabled( true ); m_transfer->setEnabled( true ); m_recordScript->setEnabled( true ); m_saveScript->setEnabled( true ); m_runScript->setEnabled( true ); m_fullscreen->setEnabled( true ); m_closewindow->setEnabled( true ); // is io_layer wants direct connection, then autoconnect //if ( ( m_curSession->layer() )->supports()[0] == 1 ) { if (prof.autoConnect()) { slotConnect(); } } void MainWindow::slotTransfer() { if ( currentSession() ) { TransferDialog dlg(currentSession()->widgetStack(), this); dlg.showMaximized(); //currentSession()->widgetStack()->add(dlg); dlg.exec(); } } void MainWindow::slotOpenKeb(bool state) { if (state) m_keyBar->show(); else m_keyBar->hide(); } void MainWindow::slotOpenButtons( bool state ) { if ( state ) { m_buttonBar->show(); } else { m_buttonBar->hide(); } } void MainWindow::slotSessionChanged( Session* ses ) { qWarning("changed!"); if ( ses ) { m_curSession = ses; qDebug(QString("is connected : %1").arg( m_curSession->layer()->isConnected() ) ); if ( m_curSession->layer()->isConnected() ) { m_connect->setEnabled( false ); m_disconnect->setEnabled( true ); } else { m_connect->setEnabled( true ); m_disconnect->setEnabled( false ); } } } void MainWindow::slotFullscreen() { if ( m_isFullscreen ) { ( m_curSession->widgetStack() )->reparent( savedParentFullscreen, 0, QPoint(0,0), false ); ( m_curSession->widgetStack() )->setFrameStyle( QFrame::Panel | QFrame::Sunken ); setCentralWidget( m_consoleWindow ); ( m_curSession->widgetStack() )->show(); ( m_curSession->emulationHandler() )->cornerButton()->hide(); disconnect( ( m_curSession->emulationHandler() )->cornerButton(), SIGNAL( pressed() ), this, SLOT( slotFullscreen() ) ); } else { savedParentFullscreen = ( m_curSession->widgetStack() )->parentWidget(); ( m_curSession->widgetStack() )->setFrameStyle( QFrame::NoFrame ); ( m_curSession->widgetStack() )->reparent( 0, WStyle_Tool | WStyle_Customize | WStyle_StaysOnTop , QPoint(0,0), false ); ( m_curSession->widgetStack() )->resize( qApp->desktop()->width(), qApp->desktop()->height() ); ( m_curSession->widgetStack() )->setFocus(); ( m_curSession->widgetStack() )->show(); ( ( m_curSession->emulationHandler() )->cornerButton() )->show(); connect( ( m_curSession->emulationHandler() )->cornerButton(), SIGNAL( pressed() ), this, SLOT( slotFullscreen() ) ); } diff --git a/noncore/apps/opie-console/session.cpp b/noncore/apps/opie-console/session.cpp index 2ce6872..03d0fcd 100644 --- a/noncore/apps/opie-console/session.cpp +++ b/noncore/apps/opie-console/session.cpp @@ -1,98 +1,100 @@ #include "io_layer.h" #include "file_layer.h" #include "emulation_handler.h" #include "session.h" Session::Session() { m_widget = 0l; m_layer = 0l; m_emu = 0l; } Session::Session( const QString& na, QWidgetStack* widget, IOLayer* lay) : m_name( na ), m_widget( widget ), m_layer( lay ) { // m_widLay = 0l; // m_emLay = 0l; m_emu = 0l; } Session::~Session() { delete m_layer; delete m_emu; delete m_widget; /* the widget layer should be deleted by the m_widget */ } QString Session::name()const { return m_name; } QWidgetStack* Session::widgetStack() { return m_widget; } IOLayer* Session::layer() { return m_layer; } EmulationHandler* Session::emulationHandler() { return m_emu; } QWidget* Session::widget() { if (!m_emu ) return 0l; return m_emu->widget(); } /* WidgetLayer* Session::emulationWidget() { return m_widLay; } */ void Session::connect() { if ( !m_layer || !m_emu ) return; QObject::connect(m_layer, SIGNAL(received(const QByteArray&) ), m_emu, SLOT(recv(const QByteArray&) ) ); QObject::connect(m_emu, SIGNAL(send(const QByteArray&) ), m_layer, SLOT(send(const QByteArray&) ) ); + QObject::connect(m_emu, SIGNAL(changeSize(int, int) ), + m_layer, SLOT(setSize(int, int) ) ); } void Session::disconnect() { if ( !m_layer || !m_emu ) return; QObject::disconnect(m_layer, SIGNAL(received(const QByteArray&) ), m_emu, SLOT(recv(const QByteArray&) ) ); QObject::disconnect(m_emu, SIGNAL(send(const QByteArray&) ), m_layer, SLOT(send(const QByteArray&) ) ); } void Session::setName( const QString& na){ m_name = na; } void Session::setWidgetStack( QWidgetStack* wid ) { delete m_emu; m_emu = 0l; delete m_widget; /* the EmulationLayer was destroyed... */ m_widget = wid; } void Session::setIOLayer( IOLayer* lay ) { delete m_layer; m_layer = lay; } void Session::setEmulationHandler( EmulationHandler* lay ) { delete m_emu; m_emu = lay; } /* void Session::setEmulationWidget( WidgetLayer* lay ) { delete m_widLay; m_widLay = lay; } */ |