-rw-r--r-- | core/apps/embeddedkonsole/konsole.cpp | 103 |
1 files changed, 88 insertions, 15 deletions
diff --git a/core/apps/embeddedkonsole/konsole.cpp b/core/apps/embeddedkonsole/konsole.cpp index fff2f68..a5adc03 100644 --- a/core/apps/embeddedkonsole/konsole.cpp +++ b/core/apps/embeddedkonsole/konsole.cpp @@ -1,422 +1,494 @@ /* ---------------------------------------------------------------------- */ /* */ /* [main.C] Konsole */ /* */ /* ---------------------------------------------------------------------- */ /* */ /* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */ /* */ /* This file is part of Konsole, an X terminal. */ /* */ /* The material contained in here more or less directly orginates from */ /* kvt, which is copyright (c) 1996 by Matthias Ettrich <ettrich@kde.org> */ /* */ /* ---------------------------------------------------------------------- */ /* */ /* Ported Konsole to Qt/Embedded */ /* */ /* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */ /* */ /* -------------------------------------------------------------------------- */ // enhancements added by L.J. Potter <ljp@llornkcor.com> -#define QT_QWS_OPIE +//#define QT_QWS_OPIE + +#include "signal.h" #include <qpe/resource.h> #include <qdir.h> #include <qevent.h> #include <qdragobject.h> #include <qobjectlist.h> #include <qtoolbutton.h> #include <qtoolbar.h> #include <qpushbutton.h> #include <qfontdialog.h> #include <qglobal.h> #include <qpainter.h> #include <qmenubar.h> #include <qmessagebox.h> #include <qaction.h> #include <qapplication.h> #include <qfontmetrics.h> #include <qcombobox.h> #include <qevent.h> #include <qtabwidget.h> #include <qtabbar.h> #include <qpe/config.h> #include <qstringlist.h> #include <qpalette.h> #include <unistd.h> #include <pwd.h> #include <sys/types.h> -#include <sys/wait.h> +//#include <sys/wait.h> #include <stdio.h> #include <stdlib.h> #include <assert.h> #include "konsole.h" #include "keytrans.h" #include "commandeditdialog.h" #ifdef QT_QWS_OPIE #include <opie/colorpopupmenu.h> #endif +#include <qfontdatabase.h> // U.B. +#include <qstringlist.h> // U.B. +#include <qvaluelist.h> // U.B. + class EKNumTabBar : public QTabBar { public: void numberTabs() { // Yes, it really is this messy. QTabWidget needs functions // that provide acces to tabs in a sequential way. int m=INT_MIN; for (int i=0; i<count(); i++) { QTab* left=0; QListIterator<QTab> it(*tabList()); int x=INT_MAX; for( QTab* t; (t=it.current()); ++it ) { int tx = t->rect().x(); if ( tx<x && tx>m ) { x = tx; left = t; } } if ( left ) { left->setText(QString::number(i+1)); m = left->rect().x(); } } } }; class EKNumTabWidget : public QTabWidget { public: EKNumTabWidget(QWidget* parent) : QTabWidget(parent) { } void addTab(QWidget* w) { QTab* t = new QTab(QString::number(tabBar()->count()+1)); QTabWidget::addTab(w,t); } void removeTab(QWidget* w) { removePage(w); ((EKNumTabBar*)tabBar())->numberTabs(); } }; // This could be configurable or dynamicly generated from the bash history // file of the user static const char *commonCmds[] = { "ls ", // I left this here, cause it looks better than the first alpha "cardctl eject", "cat ", "cd ", "chmod ", "clear", "cp ", "dc ", "df ", "dmesg", "echo ", "env", "find ", "free", "grep ", "ifconfig ", "ipkg ", "mkdir ", "mv ", "nc localhost 7776", "nc localhost 7777", "netstat ", "nslookup ", "ping ", "ps aux", "pwd ", "qcop QPE/System 'linkChanged(QString)' ''", "qcop QPE/System 'restart()'", "qcop QPE/System 'quit()'", "rm ", "rmdir ", "route ", "set ", "traceroute", /* "gzip", "gunzip", "chgrp", "chown", "date", "dd", "df", "dmesg", "fuser", "hostname", "kill", "killall", "ln", "ping", "mount", "more", "sort", "touch", "umount", "mknod", "netstat", */ "exit", NULL }; static void konsoleInit(const char** shell) { if(setuid(getuid()) !=0) qDebug("setuid failed"); if(setgid(getgid()) != 0) qDebug("setgid failed"); // drop privileges - +// signal (SIGSTOP, SIG_IGN); + // QPEApplication::grabKeyboard(); // for CTRL and ALT - qDebug("keyboard grabbed"); +// qDebug("keyboard grabbed"); #ifdef FAKE_CTRL_AND_ALT qDebug("Fake Ctrl and Alt defined"); QPEApplication::grabKeyboard(); // for CTRL and ALT #endif *shell = getenv("SHELL"); - qWarning("SHell initially is %s", *shell ); +// qWarning("SHell initially is %s", *shell ); if (shell == NULL || *shell == '\0') { struct passwd *ent = 0; uid_t me = getuid(); *shell = "/bin/sh"; while ( (ent = getpwent()) != 0 ) { if (ent->pw_uid == me) { if (ent->pw_shell != "") *shell = ent->pw_shell; break; } } endpwent(); } - qWarning("SHELL now is %s", *shell ); +// qWarning("SHELL now is %s", *shell ); if( putenv((char*)"COLORTERM=") !=0) qDebug("putenv failed"); // to trigger mc's color detection } Konsole::Konsole(QWidget* parent, const char* name, WFlags fl) : QMainWindow(parent, name, fl) { QStrList tmp; const char* shell; setCaption( tr("Terminal") ); konsoleInit( &shell); - qWarning("Using shell %s", shell); +// qWarning("Using shell %s", shell); init(shell,tmp); } void Konsole::initCommandList() { // qDebug("Konsole::initCommandList"); Config cfg("Konsole"); cfg.setGroup("Commands"); commonCombo->setInsertionPolicy(QComboBox::AtCurrent); commonCombo->clear(); if (cfg.readEntry("Commands Set","FALSE") == "FALSE") { for (int i = 0; commonCmds[i] != NULL; i++) { commonCombo->insertItem(commonCmds[i],i); } } else { for (int i = 0; i < 100; i++) { if (!(cfg.readEntry( QString::number(i),"")).isEmpty()) commonCombo->insertItem((cfg.readEntry( QString::number(i),""))); } } } void Konsole::init(const char* _pgm, QStrList & _args) { b_scroll = TRUE; // histon; n_keytab = 0; n_render = 0; startUp=0; fromMenu = FALSE; setCaption( tr("Terminal") ); setIcon( Resource::loadPixmap( "konsole" ) ); Config cfg("Konsole"); cfg.setGroup("Konsole"); QString tmp; // initialize the list of allowed fonts /////////////////////////////////// cfont = cfg.readNumEntry("FontID", 1); + QFont f = QFont("Micro", 4, QFont::Normal); f.setFixedPitch(TRUE); fonts.append(new VTFont(tr("Micro"), f)); f = QFont("Fixed", 7, QFont::Normal); f.setFixedPitch(TRUE); fonts.append(new VTFont(tr("Small Fixed"), f)); f = QFont("Fixed", 12, QFont::Normal); f.setFixedPitch(TRUE); fonts.append(new VTFont(tr("Medium Fixed"), f)); - // create terminal emulation framework //////////////////////////////////// +// NEW STUFF + + QStringList ignfont = cfg.readListEntry("IgnFont", ','); + /* If there is no "IgnFont = ..." entry in "myonsole.conf", + * put some Japanese fonts of the SL-C7x0 to "ignfont". */ + + if (ignfont.isEmpty()) { + ignfont = QStringList::split (',',"jisupasp,mmkjg1,mmkjg4,mmkjg5"); + } + +// QFont + f = QFont("Fixed", 16, QFont::Normal); + f.setFixedPitch(true); + fonts.append(new VTFont(tr("Default"), f)); + + int fcount = 1; + + f.setCharSet(QFont::AnyCharSet); + f.setStyleHint(QFont::TypeWriter, QFont::PreferMatch); +// f.setWeight(QFont::Normal); + + /* + * Look for installed font families. If the family is not in + * the "ignfont" list, look for available sizes. + * If it is fixed pitch font, put the font and the size + * to the fontlist. + */ + QFontDatabase fdb; + QStringList ff = fdb.families(false); + + for (QStringList::Iterator it = ff.begin(); it != ff.end(); ++it ) { + QString fit = *it; + + if( fit != "fixed" && fit != "micro" ) { + if ( ignfont.contains(*it) == 0) { + QValueList<int> pt = fdb.pointSizes(*it); + + for (QValueList<int>::Iterator itv = pt.begin(); + itv != pt.end(); ++itv ) { + int size = (*itv)/10; + if(size > 0) { + f.setFamily(*it); + f.setPointSize(size); + } + + QFontMetrics fm(f); + +//qDebug("%s %d:\twidth('i')=%d, width('w')=%d", (*it).latin1(), (*itv)/10, fm.width('i'), fm.width('w')); + + if (fm.width('i') == fm.width('w') ) { + qDebug((*it)); + f.setFixedPitch(true); + fonts.append(new VTFont(*it + ' ' + QString::number(size), f)); + fcount++; + } + } + } + } + } + +// END NEW STUFF + + +// create terminal emulation framework //////////////////////////////////// nsessions = 0; tab = new EKNumTabWidget(this); connect(tab, SIGNAL(currentChanged(QWidget*)), this, SLOT(switchSession(QWidget*))); // create terminal toolbar //////////////////////////////////////////////// setToolBarsMovable( FALSE ); QToolBar *menuToolBar = new QToolBar( this ); menuToolBar->setHorizontalStretchable( TRUE ); QMenuBar *menuBar = new QMenuBar( menuToolBar ); fontList = new QPopupMenu( this ); for(uint i = 0; i < fonts.count(); i++) { VTFont *fnt = fonts.at(i); fontList->insertItem(fnt->getName(), i); } + fontChanged(cfont); configMenu = new QPopupMenu( this); colorMenu = new QPopupMenu( this); scrollMenu = new QPopupMenu( this); editCommandListMenu = new QPopupMenu( this); configMenu->insertItem(tr("Command List"), editCommandListMenu); bool listHidden; cfg.setGroup("Menubar"); if( cfg.readEntry("Hidden","FALSE") == "TRUE") { editCommandListMenu->insertItem( tr( "Show command list" )); listHidden=TRUE; } else { editCommandListMenu->insertItem( tr( "Hide command list" )); listHidden=FALSE; } cfg.setGroup("Tabs"); tmp=cfg.readEntry("Position","Bottom"); if(tmp=="Top") { tab->setTabPosition(QTabWidget::Top); configMenu->insertItem( tr( "Tabs on Bottom" ) ); } else { tab->setTabPosition(QTabWidget::Bottom); configMenu->insertItem(tr("Tabs on Top")); } configMenu->insertSeparator(2); colorMenu->insertItem(tr( "Green on Black")); colorMenu->insertItem(tr( "Black on White")); colorMenu->insertItem(tr( "White on Black")); colorMenu->insertItem(tr( "Black on Transparent")); colorMenu->insertItem(tr( "Black on Red")); colorMenu->insertItem(tr( "Red on Black")); colorMenu->insertItem(tr( "Green on Yellow")); colorMenu->insertItem(tr( "Blue on Magenta")); colorMenu->insertItem(tr( "Magenta on Blue")); colorMenu->insertItem(tr( "Cyan on White")); colorMenu->insertItem(tr( "White on Cyan")); colorMenu->insertItem(tr( "Blue on Black")); colorMenu->insertItem(tr( "Amber on Black")); #ifdef QT_QWS_OPIE colorMenu->insertItem(tr( "Custom")); #endif configMenu->insertItem( tr("Font"), fontList ); configMenu->insertItem(tr( "Colors") ,colorMenu); connect( fontList, SIGNAL( activated(int) ), this, SLOT( fontChanged(int) )); connect( configMenu, SIGNAL( activated(int) ), this, SLOT( configMenuSelected(int) )); connect( colorMenu, SIGNAL( activated(int) ), this, SLOT( colorMenuIsSelected(int) )); connect( scrollMenu, SIGNAL(activated(int)),this,SLOT(scrollMenuSelected(int))); connect(editCommandListMenu,SIGNAL(activated(int)),this,SLOT(editCommandListMenuSelected(int))); menuBar->insertItem( tr("Options"), configMenu ); QToolBar *toolbar = new QToolBar( this ); QAction *a; // Button Commands a = new QAction( tr("New"), Resource::loadPixmap( "konsole" ), QString::null, 0, this, 0 ); connect( a, SIGNAL( activated() ), this, SLOT( newSession() ) ); a->addTo( toolbar ); a = new QAction( tr("Enter"), Resource::loadPixmap( "konsole/enter" ), QString::null, 0, this, 0 ); connect( a, SIGNAL( activated() ), this, SLOT( hitEnter() ) ); a->addTo( toolbar ); a = new QAction( tr("Space"), Resource::loadPixmap( "konsole/space" ), QString::null, 0, this, 0 ); connect( a, SIGNAL( activated() ), this, SLOT( hitSpace() ) ); a->addTo( toolbar ); a = new QAction( tr("Tab"), Resource::loadPixmap( "konsole/tab" ), QString::null, 0, this, 0 ); connect( a, SIGNAL( activated() ), this, SLOT( hitTab() ) ); a->addTo( toolbar ); a = new QAction( tr("Up"), Resource::loadPixmap( "konsole/up" ), QString::null, 0, this, 0 ); connect( a, SIGNAL( activated() ), this, SLOT( hitUp() ) ); a->addTo( toolbar ); a = new QAction( tr("Down"), Resource::loadPixmap( "konsole/down" ), QString::null, 0, this, 0 ); connect( a, SIGNAL( activated() ), this, SLOT( hitDown() ) ); a->addTo( toolbar ); a = new QAction( tr("Paste"), Resource::loadPixmap( "paste" ), QString::null, 0, this, 0 ); connect( a, SIGNAL( activated() ), this, SLOT( hitPaste() ) ); a->addTo( toolbar ); /* a = new QAction( tr("Up"), Resource::loadPixmap( "up" ), QString::null, 0, this, 0 ); connect( a, SIGNAL( activated() ), this, SLOT( hitUp() ) ); a->addTo( toolbar ); a = new QAction( tr("Down"), Resource::loadPixmap( "down" ), QString::null, 0, this, 0 ); connect( a, SIGNAL( activated() ), this, SLOT( hitDown() ) ); a->addTo( toolbar ); */ secondToolBar = new QToolBar( this ); secondToolBar->setHorizontalStretchable( TRUE ); commonCombo = new QComboBox( secondToolBar ); commonCombo->setMaximumWidth(236); editCommandListMenu->insertItem( tr( "Quick Edit" ) ); if( listHidden) { secondToolBar->hide(); editCommandListMenu->setItemEnabled(-23 ,FALSE); } editCommandListMenu->insertItem(tr( "Edit" ) ); cfg.setGroup("Commands"); commonCombo->setInsertionPolicy(QComboBox::AtCurrent); initCommandList(); // for (int i = 0; commonCmds[i] != NULL; i++) { // commonCombo->insertItem( commonCmds[i], i ); // tmp = cfg.readEntry( QString::number(i),""); // if(tmp != "") // commonCombo->changeItem( tmp,i ); // } connect( commonCombo, SIGNAL( activated(int) ), this, SLOT( enterCommand(int) )); scrollMenu->insertItem(tr( "None" )); scrollMenu->insertItem(tr( "Left" )); scrollMenu->insertItem(tr( "Right" )); // scrollMenu->insertSeparator(4); // scrollMenu->insertItem(tr( "Horizontal" )); configMenu->insertItem(tr( "ScrollBar" ),scrollMenu); int jut = configMenu->insertItem(tr( "Wrap" )); cfg.setGroup("ScrollBar"); configMenu->setItemChecked(jut, cfg.readBoolEntry("HorzScroll",0)); jut = configMenu->insertItem(tr( "Use Beep" )); cfg.setGroup("Menubar"); configMenu->setItemChecked(jut, cfg.readBoolEntry("useBeep",0)); @@ -500,263 +572,264 @@ void Konsole::enterCommand(int c) TEWidget* te = getTe(); if (te != 0) { if(!commonCombo->editable()) { QString text = commonCombo->text(c); //commonCmds[c]; te->emitText(text); } else { changeCommand( commonCombo->text(c), c); } } } void Konsole::hitEnter() { TEWidget* te = getTe(); if (te != 0) { te->emitText(QString("\r")); } } void Konsole::hitSpace() { TEWidget* te = getTe(); if (te != 0) { te->emitText(QString(" ")); } } void Konsole::hitTab() { TEWidget* te = getTe(); if (te != 0) { te->emitText(QString("\t")); } } void Konsole::hitPaste() { TEWidget* te = getTe(); if (te != 0) { te->pasteClipboard(); } } void Konsole::hitUp() { TEWidget* te = getTe(); if (te != 0) { QKeyEvent ke( QKeyEvent::KeyPress, Qt::Key_Up, 0, 0); QApplication::sendEvent( te, &ke ); } } void Konsole::hitDown() { TEWidget* te = getTe(); if (te != 0) { QKeyEvent ke( QKeyEvent::KeyPress, Qt::Key_Down, 0, 0); QApplication::sendEvent( te, &ke ); } } /** This function calculates the size of the external widget needed for the internal widget to be */ QSize Konsole::calcSize(int columns, int lines) { TEWidget* te = getTe(); if (te != 0) { QSize size = te->calcSize(columns, lines); return size; } else { QSize size; return size; } } /** sets application window to a size based on columns X lines of the te guest widget. Call with (0,0) for setting default size. */ void Konsole::setColLin(int columns, int lines) { qDebug("konsole::setColLin:: Columns %d", columns); if ((columns==0) || (lines==0)) { if (defaultSize.isEmpty()) // not in config file : set default value { defaultSize = calcSize(80,24); // notifySize(24,80); // set menu items (strange arg order !) } resize(defaultSize); } else { resize(calcSize(columns, lines)); // notifySize(lines,columns); // set menu items (strange arg order !) } } /* void Konsole::setFont(int fontno) { QFont f; if (fontno == 0) f = defaultFont = QFont( "Helvetica", 12 ); else if (fonts[fontno][0] == '-') f.setRawName( fonts[fontno] ); else { f.setFamily(fonts[fontno]); f.setRawMode( TRUE ); } if ( !f.exactMatch() && fontno != 0) { QString msg = i18n("Font `%1' not found.\nCheck README.linux.console for help.").arg(fonts[fontno]); QMessageBox(this, msg); return; } if (se) se->setFontNo(fontno); te->setVTFont(f); n_font = fontno; } */ // --| color selection |------------------------------------------------------- void Konsole::changeColumns(int columns) -{ //FIXME this seems to cause silliness when reset command is executed -// qDebug("change columns"); -// TEWidget* te = getTe(); -// if (te != 0) { -// setColLin(columns,te->Lines()); -// te->update(); -// } +{ + //FIXME this seems to cause silliness when reset command is executed +// qDebug("change columns"); +// TEWidget* te = getTe(); +// if (te != 0) { +// setColLin(columns,te->Lines()); +// te->update(); +// } } //FIXME: If a child dies during session swap, // this routine might be called before // session swap is completed. void Konsole::doneSession(TESession*, int ) { TEWidget *te = getTe(); if (te != 0) { te->currentSession->setConnect(FALSE); tab->removeTab(te); delete te->currentSession; delete te; nsessions--; } if (nsessions == 0) { close(); } } void Konsole::newSession() { if(nsessions < 15) { // seems to be something weird about 16 tabs on the Zaurus.... memory? TEWidget* te = new TEWidget(tab); Config c("Konsole"); c.setGroup("Menubar"); te->useBeep=c.readBoolEntry("useBeep",0); // te->setBackgroundMode(PaletteBase); //we want transparent!! te->setVTFont(fonts.at(cfont)->getFont()); tab->addTab(te); TESession* se = new TESession(this, te, se_pgm, se_args, "xterm"); te->currentSession = se; connect( se, SIGNAL(done(TESession*,int)), this, SLOT(doneSession(TESession*,int)) ); se->run(); se->setConnect(TRUE); se->setHistory(b_scroll); tab->setCurrentPage(nsessions); nsessions++; doWrap(); setColor(); } } TEWidget* Konsole::getTe() { if (nsessions) { return (TEWidget *) tab->currentPage(); } else { return 0; } } void Konsole::switchSession(QWidget* w) { TEWidget* te = (TEWidget *) w; QFont teFnt = te->getVTFont(); for(uint i = 0; i < fonts.count(); i++) { VTFont *fnt = fonts.at(i); bool cf = fnt->getFont() == teFnt; fontList->setItemChecked(i, cf); if (cf) { cfont = i; } } } void Konsole::colorMenuIsSelected(int iD) { fromMenu = TRUE; colorMenuSelected(iD); } /// ------------------------------- some new stuff by L.J. Potter void Konsole::colorMenuSelected(int iD) { // this is NOT pretty, elegant or anything else besides functional // QString temp; // qDebug( temp.sprintf("colormenu %d", iD)); TEWidget* te = getTe(); Config cfg("Konsole"); cfg.setGroup("Colors"); // QColor foreground; // QColor background; colorMenu->setItemChecked(lastSelectedMenu,FALSE); ColorEntry m_table[TABLE_COLORS]; const ColorEntry * defaultCt=te->getdefaultColorTable(); /////////// fore back int i; if(iD==-9) { // default default for (i = 0; i < TABLE_COLORS; i++) { m_table[i].color = defaultCt[i].color; if(i==1 || i == 11) m_table[i].transparent=1; cfg.writeEntry("Schema","9"); colorMenu->setItemChecked(-9,TRUE); } } else { if(iD==-6) { // green black foreground.setRgb(0x18,255,0x18); background.setRgb(0x00,0x00,0x00); cfg.writeEntry("Schema","6"); colorMenu->setItemChecked(-6,TRUE); } if(iD==-7) { // black white foreground.setRgb(0x00,0x00,0x00); background.setRgb(0xFF,0xFF,0xFF); cfg.writeEntry("Schema","7"); colorMenu->setItemChecked(-7,TRUE); } if(iD==-8) { // white black foreground.setRgb(0xFF,0xFF,0xFF); background.setRgb(0x00,0x00,0x00); cfg.writeEntry("Schema","8"); colorMenu->setItemChecked(-8,TRUE); } if(iD==-10) {// Black, Red foreground.setRgb(0x00,0x00,0x00); background.setRgb(0xB2,0x18,0x18); cfg.writeEntry("Schema","10"); colorMenu->setItemChecked(-10,TRUE); } if(iD==-11) {// Red, Black foreground.setRgb(230,31,31); //0xB2,0x18,0x18 background.setRgb(0x00,0x00,0x00); cfg.writeEntry("Schema","11"); colorMenu->setItemChecked(-11,TRUE); } if(iD==-12) {// Green, Yellow - is ugly |