summaryrefslogtreecommitdiff
authorllornkcor <llornkcor>2002-10-31 14:49:24 (UTC)
committer llornkcor <llornkcor>2002-10-31 14:49:24 (UTC)
commitc3a6f53669140cf9e3c953772c610cd91d69ab78 (patch) (unidiff)
treeab8579e66582aedc01da2aea4272e754902e9287
parent7d8a563125b981718ae963ba6308e3506e870045 (diff)
downloadopie-c3a6f53669140cf9e3c953772c610cd91d69ab78.zip
opie-c3a6f53669140cf9e3c953772c610cd91d69ab78.tar.gz
opie-c3a6f53669140cf9e3c953772c610cd91d69ab78.tar.bz2
no wrap mode taken from console, gui needs work
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--core/apps/embeddedkonsole/TEHistory.cpp29
-rw-r--r--core/apps/embeddedkonsole/TEScreen.cpp415
-rw-r--r--core/apps/embeddedkonsole/TEWidget.cpp169
-rw-r--r--core/apps/embeddedkonsole/TEWidget.h15
-rw-r--r--core/apps/embeddedkonsole/TEmulation.cpp43
-rw-r--r--core/apps/embeddedkonsole/konsole.cpp34
6 files changed, 491 insertions, 214 deletions
diff --git a/core/apps/embeddedkonsole/TEHistory.cpp b/core/apps/embeddedkonsole/TEHistory.cpp
index 317ce57..db9d10c 100644
--- a/core/apps/embeddedkonsole/TEHistory.cpp
+++ b/core/apps/embeddedkonsole/TEHistory.cpp
@@ -1,212 +1,219 @@
1/* -------------------------------------------------------------------------- */ 1/* -------------------------------------------------------------------------- */
2/* */ 2/* */
3/* [TEHistory.C] History Buffer */ 3/* [TEHistory.C] History Buffer */
4/* */ 4/* */
5/* -------------------------------------------------------------------------- */ 5/* -------------------------------------------------------------------------- */
6/* */ 6/* */
7/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */ 7/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */
8/* */ 8/* */
9/* This file is part of Konsole - an X terminal for KDE */ 9/* This file is part of Konsole - an X terminal for KDE */
10/* */ 10/* */
11/* -------------------------------------------------------------------------- */ 11/* -------------------------------------------------------------------------- */
12 /* */ 12/* */
13/* Ported Konsole to Qt/Embedded */ 13/* Ported Konsole to Qt/Embedded */
14 /* */ 14/* */
15/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */ 15/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */
16 /* */ 16/* */
17/* -------------------------------------------------------------------------- */ 17/* -------------------------------------------------------------------------- */
18 18
19#include "TEHistory.h" 19#include "TEHistory.h"
20#include <stdlib.h> 20#include <stdlib.h>
21#include <assert.h> 21#include <assert.h>
22#include <stdio.h> 22#include <stdio.h>
23#include <sys/types.h> 23#include <sys/types.h>
24#include <unistd.h> 24#include <unistd.h>
25#include <errno.h> 25#include <errno.h>
26 26
27#define HERE printf("%s(%d): here\n",__FILE__,__LINE__) 27#define HERE printf("%s(%d): here\n",__FILE__,__LINE__)
28 28
29/* 29/*
30 An arbitrary long scroll. 30 An arbitrary long scroll.
31 31
32 One can modify the scroll only by adding either cells 32 One can modify the scroll only by adding either cells
33 or newlines, but access it randomly. 33 or newlines, but access it randomly.
34 34
35 The model is that of an arbitrary wide typewriter scroll 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 36 in that the scroll is a serie of lines and each line is
37 a serie of cells with no overwriting permitted. 37 a serie of cells with no overwriting permitted.
38 38
39 The implementation provides arbitrary length and numbers 39 The implementation provides arbitrary length and numbers
40 of cells and line/column indexed read access to the scroll 40 of cells and line/column indexed read access to the scroll
41 at constant costs. 41 at constant costs.
42 42
43FIXME: some complain about the history buffer comsuming the 43FIXME: some complain about the history buffer comsuming the
44 memory of their machines. This problem is critical 44 memory of their machines. This problem is critical
45 since the history does not behave gracefully in cases 45 since the history does not behave gracefully in cases
46 where the memory is used up completely. 46 where the memory is used up completely.
47 47
48 I put in a workaround that should handle it problem 48 I put in a workaround that should handle it problem
49 now gracefully. I'm not satisfied with the solution. 49 now gracefully. I'm not satisfied with the solution.
50 50
51FIXME: Terminating the history is not properly indicated 51FIXME: Terminating the history is not properly indicated
52 in the menu. We should throw a signal. 52 in the menu. We should throw a signal.
53 53
54FIXME: There is noticable decrease in speed, also. Perhaps, 54FIXME: There is noticable decrease in speed, also. Perhaps,
55 there whole feature needs to be revisited therefore. 55 there whole feature needs to be revisited therefore.
56 Disadvantage of a more elaborated, say block-oriented 56 Disadvantage of a more elaborated, say block-oriented
57 scheme with wrap around would be it's complexity. 57 scheme with wrap around would be it's complexity.
58*/ 58*/
59 59
60//FIXME: tempory replacement for tmpfile 60//FIXME: tempory replacement for tmpfile
61// this is here one for debugging purpose. 61// this is here one for debugging purpose.
62 62
63//#define tmpfile xTmpFile 63//#define tmpfile xTmpFile
64 64
65FILE* xTmpFile() 65FILE* xTmpFile()
66{ 66{
67 static int fid = 0; 67 static int fid = 0;
68 char fname[80]; 68 char fname[80];
69 sprintf(fname,"TmpFile.%d",fid++); 69 sprintf(fname,"TmpFile.%d",fid++);
70 return fopen(fname,"w"); 70 return fopen(fname,"w");
71} 71}
72 72
73 73
74// History Buffer /////////////////////////////////////////// 74// History Buffer ///////////////////////////////////////////
75 75
76/* 76/*
77 A Row(X) data type which allows adding elements to the end. 77 A Row(X) data type which allows adding elements to the end.
78*/ 78*/
79 79
80HistoryBuffer::HistoryBuffer() 80HistoryBuffer::HistoryBuffer()
81{ 81{
82 ion = -1; 82 ion = -1;
83 length = 0; 83 length = 0;
84} 84}
85 85
86HistoryBuffer::~HistoryBuffer() 86HistoryBuffer::~HistoryBuffer()
87{ 87{
88 setScroll(FALSE); 88 setScroll(FALSE);
89} 89}
90 90
91void HistoryBuffer::setScroll(bool on) 91void HistoryBuffer::setScroll(bool on)
92{ 92{
93 if (on == hasScroll()) return; 93 if (on == hasScroll()) return;
94 94
95 if (on) 95 if (on)
96 { 96 {
97 assert( ion < 0 ); 97 assert( ion < 0 );
98 assert( length == 0); 98 assert( length == 0);
99 FILE* tmp = tmpfile(); if (!tmp) { perror("konsole: cannot open temp file.\n"); return; } 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"); 100 ion = dup(fileno(tmp)); if (ion<0) perror("konsole: cannot dup temp file.\n");
101 fclose(tmp); 101 fclose(tmp);
102 } 102 }
103 else 103 else
104 { 104 {
105 assert( ion >= 0 ); 105 assert( ion >= 0 );
106 close(ion); 106 close(ion);
107 ion = -1; 107 ion = -1;
108 length = 0; 108 length = 0;
109 } 109 }
110} 110}
111 111
112bool HistoryBuffer::hasScroll() 112bool HistoryBuffer::hasScroll()
113{ 113{
114 return ion >= 0; 114 return ion >= 0;
115} 115}
116 116
117void HistoryBuffer::add(const unsigned char* bytes, int len) 117void HistoryBuffer::add(const unsigned char* bytes, int len)
118{ int rc; 118{ int rc;
119 assert(hasScroll()); 119 assert(hasScroll());
120 rc = lseek(ion,length,SEEK_SET); if (rc < 0) { perror("HistoryBuffer::add.seek"); setScroll(FALSE); return; } 120 rc = lseek( ion, length, SEEK_SET);
121 rc = write(ion,bytes,len); if (rc < 0) { perror("HistoryBuffer::add.write"); setScroll(FALSE); return; } 121 if (rc < 0) { perror("HistoryBuffer::add.seek"); setScroll(FALSE); return; }
122 rc = write( ion, bytes, len);
123 if (rc < 0) { perror("HistoryBuffer::add.write"); setScroll(FALSE); return; }
122 length += rc; 124 length += rc;
123} 125}
124 126
125void HistoryBuffer::get(unsigned char* bytes, int len, int loc) 127void HistoryBuffer::get(unsigned char* bytes, int len, int loc) {
126{ int rc; 128 int rc;
127 assert(hasScroll()); 129 assert(hasScroll());
130// qDebug("history get len %d, loc %d, length %d", len, loc, length);
128 if (loc < 0 || len < 0 || loc + len > length) 131 if (loc < 0 || len < 0 || loc + len > length)
129 fprintf(stderr,"getHist(...,%d,%d): invalid args.\n",len,loc); 132 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; } 133
131 rc = read(ion,bytes,len); if (rc < 0) { perror("HistoryBuffer::get.read"); setScroll(FALSE); return; } 134 rc = lseek( ion, loc, SEEK_SET);
135 if (rc < 0) { perror("HistoryBuffer::get.seek"); setScroll(FALSE); return; }
136 rc = read( ion, bytes, len);
137 if (rc < 0) { perror("HistoryBuffer::get.read"); setScroll(FALSE); return; }
132} 138}
133 139
134int HistoryBuffer::len() 140int HistoryBuffer::len()
135{ 141{
136 return length; 142 return length;
137} 143}
138 144
139// History Scroll ////////////////////////////////////// 145// History Scroll //////////////////////////////////////
140 146
141/* 147/*
142 The history scroll makes a Row(Row(Cell)) from 148 The history scroll makes a Row(Row(Cell)) from
143 two history buffers. The index buffer contains 149 two history buffers. The index buffer contains
144 start of line positions which refere to the cells 150 start of line positions which refere to the cells
145 buffer. 151 buffer.
146 152
147 Note that index[0] addresses the second line 153 Note that index[0] addresses the second line
148 (line #1), while the first line (line #0) starts 154 (line #1), while the first line (line #0) starts
149 at 0 in cells. 155 at 0 in cells.
150*/ 156*/
151 157
152HistoryScroll::HistoryScroll() 158HistoryScroll::HistoryScroll()
153{ 159{
154} 160}
155 161
156HistoryScroll::~HistoryScroll() 162HistoryScroll::~HistoryScroll()
157{ 163{
158} 164}
159 165
160void HistoryScroll::setScroll(bool on) 166void HistoryScroll::setScroll(bool on)
161{ 167{
162 index.setScroll(on); 168 index.setScroll(on);
163 cells.setScroll(on); 169 cells.setScroll(on);
164} 170}
165 171
166bool HistoryScroll::hasScroll() 172bool HistoryScroll::hasScroll()
167{ 173{
168 return index.hasScroll() && cells.hasScroll(); 174 return index.hasScroll() && cells.hasScroll();
169} 175}
170 176
171int HistoryScroll::getLines() 177int HistoryScroll::getLines()
172{ 178{
173 if (!hasScroll()) return 0; 179 if (!hasScroll()) return 0;
174 return index.len() / sizeof(int); 180 return index.len() / sizeof(int);
175} 181}
176 182
177int HistoryScroll::getLineLen(int lineno) 183int HistoryScroll::getLineLen(int lineno)
178{ 184{
179 if (!hasScroll()) return 0; 185 if (!hasScroll()) return 0;
180 return (startOfLine(lineno+1) - startOfLine(lineno)) / sizeof(ca); 186 return (startOfLine(lineno+1) - startOfLine(lineno)) / sizeof(ca);
181} 187}
182 188
183int HistoryScroll::startOfLine(int lineno) 189int HistoryScroll::startOfLine(int lineno)
184{ 190{
185 if (lineno <= 0) return 0; 191 if (lineno <= 0) return 0;
186 if (!hasScroll()) return 0; 192 if (!hasScroll()) return 0;
187 if (lineno <= getLines()) 193 if (lineno <= getLines())
188 { int res; 194 { int res;
189 index.get((unsigned char*)&res,sizeof(int),(lineno-1)*sizeof(int)); 195 index.get((unsigned char*)&res,sizeof(int),(lineno-1)*sizeof(int));
190 return res; 196 return res;
191 } 197 }
192 return cells.len(); 198 return cells.len();
193} 199}
194 200
195void HistoryScroll::getCells(int lineno, int colno, int count, ca res[]) 201void HistoryScroll::getCells(int lineno, int colno, int count, ca res[])
196{ 202{
197 assert(hasScroll()); 203 assert(hasScroll());
198 cells.get((unsigned char*)res,count*sizeof(ca),startOfLine(lineno)+colno*sizeof(ca)); 204//get(unsigned char* bytes, int len, int loc)
205 cells.get( (unsigned char*)res, count * sizeof(ca), startOfLine( lineno) + colno * sizeof(ca) );
199} 206}
200 207
201void HistoryScroll::addCells(ca text[], int count) 208void HistoryScroll::addCells(ca text[], int count)
202{ 209{
203 if (!hasScroll()) return; 210 if (!hasScroll()) return;
204 cells.add((unsigned char*)text,count*sizeof(ca)); 211 cells.add((unsigned char*)text,count*sizeof(ca));
205} 212}
206 213
207void HistoryScroll::addLine() 214void HistoryScroll::addLine()
208{ 215{
209 if (!hasScroll()) return; 216 if (!hasScroll()) return;
210 int locn = cells.len(); 217 int locn = cells.len();
211 index.add((unsigned char*)&locn,sizeof(int)); 218 index.add((unsigned char*)&locn,sizeof(int));
212} 219}
diff --git a/core/apps/embeddedkonsole/TEScreen.cpp b/core/apps/embeddedkonsole/TEScreen.cpp
index a3d115d..50807d3 100644
--- a/core/apps/embeddedkonsole/TEScreen.cpp
+++ b/core/apps/embeddedkonsole/TEScreen.cpp
@@ -1,138 +1,142 @@
1/* -------------------------------------------------------------------------- */ 1/* -------------------------------------------------------------------------- */
2/* */ 2/* */
3/* [TEScreen.C] Screen Data Type */ 3/* [TEScreen.C] Screen Data Type */
4/* */ 4/* */
5/* -------------------------------------------------------------------------- */ 5/* -------------------------------------------------------------------------- */
6/* */ 6/* */
7/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */ 7/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */
8/* */ 8/* */
9/* This file is part of Konsole - an X terminal for KDE */ 9/* This file is part of Konsole - an X terminal for KDE */
10/* */ 10/* */
11/* -------------------------------------------------------------------------- */ 11/* -------------------------------------------------------------------------- */
12 /* */ 12/* */
13/* Ported Konsole to Qt/Embedded */ 13/* Ported Konsole to Qt/Embedded */
14 /* */ 14/* */
15/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */ 15/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */
16 /* */ 16/* */
17/* -------------------------------------------------------------------------- */ 17/* -------------------------------------------------------------------------- */
18// enhancements added by L.J. Potter <ljp@llornkcor.com>
18 19
19/*! \file 20/*! \file
20*/ 21*/
21 22
22/*! \class TEScreen 23/*! \class TEScreen
23 24
24 \brief The image manipulated by the emulation. 25 \brief The image manipulated by the emulation.
25 26
26 This class implements the operations of the terminal emulation framework. 27 This class implements the operations of the terminal emulation framework.
27 It is a complete passive device, driven by the emulation decoder 28 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 (TEmuVT102). By this it forms in fact an ADT, that defines operations
29 on a rectangular image. 30 on a rectangular image.
30 31
31 It does neither know how to display its image nor about escape sequences. 32 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 It is further independent of the underlying toolkit. By this, one can even
33 use this module for an ordinary text surface. 34 use this module for an ordinary text surface.
34 35
35 Since the operations are called by a specific emulation decoder, one may 36 Since the operations are called by a specific emulation decoder, one may
36 collect their different operations here. 37 collect their different operations here.
37 38
38 The state manipulated by the operations is mainly kept in `image', though 39 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 it is a little more complex bejond this. See the header file of the class.
40 41
41 \sa TEWidget \sa VT102Emulation 42 \sa TEWidget \sa VT102Emulation
42*/ 43*/
43 44
44#include <stdio.h> 45#include <stdio.h>
45#include <stdlib.h> 46#include <stdlib.h>
46#include <unistd.h> 47#include <unistd.h>
47// #include <kdebug.h> 48// #include <kdebug.h>
48 49
49#include <assert.h> 50#include <assert.h>
50#include <string.h> 51#include <string.h>
51#include <ctype.h> 52#include <ctype.h>
52 53
54#include <qpe/config.h>
53#include "TEScreen.h" 55#include "TEScreen.h"
54 56
55#define HERE printf("%s(%d): here\n",__FILE__,__LINE__) 57#define HERE printf("%s(%d): here\n",__FILE__,__LINE__)
56 58
57//FIXME: this is emulation specific. Use FALSE for xterm, TRUE for ANSI. 59//FIXME: this is emulation specific. Use FALSE for xterm, TRUE for ANSI.
58//FIXME: see if we can get this from terminfo. 60//FIXME: see if we can get this from terminfo.
59#define BS_CLEARS FALSE 61#define BS_CLEARS FALSE
60 62
61#define loc(X,Y) ((Y)*columns+(X)) 63#define loc(X,Y) ((Y) * columns + (X))
62 64
63/*! creates a `TEScreen' of `lines' lines and `columns' columns. 65/*! creates a `TEScreen' of `lines' lines and `columns' columns.
64*/ 66*/
65 67
66TEScreen::TEScreen(int lines, int columns) 68TEScreen::TEScreen(int lines, int columns)
67{ 69{
68 this->lines = lines; 70 this->lines = lines;
69 this->columns = columns; 71 this->columns = columns;
70 72// qDebug("Columns %d", columns);
73
71 image = (ca*) malloc(lines*columns*sizeof(ca)); 74 image = (ca*) malloc(lines*columns*sizeof(ca));
72 tabstops = NULL; initTabStops(); 75 tabstops = NULL; initTabStops();
73 76
74 histCursor = 0; 77 histCursor = 0;
78 horzCursor = 0;
75 79
76 clearSelection(); 80 clearSelection();
77 reset(); 81 reset();
78} 82}
79 83
80/*! Destructor 84/*! Destructor
81*/ 85*/
82 86
83TEScreen::~TEScreen() 87TEScreen::~TEScreen()
84{ 88{
85 free(image); 89 free(image);
86 if (tabstops) free(tabstops); 90 if (tabstops) free(tabstops);
87} 91}
88 92
89/* ------------------------------------------------------------------------- */ 93/* ------------------------------------------------------------------------- */
90/* */ 94/* */
91/* Normalized Screen Operations */ 95/* Normalized Screen Operations */
92/* */ 96/* */
93/* ------------------------------------------------------------------------- */ 97/* ------------------------------------------------------------------------- */
94 98
95// Cursor Setting -------------------------------------------------------------- 99// Cursor Setting --------------------------------------------------------------
96 100
97/*! \section Cursor 101/*! \section Cursor
98 102
99 The `cursor' is a location within the screen that is implicitely used in 103 The `cursor' is a location within the screen that is implicitely used in
100 many operations. The operations within this section allow to manipulate 104 many operations. The operations within this section allow to manipulate
101 the cursor explicitly and to obtain it's value. 105 the cursor explicitly and to obtain it's value.
102 106
103 The position of the cursor is guarantied to be between (including) 0 and 107 The position of the cursor is guarantied to be between (including) 0 and
104 `columns-1' and `lines-1'. 108 `columns-1' and `lines-1'.
105*/ 109*/
106 110
107/*! 111/*!
108 Move the cursor up. 112 Move the cursor up.
109 113
110 The cursor will not be moved beyond the top margin. 114 The cursor will not be moved beyond the top margin.
111*/ 115*/
112 116
113void TEScreen::cursorUp(int n) 117void TEScreen::cursorUp(int n)
114//=CUU 118//=CUU
115{ 119{
116 if (n == 0) n = 1; // Default 120 if (n == 0) n = 1; // Default
117 int stop = cuY < tmargin ? 0 : tmargin; 121 int stop = cuY < tmargin ? 0 : tmargin;
118 cuX = QMIN(columns-1,cuX); // nowrap! 122 cuX = QMIN(columns-1,cuX); // nowrap!
119 cuY = QMAX(stop,cuY-n); 123 cuY = QMAX(stop,cuY-n);
120} 124}
121 125
122/*! 126/*!
123 Move the cursor down. 127 Move the cursor down.
124 128
125 The cursor will not be moved beyond the bottom margin. 129 The cursor will not be moved beyond the bottom margin.
126*/ 130*/
127 131
128void TEScreen::cursorDown(int n) 132void TEScreen::cursorDown(int n)
129//=CUD 133//=CUD
130{ 134{
131 if (n == 0) n = 1; // Default 135 if (n == 0) n = 1; // Default
132 int stop = cuY > bmargin ? lines-1 : bmargin; 136 int stop = cuY > bmargin ? lines-1 : bmargin;
133 cuX = QMIN(columns-1,cuX); // nowrap! 137 cuX = QMIN(columns-1,cuX); // nowrap!
134 cuY = QMIN(stop,cuY+n); 138 cuY = QMIN(stop,cuY+n);
135} 139}
136 140
137/*! 141/*!
138 Move the cursor left. 142 Move the cursor left.
@@ -322,451 +326,518 @@ void TEScreen::resetMode(int m)
322} 326}
323 327
324/*! Save a specific mode. */ 328/*! Save a specific mode. */
325 329
326void TEScreen::saveMode(int m) 330void TEScreen::saveMode(int m)
327{ 331{
328 saveParm.mode[m] = currParm.mode[m]; 332 saveParm.mode[m] = currParm.mode[m];
329} 333}
330 334
331/*! Restore a specific mode. */ 335/*! Restore a specific mode. */
332 336
333void TEScreen::restoreMode(int m) 337void TEScreen::restoreMode(int m)
334{ 338{
335 currParm.mode[m] = saveParm.mode[m]; 339 currParm.mode[m] = saveParm.mode[m];
336} 340}
337 341
338//NOTE: this is a helper function 342//NOTE: this is a helper function
339/*! Return the setting a specific mode. */ 343/*! Return the setting a specific mode. */
340BOOL TEScreen::getMode(int m) 344BOOL TEScreen::getMode(int m)
341{ 345{
342 return currParm.mode[m]; 346 return currParm.mode[m];
343} 347}
344 348
345/*! Save the cursor position and the rendition attribute settings. */ 349/*! Save the cursor position and the rendition attribute settings. */
346 350
347void TEScreen::saveCursor() 351void TEScreen::saveCursor()
348{ 352{
349 sa_cuX = cuX; 353 sa_cuX = cuX;
350 sa_cuY = cuY; 354 sa_cuY = cuY;
351 sa_cu_re = cu_re; 355 sa_cu_re = cu_re;
352 sa_cu_fg = cu_fg; 356 sa_cu_fg = cu_fg;
353 sa_cu_bg = cu_bg; 357 sa_cu_bg = cu_bg;
354} 358}
355 359
356/*! Restore the cursor position and the rendition attribute settings. */ 360/*! Restore the cursor position and the rendition attribute settings. */
357 361
358void TEScreen::restoreCursor() 362void TEScreen::restoreCursor()
359{ 363{
360 cuX = QMIN(sa_cuX,columns-1); 364 cuX = QMIN(sa_cuX,columns-1);
361 cuY = QMIN(sa_cuY,lines-1); 365 cuY = QMIN(sa_cuY,lines-1);
362 cu_re = sa_cu_re; 366 cu_re = sa_cu_re;
363 cu_fg = sa_cu_fg; 367 cu_fg = sa_cu_fg;
364 cu_bg = sa_cu_bg; 368 cu_bg = sa_cu_bg;
365 effectiveRendition(); 369 effectiveRendition();
366} 370}
367 371
368/* ------------------------------------------------------------------------- */ 372/* ------------------------------------------------------------------------- */
369/* */ 373/* */
370/* Screen Operations */ 374/* Screen Operations */
371/* */ 375/* */
372/* ------------------------------------------------------------------------- */ 376/* ------------------------------------------------------------------------- */
373 377
374/*! Assing a new size to the screen. 378/*! Assing a new size to the screen.
375 379
376 The topmost left position is maintained, while lower lines 380 The topmost left position is maintained, while lower lines
377 or right hand side columns might be removed or filled with 381 or right hand side columns might be removed or filled with
378 spaces to fit the new size. 382 spaces to fit the new size.
379 383
380 The region setting is reset to the whole screen and the 384 The region setting is reset to the whole screen and the
381 tab positions reinitialized. 385 tab positions reinitialized.
382*/ 386*/
383 387
384void TEScreen::resizeImage(int new_lines, int new_columns) 388void TEScreen::resizeImage(int new_lines, int new_columns)
385{ 389{
386 390 if (cuY > new_lines-1) {
387 if (cuY > new_lines-1) 391// attempt to preserve focus and lines
388 { // attempt to preserve focus and lines 392 bmargin = lines-1; //FIXME: margin lost
389 bmargin = lines-1; //FIXME: margin lost 393 for (int i = 0; i < cuY-(new_lines-1); i++) {
390 for (int i = 0; i < cuY-(new_lines-1); i++) 394 addHistLine(); scrollUp(horzCursor,1);
391 { 395 }
392 addHistLine(); scrollUp(0,1);
393 } 396 }
394 }
395 397
396 // make new image 398 // make new image
397 ca* newimg = (ca*)malloc(new_lines*new_columns*sizeof(ca)); 399 ca* newimg = (ca*)malloc( new_lines * new_columns * sizeof( ca));
398 400
399 clearSelection(); 401 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 402
428 // FIXME: try to keep values, evtl. 403 // clear new image
429 tmargin=0; 404 for (int y = 0; y < new_lines; y++)
430 bmargin=lines-1; 405 for (int x = 0; x < new_columns; x++) {
431 initTabStops(); 406 newimg[y*new_columns+x].c = ' ';
432 clearSelection(); 407 newimg[y*new_columns+x].f = DEFAULT_FORE_COLOR;
408 newimg[y*new_columns+x].b = DEFAULT_BACK_COLOR;
409 newimg[y*new_columns+x].r = DEFAULT_RENDITION;
410 }
411 int cpy_lines = QMIN(new_lines, lines);
412 int cpy_columns = QMIN(new_columns,columns);
413 // copy to new image
414 for (int y = 0; y < cpy_lines; y++)
415 for (int x = 0; x < cpy_columns; x++) {
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} 433}
434 434
435/* 435/*
436 Clarifying rendition here and in TEWidget. 436 Clarifying rendition here and in TEWidget.
437 437
438 currently, TEWidget's color table is 438 currently, TEWidget's color table is
439 0 1 2 .. 9 10 .. 17 439 0 1 2 .. 9 10 .. 17
440 dft_fg, dft_bg, dim 0..7, intensive 0..7 440 dft_fg, dft_bg, dim 0..7, intensive 0..7
441 441
442 cu_fg, cu_bg contain values 0..8; 442 cu_fg, cu_bg contain values 0..8;
443 - 0 = default color 443 - 0 = default color
444 - 1..8 = ansi specified color 444 - 1..8 = ansi specified color
445 445
446 re_fg, re_bg contain values 0..17 446 re_fg, re_bg contain values 0..17
447 due to the TEWidget's color table 447 due to the TEWidget's color table
448 448
449 rendition attributes are 449 rendition attributes are
450 450
451 attr widget screen 451 attr widget screen
452 -------------- ------ ------ 452 -------------- ------ ------
453 RE_UNDERLINE XX XX affects foreground only 453 RE_UNDERLINE XX XX affects foreground only
454 RE_BLINK XX XX affects foreground only 454 RE_BLINK XX XX affects foreground only
455 RE_BOLD XX XX affects foreground only 455 RE_BOLD XX XX affects foreground only
456 RE_REVERSE -- XX 456 RE_REVERSE -- XX
457 RE_TRANSPARENT XX -- affects background only 457 RE_TRANSPARENT XX -- affects background only
458 RE_INTENSIVE XX -- affects foreground only 458 RE_INTENSIVE XX -- affects foreground only
459 459
460 Note that RE_BOLD is used in both widget 460 Note that RE_BOLD is used in both widget
461 and screen rendition. Since xterm/vt102 461 and screen rendition. Since xterm/vt102
462 is to poor to distinguish between bold 462 is to poor to distinguish between bold
463 (which is a font attribute) and intensive 463 (which is a font attribute) and intensive
464 (which is a color attribute), we translate 464 (which is a color attribute), we translate
465 this and RE_BOLD in falls eventually appart 465 this and RE_BOLD in falls eventually appart
466 into RE_BOLD and RE_INTENSIVE. 466 into RE_BOLD and RE_INTENSIVE.
467*/ 467*/
468 468
469void TEScreen::reverseRendition(ca* p) 469void TEScreen::reverseRendition(ca* p)
470{ UINT8 f = p->f; UINT8 b = p->b; 470{ UINT8 f = p->f; UINT8 b = p->b;
471 p->f = b; p->b = f; //p->r &= ~RE_TRANSPARENT; 471 p->f = b; p->b = f; //p->r &= ~RE_TRANSPARENT;
472} 472}
473 473
474void TEScreen::effectiveRendition() 474void TEScreen::effectiveRendition()
475// calculate rendition 475// calculate rendition
476{ 476{
477 ef_re = cu_re & (RE_UNDERLINE | RE_BLINK); 477 ef_re = cu_re & (RE_UNDERLINE | RE_BLINK);
478 if (cu_re & RE_REVERSE) 478 if (cu_re & RE_REVERSE)
479 { 479 {
480 ef_fg = cu_bg; 480 ef_fg = cu_bg;
481 ef_bg = cu_fg; 481 ef_bg = cu_fg;
482 } 482 }
483 else 483 else
484 { 484 {
485 ef_fg = cu_fg; 485 ef_fg = cu_fg;
486 ef_bg = cu_bg; 486 ef_bg = cu_bg;
487 } 487 }
488 if (cu_re & RE_BOLD) 488 if (cu_re & RE_BOLD)
489 { 489 {
490 if (ef_fg < BASE_COLORS) 490 if (ef_fg < BASE_COLORS)
491 ef_fg += BASE_COLORS; 491 ef_fg += BASE_COLORS;
492 else 492 else
493 ef_fg -= BASE_COLORS; 493 ef_fg -= BASE_COLORS;
494 } 494 }
495} 495}
496 496
497/*! 497/*!
498 returns the image. 498 returns the image.
499 499
500 Get the size of the image by \sa getLines and \sa getColumns. 500 Get the size of the image by \sa getLines and \sa getColumns.
501 501
502 NOTE that the image returned by this function must later be 502 NOTE that the image returned by this function must later be
503 freed. 503 freed.
504 504
505*/ 505*/
506 506
507ca* TEScreen::getCookedImage() 507ca* TEScreen::getCookedImage()
508{ int x,y; 508{
509 int x,y;
509 ca* merged = (ca*)malloc(lines*columns*sizeof(ca)); 510 ca* merged = (ca*)malloc(lines*columns*sizeof(ca));
510 ca dft(' ',DEFAULT_FORE_COLOR,DEFAULT_BACK_COLOR,DEFAULT_RENDITION); 511 ca dft(' ',DEFAULT_FORE_COLOR,DEFAULT_BACK_COLOR,DEFAULT_RENDITION);
511 512
512 for (y = 0; (y < lines) && (y < (hist.getLines()-histCursor)); y++) 513 for (y = 0; (y < lines) && (y < (hist.getLines()-histCursor)); y++)
513 { 514 {
514 int len = QMIN(columns,hist.getLineLen(y+histCursor)); 515 int len = QMIN(columns,hist.getLineLen(y+histCursor));
515 int yp = y*columns; 516 int yp = y*columns;
516 int yq = (y+histCursor)*columns; 517 int yq = (y+histCursor)*columns;
517 518
518 hist.getCells(y+histCursor,0,len,merged+yp); 519 hist.getCells(y+histCursor,0,len,merged+yp);
519 for (x = len; x < columns; x++) merged[yp+x] = dft; 520 for (x = len; x < columns; x++) merged[yp+x] = dft;
520 for (x = 0; x < columns; x++) 521 for (x = 0; x < columns; x++)
521 { int p=x + yp; int q=x + yq; 522 { int p=x + yp; int q=x + yq;
522 if ( ( q >= sel_TL ) && ( q <= sel_BR ) ) 523 if ( ( q >= sel_TL ) && ( q <= sel_BR ) )
523 reverseRendition(&merged[p]); // for selection 524 reverseRendition(&merged[p]); // for selection
524 } 525 }
525 } 526 }
526 if (lines >= hist.getLines()-histCursor) 527 if (lines >= hist.getLines()-histCursor)
527 { 528 {
528 for (y = (hist.getLines()-histCursor); y < lines ; y++) 529 for (y = (hist.getLines()-histCursor); y < lines ; y++)
529 { 530 {
530 int yp = y*columns; 531 int yp = y*columns;
531 int yq = (y+histCursor)*columns; 532 int yq = (y+histCursor)*columns;
532 int yr = (y-hist.getLines()+histCursor)*columns; 533 int yr = (y-hist.getLines()+histCursor)*columns;
533 for (x = 0; x < columns; x++) 534 for (x = 0; x < columns; x++)
534 { int p = x + yp; int q = x + yq; int r = x + yr; 535 { int p = x + yp; int q = x + yq; int r = x + yr;
535 merged[p] = image[r]; 536 merged[p] = image[r];
536 if ( q >= sel_TL && q <= sel_BR ) 537 if ( q >= sel_TL && q <= sel_BR )
537 reverseRendition(&merged[p]); // for selection 538 reverseRendition(&merged[p]); // for selection
538 } 539 }
539 540
540 } 541 }
541 } 542 }
542 // evtl. inverse display 543 // evtl. inverse display
543 if (getMode(MODE_Screen)) 544 if (getMode(MODE_Screen))
544 { int i,n = lines*columns; 545 { int i,n = lines*columns;
545 for (i = 0; i < n; i++) 546 for (i = 0; i < n; i++)
546 reverseRendition(&merged[i]); // for reverse display 547 reverseRendition(&merged[i]); // for reverse display
547 } 548 }
548 if (getMode(MODE_Cursor) && (cuY+(hist.getLines()-histCursor) < lines)) // cursor visible 549 if (getMode(MODE_Cursor) && (cuY+(hist.getLines()-histCursor) < lines)) // cursor visible
549 reverseRendition(&merged[loc(cuX,cuY+(hist.getLines()-histCursor))]); 550 reverseRendition(&merged[loc(cuX,cuY+(hist.getLines()-histCursor))]);
550 return merged; 551 return merged;
552
553 /*
554 int x, y, z;
555
556 ca* merged = (ca*)malloc( lines * columns * sizeof( ca));
557
558 ca dft(' ',DEFAULT_FORE_COLOR,DEFAULT_BACK_COLOR,DEFAULT_RENDITION);
559
560// qDebug("hist lines %d, historyCursor %d, minus %d ,lines %d, columns %d",
561// hist.getLines(), histCursor, hist.getLines() - histCursor , lines, columns);
562 for (y = 0; (y < lines) && (y < ( hist.getLines() - histCursor )); y++) {
563
564 int len = QMIN( columns, hist.getLineLen( y + histCursor) );
565 int yp = y * columns;
566 int yq = ( y + histCursor) * columns;
567// qDebug("horzCursor %d, columns %d, len %d", horzCursor, columns, len);
568// qDebug("lineno %d, colno %d, count %d\n", y + histCursor, (horzCursor / 2), len );
569 qDebug("Y %d", y);
570 hist.getCells( y + histCursor, (horzCursor / 2), len, merged + yp);
571
572 for (x = len; x < columns; x++)
573 merged[yp + x] = dft;
574 for (x = 0; x < columns; x++) {
575 int p = x + yp; int q = x + yq;
576 if ( ( q >= sel_TL ) && ( q <= sel_BR ) )
577 reverseRendition(&merged[p]); // for selection
578 }
579 }
580
581 if (lines >= hist.getLines() - histCursor) {
582 for (y = ( hist.getLines() - histCursor); y < lines ; y++) {
583 int z = horzCursor;
584 int yp = y * columns;
585 int yq = ( y + histCursor) * columns;
586 int yr = ( y - hist.getLines() + histCursor) * columns;
587// qDebug("y %d, yp %d, yq %d, columns %d, z cursor %d", y, yp, yq, columns, z);
588 for (x = 0; x < columns; x++) {
589 int p = x + yp; int q = x + yq; int r = (x + (horzCursor/2) ) + yr;
590 merged[p] = image[r];
591 if ( q >= sel_TL && q <= sel_BR )
592 reverseRendition( &merged[p]); // for selection
593 }
594 }
595 }
596
597
598// evtl. inverse display
599 if (getMode(MODE_Screen))
600 { int i, n = lines * columns;
601 for (i = 0; i < n; i++)
602 reverseRendition( &merged[i]); // for reverse display
603 }
604 if (getMode(MODE_Cursor) && ( cuY + ( hist.getLines() - histCursor) < lines)) // cursor visible
605
606 reverseRendition( &merged[ loc( cuX, cuY + ( hist.getLines() - histCursor))] );
607
608 return merged;
609 */
610
551} 611}
552 612
553 613
554/*! 614/*!
555*/ 615*/
556 616
557void TEScreen::reset() 617void TEScreen::reset()
558{ 618{
619 Config cfg("Konsole");
620 cfg.setGroup("ScrollBar");
621 if( !cfg.readBoolEntry("HorzScroll",0) )
559 setMode(MODE_Wrap ); saveMode(MODE_Wrap ); // wrap at end of margin 622 setMode(MODE_Wrap ); saveMode(MODE_Wrap ); // wrap at end of margin
623
624
560 resetMode(MODE_Origin); saveMode(MODE_Origin); // position refere to [1,1] 625 resetMode(MODE_Origin); saveMode(MODE_Origin); // position refere to [1,1]
561 resetMode(MODE_Insert); saveMode(MODE_Insert); // overstroke 626 resetMode(MODE_Insert); saveMode(MODE_Insert); // overstroke
562 setMode(MODE_Cursor); // cursor visible 627 setMode(MODE_Cursor); // cursor visible
563 resetMode(MODE_Screen); // screen not inverse 628 resetMode(MODE_Screen); // screen not inverse
564 resetMode(MODE_NewLine); 629 resetMode(MODE_NewLine);
565 630
566 tmargin=0; 631 tmargin=0;
567 bmargin=lines-1; 632 bmargin=lines-1;
568 633
569 setDefaultRendition(); 634 setDefaultRendition();
570 saveCursor(); 635 saveCursor();
571 636
572 clear(); 637 clear();
573} 638}
574 639
575/*! Clear the entire screen and home the cursor. 640/*! Clear the entire screen and home the cursor.
576*/ 641*/
577 642
578void TEScreen::clear() 643void TEScreen::clear()
579{ 644{
580 clearEntireScreen(); 645 clearEntireScreen();
581 home(); 646 home();
582} 647}
583 648
584/*! Moves the cursor left one column. 649/*! Moves the cursor left one column.
585*/ 650*/
586 651
587void TEScreen::BackSpace() 652void TEScreen::BackSpace()
588{ 653{
589 cuX = QMAX(0,cuX-1); 654 cuX = QMAX(0,cuX-1);
590 if (BS_CLEARS) image[loc(cuX,cuY)].c = ' '; 655 if (BS_CLEARS) image[loc(cuX,cuY)].c = ' ';
591} 656}
592 657
593/*! 658/*!
594*/ 659*/
595 660
596void TEScreen::Tabulate() 661void TEScreen::Tabulate()
597{ 662{
598 // note that TAB is a format effector (does not write ' '); 663 // note that TAB is a format effector (does not write ' ');
599 cursorRight(1); while(cuX < columns-1 && !tabstops[cuX]) cursorRight(1); 664 cursorRight(1); while(cuX < columns-1 && !tabstops[cuX]) cursorRight(1);
600} 665}
601 666
602void TEScreen::clearTabStops() 667void TEScreen::clearTabStops()
603{ 668{
604 for (int i = 0; i < columns; i++) tabstops[i-1] = FALSE; 669 for (int i = 0; i < columns; i++) tabstops[i-1] = FALSE;
605} 670}
606 671
607void TEScreen::changeTabStop(bool set) 672void TEScreen::changeTabStop(bool set)
608{ 673{
609 if (cuX >= columns) return; 674 if (cuX >= columns) return;
610 tabstops[cuX] = set; 675 tabstops[cuX] = set;
611} 676}
612 677
613void TEScreen::initTabStops() 678void TEScreen::initTabStops()
614{ 679{
615 if (tabstops) free(tabstops); 680 if (tabstops) free(tabstops);
616 tabstops = (bool*)malloc(columns*sizeof(bool)); 681 tabstops = (bool*)malloc(columns*sizeof(bool));
617 // Arrg! The 1st tabstop has to be one longer than the other. 682 // Arrg! The 1st tabstop has to be one longer than the other.
618 // i.e. the kids start counting from 0 instead of 1. 683 // i.e. the kids start counting from 0 instead of 1.
619 // Other programs might behave correctly. Be aware. 684 // Other programs might behave correctly. Be aware.
620 for (int i = 0; i < columns; i++) tabstops[i] = (i%8 == 0 && i != 0); 685 for (int i = 0; i < columns; i++) tabstops[i] = (i%8 == 0 && i != 0);
621} 686}
622 687
623/*! 688/*!
624 This behaves either as IND (Screen::Index) or as NEL (Screen::NextLine) 689 This behaves either as IND (Screen::Index) or as NEL (Screen::NextLine)
625 depending on the NewLine Mode (LNM). This mode also 690 depending on the NewLine Mode (LNM). This mode also
626 affects the key sequence returned for newline ([CR]LF). 691 affects the key sequence returned for newline ([CR]LF).
627*/ 692*/
628 693
629void TEScreen::NewLine() 694void TEScreen::NewLine()
630{ 695{
631 if (getMode(MODE_NewLine)) Return(); 696 if (getMode(MODE_NewLine)) Return();
632 index(); 697 index();
633} 698}
634 699
635/*! put `c' literally onto the screen at the current cursor position. 700/*! put `c' literally onto the screen at the current cursor position.
636 701
637 VT100 uses the convention to produce an automatic newline (am) 702 VT100 uses the convention to produce an automatic newline (am)
638 with the *first* character that would fall onto the next line (xenl). 703 with the *first* character that would fall onto the next line (xenl).
639*/ 704*/
640 705
641void TEScreen::checkSelection(int from, int to) 706void TEScreen::checkSelection(int from, int to)
642{ 707{
643 if (sel_begin == -1) return; 708 if (sel_begin == -1) return;
644 int scr_TL = loc(0, hist.getLines()); 709 int scr_TL = loc(0, hist.getLines());
645 //Clear entire selection if it overlaps region [from, to] 710 //Clear entire selection if it overlaps region [from, to]
646 if ( (sel_BR > (from+scr_TL) )&&(sel_TL < (to+scr_TL)) ) 711 if ( (sel_BR > (from+scr_TL) )&&(sel_TL < (to+scr_TL)) )
647 { 712 {
648 clearSelection(); 713 clearSelection();
649 } 714 }
650} 715}
651 716
652void TEScreen::ShowCharacter(unsigned short c) 717void TEScreen::ShowCharacter(unsigned short c)
653{ 718{
654 // Note that VT100 does wrapping BEFORE putting the character. 719 // Note that VT100 does wrapping BEFORE putting the character.
655 // This has impact on the assumption of valid cursor positions. 720 // This has impact on the assumption of valid cursor positions.
656 // We indicate the fact that a newline has to be triggered by 721 // 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. 722 // putting the cursor one right to the last column of the screen.
658 723
659 if (cuX >= columns) 724 if (cuX >= columns)
660 { 725 {
661 if (getMode(MODE_Wrap)) NextLine(); else cuX = columns-1; 726 if (getMode(MODE_Wrap)) NextLine(); else cuX = columns - 1;
727 // comment out for no wrap
662 } 728 }
663 729
664 if (getMode(MODE_Insert)) insertChars(1); 730 if (getMode(MODE_Insert)) insertChars(1);
665 731
666 int i = loc(cuX,cuY); 732 int i = loc( cuX, cuY);
667 733
668 checkSelection(i, i); // check if selection is still valid. 734 checkSelection(i, i); // check if selection is still valid.
669 735
670 image[i].c = c; 736 image[i].c = c;
671 image[i].f = ef_fg; 737 image[i].f = ef_fg;
672 image[i].b = ef_bg; 738 image[i].b = ef_bg;
673 image[i].r = ef_re; 739 image[i].r = ef_re;
674 740
675 cuX += 1; 741 cuX += 1;
676} 742}
677 743
678// Region commands ------------------------------------------------------------- 744// Region commands -------------------------------------------------------------
679 745
680 746
681/*! scroll up `n' lines within current region. 747/*! scroll up `n' lines within current region.
682 The `n' new lines are cleared. 748 The `n' new lines are cleared.
683 \sa setRegion \sa scrollDown 749 \sa setRegion \sa scrollDown
684*/ 750*/
685 751
686void TEScreen::scrollUp(int from, int n) 752void TEScreen::scrollUp(int from, int n)
687{ 753{
688 if (n <= 0 || from + n > bmargin) return; 754 if (n <= 0 || from + n > bmargin) return;
689 //FIXME: make sure `tmargin', `bmargin', `from', `n' is in bounds. 755 //FIXME: make sure `tmargin', `bmargin', `from', `n' is in bounds.
690 moveImage(loc(0,from),loc(0,from+n),loc(columns-1,bmargin)); 756
691 clearImage(loc(0,bmargin-n+1),loc(columns-1,bmargin),' '); 757 moveImage( loc( 0, from), loc( 0, from + n), loc( columns - 1, bmargin));
758 clearImage( loc( 0, bmargin - n + 1), loc( columns - 1, bmargin), ' ');
692} 759}
693 760
694/*! scroll down `n' lines within current region. 761/*! scroll down `n' lines within current region.
695 The `n' new lines are cleared. 762 The `n' new lines are cleared.
696 \sa setRegion \sa scrollUp 763 \sa setRegion \sa scrollUp
697*/ 764*/
698 765
699void TEScreen::scrollDown(int from, int n) 766void TEScreen::scrollDown(int from, int n)
700{ 767{
768
701//FIXME: make sure `tmargin', `bmargin', `from', `n' is in bounds. 769//FIXME: make sure `tmargin', `bmargin', `from', `n' is in bounds.
702 if (n <= 0) return; 770 if (n <= 0) return;
703 if (from > bmargin) return; 771 if (from > bmargin) return;
704 if (from + n > bmargin) n = bmargin - from; 772 if (from + n > bmargin) n = bmargin - from;
705 moveImage(loc(0,from+n),loc(0,from),loc(columns-1,bmargin-n)); 773
774 moveImage( loc(0,from+n), loc(0,from), loc(columns-1,bmargin-n));
706 clearImage(loc(0,from),loc(columns-1,from+n-1),' '); 775 clearImage(loc(0,from),loc(columns-1,from+n-1),' ');
707} 776}
708 777
778
779
709/*! position the cursor to a specific line and column. */ 780/*! position the cursor to a specific line and column. */
710void TEScreen::setCursorYX(int y, int x) 781void TEScreen::setCursorYX(int y, int x)
711{ 782{
712 setCursorY(y); setCursorX(x); 783 setCursorY(y); setCursorX(x);
713} 784}
714 785
715/*! Set the cursor to x-th line. */ 786/*! Set the cursor to x-th line. */
716 787
717void TEScreen::setCursorX(int x) 788void TEScreen::setCursorX(int x)
718{ 789{
719 if (x == 0) x = 1; // Default 790 if (x == 0) x = 1; // Default
720 x -= 1; // Adjust 791 x -= 1; // Adjust
721 cuX = QMAX(0,QMIN(columns-1, x)); 792 cuX = QMAX(0,QMIN(columns-1, x));
722} 793}
723 794
724/*! Set the cursor to y-th line. */ 795/*! Set the cursor to y-th line. */
725 796
726void TEScreen::setCursorY(int y) 797void TEScreen::setCursorY(int y)
727{ 798{
728 if (y == 0) y = 1; // Default 799 if (y == 0) y = 1; // Default
729 y -= 1; // Adjust 800 y -= 1; // Adjust
730 cuY = QMAX(0,QMIN(lines -1, y + (getMode(MODE_Origin) ? tmargin : 0) )); 801 cuY = QMAX(0,QMIN(lines -1, y + (getMode(MODE_Origin) ? tmargin : 0) ));
731} 802}
732 803
733/*! set cursor to the `left upper' corner of the screen (1,1). 804/*! set cursor to the `left upper' corner of the screen (1,1).
734*/ 805*/
735 806
736void TEScreen::home() 807void TEScreen::home()
737{ 808{
738 cuX = 0; 809 cuX = 0;
739 cuY = 0; 810 cuY = 0;
740} 811}
741 812
742/*! set cursor to the begin of the current line. 813/*! set cursor to the begin of the current line.
743*/ 814*/
744 815
745void TEScreen::Return() 816void TEScreen::Return()
746{ 817{
747 cuX = 0; 818 cuX = 0;
748} 819}
749 820
750/*! returns the current cursor columns. 821/*! returns the current cursor columns.
751*/ 822*/
752 823
753int TEScreen::getCursorX() 824int TEScreen::getCursorX()
754{ 825{
755 return cuX; 826 return cuX;
756} 827}
757 828
758/*! returns the current cursor line. 829/*! returns the current cursor line.
759*/ 830*/
760 831
761int TEScreen::getCursorY() 832int TEScreen::getCursorY()
762{ 833{
763 return cuY; 834 return cuY;
764} 835}
765 836
766// Erasing --------------------------------------------------------------------- 837// Erasing ---------------------------------------------------------------------
767 838
768/*! \section Erasing 839/*! \section Erasing
769 840
770 This group of operations erase parts of the screen contents by filling 841 This group of operations erase parts of the screen contents by filling
771 it with spaces colored due to the current rendition settings. 842 it with spaces colored due to the current rendition settings.
772 843
@@ -810,388 +881,398 @@ void TEScreen::clearImage(int loca, int loce, char c)
810void TEScreen::moveImage(int dst, int loca, int loce) 881void TEScreen::moveImage(int dst, int loca, int loce)
811{ 882{
812//FIXME: check positions 883//FIXME: check positions
813 if (loce < loca) { 884 if (loce < loca) {
814 // kdDebug() << "WARNING!!! call to TEScreen:moveImage with loce < loca!" << endl; 885 // kdDebug() << "WARNING!!! call to TEScreen:moveImage with loce < loca!" << endl;
815 return; 886 return;
816 } 887 }
817 memmove(&image[dst],&image[loca],(loce-loca+1)*sizeof(ca)); 888 memmove(&image[dst],&image[loca],(loce-loca+1)*sizeof(ca));
818} 889}
819 890
820/*! clear from (including) current cursor position to end of screen. 891/*! clear from (including) current cursor position to end of screen.
821*/ 892*/
822 893
823void TEScreen::clearToEndOfScreen() 894void TEScreen::clearToEndOfScreen()
824{ 895{
825 clearImage(loc(cuX,cuY),loc(columns-1,lines-1),' '); 896 clearImage(loc(cuX,cuY),loc(columns-1,lines-1),' ');
826} 897}
827 898
828/*! clear from begin of screen to (including) current cursor position. 899/*! clear from begin of screen to (including) current cursor position.
829*/ 900*/
830 901
831void TEScreen::clearToBeginOfScreen() 902void TEScreen::clearToBeginOfScreen()
832{ 903{
833 clearImage(loc(0,0),loc(cuX,cuY),' '); 904 clearImage(loc(0,0),loc(cuX,cuY),' ');
834} 905}
835 906
836/*! clear the entire screen. 907/*! clear the entire screen.
837*/ 908*/
838 909
839void TEScreen::clearEntireScreen() 910void TEScreen::clearEntireScreen()
840{ 911{
841 clearImage(loc(0,0),loc(columns-1,lines-1),' '); 912 clearImage(loc(0,0),loc(columns-1,lines-1),' ');
842} 913}
843 914
844/*! fill screen with 'E' 915/*! fill screen with 'E'
845 This is to aid screen alignment 916 This is to aid screen alignment
846*/ 917*/
847 918
848void TEScreen::helpAlign() 919void TEScreen::helpAlign()
849{ 920{
850 clearImage(loc(0,0),loc(columns-1,lines-1),'E'); 921 clearImage(loc(0,0),loc(columns-1,lines-1),'E');
851} 922}
852 923
853/*! clear from (including) current cursor position to end of current cursor line. 924/*! clear from (including) current cursor position to end of current cursor line.
854*/ 925*/
855 926
856void TEScreen::clearToEndOfLine() 927void TEScreen::clearToEndOfLine()
857{ 928{
858 clearImage(loc(cuX,cuY),loc(columns-1,cuY),' '); 929 clearImage(loc(cuX,cuY),loc(columns-1,cuY),' ');
859} 930}
860 931
861/*! clear from begin of current cursor line to (including) current cursor position. 932/*! clear from begin of current cursor line to (including) current cursor position.
862*/ 933*/
863 934
864void TEScreen::clearToBeginOfLine() 935void TEScreen::clearToBeginOfLine()
865{ 936{
866 clearImage(loc(0,cuY),loc(cuX,cuY),' '); 937 clearImage(loc(0,cuY),loc(cuX,cuY),' ');
867} 938}
868 939
869/*! clears entire current cursor line 940/*! clears entire current cursor line
870*/ 941*/
871 942
872void TEScreen::clearEntireLine() 943void TEScreen::clearEntireLine()
873{ 944{
874 clearImage(loc(0,cuY),loc(columns-1,cuY),' '); 945 clearImage( loc( 0, cuY),loc( columns - 1, cuY),' ');
875} 946}
876 947
877// Rendition ------------------------------------------------------------------ 948// Rendition ------------------------------------------------------------------
878 949
879/*! 950/*!
880 set rendition mode 951 set rendition mode
881*/ 952*/
882 953
883void TEScreen::setRendition(int re) 954void TEScreen::setRendition(int re)
884{ 955{
885 cu_re |= re; 956 cu_re |= re;
886 effectiveRendition(); 957 effectiveRendition();
887} 958}
888 959
889/*! 960/*!
890 reset rendition mode 961 reset rendition mode
891*/ 962*/
892 963
893void TEScreen::resetRendition(int re) 964void TEScreen::resetRendition(int re)
894{ 965{
895 cu_re &= ~re; 966 cu_re &= ~re;
896 effectiveRendition(); 967 effectiveRendition();
897} 968}
898 969
899/*! 970/*!
900*/ 971*/
901 972
902void TEScreen::setDefaultRendition() 973void TEScreen::setDefaultRendition()
903{ 974{
904 setForeColorToDefault(); 975 setForeColorToDefault();
905 setBackColorToDefault(); 976 setBackColorToDefault();
906 cu_re = DEFAULT_RENDITION; 977 cu_re = DEFAULT_RENDITION;
907 effectiveRendition(); 978 effectiveRendition();
908} 979}
909 980
910/*! 981/*!
911*/ 982*/
912 983
913void TEScreen::setForeColor(int fgcolor) 984void TEScreen::setForeColor(int fgcolor)
914{ 985{
915 cu_fg = (fgcolor&7)+((fgcolor&8) ? 4+8 : 2); 986 cu_fg = (fgcolor&7)+((fgcolor&8) ? 4+8 : 2);
916 effectiveRendition(); 987 effectiveRendition();
917} 988}
918 989
919/*! 990/*!
920*/ 991*/
921 992
922void TEScreen::setBackColor(int bgcolor) 993void TEScreen::setBackColor(int bgcolor)
923{ 994{
924 cu_bg = (bgcolor&7)+((bgcolor&8) ? 4+8 : 2); 995 cu_bg = (bgcolor&7)+((bgcolor&8) ? 4+8 : 2);
925 effectiveRendition(); 996 effectiveRendition();
926} 997}
927 998
928/*! 999/*!
929*/ 1000*/
930 1001
931void TEScreen::setBackColorToDefault() 1002void TEScreen::setBackColorToDefault()
932{ 1003{
933 cu_bg = DEFAULT_BACK_COLOR; 1004 cu_bg = DEFAULT_BACK_COLOR;
934 effectiveRendition(); 1005 effectiveRendition();
935} 1006}
936 1007
937/*! 1008/*!
938*/ 1009*/
939 1010
940void TEScreen::setForeColorToDefault() 1011void TEScreen::setForeColorToDefault()
941{ 1012{
942 cu_fg = DEFAULT_FORE_COLOR; 1013 cu_fg = DEFAULT_FORE_COLOR;
943 effectiveRendition(); 1014 effectiveRendition();
944} 1015}
945 1016
946/* ------------------------------------------------------------------------- */ 1017/* ------------------------------------------------------------------------- */
947/* */ 1018/* */
948/* Marking & Selection */ 1019/* Marking & Selection */
949/* */ 1020/* */
950/* ------------------------------------------------------------------------- */ 1021/* ------------------------------------------------------------------------- */
951 1022
952void TEScreen::clearSelection() 1023void TEScreen::clearSelection()
953{ 1024{
954 sel_BR = -1; 1025 sel_BR = -1;
955 sel_TL = -1; 1026 sel_TL = -1;
956 sel_begin = -1; 1027 sel_begin = -1;
957} 1028}
958 1029
959void TEScreen::setSelBeginXY(const int x, const int y) 1030void TEScreen::setSelBeginXY(const int x, const int y)
960{ 1031{
961 sel_begin = loc(x,y+histCursor) ; 1032 sel_begin = loc(x,y+histCursor) ;
962 sel_BR = sel_begin; 1033 sel_BR = sel_begin;
963 sel_TL = sel_begin; 1034 sel_TL = sel_begin;
964} 1035}
965 1036
966void TEScreen::setSelExtentXY(const int x, const int y) 1037void TEScreen::setSelExtentXY(const int x, const int y)
967{ 1038{
968 if (sel_begin == -1) return; 1039 if (sel_begin == -1) return;
969 int l = loc(x,y + histCursor); 1040 int l = loc(x,y + histCursor);
970 1041
971 if (l < sel_begin) 1042 if (l < sel_begin)
972 { 1043 {
973 sel_TL = l; 1044 sel_TL = l;
974 sel_BR = sel_begin; 1045 sel_BR = sel_begin;
975 } 1046 }
976 else 1047 else
977 { 1048 {
978 /* FIXME, HACK to correct for x too far to the right... */ 1049 /* FIXME, HACK to correct for x too far to the right... */
979 if (( x == columns )|| (x == 0)) l--; 1050 if (( x == columns )|| (x == 0)) l--;
980 1051
981 sel_TL = sel_begin; 1052 sel_TL = sel_begin;
982 sel_BR = l; 1053 sel_BR = l;
983 } 1054 }
984} 1055}
985 1056
986QString TEScreen::getSelText(const BOOL preserve_line_breaks) 1057QString TEScreen::getSelText(const BOOL preserve_line_breaks)
987{ 1058{
988 if (sel_begin == -1) 1059 if (sel_begin == -1)
989 return QString::null; // Selection got clear while selecting. 1060 return QString::null; // Selection got clear while selecting.
990 1061
991 int *m; // buffer to fill. 1062 int *m; // buffer to fill.
992 int s, d; // source index, dest. index. 1063 int s, d; // source index, dest. index.
993 int hist_BR = loc(0, hist.getLines()); 1064 int hist_BR = loc(0, hist.getLines());
994 int hY = sel_TL / columns; 1065 int hY = sel_TL / columns;
995 int hX = sel_TL % columns; 1066 int hX = sel_TL % columns;
996 int eol; // end of line 1067 int eol; // end of line
997 1068
998 s = sel_TL; // tracks copy in source. 1069 s = sel_TL; // tracks copy in source.
999 1070
1000 // allocate buffer for maximum 1071 // allocate buffer for maximum
1001 // possible size... 1072 // possible size...
1002 d = (sel_BR - sel_TL) / columns + 1; 1073 d = (sel_BR - sel_TL) / columns + 1;
1003 m = new int[d * (columns + 1) + 2]; 1074 m = new int[d * (columns + 1) + 2];
1004 d = 0; 1075 d = 0;
1005 1076
1006 while (s <= sel_BR) 1077 while (s <= sel_BR)
1007 { 1078 {
1008 if (s < hist_BR) 1079 if (s < hist_BR)
1009 { // get lines from hist.history 1080 { // get lines from hist.history
1010 // buffer. 1081 // buffer.
1011 eol = hist.getLineLen(hY); 1082 eol = hist.getLineLen(hY);
1012 1083
1013 if ((hY == (sel_BR / columns)) && 1084 if ((hY == (sel_BR / columns)) &&
1014 (eol >= (sel_BR % columns))) 1085 (eol >= (sel_BR % columns)))
1015 { 1086 {
1016 eol = sel_BR % columns + 1; 1087 eol = sel_BR % columns + 1;
1017 } 1088 }
1018 1089
1019 while (hX < eol) 1090 while (hX < eol)
1020 { 1091 {
1021 m[d++] = hist.getCell(hY, hX++).c; 1092 m[d++] = hist.getCell(hY, hX++).c;
1022 s++; 1093 s++;
1023 } 1094 }
1024 1095
1025 if (s <= sel_BR) 1096 if (s <= sel_BR)
1026 { 1097 {
1027 // The line break handling 1098 // The line break handling
1028 // It's different from the screen 1099 // It's different from the screen
1029 // image case! 1100 // image case!
1030 if (eol % columns == 0) 1101 if (eol % columns == 0)
1031 { 1102 {
1032 // That's either a completely filled 1103 // That's either a completely filled
1033 // line or an empty line 1104 // line or an empty line
1034 if (eol == 0) 1105 if (eol == 0)
1035 { 1106 {
1036 m[d++] = '\n'; 1107 m[d++] = '\n';
1037 } 1108 }
1038 else 1109 else
1039 { 1110 {
1040 // We have a full line. 1111 // We have a full line.
1041 // FIXME: How can we handle newlines 1112 // FIXME: How can we handle newlines
1042 // at this position?! 1113 // at this position?!
1043 } 1114 }
1044 } 1115 }
1045 else if ((eol + 1) % columns == 0) 1116 else if ((eol + 1) % columns == 0)
1046 { 1117 {
1047 // FIXME: We don't know if this was a 1118 // FIXME: We don't know if this was a
1048 // space at the last position or a 1119 // space at the last position or a
1049 // short line!! 1120 // short line!!
1050 m[d++] = ' '; 1121 m[d++] = ' ';
1051 } 1122 }
1052 else 1123 else
1053 { 1124 {
1054 // We have a short line here. Put a 1125 // We have a short line here. Put a
1055 // newline or a space into the 1126 // newline or a space into the
1056 // buffer. 1127 // buffer.
1057 m[d++] = preserve_line_breaks ? '\n' : ' '; 1128 m[d++] = preserve_line_breaks ? '\n' : ' ';
1058 } 1129 }
1059 } 1130 }
1060 1131
1061 hY++; 1132 hY++;
1062 hX = 0; 1133 hX = 0;
1063 s = hY * columns; 1134 s = hY * columns;
1064 } 1135 }
1065 else 1136 else
1066 { // or from screen image. 1137 { // or from screen image.
1067 eol = (s / columns + 1) * columns - 1; 1138 eol = (s / columns + 1) * columns - 1;
1068 1139
1069 if (eol < sel_BR) 1140 if (eol < sel_BR)
1070 { 1141 {
1071 while ((eol > s) && 1142 while ((eol > s) &&
1072 isspace(image[eol - hist_BR].c)) 1143 isspace(image[eol - hist_BR].c))
1073 { 1144 {
1074 eol--; 1145 eol--;
1075 } 1146 }
1076 } 1147 }
1077 else 1148 else
1078 { 1149 {
1079 eol = sel_BR; 1150 eol = sel_BR;
1080 } 1151 }
1081 1152
1082 while (s <= eol) 1153 while (s <= eol)
1083 { 1154 {
1084 m[d++] = image[s++ - hist_BR].c; 1155 m[d++] = image[s++ - hist_BR].c;
1085 } 1156 }
1086 1157
1087 if (eol < sel_BR) 1158 if (eol < sel_BR)
1088 { 1159 {
1089 // eol processing see below ... 1160 // eol processing see below ...
1090 if ((eol + 1) % columns == 0) 1161 if ((eol + 1) % columns == 0)
1091 { 1162 {
1092 if (image[eol - hist_BR].c == ' ') 1163 if (image[eol - hist_BR].c == ' ')
1093 { 1164 {
1094 m[d++] = ' '; 1165 m[d++] = ' ';
1095 } 1166 }
1096 } 1167 }
1097 else 1168 else
1098 { 1169 {
1099 m[d++] = ((preserve_line_breaks || 1170 m[d++] = ((preserve_line_breaks ||
1100 ((eol % columns) == 0)) ? 1171 ((eol % columns) == 0)) ?
1101 '\n' : ' '); 1172 '\n' : ' ');
1102 } 1173 }
1103 } 1174 }
1104 1175
1105 s = (eol / columns + 1) * columns; 1176 s = (eol / columns + 1) * columns;
1106 } 1177 }
1107 } 1178 }
1108 1179
1109 QChar* qc = new QChar[d]; 1180 QChar* qc = new QChar[d];
1110 1181
1111 for (int i = 0; i < d; i++) 1182 for (int i = 0; i < d; i++)
1112 { 1183 {
1113 qc[i] = m[i]; 1184 qc[i] = m[i];
1114 } 1185 }
1115 1186
1116 QString res(qc, d); 1187 QString res(qc, d);
1117 1188
1118 delete m; 1189 delete m;
1119 delete qc; 1190 delete qc;
1120 1191
1121 return res; 1192 return res;
1122} 1193}
1123/* above ... end of line processing for selection -- psilva 1194/* above ... end of line processing for selection -- psilva
1124cases: 1195cases:
1125 1196
11261) (eol+1)%columns == 0 --> the whole line is filled. 11971) (eol+1)%columns == 0 --> the whole line is filled.
1127 If the last char is a space, insert (preserve) space. otherwise 1198 If the last char is a space, insert (preserve) space. otherwise
1128 leave the text alone, so that words that are broken by linewrap 1199 leave the text alone, so that words that are broken by linewrap
1129 are preserved. 1200 are preserved.
1130 1201
1131FIXME: 1202FIXME:
1132 * this suppresses \n for command output that is 1203 * this suppresses \n for command output that is
1133 sized to the exact column width of the screen. 1204 sized to the exact column width of the screen.
1134 1205
11352) eol%columns == 0 --> blank line. 12062) eol%columns == 0 --> blank line.
1136 insert a \n unconditionally. 1207 insert a \n unconditionally.
1137 Do it either you would because you are in preserve_line_break mode, 1208 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 1209 or because it's an ASCII paragraph delimiter, so even when
1139 not preserving line_breaks, you want to preserve paragraph breaks. 1210 not preserving line_breaks, you want to preserve paragraph breaks.
1140 1211
1141 3) else --> partially filled line 12123) else --> partially filled line
1142 insert a \n in preserve line break mode, else a space 1213 insert a \n in preserve line break mode, else a space
1143 The space prevents concatenation of the last word of one 1214 The space prevents concatenation of the last word of one
1144 line with the first of the next. 1215 line with the first of the next.
1145 1216
1146*/ 1217*/
1147 1218
1148void TEScreen::addHistLine() 1219void TEScreen::addHistLine()
1149{ 1220{
1150 assert(hasScroll() || histCursor == 0); 1221 assert(hasScroll() || histCursor == 0);
1151 1222
1152 // add to hist buffer 1223 // add to hist buffer
1153 // we have to take care about scrolling, too... 1224 // we have to take care about scrolling, too...
1154 1225
1155 if (hasScroll()) 1226 if (hasScroll()){
1156 { ca dft; 1227 ca dft;
1157 1228
1158 int end = columns-1; 1229 int end = columns - 1;
1159 while (end >= 0 && image[end] == dft) 1230 while (end >= 0 && image[end] == dft)
1160 end -= 1; 1231 end -= 1;
1161 1232
1162 hist.addCells(image,end+1); 1233 hist.addCells( image, end + 1);
1163 hist.addLine(); 1234 hist.addLine();
1164 1235
1165 // adjust history cursor 1236 // adjust history cursor
1166 histCursor += (hist.getLines()-1 == histCursor); 1237 histCursor += ( hist.getLines() - 1 == histCursor);
1167 } 1238 }
1168 1239
1169 if (!hasScroll()) histCursor = 0; //FIXME: a poor workaround 1240 if (!hasScroll()) histCursor = 0; //FIXME: a poor workaround
1170} 1241}
1171 1242
1172void TEScreen::setHistCursor(int cursor) 1243void TEScreen::setHistCursor(int cursor)
1173{ 1244{
1174 histCursor = cursor; //FIXME:rangecheck 1245 histCursor = cursor; //FIXME:rangecheck
1175} 1246}
1176 1247
1248void TEScreen::setHorzCursor(int cursor)
1249{
1250 horzCursor = cursor;
1251}
1252
1177int TEScreen::getHistCursor() 1253int TEScreen::getHistCursor()
1178{ 1254{
1179 return histCursor; 1255 return histCursor;
1180} 1256}
1181 1257
1258int TEScreen::getHorzCursor()
1259{
1260 return horzCursor;
1261}
1262
1182int TEScreen::getHistLines() 1263int TEScreen::getHistLines()
1183{ 1264{
1184 return hist.getLines(); 1265 return hist.getLines();
1185} 1266}
1186 1267
1187void TEScreen::setScroll(bool on) 1268void TEScreen::setScroll(bool on)
1188{ 1269{
1189 histCursor = 0; 1270 histCursor = 0;
1190 clearSelection(); 1271 clearSelection();
1191 hist.setScroll(on); 1272 hist.setScroll(on);
1192} 1273}
1193 1274
1194bool TEScreen::hasScroll() 1275bool TEScreen::hasScroll()
1195{ 1276{
1196 return hist.hasScroll(); 1277 return hist.hasScroll();
1197} 1278}
diff --git a/core/apps/embeddedkonsole/TEWidget.cpp b/core/apps/embeddedkonsole/TEWidget.cpp
index b1ad008..c10c7a8 100644
--- a/core/apps/embeddedkonsole/TEWidget.cpp
+++ b/core/apps/embeddedkonsole/TEWidget.cpp
@@ -1,118 +1,125 @@
1/* ------------------------------------------------------------------------ */ 1/* ------------------------------------------------------------------------ */
2/* */ 2/* */
3/* [TEWidget.C] Terminal Emulation Widget */ 3/* [TEWidget.C] Terminal Emulation Widget */
4/* */ 4/* */
5/* ------------------------------------------------------------------------ */ 5/* ------------------------------------------------------------------------ */
6/* */ 6/* */
7/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */ 7/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */
8/* */ 8/* */
9/* This file is part of Konsole - an X terminal for KDE */ 9/* This file is part of Konsole - an X terminal for KDE */
10/* */ 10/* */
11/* ------------------------------------------------------------------------ */ 11/* ------------------------------------------------------------------------ */
12/* */ 12/* */
13/* Ported Konsole to Qt/Embedded */ 13/* Ported Konsole to Qt/Embedded */
14/* */ 14/* */
15/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */ 15/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */
16/* */ 16/* */
17/* -------------------------------------------------------------------------- */ 17/* -------------------------------------------------------------------------- */
18/*! \class TEWidget 18/*! \class TEWidget
19 19
20 \brief Visible screen contents 20 \brief Visible screen contents
21 21
22 This class is responsible to map the `image' of a terminal emulation to the 22 This class is responsible to map the `image' of a terminal emulation to the
23 display. All the dependency of the emulation to a specific GUI or toolkit is 23 display. All the dependency of the emulation to a specific GUI or toolkit is
24 localized here. Further, this widget has no knowledge about being part of an 24 localized here. Further, this widget has no knowledge about being part of an
25 emulation, it simply work within the terminal emulation framework by exposing 25 emulation, it simply work within the terminal emulation framework by exposing
26 size and key events and by being ordered to show a new image. 26 size and key events and by being ordered to show a new image.
27 27
28 <ul> 28 <ul>
29 <li> The internal image has the size of the widget (evtl. rounded up) 29 <li> The internal image has the size of the widget (evtl. rounded up)
30 <li> The external image used in setImage can have any size. 30 <li> The external image used in setImage can have any size.
31 <li> (internally) the external image is simply copied to the internal 31 <li> (internally) the external image is simply copied to the internal
32 when a setImage happens. During a resizeEvent no painting is done 32 when a setImage happens. During a resizeEvent no painting is done
33 a paintEvent is expected to follow anyway. 33 a paintEvent is expected to follow anyway.
34 </ul> 34 </ul>
35 35
36 \sa TEScreen \sa Emulation 36 \sa TEScreen \sa Emulation
37*/ 37*/
38 38
39/* FIXME: 39/* FIXME:
40 - 'image' may also be used uninitialized (it isn't in fact) in resizeEvent 40 - 'image' may also be used uninitialized (it isn't in fact) in resizeEvent
41 - 'font_a' not used in mouse events 41 - 'font_a' not used in mouse events
42 - add destructor 42 - add destructor
43*/ 43*/
44 44
45/* TODO 45/* TODO
46 - evtl. be sensitive to `paletteChange' while using default colors. 46 - evtl. be sensitive to `paletteChange' while using default colors.
47 - set different 'rounding' styles? I.e. have a mode to show clipped chars? 47 - set different 'rounding' styles? I.e. have a mode to show clipped chars?
48*/ 48*/
49 49
50// #include "config.h" 50// #include "config.h"
51#include "TEWidget.h" 51#include "TEWidget.h"
52#include "session.h" 52#include "session.h"
53#include <qpe/config.h> 53#include <qpe/config.h>
54 54
55#include <qpe/resource.h>
56#include <qpe/sound.h>
57
58#ifdef QWS
59#include <qpe/qcopenvelope_qws.h>
60#endif
61
55#include <qcursor.h> 62#include <qcursor.h>
56#include <qregexp.h> 63#include <qregexp.h>
57#include <qpainter.h> 64#include <qpainter.h>
58#include <qclipboard.h> 65#include <qclipboard.h>
59#include <qstyle.h> 66#include <qstyle.h>
60#include <qfile.h> 67#include <qfile.h>
61#include <qdragobject.h> 68#include <qdragobject.h>
62 69
63#include <stdio.h> 70#include <stdio.h>
64#include <stdlib.h> 71#include <stdlib.h>
65#include <unistd.h> 72#include <unistd.h>
66#include <ctype.h> 73#include <ctype.h>
67#include <sys/stat.h> 74#include <sys/stat.h>
68#include <sys/types.h> 75#include <sys/types.h>
69#include <signal.h> 76#include <signal.h>
70 77
71#include <assert.h> 78#include <assert.h>
72 79
73// #include "TEWidget.moc" 80// #include "TEWidget.moc"
74//#include <kapp.h> 81//#include <kapp.h>
75//#include <kcursor.h> 82//#include <kcursor.h>
76//#include <kurl.h> 83//#include <kurl.h>
77//#include <kdebug.h> 84//#include <kdebug.h>
78//#include <klocale.h> 85//#include <klocale.h>
79 86
80#define HERE printf("%s(%d): %s\n",__FILE__,__LINE__,__FUNCTION__) 87#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++); } 88#define HCNT(Name) // { static int cnt = 1; printf("%s(%d): %s %d\n",__FILE__,__LINE__,Name,cnt++); }
82 89
83#define loc(X,Y) ((Y)*columns+(X)) 90#define loc(X,Y) ((Y)*columns+(X))
84 91
85//FIXME: the rim should normally be 1, 0 only when running in full screen mode. 92//FIXME: the rim should normally be 1, 0 only when running in full screen mode.
86#define rimX 0 // left/right rim width 93#define rimX 0 // left/right rim width
87#define rimY 0 // top/bottom rim high 94#define rimY 0 // top/bottom rim high
88 95
89#define SCRWIDTH 16 // width of the scrollbar 96#define SCRWIDTH 16 // width of the scrollbar
90 97
91#define yMouseScroll 1 98#define yMouseScroll 1
92// scroll increment used when dragging selection at top/bottom of window. 99// scroll increment used when dragging selection at top/bottom of window.
93 100
94/* ------------------------------------------------------------------------- */ 101/* ------------------------------------------------------------------------- */
95/* */ 102/* */
96/* Colors */ 103/* Colors */
97/* */ 104/* */
98/* ------------------------------------------------------------------------- */ 105/* ------------------------------------------------------------------------- */
99 106
100//FIXME: the default color table is in session.C now. 107//FIXME: the default color table is in session.C now.
101// We need a way to get rid of this one, here. 108// We need a way to get rid of this one, here.
102static const ColorEntry base_color_table[TABLE_COLORS] = 109static const ColorEntry base_color_table[TABLE_COLORS] =
103// The following are almost IBM standard color codes, with some slight 110// The following are almost IBM standard color codes, with some slight
104// gamma correction for the dim colors to compensate for bright X screens. 111// gamma correction for the dim colors to compensate for bright X screens.
105// It contains the 8 ansiterm/xterm colors in 2 intensities. 112// It contains the 8 ansiterm/xterm colors in 2 intensities.
106{ 113{
107 // Fixme: could add faint colors here, also. 114 // Fixme: could add faint colors here, also.
108 // normal 115 // normal
109 ColorEntry(QColor(0x00,0x00,0x00), 0, 0 ), ColorEntry( QColor(0xB2,0xB2,0xB2), 1, 0 ), // Dfore, Dback 116 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 117 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 118 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 119 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 120 ColorEntry(QColor(0x18,0xB2,0xB2), 0, 0 ), ColorEntry( QColor(0xB2,0xB2,0xB2), 0, 0 ), // Cyan, White
114 // intensiv 121 // intensiv
115 ColorEntry(QColor(0x00,0x00,0x00), 0, 1 ), ColorEntry( QColor(0xFF,0xFF,0xFF), 1, 0 ), 122 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 ), 123 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 ), 124 ColorEntry(QColor(0x54,0xFF,0x54), 0, 0 ), ColorEntry( QColor(0xFF,0xFF,0x54), 0, 0 ),
118 ColorEntry(QColor(0x54,0x54,0xFF), 0, 0 ), ColorEntry( QColor(0xB2,0x18,0xB2), 0, 0 ), 125 ColorEntry(QColor(0x54,0x54,0xFF), 0, 0 ), ColorEntry( QColor(0xB2,0x18,0xB2), 0, 0 ),
@@ -226,255 +233,262 @@ static QChar vt100extended(QChar c)
226 case 0x00b7 : return 31; 233 case 0x00b7 : return 31;
227 } 234 }
228 return c; 235 return c;
229} 236}
230 237
231static QChar identicalMap(QChar c) 238static QChar identicalMap(QChar c)
232{ 239{
233 return c; 240 return c;
234} 241}
235 242
236void TEWidget::fontChange(const QFont &) 243void TEWidget::fontChange(const QFont &)
237{ 244{
238 QFontMetrics fm(font()); 245 QFontMetrics fm(font());
239 font_h = fm.height(); 246 font_h = fm.height();
240 font_w = fm.maxWidth(); 247 font_w = fm.maxWidth();
241 font_a = fm.ascent(); 248 font_a = fm.ascent();
242//printf("font_h: %d\n",font_h); 249//printf("font_h: %d\n",font_h);
243//printf("font_w: %d\n",font_w); 250//printf("font_w: %d\n",font_w);
244//printf("font_a: %d\n",font_a); 251//printf("font_a: %d\n",font_a);
245//printf("charset: %s\n",QFont::encodingName(font().charSet()).ascii()); 252//printf("charset: %s\n",QFont::encodingName(font().charSet()).ascii());
246//printf("rawname: %s\n",font().rawName().ascii()); 253//printf("rawname: %s\n",font().rawName().ascii());
247 fontMap = 254 fontMap =
248#if QT_VERSION < 300 255#if QT_VERSION < 300
249 strcmp(QFont::encodingName(font().charSet()).ascii(),"iso10646") 256 strcmp(QFont::encodingName(font().charSet()).ascii(),"iso10646")
250 ? vt100extended 257 ? vt100extended
251 : 258 :
252#endif 259#endif
253 identicalMap; 260 identicalMap;
254 propagateSize(); 261 propagateSize();
255 update(); 262 update();
256} 263}
257 264
258void TEWidget::setVTFont(const QFont& f) 265void TEWidget::setVTFont(const QFont& f)
259{ 266{
260 QFrame::setFont(f); 267 QFrame::setFont(f);
261} 268}
262 269
263QFont TEWidget::getVTFont() { 270QFont TEWidget::getVTFont() {
264 return font(); 271 return font();
265} 272}
266 273
267void TEWidget::setFont(const QFont &) 274void TEWidget::setFont(const QFont &)
268{ 275{
269 // ignore font change request if not coming from konsole itself 276 // ignore font change request if not coming from konsole itself
270} 277}
271 278
272/* ------------------------------------------------------------------------- */ 279/* ------------------------------------------------------------------------- */
273/* */ 280/* */
274/* Constructor / Destructor */ 281/* Constructor / Destructor */
275/* */ 282/* */
276/* ------------------------------------------------------------------------- */ 283/* ------------------------------------------------------------------------- */
277 284
278TEWidget::TEWidget(QWidget *parent, const char *name) : QFrame(parent,name) 285TEWidget::TEWidget(QWidget *parent, const char *name) : QFrame(parent,name)
279{ 286{
280#ifndef QT_NO_CLIPBOARD 287#ifndef QT_NO_CLIPBOARD
281 cb = QApplication::clipboard(); 288 cb = QApplication::clipboard();
282 QObject::connect( (QObject*)cb, SIGNAL(dataChanged()), 289 QObject::connect( (QObject*)cb, SIGNAL(dataChanged()),
283 this, SLOT(onClearSelection()) ); 290 this, SLOT(onClearSelection()) );
284#endif 291#endif
285 292
286 scrollbar = new QScrollBar(this); 293 scrollbar = new QScrollBar(this);
287 scrollbar->setCursor( arrowCursor ); 294 scrollbar->setCursor( arrowCursor );
288 connect(scrollbar, SIGNAL(valueChanged(int)), this, SLOT(scrollChanged(int))); 295 connect(scrollbar, SIGNAL(valueChanged(int)), this, SLOT(scrollChanged(int)));
289 296
297 hScrollbar = new QScrollBar(this);
298 hScrollbar->setCursor( arrowCursor );
299 hScrollbar->setOrientation(QScrollBar::Horizontal);
300 hScrollbar->setMaximumHeight(16);
301
302 connect( hScrollbar, SIGNAL(valueChanged(int)), this, SLOT( hScrollChanged(int)));
303
290 Config cfg("Konsole"); 304 Config cfg("Konsole");
291 cfg.setGroup("ScrollBar"); 305 cfg.setGroup("ScrollBar");
292 switch( cfg.readNumEntry("Position",2)){ 306 switch( cfg.readNumEntry("Position",2)){
293 case 0: 307 case 0:
294 scrollLoc = SCRNONE; 308 scrollLoc = SCRNONE;
295 break; 309 break;
296 case 1: 310 case 1:
297 scrollLoc = SCRLEFT; 311 scrollLoc = SCRLEFT;
298 break; 312 break;
299 case 2: 313 case 2:
300 scrollLoc = SCRRIGHT; 314 scrollLoc = SCRRIGHT;
301 break; 315 break;
302 }; 316 };
303 317
318 useHorzScroll=cfg.readBoolEntry("HorzScroll",0);
319
304 blinkT = new QTimer(this); 320 blinkT = new QTimer(this);
305 connect(blinkT, SIGNAL(timeout()), this, SLOT(blinkEvent())); 321 connect(blinkT, SIGNAL(timeout()), this, SLOT(blinkEvent()));
306 // blinking = FALSE; 322 // blinking = FALSE;
307 blinking = TRUE; 323 blinking = TRUE;
308 324
309 resizing = FALSE; 325 resizing = FALSE;
310 actSel = 0; 326 actSel = 0;
311 image = 0; 327 image = 0;
312 lines = 1; 328 lines = 1;
313 columns = 1; 329 columns = 1;
314 font_w = 1; 330 font_w = 1;
315 font_h = 1; 331 font_h = 1;
316 font_a = 1; 332 font_a = 1;
317 word_selection_mode = FALSE; 333 word_selection_mode = FALSE;
334 hposition = 0;
318 335
319 setMouseMarks(TRUE); 336 setMouseMarks(TRUE);
320 setVTFont( QFont("fixed") ); 337 setVTFont( QFont("fixed") );
321 setColorTable(base_color_table); // init color table 338 setColorTable(base_color_table); // init color table
322 339
323 qApp->installEventFilter( this ); //FIXME: see below 340 qApp->installEventFilter( this ); //FIXME: see below
324// KCursor::setAutoHideCursor( this, true ); 341// KCursor::setAutoHideCursor( this, true );
325 342
326 // Init DnD //////////////////////////////////////////////////////////////// 343 // Init DnD ////////////////////////////////////////////////////////////////
327 currentSession = NULL; 344 currentSession = NULL;
328// setAcceptDrops(true); // attempt 345// setAcceptDrops(true); // attempt
329// m_drop = new QPopupMenu(this); 346// m_drop = new QPopupMenu(this);
330// m_drop->insertItem( QString("Paste"), 0); 347// m_drop->insertItem( QString("Paste"), 0);
331// m_drop->insertItem( QString("cd"), 1); 348// m_drop->insertItem( QString("cd"), 1);
332// connect(m_drop, SIGNAL(activated(int)), SLOT(drop_menu_activated(int))); 349// connect(m_drop, SIGNAL(activated(int)), SLOT(drop_menu_activated(int)));
333 350
334 // we need focus so that the auto-hide cursor feature works 351 // we need focus so that the auto-hide cursor feature works
335 setFocus(); 352 setFocus();
336 setFocusPolicy( WheelFocus ); 353 setFocusPolicy( WheelFocus );
337} 354}
338 355
339//FIXME: make proper destructor 356//FIXME: make proper destructor
340// Here's a start (David) 357// Here's a start (David)
341TEWidget::~TEWidget() 358TEWidget::~TEWidget()
342{ 359{
343 qApp->removeEventFilter( this ); 360 qApp->removeEventFilter( this );
344 if (image) free(image); 361 if (image) free(image);
345} 362}
346 363
347/* ------------------------------------------------------------------------- */ 364/* ------------------------------------------------------------------------- */
348/* */ 365/* */
349/* Display Operations */ 366/* Display Operations */
350/* */ 367/* */
351/* ------------------------------------------------------------------------- */ 368/* ------------------------------------------------------------------------- */
352 369
353/*! 370/*!
354 attributed string draw primitive 371 attributed string draw primitive
355*/ 372*/
356 373
357void TEWidget::drawAttrStr(QPainter &paint, QRect rect, 374void TEWidget::drawAttrStr(QPainter &paint, QRect rect,
358 QString& str, ca attr, BOOL pm, BOOL clear) 375 QString& str, ca attr, BOOL pm, BOOL clear)
359{ 376{
360 if (pm && color_table[attr.b].transparent) 377 if (pm && color_table[attr.b].transparent)
361 { 378 {
362 paint.setBackgroundMode( TransparentMode ); 379 paint.setBackgroundMode( TransparentMode );
363 if (clear) erase(rect); 380 if (clear) erase(rect);
364 } 381 }
365 else 382 else
366 { 383 {
367 if (blinking) 384 if (blinking)
368 paint.fillRect(rect, color_table[attr.b].color); 385 paint.fillRect(rect, color_table[attr.b].color);
369 else 386 else
370 { 387 {
371 paint.setBackgroundMode( OpaqueMode ); 388 paint.setBackgroundMode( OpaqueMode );
372 paint.setBackgroundColor( color_table[attr.b].color ); 389 paint.setBackgroundColor( color_table[attr.b].color );
373 } 390 }
374 } 391 }
375 392
376 if (color_table[attr.f].bold) 393 if (color_table[attr.f].bold)
377 paint.setPen(QColor( 0x8F, 0x00, 0x00 )); 394 paint.setPen(QColor( 0x8F, 0x00, 0x00 ));
378 else 395 else
379 paint.setPen(color_table[attr.f].color); 396 paint.setPen(color_table[attr.f].color);
380 397
381 paint.drawText(rect.x(),rect.y()+font_a, str); 398 paint.drawText(rect.x(),rect.y()+font_a, str);
382 399
383 if (attr.r & RE_UNDERLINE) 400 if (attr.r & RE_UNDERLINE)
384 paint.drawLine(rect.left(), rect.y()+font_a+1, rect.right(),rect.y()+font_a+1 ); 401 paint.drawLine(rect.left(), rect.y()+font_a+1, rect.right(),rect.y()+font_a+1 );
385} 402}
386 403
387/*! 404/*!
388 The image can only be set completely. 405 The image can only be set completely.
389 406
390 The size of the new image may or may not match the size of the widget. 407 The size of the new image may or may not match the size of the widget.
391*/ 408*/
392 409
393void TEWidget::setImage(const ca* const newimg, int lines, int columns) 410void TEWidget::setImage(const ca* const newimg, int lines, int columns)
394{ int y,x,len; 411{ int y,x,len;
395 const QPixmap* pm = backgroundPixmap(); 412 const QPixmap* pm = backgroundPixmap();
396 QPainter paint; 413 QPainter paint;
397 setUpdatesEnabled(FALSE); 414 setUpdatesEnabled(FALSE);
398 paint.begin( this ); 415 paint.begin( this );
399HCNT("setImage"); 416HCNT("setImage");
400 417
401 QPoint tL = contentsRect().topLeft(); 418 QPoint tL = contentsRect().topLeft();
402 int tLx = tL.x(); 419 int tLx = tL.x();
403 int tLy = tL.y(); 420 int tLy = tL.y();
404 hasBlinker = FALSE; 421 hasBlinker = FALSE;
405 422
406 int cf = -1; // undefined 423 int cf = -1; // undefined
407 int cb = -1; // undefined 424 int cb = -1; // undefined
408 int cr = -1; // undefined 425 int cr = -1; // undefined
409 426
410 int lins = QMIN(this->lines, QMAX(0,lines )); 427 int lins = QMIN(this->lines, QMAX(0,lines ));
411 int cols = QMIN(this->columns,QMAX(0,columns)); 428 int cols = QMIN(this->columns,QMAX(0,columns));
412 QChar *disstrU = new QChar[cols]; 429 QChar *disstrU = new QChar[cols];
413 430 for (y = 0; y < lins; y++) {
414//{ static int cnt = 0; printf("setImage %d\n",cnt++); }
415 for (y = 0; y < lins; y++)
416 {
417 const ca* lcl = &image[y*this->columns]; 431 const ca* lcl = &image[y*this->columns];
418 const ca* const ext = &newimg[y*columns]; 432 const ca* const ext = &newimg[y*columns];
419 if (!resizing) // not while resizing, we're expecting a paintEvent 433 if (!resizing) // not while resizing, we're expecting a paintEvent
420 for (x = 0; x < cols; x++) 434 for (x = 0; x < cols; x++)
421 { 435 {
422 hasBlinker |= (ext[x].r & RE_BLINK); 436 hasBlinker |= (ext[x].r & RE_BLINK);
423 if (ext[x] != lcl[x]) 437 if (ext[x] != lcl[x])
424 { 438 {
425 cr = ext[x].r; 439 cr = ext[x].r;
426 cb = ext[x].b; 440 cb = ext[x].b;
427 if (ext[x].f != cf) cf = ext[x].f; 441 if (ext[x].f != cf) cf = ext[x].f;
428 int lln = cols - x; 442 int lln = cols - x;
429 disstrU[0] = fontMap(ext[x+0].c); 443 disstrU[0] = fontMap(ext[x+0].c);
430 for (len = 1; len < lln; len++) 444 for (len = 1; len < lln; len++)
431 { 445 {
432 if (ext[x+len].f != cf || ext[x+len].b != cb || ext[x+len].r != cr || 446 if (ext[x+len].f != cf || ext[x+len].b != cb || ext[x+len].r != cr ||
433 ext[x+len] == lcl[x+len] ) 447 ext[x+len] == lcl[x+len] )
434 break; 448 break;
435 disstrU[len] = fontMap(ext[x+len].c); 449 disstrU[len] = fontMap(ext[x+len].c);
436 } 450 }
437 QString unistr(disstrU,len); 451 QString unistr(disstrU,len);
438 drawAttrStr(paint, 452 drawAttrStr(paint,
439 QRect(blX+tLx+font_w*x,bY+tLy+font_h*y,font_w*len,font_h), 453 QRect(blX+tLx+font_w*x,bY+tLy+font_h*y,font_w*len,font_h),
440 unistr, ext[x], pm != NULL, true); 454 unistr, ext[x], pm != NULL, true);
441 x += len - 1; 455 x += len - 1;
442 } 456 }
443 } 457 }
444 // finally, make `image' become `newimg'. 458 // finally, make `image' become `newimg'.
445 memcpy((void*)lcl,(const void*)ext,cols*sizeof(ca)); 459 memcpy((void*)lcl,(const void*)ext,cols*sizeof(ca));
446 } 460 }
447 drawFrame( &paint ); 461 drawFrame( &paint );
448 paint.end(); 462 paint.end();
449 setUpdatesEnabled(TRUE); 463 setUpdatesEnabled(TRUE);
450 if ( hasBlinker && !blinkT->isActive()) blinkT->start(1000); // 1000 ms 464 if ( hasBlinker && !blinkT->isActive()) blinkT->start(1000); // 1000 ms
451 if (!hasBlinker && blinkT->isActive()) { blinkT->stop(); blinking = FALSE; } 465 if (!hasBlinker && blinkT->isActive()) { blinkT->stop(); blinking = FALSE; }
452 delete [] disstrU; 466 delete [] disstrU;
453} 467}
454 468
455// paint Event //////////////////////////////////////////////////// 469// paint Event ////////////////////////////////////////////////////
456 470
457/*! 471/*!
458 The difference of this routine vs. the `setImage' is, 472 The difference of this routine vs. the `setImage' is,
459 that the drawing does not include a difference analysis 473 that the drawing does not include a difference analysis
460 between the old and the new image. Instead, the internal 474 between the old and the new image. Instead, the internal
461 image is used and the painting bound by the PaintEvent box. 475 image is used and the painting bound by the PaintEvent box.
462*/ 476*/
463 477
464void TEWidget::paintEvent( QPaintEvent* pe ) 478void TEWidget::paintEvent( QPaintEvent* pe )
465{ 479{
466 480
467//{ static int cnt = 0; printf("paint %d\n",cnt++); } 481//{ static int cnt = 0; printf("paint %d\n",cnt++); }
468 const QPixmap* pm = backgroundPixmap(); 482 const QPixmap* pm = backgroundPixmap();
469 QPainter paint; 483 QPainter paint;
470 setUpdatesEnabled(FALSE); 484 setUpdatesEnabled(FALSE);
471 paint.begin( this ); 485 paint.begin( this );
472 paint.setBackgroundMode( TransparentMode ); 486 paint.setBackgroundMode( TransparentMode );
473HCNT("paintEvent"); 487HCNT("paintEvent");
474 488
475 // Note that the actual widget size can be slightly larger 489 // Note that the actual widget size can be slightly larger
476 // that the image (the size is truncated towards the smaller 490 // that the image (the size is truncated towards the smaller
477 // number of characters in `resizeEvent'. The paint rectangle 491 // number of characters in `resizeEvent'. The paint rectangle
478 // can thus be larger than the image, but less then the size 492 // can thus be larger than the image, but less then the size
479 // of one character. 493 // of one character.
480 494
@@ -527,237 +541,245 @@ HCNT("paintEvent");
527 setUpdatesEnabled(TRUE); 541 setUpdatesEnabled(TRUE);
528} 542}
529 543
530void TEWidget::blinkEvent() 544void TEWidget::blinkEvent()
531{ 545{
532 blinking = !blinking; 546 blinking = !blinking;
533 repaint(FALSE); 547 repaint(FALSE);
534} 548}
535 549
536/* ------------------------------------------------------------------------- */ 550/* ------------------------------------------------------------------------- */
537/* */ 551/* */
538/* Resizing */ 552/* Resizing */
539/* */ 553/* */
540/* ------------------------------------------------------------------------- */ 554/* ------------------------------------------------------------------------- */
541 555
542void TEWidget::resizeEvent(QResizeEvent* ev) 556void TEWidget::resizeEvent(QResizeEvent* ev)
543{ 557{
544// printf("resize: %d,%d\n",ev->size().width(),ev->size().height()); 558// printf("resize: %d,%d\n",ev->size().width(),ev->size().height());
545 //printf("approx: %d,%d\n",ev->size().width()/font_w,ev->size().height()/font_h); 559 //printf("approx: %d,%d\n",ev->size().width()/font_w,ev->size().height()/font_h);
546 //printf("leaves: %d,%d\n",ev->size().width()%font_w,ev->size().height()%font_h); 560 //printf("leaves: %d,%d\n",ev->size().width()%font_w,ev->size().height()%font_h);
547 //printf("curren: %d,%d\n",width(),height()); 561 //printf("curren: %d,%d\n",width(),height());
548HCNT("resizeEvent"); 562HCNT("resizeEvent");
549 563
550 // see comment in `paintEvent' concerning the rounding. 564 // see comment in `paintEvent' concerning the rounding.
551 //FIXME: could make a routine here; check width(),height() 565 //FIXME: could make a routine here; check width(),height()
552 assert(ev->size().width() == width()); 566 assert(ev->size().width() == width());
553 assert(ev->size().height() == height()); 567 assert(ev->size().height() == height());
554 568
555 propagateSize(); 569 propagateSize();
556} 570}
557 571
558void TEWidget::propagateSize() 572void TEWidget::propagateSize()
559{ 573{
560 ca* oldimg = image; 574 ca* oldimg = image;
561 int oldlin = lines; 575 int oldlin = lines;
562 int oldcol = columns; 576 int oldcol = columns;
563 makeImage(); 577 makeImage();
564 // we copy the old image to reduce flicker 578 // we copy the old image to reduce flicker
565 int lins = QMIN(oldlin,lines); 579 int lins = QMIN(oldlin,lines);
566 int cols = QMIN(oldcol,columns); 580 int cols = QMIN(oldcol,columns);
567 if (oldimg) 581 if (oldimg)
568 { 582 {
569 for (int lin = 0; lin < lins; lin++) 583 for (int lin = 0; lin < lins; lin++)
570 memcpy((void*)&image[columns*lin], 584 memcpy((void*)&image[columns*lin],
571 (void*)&oldimg[oldcol*lin],cols*sizeof(ca)); 585 (void*)&oldimg[oldcol*lin],cols*sizeof(ca));
572 free(oldimg); //FIXME: try new,delete 586 free(oldimg); //FIXME: try new,delete
573 } 587 }
574 else 588 else
575 clearImage(); 589 clearImage();
576 590
577 //NOTE: control flows from the back through the chest right into the eye. 591 //NOTE: control flows from the back through the chest right into the eye.
578 // `emu' will call back via `setImage'. 592 // `emu' will call back via `setImage'.
579 593
580 resizing = TRUE; 594 resizing = TRUE;
581 emit changedImageSizeSignal(lines, columns); // expose resizeEvent 595 emit changedImageSizeSignal(lines, columns); // expose resizeEvent
582 resizing = FALSE; 596 resizing = FALSE;
583} 597}
584 598
585/* ------------------------------------------------------------------------- */ 599/* ------------------------------------------------------------------------- */
586/* */ 600/* */
587/* Scrollbar */ 601/* Scrollbar */
588/* */ 602/* */
589/* ------------------------------------------------------------------------- */ 603/* ------------------------------------------------------------------------- */
590 604
591void TEWidget::scrollChanged(int) 605void TEWidget::scrollChanged(int) {
592{
593 emit changedHistoryCursor(scrollbar->value()); //expose 606 emit changedHistoryCursor(scrollbar->value()); //expose
594} 607}
595 608
609void TEWidget::hScrollChanged(int loc) {
610 hposition = loc;
611 propagateSize();
612 update();
613
614// emit changedHorzCursor( hScrollbar->value()); //expose
615}
616
596void TEWidget::setScroll(int cursor, int slines) 617void TEWidget::setScroll(int cursor, int slines)
597{ 618{
598 disconnect(scrollbar, SIGNAL(valueChanged(int)), this, SLOT(scrollChanged(int))); 619 disconnect(scrollbar, SIGNAL(valueChanged(int)), this, SLOT(scrollChanged(int)));
599 scrollbar->setRange(0,slines); 620 scrollbar->setRange(0,slines);
600 scrollbar->setSteps(1,lines); 621 scrollbar->setSteps(1,lines);
601 scrollbar->setValue(cursor); 622 scrollbar->setValue(cursor);
602 connect(scrollbar, SIGNAL(valueChanged(int)), this, SLOT(scrollChanged(int))); 623 connect(scrollbar, SIGNAL(valueChanged(int)), this, SLOT(scrollChanged(int)));
603} 624}
604 625
605void TEWidget::setScrollbarLocation(int loc) 626void TEWidget::setScrollbarLocation(int loc)
606{ 627{
607 if (scrollLoc == loc) return; // quickly 628 if (scrollLoc == loc) return; // quickly
608 scrollLoc = loc; 629 scrollLoc = loc;
609 propagateSize(); 630 propagateSize();
610 update(); 631 update();
611} 632}
612 633
613/* ------------------------------------------------------------------------- */ 634/* ------------------------------------------------------------------------- */
614/* */ 635/* */
615/* Mouse */ 636/* Mouse */
616/* */ 637/* */
617/* ------------------------------------------------------------------------- */ 638/* ------------------------------------------------------------------------- */
618 639
619/*! 640/*!
620 Three different operations can be performed using the mouse, and the 641 Three different operations can be performed using the mouse, and the
621 routines in this section serve all of them: 642 routines in this section serve all of them:
622 643
623 1) The press/release events are exposed to the application 644 1) The press/release events are exposed to the application
624 2) Marking (press and move left button) and Pasting (press middle button) 645 2) Marking (press and move left button) and Pasting (press middle button)
625 3) The right mouse button is used from the configuration menu 646 3) The right mouse button is used from the configuration menu
626 647
627 NOTE: During the marking process we attempt to keep the cursor within 648 NOTE: During the marking process we attempt to keep the cursor within
628 the bounds of the text as being displayed by setting the mouse position 649 the bounds of the text as being displayed by setting the mouse position
629 whenever the mouse has left the text area. 650 whenever the mouse has left the text area.
630 651
631 Two reasons to do so: 652 Two reasons to do so:
632 1) QT does not allow the `grabMouse' to confine-to the TEWidget. 653 1) QT does not allow the `grabMouse' to confine-to the TEWidget.
633 Thus a `XGrapPointer' would have to be used instead. 654 Thus a `XGrapPointer' would have to be used instead.
634 2) Even if so, this would not help too much, since the text area 655 2) Even if so, this would not help too much, since the text area
635 of the TEWidget is normally not identical with it's bounds. 656 of the TEWidget is normally not identical with it's bounds.
636 657
637 The disadvantage of the current handling is, that the mouse can visibly 658 The disadvantage of the current handling is, that the mouse can visibly
638 leave the bounds of the widget and is then moved back. Because of the 659 leave the bounds of the widget and is then moved back. Because of the
639 current construction, and the reasons mentioned above, we cannot do better 660 current construction, and the reasons mentioned above, we cannot do better
640 without changing the overall construction. 661 without changing the overall construction.
641*/ 662*/
642 663
643/*! 664/*!
644*/ 665*/
645 666
646void TEWidget::mousePressEvent(QMouseEvent* ev) 667void TEWidget::mousePressEvent(QMouseEvent* ev)
647{ 668{
648//printf("press [%d,%d] %d\n",ev->x()/font_w,ev->y()/font_h,ev->button()); 669//printf("press [%d,%d] %d\n",ev->x()/font_w,ev->y()/font_h,ev->button());
649 if ( !contentsRect().contains(ev->pos()) ) return; 670 if ( !contentsRect().contains(ev->pos()) ) return;
650 QPoint tL = contentsRect().topLeft(); 671 QPoint tL = contentsRect().topLeft();
651 int tLx = tL.x(); 672 int tLx = tL.x();
652 int tLy = tL.y(); 673 int tLy = tL.y();
653 674
654 word_selection_mode = FALSE; 675 word_selection_mode = FALSE;
655 676
656//printf("press top left [%d,%d] by=%d\n",tLx,tLy, bY); 677//printf("press top left [%d,%d] by=%d\n",tLx,tLy, bY);
657 if ( ev->button() == LeftButton) 678 if ( ev->button() == LeftButton)
658 { 679 {
659 QPoint pos = QPoint((ev->x()-tLx-blX)/font_w,(ev->y()-tLy-bY)/font_h); 680 QPoint pos = QPoint((ev->x()-tLx-blX)/font_w,(ev->y()-tLy-bY)/font_h);
660 681
661 if ( ev->state() & ControlButton ) preserve_line_breaks = FALSE ; 682 if ( ev->state() & ControlButton ) preserve_line_breaks = FALSE ;
662 683
663 if (mouse_marks || (ev->state() & ShiftButton)) 684 if (mouse_marks || (ev->state() & ShiftButton))
664 { 685 {
665 emit clearSelectionSignal(); 686 emit clearSelectionSignal();
666 iPntSel = pntSel = pos; 687 iPntSel = pntSel = pos;
667 actSel = 1; // left mouse button pressed but nothing selected yet. 688 actSel = 1; // left mouse button pressed but nothing selected yet.
668 grabMouse( /*crossCursor*/ ); // handle with care! 689 grabMouse( /*crossCursor*/ ); // handle with care!
669 } 690 }
670 else 691 else
671 { 692 {
672 emit mouseSignal( 0, pos.x() + 1, pos.y() + 1 ); // left button 693 emit mouseSignal( 0, pos.x() + 1, pos.y() + 1 ); // left button
673 } 694 }
674 } 695 }
675 if ( ev->button() == MidButton ) 696 if ( ev->button() == MidButton )
676 { 697 {
677 emitSelection(); 698 emitSelection();
678 } 699 }
679 if ( ev->button() == RightButton ) // Configure 700 if ( ev->button() == RightButton ) // Configure
680 { 701 {
681 emit configureRequest( this, ev->state()&(ShiftButton|ControlButton), ev->x(), ev->y() ); 702 emit configureRequest( this, ev->state()&(ShiftButton|ControlButton), ev->x(), ev->y() );
682 } 703 }
683} 704}
684 705
685void TEWidget::mouseMoveEvent(QMouseEvent* ev) 706void TEWidget::mouseMoveEvent(QMouseEvent* ev)
686{ 707{
687 // for auto-hiding the cursor, we need mouseTracking 708 // for auto-hiding the cursor, we need mouseTracking
688 if (ev->state() == NoButton ) return; 709 if (ev->state() == NoButton ) return;
689 710
690 if (actSel == 0) return; 711 if (actSel == 0) return;
691 712
692 // don't extend selection while pasting 713 // don't extend selection while pasting
693 if (ev->state() & MidButton) return; 714 if (ev->state() & MidButton) return;
694 715
695 //if ( !contentsRect().contains(ev->pos()) ) return; 716 //if ( !contentsRect().contains(ev->pos()) ) return;
696 QPoint tL = contentsRect().topLeft(); 717 QPoint tL = contentsRect().topLeft();
697 int tLx = tL.x(); 718 int tLx = tL.x();
698 int tLy = tL.y(); 719 int tLy = tL.y();
699 int scroll = scrollbar->value(); 720 int scroll = scrollbar->value();
721// int hScroll = hScrollbar->value();
700 722
701 // we're in the process of moving the mouse with the left button pressed 723 // we're in the process of moving the mouse with the left button pressed
702 // the mouse cursor will kept catched within the bounds of the text in 724 // the mouse cursor will kept catched within the bounds of the text in
703 // this widget. 725 // this widget.
704 726
705 // Adjust position within text area bounds. See FIXME above. 727 // Adjust position within text area bounds. See FIXME above.
706 QPoint pos = ev->pos(); 728 QPoint pos = ev->pos();
707 if ( pos.x() < tLx+blX ) pos.setX( tLx+blX ); 729 if ( pos.x() < tLx+blX ) pos.setX( tLx+blX );
708 if ( pos.x() > tLx+blX+columns*font_w-1 ) pos.setX( tLx+blX+columns*font_w ); 730 if ( pos.x() > tLx+blX+columns*font_w-1 ) pos.setX( tLx+blX+columns*font_w );
709 if ( pos.y() < tLy+bY ) pos.setY( tLy+bY ); 731 if ( pos.y() < tLy+bY ) pos.setY( tLy+bY );
710 if ( pos.y() > tLy+bY+lines*font_h-1 ) pos.setY( tLy+bY+lines*font_h-1 ); 732 if ( pos.y() > tLy+bY+lines*font_h-1 ) pos.setY( tLy+bY+lines*font_h-1 );
711 // check if we produce a mouse move event by this 733 // check if we produce a mouse move event by this
712 if ( pos != ev->pos() ) cursor().setPos(mapToGlobal(pos)); 734 if ( pos != ev->pos() ) cursor().setPos(mapToGlobal(pos));
713 735
714 if ( pos.y() == tLy+bY+lines*font_h-1 ) 736 if ( pos.y() == tLy+bY+lines*font_h-1 )
715 { 737 {
716 scrollbar->setValue(scrollbar->value()+yMouseScroll); // scrollforward 738 scrollbar->setValue(scrollbar->value()+yMouseScroll); // scrollforward
717 } 739 }
718 if ( pos.y() == tLy+bY ) 740 if ( pos.y() == tLy+bY )
719 { 741 {
720 scrollbar->setValue(scrollbar->value()-yMouseScroll); // scrollback 742 scrollbar->setValue(scrollbar->value()-yMouseScroll); // scrollback
721 } 743 }
722 744
723 QPoint here = QPoint((pos.x()-tLx-blX)/font_w,(pos.y()-tLy-bY)/font_h); 745 QPoint here = QPoint((pos.x()-tLx-blX)/font_w,(pos.y()-tLy-bY)/font_h);
724 QPoint ohere; 746 QPoint ohere;
725 bool swapping = FALSE; 747 bool swapping = FALSE;
726 748
727 if ( word_selection_mode ) 749 if ( word_selection_mode )
728 { 750 {
729 // Extend to word boundaries 751 // Extend to word boundaries
730 int i; 752 int i;
731 int selClass; 753 int selClass;
732 754
733 bool left_not_right = ( here.y() < iPntSel.y() || 755 bool left_not_right = ( here.y() < iPntSel.y() ||
734 here.y() == iPntSel.y() && here.x() < iPntSel.x() ); 756 here.y() == iPntSel.y() && here.x() < iPntSel.x() );
735 bool old_left_not_right = ( pntSel.y() < iPntSel.y() || 757 bool old_left_not_right = ( pntSel.y() < iPntSel.y() ||
736 pntSel.y() == iPntSel.y() && pntSel.x() < iPntSel.x() ); 758 pntSel.y() == iPntSel.y() && pntSel.x() < iPntSel.x() );
737 swapping = left_not_right != old_left_not_right; 759 swapping = left_not_right != old_left_not_right;
738 760
739 // Find left (left_not_right ? from here : from start) 761 // Find left (left_not_right ? from here : from start)
740 QPoint left = left_not_right ? here : iPntSel; 762 QPoint left = left_not_right ? here : iPntSel;
741 i = loc(left.x(),left.y()); 763 i = loc(left.x(),left.y());
742 selClass = charClass(image[i].c); 764 selClass = charClass(image[i].c);
743 while ( left.x() > 0 && charClass(image[i-1].c) == selClass ) 765 while ( left.x() > 0 && charClass(image[i-1].c) == selClass )
744 { i--; left.rx()--; } 766 { i--; left.rx()--; }
745 767
746 // Find left (left_not_right ? from start : from here) 768 // Find left (left_not_right ? from start : from here)
747 QPoint right = left_not_right ? iPntSel : here; 769 QPoint right = left_not_right ? iPntSel : here;
748 i = loc(right.x(),right.y()); 770 i = loc(right.x(),right.y());
749 selClass = charClass(image[i].c); 771 selClass = charClass(image[i].c);
750 while ( right.x() < columns-1 && charClass(image[i+1].c) == selClass ) 772 while ( right.x() < columns-1 && charClass(image[i+1].c) == selClass )
751 { i++; right.rx()++; } 773 { i++; right.rx()++; }
752 774
753 // Pick which is start (ohere) and which is extension (here) 775 // Pick which is start (ohere) and which is extension (here)
754 if ( left_not_right ) 776 if ( left_not_right )
755 { 777 {
756 here = left; ohere = right; 778 here = left; ohere = right;
757 } 779 }
758 else 780 else
759 { 781 {
760 here = right; ohere = left; 782 here = right; ohere = left;
761 } 783 }
762 } 784 }
763 785
@@ -912,290 +934,399 @@ void TEWidget::emitSelection()
912 text.replace(QRegExp("\n"), "\r"); 934 text.replace(QRegExp("\n"), "\r");
913 QKeyEvent e(QEvent::KeyPress, 0, -1, 0, text); 935 QKeyEvent e(QEvent::KeyPress, 0, -1, 0, text);
914 emit keyPressedSignal(&e); // expose as a big fat keypress event 936 emit keyPressedSignal(&e); // expose as a big fat keypress event
915 emit clearSelectionSignal(); 937 emit clearSelectionSignal();
916 } 938 }
917#endif 939#endif
918} 940}
919 941
920void TEWidget::emitText(QString text) 942void TEWidget::emitText(QString text)
921{ 943{
922 QKeyEvent e(QEvent::KeyPress, 0, -1, 0, text); 944 QKeyEvent e(QEvent::KeyPress, 0, -1, 0, text);
923 emit keyPressedSignal(&e); // expose as a big fat keypress event 945 emit keyPressedSignal(&e); // expose as a big fat keypress event
924} 946}
925 947
926void TEWidget::pasteClipboard( ) 948void TEWidget::pasteClipboard( )
927{ 949{
928 emitSelection(); 950 emitSelection();
929} 951}
930 952
931void TEWidget::setSelection(const QString& t) 953void TEWidget::setSelection(const QString& t)
932{ 954{
933#ifndef QT_NO_CLIPBOARD 955#ifndef QT_NO_CLIPBOARD
934 // Disconnect signal while WE set the clipboard 956 // Disconnect signal while WE set the clipboard
935 QObject *cb = QApplication::clipboard(); 957 QObject *cb = QApplication::clipboard();
936 QObject::disconnect( cb, SIGNAL(dataChanged()), 958 QObject::disconnect( cb, SIGNAL(dataChanged()),
937 this, SLOT(onClearSelection()) ); 959 this, SLOT(onClearSelection()) );
938 960
939 QApplication::clipboard()->setText(t); 961 QApplication::clipboard()->setText(t);
940 962
941 QObject::connect( cb, SIGNAL(dataChanged()), 963 QObject::connect( cb, SIGNAL(dataChanged()),
942 this, SLOT(onClearSelection()) ); 964 this, SLOT(onClearSelection()) );
943#endif 965#endif
944} 966}
945 967
946void TEWidget::onClearSelection() 968void TEWidget::onClearSelection()
947{ 969{
948 emit clearSelectionSignal(); 970 emit clearSelectionSignal();
949} 971}
950 972
951/* ------------------------------------------------------------------------- */ 973/* ------------------------------------------------------------------------- */
952/* */ 974/* */
953/* Keyboard */ 975/* Keyboard */
954/* */ 976/* */
955/* ------------------------------------------------------------------------- */ 977/* ------------------------------------------------------------------------- */
956 978
957//FIXME: an `eventFilter' has been installed instead of a `keyPressEvent' 979//FIXME: an `eventFilter' has been installed instead of a `keyPressEvent'
958// due to a bug in `QT' or the ignorance of the author to prevent 980// due to a bug in `QT' or the ignorance of the author to prevent
959// repaint events being emitted to the screen whenever one leaves 981// repaint events being emitted to the screen whenever one leaves
960// or reenters the screen to/from another application. 982// or reenters the screen to/from another application.
961// 983//
962// Troll says one needs to change focusInEvent() and focusOutEvent(), 984// Troll says one needs to change focusInEvent() and focusOutEvent(),
963// which would also let you have an in-focus cursor and an out-focus 985// which would also let you have an in-focus cursor and an out-focus
964// cursor like xterm does. 986// cursor like xterm does.
965 987
966// for the auto-hide cursor feature, I added empty focusInEvent() and 988// for the auto-hide cursor feature, I added empty focusInEvent() and
967// focusOutEvent() so that update() isn't called. 989// focusOutEvent() so that update() isn't called.
968// For auto-hide, we need to get keypress-events, but we only get them when 990// For auto-hide, we need to get keypress-events, but we only get them when
969// we have focus. 991// we have focus.
970 992
971void TEWidget::doScroll(int lines) 993void TEWidget::doScroll(int lines)
972{ 994{
973 scrollbar->setValue(scrollbar->value()+lines); 995 scrollbar->setValue(scrollbar->value()+lines);
974} 996}
975 997
998void TEWidget::doHScroll(int lines) {
999 hScrollbar->setValue( hScrollbar->value()+lines);
1000}
1001
976bool TEWidget::eventFilter( QObject *obj, QEvent *e ) 1002bool TEWidget::eventFilter( QObject *obj, QEvent *e )
977{ 1003{
978 if ( (e->type() == QEvent::Accel || 1004 if ( (e->type() == QEvent::Accel ||
979 e->type() == QEvent::AccelAvailable ) && qApp->focusWidget() == this ) { 1005 e->type() == QEvent::AccelAvailable ) && qApp->focusWidget() == this ) {
980 static_cast<QKeyEvent *>( e )->ignore(); 1006 static_cast<QKeyEvent *>( e )->ignore();
981 return true; 1007 return true;
982 } 1008 }
983 if ( obj != this /* when embedded */ && obj != parent() /* when standalone */ ) 1009 if ( obj != this /* when embedded */ && obj != parent() /* when standalone */ )
984 return FALSE; // not us 1010 return FALSE; // not us
985 if ( e->type() == QEvent::Wheel) { 1011 if ( e->type() == QEvent::Wheel) {
986 QApplication::sendEvent(scrollbar, e); 1012 QApplication::sendEvent(scrollbar, e);
987 } 1013 }
988 1014
989#ifdef FAKE_CTRL_AND_ALT 1015#ifdef FAKE_CTRL_AND_ALT
990 static bool control = FALSE; 1016 static bool control = FALSE;
991 static bool alt = FALSE; 1017 static bool alt = FALSE;
992// qDebug(" Has a keyboard with no CTRL and ALT keys, but we fake it:"); 1018// qDebug(" Has a keyboard with no CTRL and ALT keys, but we fake it:");
993 bool dele=FALSE; 1019 bool dele=FALSE;
994 if ( e->type() == QEvent::KeyPress || e->type() == QEvent::KeyRelease ) { 1020 if ( e->type() == QEvent::KeyPress || e->type() == QEvent::KeyRelease ) {
995 QKeyEvent* ke = (QKeyEvent*)e; 1021 QKeyEvent* ke = (QKeyEvent*)e;
996 bool keydown = e->type() == QEvent::KeyPress || ke->isAutoRepeat(); 1022 bool keydown = e->type() == QEvent::KeyPress || ke->isAutoRepeat();
997 switch (ke->key()) { 1023 switch (ke->key()) {
998 case Key_F9: // let this be "Control" 1024 case Key_F9: // let this be "Control"
999 control = keydown; 1025 control = keydown;
1000 e = new QKeyEvent(QEvent::KeyPress, Key_Control, 0, ke->state()); 1026 e = new QKeyEvent(QEvent::KeyPress, Key_Control, 0, ke->state());
1001 dele=TRUE; 1027 dele=TRUE;
1002 break; 1028 break;
1003 case Key_F13: // let this be "Alt" 1029 case Key_F13: // let this be "Alt"
1004 alt = keydown; 1030 alt = keydown;
1005 e = new QKeyEvent(QEvent::KeyPress, Key_Alt, 0, ke->state()); 1031 e = new QKeyEvent(QEvent::KeyPress, Key_Alt, 0, ke->state());
1006 dele=TRUE; 1032 dele=TRUE;
1007 break; 1033 break;
1008 default: 1034 default:
1009 if ( control ) { 1035 if ( control ) {
1010 int a = toupper(ke->ascii())-64; 1036 int a = toupper(ke->ascii())-64;
1011 if ( a >= 0 && a < ' ' ) { 1037 if ( a >= 0 && a < ' ' ) {
1012 e = new QKeyEvent(e->type(), ke->key(), 1038 e = new QKeyEvent(e->type(), ke->key(),
1013 a, ke->state()|ControlButton, QChar(a,0)); 1039 a, ke->state()|ControlButton, QChar(a,0));
1014 dele=TRUE; 1040 dele=TRUE;
1015 } 1041 }
1016 } 1042 }
1017 if ( alt ) { 1043 if ( alt ) {
1018 e = new QKeyEvent(e->type(), ke->key(), 1044 e = new QKeyEvent(e->type(), ke->key(),
1019 ke->ascii(), ke->state()|AltButton, ke->text()); 1045 ke->ascii(), ke->state()|AltButton, ke->text());
1020 dele=TRUE; 1046 dele=TRUE;
1021 } 1047 }
1022 } 1048 }
1023 } 1049 }
1024#endif 1050#endif
1025 1051
1026 if ( e->type() == QEvent::KeyPress ) { 1052 if ( e->type() == QEvent::KeyPress ) {
1027 QKeyEvent* ke = (QKeyEvent*)e; 1053 QKeyEvent* ke = (QKeyEvent*)e;
1028 actSel=0; // Key stroke implies a screen update, so TEWidget won't 1054 actSel=0; // Key stroke implies a screen update, so TEWidget won't
1029 // know where the current selection is. 1055 // know where the current selection is.
1030 1056
1031// qDebug("key pressed is 0x%x, state %d",ke->key(), ke->state()); 1057// qDebug("key pressed is 0x%x, state %d",ke->key(), ke->state());
1032 1058
1033 if( ke->state() == ShiftButton && ke->key() == Key_Tab) { 1059 if( ke->state() == ShiftButton && ke->key() == Key_Tab) {
1034 //lets hardcode this sucker 1060 //lets hardcode this sucker
1035 1061
1036// qDebug("key pressed 2 is 0x%x",ke->key()); 1062// qDebug("key pressed 2 is 0x%x",ke->key());
1037 emitText("\\"); // expose 1063 emitText("\\"); // expose
1038 } 1064 }
1039 else if( ke->state() == ControlButton && ke->key() == Key_V) { 1065 else if( ke->state() == ControlButton && ke->key() == Key_V) {
1040 pasteClipboard(); 1066 pasteClipboard();
1041 } 1067 }
1042 else 1068 else
1043 emit keyPressedSignal(ke); // expose 1069 emit keyPressedSignal(ke); // expose
1044 ke->accept(); 1070 ke->accept();
1045#ifdef FAKE_CTRL_AND_ALT 1071#ifdef FAKE_CTRL_AND_ALT
1046 if ( dele ) delete e; 1072 if ( dele ) delete e;
1047#endif 1073#endif
1048 return true; // stop the event 1074 return true; // stop the event
1049 } 1075 }
1050 if ( e->type() == QEvent::Enter ) { 1076 if ( e->type() == QEvent::Enter ) {
1051 QObject::disconnect( (QObject*)cb, SIGNAL(dataChanged()), 1077 QObject::disconnect( (QObject*)cb, SIGNAL(dataChanged()),
1052 this, SLOT(onClearSelection()) ); 1078 this, SLOT(onClearSelection()) );
1053 } 1079 }
1054 if ( e->type() == QEvent::Leave ) { 1080 if ( e->type() == QEvent::Leave ) {
1055 QObject::connect( (QObject*)cb, SIGNAL(dataChanged()), 1081 QObject::connect( (QObject*)cb, SIGNAL(dataChanged()),
1056 this, SLOT(onClearSelection()) ); 1082 this, SLOT(onClearSelection()) );
1057 } 1083 }
1058 return QFrame::eventFilter( obj, e ); 1084 return QFrame::eventFilter( obj, e );
1059} 1085}
1060 1086
1061/* ------------------------------------------------------------------------- */ 1087/* ------------------------------------------------------------------------- */
1062/* */ 1088/* */
1063/* Frame */ 1089/* Frame */
1064/* */ 1090/* */
1065/* ------------------------------------------------------------------------- */ 1091/* ------------------------------------------------------------------------- */
1066 1092
1067void TEWidget::frameChanged() 1093void TEWidget::frameChanged()
1068{ 1094{
1069 propagateSize(); 1095 propagateSize();
1070 update(); 1096 update();
1071} 1097}
1072 1098
1073/* ------------------------------------------------------------------------- */ 1099/* ------------------------------------------------------------------------- */
1074/* */ 1100/* */
1075/* Sound */ 1101/* Sound */
1076/* */ 1102/* */
1077/* ------------------------------------------------------------------------- */ 1103/* ------------------------------------------------------------------------- */
1078 1104
1079void TEWidget::Bell() 1105void TEWidget::Bell()
1080{ 1106{
1081 QApplication::beep(); 1107//#ifdef QT_QWS_CUSTOM
1108//# ifndef QT_NO_COP
1109 QCopEnvelope( "QPE/TaskBar", "soundAlarm()" );
1110//# endif
1111//#else
1112//# ifndef QT_NO_SOUND
1113// QSound::play(Resource::findSound("alarm"));
1114//# endif
1115//#endif
1116
1117// QApplication::beep();
1082} 1118}
1083 1119
1084/* ------------------------------------------------------------------------- */ 1120/* ------------------------------------------------------------------------- */
1085/* */ 1121/* */
1086/* Auxiluary */ 1122/* Auxiluary */
1087/* */ 1123/* */
1088/* ------------------------------------------------------------------------- */ 1124/* ------------------------------------------------------------------------- */
1089 1125
1090void TEWidget::clearImage() 1126void TEWidget::clearImage()
1091// initialize the image 1127// initialize the image
1092// for internal use only 1128// for internal use only
1093{ 1129{
1094 for (int y = 0; y < lines; y++) 1130 for (int y = 0; y < lines; y++)
1095 for (int x = 0; x < columns; x++) 1131 for (int x = 0; x < columns; x++)
1096 { 1132 {
1097 image[loc(x,y)].c = 0xff; //' '; 1133 image[loc(x,y)].c = 0xff; //' ';
1098 image[loc(x,y)].f = 0xff; //DEFAULT_FORE_COLOR; 1134 image[loc(x,y)].f = 0xff; //DEFAULT_FORE_COLOR;
1099 image[loc(x,y)].b = 0xff; //DEFAULT_BACK_COLOR; 1135 image[loc(x,y)].b = 0xff; //DEFAULT_BACK_COLOR;
1100 image[loc(x,y)].r = 0xff; //DEFAULT_RENDITION; 1136 image[loc(x,y)].r = 0xff; //DEFAULT_RENDITION;
1101 } 1137 }
1102} 1138}
1103 1139
1104// Create Image /////////////////////////////////////////////////////// 1140// Create Image ///////////////////////////////////////////////////////
1105 1141
1106void TEWidget::calcGeometry() 1142void TEWidget::calcGeometry()
1107{ 1143{
1108 //FIXME: set rimX == rimY == 0 when running in full screen mode. 1144 int showhscrollbar = 1;
1145 int hwidth = 0;
1146 int dcolumns;
1147 Config cfg("Konsole");
1148 cfg.setGroup("ScrollBar");
1149 useHorzScroll=cfg.readBoolEntry("HorzScroll",0);
1150
1151 if(vcolumns == 0) showhscrollbar = 0;
1152 if(showhscrollbar == 1) hwidth = QApplication::style().scrollBarExtent().width();
1153
1154 scrollbar->resize(QApplication::style().scrollBarExtent().width(),
1155 contentsRect().height() - hwidth);
1156
1157 switch(scrollLoc) {
1158 case SCRNONE :
1159 columns = ( contentsRect().width() - 2 * rimX ) / font_w;
1160 dcolumns = columns;
1161 if(vcolumns) columns = vcolumns;
1162 blX = (contentsRect().width() - (columns*font_w) ) / 2;
1163 if(showhscrollbar)
1164 blX = -hposition * font_w;
1165 brX = blX;
1166 scrollbar->hide();
1167 break;
1168 case SCRLEFT :
1169 columns = ( contentsRect().width() - 2 * rimX - scrollbar->width()) / font_w;
1170 dcolumns = columns;
1171 if(vcolumns) columns = vcolumns;
1172 brX = (contentsRect().width() - (columns*font_w) - scrollbar->width() ) / 2;
1173 if(showhscrollbar)
1174 brX = -hposition * font_w;
1175 blX = brX + scrollbar->width();
1176 scrollbar->move(contentsRect().topLeft());
1177 scrollbar->show();
1178 break;
1179 case SCRRIGHT:
1180 columns = ( contentsRect().width() - 2 * rimX - scrollbar->width()) / font_w;
1181 dcolumns = columns;
1182 if(vcolumns) columns = vcolumns;
1183 blX = (contentsRect().width() - (columns*font_w) - scrollbar->width() ) / 2;
1184 if(showhscrollbar)
1185 blX = -hposition * font_w;
1186 brX = blX;
1187 scrollbar->move(contentsRect().topRight() - QPoint(scrollbar->width()-1,0));
1188 scrollbar->show();
1189 break;
1190 }
1191 //FIXME: support 'rounding' styles
1192 lines = ( contentsRect().height() - 2 * rimY ) / font_h;
1193 bY = (contentsRect().height() - (lines *font_h)) / 2;
1109 1194
1110 scrollbar->resize(QApplication::style().scrollBarExtent().width(), 1195 if(showhscrollbar == 1) {
1196 hScrollbar->resize(contentsRect().width() - hwidth, hwidth);
1197 hScrollbar->setRange(0, vcolumns - dcolumns);
1198
1199 QPoint p = contentsRect().bottomLeft();
1200 hScrollbar->move(QPoint(p.x(), p.y() - hwidth));
1201 hScrollbar->show();
1202 }
1203 else hScrollbar->hide();
1204
1205 if(showhscrollbar == 1) {
1206 lines = lines - (hwidth / font_h) - 1;
1207 if(lines < 1) lines = 1;
1208 }
1209
1210 /*//FIXME: set rimX == rimY == 0 when running in full screen mode.
1211 Config cfg("Konsole");
1212 cfg.setGroup("ScrollBar");
1213 useHorzScroll=cfg.readBoolEntry("HorzScroll",0);
1214
1215 scrollbar->resize( QApplication::style().scrollBarExtent().width(),
1111 contentsRect().height()); 1216 contentsRect().height());
1217 qDebug("font_w %d", font_w);
1112 switch(scrollLoc) 1218 switch(scrollLoc)
1113 { 1219 {
1114 case SCRNONE : 1220 case SCRNONE :
1115 columns = ( contentsRect().width() - 2 * rimX ) / font_w; 1221 columns = ( contentsRect().width() - 2 * rimX ) / font_w;
1116 blX = (contentsRect().width() - (columns*font_w) ) / 2; 1222 blX = (contentsRect().width() - (columns*font_w) ) / 2;
1117 brX = blX; 1223 brX = blX;
1118 scrollbar->hide(); 1224 scrollbar->hide();
1119 break; 1225 break;
1120 case SCRLEFT : 1226 case SCRLEFT :
1121 columns = ( contentsRect().width() - 2 * rimX - scrollbar->width()) / font_w; 1227 columns = ( contentsRect().width() - 2 * rimX - scrollbar->width()) / font_w;
1228 if(useHorzScroll) columns = columns * (font_w/2);
1122 brX = (contentsRect().width() - (columns*font_w) - scrollbar->width() ) / 2; 1229 brX = (contentsRect().width() - (columns*font_w) - scrollbar->width() ) / 2;
1123 blX = brX + scrollbar->width(); 1230 blX = brX + scrollbar->width();
1124 scrollbar->move(contentsRect().topLeft()); 1231 scrollbar->move(contentsRect().topLeft());
1125 scrollbar->show(); 1232 scrollbar->show();
1126 break; 1233 break;
1127 case SCRRIGHT: 1234 case SCRRIGHT:
1128 columns = ( contentsRect().width() - 2 * rimX - scrollbar->width()) / font_w; 1235 columns = ( contentsRect().width() - 2 * rimX - scrollbar->width() ) / font_w;
1129 blX = (contentsRect().width() - (columns*font_w) - scrollbar->width() ) / 2; 1236 if(useHorzScroll) columns = columns * (font_w/2);
1130 brX = blX; 1237 blX = (contentsRect().width() - (columns*font_w) - scrollbar->width() ) / 2;
1131 scrollbar->move(contentsRect().topRight() - QPoint(scrollbar->width()-1,0)); 1238 if(useHorzScroll) {
1239 brX = blX =2;
1240 } else {
1241 brX=blX;
1242 }
1243 scrollbar->move(contentsRect().topRight() - QPoint(scrollbar->width()-1,0) );
1132 scrollbar->show(); 1244 scrollbar->show();
1133 break; 1245 break;
1134 } 1246 }
1247
1248 if( !scrollbar->isHidden())
1249 hScrollbar->resize( contentsRect().width()-SCRWIDTH, QApplication::style()
1250 .scrollBarExtent().height());
1251 else
1252 hScrollbar->resize( contentsRect().width(), QApplication::style()
1253 .scrollBarExtent().height());
1254
1255 hScrollbar->move( 0, contentsRect().height() - SCRWIDTH);
1256
1257
1258 if(useHorzScroll) {
1259 hScrollbar->show();
1260 lines = ( (contentsRect().height() - SCRWIDTH) - 2 * rimY ) / font_h;
1261 bY = ((contentsRect().height() - SCRWIDTH) - (lines *font_h)) / 2;
1262 } else {
1263 hScrollbar->hide();
1264 lines = (contentsRect().height() - 2 * rimY ) / font_h;
1265 bY = (contentsRect().height() - (lines *font_h)) / 2;
1266 }
1267 */
1135 //FIXME: support 'rounding' styles 1268 //FIXME: support 'rounding' styles
1136 lines = ( contentsRect().height() - 2 * rimY ) / font_h;
1137 bY = (contentsRect().height() - (lines *font_h)) / 2;
1138} 1269}
1139 1270
1140void TEWidget::makeImage() 1271void TEWidget::makeImage()
1141//FIXME: rename 'calcGeometry? 1272//FIXME: rename 'calcGeometry?
1142{ 1273{
1143 calcGeometry(); 1274 calcGeometry();
1144 image = (ca*) malloc(lines*columns*sizeof(ca)); 1275 image = (ca*) malloc(lines*columns*sizeof(ca));
1145 clearImage(); 1276 clearImage();
1146} 1277}
1147 1278
1148// calculate the needed size 1279// calculate the needed size
1149QSize TEWidget::calcSize(int cols, int lins) const 1280QSize TEWidget::calcSize(int cols, int lins) const
1150{ 1281{
1151 int frw = width() - contentsRect().width(); 1282 int frw = width() - contentsRect().width();
1152 int frh = height() - contentsRect().height(); 1283 int frh = height() - contentsRect().height();
1153 int scw = (scrollLoc==SCRNONE?0:scrollbar->width()); 1284 int scw = (scrollLoc==SCRNONE?0:scrollbar->width());
1154 return QSize( font_w*cols + 2*rimX + frw + scw, font_h*lins + 2*rimY + frh ); 1285 return QSize( font_w*cols + 2*rimX + frw + scw, font_h*lins + 2*rimY + frh );
1155} 1286}
1156 1287
1157QSize TEWidget::sizeHint() const 1288QSize TEWidget::sizeHint() const
1158{ 1289{
1159 return size(); 1290 return size();
1160} 1291}
1161 1292
1162void TEWidget::styleChange(QStyle &) 1293void TEWidget::styleChange(QStyle &)
1163{ 1294{
1164 propagateSize(); 1295 propagateSize();
1165} 1296}
1166 1297
1167#ifndef QT_NO_DRAGANDDROP 1298#ifndef QT_NO_DRAGANDDROP
1168 1299
1169/* --------------------------------------------------------------------- */ 1300/* --------------------------------------------------------------------- */
1170/* */ 1301/* */
1171/* Drag & Drop */ 1302/* Drag & Drop */
1172/* */ 1303/* */
1173/* --------------------------------------------------------------------- */ 1304/* --------------------------------------------------------------------- */
1174 1305
1175 1306
1176void TEWidget::dragEnterEvent(QDragEnterEvent* e) 1307void TEWidget::dragEnterEvent(QDragEnterEvent* e)
1177{ 1308{
1178 e->accept(QTextDrag::canDecode(e) || 1309 e->accept(QTextDrag::canDecode(e) ||
1179 QUriDrag::canDecode(e)); 1310 QUriDrag::canDecode(e));
1180} 1311}
1181 1312
1182void TEWidget::dropEvent(QDropEvent* event) 1313void TEWidget::dropEvent(QDropEvent* event)
1183{ 1314{
1184 // The current behaviour when url(s) are dropped is 1315 // The current behaviour when url(s) are dropped is
1185 // * if there is only ONE url and if it's a LOCAL one, ask for paste or cd 1316 // * if there is only ONE url and if it's a LOCAL one, ask for paste or cd
1186 // * in all other cases, just paste 1317 // * in all other cases, just paste
1187 // (for non-local ones, or for a list of URLs, 'cd' is nonsense) 1318 // (for non-local ones, or for a list of URLs, 'cd' is nonsense)
1188 QStrList strlist; 1319 QStrList strlist;
1189 int file_count = 0; 1320 int file_count = 0;
1190 dropText = ""; 1321 dropText = "";
1191 bool bPopup = true; 1322 bool bPopup = true;
1192 1323
1193 if(QUriDrag::decode(event, strlist)) { 1324 if(QUriDrag::decode(event, strlist)) {
1194 if (strlist.count()) { 1325 if (strlist.count()) {
1195 for(const char* p = strlist.first(); p; p = strlist.next()) { 1326 for(const char* p = strlist.first(); p; p = strlist.next()) {
1196 if(file_count++ > 0) { 1327 if(file_count++ > 0) {
1197 dropText += " "; 1328 dropText += " ";
1198 bPopup = false; // more than one file, don't popup 1329 bPopup = false; // more than one file, don't popup
1199 } 1330 }
1200 1331
1201/* 1332/*
@@ -1205,64 +1336,72 @@ void TEWidget::dropEvent(QDropEvent* event)
1205 } 1336 }
1206 else { 1337 else {
1207 dropText += url.prettyURL(); 1338 dropText += url.prettyURL();
1208 bPopup = false; // a non-local file, don't popup 1339 bPopup = false; // a non-local file, don't popup
1209 } 1340 }
1210*/ 1341*/
1211 1342
1212 } 1343 }
1213 1344
1214 if (bPopup) 1345 if (bPopup)
1215 // m_drop->popup(pos() + event->pos()); 1346 // m_drop->popup(pos() + event->pos());
1216 m_drop->popup(mapToGlobal(event->pos())); 1347 m_drop->popup(mapToGlobal(event->pos()));
1217 else 1348 else
1218 { 1349 {
1219 if (currentSession) { 1350 if (currentSession) {
1220 currentSession->getEmulation()->sendString(dropText.local8Bit()); 1351 currentSession->getEmulation()->sendString(dropText.local8Bit());
1221 } 1352 }
1222// kdDebug() << "Drop:" << dropText.local8Bit() << "\n"; 1353// kdDebug() << "Drop:" << dropText.local8Bit() << "\n";
1223 } 1354 }
1224 } 1355 }
1225 } 1356 }
1226 else if(QTextDrag::decode(event, dropText)) { 1357 else if(QTextDrag::decode(event, dropText)) {
1227// kdDebug() << "Drop:" << dropText.local8Bit() << "\n"; 1358// kdDebug() << "Drop:" << dropText.local8Bit() << "\n";
1228 if (currentSession) { 1359 if (currentSession) {
1229 currentSession->getEmulation()->sendString(dropText.local8Bit()); 1360 currentSession->getEmulation()->sendString(dropText.local8Bit());
1230 } 1361 }
1231 // Paste it 1362 // Paste it
1232 } 1363 }
1233} 1364}
1234#endif 1365#endif
1235 1366
1236 1367
1237void TEWidget::drop_menu_activated(int item) 1368void TEWidget::drop_menu_activated(int item)
1238{ 1369{
1239#ifndef QT_NO_DRAGANDDROP 1370#ifndef QT_NO_DRAGANDDROP
1240 switch (item) 1371 switch (item)
1241 { 1372 {
1242 case 0: // paste 1373 case 0: // paste
1243 currentSession->getEmulation()->sendString(dropText.local8Bit()); 1374 currentSession->getEmulation()->sendString(dropText.local8Bit());
1244// KWM::activate((Window)this->winId()); 1375// KWM::activate((Window)this->winId());
1245 break; 1376 break;
1246 case 1: // cd ... 1377 case 1: // cd ...
1247 currentSession->getEmulation()->sendString("cd "); 1378 currentSession->getEmulation()->sendString("cd ");
1248 struct stat statbuf; 1379 struct stat statbuf;
1249 if ( ::stat( QFile::encodeName( dropText ), &statbuf ) == 0 ) 1380 if ( ::stat( QFile::encodeName( dropText ), &statbuf ) == 0 )
1250 { 1381 {
1251 if ( !S_ISDIR(statbuf.st_mode) ) 1382 if ( !S_ISDIR(statbuf.st_mode) )
1252 { 1383 {
1253/* 1384/*
1254 KURL url; 1385 KURL url;
1255 url.setPath( dropText ); 1386 url.setPath( dropText );
1256 dropText = url.directory( true, false ); // remove filename 1387 dropText = url.directory( true, false ); // remove filename
1257*/ 1388*/
1258 } 1389 }
1259 } 1390 }
1260 dropText.replace(QRegExp(" "), "\\ "); // escape spaces 1391 dropText.replace(QRegExp(" "), "\\ "); // escape spaces
1261 currentSession->getEmulation()->sendString(dropText.local8Bit()); 1392 currentSession->getEmulation()->sendString(dropText.local8Bit());
1262 currentSession->getEmulation()->sendString("\n"); 1393 currentSession->getEmulation()->sendString("\n");
1263// KWM::activate((Window)this->winId()); 1394// KWM::activate((Window)this->winId());
1264 break; 1395 break;
1265 } 1396 }
1266#endif 1397#endif
1267} 1398}
1268 1399
1400void TEWidget::setWrapAt(int columns)
1401{
1402 vcolumns = columns;
1403 propagateSize();
1404 update();
1405}
1406
1407
diff --git a/core/apps/embeddedkonsole/TEWidget.h b/core/apps/embeddedkonsole/TEWidget.h
index 40e1aea..a480d45 100644
--- a/core/apps/embeddedkonsole/TEWidget.h
+++ b/core/apps/embeddedkonsole/TEWidget.h
@@ -1,202 +1,211 @@
1/* ----------------------------------------------------------------------- */ 1/* ----------------------------------------------------------------------- */
2/* */ 2/* */
3/* [te_widget.h] Terminal Emulation Widget */ 3/* [te_widget.h] Terminal Emulation Widget */
4/* */ 4/* */
5/* ----------------------------------------------------------------------- */ 5/* ----------------------------------------------------------------------- */
6/* */ 6/* */
7/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */ 7/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */
8/* */ 8/* */
9/* This file is part of Konsole - an X terminal for KDE */ 9/* This file is part of Konsole - an X terminal for KDE */
10/* */ 10/* */
11/* ----------------------------------------------------------------------- */ 11/* ----------------------------------------------------------------------- */
12/* */ 12/* */
13/* Ported Konsole to Qt/Embedded */ 13/* Ported Konsole to Qt/Embedded */
14/* */ 14/* */
15/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */ 15/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */
16/* */ 16/* */
17/* -------------------------------------------------------------------------- */ 17/* -------------------------------------------------------------------------- */
18#ifndef TE_WIDGET_H 18#ifndef TE_WIDGET_H
19#define TE_WIDGET_H 19#define TE_WIDGET_H
20 20
21#include <qwidget.h> 21#include <qwidget.h>
22#include <qlabel.h> 22#include <qlabel.h>
23#include <qtimer.h> 23#include <qtimer.h>
24#include <qcolor.h> 24#include <qcolor.h>
25#include <qkeycode.h> 25#include <qkeycode.h>
26#include <qscrollbar.h> 26#include <qscrollbar.h>
27 27
28#include <qpopupmenu.h> 28#include <qpopupmenu.h>
29 29
30#include "TECommon.h" 30#include "TECommon.h"
31 31
32extern unsigned short vt100_graphics[32]; 32extern unsigned short vt100_graphics[32];
33 33
34class TESession; 34class TESession;
35 35
36// class Konsole; 36// class Konsole;
37 37
38class TEWidget : public QFrame 38class TEWidget : public QFrame
39// a widget representing attributed text 39// a widget representing attributed text
40{ Q_OBJECT 40{ Q_OBJECT
41 41
42// friend class Konsole; 42// friend class Konsole;
43 43
44public: 44public:
45 45
46 TEWidget(QWidget *parent=0, const char *name=0); 46 TEWidget(QWidget *parent=0, const char *name=0);
47 virtual ~TEWidget(); 47 virtual ~TEWidget();
48 48
49public: 49public:
50 50
51 QColor getDefaultBackColor(); 51 QColor getDefaultBackColor();
52 52
53 const ColorEntry* getColorTable() const; 53 const ColorEntry* getColorTable() const;
54 const ColorEntry* getdefaultColorTable() const; 54 const ColorEntry* getdefaultColorTable() const;
55 void setColorTable(const ColorEntry table[]); 55 void setColorTable(const ColorEntry table[]);
56 56
57 void setScrollbarLocation(int loc); 57 void setScrollbarLocation(int loc);
58 enum { SCRNONE=0, SCRLEFT=1, SCRRIGHT=2 }; 58 enum { SCRNONE=0, SCRLEFT=1, SCRRIGHT=2 };
59 59
60 void setScroll(int cursor, int lines); 60 void setScroll(int cursor, int lines);
61 void doScroll(int lines); 61 void doScroll(int lines);
62 62
63 void doHScroll(int lines);
64
65
63 void emitSelection(); 66 void emitSelection();
67 void setWrapAt(int columns);
64 68
65public: 69public:
66 70
67 void setImage(const ca* const newimg, int lines, int columns); 71 void setImage(const ca* const newimg, int lines, int columns);
68 72
69 int Lines() { return lines; } 73 int Lines() { return lines; }
70 int Columns() { return columns; } 74 int Columns() { return columns; }
71 75
72 void calcGeometry(); 76 void calcGeometry();
73 void propagateSize(); 77 void propagateSize();
74 QSize calcSize(int cols, int lins) const; 78 QSize calcSize(int cols, int lins) const;
75 79
76 QSize sizeHint() const; 80 QSize sizeHint() const;
77 81
78public: 82public:
83 bool useHorzScroll;
79 84
80 void Bell(); 85 void Bell();
81 void emitText(QString text); 86 void emitText(QString text);
82 void pasteClipboard(); 87 void pasteClipboard();
83 88
84signals: 89signals:
85 90
86 void keyPressedSignal(QKeyEvent *e); 91 void keyPressedSignal(QKeyEvent *e);
87 void mouseSignal(int cb, int cx, int cy); 92 void mouseSignal(int cb, int cx, int cy);
88 void changedImageSizeSignal(int lines, int columns); 93 void changedImageSizeSignal(int lines, int columns);
89 void changedHistoryCursor(int value); 94 void changedHistoryCursor(int value);
95 void changedHorzCursor(int value);
90 void configureRequest( TEWidget*, int state, int x, int y ); 96 void configureRequest( TEWidget*, int state, int x, int y );
91 97
92 void clearSelectionSignal(); 98 void clearSelectionSignal();
93 void beginSelectionSignal( const int x, const int y ); 99 void beginSelectionSignal( const int x, const int y );
94 void extendSelectionSignal( const int x, const int y ); 100 void extendSelectionSignal( const int x, const int y );
95 void endSelectionSignal(const BOOL preserve_line_breaks); 101 void endSelectionSignal(const BOOL preserve_line_breaks);
96 102
97 103
98protected: 104protected:
99
100 virtual void styleChange( QStyle& ); 105 virtual void styleChange( QStyle& );
101 106
102 bool eventFilter( QObject *, QEvent * ); 107 bool eventFilter( QObject *, QEvent * );
103 108
104 void drawAttrStr(QPainter &paint, QRect rect, 109 void drawAttrStr(QPainter &paint, QRect rect,
105 QString& str, ca attr, BOOL pm, BOOL clear); 110 QString& str, ca attr, BOOL pm, BOOL clear);
106 void paintEvent( QPaintEvent * ); 111 void paintEvent( QPaintEvent * );
107 112
108 void resizeEvent(QResizeEvent*); 113 void resizeEvent(QResizeEvent*);
109 114
110 void fontChange(const QFont &font); 115 void fontChange(const QFont &font);
111 void frameChanged(); 116 void frameChanged();
112 117
113 void mouseDoubleClickEvent(QMouseEvent* ev); 118 void mouseDoubleClickEvent(QMouseEvent* ev);
114 void mousePressEvent( QMouseEvent* ); 119 void mousePressEvent( QMouseEvent* );
115 void mouseReleaseEvent( QMouseEvent* ); 120 void mouseReleaseEvent( QMouseEvent* );
116 void mouseMoveEvent( QMouseEvent* ); 121 void mouseMoveEvent( QMouseEvent* );
117 122
118 void focusInEvent( QFocusEvent * ); 123 void focusInEvent( QFocusEvent * );
119 void focusOutEvent( QFocusEvent * ); 124 void focusOutEvent( QFocusEvent * );
120 bool focusNextPrevChild( bool next ); 125 bool focusNextPrevChild( bool next );
121 126
122#ifndef QT_NO_DRAGANDDROP 127#ifndef QT_NO_DRAGANDDROP
123 // Dnd 128 // Dnd
124 void dragEnterEvent(QDragEnterEvent* event); 129 void dragEnterEvent(QDragEnterEvent* event);
125 void dropEvent(QDropEvent* event); 130 void dropEvent(QDropEvent* event);
126#endif 131#endif
127 132
128 virtual int charClass(char) const; 133 virtual int charClass(char) const;
129 134
130 void clearImage(); 135 void clearImage();
131 136
132public: 137public:
133 const QPixmap *backgroundPixmap(); 138 const QPixmap *backgroundPixmap();
134 139
135 void setSelection(const QString &t); 140 void setSelection(const QString &t);
136 141
137 virtual void setFont(const QFont &); 142 virtual void setFont(const QFont &);
138 void setVTFont(const QFont &); 143 void setVTFont(const QFont &);
139 QFont getVTFont(); 144 QFont getVTFont();
140 145
141 void setMouseMarks(bool on); 146 void setMouseMarks(bool on);
142 147
143public slots: 148public slots:
144 149
145 void onClearSelection(); 150 void onClearSelection();
146 151
147protected slots: 152protected slots:
148 153
149 void scrollChanged(int value); 154 void scrollChanged(int value);
155 void hScrollChanged(int value);
150 void blinkEvent(); 156 void blinkEvent();
151 157
152private: 158private:
153 159
154 QChar (*fontMap)(QChar); // possible vt100 font extention 160 QChar (*fontMap)(QChar); // possible vt100 font extention
155 161
156 bool fixed_font; // has fixed pitch 162 bool fixed_font; // has fixed pitch
157 int font_h; // height 163 int font_h; // height
158 int font_w; // width 164 int font_w; // width
159 int font_a; // ascend 165 int font_a; // ascend
160 166
161 int blX; // actual offset (left) 167 int blX; // actual offset (left)
162 int brX; // actual offset (right) 168 int brX; // actual offset (right)
163 int bY; // actual offset 169 int bY; // actual offset
164 170
165 int lines; 171 int lines;
166 int columns; 172 int columns;
167 ca *image; // [lines][columns] 173 ca *image; // [lines][columns]
168 174
169 ColorEntry color_table[TABLE_COLORS]; 175 ColorEntry color_table[TABLE_COLORS];
170 176
171 BOOL resizing; 177 BOOL resizing;
172 bool mouse_marks; 178 bool mouse_marks;
173 179
174 void makeImage(); 180 void makeImage();
175 181
176 QPoint iPntSel; // initial selection point 182 QPoint iPntSel; // initial selection point
177 QPoint pntSel; // current selection point 183 QPoint pntSel; // current selection point
178 int actSel; // selection state 184 int actSel; // selection state
179 BOOL word_selection_mode; 185 BOOL word_selection_mode;
180 BOOL preserve_line_breaks; 186 BOOL preserve_line_breaks;
181 187
182 QClipboard* cb; 188 QClipboard* cb;
183 QScrollBar* scrollbar; 189 QScrollBar* scrollbar, *hScrollbar;
184 int scrollLoc; 190
191 int scrollLoc, hScrollLoc;
192 int hposition, vcolumns;
185 193
194
186//#define SCRNONE 0 195//#define SCRNONE 0
187//#define SCRLEFT 1 196//#define SCRLEFT 1
188//#define SCRRIGHT 2 197//#define SCRRIGHT 2
189 198
190 BOOL blinking; // hide text in paintEvent 199 BOOL blinking; // hide text in paintEvent
191 BOOL hasBlinker; // has characters to blink 200 BOOL hasBlinker; // has characters to blink
192 QTimer* blinkT; // active when hasBlinker 201 QTimer* blinkT; // active when hasBlinker
193 QPopupMenu* m_drop; 202 QPopupMenu* m_drop;
194 QString dropText; 203 QString dropText;
195 public: 204 public:
196 // current session in this widget 205 // current session in this widget
197 TESession *currentSession; 206 TESession *currentSession;
198private slots: 207private slots:
199 void drop_menu_activated(int item); 208 void drop_menu_activated(int item);
200}; 209};
201 210
202#endif // TE_WIDGET_H 211#endif // TE_WIDGET_H
diff --git a/core/apps/embeddedkonsole/TEmulation.cpp b/core/apps/embeddedkonsole/TEmulation.cpp
index 6f3ad32..c19f2a1 100644
--- a/core/apps/embeddedkonsole/TEmulation.cpp
+++ b/core/apps/embeddedkonsole/TEmulation.cpp
@@ -1,183 +1,193 @@
1/* -------------------------------------------------------------------------- */ 1/* -------------------------------------------------------------------------- */
2/* */ 2/* */
3/* [TEmulation.cpp] Terminal Emulation Decoder */ 3/* [TEmulation.cpp] Terminal Emulation Decoder */
4/* */ 4/* */
5/* -------------------------------------------------------------------------- */ 5/* -------------------------------------------------------------------------- */
6/* */ 6/* */
7/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */ 7/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */
8/* */ 8/* */
9/* This file is part of Konsole - an X terminal for KDE */ 9/* This file is part of Konsole - an X terminal for KDE */
10/* */ 10/* */
11/* -------------------------------------------------------------------------- */ 11/* -------------------------------------------------------------------------- */
12 /* */ 12/* */
13/* Ported Konsole to Qt/Embedded */ 13/* Ported Konsole to Qt/Embedded */
14 /* */ 14/* */
15/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */ 15/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */
16 /* */ 16/* */
17/* -------------------------------------------------------------------------- */ 17/* -------------------------------------------------------------------------- */
18 18
19/*! \class TEmulation 19/*! \class TEmulation
20 20
21 \brief Mediator between TEWidget and TEScreen. 21 \brief Mediator between TEWidget and TEScreen.
22 22
23 This class is responsible to scan the escapes sequences of the terminal 23 This class is responsible to scan the escapes sequences of the terminal
24 emulation and to map it to their corresponding semantic complements. 24 emulation and to map it to their corresponding semantic complements.
25 Thus this module knows mainly about decoding escapes sequences and 25 Thus this module knows mainly about decoding escapes sequences and
26 is a stateless device w.r.t. the semantics. 26 is a stateless device w.r.t. the semantics.
27 27
28 It is also responsible to refresh the TEWidget by certain rules. 28 It is also responsible to refresh the TEWidget by certain rules.
29 29
30 \sa TEWidget \sa TEScreen 30 \sa TEWidget \sa TEScreen
31 31
32 \par A note on refreshing 32 \par A note on refreshing
33 33
34 Although the modifications to the current screen image could immediately 34 Although the modifications to the current screen image could immediately
35 be propagated via `TEWidget' to the graphical surface, we have chosen 35 be propagated via `TEWidget' to the graphical surface, we have chosen
36 another way here. 36 another way here.
37 37
38 The reason for doing so is twofold. 38 The reason for doing so is twofold.
39 39
40 First, experiments show that directly displaying the operation results 40 First, experiments show that directly displaying the operation results
41 in slowing down the overall performance of emulations. Displaying 41 in slowing down the overall performance of emulations. Displaying
42 individual characters using X11 creates a lot of overhead. 42 individual characters using X11 creates a lot of overhead.
43 43
44 Second, by using the following refreshing method, the screen operations 44 Second, by using the following refreshing method, the screen operations
45 can be completely separated from the displaying. This greatly simplifies 45 can be completely separated from the displaying. This greatly simplifies
46 the programmer's task of coding and maintaining the screen operations, 46 the programmer's task of coding and maintaining the screen operations,
47 since one need not worry about differential modifications on the 47 since one need not worry about differential modifications on the
48 display affecting the operation of concern. 48 display affecting the operation of concern.
49 49
50 We use a refreshing algorithm here that has been adoped from rxvt/kvt. 50 We use a refreshing algorithm here that has been adoped from rxvt/kvt.
51 51
52 By this, refreshing is driven by a timer, which is (re)started whenever 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'. 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 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 55 refresh. This rule suits both bulk display operation as done by curses as
56 well as individual characters typed. 56 well as individual characters typed.
57 (BULK_TIMEOUT < 1000 / max characters received from keyboard per second). 57 (BULK_TIMEOUT < 1000 / max characters received from keyboard per second).
58 58
59 Additionally, we trigger refreshing by newlines comming in to make visual 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 60 snapshots of lists as produced by `cat', `ls' and likely programs, thereby
61 producing the illusion of a permanent and immediate display operation. 61 producing the illusion of a permanent and immediate display operation.
62 62
63 As a sort of catch-all needed for cases where none of the above 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 64 conditions catch, the screen refresh is also triggered by a count
65 of incoming bulks (`bulk_incnt'). 65 of incoming bulks (`bulk_incnt').
66*/ 66*/
67 67
68/* FIXME 68/* FIXME
69 - evtl. the bulk operations could be made more transparent. 69 - evtl. the bulk operations could be made more transparent.
70*/ 70*/
71 71
72#include "TEmulation.h" 72#include "TEmulation.h"
73#include "TEWidget.h" 73#include "TEWidget.h"
74#include "TEScreen.h" 74#include "TEScreen.h"
75#include <stdio.h> 75#include <stdio.h>
76#include <stdlib.h> 76#include <stdlib.h>
77#include <unistd.h> 77#include <unistd.h>
78#include <qkeycode.h> 78#include <qkeycode.h>
79 79
80 80
81/* ------------------------------------------------------------------------- */ 81/* ------------------------------------------------------------------------- */
82/* */ 82/* */
83/* TEmulation */ 83/* TEmulation */
84/* */ 84/* */
85/* ------------------------------------------------------------------------- */ 85/* ------------------------------------------------------------------------- */
86 86
87#define CNTL(c) ((c)-'@') 87#define CNTL(c) ((c)-'@')
88 88
89/*! 89/*!
90*/ 90*/
91 91
92TEmulation::TEmulation(TEWidget* gui) 92TEmulation::TEmulation(TEWidget* gui)
93: decoder((QTextDecoder*)NULL) 93: decoder((QTextDecoder*)NULL)
94{ 94{
95 this->gui = gui; 95 this->gui = gui;
96 96
97 screen[0] = new TEScreen(gui->Lines(),gui->Columns()); 97 screen[0] = new TEScreen(gui->Lines(),gui->Columns());
98 screen[1] = new TEScreen(gui->Lines(),gui->Columns()); 98 screen[1] = new TEScreen(gui->Lines(),gui->Columns());
99 scr = screen[0]; 99 scr = screen[0];
100 100
101 bulk_nlcnt = 0; // reset bulk newline counter 101 bulk_nlcnt = 0; // reset bulk newline counter
102 bulk_incnt = 0; // reset bulk counter 102 bulk_incnt = 0; // reset bulk counter
103 connected = FALSE; 103 connected = FALSE;
104 104
105 QObject::connect(&bulk_timer, SIGNAL(timeout()), this, SLOT(showBulk()) ); 105 QObject::connect(&bulk_timer, SIGNAL(timeout()), this, SLOT(showBulk()) );
106
106 QObject::connect(gui,SIGNAL(changedImageSizeSignal(int,int)), 107 QObject::connect(gui,SIGNAL(changedImageSizeSignal(int,int)),
107 this,SLOT(onImageSizeChange(int,int))); 108 this,SLOT(onImageSizeChange(int,int)));
109
108 QObject::connect(gui,SIGNAL(changedHistoryCursor(int)), 110 QObject::connect(gui,SIGNAL(changedHistoryCursor(int)),
109 this,SLOT(onHistoryCursorChange(int))); 111 this,SLOT(onHistoryCursorChange(int)));
112
113 QObject::connect(gui,SIGNAL(changedHorzCursor(int)),
114 this,SLOT(onHorzCursorChange(int)));
115
110 QObject::connect(gui,SIGNAL(keyPressedSignal(QKeyEvent*)), 116 QObject::connect(gui,SIGNAL(keyPressedSignal(QKeyEvent*)),
111 this,SLOT(onKeyPress(QKeyEvent*))); 117 this,SLOT(onKeyPress(QKeyEvent*)));
118
112 QObject::connect(gui,SIGNAL(beginSelectionSignal(const int,const int)), 119 QObject::connect(gui,SIGNAL(beginSelectionSignal(const int,const int)),
113 this,SLOT(onSelectionBegin(const int,const int)) ); 120 this,SLOT(onSelectionBegin(const int,const int)) );
121
114 QObject::connect(gui,SIGNAL(extendSelectionSignal(const int,const int)), 122 QObject::connect(gui,SIGNAL(extendSelectionSignal(const int,const int)),
115 this,SLOT(onSelectionExtend(const int,const int)) ); 123 this,SLOT(onSelectionExtend(const int,const int)) );
124
116 QObject::connect(gui,SIGNAL(endSelectionSignal(const BOOL)), 125 QObject::connect(gui,SIGNAL(endSelectionSignal(const BOOL)),
117 this,SLOT(setSelection(const BOOL)) ); 126 this,SLOT(setSelection(const BOOL)) );
127
118 QObject::connect(gui,SIGNAL(clearSelectionSignal()), 128 QObject::connect(gui,SIGNAL(clearSelectionSignal()),
119 this,SLOT(clearSelection()) ); 129 this,SLOT(clearSelection()) );
120} 130}
121 131
122/*! 132/*!
123*/ 133*/
124 134
125TEmulation::~TEmulation() 135TEmulation::~TEmulation()
126{ 136{
127 delete screen[0]; 137 delete screen[0];
128 delete screen[1]; 138 delete screen[1];
129 bulk_timer.stop(); 139 bulk_timer.stop();
130} 140}
131 141
132/*! change between primary and alternate screen 142/*! change between primary and alternate screen
133*/ 143*/
134 144
135void TEmulation::setScreen(int n) 145void TEmulation::setScreen(int n)
136{ 146{
137 scr = screen[n&1]; 147 scr = screen[n&1];
138} 148}
139 149
140void TEmulation::setHistory(bool on) 150void TEmulation::setHistory(bool on)
141{ 151{
142 screen[0]->setScroll(on); 152 screen[0]->setScroll(on);
143 if (!connected) return; 153 if (!connected) return;
144 showBulk(); 154 showBulk();
145} 155}
146 156
147bool TEmulation::history() 157bool TEmulation::history()
148{ 158{
149 return screen[0]->hasScroll(); 159 return screen[0]->hasScroll();
150} 160}
151 161
152void TEmulation::setCodec(int c) 162void TEmulation::setCodec(int c)
153{ 163{
154 //FIXME: check whether we have to free codec 164 //FIXME: check whether we have to free codec
155 codec = c ? QTextCodec::codecForName("utf8") 165 codec = c ? QTextCodec::codecForName("utf8")
156 : QTextCodec::codecForLocale(); 166 : QTextCodec::codecForLocale();
157 if (decoder) delete decoder; 167 if (decoder) delete decoder;
158 decoder = codec->makeDecoder(); 168 decoder = codec->makeDecoder();
159} 169}
160 170
161void TEmulation::setKeytrans(int no) 171void TEmulation::setKeytrans(int no)
162{ 172{
163 keytrans = KeyTrans::find(no); 173 keytrans = KeyTrans::find(no);
164} 174}
165 175
166void TEmulation::setKeytrans(const char * no) 176void TEmulation::setKeytrans(const char * no)
167{ 177{
168 keytrans = KeyTrans::find(no); 178 keytrans = KeyTrans::find(no);
169} 179}
170 180
171// Interpreting Codes --------------------------------------------------------- 181// Interpreting Codes ---------------------------------------------------------
172 182
173/* 183/*
174 This section deals with decoding the incoming character stream. 184 This section deals with decoding the incoming character stream.
175 Decoding means here, that the stream is first seperated into `tokens' 185 Decoding means here, that the stream is first seperated into `tokens'
176 which are then mapped to a `meaning' provided as operations by the 186 which are then mapped to a `meaning' provided as operations by the
177 `Screen' class. 187 `Screen' class.
178*/ 188*/
179 189
180/*! 190/*!
181*/ 191*/
182 192
183void TEmulation::onRcvChar(int c) 193void TEmulation::onRcvChar(int c)
@@ -238,126 +248,131 @@ void TEmulation::onRcvBlock(const char *s, int len)
238 { 248 {
239 QString result = decoder->toUnicode(&s[i],1); 249 QString result = decoder->toUnicode(&s[i],1);
240 int reslen = result.length(); 250 int reslen = result.length();
241 for (int j = 0; j < reslen; j++) 251 for (int j = 0; j < reslen; j++)
242 onRcvChar(result[j].unicode()); 252 onRcvChar(result[j].unicode());
243 if (s[i] == '\n') bulkNewline(); 253 if (s[i] == '\n') bulkNewline();
244 } 254 }
245 bulkEnd(); 255 bulkEnd();
246} 256}
247 257
248// Selection --------------------------------------------------------------- -- 258// Selection --------------------------------------------------------------- --
249 259
250void TEmulation::onSelectionBegin(const int x, const int y) { 260void TEmulation::onSelectionBegin(const int x, const int y) {
251 if (!connected) return; 261 if (!connected) return;
252 scr->setSelBeginXY(x,y); 262 scr->setSelBeginXY(x,y);
253 showBulk(); 263 showBulk();
254} 264}
255 265
256void TEmulation::onSelectionExtend(const int x, const int y) { 266void TEmulation::onSelectionExtend(const int x, const int y) {
257 if (!connected) return; 267 if (!connected) return;
258 scr->setSelExtentXY(x,y); 268 scr->setSelExtentXY(x,y);
259 showBulk(); 269 showBulk();
260} 270}
261 271
262void TEmulation::setSelection(const BOOL preserve_line_breaks) { 272void TEmulation::setSelection(const BOOL preserve_line_breaks) {
263 if (!connected) return; 273 if (!connected) return;
264 QString t = scr->getSelText(preserve_line_breaks); 274 QString t = scr->getSelText(preserve_line_breaks);
265 if (!t.isNull()) gui->setSelection(t); 275 if (!t.isNull()) gui->setSelection(t);
266} 276}
267 277
268void TEmulation::clearSelection() { 278void TEmulation::clearSelection() {
269 if (!connected) return; 279 if (!connected) return;
270 scr->clearSelection(); 280 scr->clearSelection();
271 showBulk(); 281 showBulk();
272} 282}
273 283
274// Refreshing -------------------------------------------------------------- -- 284// Refreshing -------------------------------------------------------------- --
275 285
276#define BULK_TIMEOUT 20 286#define BULK_TIMEOUT 20
277 287
278/*! 288/*!
279 called when \n comes in. Evtl. triggers showBulk at endBulk 289 called when \n comes in. Evtl. triggers showBulk at endBulk
280*/ 290*/
281 291
282void TEmulation::bulkNewline() 292void TEmulation::bulkNewline()
283{ 293{
284 bulk_nlcnt += 1; 294 bulk_nlcnt += 1;
285 bulk_incnt = 0; // reset bulk counter since `nl' rule applies 295 bulk_incnt = 0; // reset bulk counter since `nl' rule applies
286} 296}
287 297
288/*! 298/*!
289*/ 299*/
290 300
291void TEmulation::showBulk() 301void TEmulation::showBulk()
292{ 302{
293 bulk_nlcnt = 0; // reset bulk newline counter 303 bulk_nlcnt = 0; // reset bulk newline counter
294 bulk_incnt = 0; // reset bulk counter 304 bulk_incnt = 0; // reset bulk counter
295 if (connected) 305 if (connected)
296 { 306 {
297 ca* image = scr->getCookedImage(); // get the image 307 ca* image = scr->getCookedImage(); // get the image
298 gui->setImage(image, 308 gui->setImage(image,
299 scr->getLines(), 309 scr->getLines(),
300 scr->getColumns()); // actual refresh 310 scr->getColumns()); // actual refresh
301 free(image); 311 free(image);
302 //FIXME: check that we do not trigger other draw event here. 312
313 //FIXME: check that we do not trigger other draw event here.
303 gui->setScroll(scr->getHistCursor(),scr->getHistLines()); 314 gui->setScroll(scr->getHistCursor(),scr->getHistLines());
315
304 } 316 }
305} 317}
306 318
307void TEmulation::bulkStart() 319void TEmulation::bulkStart()
308{ 320{
309 if (bulk_timer.isActive()) bulk_timer.stop(); 321 if (bulk_timer.isActive()) bulk_timer.stop();
310} 322}
311 323
312void TEmulation::bulkEnd() 324void TEmulation::bulkEnd()
313{ 325{
314 if ( bulk_nlcnt > gui->Lines() || bulk_incnt > 20 ) 326 if ( bulk_nlcnt > gui->Lines() || bulk_incnt > 20 )
315 showBulk(); // resets bulk_??cnt to 0, too. 327 showBulk(); // resets bulk_??cnt to 0, too.
316 else 328 else
317 bulk_timer.start(BULK_TIMEOUT,TRUE); 329 bulk_timer.start(BULK_TIMEOUT,TRUE);
318} 330}
319 331
320void TEmulation::setConnect(bool c) 332void TEmulation::setConnect(bool c)
321{ 333{
322 connected = c; 334 connected = c;
323 if ( connected) 335 if ( connected)
324 { 336 {
325 onImageSizeChange(gui->Lines(), gui->Columns()); 337 onImageSizeChange(gui->Lines(), gui->Columns());
326 showBulk(); 338 showBulk();
327 } 339 }
328 else 340 else
329 { 341 {
330 scr->clearSelection(); 342 scr->clearSelection();
331 } 343 }
332} 344}
333 345
334// --------------------------------------------------------------------------- 346// ---------------------------------------------------------------------------
335 347
336/*! triggered by image size change of the TEWidget `gui'. 348/*! triggered by image size change of the TEWidget `gui'.
337 349
338 This event is simply propagated to the attached screens 350 This event is simply propagated to the attached screens
339 and to the related serial line. 351 and to the related serial line.
340*/ 352*/
341 353
342void TEmulation::onImageSizeChange(int lines, int columns) 354void TEmulation::onImageSizeChange(int lines, int columns) {
343{
344 if (!connected) return; 355 if (!connected) return;
345 screen[0]->resizeImage(lines,columns); 356 screen[0]->resizeImage(lines,columns);
346 screen[1]->resizeImage(lines,columns); 357 screen[1]->resizeImage(lines,columns);
347 showBulk(); 358 showBulk();
348 emit ImageSizeChanged(lines,columns); // propagate event to serial line 359 emit ImageSizeChanged(lines,columns); // propagate event to serial line
349} 360}
350 361
351void TEmulation::onHistoryCursorChange(int cursor) 362void TEmulation::onHistoryCursorChange(int cursor) {
352{
353 if (!connected) return; 363 if (!connected) return;
354 scr->setHistCursor(cursor); 364 scr->setHistCursor(cursor);
355 showBulk(); 365 showBulk();
356} 366}
357 367
358void TEmulation::setColumns(int columns) 368void TEmulation::onHorzCursorChange(int cursor) {
359{ 369 if (!connected) return;
370 scr->setHorzCursor(cursor);
371 showBulk();
372}
373
374void TEmulation::setColumns(int columns) {
360 //FIXME: this goes strange ways. 375 //FIXME: this goes strange ways.
361 // Can we put this straight or explain it at least? 376 // Can we put this straight or explain it at least?
362 emit changeColumns(columns); 377 emit changeColumns(columns);
363} 378}
diff --git a/core/apps/embeddedkonsole/konsole.cpp b/core/apps/embeddedkonsole/konsole.cpp
index a8ddc99..3c87ad4 100644
--- a/core/apps/embeddedkonsole/konsole.cpp
+++ b/core/apps/embeddedkonsole/konsole.cpp
@@ -297,143 +297,155 @@ void Konsole::init(const char* _pgm, QStrList & _args)
297 297
298 connect( fontList, SIGNAL( activated(int) ), this, SLOT( fontChanged(int) )); 298 connect( fontList, SIGNAL( activated(int) ), this, SLOT( fontChanged(int) ));
299 connect( configMenu, SIGNAL( activated(int) ), this, SLOT( configMenuSelected(int) )); 299 connect( configMenu, SIGNAL( activated(int) ), this, SLOT( configMenuSelected(int) ));
300 connect( colorMenu, SIGNAL( activated(int) ), this, SLOT( colorMenuIsSelected(int) )); 300 connect( colorMenu, SIGNAL( activated(int) ), this, SLOT( colorMenuIsSelected(int) ));
301 connect( scrollMenu, SIGNAL(activated(int)),this,SLOT(scrollMenuSelected(int))); 301 connect( scrollMenu, SIGNAL(activated(int)),this,SLOT(scrollMenuSelected(int)));
302 connect(editCommandListMenu,SIGNAL(activated(int)),this,SLOT(editCommandListMenuSelected(int))); 302 connect(editCommandListMenu,SIGNAL(activated(int)),this,SLOT(editCommandListMenuSelected(int)));
303 menuBar->insertItem( tr("Font"), fontList ); 303 menuBar->insertItem( tr("Font"), fontList );
304 menuBar->insertItem( tr("Options"), configMenu ); 304 menuBar->insertItem( tr("Options"), configMenu );
305 305
306 QPEToolBar *toolbar = new QPEToolBar( this ); 306 QPEToolBar *toolbar = new QPEToolBar( this );
307 307
308 QAction *a; 308 QAction *a;
309 309
310 // Button Commands 310 // Button Commands
311 a = new QAction( tr("New"), Resource::loadPixmap( "konsole" ), QString::null, 0, this, 0 ); 311 a = new QAction( tr("New"), Resource::loadPixmap( "konsole" ), QString::null, 0, this, 0 );
312 connect( a, SIGNAL( activated() ), this, SLOT( newSession() ) ); a->addTo( toolbar ); 312 connect( a, SIGNAL( activated() ), this, SLOT( newSession() ) ); a->addTo( toolbar );
313 a = new QAction( tr("Enter"), Resource::loadPixmap( "konsole/enter" ), QString::null, 0, this, 0 ); 313 a = new QAction( tr("Enter"), Resource::loadPixmap( "konsole/enter" ), QString::null, 0, this, 0 );
314 connect( a, SIGNAL( activated() ), this, SLOT( hitEnter() ) ); a->addTo( toolbar ); 314 connect( a, SIGNAL( activated() ), this, SLOT( hitEnter() ) ); a->addTo( toolbar );
315 a = new QAction( tr("Space"), Resource::loadPixmap( "konsole/space" ), QString::null, 0, this, 0 ); 315 a = new QAction( tr("Space"), Resource::loadPixmap( "konsole/space" ), QString::null, 0, this, 0 );
316 connect( a, SIGNAL( activated() ), this, SLOT( hitSpace() ) ); a->addTo( toolbar ); 316 connect( a, SIGNAL( activated() ), this, SLOT( hitSpace() ) ); a->addTo( toolbar );
317 a = new QAction( tr("Tab"), Resource::loadPixmap( "konsole/tab" ), QString::null, 0, this, 0 ); 317 a = new QAction( tr("Tab"), Resource::loadPixmap( "konsole/tab" ), QString::null, 0, this, 0 );
318 connect( a, SIGNAL( activated() ), this, SLOT( hitTab() ) ); a->addTo( toolbar ); 318 connect( a, SIGNAL( activated() ), this, SLOT( hitTab() ) ); a->addTo( toolbar );
319 a = new QAction( tr("Up"), Resource::loadPixmap( "konsole/up" ), QString::null, 0, this, 0 ); 319 a = new QAction( tr("Up"), Resource::loadPixmap( "konsole/up" ), QString::null, 0, this, 0 );
320 connect( a, SIGNAL( activated() ), this, SLOT( hitUp() ) ); a->addTo( toolbar ); 320 connect( a, SIGNAL( activated() ), this, SLOT( hitUp() ) ); a->addTo( toolbar );
321 a = new QAction( tr("Down"), Resource::loadPixmap( "konsole/down" ), QString::null, 0, this, 0 ); 321 a = new QAction( tr("Down"), Resource::loadPixmap( "konsole/down" ), QString::null, 0, this, 0 );
322 connect( a, SIGNAL( activated() ), this, SLOT( hitDown() ) ); a->addTo( toolbar ); 322 connect( a, SIGNAL( activated() ), this, SLOT( hitDown() ) ); a->addTo( toolbar );
323 a = new QAction( tr("Paste"), Resource::loadPixmap( "paste" ), QString::null, 0, this, 0 ); 323 a = new QAction( tr("Paste"), Resource::loadPixmap( "paste" ), QString::null, 0, this, 0 );
324 connect( a, SIGNAL( activated() ), this, SLOT( hitPaste() ) ); a->addTo( toolbar ); 324 connect( a, SIGNAL( activated() ), this, SLOT( hitPaste() ) ); a->addTo( toolbar );
325/* 325/*
326 a = new QAction( tr("Up"), Resource::loadPixmap( "up" ), QString::null, 0, this, 0 ); 326 a = new QAction( tr("Up"), Resource::loadPixmap( "up" ), QString::null, 0, this, 0 );
327 connect( a, SIGNAL( activated() ), this, SLOT( hitUp() ) ); a->addTo( toolbar ); 327 connect( a, SIGNAL( activated() ), this, SLOT( hitUp() ) ); a->addTo( toolbar );
328 a = new QAction( tr("Down"), Resource::loadPixmap( "down" ), QString::null, 0, this, 0 ); 328 a = new QAction( tr("Down"), Resource::loadPixmap( "down" ), QString::null, 0, this, 0 );
329 connect( a, SIGNAL( activated() ), this, SLOT( hitDown() ) ); a->addTo( toolbar ); 329 connect( a, SIGNAL( activated() ), this, SLOT( hitDown() ) ); a->addTo( toolbar );
330*/ 330*/
331 331
332 secondToolBar = new QPEToolBar( this ); 332 secondToolBar = new QPEToolBar( this );
333 secondToolBar->setHorizontalStretchable( TRUE ); 333 secondToolBar->setHorizontalStretchable( TRUE );
334 334
335 commonCombo = new QComboBox( secondToolBar ); 335 commonCombo = new QComboBox( secondToolBar );
336 commonCombo->setMaximumWidth(236); 336 commonCombo->setMaximumWidth(236);
337 337
338 editCommandListMenu->insertItem( tr( "Quick Edit" ) ); 338 editCommandListMenu->insertItem( tr( "Quick Edit" ) );
339 if( listHidden) { 339 if( listHidden) {
340 secondToolBar->hide(); 340 secondToolBar->hide();
341 editCommandListMenu->setItemEnabled(-23 ,FALSE); 341 editCommandListMenu->setItemEnabled(-23 ,FALSE);
342 } 342 }
343 editCommandListMenu->insertItem(tr( "Edit" ) ); 343 editCommandListMenu->insertItem(tr( "Edit" ) );
344 344
345 cfg.setGroup("Commands"); 345 cfg.setGroup("Commands");
346 commonCombo->setInsertionPolicy(QComboBox::AtCurrent); 346 commonCombo->setInsertionPolicy(QComboBox::AtCurrent);
347 347
348 initCommandList(); 348 initCommandList();
349// for (int i = 0; commonCmds[i] != NULL; i++) { 349// for (int i = 0; commonCmds[i] != NULL; i++) {
350// commonCombo->insertItem( commonCmds[i], i ); 350// commonCombo->insertItem( commonCmds[i], i );
351// tmp = cfg.readEntry( QString::number(i),""); 351// tmp = cfg.readEntry( QString::number(i),"");
352// if(tmp != "") 352// if(tmp != "")
353// commonCombo->changeItem( tmp,i ); 353// commonCombo->changeItem( tmp,i );
354// } 354// }
355 355
356 connect( commonCombo, SIGNAL( activated(int) ), this, SLOT( enterCommand(int) )); 356 connect( commonCombo, SIGNAL( activated(int) ), this, SLOT( enterCommand(int) ));
357 357
358 scrollMenu->insertItem(tr( "None" )); 358 scrollMenu->insertItem(tr( "None" ));
359 scrollMenu->insertItem(tr( "Left" )); 359 scrollMenu->insertItem(tr( "Left" ));
360 scrollMenu->insertItem(tr( "Right" )); 360 scrollMenu->insertItem(tr( "Right" ));
361 scrollMenu->insertSeparator(4);
362 scrollMenu->insertItem(tr( "Horizontal" ));
363
361 configMenu->insertItem(tr( "ScrollBar" ),scrollMenu); 364 configMenu->insertItem(tr( "ScrollBar" ),scrollMenu);
362 365//scrollMenuSelected(-29);
366// cfg.setGroup("ScrollBar");
367// if(cfg.readBoolEntry("HorzScroll",0)) {
368// if(cfg.readNumEntry("Position",2) == 0)
369// te->setScrollbarLocation(1);
370// else
371// te->setScrollbarLocation(0);
372// te->setScrollbarLocation( cfg.readNumEntry("Position",2));
373// te->setWrapAt(120);
374// }
363 // create applications ///////////////////////////////////////////////////// 375 // create applications /////////////////////////////////////////////////////
364 setCentralWidget(tab); 376 setCentralWidget(tab);
365 377
366 // load keymaps //////////////////////////////////////////////////////////// 378 // load keymaps ////////////////////////////////////////////////////////////
367 KeyTrans::loadAll(); 379 KeyTrans::loadAll();
368 for (int i = 0; i < KeyTrans::count(); i++) 380 for (int i = 0; i < KeyTrans::count(); i++)
369 { KeyTrans* s = KeyTrans::find(i); 381 { KeyTrans* s = KeyTrans::find(i);
370 assert( s ); 382 assert( s );
371 } 383 }
372 384
373 se_pgm = _pgm; 385 se_pgm = _pgm;
374 se_args = _args; 386 se_args = _args;
375 387 se_args.prepend("--login");
376parseCommandLine(); 388parseCommandLine();
377 // read and apply default values /////////////////////////////////////////// 389 // read and apply default values ///////////////////////////////////////////
378 resize(321, 321); // Dummy. 390 resize(321, 321); // Dummy.
379 QSize currentSize = size(); 391 QSize currentSize = size();
380 if (currentSize != size()) 392 if (currentSize != size())
381 defaultSize = size(); 393 defaultSize = size();
382} 394}
383 395
384void Konsole::show() 396void Konsole::show()
385{ 397{
386 if ( !nsessions ) { 398 if ( !nsessions ) {
387 newSession(); 399 newSession();
388 } 400 }
389 QMainWindow::show(); 401 QMainWindow::show();
390} 402}
391 403
392void Konsole::initSession(const char*, QStrList &) 404void Konsole::initSession(const char*, QStrList &)
393{ 405{
394 QMainWindow::show(); 406 QMainWindow::show();
395} 407}
396 408
397Konsole::~Konsole() 409Konsole::~Konsole()
398{ 410{
399 while (nsessions > 0) { 411 while (nsessions > 0) {
400 doneSession(getTe()->currentSession, 0); 412 doneSession(getTe()->currentSession, 0);
401 } 413 }
402 414
403 Config cfg("Konsole"); 415 Config cfg("Konsole");
404 cfg.setGroup("Konsole"); 416 cfg.setGroup("Konsole");
405 cfg.writeEntry("FontID", cfont); 417 cfg.writeEntry("FontID", cfont);
406} 418}
407 419
408void Konsole::fontChanged(int f) 420void Konsole::fontChanged(int f)
409{ 421{
410 VTFont* font = fonts.at(f); 422 VTFont* font = fonts.at(f);
411 if (font != 0) { 423 if (font != 0) {
412 for(uint i = 0; i < fonts.count(); i++) { 424 for(uint i = 0; i < fonts.count(); i++) {
413 fontList->setItemChecked(i, (i == (uint) f) ? TRUE : FALSE); 425 fontList->setItemChecked(i, (i == (uint) f) ? TRUE : FALSE);
414 } 426 }
415 427
416 cfont = f; 428 cfont = f;
417 429
418 TEWidget* te = getTe(); 430 TEWidget* te = getTe();
419 if (te != 0) { 431 if (te != 0) {
420 te->setVTFont(font->getFont()); 432 te->setVTFont(font->getFont());
421 } 433 }
422 } 434 }
423} 435}
424 436
425 437
426void Konsole::enterCommand(int c) 438void Konsole::enterCommand(int c)
427{ 439{
428 TEWidget* te = getTe(); 440 TEWidget* te = getTe();
429 if (te != 0) { 441 if (te != 0) {
430 if(!commonCombo->editable()) { 442 if(!commonCombo->editable()) {
431 QString text = commonCombo->text(c); //commonCmds[c]; 443 QString text = commonCombo->text(c); //commonCmds[c];
432 te->emitText(text); 444 te->emitText(text);
433 } else { 445 } else {
434 changeCommand( commonCombo->text(c), c); 446 changeCommand( commonCombo->text(c), c);
435 } 447 }
436 } 448 }
437} 449}
438 450
439void Konsole::hitEnter() 451void Konsole::hitEnter()
@@ -447,172 +459,175 @@ void Konsole::hitEnter()
447void Konsole::hitSpace() 459void Konsole::hitSpace()
448{ 460{
449 TEWidget* te = getTe(); 461 TEWidget* te = getTe();
450 if (te != 0) { 462 if (te != 0) {
451 te->emitText(QString(" ")); 463 te->emitText(QString(" "));
452 } 464 }
453} 465}
454 466
455void Konsole::hitTab() 467void Konsole::hitTab()
456{ 468{
457 TEWidget* te = getTe(); 469 TEWidget* te = getTe();
458 if (te != 0) { 470 if (te != 0) {
459 te->emitText(QString("\t")); 471 te->emitText(QString("\t"));
460 } 472 }
461} 473}
462 474
463void Konsole::hitPaste() 475void Konsole::hitPaste()
464{ 476{
465 TEWidget* te = getTe(); 477 TEWidget* te = getTe();
466 if (te != 0) { 478 if (te != 0) {
467 te->pasteClipboard(); 479 te->pasteClipboard();
468 } 480 }
469} 481}
470 482
471void Konsole::hitUp() 483void Konsole::hitUp()
472{ 484{
473 TEWidget* te = getTe(); 485 TEWidget* te = getTe();
474 if (te != 0) { 486 if (te != 0) {
475 QKeyEvent ke( QKeyEvent::KeyPress, Qt::Key_Up, 0, 0); 487 QKeyEvent ke( QKeyEvent::KeyPress, Qt::Key_Up, 0, 0);
476 QApplication::sendEvent( te, &ke ); 488 QApplication::sendEvent( te, &ke );
477 } 489 }
478} 490}
479 491
480void Konsole::hitDown() 492void Konsole::hitDown()
481{ 493{
482 TEWidget* te = getTe(); 494 TEWidget* te = getTe();
483 if (te != 0) { 495 if (te != 0) {
484 QKeyEvent ke( QKeyEvent::KeyPress, Qt::Key_Down, 0, 0); 496 QKeyEvent ke( QKeyEvent::KeyPress, Qt::Key_Down, 0, 0);
485 QApplication::sendEvent( te, &ke ); 497 QApplication::sendEvent( te, &ke );
486 } 498 }
487} 499}
488 500
489/** 501/**
490 This function calculates the size of the external widget 502 This function calculates the size of the external widget
491 needed for the internal widget to be 503 needed for the internal widget to be
492 */ 504 */
493QSize Konsole::calcSize(int columns, int lines) { 505QSize Konsole::calcSize(int columns, int lines) {
494 TEWidget* te = getTe(); 506 TEWidget* te = getTe();
495 if (te != 0) { 507 if (te != 0) {
496 QSize size = te->calcSize(columns, lines); 508 QSize size = te->calcSize(columns, lines);
497 return size; 509 return size;
498 } else { 510 } else {
499 QSize size; 511 QSize size;
500 return size; 512 return size;
501 } 513 }
502} 514}
503 515
504/** 516/**
505 sets application window to a size based on columns X lines of the te 517 sets application window to a size based on columns X lines of the te
506 guest widget. Call with (0,0) for setting default size. 518 guest widget. Call with (0,0) for setting default size.
507*/ 519*/
508 520
509void Konsole::setColLin(int columns, int lines) 521void Konsole::setColLin(int columns, int lines)
510{ 522{
523 qDebug("konsole::setColLin:: Columns %d", columns);
524
511 if ((columns==0) || (lines==0)) 525 if ((columns==0) || (lines==0))
512 { 526 {
513 if (defaultSize.isEmpty()) // not in config file : set default value 527 if (defaultSize.isEmpty()) // not in config file : set default value
514 { 528 {
515 defaultSize = calcSize(80,24); 529 defaultSize = calcSize(80,24);
516 // notifySize(24,80); // set menu items (strange arg order !) 530 // notifySize(24,80); // set menu items (strange arg order !)
517 } 531 }
518 resize(defaultSize); 532 resize(defaultSize);
519 } else { 533 } else {
520 resize(calcSize(columns, lines)); 534 resize(calcSize(columns, lines));
521 // notifySize(lines,columns); // set menu items (strange arg order !) 535 // notifySize(lines,columns); // set menu items (strange arg order !)
522 } 536 }
523} 537}
524 538
525/* 539/*
526void Konsole::setFont(int fontno) 540void Konsole::setFont(int fontno)
527{ 541{
528 QFont f; 542 QFont f;
529 if (fontno == 0) 543 if (fontno == 0)
530 f = defaultFont = QFont( "Helvetica", 12 ); 544 f = defaultFont = QFont( "Helvetica", 12 );
531 else 545 else
532 if (fonts[fontno][0] == '-') 546 if (fonts[fontno][0] == '-')
533 f.setRawName( fonts[fontno] ); 547 f.setRawName( fonts[fontno] );
534 else 548 else
535 { 549 {
536 f.setFamily(fonts[fontno]); 550 f.setFamily(fonts[fontno]);
537 f.setRawMode( TRUE ); 551 f.setRawMode( TRUE );
538 } 552 }
539 if ( !f.exactMatch() && fontno != 0) 553 if ( !f.exactMatch() && fontno != 0)
540 { 554 {
541 QString msg = i18n("Font `%1' not found.\nCheck README.linux.console for help.").arg(fonts[fontno]); 555 QString msg = i18n("Font `%1' not found.\nCheck README.linux.console for help.").arg(fonts[fontno]);
542 QMessageBox(this, msg); 556 QMessageBox(this, msg);
543 return; 557 return;
544 } 558 }
545 if (se) se->setFontNo(fontno); 559 if (se) se->setFontNo(fontno);
546 te->setVTFont(f); 560 te->setVTFont(f);
547 n_font = fontno; 561 n_font = fontno;
548} 562}
549*/ 563*/
550 564
551// --| color selection |------------------------------------------------------- 565// --| color selection |-------------------------------------------------------
552 566
553void Konsole::changeColumns(int columns) 567void Konsole::changeColumns(int columns)
554{ 568{
569 qDebug("change columns");
555 TEWidget* te = getTe(); 570 TEWidget* te = getTe();
556 if (te != 0) { 571 if (te != 0) {
557 setColLin(columns,te->Lines()); 572 setColLin(columns,te->Lines());
558 te->update(); 573 te->update();
559 } 574 }
560} 575}
561 576
562//FIXME: If a child dies during session swap, 577//FIXME: If a child dies during session swap,
563// this routine might be called before 578// this routine might be called before
564// session swap is completed. 579// session swap is completed.
565 580
566void Konsole::doneSession(TESession*, int ) 581void Konsole::doneSession(TESession*, int )
567{ 582{
568 TEWidget *te = getTe(); 583 TEWidget *te = getTe();
569 if (te != 0) { 584 if (te != 0) {
570 te->currentSession->setConnect(FALSE); 585 te->currentSession->setConnect(FALSE);
571 tab->removeTab(te); 586 tab->removeTab(te);
572 delete te->currentSession; 587 delete te->currentSession;
573 delete te; 588 delete te;
574 nsessions--; 589 nsessions--;
575 } 590 }
576 591
577 if (nsessions == 0) { 592 if (nsessions == 0) {
578 close(); 593 close();
579 } 594 }
580} 595}
581 596
582void Konsole::newSession() { 597void Konsole::newSession() {
583 if(nsessions < 15) { // seems to be something weird about 16 tabs on the Zaurus.... memory? 598 if(nsessions < 15) { // seems to be something weird about 16 tabs on the Zaurus.... memory?
584 TEWidget* te = new TEWidget(tab); 599 TEWidget* te = new TEWidget(tab);
585// te->setBackgroundMode(PaletteBase); //we want transparent!! 600// te->setBackgroundMode(PaletteBase); //we want transparent!!
586 te->setVTFont(fonts.at(cfont)->getFont()); 601 te->setVTFont(fonts.at(cfont)->getFont());
587 tab->addTab(te); 602 tab->addTab(te);
588 TESession* se = new TESession(this, te, se_pgm, se_args, "xterm"); 603 TESession* se = new TESession(this, te, se_pgm, se_args, "xterm");
589 te->currentSession = se; 604 te->currentSession = se;
590 connect( se, SIGNAL(done(TESession*,int)), this, SLOT(doneSession(TESession*,int)) ); 605 connect( se, SIGNAL(done(TESession*,int)), this, SLOT(doneSession(TESession*,int)) );
591 se->run(); 606 se->run();
592 se->setConnect(TRUE); 607 se->setConnect(TRUE);
593 se->setHistory(b_scroll); 608 se->setHistory(b_scroll);
594 tab->setCurrentPage(nsessions); 609 tab->setCurrentPage(nsessions);
595 nsessions++; 610 nsessions++;
596 setColor(); 611 setColor();
597 } 612 }
598} 613}
599 614
600TEWidget* Konsole::getTe() { 615TEWidget* Konsole::getTe() {
601 if (nsessions) { 616 if (nsessions) {
602 return (TEWidget *) tab->currentPage(); 617 return (TEWidget *) tab->currentPage();
603 } else { 618 } else {
604 return 0; 619 return 0;
605 } 620 }
606} 621}
607 622
608void Konsole::switchSession(QWidget* w) { 623void Konsole::switchSession(QWidget* w) {
609 TEWidget* te = (TEWidget *) w; 624 TEWidget* te = (TEWidget *) w;
610 625
611 QFont teFnt = te->getVTFont(); 626 QFont teFnt = te->getVTFont();
612 for(uint i = 0; i < fonts.count(); i++) { 627 for(uint i = 0; i < fonts.count(); i++) {
613 VTFont *fnt = fonts.at(i); 628 VTFont *fnt = fonts.at(i);
614 bool cf = fnt->getFont() == teFnt; 629 bool cf = fnt->getFont() == teFnt;
615 fontList->setItemChecked(i, cf); 630 fontList->setItemChecked(i, cf);
616 if (cf) { 631 if (cf) {
617 cfont = i; 632 cfont = i;
618 } 633 }
@@ -739,146 +754,157 @@ void Konsole::colorMenuSelected(int iD)
739 colorMenu->setItemChecked(-19,TRUE); 754 colorMenu->setItemChecked(-19,TRUE);
740 } 755 }
741 756
742 for (i = 0; i < TABLE_COLORS; i++) { 757 for (i = 0; i < TABLE_COLORS; i++) {
743 if(i==0 || i == 10) { 758 if(i==0 || i == 10) {
744 m_table[i].color = foreground; 759 m_table[i].color = foreground;
745 } 760 }
746 else if(i==1 || i == 11) { 761 else if(i==1 || i == 11) {
747 m_table[i].color = background; m_table[i].transparent=0; 762 m_table[i].color = background; m_table[i].transparent=0;
748 } 763 }
749 else 764 else
750 m_table[i].color = defaultCt[i].color; 765 m_table[i].color = defaultCt[i].color;
751 } 766 }
752 } 767 }
753 lastSelectedMenu = iD; 768 lastSelectedMenu = iD;
754 te->setColorTable(m_table); 769 te->setColorTable(m_table);
755 update(); 770 update();
756 771
757} 772}
758 773
759void Konsole::configMenuSelected(int iD) 774void Konsole::configMenuSelected(int iD)
760{ 775{
761// QString temp; 776// QString temp;
762// qDebug( temp.sprintf("configmenu %d",iD)); 777// qDebug( temp.sprintf("configmenu %d",iD));
763 TEWidget* te = getTe(); 778 TEWidget* te = getTe();
764 Config cfg("Konsole"); 779 Config cfg("Konsole");
765 cfg.setGroup("Menubar"); 780 cfg.setGroup("Menubar");
766 if( iD == -4) { 781 if( iD == -4) {
767 cfg.setGroup("Tabs"); 782 cfg.setGroup("Tabs");
768 QString tmp=cfg.readEntry("Position","Bottom"); 783 QString tmp=cfg.readEntry("Position","Bottom");
769 784
770 if(tmp=="Top") { 785 if(tmp=="Top") {
771 tab->setTabPosition(QTabWidget::Bottom); 786 tab->setTabPosition(QTabWidget::Bottom);
772 configMenu->changeItem( iD,"Tabs on Top"); 787 configMenu->changeItem( iD,"Tabs on Top");
773 cfg.writeEntry("Position","Bottom"); 788 cfg.writeEntry("Position","Bottom");
774 } else { 789 } else {
775 tab->setTabPosition(QTabWidget::Top); 790 tab->setTabPosition(QTabWidget::Top);
776 configMenu->changeItem( iD,"Tabs on Bottom"); 791 configMenu->changeItem( iD,"Tabs on Bottom");
777 cfg.writeEntry("Position","Top"); 792 cfg.writeEntry("Position","Top");
778 } 793 }
779 } 794 }
780} 795}
781 796
782void Konsole::changeCommand(const QString &text, int c) 797void Konsole::changeCommand(const QString &text, int c)
783{ 798{
784 Config cfg("Konsole"); 799 Config cfg("Konsole");
785 cfg.setGroup("Commands"); 800 cfg.setGroup("Commands");
786 if(commonCmds[c] != text) { 801 if(commonCmds[c] != text) {
787 cfg.writeEntry(QString::number(c),text); 802 cfg.writeEntry(QString::number(c),text);
788 commonCombo->clearEdit(); 803 commonCombo->clearEdit();
789 commonCombo->setCurrentItem(c); 804 commonCombo->setCurrentItem(c);
790 } 805 }
791} 806}
792 807
793void Konsole::setColor() 808void Konsole::setColor()
794{ 809{
795 Config cfg("Konsole"); 810 Config cfg("Konsole");
796 cfg.setGroup("Colors"); 811 cfg.setGroup("Colors");
797 int scheme = cfg.readNumEntry("Schema",1); 812 int scheme = cfg.readNumEntry("Schema",1);
798 if(scheme != 1) colorMenuSelected( -scheme); 813 if(scheme != 1) colorMenuSelected( -scheme);
799} 814}
800 815
801void Konsole::scrollMenuSelected(int index) 816void Konsole::scrollMenuSelected(int index)
802{ 817{
803// QString temp; 818 qDebug( "scrollbar menu %d",index);
804// qDebug( temp.sprintf("scrollbar menu %d",index));
805 TEWidget* te = getTe(); 819 TEWidget* te = getTe();
806 Config cfg("Konsole"); 820 Config cfg("Konsole");
807 cfg.setGroup("ScrollBar"); 821 cfg.setGroup("ScrollBar");
808 switch( index){ 822 switch( index){
809 case -25: 823 case -25:
810 te->setScrollbarLocation(0); 824 te->setScrollbarLocation(0);
811 cfg.writeEntry("Position",0); 825 cfg.writeEntry("Position",0);
812 break; 826 break;
813 case -26: 827 case -26:
814 te->setScrollbarLocation(1); 828 te->setScrollbarLocation(1);
815 cfg.writeEntry("Position",1); 829 cfg.writeEntry("Position",1);
816 break; 830 break;
817 case -27: 831 case -27:
818 te->setScrollbarLocation(2); 832 te->setScrollbarLocation(2);
819 cfg.writeEntry("Position",2); 833 cfg.writeEntry("Position",2);
820 break; 834 break;
835 case -29: {
836 bool b=cfg.readBoolEntry("HorzScroll",0);
837 cfg.writeEntry("HorzScroll", !b );
838 cfg.write();
839 if(cfg.readNumEntry("Position",2) == 0)
840 te->setScrollbarLocation(1);
841 else
842 te->setScrollbarLocation(0);
843 te->setScrollbarLocation( cfg.readNumEntry("Position",2));
844 te->setWrapAt(120);
845 }
846 break;
821 }; 847 };
822 848
823} 849}
824 850
825void Konsole::editCommandListMenuSelected(int iD) 851void Konsole::editCommandListMenuSelected(int iD)
826{ 852{
827// QString temp; 853// QString temp;
828// qDebug( temp.sprintf("edit command list %d",iD)); 854// qDebug( temp.sprintf("edit command list %d",iD));
829 TEWidget* te = getTe(); 855 TEWidget* te = getTe();
830 Config cfg("Konsole"); 856 Config cfg("Konsole");
831 cfg.setGroup("Menubar"); 857 cfg.setGroup("Menubar");
832 if( iD == -3) { 858 if( iD == -3) {
833 if(!secondToolBar->isHidden()) { 859 if(!secondToolBar->isHidden()) {
834 secondToolBar->hide(); 860 secondToolBar->hide();
835 configMenu->changeItem( iD,tr( "Show Command List" )); 861 configMenu->changeItem( iD,tr( "Show Command List" ));
836 cfg.writeEntry("Hidden","TRUE"); 862 cfg.writeEntry("Hidden","TRUE");
837 configMenu->setItemEnabled(-23 ,FALSE); 863 configMenu->setItemEnabled(-23 ,FALSE);
838 } else { 864 } else {
839 secondToolBar->show(); 865 secondToolBar->show();
840 configMenu->changeItem( iD,tr( "Hide Command List" )); 866 configMenu->changeItem( iD,tr( "Hide Command List" ));
841 cfg.writeEntry("Hidden","FALSE"); 867 cfg.writeEntry("Hidden","FALSE");
842 configMenu->setItemEnabled(-23 ,TRUE); 868 configMenu->setItemEnabled(-23 ,TRUE);
843 869
844 if(cfg.readEntry("EditEnabled","FALSE")=="TRUE") { 870 if(cfg.readEntry("EditEnabled","FALSE")=="TRUE") {
845 configMenu->setItemChecked(-23,TRUE); 871 configMenu->setItemChecked(-23,TRUE);
846 commonCombo->setEditable( TRUE ); 872 commonCombo->setEditable( TRUE );
847 } else { 873 } else {
848 configMenu->setItemChecked(-23,FALSE); 874 configMenu->setItemChecked(-23,FALSE);
849 commonCombo->setEditable( FALSE ); 875 commonCombo->setEditable( FALSE );
850 } 876 }
851 } 877 }
852 } 878 }
853 if( iD == -23) { 879 if( iD == -23) {
854 cfg.setGroup("Commands"); 880 cfg.setGroup("Commands");
855// qDebug("enableCommandEdit"); 881// qDebug("enableCommandEdit");
856 if( !configMenu->isItemChecked(iD) ) { 882 if( !configMenu->isItemChecked(iD) ) {
857 commonCombo->setEditable( TRUE ); 883 commonCombo->setEditable( TRUE );
858 configMenu->setItemChecked(iD,TRUE); 884 configMenu->setItemChecked(iD,TRUE);
859 commonCombo->setCurrentItem(0); 885 commonCombo->setCurrentItem(0);
860 cfg.writeEntry("EditEnabled","TRUE"); 886 cfg.writeEntry("EditEnabled","TRUE");
861 } else { 887 } else {
862 commonCombo->setEditable( FALSE ); 888 commonCombo->setEditable( FALSE );
863 configMenu->setItemChecked(iD,FALSE); 889 configMenu->setItemChecked(iD,FALSE);
864 cfg.writeEntry("EditEnabled","FALSE"); 890 cfg.writeEntry("EditEnabled","FALSE");
865 commonCombo->setFocusPolicy(QWidget::NoFocus); 891 commonCombo->setFocusPolicy(QWidget::NoFocus);
866 te->setFocus(); 892 te->setFocus();
867 } 893 }
868 } 894 }
869 if(iD == -24) { 895 if(iD == -24) {
870 // "edit commands" 896 // "edit commands"
871 CommandEditDialog *m = new CommandEditDialog(this); 897 CommandEditDialog *m = new CommandEditDialog(this);
872 connect(m,SIGNAL(commandsEdited()),this,SLOT(initCommandList())); 898 connect(m,SIGNAL(commandsEdited()),this,SLOT(initCommandList()));
873 m->showMaximized(); 899 m->showMaximized();
874 } 900 }
875 901
876} 902}
877 903
878// $QPEDIR/bin/qcop QPE/Application/embeddedkonsole 'setDocument(QString)' 'ssh -V' 904// $QPEDIR/bin/qcop QPE/Application/embeddedkonsole 'setDocument(QString)' 'ssh -V'
879void Konsole::setDocument( const QString &cmd) { 905void Konsole::setDocument( const QString &cmd) {
880 newSession(); 906 newSession();
881 TEWidget* te = getTe(); 907 TEWidget* te = getTe();
882 if(cmd.find("-e", 0, TRUE) != -1) { 908 if(cmd.find("-e", 0, TRUE) != -1) {
883 QString cmd2; 909 QString cmd2;
884 cmd2=cmd.right(cmd.length()-3)+" &"; 910 cmd2=cmd.right(cmd.length()-3)+" &";