summaryrefslogtreecommitdiff
path: root/core/apps/embeddedkonsole
Side-by-side diff
Diffstat (limited to 'core/apps/embeddedkonsole') (more/less context) (ignore whitespace changes)
-rw-r--r--core/apps/embeddedkonsole/.cvsignore2
-rw-r--r--core/apps/embeddedkonsole/Makefile.in285
-rw-r--r--core/apps/embeddedkonsole/MyPty.cpp279
-rw-r--r--core/apps/embeddedkonsole/MyPty.h88
-rw-r--r--core/apps/embeddedkonsole/TECommon.h114
-rw-r--r--core/apps/embeddedkonsole/TEHistory.cpp212
-rw-r--r--core/apps/embeddedkonsole/TEHistory.h75
-rw-r--r--core/apps/embeddedkonsole/TEScreen.cpp1197
-rw-r--r--core/apps/embeddedkonsole/TEScreen.h259
-rw-r--r--core/apps/embeddedkonsole/TEWidget.cpp1243
-rw-r--r--core/apps/embeddedkonsole/TEWidget.h202
-rw-r--r--core/apps/embeddedkonsole/TEmuVt102.cpp991
-rw-r--r--core/apps/embeddedkonsole/TEmuVt102.h135
-rw-r--r--core/apps/embeddedkonsole/TEmulation.cpp363
-rw-r--r--core/apps/embeddedkonsole/TEmulation.h117
-rw-r--r--core/apps/embeddedkonsole/default.keytab.h103
-rwxr-xr-xcore/apps/embeddedkonsole/embeddedkonsole.pro38
-rw-r--r--core/apps/embeddedkonsole/faded_bg.pngbin0 -> 1300 bytes
-rw-r--r--core/apps/embeddedkonsole/keytrans.cpp706
-rw-r--r--core/apps/embeddedkonsole/keytrans.h93
-rw-r--r--core/apps/embeddedkonsole/konsole.cpp512
-rw-r--r--core/apps/embeddedkonsole/konsole.h125
-rw-r--r--core/apps/embeddedkonsole/main.cpp60
-rw-r--r--core/apps/embeddedkonsole/qpe-embeddedkonsole.control9
-rw-r--r--core/apps/embeddedkonsole/session.cpp157
-rw-r--r--core/apps/embeddedkonsole/session.h93
26 files changed, 7458 insertions, 0 deletions
diff --git a/core/apps/embeddedkonsole/.cvsignore b/core/apps/embeddedkonsole/.cvsignore
new file mode 100644
index 0000000..6fe2396
--- a/dev/null
+++ b/core/apps/embeddedkonsole/.cvsignore
@@ -0,0 +1,2 @@
+moc_*
+Makefile
diff --git a/core/apps/embeddedkonsole/Makefile.in b/core/apps/embeddedkonsole/Makefile.in
new file mode 100644
index 0000000..b858cd4
--- a/dev/null
+++ b/core/apps/embeddedkonsole/Makefile.in
@@ -0,0 +1,285 @@
+#############################################################################
+
+####### Compiler, tools and options
+
+CXX = $(SYSCONF_CXX) $(QT_CXX_MT)
+CXXFLAGS= $(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS)
+CC = $(SYSCONF_CC) $(QT_C_MT)
+CFLAGS = $(SYSCONF_CFLAGS)
+INCPATH = -I$(QPEDIR)/include
+LFLAGS = $(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT)
+LIBS = $(SUBLIBS) -lqpe $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS) $(SYSCONF_LIBS_QTAPP)
+MOC = $(SYSCONF_MOC)
+UIC = $(SYSCONF_UIC)
+
+####### Target
+
+DESTDIR = $(QPEDIR)/bin/
+VER_MAJ = 1
+VER_MIN = 0
+VER_PATCH = 0
+TARGET = embeddedkonsole
+TARGET1 = lib$(TARGET).so.$(VER_MAJ)
+
+####### Files
+
+HEADERS = TEWidget.h \
+ TEScreen.h \
+ TECommon.h \
+ TEHistory.h \
+ TEmulation.h \
+ TEmuVt102.h \
+ session.h \
+ keytrans.h \
+ konsole.h \
+ MyPty.h
+SOURCES = TEScreen.cpp \
+ TEWidget.cpp \
+ TEHistory.cpp \
+ TEmulation.cpp \
+ TEmuVt102.cpp \
+ session.cpp \
+ keytrans.cpp \
+ konsole.cpp \
+ main.cpp \
+ MyPty.cpp
+OBJECTS = TEScreen.o \
+ TEWidget.o \
+ TEHistory.o \
+ TEmulation.o \
+ TEmuVt102.o \
+ session.o \
+ keytrans.o \
+ konsole.o \
+ main.o \
+ MyPty.o
+INTERFACES =
+UICDECLS =
+UICIMPLS =
+SRCMOC = moc_TEWidget.cpp \
+ moc_TEmulation.cpp \
+ moc_TEmuVt102.cpp \
+ moc_session.cpp \
+ moc_konsole.cpp \
+ moc_MyPty.cpp
+OBJMOC = moc_TEWidget.o \
+ moc_TEmulation.o \
+ moc_TEmuVt102.o \
+ moc_session.o \
+ moc_konsole.o \
+ moc_MyPty.o
+
+
+####### Implicit rules
+
+.SUFFIXES: .cpp .cxx .cc .C .c
+
+.cpp.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cxx.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.cc.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.C.o:
+ $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
+
+.c.o:
+ $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
+
+####### Build rules
+
+
+all: $(DESTDIR)$(TARGET)
+
+$(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
+ $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)
+
+moc: $(SRCMOC)
+
+tmake:
+ tmake embeddedkonsole.pro
+
+clean:
+ -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
+ -rm -f *~ core
+ -rm -f allmoc.cpp
+
+####### Extension Modules
+
+listpromodules:
+ @echo
+
+listallmodules:
+ @echo
+
+listaddonpromodules:
+ @echo
+
+listaddonentmodules:
+ @echo
+
+
+REQUIRES=embeddedkonsole
+
+####### Sub-libraries
+
+
+###### Combined headers
+
+
+
+####### Compile
+
+TEScreen.o: TEScreen.cpp \
+ TEScreen.h \
+ TECommon.h \
+ TEHistory.h
+
+TEWidget.o: TEWidget.cpp \
+ TEWidget.h \
+ TECommon.h \
+ session.h \
+ MyPty.h \
+ TEmuVt102.h \
+ TEScreen.h \
+ TEHistory.h \
+ TEmulation.h \
+ keytrans.h
+
+TEHistory.o: TEHistory.cpp \
+ TEHistory.h \
+ TECommon.h
+
+TEmulation.o: TEmulation.cpp \
+ TEmulation.h \
+ TEWidget.h \
+ TECommon.h \
+ TEScreen.h \
+ TEHistory.h \
+ keytrans.h
+
+TEmuVt102.o: TEmuVt102.cpp \
+ TEmuVt102.h \
+ TEWidget.h \
+ TECommon.h \
+ TEScreen.h \
+ TEHistory.h \
+ TEmulation.h \
+ keytrans.h
+
+session.o: session.cpp \
+ session.h \
+ MyPty.h \
+ TEWidget.h \
+ TECommon.h \
+ TEmuVt102.h \
+ TEScreen.h \
+ TEHistory.h \
+ TEmulation.h \
+ keytrans.h
+
+keytrans.o: keytrans.cpp \
+ keytrans.h \
+ $(QPEDIR)/include/qpe/qpeapplication.h \
+ default.keytab.h
+
+konsole.o: konsole.cpp \
+ $(QPEDIR)/include/qpe/resource.h \
+ $(QPEDIR)/include/qpe/qpetoolbar.h \
+ $(QPEDIR)/include/qpe/qpemenubar.h \
+ konsole.h \
+ MyPty.h \
+ TEWidget.h \
+ TECommon.h \
+ TEmuVt102.h \
+ TEScreen.h \
+ TEHistory.h \
+ TEmulation.h \
+ keytrans.h \
+ session.h
+
+main.o: main.cpp \
+ konsole.h \
+ MyPty.h \
+ TEWidget.h \
+ TECommon.h \
+ TEmuVt102.h \
+ TEScreen.h \
+ TEHistory.h \
+ TEmulation.h \
+ keytrans.h \
+ session.h \
+ $(QPEDIR)/include/qpe/qpeapplication.h
+
+MyPty.o: MyPty.cpp \
+ MyPty.h
+
+moc_TEWidget.o: moc_TEWidget.cpp \
+ TEWidget.h \
+ TECommon.h
+
+moc_TEmulation.o: moc_TEmulation.cpp \
+ TEmulation.h \
+ TEWidget.h \
+ TECommon.h \
+ TEScreen.h \
+ TEHistory.h \
+ keytrans.h
+
+moc_TEmuVt102.o: moc_TEmuVt102.cpp \
+ TEmuVt102.h \
+ TEWidget.h \
+ TECommon.h \
+ TEScreen.h \
+ TEHistory.h \
+ TEmulation.h \
+ keytrans.h
+
+moc_session.o: moc_session.cpp \
+ session.h \
+ MyPty.h \
+ TEWidget.h \
+ TECommon.h \
+ TEmuVt102.h \
+ TEScreen.h \
+ TEHistory.h \
+ TEmulation.h \
+ keytrans.h
+
+moc_konsole.o: moc_konsole.cpp \
+ konsole.h \
+ MyPty.h \
+ TEWidget.h \
+ TECommon.h \
+ TEmuVt102.h \
+ TEScreen.h \
+ TEHistory.h \
+ TEmulation.h \
+ keytrans.h \
+ session.h
+
+moc_MyPty.o: moc_MyPty.cpp \
+ MyPty.h
+
+moc_TEWidget.cpp: TEWidget.h
+ $(MOC) TEWidget.h -o moc_TEWidget.cpp
+
+moc_TEmulation.cpp: TEmulation.h
+ $(MOC) TEmulation.h -o moc_TEmulation.cpp
+
+moc_TEmuVt102.cpp: TEmuVt102.h
+ $(MOC) TEmuVt102.h -o moc_TEmuVt102.cpp
+
+moc_session.cpp: session.h
+ $(MOC) session.h -o moc_session.cpp
+
+moc_konsole.cpp: konsole.h
+ $(MOC) konsole.h -o moc_konsole.cpp
+
+moc_MyPty.cpp: MyPty.h
+ $(MOC) MyPty.h -o moc_MyPty.cpp
+
+
diff --git a/core/apps/embeddedkonsole/MyPty.cpp b/core/apps/embeddedkonsole/MyPty.cpp
new file mode 100644
index 0000000..3622d48
--- a/dev/null
+++ b/core/apps/embeddedkonsole/MyPty.cpp
@@ -0,0 +1,279 @@
+/* -------------------------------------------------------------------------- */
+/* */
+/* [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 "MyPty.h"
+
+
+#undef VERBOSE_DEBUG
+
+
+/* -------------------------------------------------------------------------- */
+
+/*!
+ Informs the client program about the
+ actual size of the window.
+*/
+
+void MyPty::setSize(int lines, int columns)
+{
+ struct winsize wsize;
+ wsize.ws_row = (unsigned short)lines;
+ wsize.ws_col = (unsigned short)columns;
+ if(fd < 0) return;
+ ioctl(fd,TIOCSWINSZ,(char *)&wsize);
+}
+
+
+void MyPty::donePty()
+{
+ // This is code from the Qt DumbTerminal example
+ int status = 0;
+
+ ::close(fd);
+
+ if (cpid) {
+ kill(cpid, SIGHUP);
+ waitpid(cpid, &status, 0);
+ }
+
+ emit done(status);
+}
+
+
+const char* MyPty::deviceName()
+{
+ return ttynam;
+}
+
+
+void MyPty::error()
+{
+ // This is code from the Qt DumbTerminal example
+ donePty();
+}
+
+
+/*!
+ start the client program.
+*/
+int MyPty::run(const char* cmd, QStrList &, const char*, int)
+{
+ // This is code from the Qt DumbTerminal example
+ cpid = fork();
+
+ if ( !cpid ) {
+ // child - exec shell on tty
+ for (int sig = 1; sig < NSIG; sig++) signal(sig,SIG_DFL);
+ int ttyfd = open(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
+ QSocketNotifier* sn_r = new QSocketNotifier(fd,QSocketNotifier::Read,this);
+ QSocketNotifier* sn_e = new QSocketNotifier(fd,QSocketNotifier::Exception,this);
+ connect(sn_r,SIGNAL(activated(int)),this,SLOT(readPty()));
+ connect(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(ptynam,"/dev/pty%c%c",*c0,*c1);
+ sprintf(ttynam,"/dev/tty%c%c",*c0,*c1);
+ if ((ptyfd = ::open(ptynam,O_RDWR)) >= 0) {
+ if (geteuid() != 0 && !access(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() : cpid(0)
+{
+ fd = openPty();
+}
+
+/*!
+ Destructor.
+ Note that the related client program is not killed
+ (yet) when a instance is deleted.
+*/
+MyPty::~MyPty()
+{
+ donePty();
+}
+
+
+/*! sends len bytes through the line */
+void MyPty::send_bytes(const char* s, int len)
+{
+
+#ifdef VERBOSE_DEBUG
+ // verbose debug
+ printf("sending bytes:\n");
+ for (int i = 0; i < len; i++)
+ printf("%c", s[i]);
+ printf("\n");
+#endif
+
+ ::write(fd, s, len);
+}
+
+/*! indicates that a block of data is received */
+void MyPty::readPty()
+{
+ char buf[4096];
+
+ int len = ::read( fd, buf, 4096 );
+
+ if (len == -1)
+ donePty();
+
+ if (len < 0)
+ return;
+
+ emit block_in(buf,len);
+
+#ifdef VERBOSE_DEBUG
+ // verbose debug
+ printf("read bytes:\n");
+ for (int i = 0; i < len; i++)
+ printf("%c", buf[i]);
+ printf("\n");
+#endif
+
+}
+
diff --git a/core/apps/embeddedkonsole/MyPty.h b/core/apps/embeddedkonsole/MyPty.h
new file mode 100644
index 0000000..b2a5b58
--- a/dev/null
+++ b/core/apps/embeddedkonsole/MyPty.h
@@ -0,0 +1,88 @@
+/* -------------------------------------------------------------------------- */
+/* */
+/* [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 <qstrlist.h>
+
+
+class MyPty : public QObject
+{
+Q_OBJECT
+
+ public:
+
+ MyPty();
+ ~MyPty();
+
+ /*!
+ 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.
+ */
+ int run(const char* pgm, QStrList & args, const char* term, int addutmp);
+
+ public slots:
+
+ void send_bytes(const char* s, int len);
+ void setSize(int lines, int columns);
+ void error();
+
+ 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 block_in(const char* s, int len);
+
+ public:
+
+ void send_byte(char s);
+// void send_string(const char* s);
+
+ const char* deviceName();
+
+ protected slots:
+ void readPty();
+ void donePty();
+
+ private:
+ int openPty();
+
+ private:
+
+ char ptynam[16]; // "/dev/ptyxx" | "/dev/ptmx"
+ char ttynam[16]; // "/dev/ttyxx" | "/dev/pts/########..."
+ int fd;
+ int cpid;
+};
+
+#endif
diff --git a/core/apps/embeddedkonsole/TECommon.h b/core/apps/embeddedkonsole/TECommon.h
new file mode 100644
index 0000000..261d51b
--- a/dev/null
+++ b/core/apps/embeddedkonsole/TECommon.h
@@ -0,0 +1,114 @@
+/* -------------------------------------------------------------------------- */
+/* */
+/* [TECommon.h] Common Definitions */
+/* */
+/* -------------------------------------------------------------------------- */
+/* */
+/* 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 TECommon.h
+ \brief Definitions shared between TEScreen and TEWidget.
+*/
+
+#ifndef TECOMMON_H
+#define TECOMMON_H
+
+#include <qcolor.h>
+
+#ifndef BOOL
+typedef int BOOL;
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef UINT8
+typedef unsigned char UINT8;
+#endif
+
+#ifndef UINT16
+typedef unsigned short UINT16;
+#endif
+
+// Attributed Character Representations ///////////////////////////////
+
+// Colors
+
+#define BASE_COLORS (2+8)
+#define INTENSITIES 2
+#define TABLE_COLORS (INTENSITIES*BASE_COLORS)
+
+#define DEFAULT_FORE_COLOR 0
+#define DEFAULT_BACK_COLOR 1
+
+#define DEFAULT_RENDITION 0
+#define RE_BOLD (1 << 0)
+#define RE_BLINK (1 << 1)
+#define RE_UNDERLINE (1 << 2)
+#define RE_REVERSE (1 << 3) // Screen only
+#define RE_INTENSIVE (1 << 3) // Widget only
+
+/*! \class ca
+ * \brief a character with rendition attributes.
+*/
+
+class ca
+{
+public:
+ inline ca(UINT16 _c = ' ',
+ UINT8 _f = DEFAULT_FORE_COLOR,
+ UINT8 _b = DEFAULT_BACK_COLOR,
+ UINT8 _r = DEFAULT_RENDITION)
+ : c(_c), f(_f), b(_b), r(_r) {}
+public:
+ UINT16 c; // character
+ UINT8 f; // foreground color
+ UINT8 b; // background color
+ UINT8 r; // rendition
+public:
+ friend BOOL operator == (ca a, ca b);
+ friend BOOL operator != (ca a, ca b);
+};
+
+inline BOOL operator == (ca a, ca b)
+{
+ return a.c == b.c && a.f == b.f && a.b == b.b && a.r == b.r;
+}
+
+inline BOOL operator != (ca a, ca b)
+{
+ return a.c != b.c || a.f != b.f || a.b != b.b || a.r != b.r;
+}
+
+/*!
+*/
+struct ColorEntry
+{
+ ColorEntry(QColor c, bool tr, bool b) : color(c), transparent(tr), bold(b) {}
+ ColorEntry() : transparent(false), bold(false) {} // default constructors
+ void operator=(const ColorEntry& rhs) {
+ color = rhs.color;
+ transparent = rhs.transparent;
+ bold = rhs.bold;
+ }
+ QColor color;
+ bool transparent; // if used on bg
+ bool bold; // if used on fg
+};
+
+#endif // TECOMMON_H
diff --git a/core/apps/embeddedkonsole/TEHistory.cpp b/core/apps/embeddedkonsole/TEHistory.cpp
new file mode 100644
index 0000000..317ce57
--- a/dev/null
+++ b/core/apps/embeddedkonsole/TEHistory.cpp
@@ -0,0 +1,212 @@
+/* -------------------------------------------------------------------------- */
+/* */
+/* [TEHistory.C] History Buffer */
+/* */
+/* -------------------------------------------------------------------------- */
+/* */
+/* 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> */
+/* */
+/* -------------------------------------------------------------------------- */
+
+#include "TEHistory.h"
+#include <stdlib.h>
+#include <assert.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <errno.h>
+
+#define HERE printf("%s(%d): here\n",__FILE__,__LINE__)
+
+/*
+ An arbitrary long scroll.
+
+ One can modify the scroll only by adding either cells
+ or newlines, but access it randomly.
+
+ The model is that of an arbitrary wide typewriter scroll
+ in that the scroll is a serie of lines and each line is
+ a serie of cells with no overwriting permitted.
+
+ The implementation provides arbitrary length and numbers
+ of cells and line/column indexed read access to the scroll
+ at constant costs.
+
+FIXME: some complain about the history buffer comsuming the
+ memory of their machines. This problem is critical
+ since the history does not behave gracefully in cases
+ where the memory is used up completely.
+
+ I put in a workaround that should handle it problem
+ now gracefully. I'm not satisfied with the solution.
+
+FIXME: Terminating the history is not properly indicated
+ in the menu. We should throw a signal.
+
+FIXME: There is noticable decrease in speed, also. Perhaps,
+ there whole feature needs to be revisited therefore.
+ Disadvantage of a more elaborated, say block-oriented
+ scheme with wrap around would be it's complexity.
+*/
+
+//FIXME: tempory replacement for tmpfile
+// this is here one for debugging purpose.
+
+//#define tmpfile xTmpFile
+
+FILE* xTmpFile()
+{
+ static int fid = 0;
+ char fname[80];
+ sprintf(fname,"TmpFile.%d",fid++);
+ return fopen(fname,"w");
+}
+
+
+// History Buffer ///////////////////////////////////////////
+
+/*
+ A Row(X) data type which allows adding elements to the end.
+*/
+
+HistoryBuffer::HistoryBuffer()
+{
+ ion = -1;
+ length = 0;
+}
+
+HistoryBuffer::~HistoryBuffer()
+{
+ setScroll(FALSE);
+}
+
+void HistoryBuffer::setScroll(bool on)
+{
+ if (on == hasScroll()) return;
+
+ if (on)
+ {
+ assert( ion < 0 );
+ assert( length == 0);
+ FILE* tmp = tmpfile(); if (!tmp) { perror("konsole: cannot open temp file.\n"); return; }
+ ion = dup(fileno(tmp)); if (ion<0) perror("konsole: cannot dup temp file.\n");
+ fclose(tmp);
+ }
+ else
+ {
+ assert( ion >= 0 );
+ close(ion);
+ ion = -1;
+ length = 0;
+ }
+}
+
+bool HistoryBuffer::hasScroll()
+{
+ return ion >= 0;
+}
+
+void HistoryBuffer::add(const unsigned char* bytes, int len)
+{ int rc;
+ assert(hasScroll());
+ rc = lseek(ion,length,SEEK_SET); if (rc < 0) { perror("HistoryBuffer::add.seek"); setScroll(FALSE); return; }
+ rc = write(ion,bytes,len); if (rc < 0) { perror("HistoryBuffer::add.write"); setScroll(FALSE); return; }
+ length += rc;
+}
+
+void HistoryBuffer::get(unsigned char* bytes, int len, int loc)
+{ int rc;
+ assert(hasScroll());
+ if (loc < 0 || len < 0 || loc + len > length)
+ fprintf(stderr,"getHist(...,%d,%d): invalid args.\n",len,loc);
+ rc = lseek(ion,loc,SEEK_SET); if (rc < 0) { perror("HistoryBuffer::get.seek"); setScroll(FALSE); return; }
+ rc = read(ion,bytes,len); if (rc < 0) { perror("HistoryBuffer::get.read"); setScroll(FALSE); return; }
+}
+
+int HistoryBuffer::len()
+{
+ return length;
+}
+
+// History Scroll //////////////////////////////////////
+
+/*
+ The history scroll makes a Row(Row(Cell)) from
+ two history buffers. The index buffer contains
+ start of line positions which refere to the cells
+ buffer.
+
+ Note that index[0] addresses the second line
+ (line #1), while the first line (line #0) starts
+ at 0 in cells.
+*/
+
+HistoryScroll::HistoryScroll()
+{
+}
+
+HistoryScroll::~HistoryScroll()
+{
+}
+
+void HistoryScroll::setScroll(bool on)
+{
+ index.setScroll(on);
+ cells.setScroll(on);
+}
+
+bool HistoryScroll::hasScroll()
+{
+ return index.hasScroll() && cells.hasScroll();
+}
+
+int HistoryScroll::getLines()
+{
+ if (!hasScroll()) return 0;
+ return index.len() / sizeof(int);
+}
+
+int HistoryScroll::getLineLen(int lineno)
+{
+ if (!hasScroll()) return 0;
+ return (startOfLine(lineno+1) - startOfLine(lineno)) / sizeof(ca);
+}
+
+int HistoryScroll::startOfLine(int lineno)
+{
+ if (lineno <= 0) return 0;
+ if (!hasScroll()) return 0;
+ if (lineno <= getLines())
+ { int res;
+ index.get((unsigned char*)&res,sizeof(int),(lineno-1)*sizeof(int));
+ return res;
+ }
+ return cells.len();
+}
+
+void HistoryScroll::getCells(int lineno, int colno, int count, ca res[])
+{
+ assert(hasScroll());
+ cells.get((unsigned char*)res,count*sizeof(ca),startOfLine(lineno)+colno*sizeof(ca));
+}
+
+void HistoryScroll::addCells(ca text[], int count)
+{
+ if (!hasScroll()) return;
+ cells.add((unsigned char*)text,count*sizeof(ca));
+}
+
+void HistoryScroll::addLine()
+{
+ if (!hasScroll()) return;
+ int locn = cells.len();
+ index.add((unsigned char*)&locn,sizeof(int));
+}
diff --git a/core/apps/embeddedkonsole/TEHistory.h b/core/apps/embeddedkonsole/TEHistory.h
new file mode 100644
index 0000000..8339ec6
--- a/dev/null
+++ b/core/apps/embeddedkonsole/TEHistory.h
@@ -0,0 +1,75 @@
+/* -------------------------------------------------------------------------- */
+/* */
+/* [TEHistory.H] History Buffer */
+/* */
+/* -------------------------------------------------------------------------- */
+/* */
+/* 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> */
+/* */
+/* -------------------------------------------------------------------------- */
+
+#ifndef TEHISTORY_H
+#define TEHISTORY_H
+
+#include "TECommon.h"
+
+/*
+ An extendable tmpfile(1) based buffer.
+*/
+class HistoryBuffer
+{
+public:
+ HistoryBuffer();
+ ~HistoryBuffer();
+
+public:
+ void setScroll(bool on);
+ bool hasScroll();
+
+public:
+ void add(const unsigned char* bytes, int len);
+ void get(unsigned char* bytes, int len, int loc);
+ int len();
+
+private:
+ int ion;
+ int length;
+};
+
+class HistoryScroll
+{
+public:
+ HistoryScroll();
+ ~HistoryScroll();
+
+public:
+ void setScroll(bool on);
+ bool hasScroll();
+
+public: // access to history
+ int getLines();
+ int getLineLen(int lineno);
+ void getCells(int lineno, int colno, int count, ca res[]);
+
+public: // backward compatibility (obsolete)
+ ca getCell(int lineno, int colno) { ca res; getCells(lineno,colno,1,&res); return res; }
+
+public: // adding lines.
+ void addCells(ca a[], int count);
+ void addLine();
+
+private:
+ int startOfLine(int lineno);
+ HistoryBuffer index; // lines Row(int)
+ HistoryBuffer cells; // text Row(ca)
+};
+
+#endif // TEHISTORY_H
diff --git a/core/apps/embeddedkonsole/TEScreen.cpp b/core/apps/embeddedkonsole/TEScreen.cpp
new file mode 100644
index 0000000..a3d115d
--- a/dev/null
+++ b/core/apps/embeddedkonsole/TEScreen.cpp
@@ -0,0 +1,1197 @@
+/* -------------------------------------------------------------------------- */
+/* */
+/* [TEScreen.C] Screen Data Type */
+/* */
+/* -------------------------------------------------------------------------- */
+/* */
+/* 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
+*/
+
+/*! \class TEScreen
+
+ \brief The image manipulated by the emulation.
+
+ This class implements the operations of the terminal emulation framework.
+ It is a complete passive device, driven by the emulation decoder
+ (TEmuVT102). By this it forms in fact an ADT, that defines operations
+ on a rectangular image.
+
+ It does neither know how to display its image nor about escape sequences.
+ It is further independent of the underlying toolkit. By this, one can even
+ use this module for an ordinary text surface.
+
+ Since the operations are called by a specific emulation decoder, one may
+ collect their different operations here.
+
+ The state manipulated by the operations is mainly kept in `image', though
+ it is a little more complex bejond this. See the header file of the class.
+
+ \sa TEWidget \sa VT102Emulation
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+// #include <kdebug.h>
+
+#include <assert.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "TEScreen.h"
+
+#define HERE printf("%s(%d): here\n",__FILE__,__LINE__)
+
+//FIXME: this is emulation specific. Use FALSE for xterm, TRUE for ANSI.
+//FIXME: see if we can get this from terminfo.
+#define BS_CLEARS FALSE
+
+#define loc(X,Y) ((Y)*columns+(X))
+
+/*! creates a `TEScreen' of `lines' lines and `columns' columns.
+*/
+
+TEScreen::TEScreen(int lines, int columns)
+{
+ this->lines = lines;
+ this->columns = columns;
+
+ image = (ca*) malloc(lines*columns*sizeof(ca));
+ tabstops = NULL; initTabStops();
+
+ histCursor = 0;
+
+ clearSelection();
+ reset();
+}
+
+/*! Destructor
+*/
+
+TEScreen::~TEScreen()
+{
+ free(image);
+ if (tabstops) free(tabstops);
+}
+
+/* ------------------------------------------------------------------------- */
+/* */
+/* Normalized Screen Operations */
+/* */
+/* ------------------------------------------------------------------------- */
+
+// Cursor Setting --------------------------------------------------------------
+
+/*! \section Cursor
+
+ The `cursor' is a location within the screen that is implicitely used in
+ many operations. The operations within this section allow to manipulate
+ the cursor explicitly and to obtain it's value.
+
+ The position of the cursor is guarantied to be between (including) 0 and
+ `columns-1' and `lines-1'.
+*/
+
+/*!
+ Move the cursor up.
+
+ The cursor will not be moved beyond the top margin.
+*/
+
+void TEScreen::cursorUp(int n)
+//=CUU
+{
+ if (n == 0) n = 1; // Default
+ int stop = cuY < tmargin ? 0 : tmargin;
+ cuX = QMIN(columns-1,cuX); // nowrap!
+ cuY = QMAX(stop,cuY-n);
+}
+
+/*!
+ Move the cursor down.
+
+ The cursor will not be moved beyond the bottom margin.
+*/
+
+void TEScreen::cursorDown(int n)
+//=CUD
+{
+ if (n == 0) n = 1; // Default
+ int stop = cuY > bmargin ? lines-1 : bmargin;
+ cuX = QMIN(columns-1,cuX); // nowrap!
+ cuY = QMIN(stop,cuY+n);
+}
+
+/*!
+ Move the cursor left.
+
+ The cursor will not move beyond the first column.
+*/
+
+void TEScreen::cursorLeft(int n)
+//=CUB
+{
+ if (n == 0) n = 1; // Default
+ cuX = QMIN(columns-1,cuX); // nowrap!
+ cuX = QMAX(0,cuX-n);
+}
+
+/*!
+ Move the cursor left.
+
+ The cursor will not move beyond the rightmost column.
+*/
+
+void TEScreen::cursorRight(int n)
+//=CUF
+{
+ if (n == 0) n = 1; // Default
+ cuX = QMIN(columns-1,cuX+n);
+}
+
+/*!
+ Set top and bottom margin.
+*/
+
+void TEScreen::setMargins(int top, int bot)
+//=STBM
+{
+ if (top == 0) top = 1; // Default
+ if (bot == 0) bot = lines; // Default
+ top = top - 1; // Adjust to internal lineno
+ bot = bot - 1; // Adjust to internal lineno
+ if ( !( 0 <= top && top < bot && bot < lines ) )
+ { fprintf(stderr,"%s(%d) : setRegion(%d,%d) : bad range.\n",
+ __FILE__,__LINE__,top,bot);
+ return; // Default error action: ignore
+ }
+ tmargin = top;
+ bmargin = bot;
+ cuX = 0;
+ cuY = getMode(MODE_Origin) ? top : 0;
+}
+
+/*!
+ Move the cursor down one line.
+
+ If cursor is on bottom margin, the region between the
+ actual top and bottom margin is scrolled up instead.
+*/
+
+void TEScreen::index()
+//=IND
+{
+ if (cuY == bmargin)
+ {
+ if (tmargin == 0 && bmargin == lines-1) addHistLine(); // hist.history
+ scrollUp(tmargin,1);
+ }
+ else if (cuY < lines-1)
+ cuY += 1;
+}
+
+/*!
+ Move the cursor up one line.
+
+ If cursor is on the top margin, the region between the
+ actual top and bottom margin is scrolled down instead.
+*/
+
+void TEScreen::reverseIndex()
+//=RI
+{
+ if (cuY == tmargin)
+ scrollDown(tmargin,1);
+ else if (cuY > 0)
+ cuY -= 1;
+}
+
+/*!
+ Move the cursor to the begin of the next line.
+
+ If cursor is on bottom margin, the region between the
+ actual top and bottom margin is scrolled up.
+*/
+
+void TEScreen::NextLine()
+//=NEL
+{
+ Return(); index();
+}
+
+// Line Editing ----------------------------------------------------------------
+
+/*! \section inserting / deleting characters
+*/
+
+/*! erase `n' characters starting from (including) the cursor position.
+
+ The line is filled in from the right with spaces.
+*/
+
+void TEScreen::eraseChars(int n)
+{
+ if (n == 0) n = 1; // Default
+ int p = QMAX(0,QMIN(cuX+n-1,columns-1));
+ clearImage(loc(cuX,cuY),loc(p,cuY),' ');
+}
+
+/*! delete `n' characters starting from (including) the cursor position.
+
+ The line is filled in from the right with spaces.
+*/
+
+void TEScreen::deleteChars(int n)
+{
+ if (n == 0) n = 1; // Default
+ int p = QMAX(0,QMIN(cuX+n,columns-1));
+ moveImage(loc(cuX,cuY),loc(p,cuY),loc(columns-1,cuY));
+ clearImage(loc(columns-n,cuY),loc(columns-1,cuY),' ');
+}
+
+/*! insert `n' spaces at the cursor position.
+
+ The cursor is not moved by the operation.
+*/
+
+void TEScreen::insertChars(int n)
+{
+ if (n == 0) n = 1; // Default
+ int p = QMAX(0,QMIN(columns-1-n,columns-1));
+ int q = QMAX(0,QMIN(cuX+n,columns-1));
+ moveImage(loc(q,cuY),loc(cuX,cuY),loc(p,cuY));
+ clearImage(loc(cuX,cuY),loc(q-1,cuY),' ');
+}
+
+/*! delete `n' lines starting from (including) the cursor position.
+
+ The cursor is not moved by the operation.
+*/
+
+void TEScreen::deleteLines(int n)
+{
+ if (n == 0) n = 1; // Default
+ scrollUp(cuY,n);
+}
+
+/*! insert `n' lines at the cursor position.
+
+ The cursor is not moved by the operation.
+*/
+
+void TEScreen::insertLines(int n)
+{
+ if (n == 0) n = 1; // Default
+ scrollDown(cuY,n);
+}
+
+// Mode Operations -----------------------------------------------------------
+
+/*! Set a specific mode. */
+
+void TEScreen::setMode(int m)
+{
+ currParm.mode[m] = TRUE;
+ switch(m)
+ {
+ case MODE_Origin : cuX = 0; cuY = tmargin; break; //FIXME: home
+ }
+}
+
+/*! Reset a specific mode. */
+
+void TEScreen::resetMode(int m)
+{
+ currParm.mode[m] = FALSE;
+ switch(m)
+ {
+ case MODE_Origin : cuX = 0; cuY = 0; break; //FIXME: home
+ }
+}
+
+/*! Save a specific mode. */
+
+void TEScreen::saveMode(int m)
+{
+ saveParm.mode[m] = currParm.mode[m];
+}
+
+/*! Restore a specific mode. */
+
+void TEScreen::restoreMode(int m)
+{
+ currParm.mode[m] = saveParm.mode[m];
+}
+
+//NOTE: this is a helper function
+/*! Return the setting a specific mode. */
+BOOL TEScreen::getMode(int m)
+{
+ return currParm.mode[m];
+}
+
+/*! Save the cursor position and the rendition attribute settings. */
+
+void TEScreen::saveCursor()
+{
+ sa_cuX = cuX;
+ sa_cuY = cuY;
+ sa_cu_re = cu_re;
+ sa_cu_fg = cu_fg;
+ sa_cu_bg = cu_bg;
+}
+
+/*! Restore the cursor position and the rendition attribute settings. */
+
+void TEScreen::restoreCursor()
+{
+ cuX = QMIN(sa_cuX,columns-1);
+ cuY = QMIN(sa_cuY,lines-1);
+ cu_re = sa_cu_re;
+ cu_fg = sa_cu_fg;
+ cu_bg = sa_cu_bg;
+ effectiveRendition();
+}
+
+/* ------------------------------------------------------------------------- */
+/* */
+/* Screen Operations */
+/* */
+/* ------------------------------------------------------------------------- */
+
+/*! Assing a new size to the screen.
+
+ The topmost left position is maintained, while lower lines
+ or right hand side columns might be removed or filled with
+ spaces to fit the new size.
+
+ The region setting is reset to the whole screen and the
+ tab positions reinitialized.
+*/
+
+void TEScreen::resizeImage(int new_lines, int new_columns)
+{
+
+ if (cuY > new_lines-1)
+ { // attempt to preserve focus and lines
+ bmargin = lines-1; //FIXME: margin lost
+ for (int i = 0; i < cuY-(new_lines-1); i++)
+ {
+ addHistLine(); scrollUp(0,1);
+ }
+ }
+
+ // make new image
+ ca* newimg = (ca*)malloc(new_lines*new_columns*sizeof(ca));
+
+ clearSelection();
+
+ // clear new image
+ for (int y = 0; y < new_lines; y++)
+ for (int x = 0; x < new_columns; x++)
+ {
+ newimg[y*new_columns+x].c = ' ';
+ newimg[y*new_columns+x].f = DEFAULT_FORE_COLOR;
+ newimg[y*new_columns+x].b = DEFAULT_BACK_COLOR;
+ newimg[y*new_columns+x].r = DEFAULT_RENDITION;
+ }
+ int cpy_lines = QMIN(new_lines, lines);
+ int cpy_columns = QMIN(new_columns,columns);
+ // copy to new image
+ for (int y = 0; y < cpy_lines; y++)
+ for (int x = 0; x < cpy_columns; x++)
+ {
+ newimg[y*new_columns+x].c = image[loc(x,y)].c;
+ newimg[y*new_columns+x].f = image[loc(x,y)].f;
+ newimg[y*new_columns+x].b = image[loc(x,y)].b;
+ newimg[y*new_columns+x].r = image[loc(x,y)].r;
+ }
+ free(image);
+ image = newimg;
+ lines = new_lines;
+ columns = new_columns;
+ cuX = QMIN(cuX,columns-1);
+ cuY = QMIN(cuY,lines-1);
+
+ // FIXME: try to keep values, evtl.
+ tmargin=0;
+ bmargin=lines-1;
+ initTabStops();
+ clearSelection();
+}
+
+/*
+ Clarifying rendition here and in TEWidget.
+
+ currently, TEWidget's color table is
+ 0 1 2 .. 9 10 .. 17
+ dft_fg, dft_bg, dim 0..7, intensive 0..7
+
+ cu_fg, cu_bg contain values 0..8;
+ - 0 = default color
+ - 1..8 = ansi specified color
+
+ re_fg, re_bg contain values 0..17
+ due to the TEWidget's color table
+
+ rendition attributes are
+
+ attr widget screen
+ -------------- ------ ------
+ RE_UNDERLINE XX XX affects foreground only
+ RE_BLINK XX XX affects foreground only
+ RE_BOLD XX XX affects foreground only
+ RE_REVERSE -- XX
+ RE_TRANSPARENT XX -- affects background only
+ RE_INTENSIVE XX -- affects foreground only
+
+ Note that RE_BOLD is used in both widget
+ and screen rendition. Since xterm/vt102
+ is to poor to distinguish between bold
+ (which is a font attribute) and intensive
+ (which is a color attribute), we translate
+ this and RE_BOLD in falls eventually appart
+ into RE_BOLD and RE_INTENSIVE.
+*/
+
+void TEScreen::reverseRendition(ca* p)
+{ UINT8 f = p->f; UINT8 b = p->b;
+ p->f = b; p->b = f; //p->r &= ~RE_TRANSPARENT;
+}
+
+void TEScreen::effectiveRendition()
+// calculate rendition
+{
+ ef_re = cu_re & (RE_UNDERLINE | RE_BLINK);
+ if (cu_re & RE_REVERSE)
+ {
+ ef_fg = cu_bg;
+ ef_bg = cu_fg;
+ }
+ else
+ {
+ ef_fg = cu_fg;
+ ef_bg = cu_bg;
+ }
+ if (cu_re & RE_BOLD)
+ {
+ if (ef_fg < BASE_COLORS)
+ ef_fg += BASE_COLORS;
+ else
+ ef_fg -= BASE_COLORS;
+ }
+}
+
+/*!
+ returns the image.
+
+ Get the size of the image by \sa getLines and \sa getColumns.
+
+ NOTE that the image returned by this function must later be
+ freed.
+
+*/
+
+ca* TEScreen::getCookedImage()
+{ int x,y;
+ ca* merged = (ca*)malloc(lines*columns*sizeof(ca));
+ ca dft(' ',DEFAULT_FORE_COLOR,DEFAULT_BACK_COLOR,DEFAULT_RENDITION);
+
+ for (y = 0; (y < lines) && (y < (hist.getLines()-histCursor)); y++)
+ {
+ int len = QMIN(columns,hist.getLineLen(y+histCursor));
+ int yp = y*columns;
+ int yq = (y+histCursor)*columns;
+
+ hist.getCells(y+histCursor,0,len,merged+yp);
+ for (x = len; x < columns; x++) merged[yp+x] = dft;
+ for (x = 0; x < columns; x++)
+ { int p=x + yp; int q=x + yq;
+ if ( ( q >= sel_TL ) && ( q <= sel_BR ) )
+ reverseRendition(&merged[p]); // for selection
+ }
+ }
+ if (lines >= hist.getLines()-histCursor)
+ {
+ for (y = (hist.getLines()-histCursor); y < lines ; y++)
+ {
+ int yp = y*columns;
+ int yq = (y+histCursor)*columns;
+ int yr = (y-hist.getLines()+histCursor)*columns;
+ for (x = 0; x < columns; x++)
+ { int p = x + yp; int q = x + yq; int r = x + yr;
+ merged[p] = image[r];
+ if ( q >= sel_TL && q <= sel_BR )
+ reverseRendition(&merged[p]); // for selection
+ }
+
+ }
+ }
+ // evtl. inverse display
+ if (getMode(MODE_Screen))
+ { int i,n = lines*columns;
+ for (i = 0; i < n; i++)
+ reverseRendition(&merged[i]); // for reverse display
+ }
+ if (getMode(MODE_Cursor) && (cuY+(hist.getLines()-histCursor) < lines)) // cursor visible
+ reverseRendition(&merged[loc(cuX,cuY+(hist.getLines()-histCursor))]);
+ return merged;
+}
+
+
+/*!
+*/
+
+void TEScreen::reset()
+{
+ setMode(MODE_Wrap ); saveMode(MODE_Wrap ); // wrap at end of margin
+ resetMode(MODE_Origin); saveMode(MODE_Origin); // position refere to [1,1]
+ resetMode(MODE_Insert); saveMode(MODE_Insert); // overstroke
+ setMode(MODE_Cursor); // cursor visible
+ resetMode(MODE_Screen); // screen not inverse
+ resetMode(MODE_NewLine);
+
+ tmargin=0;
+ bmargin=lines-1;
+
+ setDefaultRendition();
+ saveCursor();
+
+ clear();
+}
+
+/*! Clear the entire screen and home the cursor.
+*/
+
+void TEScreen::clear()
+{
+ clearEntireScreen();
+ home();
+}
+
+/*! Moves the cursor left one column.
+*/
+
+void TEScreen::BackSpace()
+{
+ cuX = QMAX(0,cuX-1);
+ if (BS_CLEARS) image[loc(cuX,cuY)].c = ' ';
+}
+
+/*!
+*/
+
+void TEScreen::Tabulate()
+{
+ // note that TAB is a format effector (does not write ' ');
+ cursorRight(1); while(cuX < columns-1 && !tabstops[cuX]) cursorRight(1);
+}
+
+void TEScreen::clearTabStops()
+{
+ for (int i = 0; i < columns; i++) tabstops[i-1] = FALSE;
+}
+
+void TEScreen::changeTabStop(bool set)
+{
+ if (cuX >= columns) return;
+ tabstops[cuX] = set;
+}
+
+void TEScreen::initTabStops()
+{
+ if (tabstops) free(tabstops);
+ tabstops = (bool*)malloc(columns*sizeof(bool));
+ // Arrg! The 1st tabstop has to be one longer than the other.
+ // i.e. the kids start counting from 0 instead of 1.
+ // Other programs might behave correctly. Be aware.
+ for (int i = 0; i < columns; i++) tabstops[i] = (i%8 == 0 && i != 0);
+}
+
+/*!
+ This behaves either as IND (Screen::Index) or as NEL (Screen::NextLine)
+ depending on the NewLine Mode (LNM). This mode also
+ affects the key sequence returned for newline ([CR]LF).
+*/
+
+void TEScreen::NewLine()
+{
+ if (getMode(MODE_NewLine)) Return();
+ index();
+}
+
+/*! put `c' literally onto the screen at the current cursor position.
+
+ VT100 uses the convention to produce an automatic newline (am)
+ with the *first* character that would fall onto the next line (xenl).
+*/
+
+void TEScreen::checkSelection(int from, int to)
+{
+ if (sel_begin == -1) return;
+ int scr_TL = loc(0, hist.getLines());
+ //Clear entire selection if it overlaps region [from, to]
+ if ( (sel_BR > (from+scr_TL) )&&(sel_TL < (to+scr_TL)) )
+ {
+ clearSelection();
+ }
+}
+
+void TEScreen::ShowCharacter(unsigned short c)
+{
+ // Note that VT100 does wrapping BEFORE putting the character.
+ // This has impact on the assumption of valid cursor positions.
+ // We indicate the fact that a newline has to be triggered by
+ // putting the cursor one right to the last column of the screen.
+
+ if (cuX >= columns)
+ {
+ if (getMode(MODE_Wrap)) NextLine(); else cuX = columns-1;
+ }
+
+ if (getMode(MODE_Insert)) insertChars(1);
+
+ int i = loc(cuX,cuY);
+
+ checkSelection(i, i); // check if selection is still valid.
+
+ image[i].c = c;
+ image[i].f = ef_fg;
+ image[i].b = ef_bg;
+ image[i].r = ef_re;
+
+ cuX += 1;
+}
+
+// Region commands -------------------------------------------------------------
+
+
+/*! scroll up `n' lines within current region.
+ The `n' new lines are cleared.
+ \sa setRegion \sa scrollDown
+*/
+
+void TEScreen::scrollUp(int from, int n)
+{
+ if (n <= 0 || from + n > bmargin) return;
+ //FIXME: make sure `tmargin', `bmargin', `from', `n' is in bounds.
+ moveImage(loc(0,from),loc(0,from+n),loc(columns-1,bmargin));
+ clearImage(loc(0,bmargin-n+1),loc(columns-1,bmargin),' ');
+}
+
+/*! scroll down `n' lines within current region.
+ The `n' new lines are cleared.
+ \sa setRegion \sa scrollUp
+*/
+
+void TEScreen::scrollDown(int from, int n)
+{
+//FIXME: make sure `tmargin', `bmargin', `from', `n' is in bounds.
+ if (n <= 0) return;
+ if (from > bmargin) return;
+ if (from + n > bmargin) n = bmargin - from;
+ moveImage(loc(0,from+n),loc(0,from),loc(columns-1,bmargin-n));
+ clearImage(loc(0,from),loc(columns-1,from+n-1),' ');
+}
+
+/*! position the cursor to a specific line and column. */
+void TEScreen::setCursorYX(int y, int x)
+{
+ setCursorY(y); setCursorX(x);
+}
+
+/*! Set the cursor to x-th line. */
+
+void TEScreen::setCursorX(int x)
+{
+ if (x == 0) x = 1; // Default
+ x -= 1; // Adjust
+ cuX = QMAX(0,QMIN(columns-1, x));
+}
+
+/*! Set the cursor to y-th line. */
+
+void TEScreen::setCursorY(int y)
+{
+ if (y == 0) y = 1; // Default
+ y -= 1; // Adjust
+ cuY = QMAX(0,QMIN(lines -1, y + (getMode(MODE_Origin) ? tmargin : 0) ));
+}
+
+/*! set cursor to the `left upper' corner of the screen (1,1).
+*/
+
+void TEScreen::home()
+{
+ cuX = 0;
+ cuY = 0;
+}
+
+/*! set cursor to the begin of the current line.
+*/
+
+void TEScreen::Return()
+{
+ cuX = 0;
+}
+
+/*! returns the current cursor columns.
+*/
+
+int TEScreen::getCursorX()
+{
+ return cuX;
+}
+
+/*! returns the current cursor line.
+*/
+
+int TEScreen::getCursorY()
+{
+ return cuY;
+}
+
+// Erasing ---------------------------------------------------------------------
+
+/*! \section Erasing
+
+ This group of operations erase parts of the screen contents by filling
+ it with spaces colored due to the current rendition settings.
+
+ Althought the cursor position is involved in most of these operations,
+ it is never modified by them.
+*/
+
+/*! fill screen between (including) `loca' and `loce' with spaces.
+
+ This is an internal helper functions. The parameter types are internal
+ addresses of within the screen image and make use of the way how the
+ screen matrix is mapped to the image vector.
+*/
+
+void TEScreen::clearImage(int loca, int loce, char c)
+{ int i;
+ int scr_TL=loc(0,hist.getLines());
+ //FIXME: check positions
+
+ //Clear entire selection if it overlaps region to be moved...
+ if ( (sel_BR > (loca+scr_TL) )&&(sel_TL < (loce+scr_TL)) )
+ {
+ clearSelection();
+ }
+ for (i = loca; i <= loce; i++)
+ {
+ image[i].c = c;
+ image[i].f = ef_fg; //DEFAULT_FORE_COLOR; //FIXME: xterm and linux/ansi
+ image[i].b = ef_bg; //DEFAULT_BACK_COLOR; // many have different
+ image[i].r = ef_re; //DEFAULT_RENDITION; // ideas here.
+ }
+}
+
+/*! move image between (including) `loca' and `loce' to 'dst'.
+
+ This is an internal helper functions. The parameter types are internal
+ addresses of within the screen image and make use of the way how the
+ screen matrix is mapped to the image vector.
+*/
+
+void TEScreen::moveImage(int dst, int loca, int loce)
+{
+//FIXME: check positions
+ if (loce < loca) {
+ // kdDebug() << "WARNING!!! call to TEScreen:moveImage with loce < loca!" << endl;
+ return;
+ }
+ memmove(&image[dst],&image[loca],(loce-loca+1)*sizeof(ca));
+}
+
+/*! clear from (including) current cursor position to end of screen.
+*/
+
+void TEScreen::clearToEndOfScreen()
+{
+ clearImage(loc(cuX,cuY),loc(columns-1,lines-1),' ');
+}
+
+/*! clear from begin of screen to (including) current cursor position.
+*/
+
+void TEScreen::clearToBeginOfScreen()
+{
+ clearImage(loc(0,0),loc(cuX,cuY),' ');
+}
+
+/*! clear the entire screen.
+*/
+
+void TEScreen::clearEntireScreen()
+{
+ clearImage(loc(0,0),loc(columns-1,lines-1),' ');
+}
+
+/*! fill screen with 'E'
+ This is to aid screen alignment
+*/
+
+void TEScreen::helpAlign()
+{
+ clearImage(loc(0,0),loc(columns-1,lines-1),'E');
+}
+
+/*! clear from (including) current cursor position to end of current cursor line.
+*/
+
+void TEScreen::clearToEndOfLine()
+{
+ clearImage(loc(cuX,cuY),loc(columns-1,cuY),' ');
+}
+
+/*! clear from begin of current cursor line to (including) current cursor position.
+*/
+
+void TEScreen::clearToBeginOfLine()
+{
+ clearImage(loc(0,cuY),loc(cuX,cuY),' ');
+}
+
+/*! clears entire current cursor line
+*/
+
+void TEScreen::clearEntireLine()
+{
+ clearImage(loc(0,cuY),loc(columns-1,cuY),' ');
+}
+
+// Rendition ------------------------------------------------------------------
+
+/*!
+ set rendition mode
+*/
+
+void TEScreen::setRendition(int re)
+{
+ cu_re |= re;
+ effectiveRendition();
+}
+
+/*!
+ reset rendition mode
+*/
+
+void TEScreen::resetRendition(int re)
+{
+ cu_re &= ~re;
+ effectiveRendition();
+}
+
+/*!
+*/
+
+void TEScreen::setDefaultRendition()
+{
+ setForeColorToDefault();
+ setBackColorToDefault();
+ cu_re = DEFAULT_RENDITION;
+ effectiveRendition();
+}
+
+/*!
+*/
+
+void TEScreen::setForeColor(int fgcolor)
+{
+ cu_fg = (fgcolor&7)+((fgcolor&8) ? 4+8 : 2);
+ effectiveRendition();
+}
+
+/*!
+*/
+
+void TEScreen::setBackColor(int bgcolor)
+{
+ cu_bg = (bgcolor&7)+((bgcolor&8) ? 4+8 : 2);
+ effectiveRendition();
+}
+
+/*!
+*/
+
+void TEScreen::setBackColorToDefault()
+{
+ cu_bg = DEFAULT_BACK_COLOR;
+ effectiveRendition();
+}
+
+/*!
+*/
+
+void TEScreen::setForeColorToDefault()
+{
+ cu_fg = DEFAULT_FORE_COLOR;
+ effectiveRendition();
+}
+
+/* ------------------------------------------------------------------------- */
+/* */
+/* Marking & Selection */
+/* */
+/* ------------------------------------------------------------------------- */
+
+void TEScreen::clearSelection()
+{
+ sel_BR = -1;
+ sel_TL = -1;
+ sel_begin = -1;
+}
+
+void TEScreen::setSelBeginXY(const int x, const int y)
+{
+ sel_begin = loc(x,y+histCursor) ;
+ sel_BR = sel_begin;
+ sel_TL = sel_begin;
+}
+
+void TEScreen::setSelExtentXY(const int x, const int y)
+{
+ if (sel_begin == -1) return;
+ int l = loc(x,y + histCursor);
+
+ if (l < sel_begin)
+ {
+ sel_TL = l;
+ sel_BR = sel_begin;
+ }
+ else
+ {
+ /* FIXME, HACK to correct for x too far to the right... */
+ if (( x == columns )|| (x == 0)) l--;
+
+ sel_TL = sel_begin;
+ sel_BR = l;
+ }
+}
+
+QString TEScreen::getSelText(const BOOL preserve_line_breaks)
+{
+ if (sel_begin == -1)
+ return QString::null; // Selection got clear while selecting.
+
+ int *m; // buffer to fill.
+ int s, d; // source index, dest. index.
+ int hist_BR = loc(0, hist.getLines());
+ int hY = sel_TL / columns;
+ int hX = sel_TL % columns;
+ int eol; // end of line
+
+ s = sel_TL; // tracks copy in source.
+
+ // allocate buffer for maximum
+ // possible size...
+ d = (sel_BR - sel_TL) / columns + 1;
+ m = new int[d * (columns + 1) + 2];
+ d = 0;
+
+ while (s <= sel_BR)
+ {
+ if (s < hist_BR)
+ { // get lines from hist.history
+ // buffer.
+ eol = hist.getLineLen(hY);
+
+ if ((hY == (sel_BR / columns)) &&
+ (eol >= (sel_BR % columns)))
+ {
+ eol = sel_BR % columns + 1;
+ }
+
+ while (hX < eol)
+ {
+ m[d++] = hist.getCell(hY, hX++).c;
+ s++;
+ }
+
+ if (s <= sel_BR)
+ {
+ // The line break handling
+ // It's different from the screen
+ // image case!
+ if (eol % columns == 0)
+ {
+ // That's either a completely filled
+ // line or an empty line
+ if (eol == 0)
+ {
+ m[d++] = '\n';
+ }
+ else
+ {
+ // We have a full line.
+ // FIXME: How can we handle newlines
+ // at this position?!
+ }
+ }
+ else if ((eol + 1) % columns == 0)
+ {
+ // FIXME: We don't know if this was a
+ // space at the last position or a
+ // short line!!
+ m[d++] = ' ';
+ }
+ else
+ {
+ // We have a short line here. Put a
+ // newline or a space into the
+ // buffer.
+ m[d++] = preserve_line_breaks ? '\n' : ' ';
+ }
+ }
+
+ hY++;
+ hX = 0;
+ s = hY * columns;
+ }
+ else
+ { // or from screen image.
+ eol = (s / columns + 1) * columns - 1;
+
+ if (eol < sel_BR)
+ {
+ while ((eol > s) &&
+ isspace(image[eol - hist_BR].c))
+ {
+ eol--;
+ }
+ }
+ else
+ {
+ eol = sel_BR;
+ }
+
+ while (s <= eol)
+ {
+ m[d++] = image[s++ - hist_BR].c;
+ }
+
+ if (eol < sel_BR)
+ {
+ // eol processing see below ...
+ if ((eol + 1) % columns == 0)
+ {
+ if (image[eol - hist_BR].c == ' ')
+ {
+ m[d++] = ' ';
+ }
+ }
+ else
+ {
+ m[d++] = ((preserve_line_breaks ||
+ ((eol % columns) == 0)) ?
+ '\n' : ' ');
+ }
+ }
+
+ s = (eol / columns + 1) * columns;
+ }
+ }
+
+ QChar* qc = new QChar[d];
+
+ for (int i = 0; i < d; i++)
+ {
+ qc[i] = m[i];
+ }
+
+ QString res(qc, d);
+
+ delete m;
+ delete qc;
+
+ return res;
+}
+/* above ... end of line processing for selection -- psilva
+cases:
+
+1) (eol+1)%columns == 0 --> the whole line is filled.
+ If the last char is a space, insert (preserve) space. otherwise
+ leave the text alone, so that words that are broken by linewrap
+ are preserved.
+
+FIXME:
+ * this suppresses \n for command output that is
+ sized to the exact column width of the screen.
+
+2) eol%columns == 0 --> blank line.
+ insert a \n unconditionally.
+ Do it either you would because you are in preserve_line_break mode,
+ or because it's an ASCII paragraph delimiter, so even when
+ not preserving line_breaks, you want to preserve paragraph breaks.
+
+3) else --> partially filled line
+ insert a \n in preserve line break mode, else a space
+ The space prevents concatenation of the last word of one
+ line with the first of the next.
+
+*/
+
+void TEScreen::addHistLine()
+{
+ assert(hasScroll() || histCursor == 0);
+
+ // add to hist buffer
+ // we have to take care about scrolling, too...
+
+ if (hasScroll())
+ { ca dft;
+
+ int end = columns-1;
+ while (end >= 0 && image[end] == dft)
+ end -= 1;
+
+ hist.addCells(image,end+1);
+ hist.addLine();
+
+ // adjust history cursor
+ histCursor += (hist.getLines()-1 == histCursor);
+ }
+
+ if (!hasScroll()) histCursor = 0; //FIXME: a poor workaround
+}
+
+void TEScreen::setHistCursor(int cursor)
+{
+ histCursor = cursor; //FIXME:rangecheck
+}
+
+int TEScreen::getHistCursor()
+{
+ return histCursor;
+}
+
+int TEScreen::getHistLines()
+{
+ return hist.getLines();
+}
+
+void TEScreen::setScroll(bool on)
+{
+ histCursor = 0;
+ clearSelection();
+ hist.setScroll(on);
+}
+
+bool TEScreen::hasScroll()
+{
+ return hist.hasScroll();
+}
diff --git a/core/apps/embeddedkonsole/TEScreen.h b/core/apps/embeddedkonsole/TEScreen.h
new file mode 100644
index 0000000..ba47ee5
--- a/dev/null
+++ b/core/apps/embeddedkonsole/TEScreen.h
@@ -0,0 +1,259 @@
+/* -------------------------------------------------------------------------- */
+/* */
+/* [te_screen.h] Screen Data Type */
+/* */
+/* -------------------------------------------------------------------------- */
+/* */
+/* 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> */
+/* */
+/* -------------------------------------------------------------------------- */
+
+#ifndef TESCREEN_H
+#define TESCREEN_H
+
+/*! \file
+*/
+
+#include "TECommon.h"
+#include "TEHistory.h"
+
+#define MODE_Origin 0
+#define MODE_Wrap 1
+#define MODE_Insert 2
+#define MODE_Screen 3
+#define MODE_Cursor 4
+#define MODE_NewLine 5
+#define MODES_SCREEN 6
+
+/*!
+*/
+struct ScreenParm
+{
+ int mode[MODES_SCREEN];
+};
+
+
+class TEScreen
+{
+public:
+ TEScreen(int lines, int columns);
+ ~TEScreen();
+
+public: // these are all `Screen' operations
+ //
+ // VT100/2 Operations ------------------
+ //
+ // Cursor Movement
+ //
+ void cursorUp (int n);
+ void cursorDown (int n);
+ void cursorLeft (int n);
+ void cursorRight (int n);
+ void setCursorY (int y);
+ void setCursorX (int x);
+ void setCursorYX (int y, int x);
+ void setMargins (int t, int b);
+ //
+ // Cursor Movement with Scrolling
+ //
+ void NewLine ();
+ void NextLine ();
+ void index ();
+ void reverseIndex();
+ //
+ void Return ();
+ void BackSpace ();
+ void Tabulate ();
+ //
+ // Editing
+ //
+ void eraseChars (int n);
+ void deleteChars (int n);
+ void insertChars (int n);
+ void deleteLines (int n);
+ void insertLines (int n);
+ //
+ // -------------------------------------
+ //
+ void clearTabStops();
+ void changeTabStop(bool set);
+ //
+ void resetMode (int n);
+ void setMode (int n);
+ void saveMode (int n);
+ void restoreMode (int n);
+ //
+ void saveCursor ();
+ void restoreCursor();
+ //
+ // -------------------------------------
+ //
+ void clearEntireScreen();
+ void clearToEndOfScreen();
+ void clearToBeginOfScreen();
+ //
+ void clearEntireLine();
+ void clearToEndOfLine();
+ void clearToBeginOfLine();
+ //
+ void helpAlign ();
+ //
+ // -------------------------------------
+ //
+ void setRendition (int rendition);
+ void resetRendition(int rendition);
+ void setForeColor (int fgcolor);
+ void setBackColor (int bgcolor);
+ //
+ void setDefaultRendition();
+ void setForeColorToDefault();
+ void setBackColorToDefault();
+ //
+ // -------------------------------------
+ //
+ BOOL getMode (int n);
+ //
+ // only for report cursor position
+ //
+ int getCursorX();
+ int getCursorY();
+ //
+ // -------------------------------------
+ //
+ void clear();
+ void home();
+ void reset();
+ //
+ void ShowCharacter(unsigned short c);
+ //
+ void resizeImage(int new_lines, int new_columns);
+ //
+ ca* getCookedImage();
+
+ /*! return the number of lines. */
+ int getLines() { return lines; }
+ /*! return the number of columns. */
+ int getColumns() { return columns; }
+
+ /*! set the position of the history cursor. */
+ void setHistCursor(int cursor);
+ /*! return the position of the history cursor. */
+ int getHistCursor();
+
+ int getHistLines ();
+ void setScroll(bool on);
+ bool hasScroll();
+
+ //
+ // Selection
+ //
+ void setSelBeginXY(const int x, const int y);
+ void setSelExtentXY(const int x, const int y);
+ void clearSelection();
+ QString getSelText(const BOOL preserve_line_breaks);
+
+ void checkSelection(int from, int to);
+
+private: // helper
+
+ void clearImage(int loca, int loce, char c);
+ void moveImage(int dst, int loca, int loce);
+
+ void scrollUp(int from, int i);
+ void scrollDown(int from, int i);
+
+ void addHistLine();
+
+ void initTabStops();
+
+ void effectiveRendition();
+ void reverseRendition(ca* p);
+
+private:
+
+ /*
+ The state of the screen is more complex as one would
+ expect first. The screem does really do part of the
+ emulation providing state informations in form of modes,
+ margins, tabulators, cursor etc.
+
+ Even more unexpected are variables to save and restore
+ parts of the state.
+ */
+
+ // screen image ----------------
+
+ int lines;
+ int columns;
+ ca *image; // [lines][columns]
+
+ // history buffer ---------------
+
+ int histCursor; // display position relative to start of the history buffer
+ HistoryScroll hist;
+
+ // cursor location
+
+ int cuX;
+ int cuY;
+
+ // cursor color and rendition info
+
+ UINT8 cu_fg; // foreground
+ UINT8 cu_bg; // background
+ UINT8 cu_re; // rendition
+
+ // margins ----------------
+
+ int tmargin; // top margin
+ int bmargin; // bottom margin
+
+ // states ----------------
+
+ ScreenParm currParm;
+
+ // ----------------------------
+
+ bool* tabstops;
+
+ // selection -------------------
+
+ int sel_begin; // The first location selected.
+ int sel_TL; // TopLeft Location.
+ int sel_BR; // Bottom Right Location.
+
+ // effective colors and rendition ------------
+
+ UINT8 ef_fg; // These are derived from
+ UINT8 ef_bg; // the cu_* variables above
+ UINT8 ef_re; // to speed up operation
+
+ //
+ // save cursor, rendition & states ------------
+ //
+
+ // cursor location
+
+ int sa_cuX;
+ int sa_cuY;
+
+ // rendition info
+
+ UINT8 sa_cu_re;
+ UINT8 sa_cu_fg;
+ UINT8 sa_cu_bg;
+
+ // modes
+
+ ScreenParm saveParm;
+};
+
+#endif // TESCREEN_H
diff --git a/core/apps/embeddedkonsole/TEWidget.cpp b/core/apps/embeddedkonsole/TEWidget.cpp
new file mode 100644
index 0000000..dc83998
--- a/dev/null
+++ b/core/apps/embeddedkonsole/TEWidget.cpp
@@ -0,0 +1,1243 @@
+/* ------------------------------------------------------------------------ */
+/* */
+/* [TEWidget.C] Terminal Emulation Widget */
+/* */
+/* ------------------------------------------------------------------------ */
+/* */
+/* 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 TEWidget
+
+ \brief Visible screen contents
+
+ This class is responsible to map the `image' of a terminal emulation to the
+ display. All the dependency of the emulation to a specific GUI or toolkit is
+ localized here. Further, this widget has no knowledge about being part of an
+ emulation, it simply work within the terminal emulation framework by exposing
+ size and key events and by being ordered to show a new image.
+
+ <ul>
+ <li> The internal image has the size of the widget (evtl. rounded up)
+ <li> The external image used in setImage can have any size.
+ <li> (internally) the external image is simply copied to the internal
+ when a setImage happens. During a resizeEvent no painting is done
+ a paintEvent is expected to follow anyway.
+ </ul>
+
+ \sa TEScreen \sa Emulation
+*/
+
+/* FIXME:
+ - 'image' may also be used uninitialized (it isn't in fact) in resizeEvent
+ - 'font_a' not used in mouse events
+ - add destructor
+*/
+
+/* TODO
+ - evtl. be sensitive to `paletteChange' while using default colors.
+ - set different 'rounding' styles? I.e. have a mode to show clipped chars?
+*/
+
+// #include "config.h"
+#include "TEWidget.h"
+#include "session.h"
+
+#include <qcursor.h>
+#include <qregexp.h>
+#include <qpainter.h>
+#include <qclipboard.h>
+#include <qstyle.h>
+#include <qfile.h>
+#include <qdragobject.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <ctype.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <signal.h>
+
+#include <assert.h>
+
+// #include "TEWidget.moc"
+//#include <kapp.h>
+//#include <kcursor.h>
+//#include <kurl.h>
+//#include <kdebug.h>
+//#include <klocale.h>
+
+#define HERE printf("%s(%d): %s\n",__FILE__,__LINE__,__FUNCTION__)
+#define HCNT(Name) // { static int cnt = 1; printf("%s(%d): %s %d\n",__FILE__,__LINE__,Name,cnt++); }
+
+#define loc(X,Y) ((Y)*columns+(X))
+
+//FIXME: the rim should normally be 1, 0 only when running in full screen mode.
+#define rimX 0 // left/right rim width
+#define rimY 0 // top/bottom rim high
+
+#define SCRWIDTH 16 // width of the scrollbar
+
+#define yMouseScroll 1
+// scroll increment used when dragging selection at top/bottom of window.
+
+/* ------------------------------------------------------------------------- */
+/* */
+/* Colors */
+/* */
+/* ------------------------------------------------------------------------- */
+
+//FIXME: the default color table is in session.C now.
+// We need a way to get rid of this one, here.
+static const ColorEntry base_color_table[TABLE_COLORS] =
+// The following are almost IBM standard color codes, with some slight
+// gamma correction for the dim colors to compensate for bright X screens.
+// It contains the 8 ansiterm/xterm colors in 2 intensities.
+{
+ // Fixme: could add faint colors here, also.
+ // normal
+ ColorEntry(QColor(0x00,0x00,0x00), 0, 0 ), ColorEntry( QColor(0xB2,0xB2,0xB2), 1, 0 ), // Dfore, Dback
+ ColorEntry(QColor(0x00,0x00,0x00), 0, 0 ), ColorEntry( QColor(0xB2,0x18,0x18), 0, 0 ), // Black, Red
+ ColorEntry(QColor(0x18,0xB2,0x18), 0, 0 ), ColorEntry( QColor(0xB2,0x68,0x18), 0, 0 ), // Green, Yellow
+ ColorEntry(QColor(0x18,0x18,0xB2), 0, 0 ), ColorEntry( QColor(0xB2,0x18,0xB2), 0, 0 ), // Blue, Magenta
+ ColorEntry(QColor(0x18,0xB2,0xB2), 0, 0 ), ColorEntry( QColor(0xB2,0xB2,0xB2), 0, 0 ), // Cyan, White
+ // intensiv
+ ColorEntry(QColor(0x00,0x00,0x00), 0, 1 ), ColorEntry( QColor(0xFF,0xFF,0xFF), 1, 0 ),
+ ColorEntry(QColor(0x68,0x68,0x68), 0, 0 ), ColorEntry( QColor(0xFF,0x54,0x54), 0, 0 ),
+ ColorEntry(QColor(0x54,0xFF,0x54), 0, 0 ), ColorEntry( QColor(0xFF,0xFF,0x54), 0, 0 ),
+ ColorEntry(QColor(0x54,0x54,0xFF), 0, 0 ), ColorEntry( QColor(0xFF,0x54,0xFF), 0, 0 ),
+ ColorEntry(QColor(0x54,0xFF,0xFF), 0, 0 ), ColorEntry( QColor(0xFF,0xFF,0xFF), 0, 0 )
+};
+
+/* Note that we use ANSI color order (bgr), while IBMPC color order is (rgb)
+
+ Code 0 1 2 3 4 5 6 7
+ ----------- ------- ------- ------- ------- ------- ------- ------- -------
+ ANSI (bgr) Black Red Green Yellow Blue Magenta Cyan White
+ IBMPC (rgb) Black Blue Green Cyan Red Magenta Yellow White
+*/
+
+QColor TEWidget::getDefaultBackColor()
+{
+ return color_table[DEFAULT_BACK_COLOR].color;
+}
+
+const ColorEntry* TEWidget::getColorTable() const
+{
+ return color_table;
+}
+
+const QPixmap *TEWidget::backgroundPixmap()
+{
+ static QPixmap *bg = new QPixmap("~/qpim/main/pics/faded_bg.xpm");
+ const QPixmap *pm = bg;
+ return pm;
+}
+
+void TEWidget::setColorTable(const ColorEntry table[])
+{
+ for (int i = 0; i < TABLE_COLORS; i++) color_table[i] = table[i];
+
+ const QPixmap* pm = backgroundPixmap();
+ if (!pm) setBackgroundColor(color_table[DEFAULT_BACK_COLOR].color);
+ update();
+}
+
+//FIXME: add backgroundPixmapChanged.
+
+/* ------------------------------------------------------------------------- */
+/* */
+/* Font */
+/* */
+/* ------------------------------------------------------------------------- */
+
+/*
+ The VT100 has 32 special graphical characters. The usual vt100 extended
+ xterm fonts have these at 0x00..0x1f.
+
+ QT's iso mapping leaves 0x00..0x7f without any changes. But the graphicals
+ come in here as proper unicode characters.
+
+ We treat non-iso10646 fonts as VT100 extended and do the requiered mapping
+ from unicode to 0x00..0x1f. The remaining translation is then left to the
+ QCodec.
+*/
+
+// assert for i in [0..31] : vt100extended(vt100_graphics[i]) == i.
+
+unsigned short vt100_graphics[32] =
+{ // 0/8 1/9 2/10 3/11 4/12 5/13 6/14 7/15
+ 0x0020, 0x25C6, 0x2592, 0x2409, 0x240c, 0x240d, 0x240a, 0x00b0,
+ 0x00b1, 0x2424, 0x240b, 0x2518, 0x2510, 0x250c, 0x2514, 0x253c,
+ 0xF800, 0xF801, 0x2500, 0xF803, 0xF804, 0x251c, 0x2524, 0x2534,
+ 0x252c, 0x2502, 0x2264, 0x2265, 0x03C0, 0x2260, 0x00A3, 0x00b7
+};
+
+static QChar vt100extended(QChar c)
+{
+ switch (c.unicode())
+ {
+ case 0x25c6 : return 1;
+ case 0x2592 : return 2;
+ case 0x2409 : return 3;
+ case 0x240c : return 4;
+ case 0x240d : return 5;
+ case 0x240a : return 6;
+ case 0x00b0 : return 7;
+ case 0x00b1 : return 8;
+ case 0x2424 : return 9;
+ case 0x240b : return 10;
+ case 0x2518 : return 11;
+ case 0x2510 : return 12;
+ case 0x250c : return 13;
+ case 0x2514 : return 14;
+ case 0x253c : return 15;
+ case 0xf800 : return 16;
+ case 0xf801 : return 17;
+ case 0x2500 : return 18;
+ case 0xf803 : return 19;
+ case 0xf804 : return 20;
+ case 0x251c : return 21;
+ case 0x2524 : return 22;
+ case 0x2534 : return 23;
+ case 0x252c : return 24;
+ case 0x2502 : return 25;
+ case 0x2264 : return 26;
+ case 0x2265 : return 27;
+ case 0x03c0 : return 28;
+ case 0x2260 : return 29;
+ case 0x00a3 : return 30;
+ case 0x00b7 : return 31;
+ }
+ return c;
+}
+
+static QChar identicalMap(QChar c)
+{
+ return c;
+}
+
+void TEWidget::fontChange(const QFont &)
+{
+ QFontMetrics fm(font());
+ font_h = fm.height();
+ font_w = fm.maxWidth();
+ font_a = fm.ascent();
+//printf("font_h: %d\n",font_h);
+//printf("font_w: %d\n",font_w);
+//printf("font_a: %d\n",font_a);
+//printf("charset: %s\n",QFont::encodingName(font().charSet()).ascii());
+//printf("rawname: %s\n",font().rawName().ascii());
+ fontMap =
+#if QT_VERSION < 300
+ strcmp(QFont::encodingName(font().charSet()).ascii(),"iso10646")
+ ? vt100extended
+ :
+#endif
+ identicalMap;
+ propagateSize();
+ update();
+}
+
+void TEWidget::setVTFont(const QFont& f)
+{
+ QFrame::setFont(f);
+}
+
+QFont TEWidget::getVTFont()
+{
+ return font();
+}
+
+void TEWidget::setFont(const QFont &)
+{
+ // ignore font change request if not coming from konsole itself
+}
+
+/* ------------------------------------------------------------------------- */
+/* */
+/* Constructor / Destructor */
+/* */
+/* ------------------------------------------------------------------------- */
+
+TEWidget::TEWidget(QWidget *parent, const char *name) : QFrame(parent,name)
+{
+#ifndef QT_NO_CLIPBOARD
+ cb = QApplication::clipboard();
+ QObject::connect( (QObject*)cb, SIGNAL(dataChanged()),
+ this, SLOT(onClearSelection()) );
+#endif
+
+ scrollbar = new QScrollBar(this);
+ scrollbar->setCursor( arrowCursor );
+ connect(scrollbar, SIGNAL(valueChanged(int)), this, SLOT(scrollChanged(int)));
+ scrollLoc = SCRNONE;
+
+ blinkT = new QTimer(this);
+ connect(blinkT, SIGNAL(timeout()), this, SLOT(blinkEvent()));
+ // blinking = FALSE;
+ blinking = TRUE;
+
+ resizing = FALSE;
+ actSel = 0;
+ image = 0;
+ lines = 1;
+ columns = 1;
+ font_w = 1;
+ font_h = 1;
+ font_a = 1;
+ word_selection_mode = FALSE;
+
+ setMouseMarks(TRUE);
+ setVTFont( QFont("fixed") );
+ setColorTable(base_color_table); // init color table
+
+ qApp->installEventFilter( this ); //FIXME: see below
+// KCursor::setAutoHideCursor( this, true );
+
+ // Init DnD ////////////////////////////////////////////////////////////////
+ currentSession = NULL;
+// setAcceptDrops(true); // attempt
+// m_drop = new QPopupMenu(this);
+// m_drop->insertItem( QString("Paste"), 0);
+// m_drop->insertItem( QString("cd"), 1);
+// connect(m_drop, SIGNAL(activated(int)), SLOT(drop_menu_activated(int)));
+
+ // we need focus so that the auto-hide cursor feature works
+ setFocus();
+ setFocusPolicy( WheelFocus );
+}
+
+//FIXME: make proper destructor
+// Here's a start (David)
+TEWidget::~TEWidget()
+{
+ qApp->removeEventFilter( this );
+ if (image) free(image);
+}
+
+/* ------------------------------------------------------------------------- */
+/* */
+/* Display Operations */
+/* */
+/* ------------------------------------------------------------------------- */
+
+/*!
+ attributed string draw primitive
+*/
+
+void TEWidget::drawAttrStr(QPainter &paint, QRect rect,
+ QString& str, ca attr, BOOL pm, BOOL clear)
+{
+ if (pm && color_table[attr.b].transparent)
+ {
+ paint.setBackgroundMode( TransparentMode );
+ if (clear) erase(rect);
+ }
+ else
+ {
+ if (blinking)
+ paint.fillRect(rect, color_table[attr.b].color);
+ else
+ {
+ paint.setBackgroundMode( OpaqueMode );
+ paint.setBackgroundColor( color_table[attr.b].color );
+ }
+ }
+
+ if (color_table[attr.f].bold)
+ paint.setPen(QColor( 0x8F, 0x00, 0x00 ));
+ else
+ paint.setPen(color_table[attr.f].color);
+
+ paint.drawText(rect.x(),rect.y()+font_a, str);
+
+ if (attr.r & RE_UNDERLINE)
+ paint.drawLine(rect.left(), rect.y()+font_a+1, rect.right(),rect.y()+font_a+1 );
+}
+
+/*!
+ The image can only be set completely.
+
+ The size of the new image may or may not match the size of the widget.
+*/
+
+void TEWidget::setImage(const ca* const newimg, int lines, int columns)
+{ int y,x,len;
+ const QPixmap* pm = backgroundPixmap();
+ QPainter paint;
+ setUpdatesEnabled(FALSE);
+ paint.begin( this );
+HCNT("setImage");
+
+ QPoint tL = contentsRect().topLeft();
+ int tLx = tL.x();
+ int tLy = tL.y();
+ hasBlinker = FALSE;
+
+ int cf = -1; // undefined
+ int cb = -1; // undefined
+ int cr = -1; // undefined
+
+ int lins = QMIN(this->lines, QMAX(0,lines ));
+ int cols = QMIN(this->columns,QMAX(0,columns));
+ QChar *disstrU = new QChar[cols];
+
+//{ static int cnt = 0; printf("setImage %d\n",cnt++); }
+ for (y = 0; y < lins; y++)
+ {
+ const ca* lcl = &image[y*this->columns];
+ const ca* const ext = &newimg[y*columns];
+ if (!resizing) // not while resizing, we're expecting a paintEvent
+ for (x = 0; x < cols; x++)
+ {
+ hasBlinker |= (ext[x].r & RE_BLINK);
+ if (ext[x] != lcl[x])
+ {
+ cr = ext[x].r;
+ cb = ext[x].b;
+ if (ext[x].f != cf) cf = ext[x].f;
+ int lln = cols - x;
+ disstrU[0] = fontMap(ext[x+0].c);
+ for (len = 1; len < lln; len++)
+ {
+ if (ext[x+len].f != cf || ext[x+len].b != cb || ext[x+len].r != cr ||
+ ext[x+len] == lcl[x+len] )
+ break;
+ disstrU[len] = fontMap(ext[x+len].c);
+ }
+ QString unistr(disstrU,len);
+ drawAttrStr(paint,
+ QRect(blX+tLx+font_w*x,bY+tLy+font_h*y,font_w*len,font_h),
+ unistr, ext[x], pm != NULL, true);
+ x += len - 1;
+ }
+ }
+ // finally, make `image' become `newimg'.
+ memcpy((void*)lcl,(const void*)ext,cols*sizeof(ca));
+ }
+ drawFrame( &paint );
+ paint.end();
+ setUpdatesEnabled(TRUE);
+ if ( hasBlinker && !blinkT->isActive()) blinkT->start(1000); // 1000 ms
+ if (!hasBlinker && blinkT->isActive()) { blinkT->stop(); blinking = FALSE; }
+ delete [] disstrU;
+}
+
+// paint Event ////////////////////////////////////////////////////
+
+/*!
+ The difference of this routine vs. the `setImage' is,
+ that the drawing does not include a difference analysis
+ between the old and the new image. Instead, the internal
+ image is used and the painting bound by the PaintEvent box.
+*/
+
+void TEWidget::paintEvent( QPaintEvent* pe )
+{
+
+//{ static int cnt = 0; printf("paint %d\n",cnt++); }
+ const QPixmap* pm = backgroundPixmap();
+ QPainter paint;
+ setUpdatesEnabled(FALSE);
+ paint.begin( this );
+ paint.setBackgroundMode( TransparentMode );
+HCNT("paintEvent");
+
+ // Note that the actual widget size can be slightly larger
+ // that the image (the size is truncated towards the smaller
+ // number of characters in `resizeEvent'. The paint rectangle
+ // can thus be larger than the image, but less then the size
+ // of one character.
+
+ QRect rect = pe->rect().intersect(contentsRect());
+
+ QPoint tL = contentsRect().topLeft();
+ int tLx = tL.x();
+ int tLy = tL.y();
+
+ int lux = QMIN(columns-1, QMAX(0,(rect.left() - tLx - blX ) / font_w));
+ int luy = QMIN(lines-1, QMAX(0,(rect.top() - tLy - bY ) / font_h));
+ int rlx = QMIN(columns-1, QMAX(0,(rect.right() - tLx - blX ) / font_w));
+ int rly = QMIN(lines-1, QMAX(0,(rect.bottom() - tLy - bY ) / font_h));
+
+ /*
+ printf("paintEvent: %d..%d, %d..%d (%d..%d, %d..%d)\n",lux,rlx,luy,rly,
+ rect.left(), rect.right(), rect.top(), rect.bottom());
+ */
+
+ // if (pm != NULL && color_table[image->b].transparent)
+ // erase(rect);
+ // BL: I have no idea why we need this, and it breaks the refresh.
+
+ QChar *disstrU = new QChar[columns];
+ for (int y = luy; y <= rly; y++)
+ for (int x = lux; x <= rlx; x++)
+ {
+ int len = 1;
+ disstrU[0] = fontMap(image[loc(x,y)].c);
+ int cf = image[loc(x,y)].f;
+ int cb = image[loc(x,y)].b;
+ int cr = image[loc(x,y)].r;
+ while (x+len <= rlx &&
+ image[loc(x+len,y)].f == cf &&
+ image[loc(x+len,y)].b == cb &&
+ image[loc(x+len,y)].r == cr )
+ {
+ disstrU[len] = fontMap(image[loc(x+len,y)].c);
+ len += 1;
+ }
+ QString unistr(disstrU,len);
+ drawAttrStr(paint,
+ QRect(blX+tLx+font_w*x,bY+tLy+font_h*y,font_w*len,font_h),
+ unistr, image[loc(x,y)], pm != NULL, false);
+ x += len - 1;
+ }
+ delete [] disstrU;
+ drawFrame( &paint );
+ paint.end();
+ setUpdatesEnabled(TRUE);
+}
+
+void TEWidget::blinkEvent()
+{
+ blinking = !blinking;
+ repaint(FALSE);
+}
+
+/* ------------------------------------------------------------------------- */
+/* */
+/* Resizing */
+/* */
+/* ------------------------------------------------------------------------- */
+
+void TEWidget::resizeEvent(QResizeEvent* ev)
+{
+ //printf("resize: %d,%d\n",ev->size().width(),ev->size().height());
+ //printf("approx: %d,%d\n",ev->size().width()/font_w,ev->size().height()/font_h);
+ //printf("leaves: %d,%d\n",ev->size().width()%font_w,ev->size().height()%font_h);
+ //printf("curren: %d,%d\n",width(),height());
+HCNT("resizeEvent");
+
+ // see comment in `paintEvent' concerning the rounding.
+ //FIXME: could make a routine here; check width(),height()
+ assert(ev->size().width() == width());
+ assert(ev->size().height() == height());
+
+ propagateSize();
+}
+
+void TEWidget::propagateSize()
+{
+ ca* oldimg = image;
+ int oldlin = lines;
+ int oldcol = columns;
+ makeImage();
+ // we copy the old image to reduce flicker
+ int lins = QMIN(oldlin,lines);
+ int cols = QMIN(oldcol,columns);
+ if (oldimg)
+ {
+ for (int lin = 0; lin < lins; lin++)
+ memcpy((void*)&image[columns*lin],
+ (void*)&oldimg[oldcol*lin],cols*sizeof(ca));
+ free(oldimg); //FIXME: try new,delete
+ }
+ else
+ clearImage();
+
+ //NOTE: control flows from the back through the chest right into the eye.
+ // `emu' will call back via `setImage'.
+
+ resizing = TRUE;
+ emit changedImageSizeSignal(lines, columns); // expose resizeEvent
+ resizing = FALSE;
+}
+
+/* ------------------------------------------------------------------------- */
+/* */
+/* Scrollbar */
+/* */
+/* ------------------------------------------------------------------------- */
+
+void TEWidget::scrollChanged(int)
+{
+ emit changedHistoryCursor(scrollbar->value()); //expose
+}
+
+void TEWidget::setScroll(int cursor, int slines)
+{
+ disconnect(scrollbar, SIGNAL(valueChanged(int)), this, SLOT(scrollChanged(int)));
+ scrollbar->setRange(0,slines);
+ scrollbar->setSteps(1,lines);
+ scrollbar->setValue(cursor);
+ connect(scrollbar, SIGNAL(valueChanged(int)), this, SLOT(scrollChanged(int)));
+}
+
+void TEWidget::setScrollbarLocation(int loc)
+{
+ if (scrollLoc == loc) return; // quickly
+ scrollLoc = loc;
+ propagateSize();
+ update();
+}
+
+/* ------------------------------------------------------------------------- */
+/* */
+/* Mouse */
+/* */
+/* ------------------------------------------------------------------------- */
+
+/*!
+ Three different operations can be performed using the mouse, and the
+ routines in this section serve all of them:
+
+ 1) The press/release events are exposed to the application
+ 2) Marking (press and move left button) and Pasting (press middle button)
+ 3) The right mouse button is used from the configuration menu
+
+ NOTE: During the marking process we attempt to keep the cursor within
+ the bounds of the text as being displayed by setting the mouse position
+ whenever the mouse has left the text area.
+
+ Two reasons to do so:
+ 1) QT does not allow the `grabMouse' to confine-to the TEWidget.
+ Thus a `XGrapPointer' would have to be used instead.
+ 2) Even if so, this would not help too much, since the text area
+ of the TEWidget is normally not identical with it's bounds.
+
+ The disadvantage of the current handling is, that the mouse can visibly
+ leave the bounds of the widget and is then moved back. Because of the
+ current construction, and the reasons mentioned above, we cannot do better
+ without changing the overall construction.
+*/
+
+/*!
+*/
+
+void TEWidget::mousePressEvent(QMouseEvent* ev)
+{
+//printf("press [%d,%d] %d\n",ev->x()/font_w,ev->y()/font_h,ev->button());
+ if ( !contentsRect().contains(ev->pos()) ) return;
+ QPoint tL = contentsRect().topLeft();
+ int tLx = tL.x();
+ int tLy = tL.y();
+
+ word_selection_mode = FALSE;
+
+//printf("press top left [%d,%d] by=%d\n",tLx,tLy, bY);
+ if ( ev->button() == LeftButton)
+ {
+ QPoint pos = QPoint((ev->x()-tLx-blX)/font_w,(ev->y()-tLy-bY)/font_h);
+
+ if ( ev->state() & ControlButton ) preserve_line_breaks = FALSE ;
+
+ if (mouse_marks || (ev->state() & ShiftButton))
+ {
+ emit clearSelectionSignal();
+ iPntSel = pntSel = pos;
+ actSel = 1; // left mouse button pressed but nothing selected yet.
+ grabMouse( /*crossCursor*/ ); // handle with care!
+ }
+ else
+ {
+ emit mouseSignal( 0, pos.x() + 1, pos.y() + 1 ); // left button
+ }
+ }
+ if ( ev->button() == MidButton )
+ {
+ emitSelection();
+ }
+ if ( ev->button() == RightButton ) // Configure
+ {
+ emit configureRequest( this, ev->state()&(ShiftButton|ControlButton), ev->x(), ev->y() );
+ }
+}
+
+void TEWidget::mouseMoveEvent(QMouseEvent* ev)
+{
+ // for auto-hiding the cursor, we need mouseTracking
+ if (ev->state() == NoButton ) return;
+
+ if (actSel == 0) return;
+
+ // don't extend selection while pasting
+ if (ev->state() & MidButton) return;
+
+ //if ( !contentsRect().contains(ev->pos()) ) return;
+ QPoint tL = contentsRect().topLeft();
+ int tLx = tL.x();
+ int tLy = tL.y();
+ int scroll = scrollbar->value();
+
+ // we're in the process of moving the mouse with the left button pressed
+ // the mouse cursor will kept catched within the bounds of the text in
+ // this widget.
+
+ // Adjust position within text area bounds. See FIXME above.
+ QPoint pos = ev->pos();
+ if ( pos.x() < tLx+blX ) pos.setX( tLx+blX );
+ if ( pos.x() > tLx+blX+columns*font_w-1 ) pos.setX( tLx+blX+columns*font_w );
+ if ( pos.y() < tLy+bY ) pos.setY( tLy+bY );
+ if ( pos.y() > tLy+bY+lines*font_h-1 ) pos.setY( tLy+bY+lines*font_h-1 );
+ // check if we produce a mouse move event by this
+ if ( pos != ev->pos() ) cursor().setPos(mapToGlobal(pos));
+
+ if ( pos.y() == tLy+bY+lines*font_h-1 )
+ {
+ scrollbar->setValue(scrollbar->value()+yMouseScroll); // scrollforward
+ }
+ if ( pos.y() == tLy+bY )
+ {
+ scrollbar->setValue(scrollbar->value()-yMouseScroll); // scrollback
+ }
+
+ QPoint here = QPoint((pos.x()-tLx-blX)/font_w,(pos.y()-tLy-bY)/font_h);
+ QPoint ohere;
+ bool swapping = FALSE;
+
+ if ( word_selection_mode )
+ {
+ // Extend to word boundaries
+ int i;
+ int selClass;
+
+ bool left_not_right = ( here.y() < iPntSel.y() ||
+ here.y() == iPntSel.y() && here.x() < iPntSel.x() );
+ bool old_left_not_right = ( pntSel.y() < iPntSel.y() ||
+ pntSel.y() == iPntSel.y() && pntSel.x() < iPntSel.x() );
+ swapping = left_not_right != old_left_not_right;
+
+ // Find left (left_not_right ? from here : from start)
+ QPoint left = left_not_right ? here : iPntSel;
+ i = loc(left.x(),left.y());
+ selClass = charClass(image[i].c);
+ while ( left.x() > 0 && charClass(image[i-1].c) == selClass )
+ { i--; left.rx()--; }
+
+ // Find left (left_not_right ? from start : from here)
+ QPoint right = left_not_right ? iPntSel : here;
+ i = loc(right.x(),right.y());
+ selClass = charClass(image[i].c);
+ while ( right.x() < columns-1 && charClass(image[i+1].c) == selClass )
+ { i++; right.rx()++; }
+
+ // Pick which is start (ohere) and which is extension (here)
+ if ( left_not_right )
+ {
+ here = left; ohere = right;
+ }
+ else
+ {
+ here = right; ohere = left;
+ }
+ }
+
+ if (here == pntSel && scroll == scrollbar->value()) return; // not moved
+
+ if ( word_selection_mode ) {
+ if ( actSel < 2 || swapping ) {
+ emit beginSelectionSignal( ohere.x(), ohere.y() );
+ }
+ } else if ( actSel < 2 ) {
+ emit beginSelectionSignal( pntSel.x(), pntSel.y() );
+ }
+
+ actSel = 2; // within selection
+ pntSel = here;
+ emit extendSelectionSignal( here.x(), here.y() );
+}
+
+void TEWidget::mouseReleaseEvent(QMouseEvent* ev)
+{
+//printf("release [%d,%d] %d\n",ev->x()/font_w,ev->y()/font_h,ev->button());
+ if ( ev->button() == LeftButton)
+ {
+ if ( actSel > 1 ) emit endSelectionSignal(preserve_line_breaks);
+ preserve_line_breaks = TRUE;
+ actSel = 0;
+
+ //FIXME: emits a release event even if the mouse is
+ // outside the range. The procedure used in `mouseMoveEvent'
+ // applies here, too.
+
+ QPoint tL = contentsRect().topLeft();
+ int tLx = tL.x();
+ int tLy = tL.y();
+
+ if (!mouse_marks && !(ev->state() & ShiftButton))
+ emit mouseSignal( 3, // release
+ (ev->x()-tLx-blX)/font_w + 1,
+ (ev->y()-tLy-bY)/font_h + 1 );
+ releaseMouse();
+ }
+}
+
+void TEWidget::mouseDoubleClickEvent(QMouseEvent* ev)
+{
+ if ( ev->button() != LeftButton) return;
+
+ QPoint tL = contentsRect().topLeft();
+ int tLx = tL.x();
+ int tLy = tL.y();
+ QPoint pos = QPoint((ev->x()-tLx-blX)/font_w,(ev->y()-tLy-bY)/font_h);
+
+ // pass on double click as two clicks.
+ if (!mouse_marks && !(ev->state() & ShiftButton))
+ {
+ emit mouseSignal( 0, pos.x()+1, pos.y()+1 ); // left button
+ emit mouseSignal( 3, pos.x()+1, pos.y()+1 ); // release
+ emit mouseSignal( 0, pos.x()+1, pos.y()+1 ); // left button
+ return;
+ }
+
+
+ emit clearSelectionSignal();
+ QPoint bgnSel = pos;
+ QPoint endSel = QPoint((ev->x()-tLx-blX)/font_w,(ev->y()-tLy-bY)/font_h);
+ int i = loc(bgnSel.x(),bgnSel.y());
+ iPntSel = bgnSel;
+
+ word_selection_mode = TRUE;
+
+ // find word boundaries...
+ int selClass = charClass(image[i].c);
+ {
+ // set the start...
+ int x = bgnSel.x();
+ while ( x > 0 && charClass(image[i-1].c) == selClass )
+ { i--; x--; }
+ bgnSel.setX(x);
+ emit beginSelectionSignal( bgnSel.x(), bgnSel.y() );
+
+ // set the end...
+ i = loc( endSel.x(), endSel.y() );
+ x = endSel.x();
+ while( x < columns-1 && charClass(image[i+1].c) == selClass )
+ { i++; x++ ; }
+ endSel.setX(x);
+ actSel = 2; // within selection
+ emit extendSelectionSignal( endSel.x(), endSel.y() );
+ emit endSelectionSignal(preserve_line_breaks);
+ preserve_line_breaks = TRUE;
+ }
+}
+
+void TEWidget::focusInEvent( QFocusEvent * )
+{
+ // do nothing, to prevent repainting
+}
+
+
+void TEWidget::focusOutEvent( QFocusEvent * )
+{
+ // do nothing, to prevent repainting
+}
+
+bool TEWidget::focusNextPrevChild( bool next )
+{
+ if (next)
+ return false; // This disables changing the active part in konqueror
+ // when pressing Tab
+ return QFrame::focusNextPrevChild( next );
+}
+
+
+int TEWidget::charClass(char ch) const
+{
+ // This might seem like overkill, but imagine if ch was a Unicode
+ // character (Qt 2.0 QChar) - it might then be sensible to separate
+ // the different language ranges, etc.
+
+ if ( isspace(ch) ) return ' ';
+
+ static const char *word_characters = ":@-./_~";
+ if ( isalnum(ch) || strchr(word_characters, ch) )
+ return 'a';
+
+ // Everything else is weird
+ return 1;
+}
+
+void TEWidget::setMouseMarks(bool on)
+{
+ mouse_marks = on;
+ setCursor( mouse_marks ? ibeamCursor : arrowCursor );
+}
+
+/* ------------------------------------------------------------------------- */
+/* */
+/* Clipboard */
+/* */
+/* ------------------------------------------------------------------------- */
+
+#undef KeyPress
+
+void TEWidget::emitSelection()
+// Paste Clipboard by simulating keypress events
+{
+#ifndef QT_NO_CLIPBOARD
+ QString text = QApplication::clipboard()->text();
+ if ( ! text.isNull() )
+ {
+ text.replace(QRegExp("\n"), "\r");
+ QKeyEvent e(QEvent::KeyPress, 0, -1, 0, text);
+ emit keyPressedSignal(&e); // expose as a big fat keypress event
+ emit clearSelectionSignal();
+ }
+#endif
+}
+
+void TEWidget::emitText(QString text)
+{
+ QKeyEvent e(QEvent::KeyPress, 0, -1, 0, text);
+ emit keyPressedSignal(&e); // expose as a big fat keypress event
+}
+
+void TEWidget::pasteClipboard( )
+{
+ emitSelection();
+}
+
+void TEWidget::setSelection(const QString& t)
+{
+#ifndef QT_NO_CLIPBOARD
+ // Disconnect signal while WE set the clipboard
+ QObject *cb = QApplication::clipboard();
+ QObject::disconnect( cb, SIGNAL(dataChanged()),
+ this, SLOT(onClearSelection()) );
+
+ QApplication::clipboard()->setText(t);
+
+ QObject::connect( cb, SIGNAL(dataChanged()),
+ this, SLOT(onClearSelection()) );
+#endif
+}
+
+void TEWidget::onClearSelection()
+{
+ emit clearSelectionSignal();
+}
+
+/* ------------------------------------------------------------------------- */
+/* */
+/* Keyboard */
+/* */
+/* ------------------------------------------------------------------------- */
+
+//FIXME: an `eventFilter' has been installed instead of a `keyPressEvent'
+// due to a bug in `QT' or the ignorance of the author to prevent
+// repaint events being emitted to the screen whenever one leaves
+// or reenters the screen to/from another application.
+//
+// Troll says one needs to change focusInEvent() and focusOutEvent(),
+// which would also let you have an in-focus cursor and an out-focus
+// cursor like xterm does.
+
+// for the auto-hide cursor feature, I added empty focusInEvent() and
+// focusOutEvent() so that update() isn't called.
+// For auto-hide, we need to get keypress-events, but we only get them when
+// we have focus.
+
+void TEWidget::doScroll(int lines)
+{
+ scrollbar->setValue(scrollbar->value()+lines);
+}
+
+bool TEWidget::eventFilter( QObject *obj, QEvent *e )
+{
+ if ( (e->type() == QEvent::Accel ||
+ e->type() == QEvent::AccelAvailable ) && qApp->focusWidget() == this )
+ {
+ static_cast<QKeyEvent *>( e )->ignore();
+ return true;
+ }
+ if ( obj != this /* when embedded */ && obj != parent() /* when standalone */ )
+ return FALSE; // not us
+ if ( e->type() == QEvent::Wheel)
+ {
+ QApplication::sendEvent(scrollbar, e);
+ }
+
+#ifdef FAKE_CTRL_AND_ALT
+ static bool control = FALSE;
+ static bool alt = FALSE;
+ // Has a keyboard with no CTRL and ALT keys, but we fake it:
+ bool dele=FALSE;
+ if ( e->type() == QEvent::KeyPress || e->type() == QEvent::KeyRelease ) {
+ QKeyEvent* ke = (QKeyEvent*)e;
+ bool keydown = e->type() == QEvent::KeyPress || ke->isAutoRepeat();
+ switch (ke->key()) {
+ case Key_F9: // let this be "Control"
+ control = keydown;
+ e = new QKeyEvent(QEvent::KeyPress, Key_Control, 0, ke->state());
+ dele=TRUE;
+ break;
+ case Key_F13: // let this be "Alt"
+ alt = keydown;
+ e = new QKeyEvent(QEvent::KeyPress, Key_Alt, 0, ke->state());
+ dele=TRUE;
+ break;
+ default:
+ if ( control ) {
+ int a = toupper(ke->ascii())-64;
+ if ( a >= 0 && a < ' ' ) {
+ e = new QKeyEvent(e->type(), ke->key(),
+ a, ke->state()|ControlButton, QChar(a,0));
+ dele=TRUE;
+ }
+ }
+ if ( alt ) {
+ e = new QKeyEvent(e->type(), ke->key(),
+ ke->ascii(), ke->state()|AltButton, ke->text());
+ dele=TRUE;
+ }
+ }
+ }
+#endif
+
+ if ( e->type() == QEvent::KeyPress )
+ {
+ QKeyEvent* ke = (QKeyEvent*)e;
+
+ actSel=0; // Key stroke implies a screen update, so TEWidget won't
+ // know where the current selection is.
+
+ emit keyPressedSignal(ke); // expose
+ ke->accept();
+#ifdef FAKE_CTRL_AND_ALT
+ if ( dele ) delete e;
+#endif
+ return true; // stop the event
+ }
+ if ( e->type() == QEvent::Enter )
+ {
+ QObject::disconnect( (QObject*)cb, SIGNAL(dataChanged()),
+ this, SLOT(onClearSelection()) );
+ }
+ if ( e->type() == QEvent::Leave )
+ {
+ QObject::connect( (QObject*)cb, SIGNAL(dataChanged()),
+ this, SLOT(onClearSelection()) );
+ }
+ return QFrame::eventFilter( obj, e );
+}
+
+/* ------------------------------------------------------------------------- */
+/* */
+/* Frame */
+/* */
+/* ------------------------------------------------------------------------- */
+
+void TEWidget::frameChanged()
+{
+ propagateSize();
+ update();
+}
+
+/* ------------------------------------------------------------------------- */
+/* */
+/* Sound */
+/* */
+/* ------------------------------------------------------------------------- */
+
+void TEWidget::Bell()
+{
+ QApplication::beep();
+}
+
+/* ------------------------------------------------------------------------- */
+/* */
+/* Auxiluary */
+/* */
+/* ------------------------------------------------------------------------- */
+
+void TEWidget::clearImage()
+// initialize the image
+// for internal use only
+{
+ for (int y = 0; y < lines; y++)
+ for (int x = 0; x < columns; x++)
+ {
+ image[loc(x,y)].c = 0xff; //' ';
+ image[loc(x,y)].f = 0xff; //DEFAULT_FORE_COLOR;
+ image[loc(x,y)].b = 0xff; //DEFAULT_BACK_COLOR;
+ image[loc(x,y)].r = 0xff; //DEFAULT_RENDITION;
+ }
+}
+
+// Create Image ///////////////////////////////////////////////////////
+
+void TEWidget::calcGeometry()
+{
+ //FIXME: set rimX == rimY == 0 when running in full screen mode.
+
+ scrollbar->resize(QApplication::style().scrollBarExtent().width(),
+ contentsRect().height());
+ switch(scrollLoc)
+ {
+ case SCRNONE :
+ columns = ( contentsRect().width() - 2 * rimX ) / font_w;
+ blX = (contentsRect().width() - (columns*font_w) ) / 2;
+ brX = blX;
+ scrollbar->hide();
+ break;
+ case SCRLEFT :
+ columns = ( contentsRect().width() - 2 * rimX - scrollbar->width()) / font_w;
+ brX = (contentsRect().width() - (columns*font_w) - scrollbar->width() ) / 2;
+ blX = brX + scrollbar->width();
+ scrollbar->move(contentsRect().topLeft());
+ scrollbar->show();
+ break;
+ case SCRRIGHT:
+ columns = ( contentsRect().width() - 2 * rimX - scrollbar->width()) / font_w;
+ blX = (contentsRect().width() - (columns*font_w) - scrollbar->width() ) / 2;
+ brX = blX;
+ scrollbar->move(contentsRect().topRight() - QPoint(scrollbar->width()-1,0));
+ scrollbar->show();
+ break;
+ }
+ //FIXME: support 'rounding' styles
+ lines = ( contentsRect().height() - 2 * rimY ) / font_h;
+ bY = (contentsRect().height() - (lines *font_h)) / 2;
+}
+
+void TEWidget::makeImage()
+//FIXME: rename 'calcGeometry?
+{
+ calcGeometry();
+ image = (ca*) malloc(lines*columns*sizeof(ca));
+ clearImage();
+}
+
+// calculate the needed size
+QSize TEWidget::calcSize(int cols, int lins) const
+{
+ int frw = width() - contentsRect().width();
+ int frh = height() - contentsRect().height();
+ int scw = (scrollLoc==SCRNONE?0:scrollbar->width());
+ return QSize( font_w*cols + 2*rimX + frw + scw, font_h*lins + 2*rimY + frh );
+}
+
+QSize TEWidget::sizeHint() const
+{
+ return size();
+}
+
+void TEWidget::styleChange(QStyle &)
+{
+ propagateSize();
+}
+
+#ifndef QT_NO_DRAGANDDROP
+
+/* --------------------------------------------------------------------- */
+/* */
+/* Drag & Drop */
+/* */
+/* --------------------------------------------------------------------- */
+
+
+void TEWidget::dragEnterEvent(QDragEnterEvent* e)
+{
+ e->accept(QTextDrag::canDecode(e) ||
+ QUriDrag::canDecode(e));
+}
+
+void TEWidget::dropEvent(QDropEvent* event)
+{
+ // The current behaviour when url(s) are dropped is
+ // * if there is only ONE url and if it's a LOCAL one, ask for paste or cd
+ // * in all other cases, just paste
+ // (for non-local ones, or for a list of URLs, 'cd' is nonsense)
+ QStrList strlist;
+ int file_count = 0;
+ dropText = "";
+ bool bPopup = true;
+
+ if(QUriDrag::decode(event, strlist)) {
+ if (strlist.count()) {
+ for(const char* p = strlist.first(); p; p = strlist.next()) {
+ if(file_count++ > 0) {
+ dropText += " ";
+ bPopup = false; // more than one file, don't popup
+ }
+
+/*
+ KURL url(p);
+ if (url.isLocalFile()) {
+ dropText += url.path(); // local URL : remove protocol
+ }
+ else {
+ dropText += url.prettyURL();
+ bPopup = false; // a non-local file, don't popup
+ }
+*/
+
+ }
+
+ if (bPopup)
+ // m_drop->popup(pos() + event->pos());
+ m_drop->popup(mapToGlobal(event->pos()));
+ else
+ {
+ if (currentSession) {
+ currentSession->getEmulation()->sendString(dropText.local8Bit());
+ }
+// kdDebug() << "Drop:" << dropText.local8Bit() << "\n";
+ }
+ }
+ }
+ else if(QTextDrag::decode(event, dropText)) {
+// kdDebug() << "Drop:" << dropText.local8Bit() << "\n";
+ if (currentSession) {
+ currentSession->getEmulation()->sendString(dropText.local8Bit());
+ }
+ // Paste it
+ }
+}
+#endif
+
+
+void TEWidget::drop_menu_activated(int item)
+{
+#ifndef QT_NO_DRAGANDDROP
+ switch (item)
+ {
+ case 0: // paste
+ currentSession->getEmulation()->sendString(dropText.local8Bit());
+// KWM::activate((Window)this->winId());
+ break;
+ case 1: // cd ...
+ currentSession->getEmulation()->sendString("cd ");
+ struct stat statbuf;
+ if ( ::stat( QFile::encodeName( dropText ), &statbuf ) == 0 )
+ {
+ if ( !S_ISDIR(statbuf.st_mode) )
+ {
+/*
+ KURL url;
+ url.setPath( dropText );
+ dropText = url.directory( true, false ); // remove filename
+*/
+ }
+ }
+ dropText.replace(QRegExp(" "), "\\ "); // escape spaces
+ currentSession->getEmulation()->sendString(dropText.local8Bit());
+ currentSession->getEmulation()->sendString("\n");
+// KWM::activate((Window)this->winId());
+ break;
+ }
+#endif
+}
+
diff --git a/core/apps/embeddedkonsole/TEWidget.h b/core/apps/embeddedkonsole/TEWidget.h
new file mode 100644
index 0000000..3f9f4ae
--- a/dev/null
+++ b/core/apps/embeddedkonsole/TEWidget.h
@@ -0,0 +1,202 @@
+/* ----------------------------------------------------------------------- */
+/* */
+/* [te_widget.h] Terminal Emulation Widget */
+/* */
+/* ----------------------------------------------------------------------- */
+/* */
+/* 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> */
+/* */
+/* -------------------------------------------------------------------------- */
+
+#ifndef TE_WIDGET_H
+#define TE_WIDGET_H
+
+#include <qwidget.h>
+#include <qlabel.h>
+#include <qtimer.h>
+#include <qcolor.h>
+#include <qkeycode.h>
+#include <qscrollbar.h>
+
+#include <qpopupmenu.h>
+
+#include "TECommon.h"
+
+extern unsigned short vt100_graphics[32];
+
+class TESession;
+
+// class Konsole;
+
+class TEWidget : public QFrame
+// a widget representing attributed text
+{ Q_OBJECT
+
+// friend class Konsole;
+
+public:
+
+ TEWidget(QWidget *parent=0, const char *name=0);
+ virtual ~TEWidget();
+
+public:
+
+ QColor getDefaultBackColor();
+
+ const ColorEntry* getColorTable() const;
+ void setColorTable(const ColorEntry table[]);
+
+ void setScrollbarLocation(int loc);
+ enum { SCRNONE=0, SCRLEFT=1, SCRRIGHT=2 };
+
+ void setScroll(int cursor, int lines);
+ void doScroll(int lines);
+
+ void emitSelection();
+
+public:
+
+ void setImage(const ca* const newimg, int lines, int columns);
+
+ int Lines() { return lines; }
+ int Columns() { return columns; }
+
+ void calcGeometry();
+ void propagateSize();
+ QSize calcSize(int cols, int lins) const;
+
+ QSize sizeHint() const;
+
+public:
+
+ void Bell();
+ void emitText(QString text);
+ void pasteClipboard();
+
+signals:
+
+ void keyPressedSignal(QKeyEvent *e);
+ void mouseSignal(int cb, int cx, int cy);
+ void changedImageSizeSignal(int lines, int columns);
+ void changedHistoryCursor(int value);
+ void configureRequest( TEWidget*, int state, int x, int y );
+
+ void clearSelectionSignal();
+ void beginSelectionSignal( const int x, const int y );
+ void extendSelectionSignal( const int x, const int y );
+ void endSelectionSignal(const BOOL preserve_line_breaks);
+
+
+protected:
+
+ virtual void styleChange( QStyle& );
+
+ bool eventFilter( QObject *, QEvent * );
+
+ void drawAttrStr(QPainter &paint, QRect rect,
+ QString& str, ca attr, BOOL pm, BOOL clear);
+ void paintEvent( QPaintEvent * );
+
+ void resizeEvent(QResizeEvent*);
+
+ void fontChange(const QFont &font);
+ void frameChanged();
+
+ void mouseDoubleClickEvent(QMouseEvent* ev);
+ void mousePressEvent( QMouseEvent* );
+ void mouseReleaseEvent( QMouseEvent* );
+ void mouseMoveEvent( QMouseEvent* );
+
+ void focusInEvent( QFocusEvent * );
+ void focusOutEvent( QFocusEvent * );
+ bool focusNextPrevChild( bool next );
+
+#ifndef QT_NO_DRAGANDDROP
+ // Dnd
+ void dragEnterEvent(QDragEnterEvent* event);
+ void dropEvent(QDropEvent* event);
+#endif
+
+ virtual int charClass(char) const;
+
+ void clearImage();
+
+public:
+ const QPixmap *backgroundPixmap();
+
+ void setSelection(const QString &t);
+
+ virtual void setFont(const QFont &);
+ void setVTFont(const QFont &);
+ QFont getVTFont();
+
+ void setMouseMarks(bool on);
+
+public slots:
+
+ void onClearSelection();
+
+protected slots:
+
+ void scrollChanged(int value);
+ void blinkEvent();
+
+private:
+
+ QChar (*fontMap)(QChar); // possible vt100 font extention
+
+ bool fixed_font; // has fixed pitch
+ int font_h; // height
+ int font_w; // width
+ int font_a; // ascend
+
+ int blX; // actual offset (left)
+ int brX; // actual offset (right)
+ int bY; // actual offset
+
+ int lines;
+ int columns;
+ ca *image; // [lines][columns]
+
+ ColorEntry color_table[TABLE_COLORS];
+
+ BOOL resizing;
+ bool mouse_marks;
+
+ void makeImage();
+
+ QPoint iPntSel; // initial selection point
+ QPoint pntSel; // current selection point
+ int actSel; // selection state
+ BOOL word_selection_mode;
+ BOOL preserve_line_breaks;
+
+ QClipboard* cb;
+ QScrollBar* scrollbar;
+ int scrollLoc;
+
+//#define SCRNONE 0
+//#define SCRLEFT 1
+//#define SCRRIGHT 2
+
+ BOOL blinking; // hide text in paintEvent
+ BOOL hasBlinker; // has characters to blink
+ QTimer* blinkT; // active when hasBlinker
+ QPopupMenu* m_drop;
+ QString dropText;
+ public:
+ // current session in this widget
+ TESession *currentSession;
+private slots:
+ void drop_menu_activated(int item);
+};
+
+#endif // TE_WIDGET_H
diff --git a/core/apps/embeddedkonsole/TEmuVt102.cpp b/core/apps/embeddedkonsole/TEmuVt102.cpp
new file mode 100644
index 0000000..752c49f
--- a/dev/null
+++ b/core/apps/embeddedkonsole/TEmuVt102.cpp
@@ -0,0 +1,991 @@
+/* ------------------------------------------------------------------------- */
+/* */
+/* [TEmuVt102.C] VT102 Terminal Emulation */
+/* */
+/* ------------------------------------------------------------------------- */
+/* */
+/* 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 TEmuVt102
+
+ \brief Actual Emulation for Konsole
+
+ \sa TEWidget \sa TEScreen
+*/
+
+#include "TEmuVt102.h"
+#include "TEWidget.h"
+#include "TEScreen.h"
+#include "keytrans.h"
+
+#include <stdio.h>
+#include <unistd.h>
+#include <qkeycode.h>
+#include <qtextcodec.h>
+
+
+/* VT102 Terminal Emulation
+
+ This class puts together the screens, the pty and the widget to a
+ complete terminal emulation. Beside combining it's componentes, it
+ handles the emulations's protocol.
+
+ This module consists of the following sections:
+
+ - Constructor/Destructor
+ - Incoming Bytes Event pipeline
+ - Outgoing Bytes
+ - Mouse Events
+ - Keyboard Events
+ - Modes and Charset State
+ - Diagnostics
+*/
+
+
+/* ------------------------------------------------------------------------- */
+/* */
+/* Constructor / Destructor */
+/* */
+/* ------------------------------------------------------------------------- */
+
+/*
+ Nothing really intesting happens here.
+*/
+
+/*!
+*/
+
+TEmuVt102::TEmuVt102(TEWidget* gui) : TEmulation(gui)
+{
+ QObject::connect(gui,SIGNAL(mouseSignal(int,int,int)),
+ this,SLOT(onMouse(int,int,int)));
+ initTokenizer();
+ reset();
+}
+
+/*!
+*/
+
+TEmuVt102::~TEmuVt102()
+{
+}
+
+/*!
+*/
+
+void TEmuVt102::reset()
+{
+ resetToken();
+ resetModes();
+ resetCharset(0); screen[0]->reset();
+ resetCharset(1); screen[0]->reset();
+ setCodec(0);
+ setKeytrans("linux.keytab");
+}
+
+/* ------------------------------------------------------------------------- */
+/* */
+/* Processing the incoming byte stream */
+/* */
+/* ------------------------------------------------------------------------- */
+
+/* Incoming Bytes Event pipeline
+
+ 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
+ `TEScreen' class or by the emulation class itself.
+
+ The pipeline proceeds as follows:
+
+ - Tokenizing the ESC codes (onRcvChar)
+ - VT100 code page translation of plain characters (applyCharset)
+ - Interpretation of ESC codes (tau)
+
+ The escape codes and their meaning are described in the
+ technical reference of this program.
+*/
+
+// Tokens ------------------------------------------------------------------ --
+
+/*
+ Since the tokens are the central notion if this section, we've put them
+ in front. They provide the syntactical elements used to represent the
+ terminals operations as byte sequences.
+
+ They are encodes here into a single machine word, so that we can later
+ switch over them easily. Depending on the token itself, additional
+ argument variables are filled with parameter values.
+
+ The tokens are defined below:
+
+ - CHR - Printable characters (32..255 but DEL (=127))
+ - CTL - Control characters (0..31 but ESC (= 27), DEL)
+ - ESC - Escape codes of the form <ESC><CHR but `[]()+*#'>
+ - ESC_DE - Escape codes of the form <ESC><any of `()+*#%'> C
+ - CSI_PN - Escape codes of the form <ESC>'[' {Pn} ';' {Pn} C
+ - CSI_PS - Escape codes of the form <ESC>'[' {Pn} ';' ... C
+ - CSI_PR - Escape codes of the form <ESC>'[' '?' {Pn} ';' ... C
+ - VT52 - VT52 escape codes
+ - <ESC><Chr>
+ - <ESC>'Y'{Pc}{Pc}
+ - XTE_HA - Xterm hacks <ESC>`]' {Pn} `;' {Text} <BEL>
+ note that this is handled differently
+
+ The last two forms allow list of arguments. Since the elements of
+ the lists are treated individually the same way, they are passed
+ as individual tokens to the interpretation. Further, because the
+ meaning of the parameters are names (althought represented as numbers),
+ they are includes within the token ('N').
+
+*/
+
+#define TY_CONSTR(T,A,N) ( ((((int)N) & 0xffff) << 16) | ((((int)A) & 0xff) << 8) | (((int)T) & 0xff) )
+
+#define TY_CHR___( ) TY_CONSTR(0,0,0)
+#define TY_CTL___(A ) TY_CONSTR(1,A,0)
+#define TY_ESC___(A ) TY_CONSTR(2,A,0)
+#define TY_ESC_CS(A,B) TY_CONSTR(3,A,B)
+#define TY_ESC_DE(A ) TY_CONSTR(4,A,0)
+#define TY_CSI_PS(A,N) TY_CONSTR(5,A,N)
+#define TY_CSI_PN(A ) TY_CONSTR(6,A,0)
+#define TY_CSI_PR(A,N) TY_CONSTR(7,A,N)
+
+#define TY_VT52__(A ) TY_CONSTR(8,A,0)
+
+// Tokenizer --------------------------------------------------------------- --
+
+/* The tokenizers state
+
+ The state is represented by the buffer (pbuf, ppos),
+ and accompanied by decoded arguments kept in (argv,argc).
+ Note that they are kept internal in the tokenizer.
+*/
+
+void TEmuVt102::resetToken()
+{
+ ppos = 0; argc = 0; argv[0] = 0; argv[1] = 0;
+}
+
+void TEmuVt102::addDigit(int dig)
+{
+ argv[argc] = 10*argv[argc] + dig;
+}
+
+void TEmuVt102::addArgument()
+{
+ argc = QMIN(argc+1,MAXARGS-1);
+ argv[argc] = 0;
+}
+
+void TEmuVt102::pushToToken(int cc)
+{
+ pbuf[ppos] = cc;
+ ppos = QMIN(ppos+1,MAXPBUF-1);
+}
+
+// Character Classes used while decoding
+
+#define CTL 1
+#define CHR 2
+#define CPN 4
+#define DIG 8
+#define SCS 16
+#define GRP 32
+
+void TEmuVt102::initTokenizer()
+{ int i; UINT8* s;
+ for(i = 0; i < 256; i++) tbl[ i] = 0;
+ for(i = 0; i < 32; i++) tbl[ i] |= CTL;
+ for(i = 32; i < 256; i++) tbl[ i] |= CHR;
+ for(s = (UINT8*)"@ABCDGHLMPXcdfry"; *s; s++) tbl[*s] |= CPN;
+ for(s = (UINT8*)"0123456789" ; *s; s++) tbl[*s] |= DIG;
+ for(s = (UINT8*)"()+*%" ; *s; s++) tbl[*s] |= SCS;
+ for(s = (UINT8*)"()+*#[]%" ; *s; s++) tbl[*s] |= GRP;
+ resetToken();
+}
+
+/* Ok, here comes the nasty part of the decoder.
+
+ Instead of keeping an explicit state, we deduce it from the
+ token scanned so far. It is then immediately combined with
+ the current character to form a scanning decision.
+
+ This is done by the following defines.
+
+ - P is the length of the token scanned so far.
+ - L (often P-1) is the position on which contents we base a decision.
+ - C is a character or a group of characters (taken from 'tbl').
+
+ Note that they need to applied in proper order.
+*/
+
+#define lec(P,L,C) (p == (P) && s[(L)] == (C))
+#define lun( ) (p == 1 && cc >= 32 )
+#define les(P,L,C) (p == (P) && s[L] < 256 && (tbl[s[(L)]] & (C)) == (C))
+#define eec(C) (p >= 3 && cc == (C))
+#define ees(C) (p >= 3 && cc < 256 && (tbl[ cc ] & (C)) == (C))
+#define eps(C) (p >= 3 && s[2] != '?' && cc < 256 && (tbl[ cc ] & (C)) == (C))
+#define epp( ) (p >= 3 && s[2] == '?' )
+#define egt( ) (p == 3 && s[2] == '>' )
+#define Xpe (ppos>=2 && pbuf[1] == ']' )
+#define Xte (Xpe && cc == 7 )
+#define ces(C) ( cc < 256 && (tbl[ cc ] & (C)) == (C) && !Xte)
+
+#define ESC 27
+#define CNTL(c) ((c)-'@')
+
+// process an incoming unicode character
+
+void TEmuVt102::onRcvChar(int cc)
+{ int i;
+
+ if (cc == 127) return; //VT100: ignore.
+
+ if (ces( CTL))
+ { // DEC HACK ALERT! Control Characters are allowed *within* esc sequences in VT100
+ // This means, they do neither a resetToken nor a pushToToken. Some of them, do
+ // of course. Guess this originates from a weakly layered handling of the X-on
+ // X-off protocol, which comes really below this level.
+ if (cc == CNTL('X') || cc == CNTL('Z') || cc == ESC) resetToken(); //VT100: CAN or SUB
+ if (cc != ESC) { tau( TY_CTL___(cc+'@' ), 0, 0); return; }
+ }
+
+ pushToToken(cc); // advance the state
+
+ int* s = pbuf;
+ int p = ppos;
+
+ if (getMode(MODE_Ansi)) // decide on proper action
+ {
+ if (lec(1,0,ESC)) { return; }
+ if (les(2,1,GRP)) { return; }
+ if (Xte ) { XtermHack(); resetToken(); return; }
+ if (Xpe ) { return; }
+ if (lec(3,2,'?')) { return; }
+ if (lec(3,2,'>')) { return; }
+ if (lun( )) { tau( TY_CHR___(), applyCharset(cc), 0); resetToken(); return; }
+ if (lec(2,0,ESC)) { tau( TY_ESC___(s[1]), 0, 0); resetToken(); return; }
+ if (les(3,1,SCS)) { tau( TY_ESC_CS(s[1],s[2]), 0, 0); resetToken(); return; }
+ if (lec(3,1,'#')) { tau( TY_ESC_DE(s[2]), 0, 0); resetToken(); return; }
+// if (egt( )) { tau( TY_CSI_PG(cc ), '>', 0); resetToken(); return; }
+ if (eps( CPN)) { tau( TY_CSI_PN(cc), argv[0],argv[1]); resetToken(); return; }
+ if (ees( DIG)) { addDigit(cc-'0'); return; }
+ if (eec( ';')) { addArgument(); return; }
+ for (i=0;i<=argc;i++)
+ if (epp( )) tau( TY_CSI_PR(cc,argv[i]), 0, 0); else
+ tau( TY_CSI_PS(cc,argv[i]), 0, 0);
+ resetToken();
+ }
+ else // mode VT52
+ {
+ if (lec(1,0,ESC)) return;
+ if (les(1,0,CHR)) { tau( TY_CHR___( ), s[0], 0); resetToken(); return; }
+ if (lec(2,1,'Y')) return;
+ if (lec(3,1,'Y')) return;
+ if (p < 4) { tau( TY_VT52__(s[1] ), 0, 0); resetToken(); return; }
+ tau( TY_VT52__(s[1] ), s[2],s[3]); resetToken(); return;
+ }
+}
+
+void TEmuVt102::XtermHack()
+{ int i,arg = 0;
+ for (i = 2; i < ppos && '0'<=pbuf[i] && pbuf[i]<'9' ; i++)
+ arg = 10*arg + (pbuf[i]-'0');
+ if (pbuf[i] != ';') { ReportErrorToken(); return; }
+ QChar *str = new QChar[ppos-i-2];
+ for (int j = 0; j < ppos-i-2; j++) str[j] = pbuf[i+1+j];
+ QString unistr(str,ppos-i-2);
+ // arg == 1 doesn't change the title. In XTerm it only changes the icon name
+ // (btw: arg=0 changes title and icon, arg=1 only icon, arg=2 only title
+ if (arg == 0 || arg == 2) emit changeTitle(arg,unistr);
+ delete [] str;
+}
+
+// Interpreting Codes ---------------------------------------------------------
+
+/*
+ Now that the incoming character stream is properly tokenized,
+ meaning is assigned to them. These are either operations of
+ the current screen, or of the emulation class itself.
+
+ The token to be interpreteted comes in as a machine word
+ possibly accompanied by two parameters.
+
+ Likewise, the operations assigned to, come with up to two
+ arguments. One could consider to make up a proper table
+ from the function below.
+
+ The technical reference manual provides more informations
+ about this mapping.
+*/
+
+void TEmuVt102::tau( int token, int p, int q )
+{
+//scan_buffer_report();
+//if (token == TY_CHR___()) printf("%c",p); else
+//printf("tau(%d,%d,%d, %d,%d)\n",(token>>0)&0xff,(token>>8)&0xff,(token>>16)&0xffff,p,q);
+ switch (token)
+ {
+
+ case TY_CHR___( ) : scr->ShowCharacter (p ); break; //UTF16
+
+ // 127 DEL : ignored on input
+
+ case TY_CTL___('@' ) : /* NUL: ignored */ break;
+ case TY_CTL___('A' ) : /* SOH: ignored */ break;
+ case TY_CTL___('B' ) : /* STX: ignored */ break;
+ case TY_CTL___('C' ) : /* ETX: ignored */ break;
+ case TY_CTL___('D' ) : /* EOT: ignored */ break;
+ case TY_CTL___('E' ) : reportAnswerBack ( ); break; //VT100
+ case TY_CTL___('F' ) : /* ACK: ignored */ break;
+ case TY_CTL___('G' ) : gui->Bell ( ); break; //VT100
+ case TY_CTL___('H' ) : scr->BackSpace ( ); break; //VT100
+ case TY_CTL___('I' ) : scr->Tabulate ( ); break; //VT100
+ case TY_CTL___('J' ) : scr->NewLine ( ); break; //VT100
+ case TY_CTL___('K' ) : scr->NewLine ( ); break; //VT100
+ case TY_CTL___('L' ) : scr->NewLine ( ); break; //VT100
+ case TY_CTL___('M' ) : scr->Return ( ); break; //VT100
+
+ case TY_CTL___('N' ) : useCharset ( 1); break; //VT100
+ case TY_CTL___('O' ) : useCharset ( 0); break; //VT100
+
+ case TY_CTL___('P' ) : /* DLE: ignored */ break;
+ case TY_CTL___('Q' ) : /* DC1: XON continue */ break; //VT100
+ case TY_CTL___('R' ) : /* DC2: ignored */ break;
+ case TY_CTL___('S' ) : /* DC3: XOFF halt */ break; //VT100
+ case TY_CTL___('T' ) : /* DC4: ignored */ break;
+ case TY_CTL___('U' ) : /* NAK: ignored */ break;
+ case TY_CTL___('V' ) : /* SYN: ignored */ break;
+ case TY_CTL___('W' ) : /* ETB: ignored */ break;
+ case TY_CTL___('X' ) : scr->ShowCharacter ( 0x2592); break; //VT100
+ case TY_CTL___('Y' ) : /* EM : ignored */ break;
+ case TY_CTL___('Z' ) : scr->ShowCharacter ( 0x2592); break; //VT100
+ case TY_CTL___('[' ) : /* ESC: cannot be seen here. */ break;
+ case TY_CTL___('\\' ) : /* FS : ignored */ break;
+ case TY_CTL___(']' ) : /* GS : ignored */ break;
+ case TY_CTL___('^' ) : /* RS : ignored */ break;
+ case TY_CTL___('_' ) : /* US : ignored */ break;
+
+ case TY_ESC___('D' ) : scr->index ( ); break; //VT100
+ case TY_ESC___('E' ) : scr->NextLine ( ); break; //VT100
+ case TY_ESC___('H' ) : scr->changeTabStop (TRUE ); break; //VT100
+ case TY_ESC___('M' ) : scr->reverseIndex ( ); break; //VT100
+ case TY_ESC___('Z' ) : reportTerminalType ( ); break;
+ case TY_ESC___('c' ) : reset ( ); break;
+
+ case TY_ESC___('n' ) : useCharset ( 2); break;
+ case TY_ESC___('o' ) : useCharset ( 3); break;
+ case TY_ESC___('7' ) : saveCursor ( ); break;
+ case TY_ESC___('8' ) : restoreCursor ( ); break;
+
+ case TY_ESC___('=' ) : setMode (MODE_AppKeyPad); break;
+ case TY_ESC___('>' ) : resetMode (MODE_AppKeyPad); break;
+ case TY_ESC___('<' ) : setMode (MODE_Ansi ); break; //VT100
+
+ case TY_ESC_CS('(', '0') : setCharset (0, '0'); break; //VT100
+ case TY_ESC_CS('(', 'A') : setCharset (0, 'A'); break; //VT100
+ case TY_ESC_CS('(', 'B') : setCharset (0, 'B'); break; //VT100
+
+ case TY_ESC_CS(')', '0') : setCharset (1, '0'); break; //VT100
+ case TY_ESC_CS(')', 'A') : setCharset (1, 'A'); break; //VT100
+ case TY_ESC_CS(')', 'B') : setCharset (1, 'B'); break; //VT100
+
+ case TY_ESC_CS('*', '0') : setCharset (2, '0'); break; //VT100
+ case TY_ESC_CS('*', 'A') : setCharset (2, 'A'); break; //VT100
+ case TY_ESC_CS('*', 'B') : setCharset (2, 'B'); break; //VT100
+
+ case TY_ESC_CS('+', '0') : setCharset (3, '0'); break; //VT100
+ case TY_ESC_CS('+', 'A') : setCharset (3, 'A'); break; //VT100
+ case TY_ESC_CS('+', 'B') : setCharset (3, 'B'); break; //VT100
+
+ case TY_ESC_CS('%', 'G') : setCodec (1 ); break; //LINUX
+ case TY_ESC_CS('%', '@') : setCodec (0 ); break; //LINUX
+
+ case TY_ESC_DE('3' ) : /* IGNORED: double high, top half */ break;
+ case TY_ESC_DE('4' ) : /* IGNORED: double high, bottom half */ break;
+ case TY_ESC_DE('5' ) : /* IGNORED: single width, single high*/ break;
+ case TY_ESC_DE('6' ) : /* IGNORED: double width, single high*/ break;
+ case TY_ESC_DE('8' ) : scr->helpAlign ( ); break;
+
+ case TY_CSI_PS('K', 0) : scr->clearToEndOfLine ( ); break;
+ case TY_CSI_PS('K', 1) : scr->clearToBeginOfLine ( ); break;
+ case TY_CSI_PS('K', 2) : scr->clearEntireLine ( ); break;
+ case TY_CSI_PS('J', 0) : scr->clearToEndOfScreen ( ); break;
+ case TY_CSI_PS('J', 1) : scr->clearToBeginOfScreen ( ); break;
+ case TY_CSI_PS('J', 2) : scr->clearEntireScreen ( ); break;
+ case TY_CSI_PS('g', 0) : scr->changeTabStop (FALSE ); break; //VT100
+ case TY_CSI_PS('g', 3) : scr->clearTabStops ( ); break; //VT100
+ case TY_CSI_PS('h', 4) : scr-> setMode (MODE_Insert ); break;
+ case TY_CSI_PS('h', 20) : setMode (MODE_NewLine ); break;
+ case TY_CSI_PS('i', 0) : /* IGNORE: attached printer */ break; //VT100
+ case TY_CSI_PS('l', 4) : scr-> resetMode (MODE_Insert ); break;
+ case TY_CSI_PS('l', 20) : resetMode (MODE_NewLine ); break;
+
+ case TY_CSI_PS('m', 0) : scr->setDefaultRendition ( ); break;
+ case TY_CSI_PS('m', 1) : scr-> setRendition (RE_BOLD ); break; //VT100
+ case TY_CSI_PS('m', 4) : scr-> setRendition (RE_UNDERLINE); break; //VT100
+ case TY_CSI_PS('m', 5) : scr-> setRendition (RE_BLINK ); break; //VT100
+ case TY_CSI_PS('m', 7) : scr-> setRendition (RE_REVERSE ); break;
+ case TY_CSI_PS('m', 10) : /* IGNORED: mapping related */ break; //LINUX
+ case TY_CSI_PS('m', 11) : /* IGNORED: mapping related */ break; //LINUX
+ case TY_CSI_PS('m', 12) : /* IGNORED: mapping related */ break; //LINUX
+ case TY_CSI_PS('m', 22) : scr->resetRendition (RE_BOLD ); break;
+ case TY_CSI_PS('m', 24) : scr->resetRendition (RE_UNDERLINE); break;
+ case TY_CSI_PS('m', 25) : scr->resetRendition (RE_BLINK ); break;
+ case TY_CSI_PS('m', 27) : scr->resetRendition (RE_REVERSE ); break;
+
+ case TY_CSI_PS('m', 30) : scr->setForeColor ( 0); break;
+ case TY_CSI_PS('m', 31) : scr->setForeColor ( 1); break;
+ case TY_CSI_PS('m', 32) : scr->setForeColor ( 2); break;
+ case TY_CSI_PS('m', 33) : scr->setForeColor ( 3); break;
+ case TY_CSI_PS('m', 34) : scr->setForeColor ( 4); break;
+ case TY_CSI_PS('m', 35) : scr->setForeColor ( 5); break;
+ case TY_CSI_PS('m', 36) : scr->setForeColor ( 6); break;
+ case TY_CSI_PS('m', 37) : scr->setForeColor ( 7); break;
+ case TY_CSI_PS('m', 39) : scr->setForeColorToDefault( ); break;
+
+ case TY_CSI_PS('m', 40) : scr->setBackColor ( 0); break;
+ case TY_CSI_PS('m', 41) : scr->setBackColor ( 1); break;
+ case TY_CSI_PS('m', 42) : scr->setBackColor ( 2); break;
+ case TY_CSI_PS('m', 43) : scr->setBackColor ( 3); break;
+ case TY_CSI_PS('m', 44) : scr->setBackColor ( 4); break;
+ case TY_CSI_PS('m', 45) : scr->setBackColor ( 5); break;
+ case TY_CSI_PS('m', 46) : scr->setBackColor ( 6); break;
+ case TY_CSI_PS('m', 47) : scr->setBackColor ( 7); break;
+ case TY_CSI_PS('m', 49) : scr->setBackColorToDefault( ); break;
+
+ case TY_CSI_PS('m', 90) : scr->setForeColor ( 8); break;
+ case TY_CSI_PS('m', 91) : scr->setForeColor ( 9); break;
+ case TY_CSI_PS('m', 92) : scr->setForeColor ( 10); break;
+ case TY_CSI_PS('m', 93) : scr->setForeColor ( 11); break;
+ case TY_CSI_PS('m', 94) : scr->setForeColor ( 12); break;
+ case TY_CSI_PS('m', 95) : scr->setForeColor ( 13); break;
+ case TY_CSI_PS('m', 96) : scr->setForeColor ( 14); break;
+ case TY_CSI_PS('m', 97) : scr->setForeColor ( 15); break;
+
+ case TY_CSI_PS('m', 100) : scr->setBackColor ( 8); break;
+ case TY_CSI_PS('m', 101) : scr->setBackColor ( 9); break;
+ case TY_CSI_PS('m', 102) : scr->setBackColor ( 10); break;
+ case TY_CSI_PS('m', 103) : scr->setBackColor ( 11); break;
+ case TY_CSI_PS('m', 104) : scr->setBackColor ( 12); break;
+ case TY_CSI_PS('m', 105) : scr->setBackColor ( 13); break;
+ case TY_CSI_PS('m', 106) : scr->setBackColor ( 14); break;
+ case TY_CSI_PS('m', 107) : scr->setBackColor ( 15); break;
+
+ case TY_CSI_PS('n', 5) : reportStatus ( ); break;
+ case TY_CSI_PS('n', 6) : reportCursorPosition ( ); break;
+ case TY_CSI_PS('q', 0) : /* IGNORED: LEDs off */ break; //VT100
+ case TY_CSI_PS('q', 1) : /* IGNORED: LED1 on */ break; //VT100
+ case TY_CSI_PS('q', 2) : /* IGNORED: LED2 on */ break; //VT100
+ case TY_CSI_PS('q', 3) : /* IGNORED: LED3 on */ break; //VT100
+ case TY_CSI_PS('q', 4) : /* IGNORED: LED4 on */ break; //VT100
+ case TY_CSI_PS('x', 0) : reportTerminalParms ( 2); break; //VT100
+ case TY_CSI_PS('x', 1) : reportTerminalParms ( 3); break; //VT100
+
+ case TY_CSI_PN('@' ) : scr->insertChars (p ); break;
+ case TY_CSI_PN('A' ) : scr->cursorUp (p ); break; //VT100
+ case TY_CSI_PN('B' ) : scr->cursorDown (p ); break; //VT100
+ case TY_CSI_PN('C' ) : scr->cursorRight (p ); break; //VT100
+ case TY_CSI_PN('D' ) : scr->cursorLeft (p ); break; //VT100
+ case TY_CSI_PN('G' ) : scr->setCursorX (p ); break; //LINUX
+ case TY_CSI_PN('H' ) : scr->setCursorYX (p, q); break; //VT100
+ case TY_CSI_PN('L' ) : scr->insertLines (p ); break;
+ case TY_CSI_PN('M' ) : scr->deleteLines (p ); break;
+ case TY_CSI_PN('P' ) : scr->deleteChars (p ); break;
+ case TY_CSI_PN('X' ) : scr->eraseChars (p ); break;
+ case TY_CSI_PN('c' ) : reportTerminalType ( ); break; //VT100
+ case TY_CSI_PN('d' ) : scr->setCursorY (p ); break; //LINUX
+ case TY_CSI_PN('f' ) : scr->setCursorYX (p, q); break; //VT100
+ case TY_CSI_PN('r' ) : scr->setMargins (p, q); break; //VT100
+ case TY_CSI_PN('y' ) : /* IGNORED: Confidence test */ break; //VT100
+
+ case TY_CSI_PR('h', 1) : setMode (MODE_AppCuKeys); break; //VT100
+ case TY_CSI_PR('l', 1) : resetMode (MODE_AppCuKeys); break; //VT100
+ case TY_CSI_PR('s', 1) : saveMode (MODE_AppCuKeys); break; //FIXME
+ case TY_CSI_PR('r', 1) : restoreMode (MODE_AppCuKeys); break; //FIXME
+
+ case TY_CSI_PR('l', 2) : resetMode (MODE_Ansi ); break; //VT100
+
+ case TY_CSI_PR('h', 3) : setColumns ( 132); break; //VT100
+ case TY_CSI_PR('l', 3) : setColumns ( 80); break; //VT100
+
+ case TY_CSI_PR('h', 4) : /* IGNORED: soft scrolling */ break; //VT100
+ case TY_CSI_PR('l', 4) : /* IGNORED: soft scrolling */ break; //VT100
+
+ case TY_CSI_PR('h', 5) : scr-> setMode (MODE_Screen ); break; //VT100
+ case TY_CSI_PR('l', 5) : scr-> resetMode (MODE_Screen ); break; //VT100
+
+ case TY_CSI_PR('h', 6) : scr-> setMode (MODE_Origin ); break; //VT100
+ case TY_CSI_PR('l', 6) : scr-> resetMode (MODE_Origin ); break; //VT100
+ case TY_CSI_PR('s', 6) : scr-> saveMode (MODE_Origin ); break; //FIXME
+ case TY_CSI_PR('r', 6) : scr->restoreMode (MODE_Origin ); break; //FIXME
+
+ case TY_CSI_PR('h', 7) : scr-> setMode (MODE_Wrap ); break; //VT100
+ case TY_CSI_PR('l', 7) : scr-> resetMode (MODE_Wrap ); break; //VT100
+ case TY_CSI_PR('s', 7) : scr-> saveMode (MODE_Wrap ); break; //FIXME
+ case TY_CSI_PR('r', 7) : scr->restoreMode (MODE_Wrap ); break; //FIXME
+
+ case TY_CSI_PR('h', 8) : /* IGNORED: autorepeat on */ break; //VT100
+ case TY_CSI_PR('l', 8) : /* IGNORED: autorepeat off */ break; //VT100
+
+ case TY_CSI_PR('h', 9) : /* IGNORED: interlace */ break; //VT100
+ case TY_CSI_PR('l', 9) : /* IGNORED: interlace */ break; //VT100
+
+ case TY_CSI_PR('h', 25) : setMode (MODE_Cursor ); break; //VT100
+ case TY_CSI_PR('l', 25) : resetMode (MODE_Cursor ); break; //VT100
+
+ case TY_CSI_PR('h', 41) : /* IGNORED: obsolete more(1) fix */ break; //XTERM
+ case TY_CSI_PR('l', 41) : /* IGNORED: obsolete more(1) fix */ break; //XTERM
+ case TY_CSI_PR('s', 41) : /* IGNORED: obsolete more(1) fix */ break; //XTERM
+ case TY_CSI_PR('r', 41) : /* IGNORED: obsolete more(1) fix */ break; //XTERM
+
+ case TY_CSI_PR('h', 47) : setMode (MODE_AppScreen); break; //VT100
+ case TY_CSI_PR('l', 47) : resetMode (MODE_AppScreen); break; //VT100
+
+ case TY_CSI_PR('h', 1000) : setMode (MODE_Mouse1000); break; //XTERM
+ case TY_CSI_PR('l', 1000) : resetMode (MODE_Mouse1000); break; //XTERM
+ case TY_CSI_PR('s', 1000) : saveMode (MODE_Mouse1000); break; //XTERM
+ case TY_CSI_PR('r', 1000) : restoreMode (MODE_Mouse1000); break; //XTERM
+
+ case TY_CSI_PR('h', 1001) : /* IGNORED: hilite mouse tracking */ break; //XTERM
+ case TY_CSI_PR('l', 1001) : /* IGNORED: hilite mouse tracking */ break; //XTERM
+ case TY_CSI_PR('s', 1001) : /* IGNORED: hilite mouse tracking */ break; //XTERM
+ case TY_CSI_PR('r', 1001) : /* IGNORED: hilite mouse tracking */ break; //XTERM
+
+ case TY_CSI_PR('h', 1047) : setMode (MODE_AppScreen); break; //XTERM
+ case TY_CSI_PR('l', 1047) : resetMode (MODE_AppScreen); break; //XTERM
+
+ //FIXME: Unitoken: save translations
+ case TY_CSI_PR('h', 1048) : saveCursor ( ); break; //XTERM
+ case TY_CSI_PR('l', 1048) : restoreCursor ( ); break; //XTERM
+
+ //FIXME: every once new sequences like this pop up in xterm.
+ // Here's a guess of what they could mean.
+ case TY_CSI_PR('h', 1049) : setMode (MODE_AppScreen); break; //XTERM
+ case TY_CSI_PR('l', 1049) : resetMode (MODE_AppScreen); break; //XTERM
+
+ //FIXME: when changing between vt52 and ansi mode evtl do some resetting.
+ case TY_VT52__('A' ) : scr->cursorUp ( 1); break; //VT52
+ case TY_VT52__('B' ) : scr->cursorDown ( 1); break; //VT52
+ case TY_VT52__('C' ) : scr->cursorRight ( 1); break; //VT52
+ case TY_VT52__('D' ) : scr->cursorLeft ( 1); break; //VT52
+
+ case TY_VT52__('F' ) : setAndUseCharset (0, '0'); break; //VT52
+ case TY_VT52__('G' ) : setAndUseCharset (0, 'B'); break; //VT52
+
+ case TY_VT52__('H' ) : scr->setCursorYX (1,1 ); break; //VT52
+ case TY_VT52__('I' ) : scr->reverseIndex ( ); break; //VT52
+ case TY_VT52__('J' ) : scr->clearToEndOfScreen ( ); break; //VT52
+ case TY_VT52__('K' ) : scr->clearToEndOfLine ( ); break; //VT52
+ case TY_VT52__('Y' ) : scr->setCursorYX (p-31,q-31 ); break; //VT52
+ case TY_VT52__('Z' ) : reportTerminalType ( ); break; //VT52
+ case TY_VT52__('<' ) : setMode (MODE_Ansi ); break; //VT52
+ case TY_VT52__('=' ) : setMode (MODE_AppKeyPad); break; //VT52
+ case TY_VT52__('>' ) : resetMode (MODE_AppKeyPad); break; //VT52
+
+ default : ReportErrorToken(); break;
+ };
+}
+
+/* ------------------------------------------------------------------------- */
+/* */
+/* Terminal to Host protocol */
+/* */
+/* ------------------------------------------------------------------------- */
+
+/*
+ Outgoing bytes originate from several sources:
+
+ - Replies to Enquieries.
+ - Mouse Events
+ - Keyboard Events
+*/
+
+/*!
+*/
+
+void TEmuVt102::sendString(const char* s)
+{
+ emit sndBlock(s,strlen(s));
+}
+
+// Replies ----------------------------------------------------------------- --
+
+// This section copes with replies send as response to an enquiery control code.
+
+/*!
+*/
+
+void TEmuVt102::reportCursorPosition()
+{ char tmp[20];
+ sprintf(tmp,"\033[%d;%dR",scr->getCursorY()+1,scr->getCursorX()+1);
+ sendString(tmp);
+}
+
+/*
+ What follows here is rather obsolete and faked stuff.
+ The correspondent enquieries are neverthenless issued.
+*/
+
+/*!
+*/
+
+void TEmuVt102::reportTerminalType()
+{
+//FIXME: should change?
+ if (getMode(MODE_Ansi))
+// sendString("\033[?1;2c"); // I'm a VT100 with AP0 //FIXME: send only in response to ^[[0c
+ sendString("\033[>0;115;0c"); // I'm a VT220 //FIXME: send only in response to ^[[>c
+ else
+ sendString("\033/Z"); // I'm a VT52
+}
+
+void TEmuVt102::reportTerminalParms(int p)
+// DECREPTPARM
+{ char tmp[100];
+ sprintf(tmp,"\033[%d;1;1;112;112;1;0x",p); // not really true.
+ sendString(tmp);
+}
+
+/*!
+*/
+
+void TEmuVt102::reportStatus()
+{
+ sendString("\033[0n"); //VT100. Device status report. 0 = Ready.
+}
+
+/*!
+*/
+
+#define ANSWER_BACK "" // This is really obsolete VT100 stuff.
+
+void TEmuVt102::reportAnswerBack()
+{
+ sendString(ANSWER_BACK);
+}
+
+// Mouse Handling ---------------------------------------------------------- --
+
+/*!
+ Mouse clicks are possibly reported to the client
+ application if it has issued interest in them.
+ They are normally consumed by the widget for copy
+ and paste, but may be propagated from the widget
+ when gui->setMouseMarks is set via setMode(MODE_Mouse1000).
+
+ `x',`y' are 1-based.
+ `ev' (event) indicates the button pressed (0-2)
+ or a general mouse release (3).
+*/
+
+void TEmuVt102::onMouse( int cb, int cx, int cy )
+{ char tmp[20];
+ if (!connected) return;
+ sprintf(tmp,"\033[M%c%c%c",cb+040,cx+040,cy+040);
+ sendString(tmp);
+}
+
+// Keyboard Handling ------------------------------------------------------- --
+
+#define encodeMode(M,B) BITS(B,getMode(M))
+#define encodeStat(M,B) BITS(B,((ev->state() & (M)) == (M)))
+
+/*
+ Keyboard event handling has been simplified somewhat by pushing
+ the complications towards a configuration file [see KeyTrans class].
+*/
+
+void TEmuVt102::onKeyPress( QKeyEvent* ev )
+{
+ if (!connected) return; // someone else gets the keys
+
+//printf("State/Key: 0x%04x 0x%04x (%d,%d)\n",ev->state(),ev->key(),ev->text().length(),ev->text().length()?ev->text().ascii()[0]:0);
+
+ // revert to non-history when typing
+ if (scr->getHistCursor() != scr->getHistLines());
+ scr->setHistCursor(scr->getHistLines());
+
+ // lookup in keyboard translation table ...
+ int cmd; const char* txt; int len;
+ if (keytrans->findEntry(ev->key(), encodeMode(MODE_NewLine , BITS_NewLine ) + // OLD,
+ encodeMode(MODE_Ansi , BITS_Ansi ) + // OBSOLETE,
+ encodeMode(MODE_AppCuKeys, BITS_AppCuKeys ) + // VT100 stuff
+ encodeStat(ControlButton , BITS_Control ) +
+ encodeStat(ShiftButton , BITS_Shift ) +
+ encodeStat(AltButton , BITS_Alt ),
+ &cmd, &txt, &len ))
+//printf("cmd: %d, %s, %d\n",cmd,txt,len);
+ switch(cmd) // ... and execute if found.
+ {
+ case CMD_emitSelection : gui->emitSelection(); return;
+ case CMD_scrollPageUp : gui->doScroll(-gui->Lines()/2); return;
+ case CMD_scrollPageDown : gui->doScroll(+gui->Lines()/2); return;
+ case CMD_scrollLineUp : gui->doScroll(-1 ); return;
+ case CMD_scrollLineDown : gui->doScroll(+1 ); return;
+ case CMD_send : emit sndBlock(txt,len); return;
+ case CMD_prevSession : emit prevSession(); return;
+ case CMD_nextSession : emit nextSession(); return;
+ }
+
+ // fall back handling
+ if (!ev->text().isEmpty())
+ {
+ if (ev->state() & AltButton) sendString("\033"); // ESC, this is the ALT prefix
+ QCString s = codec->fromUnicode(ev->text()); // encode for application
+ emit sndBlock(s.data(),s.length()); // we may well have s.length() > 1
+ return;
+ }
+}
+
+/* ------------------------------------------------------------------------- */
+/* */
+/* VT100 Charsets */
+/* */
+/* ------------------------------------------------------------------------- */
+
+// Character Set Conversion ------------------------------------------------ --
+
+/*
+ The processing contains a VT100 specific code translation layer.
+ It's still in use and mainly responsible for the line drawing graphics.
+
+ These and some other glyphs are assigned to codes (0x5f-0xfe)
+ normally occupied by the latin letters. Since this codes also
+ appear within control sequences, the extra code conversion
+ does not permute with the tokenizer and is placed behind it
+ in the pipeline. It only applies to tokens, which represent
+ plain characters.
+
+ This conversion it eventually continued in TEWidget.C, since
+ it might involve VT100 enhanced fonts, which have these
+ particular glyphs allocated in (0x00-0x1f) in their code page.
+*/
+
+#define CHARSET charset[scr==screen[1]]
+
+// Apply current character map.
+
+unsigned short TEmuVt102::applyCharset(unsigned short c)
+{
+ if (CHARSET.graphic && 0x5f <= c && c <= 0x7e) return vt100_graphics[c-0x5f];
+ if (CHARSET.pound && c == '#' ) return 0xa3; //This mode is obsolete
+ return c;
+}
+
+/*
+ "Charset" related part of the emulation state.
+ This configures the VT100 charset filter.
+
+ While most operation work on the current screen,
+ the following two are different.
+*/
+
+void TEmuVt102::resetCharset(int scrno)
+{
+ charset[scrno].cu_cs = 0;
+ strncpy(charset[scrno].charset,"BBBB",4);
+ charset[scrno].sa_graphic = FALSE;
+ charset[scrno].sa_pound = FALSE;
+ charset[scrno].graphic = FALSE;
+ charset[scrno].pound = FALSE;
+}
+
+/*!
+*/
+
+void TEmuVt102::setCharset(int n, int cs) // on both screens.
+{
+ charset[0].charset[n&3] = cs; useCharset(charset[0].cu_cs);
+ charset[1].charset[n&3] = cs; useCharset(charset[1].cu_cs);
+}
+
+/*!
+*/
+
+void TEmuVt102::setAndUseCharset(int n, int cs)
+{
+ CHARSET.charset[n&3] = cs;
+ useCharset(n&3);
+}
+
+/*!
+*/
+
+void TEmuVt102::useCharset(int n)
+{
+ CHARSET.cu_cs = n&3;
+ CHARSET.graphic = (CHARSET.charset[n&3] == '0');
+ CHARSET.pound = (CHARSET.charset[n&3] == 'A'); //This mode is obsolete
+}
+
+/*! Save the cursor position and the rendition attribute settings. */
+
+void TEmuVt102::saveCursor()
+{
+ CHARSET.sa_graphic = CHARSET.graphic;
+ CHARSET.sa_pound = CHARSET.pound; //This mode is obsolete
+ // we are not clear about these
+ //sa_charset = charsets[cScreen->charset];
+ //sa_charset_num = cScreen->charset;
+ scr->saveCursor();
+}
+
+/*! Restore the cursor position and the rendition attribute settings. */
+
+void TEmuVt102::restoreCursor()
+{
+ CHARSET.graphic = CHARSET.sa_graphic;
+ CHARSET.pound = CHARSET.sa_pound; //This mode is obsolete
+ scr->restoreCursor();
+}
+
+/* ------------------------------------------------------------------------- */
+/* */
+/* Mode Operations */
+/* */
+/* ------------------------------------------------------------------------- */
+
+/*
+ Some of the emulations state is either added to the state of the screens.
+
+ This causes some scoping problems, since different emulations choose to
+ located the mode either to the current screen or to both.
+
+ For strange reasons, the extend of the rendition attributes ranges over
+ all screens and not over the actual screen.
+
+ We decided on the precise precise extend, somehow.
+*/
+
+// "Mode" related part of the state. These are all booleans.
+
+void TEmuVt102::resetModes()
+{
+ resetMode(MODE_Mouse1000); saveMode(MODE_Mouse1000);
+ resetMode(MODE_AppScreen); saveMode(MODE_AppScreen);
+ // here come obsolete modes
+ resetMode(MODE_AppCuKeys); saveMode(MODE_AppCuKeys);
+ resetMode(MODE_NewLine );
+ setMode(MODE_Ansi );
+}
+
+void TEmuVt102::setMode(int m)
+{
+ currParm.mode[m] = TRUE;
+ switch (m)
+ {
+ case MODE_Mouse1000 : gui->setMouseMarks(FALSE);
+ break;
+ case MODE_AppScreen : screen[1]->clearSelection();
+ screen[1]->clearEntireScreen();
+ setScreen(1);
+ break;
+ }
+ if (m < MODES_SCREEN || m == MODE_NewLine)
+ {
+ screen[0]->setMode(m);
+ screen[1]->setMode(m);
+ }
+}
+
+void TEmuVt102::resetMode(int m)
+{
+ currParm.mode[m] = FALSE;
+ switch (m)
+ {
+ case MODE_Mouse1000 : gui->setMouseMarks(TRUE);
+ break;
+ case MODE_AppScreen : screen[0]->clearSelection();
+ setScreen(0);
+ break;
+ }
+ if (m < MODES_SCREEN || m == MODE_NewLine)
+ {
+ screen[0]->resetMode(m);
+ screen[1]->resetMode(m);
+ }
+}
+
+void TEmuVt102::saveMode(int m)
+{
+ saveParm.mode[m] = currParm.mode[m];
+}
+
+void TEmuVt102::restoreMode(int m)
+{
+ if(saveParm.mode[m]) setMode(m); else resetMode(m);
+}
+
+BOOL TEmuVt102::getMode(int m)
+{
+ return currParm.mode[m];
+}
+
+void TEmuVt102::setConnect(bool c)
+{
+ TEmulation::setConnect(c);
+ if (c)
+ { // refresh mouse mode
+ if (getMode(MODE_Mouse1000))
+ setMode(MODE_Mouse1000);
+ else
+ resetMode(MODE_Mouse1000);
+ }
+}
+
+/* ------------------------------------------------------------------------- */
+/* */
+/* Diagnostic */
+/* */
+/* ------------------------------------------------------------------------- */
+
+/*! shows the contents of the scan buffer.
+
+ This functions is used for diagnostics. It is called by \e ReportErrorToken
+ to inform about strings that cannot be decoded or handled by the emulation.
+
+ \sa ReportErrorToken
+*/
+
+/*!
+*/
+
+static void hexdump(int* s, int len)
+{ int i;
+ for (i = 0; i < len; i++)
+ {
+ if (s[i] == '\\')
+ printf("\\\\");
+ else
+ if ((s[i]) > 32 && s[i] < 127)
+ printf("%c",s[i]);
+ else
+ printf("\\%04x(hex)",s[i]);
+ }
+}
+
+void TEmuVt102::scan_buffer_report()
+{
+ if (ppos == 0 || ppos == 1 && (pbuf[0] & 0xff) >= 32) return;
+ printf("token: "); hexdump(pbuf,ppos); printf("\n");
+}
+
+/*!
+*/
+
+void TEmuVt102::ReportErrorToken()
+{
+ printf("undecodable "); scan_buffer_report();
+}
diff --git a/core/apps/embeddedkonsole/TEmuVt102.h b/core/apps/embeddedkonsole/TEmuVt102.h
new file mode 100644
index 0000000..a448a71
--- a/dev/null
+++ b/core/apps/embeddedkonsole/TEmuVt102.h
@@ -0,0 +1,135 @@
+/* -------------------------------------------------------------------------- */
+/* */
+/* [TEmuVt102.h] X Terminal Emulation */
+/* */
+/* -------------------------------------------------------------------------- */
+/* */
+/* 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> */
+/* */
+/* -------------------------------------------------------------------------- */
+
+#ifndef VT102EMU_H
+#define VT102EMU_H
+
+#include "TEWidget.h"
+#include "TEScreen.h"
+#include "TEmulation.h"
+#include <qtimer.h>
+#include <stdio.h>
+
+//
+
+#define MODE_AppScreen (MODES_SCREEN+0)
+#define MODE_AppCuKeys (MODES_SCREEN+1)
+#define MODE_AppKeyPad (MODES_SCREEN+2)
+#define MODE_Mouse1000 (MODES_SCREEN+3)
+#define MODE_Ansi (MODES_SCREEN+4)
+#define MODE_total (MODES_SCREEN+5)
+
+struct DECpar
+{
+ BOOL mode[MODE_total];
+};
+
+struct CharCodes
+{
+ // coding info
+ char charset[4]; //
+ int cu_cs; // actual charset.
+ bool graphic; // Some VT100 tricks
+ bool pound ; // Some VT100 tricks
+ bool sa_graphic; // saved graphic
+ bool sa_pound; // saved pound
+};
+
+class TEmuVt102 : public TEmulation
+{ Q_OBJECT
+
+public:
+
+ TEmuVt102(TEWidget* gui);
+ ~TEmuVt102();
+
+public slots: // signals incoming from TEWidget
+
+ void onKeyPress(QKeyEvent*);
+ void onMouse(int cb, int cx, int cy);
+
+signals:
+
+ void changeTitle(int,const QString&);
+ void prevSession();
+ void nextSession();
+
+public:
+
+ void reset();
+
+ void onRcvChar(int cc);
+ void sendString(const char *);
+
+public:
+
+ BOOL getMode (int m);
+
+ void setMode (int m);
+ void resetMode (int m);
+ void saveMode (int m);
+ void restoreMode(int m);
+ void resetModes();
+
+ void setConnect(bool r);
+
+private:
+
+ void resetToken();
+#define MAXPBUF 80
+ void pushToToken(int cc);
+ int pbuf[MAXPBUF]; //FIXME: overflow?
+ int ppos;
+#define MAXARGS 15
+ void addDigit(int dig);
+ void addArgument();
+ int argv[MAXARGS];
+ int argc;
+ void initTokenizer();
+ int tbl[256];
+
+ void scan_buffer_report(); //FIXME: rename
+ void ReportErrorToken(); //FIXME: rename
+
+ void tau(int code, int p, int q);
+ void XtermHack();
+
+ //
+
+ void reportTerminalType();
+ void reportStatus();
+ void reportAnswerBack();
+ void reportCursorPosition();
+ void reportTerminalParms(int p);
+
+protected:
+
+ unsigned short applyCharset(unsigned short c);
+ void setCharset(int n, int cs);
+ void useCharset(int n);
+ void setAndUseCharset(int n, int cs);
+ void saveCursor();
+ void restoreCursor();
+ void resetCharset(int scrno);
+ CharCodes charset[2];
+
+ DECpar currParm;
+ DECpar saveParm;
+};
+
+#endif // ifndef ANSIEMU_H
diff --git a/core/apps/embeddedkonsole/TEmulation.cpp b/core/apps/embeddedkonsole/TEmulation.cpp
new file mode 100644
index 0000000..6f3ad32
--- a/dev/null
+++ b/core/apps/embeddedkonsole/TEmulation.cpp
@@ -0,0 +1,363 @@
+/* -------------------------------------------------------------------------- */
+/* */
+/* [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 )
+{
+ 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/core/apps/embeddedkonsole/TEmulation.h b/core/apps/embeddedkonsole/TEmulation.h
new file mode 100644
index 0000000..ec15e7a
--- a/dev/null
+++ b/core/apps/embeddedkonsole/TEmulation.h
@@ -0,0 +1,117 @@
+/* -------------------------------------------------------------------------- */
+/* */
+/* [emulation.h] Fundamental Terminal Emulation */
+/* */
+/* -------------------------------------------------------------------------- */
+/* */
+/* 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> */
+/* */
+/* -------------------------------------------------------------------------- */
+
+#ifndef EMULATION_H
+#define EMULATION_H
+
+#include "TEWidget.h"
+#include "TEScreen.h"
+#include <qtimer.h>
+#include <stdio.h>
+#include <qtextcodec.h>
+#include "keytrans.h"
+
+class TEmulation : public QObject
+{ Q_OBJECT
+
+public:
+
+ TEmulation(TEWidget* gui);
+ ~TEmulation();
+
+public:
+ virtual void setHistory(bool on);
+ virtual bool history();
+
+public slots: // signals incoming from TEWidget
+
+ virtual void onImageSizeChange(int lines, int columns);
+ virtual void onHistoryCursorChange(int cursor);
+ virtual void onKeyPress(QKeyEvent*);
+
+ virtual void clearSelection();
+ virtual void onSelectionBegin(const int x, const int y);
+ virtual void onSelectionExtend(const int x, const int y);
+ virtual void setSelection(const BOOL preserve_line_breaks);
+
+public slots: // signals incoming from data source
+
+ void onRcvBlock(const char* txt,int len);
+
+signals:
+
+ void sndBlock(const char* txt,int len);
+ void ImageSizeChanged(int lines, int columns);
+ void changeColumns(int columns);
+ void changeTitle(int arg, const char* str);
+
+public:
+
+ virtual void onRcvChar(int);
+
+ virtual void setMode (int) = 0;
+ virtual void resetMode(int) = 0;
+
+ virtual void sendString(const char*) = 0;
+
+ virtual void setConnect(bool r);
+ void setColumns(int columns);
+
+ void setKeytrans(int no);
+ void setKeytrans(const char * no);
+
+protected:
+
+ TEWidget* gui;
+ TEScreen* scr; // referes to one `screen'
+ TEScreen* screen[2]; // 0 = primary, 1 = alternate
+ void setScreen(int n); // set `scr' to `screen[n]'
+
+ bool connected; // communicate with widget
+
+ void setCodec(int c); // codec number, 0 = locale, 1=utf8
+
+ QTextCodec* codec;
+ QTextCodec* localeCodec;
+ QTextDecoder* decoder;
+
+ KeyTrans* keytrans;
+
+// refreshing related material.
+// this is localized in the class.
+private slots: // triggered by timer
+
+ void showBulk();
+
+private:
+
+ void bulkNewline();
+ void bulkStart();
+ void bulkEnd();
+
+private:
+
+ QTimer bulk_timer;
+ int bulk_nlcnt; // bulk newline counter
+ char* SelectedText;
+ int bulk_incnt; // bulk counter
+
+
+};
+
+#endif // ifndef EMULATION_H
diff --git a/core/apps/embeddedkonsole/default.keytab.h b/core/apps/embeddedkonsole/default.keytab.h
new file mode 100644
index 0000000..503ea46
--- a/dev/null
+++ b/core/apps/embeddedkonsole/default.keytab.h
@@ -0,0 +1,103 @@
+ /* generated by '../tests/quote ../other/default.Keytab' */
+
+ "# [default.Keytab] Buildin Keyboard Table\n"
+ "\n"
+ "# --------------------------------------------------------------\n"
+ "#\n"
+ "# This file in included only for reference purposes. \n"
+ "#\n"
+ "# Modifying it does not have any effect (unless you\n"
+ "# derive the default.keytab.h and recompile konsole).\n"
+ "#\n"
+ "# To customize your keyboard, copy this file to something\n"
+ "# ending with .keytab and change it to meet you needs.\n"
+ "#\n"
+ "# --------------------------------------------------------------\n"
+ "\n"
+ "keyboard \"xterm (default)\"\n"
+ "\n"
+ "# --------------------------------------------------------------\n"
+ "#\n"
+ "# The syntax of each entry has the form\n"
+ "#\n"
+ "# \"key\" Keyname { (\"+\"|\"-\") Modename } \":\" (String|Operation)\n"
+ "#\n"
+ "# Keynames are those defined in <qnamespace.h>\n"
+ "# with the \"Qt::Key_\" prefix removed.\n"
+ "#\n"
+ "# Mode names are: Shift, Alt, Control.\n"
+ "#\n"
+ "# If the key is not found here, the text of the\n"
+ "# key event as provided by QT is emitted, possibly\n"
+ "# preceeded by ESC if the Alt key is pressed.\n"
+ "#\n"
+ "# --------------------------------------------------------------\n"
+ "#\n"
+ "# Note that this particular table is a \"risc\" version made to\n"
+ "# ease customization without bothering with obsolete details.\n"
+ "# See VT100.keytab for the more hairy stuff.\n"
+ "#\n"
+ "# --------------------------------------------------------------\n"
+ "\n"
+ "# common keys\n"
+ "\n"
+ "key Escape : \"\\E\"\n"
+ "key Tab : \"\\t\"\n"
+ "\n"
+ "key Return-Alt : \"\\r\"\n"
+ "key Return+Alt : \"\\E\\r\"\n"
+ "\n"
+ "# Backspace and Delete codes are preserving CTRL-H.\n"
+ "\n"
+ "key Backspace : \"\\x7f\"\n"
+ "\n"
+ "# cursor keys\n"
+ "\n"
+ "key Up -Shift : \"\\EOA\"\n"
+ "key Down -Shift : \"\\EOB\"\n"
+ "key Right -Shift : \"\\EOC\"\n"
+ "key Left -Shift : \"\\EOD\"\n"
+ "\n"
+ "# other grey PC keys\n"
+ "\n"
+ "key Enter : \"\\r\"\n"
+ "\n"
+ "key Home : \"\\E[1~\"\n"
+ "key Insert-Shift : \"\\E[2~\"\n"
+ "key Delete : \"\\E[3~\"\n"
+ "key End : \"\\E[4~\"\n"
+ "key Prior -Shift : \"\\E[5~\"\n"
+ "key Next -Shift : \"\\E[6~\"\n"
+ "\n"
+ "# function keys\n"
+ "\n"
+ "key F1 : \"\\E[11~\"\n"
+ "key F2 : \"\\E[12~\"\n"
+ "key F3 : \"\\E[13~\"\n"
+ "key F4 : \"\\E[14~\"\n"
+ "key F5 : \"\\E[15~\"\n"
+ "key F6 : \"\\E[17~\"\n"
+ "key F7 : \"\\E[18~\"\n"
+ "key F8 : \"\\E[19~\"\n"
+ "key F9 : \"\\E[20~\"\n"
+ "key F10 : \"\\E[21~\"\n"
+ "key F11 : \"\\E[23~\"\n"
+ "key F12 : \"\\E[24~\"\n"
+ "\n"
+ "# Work around dead keys\n"
+ "\n"
+ "key Space +Control : \"\\x00\"\n"
+ "\n"
+ "# Some keys are used by konsole to cause operations.\n"
+ "# The scroll* operations refer to the history buffer.\n"
+ "\n"
+ "key Left +Shift : prevSession\n"
+ "key Right +Shift : nextSession\n"
+ "key Up +Shift : scrollLineUp\n"
+ "key Prior +Shift : scrollPageUp\n"
+ "key Down +Shift : scrollLineDown\n"
+ "key Next +Shift : scrollPageDown\n"
+ "key Insert+Shift : emitSelection\n"
+ "\n"
+ "# keypad characters are not offered differently by Qt.\n"
+ ""
diff --git a/core/apps/embeddedkonsole/embeddedkonsole.pro b/core/apps/embeddedkonsole/embeddedkonsole.pro
new file mode 100755
index 0000000..b757ea5
--- a/dev/null
+++ b/core/apps/embeddedkonsole/embeddedkonsole.pro
@@ -0,0 +1,38 @@
+TEMPLATE = app
+
+CONFIG += qt warn_on release
+
+DESTDIR = $(QPEDIR)/bin
+
+HEADERS = TEWidget.h \
+ TEScreen.h \
+ TECommon.h \
+ TEHistory.h \
+ TEmulation.h \
+ TEmuVt102.h \
+ session.h \
+ keytrans.h \
+ konsole.h \
+ MyPty.h
+
+SOURCES = TEScreen.cpp \
+ TEWidget.cpp \
+ TEHistory.cpp \
+ TEmulation.cpp \
+ TEmuVt102.cpp \
+ session.cpp \
+ keytrans.cpp \
+ konsole.cpp \
+ main.cpp \
+ MyPty.cpp
+
+TARGET = embeddedkonsole
+
+INCLUDEPATH += $(QPEDIR)/include
+
+DEPENDPATH += $(QPEDIR)/include
+
+LIBS += -lqpe
+
+REQUIRES = embeddedkonsole
+
diff --git a/core/apps/embeddedkonsole/faded_bg.png b/core/apps/embeddedkonsole/faded_bg.png
new file mode 100644
index 0000000..7dbf6b4
--- a/dev/null
+++ b/core/apps/embeddedkonsole/faded_bg.png
Binary files differ
diff --git a/core/apps/embeddedkonsole/keytrans.cpp b/core/apps/embeddedkonsole/keytrans.cpp
new file mode 100644
index 0000000..d569ae0
--- a/dev/null
+++ b/core/apps/embeddedkonsole/keytrans.cpp
@@ -0,0 +1,706 @@
+/* -------------------------------------------------------------------------- */
+/* */
+/* [keytrans.C] Keyboard Translation */
+/* */
+/* -------------------------------------------------------------------------- */
+/* */
+/* 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> */
+/* */
+/* -------------------------------------------------------------------------- */
+
+/*
+ The keyboard translation table allows to configure konsoles behavior
+ on key strokes.
+
+ FIXME: some bug crept in, disallowing '\0' to be emitted.
+*/
+
+#include "keytrans.h"
+
+#include <qpe/qpeapplication.h>
+
+#include <qnamespace.h>
+#include <qbuffer.h>
+#include <qobject.h>
+#include <qdict.h>
+#include <qintdict.h>
+#include <qfile.h>
+#include <qglobal.h>
+#include <qdir.h>
+
+//#include <kstddirs.h>
+//nclude <klocale.h>
+
+#include <stdio.h>
+
+
+#undef USE_APPDATA_DIR
+
+
+#define HERE printf("%s(%d): here\n",__FILE__,__LINE__)
+
+/* KeyEntry
+
+ instances represent the individual assignments
+*/
+
+KeyTrans::KeyEntry::KeyEntry(int _ref, int _key, int _bits, int _mask, int _cmd, QString _txt)
+: ref(_ref), key(_key), bits(_bits), mask(_mask), cmd(_cmd), txt(_txt)
+{
+}
+
+KeyTrans::KeyEntry::~KeyEntry()
+{
+}
+
+bool KeyTrans::KeyEntry::matches(int _key, int _bits, int _mask)
+{ int m = mask & _mask;
+ return _key == key && (bits & m) == (_bits & m);
+}
+
+QString KeyTrans::KeyEntry::text()
+{
+ return txt;
+}
+
+/* KeyTrans
+
+ combines the individual assignments to a proper map
+ Takes part in a collection themself.
+*/
+
+KeyTrans::KeyTrans()
+{
+ path = "";
+ numb = 0;
+}
+
+KeyTrans::~KeyTrans()
+{
+}
+
+KeyTrans::KeyEntry* KeyTrans::addEntry(int ref, int key, int bits, int mask, int cmd, QString txt)
+// returns conflicting entry
+{
+ for (QListIterator<KeyEntry> it(table); it.current(); ++it)
+ {
+ if (it.current()->matches(key,bits,mask))
+ {
+ return it.current();
+ }
+ }
+ table.append(new KeyEntry(ref,key,bits,mask,cmd,txt));
+ return (KeyEntry*)NULL;
+}
+
+bool KeyTrans::findEntry(int key, int bits, int* cmd, const char** txt, int* len)
+{
+ for (QListIterator<KeyEntry> it(table); it.current(); ++it)
+ if (it.current()->matches(key,bits,0xffff))
+ {
+ *cmd = it.current()->cmd;
+ *txt = it.current()->txt.ascii();
+ *len = it.current()->txt.length();
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/* ------------------------------------------------------------------------- */
+/* */
+/* Scanner for keyboard configuration */
+/* */
+/* ------------------------------------------------------------------------- */
+
+// regular tokenizer
+/* Tokens
+ - Spaces
+ - Name (A-Za-z0-9)+
+ - String
+ - Opr on of +-:
+*/
+
+#define SYMName 0
+#define SYMString 1
+#define SYMEol 2
+#define SYMEof 3
+#define SYMOpr 4
+#define SYMError 5
+
+#define inRange(L,X,H) ((L <= X) && (X <= H))
+#define isNibble(X) (inRange('A',X,'F')||inRange('a',X,'f')||inRange('0',X,'9'))
+#define convNibble(X) (inRange('0',X,'9')?X-'0':X+10-(inRange('A',X,'F')?'A':'a'))
+
+class KeytabReader
+{
+public:
+ KeytabReader(QString p, QIODevice &d);
+public:
+ void getCc();
+ void getSymbol();
+ void parseTo(KeyTrans* kt);
+ void ReportError(const char* msg);
+ void ReportToken(); // diagnostic
+private:
+ int sym;
+ QString res;
+ int len;
+ int slinno;
+ int scolno;
+private:
+ int cc;
+ int linno;
+ int colno;
+ QIODevice* buf;
+ QString path;
+};
+
+
+KeytabReader::KeytabReader(QString p, QIODevice &d)
+{
+ path = p;
+ buf = &d;
+ cc = 0;
+}
+
+void KeytabReader::getCc()
+{
+ if (cc == '\n') { linno += 1; colno = 0; }
+ if (cc < 0) return;
+ cc = buf->getch();
+ colno += 1;
+}
+
+void KeytabReader::getSymbol()
+{
+ res = ""; len = 0; sym = SYMError;
+ while (cc == ' ') getCc(); // skip spaces
+ if (cc == '#') // skip comment
+ {
+ while (cc != '\n' && cc > 0) getCc();
+ }
+ slinno = linno;
+ scolno = colno;
+ if (cc <= 0)
+ {
+ sym = SYMEof; return; // eos
+ }
+ if (cc == '\n')
+ {
+ getCc();
+ sym = SYMEol; return; // eol
+ }
+ if (inRange('A',cc,'Z')||inRange('a',cc,'z')||inRange('0',cc,'9'))
+ {
+ while (inRange('A',cc,'Z') || inRange('a',cc,'z') || inRange('0',cc,'9'))
+ {
+ res = res + (char)cc;
+ getCc();
+ }
+ sym = SYMName;
+ return;
+ }
+ if (strchr("+-:",cc))
+ {
+ res = "";
+ res = res + (char)cc;
+ getCc();
+ sym = SYMOpr; return;
+ }
+ if (cc == '"')
+ {
+ getCc();
+ while (cc >= ' ' && cc != '"')
+ { int sc;
+ if (cc == '\\') // handle quotation
+ {
+ getCc();
+ switch (cc)
+ {
+ case 'E' : sc = 27; getCc(); break;
+ case 'b' : sc = 8; getCc(); break;
+ case 'f' : sc = 12; getCc(); break;
+ case 't' : sc = 9; getCc(); break;
+ case 'r' : sc = 13; getCc(); break;
+ case 'n' : sc = 10; getCc(); break;
+ case '\\' : // fall thru
+ case '"' : sc = cc; getCc(); break;
+ case 'x' : getCc();
+ sc = 0;
+ if (!isNibble(cc)) return; sc = 16*sc + convNibble(cc); getCc();
+ if (!isNibble(cc)) return; sc = 16*sc + convNibble(cc); getCc();
+ break;
+ default : return;
+ }
+ }
+ else
+ {
+ // regular char
+ sc = cc; getCc();
+ }
+ res = res + (char)sc;
+ len = len + 1;
+ }
+ if (cc != '"') return;
+ getCc();
+ sym = SYMString; return;
+ }
+}
+
+void KeytabReader::ReportToken() // diagnostic
+{
+ printf("sym(%d): ",slinno);
+ switch(sym)
+ {
+ case SYMEol : printf("End of line"); break;
+ case SYMEof : printf("End of file"); break;
+ case SYMName : printf("Name: %s",res.latin1()); break;
+ case SYMOpr : printf("Opr : %s",res.latin1()); break;
+ case SYMString : printf("String len %d,%d ",res.length(),len);
+ for (unsigned i = 0; i < res.length(); i++)
+ printf(" %02x(%c)",res.latin1()[i],res.latin1()[i]>=' '?res.latin1()[i]:'?');
+ break;
+ }
+ printf("\n");
+}
+
+void KeytabReader::ReportError(const char* msg) // diagnostic
+{
+ fprintf(stderr,"%s(%d,%d):error: %s.\n",path.ascii(),slinno,scolno,msg);
+}
+
+// local symbol tables ---------------------------------------------------------------------
+
+class KeyTransSymbols
+{
+public:
+ KeyTransSymbols();
+protected:
+ void defOprSyms();
+ void defModSyms();
+ void defKeySyms();
+ void defKeySym(const char* key, int val);
+ void defOprSym(const char* key, int val);
+ void defModSym(const char* key, int val);
+public:
+ QDict<QObject> keysyms;
+ QDict<QObject> modsyms;
+ QDict<QObject> oprsyms;
+};
+
+static KeyTransSymbols * syms = 0L;
+
+// parser ----------------------------------------------------------------------------------
+/* Syntax
+ - Line :: [KeyName { ("+" | "-") ModeName } ":" (String|CommandName)] "\n"
+ - Comment :: '#' (any but \n)*
+*/
+
+KeyTrans* KeyTrans::fromDevice(QString path, QIODevice &buf)
+{
+ KeyTrans* kt = new KeyTrans;
+ kt->path = path;
+ KeytabReader ktr(path,buf); ktr.parseTo(kt);
+ return kt;
+}
+
+
+#define assertSyntax(Cond,Message) if (!(Cond)) { ReportError(Message); goto ERROR; }
+
+void KeytabReader::parseTo(KeyTrans* kt)
+{
+ // Opening sequence
+
+ buf->open(IO_ReadOnly);
+ getCc();
+ linno = 1;
+ colno = 1;
+ getSymbol();
+
+Loop:
+ // syntax: ["key" KeyName { ("+" | "-") ModeName } ":" String/CommandName] ["#" Comment]
+ if (sym == SYMName && !strcmp(res.latin1(),"keyboard"))
+ {
+ getSymbol(); assertSyntax(sym == SYMString, "Header expected")
+ kt->hdr = res.latin1();
+ getSymbol(); assertSyntax(sym == SYMEol, "Text unexpected")
+ getSymbol(); // eoln
+ goto Loop;
+ }
+ if (sym == SYMName && !strcmp(res.latin1(),"key"))
+ {
+//printf("line %3d: ",startofsym);
+ getSymbol(); assertSyntax(sym == SYMName, "Name expected")
+ assertSyntax(syms->keysyms[res], "Unknown key name")
+ int key = (int)syms->keysyms[res]-1;
+//printf(" key %s (%04x)",res.latin1(),(int)syms->keysyms[res]-1);
+ getSymbol(); // + - :
+ int mode = 0;
+ int mask = 0;
+ while (sym == SYMOpr && (!strcmp(res.latin1(),"+") || !strcmp(res.latin1(),"-")))
+ {
+ bool on = !strcmp(res.latin1(),"+");
+ getSymbol();
+ // mode name
+ assertSyntax(sym == SYMName, "Name expected")
+ assertSyntax(syms->modsyms[res], "Unknown mode name")
+ int bits = (int)syms->modsyms[res]-1;
+ if (mask & (1 << bits))
+ {
+ fprintf(stderr,"%s(%d,%d): mode name used multible times.\n",path.ascii(),slinno,scolno);
+ }
+ else
+ {
+ mode |= (on << bits);
+ mask |= (1 << bits);
+ }
+//printf(", mode %s(%d) %s",res.latin1(),(int)syms->modsyms[res]-1,on?"on":"off");
+ getSymbol();
+ }
+ assertSyntax(sym == SYMOpr && !strcmp(res.latin1(),":"), "':' expected")
+ getSymbol();
+ // string or command
+ assertSyntax(sym == SYMName || sym == SYMString,"Command or string expected")
+ int cmd = 0;
+ if (sym == SYMName)
+ {
+ assertSyntax(syms->oprsyms[res], "Unknown operator name")
+ cmd = (int)syms->oprsyms[res]-1;
+//printf(": do %s(%d)",res.latin1(),(int)syms->oprsyms[res]-1);
+ }
+ if (sym == SYMString)
+ {
+ cmd = CMD_send;
+//printf(": send");
+//for (unsigned i = 0; i < res.length(); i++)
+//printf(" %02x(%c)",res.latin1()[i],res.latin1()[i]>=' '?res.latin1()[i]:'?');
+ }
+//printf(". summary %04x,%02x,%02x,%d\n",key,mode,mask,cmd);
+ KeyTrans::KeyEntry* ke = kt->addEntry(slinno,key,mode,mask,cmd,res);
+ if (ke)
+ {
+ fprintf(stderr,"%s(%d): keystroke already assigned in line %d.\n",path.ascii(),slinno,ke->ref);
+ }
+ getSymbol();
+ assertSyntax(sym == SYMEol, "Unexpected text")
+ goto Loop;
+ }
+ if (sym == SYMEol)
+ {
+ getSymbol();
+ goto Loop;
+ }
+
+ assertSyntax(sym == SYMEof, "Undecodable Line")
+
+ buf->close();
+ return;
+
+ERROR:
+ while (sym != SYMEol && sym != SYMEof) getSymbol(); // eoln
+ goto Loop;
+}
+
+
+KeyTrans* KeyTrans::defaultKeyTrans()
+{
+ QCString txt =
+#include "default.keytab.h"
+ ;
+ QBuffer buf(txt);
+ return fromDevice("[buildin]",buf);
+}
+
+KeyTrans* KeyTrans::fromFile(const char* path)
+{
+ QFile file(path);
+ return fromDevice(path,file);
+}
+
+// local symbol tables ---------------------------------------------------------------------
+// material needed for parsing the config file.
+// This is incomplete work.
+
+void KeyTransSymbols::defKeySym(const char* key, int val)
+{
+ keysyms.insert(key,(QObject*)(val+1));
+}
+
+void KeyTransSymbols::defOprSym(const char* key, int val)
+{
+ oprsyms.insert(key,(QObject*)(val+1));
+}
+
+void KeyTransSymbols::defModSym(const char* key, int val)
+{
+ modsyms.insert(key,(QObject*)(val+1));
+}
+
+void KeyTransSymbols::defOprSyms()
+{
+ // Modifier
+ defOprSym("scrollLineUp", CMD_scrollLineUp );
+ defOprSym("scrollLineDown",CMD_scrollLineDown);
+ defOprSym("scrollPageUp", CMD_scrollPageUp );
+ defOprSym("scrollPageDown",CMD_scrollPageDown);
+ defOprSym("emitSelection", CMD_emitSelection );
+ defOprSym("prevSession", CMD_prevSession );
+ defOprSym("nextSession", CMD_nextSession );
+}
+
+void KeyTransSymbols::defModSyms()
+{
+ // Modifier
+ defModSym("Shift", BITS_Shift );
+ defModSym("Control", BITS_Control );
+ defModSym("Alt", BITS_Alt );
+ // Modes
+ defModSym("BsHack", BITS_BsHack ); // deprecated
+ defModSym("Ansi", BITS_Ansi );
+ defModSym("NewLine", BITS_NewLine );
+ defModSym("AppCuKeys", BITS_AppCuKeys );
+}
+
+void KeyTransSymbols::defKeySyms()
+{
+ // Grey keys
+ defKeySym("Escape", Qt::Key_Escape );
+ defKeySym("Tab", Qt::Key_Tab );
+ defKeySym("Backtab", Qt::Key_Backtab );
+ defKeySym("Backspace", Qt::Key_Backspace );
+ defKeySym("Return", Qt::Key_Return );
+ defKeySym("Enter", Qt::Key_Enter );
+ defKeySym("Insert", Qt::Key_Insert );
+ defKeySym("Delete", Qt::Key_Delete );
+ defKeySym("Pause", Qt::Key_Pause );
+ defKeySym("Print", Qt::Key_Print );
+ defKeySym("SysReq", Qt::Key_SysReq );
+ defKeySym("Home", Qt::Key_Home );
+ defKeySym("End", Qt::Key_End );
+ defKeySym("Left", Qt::Key_Left );
+ defKeySym("Up", Qt::Key_Up );
+ defKeySym("Right", Qt::Key_Right );
+ defKeySym("Down", Qt::Key_Down );
+ defKeySym("Prior", Qt::Key_Prior );
+ defKeySym("Next", Qt::Key_Next );
+ defKeySym("Shift", Qt::Key_Shift );
+ defKeySym("Control", Qt::Key_Control );
+ defKeySym("Meta", Qt::Key_Meta );
+ defKeySym("Alt", Qt::Key_Alt );
+ defKeySym("CapsLock", Qt::Key_CapsLock );
+ defKeySym("NumLock", Qt::Key_NumLock );
+ defKeySym("ScrollLock", Qt::Key_ScrollLock );
+ defKeySym("F1", Qt::Key_F1 );
+ defKeySym("F2", Qt::Key_F2 );
+ defKeySym("F3", Qt::Key_F3 );
+ defKeySym("F4", Qt::Key_F4 );
+ defKeySym("F5", Qt::Key_F5 );
+ defKeySym("F6", Qt::Key_F6 );
+ defKeySym("F7", Qt::Key_F7 );
+ defKeySym("F8", Qt::Key_F8 );
+ defKeySym("F9", Qt::Key_F9 );
+ defKeySym("F10", Qt::Key_F10 );
+ defKeySym("F11", Qt::Key_F11 );
+ defKeySym("F12", Qt::Key_F12 );
+ defKeySym("F13", Qt::Key_F13 );
+ defKeySym("F14", Qt::Key_F14 );
+ defKeySym("F15", Qt::Key_F15 );
+ defKeySym("F16", Qt::Key_F16 );
+ defKeySym("F17", Qt::Key_F17 );
+ defKeySym("F18", Qt::Key_F18 );
+ defKeySym("F19", Qt::Key_F19 );
+ defKeySym("F20", Qt::Key_F20 );
+ defKeySym("F21", Qt::Key_F21 );
+ defKeySym("F22", Qt::Key_F22 );
+ defKeySym("F23", Qt::Key_F23 );
+ defKeySym("F24", Qt::Key_F24 );
+ defKeySym("F25", Qt::Key_F25 );
+ defKeySym("F26", Qt::Key_F26 );
+ defKeySym("F27", Qt::Key_F27 );
+ defKeySym("F28", Qt::Key_F28 );
+ defKeySym("F29", Qt::Key_F29 );
+ defKeySym("F30", Qt::Key_F30 );
+ defKeySym("F31", Qt::Key_F31 );
+ defKeySym("F32", Qt::Key_F32 );
+ defKeySym("F33", Qt::Key_F33 );
+ defKeySym("F34", Qt::Key_F34 );
+ defKeySym("F35", Qt::Key_F35 );
+ defKeySym("Super_L", Qt::Key_Super_L );
+ defKeySym("Super_R", Qt::Key_Super_R );
+ defKeySym("Menu", Qt::Key_Menu );
+ defKeySym("Hyper_L", Qt::Key_Hyper_L );
+ defKeySym("Hyper_R", Qt::Key_Hyper_R );
+
+ // Regular keys
+ defKeySym("Space", Qt::Key_Space );
+ defKeySym("Exclam", Qt::Key_Exclam );
+ defKeySym("QuoteDbl", Qt::Key_QuoteDbl );
+ defKeySym("NumberSign", Qt::Key_NumberSign );
+ defKeySym("Dollar", Qt::Key_Dollar );
+ defKeySym("Percent", Qt::Key_Percent );
+ defKeySym("Ampersand", Qt::Key_Ampersand );
+ defKeySym("Apostrophe", Qt::Key_Apostrophe );
+ defKeySym("ParenLeft", Qt::Key_ParenLeft );
+ defKeySym("ParenRight", Qt::Key_ParenRight );
+ defKeySym("Asterisk", Qt::Key_Asterisk );
+ defKeySym("Plus", Qt::Key_Plus );
+ defKeySym("Comma", Qt::Key_Comma );
+ defKeySym("Minus", Qt::Key_Minus );
+ defKeySym("Period", Qt::Key_Period );
+ defKeySym("Slash", Qt::Key_Slash );
+ defKeySym("0", Qt::Key_0 );
+ defKeySym("1", Qt::Key_1 );
+ defKeySym("2", Qt::Key_2 );
+ defKeySym("3", Qt::Key_3 );
+ defKeySym("4", Qt::Key_4 );
+ defKeySym("5", Qt::Key_5 );
+ defKeySym("6", Qt::Key_6 );
+ defKeySym("7", Qt::Key_7 );
+ defKeySym("8", Qt::Key_8 );
+ defKeySym("9", Qt::Key_9 );
+ defKeySym("Colon", Qt::Key_Colon );
+ defKeySym("Semicolon", Qt::Key_Semicolon );
+ defKeySym("Less", Qt::Key_Less );
+ defKeySym("Equal", Qt::Key_Equal );
+ defKeySym("Greater", Qt::Key_Greater );
+ defKeySym("Question", Qt::Key_Question );
+ defKeySym("At", Qt::Key_At );
+ defKeySym("A", Qt::Key_A );
+ defKeySym("B", Qt::Key_B );
+ defKeySym("C", Qt::Key_C );
+ defKeySym("D", Qt::Key_D );
+ defKeySym("E", Qt::Key_E );
+ defKeySym("F", Qt::Key_F );
+ defKeySym("G", Qt::Key_G );
+ defKeySym("H", Qt::Key_H );
+ defKeySym("I", Qt::Key_I );
+ defKeySym("J", Qt::Key_J );
+ defKeySym("K", Qt::Key_K );
+ defKeySym("L", Qt::Key_L );
+ defKeySym("M", Qt::Key_M );
+ defKeySym("N", Qt::Key_N );
+ defKeySym("O", Qt::Key_O );
+ defKeySym("P", Qt::Key_P );
+ defKeySym("Q", Qt::Key_Q );
+ defKeySym("R", Qt::Key_R );
+ defKeySym("S", Qt::Key_S );
+ defKeySym("T", Qt::Key_T );
+ defKeySym("U", Qt::Key_U );
+ defKeySym("V", Qt::Key_V );
+ defKeySym("W", Qt::Key_W );
+ defKeySym("X", Qt::Key_X );
+ defKeySym("Y", Qt::Key_Y );
+ defKeySym("Z", Qt::Key_Z );
+ defKeySym("BracketLeft", Qt::Key_BracketLeft );
+ defKeySym("Backslash", Qt::Key_Backslash );
+ defKeySym("BracketRight", Qt::Key_BracketRight);
+ defKeySym("AsciiCircum", Qt::Key_AsciiCircum );
+ defKeySym("Underscore", Qt::Key_Underscore );
+ defKeySym("QuoteLeft", Qt::Key_QuoteLeft );
+ defKeySym("BraceLeft", Qt::Key_BraceLeft );
+ defKeySym("Bar", Qt::Key_Bar );
+ defKeySym("BraceRight", Qt::Key_BraceRight );
+ defKeySym("AsciiTilde", Qt::Key_AsciiTilde );
+}
+
+KeyTransSymbols::KeyTransSymbols()
+{
+ defModSyms();
+ defOprSyms();
+ defKeySyms();
+}
+
+// Global material -----------------------------------------------------------
+
+static int keytab_serial = 0; //FIXME: remove,localize
+
+static QIntDict<KeyTrans> * numb2keymap = 0L;
+static QDict<KeyTrans> * path2keymap = 0L;
+
+KeyTrans* KeyTrans::find(int numb)
+{
+ KeyTrans* res = numb2keymap->find(numb);
+ return res ? res : numb2keymap->find(0);
+}
+
+KeyTrans* KeyTrans::find(const char* path)
+{
+ KeyTrans* res = path2keymap->find(path);
+ return res ? res : numb2keymap->find(0);
+}
+
+int KeyTrans::count()
+{
+ return numb2keymap->count();
+}
+
+void KeyTrans::addKeyTrans()
+{
+ this->numb = keytab_serial ++;
+ numb2keymap->insert(numb,this);
+ path2keymap->insert(path,this);
+}
+
+void KeyTrans::loadAll()
+{
+ if (!numb2keymap)
+ numb2keymap = new QIntDict<KeyTrans>;
+ if (!path2keymap)
+ path2keymap = new QDict<KeyTrans>;
+ if (!syms)
+ syms = new KeyTransSymbols;
+
+ defaultKeyTrans()->addKeyTrans();
+
+
+ QString path = QPEApplication::qpeDir() + "etc/keytabs";
+ QDir dir(path);
+ QStringList lst = dir.entryList("*.keytab");
+
+ for(QStringList::Iterator it = lst.begin(); it != lst.end(); ++it ) {
+ QFile file(path + "/" + *it);
+ KeyTrans* sc = KeyTrans::fromDevice(*it, file);
+ if (sc) {
+ sc->addKeyTrans();
+ }
+ }
+
+}
+
+// Debugging material -----------------------------------------------------------
+/*
+void TestTokenizer(QBuffer &buf)
+{
+ // opening sequence
+
+ buf.open(IO_ReadOnly);
+ cc = buf.getch();
+ lineno = 1;
+
+ // Test tokenizer
+
+ while (getSymbol(buf)) ReportToken();
+
+ buf.close();
+}
+
+void test()
+{
+ // Opening sequence
+
+ QCString txt =
+#include "default.keytab.h"
+ ;
+ QBuffer buf(txt);
+ if (0) TestTokenizer(buf);
+ if (1) { KeyTrans kt; kt.scanTable(buf); }
+}
+*/
diff --git a/core/apps/embeddedkonsole/keytrans.h b/core/apps/embeddedkonsole/keytrans.h
new file mode 100644
index 0000000..ef6ed15
--- a/dev/null
+++ b/core/apps/embeddedkonsole/keytrans.h
@@ -0,0 +1,93 @@
+/* -------------------------------------------------------------------------- */
+/* */
+/* [keytrans.h] X Terminal Emulation */
+/* */
+/* -------------------------------------------------------------------------- */
+/* */
+/* 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> */
+/* */
+/* -------------------------------------------------------------------------- */
+
+#ifndef KEYTRANS_H
+#define KEYTRANS_H
+
+#include <qstring.h>
+#include <qlist.h>
+#include <qiodevice.h>
+
+#define BITS_NewLine 0
+#define BITS_BsHack 1
+#define BITS_Ansi 2
+#define BITS_AppCuKeys 3
+#define BITS_Control 4
+#define BITS_Shift 5
+#define BITS_Alt 6
+#define BITS_COUNT 7
+
+#define CMD_send 0
+#define CMD_emitSelection 1
+#define CMD_scrollPageUp 2
+#define CMD_scrollPageDown 3
+#define CMD_scrollLineUp 4
+#define CMD_scrollLineDown 5
+#define CMD_prevSession 6
+#define CMD_nextSession 7
+
+#define BITS(x,v) ((((v)!=0)<<(x)))
+
+
+class KeyTrans
+{
+public:
+ KeyTrans();
+ ~KeyTrans();
+ static KeyTrans* defaultKeyTrans();
+ static KeyTrans* fromFile(const char* path);
+ static KeyTrans* find(int numb);
+ static KeyTrans* find(const char* path);
+public:
+ static int count();
+ static void loadAll();
+public:
+ bool findEntry(int key, int bits, int* cmd, const char** txt, int* len);
+private:
+ void addKeyTrans();
+ static KeyTrans* fromDevice(QString path, QIODevice &buf);
+public:
+ class KeyEntry
+ {
+ public:
+ KeyEntry(int ref, int key, int bits, int mask, int cmd, QString txt);
+ ~KeyEntry();
+ public:
+ bool matches(int key, int bits, int mask);
+ QString text();
+ public:
+ int ref;
+ private:
+ int key;
+ int bits;
+ int mask;
+ public:
+ int cmd;
+ QString txt;
+ };
+public:
+ KeyEntry* addEntry(int ref, int key, int bits, int mask, int cmd, QString txt);
+private:
+ QList<KeyEntry> table;
+public: //FIXME: we'd do better
+ QString hdr;
+ int numb;
+ QString path;
+};
+
+#endif
diff --git a/core/apps/embeddedkonsole/konsole.cpp b/core/apps/embeddedkonsole/konsole.cpp
new file mode 100644
index 0000000..7253baf
--- a/dev/null
+++ b/core/apps/embeddedkonsole/konsole.cpp
@@ -0,0 +1,512 @@
+/* ---------------------------------------------------------------------- */
+/* */
+/* [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> */
+/* */
+/* -------------------------------------------------------------------------- */
+
+#include <qpe/resource.h>
+
+#include <qdir.h>
+#include <qevent.h>
+#include <qdragobject.h>
+#include <qobjectlist.h>
+#include <qtoolbutton.h>
+#include <qpe/qpetoolbar.h>
+#include <qpushbutton.h>
+#include <qfontdialog.h>
+#include <qglobal.h>
+#include <qpainter.h>
+#include <qpe/qpemenubar.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 <sys/wait.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#include "konsole.h"
+#include "keytrans.h"
+
+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 ",
+ //"ls -la ",
+ "cd ",
+ "pwd",
+ //"cat",
+ //"less ",
+ //"vi ",
+ //"man ",
+ "echo ",
+ "set ",
+ //"ps",
+ "ps aux",
+ //"tar",
+ //"tar -zxf",
+ "grep ",
+ //"grep -i",
+ //"mkdir",
+ "cp ",
+ "mv ",
+ "rm ",
+ "rmdir ",
+ //"chmod",
+ //"su",
+// "top",
+ //"find",
+ //"make",
+ //"tail",
+ "cardctl eject",
+ "ifconfig ",
+// "iwconfig eth0 ",
+ "nc localhost 7777",
+ "nc localhost 7776",
+ //"mount /dev/hda1",
+
+/*
+ "gzip",
+ "gunzip",
+ "chgrp",
+ "chown",
+ "date",
+ "dd",
+ "df",
+ "dmesg",
+ "fuser",
+ "hostname",
+ "kill",
+ "killall",
+ "ln",
+ "ping",
+ "mount",
+ "more",
+ "sort",
+ "touch",
+ "umount",
+ "mknod",
+ "netstat",
+*/
+
+ "exit",
+ NULL
+};
+
+
+Konsole::Konsole(QWidget* parent, const char* name, WFlags fl) :
+ QMainWindow(parent, name, fl)
+{
+ QStrList args;
+ init("/bin/sh",args);
+}
+
+Konsole::Konsole(const char* name, const char* _pgm, QStrList & _args, int)
+ : QMainWindow(0, name)
+{
+ init(_pgm,_args);
+}
+
+void Konsole::init(const char* _pgm, QStrList & _args)
+{
+ b_scroll = TRUE; // histon;
+ n_keytab = 0;
+ n_render = 0;
+
+ setCaption( tr("Terminal") );
+ setIcon( Resource::loadPixmap( "konsole" ) );
+
+ Config cfg("Konsole");
+ cfg.setGroup("Konsole");
+
+ // 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 ////////////////////////////////////
+ nsessions = 0;
+ tab = new EKNumTabWidget(this);
+ tab->setTabPosition(QTabWidget::Bottom);
+ connect(tab, SIGNAL(currentChanged(QWidget*)), this, SLOT(switchSession(QWidget*)));
+
+ // create terminal toolbar ////////////////////////////////////////////////
+ setToolBarsMovable( FALSE );
+ QPEToolBar *menuToolBar = new QPEToolBar( this );
+ menuToolBar->setHorizontalStretchable( TRUE );
+
+ QPEMenuBar *menuBar = new QPEMenuBar( 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);
+
+ connect( fontList, SIGNAL( activated(int) ), this, SLOT( fontChanged(int) ));
+
+ menuBar->insertItem( tr("Font"), fontList );
+
+ QPEToolBar *toolbar = new QPEToolBar( 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 );
+*/
+
+ QPEToolBar *secondToolBar = new QPEToolBar( this );
+ secondToolBar->setHorizontalStretchable( TRUE );
+
+ QComboBox *commonCombo = new QComboBox( secondToolBar );
+// commonCombo->setEditable( TRUE );
+ for (int i = 0; commonCmds[i] != NULL; i++)
+ commonCombo->insertItem( commonCmds[i], i );
+ connect( commonCombo, SIGNAL( activated(int) ), this, SLOT( enterCommand(int) ));
+
+ // create applications /////////////////////////////////////////////////////
+ setCentralWidget(tab);
+
+ // load keymaps ////////////////////////////////////////////////////////////
+ KeyTrans::loadAll();
+ for (int i = 0; i < KeyTrans::count(); i++)
+ { KeyTrans* s = KeyTrans::find(i);
+ assert( s );
+ }
+
+ se_pgm = _pgm;
+ se_args = _args;
+
+ // read and apply default values ///////////////////////////////////////////
+ resize(321, 321); // Dummy.
+ QSize currentSize = size();
+ if (currentSize != size())
+ defaultSize = size();
+}
+
+void Konsole::show()
+{
+ if ( !nsessions ) {
+ newSession();
+ }
+ QMainWindow::show();
+}
+
+void Konsole::initSession(const char*, QStrList &)
+{
+ QMainWindow::show();
+}
+
+Konsole::~Konsole()
+{
+ while (nsessions > 0) {
+ doneSession(getTe()->currentSession, 0);
+ }
+
+ Config cfg("Konsole");
+ cfg.setGroup("Konsole");
+ cfg.writeEntry("FontID", cfont);
+}
+
+void Konsole::fontChanged(int f)
+{
+ VTFont* font = fonts.at(f);
+ if (font != 0) {
+ for(uint i = 0; i < fonts.count(); i++) {
+ fontList->setItemChecked(i, (i == (uint) f) ? TRUE : FALSE);
+ }
+
+ cfont = f;
+
+ TEWidget* te = getTe();
+ if (te != 0) {
+ te->setVTFont(font->getFont());
+ }
+ }
+}
+
+void Konsole::enterCommand(int c)
+{
+ TEWidget* te = getTe();
+ if (te != 0) {
+ QString text = commonCmds[c];
+ te->emitText(text);
+ }
+}
+
+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)
+{
+ 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)
+{
+ 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() {
+ TEWidget* te = new TEWidget(tab);
+ te->setBackgroundMode(PaletteBase);
+ 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++;
+}
+
+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;
+ }
+ }
+}
diff --git a/core/apps/embeddedkonsole/konsole.h b/core/apps/embeddedkonsole/konsole.h
new file mode 100644
index 0000000..819ea5d
--- a/dev/null
+++ b/core/apps/embeddedkonsole/konsole.h
@@ -0,0 +1,125 @@
+/* ----------------------------------------------------------------------- */
+/* */
+/* [konsole.h] 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> */
+/* */
+/* -------------------------------------------------------------------------- */
+
+#ifndef KONSOLE_H
+#define KONSOLE_H
+
+
+#include <qmainwindow.h>
+#include <qaction.h>
+#include <qpopupmenu.h>
+#include <qstrlist.h>
+#include <qintdict.h>
+#include <qptrdict.h>
+#include <qtabwidget.h>
+
+#include "MyPty.h"
+#include "TEWidget.h"
+#include "TEmuVt102.h"
+#include "session.h"
+
+class EKNumTabWidget;
+
+class Konsole : public QMainWindow
+{
+Q_OBJECT
+
+public:
+
+ Konsole(QWidget* parent = 0, const char* name = 0, WFlags fl = 0);
+ Konsole(const char * name, const char* pgm, QStrList & _args, int histon);
+ ~Konsole();
+ void setColLin(int columns, int lines);
+
+ void show();
+
+private slots:
+ void doneSession(TESession*,int);
+ void changeColumns(int);
+ void fontChanged(int);
+ void enterCommand(int);
+ void hitEnter();
+ void hitSpace();
+ void hitTab();
+ void hitPaste();
+ void hitUp();
+ void hitDown();
+ void switchSession(QWidget *);
+ void newSession();
+
+private:
+ void init(const char* _pgm, QStrList & _args);
+ void initSession(const char* _pgm, QStrList & _args);
+ void runSession(TESession* s);
+ void setColorPixmaps();
+ void setHistory(bool);
+ QSize calcSize(int columns, int lines);
+ TEWidget* getTe();
+
+private:
+ class VTFont
+ {
+ public:
+ VTFont(QString name, QFont& font)
+ {
+ this->name = name;
+ this->font = font;
+ }
+
+ QFont& getFont()
+ {
+ return font;
+ }
+
+ QString getName()
+ {
+ return name;
+ }
+
+ private:
+ QString name;
+ QFont font;
+ };
+
+ EKNumTabWidget* tab;
+ int nsessions;
+ QList<VTFont> fonts;
+ int cfont;
+ QCString se_pgm;
+ QStrList se_args;
+
+ QPopupMenu* fontList;
+
+ // history scrolling I think
+ bool b_scroll;
+
+ int n_keytab;
+ int n_scroll;
+ int n_render;
+ QString pmPath; // pixmap path
+ QString dropText;
+ QFont defaultFont;
+ QSize defaultSize;
+
+};
+
+#endif
+
diff --git a/core/apps/embeddedkonsole/main.cpp b/core/apps/embeddedkonsole/main.cpp
new file mode 100644
index 0000000..e3ba346
--- a/dev/null
+++ b/core/apps/embeddedkonsole/main.cpp
@@ -0,0 +1,60 @@
+/* ---------------------------------------------------------------------- */
+/* */
+/* [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> */
+/* */
+/* -------------------------------------------------------------------------- */
+
+#include "konsole.h"
+
+#include <qpe/qpeapplication.h>
+
+#include <qfile.h>
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+
+/* --| main |------------------------------------------------------ */
+int main(int argc, char* argv[])
+{
+ setuid(getuid()); setgid(getgid()); // drop privileges
+
+ QPEApplication a( argc, argv );
+
+#ifdef FAKE_CTRL_AND_ALT
+ QPEApplication::grabKeyboard(); // for CTRL and ALT
+#endif
+
+ QStrList tmp;
+ const char* shell = getenv("SHELL");
+ if (shell == NULL || *shell == '\0')
+ shell = "/bin/sh";
+
+ // sh is completely broken on familiar. Let's try to get something better
+ if ( qstrcmp( shell, "/bin/shell" ) == 0 && QFile::exists( "/bin/bash" ) )
+ shell = "/bin/bash";
+
+ putenv((char*)"COLORTERM="); // to trigger mc's color detection
+
+ Konsole m( "test", shell, tmp, TRUE );
+ m.setCaption( Konsole::tr("Terminal") );
+ a.showMainWidget( &m );
+
+ return a.exec();
+}
diff --git a/core/apps/embeddedkonsole/qpe-embeddedkonsole.control b/core/apps/embeddedkonsole/qpe-embeddedkonsole.control
new file mode 100644
index 0000000..9b7c355
--- a/dev/null
+++ b/core/apps/embeddedkonsole/qpe-embeddedkonsole.control
@@ -0,0 +1,9 @@
+Files: bin/embeddedkonsole apps/Applications/embeddedkonsole.desktop pics/konsole etc/keytabs/*
+Priority: optional
+Section: qpe/applications
+Maintainer: Warwick Allison <warwick@trolltech.com>
+Architecture: arm
+Version: $QPE_VERSION-4
+Depends: qpe-base ($QPE_VERSION), ptydevs
+Description: KDE's konsole (shell terminal)
+ Ported to the Qtopia environment.
diff --git a/core/apps/embeddedkonsole/session.cpp b/core/apps/embeddedkonsole/session.cpp
new file mode 100644
index 0000000..520af86
--- a/dev/null
+++ b/core/apps/embeddedkonsole/session.cpp
@@ -0,0 +1,157 @@
+/* -------------------------------------------------------------------------- */
+/* */
+/* Ported Konsole to Qt/Embedded */
+/* */
+/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */
+/* */
+/* -------------------------------------------------------------------------- */
+#include "session.h"
+#include <qpushbutton.h>
+// #include <kdebug.h>
+
+#include <stdlib.h>
+
+#define HERE fprintf(stderr,"%s(%d): here\n",__FILE__,__LINE__)
+
+/*! \class TESession
+
+ Sessions are combinations of TEPTy and Emulations.
+
+ The stuff in here does not belong to the terminal emulation framework,
+ but to main.C. 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(QMainWindow* main, TEWidget* te, const char* _pgm, QStrList & _args, const char *_term) : schema_no(0), font_no(3), pgm(_pgm), args(_args)
+{
+ // sh = new TEPty();
+ sh = new MyPty();
+ em = new TEmuVt102(te);
+
+ term = _term;
+
+ sh->setSize(te->Lines(),te->Columns()); // not absolutely nessesary
+ QObject::connect( sh,SIGNAL(block_in(const char*,int)),
+ em,SLOT(onRcvBlock(const char*,int)) );
+ QObject::connect( em,SIGNAL(ImageSizeChanged(int,int)),
+ sh,SLOT(setSize(int,int)));
+
+ // 'main' should do those connects itself, somehow.
+ // These aren't KTMW's slots, but konsole's.(David)
+
+/*
+ QObject::connect( em,SIGNAL(ImageSizeChanged(int,int)),
+ main,SLOT(notifySize(int,int)));
+*/
+ QObject::connect( em,SIGNAL(sndBlock(const char*,int)),
+ sh,SLOT(send_bytes(const char*,int)) );
+ QObject::connect( em,SIGNAL(changeColumns(int)),
+ main,SLOT(changeColumns(int)) );
+/*
+ QObject::connect( em,SIGNAL(changeTitle(int, const QString&)),
+ main,SLOT(changeTitle(int, const QString&)) );
+*/
+ QObject::connect( sh,SIGNAL(done(int)), this,SLOT(done(int)) );
+}
+
+
+
+void TESession::run()
+{
+ //kdDebug() << "Running the session!" << pgm << "\n";
+ sh->run(pgm,args,term.data(),FALSE);
+}
+
+void TESession::kill(int ) // signal)
+{
+// sh->kill(signal);
+}
+
+TESession::~TESession()
+{
+ QObject::disconnect( sh, SIGNAL( done( int ) ),
+ this, SLOT( done( int ) ) );
+ delete em;
+ delete sh;
+}
+
+void TESession::setConnect(bool c)
+{
+ em->setConnect(c);
+}
+
+void TESession::done(int status)
+{
+ emit done(this,status);
+}
+
+void TESession::terminate()
+{
+ delete this;
+}
+
+TEmulation* TESession::getEmulation()
+{
+ return em;
+}
+
+// following interfaces might be misplaced ///
+
+int TESession::schemaNo()
+{
+ return schema_no;
+}
+
+int TESession::keymap()
+{
+ return keymap_no;
+}
+
+int TESession::fontNo()
+{
+ return font_no;
+}
+
+const char* TESession::emuName()
+{
+ return term.data();
+}
+
+void TESession::setSchemaNo(int sn)
+{
+ schema_no = sn;
+}
+
+void TESession::setKeymapNo(int kn)
+{
+ keymap_no = kn;
+ em->setKeytrans(kn);
+}
+
+void TESession::setFontNo(int fn)
+{
+ font_no = fn;
+}
+
+void TESession::setTitle(const QString& title)
+{
+ this->title = title;
+}
+
+const QString& TESession::Title()
+{
+ return title;
+}
+
+void TESession::setHistory(bool on)
+{
+ em->setHistory( on );
+}
+
+bool TESession::history()
+{
+ return em->history();
+}
+
+// #include "session.moc"
diff --git a/core/apps/embeddedkonsole/session.h b/core/apps/embeddedkonsole/session.h
new file mode 100644
index 0000000..4a61569
--- a/dev/null
+++ b/core/apps/embeddedkonsole/session.h
@@ -0,0 +1,93 @@
+/* -------------------------------------------------------------------------- */
+/* */
+/* [session.h] Testbed for TE framework */
+/* */
+/* -------------------------------------------------------------------------- */
+/* */
+/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */
+/* */
+/* This file is part of Konsole, an X terminal. */
+/* */
+/* -------------------------------------------------------------------------- */
+/* */
+/* Ported Konsole to Qt/Embedded */
+/* */
+/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */
+/* */
+/* -------------------------------------------------------------------------- */
+
+#ifndef SESSION_H
+#define SESSION_H
+
+#include <qapplication.h>
+#include <qmainwindow.h>
+#include <qstrlist.h>
+
+#include "MyPty.h"
+#include "TEWidget.h"
+#include "TEmuVt102.h"
+
+class TESession : public QObject
+{ Q_OBJECT
+
+public:
+
+ TESession(QMainWindow* main, TEWidget* w,
+ const char* pgm, QStrList & _args,
+ const char* term);
+ ~TESession();
+
+public:
+
+ void setConnect(bool r);
+ TEmulation* getEmulation(); // to control emulation
+ bool isSecure();
+
+public:
+
+ int schemaNo();
+ int fontNo();
+ const char* emuName();
+ const QString& Title();
+ bool history();
+ int keymap();
+
+ void setHistory(bool on);
+ void setSchemaNo(int sn);
+ void setKeymapNo(int kn);
+ void setFontNo(int fn);
+ void setTitle(const QString& title);
+ void kill(int signal);
+
+public slots:
+
+ void run();
+ void done(int status);
+ void terminate();
+
+signals:
+
+ void done(TESession*, int);
+
+private:
+
+ // TEPty* sh;
+ MyPty* sh;
+ TEWidget* te;
+ TEmulation* em;
+
+ //FIXME: using the indices here
+ // is propably very bad. We should
+ // use a persistent reference instead.
+ int schema_no;
+ int font_no;
+ int keymap_no;
+ QString title;
+
+ const char* pgm;
+ QStrList args;
+
+ QCString term;
+};
+
+#endif