summaryrefslogtreecommitdiff
path: root/core/apps
Unidiff
Diffstat (limited to 'core/apps') (more/less context) (ignore whitespace changes)
-rw-r--r--core/apps/calibrate/.cvsignore3
-rw-r--r--core/apps/calibrate/calibrate.cpp243
-rw-r--r--core/apps/calibrate/calibrate.h67
-rw-r--r--core/apps/calibrate/calibrate.pro1
-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
-rw-r--r--core/apps/helpbrowser/.cvsignore2
-rw-r--r--core/apps/helpbrowser/Makefile.in119
-rw-r--r--core/apps/helpbrowser/helpbrowser.cpp227
-rw-r--r--core/apps/helpbrowser/helpbrowser.h69
-rw-r--r--core/apps/helpbrowser/helpbrowser.pro12
-rw-r--r--core/apps/helpbrowser/main.cpp34
-rw-r--r--core/apps/helpbrowser/qpe-helpbrowser.control10
-rw-r--r--core/apps/qcop/.cvsignore3
-rw-r--r--core/apps/qcop/Makefile.in102
-rw-r--r--core/apps/qcop/main.cpp85
-rw-r--r--core/apps/qcop/qcop.pro10
-rw-r--r--core/apps/qcop/qpe-qcop.control9
-rw-r--r--core/apps/textedit/.cvsignore3
-rw-r--r--core/apps/textedit/Makefile.in125
-rw-r--r--core/apps/textedit/inserttable.ui103
-rw-r--r--core/apps/textedit/main.cpp35
-rw-r--r--core/apps/textedit/qpe-textedit.control9
-rw-r--r--core/apps/textedit/qtextedit.h282
-rw-r--r--core/apps/textedit/textedit.cpp594
-rw-r--r--core/apps/textedit/textedit.h102
-rw-r--r--core/apps/textedit/textedit.po108
-rw-r--r--core/apps/textedit/textedit.pro16
52 files changed, 9831 insertions, 0 deletions
diff --git a/core/apps/calibrate/.cvsignore b/core/apps/calibrate/.cvsignore
new file mode 100644
index 0000000..edfa921
--- a/dev/null
+++ b/core/apps/calibrate/.cvsignore
@@ -0,0 +1,3 @@
1moc_*
2*.moc
3Makefile
diff --git a/core/apps/calibrate/calibrate.cpp b/core/apps/calibrate/calibrate.cpp
new file mode 100644
index 0000000..96cd1ca
--- a/dev/null
+++ b/core/apps/calibrate/calibrate.cpp
@@ -0,0 +1,243 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#include "calibrate.h"
22
23#include <qpe/resource.h>
24
25#include <qapplication.h>
26
27#if defined(Q_WS_QWS) || defined(_WS_QWS_)
28
29#include <qpainter.h>
30#include <qtimer.h>
31#include <qwindowsystem_qws.h>
32#include <qgfx_qws.h>
33
34
35Calibrate::Calibrate(QWidget* parent, const char * name, WFlags wf) :
36 QDialog( parent, name, TRUE, wf | WStyle_Tool | WStyle_Customize | WStyle_StaysOnTop )
37{
38 showCross = TRUE;
39 const int offset = 30;
40 QRect desk = qApp->desktop()->geometry();
41 setGeometry( 0, 0, desk.width(), desk.height() );
42 if ( desk.height() < 250 ) {
43 int w = desk.height()/3;
44 logo.convertFromImage(Resource::loadImage("qtlogo").smoothScale(w,w));
45 } else {
46 logo = Resource::loadPixmap( "qtlogo" );
47 }
48 cd.screenPoints[QWSPointerCalibrationData::TopLeft] = QPoint( offset, offset );
49 cd.screenPoints[QWSPointerCalibrationData::BottomLeft] = QPoint( offset, qt_screen->deviceHeight() - offset );
50 cd.screenPoints[QWSPointerCalibrationData::BottomRight] = QPoint( qt_screen->deviceWidth() - offset, qt_screen->deviceHeight() - offset );
51 cd.screenPoints[QWSPointerCalibrationData::TopRight] = QPoint( qt_screen->deviceWidth() - offset, offset );
52 cd.screenPoints[QWSPointerCalibrationData::Center] = QPoint( qt_screen->deviceWidth()/2, qt_screen->deviceHeight()/2 );
53 goodcd = cd;
54 reset();
55
56 timer = new QTimer( this );
57 connect( timer, SIGNAL(timeout()), this, SLOT(timeout()) );
58}
59
60Calibrate::~Calibrate()
61{
62 store();
63}
64
65void Calibrate::show()
66{
67 grabMouse();
68 QWSServer::mouseHandler()->getCalibration(&goodcd);
69 QWSServer::mouseHandler()->clearCalibration();
70 QDialog::show();
71}
72
73void Calibrate::store()
74{
75 QWSServer::mouseHandler()->calibrate( &goodcd );
76}
77
78void Calibrate::hide()
79{
80 if ( isVisible() )
81 store();
82 QDialog::hide();
83}
84
85void Calibrate::reset()
86{
87 penPos = QPoint();
88 location = QWSPointerCalibrationData::TopLeft;
89 crossPos = fromDevice( cd.screenPoints[location] );
90}
91
92QPoint Calibrate::fromDevice( const QPoint &p )
93{
94 return qt_screen->mapFromDevice( p,
95 QSize(qt_screen->deviceWidth(), qt_screen->deviceHeight()) );
96}
97
98bool Calibrate::sanityCheck()
99{
100 QPoint tl = cd.devPoints[QWSPointerCalibrationData::TopLeft];
101 QPoint tr = cd.devPoints[QWSPointerCalibrationData::TopRight];
102 QPoint bl = cd.devPoints[QWSPointerCalibrationData::BottomLeft];
103 QPoint br = cd.devPoints[QWSPointerCalibrationData::BottomRight];
104
105 int vl = QABS( tl.y() - bl.y() );
106 int vr = QABS( tr.y() - br.y() );
107 int diff = QABS( vl - vr );
108 int avg = ( vl + vr ) / 2;
109 if ( diff > avg / 20 ) // 5% leeway
110 return FALSE;
111
112 int ht = QABS( tl.x() - tr.x() );
113 int hb = QABS( br.x() - bl.x() );
114 diff = QABS( ht - hb );
115 avg = ( ht + hb ) / 2;
116 if ( diff > avg / 20 ) // 5% leeway
117 return FALSE;
118
119 return TRUE;
120}
121
122void Calibrate::moveCrosshair( QPoint pt )
123{
124/*
125 QPainter p( this );
126 p.drawPixmap( crossPos.x()-8, crossPos.y()-8, saveUnder );
127 saveUnder = QPixmap::grabWindow( winId(), pt.x()-8, pt.y()-8, 16, 16 );
128 p.drawRect( pt.x()-1, pt.y()-8, 2, 7 );
129 p.drawRect( pt.x()-1, pt.y()+1, 2, 7 );
130 p.drawRect( pt.x()-8, pt.y()-1, 7, 2 );
131 p.drawRect( pt.x()+1, pt.y()-1, 7, 2 );
132*/
133 showCross = FALSE;
134 repaint( crossPos.x()-8, crossPos.y()-8, 16, 16 );
135 showCross = TRUE;
136 crossPos = pt;
137 repaint( crossPos.x()-8, crossPos.y()-8, 16, 16 );
138}
139
140void Calibrate::paintEvent( QPaintEvent * )
141{
142 QPainter p( this );
143
144 int y;
145
146 if ( !logo.isNull() ) {
147 y = height() / 2 - logo.height() - 15;
148 p.drawPixmap( (width() - logo.width())/2, y, logo );
149 }
150
151 y = height() / 2 + 15;
152
153 p.drawText( 0, y+height()/8, width(), height() - y, AlignHCenter,
154 tr("Touch the crosshairs firmly and\n"
155 "accurately to calibrate your screen.") );
156
157 QFont f = p.font(); f.setBold(TRUE);
158 p.setFont( f );
159 p.drawText( 0, y, width(), height() - y, AlignHCenter|WordBreak,
160 tr("Welcome to Qtopia") );
161
162/*
163 saveUnder = QPixmap::grabWindow( winId(), crossPos.x()-8, crossPos.y()-8,
164 16, 16 );
165 moveCrosshair( crossPos );
166*/
167 if ( showCross ) {
168 p.drawRect( crossPos.x()-1, crossPos.y()-8, 2, 7 );
169 p.drawRect( crossPos.x()-1, crossPos.y()+1, 2, 7 );
170 p.drawRect( crossPos.x()-8, crossPos.y()-1, 7, 2 );
171 p.drawRect( crossPos.x()+1, crossPos.y()-1, 7, 2 );
172 }
173}
174
175void Calibrate::mousePressEvent( QMouseEvent *e )
176{
177 // map to device coordinates
178 QPoint devPos = qt_screen->mapToDevice( e->pos(),
179 QSize(qt_screen->width(), qt_screen->height()) );
180 if ( penPos.isNull() )
181 penPos = devPos;
182 else
183 penPos = QPoint( (penPos.x() + devPos.x())/2,
184 (penPos.y() + devPos.y())/2 );
185}
186
187void Calibrate::mouseReleaseEvent( QMouseEvent * )
188{
189 if ( timer->isActive() )
190 return;
191
192 bool doMove = TRUE;
193
194 cd.devPoints[location] = penPos;
195 if ( location < QWSPointerCalibrationData::LastLocation ) {
196 location = (QWSPointerCalibrationData::Location)((int)location + 1);
197 } else {
198 if ( sanityCheck() ) {
199 reset();
200 goodcd = cd;
201 hide();
202 emit accept();
203 doMove = FALSE;
204 } else {
205 location = QWSPointerCalibrationData::TopLeft;
206 }
207 }
208
209 if ( doMove ) {
210 QPoint target = fromDevice( cd.screenPoints[location] );
211 dx = (target.x() - crossPos.x())/10;
212 dy = (target.y() - crossPos.y())/10;
213 timer->start( 30 );
214 }
215}
216
217void Calibrate::timeout()
218{
219 QPoint target = fromDevice( cd.screenPoints[location] );
220
221 bool doneX = FALSE;
222 bool doneY = FALSE;
223 QPoint newPos( crossPos.x() + dx, crossPos.y() + dy );
224
225 if ( QABS(crossPos.x() - target.x()) <= QABS(dx) ) {
226 newPos.setX( target.x() );
227 doneX = TRUE;
228 }
229
230 if ( QABS(crossPos.y() - target.y()) <= QABS(dy) ) {
231 newPos.setY(target.y());
232 doneY = TRUE;
233 }
234
235 if ( doneX && doneY ) {
236 penPos = QPoint();
237 timer->stop();
238 }
239
240 moveCrosshair( newPos );
241}
242
243#endif // _WS_QWS_
diff --git a/core/apps/calibrate/calibrate.h b/core/apps/calibrate/calibrate.h
new file mode 100644
index 0000000..97108c9
--- a/dev/null
+++ b/core/apps/calibrate/calibrate.h
@@ -0,0 +1,67 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#include <qwsmouse_qws.h>
22
23#if defined(Q_WS_QWS) || defined(_WS_QWS_)
24
25#include <qdialog.h>
26#include <qpixmap.h>
27
28class QTimer;
29
30class Calibrate : public QDialog
31{
32 Q_OBJECT
33public:
34 Calibrate(QWidget* parent=0, const char * name=0, WFlags=0);
35 ~Calibrate();
36
37 void show();
38 void hide();
39
40private:
41 QPoint fromDevice( const QPoint &p );
42 bool sanityCheck();
43 void moveCrosshair( QPoint pt );
44 void paintEvent( QPaintEvent * );
45 void mousePressEvent( QMouseEvent * );
46 void mouseReleaseEvent( QMouseEvent * );
47
48private slots:
49 void timeout();
50
51private:
52 void store();
53 void reset();
54 QPixmap logo;
55 QWSPointerCalibrationData goodcd,cd;
56 QWSPointerCalibrationData::Location location;
57 QPoint crossPos;
58 QPoint penPos;
59 QPixmap saveUnder;
60 QTimer *timer;
61 int dx;
62 int dy;
63 bool showCross;
64};
65
66#endif // _WS_QWS_
67
diff --git a/core/apps/calibrate/calibrate.pro b/core/apps/calibrate/calibrate.pro
new file mode 100644
index 0000000..9769ea6
--- a/dev/null
+++ b/core/apps/calibrate/calibrate.pro
@@ -0,0 +1 @@
# This is part of the taskbar
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 @@
1moc_*
2Makefile
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 @@
1#############################################################################
2
3####### Compiler, tools and options
4
5 CXX =$(SYSCONF_CXX) $(QT_CXX_MT)
6 CXXFLAGS=$(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS)
7 CC =$(SYSCONF_CC) $(QT_C_MT)
8 CFLAGS =$(SYSCONF_CFLAGS)
9 INCPATH =-I$(QPEDIR)/include
10 LFLAGS =$(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT)
11 LIBS =$(SUBLIBS) -lqpe $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS) $(SYSCONF_LIBS_QTAPP)
12 MOC =$(SYSCONF_MOC)
13 UIC =$(SYSCONF_UIC)
14
15####### Target
16
17DESTDIR = $(QPEDIR)/bin/
18VER_MAJ = 1
19VER_MIN = 0
20VER_PATCH = 0
21 TARGET= embeddedkonsole
22TARGET1 = lib$(TARGET).so.$(VER_MAJ)
23
24####### Files
25
26 HEADERS =TEWidget.h \
27 TEScreen.h \
28 TECommon.h \
29 TEHistory.h \
30 TEmulation.h \
31 TEmuVt102.h \
32 session.h \
33 keytrans.h \
34 konsole.h \
35 MyPty.h
36 SOURCES =TEScreen.cpp \
37 TEWidget.cpp \
38 TEHistory.cpp \
39 TEmulation.cpp \
40 TEmuVt102.cpp \
41 session.cpp \
42 keytrans.cpp \
43 konsole.cpp \
44 main.cpp \
45 MyPty.cpp
46 OBJECTS =TEScreen.o \
47 TEWidget.o \
48 TEHistory.o \
49 TEmulation.o \
50 TEmuVt102.o \
51 session.o \
52 keytrans.o \
53 konsole.o \
54 main.o \
55 MyPty.o
56INTERFACES =
57UICDECLS =
58UICIMPLS =
59 SRCMOC =moc_TEWidget.cpp \
60 moc_TEmulation.cpp \
61 moc_TEmuVt102.cpp \
62 moc_session.cpp \
63 moc_konsole.cpp \
64 moc_MyPty.cpp
65 OBJMOC =moc_TEWidget.o \
66 moc_TEmulation.o \
67 moc_TEmuVt102.o \
68 moc_session.o \
69 moc_konsole.o \
70 moc_MyPty.o
71
72
73####### Implicit rules
74
75.SUFFIXES: .cpp .cxx .cc .C .c
76
77.cpp.o:
78 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
79
80.cxx.o:
81 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
82
83.cc.o:
84 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
85
86.C.o:
87 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
88
89.c.o:
90 $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
91
92####### Build rules
93
94
95all: $(DESTDIR)$(TARGET)
96
97$(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
98 $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)
99
100moc: $(SRCMOC)
101
102tmake:
103 tmake embeddedkonsole.pro
104
105clean:
106 -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
107 -rm -f *~ core
108 -rm -f allmoc.cpp
109
110####### Extension Modules
111
112listpromodules:
113 @echo
114
115listallmodules:
116 @echo
117
118listaddonpromodules:
119 @echo
120
121listaddonentmodules:
122 @echo
123
124
125REQUIRES=embeddedkonsole
126
127####### Sub-libraries
128
129
130###### Combined headers
131
132
133
134####### Compile
135
136TEScreen.o: TEScreen.cpp \
137 TEScreen.h \
138 TECommon.h \
139 TEHistory.h
140
141TEWidget.o: TEWidget.cpp \
142 TEWidget.h \
143 TECommon.h \
144 session.h \
145 MyPty.h \
146 TEmuVt102.h \
147 TEScreen.h \
148 TEHistory.h \
149 TEmulation.h \
150 keytrans.h
151
152TEHistory.o: TEHistory.cpp \
153 TEHistory.h \
154 TECommon.h
155
156TEmulation.o: TEmulation.cpp \
157 TEmulation.h \
158 TEWidget.h \
159 TECommon.h \
160 TEScreen.h \
161 TEHistory.h \
162 keytrans.h
163
164TEmuVt102.o: TEmuVt102.cpp \
165 TEmuVt102.h \
166 TEWidget.h \
167 TECommon.h \
168 TEScreen.h \
169 TEHistory.h \
170 TEmulation.h \
171 keytrans.h
172
173session.o: session.cpp \
174 session.h \
175 MyPty.h \
176 TEWidget.h \
177 TECommon.h \
178 TEmuVt102.h \
179 TEScreen.h \
180 TEHistory.h \
181 TEmulation.h \
182 keytrans.h
183
184keytrans.o: keytrans.cpp \
185 keytrans.h \
186 $(QPEDIR)/include/qpe/qpeapplication.h \
187 default.keytab.h
188
189konsole.o: konsole.cpp \
190 $(QPEDIR)/include/qpe/resource.h \
191 $(QPEDIR)/include/qpe/qpetoolbar.h \
192 $(QPEDIR)/include/qpe/qpemenubar.h \
193 konsole.h \
194 MyPty.h \
195 TEWidget.h \
196 TECommon.h \
197 TEmuVt102.h \
198 TEScreen.h \
199 TEHistory.h \
200 TEmulation.h \
201 keytrans.h \
202 session.h
203
204main.o: main.cpp \
205 konsole.h \
206 MyPty.h \
207 TEWidget.h \
208 TECommon.h \
209 TEmuVt102.h \
210 TEScreen.h \
211 TEHistory.h \
212 TEmulation.h \
213 keytrans.h \
214 session.h \
215 $(QPEDIR)/include/qpe/qpeapplication.h
216
217MyPty.o: MyPty.cpp \
218 MyPty.h
219
220moc_TEWidget.o: moc_TEWidget.cpp \
221 TEWidget.h \
222 TECommon.h
223
224moc_TEmulation.o: moc_TEmulation.cpp \
225 TEmulation.h \
226 TEWidget.h \
227 TECommon.h \
228 TEScreen.h \
229 TEHistory.h \
230 keytrans.h
231
232moc_TEmuVt102.o: moc_TEmuVt102.cpp \
233 TEmuVt102.h \
234 TEWidget.h \
235 TECommon.h \
236 TEScreen.h \
237 TEHistory.h \
238 TEmulation.h \
239 keytrans.h
240
241moc_session.o: moc_session.cpp \
242 session.h \
243 MyPty.h \
244 TEWidget.h \
245 TECommon.h \
246 TEmuVt102.h \
247 TEScreen.h \
248 TEHistory.h \
249 TEmulation.h \
250 keytrans.h
251
252moc_konsole.o: moc_konsole.cpp \
253 konsole.h \
254 MyPty.h \
255 TEWidget.h \
256 TECommon.h \
257 TEmuVt102.h \
258 TEScreen.h \
259 TEHistory.h \
260 TEmulation.h \
261 keytrans.h \
262 session.h
263
264moc_MyPty.o: moc_MyPty.cpp \
265 MyPty.h
266
267moc_TEWidget.cpp: TEWidget.h
268 $(MOC) TEWidget.h -o moc_TEWidget.cpp
269
270moc_TEmulation.cpp: TEmulation.h
271 $(MOC) TEmulation.h -o moc_TEmulation.cpp
272
273moc_TEmuVt102.cpp: TEmuVt102.h
274 $(MOC) TEmuVt102.h -o moc_TEmuVt102.cpp
275
276moc_session.cpp: session.h
277 $(MOC) session.h -o moc_session.cpp
278
279moc_konsole.cpp: konsole.h
280 $(MOC) konsole.h -o moc_konsole.cpp
281
282moc_MyPty.cpp: MyPty.h
283 $(MOC) MyPty.h -o moc_MyPty.cpp
284
285
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 @@
1/* -------------------------------------------------------------------------- */
2/* */
3/* [MyPty.C] Pseudo Terminal Device */
4/* */
5/* -------------------------------------------------------------------------- */
6/* */
7/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */
8/* */
9/* This file is part of Konsole - an X terminal for KDE */
10/* -------------------------------------------------------------------------- */
11 /* */
12/* Ported Konsole to Qt/Embedded */
13 /* */
14/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */
15 /* */
16/* -------------------------------------------------------------------------- */
17
18/* If you're compiling konsole on non-Linux platforms and find
19 problems that you can track down to this file, please have
20 a look into ../README.ports, too.
21*/
22
23/*! \file
24*/
25
26/*! \class TEPty
27
28 \brief Ptys provide a pseudo terminal connection to a program.
29
30 Although closely related to pipes, these pseudo terminal connections have
31 some ability, that makes it nessesary to uses them. Most importent, they
32 know about changing screen sizes and UNIX job control.
33
34 Within the terminal emulation framework, this class represents the
35 host side of the terminal together with the connecting serial line.
36
37 One can create many instances of this class within a program.
38 As a side effect of using this class, a signal(2) handler is
39 installed on SIGCHLD.
40
41 \par FIXME
42
43 [NOTE: much of the technical stuff below will be replaced by forkpty.]
44
45 publish the SIGCHLD signal if not related to an instance.
46
47 clearify TEPty::done vs. TEPty::~TEPty semantics.
48 check if pty is restartable via run after done.
49
50 \par Pseudo terminals
51
52 Pseudo terminals are a unique feature of UNIX, and always come in form of
53 pairs of devices (/dev/ptyXX and /dev/ttyXX), which are connected to each
54 other by the operating system. One may think of them as two serial devices
55 linked by a null-modem cable. Being based on devices the number of
56 simultanous instances of this class is (globally) limited by the number of
57 those device pairs, which is 256.
58
59 Another technic are UNIX 98 PTY's. These are supported also, and prefered
60 over the (obsolete) predecessor.
61
62 There's a sinister ioctl(2), signal(2) and job control stuff
63 nessesary to make everything work as it should.
64*/
65
66
67#include <qapplication.h>
68#include <qsocketnotifier.h>
69#include <qstring.h>
70
71#include <stdlib.h>
72#include <stdio.h>
73#include <signal.h>
74#include <fcntl.h>
75#include <unistd.h>
76#include <termios.h>
77#include <sys/types.h>
78#include <sys/ioctl.h>
79#include <sys/wait.h>
80
81#ifdef HAVE_OPENPTY
82#include <pty.h>
83#endif
84
85#include "MyPty.h"
86
87
88#undef VERBOSE_DEBUG
89
90
91/* -------------------------------------------------------------------------- */
92
93/*!
94 Informs the client program about the
95 actual size of the window.
96*/
97
98void MyPty::setSize(int lines, int columns)
99{
100 struct winsize wsize;
101 wsize.ws_row = (unsigned short)lines;
102 wsize.ws_col = (unsigned short)columns;
103 if(fd < 0) return;
104 ioctl(fd,TIOCSWINSZ,(char *)&wsize);
105}
106
107
108void MyPty::donePty()
109{
110 // This is code from the Qt DumbTerminal example
111 int status = 0;
112
113 ::close(fd);
114
115 if (cpid) {
116 kill(cpid, SIGHUP);
117 waitpid(cpid, &status, 0);
118 }
119
120 emit done(status);
121}
122
123
124const char* MyPty::deviceName()
125{
126 return ttynam;
127}
128
129
130void MyPty::error()
131{
132 // This is code from the Qt DumbTerminal example
133 donePty();
134}
135
136
137/*!
138 start the client program.
139*/
140int MyPty::run(const char* cmd, QStrList &, const char*, int)
141{
142 // This is code from the Qt DumbTerminal example
143 cpid = fork();
144
145 if ( !cpid ) {
146 // child - exec shell on tty
147 for (int sig = 1; sig < NSIG; sig++) signal(sig,SIG_DFL);
148 int ttyfd = open(ttynam, O_RDWR);
149 dup2(ttyfd, STDIN_FILENO);
150 dup2(ttyfd, STDOUT_FILENO);
151 dup2(ttyfd, STDERR_FILENO);
152 // should be done with tty, so close it
153 close(ttyfd);
154 static struct termios ttmode;
155 if ( setsid() < 0 )
156 perror( "failed to set process group" );
157#if defined (TIOCSCTTY)
158 // grabbed from APUE by Stevens
159 ioctl(STDIN_FILENO, TIOCSCTTY, 0);
160#endif
161 tcgetattr( STDIN_FILENO, &ttmode );
162 ttmode.c_cc[VINTR] = 3;
163 ttmode.c_cc[VERASE] = 8;
164 tcsetattr( STDIN_FILENO, TCSANOW, &ttmode );
165 setenv("TERM","vt100",1);
166 setenv("COLORTERM","0",1);
167
168 if (getuid() == 0) {
169 char msg[] = "WARNING: You are running this shell as root!\n";
170 write(ttyfd, msg, sizeof(msg));
171 }
172 execl(cmd, cmd, 0);
173
174 donePty();
175 exit(-1);
176 }
177
178 // parent - continue as a widget
179 QSocketNotifier* sn_r = new QSocketNotifier(fd,QSocketNotifier::Read,this);
180 QSocketNotifier* sn_e = new QSocketNotifier(fd,QSocketNotifier::Exception,this);
181 connect(sn_r,SIGNAL(activated(int)),this,SLOT(readPty()));
182 connect(sn_e,SIGNAL(activated(int)),this,SLOT(error()));
183
184 return 0;
185}
186
187int MyPty::openPty()
188{
189 // This is code from the Qt DumbTerminal example
190 int ptyfd = -1;
191
192#ifdef HAVE_OPENPTY
193 int ttyfd;
194 if ( openpty(&ptyfd,&ttyfd,ttynam,0,0) )
195 ptyfd = -1;
196 else
197 close(ttyfd); // we open the ttynam ourselves.
198#else
199 for (const char* c0 = "pqrstuvwxyzabcde"; ptyfd < 0 && *c0 != 0; c0++) {
200 for (const char* c1 = "0123456789abcdef"; ptyfd < 0 && *c1 != 0; c1++) {
201 sprintf(ptynam,"/dev/pty%c%c",*c0,*c1);
202 sprintf(ttynam,"/dev/tty%c%c",*c0,*c1);
203 if ((ptyfd = ::open(ptynam,O_RDWR)) >= 0) {
204 if (geteuid() != 0 && !access(ttynam,R_OK|W_OK) == 0) {
205 ::close(ptyfd);
206 ptyfd = -1;
207 }
208 }
209 }
210 }
211#endif
212
213 if ( ptyfd < 0 ) {
214 qApp->exit(1);
215 return -1;
216 }
217
218 return ptyfd;
219}
220
221/*!
222 Create an instance.
223*/
224MyPty::MyPty() : cpid(0)
225{
226 fd = openPty();
227}
228
229/*!
230 Destructor.
231 Note that the related client program is not killed
232 (yet) when a instance is deleted.
233*/
234MyPty::~MyPty()
235{
236 donePty();
237}
238
239
240/*! sends len bytes through the line */
241void MyPty::send_bytes(const char* s, int len)
242{
243
244#ifdef VERBOSE_DEBUG
245 // verbose debug
246 printf("sending bytes:\n");
247 for (int i = 0; i < len; i++)
248 printf("%c", s[i]);
249 printf("\n");
250#endif
251
252 ::write(fd, s, len);
253}
254
255/*! indicates that a block of data is received */
256void MyPty::readPty()
257{
258 char buf[4096];
259
260 int len = ::read( fd, buf, 4096 );
261
262 if (len == -1)
263 donePty();
264
265 if (len < 0)
266 return;
267
268 emit block_in(buf,len);
269
270#ifdef VERBOSE_DEBUG
271 // verbose debug
272 printf("read bytes:\n");
273 for (int i = 0; i < len; i++)
274 printf("%c", buf[i]);
275 printf("\n");
276#endif
277
278}
279
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 @@
1/* -------------------------------------------------------------------------- */
2/* */
3/* [MyPty.h] Pseudo Terminal Device */
4/* */
5/* -------------------------------------------------------------------------- */
6/* */
7/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */
8/* */
9/* This file is part of Konsole - an X terminal for KDE */
10/* */
11/* -------------------------------------------------------------------------- */
12 /* */
13/* Ported Konsole to Qt/Embedded */
14 /* */
15/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */
16 /* */
17/* -------------------------------------------------------------------------- */
18
19/*! \file
20*/
21
22#ifndef MY_PTY_H
23#define MY_PTY_H
24
25#include <qobject.h>
26#include <qstrlist.h>
27
28
29class MyPty : public QObject
30{
31Q_OBJECT
32
33 public:
34
35 MyPty();
36 ~MyPty();
37
38 /*!
39 having a `run' separate from the constructor allows to make
40 the necessary connections to the signals and slots of the
41 instance before starting the execution of the client.
42 */
43 int run(const char* pgm, QStrList & args, const char* term, int addutmp);
44
45 public slots:
46
47 void send_bytes(const char* s, int len);
48 void setSize(int lines, int columns);
49 void error();
50
51 signals:
52
53 /*!
54 emitted when the client program terminates.
55 \param status the wait(2) status code of the terminated client program.
56 */
57 void done(int status);
58
59 /*!
60 emitted when a new block of data comes in.
61 \param s - the data
62 \param len - the length of the block
63 */
64 void block_in(const char* s, int len);
65
66 public:
67
68 void send_byte(char s);
69// void send_string(const char* s);
70
71 const char* deviceName();
72
73 protected slots:
74 void readPty();
75 void donePty();
76
77 private:
78 int openPty();
79
80 private:
81
82 char ptynam[16]; // "/dev/ptyxx" | "/dev/ptmx"
83 char ttynam[16]; // "/dev/ttyxx" | "/dev/pts/########..."
84 int fd;
85 int cpid;
86};
87
88#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 @@
1/* -------------------------------------------------------------------------- */
2/* */
3/* [TECommon.h] Common Definitions */
4/* */
5/* -------------------------------------------------------------------------- */
6/* */
7/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */
8/* */
9/* This file is part of Konsole - an X terminal for KDE */
10/* */
11/* -------------------------------------------------------------------------- */
12 /* */
13/* Ported Konsole to Qt/Embedded */
14 /* */
15/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */
16 /* */
17/* -------------------------------------------------------------------------- */
18
19/*! \file TECommon.h
20 \brief Definitions shared between TEScreen and TEWidget.
21*/
22
23#ifndef TECOMMON_H
24#define TECOMMON_H
25
26#include <qcolor.h>
27
28#ifndef BOOL
29typedef int BOOL;
30#endif
31
32#ifndef FALSE
33#define FALSE 0
34#endif
35
36#ifndef TRUE
37#define TRUE 1
38#endif
39
40#ifndef UINT8
41typedef unsigned char UINT8;
42#endif
43
44#ifndef UINT16
45typedef unsigned short UINT16;
46#endif
47
48// Attributed Character Representations ///////////////////////////////
49
50// Colors
51
52#define BASE_COLORS (2+8)
53#define INTENSITIES 2
54#define TABLE_COLORS (INTENSITIES*BASE_COLORS)
55
56#define DEFAULT_FORE_COLOR 0
57#define DEFAULT_BACK_COLOR 1
58
59#define DEFAULT_RENDITION 0
60#define RE_BOLD (1 << 0)
61#define RE_BLINK (1 << 1)
62#define RE_UNDERLINE (1 << 2)
63#define RE_REVERSE (1 << 3) // Screen only
64#define RE_INTENSIVE (1 << 3) // Widget only
65
66/*! \class ca
67 * \brief a character with rendition attributes.
68*/
69
70class ca
71{
72public:
73 inline ca(UINT16 _c = ' ',
74 UINT8 _f = DEFAULT_FORE_COLOR,
75 UINT8 _b = DEFAULT_BACK_COLOR,
76 UINT8 _r = DEFAULT_RENDITION)
77 : c(_c), f(_f), b(_b), r(_r) {}
78public:
79 UINT16 c; // character
80 UINT8 f; // foreground color
81 UINT8 b; // background color
82 UINT8 r; // rendition
83public:
84 friend BOOL operator == (ca a, ca b);
85 friend BOOL operator != (ca a, ca b);
86};
87
88inline BOOL operator == (ca a, ca b)
89{
90 return a.c == b.c && a.f == b.f && a.b == b.b && a.r == b.r;
91}
92
93inline BOOL operator != (ca a, ca b)
94{
95 return a.c != b.c || a.f != b.f || a.b != b.b || a.r != b.r;
96}
97
98/*!
99*/
100struct ColorEntry
101{
102 ColorEntry(QColor c, bool tr, bool b) : color(c), transparent(tr), bold(b) {}
103 ColorEntry() : transparent(false), bold(false) {} // default constructors
104 void operator=(const ColorEntry& rhs) {
105 color = rhs.color;
106 transparent = rhs.transparent;
107 bold = rhs.bold;
108 }
109 QColor color;
110 bool transparent; // if used on bg
111 bool bold; // if used on fg
112};
113
114#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 @@
1/* -------------------------------------------------------------------------- */
2/* */
3/* [TEHistory.C] History Buffer */
4/* */
5/* -------------------------------------------------------------------------- */
6/* */
7/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */
8/* */
9/* This file is part of Konsole - an X terminal for KDE */
10/* */
11/* -------------------------------------------------------------------------- */
12 /* */
13/* Ported Konsole to Qt/Embedded */
14 /* */
15/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */
16 /* */
17/* -------------------------------------------------------------------------- */
18
19#include "TEHistory.h"
20#include <stdlib.h>
21#include <assert.h>
22#include <stdio.h>
23#include <sys/types.h>
24#include <unistd.h>
25#include <errno.h>
26
27#define HERE printf("%s(%d): here\n",__FILE__,__LINE__)
28
29/*
30 An arbitrary long scroll.
31
32 One can modify the scroll only by adding either cells
33 or newlines, but access it randomly.
34
35 The model is that of an arbitrary wide typewriter scroll
36 in that the scroll is a serie of lines and each line is
37 a serie of cells with no overwriting permitted.
38
39 The implementation provides arbitrary length and numbers
40 of cells and line/column indexed read access to the scroll
41 at constant costs.
42
43FIXME: some complain about the history buffer comsuming the
44 memory of their machines. This problem is critical
45 since the history does not behave gracefully in cases
46 where the memory is used up completely.
47
48 I put in a workaround that should handle it problem
49 now gracefully. I'm not satisfied with the solution.
50
51FIXME: Terminating the history is not properly indicated
52 in the menu. We should throw a signal.
53
54FIXME: There is noticable decrease in speed, also. Perhaps,
55 there whole feature needs to be revisited therefore.
56 Disadvantage of a more elaborated, say block-oriented
57 scheme with wrap around would be it's complexity.
58*/
59
60//FIXME: tempory replacement for tmpfile
61// this is here one for debugging purpose.
62
63//#define tmpfile xTmpFile
64
65FILE* xTmpFile()
66{
67 static int fid = 0;
68 char fname[80];
69 sprintf(fname,"TmpFile.%d",fid++);
70 return fopen(fname,"w");
71}
72
73
74// History Buffer ///////////////////////////////////////////
75
76/*
77 A Row(X) data type which allows adding elements to the end.
78*/
79
80HistoryBuffer::HistoryBuffer()
81{
82 ion = -1;
83 length = 0;
84}
85
86HistoryBuffer::~HistoryBuffer()
87{
88 setScroll(FALSE);
89}
90
91void HistoryBuffer::setScroll(bool on)
92{
93 if (on == hasScroll()) return;
94
95 if (on)
96 {
97 assert( ion < 0 );
98 assert( length == 0);
99 FILE* tmp = tmpfile(); if (!tmp) { perror("konsole: cannot open temp file.\n"); return; }
100 ion = dup(fileno(tmp)); if (ion<0) perror("konsole: cannot dup temp file.\n");
101 fclose(tmp);
102 }
103 else
104 {
105 assert( ion >= 0 );
106 close(ion);
107 ion = -1;
108 length = 0;
109 }
110}
111
112bool HistoryBuffer::hasScroll()
113{
114 return ion >= 0;
115}
116
117void HistoryBuffer::add(const unsigned char* bytes, int len)
118{ int rc;
119 assert(hasScroll());
120 rc = lseek(ion,length,SEEK_SET); if (rc < 0) { perror("HistoryBuffer::add.seek"); setScroll(FALSE); return; }
121 rc = write(ion,bytes,len); if (rc < 0) { perror("HistoryBuffer::add.write"); setScroll(FALSE); return; }
122 length += rc;
123}
124
125void HistoryBuffer::get(unsigned char* bytes, int len, int loc)
126{ int rc;
127 assert(hasScroll());
128 if (loc < 0 || len < 0 || loc + len > length)
129 fprintf(stderr,"getHist(...,%d,%d): invalid args.\n",len,loc);
130 rc = lseek(ion,loc,SEEK_SET); if (rc < 0) { perror("HistoryBuffer::get.seek"); setScroll(FALSE); return; }
131 rc = read(ion,bytes,len); if (rc < 0) { perror("HistoryBuffer::get.read"); setScroll(FALSE); return; }
132}
133
134int HistoryBuffer::len()
135{
136 return length;
137}
138
139// History Scroll //////////////////////////////////////
140
141/*
142 The history scroll makes a Row(Row(Cell)) from
143 two history buffers. The index buffer contains
144 start of line positions which refere to the cells
145 buffer.
146
147 Note that index[0] addresses the second line
148 (line #1), while the first line (line #0) starts
149 at 0 in cells.
150*/
151
152HistoryScroll::HistoryScroll()
153{
154}
155
156HistoryScroll::~HistoryScroll()
157{
158}
159
160void HistoryScroll::setScroll(bool on)
161{
162 index.setScroll(on);
163 cells.setScroll(on);
164}
165
166bool HistoryScroll::hasScroll()
167{
168 return index.hasScroll() && cells.hasScroll();
169}
170
171int HistoryScroll::getLines()
172{
173 if (!hasScroll()) return 0;
174 return index.len() / sizeof(int);
175}
176
177int HistoryScroll::getLineLen(int lineno)
178{
179 if (!hasScroll()) return 0;
180 return (startOfLine(lineno+1) - startOfLine(lineno)) / sizeof(ca);
181}
182
183int HistoryScroll::startOfLine(int lineno)
184{
185 if (lineno <= 0) return 0;
186 if (!hasScroll()) return 0;
187 if (lineno <= getLines())
188 { int res;
189 index.get((unsigned char*)&res,sizeof(int),(lineno-1)*sizeof(int));
190 return res;
191 }
192 return cells.len();
193}
194
195void HistoryScroll::getCells(int lineno, int colno, int count, ca res[])
196{
197 assert(hasScroll());
198 cells.get((unsigned char*)res,count*sizeof(ca),startOfLine(lineno)+colno*sizeof(ca));
199}
200
201void HistoryScroll::addCells(ca text[], int count)
202{
203 if (!hasScroll()) return;
204 cells.add((unsigned char*)text,count*sizeof(ca));
205}
206
207void HistoryScroll::addLine()
208{
209 if (!hasScroll()) return;
210 int locn = cells.len();
211 index.add((unsigned char*)&locn,sizeof(int));
212}
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 @@
1/* -------------------------------------------------------------------------- */
2/* */
3/* [TEHistory.H] History Buffer */
4/* */
5/* -------------------------------------------------------------------------- */
6/* */
7/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */
8/* */
9/* This file is part of Konsole - an X terminal for KDE */
10/* */
11/* -------------------------------------------------------------------------- */
12 /* */
13/* Ported Konsole to Qt/Embedded */
14 /* */
15/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */
16 /* */
17/* -------------------------------------------------------------------------- */
18
19#ifndef TEHISTORY_H
20#define TEHISTORY_H
21
22#include "TECommon.h"
23
24/*
25 An extendable tmpfile(1) based buffer.
26*/
27class HistoryBuffer
28{
29public:
30 HistoryBuffer();
31 ~HistoryBuffer();
32
33public:
34 void setScroll(bool on);
35 bool hasScroll();
36
37public:
38 void add(const unsigned char* bytes, int len);
39 void get(unsigned char* bytes, int len, int loc);
40 int len();
41
42private:
43 int ion;
44 int length;
45};
46
47class HistoryScroll
48{
49public:
50 HistoryScroll();
51 ~HistoryScroll();
52
53public:
54 void setScroll(bool on);
55 bool hasScroll();
56
57public: // access to history
58 int getLines();
59 int getLineLen(int lineno);
60 void getCells(int lineno, int colno, int count, ca res[]);
61
62public: // backward compatibility (obsolete)
63 ca getCell(int lineno, int colno) { ca res; getCells(lineno,colno,1,&res); return res; }
64
65public: // adding lines.
66 void addCells(ca a[], int count);
67 void addLine();
68
69private:
70 int startOfLine(int lineno);
71 HistoryBuffer index; // lines Row(int)
72 HistoryBuffer cells; // text Row(ca)
73};
74
75#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 @@
1/* -------------------------------------------------------------------------- */
2/* */
3/* [TEScreen.C] Screen Data Type */
4/* */
5/* -------------------------------------------------------------------------- */
6/* */
7/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */
8/* */
9/* This file is part of Konsole - an X terminal for KDE */
10/* */
11/* -------------------------------------------------------------------------- */
12 /* */
13/* Ported Konsole to Qt/Embedded */
14 /* */
15/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */
16 /* */
17/* -------------------------------------------------------------------------- */
18
19/*! \file
20*/
21
22/*! \class TEScreen
23
24 \brief The image manipulated by the emulation.
25
26 This class implements the operations of the terminal emulation framework.
27 It is a complete passive device, driven by the emulation decoder
28 (TEmuVT102). By this it forms in fact an ADT, that defines operations
29 on a rectangular image.
30
31 It does neither know how to display its image nor about escape sequences.
32 It is further independent of the underlying toolkit. By this, one can even
33 use this module for an ordinary text surface.
34
35 Since the operations are called by a specific emulation decoder, one may
36 collect their different operations here.
37
38 The state manipulated by the operations is mainly kept in `image', though
39 it is a little more complex bejond this. See the header file of the class.
40
41 \sa TEWidget \sa VT102Emulation
42*/
43
44#include <stdio.h>
45#include <stdlib.h>
46#include <unistd.h>
47// #include <kdebug.h>
48
49#include <assert.h>
50#include <string.h>
51#include <ctype.h>
52
53#include "TEScreen.h"
54
55#define HERE printf("%s(%d): here\n",__FILE__,__LINE__)
56
57//FIXME: this is emulation specific. Use FALSE for xterm, TRUE for ANSI.
58//FIXME: see if we can get this from terminfo.
59#define BS_CLEARS FALSE
60
61#define loc(X,Y) ((Y)*columns+(X))
62
63/*! creates a `TEScreen' of `lines' lines and `columns' columns.
64*/
65
66TEScreen::TEScreen(int lines, int columns)
67{
68 this->lines = lines;
69 this->columns = columns;
70
71 image = (ca*) malloc(lines*columns*sizeof(ca));
72 tabstops = NULL; initTabStops();
73
74 histCursor = 0;
75
76 clearSelection();
77 reset();
78}
79
80/*! Destructor
81*/
82
83TEScreen::~TEScreen()
84{
85 free(image);
86 if (tabstops) free(tabstops);
87}
88
89/* ------------------------------------------------------------------------- */
90/* */
91/* Normalized Screen Operations */
92/* */
93/* ------------------------------------------------------------------------- */
94
95// Cursor Setting --------------------------------------------------------------
96
97/*! \section Cursor
98
99 The `cursor' is a location within the screen that is implicitely used in
100 many operations. The operations within this section allow to manipulate
101 the cursor explicitly and to obtain it's value.
102
103 The position of the cursor is guarantied to be between (including) 0 and
104 `columns-1' and `lines-1'.
105*/
106
107/*!
108 Move the cursor up.
109
110 The cursor will not be moved beyond the top margin.
111*/
112
113void TEScreen::cursorUp(int n)
114//=CUU
115{
116 if (n == 0) n = 1; // Default
117 int stop = cuY < tmargin ? 0 : tmargin;
118 cuX = QMIN(columns-1,cuX); // nowrap!
119 cuY = QMAX(stop,cuY-n);
120}
121
122/*!
123 Move the cursor down.
124
125 The cursor will not be moved beyond the bottom margin.
126*/
127
128void TEScreen::cursorDown(int n)
129//=CUD
130{
131 if (n == 0) n = 1; // Default
132 int stop = cuY > bmargin ? lines-1 : bmargin;
133 cuX = QMIN(columns-1,cuX); // nowrap!
134 cuY = QMIN(stop,cuY+n);
135}
136
137/*!
138 Move the cursor left.
139
140 The cursor will not move beyond the first column.
141*/
142
143void TEScreen::cursorLeft(int n)
144//=CUB
145{
146 if (n == 0) n = 1; // Default
147 cuX = QMIN(columns-1,cuX); // nowrap!
148 cuX = QMAX(0,cuX-n);
149}
150
151/*!
152 Move the cursor left.
153
154 The cursor will not move beyond the rightmost column.
155*/
156
157void TEScreen::cursorRight(int n)
158//=CUF
159{
160 if (n == 0) n = 1; // Default
161 cuX = QMIN(columns-1,cuX+n);
162}
163
164/*!
165 Set top and bottom margin.
166*/
167
168void TEScreen::setMargins(int top, int bot)
169//=STBM
170{
171 if (top == 0) top = 1; // Default
172 if (bot == 0) bot = lines; // Default
173 top = top - 1; // Adjust to internal lineno
174 bot = bot - 1; // Adjust to internal lineno
175 if ( !( 0 <= top && top < bot && bot < lines ) )
176 { fprintf(stderr,"%s(%d) : setRegion(%d,%d) : bad range.\n",
177 __FILE__,__LINE__,top,bot);
178 return; // Default error action: ignore
179 }
180 tmargin = top;
181 bmargin = bot;
182 cuX = 0;
183 cuY = getMode(MODE_Origin) ? top : 0;
184}
185
186/*!
187 Move the cursor down one line.
188
189 If cursor is on bottom margin, the region between the
190 actual top and bottom margin is scrolled up instead.
191*/
192
193void TEScreen::index()
194//=IND
195{
196 if (cuY == bmargin)
197 {
198 if (tmargin == 0 && bmargin == lines-1) addHistLine(); // hist.history
199 scrollUp(tmargin,1);
200 }
201 else if (cuY < lines-1)
202 cuY += 1;
203}
204
205/*!
206 Move the cursor up one line.
207
208 If cursor is on the top margin, the region between the
209 actual top and bottom margin is scrolled down instead.
210*/
211
212void TEScreen::reverseIndex()
213//=RI
214{
215 if (cuY == tmargin)
216 scrollDown(tmargin,1);
217 else if (cuY > 0)
218 cuY -= 1;
219}
220
221/*!
222 Move the cursor to the begin of the next line.
223
224 If cursor is on bottom margin, the region between the
225 actual top and bottom margin is scrolled up.
226*/
227
228void TEScreen::NextLine()
229//=NEL
230{
231 Return(); index();
232}
233
234// Line Editing ----------------------------------------------------------------
235
236/*! \section inserting / deleting characters
237*/
238
239/*! erase `n' characters starting from (including) the cursor position.
240
241 The line is filled in from the right with spaces.
242*/
243
244void TEScreen::eraseChars(int n)
245{
246 if (n == 0) n = 1; // Default
247 int p = QMAX(0,QMIN(cuX+n-1,columns-1));
248 clearImage(loc(cuX,cuY),loc(p,cuY),' ');
249}
250
251/*! delete `n' characters starting from (including) the cursor position.
252
253 The line is filled in from the right with spaces.
254*/
255
256void TEScreen::deleteChars(int n)
257{
258 if (n == 0) n = 1; // Default
259 int p = QMAX(0,QMIN(cuX+n,columns-1));
260 moveImage(loc(cuX,cuY),loc(p,cuY),loc(columns-1,cuY));
261 clearImage(loc(columns-n,cuY),loc(columns-1,cuY),' ');
262}
263
264/*! insert `n' spaces at the cursor position.
265
266 The cursor is not moved by the operation.
267*/
268
269void TEScreen::insertChars(int n)
270{
271 if (n == 0) n = 1; // Default
272 int p = QMAX(0,QMIN(columns-1-n,columns-1));
273 int q = QMAX(0,QMIN(cuX+n,columns-1));
274 moveImage(loc(q,cuY),loc(cuX,cuY),loc(p,cuY));
275 clearImage(loc(cuX,cuY),loc(q-1,cuY),' ');
276}
277
278/*! delete `n' lines starting from (including) the cursor position.
279
280 The cursor is not moved by the operation.
281*/
282
283void TEScreen::deleteLines(int n)
284{
285 if (n == 0) n = 1; // Default
286 scrollUp(cuY,n);
287}
288
289/*! insert `n' lines at the cursor position.
290
291 The cursor is not moved by the operation.
292*/
293
294void TEScreen::insertLines(int n)
295{
296 if (n == 0) n = 1; // Default
297 scrollDown(cuY,n);
298}
299
300// Mode Operations -----------------------------------------------------------
301
302/*! Set a specific mode. */
303
304void TEScreen::setMode(int m)
305{
306 currParm.mode[m] = TRUE;
307 switch(m)
308 {
309 case MODE_Origin : cuX = 0; cuY = tmargin; break; //FIXME: home
310 }
311}
312
313/*! Reset a specific mode. */
314
315void TEScreen::resetMode(int m)
316{
317 currParm.mode[m] = FALSE;
318 switch(m)
319 {
320 case MODE_Origin : cuX = 0; cuY = 0; break; //FIXME: home
321 }
322}
323
324/*! Save a specific mode. */
325
326void TEScreen::saveMode(int m)
327{
328 saveParm.mode[m] = currParm.mode[m];
329}
330
331/*! Restore a specific mode. */
332
333void TEScreen::restoreMode(int m)
334{
335 currParm.mode[m] = saveParm.mode[m];
336}
337
338//NOTE: this is a helper function
339/*! Return the setting a specific mode. */
340BOOL TEScreen::getMode(int m)
341{
342 return currParm.mode[m];
343}
344
345/*! Save the cursor position and the rendition attribute settings. */
346
347void TEScreen::saveCursor()
348{
349 sa_cuX = cuX;
350 sa_cuY = cuY;
351 sa_cu_re = cu_re;
352 sa_cu_fg = cu_fg;
353 sa_cu_bg = cu_bg;
354}
355
356/*! Restore the cursor position and the rendition attribute settings. */
357
358void TEScreen::restoreCursor()
359{
360 cuX = QMIN(sa_cuX,columns-1);
361 cuY = QMIN(sa_cuY,lines-1);
362 cu_re = sa_cu_re;
363 cu_fg = sa_cu_fg;
364 cu_bg = sa_cu_bg;
365 effectiveRendition();
366}
367
368/* ------------------------------------------------------------------------- */
369/* */
370/* Screen Operations */
371/* */
372/* ------------------------------------------------------------------------- */
373
374/*! Assing a new size to the screen.
375
376 The topmost left position is maintained, while lower lines
377 or right hand side columns might be removed or filled with
378 spaces to fit the new size.
379
380 The region setting is reset to the whole screen and the
381 tab positions reinitialized.
382*/
383
384void TEScreen::resizeImage(int new_lines, int new_columns)
385{
386
387 if (cuY > new_lines-1)
388 { // attempt to preserve focus and lines
389 bmargin = lines-1; //FIXME: margin lost
390 for (int i = 0; i < cuY-(new_lines-1); i++)
391 {
392 addHistLine(); scrollUp(0,1);
393 }
394 }
395
396 // make new image
397 ca* newimg = (ca*)malloc(new_lines*new_columns*sizeof(ca));
398
399 clearSelection();
400
401 // clear new image
402 for (int y = 0; y < new_lines; y++)
403 for (int x = 0; x < new_columns; x++)
404 {
405 newimg[y*new_columns+x].c = ' ';
406 newimg[y*new_columns+x].f = DEFAULT_FORE_COLOR;
407 newimg[y*new_columns+x].b = DEFAULT_BACK_COLOR;
408 newimg[y*new_columns+x].r = DEFAULT_RENDITION;
409 }
410 int cpy_lines = QMIN(new_lines, lines);
411 int cpy_columns = QMIN(new_columns,columns);
412 // copy to new image
413 for (int y = 0; y < cpy_lines; y++)
414 for (int x = 0; x < cpy_columns; x++)
415 {
416 newimg[y*new_columns+x].c = image[loc(x,y)].c;
417 newimg[y*new_columns+x].f = image[loc(x,y)].f;
418 newimg[y*new_columns+x].b = image[loc(x,y)].b;
419 newimg[y*new_columns+x].r = image[loc(x,y)].r;
420 }
421 free(image);
422 image = newimg;
423 lines = new_lines;
424 columns = new_columns;
425 cuX = QMIN(cuX,columns-1);
426 cuY = QMIN(cuY,lines-1);
427
428 // FIXME: try to keep values, evtl.
429 tmargin=0;
430 bmargin=lines-1;
431 initTabStops();
432 clearSelection();
433}
434
435/*
436 Clarifying rendition here and in TEWidget.
437
438 currently, TEWidget's color table is
439 0 1 2 .. 9 10 .. 17
440 dft_fg, dft_bg, dim 0..7, intensive 0..7
441
442 cu_fg, cu_bg contain values 0..8;
443 - 0 = default color
444 - 1..8 = ansi specified color
445
446 re_fg, re_bg contain values 0..17
447 due to the TEWidget's color table
448
449 rendition attributes are
450
451 attr widget screen
452 -------------- ------ ------
453 RE_UNDERLINE XX XX affects foreground only
454 RE_BLINK XX XX affects foreground only
455 RE_BOLD XX XX affects foreground only
456 RE_REVERSE -- XX
457 RE_TRANSPARENT XX -- affects background only
458 RE_INTENSIVE XX -- affects foreground only
459
460 Note that RE_BOLD is used in both widget
461 and screen rendition. Since xterm/vt102
462 is to poor to distinguish between bold
463 (which is a font attribute) and intensive
464 (which is a color attribute), we translate
465 this and RE_BOLD in falls eventually appart
466 into RE_BOLD and RE_INTENSIVE.
467*/
468
469void TEScreen::reverseRendition(ca* p)
470{ UINT8 f = p->f; UINT8 b = p->b;
471 p->f = b; p->b = f; //p->r &= ~RE_TRANSPARENT;
472}
473
474void TEScreen::effectiveRendition()
475// calculate rendition
476{
477 ef_re = cu_re & (RE_UNDERLINE | RE_BLINK);
478 if (cu_re & RE_REVERSE)
479 {
480 ef_fg = cu_bg;
481 ef_bg = cu_fg;
482 }
483 else
484 {
485 ef_fg = cu_fg;
486 ef_bg = cu_bg;
487 }
488 if (cu_re & RE_BOLD)
489 {
490 if (ef_fg < BASE_COLORS)
491 ef_fg += BASE_COLORS;
492 else
493 ef_fg -= BASE_COLORS;
494 }
495}
496
497/*!
498 returns the image.
499
500 Get the size of the image by \sa getLines and \sa getColumns.
501
502 NOTE that the image returned by this function must later be
503 freed.
504
505*/
506
507ca* TEScreen::getCookedImage()
508{ int x,y;
509 ca* merged = (ca*)malloc(lines*columns*sizeof(ca));
510 ca dft(' ',DEFAULT_FORE_COLOR,DEFAULT_BACK_COLOR,DEFAULT_RENDITION);
511
512 for (y = 0; (y < lines) && (y < (hist.getLines()-histCursor)); y++)
513 {
514 int len = QMIN(columns,hist.getLineLen(y+histCursor));
515 int yp = y*columns;
516 int yq = (y+histCursor)*columns;
517
518 hist.getCells(y+histCursor,0,len,merged+yp);
519 for (x = len; x < columns; x++) merged[yp+x] = dft;
520 for (x = 0; x < columns; x++)
521 { int p=x + yp; int q=x + yq;
522 if ( ( q >= sel_TL ) && ( q <= sel_BR ) )
523 reverseRendition(&merged[p]); // for selection
524 }
525 }
526 if (lines >= hist.getLines()-histCursor)
527 {
528 for (y = (hist.getLines()-histCursor); y < lines ; y++)
529 {
530 int yp = y*columns;
531 int yq = (y+histCursor)*columns;
532 int yr = (y-hist.getLines()+histCursor)*columns;
533 for (x = 0; x < columns; x++)
534 { int p = x + yp; int q = x + yq; int r = x + yr;
535 merged[p] = image[r];
536 if ( q >= sel_TL && q <= sel_BR )
537 reverseRendition(&merged[p]); // for selection
538 }
539
540 }
541 }
542 // evtl. inverse display
543 if (getMode(MODE_Screen))
544 { int i,n = lines*columns;
545 for (i = 0; i < n; i++)
546 reverseRendition(&merged[i]); // for reverse display
547 }
548 if (getMode(MODE_Cursor) && (cuY+(hist.getLines()-histCursor) < lines)) // cursor visible
549 reverseRendition(&merged[loc(cuX,cuY+(hist.getLines()-histCursor))]);
550 return merged;
551}
552
553
554/*!
555*/
556
557void TEScreen::reset()
558{
559 setMode(MODE_Wrap ); saveMode(MODE_Wrap ); // wrap at end of margin
560 resetMode(MODE_Origin); saveMode(MODE_Origin); // position refere to [1,1]
561 resetMode(MODE_Insert); saveMode(MODE_Insert); // overstroke
562 setMode(MODE_Cursor); // cursor visible
563 resetMode(MODE_Screen); // screen not inverse
564 resetMode(MODE_NewLine);
565
566 tmargin=0;
567 bmargin=lines-1;
568
569 setDefaultRendition();
570 saveCursor();
571
572 clear();
573}
574
575/*! Clear the entire screen and home the cursor.
576*/
577
578void TEScreen::clear()
579{
580 clearEntireScreen();
581 home();
582}
583
584/*! Moves the cursor left one column.
585*/
586
587void TEScreen::BackSpace()
588{
589 cuX = QMAX(0,cuX-1);
590 if (BS_CLEARS) image[loc(cuX,cuY)].c = ' ';
591}
592
593/*!
594*/
595
596void TEScreen::Tabulate()
597{
598 // note that TAB is a format effector (does not write ' ');
599 cursorRight(1); while(cuX < columns-1 && !tabstops[cuX]) cursorRight(1);
600}
601
602void TEScreen::clearTabStops()
603{
604 for (int i = 0; i < columns; i++) tabstops[i-1] = FALSE;
605}
606
607void TEScreen::changeTabStop(bool set)
608{
609 if (cuX >= columns) return;
610 tabstops[cuX] = set;
611}
612
613void TEScreen::initTabStops()
614{
615 if (tabstops) free(tabstops);
616 tabstops = (bool*)malloc(columns*sizeof(bool));
617 // Arrg! The 1st tabstop has to be one longer than the other.
618 // i.e. the kids start counting from 0 instead of 1.
619 // Other programs might behave correctly. Be aware.
620 for (int i = 0; i < columns; i++) tabstops[i] = (i%8 == 0 && i != 0);
621}
622
623/*!
624 This behaves either as IND (Screen::Index) or as NEL (Screen::NextLine)
625 depending on the NewLine Mode (LNM). This mode also
626 affects the key sequence returned for newline ([CR]LF).
627*/
628
629void TEScreen::NewLine()
630{
631 if (getMode(MODE_NewLine)) Return();
632 index();
633}
634
635/*! put `c' literally onto the screen at the current cursor position.
636
637 VT100 uses the convention to produce an automatic newline (am)
638 with the *first* character that would fall onto the next line (xenl).
639*/
640
641void TEScreen::checkSelection(int from, int to)
642{
643 if (sel_begin == -1) return;
644 int scr_TL = loc(0, hist.getLines());
645 //Clear entire selection if it overlaps region [from, to]
646 if ( (sel_BR > (from+scr_TL) )&&(sel_TL < (to+scr_TL)) )
647 {
648 clearSelection();
649 }
650}
651
652void TEScreen::ShowCharacter(unsigned short c)
653{
654 // Note that VT100 does wrapping BEFORE putting the character.
655 // This has impact on the assumption of valid cursor positions.
656 // We indicate the fact that a newline has to be triggered by
657 // putting the cursor one right to the last column of the screen.
658
659 if (cuX >= columns)
660 {
661 if (getMode(MODE_Wrap)) NextLine(); else cuX = columns-1;
662 }
663
664 if (getMode(MODE_Insert)) insertChars(1);
665
666 int i = loc(cuX,cuY);
667
668 checkSelection(i, i); // check if selection is still valid.
669
670 image[i].c = c;
671 image[i].f = ef_fg;
672 image[i].b = ef_bg;
673 image[i].r = ef_re;
674
675 cuX += 1;
676}
677
678// Region commands -------------------------------------------------------------
679
680
681/*! scroll up `n' lines within current region.
682 The `n' new lines are cleared.
683 \sa setRegion \sa scrollDown
684*/
685
686void TEScreen::scrollUp(int from, int n)
687{
688 if (n <= 0 || from + n > bmargin) return;
689 //FIXME: make sure `tmargin', `bmargin', `from', `n' is in bounds.
690 moveImage(loc(0,from),loc(0,from+n),loc(columns-1,bmargin));
691 clearImage(loc(0,bmargin-n+1),loc(columns-1,bmargin),' ');
692}
693
694/*! scroll down `n' lines within current region.
695 The `n' new lines are cleared.
696 \sa setRegion \sa scrollUp
697*/
698
699void TEScreen::scrollDown(int from, int n)
700{
701//FIXME: make sure `tmargin', `bmargin', `from', `n' is in bounds.
702 if (n <= 0) return;
703 if (from > bmargin) return;
704 if (from + n > bmargin) n = bmargin - from;
705 moveImage(loc(0,from+n),loc(0,from),loc(columns-1,bmargin-n));
706 clearImage(loc(0,from),loc(columns-1,from+n-1),' ');
707}
708
709/*! position the cursor to a specific line and column. */
710void TEScreen::setCursorYX(int y, int x)
711{
712 setCursorY(y); setCursorX(x);
713}
714
715/*! Set the cursor to x-th line. */
716
717void TEScreen::setCursorX(int x)
718{
719 if (x == 0) x = 1; // Default
720 x -= 1; // Adjust
721 cuX = QMAX(0,QMIN(columns-1, x));
722}
723
724/*! Set the cursor to y-th line. */
725
726void TEScreen::setCursorY(int y)
727{
728 if (y == 0) y = 1; // Default
729 y -= 1; // Adjust
730 cuY = QMAX(0,QMIN(lines -1, y + (getMode(MODE_Origin) ? tmargin : 0) ));
731}
732
733/*! set cursor to the `left upper' corner of the screen (1,1).
734*/
735
736void TEScreen::home()
737{
738 cuX = 0;
739 cuY = 0;
740}
741
742/*! set cursor to the begin of the current line.
743*/
744
745void TEScreen::Return()
746{
747 cuX = 0;
748}
749
750/*! returns the current cursor columns.
751*/
752
753int TEScreen::getCursorX()
754{
755 return cuX;
756}
757
758/*! returns the current cursor line.
759*/
760
761int TEScreen::getCursorY()
762{
763 return cuY;
764}
765
766// Erasing ---------------------------------------------------------------------
767
768/*! \section Erasing
769
770 This group of operations erase parts of the screen contents by filling
771 it with spaces colored due to the current rendition settings.
772
773 Althought the cursor position is involved in most of these operations,
774 it is never modified by them.
775*/
776
777/*! fill screen between (including) `loca' and `loce' with spaces.
778
779 This is an internal helper functions. The parameter types are internal
780 addresses of within the screen image and make use of the way how the
781 screen matrix is mapped to the image vector.
782*/
783
784void TEScreen::clearImage(int loca, int loce, char c)
785{ int i;
786 int scr_TL=loc(0,hist.getLines());
787 //FIXME: check positions
788
789 //Clear entire selection if it overlaps region to be moved...
790 if ( (sel_BR > (loca+scr_TL) )&&(sel_TL < (loce+scr_TL)) )
791 {
792 clearSelection();
793 }
794 for (i = loca; i <= loce; i++)
795 {
796 image[i].c = c;
797 image[i].f = ef_fg; //DEFAULT_FORE_COLOR; //FIXME: xterm and linux/ansi
798 image[i].b = ef_bg; //DEFAULT_BACK_COLOR; // many have different
799 image[i].r = ef_re; //DEFAULT_RENDITION; // ideas here.
800 }
801}
802
803/*! move image between (including) `loca' and `loce' to 'dst'.
804
805 This is an internal helper functions. The parameter types are internal
806 addresses of within the screen image and make use of the way how the
807 screen matrix is mapped to the image vector.
808*/
809
810void TEScreen::moveImage(int dst, int loca, int loce)
811{
812//FIXME: check positions
813 if (loce < loca) {
814 // kdDebug() << "WARNING!!! call to TEScreen:moveImage with loce < loca!" << endl;
815 return;
816 }
817 memmove(&image[dst],&image[loca],(loce-loca+1)*sizeof(ca));
818}
819
820/*! clear from (including) current cursor position to end of screen.
821*/
822
823void TEScreen::clearToEndOfScreen()
824{
825 clearImage(loc(cuX,cuY),loc(columns-1,lines-1),' ');
826}
827
828/*! clear from begin of screen to (including) current cursor position.
829*/
830
831void TEScreen::clearToBeginOfScreen()
832{
833 clearImage(loc(0,0),loc(cuX,cuY),' ');
834}
835
836/*! clear the entire screen.
837*/
838
839void TEScreen::clearEntireScreen()
840{
841 clearImage(loc(0,0),loc(columns-1,lines-1),' ');
842}
843
844/*! fill screen with 'E'
845 This is to aid screen alignment
846*/
847
848void TEScreen::helpAlign()
849{
850 clearImage(loc(0,0),loc(columns-1,lines-1),'E');
851}
852
853/*! clear from (including) current cursor position to end of current cursor line.
854*/
855
856void TEScreen::clearToEndOfLine()
857{
858 clearImage(loc(cuX,cuY),loc(columns-1,cuY),' ');
859}
860
861/*! clear from begin of current cursor line to (including) current cursor position.
862*/
863
864void TEScreen::clearToBeginOfLine()
865{
866 clearImage(loc(0,cuY),loc(cuX,cuY),' ');
867}
868
869/*! clears entire current cursor line
870*/
871
872void TEScreen::clearEntireLine()
873{
874 clearImage(loc(0,cuY),loc(columns-1,cuY),' ');
875}
876
877// Rendition ------------------------------------------------------------------
878
879/*!
880 set rendition mode
881*/
882
883void TEScreen::setRendition(int re)
884{
885 cu_re |= re;
886 effectiveRendition();
887}
888
889/*!
890 reset rendition mode
891*/
892
893void TEScreen::resetRendition(int re)
894{
895 cu_re &= ~re;
896 effectiveRendition();
897}
898
899/*!
900*/
901
902void TEScreen::setDefaultRendition()
903{
904 setForeColorToDefault();
905 setBackColorToDefault();
906 cu_re = DEFAULT_RENDITION;
907 effectiveRendition();
908}
909
910/*!
911*/
912
913void TEScreen::setForeColor(int fgcolor)
914{
915 cu_fg = (fgcolor&7)+((fgcolor&8) ? 4+8 : 2);
916 effectiveRendition();
917}
918
919/*!
920*/
921
922void TEScreen::setBackColor(int bgcolor)
923{
924 cu_bg = (bgcolor&7)+((bgcolor&8) ? 4+8 : 2);
925 effectiveRendition();
926}
927
928/*!
929*/
930
931void TEScreen::setBackColorToDefault()
932{
933 cu_bg = DEFAULT_BACK_COLOR;
934 effectiveRendition();
935}
936
937/*!
938*/
939
940void TEScreen::setForeColorToDefault()
941{
942 cu_fg = DEFAULT_FORE_COLOR;
943 effectiveRendition();
944}
945
946/* ------------------------------------------------------------------------- */
947/* */
948/* Marking & Selection */
949/* */
950/* ------------------------------------------------------------------------- */
951
952void TEScreen::clearSelection()
953{
954 sel_BR = -1;
955 sel_TL = -1;
956 sel_begin = -1;
957}
958
959void TEScreen::setSelBeginXY(const int x, const int y)
960{
961 sel_begin = loc(x,y+histCursor) ;
962 sel_BR = sel_begin;
963 sel_TL = sel_begin;
964}
965
966void TEScreen::setSelExtentXY(const int x, const int y)
967{
968 if (sel_begin == -1) return;
969 int l = loc(x,y + histCursor);
970
971 if (l < sel_begin)
972 {
973 sel_TL = l;
974 sel_BR = sel_begin;
975 }
976 else
977 {
978 /* FIXME, HACK to correct for x too far to the right... */
979 if (( x == columns )|| (x == 0)) l--;
980
981 sel_TL = sel_begin;
982 sel_BR = l;
983 }
984}
985
986QString TEScreen::getSelText(const BOOL preserve_line_breaks)
987{
988 if (sel_begin == -1)
989 return QString::null; // Selection got clear while selecting.
990
991 int *m; // buffer to fill.
992 int s, d; // source index, dest. index.
993 int hist_BR = loc(0, hist.getLines());
994 int hY = sel_TL / columns;
995 int hX = sel_TL % columns;
996 int eol; // end of line
997
998 s = sel_TL; // tracks copy in source.
999
1000 // allocate buffer for maximum
1001 // possible size...
1002 d = (sel_BR - sel_TL) / columns + 1;
1003 m = new int[d * (columns + 1) + 2];
1004 d = 0;
1005
1006 while (s <= sel_BR)
1007 {
1008 if (s < hist_BR)
1009 { // get lines from hist.history
1010 // buffer.
1011 eol = hist.getLineLen(hY);
1012
1013 if ((hY == (sel_BR / columns)) &&
1014 (eol >= (sel_BR % columns)))
1015 {
1016 eol = sel_BR % columns + 1;
1017 }
1018
1019 while (hX < eol)
1020 {
1021 m[d++] = hist.getCell(hY, hX++).c;
1022 s++;
1023 }
1024
1025 if (s <= sel_BR)
1026 {
1027 // The line break handling
1028 // It's different from the screen
1029 // image case!
1030 if (eol % columns == 0)
1031 {
1032 // That's either a completely filled
1033 // line or an empty line
1034 if (eol == 0)
1035 {
1036 m[d++] = '\n';
1037 }
1038 else
1039 {
1040 // We have a full line.
1041 // FIXME: How can we handle newlines
1042 // at this position?!
1043 }
1044 }
1045 else if ((eol + 1) % columns == 0)
1046 {
1047 // FIXME: We don't know if this was a
1048 // space at the last position or a
1049 // short line!!
1050 m[d++] = ' ';
1051 }
1052 else
1053 {
1054 // We have a short line here. Put a
1055 // newline or a space into the
1056 // buffer.
1057 m[d++] = preserve_line_breaks ? '\n' : ' ';
1058 }
1059 }
1060
1061 hY++;
1062 hX = 0;
1063 s = hY * columns;
1064 }
1065 else
1066 { // or from screen image.
1067 eol = (s / columns + 1) * columns - 1;
1068
1069 if (eol < sel_BR)
1070 {
1071 while ((eol > s) &&
1072 isspace(image[eol - hist_BR].c))
1073 {
1074 eol--;
1075 }
1076 }
1077 else
1078 {
1079 eol = sel_BR;
1080 }
1081
1082 while (s <= eol)
1083 {
1084 m[d++] = image[s++ - hist_BR].c;
1085 }
1086
1087 if (eol < sel_BR)
1088 {
1089 // eol processing see below ...
1090 if ((eol + 1) % columns == 0)
1091 {
1092 if (image[eol - hist_BR].c == ' ')
1093 {
1094 m[d++] = ' ';
1095 }
1096 }
1097 else
1098 {
1099 m[d++] = ((preserve_line_breaks ||
1100 ((eol % columns) == 0)) ?
1101 '\n' : ' ');
1102 }
1103 }
1104
1105 s = (eol / columns + 1) * columns;
1106 }
1107 }
1108
1109 QChar* qc = new QChar[d];
1110
1111 for (int i = 0; i < d; i++)
1112 {
1113 qc[i] = m[i];
1114 }
1115
1116 QString res(qc, d);
1117
1118 delete m;
1119 delete qc;
1120
1121 return res;
1122}
1123/* above ... end of line processing for selection -- psilva
1124cases:
1125
11261) (eol+1)%columns == 0 --> the whole line is filled.
1127 If the last char is a space, insert (preserve) space. otherwise
1128 leave the text alone, so that words that are broken by linewrap
1129 are preserved.
1130
1131FIXME:
1132 * this suppresses \n for command output that is
1133 sized to the exact column width of the screen.
1134
11352) eol%columns == 0 --> blank line.
1136 insert a \n unconditionally.
1137 Do it either you would because you are in preserve_line_break mode,
1138 or because it's an ASCII paragraph delimiter, so even when
1139 not preserving line_breaks, you want to preserve paragraph breaks.
1140
1141 3) else --> partially filled line
1142 insert a \n in preserve line break mode, else a space
1143 The space prevents concatenation of the last word of one
1144 line with the first of the next.
1145
1146*/
1147
1148void TEScreen::addHistLine()
1149{
1150 assert(hasScroll() || histCursor == 0);
1151
1152 // add to hist buffer
1153 // we have to take care about scrolling, too...
1154
1155 if (hasScroll())
1156 { ca dft;
1157
1158 int end = columns-1;
1159 while (end >= 0 && image[end] == dft)
1160 end -= 1;
1161
1162 hist.addCells(image,end+1);
1163 hist.addLine();
1164
1165 // adjust history cursor
1166 histCursor += (hist.getLines()-1 == histCursor);
1167 }
1168
1169 if (!hasScroll()) histCursor = 0; //FIXME: a poor workaround
1170}
1171
1172void TEScreen::setHistCursor(int cursor)
1173{
1174 histCursor = cursor; //FIXME:rangecheck
1175}
1176
1177int TEScreen::getHistCursor()
1178{
1179 return histCursor;
1180}
1181
1182int TEScreen::getHistLines()
1183{
1184 return hist.getLines();
1185}
1186
1187void TEScreen::setScroll(bool on)
1188{
1189 histCursor = 0;
1190 clearSelection();
1191 hist.setScroll(on);
1192}
1193
1194bool TEScreen::hasScroll()
1195{
1196 return hist.hasScroll();
1197}
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 @@
1/* -------------------------------------------------------------------------- */
2/* */
3/* [te_screen.h] Screen Data Type */
4/* */
5/* -------------------------------------------------------------------------- */
6/* */
7/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */
8/* */
9/* This file is part of Konsole - an X terminal for KDE */
10/* */
11/* -------------------------------------------------------------------------- */
12 /* */
13/* Ported Konsole to Qt/Embedded */
14 /* */
15/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */
16 /* */
17/* -------------------------------------------------------------------------- */
18
19#ifndef TESCREEN_H
20#define TESCREEN_H
21
22/*! \file
23*/
24
25#include "TECommon.h"
26#include "TEHistory.h"
27
28#define MODE_Origin 0
29#define MODE_Wrap 1
30#define MODE_Insert 2
31#define MODE_Screen 3
32#define MODE_Cursor 4
33#define MODE_NewLine 5
34#define MODES_SCREEN 6
35
36/*!
37*/
38struct ScreenParm
39{
40 int mode[MODES_SCREEN];
41};
42
43
44class TEScreen
45{
46public:
47 TEScreen(int lines, int columns);
48 ~TEScreen();
49
50public: // these are all `Screen' operations
51 //
52 // VT100/2 Operations ------------------
53 //
54 // Cursor Movement
55 //
56 void cursorUp (int n);
57 void cursorDown (int n);
58 void cursorLeft (int n);
59 void cursorRight (int n);
60 void setCursorY (int y);
61 void setCursorX (int x);
62 void setCursorYX (int y, int x);
63 void setMargins (int t, int b);
64 //
65 // Cursor Movement with Scrolling
66 //
67 void NewLine ();
68 void NextLine ();
69 void index ();
70 void reverseIndex();
71 //
72 void Return ();
73 void BackSpace ();
74 void Tabulate ();
75 //
76 // Editing
77 //
78 void eraseChars (int n);
79 void deleteChars (int n);
80 void insertChars (int n);
81 void deleteLines (int n);
82 void insertLines (int n);
83 //
84 // -------------------------------------
85 //
86 void clearTabStops();
87 void changeTabStop(bool set);
88 //
89 void resetMode (int n);
90 void setMode (int n);
91 void saveMode (int n);
92 void restoreMode (int n);
93 //
94 void saveCursor ();
95 void restoreCursor();
96 //
97 // -------------------------------------
98 //
99 void clearEntireScreen();
100 void clearToEndOfScreen();
101 void clearToBeginOfScreen();
102 //
103 void clearEntireLine();
104 void clearToEndOfLine();
105 void clearToBeginOfLine();
106 //
107 void helpAlign ();
108 //
109 // -------------------------------------
110 //
111 void setRendition (int rendition);
112 void resetRendition(int rendition);
113 void setForeColor (int fgcolor);
114 void setBackColor (int bgcolor);
115 //
116 void setDefaultRendition();
117 void setForeColorToDefault();
118 void setBackColorToDefault();
119 //
120 // -------------------------------------
121 //
122 BOOL getMode (int n);
123 //
124 // only for report cursor position
125 //
126 int getCursorX();
127 int getCursorY();
128 //
129 // -------------------------------------
130 //
131 void clear();
132 void home();
133 void reset();
134 //
135 void ShowCharacter(unsigned short c);
136 //
137 void resizeImage(int new_lines, int new_columns);
138 //
139 ca* getCookedImage();
140
141 /*! return the number of lines. */
142 int getLines() { return lines; }
143 /*! return the number of columns. */
144 int getColumns() { return columns; }
145
146 /*! set the position of the history cursor. */
147 void setHistCursor(int cursor);
148 /*! return the position of the history cursor. */
149 int getHistCursor();
150
151 int getHistLines ();
152 void setScroll(bool on);
153 bool hasScroll();
154
155 //
156 // Selection
157 //
158 void setSelBeginXY(const int x, const int y);
159 void setSelExtentXY(const int x, const int y);
160 void clearSelection();
161 QString getSelText(const BOOL preserve_line_breaks);
162
163 void checkSelection(int from, int to);
164
165private: // helper
166
167 void clearImage(int loca, int loce, char c);
168 void moveImage(int dst, int loca, int loce);
169
170 void scrollUp(int from, int i);
171 void scrollDown(int from, int i);
172
173 void addHistLine();
174
175 void initTabStops();
176
177 void effectiveRendition();
178 void reverseRendition(ca* p);
179
180private:
181
182 /*
183 The state of the screen is more complex as one would
184 expect first. The screem does really do part of the
185 emulation providing state informations in form of modes,
186 margins, tabulators, cursor etc.
187
188 Even more unexpected are variables to save and restore
189 parts of the state.
190 */
191
192 // screen image ----------------
193
194 int lines;
195 int columns;
196 ca *image; // [lines][columns]
197
198 // history buffer ---------------
199
200 int histCursor; // display position relative to start of the history buffer
201 HistoryScroll hist;
202
203 // cursor location
204
205 int cuX;
206 int cuY;
207
208 // cursor color and rendition info
209
210 UINT8 cu_fg; // foreground
211 UINT8 cu_bg; // background
212 UINT8 cu_re; // rendition
213
214 // margins ----------------
215
216 int tmargin; // top margin
217 int bmargin; // bottom margin
218
219 // states ----------------
220
221 ScreenParm currParm;
222
223 // ----------------------------
224
225 bool* tabstops;
226
227 // selection -------------------
228
229 int sel_begin; // The first location selected.
230 int sel_TL; // TopLeft Location.
231 int sel_BR; // Bottom Right Location.
232
233 // effective colors and rendition ------------
234
235 UINT8 ef_fg; // These are derived from
236 UINT8 ef_bg; // the cu_* variables above
237 UINT8 ef_re; // to speed up operation
238
239 //
240 // save cursor, rendition & states ------------
241 //
242
243 // cursor location
244
245 int sa_cuX;
246 int sa_cuY;
247
248 // rendition info
249
250 UINT8 sa_cu_re;
251 UINT8 sa_cu_fg;
252 UINT8 sa_cu_bg;
253
254 // modes
255
256 ScreenParm saveParm;
257};
258
259#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 @@
1/* ------------------------------------------------------------------------ */
2/* */
3/* [TEWidget.C] Terminal Emulation Widget */
4/* */
5/* ------------------------------------------------------------------------ */
6/* */
7/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */
8/* */
9/* This file is part of Konsole - an X terminal for KDE */
10/* */
11/* ------------------------------------------------------------------------ */
12 /* */
13/* Ported Konsole to Qt/Embedded */
14 /* */
15/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */
16 /* */
17/* -------------------------------------------------------------------------- */
18
19/*! \class TEWidget
20
21 \brief Visible screen contents
22
23 This class is responsible to map the `image' of a terminal emulation to the
24 display. All the dependency of the emulation to a specific GUI or toolkit is
25 localized here. Further, this widget has no knowledge about being part of an
26 emulation, it simply work within the terminal emulation framework by exposing
27 size and key events and by being ordered to show a new image.
28
29 <ul>
30 <li> The internal image has the size of the widget (evtl. rounded up)
31 <li> The external image used in setImage can have any size.
32 <li> (internally) the external image is simply copied to the internal
33 when a setImage happens. During a resizeEvent no painting is done
34 a paintEvent is expected to follow anyway.
35 </ul>
36
37 \sa TEScreen \sa Emulation
38*/
39
40/* FIXME:
41 - 'image' may also be used uninitialized (it isn't in fact) in resizeEvent
42 - 'font_a' not used in mouse events
43 - add destructor
44*/
45
46/* TODO
47 - evtl. be sensitive to `paletteChange' while using default colors.
48 - set different 'rounding' styles? I.e. have a mode to show clipped chars?
49*/
50
51// #include "config.h"
52#include "TEWidget.h"
53#include "session.h"
54
55#include <qcursor.h>
56#include <qregexp.h>
57#include <qpainter.h>
58#include <qclipboard.h>
59#include <qstyle.h>
60#include <qfile.h>
61#include <qdragobject.h>
62
63#include <stdio.h>
64#include <stdlib.h>
65#include <unistd.h>
66#include <ctype.h>
67#include <sys/stat.h>
68#include <sys/types.h>
69#include <signal.h>
70
71#include <assert.h>
72
73// #include "TEWidget.moc"
74//#include <kapp.h>
75//#include <kcursor.h>
76//#include <kurl.h>
77//#include <kdebug.h>
78//#include <klocale.h>
79
80#define HERE printf("%s(%d): %s\n",__FILE__,__LINE__,__FUNCTION__)
81#define HCNT(Name) // { static int cnt = 1; printf("%s(%d): %s %d\n",__FILE__,__LINE__,Name,cnt++); }
82
83#define loc(X,Y) ((Y)*columns+(X))
84
85//FIXME: the rim should normally be 1, 0 only when running in full screen mode.
86#define rimX 0 // left/right rim width
87#define rimY 0 // top/bottom rim high
88
89#define SCRWIDTH 16 // width of the scrollbar
90
91#define yMouseScroll 1
92// scroll increment used when dragging selection at top/bottom of window.
93
94/* ------------------------------------------------------------------------- */
95/* */
96/* Colors */
97/* */
98/* ------------------------------------------------------------------------- */
99
100//FIXME: the default color table is in session.C now.
101// We need a way to get rid of this one, here.
102static const ColorEntry base_color_table[TABLE_COLORS] =
103// The following are almost IBM standard color codes, with some slight
104// gamma correction for the dim colors to compensate for bright X screens.
105// It contains the 8 ansiterm/xterm colors in 2 intensities.
106{
107 // Fixme: could add faint colors here, also.
108 // normal
109 ColorEntry(QColor(0x00,0x00,0x00), 0, 0 ), ColorEntry( QColor(0xB2,0xB2,0xB2), 1, 0 ), // Dfore, Dback
110 ColorEntry(QColor(0x00,0x00,0x00), 0, 0 ), ColorEntry( QColor(0xB2,0x18,0x18), 0, 0 ), // Black, Red
111 ColorEntry(QColor(0x18,0xB2,0x18), 0, 0 ), ColorEntry( QColor(0xB2,0x68,0x18), 0, 0 ), // Green, Yellow
112 ColorEntry(QColor(0x18,0x18,0xB2), 0, 0 ), ColorEntry( QColor(0xB2,0x18,0xB2), 0, 0 ), // Blue, Magenta
113 ColorEntry(QColor(0x18,0xB2,0xB2), 0, 0 ), ColorEntry( QColor(0xB2,0xB2,0xB2), 0, 0 ), // Cyan, White
114 // intensiv
115 ColorEntry(QColor(0x00,0x00,0x00), 0, 1 ), ColorEntry( QColor(0xFF,0xFF,0xFF), 1, 0 ),
116 ColorEntry(QColor(0x68,0x68,0x68), 0, 0 ), ColorEntry( QColor(0xFF,0x54,0x54), 0, 0 ),
117 ColorEntry(QColor(0x54,0xFF,0x54), 0, 0 ), ColorEntry( QColor(0xFF,0xFF,0x54), 0, 0 ),
118 ColorEntry(QColor(0x54,0x54,0xFF), 0, 0 ), ColorEntry( QColor(0xFF,0x54,0xFF), 0, 0 ),
119 ColorEntry(QColor(0x54,0xFF,0xFF), 0, 0 ), ColorEntry( QColor(0xFF,0xFF,0xFF), 0, 0 )
120};
121
122/* Note that we use ANSI color order (bgr), while IBMPC color order is (rgb)
123
124 Code 0 1 2 3 4 5 6 7
125 ----------- ------- ------- ------- ------- ------- ------- ------- -------
126 ANSI (bgr) Black Red Green Yellow Blue Magenta Cyan White
127 IBMPC (rgb) Black Blue Green Cyan Red Magenta Yellow White
128*/
129
130QColor TEWidget::getDefaultBackColor()
131{
132 return color_table[DEFAULT_BACK_COLOR].color;
133}
134
135const ColorEntry* TEWidget::getColorTable() const
136{
137 return color_table;
138}
139
140const QPixmap *TEWidget::backgroundPixmap()
141{
142 static QPixmap *bg = new QPixmap("~/qpim/main/pics/faded_bg.xpm");
143 const QPixmap *pm = bg;
144 return pm;
145}
146
147void TEWidget::setColorTable(const ColorEntry table[])
148{
149 for (int i = 0; i < TABLE_COLORS; i++) color_table[i] = table[i];
150
151 const QPixmap* pm = backgroundPixmap();
152 if (!pm) setBackgroundColor(color_table[DEFAULT_BACK_COLOR].color);
153 update();
154}
155
156//FIXME: add backgroundPixmapChanged.
157
158/* ------------------------------------------------------------------------- */
159/* */
160/* Font */
161/* */
162/* ------------------------------------------------------------------------- */
163
164/*
165 The VT100 has 32 special graphical characters. The usual vt100 extended
166 xterm fonts have these at 0x00..0x1f.
167
168 QT's iso mapping leaves 0x00..0x7f without any changes. But the graphicals
169 come in here as proper unicode characters.
170
171 We treat non-iso10646 fonts as VT100 extended and do the requiered mapping
172 from unicode to 0x00..0x1f. The remaining translation is then left to the
173 QCodec.
174*/
175
176// assert for i in [0..31] : vt100extended(vt100_graphics[i]) == i.
177
178unsigned short vt100_graphics[32] =
179{ // 0/8 1/9 2/10 3/11 4/12 5/13 6/14 7/15
180 0x0020, 0x25C6, 0x2592, 0x2409, 0x240c, 0x240d, 0x240a, 0x00b0,
181 0x00b1, 0x2424, 0x240b, 0x2518, 0x2510, 0x250c, 0x2514, 0x253c,
182 0xF800, 0xF801, 0x2500, 0xF803, 0xF804, 0x251c, 0x2524, 0x2534,
183 0x252c, 0x2502, 0x2264, 0x2265, 0x03C0, 0x2260, 0x00A3, 0x00b7
184};
185
186static QChar vt100extended(QChar c)
187{
188 switch (c.unicode())
189 {
190 case 0x25c6 : return 1;
191 case 0x2592 : return 2;
192 case 0x2409 : return 3;
193 case 0x240c : return 4;
194 case 0x240d : return 5;
195 case 0x240a : return 6;
196 case 0x00b0 : return 7;
197 case 0x00b1 : return 8;
198 case 0x2424 : return 9;
199 case 0x240b : return 10;
200 case 0x2518 : return 11;
201 case 0x2510 : return 12;
202 case 0x250c : return 13;
203 case 0x2514 : return 14;
204 case 0x253c : return 15;
205 case 0xf800 : return 16;
206 case 0xf801 : return 17;
207 case 0x2500 : return 18;
208 case 0xf803 : return 19;
209 case 0xf804 : return 20;
210 case 0x251c : return 21;
211 case 0x2524 : return 22;
212 case 0x2534 : return 23;
213 case 0x252c : return 24;
214 case 0x2502 : return 25;
215 case 0x2264 : return 26;
216 case 0x2265 : return 27;
217 case 0x03c0 : return 28;
218 case 0x2260 : return 29;
219 case 0x00a3 : return 30;
220 case 0x00b7 : return 31;
221 }
222 return c;
223}
224
225static QChar identicalMap(QChar c)
226{
227 return c;
228}
229
230void TEWidget::fontChange(const QFont &)
231{
232 QFontMetrics fm(font());
233 font_h = fm.height();
234 font_w = fm.maxWidth();
235 font_a = fm.ascent();
236//printf("font_h: %d\n",font_h);
237//printf("font_w: %d\n",font_w);
238//printf("font_a: %d\n",font_a);
239//printf("charset: %s\n",QFont::encodingName(font().charSet()).ascii());
240//printf("rawname: %s\n",font().rawName().ascii());
241 fontMap =
242#if QT_VERSION < 300
243 strcmp(QFont::encodingName(font().charSet()).ascii(),"iso10646")
244 ? vt100extended
245 :
246#endif
247 identicalMap;
248 propagateSize();
249 update();
250}
251
252void TEWidget::setVTFont(const QFont& f)
253{
254 QFrame::setFont(f);
255}
256
257QFont TEWidget::getVTFont()
258{
259 return font();
260}
261
262void TEWidget::setFont(const QFont &)
263{
264 // ignore font change request if not coming from konsole itself
265}
266
267/* ------------------------------------------------------------------------- */
268/* */
269/* Constructor / Destructor */
270/* */
271/* ------------------------------------------------------------------------- */
272
273TEWidget::TEWidget(QWidget *parent, const char *name) : QFrame(parent,name)
274{
275#ifndef QT_NO_CLIPBOARD
276 cb = QApplication::clipboard();
277 QObject::connect( (QObject*)cb, SIGNAL(dataChanged()),
278 this, SLOT(onClearSelection()) );
279#endif
280
281 scrollbar = new QScrollBar(this);
282 scrollbar->setCursor( arrowCursor );
283 connect(scrollbar, SIGNAL(valueChanged(int)), this, SLOT(scrollChanged(int)));
284 scrollLoc = SCRNONE;
285
286 blinkT = new QTimer(this);
287 connect(blinkT, SIGNAL(timeout()), this, SLOT(blinkEvent()));
288 // blinking = FALSE;
289 blinking = TRUE;
290
291 resizing = FALSE;
292 actSel = 0;
293 image = 0;
294 lines = 1;
295 columns = 1;
296 font_w = 1;
297 font_h = 1;
298 font_a = 1;
299 word_selection_mode = FALSE;
300
301 setMouseMarks(TRUE);
302 setVTFont( QFont("fixed") );
303 setColorTable(base_color_table); // init color table
304
305 qApp->installEventFilter( this ); //FIXME: see below
306// KCursor::setAutoHideCursor( this, true );
307
308 // Init DnD ////////////////////////////////////////////////////////////////
309 currentSession = NULL;
310// setAcceptDrops(true); // attempt
311// m_drop = new QPopupMenu(this);
312// m_drop->insertItem( QString("Paste"), 0);
313// m_drop->insertItem( QString("cd"), 1);
314// connect(m_drop, SIGNAL(activated(int)), SLOT(drop_menu_activated(int)));
315
316 // we need focus so that the auto-hide cursor feature works
317 setFocus();
318 setFocusPolicy( WheelFocus );
319}
320
321//FIXME: make proper destructor
322// Here's a start (David)
323TEWidget::~TEWidget()
324{
325 qApp->removeEventFilter( this );
326 if (image) free(image);
327}
328
329/* ------------------------------------------------------------------------- */
330/* */
331/* Display Operations */
332/* */
333/* ------------------------------------------------------------------------- */
334
335/*!
336 attributed string draw primitive
337*/
338
339void TEWidget::drawAttrStr(QPainter &paint, QRect rect,
340 QString& str, ca attr, BOOL pm, BOOL clear)
341{
342 if (pm && color_table[attr.b].transparent)
343 {
344 paint.setBackgroundMode( TransparentMode );
345 if (clear) erase(rect);
346 }
347 else
348 {
349 if (blinking)
350 paint.fillRect(rect, color_table[attr.b].color);
351 else
352 {
353 paint.setBackgroundMode( OpaqueMode );
354 paint.setBackgroundColor( color_table[attr.b].color );
355 }
356 }
357
358 if (color_table[attr.f].bold)
359 paint.setPen(QColor( 0x8F, 0x00, 0x00 ));
360 else
361 paint.setPen(color_table[attr.f].color);
362
363 paint.drawText(rect.x(),rect.y()+font_a, str);
364
365 if (attr.r & RE_UNDERLINE)
366 paint.drawLine(rect.left(), rect.y()+font_a+1, rect.right(),rect.y()+font_a+1 );
367}
368
369/*!
370 The image can only be set completely.
371
372 The size of the new image may or may not match the size of the widget.
373*/
374
375void TEWidget::setImage(const ca* const newimg, int lines, int columns)
376{ int y,x,len;
377 const QPixmap* pm = backgroundPixmap();
378 QPainter paint;
379 setUpdatesEnabled(FALSE);
380 paint.begin( this );
381HCNT("setImage");
382
383 QPoint tL = contentsRect().topLeft();
384 int tLx = tL.x();
385 int tLy = tL.y();
386 hasBlinker = FALSE;
387
388 int cf = -1; // undefined
389 int cb = -1; // undefined
390 int cr = -1; // undefined
391
392 int lins = QMIN(this->lines, QMAX(0,lines ));
393 int cols = QMIN(this->columns,QMAX(0,columns));
394 QChar *disstrU = new QChar[cols];
395
396//{ static int cnt = 0; printf("setImage %d\n",cnt++); }
397 for (y = 0; y < lins; y++)
398 {
399 const ca* lcl = &image[y*this->columns];
400 const ca* const ext = &newimg[y*columns];
401 if (!resizing) // not while resizing, we're expecting a paintEvent
402 for (x = 0; x < cols; x++)
403 {
404 hasBlinker |= (ext[x].r & RE_BLINK);
405 if (ext[x] != lcl[x])
406 {
407 cr = ext[x].r;
408 cb = ext[x].b;
409 if (ext[x].f != cf) cf = ext[x].f;
410 int lln = cols - x;
411 disstrU[0] = fontMap(ext[x+0].c);
412 for (len = 1; len < lln; len++)
413 {
414 if (ext[x+len].f != cf || ext[x+len].b != cb || ext[x+len].r != cr ||
415 ext[x+len] == lcl[x+len] )
416 break;
417 disstrU[len] = fontMap(ext[x+len].c);
418 }
419 QString unistr(disstrU,len);
420 drawAttrStr(paint,
421 QRect(blX+tLx+font_w*x,bY+tLy+font_h*y,font_w*len,font_h),
422 unistr, ext[x], pm != NULL, true);
423 x += len - 1;
424 }
425 }
426 // finally, make `image' become `newimg'.
427 memcpy((void*)lcl,(const void*)ext,cols*sizeof(ca));
428 }
429 drawFrame( &paint );
430 paint.end();
431 setUpdatesEnabled(TRUE);
432 if ( hasBlinker && !blinkT->isActive()) blinkT->start(1000); // 1000 ms
433 if (!hasBlinker && blinkT->isActive()) { blinkT->stop(); blinking = FALSE; }
434 delete [] disstrU;
435}
436
437// paint Event ////////////////////////////////////////////////////
438
439/*!
440 The difference of this routine vs. the `setImage' is,
441 that the drawing does not include a difference analysis
442 between the old and the new image. Instead, the internal
443 image is used and the painting bound by the PaintEvent box.
444*/
445
446void TEWidget::paintEvent( QPaintEvent* pe )
447{
448
449//{ static int cnt = 0; printf("paint %d\n",cnt++); }
450 const QPixmap* pm = backgroundPixmap();
451 QPainter paint;
452 setUpdatesEnabled(FALSE);
453 paint.begin( this );
454 paint.setBackgroundMode( TransparentMode );
455HCNT("paintEvent");
456
457 // Note that the actual widget size can be slightly larger
458 // that the image (the size is truncated towards the smaller
459 // number of characters in `resizeEvent'. The paint rectangle
460 // can thus be larger than the image, but less then the size
461 // of one character.
462
463 QRect rect = pe->rect().intersect(contentsRect());
464
465 QPoint tL = contentsRect().topLeft();
466 int tLx = tL.x();
467 int tLy = tL.y();
468
469 int lux = QMIN(columns-1, QMAX(0,(rect.left() - tLx - blX ) / font_w));
470 int luy = QMIN(lines-1, QMAX(0,(rect.top() - tLy - bY ) / font_h));
471 int rlx = QMIN(columns-1, QMAX(0,(rect.right() - tLx - blX ) / font_w));
472 int rly = QMIN(lines-1, QMAX(0,(rect.bottom() - tLy - bY ) / font_h));
473
474 /*
475 printf("paintEvent: %d..%d, %d..%d (%d..%d, %d..%d)\n",lux,rlx,luy,rly,
476 rect.left(), rect.right(), rect.top(), rect.bottom());
477 */
478
479 // if (pm != NULL && color_table[image->b].transparent)
480 // erase(rect);
481 // BL: I have no idea why we need this, and it breaks the refresh.
482
483 QChar *disstrU = new QChar[columns];
484 for (int y = luy; y <= rly; y++)
485 for (int x = lux; x <= rlx; x++)
486 {
487 int len = 1;
488 disstrU[0] = fontMap(image[loc(x,y)].c);
489 int cf = image[loc(x,y)].f;
490 int cb = image[loc(x,y)].b;
491 int cr = image[loc(x,y)].r;
492 while (x+len <= rlx &&
493 image[loc(x+len,y)].f == cf &&
494 image[loc(x+len,y)].b == cb &&
495 image[loc(x+len,y)].r == cr )
496 {
497 disstrU[len] = fontMap(image[loc(x+len,y)].c);
498 len += 1;
499 }
500 QString unistr(disstrU,len);
501 drawAttrStr(paint,
502 QRect(blX+tLx+font_w*x,bY+tLy+font_h*y,font_w*len,font_h),
503 unistr, image[loc(x,y)], pm != NULL, false);
504 x += len - 1;
505 }
506 delete [] disstrU;
507 drawFrame( &paint );
508 paint.end();
509 setUpdatesEnabled(TRUE);
510}
511
512void TEWidget::blinkEvent()
513{
514 blinking = !blinking;
515 repaint(FALSE);
516}
517
518/* ------------------------------------------------------------------------- */
519/* */
520/* Resizing */
521/* */
522/* ------------------------------------------------------------------------- */
523
524void TEWidget::resizeEvent(QResizeEvent* ev)
525{
526 //printf("resize: %d,%d\n",ev->size().width(),ev->size().height());
527 //printf("approx: %d,%d\n",ev->size().width()/font_w,ev->size().height()/font_h);
528 //printf("leaves: %d,%d\n",ev->size().width()%font_w,ev->size().height()%font_h);
529 //printf("curren: %d,%d\n",width(),height());
530HCNT("resizeEvent");
531
532 // see comment in `paintEvent' concerning the rounding.
533 //FIXME: could make a routine here; check width(),height()
534 assert(ev->size().width() == width());
535 assert(ev->size().height() == height());
536
537 propagateSize();
538}
539
540void TEWidget::propagateSize()
541{
542 ca* oldimg = image;
543 int oldlin = lines;
544 int oldcol = columns;
545 makeImage();
546 // we copy the old image to reduce flicker
547 int lins = QMIN(oldlin,lines);
548 int cols = QMIN(oldcol,columns);
549 if (oldimg)
550 {
551 for (int lin = 0; lin < lins; lin++)
552 memcpy((void*)&image[columns*lin],
553 (void*)&oldimg[oldcol*lin],cols*sizeof(ca));
554 free(oldimg); //FIXME: try new,delete
555 }
556 else
557 clearImage();
558
559 //NOTE: control flows from the back through the chest right into the eye.
560 // `emu' will call back via `setImage'.
561
562 resizing = TRUE;
563 emit changedImageSizeSignal(lines, columns); // expose resizeEvent
564 resizing = FALSE;
565}
566
567/* ------------------------------------------------------------------------- */
568/* */
569/* Scrollbar */
570/* */
571/* ------------------------------------------------------------------------- */
572
573void TEWidget::scrollChanged(int)
574{
575 emit changedHistoryCursor(scrollbar->value()); //expose
576}
577
578void TEWidget::setScroll(int cursor, int slines)
579{
580 disconnect(scrollbar, SIGNAL(valueChanged(int)), this, SLOT(scrollChanged(int)));
581 scrollbar->setRange(0,slines);
582 scrollbar->setSteps(1,lines);
583 scrollbar->setValue(cursor);
584 connect(scrollbar, SIGNAL(valueChanged(int)), this, SLOT(scrollChanged(int)));
585}
586
587void TEWidget::setScrollbarLocation(int loc)
588{
589 if (scrollLoc == loc) return; // quickly
590 scrollLoc = loc;
591 propagateSize();
592 update();
593}
594
595/* ------------------------------------------------------------------------- */
596/* */
597/* Mouse */
598/* */
599/* ------------------------------------------------------------------------- */
600
601/*!
602 Three different operations can be performed using the mouse, and the
603 routines in this section serve all of them:
604
605 1) The press/release events are exposed to the application
606 2) Marking (press and move left button) and Pasting (press middle button)
607 3) The right mouse button is used from the configuration menu
608
609 NOTE: During the marking process we attempt to keep the cursor within
610 the bounds of the text as being displayed by setting the mouse position
611 whenever the mouse has left the text area.
612
613 Two reasons to do so:
614 1) QT does not allow the `grabMouse' to confine-to the TEWidget.
615 Thus a `XGrapPointer' would have to be used instead.
616 2) Even if so, this would not help too much, since the text area
617 of the TEWidget is normally not identical with it's bounds.
618
619 The disadvantage of the current handling is, that the mouse can visibly
620 leave the bounds of the widget and is then moved back. Because of the
621 current construction, and the reasons mentioned above, we cannot do better
622 without changing the overall construction.
623*/
624
625/*!
626*/
627
628void TEWidget::mousePressEvent(QMouseEvent* ev)
629{
630//printf("press [%d,%d] %d\n",ev->x()/font_w,ev->y()/font_h,ev->button());
631 if ( !contentsRect().contains(ev->pos()) ) return;
632 QPoint tL = contentsRect().topLeft();
633 int tLx = tL.x();
634 int tLy = tL.y();
635
636 word_selection_mode = FALSE;
637
638//printf("press top left [%d,%d] by=%d\n",tLx,tLy, bY);
639 if ( ev->button() == LeftButton)
640 {
641 QPoint pos = QPoint((ev->x()-tLx-blX)/font_w,(ev->y()-tLy-bY)/font_h);
642
643 if ( ev->state() & ControlButton ) preserve_line_breaks = FALSE ;
644
645 if (mouse_marks || (ev->state() & ShiftButton))
646 {
647 emit clearSelectionSignal();
648 iPntSel = pntSel = pos;
649 actSel = 1; // left mouse button pressed but nothing selected yet.
650 grabMouse( /*crossCursor*/ ); // handle with care!
651 }
652 else
653 {
654 emit mouseSignal( 0, pos.x() + 1, pos.y() + 1 ); // left button
655 }
656 }
657 if ( ev->button() == MidButton )
658 {
659 emitSelection();
660 }
661 if ( ev->button() == RightButton ) // Configure
662 {
663 emit configureRequest( this, ev->state()&(ShiftButton|ControlButton), ev->x(), ev->y() );
664 }
665}
666
667void TEWidget::mouseMoveEvent(QMouseEvent* ev)
668{
669 // for auto-hiding the cursor, we need mouseTracking
670 if (ev->state() == NoButton ) return;
671
672 if (actSel == 0) return;
673
674 // don't extend selection while pasting
675 if (ev->state() & MidButton) return;
676
677 //if ( !contentsRect().contains(ev->pos()) ) return;
678 QPoint tL = contentsRect().topLeft();
679 int tLx = tL.x();
680 int tLy = tL.y();
681 int scroll = scrollbar->value();
682
683 // we're in the process of moving the mouse with the left button pressed
684 // the mouse cursor will kept catched within the bounds of the text in
685 // this widget.
686
687 // Adjust position within text area bounds. See FIXME above.
688 QPoint pos = ev->pos();
689 if ( pos.x() < tLx+blX ) pos.setX( tLx+blX );
690 if ( pos.x() > tLx+blX+columns*font_w-1 ) pos.setX( tLx+blX+columns*font_w );
691 if ( pos.y() < tLy+bY ) pos.setY( tLy+bY );
692 if ( pos.y() > tLy+bY+lines*font_h-1 ) pos.setY( tLy+bY+lines*font_h-1 );
693 // check if we produce a mouse move event by this
694 if ( pos != ev->pos() ) cursor().setPos(mapToGlobal(pos));
695
696 if ( pos.y() == tLy+bY+lines*font_h-1 )
697 {
698 scrollbar->setValue(scrollbar->value()+yMouseScroll); // scrollforward
699 }
700 if ( pos.y() == tLy+bY )
701 {
702 scrollbar->setValue(scrollbar->value()-yMouseScroll); // scrollback
703 }
704
705 QPoint here = QPoint((pos.x()-tLx-blX)/font_w,(pos.y()-tLy-bY)/font_h);
706 QPoint ohere;
707 bool swapping = FALSE;
708
709 if ( word_selection_mode )
710 {
711 // Extend to word boundaries
712 int i;
713 int selClass;
714
715 bool left_not_right = ( here.y() < iPntSel.y() ||
716 here.y() == iPntSel.y() && here.x() < iPntSel.x() );
717 bool old_left_not_right = ( pntSel.y() < iPntSel.y() ||
718 pntSel.y() == iPntSel.y() && pntSel.x() < iPntSel.x() );
719 swapping = left_not_right != old_left_not_right;
720
721 // Find left (left_not_right ? from here : from start)
722 QPoint left = left_not_right ? here : iPntSel;
723 i = loc(left.x(),left.y());
724 selClass = charClass(image[i].c);
725 while ( left.x() > 0 && charClass(image[i-1].c) == selClass )
726 { i--; left.rx()--; }
727
728 // Find left (left_not_right ? from start : from here)
729 QPoint right = left_not_right ? iPntSel : here;
730 i = loc(right.x(),right.y());
731 selClass = charClass(image[i].c);
732 while ( right.x() < columns-1 && charClass(image[i+1].c) == selClass )
733 { i++; right.rx()++; }
734
735 // Pick which is start (ohere) and which is extension (here)
736 if ( left_not_right )
737 {
738 here = left; ohere = right;
739 }
740 else
741 {
742 here = right; ohere = left;
743 }
744 }
745
746 if (here == pntSel && scroll == scrollbar->value()) return; // not moved
747
748 if ( word_selection_mode ) {
749 if ( actSel < 2 || swapping ) {
750 emit beginSelectionSignal( ohere.x(), ohere.y() );
751 }
752 } else if ( actSel < 2 ) {
753 emit beginSelectionSignal( pntSel.x(), pntSel.y() );
754 }
755
756 actSel = 2; // within selection
757 pntSel = here;
758 emit extendSelectionSignal( here.x(), here.y() );
759}
760
761void TEWidget::mouseReleaseEvent(QMouseEvent* ev)
762{
763//printf("release [%d,%d] %d\n",ev->x()/font_w,ev->y()/font_h,ev->button());
764 if ( ev->button() == LeftButton)
765 {
766 if ( actSel > 1 ) emit endSelectionSignal(preserve_line_breaks);
767 preserve_line_breaks = TRUE;
768 actSel = 0;
769
770 //FIXME: emits a release event even if the mouse is
771 // outside the range. The procedure used in `mouseMoveEvent'
772 // applies here, too.
773
774 QPoint tL = contentsRect().topLeft();
775 int tLx = tL.x();
776 int tLy = tL.y();
777
778 if (!mouse_marks && !(ev->state() & ShiftButton))
779 emit mouseSignal( 3, // release
780 (ev->x()-tLx-blX)/font_w + 1,
781 (ev->y()-tLy-bY)/font_h + 1 );
782 releaseMouse();
783 }
784}
785
786void TEWidget::mouseDoubleClickEvent(QMouseEvent* ev)
787{
788 if ( ev->button() != LeftButton) return;
789
790 QPoint tL = contentsRect().topLeft();
791 int tLx = tL.x();
792 int tLy = tL.y();
793 QPoint pos = QPoint((ev->x()-tLx-blX)/font_w,(ev->y()-tLy-bY)/font_h);
794
795 // pass on double click as two clicks.
796 if (!mouse_marks && !(ev->state() & ShiftButton))
797 {
798 emit mouseSignal( 0, pos.x()+1, pos.y()+1 ); // left button
799 emit mouseSignal( 3, pos.x()+1, pos.y()+1 ); // release
800 emit mouseSignal( 0, pos.x()+1, pos.y()+1 ); // left button
801 return;
802 }
803
804
805 emit clearSelectionSignal();
806 QPoint bgnSel = pos;
807 QPoint endSel = QPoint((ev->x()-tLx-blX)/font_w,(ev->y()-tLy-bY)/font_h);
808 int i = loc(bgnSel.x(),bgnSel.y());
809 iPntSel = bgnSel;
810
811 word_selection_mode = TRUE;
812
813 // find word boundaries...
814 int selClass = charClass(image[i].c);
815 {
816 // set the start...
817 int x = bgnSel.x();
818 while ( x > 0 && charClass(image[i-1].c) == selClass )
819 { i--; x--; }
820 bgnSel.setX(x);
821 emit beginSelectionSignal( bgnSel.x(), bgnSel.y() );
822
823 // set the end...
824 i = loc( endSel.x(), endSel.y() );
825 x = endSel.x();
826 while( x < columns-1 && charClass(image[i+1].c) == selClass )
827 { i++; x++ ; }
828 endSel.setX(x);
829 actSel = 2; // within selection
830 emit extendSelectionSignal( endSel.x(), endSel.y() );
831 emit endSelectionSignal(preserve_line_breaks);
832 preserve_line_breaks = TRUE;
833 }
834}
835
836void TEWidget::focusInEvent( QFocusEvent * )
837{
838 // do nothing, to prevent repainting
839}
840
841
842void TEWidget::focusOutEvent( QFocusEvent * )
843{
844 // do nothing, to prevent repainting
845}
846
847bool TEWidget::focusNextPrevChild( bool next )
848{
849 if (next)
850 return false; // This disables changing the active part in konqueror
851 // when pressing Tab
852 return QFrame::focusNextPrevChild( next );
853}
854
855
856int TEWidget::charClass(char ch) const
857{
858 // This might seem like overkill, but imagine if ch was a Unicode
859 // character (Qt 2.0 QChar) - it might then be sensible to separate
860 // the different language ranges, etc.
861
862 if ( isspace(ch) ) return ' ';
863
864 static const char *word_characters = ":@-./_~";
865 if ( isalnum(ch) || strchr(word_characters, ch) )
866 return 'a';
867
868 // Everything else is weird
869 return 1;
870}
871
872void TEWidget::setMouseMarks(bool on)
873{
874 mouse_marks = on;
875 setCursor( mouse_marks ? ibeamCursor : arrowCursor );
876}
877
878/* ------------------------------------------------------------------------- */
879/* */
880/* Clipboard */
881/* */
882/* ------------------------------------------------------------------------- */
883
884#undef KeyPress
885
886void TEWidget::emitSelection()
887// Paste Clipboard by simulating keypress events
888{
889#ifndef QT_NO_CLIPBOARD
890 QString text = QApplication::clipboard()->text();
891 if ( ! text.isNull() )
892 {
893 text.replace(QRegExp("\n"), "\r");
894 QKeyEvent e(QEvent::KeyPress, 0, -1, 0, text);
895 emit keyPressedSignal(&e); // expose as a big fat keypress event
896 emit clearSelectionSignal();
897 }
898#endif
899}
900
901void TEWidget::emitText(QString text)
902{
903 QKeyEvent e(QEvent::KeyPress, 0, -1, 0, text);
904 emit keyPressedSignal(&e); // expose as a big fat keypress event
905}
906
907void TEWidget::pasteClipboard( )
908{
909 emitSelection();
910}
911
912void TEWidget::setSelection(const QString& t)
913{
914#ifndef QT_NO_CLIPBOARD
915 // Disconnect signal while WE set the clipboard
916 QObject *cb = QApplication::clipboard();
917 QObject::disconnect( cb, SIGNAL(dataChanged()),
918 this, SLOT(onClearSelection()) );
919
920 QApplication::clipboard()->setText(t);
921
922 QObject::connect( cb, SIGNAL(dataChanged()),
923 this, SLOT(onClearSelection()) );
924#endif
925}
926
927void TEWidget::onClearSelection()
928{
929 emit clearSelectionSignal();
930}
931
932/* ------------------------------------------------------------------------- */
933/* */
934/* Keyboard */
935/* */
936/* ------------------------------------------------------------------------- */
937
938//FIXME: an `eventFilter' has been installed instead of a `keyPressEvent'
939// due to a bug in `QT' or the ignorance of the author to prevent
940// repaint events being emitted to the screen whenever one leaves
941// or reenters the screen to/from another application.
942//
943// Troll says one needs to change focusInEvent() and focusOutEvent(),
944// which would also let you have an in-focus cursor and an out-focus
945// cursor like xterm does.
946
947// for the auto-hide cursor feature, I added empty focusInEvent() and
948// focusOutEvent() so that update() isn't called.
949// For auto-hide, we need to get keypress-events, but we only get them when
950// we have focus.
951
952void TEWidget::doScroll(int lines)
953{
954 scrollbar->setValue(scrollbar->value()+lines);
955}
956
957bool TEWidget::eventFilter( QObject *obj, QEvent *e )
958{
959 if ( (e->type() == QEvent::Accel ||
960 e->type() == QEvent::AccelAvailable ) && qApp->focusWidget() == this )
961 {
962 static_cast<QKeyEvent *>( e )->ignore();
963 return true;
964 }
965 if ( obj != this /* when embedded */ && obj != parent() /* when standalone */ )
966 return FALSE; // not us
967 if ( e->type() == QEvent::Wheel)
968 {
969 QApplication::sendEvent(scrollbar, e);
970 }
971
972#ifdef FAKE_CTRL_AND_ALT
973 static bool control = FALSE;
974 static bool alt = FALSE;
975 // Has a keyboard with no CTRL and ALT keys, but we fake it:
976 bool dele=FALSE;
977 if ( e->type() == QEvent::KeyPress || e->type() == QEvent::KeyRelease ) {
978 QKeyEvent* ke = (QKeyEvent*)e;
979 bool keydown = e->type() == QEvent::KeyPress || ke->isAutoRepeat();
980 switch (ke->key()) {
981 case Key_F9: // let this be "Control"
982 control = keydown;
983 e = new QKeyEvent(QEvent::KeyPress, Key_Control, 0, ke->state());
984 dele=TRUE;
985 break;
986 case Key_F13: // let this be "Alt"
987 alt = keydown;
988 e = new QKeyEvent(QEvent::KeyPress, Key_Alt, 0, ke->state());
989 dele=TRUE;
990 break;
991 default:
992 if ( control ) {
993 int a = toupper(ke->ascii())-64;
994 if ( a >= 0 && a < ' ' ) {
995 e = new QKeyEvent(e->type(), ke->key(),
996 a, ke->state()|ControlButton, QChar(a,0));
997 dele=TRUE;
998 }
999 }
1000 if ( alt ) {
1001 e = new QKeyEvent(e->type(), ke->key(),
1002 ke->ascii(), ke->state()|AltButton, ke->text());
1003 dele=TRUE;
1004 }
1005 }
1006 }
1007#endif
1008
1009 if ( e->type() == QEvent::KeyPress )
1010 {
1011 QKeyEvent* ke = (QKeyEvent*)e;
1012
1013 actSel=0; // Key stroke implies a screen update, so TEWidget won't
1014 // know where the current selection is.
1015
1016 emit keyPressedSignal(ke); // expose
1017 ke->accept();
1018#ifdef FAKE_CTRL_AND_ALT
1019 if ( dele ) delete e;
1020#endif
1021 return true; // stop the event
1022 }
1023 if ( e->type() == QEvent::Enter )
1024 {
1025 QObject::disconnect( (QObject*)cb, SIGNAL(dataChanged()),
1026 this, SLOT(onClearSelection()) );
1027 }
1028 if ( e->type() == QEvent::Leave )
1029 {
1030 QObject::connect( (QObject*)cb, SIGNAL(dataChanged()),
1031 this, SLOT(onClearSelection()) );
1032 }
1033 return QFrame::eventFilter( obj, e );
1034}
1035
1036/* ------------------------------------------------------------------------- */
1037/* */
1038/* Frame */
1039/* */
1040/* ------------------------------------------------------------------------- */
1041
1042void TEWidget::frameChanged()
1043{
1044 propagateSize();
1045 update();
1046}
1047
1048/* ------------------------------------------------------------------------- */
1049/* */
1050/* Sound */
1051/* */
1052/* ------------------------------------------------------------------------- */
1053
1054void TEWidget::Bell()
1055{
1056 QApplication::beep();
1057}
1058
1059/* ------------------------------------------------------------------------- */
1060/* */
1061/* Auxiluary */
1062/* */
1063/* ------------------------------------------------------------------------- */
1064
1065void TEWidget::clearImage()
1066// initialize the image
1067// for internal use only
1068{
1069 for (int y = 0; y < lines; y++)
1070 for (int x = 0; x < columns; x++)
1071 {
1072 image[loc(x,y)].c = 0xff; //' ';
1073 image[loc(x,y)].f = 0xff; //DEFAULT_FORE_COLOR;
1074 image[loc(x,y)].b = 0xff; //DEFAULT_BACK_COLOR;
1075 image[loc(x,y)].r = 0xff; //DEFAULT_RENDITION;
1076 }
1077}
1078
1079// Create Image ///////////////////////////////////////////////////////
1080
1081void TEWidget::calcGeometry()
1082{
1083 //FIXME: set rimX == rimY == 0 when running in full screen mode.
1084
1085 scrollbar->resize(QApplication::style().scrollBarExtent().width(),
1086 contentsRect().height());
1087 switch(scrollLoc)
1088 {
1089 case SCRNONE :
1090 columns = ( contentsRect().width() - 2 * rimX ) / font_w;
1091 blX = (contentsRect().width() - (columns*font_w) ) / 2;
1092 brX = blX;
1093 scrollbar->hide();
1094 break;
1095 case SCRLEFT :
1096 columns = ( contentsRect().width() - 2 * rimX - scrollbar->width()) / font_w;
1097 brX = (contentsRect().width() - (columns*font_w) - scrollbar->width() ) / 2;
1098 blX = brX + scrollbar->width();
1099 scrollbar->move(contentsRect().topLeft());
1100 scrollbar->show();
1101 break;
1102 case SCRRIGHT:
1103 columns = ( contentsRect().width() - 2 * rimX - scrollbar->width()) / font_w;
1104 blX = (contentsRect().width() - (columns*font_w) - scrollbar->width() ) / 2;
1105 brX = blX;
1106 scrollbar->move(contentsRect().topRight() - QPoint(scrollbar->width()-1,0));
1107 scrollbar->show();
1108 break;
1109 }
1110 //FIXME: support 'rounding' styles
1111 lines = ( contentsRect().height() - 2 * rimY ) / font_h;
1112 bY = (contentsRect().height() - (lines *font_h)) / 2;
1113}
1114
1115void TEWidget::makeImage()
1116//FIXME: rename 'calcGeometry?
1117{
1118 calcGeometry();
1119 image = (ca*) malloc(lines*columns*sizeof(ca));
1120 clearImage();
1121}
1122
1123// calculate the needed size
1124QSize TEWidget::calcSize(int cols, int lins) const
1125{
1126 int frw = width() - contentsRect().width();
1127 int frh = height() - contentsRect().height();
1128 int scw = (scrollLoc==SCRNONE?0:scrollbar->width());
1129 return QSize( font_w*cols + 2*rimX + frw + scw, font_h*lins + 2*rimY + frh );
1130}
1131
1132QSize TEWidget::sizeHint() const
1133{
1134 return size();
1135}
1136
1137void TEWidget::styleChange(QStyle &)
1138{
1139 propagateSize();
1140}
1141
1142#ifndef QT_NO_DRAGANDDROP
1143
1144/* --------------------------------------------------------------------- */
1145/* */
1146/* Drag & Drop */
1147/* */
1148/* --------------------------------------------------------------------- */
1149
1150
1151void TEWidget::dragEnterEvent(QDragEnterEvent* e)
1152{
1153 e->accept(QTextDrag::canDecode(e) ||
1154 QUriDrag::canDecode(e));
1155}
1156
1157void TEWidget::dropEvent(QDropEvent* event)
1158{
1159 // The current behaviour when url(s) are dropped is
1160 // * if there is only ONE url and if it's a LOCAL one, ask for paste or cd
1161 // * in all other cases, just paste
1162 // (for non-local ones, or for a list of URLs, 'cd' is nonsense)
1163 QStrList strlist;
1164 int file_count = 0;
1165 dropText = "";
1166 bool bPopup = true;
1167
1168 if(QUriDrag::decode(event, strlist)) {
1169 if (strlist.count()) {
1170 for(const char* p = strlist.first(); p; p = strlist.next()) {
1171 if(file_count++ > 0) {
1172 dropText += " ";
1173 bPopup = false; // more than one file, don't popup
1174 }
1175
1176/*
1177 KURL url(p);
1178 if (url.isLocalFile()) {
1179 dropText += url.path(); // local URL : remove protocol
1180 }
1181 else {
1182 dropText += url.prettyURL();
1183 bPopup = false; // a non-local file, don't popup
1184 }
1185*/
1186
1187 }
1188
1189 if (bPopup)
1190 // m_drop->popup(pos() + event->pos());
1191 m_drop->popup(mapToGlobal(event->pos()));
1192 else
1193 {
1194 if (currentSession) {
1195 currentSession->getEmulation()->sendString(dropText.local8Bit());
1196 }
1197 // kdDebug() << "Drop:" << dropText.local8Bit() << "\n";
1198 }
1199 }
1200 }
1201 else if(QTextDrag::decode(event, dropText)) {
1202// kdDebug() << "Drop:" << dropText.local8Bit() << "\n";
1203 if (currentSession) {
1204 currentSession->getEmulation()->sendString(dropText.local8Bit());
1205 }
1206 // Paste it
1207 }
1208}
1209#endif
1210
1211
1212void TEWidget::drop_menu_activated(int item)
1213{
1214#ifndef QT_NO_DRAGANDDROP
1215 switch (item)
1216 {
1217 case 0: // paste
1218 currentSession->getEmulation()->sendString(dropText.local8Bit());
1219// KWM::activate((Window)this->winId());
1220 break;
1221 case 1: // cd ...
1222 currentSession->getEmulation()->sendString("cd ");
1223 struct stat statbuf;
1224 if ( ::stat( QFile::encodeName( dropText ), &statbuf ) == 0 )
1225 {
1226 if ( !S_ISDIR(statbuf.st_mode) )
1227 {
1228/*
1229 KURL url;
1230 url.setPath( dropText );
1231 dropText = url.directory( true, false ); // remove filename
1232*/
1233 }
1234 }
1235 dropText.replace(QRegExp(" "), "\\ "); // escape spaces
1236 currentSession->getEmulation()->sendString(dropText.local8Bit());
1237 currentSession->getEmulation()->sendString("\n");
1238// KWM::activate((Window)this->winId());
1239 break;
1240 }
1241#endif
1242}
1243
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 @@
1/* ----------------------------------------------------------------------- */
2/* */
3/* [te_widget.h] Terminal Emulation Widget */
4/* */
5/* ----------------------------------------------------------------------- */
6/* */
7/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */
8/* */
9/* This file is part of Konsole - an X terminal for KDE */
10/* */
11/* ----------------------------------------------------------------------- */
12 /* */
13/* Ported Konsole to Qt/Embedded */
14 /* */
15/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */
16 /* */
17/* -------------------------------------------------------------------------- */
18
19#ifndef TE_WIDGET_H
20#define TE_WIDGET_H
21
22#include <qwidget.h>
23#include <qlabel.h>
24#include <qtimer.h>
25#include <qcolor.h>
26#include <qkeycode.h>
27#include <qscrollbar.h>
28
29#include <qpopupmenu.h>
30
31#include "TECommon.h"
32
33extern unsigned short vt100_graphics[32];
34
35class TESession;
36
37// class Konsole;
38
39class TEWidget : public QFrame
40// a widget representing attributed text
41{ Q_OBJECT
42
43// friend class Konsole;
44
45public:
46
47 TEWidget(QWidget *parent=0, const char *name=0);
48 virtual ~TEWidget();
49
50public:
51
52 QColor getDefaultBackColor();
53
54 const ColorEntry* getColorTable() const;
55 void setColorTable(const ColorEntry table[]);
56
57 void setScrollbarLocation(int loc);
58 enum { SCRNONE=0, SCRLEFT=1, SCRRIGHT=2 };
59
60 void setScroll(int cursor, int lines);
61 void doScroll(int lines);
62
63 void emitSelection();
64
65public:
66
67 void setImage(const ca* const newimg, int lines, int columns);
68
69 int Lines() { return lines; }
70 int Columns() { return columns; }
71
72 void calcGeometry();
73 void propagateSize();
74 QSize calcSize(int cols, int lins) const;
75
76 QSize sizeHint() const;
77
78public:
79
80 void Bell();
81 void emitText(QString text);
82 void pasteClipboard();
83
84signals:
85
86 void keyPressedSignal(QKeyEvent *e);
87 void mouseSignal(int cb, int cx, int cy);
88 void changedImageSizeSignal(int lines, int columns);
89 void changedHistoryCursor(int value);
90 void configureRequest( TEWidget*, int state, int x, int y );
91
92 void clearSelectionSignal();
93 void beginSelectionSignal( const int x, const int y );
94 void extendSelectionSignal( const int x, const int y );
95 void endSelectionSignal(const BOOL preserve_line_breaks);
96
97
98protected:
99
100 virtual void styleChange( QStyle& );
101
102 bool eventFilter( QObject *, QEvent * );
103
104 void drawAttrStr(QPainter &paint, QRect rect,
105 QString& str, ca attr, BOOL pm, BOOL clear);
106 void paintEvent( QPaintEvent * );
107
108 void resizeEvent(QResizeEvent*);
109
110 void fontChange(const QFont &font);
111 void frameChanged();
112
113 void mouseDoubleClickEvent(QMouseEvent* ev);
114 void mousePressEvent( QMouseEvent* );
115 void mouseReleaseEvent( QMouseEvent* );
116 void mouseMoveEvent( QMouseEvent* );
117
118 void focusInEvent( QFocusEvent * );
119 void focusOutEvent( QFocusEvent * );
120 bool focusNextPrevChild( bool next );
121
122#ifndef QT_NO_DRAGANDDROP
123 // Dnd
124 void dragEnterEvent(QDragEnterEvent* event);
125 void dropEvent(QDropEvent* event);
126#endif
127
128 virtual int charClass(char) const;
129
130 void clearImage();
131
132public:
133 const QPixmap *backgroundPixmap();
134
135 void setSelection(const QString &t);
136
137 virtual void setFont(const QFont &);
138 void setVTFont(const QFont &);
139 QFont getVTFont();
140
141 void setMouseMarks(bool on);
142
143public slots:
144
145 void onClearSelection();
146
147protected slots:
148
149 void scrollChanged(int value);
150 void blinkEvent();
151
152private:
153
154 QChar (*fontMap)(QChar); // possible vt100 font extention
155
156 bool fixed_font; // has fixed pitch
157 int font_h; // height
158 int font_w; // width
159 int font_a; // ascend
160
161 int blX; // actual offset (left)
162 int brX; // actual offset (right)
163 int bY; // actual offset
164
165 int lines;
166 int columns;
167 ca *image; // [lines][columns]
168
169 ColorEntry color_table[TABLE_COLORS];
170
171 BOOL resizing;
172 bool mouse_marks;
173
174 void makeImage();
175
176 QPoint iPntSel; // initial selection point
177 QPoint pntSel; // current selection point
178 int actSel; // selection state
179 BOOL word_selection_mode;
180 BOOL preserve_line_breaks;
181
182 QClipboard* cb;
183 QScrollBar* scrollbar;
184 int scrollLoc;
185
186//#define SCRNONE 0
187//#define SCRLEFT 1
188//#define SCRRIGHT 2
189
190 BOOL blinking; // hide text in paintEvent
191 BOOL hasBlinker; // has characters to blink
192 QTimer* blinkT; // active when hasBlinker
193 QPopupMenu* m_drop;
194 QString dropText;
195 public:
196 // current session in this widget
197 TESession *currentSession;
198private slots:
199 void drop_menu_activated(int item);
200};
201
202#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 @@
1/* ------------------------------------------------------------------------- */
2/* */
3/* [TEmuVt102.C] VT102 Terminal Emulation */
4/* */
5/* ------------------------------------------------------------------------- */
6/* */
7/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */
8/* */
9/* This file is part of Konsole - an X terminal for KDE */
10/* */
11/* ------------------------------------------------------------------------- */
12 /* */
13/* Ported Konsole to Qt/Embedded */
14 /* */
15/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */
16 /* */
17/* -------------------------------------------------------------------------- */
18
19/*! \class TEmuVt102
20
21 \brief Actual Emulation for Konsole
22
23 \sa TEWidget \sa TEScreen
24*/
25
26#include "TEmuVt102.h"
27#include "TEWidget.h"
28#include "TEScreen.h"
29#include "keytrans.h"
30
31#include <stdio.h>
32#include <unistd.h>
33#include <qkeycode.h>
34#include <qtextcodec.h>
35
36
37/* VT102 Terminal Emulation
38
39 This class puts together the screens, the pty and the widget to a
40 complete terminal emulation. Beside combining it's componentes, it
41 handles the emulations's protocol.
42
43 This module consists of the following sections:
44
45 - Constructor/Destructor
46 - Incoming Bytes Event pipeline
47 - Outgoing Bytes
48 - Mouse Events
49 - Keyboard Events
50 - Modes and Charset State
51 - Diagnostics
52*/
53
54
55/* ------------------------------------------------------------------------- */
56/* */
57/* Constructor / Destructor */
58/* */
59/* ------------------------------------------------------------------------- */
60
61/*
62 Nothing really intesting happens here.
63*/
64
65/*!
66*/
67
68TEmuVt102::TEmuVt102(TEWidget* gui) : TEmulation(gui)
69{
70 QObject::connect(gui,SIGNAL(mouseSignal(int,int,int)),
71 this,SLOT(onMouse(int,int,int)));
72 initTokenizer();
73 reset();
74}
75
76/*!
77*/
78
79TEmuVt102::~TEmuVt102()
80{
81}
82
83/*!
84*/
85
86void TEmuVt102::reset()
87{
88 resetToken();
89 resetModes();
90 resetCharset(0); screen[0]->reset();
91 resetCharset(1); screen[0]->reset();
92 setCodec(0);
93 setKeytrans("linux.keytab");
94}
95
96/* ------------------------------------------------------------------------- */
97/* */
98/* Processing the incoming byte stream */
99/* */
100/* ------------------------------------------------------------------------- */
101
102/* Incoming Bytes Event pipeline
103
104 This section deals with decoding the incoming character stream.
105 Decoding means here, that the stream is first seperated into `tokens'
106 which are then mapped to a `meaning' provided as operations by the
107 `TEScreen' class or by the emulation class itself.
108
109 The pipeline proceeds as follows:
110
111 - Tokenizing the ESC codes (onRcvChar)
112 - VT100 code page translation of plain characters (applyCharset)
113 - Interpretation of ESC codes (tau)
114
115 The escape codes and their meaning are described in the
116 technical reference of this program.
117*/
118
119// Tokens ------------------------------------------------------------------ --
120
121/*
122 Since the tokens are the central notion if this section, we've put them
123 in front. They provide the syntactical elements used to represent the
124 terminals operations as byte sequences.
125
126 They are encodes here into a single machine word, so that we can later
127 switch over them easily. Depending on the token itself, additional
128 argument variables are filled with parameter values.
129
130 The tokens are defined below:
131
132 - CHR - Printable characters (32..255 but DEL (=127))
133 - CTL - Control characters (0..31 but ESC (= 27), DEL)
134 - ESC - Escape codes of the form <ESC><CHR but `[]()+*#'>
135 - ESC_DE - Escape codes of the form <ESC><any of `()+*#%'> C
136 - CSI_PN - Escape codes of the form <ESC>'[' {Pn} ';' {Pn} C
137 - CSI_PS - Escape codes of the form <ESC>'[' {Pn} ';' ... C
138 - CSI_PR - Escape codes of the form <ESC>'[' '?' {Pn} ';' ... C
139 - VT52 - VT52 escape codes
140 - <ESC><Chr>
141 - <ESC>'Y'{Pc}{Pc}
142 - XTE_HA - Xterm hacks <ESC>`]' {Pn} `;' {Text} <BEL>
143 note that this is handled differently
144
145 The last two forms allow list of arguments. Since the elements of
146 the lists are treated individually the same way, they are passed
147 as individual tokens to the interpretation. Further, because the
148 meaning of the parameters are names (althought represented as numbers),
149 they are includes within the token ('N').
150
151*/
152
153#define TY_CONSTR(T,A,N) ( ((((int)N) & 0xffff) << 16) | ((((int)A) & 0xff) << 8) | (((int)T) & 0xff) )
154
155#define TY_CHR___( ) TY_CONSTR(0,0,0)
156#define TY_CTL___(A ) TY_CONSTR(1,A,0)
157#define TY_ESC___(A ) TY_CONSTR(2,A,0)
158#define TY_ESC_CS(A,B) TY_CONSTR(3,A,B)
159#define TY_ESC_DE(A ) TY_CONSTR(4,A,0)
160#define TY_CSI_PS(A,N) TY_CONSTR(5,A,N)
161#define TY_CSI_PN(A ) TY_CONSTR(6,A,0)
162#define TY_CSI_PR(A,N) TY_CONSTR(7,A,N)
163
164#define TY_VT52__(A ) TY_CONSTR(8,A,0)
165
166// Tokenizer --------------------------------------------------------------- --
167
168/* The tokenizers state
169
170 The state is represented by the buffer (pbuf, ppos),
171 and accompanied by decoded arguments kept in (argv,argc).
172 Note that they are kept internal in the tokenizer.
173*/
174
175void TEmuVt102::resetToken()
176{
177 ppos = 0; argc = 0; argv[0] = 0; argv[1] = 0;
178}
179
180void TEmuVt102::addDigit(int dig)
181{
182 argv[argc] = 10*argv[argc] + dig;
183}
184
185void TEmuVt102::addArgument()
186{
187 argc = QMIN(argc+1,MAXARGS-1);
188 argv[argc] = 0;
189}
190
191void TEmuVt102::pushToToken(int cc)
192{
193 pbuf[ppos] = cc;
194 ppos = QMIN(ppos+1,MAXPBUF-1);
195}
196
197// Character Classes used while decoding
198
199#define CTL 1
200#define CHR 2
201#define CPN 4
202#define DIG 8
203#define SCS 16
204#define GRP 32
205
206void TEmuVt102::initTokenizer()
207{ int i; UINT8* s;
208 for(i = 0; i < 256; i++) tbl[ i] = 0;
209 for(i = 0; i < 32; i++) tbl[ i] |= CTL;
210 for(i = 32; i < 256; i++) tbl[ i] |= CHR;
211 for(s = (UINT8*)"@ABCDGHLMPXcdfry"; *s; s++) tbl[*s] |= CPN;
212 for(s = (UINT8*)"0123456789" ; *s; s++) tbl[*s] |= DIG;
213 for(s = (UINT8*)"()+*%" ; *s; s++) tbl[*s] |= SCS;
214 for(s = (UINT8*)"()+*#[]%" ; *s; s++) tbl[*s] |= GRP;
215 resetToken();
216}
217
218/* Ok, here comes the nasty part of the decoder.
219
220 Instead of keeping an explicit state, we deduce it from the
221 token scanned so far. It is then immediately combined with
222 the current character to form a scanning decision.
223
224 This is done by the following defines.
225
226 - P is the length of the token scanned so far.
227 - L (often P-1) is the position on which contents we base a decision.
228 - C is a character or a group of characters (taken from 'tbl').
229
230 Note that they need to applied in proper order.
231*/
232
233#define lec(P,L,C) (p == (P) && s[(L)] == (C))
234#define lun( ) (p == 1 && cc >= 32 )
235#define les(P,L,C) (p == (P) && s[L] < 256 && (tbl[s[(L)]] & (C)) == (C))
236#define eec(C) (p >= 3 && cc == (C))
237#define ees(C) (p >= 3 && cc < 256 && (tbl[ cc ] & (C)) == (C))
238#define eps(C) (p >= 3 && s[2] != '?' && cc < 256 && (tbl[ cc ] & (C)) == (C))
239#define epp( ) (p >= 3 && s[2] == '?' )
240#define egt( ) (p == 3 && s[2] == '>' )
241#define Xpe (ppos>=2 && pbuf[1] == ']' )
242#define Xte (Xpe && cc == 7 )
243#define ces(C) ( cc < 256 && (tbl[ cc ] & (C)) == (C) && !Xte)
244
245#define ESC 27
246#define CNTL(c) ((c)-'@')
247
248// process an incoming unicode character
249
250void TEmuVt102::onRcvChar(int cc)
251{ int i;
252
253 if (cc == 127) return; //VT100: ignore.
254
255 if (ces( CTL))
256 { // DEC HACK ALERT! Control Characters are allowed *within* esc sequences in VT100
257 // This means, they do neither a resetToken nor a pushToToken. Some of them, do
258 // of course. Guess this originates from a weakly layered handling of the X-on
259 // X-off protocol, which comes really below this level.
260 if (cc == CNTL('X') || cc == CNTL('Z') || cc == ESC) resetToken(); //VT100: CAN or SUB
261 if (cc != ESC) { tau( TY_CTL___(cc+'@' ), 0, 0); return; }
262 }
263
264 pushToToken(cc); // advance the state
265
266 int* s = pbuf;
267 int p = ppos;
268
269 if (getMode(MODE_Ansi)) // decide on proper action
270 {
271 if (lec(1,0,ESC)) { return; }
272 if (les(2,1,GRP)) { return; }
273 if (Xte ) { XtermHack(); resetToken(); return; }
274 if (Xpe ) { return; }
275 if (lec(3,2,'?')) { return; }
276 if (lec(3,2,'>')) { return; }
277 if (lun( )) { tau( TY_CHR___(), applyCharset(cc), 0); resetToken(); return; }
278 if (lec(2,0,ESC)) { tau( TY_ESC___(s[1]), 0, 0); resetToken(); return; }
279 if (les(3,1,SCS)) { tau( TY_ESC_CS(s[1],s[2]), 0, 0); resetToken(); return; }
280 if (lec(3,1,'#')) { tau( TY_ESC_DE(s[2]), 0, 0); resetToken(); return; }
281// if (egt( )) { tau( TY_CSI_PG(cc ), '>', 0); resetToken(); return; }
282 if (eps( CPN)) { tau( TY_CSI_PN(cc), argv[0],argv[1]); resetToken(); return; }
283 if (ees( DIG)) { addDigit(cc-'0'); return; }
284 if (eec( ';')) { addArgument(); return; }
285 for (i=0;i<=argc;i++)
286 if (epp( )) tau( TY_CSI_PR(cc,argv[i]), 0, 0); else
287 tau( TY_CSI_PS(cc,argv[i]), 0, 0);
288 resetToken();
289 }
290 else // mode VT52
291 {
292 if (lec(1,0,ESC)) return;
293 if (les(1,0,CHR)) { tau( TY_CHR___( ), s[0], 0); resetToken(); return; }
294 if (lec(2,1,'Y')) return;
295 if (lec(3,1,'Y')) return;
296 if (p < 4) { tau( TY_VT52__(s[1] ), 0, 0); resetToken(); return; }
297 tau( TY_VT52__(s[1] ), s[2],s[3]); resetToken(); return;
298 }
299}
300
301void TEmuVt102::XtermHack()
302{ int i,arg = 0;
303 for (i = 2; i < ppos && '0'<=pbuf[i] && pbuf[i]<'9' ; i++)
304 arg = 10*arg + (pbuf[i]-'0');
305 if (pbuf[i] != ';') { ReportErrorToken(); return; }
306 QChar *str = new QChar[ppos-i-2];
307 for (int j = 0; j < ppos-i-2; j++) str[j] = pbuf[i+1+j];
308 QString unistr(str,ppos-i-2);
309 // arg == 1 doesn't change the title. In XTerm it only changes the icon name
310 // (btw: arg=0 changes title and icon, arg=1 only icon, arg=2 only title
311 if (arg == 0 || arg == 2) emit changeTitle(arg,unistr);
312 delete [] str;
313}
314
315// Interpreting Codes ---------------------------------------------------------
316
317/*
318 Now that the incoming character stream is properly tokenized,
319 meaning is assigned to them. These are either operations of
320 the current screen, or of the emulation class itself.
321
322 The token to be interpreteted comes in as a machine word
323 possibly accompanied by two parameters.
324
325 Likewise, the operations assigned to, come with up to two
326 arguments. One could consider to make up a proper table
327 from the function below.
328
329 The technical reference manual provides more informations
330 about this mapping.
331*/
332
333void TEmuVt102::tau( int token, int p, int q )
334{
335//scan_buffer_report();
336//if (token == TY_CHR___()) printf("%c",p); else
337//printf("tau(%d,%d,%d, %d,%d)\n",(token>>0)&0xff,(token>>8)&0xff,(token>>16)&0xffff,p,q);
338 switch (token)
339 {
340
341 case TY_CHR___( ) : scr->ShowCharacter (p ); break; //UTF16
342
343 // 127 DEL : ignored on input
344
345 case TY_CTL___('@' ) : /* NUL: ignored */ break;
346 case TY_CTL___('A' ) : /* SOH: ignored */ break;
347 case TY_CTL___('B' ) : /* STX: ignored */ break;
348 case TY_CTL___('C' ) : /* ETX: ignored */ break;
349 case TY_CTL___('D' ) : /* EOT: ignored */ break;
350 case TY_CTL___('E' ) : reportAnswerBack ( ); break; //VT100
351 case TY_CTL___('F' ) : /* ACK: ignored */ break;
352 case TY_CTL___('G' ) : gui->Bell ( ); break; //VT100
353 case TY_CTL___('H' ) : scr->BackSpace ( ); break; //VT100
354 case TY_CTL___('I' ) : scr->Tabulate ( ); break; //VT100
355 case TY_CTL___('J' ) : scr->NewLine ( ); break; //VT100
356 case TY_CTL___('K' ) : scr->NewLine ( ); break; //VT100
357 case TY_CTL___('L' ) : scr->NewLine ( ); break; //VT100
358 case TY_CTL___('M' ) : scr->Return ( ); break; //VT100
359
360 case TY_CTL___('N' ) : useCharset ( 1); break; //VT100
361 case TY_CTL___('O' ) : useCharset ( 0); break; //VT100
362
363 case TY_CTL___('P' ) : /* DLE: ignored */ break;
364 case TY_CTL___('Q' ) : /* DC1: XON continue */ break; //VT100
365 case TY_CTL___('R' ) : /* DC2: ignored */ break;
366 case TY_CTL___('S' ) : /* DC3: XOFF halt */ break; //VT100
367 case TY_CTL___('T' ) : /* DC4: ignored */ break;
368 case TY_CTL___('U' ) : /* NAK: ignored */ break;
369 case TY_CTL___('V' ) : /* SYN: ignored */ break;
370 case TY_CTL___('W' ) : /* ETB: ignored */ break;
371 case TY_CTL___('X' ) : scr->ShowCharacter ( 0x2592); break; //VT100
372 case TY_CTL___('Y' ) : /* EM : ignored */ break;
373 case TY_CTL___('Z' ) : scr->ShowCharacter ( 0x2592); break; //VT100
374 case TY_CTL___('[' ) : /* ESC: cannot be seen here. */ break;
375 case TY_CTL___('\\' ) : /* FS : ignored */ break;
376 case TY_CTL___(']' ) : /* GS : ignored */ break;
377 case TY_CTL___('^' ) : /* RS : ignored */ break;
378 case TY_CTL___('_' ) : /* US : ignored */ break;
379
380 case TY_ESC___('D' ) : scr->index ( ); break; //VT100
381 case TY_ESC___('E' ) : scr->NextLine ( ); break; //VT100
382 case TY_ESC___('H' ) : scr->changeTabStop (TRUE ); break; //VT100
383 case TY_ESC___('M' ) : scr->reverseIndex ( ); break; //VT100
384 case TY_ESC___('Z' ) : reportTerminalType ( ); break;
385 case TY_ESC___('c' ) : reset ( ); break;
386
387 case TY_ESC___('n' ) : useCharset ( 2); break;
388 case TY_ESC___('o' ) : useCharset ( 3); break;
389 case TY_ESC___('7' ) : saveCursor ( ); break;
390 case TY_ESC___('8' ) : restoreCursor ( ); break;
391
392 case TY_ESC___('=' ) : setMode (MODE_AppKeyPad); break;
393 case TY_ESC___('>' ) : resetMode (MODE_AppKeyPad); break;
394 case TY_ESC___('<' ) : setMode (MODE_Ansi ); break; //VT100
395
396 case TY_ESC_CS('(', '0') : setCharset (0, '0'); break; //VT100
397 case TY_ESC_CS('(', 'A') : setCharset (0, 'A'); break; //VT100
398 case TY_ESC_CS('(', 'B') : setCharset (0, 'B'); break; //VT100
399
400 case TY_ESC_CS(')', '0') : setCharset (1, '0'); break; //VT100
401 case TY_ESC_CS(')', 'A') : setCharset (1, 'A'); break; //VT100
402 case TY_ESC_CS(')', 'B') : setCharset (1, 'B'); break; //VT100
403
404 case TY_ESC_CS('*', '0') : setCharset (2, '0'); break; //VT100
405 case TY_ESC_CS('*', 'A') : setCharset (2, 'A'); break; //VT100
406 case TY_ESC_CS('*', 'B') : setCharset (2, 'B'); break; //VT100
407
408 case TY_ESC_CS('+', '0') : setCharset (3, '0'); break; //VT100
409 case TY_ESC_CS('+', 'A') : setCharset (3, 'A'); break; //VT100
410 case TY_ESC_CS('+', 'B') : setCharset (3, 'B'); break; //VT100
411
412 case TY_ESC_CS('%', 'G') : setCodec (1 ); break; //LINUX
413 case TY_ESC_CS('%', '@') : setCodec (0 ); break; //LINUX
414
415 case TY_ESC_DE('3' ) : /* IGNORED: double high, top half */ break;
416 case TY_ESC_DE('4' ) : /* IGNORED: double high, bottom half */ break;
417 case TY_ESC_DE('5' ) : /* IGNORED: single width, single high*/ break;
418 case TY_ESC_DE('6' ) : /* IGNORED: double width, single high*/ break;
419 case TY_ESC_DE('8' ) : scr->helpAlign ( ); break;
420
421 case TY_CSI_PS('K', 0) : scr->clearToEndOfLine ( ); break;
422 case TY_CSI_PS('K', 1) : scr->clearToBeginOfLine ( ); break;
423 case TY_CSI_PS('K', 2) : scr->clearEntireLine ( ); break;
424 case TY_CSI_PS('J', 0) : scr->clearToEndOfScreen ( ); break;
425 case TY_CSI_PS('J', 1) : scr->clearToBeginOfScreen ( ); break;
426 case TY_CSI_PS('J', 2) : scr->clearEntireScreen ( ); break;
427 case TY_CSI_PS('g', 0) : scr->changeTabStop (FALSE ); break; //VT100
428 case TY_CSI_PS('g', 3) : scr->clearTabStops ( ); break; //VT100
429 case TY_CSI_PS('h', 4) : scr-> setMode (MODE_Insert ); break;
430 case TY_CSI_PS('h', 20) : setMode (MODE_NewLine ); break;
431 case TY_CSI_PS('i', 0) : /* IGNORE: attached printer */ break; //VT100
432 case TY_CSI_PS('l', 4) : scr-> resetMode (MODE_Insert ); break;
433 case TY_CSI_PS('l', 20) : resetMode (MODE_NewLine ); break;
434
435 case TY_CSI_PS('m', 0) : scr->setDefaultRendition ( ); break;
436 case TY_CSI_PS('m', 1) : scr-> setRendition (RE_BOLD ); break; //VT100
437 case TY_CSI_PS('m', 4) : scr-> setRendition (RE_UNDERLINE); break; //VT100
438 case TY_CSI_PS('m', 5) : scr-> setRendition (RE_BLINK ); break; //VT100
439 case TY_CSI_PS('m', 7) : scr-> setRendition (RE_REVERSE ); break;
440 case TY_CSI_PS('m', 10) : /* IGNORED: mapping related */ break; //LINUX
441 case TY_CSI_PS('m', 11) : /* IGNORED: mapping related */ break; //LINUX
442 case TY_CSI_PS('m', 12) : /* IGNORED: mapping related */ break; //LINUX
443 case TY_CSI_PS('m', 22) : scr->resetRendition (RE_BOLD ); break;
444 case TY_CSI_PS('m', 24) : scr->resetRendition (RE_UNDERLINE); break;
445 case TY_CSI_PS('m', 25) : scr->resetRendition (RE_BLINK ); break;
446 case TY_CSI_PS('m', 27) : scr->resetRendition (RE_REVERSE ); break;
447
448 case TY_CSI_PS('m', 30) : scr->setForeColor ( 0); break;
449 case TY_CSI_PS('m', 31) : scr->setForeColor ( 1); break;
450 case TY_CSI_PS('m', 32) : scr->setForeColor ( 2); break;
451 case TY_CSI_PS('m', 33) : scr->setForeColor ( 3); break;
452 case TY_CSI_PS('m', 34) : scr->setForeColor ( 4); break;
453 case TY_CSI_PS('m', 35) : scr->setForeColor ( 5); break;
454 case TY_CSI_PS('m', 36) : scr->setForeColor ( 6); break;
455 case TY_CSI_PS('m', 37) : scr->setForeColor ( 7); break;
456 case TY_CSI_PS('m', 39) : scr->setForeColorToDefault( ); break;
457
458 case TY_CSI_PS('m', 40) : scr->setBackColor ( 0); break;
459 case TY_CSI_PS('m', 41) : scr->setBackColor ( 1); break;
460 case TY_CSI_PS('m', 42) : scr->setBackColor ( 2); break;
461 case TY_CSI_PS('m', 43) : scr->setBackColor ( 3); break;
462 case TY_CSI_PS('m', 44) : scr->setBackColor ( 4); break;
463 case TY_CSI_PS('m', 45) : scr->setBackColor ( 5); break;
464 case TY_CSI_PS('m', 46) : scr->setBackColor ( 6); break;
465 case TY_CSI_PS('m', 47) : scr->setBackColor ( 7); break;
466 case TY_CSI_PS('m', 49) : scr->setBackColorToDefault( ); break;
467
468 case TY_CSI_PS('m', 90) : scr->setForeColor ( 8); break;
469 case TY_CSI_PS('m', 91) : scr->setForeColor ( 9); break;
470 case TY_CSI_PS('m', 92) : scr->setForeColor ( 10); break;
471 case TY_CSI_PS('m', 93) : scr->setForeColor ( 11); break;
472 case TY_CSI_PS('m', 94) : scr->setForeColor ( 12); break;
473 case TY_CSI_PS('m', 95) : scr->setForeColor ( 13); break;
474 case TY_CSI_PS('m', 96) : scr->setForeColor ( 14); break;
475 case TY_CSI_PS('m', 97) : scr->setForeColor ( 15); break;
476
477 case TY_CSI_PS('m', 100) : scr->setBackColor ( 8); break;
478 case TY_CSI_PS('m', 101) : scr->setBackColor ( 9); break;
479 case TY_CSI_PS('m', 102) : scr->setBackColor ( 10); break;
480 case TY_CSI_PS('m', 103) : scr->setBackColor ( 11); break;
481 case TY_CSI_PS('m', 104) : scr->setBackColor ( 12); break;
482 case TY_CSI_PS('m', 105) : scr->setBackColor ( 13); break;
483 case TY_CSI_PS('m', 106) : scr->setBackColor ( 14); break;
484 case TY_CSI_PS('m', 107) : scr->setBackColor ( 15); break;
485
486 case TY_CSI_PS('n', 5) : reportStatus ( ); break;
487 case TY_CSI_PS('n', 6) : reportCursorPosition ( ); break;
488 case TY_CSI_PS('q', 0) : /* IGNORED: LEDs off */ break; //VT100
489 case TY_CSI_PS('q', 1) : /* IGNORED: LED1 on */ break; //VT100
490 case TY_CSI_PS('q', 2) : /* IGNORED: LED2 on */ break; //VT100
491 case TY_CSI_PS('q', 3) : /* IGNORED: LED3 on */ break; //VT100
492 case TY_CSI_PS('q', 4) : /* IGNORED: LED4 on */ break; //VT100
493 case TY_CSI_PS('x', 0) : reportTerminalParms ( 2); break; //VT100
494 case TY_CSI_PS('x', 1) : reportTerminalParms ( 3); break; //VT100
495
496 case TY_CSI_PN('@' ) : scr->insertChars (p ); break;
497 case TY_CSI_PN('A' ) : scr->cursorUp (p ); break; //VT100
498 case TY_CSI_PN('B' ) : scr->cursorDown (p ); break; //VT100
499 case TY_CSI_PN('C' ) : scr->cursorRight (p ); break; //VT100
500 case TY_CSI_PN('D' ) : scr->cursorLeft (p ); break; //VT100
501 case TY_CSI_PN('G' ) : scr->setCursorX (p ); break; //LINUX
502 case TY_CSI_PN('H' ) : scr->setCursorYX (p, q); break; //VT100
503 case TY_CSI_PN('L' ) : scr->insertLines (p ); break;
504 case TY_CSI_PN('M' ) : scr->deleteLines (p ); break;
505 case TY_CSI_PN('P' ) : scr->deleteChars (p ); break;
506 case TY_CSI_PN('X' ) : scr->eraseChars (p ); break;
507 case TY_CSI_PN('c' ) : reportTerminalType ( ); break; //VT100
508 case TY_CSI_PN('d' ) : scr->setCursorY (p ); break; //LINUX
509 case TY_CSI_PN('f' ) : scr->setCursorYX (p, q); break; //VT100
510 case TY_CSI_PN('r' ) : scr->setMargins (p, q); break; //VT100
511 case TY_CSI_PN('y' ) : /* IGNORED: Confidence test */ break; //VT100
512
513 case TY_CSI_PR('h', 1) : setMode (MODE_AppCuKeys); break; //VT100
514 case TY_CSI_PR('l', 1) : resetMode (MODE_AppCuKeys); break; //VT100
515 case TY_CSI_PR('s', 1) : saveMode (MODE_AppCuKeys); break; //FIXME
516 case TY_CSI_PR('r', 1) : restoreMode (MODE_AppCuKeys); break; //FIXME
517
518 case TY_CSI_PR('l', 2) : resetMode (MODE_Ansi ); break; //VT100
519
520 case TY_CSI_PR('h', 3) : setColumns ( 132); break; //VT100
521 case TY_CSI_PR('l', 3) : setColumns ( 80); break; //VT100
522
523 case TY_CSI_PR('h', 4) : /* IGNORED: soft scrolling */ break; //VT100
524 case TY_CSI_PR('l', 4) : /* IGNORED: soft scrolling */ break; //VT100
525
526 case TY_CSI_PR('h', 5) : scr-> setMode (MODE_Screen ); break; //VT100
527 case TY_CSI_PR('l', 5) : scr-> resetMode (MODE_Screen ); break; //VT100
528
529 case TY_CSI_PR('h', 6) : scr-> setMode (MODE_Origin ); break; //VT100
530 case TY_CSI_PR('l', 6) : scr-> resetMode (MODE_Origin ); break; //VT100
531 case TY_CSI_PR('s', 6) : scr-> saveMode (MODE_Origin ); break; //FIXME
532 case TY_CSI_PR('r', 6) : scr->restoreMode (MODE_Origin ); break; //FIXME
533
534 case TY_CSI_PR('h', 7) : scr-> setMode (MODE_Wrap ); break; //VT100
535 case TY_CSI_PR('l', 7) : scr-> resetMode (MODE_Wrap ); break; //VT100
536 case TY_CSI_PR('s', 7) : scr-> saveMode (MODE_Wrap ); break; //FIXME
537 case TY_CSI_PR('r', 7) : scr->restoreMode (MODE_Wrap ); break; //FIXME
538
539 case TY_CSI_PR('h', 8) : /* IGNORED: autorepeat on */ break; //VT100
540 case TY_CSI_PR('l', 8) : /* IGNORED: autorepeat off */ break; //VT100
541
542 case TY_CSI_PR('h', 9) : /* IGNORED: interlace */ break; //VT100
543 case TY_CSI_PR('l', 9) : /* IGNORED: interlace */ break; //VT100
544
545 case TY_CSI_PR('h', 25) : setMode (MODE_Cursor ); break; //VT100
546 case TY_CSI_PR('l', 25) : resetMode (MODE_Cursor ); break; //VT100
547
548 case TY_CSI_PR('h', 41) : /* IGNORED: obsolete more(1) fix */ break; //XTERM
549 case TY_CSI_PR('l', 41) : /* IGNORED: obsolete more(1) fix */ break; //XTERM
550 case TY_CSI_PR('s', 41) : /* IGNORED: obsolete more(1) fix */ break; //XTERM
551 case TY_CSI_PR('r', 41) : /* IGNORED: obsolete more(1) fix */ break; //XTERM
552
553 case TY_CSI_PR('h', 47) : setMode (MODE_AppScreen); break; //VT100
554 case TY_CSI_PR('l', 47) : resetMode (MODE_AppScreen); break; //VT100
555
556 case TY_CSI_PR('h', 1000) : setMode (MODE_Mouse1000); break; //XTERM
557 case TY_CSI_PR('l', 1000) : resetMode (MODE_Mouse1000); break; //XTERM
558 case TY_CSI_PR('s', 1000) : saveMode (MODE_Mouse1000); break; //XTERM
559 case TY_CSI_PR('r', 1000) : restoreMode (MODE_Mouse1000); break; //XTERM
560
561 case TY_CSI_PR('h', 1001) : /* IGNORED: hilite mouse tracking */ break; //XTERM
562 case TY_CSI_PR('l', 1001) : /* IGNORED: hilite mouse tracking */ break; //XTERM
563 case TY_CSI_PR('s', 1001) : /* IGNORED: hilite mouse tracking */ break; //XTERM
564 case TY_CSI_PR('r', 1001) : /* IGNORED: hilite mouse tracking */ break; //XTERM
565
566 case TY_CSI_PR('h', 1047) : setMode (MODE_AppScreen); break; //XTERM
567 case TY_CSI_PR('l', 1047) : resetMode (MODE_AppScreen); break; //XTERM
568
569 //FIXME: Unitoken: save translations
570 case TY_CSI_PR('h', 1048) : saveCursor ( ); break; //XTERM
571 case TY_CSI_PR('l', 1048) : restoreCursor ( ); break; //XTERM
572
573 //FIXME: every once new sequences like this pop up in xterm.
574 // Here's a guess of what they could mean.
575 case TY_CSI_PR('h', 1049) : setMode (MODE_AppScreen); break; //XTERM
576 case TY_CSI_PR('l', 1049) : resetMode (MODE_AppScreen); break; //XTERM
577
578 //FIXME: when changing between vt52 and ansi mode evtl do some resetting.
579 case TY_VT52__('A' ) : scr->cursorUp ( 1); break; //VT52
580 case TY_VT52__('B' ) : scr->cursorDown ( 1); break; //VT52
581 case TY_VT52__('C' ) : scr->cursorRight ( 1); break; //VT52
582 case TY_VT52__('D' ) : scr->cursorLeft ( 1); break; //VT52
583
584 case TY_VT52__('F' ) : setAndUseCharset (0, '0'); break; //VT52
585 case TY_VT52__('G' ) : setAndUseCharset (0, 'B'); break; //VT52
586
587 case TY_VT52__('H' ) : scr->setCursorYX (1,1 ); break; //VT52
588 case TY_VT52__('I' ) : scr->reverseIndex ( ); break; //VT52
589 case TY_VT52__('J' ) : scr->clearToEndOfScreen ( ); break; //VT52
590 case TY_VT52__('K' ) : scr->clearToEndOfLine ( ); break; //VT52
591 case TY_VT52__('Y' ) : scr->setCursorYX (p-31,q-31 ); break; //VT52
592 case TY_VT52__('Z' ) : reportTerminalType ( ); break; //VT52
593 case TY_VT52__('<' ) : setMode (MODE_Ansi ); break; //VT52
594 case TY_VT52__('=' ) : setMode (MODE_AppKeyPad); break; //VT52
595 case TY_VT52__('>' ) : resetMode (MODE_AppKeyPad); break; //VT52
596
597 default : ReportErrorToken(); break;
598 };
599}
600
601/* ------------------------------------------------------------------------- */
602/* */
603/* Terminal to Host protocol */
604/* */
605/* ------------------------------------------------------------------------- */
606
607/*
608 Outgoing bytes originate from several sources:
609
610 - Replies to Enquieries.
611 - Mouse Events
612 - Keyboard Events
613*/
614
615/*!
616*/
617
618void TEmuVt102::sendString(const char* s)
619{
620 emit sndBlock(s,strlen(s));
621}
622
623// Replies ----------------------------------------------------------------- --
624
625// This section copes with replies send as response to an enquiery control code.
626
627/*!
628*/
629
630void TEmuVt102::reportCursorPosition()
631{ char tmp[20];
632 sprintf(tmp,"\033[%d;%dR",scr->getCursorY()+1,scr->getCursorX()+1);
633 sendString(tmp);
634}
635
636/*
637 What follows here is rather obsolete and faked stuff.
638 The correspondent enquieries are neverthenless issued.
639*/
640
641/*!
642*/
643
644void TEmuVt102::reportTerminalType()
645{
646//FIXME: should change?
647 if (getMode(MODE_Ansi))
648// sendString("\033[?1;2c"); // I'm a VT100 with AP0 //FIXME: send only in response to ^[[0c
649 sendString("\033[>0;115;0c"); // I'm a VT220 //FIXME: send only in response to ^[[>c
650 else
651 sendString("\033/Z"); // I'm a VT52
652}
653
654void TEmuVt102::reportTerminalParms(int p)
655// DECREPTPARM
656{ char tmp[100];
657 sprintf(tmp,"\033[%d;1;1;112;112;1;0x",p); // not really true.
658 sendString(tmp);
659}
660
661/*!
662*/
663
664void TEmuVt102::reportStatus()
665{
666 sendString("\033[0n"); //VT100. Device status report. 0 = Ready.
667}
668
669/*!
670*/
671
672#define ANSWER_BACK "" // This is really obsolete VT100 stuff.
673
674void TEmuVt102::reportAnswerBack()
675{
676 sendString(ANSWER_BACK);
677}
678
679// Mouse Handling ---------------------------------------------------------- --
680
681/*!
682 Mouse clicks are possibly reported to the client
683 application if it has issued interest in them.
684 They are normally consumed by the widget for copy
685 and paste, but may be propagated from the widget
686 when gui->setMouseMarks is set via setMode(MODE_Mouse1000).
687
688 `x',`y' are 1-based.
689 `ev' (event) indicates the button pressed (0-2)
690 or a general mouse release (3).
691*/
692
693void TEmuVt102::onMouse( int cb, int cx, int cy )
694{ char tmp[20];
695 if (!connected) return;
696 sprintf(tmp,"\033[M%c%c%c",cb+040,cx+040,cy+040);
697 sendString(tmp);
698}
699
700// Keyboard Handling ------------------------------------------------------- --
701
702#define encodeMode(M,B) BITS(B,getMode(M))
703#define encodeStat(M,B) BITS(B,((ev->state() & (M)) == (M)))
704
705/*
706 Keyboard event handling has been simplified somewhat by pushing
707 the complications towards a configuration file [see KeyTrans class].
708*/
709
710void TEmuVt102::onKeyPress( QKeyEvent* ev )
711{
712 if (!connected) return; // someone else gets the keys
713
714//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);
715
716 // revert to non-history when typing
717 if (scr->getHistCursor() != scr->getHistLines());
718 scr->setHistCursor(scr->getHistLines());
719
720 // lookup in keyboard translation table ...
721 int cmd; const char* txt; int len;
722 if (keytrans->findEntry(ev->key(), encodeMode(MODE_NewLine , BITS_NewLine ) + // OLD,
723 encodeMode(MODE_Ansi , BITS_Ansi ) + // OBSOLETE,
724 encodeMode(MODE_AppCuKeys, BITS_AppCuKeys ) + // VT100 stuff
725 encodeStat(ControlButton , BITS_Control ) +
726 encodeStat(ShiftButton , BITS_Shift ) +
727 encodeStat(AltButton , BITS_Alt ),
728 &cmd, &txt, &len ))
729//printf("cmd: %d, %s, %d\n",cmd,txt,len);
730 switch(cmd) // ... and execute if found.
731 {
732 case CMD_emitSelection : gui->emitSelection(); return;
733 case CMD_scrollPageUp : gui->doScroll(-gui->Lines()/2); return;
734 case CMD_scrollPageDown : gui->doScroll(+gui->Lines()/2); return;
735 case CMD_scrollLineUp : gui->doScroll(-1 ); return;
736 case CMD_scrollLineDown : gui->doScroll(+1 ); return;
737 case CMD_send : emit sndBlock(txt,len); return;
738 case CMD_prevSession : emit prevSession(); return;
739 case CMD_nextSession : emit nextSession(); return;
740 }
741
742 // fall back handling
743 if (!ev->text().isEmpty())
744 {
745 if (ev->state() & AltButton) sendString("\033"); // ESC, this is the ALT prefix
746 QCString s = codec->fromUnicode(ev->text()); // encode for application
747 emit sndBlock(s.data(),s.length()); // we may well have s.length() > 1
748 return;
749 }
750}
751
752/* ------------------------------------------------------------------------- */
753/* */
754/* VT100 Charsets */
755/* */
756/* ------------------------------------------------------------------------- */
757
758// Character Set Conversion ------------------------------------------------ --
759
760/*
761 The processing contains a VT100 specific code translation layer.
762 It's still in use and mainly responsible for the line drawing graphics.
763
764 These and some other glyphs are assigned to codes (0x5f-0xfe)
765 normally occupied by the latin letters. Since this codes also
766 appear within control sequences, the extra code conversion
767 does not permute with the tokenizer and is placed behind it
768 in the pipeline. It only applies to tokens, which represent
769 plain characters.
770
771 This conversion it eventually continued in TEWidget.C, since
772 it might involve VT100 enhanced fonts, which have these
773 particular glyphs allocated in (0x00-0x1f) in their code page.
774*/
775
776#define CHARSET charset[scr==screen[1]]
777
778// Apply current character map.
779
780unsigned short TEmuVt102::applyCharset(unsigned short c)
781{
782 if (CHARSET.graphic && 0x5f <= c && c <= 0x7e) return vt100_graphics[c-0x5f];
783 if (CHARSET.pound && c == '#' ) return 0xa3; //This mode is obsolete
784 return c;
785}
786
787/*
788 "Charset" related part of the emulation state.
789 This configures the VT100 charset filter.
790
791 While most operation work on the current screen,
792 the following two are different.
793*/
794
795void TEmuVt102::resetCharset(int scrno)
796{
797 charset[scrno].cu_cs = 0;
798 strncpy(charset[scrno].charset,"BBBB",4);
799 charset[scrno].sa_graphic = FALSE;
800 charset[scrno].sa_pound = FALSE;
801 charset[scrno].graphic = FALSE;
802 charset[scrno].pound = FALSE;
803}
804
805/*!
806*/
807
808void TEmuVt102::setCharset(int n, int cs) // on both screens.
809{
810 charset[0].charset[n&3] = cs; useCharset(charset[0].cu_cs);
811 charset[1].charset[n&3] = cs; useCharset(charset[1].cu_cs);
812}
813
814/*!
815*/
816
817void TEmuVt102::setAndUseCharset(int n, int cs)
818{
819 CHARSET.charset[n&3] = cs;
820 useCharset(n&3);
821}
822
823/*!
824*/
825
826void TEmuVt102::useCharset(int n)
827{
828 CHARSET.cu_cs = n&3;
829 CHARSET.graphic = (CHARSET.charset[n&3] == '0');
830 CHARSET.pound = (CHARSET.charset[n&3] == 'A'); //This mode is obsolete
831}
832
833/*! Save the cursor position and the rendition attribute settings. */
834
835void TEmuVt102::saveCursor()
836{
837 CHARSET.sa_graphic = CHARSET.graphic;
838 CHARSET.sa_pound = CHARSET.pound; //This mode is obsolete
839 // we are not clear about these
840 //sa_charset = charsets[cScreen->charset];
841 //sa_charset_num = cScreen->charset;
842 scr->saveCursor();
843}
844
845/*! Restore the cursor position and the rendition attribute settings. */
846
847void TEmuVt102::restoreCursor()
848{
849 CHARSET.graphic = CHARSET.sa_graphic;
850 CHARSET.pound = CHARSET.sa_pound; //This mode is obsolete
851 scr->restoreCursor();
852}
853
854/* ------------------------------------------------------------------------- */
855/* */
856/* Mode Operations */
857/* */
858/* ------------------------------------------------------------------------- */
859
860/*
861 Some of the emulations state is either added to the state of the screens.
862
863 This causes some scoping problems, since different emulations choose to
864 located the mode either to the current screen or to both.
865
866 For strange reasons, the extend of the rendition attributes ranges over
867 all screens and not over the actual screen.
868
869 We decided on the precise precise extend, somehow.
870*/
871
872// "Mode" related part of the state. These are all booleans.
873
874void TEmuVt102::resetModes()
875{
876 resetMode(MODE_Mouse1000); saveMode(MODE_Mouse1000);
877 resetMode(MODE_AppScreen); saveMode(MODE_AppScreen);
878 // here come obsolete modes
879 resetMode(MODE_AppCuKeys); saveMode(MODE_AppCuKeys);
880 resetMode(MODE_NewLine );
881 setMode(MODE_Ansi );
882}
883
884void TEmuVt102::setMode(int m)
885{
886 currParm.mode[m] = TRUE;
887 switch (m)
888 {
889 case MODE_Mouse1000 : gui->setMouseMarks(FALSE);
890 break;
891 case MODE_AppScreen : screen[1]->clearSelection();
892 screen[1]->clearEntireScreen();
893 setScreen(1);
894 break;
895 }
896 if (m < MODES_SCREEN || m == MODE_NewLine)
897 {
898 screen[0]->setMode(m);
899 screen[1]->setMode(m);
900 }
901}
902
903void TEmuVt102::resetMode(int m)
904{
905 currParm.mode[m] = FALSE;
906 switch (m)
907 {
908 case MODE_Mouse1000 : gui->setMouseMarks(TRUE);
909 break;
910 case MODE_AppScreen : screen[0]->clearSelection();
911 setScreen(0);
912 break;
913 }
914 if (m < MODES_SCREEN || m == MODE_NewLine)
915 {
916 screen[0]->resetMode(m);
917 screen[1]->resetMode(m);
918 }
919}
920
921void TEmuVt102::saveMode(int m)
922{
923 saveParm.mode[m] = currParm.mode[m];
924}
925
926void TEmuVt102::restoreMode(int m)
927{
928 if(saveParm.mode[m]) setMode(m); else resetMode(m);
929}
930
931BOOL TEmuVt102::getMode(int m)
932{
933 return currParm.mode[m];
934}
935
936void TEmuVt102::setConnect(bool c)
937{
938 TEmulation::setConnect(c);
939 if (c)
940 { // refresh mouse mode
941 if (getMode(MODE_Mouse1000))
942 setMode(MODE_Mouse1000);
943 else
944 resetMode(MODE_Mouse1000);
945 }
946}
947
948/* ------------------------------------------------------------------------- */
949/* */
950/* Diagnostic */
951/* */
952/* ------------------------------------------------------------------------- */
953
954/*! shows the contents of the scan buffer.
955
956 This functions is used for diagnostics. It is called by \e ReportErrorToken
957 to inform about strings that cannot be decoded or handled by the emulation.
958
959 \sa ReportErrorToken
960*/
961
962/*!
963*/
964
965static void hexdump(int* s, int len)
966{ int i;
967 for (i = 0; i < len; i++)
968 {
969 if (s[i] == '\\')
970 printf("\\\\");
971 else
972 if ((s[i]) > 32 && s[i] < 127)
973 printf("%c",s[i]);
974 else
975 printf("\\%04x(hex)",s[i]);
976 }
977}
978
979void TEmuVt102::scan_buffer_report()
980{
981 if (ppos == 0 || ppos == 1 && (pbuf[0] & 0xff) >= 32) return;
982 printf("token: "); hexdump(pbuf,ppos); printf("\n");
983}
984
985/*!
986*/
987
988void TEmuVt102::ReportErrorToken()
989{
990 printf("undecodable "); scan_buffer_report();
991}
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 @@
1/* -------------------------------------------------------------------------- */
2/* */
3/* [TEmuVt102.h] X Terminal Emulation */
4/* */
5/* -------------------------------------------------------------------------- */
6/* */
7/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */
8/* */
9/* This file is part of Konsole - an X terminal for KDE */
10/* */
11/* -------------------------------------------------------------------------- */
12 /* */
13/* Ported Konsole to Qt/Embedded */
14 /* */
15/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */
16 /* */
17/* -------------------------------------------------------------------------- */
18
19#ifndef VT102EMU_H
20#define VT102EMU_H
21
22#include "TEWidget.h"
23#include "TEScreen.h"
24#include "TEmulation.h"
25#include <qtimer.h>
26#include <stdio.h>
27
28//
29
30#define MODE_AppScreen (MODES_SCREEN+0)
31#define MODE_AppCuKeys (MODES_SCREEN+1)
32#define MODE_AppKeyPad (MODES_SCREEN+2)
33#define MODE_Mouse1000 (MODES_SCREEN+3)
34#define MODE_Ansi (MODES_SCREEN+4)
35#define MODE_total (MODES_SCREEN+5)
36
37struct DECpar
38{
39 BOOL mode[MODE_total];
40};
41
42struct CharCodes
43{
44 // coding info
45 char charset[4]; //
46 int cu_cs; // actual charset.
47 bool graphic; // Some VT100 tricks
48 bool pound ; // Some VT100 tricks
49 bool sa_graphic; // saved graphic
50 bool sa_pound; // saved pound
51};
52
53class TEmuVt102 : public TEmulation
54{ Q_OBJECT
55
56public:
57
58 TEmuVt102(TEWidget* gui);
59 ~TEmuVt102();
60
61public slots: // signals incoming from TEWidget
62
63 void onKeyPress(QKeyEvent*);
64 void onMouse(int cb, int cx, int cy);
65
66signals:
67
68 void changeTitle(int,const QString&);
69 void prevSession();
70 void nextSession();
71
72public:
73
74 void reset();
75
76 void onRcvChar(int cc);
77 void sendString(const char *);
78
79public:
80
81 BOOL getMode (int m);
82
83 void setMode (int m);
84 void resetMode (int m);
85 void saveMode (int m);
86 void restoreMode(int m);
87 void resetModes();
88
89 void setConnect(bool r);
90
91private:
92
93 void resetToken();
94#define MAXPBUF 80
95 void pushToToken(int cc);
96 int pbuf[MAXPBUF]; //FIXME: overflow?
97 int ppos;
98#define MAXARGS 15
99 void addDigit(int dig);
100 void addArgument();
101 int argv[MAXARGS];
102 int argc;
103 void initTokenizer();
104 int tbl[256];
105
106 void scan_buffer_report(); //FIXME: rename
107 void ReportErrorToken(); //FIXME: rename
108
109 void tau(int code, int p, int q);
110 void XtermHack();
111
112 //
113
114 void reportTerminalType();
115 void reportStatus();
116 void reportAnswerBack();
117 void reportCursorPosition();
118 void reportTerminalParms(int p);
119
120protected:
121
122 unsigned short applyCharset(unsigned short c);
123 void setCharset(int n, int cs);
124 void useCharset(int n);
125 void setAndUseCharset(int n, int cs);
126 void saveCursor();
127 void restoreCursor();
128 void resetCharset(int scrno);
129 CharCodes charset[2];
130
131 DECpar currParm;
132 DECpar saveParm;
133};
134
135#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 @@
1/* -------------------------------------------------------------------------- */
2/* */
3/* [TEmulation.cpp] Terminal Emulation Decoder */
4/* */
5/* -------------------------------------------------------------------------- */
6/* */
7/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */
8/* */
9/* This file is part of Konsole - an X terminal for KDE */
10/* */
11/* -------------------------------------------------------------------------- */
12 /* */
13/* Ported Konsole to Qt/Embedded */
14 /* */
15/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */
16 /* */
17/* -------------------------------------------------------------------------- */
18
19/*! \class TEmulation
20
21 \brief Mediator between TEWidget and TEScreen.
22
23 This class is responsible to scan the escapes sequences of the terminal
24 emulation and to map it to their corresponding semantic complements.
25 Thus this module knows mainly about decoding escapes sequences and
26 is a stateless device w.r.t. the semantics.
27
28 It is also responsible to refresh the TEWidget by certain rules.
29
30 \sa TEWidget \sa TEScreen
31
32 \par A note on refreshing
33
34 Although the modifications to the current screen image could immediately
35 be propagated via `TEWidget' to the graphical surface, we have chosen
36 another way here.
37
38 The reason for doing so is twofold.
39
40 First, experiments show that directly displaying the operation results
41 in slowing down the overall performance of emulations. Displaying
42 individual characters using X11 creates a lot of overhead.
43
44 Second, by using the following refreshing method, the screen operations
45 can be completely separated from the displaying. This greatly simplifies
46 the programmer's task of coding and maintaining the screen operations,
47 since one need not worry about differential modifications on the
48 display affecting the operation of concern.
49
50 We use a refreshing algorithm here that has been adoped from rxvt/kvt.
51
52 By this, refreshing is driven by a timer, which is (re)started whenever
53 a new bunch of data to be interpreted by the emulation arives at `onRcvBlock'.
54 As soon as no more data arrive for `BULK_TIMEOUT' milliseconds, we trigger
55 refresh. This rule suits both bulk display operation as done by curses as
56 well as individual characters typed.
57 (BULK_TIMEOUT < 1000 / max characters received from keyboard per second).
58
59 Additionally, we trigger refreshing by newlines comming in to make visual
60 snapshots of lists as produced by `cat', `ls' and likely programs, thereby
61 producing the illusion of a permanent and immediate display operation.
62
63 As a sort of catch-all needed for cases where none of the above
64 conditions catch, the screen refresh is also triggered by a count
65 of incoming bulks (`bulk_incnt').
66*/
67
68/* FIXME
69 - evtl. the bulk operations could be made more transparent.
70*/
71
72#include "TEmulation.h"
73#include "TEWidget.h"
74#include "TEScreen.h"
75#include <stdio.h>
76#include <stdlib.h>
77#include <unistd.h>
78#include <qkeycode.h>
79
80
81/* ------------------------------------------------------------------------- */
82/* */
83/* TEmulation */
84/* */
85/* ------------------------------------------------------------------------- */
86
87#define CNTL(c) ((c)-'@')
88
89/*!
90*/
91
92TEmulation::TEmulation(TEWidget* gui)
93: decoder((QTextDecoder*)NULL)
94{
95 this->gui = gui;
96
97 screen[0] = new TEScreen(gui->Lines(),gui->Columns());
98 screen[1] = new TEScreen(gui->Lines(),gui->Columns());
99 scr = screen[0];
100
101 bulk_nlcnt = 0; // reset bulk newline counter
102 bulk_incnt = 0; // reset bulk counter
103 connected = FALSE;
104
105 QObject::connect(&bulk_timer, SIGNAL(timeout()), this, SLOT(showBulk()) );
106 QObject::connect(gui,SIGNAL(changedImageSizeSignal(int,int)),
107 this,SLOT(onImageSizeChange(int,int)));
108 QObject::connect(gui,SIGNAL(changedHistoryCursor(int)),
109 this,SLOT(onHistoryCursorChange(int)));
110 QObject::connect(gui,SIGNAL(keyPressedSignal(QKeyEvent*)),
111 this,SLOT(onKeyPress(QKeyEvent*)));
112 QObject::connect(gui,SIGNAL(beginSelectionSignal(const int,const int)),
113 this,SLOT(onSelectionBegin(const int,const int)) );
114 QObject::connect(gui,SIGNAL(extendSelectionSignal(const int,const int)),
115 this,SLOT(onSelectionExtend(const int,const int)) );
116 QObject::connect(gui,SIGNAL(endSelectionSignal(const BOOL)),
117 this,SLOT(setSelection(const BOOL)) );
118 QObject::connect(gui,SIGNAL(clearSelectionSignal()),
119 this,SLOT(clearSelection()) );
120}
121
122/*!
123*/
124
125TEmulation::~TEmulation()
126{
127 delete screen[0];
128 delete screen[1];
129 bulk_timer.stop();
130}
131
132/*! change between primary and alternate screen
133*/
134
135void TEmulation::setScreen(int n)
136{
137 scr = screen[n&1];
138}
139
140void TEmulation::setHistory(bool on)
141{
142 screen[0]->setScroll(on);
143 if (!connected) return;
144 showBulk();
145}
146
147bool TEmulation::history()
148{
149 return screen[0]->hasScroll();
150}
151
152void TEmulation::setCodec(int c)
153{
154 //FIXME: check whether we have to free codec
155 codec = c ? QTextCodec::codecForName("utf8")
156 : QTextCodec::codecForLocale();
157 if (decoder) delete decoder;
158 decoder = codec->makeDecoder();
159}
160
161void TEmulation::setKeytrans(int no)
162{
163 keytrans = KeyTrans::find(no);
164}
165
166void TEmulation::setKeytrans(const char * no)
167{
168 keytrans = KeyTrans::find(no);
169}
170
171// Interpreting Codes ---------------------------------------------------------
172
173/*
174 This section deals with decoding the incoming character stream.
175 Decoding means here, that the stream is first seperated into `tokens'
176 which are then mapped to a `meaning' provided as operations by the
177 `Screen' class.
178*/
179
180/*!
181*/
182
183void TEmulation::onRcvChar(int c)
184// process application unicode input to terminal
185// this is a trivial scanner
186{
187 c &= 0xff;
188 switch (c)
189 {
190 case '\b' : scr->BackSpace(); break;
191 case '\t' : scr->Tabulate(); break;
192 case '\n' : scr->NewLine(); break;
193 case '\r' : scr->Return(); break;
194 case 0x07 : gui->Bell(); break;
195 default : scr->ShowCharacter(c); break;
196 };
197}
198
199/* ------------------------------------------------------------------------- */
200/* */
201/* Keyboard Handling */
202/* */
203/* ------------------------------------------------------------------------- */
204
205/*!
206*/
207
208void TEmulation::onKeyPress( QKeyEvent* ev )
209{
210 if (!connected) return; // someone else gets the keys
211 if (scr->getHistCursor() != scr->getHistLines());
212 scr->setHistCursor(scr->getHistLines());
213 if (!ev->text().isEmpty())
214 { // A block of text
215 // Note that the text is proper unicode.
216 // We should do a conversion here, but since this
217 // routine will never be used, we simply emit plain ascii.
218 emit sndBlock(ev->text().ascii(),ev->text().length());
219 }
220 else if (ev->ascii()>0)
221 { unsigned char c[1];
222 c[0] = ev->ascii();
223 emit sndBlock((char*)c,1);
224 }
225}
226
227// Unblocking, Byte to Unicode translation --------------------------------- --
228
229/*
230 We are doing code conversion from locale to unicode first.
231*/
232
233void TEmulation::onRcvBlock(const char *s, int len)
234{
235 bulkStart();
236 bulk_incnt += 1;
237 for (int i = 0; i < len; i++)
238 {
239 QString result = decoder->toUnicode(&s[i],1);
240 int reslen = result.length();
241 for (int j = 0; j < reslen; j++)
242 onRcvChar(result[j].unicode());
243 if (s[i] == '\n') bulkNewline();
244 }
245 bulkEnd();
246}
247
248// Selection --------------------------------------------------------------- --
249
250void TEmulation::onSelectionBegin(const int x, const int y) {
251 if (!connected) return;
252 scr->setSelBeginXY(x,y);
253 showBulk();
254}
255
256void TEmulation::onSelectionExtend(const int x, const int y) {
257 if (!connected) return;
258 scr->setSelExtentXY(x,y);
259 showBulk();
260}
261
262void TEmulation::setSelection(const BOOL preserve_line_breaks) {
263 if (!connected) return;
264 QString t = scr->getSelText(preserve_line_breaks);
265 if (!t.isNull()) gui->setSelection(t);
266}
267
268void TEmulation::clearSelection() {
269 if (!connected) return;
270 scr->clearSelection();
271 showBulk();
272}
273
274// Refreshing -------------------------------------------------------------- --
275
276#define BULK_TIMEOUT 20
277
278/*!
279 called when \n comes in. Evtl. triggers showBulk at endBulk
280*/
281
282void TEmulation::bulkNewline()
283{
284 bulk_nlcnt += 1;
285 bulk_incnt = 0; // reset bulk counter since `nl' rule applies
286}
287
288/*!
289*/
290
291void TEmulation::showBulk()
292{
293 bulk_nlcnt = 0; // reset bulk newline counter
294 bulk_incnt = 0; // reset bulk counter
295 if (connected)
296 {
297 ca* image = scr->getCookedImage(); // get the image
298 gui->setImage(image,
299 scr->getLines(),
300 scr->getColumns()); // actual refresh
301 free(image);
302 //FIXME: check that we do not trigger other draw event here.
303 gui->setScroll(scr->getHistCursor(),scr->getHistLines());
304 }
305}
306
307void TEmulation::bulkStart()
308{
309 if (bulk_timer.isActive()) bulk_timer.stop();
310}
311
312void TEmulation::bulkEnd()
313{
314 if ( bulk_nlcnt > gui->Lines() || bulk_incnt > 20 )
315 showBulk(); // resets bulk_??cnt to 0, too.
316 else
317 bulk_timer.start(BULK_TIMEOUT,TRUE);
318}
319
320void TEmulation::setConnect(bool c)
321{
322 connected = c;
323 if ( connected)
324 {
325 onImageSizeChange(gui->Lines(), gui->Columns());
326 showBulk();
327 }
328 else
329 {
330 scr->clearSelection();
331 }
332}
333
334// ---------------------------------------------------------------------------
335
336/*! triggered by image size change of the TEWidget `gui'.
337
338 This event is simply propagated to the attached screens
339 and to the related serial line.
340*/
341
342void TEmulation::onImageSizeChange(int lines, int columns)
343{
344 if (!connected) return;
345 screen[0]->resizeImage(lines,columns);
346 screen[1]->resizeImage(lines,columns);
347 showBulk();
348 emit ImageSizeChanged(lines,columns); // propagate event to serial line
349}
350
351void TEmulation::onHistoryCursorChange(int cursor)
352{
353 if (!connected) return;
354 scr->setHistCursor(cursor);
355 showBulk();
356}
357
358void TEmulation::setColumns(int columns)
359{
360 //FIXME: this goes strange ways.
361 // Can we put this straight or explain it at least?
362 emit changeColumns(columns);
363}
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 @@
1/* -------------------------------------------------------------------------- */
2/* */
3/* [emulation.h] Fundamental Terminal Emulation */
4/* */
5/* -------------------------------------------------------------------------- */
6/* */
7/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */
8/* */
9/* This file is part of Konsole - an X terminal for KDE */
10/* */
11/* -------------------------------------------------------------------------- */
12 /* */
13/* Ported Konsole to Qt/Embedded */
14 /* */
15/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */
16 /* */
17/* -------------------------------------------------------------------------- */
18
19#ifndef EMULATION_H
20#define EMULATION_H
21
22#include "TEWidget.h"
23#include "TEScreen.h"
24#include <qtimer.h>
25#include <stdio.h>
26#include <qtextcodec.h>
27#include "keytrans.h"
28
29class TEmulation : public QObject
30{ Q_OBJECT
31
32public:
33
34 TEmulation(TEWidget* gui);
35 ~TEmulation();
36
37public:
38 virtual void setHistory(bool on);
39 virtual bool history();
40
41public slots: // signals incoming from TEWidget
42
43 virtual void onImageSizeChange(int lines, int columns);
44 virtual void onHistoryCursorChange(int cursor);
45 virtual void onKeyPress(QKeyEvent*);
46
47 virtual void clearSelection();
48 virtual void onSelectionBegin(const int x, const int y);
49 virtual void onSelectionExtend(const int x, const int y);
50 virtual void setSelection(const BOOL preserve_line_breaks);
51
52public slots: // signals incoming from data source
53
54 void onRcvBlock(const char* txt,int len);
55
56signals:
57
58 void sndBlock(const char* txt,int len);
59 void ImageSizeChanged(int lines, int columns);
60 void changeColumns(int columns);
61 void changeTitle(int arg, const char* str);
62
63public:
64
65 virtual void onRcvChar(int);
66
67 virtual void setMode (int) = 0;
68 virtual void resetMode(int) = 0;
69
70 virtual void sendString(const char*) = 0;
71
72 virtual void setConnect(bool r);
73 void setColumns(int columns);
74
75 void setKeytrans(int no);
76 void setKeytrans(const char * no);
77
78protected:
79
80 TEWidget* gui;
81 TEScreen* scr; // referes to one `screen'
82 TEScreen* screen[2]; // 0 = primary, 1 = alternate
83 void setScreen(int n); // set `scr' to `screen[n]'
84
85 bool connected; // communicate with widget
86
87 void setCodec(int c); // codec number, 0 = locale, 1=utf8
88
89 QTextCodec* codec;
90 QTextCodec* localeCodec;
91 QTextDecoder* decoder;
92
93 KeyTrans* keytrans;
94
95// refreshing related material.
96// this is localized in the class.
97private slots: // triggered by timer
98
99 void showBulk();
100
101private:
102
103 void bulkNewline();
104 void bulkStart();
105 void bulkEnd();
106
107private:
108
109 QTimer bulk_timer;
110 int bulk_nlcnt; // bulk newline counter
111 char* SelectedText;
112 int bulk_incnt; // bulk counter
113
114
115};
116
117#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 @@
1 /* generated by '../tests/quote ../other/default.Keytab' */
2
3 "# [default.Keytab] Buildin Keyboard Table\n"
4 "\n"
5 "# --------------------------------------------------------------\n"
6 "#\n"
7 "# This file in included only for reference purposes. \n"
8 "#\n"
9 "# Modifying it does not have any effect (unless you\n"
10 "# derive the default.keytab.h and recompile konsole).\n"
11 "#\n"
12 "# To customize your keyboard, copy this file to something\n"
13 "# ending with .keytab and change it to meet you needs.\n"
14 "#\n"
15 "# --------------------------------------------------------------\n"
16 "\n"
17 "keyboard \"xterm (default)\"\n"
18 "\n"
19 "# --------------------------------------------------------------\n"
20 "#\n"
21 "# The syntax of each entry has the form\n"
22 "#\n"
23 "# \"key\" Keyname { (\"+\"|\"-\") Modename } \":\" (String|Operation)\n"
24 "#\n"
25 "# Keynames are those defined in <qnamespace.h>\n"
26 "# with the \"Qt::Key_\" prefix removed.\n"
27 "#\n"
28 "# Mode names are: Shift, Alt, Control.\n"
29 "#\n"
30 "# If the key is not found here, the text of the\n"
31 "# key event as provided by QT is emitted, possibly\n"
32 "# preceeded by ESC if the Alt key is pressed.\n"
33 "#\n"
34 "# --------------------------------------------------------------\n"
35 "#\n"
36 "# Note that this particular table is a \"risc\" version made to\n"
37 "# ease customization without bothering with obsolete details.\n"
38 "# See VT100.keytab for the more hairy stuff.\n"
39 "#\n"
40 "# --------------------------------------------------------------\n"
41 "\n"
42 "# common keys\n"
43 "\n"
44 "key Escape : \"\\E\"\n"
45 "key Tab : \"\\t\"\n"
46 "\n"
47 "key Return-Alt : \"\\r\"\n"
48 "key Return+Alt : \"\\E\\r\"\n"
49 "\n"
50 "# Backspace and Delete codes are preserving CTRL-H.\n"
51 "\n"
52 "key Backspace : \"\\x7f\"\n"
53 "\n"
54 "# cursor keys\n"
55 "\n"
56 "key Up -Shift : \"\\EOA\"\n"
57 "key Down -Shift : \"\\EOB\"\n"
58 "key Right -Shift : \"\\EOC\"\n"
59 "key Left -Shift : \"\\EOD\"\n"
60 "\n"
61 "# other grey PC keys\n"
62 "\n"
63 "key Enter : \"\\r\"\n"
64 "\n"
65 "key Home : \"\\E[1~\"\n"
66 "key Insert-Shift : \"\\E[2~\"\n"
67 "key Delete : \"\\E[3~\"\n"
68 "key End : \"\\E[4~\"\n"
69 "key Prior -Shift : \"\\E[5~\"\n"
70 "key Next -Shift : \"\\E[6~\"\n"
71 "\n"
72 "# function keys\n"
73 "\n"
74 "key F1 : \"\\E[11~\"\n"
75 "key F2 : \"\\E[12~\"\n"
76 "key F3 : \"\\E[13~\"\n"
77 "key F4 : \"\\E[14~\"\n"
78 "key F5 : \"\\E[15~\"\n"
79 "key F6 : \"\\E[17~\"\n"
80 "key F7 : \"\\E[18~\"\n"
81 "key F8 : \"\\E[19~\"\n"
82 "key F9 : \"\\E[20~\"\n"
83 "key F10 : \"\\E[21~\"\n"
84 "key F11 : \"\\E[23~\"\n"
85 "key F12 : \"\\E[24~\"\n"
86 "\n"
87 "# Work around dead keys\n"
88 "\n"
89 "key Space +Control : \"\\x00\"\n"
90 "\n"
91 "# Some keys are used by konsole to cause operations.\n"
92 "# The scroll* operations refer to the history buffer.\n"
93 "\n"
94 "key Left +Shift : prevSession\n"
95 "key Right +Shift : nextSession\n"
96 "key Up +Shift : scrollLineUp\n"
97 "key Prior +Shift : scrollPageUp\n"
98 "key Down +Shift : scrollLineDown\n"
99 "key Next +Shift : scrollPageDown\n"
100 "key Insert+Shift : emitSelection\n"
101 "\n"
102 "# keypad characters are not offered differently by Qt.\n"
103 ""
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 @@
1 TEMPLATE= app
2
3 CONFIG += qt warn_on release
4
5 DESTDIR = $(QPEDIR)/bin
6
7 HEADERS = TEWidget.h \
8 TEScreen.h \
9 TECommon.h \
10 TEHistory.h \
11 TEmulation.h \
12 TEmuVt102.h \
13 session.h \
14 keytrans.h \
15 konsole.h \
16 MyPty.h
17
18 SOURCES = TEScreen.cpp \
19 TEWidget.cpp \
20 TEHistory.cpp \
21 TEmulation.cpp \
22 TEmuVt102.cpp \
23 session.cpp \
24 keytrans.cpp \
25 konsole.cpp \
26 main.cpp \
27 MyPty.cpp
28
29 TARGET = embeddedkonsole
30
31INCLUDEPATH += $(QPEDIR)/include
32
33 DEPENDPATH+= $(QPEDIR)/include
34
35LIBS += -lqpe
36
37 REQUIRES= embeddedkonsole
38
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 @@
1/* -------------------------------------------------------------------------- */
2/* */
3/* [keytrans.C] Keyboard Translation */
4/* */
5/* -------------------------------------------------------------------------- */
6/* */
7/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */
8/* */
9/* This file is part of Konsole - an X terminal for KDE */
10/* */
11/* -------------------------------------------------------------------------- */
12 /* */
13/* Ported Konsole to Qt/Embedded */
14 /* */
15/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */
16 /* */
17/* -------------------------------------------------------------------------- */
18
19/*
20 The keyboard translation table allows to configure konsoles behavior
21 on key strokes.
22
23 FIXME: some bug crept in, disallowing '\0' to be emitted.
24*/
25
26#include "keytrans.h"
27
28#include <qpe/qpeapplication.h>
29
30#include <qnamespace.h>
31#include <qbuffer.h>
32#include <qobject.h>
33#include <qdict.h>
34#include <qintdict.h>
35#include <qfile.h>
36#include <qglobal.h>
37#include <qdir.h>
38
39//#include <kstddirs.h>
40//nclude <klocale.h>
41
42#include <stdio.h>
43
44
45#undef USE_APPDATA_DIR
46
47
48#define HERE printf("%s(%d): here\n",__FILE__,__LINE__)
49
50/* KeyEntry
51
52 instances represent the individual assignments
53*/
54
55KeyTrans::KeyEntry::KeyEntry(int _ref, int _key, int _bits, int _mask, int _cmd, QString _txt)
56: ref(_ref), key(_key), bits(_bits), mask(_mask), cmd(_cmd), txt(_txt)
57{
58}
59
60KeyTrans::KeyEntry::~KeyEntry()
61{
62}
63
64bool KeyTrans::KeyEntry::matches(int _key, int _bits, int _mask)
65{ int m = mask & _mask;
66 return _key == key && (bits & m) == (_bits & m);
67}
68
69QString KeyTrans::KeyEntry::text()
70{
71 return txt;
72}
73
74/* KeyTrans
75
76 combines the individual assignments to a proper map
77 Takes part in a collection themself.
78*/
79
80KeyTrans::KeyTrans()
81{
82 path = "";
83 numb = 0;
84}
85
86KeyTrans::~KeyTrans()
87{
88}
89
90KeyTrans::KeyEntry* KeyTrans::addEntry(int ref, int key, int bits, int mask, int cmd, QString txt)
91// returns conflicting entry
92{
93 for (QListIterator<KeyEntry> it(table); it.current(); ++it)
94 {
95 if (it.current()->matches(key,bits,mask))
96 {
97 return it.current();
98 }
99 }
100 table.append(new KeyEntry(ref,key,bits,mask,cmd,txt));
101 return (KeyEntry*)NULL;
102}
103
104bool KeyTrans::findEntry(int key, int bits, int* cmd, const char** txt, int* len)
105{
106 for (QListIterator<KeyEntry> it(table); it.current(); ++it)
107 if (it.current()->matches(key,bits,0xffff))
108 {
109 *cmd = it.current()->cmd;
110 *txt = it.current()->txt.ascii();
111 *len = it.current()->txt.length();
112 return TRUE;
113 }
114 return FALSE;
115}
116
117/* ------------------------------------------------------------------------- */
118/* */
119/* Scanner for keyboard configuration */
120/* */
121/* ------------------------------------------------------------------------- */
122
123// regular tokenizer
124/* Tokens
125 - Spaces
126 - Name (A-Za-z0-9)+
127 - String
128 - Opr on of +-:
129*/
130
131#define SYMName 0
132#define SYMString 1
133#define SYMEol 2
134#define SYMEof 3
135#define SYMOpr 4
136#define SYMError 5
137
138#define inRange(L,X,H) ((L <= X) && (X <= H))
139#define isNibble(X) (inRange('A',X,'F')||inRange('a',X,'f')||inRange('0',X,'9'))
140#define convNibble(X) (inRange('0',X,'9')?X-'0':X+10-(inRange('A',X,'F')?'A':'a'))
141
142class KeytabReader
143{
144public:
145 KeytabReader(QString p, QIODevice &d);
146public:
147 void getCc();
148 void getSymbol();
149 void parseTo(KeyTrans* kt);
150 void ReportError(const char* msg);
151 void ReportToken(); // diagnostic
152private:
153 int sym;
154 QString res;
155 int len;
156 int slinno;
157 int scolno;
158private:
159 int cc;
160 int linno;
161 int colno;
162 QIODevice* buf;
163 QString path;
164};
165
166
167KeytabReader::KeytabReader(QString p, QIODevice &d)
168{
169 path = p;
170 buf = &d;
171 cc = 0;
172}
173
174void KeytabReader::getCc()
175{
176 if (cc == '\n') { linno += 1; colno = 0; }
177 if (cc < 0) return;
178 cc = buf->getch();
179 colno += 1;
180}
181
182void KeytabReader::getSymbol()
183{
184 res = ""; len = 0; sym = SYMError;
185 while (cc == ' ') getCc(); // skip spaces
186 if (cc == '#') // skip comment
187 {
188 while (cc != '\n' && cc > 0) getCc();
189 }
190 slinno = linno;
191 scolno = colno;
192 if (cc <= 0)
193 {
194 sym = SYMEof; return; // eos
195 }
196 if (cc == '\n')
197 {
198 getCc();
199 sym = SYMEol; return; // eol
200 }
201 if (inRange('A',cc,'Z')||inRange('a',cc,'z')||inRange('0',cc,'9'))
202 {
203 while (inRange('A',cc,'Z') || inRange('a',cc,'z') || inRange('0',cc,'9'))
204 {
205 res = res + (char)cc;
206 getCc();
207 }
208 sym = SYMName;
209 return;
210 }
211 if (strchr("+-:",cc))
212 {
213 res = "";
214 res = res + (char)cc;
215 getCc();
216 sym = SYMOpr; return;
217 }
218 if (cc == '"')
219 {
220 getCc();
221 while (cc >= ' ' && cc != '"')
222 { int sc;
223 if (cc == '\\') // handle quotation
224 {
225 getCc();
226 switch (cc)
227 {
228 case 'E' : sc = 27; getCc(); break;
229 case 'b' : sc = 8; getCc(); break;
230 case 'f' : sc = 12; getCc(); break;
231 case 't' : sc = 9; getCc(); break;
232 case 'r' : sc = 13; getCc(); break;
233 case 'n' : sc = 10; getCc(); break;
234 case '\\' : // fall thru
235 case '"' : sc = cc; getCc(); break;
236 case 'x' : getCc();
237 sc = 0;
238 if (!isNibble(cc)) return; sc = 16*sc + convNibble(cc); getCc();
239 if (!isNibble(cc)) return; sc = 16*sc + convNibble(cc); getCc();
240 break;
241 default : return;
242 }
243 }
244 else
245 {
246 // regular char
247 sc = cc; getCc();
248 }
249 res = res + (char)sc;
250 len = len + 1;
251 }
252 if (cc != '"') return;
253 getCc();
254 sym = SYMString; return;
255 }
256}
257
258void KeytabReader::ReportToken() // diagnostic
259{
260 printf("sym(%d): ",slinno);
261 switch(sym)
262 {
263 case SYMEol : printf("End of line"); break;
264 case SYMEof : printf("End of file"); break;
265 case SYMName : printf("Name: %s",res.latin1()); break;
266 case SYMOpr : printf("Opr : %s",res.latin1()); break;
267 case SYMString : printf("String len %d,%d ",res.length(),len);
268 for (unsigned i = 0; i < res.length(); i++)
269 printf(" %02x(%c)",res.latin1()[i],res.latin1()[i]>=' '?res.latin1()[i]:'?');
270 break;
271 }
272 printf("\n");
273}
274
275void KeytabReader::ReportError(const char* msg) // diagnostic
276{
277 fprintf(stderr,"%s(%d,%d):error: %s.\n",path.ascii(),slinno,scolno,msg);
278}
279
280// local symbol tables ---------------------------------------------------------------------
281
282class KeyTransSymbols
283{
284public:
285 KeyTransSymbols();
286protected:
287 void defOprSyms();
288 void defModSyms();
289 void defKeySyms();
290 void defKeySym(const char* key, int val);
291 void defOprSym(const char* key, int val);
292 void defModSym(const char* key, int val);
293public:
294 QDict<QObject> keysyms;
295 QDict<QObject> modsyms;
296 QDict<QObject> oprsyms;
297};
298
299static KeyTransSymbols * syms = 0L;
300
301// parser ----------------------------------------------------------------------------------
302/* Syntax
303 - Line :: [KeyName { ("+" | "-") ModeName } ":" (String|CommandName)] "\n"
304 - Comment :: '#' (any but \n)*
305*/
306
307KeyTrans* KeyTrans::fromDevice(QString path, QIODevice &buf)
308{
309 KeyTrans* kt = new KeyTrans;
310 kt->path = path;
311 KeytabReader ktr(path,buf); ktr.parseTo(kt);
312 return kt;
313}
314
315
316#define assertSyntax(Cond,Message) if (!(Cond)) { ReportError(Message); goto ERROR; }
317
318void KeytabReader::parseTo(KeyTrans* kt)
319{
320 // Opening sequence
321
322 buf->open(IO_ReadOnly);
323 getCc();
324 linno = 1;
325 colno = 1;
326 getSymbol();
327
328Loop:
329 // syntax: ["key" KeyName { ("+" | "-") ModeName } ":" String/CommandName] ["#" Comment]
330 if (sym == SYMName && !strcmp(res.latin1(),"keyboard"))
331 {
332 getSymbol(); assertSyntax(sym == SYMString, "Header expected")
333 kt->hdr = res.latin1();
334 getSymbol(); assertSyntax(sym == SYMEol, "Text unexpected")
335 getSymbol(); // eoln
336 goto Loop;
337 }
338 if (sym == SYMName && !strcmp(res.latin1(),"key"))
339 {
340//printf("line %3d: ",startofsym);
341 getSymbol(); assertSyntax(sym == SYMName, "Name expected")
342 assertSyntax(syms->keysyms[res], "Unknown key name")
343 int key = (int)syms->keysyms[res]-1;
344//printf(" key %s (%04x)",res.latin1(),(int)syms->keysyms[res]-1);
345 getSymbol(); // + - :
346 int mode = 0;
347 int mask = 0;
348 while (sym == SYMOpr && (!strcmp(res.latin1(),"+") || !strcmp(res.latin1(),"-")))
349 {
350 bool on = !strcmp(res.latin1(),"+");
351 getSymbol();
352 // mode name
353 assertSyntax(sym == SYMName, "Name expected")
354 assertSyntax(syms->modsyms[res], "Unknown mode name")
355 int bits = (int)syms->modsyms[res]-1;
356 if (mask & (1 << bits))
357 {
358 fprintf(stderr,"%s(%d,%d): mode name used multible times.\n",path.ascii(),slinno,scolno);
359 }
360 else
361 {
362 mode |= (on << bits);
363 mask |= (1 << bits);
364 }
365//printf(", mode %s(%d) %s",res.latin1(),(int)syms->modsyms[res]-1,on?"on":"off");
366 getSymbol();
367 }
368 assertSyntax(sym == SYMOpr && !strcmp(res.latin1(),":"), "':' expected")
369 getSymbol();
370 // string or command
371 assertSyntax(sym == SYMName || sym == SYMString,"Command or string expected")
372 int cmd = 0;
373 if (sym == SYMName)
374 {
375 assertSyntax(syms->oprsyms[res], "Unknown operator name")
376 cmd = (int)syms->oprsyms[res]-1;
377//printf(": do %s(%d)",res.latin1(),(int)syms->oprsyms[res]-1);
378 }
379 if (sym == SYMString)
380 {
381 cmd = CMD_send;
382//printf(": send");
383//for (unsigned i = 0; i < res.length(); i++)
384//printf(" %02x(%c)",res.latin1()[i],res.latin1()[i]>=' '?res.latin1()[i]:'?');
385 }
386//printf(". summary %04x,%02x,%02x,%d\n",key,mode,mask,cmd);
387 KeyTrans::KeyEntry* ke = kt->addEntry(slinno,key,mode,mask,cmd,res);
388 if (ke)
389 {
390 fprintf(stderr,"%s(%d): keystroke already assigned in line %d.\n",path.ascii(),slinno,ke->ref);
391 }
392 getSymbol();
393 assertSyntax(sym == SYMEol, "Unexpected text")
394 goto Loop;
395 }
396 if (sym == SYMEol)
397 {
398 getSymbol();
399 goto Loop;
400 }
401
402 assertSyntax(sym == SYMEof, "Undecodable Line")
403
404 buf->close();
405 return;
406
407ERROR:
408 while (sym != SYMEol && sym != SYMEof) getSymbol(); // eoln
409 goto Loop;
410}
411
412
413KeyTrans* KeyTrans::defaultKeyTrans()
414{
415 QCString txt =
416#include "default.keytab.h"
417 ;
418 QBuffer buf(txt);
419 return fromDevice("[buildin]",buf);
420}
421
422KeyTrans* KeyTrans::fromFile(const char* path)
423{
424 QFile file(path);
425 return fromDevice(path,file);
426}
427
428// local symbol tables ---------------------------------------------------------------------
429// material needed for parsing the config file.
430// This is incomplete work.
431
432void KeyTransSymbols::defKeySym(const char* key, int val)
433{
434 keysyms.insert(key,(QObject*)(val+1));
435}
436
437void KeyTransSymbols::defOprSym(const char* key, int val)
438{
439 oprsyms.insert(key,(QObject*)(val+1));
440}
441
442void KeyTransSymbols::defModSym(const char* key, int val)
443{
444 modsyms.insert(key,(QObject*)(val+1));
445}
446
447void KeyTransSymbols::defOprSyms()
448{
449 // Modifier
450 defOprSym("scrollLineUp", CMD_scrollLineUp );
451 defOprSym("scrollLineDown",CMD_scrollLineDown);
452 defOprSym("scrollPageUp", CMD_scrollPageUp );
453 defOprSym("scrollPageDown",CMD_scrollPageDown);
454 defOprSym("emitSelection", CMD_emitSelection );
455 defOprSym("prevSession", CMD_prevSession );
456 defOprSym("nextSession", CMD_nextSession );
457}
458
459void KeyTransSymbols::defModSyms()
460{
461 // Modifier
462 defModSym("Shift", BITS_Shift );
463 defModSym("Control", BITS_Control );
464 defModSym("Alt", BITS_Alt );
465 // Modes
466 defModSym("BsHack", BITS_BsHack ); // deprecated
467 defModSym("Ansi", BITS_Ansi );
468 defModSym("NewLine", BITS_NewLine );
469 defModSym("AppCuKeys", BITS_AppCuKeys );
470}
471
472void KeyTransSymbols::defKeySyms()
473{
474 // Grey keys
475 defKeySym("Escape", Qt::Key_Escape );
476 defKeySym("Tab", Qt::Key_Tab );
477 defKeySym("Backtab", Qt::Key_Backtab );
478 defKeySym("Backspace", Qt::Key_Backspace );
479 defKeySym("Return", Qt::Key_Return );
480 defKeySym("Enter", Qt::Key_Enter );
481 defKeySym("Insert", Qt::Key_Insert );
482 defKeySym("Delete", Qt::Key_Delete );
483 defKeySym("Pause", Qt::Key_Pause );
484 defKeySym("Print", Qt::Key_Print );
485 defKeySym("SysReq", Qt::Key_SysReq );
486 defKeySym("Home", Qt::Key_Home );
487 defKeySym("End", Qt::Key_End );
488 defKeySym("Left", Qt::Key_Left );
489 defKeySym("Up", Qt::Key_Up );
490 defKeySym("Right", Qt::Key_Right );
491 defKeySym("Down", Qt::Key_Down );
492 defKeySym("Prior", Qt::Key_Prior );
493 defKeySym("Next", Qt::Key_Next );
494 defKeySym("Shift", Qt::Key_Shift );
495 defKeySym("Control", Qt::Key_Control );
496 defKeySym("Meta", Qt::Key_Meta );
497 defKeySym("Alt", Qt::Key_Alt );
498 defKeySym("CapsLock", Qt::Key_CapsLock );
499 defKeySym("NumLock", Qt::Key_NumLock );
500 defKeySym("ScrollLock", Qt::Key_ScrollLock );
501 defKeySym("F1", Qt::Key_F1 );
502 defKeySym("F2", Qt::Key_F2 );
503 defKeySym("F3", Qt::Key_F3 );
504 defKeySym("F4", Qt::Key_F4 );
505 defKeySym("F5", Qt::Key_F5 );
506 defKeySym("F6", Qt::Key_F6 );
507 defKeySym("F7", Qt::Key_F7 );
508 defKeySym("F8", Qt::Key_F8 );
509 defKeySym("F9", Qt::Key_F9 );
510 defKeySym("F10", Qt::Key_F10 );
511 defKeySym("F11", Qt::Key_F11 );
512 defKeySym("F12", Qt::Key_F12 );
513 defKeySym("F13", Qt::Key_F13 );
514 defKeySym("F14", Qt::Key_F14 );
515 defKeySym("F15", Qt::Key_F15 );
516 defKeySym("F16", Qt::Key_F16 );
517 defKeySym("F17", Qt::Key_F17 );
518 defKeySym("F18", Qt::Key_F18 );
519 defKeySym("F19", Qt::Key_F19 );
520 defKeySym("F20", Qt::Key_F20 );
521 defKeySym("F21", Qt::Key_F21 );
522 defKeySym("F22", Qt::Key_F22 );
523 defKeySym("F23", Qt::Key_F23 );
524 defKeySym("F24", Qt::Key_F24 );
525 defKeySym("F25", Qt::Key_F25 );
526 defKeySym("F26", Qt::Key_F26 );
527 defKeySym("F27", Qt::Key_F27 );
528 defKeySym("F28", Qt::Key_F28 );
529 defKeySym("F29", Qt::Key_F29 );
530 defKeySym("F30", Qt::Key_F30 );
531 defKeySym("F31", Qt::Key_F31 );
532 defKeySym("F32", Qt::Key_F32 );
533 defKeySym("F33", Qt::Key_F33 );
534 defKeySym("F34", Qt::Key_F34 );
535 defKeySym("F35", Qt::Key_F35 );
536 defKeySym("Super_L", Qt::Key_Super_L );
537 defKeySym("Super_R", Qt::Key_Super_R );
538 defKeySym("Menu", Qt::Key_Menu );
539 defKeySym("Hyper_L", Qt::Key_Hyper_L );
540 defKeySym("Hyper_R", Qt::Key_Hyper_R );
541
542 // Regular keys
543 defKeySym("Space", Qt::Key_Space );
544 defKeySym("Exclam", Qt::Key_Exclam );
545 defKeySym("QuoteDbl", Qt::Key_QuoteDbl );
546 defKeySym("NumberSign", Qt::Key_NumberSign );
547 defKeySym("Dollar", Qt::Key_Dollar );
548 defKeySym("Percent", Qt::Key_Percent );
549 defKeySym("Ampersand", Qt::Key_Ampersand );
550 defKeySym("Apostrophe", Qt::Key_Apostrophe );
551 defKeySym("ParenLeft", Qt::Key_ParenLeft );
552 defKeySym("ParenRight", Qt::Key_ParenRight );
553 defKeySym("Asterisk", Qt::Key_Asterisk );
554 defKeySym("Plus", Qt::Key_Plus );
555 defKeySym("Comma", Qt::Key_Comma );
556 defKeySym("Minus", Qt::Key_Minus );
557 defKeySym("Period", Qt::Key_Period );
558 defKeySym("Slash", Qt::Key_Slash );
559 defKeySym("0", Qt::Key_0 );
560 defKeySym("1", Qt::Key_1 );
561 defKeySym("2", Qt::Key_2 );
562 defKeySym("3", Qt::Key_3 );
563 defKeySym("4", Qt::Key_4 );
564 defKeySym("5", Qt::Key_5 );
565 defKeySym("6", Qt::Key_6 );
566 defKeySym("7", Qt::Key_7 );
567 defKeySym("8", Qt::Key_8 );
568 defKeySym("9", Qt::Key_9 );
569 defKeySym("Colon", Qt::Key_Colon );
570 defKeySym("Semicolon", Qt::Key_Semicolon );
571 defKeySym("Less", Qt::Key_Less );
572 defKeySym("Equal", Qt::Key_Equal );
573 defKeySym("Greater", Qt::Key_Greater );
574 defKeySym("Question", Qt::Key_Question );
575 defKeySym("At", Qt::Key_At );
576 defKeySym("A", Qt::Key_A );
577 defKeySym("B", Qt::Key_B );
578 defKeySym("C", Qt::Key_C );
579 defKeySym("D", Qt::Key_D );
580 defKeySym("E", Qt::Key_E );
581 defKeySym("F", Qt::Key_F );
582 defKeySym("G", Qt::Key_G );
583 defKeySym("H", Qt::Key_H );
584 defKeySym("I", Qt::Key_I );
585 defKeySym("J", Qt::Key_J );
586 defKeySym("K", Qt::Key_K );
587 defKeySym("L", Qt::Key_L );
588 defKeySym("M", Qt::Key_M );
589 defKeySym("N", Qt::Key_N );
590 defKeySym("O", Qt::Key_O );
591 defKeySym("P", Qt::Key_P );
592 defKeySym("Q", Qt::Key_Q );
593 defKeySym("R", Qt::Key_R );
594 defKeySym("S", Qt::Key_S );
595 defKeySym("T", Qt::Key_T );
596 defKeySym("U", Qt::Key_U );
597 defKeySym("V", Qt::Key_V );
598 defKeySym("W", Qt::Key_W );
599 defKeySym("X", Qt::Key_X );
600 defKeySym("Y", Qt::Key_Y );
601 defKeySym("Z", Qt::Key_Z );
602 defKeySym("BracketLeft", Qt::Key_BracketLeft );
603 defKeySym("Backslash", Qt::Key_Backslash );
604 defKeySym("BracketRight", Qt::Key_BracketRight);
605 defKeySym("AsciiCircum", Qt::Key_AsciiCircum );
606 defKeySym("Underscore", Qt::Key_Underscore );
607 defKeySym("QuoteLeft", Qt::Key_QuoteLeft );
608 defKeySym("BraceLeft", Qt::Key_BraceLeft );
609 defKeySym("Bar", Qt::Key_Bar );
610 defKeySym("BraceRight", Qt::Key_BraceRight );
611 defKeySym("AsciiTilde", Qt::Key_AsciiTilde );
612}
613
614KeyTransSymbols::KeyTransSymbols()
615{
616 defModSyms();
617 defOprSyms();
618 defKeySyms();
619}
620
621// Global material -----------------------------------------------------------
622
623static int keytab_serial = 0; //FIXME: remove,localize
624
625static QIntDict<KeyTrans> * numb2keymap = 0L;
626static QDict<KeyTrans> * path2keymap = 0L;
627
628KeyTrans* KeyTrans::find(int numb)
629{
630 KeyTrans* res = numb2keymap->find(numb);
631 return res ? res : numb2keymap->find(0);
632}
633
634KeyTrans* KeyTrans::find(const char* path)
635{
636 KeyTrans* res = path2keymap->find(path);
637 return res ? res : numb2keymap->find(0);
638}
639
640int KeyTrans::count()
641{
642 return numb2keymap->count();
643}
644
645void KeyTrans::addKeyTrans()
646{
647 this->numb = keytab_serial ++;
648 numb2keymap->insert(numb,this);
649 path2keymap->insert(path,this);
650}
651
652void KeyTrans::loadAll()
653{
654 if (!numb2keymap)
655 numb2keymap = new QIntDict<KeyTrans>;
656 if (!path2keymap)
657 path2keymap = new QDict<KeyTrans>;
658 if (!syms)
659 syms = new KeyTransSymbols;
660
661 defaultKeyTrans()->addKeyTrans();
662
663
664 QString path = QPEApplication::qpeDir() + "etc/keytabs";
665 QDir dir(path);
666 QStringList lst = dir.entryList("*.keytab");
667
668 for(QStringList::Iterator it = lst.begin(); it != lst.end(); ++it ) {
669 QFile file(path + "/" + *it);
670 KeyTrans* sc = KeyTrans::fromDevice(*it, file);
671 if (sc) {
672 sc->addKeyTrans();
673 }
674 }
675
676}
677
678// Debugging material -----------------------------------------------------------
679/*
680void TestTokenizer(QBuffer &buf)
681{
682 // opening sequence
683
684 buf.open(IO_ReadOnly);
685 cc = buf.getch();
686 lineno = 1;
687
688 // Test tokenizer
689
690 while (getSymbol(buf)) ReportToken();
691
692 buf.close();
693}
694
695void test()
696{
697 // Opening sequence
698
699 QCString txt =
700#include "default.keytab.h"
701 ;
702 QBuffer buf(txt);
703 if (0) TestTokenizer(buf);
704 if (1) { KeyTrans kt; kt.scanTable(buf); }
705}
706*/
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 @@
1/* -------------------------------------------------------------------------- */
2/* */
3/* [keytrans.h] X Terminal Emulation */
4/* */
5/* -------------------------------------------------------------------------- */
6/* */
7/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */
8/* */
9/* This file is part of Konsole - an X terminal for KDE */
10/* */
11/* -------------------------------------------------------------------------- */
12 /* */
13/* Ported Konsole to Qt/Embedded */
14 /* */
15/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */
16 /* */
17/* -------------------------------------------------------------------------- */
18
19#ifndef KEYTRANS_H
20#define KEYTRANS_H
21
22#include <qstring.h>
23#include <qlist.h>
24#include <qiodevice.h>
25
26#define BITS_NewLine 0
27#define BITS_BsHack 1
28#define BITS_Ansi 2
29#define BITS_AppCuKeys 3
30#define BITS_Control 4
31#define BITS_Shift 5
32#define BITS_Alt 6
33#define BITS_COUNT 7
34
35#define CMD_send 0
36#define CMD_emitSelection 1
37#define CMD_scrollPageUp 2
38#define CMD_scrollPageDown 3
39#define CMD_scrollLineUp 4
40#define CMD_scrollLineDown 5
41#define CMD_prevSession 6
42#define CMD_nextSession 7
43
44#define BITS(x,v) ((((v)!=0)<<(x)))
45
46
47class KeyTrans
48{
49public:
50 KeyTrans();
51 ~KeyTrans();
52 static KeyTrans* defaultKeyTrans();
53 static KeyTrans* fromFile(const char* path);
54 static KeyTrans* find(int numb);
55 static KeyTrans* find(const char* path);
56public:
57 static int count();
58 static void loadAll();
59public:
60 bool findEntry(int key, int bits, int* cmd, const char** txt, int* len);
61private:
62 void addKeyTrans();
63 static KeyTrans* fromDevice(QString path, QIODevice &buf);
64public:
65 class KeyEntry
66 {
67 public:
68 KeyEntry(int ref, int key, int bits, int mask, int cmd, QString txt);
69 ~KeyEntry();
70 public:
71 bool matches(int key, int bits, int mask);
72 QString text();
73 public:
74 int ref;
75 private:
76 int key;
77 int bits;
78 int mask;
79 public:
80 int cmd;
81 QString txt;
82 };
83public:
84 KeyEntry* addEntry(int ref, int key, int bits, int mask, int cmd, QString txt);
85private:
86 QList<KeyEntry> table;
87public: //FIXME: we'd do better
88 QString hdr;
89 int numb;
90 QString path;
91};
92
93#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 @@
1/* ---------------------------------------------------------------------- */
2/* */
3/* [main.C] Konsole */
4/* */
5/* ---------------------------------------------------------------------- */
6/* */
7/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */
8/* */
9/* This file is part of Konsole, an X terminal. */
10/* */
11/* The material contained in here more or less directly orginates from */
12/* kvt, which is copyright (c) 1996 by Matthias Ettrich <ettrich@kde.org> */
13/* */
14/* ---------------------------------------------------------------------- */
15 /* */
16/* Ported Konsole to Qt/Embedded */
17 /* */
18/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */
19 /* */
20/* -------------------------------------------------------------------------- */
21
22#include <qpe/resource.h>
23
24#include <qdir.h>
25#include <qevent.h>
26#include <qdragobject.h>
27#include <qobjectlist.h>
28#include <qtoolbutton.h>
29#include <qpe/qpetoolbar.h>
30#include <qpushbutton.h>
31#include <qfontdialog.h>
32#include <qglobal.h>
33#include <qpainter.h>
34#include <qpe/qpemenubar.h>
35#include <qmessagebox.h>
36#include <qaction.h>
37#include <qapplication.h>
38#include <qfontmetrics.h>
39#include <qcombobox.h>
40#include <qevent.h>
41#include <qtabwidget.h>
42#include <qtabbar.h>
43#include <qpe/config.h>
44
45#include <sys/wait.h>
46#include <stdio.h>
47#include <stdlib.h>
48#include <assert.h>
49
50#include "konsole.h"
51#include "keytrans.h"
52
53class EKNumTabBar : public QTabBar {
54public:
55 void numberTabs()
56 {
57 // Yes, it really is this messy. QTabWidget needs functions
58 // that provide acces to tabs in a sequential way.
59 int m=INT_MIN;
60 for (int i=0; i<count(); i++) {
61 QTab* left=0;
62 QListIterator<QTab> it(*tabList());
63 int x=INT_MAX;
64 for( QTab* t; (t=it.current()); ++it ) {
65 int tx = t->rect().x();
66 if ( tx<x && tx>m ) {
67 x = tx;
68 left = t;
69 }
70 }
71 if ( left ) {
72 left->setText(QString::number(i+1));
73 m = left->rect().x();
74 }
75 }
76 }
77};
78
79class EKNumTabWidget : public QTabWidget {
80public:
81 EKNumTabWidget(QWidget* parent) : QTabWidget(parent)
82 {
83 }
84
85 void addTab(QWidget* w)
86 {
87 QTab* t = new QTab(QString::number(tabBar()->count()+1));
88 QTabWidget::addTab(w,t);
89 }
90
91 void removeTab(QWidget* w)
92 {
93 removePage(w);
94 ((EKNumTabBar*)tabBar())->numberTabs();
95 }
96};
97
98// This could be configurable or dynamicly generated from the bash history
99// file of the user
100static const char *commonCmds[] =
101{
102 "ls ",
103 //"ls -la ",
104 "cd ",
105 "pwd",
106 //"cat",
107 //"less ",
108 //"vi ",
109 //"man ",
110 "echo ",
111 "set ",
112 //"ps",
113 "ps aux",
114 //"tar",
115 //"tar -zxf",
116 "grep ",
117 //"grep -i",
118 //"mkdir",
119 "cp ",
120 "mv ",
121 "rm ",
122 "rmdir ",
123 //"chmod",
124 //"su",
125// "top",
126 //"find",
127 //"make",
128 //"tail",
129 "cardctl eject",
130 "ifconfig ",
131// "iwconfig eth0 ",
132 "nc localhost 7777",
133 "nc localhost 7776",
134 //"mount /dev/hda1",
135
136/*
137 "gzip",
138 "gunzip",
139 "chgrp",
140 "chown",
141 "date",
142 "dd",
143 "df",
144 "dmesg",
145 "fuser",
146 "hostname",
147 "kill",
148 "killall",
149 "ln",
150 "ping",
151 "mount",
152 "more",
153 "sort",
154 "touch",
155 "umount",
156 "mknod",
157 "netstat",
158*/
159
160 "exit",
161 NULL
162};
163
164
165Konsole::Konsole(QWidget* parent, const char* name, WFlags fl) :
166 QMainWindow(parent, name, fl)
167{
168 QStrList args;
169 init("/bin/sh",args);
170}
171
172Konsole::Konsole(const char* name, const char* _pgm, QStrList & _args, int)
173 : QMainWindow(0, name)
174{
175 init(_pgm,_args);
176}
177
178void Konsole::init(const char* _pgm, QStrList & _args)
179{
180 b_scroll = TRUE; // histon;
181 n_keytab = 0;
182 n_render = 0;
183
184 setCaption( tr("Terminal") );
185 setIcon( Resource::loadPixmap( "konsole" ) );
186
187 Config cfg("Konsole");
188 cfg.setGroup("Konsole");
189
190 // initialize the list of allowed fonts ///////////////////////////////////
191 cfont = cfg.readNumEntry("FontID", 1);
192 QFont f = QFont("Micro", 4, QFont::Normal);
193 f.setFixedPitch(TRUE);
194 fonts.append(new VTFont(tr("Micro"), f));
195
196 f = QFont("Fixed", 7, QFont::Normal);
197 f.setFixedPitch(TRUE);
198 fonts.append(new VTFont(tr("Small Fixed"), f));
199
200 f = QFont("Fixed", 12, QFont::Normal);
201 f.setFixedPitch(TRUE);
202 fonts.append(new VTFont(tr("Medium Fixed"), f));
203
204 // create terminal emulation framework ////////////////////////////////////
205 nsessions = 0;
206 tab = new EKNumTabWidget(this);
207 tab->setTabPosition(QTabWidget::Bottom);
208 connect(tab, SIGNAL(currentChanged(QWidget*)), this, SLOT(switchSession(QWidget*)));
209
210 // create terminal toolbar ////////////////////////////////////////////////
211 setToolBarsMovable( FALSE );
212 QPEToolBar *menuToolBar = new QPEToolBar( this );
213 menuToolBar->setHorizontalStretchable( TRUE );
214
215 QPEMenuBar *menuBar = new QPEMenuBar( menuToolBar );
216
217 fontList = new QPopupMenu( this );
218 for(uint i = 0; i < fonts.count(); i++) {
219 VTFont *fnt = fonts.at(i);
220 fontList->insertItem(fnt->getName(), i);
221 }
222 fontChanged(cfont);
223
224 connect( fontList, SIGNAL( activated(int) ), this, SLOT( fontChanged(int) ));
225
226 menuBar->insertItem( tr("Font"), fontList );
227
228 QPEToolBar *toolbar = new QPEToolBar( this );
229
230 QAction *a;
231
232 // Button Commands
233 a = new QAction( tr("New"), Resource::loadPixmap( "konsole" ), QString::null, 0, this, 0 );
234 connect( a, SIGNAL( activated() ), this, SLOT( newSession() ) ); a->addTo( toolbar );
235 a = new QAction( tr("Enter"), Resource::loadPixmap( "konsole/enter" ), QString::null, 0, this, 0 );
236 connect( a, SIGNAL( activated() ), this, SLOT( hitEnter() ) ); a->addTo( toolbar );
237 a = new QAction( tr("Space"), Resource::loadPixmap( "konsole/space" ), QString::null, 0, this, 0 );
238 connect( a, SIGNAL( activated() ), this, SLOT( hitSpace() ) ); a->addTo( toolbar );
239 a = new QAction( tr("Tab"), Resource::loadPixmap( "konsole/tab" ), QString::null, 0, this, 0 );
240 connect( a, SIGNAL( activated() ), this, SLOT( hitTab() ) ); a->addTo( toolbar );
241 a = new QAction( tr("Up"), Resource::loadPixmap( "konsole/up" ), QString::null, 0, this, 0 );
242 connect( a, SIGNAL( activated() ), this, SLOT( hitUp() ) ); a->addTo( toolbar );
243 a = new QAction( tr("Down"), Resource::loadPixmap( "konsole/down" ), QString::null, 0, this, 0 );
244 connect( a, SIGNAL( activated() ), this, SLOT( hitDown() ) ); a->addTo( toolbar );
245 a = new QAction( tr("Paste"), Resource::loadPixmap( "paste" ), QString::null, 0, this, 0 );
246 connect( a, SIGNAL( activated() ), this, SLOT( hitPaste() ) ); a->addTo( toolbar );
247/*
248 a = new QAction( tr("Up"), Resource::loadPixmap( "up" ), QString::null, 0, this, 0 );
249 connect( a, SIGNAL( activated() ), this, SLOT( hitUp() ) ); a->addTo( toolbar );
250 a = new QAction( tr("Down"), Resource::loadPixmap( "down" ), QString::null, 0, this, 0 );
251 connect( a, SIGNAL( activated() ), this, SLOT( hitDown() ) ); a->addTo( toolbar );
252*/
253
254 QPEToolBar *secondToolBar = new QPEToolBar( this );
255 secondToolBar->setHorizontalStretchable( TRUE );
256
257 QComboBox *commonCombo = new QComboBox( secondToolBar );
258// commonCombo->setEditable( TRUE );
259 for (int i = 0; commonCmds[i] != NULL; i++)
260 commonCombo->insertItem( commonCmds[i], i );
261 connect( commonCombo, SIGNAL( activated(int) ), this, SLOT( enterCommand(int) ));
262
263 // create applications /////////////////////////////////////////////////////
264 setCentralWidget(tab);
265
266 // load keymaps ////////////////////////////////////////////////////////////
267 KeyTrans::loadAll();
268 for (int i = 0; i < KeyTrans::count(); i++)
269 { KeyTrans* s = KeyTrans::find(i);
270 assert( s );
271 }
272
273 se_pgm = _pgm;
274 se_args = _args;
275
276 // read and apply default values ///////////////////////////////////////////
277 resize(321, 321); // Dummy.
278 QSize currentSize = size();
279 if (currentSize != size())
280 defaultSize = size();
281}
282
283void Konsole::show()
284{
285 if ( !nsessions ) {
286 newSession();
287 }
288 QMainWindow::show();
289}
290
291void Konsole::initSession(const char*, QStrList &)
292{
293 QMainWindow::show();
294}
295
296Konsole::~Konsole()
297{
298 while (nsessions > 0) {
299 doneSession(getTe()->currentSession, 0);
300 }
301
302 Config cfg("Konsole");
303 cfg.setGroup("Konsole");
304 cfg.writeEntry("FontID", cfont);
305}
306
307void Konsole::fontChanged(int f)
308{
309 VTFont* font = fonts.at(f);
310 if (font != 0) {
311 for(uint i = 0; i < fonts.count(); i++) {
312 fontList->setItemChecked(i, (i == (uint) f) ? TRUE : FALSE);
313 }
314
315 cfont = f;
316
317 TEWidget* te = getTe();
318 if (te != 0) {
319 te->setVTFont(font->getFont());
320 }
321 }
322}
323
324void Konsole::enterCommand(int c)
325{
326 TEWidget* te = getTe();
327 if (te != 0) {
328 QString text = commonCmds[c];
329 te->emitText(text);
330 }
331}
332
333void Konsole::hitEnter()
334{
335 TEWidget* te = getTe();
336 if (te != 0) {
337 te->emitText(QString("\r"));
338 }
339}
340
341void Konsole::hitSpace()
342{
343 TEWidget* te = getTe();
344 if (te != 0) {
345 te->emitText(QString(" "));
346 }
347}
348
349void Konsole::hitTab()
350{
351 TEWidget* te = getTe();
352 if (te != 0) {
353 te->emitText(QString("\t"));
354 }
355}
356
357void Konsole::hitPaste()
358{
359 TEWidget* te = getTe();
360 if (te != 0) {
361 te->pasteClipboard();
362 }
363}
364
365void Konsole::hitUp()
366{
367 TEWidget* te = getTe();
368 if (te != 0) {
369 QKeyEvent ke( QKeyEvent::KeyPress, Qt::Key_Up, 0, 0);
370 QApplication::sendEvent( te, &ke );
371 }
372}
373
374void Konsole::hitDown()
375{
376 TEWidget* te = getTe();
377 if (te != 0) {
378 QKeyEvent ke( QKeyEvent::KeyPress, Qt::Key_Down, 0, 0);
379 QApplication::sendEvent( te, &ke );
380 }
381}
382
383/**
384 This function calculates the size of the external widget
385 needed for the internal widget to be
386 */
387QSize Konsole::calcSize(int columns, int lines) {
388 TEWidget* te = getTe();
389 if (te != 0) {
390 QSize size = te->calcSize(columns, lines);
391 return size;
392 } else {
393 QSize size;
394 return size;
395 }
396}
397
398/**
399 sets application window to a size based on columns X lines of the te
400 guest widget. Call with (0,0) for setting default size.
401*/
402
403void Konsole::setColLin(int columns, int lines)
404{
405 if ((columns==0) || (lines==0))
406 {
407 if (defaultSize.isEmpty()) // not in config file : set default value
408 {
409 defaultSize = calcSize(80,24);
410 // notifySize(24,80); // set menu items (strange arg order !)
411 }
412 resize(defaultSize);
413 } else {
414 resize(calcSize(columns, lines));
415 // notifySize(lines,columns); // set menu items (strange arg order !)
416 }
417}
418
419/*
420void Konsole::setFont(int fontno)
421{
422 QFont f;
423 if (fontno == 0)
424 f = defaultFont = QFont( "Helvetica", 12 );
425 else
426 if (fonts[fontno][0] == '-')
427 f.setRawName( fonts[fontno] );
428 else
429 {
430 f.setFamily(fonts[fontno]);
431 f.setRawMode( TRUE );
432 }
433 if ( !f.exactMatch() && fontno != 0)
434 {
435 QString msg = i18n("Font `%1' not found.\nCheck README.linux.console for help.").arg(fonts[fontno]);
436 QMessageBox(this, msg);
437 return;
438 }
439 if (se) se->setFontNo(fontno);
440 te->setVTFont(f);
441 n_font = fontno;
442}
443*/
444
445// --| color selection |-------------------------------------------------------
446
447void Konsole::changeColumns(int columns)
448{
449 TEWidget* te = getTe();
450 if (te != 0) {
451 setColLin(columns,te->Lines());
452 te->update();
453 }
454}
455
456//FIXME: If a child dies during session swap,
457// this routine might be called before
458// session swap is completed.
459
460void Konsole::doneSession(TESession*, int )
461{
462 TEWidget *te = getTe();
463 if (te != 0) {
464 te->currentSession->setConnect(FALSE);
465 tab->removeTab(te);
466 delete te->currentSession;
467 delete te;
468 nsessions--;
469 }
470
471 if (nsessions == 0) {
472 close();
473 }
474}
475
476
477void Konsole::newSession() {
478 TEWidget* te = new TEWidget(tab);
479 te->setBackgroundMode(PaletteBase);
480 te->setVTFont(fonts.at(cfont)->getFont());
481 tab->addTab(te);
482 TESession* se = new TESession(this, te, se_pgm, se_args, "xterm");
483 te->currentSession = se;
484 connect( se, SIGNAL(done(TESession*,int)), this, SLOT(doneSession(TESession*,int)) );
485 se->run();
486 se->setConnect(TRUE);
487 se->setHistory(b_scroll);
488 tab->setCurrentPage(nsessions);
489 nsessions++;
490}
491
492TEWidget* Konsole::getTe() {
493 if (nsessions) {
494 return (TEWidget *) tab->currentPage();
495 } else {
496 return 0;
497 }
498 }
499
500void Konsole::switchSession(QWidget* w) {
501 TEWidget* te = (TEWidget *) w;
502
503 QFont teFnt = te->getVTFont();
504 for(uint i = 0; i < fonts.count(); i++) {
505 VTFont *fnt = fonts.at(i);
506 bool cf = fnt->getFont() == teFnt;
507 fontList->setItemChecked(i, cf);
508 if (cf) {
509 cfont = i;
510 }
511 }
512}
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 @@
1/* ----------------------------------------------------------------------- */
2/* */
3/* [konsole.h] Konsole */
4/* */
5/* -------------------------------------------------------------------------- */
6/* */
7/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */
8/* */
9/* This file is part of Konsole, an X terminal. */
10/* */
11/* The material contained in here more or less directly orginates from */
12/* kvt, which is copyright (c) 1996 by Matthias Ettrich <ettrich@kde.org> */
13/* */
14/* -------------------------------------------------------------------------- */
15 /* */
16/* Ported Konsole to Qt/Embedded */
17 /* */
18/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */
19 /* */
20/* -------------------------------------------------------------------------- */
21
22#ifndef KONSOLE_H
23#define KONSOLE_H
24
25
26#include <qmainwindow.h>
27#include <qaction.h>
28#include <qpopupmenu.h>
29#include <qstrlist.h>
30#include <qintdict.h>
31#include <qptrdict.h>
32#include <qtabwidget.h>
33
34#include "MyPty.h"
35#include "TEWidget.h"
36#include "TEmuVt102.h"
37#include "session.h"
38
39class EKNumTabWidget;
40
41class Konsole : public QMainWindow
42{
43Q_OBJECT
44
45public:
46
47 Konsole(QWidget* parent = 0, const char* name = 0, WFlags fl = 0);
48 Konsole(const char * name, const char* pgm, QStrList & _args, int histon);
49 ~Konsole();
50 void setColLin(int columns, int lines);
51
52 void show();
53
54private slots:
55 void doneSession(TESession*,int);
56 void changeColumns(int);
57 void fontChanged(int);
58 void enterCommand(int);
59 void hitEnter();
60 void hitSpace();
61 void hitTab();
62 void hitPaste();
63 void hitUp();
64 void hitDown();
65 void switchSession(QWidget *);
66 void newSession();
67
68private:
69 void init(const char* _pgm, QStrList & _args);
70 void initSession(const char* _pgm, QStrList & _args);
71 void runSession(TESession* s);
72 void setColorPixmaps();
73 void setHistory(bool);
74 QSize calcSize(int columns, int lines);
75 TEWidget* getTe();
76
77private:
78 class VTFont
79 {
80 public:
81 VTFont(QString name, QFont& font)
82 {
83 this->name = name;
84 this->font = font;
85 }
86
87 QFont& getFont()
88 {
89 return font;
90 }
91
92 QString getName()
93 {
94 return name;
95 }
96
97 private:
98 QString name;
99 QFont font;
100 };
101
102 EKNumTabWidget* tab;
103 int nsessions;
104 QList<VTFont> fonts;
105 int cfont;
106 QCString se_pgm;
107 QStrList se_args;
108
109 QPopupMenu* fontList;
110
111 // history scrolling I think
112 bool b_scroll;
113
114 int n_keytab;
115 int n_scroll;
116 int n_render;
117 QString pmPath; // pixmap path
118 QString dropText;
119 QFont defaultFont;
120 QSize defaultSize;
121
122};
123
124#endif
125
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 @@
1/* ---------------------------------------------------------------------- */
2/* */
3/* [main.C] Konsole */
4/* */
5/* ---------------------------------------------------------------------- */
6/* */
7/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */
8/* */
9/* This file is part of Konsole, an X terminal. */
10/* */
11/* The material contained in here more or less directly orginates from */
12/* kvt, which is copyright (c) 1996 by Matthias Ettrich <ettrich@kde.org> */
13/* */
14/* ---------------------------------------------------------------------- */
15 /* */
16/* Ported Konsole to Qt/Embedded */
17 /* */
18/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */
19 /* */
20/* -------------------------------------------------------------------------- */
21
22#include "konsole.h"
23
24#include <qpe/qpeapplication.h>
25
26#include <qfile.h>
27
28#include <unistd.h>
29#include <stdio.h>
30#include <stdlib.h>
31
32
33/* --| main |------------------------------------------------------ */
34int main(int argc, char* argv[])
35{
36 setuid(getuid()); setgid(getgid()); // drop privileges
37
38 QPEApplication a( argc, argv );
39
40#ifdef FAKE_CTRL_AND_ALT
41 QPEApplication::grabKeyboard(); // for CTRL and ALT
42#endif
43
44 QStrList tmp;
45 const char* shell = getenv("SHELL");
46 if (shell == NULL || *shell == '\0')
47 shell = "/bin/sh";
48
49 // sh is completely broken on familiar. Let's try to get something better
50 if ( qstrcmp( shell, "/bin/shell" ) == 0 && QFile::exists( "/bin/bash" ) )
51 shell = "/bin/bash";
52
53 putenv((char*)"COLORTERM="); // to trigger mc's color detection
54
55 Konsole m( "test", shell, tmp, TRUE );
56 m.setCaption( Konsole::tr("Terminal") );
57 a.showMainWidget( &m );
58
59 return a.exec();
60}
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 @@
1Files: bin/embeddedkonsole apps/Applications/embeddedkonsole.desktop pics/konsole etc/keytabs/*
2Priority: optional
3Section: qpe/applications
4Maintainer: Warwick Allison <warwick@trolltech.com>
5Architecture: arm
6Version: $QPE_VERSION-4
7Depends: qpe-base ($QPE_VERSION), ptydevs
8Description: KDE's konsole (shell terminal)
9 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 @@
1/* -------------------------------------------------------------------------- */
2 /* */
3/* Ported Konsole to Qt/Embedded */
4 /* */
5/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */
6 /* */
7/* -------------------------------------------------------------------------- */
8#include "session.h"
9#include <qpushbutton.h>
10// #include <kdebug.h>
11
12#include <stdlib.h>
13
14#define HERE fprintf(stderr,"%s(%d): here\n",__FILE__,__LINE__)
15
16/*! \class TESession
17
18 Sessions are combinations of TEPTy and Emulations.
19
20 The stuff in here does not belong to the terminal emulation framework,
21 but to main.C. It serves it's duty by providing a single reference
22 to TEPTy/Emulation pairs. In fact, it is only there to demonstrate one
23 of the abilities of the framework - multible sessions.
24*/
25
26TESession::TESession(QMainWindow* main, TEWidget* te, const char* _pgm, QStrList & _args, const char *_term) : schema_no(0), font_no(3), pgm(_pgm), args(_args)
27{
28 // sh = new TEPty();
29 sh = new MyPty();
30 em = new TEmuVt102(te);
31
32 term = _term;
33
34 sh->setSize(te->Lines(),te->Columns()); // not absolutely nessesary
35 QObject::connect( sh,SIGNAL(block_in(const char*,int)),
36 em,SLOT(onRcvBlock(const char*,int)) );
37 QObject::connect( em,SIGNAL(ImageSizeChanged(int,int)),
38 sh,SLOT(setSize(int,int)));
39
40 // 'main' should do those connects itself, somehow.
41 // These aren't KTMW's slots, but konsole's.(David)
42
43/*
44 QObject::connect( em,SIGNAL(ImageSizeChanged(int,int)),
45 main,SLOT(notifySize(int,int)));
46*/
47 QObject::connect( em,SIGNAL(sndBlock(const char*,int)),
48 sh,SLOT(send_bytes(const char*,int)) );
49 QObject::connect( em,SIGNAL(changeColumns(int)),
50 main,SLOT(changeColumns(int)) );
51/*
52 QObject::connect( em,SIGNAL(changeTitle(int, const QString&)),
53 main,SLOT(changeTitle(int, const QString&)) );
54*/
55 QObject::connect( sh,SIGNAL(done(int)), this,SLOT(done(int)) );
56}
57
58
59
60void TESession::run()
61{
62 //kdDebug() << "Running the session!" << pgm << "\n";
63 sh->run(pgm,args,term.data(),FALSE);
64}
65
66void TESession::kill(int ) // signal)
67{
68// sh->kill(signal);
69}
70
71TESession::~TESession()
72{
73 QObject::disconnect( sh, SIGNAL( done( int ) ),
74 this, SLOT( done( int ) ) );
75 delete em;
76 delete sh;
77}
78
79void TESession::setConnect(bool c)
80{
81 em->setConnect(c);
82}
83
84void TESession::done(int status)
85{
86 emit done(this,status);
87}
88
89void TESession::terminate()
90{
91 delete this;
92}
93
94TEmulation* TESession::getEmulation()
95{
96 return em;
97}
98
99// following interfaces might be misplaced ///
100
101int TESession::schemaNo()
102{
103 return schema_no;
104}
105
106int TESession::keymap()
107{
108 return keymap_no;
109}
110
111int TESession::fontNo()
112{
113 return font_no;
114}
115
116const char* TESession::emuName()
117{
118 return term.data();
119}
120
121void TESession::setSchemaNo(int sn)
122{
123 schema_no = sn;
124}
125
126void TESession::setKeymapNo(int kn)
127{
128 keymap_no = kn;
129 em->setKeytrans(kn);
130}
131
132void TESession::setFontNo(int fn)
133{
134 font_no = fn;
135}
136
137void TESession::setTitle(const QString& title)
138{
139 this->title = title;
140}
141
142const QString& TESession::Title()
143{
144 return title;
145}
146
147void TESession::setHistory(bool on)
148{
149 em->setHistory( on );
150}
151
152bool TESession::history()
153{
154 return em->history();
155}
156
157// #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 @@
1/* -------------------------------------------------------------------------- */
2/* */
3/* [session.h] Testbed for TE framework */
4/* */
5/* -------------------------------------------------------------------------- */
6/* */
7/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */
8/* */
9/* This file is part of Konsole, an X terminal. */
10/* */
11/* -------------------------------------------------------------------------- */
12 /* */
13/* Ported Konsole to Qt/Embedded */
14 /* */
15/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */
16 /* */
17/* -------------------------------------------------------------------------- */
18
19#ifndef SESSION_H
20#define SESSION_H
21
22#include <qapplication.h>
23#include <qmainwindow.h>
24#include <qstrlist.h>
25
26#include "MyPty.h"
27#include "TEWidget.h"
28#include "TEmuVt102.h"
29
30class TESession : public QObject
31{ Q_OBJECT
32
33public:
34
35 TESession(QMainWindow* main, TEWidget* w,
36 const char* pgm, QStrList & _args,
37 const char* term);
38 ~TESession();
39
40public:
41
42 void setConnect(bool r);
43 TEmulation* getEmulation(); // to control emulation
44 bool isSecure();
45
46public:
47
48 int schemaNo();
49 int fontNo();
50 const char* emuName();
51 const QString& Title();
52 bool history();
53 int keymap();
54
55 void setHistory(bool on);
56 void setSchemaNo(int sn);
57 void setKeymapNo(int kn);
58 void setFontNo(int fn);
59 void setTitle(const QString& title);
60 void kill(int signal);
61
62public slots:
63
64 void run();
65 void done(int status);
66 void terminate();
67
68signals:
69
70 void done(TESession*, int);
71
72private:
73
74 // TEPty* sh;
75 MyPty* sh;
76 TEWidget* te;
77 TEmulation* em;
78
79 //FIXME: using the indices here
80 // is propably very bad. We should
81 // use a persistent reference instead.
82 int schema_no;
83 int font_no;
84 int keymap_no;
85 QString title;
86
87 const char* pgm;
88 QStrList args;
89
90 QCString term;
91};
92
93#endif
diff --git a/core/apps/helpbrowser/.cvsignore b/core/apps/helpbrowser/.cvsignore
new file mode 100644
index 0000000..6fe2396
--- a/dev/null
+++ b/core/apps/helpbrowser/.cvsignore
@@ -0,0 +1,2 @@
1moc_*
2Makefile
diff --git a/core/apps/helpbrowser/Makefile.in b/core/apps/helpbrowser/Makefile.in
new file mode 100644
index 0000000..8f0ce0e
--- a/dev/null
+++ b/core/apps/helpbrowser/Makefile.in
@@ -0,0 +1,119 @@
1#############################################################################
2
3####### Compiler, tools and options
4
5 CXX =$(SYSCONF_CXX) $(QT_CXX_MT)
6 CXXFLAGS=$(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS)
7 CC =$(SYSCONF_CC) $(QT_C_MT)
8 CFLAGS =$(SYSCONF_CFLAGS)
9 INCPATH =-I$(QPEDIR)/include
10 LFLAGS =$(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT)
11 LIBS =$(SUBLIBS) -lqpe $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS) $(SYSCONF_LIBS_QTAPP)
12 MOC =$(SYSCONF_MOC)
13 UIC =$(SYSCONF_UIC)
14
15####### Target
16
17DESTDIR = $(QPEDIR)/bin/
18VER_MAJ = 1
19VER_MIN = 0
20VER_PATCH = 0
21 TARGET= helpbrowser
22TARGET1 = lib$(TARGET).so.$(VER_MAJ)
23
24####### Files
25
26 HEADERS =helpbrowser.h
27 SOURCES =helpbrowser.cpp \
28 main.cpp
29 OBJECTS =helpbrowser.o \
30 main.o
31INTERFACES =
32UICDECLS =
33UICIMPLS =
34 SRCMOC =moc_helpbrowser.cpp
35 OBJMOC =moc_helpbrowser.o
36
37
38####### Implicit rules
39
40.SUFFIXES: .cpp .cxx .cc .C .c
41
42.cpp.o:
43 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
44
45.cxx.o:
46 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
47
48.cc.o:
49 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
50
51.C.o:
52 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
53
54.c.o:
55 $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
56
57####### Build rules
58
59
60all: $(DESTDIR)$(TARGET)
61
62$(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
63 $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)
64
65moc: $(SRCMOC)
66
67tmake:
68 tmake helpbrowser.pro
69
70clean:
71 -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
72 -rm -f *~ core
73 -rm -f allmoc.cpp
74
75####### Extension Modules
76
77listpromodules:
78 @echo
79
80listallmodules:
81 @echo
82
83listaddonpromodules:
84 @echo
85
86listaddonentmodules:
87 @echo
88
89
90REQUIRES=
91
92####### Sub-libraries
93
94
95###### Combined headers
96
97
98
99####### Compile
100
101helpbrowser.o: helpbrowser.cpp \
102 helpbrowser.h \
103 $(QPEDIR)/include/qpe/qpeapplication.h \
104 $(QPEDIR)/include/qpe/resource.h \
105 $(QPEDIR)/include/qpe/global.h \
106 $(QPEDIR)/include/qpe/qpemenubar.h \
107 $(QPEDIR)/include/qpe/qpetoolbar.h
108
109main.o: main.cpp \
110 helpbrowser.h \
111 $(QPEDIR)/include/qpe/qpeapplication.h
112
113moc_helpbrowser.o: moc_helpbrowser.cpp \
114 helpbrowser.h
115
116moc_helpbrowser.cpp: helpbrowser.h
117 $(MOC) helpbrowser.h -o moc_helpbrowser.cpp
118
119
diff --git a/core/apps/helpbrowser/helpbrowser.cpp b/core/apps/helpbrowser/helpbrowser.cpp
new file mode 100644
index 0000000..d32fc0b
--- a/dev/null
+++ b/core/apps/helpbrowser/helpbrowser.cpp
@@ -0,0 +1,227 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#include "helpbrowser.h"
22
23#include <qpe/qpeapplication.h>
24#include <qpe/resource.h>
25#include <qpe/global.h>
26
27#include <qstatusbar.h>
28#include <qdragobject.h>
29#include <qpixmap.h>
30#include <qpopupmenu.h>
31#include <qpe/qpemenubar.h>
32#include <qpe/qpetoolbar.h>
33#include <qtoolbutton.h>
34#include <qiconset.h>
35#include <qfile.h>
36#include <qtextstream.h>
37#include <qstylesheet.h>
38#include <qmessagebox.h>
39#include <qfiledialog.h>
40#include <qevent.h>
41#include <qlineedit.h>
42#include <qobjectlist.h>
43#include <qfileinfo.h>
44#include <qfile.h>
45#include <qdatastream.h>
46#include <qprinter.h>
47#include <qsimplerichtext.h>
48#include <qpaintdevicemetrics.h>
49#include <qaction.h>
50
51#include <ctype.h>
52
53
54HelpBrowser::HelpBrowser( QWidget* parent, const char *name, WFlags f )
55 : QMainWindow( parent, name, f ),
56 selectedURL()
57{
58 init( "index.html" );
59}
60
61void HelpBrowser::init( const QString& _home )
62{
63 setIcon( Resource::loadPixmap( "help_icon" ) );
64
65 browser = new QTextBrowser( this );
66 browser->setFrameStyle( QFrame::Panel | QFrame::Sunken );
67 connect( browser, SIGNAL( textChanged() ),
68 this, SLOT( textChanged() ) );
69
70 setCentralWidget( browser );
71 setToolBarsMovable( FALSE );
72
73 if ( !_home.isEmpty() )
74 browser->setSource( _home );
75
76 QPEToolBar* toolbar = new QPEToolBar( this );
77 toolbar->setHorizontalStretchable( TRUE );
78 QPEMenuBar *menu = new QPEMenuBar( toolbar );
79
80 toolbar = new QPEToolBar( this );
81 // addToolBar( toolbar, "Toolbar");
82
83 //QPopupMenu* go = new QPopupMenu( this );
84 backAction = new QAction( tr( "Backward" ), Resource::loadIconSet( "back" ), QString::null, 0, this, 0 );
85 connect( backAction, SIGNAL( activated() ), browser, SLOT( backward() ) );
86 connect( browser, SIGNAL( backwardAvailable( bool ) ),
87 backAction, SLOT( setEnabled( bool ) ) );
88 //backAction->addTo( go );
89 backAction->addTo( toolbar );
90 backAction->setEnabled( FALSE );
91
92 forwardAction = new QAction( tr( "Forward" ), Resource::loadIconSet( "forward" ), QString::null, 0, this, 0 );
93 connect( forwardAction, SIGNAL( activated() ), browser, SLOT( forward() ) );
94 connect( browser, SIGNAL( forwardAvailable( bool ) ),
95 forwardAction, SLOT( setEnabled( bool ) ) );
96 //forwardAction->addTo( go );
97 forwardAction->addTo( toolbar );
98 forwardAction->setEnabled( FALSE );
99
100 QAction *a = new QAction( tr( "Home" ), Resource::loadPixmap( "home" ), QString::null, 0, this, 0 );
101 connect( a, SIGNAL( activated() ), browser, SLOT( home() ) );
102 //a->addTo( go );
103 a->addTo( toolbar );
104
105 bookm = new QPopupMenu( this );
106 bookm->insertItem( tr( "Add Bookmark" ), this, SLOT( addBookmark() ) );
107 bookm->insertItem( tr( "Remove from Bookmarks" ), this, SLOT( removeBookmark() ) );
108 bookm->insertSeparator();
109 connect( bookm, SIGNAL( activated( int ) ),
110 this, SLOT( bookmChosen( int ) ) );
111
112 readBookmarks();
113
114 //menu->insertItem( tr("Go"), go );
115 menu->insertItem( tr( "Bookmarks" ), bookm );
116
117 resize( 240, 300 );
118 browser->setFocus();
119
120 connect( qApp, SIGNAL(appMessage(const QCString&, const QByteArray&)),
121 this, SLOT(appMessage(const QCString&, const QByteArray&)) );
122}
123
124void HelpBrowser::appMessage(const QCString& msg, const QByteArray& data)
125{
126 if ( msg == "showFile(QString)" ) {
127 QDataStream ds(data,IO_ReadOnly);
128 QString fn;
129 ds >> fn;
130 setDocument( fn );
131 }
132}
133
134void HelpBrowser::setDocument( const QString &doc )
135{
136 if ( !doc.isEmpty() )
137 browser->setSource( doc );
138 raise();
139}
140
141
142void HelpBrowser::textChanged()
143{
144 if ( browser->documentTitle().isNull() )
145 setCaption( tr("Help Browser") );
146 else
147 setCaption( browser->documentTitle() ) ;
148
149 selectedURL = caption();
150}
151
152HelpBrowser::~HelpBrowser()
153{
154 QStringList bookmarks;
155 QMap<int, Bookmark>::Iterator it2 = mBookmarks.begin();
156 for ( ; it2 != mBookmarks.end(); ++it2 )
157 bookmarks.append( (*it2).name + "=" + (*it2).file );
158
159 QFile f2( Global::applicationFileName("helpbrowser", "bookmarks") );
160 if ( f2.open( IO_WriteOnly ) ) {
161 QDataStream s2( &f2 );
162 s2 << bookmarks;
163 f2.close();
164 }
165}
166
167void HelpBrowser::pathSelected( const QString &_path )
168{
169 browser->setSource( _path );
170}
171
172void HelpBrowser::readBookmarks()
173{
174 QString file = Global::applicationFileName("helpbrowser", "bookmarks");
175 if ( QFile::exists( file ) ) {
176 QStringList bookmarks;
177 QFile f( file );
178 if ( f.open( IO_ReadOnly ) ) {
179 QDataStream s( &f );
180 s >> bookmarks;
181 f.close();
182 }
183 QStringList::Iterator it = bookmarks.begin();
184 for ( ; it != bookmarks.end(); ++it ) {
185 Bookmark b;
186 QString current = *it;
187 int equal = current.find( "=" );
188 if ( equal < 1 || equal == (int)current.length() - 1 )
189 continue;
190 b.name = current.left( equal );
191 b.file = current.mid( equal + 1 );
192 mBookmarks[ bookm->insertItem( b.name ) ] = b;
193 }
194 }
195}
196
197void HelpBrowser::bookmChosen( int i )
198{
199 if ( mBookmarks.contains( i ) )
200 browser->setSource( mBookmarks[ i ].file );
201}
202
203void HelpBrowser::addBookmark()
204{
205 Bookmark b;
206 b.name = browser->documentTitle();
207 b.file = browser->source();
208 if (b.name.isEmpty() ) {
209 b.name = b.file.left( b.file.length() - 5 ); // remove .html
210 }
211 QMap<int, Bookmark>::Iterator it;
212 for( it = mBookmarks.begin(); it != mBookmarks.end(); ++it )
213 if ( (*it).file == b.file ) return;
214 mBookmarks[ bookm->insertItem( b.name ) ] = b;
215}
216
217void HelpBrowser::removeBookmark()
218{
219 QString file = browser->source();
220 QMap<int, Bookmark>::Iterator it = mBookmarks.begin();
221 for( ; it != mBookmarks.end(); ++it )
222 if ( (*it).file == file ) {
223 bookm->removeItem( it.key() );
224 mBookmarks.remove( it );
225 break;
226 }
227}
diff --git a/core/apps/helpbrowser/helpbrowser.h b/core/apps/helpbrowser/helpbrowser.h
new file mode 100644
index 0000000..2f7153a
--- a/dev/null
+++ b/core/apps/helpbrowser/helpbrowser.h
@@ -0,0 +1,69 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#ifndef HELPWINDOW_H
22#define HELPWINDOW_H
23
24#include <qmainwindow.h>
25#include <qtextbrowser.h>
26#include <qstringlist.h>
27#include <qmap.h>
28
29class QPopupMenu;
30class QAction;
31
32class HelpBrowser : public QMainWindow
33{
34 Q_OBJECT
35public:
36 HelpBrowser( QWidget* parent = 0, const char *name=0, WFlags f=0 );
37 ~HelpBrowser();
38
39public slots:
40 void setDocument( const QString &doc );
41
42private slots:
43 void appMessage(const QCString& msg, const QByteArray& data);
44 void textChanged();
45
46 void pathSelected( const QString & );
47 void bookmChosen( int );
48 void addBookmark();
49 void removeBookmark();
50
51private:
52 void init( const QString & );
53 void readBookmarks();
54
55 QTextBrowser* browser;
56 QAction *backAction;
57 QAction *forwardAction;
58 QString selectedURL;
59 struct Bookmark {
60 QString name;
61 QString file;
62 };
63 QMap<int, Bookmark> mBookmarks;
64 QMenuBar *menu;
65 QPopupMenu *bookm;
66};
67
68#endif
69
diff --git a/core/apps/helpbrowser/helpbrowser.pro b/core/apps/helpbrowser/helpbrowser.pro
new file mode 100644
index 0000000..43230f1
--- a/dev/null
+++ b/core/apps/helpbrowser/helpbrowser.pro
@@ -0,0 +1,12 @@
1 TEMPLATE= app
2 CONFIG = qt warn_on release
3 DESTDIR = $(QPEDIR)/bin
4 HEADERS = helpbrowser.h
5 SOURCES = helpbrowser.cpp \
6 main.cpp
7INCLUDEPATH += $(QPEDIR)/include
8 DEPENDPATH+= $(QPEDIR)/include
9LIBS += -lqpe
10 INTERFACES=
11
12TRANSLATIONS = ../i18n/de/helpbrowser.ts
diff --git a/core/apps/helpbrowser/main.cpp b/core/apps/helpbrowser/main.cpp
new file mode 100644
index 0000000..1cb10b7
--- a/dev/null
+++ b/core/apps/helpbrowser/main.cpp
@@ -0,0 +1,34 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#include "helpbrowser.h"
22
23#include <qpe/qpeapplication.h>
24
25int main( int argc, char ** argv )
26{
27 QPEApplication a( argc, argv );
28
29 HelpBrowser mw;
30 mw.setCaption( HelpBrowser::tr("HelpBrowser") );
31 a.showMainDocumentWidget( &mw );
32
33 return a.exec();
34}
diff --git a/core/apps/helpbrowser/qpe-helpbrowser.control b/core/apps/helpbrowser/qpe-helpbrowser.control
new file mode 100644
index 0000000..b6e3404
--- a/dev/null
+++ b/core/apps/helpbrowser/qpe-helpbrowser.control
@@ -0,0 +1,10 @@
1Files: bin/helpbrowser apps/Applications/helpbrowser.desktop docs
2Priority: optional
3Section: qpe/applications
4Maintainer: Warwick Allison <warwick@trolltech.com>
5Architecture: arm
6Arch: iPAQ
7Version: $QPE_VERSION-3
8Depends: qpe-base ($QPE_VERSION)
9Description: Browse HTML help documents
10 The HTML help browser for the Qtopia environment.
diff --git a/core/apps/qcop/.cvsignore b/core/apps/qcop/.cvsignore
new file mode 100644
index 0000000..edfa921
--- a/dev/null
+++ b/core/apps/qcop/.cvsignore
@@ -0,0 +1,3 @@
1moc_*
2*.moc
3Makefile
diff --git a/core/apps/qcop/Makefile.in b/core/apps/qcop/Makefile.in
new file mode 100644
index 0000000..0a12320
--- a/dev/null
+++ b/core/apps/qcop/Makefile.in
@@ -0,0 +1,102 @@
1#############################################################################
2
3####### Compiler, tools and options
4
5 CXX =$(SYSCONF_CXX) $(QT_CXX_MT)
6 CXXFLAGS=$(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS)
7 CC =$(SYSCONF_CC) $(QT_C_MT)
8 CFLAGS =$(SYSCONF_CFLAGS)
9 INCPATH =-I$(QPEDIR)/include
10 LFLAGS =$(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT)
11 LIBS =$(SUBLIBS) -lqpe $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS) $(SYSCONF_LIBS_QTAPP)
12 MOC =$(SYSCONF_MOC)
13 UIC =$(SYSCONF_UIC)
14
15####### Target
16
17DESTDIR = ../bin/
18VER_MAJ = 1
19VER_MIN = 0
20VER_PATCH = 0
21 TARGET= qcop
22TARGET1 = lib$(TARGET).so.$(VER_MAJ)
23
24####### Files
25
26 HEADERS =
27 SOURCES =main.cpp
28 OBJECTS =main.o
29INTERFACES =
30UICDECLS =
31UICIMPLS =
32 SRCMOC =
33 OBJMOC =
34
35
36####### Implicit rules
37
38.SUFFIXES: .cpp .cxx .cc .C .c
39
40.cpp.o:
41 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
42
43.cxx.o:
44 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
45
46.cc.o:
47 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
48
49.C.o:
50 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
51
52.c.o:
53 $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
54
55####### Build rules
56
57
58all: $(DESTDIR)$(TARGET)
59
60$(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
61 $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)
62
63moc: $(SRCMOC)
64
65tmake:
66 tmake qcop.pro
67
68clean:
69 -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
70 -rm -f *~ core
71 -rm -f allmoc.cpp
72
73####### Extension Modules
74
75listpromodules:
76 @echo
77
78listallmodules:
79 @echo
80
81listaddonpromodules:
82 @echo
83
84listaddonentmodules:
85 @echo
86
87
88REQUIRES=
89
90####### Sub-libraries
91
92
93###### Combined headers
94
95
96
97####### Compile
98
99main.o: main.cpp \
100 $(QPEDIR)/include/qpe/qcopenvelope_qws.h
101
102
diff --git a/core/apps/qcop/main.cpp b/core/apps/qcop/main.cpp
new file mode 100644
index 0000000..73db0f6
--- a/dev/null
+++ b/core/apps/qcop/main.cpp
@@ -0,0 +1,85 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#include <qpe/qcopenvelope_qws.h>
22
23#include <qapplication.h>
24#include <qstringlist.h>
25#include <qdatastream.h>
26#include <qtimer.h>
27
28#include <stdlib.h>
29#include <stdio.h>
30
31static void usage()
32{
33 fprintf( stderr, "Usage: qcop channel command [parameters]\n" );
34}
35
36static void syntax( const QString &where, const QString &what )
37{
38 fprintf( stderr, "Syntax error in %s: %s\n", where.latin1(), what.latin1() );
39 exit(1);
40}
41
42int main( int argc, char *argv[] )
43{
44 QApplication app( argc, argv );
45
46 if ( argc < 3 ) {
47 usage();
48 exit(1);
49 }
50
51 QString channel = argv[1];
52 QString command = argv[2];
53 command.stripWhiteSpace();
54
55 int paren = command.find( "(" );
56 if ( paren <= 0 )
57 syntax( "command", command );
58
59 QString params = command.mid( paren + 1 );
60 if ( params[params.length()-1] != ')' )
61 syntax( "command", command );
62
63 params.truncate( params.length()-1 );
64 QCopEnvelope env(channel.latin1(), command.latin1());
65
66 int argIdx = 3;
67
68 QStringList paramList = QStringList::split( ",", params );
69 QStringList::Iterator it;
70 for ( it = paramList.begin(); it != paramList.end(); ++it ) {
71 QString arg = argv[argIdx];
72 if ( *it == "QString" ) {
73 env << arg;
74 } else if ( *it == "int" ) {
75 env << arg.toInt();
76 } else {
77 syntax( "paramter type", *it );
78 }
79 argIdx++;
80 }
81
82 QTimer::singleShot( 0, &app, SLOT(quit()) );
83 return app.exec();
84}
85
diff --git a/core/apps/qcop/qcop.pro b/core/apps/qcop/qcop.pro
new file mode 100644
index 0000000..b52bfd8
--- a/dev/null
+++ b/core/apps/qcop/qcop.pro
@@ -0,0 +1,10 @@
1 TEMPLATE= app
2 CONFIG = qt warn_on release
3 DESTDIR = ../bin
4 HEADERS =
5 SOURCES = main.cpp
6INCLUDEPATH += $(QPEDIR)/include
7 DEPENDPATH+= $(QPEDIR)/include
8LIBS += -lqpe
9 INTERFACES=
10 TARGET = qcop
diff --git a/core/apps/qcop/qpe-qcop.control b/core/apps/qcop/qpe-qcop.control
new file mode 100644
index 0000000..60107c4
--- a/dev/null
+++ b/core/apps/qcop/qpe-qcop.control
@@ -0,0 +1,9 @@
1Files: bin/qcop
2Priority: required
3Section: qpe/system
4Maintainer: Martin Jones <mjones@trolltech.com>
5Architecture: arm
6Version: $QPE_VERSION-3
7Depends: qt-embedded (>=$QTE_VERSION)
8Description: Interprocess communication client
9 Interprocess communication client for the Qtopia environment.
diff --git a/core/apps/textedit/.cvsignore b/core/apps/textedit/.cvsignore
new file mode 100644
index 0000000..edfa921
--- a/dev/null
+++ b/core/apps/textedit/.cvsignore
@@ -0,0 +1,3 @@
1moc_*
2*.moc
3Makefile
diff --git a/core/apps/textedit/Makefile.in b/core/apps/textedit/Makefile.in
new file mode 100644
index 0000000..84542bb
--- a/dev/null
+++ b/core/apps/textedit/Makefile.in
@@ -0,0 +1,125 @@
1#############################################################################
2
3####### Compiler, tools and options
4
5 CXX =$(SYSCONF_CXX) $(QT_CXX_MT)
6 CXXFLAGS=$(SYSCONF_CXXFLAGS_QT) $(SYSCONF_CXXFLAGS)
7 CC =$(SYSCONF_CC) $(QT_C_MT)
8 CFLAGS =$(SYSCONF_CFLAGS)
9 INCPATH =-I$(QPEDIR)/include
10 LFLAGS =$(SYSCONF_LFLAGS_QT) $(SYSCONF_RPATH_QT) $(SYSCONF_LFLAGS) $(QT_LFLAGS_MT)
11 LIBS =$(SUBLIBS) -lqpe $(SYSCONF_LIBS_QT) $(SYSCONF_LIBS) $(SYSCONF_LIBS_QTAPP)
12 MOC =$(SYSCONF_MOC)
13 UIC =$(SYSCONF_UIC)
14
15####### Target
16
17DESTDIR = $(QPEDIR)/bin/
18VER_MAJ = 1
19VER_MIN = 0
20VER_PATCH = 0
21 TARGET= textedit
22TARGET1 = lib$(TARGET).so.$(VER_MAJ)
23
24####### Files
25
26 HEADERS =textedit.h
27 SOURCES =main.cpp \
28 textedit.cpp
29 OBJECTS =main.o \
30 textedit.o
31INTERFACES =
32UICDECLS =
33UICIMPLS =
34 SRCMOC =moc_textedit.cpp
35 OBJMOC =moc_textedit.o
36
37
38####### Implicit rules
39
40.SUFFIXES: .cpp .cxx .cc .C .c
41
42.cpp.o:
43 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
44
45.cxx.o:
46 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
47
48.cc.o:
49 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
50
51.C.o:
52 $(CXX) -c $(CXXFLAGS) $(INCPATH) -o $@ $<
53
54.c.o:
55 $(CC) -c $(CFLAGS) $(INCPATH) -o $@ $<
56
57####### Build rules
58
59
60all: $(DESTDIR)$(TARGET)
61
62$(DESTDIR)$(TARGET): $(UICDECLS) $(OBJECTS) $(OBJMOC) $(SUBLIBS)
63 $(SYSCONF_LINK) $(LFLAGS) -o $(DESTDIR)$(TARGET) $(OBJECTS) $(OBJMOC) $(LIBS)
64
65moc: $(SRCMOC)
66
67tmake:
68 tmake textedit.pro
69
70clean:
71 -rm -f $(OBJECTS) $(OBJMOC) $(SRCMOC) $(UICIMPLS) $(UICDECLS)
72 -rm -f *~ core
73 -rm -f allmoc.cpp
74
75####### Extension Modules
76
77listpromodules:
78 @echo
79
80listallmodules:
81 @echo
82
83listaddonpromodules:
84 @echo
85
86listaddonentmodules:
87 @echo
88
89
90REQUIRES=
91
92####### Sub-libraries
93
94
95###### Combined headers
96
97
98
99####### Compile
100
101main.o: main.cpp \
102 textedit.h \
103 $(QPEDIR)/include/qpe/filemanager.h \
104 $(QPEDIR)/include/qpe/qpeapplication.h
105
106textedit.o: textedit.cpp \
107 textedit.h \
108 $(QPEDIR)/include/qpe/filemanager.h \
109 $(QPEDIR)/include/qpe/global.h \
110 $(QPEDIR)/include/qpe/fileselector.h \
111 $(QPEDIR)/include/qpe/applnk.h \
112 $(QPEDIR)/include/qpe/resource.h \
113 $(QPEDIR)/include/qpe/config.h \
114 $(QPEDIR)/include/qpe/qpeapplication.h \
115 $(QPEDIR)/include/qpe/qpemenubar.h \
116 $(QPEDIR)/include/qpe/qpetoolbar.h
117
118moc_textedit.o: moc_textedit.cpp \
119 textedit.h \
120 $(QPEDIR)/include/qpe/filemanager.h
121
122moc_textedit.cpp: textedit.h
123 $(MOC) textedit.h -o moc_textedit.cpp
124
125
diff --git a/core/apps/textedit/inserttable.ui b/core/apps/textedit/inserttable.ui
new file mode 100644
index 0000000..09fe3c3
--- a/dev/null
+++ b/core/apps/textedit/inserttable.ui
@@ -0,0 +1,103 @@
1<!DOCTYPE UI><UI>
2<class>InsertTable</class><comment>*********************************************************************
3** Copyright (C) 2000 Trolltech AS. All rights reserved.
4**
5** This file is part of Qtopia Environment.
6**
7** This file may be distributed and/or modified under the terms of the
8** GNU General Public License version 2 as published by the Free Software
9** Foundation and appearing in the file LICENSE.GPL included in the
10** packaging of this file.
11**
12** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
13** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
14**
15** See http://www.trolltech.com/gpl/ for GPL licensing information.
16**
17** Contact info@trolltech.com if any conditions of this licensing are
18** not clear to you.
19**
20*********************************************************************</comment>
21<widget>
22 <class>QDialog</class>
23 <property stdset="1">
24 <name>name</name>
25 <cstring>InsertTable</cstring>
26 </property>
27 <property stdset="1">
28 <name>geometry</name>
29 <rect>
30 <x>0</x>
31 <y>0</y>
32 <width>165</width>
33 <height>79</height>
34 </rect>
35 </property>
36 <property stdset="1">
37 <name>caption</name>
38 <string>Insert Table</string>
39 </property>
40 <grid>
41 <property stdset="1">
42 <name>margin</name>
43 <number>11</number>
44 </property>
45 <property stdset="1">
46 <name>spacing</name>
47 <number>6</number>
48 </property>
49 <widget row="0" column="0" >
50 <class>QLabel</class>
51 <property stdset="1">
52 <name>name</name>
53 <cstring>TextLabel1</cstring>
54 </property>
55 <property stdset="1">
56 <name>text</name>
57 <string>Rows:</string>
58 </property>
59 </widget>
60 <widget row="0" column="1" >
61 <class>QSpinBox</class>
62 <property stdset="1">
63 <name>name</name>
64 <cstring>spinRows</cstring>
65 </property>
66 <property stdset="1">
67 <name>minValue</name>
68 <number>1</number>
69 </property>
70 <property stdset="1">
71 <name>value</name>
72 <number>1</number>
73 </property>
74 </widget>
75 <widget row="1" column="1" >
76 <class>QSpinBox</class>
77 <property stdset="1">
78 <name>name</name>
79 <cstring>spinColumns</cstring>
80 </property>
81 <property stdset="1">
82 <name>minValue</name>
83 <number>1</number>
84 </property>
85 <property stdset="1">
86 <name>value</name>
87 <number>1</number>
88 </property>
89 </widget>
90 <widget row="1" column="0" >
91 <class>QLabel</class>
92 <property stdset="1">
93 <name>name</name>
94 <cstring>TextLabel1_2</cstring>
95 </property>
96 <property stdset="1">
97 <name>text</name>
98 <string>Columns:</string>
99 </property>
100 </widget>
101 </grid>
102</widget>
103</UI>
diff --git a/core/apps/textedit/main.cpp b/core/apps/textedit/main.cpp
new file mode 100644
index 0000000..d0d37d2
--- a/dev/null
+++ b/core/apps/textedit/main.cpp
@@ -0,0 +1,35 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#include "textedit.h"
22
23#include <qpe/qpeapplication.h>
24
25int main( int argc, char **argv )
26{
27 QPEApplication a( argc, argv );
28
29 TextEdit e;
30 a.showMainDocumentWidget(&e);
31 if ( argc == 3 && argv[1] == QCString("-f") )
32 e.openFile(argv[2]);
33
34 a.exec();
35}
diff --git a/core/apps/textedit/qpe-textedit.control b/core/apps/textedit/qpe-textedit.control
new file mode 100644
index 0000000..b0dad7d
--- a/dev/null
+++ b/core/apps/textedit/qpe-textedit.control
@@ -0,0 +1,9 @@
1Files: bin/textedit apps/Applications/textedit.desktop
2Priority: optional
3Section: qpe/applications
4Maintainer: Warwick Allison <warwick@trolltech.com>
5Architecture: arm
6Version: $QPE_VERSION-3
7Depends: qpe-base ($QPE_VERSION)
8Description: Text Editor
9 The text editor for the Qtopia environment.
diff --git a/core/apps/textedit/qtextedit.h b/core/apps/textedit/qtextedit.h
new file mode 100644
index 0000000..b29a728
--- a/dev/null
+++ b/core/apps/textedit/qtextedit.h
@@ -0,0 +1,282 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#ifndef QTEXTEDIT_H
22#define QTEXTEDIT_H
23
24#include <qscrollview.h>
25#include <qstylesheet.h>
26#include <qpainter.h>
27
28class QPainter;
29class QTextDocument;
30class QTextCursor;
31class QKeyEvent;
32class QResizeEvent;
33class QMouseEvent;
34class QTimer;
35class QTextString;
36class QVBox;
37class QListBox;
38class QTextCommand;
39class QTextParag;
40class QTextFormat;
41class QFont;
42class QColor;
43
44class QTextEdit : public QScrollView
45{
46 Q_OBJECT
47
48public:
49 QTextEdit( QWidget *parent, const QString &fn, bool tabify = FALSE );
50 QTextEdit( QWidget *parent = 0, const char *name = 0 );
51 virtual ~QTextEdit();
52
53#if defined(QTEXTEDIT_OPEN_API)
54 QTextDocument *document() const;
55 QTextCursor *textCursor() const;
56#endif
57
58 QString text() const;
59 QString text( int parag, bool formatted = FALSE ) const;
60 Qt::TextFormat textFormat() const;
61 QString fileName() const;
62
63 void cursorPosition( int &parag, int &index );
64 void selection( int &parag_from, int &index_from,
65 int &parag_to, int &index_to );
66 virtual bool find( const QString &expr, bool cs, bool wo, bool forward = TRUE,
67 int *parag = 0, int *index = 0 );
68 void insert( const QString &text, bool indent = FALSE, bool checkNewLine = FALSE );
69
70 int paragraphs() const;
71 int lines() const;
72 int linesOfParagraph( int parag ) const;
73 int lineOfChar( int parag, int chr );
74
75 bool isModified() const;
76
77 bool italic() const;
78 bool bold() const;
79 bool underline() const;
80 QString family() const;
81 int pointSize() const;
82 QColor color() const;
83 QFont font() const;
84 int alignment() const;
85 int maxLines() const;
86
87 const QStyleSheet* styleSheet() const;
88 void setStyleSheet( const QStyleSheet* styleSheet );
89
90 void setPaper( const QBrush& pap);
91 QBrush paper() const;
92
93 void setLinkColor( const QColor& );
94 QColor linkColor() const;
95
96 void setLinkUnderline( bool );
97 bool linkUnderline() const;
98
99 void setMimeSourceFactory( const QMimeSourceFactory* factory );
100 const QMimeSourceFactory* mimeSourceFactory() const;
101
102 int heightForWidth( int w ) const;
103
104 void append( const QString& text );
105
106 bool hasSelectedText() const;
107 QString selectedText() const;
108
109 QString context() const;
110
111 QString documentTitle() const;
112
113 void scrollToAnchor( const QString& name );
114 QString anchorAt(const QPoint& pos);
115
116public slots:
117 virtual void undo();
118 virtual void redo();
119
120 virtual void cut();
121 virtual void copy();
122 virtual void paste();
123
124 virtual void indent();
125
126 virtual void setItalic( bool b );
127 virtual void setBold( bool b );
128 virtual void setUnderline( bool b );
129 virtual void setFamily( const QString &f );
130 virtual void setPointSize( int s );
131 virtual void setColor( const QColor &c );
132 virtual void setFont( const QFont &f );
133
134 virtual void setAlignment( int );
135
136 virtual void setParagType( QStyleSheetItem::DisplayMode, int listStyle );
137
138 virtual void setTextFormat( Qt::TextFormat f );
139 virtual void setText( const QString &txt, const QString &context = QString::null ) { setText( txt, context, FALSE ); }
140 virtual void setText( const QString &txt, const QString &context, bool tabify );
141
142 virtual void load( const QString &fn ) { load( fn, FALSE ); }
143 virtual void load( const QString &fn, bool tabify );
144 virtual void save( bool untabify = FALSE ) { save( QString::null, untabify ); }
145 virtual void save( const QString &fn, bool untabify = FALSE );
146
147 virtual void setCursorPosition( int parag, int index );
148 virtual void setSelection( int parag_from, int index_from,
149 int parag_to, int index_to );
150
151 virtual void setModified( bool m );
152 virtual void selectAll( bool select );
153
154 virtual void setMaxLines( int l );
155 virtual void resetFormat();
156
157signals:
158 void currentFontChanged( const QFont &f );
159 void currentColorChanged( const QColor &c );
160 void currentAlignmentChanged( int );
161 void textChanged();
162 void highlighted( const QString& );
163 void linkClicked( const QString& );
164
165protected:
166 void setFormat( QTextFormat *f, int flags );
167 void drawContents( QPainter *p, int cx, int cy, int cw, int ch );
168 void keyPressEvent( QKeyEvent *e );
169 void resizeEvent( QResizeEvent *e );
170 void contentsMousePressEvent( QMouseEvent *e );
171 void contentsMouseMoveEvent( QMouseEvent *e );
172 void contentsMouseReleaseEvent( QMouseEvent *e );
173 void contentsMouseDoubleClickEvent( QMouseEvent *e );
174#ifndef QT_NO_DRAGANDDROP
175 void contentsDragEnterEvent( QDragEnterEvent *e );
176 void contentsDragMoveEvent( QDragMoveEvent *e );
177 void contentsDragLeaveEvent( QDragLeaveEvent *e );
178 void contentsDropEvent( QDropEvent *e );
179#endif
180 bool eventFilter( QObject *o, QEvent *e );
181 bool focusNextPrevChild( bool next );
182#if !defined(QTEXTEDIT_OPEN_API)
183 QTextDocument *document() const;
184 QTextCursor *textCursor() const;
185#endif
186
187private slots:
188 void formatMore();
189 void doResize();
190 void doAutoScroll();
191 void doChangeInterval();
192 void blinkCursor();
193 void setModified();
194 void startDrag();
195
196private:
197 enum MoveDirection {
198 MoveLeft,
199 MoveRight,
200 MoveUp,
201 MoveDown,
202 MoveHome,
203 MoveEnd,
204 MovePgUp,
205 MovePgDown
206 };
207 enum KeyboardAction {
208 ActionBackspace,
209 ActionDelete,
210 ActionReturn
211 };
212
213 struct UndoRedoInfo {
214 enum Type { Invalid, Insert, Delete, Backspace, Return, RemoveSelected };
215 UndoRedoInfo( QTextDocument *d ) : type( Invalid ), doc( d )
216 { text = QString::null; id = -1; index = -1; }
217 void clear();
218 inline bool valid() const { return !text.isEmpty() && id >= 0&& index >= 0; }
219
220 QString text;
221 int id;
222 int index;
223 Type type;
224 QTextDocument *doc;
225 };
226
227private:
228 virtual bool isReadOnly() const { return FALSE; }
229 virtual bool linksEnabled() const { return TRUE; }
230 void init();
231 void ensureCursorVisible();
232 void drawCursor( bool visible );
233 void placeCursor( const QPoint &pos, QTextCursor *c = 0 );
234 void moveCursor( int direction, bool shift, bool control );
235 void moveCursor( int direction, bool control );
236 void removeSelectedText();
237 void doKeyboardAction( int action );
238 bool doCompletion();
239 void checkUndoRedoInfo( UndoRedoInfo::Type t );
240 void repaintChanged();
241 void updateCurrentFormat();
242 void handleReadOnlyKeyEvent( QKeyEvent *e );
243 void makeParagVisible( QTextParag *p );
244
245private:
246 QTextDocument *doc;
247 QTextCursor *cursor;
248 bool drawAll;
249 bool mousePressed;
250 QTimer *formatTimer, *scrollTimer, *changeIntervalTimer, *blinkTimer, *dragStartTimer, *resizeTimer;
251 QTextParag *lastFormatted;
252 int interval;
253 QVBox *completionPopup;
254 QListBox *completionListBox;
255 int completionOffset;
256 UndoRedoInfo undoRedoInfo;
257 QTextFormat *currentFormat;
258 QPainter painter;
259 int currentAlignment;
260 bool inDoubleClick;
261 QPoint oldMousePos, mousePos;
262 QPixmap *buf_pixmap;
263 bool cursorVisible, blinkCursorVisible;
264 bool readOnly, modified, mightStartDrag;
265 QPoint dragStartPos;
266 int mLines;
267 bool firstResize;
268 QString onLink;
269
270};
271
272inline QTextDocument *QTextEdit::document() const
273{
274 return doc;
275}
276
277inline QTextCursor *QTextEdit::textCursor() const
278{
279 return cursor;
280}
281
282#endif
diff --git a/core/apps/textedit/textedit.cpp b/core/apps/textedit/textedit.cpp
new file mode 100644
index 0000000..867625e
--- a/dev/null
+++ b/core/apps/textedit/textedit.cpp
@@ -0,0 +1,594 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#include "textedit.h"
22
23#include <qpe/global.h>
24#include <qpe/fileselector.h>
25#include <qpe/applnk.h>
26#include <qpe/resource.h>
27#include <qpe/config.h>
28#include <qpe/qpeapplication.h>
29#include <qpe/qpemenubar.h>
30#include <qpe/qpetoolbar.h>
31//#include <qpe/finddialog.h>
32
33#include <qaction.h>
34#include <qcolordialog.h>
35#include <qfileinfo.h>
36#include <qlineedit.h>
37#include <qmessagebox.h>
38#include <qobjectlist.h>
39#include <qpopupmenu.h>
40#include <qspinbox.h>
41#include <qtoolbutton.h>
42#include <qwidgetstack.h>
43
44#include <stdlib.h> //getenv
45
46
47#if QT_VERSION < 300
48
49class QpeEditor : public QMultiLineEdit
50{
51 // Q_OBJECT
52public:
53 QpeEditor( QWidget *parent, const char * name = 0 )
54 : QMultiLineEdit( parent, name ) {}
55
56 //public slots:
57 void find( const QString &txt, bool caseSensitive,
58 bool backwards );
59 /*
60signals:
61 void notFound();
62 void searchWrapped();
63 */
64
65private:
66
67};
68
69
70void QpeEditor::find ( const QString &txt, bool caseSensitive,
71 bool backwards )
72{
73 static bool wrap = FALSE;
74 int line, col;
75 if ( wrap ) {
76 if ( !backwards )
77 line = col = 0;
78 wrap = FALSE;
79 //emit searchWrapped();
80 } else {
81 getCursorPosition( &line, &col );
82 }
83 //ignore backwards for now....
84 if ( !backwards ) {
85 for ( ; ; ) {
86 if ( line >= numLines() ) {
87 wrap = TRUE;
88 //emit notFound();
89 break;
90 }
91 int findCol = getString( line )->find( txt, col, caseSensitive );
92 if ( findCol >= 0 ) {
93 setCursorPosition( line, findCol, FALSE );
94 col = findCol + txt.length();
95 setCursorPosition( line, col, TRUE );
96
97 //found = TRUE;
98 break;
99 }
100 line++;
101 col = 0;
102 }
103
104 }
105
106}
107
108
109#else
110
111#error "Must make a QpeEditor that inherits QTextEdit"
112
113#endif
114
115
116
117
118static int u_id = 1;
119static int get_unique_id()
120{
121 return u_id++;
122}
123
124static const int nfontsizes = 6;
125static const int fontsize[nfontsizes] = {8,10,12,14,18,24};
126
127TextEdit::TextEdit( QWidget *parent, const char *name, WFlags f )
128 : QMainWindow( parent, name, f ), bFromDocView( FALSE )
129{
130 doc = 0;
131
132 QString lang = getenv( "LANG" );
133
134 setToolBarsMovable( FALSE );
135
136 setIcon( Resource::loadPixmap( "TextEditor" ) );
137
138 QPEToolBar *bar = new QPEToolBar( this );
139 bar->setHorizontalStretchable( TRUE );
140 menu = bar;
141
142 QPEMenuBar *mb = new QPEMenuBar( bar );
143 QPopupMenu *file = new QPopupMenu( this );
144 QPopupMenu *edit = new QPopupMenu( this );
145 QPopupMenu *font = new QPopupMenu( this );
146
147 bar = new QPEToolBar( this );
148 editBar = bar;
149
150 QAction *a = new QAction( tr( "New" ), Resource::loadPixmap( "new" ), QString::null, 0, this, 0 );
151 connect( a, SIGNAL( activated() ), this, SLOT( fileNew() ) );
152 a->addTo( bar );
153 a->addTo( file );
154
155 a = new QAction( tr( "Open" ), Resource::loadPixmap( "fileopen" ), QString::null, 0, this, 0 );
156 connect( a, SIGNAL( activated() ), this, SLOT( fileOpen() ) );
157 a->addTo( bar );
158 a->addTo( file );
159
160 a = new QAction( tr( "Cut" ), Resource::loadPixmap( "cut" ), QString::null, 0, this, 0 );
161 connect( a, SIGNAL( activated() ), this, SLOT( editCut() ) );
162 a->addTo( editBar );
163 a->addTo( edit );
164
165 a = new QAction( tr( "Copy" ), Resource::loadPixmap( "copy" ), QString::null, 0, this, 0 );
166 connect( a, SIGNAL( activated() ), this, SLOT( editCopy() ) );
167 a->addTo( editBar );
168 a->addTo( edit );
169
170 a = new QAction( tr( "Paste" ), Resource::loadPixmap( "paste" ), QString::null, 0, this, 0 );
171 connect( a, SIGNAL( activated() ), this, SLOT( editPaste() ) );
172 a->addTo( editBar );
173 a->addTo( edit );
174
175 a = new QAction( tr( "Find..." ), Resource::loadPixmap( "find" ), QString::null, 0, this, 0 );
176 connect( a, SIGNAL( activated() ), this, SLOT( editFind() ) );
177 edit->insertSeparator();
178 a->addTo( bar );
179 a->addTo( edit );
180
181 int defsize;
182 bool defb, defi, wrap;
183 {
184 Config cfg("TextEdit");
185 cfg.setGroup("View");
186 defsize = cfg.readNumEntry("FontSize",10);
187 defb = cfg.readBoolEntry("Bold",FALSE);
188 defi = cfg.readBoolEntry("Italic",FALSE);
189 wrap = cfg.readBoolEntry("Wrap",TRUE);
190 }
191
192 zin = new QAction( tr("Zoom in"), QString::null, 0, this, 0 );
193 connect( zin, SIGNAL( activated() ), this, SLOT( zoomIn() ) );
194 zin->addTo( font );
195
196 zout = new QAction( tr("Zoom out"), QString::null, 0, this, 0 );
197 connect( zout, SIGNAL( activated() ), this, SLOT( zoomOut() ) );
198 zout->addTo( font );
199
200 font->insertSeparator();
201
202#if 0
203 QAction *ba = new QAction( tr("Bold"), QString::null, 0, this, 0 );
204 connect( ba, SIGNAL( toggled(bool) ), this, SLOT( setBold(bool) ) );
205 ba->setToggleAction(TRUE);
206 ba->addTo( font );
207
208 QAction *ia = new QAction( tr("Italic"), QString::null, 0, this, 0 );
209 connect( ia, SIGNAL( toggled(bool) ), this, SLOT( setItalic(bool) ) );
210 ia->setToggleAction(TRUE);
211 ia->addTo( font );
212
213 ba->setOn(defb);
214 ia->setOn(defi);
215
216 font->insertSeparator();
217#endif
218
219 QAction *wa = new QAction( tr("Wrap lines"), QString::null, 0, this, 0 );
220 connect( wa, SIGNAL( toggled(bool) ), this, SLOT( setWordWrap(bool) ) );
221 wa->setToggleAction(TRUE);
222 wa->addTo( font );
223
224 mb->insertItem( tr( "File" ), file );
225 mb->insertItem( tr( "Edit" ), edit );
226 mb->insertItem( tr( "View" ), font );
227
228 searchBar = new QPEToolBar(this);
229 addToolBar( searchBar, "Search", QMainWindow::Top, TRUE );
230
231 searchBar->setHorizontalStretchable( TRUE );
232
233 searchEdit = new QLineEdit( searchBar, "searchEdit" );
234 searchBar->setStretchableWidget( searchEdit );
235 connect( searchEdit, SIGNAL( textChanged( const QString & ) ),
236 this, SLOT( search() ) );
237
238 a = new QAction( tr( "Find Next" ), Resource::loadPixmap( "next" ), QString::null, 0, this, 0 );
239 connect( a, SIGNAL( activated() ), this, SLOT( findNext() ) );
240 a->addTo( searchBar );
241 a->addTo( edit );
242
243 a = new QAction( tr( "Close Find" ), Resource::loadPixmap( "close" ), QString::null, 0, this, 0 );
244 connect( a, SIGNAL( activated() ), this, SLOT( findClose() ) );
245 a->addTo( searchBar );
246
247 searchBar->hide();
248
249 editorStack = new QWidgetStack( this );
250 setCentralWidget( editorStack );
251
252 searchVisible = FALSE;
253
254 fileSelector = new FileSelector( "text/*", editorStack, "fileselector" ,
255 TRUE, FALSE );
256 fileSelector->setCategoriesVisible(TRUE);
257 connect( fileSelector, SIGNAL( closeMe() ), this, SLOT( showEditTools() ) );
258 connect( fileSelector, SIGNAL( newSelected( const DocLnk &) ), this, SLOT( newFile( const DocLnk & ) ) );
259 connect( fileSelector, SIGNAL( fileSelected( const DocLnk &) ), this, SLOT( openFile( const DocLnk & ) ) );
260 fileOpen();
261
262 editor = new QpeEditor( editorStack );
263 editorStack->addWidget( editor, get_unique_id() );
264
265 resize( 200, 300 );
266
267 setFontSize(defsize,TRUE);
268 wa->setOn(wrap);
269}
270
271TextEdit::~TextEdit()
272{
273 save();
274
275 Config cfg("TextEdit");
276 cfg.setGroup("View");
277 QFont f = editor->font();
278 cfg.writeEntry("FontSize",f.pointSize());
279 cfg.writeEntry("Bold",f.bold());
280 cfg.writeEntry("Italic",f.italic());
281 cfg.writeEntry("Wrap",editor->wordWrap() == QMultiLineEdit::WidgetWidth);
282}
283
284void TextEdit::zoomIn()
285{
286 setFontSize(editor->font().pointSize()+1,FALSE);
287}
288
289void TextEdit::zoomOut()
290{
291 setFontSize(editor->font().pointSize()-1,TRUE);
292}
293
294
295void TextEdit::setFontSize(int sz, bool round_down_not_up)
296{
297 int s=10;
298 for (int i=0; i<nfontsizes; i++) {
299 if ( fontsize[i] == sz ) {
300 s = sz;
301 break;
302 } else if ( round_down_not_up ) {
303 if ( fontsize[i] < sz )
304 s = fontsize[i];
305 } else {
306 if ( fontsize[i] > sz ) {
307 s = fontsize[i];
308 break;
309 }
310 }
311 }
312
313 QFont f = editor->font();
314 f.setPointSize(s);
315 editor->setFont(f);
316
317 zin->setEnabled(s != fontsize[nfontsizes-1]);
318 zout->setEnabled(s != fontsize[0]);
319}
320
321void TextEdit::setBold(bool y)
322{
323 QFont f = editor->font();
324 f.setBold(y);
325 editor->setFont(f);
326}
327
328void TextEdit::setItalic(bool y)
329{
330 QFont f = editor->font();
331 f.setItalic(y);
332 editor->setFont(f);
333}
334
335void TextEdit::setWordWrap(bool y)
336{
337 editor->setWordWrap(y ? QMultiLineEdit::WidgetWidth : QMultiLineEdit::NoWrap );
338}
339
340void TextEdit::fileNew()
341{
342 save();
343 newFile(DocLnk());
344}
345
346void TextEdit::fileOpen()
347{
348 if ( !save() ) {
349 if ( QMessageBox::critical( this, tr( "Out of space" ),
350 tr( "Text Editor was unable to\n"
351 "save your changes.\n"
352 "Free some space and try again.\n"
353 "\nContinue anyway?" ),
354 QMessageBox::Yes|QMessageBox::Escape,
355 QMessageBox::No|QMessageBox::Default )
356 != QMessageBox::Yes )
357 return;
358 else {
359 delete doc;
360 doc = 0;
361 }
362 }
363 menu->hide();
364 editBar->hide();
365 searchBar->hide();
366 clearWState (WState_Reserved1 );
367 editorStack->raiseWidget( fileSelector );
368 fileSelector->reread();
369 updateCaption();
370}
371
372
373#if 0
374void TextEdit::slotFind()
375{
376 FindDialog frmFind( "Text Editor", this );
377 connect( &frmFind, SIGNAL(signalFindClicked(const QString &, bool, bool, int)),
378 editor, SLOT(slotDoFind( const QString&,bool,bool)));
379
380 //case sensitive, backwards, [category]
381
382
383 connect( editor, SIGNAL(notFound()),
384 &frmFind, SLOT(slotNotFound()) );
385 connect( editor, SIGNAL(searchWrapped()),
386 &frmFind, SLOT(slotWrapAround()) );
387
388 frmFind.exec();
389
390
391}
392#endif
393
394void TextEdit::fileRevert()
395{
396 clear();
397 fileOpen();
398}
399
400void TextEdit::editCut()
401{
402#ifndef QT_NO_CLIPBOARD
403 editor->cut();
404#endif
405}
406
407void TextEdit::editCopy()
408{
409#ifndef QT_NO_CLIPBOARD
410 editor->copy();
411#endif
412}
413
414void TextEdit::editPaste()
415{
416#ifndef QT_NO_CLIPBOARD
417 editor->paste();
418#endif
419}
420
421void TextEdit::editFind()
422{
423 searchBar->show();
424 searchVisible = TRUE;
425 searchEdit->setFocus();
426}
427
428void TextEdit::findNext()
429{
430 editor->find( searchEdit->text(), FALSE, FALSE );
431
432}
433
434void TextEdit::findClose()
435{
436 searchVisible = FALSE;
437 searchBar->hide();
438}
439
440void TextEdit::search()
441{
442 editor->find( searchEdit->text(), FALSE, FALSE );
443}
444
445void TextEdit::newFile( const DocLnk &f )
446{
447 DocLnk nf = f;
448 nf.setType("text/plain");
449 clear();
450 editorStack->raiseWidget( editor );
451 setWState (WState_Reserved1 );
452 editor->setFocus();
453 doc = new DocLnk(nf);
454 updateCaption();
455}
456
457void TextEdit::openFile( const QString &f )
458{
459 bFromDocView = TRUE;
460 DocLnk nf;
461 nf.setType("text/plain");
462 nf.setFile(f);
463 openFile(nf);
464 showEditTools();
465 // Show filename in caption
466 QString name = f;
467 int sep = name.findRev( '/' );
468 if ( sep > 0 )
469 name = name.mid( sep+1 );
470 updateCaption( name );
471}
472
473void TextEdit::openFile( const DocLnk &f )
474{
475 clear();
476 FileManager fm;
477 QString txt;
478 if ( !fm.loadFile( f, txt ) ) {
479 // ####### could be a new file
480 //qDebug( "Cannot open file" );
481 //return;
482 }
483 fileNew();
484 if ( doc )
485 delete doc;
486 doc = new DocLnk(f);
487 editor->setText(txt);
488 editor->setEdited(FALSE);
489 updateCaption();
490}
491
492void TextEdit::showEditTools()
493{
494 if ( !doc )
495 close();
496 fileSelector->hide();
497 menu->show();
498 editBar->show();
499 if ( searchVisible )
500 searchBar->show();
501 updateCaption();
502}
503
504bool TextEdit::save()
505{
506 // case of nothing to save...
507 if ( !doc )
508 return true;
509 if ( !editor->edited() ) {
510 delete doc;
511 doc = 0;
512 return true;
513 }
514
515 QString rt = editor->text();
516
517 if ( doc->name().isEmpty() ) {
518 QString pt = rt.simplifyWhiteSpace();
519 int i = pt.find( ' ' );
520 QString docname = pt;
521 if ( i > 0 )
522 docname = pt.left( i );
523 // remove "." at the beginning
524 while( docname.startsWith( "." ) )
525 docname = docname.mid( 1 );
526 docname.replace( QRegExp("/"), "_" );
527 // cut the length. filenames longer than that don't make sense and something goes wrong when they get too long.
528 if ( docname.length() > 40 )
529 docname = docname.left(40);
530 if ( docname.isEmpty() )
531 docname = "Empty Text";
532 doc->setName(docname);
533
534 // append .txt to the file name
535 if ( doc->file().find(".txt") == -1 ) {
536 QString file = doc->file() + ".txt";
537 doc->setFile( file );
538 }
539 }
540
541
542 FileManager fm;
543 if ( !fm.saveFile( *doc, rt ) ) {
544 return false;
545 }
546 delete doc;
547 doc = 0;
548 editor->setEdited( false );
549 return true;
550}
551
552void TextEdit::clear()
553{
554 delete doc;
555 doc = 0;
556 editor->clear();
557}
558
559void TextEdit::updateCaption( const QString &name )
560{
561 if ( !doc )
562 setCaption( tr("Text Editor") );
563 else {
564 QString s = name;
565 if ( s.isNull() )
566 s = doc->name();
567 if ( s.isEmpty() )
568 s = tr( "Unnamed" );
569 setCaption( s + " - " + tr("Text Editor") );
570 }
571}
572
573void TextEdit::setDocument(const QString& fileref)
574{
575 bFromDocView = TRUE;
576 openFile(DocLnk(fileref));
577 showEditTools();
578}
579
580void TextEdit::closeEvent( QCloseEvent *e )
581{
582 if ( editorStack->visibleWidget() == editor && !bFromDocView ) {
583 e->ignore();
584 fileRevert();
585 } else {
586 bFromDocView = FALSE;
587 e->accept();
588 }
589}
590
591void TextEdit::accept()
592{
593 fileOpen();
594 }
diff --git a/core/apps/textedit/textedit.h b/core/apps/textedit/textedit.h
new file mode 100644
index 0000000..f7d1052
--- a/dev/null
+++ b/core/apps/textedit/textedit.h
@@ -0,0 +1,102 @@
1/**********************************************************************
2** Copyright (C) 2000 Trolltech AS. All rights reserved.
3**
4** This file is part of Qtopia Environment.
5**
6** This file may be distributed and/or modified under the terms of the
7** GNU General Public License version 2 as published by the Free Software
8** Foundation and appearing in the file LICENSE.GPL included in the
9** packaging of this file.
10**
11** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
12** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13**
14** See http://www.trolltech.com/gpl/ for GPL licensing information.
15**
16** Contact info@trolltech.com if any conditions of this licensing are
17** not clear to you.
18**
19**********************************************************************/
20
21#ifndef TEXTEDIT_H
22#define TEXTEDIT_H
23
24#define QTEXTEDIT_OPEN_API
25
26#include <qpe/filemanager.h>
27
28#include <qmainwindow.h>
29#include <qmultilineedit.h>
30#include <qlist.h>
31#include <qmap.h>
32
33class QWidgetStack;
34class QToolButton;
35class QPopupMenu;
36class QToolBar;
37class QLineEdit;
38class QAction;
39class FileSelector;
40class QpeEditor;
41
42class TextEdit : public QMainWindow
43{
44 Q_OBJECT
45
46public:
47 TextEdit( QWidget *parent = 0, const char *name = 0, WFlags f = 0 );
48 ~TextEdit();
49
50 void openFile( const QString & );
51
52protected:
53 void closeEvent( QCloseEvent *e );
54
55private slots:
56 void setDocument(const QString&);
57
58 void fileNew();
59 void fileRevert();
60 void fileOpen();
61
62 void editCut();
63 void editCopy();
64 void editPaste();
65 void editFind();
66
67 void findNext();
68 void findClose();
69
70 void search();
71 void accept();
72
73 void newFile( const DocLnk & );
74 void openFile( const DocLnk & );
75 void showEditTools();
76
77 void zoomIn();
78 void zoomOut();
79 void setBold(bool y);
80 void setItalic(bool y);
81 void setWordWrap(bool y);
82
83private:
84 void colorChanged( const QColor &c );
85 bool save();
86 void clear();
87 void updateCaption( const QString &name=QString::null );
88 void setFontSize(int sz, bool round_down_not_up);
89
90private:
91 QWidgetStack *editorStack;
92 FileSelector *fileSelector;
93 QpeEditor* editor;
94 QToolBar *menu, *editBar, *searchBar;
95 QLineEdit *searchEdit;
96 DocLnk *doc;
97 bool searchVisible;
98 bool bFromDocView;
99 QAction *zin, *zout;
100};
101
102#endif
diff --git a/core/apps/textedit/textedit.po b/core/apps/textedit/textedit.po
new file mode 100644
index 0000000..683a5e3
--- a/dev/null
+++ b/core/apps/textedit/textedit.po
@@ -0,0 +1,108 @@
1# This is a Qt message file in .po format. Each msgid starts with
2# a scope. This scope should *NOT* be translated - eg. translating
3# from French to English, "Foo::Bar" would be translated to "Pub",
4# not "Foo::Pub".
5msgid ""
6msgstr ""
7"Project-Id-Version: PROJECT VERSION\n"
8"POT-Creation-Date: 2001-03-16 14:29:14 EST\n"
9"PO-Revision-Date: YYYY-MM-DD\n"
10"Last-Translator: FULLNAME <EMAIL@ADDRESS>\n"
11"Content-Type: text/plain; charset=iso-8859-1\n"
12
13#: textedit.cpp:110
14msgid "TextEdit::&Edit"
15msgstr ""
16
17#: textedit.cpp:109
18msgid "TextEdit::&File"
19msgstr ""
20
21#: textedit.cpp:102
22msgid "TextEdit::&Insert"
23msgstr ""
24
25#: textedit.cpp:115
26msgid "TextEdit::Bold"
27msgstr ""
28
29#: textedit.cpp:191
30msgid "TextEdit::Bullet List"
31msgstr ""
32
33#: textedit.cpp:140
34msgid "TextEdit::Center"
35msgstr ""
36
37#: textedit.cpp:170
38msgid "TextEdit::Close Find"
39msgstr ""
40
41#: textedit.cpp:69
42msgid "TextEdit::Close"
43msgstr ""
44
45#: textedit.cpp:79
46msgid "TextEdit::Copy"
47msgstr ""
48
49#: textedit.cpp:74
50msgid "TextEdit::Cut"
51msgstr ""
52
53#: textedit.cpp:194
54msgid "TextEdit::Enumerated List"
55msgstr ""
56
57#: textedit.cpp:94
58msgid "TextEdit::Find Next"
59msgstr ""
60
61#: textedit.cpp:89
62msgid "TextEdit::Find..."
63msgstr ""
64
65#: textedit.cpp:120
66msgid "TextEdit::Italic"
67msgstr ""
68
69#: textedit.cpp:134
70msgid "TextEdit::Left"
71msgstr ""
72
73#: textedit.cpp:61
74msgid "TextEdit::New"
75msgstr ""
76
77#: textedit.cpp:65
78msgid "TextEdit::Open"
79msgstr ""
80
81#: textedit.cpp:84
82msgid "TextEdit::Paste"
83msgstr ""
84
85#: textedit.cpp:145
86msgid "TextEdit::Right"
87msgstr ""
88
89#: textedit.cpp:188
90msgid "TextEdit::Standard"
91msgstr ""
92
93#: textedit.cpp:104
94msgid "TextEdit::Table..."
95msgstr ""
96
97#: textedit.cpp:570
98msgid "TextEdit::Text Editor"
99msgstr ""
100
101#: textedit.cpp:125
102msgid "TextEdit::Underline"
103msgstr ""
104
105#: textedit.cpp:569
106msgid "TextEdit::Unnamed"
107msgstr ""
108
diff --git a/core/apps/textedit/textedit.pro b/core/apps/textedit/textedit.pro
new file mode 100644
index 0000000..3f5473e
--- a/dev/null
+++ b/core/apps/textedit/textedit.pro
@@ -0,0 +1,16 @@
1 TEMPLATE= app
2 CONFIG += qt warn_on release
3
4 DESTDIR = $(QPEDIR)/bin
5
6 HEADERS= textedit.h
7
8 SOURCES= main.cpp textedit.cpp
9
10INCLUDEPATH += $(QPEDIR)/include
11 DEPENDPATH+= $(QPEDIR)/include
12LIBS += -lqpe
13
14 TARGET = textedit
15
16TRANSLATIONS = ../i18n/de/textedit.ts