summaryrefslogtreecommitdiff
path: root/core/apps/embeddedkonsole/TEHistory.cpp
Unidiff
Diffstat (limited to 'core/apps/embeddedkonsole/TEHistory.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--core/apps/embeddedkonsole/TEHistory.cpp275
1 files changed, 143 insertions, 132 deletions
diff --git a/core/apps/embeddedkonsole/TEHistory.cpp b/core/apps/embeddedkonsole/TEHistory.cpp
index db9d10c..504cd13 100644
--- a/core/apps/embeddedkonsole/TEHistory.cpp
+++ b/core/apps/embeddedkonsole/TEHistory.cpp
@@ -6,11 +6,11 @@
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 Qkonsole - an X terminal for KDE */
10/* */ 10/* */
11/* -------------------------------------------------------------------------- */ 11/* -------------------------------------------------------------------------- */
12/* */ 12/* */
13/* Ported Konsole to Qt/Embedded */ 13/* Ported Qkonsole 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/* */
@@ -24,6 +24,8 @@
24#include <unistd.h> 24#include <unistd.h>
25#include <errno.h> 25#include <errno.h>
26 26
27#include <qpe/config.h>
28
27#define HERE printf("%s(%d): here\n",__FILE__,__LINE__) 29#define HERE printf("%s(%d): here\n",__FILE__,__LINE__)
28 30
29/* 31/*
@@ -40,180 +42,189 @@
40 of cells and line/column indexed read access to the scroll 42 of cells and line/column indexed read access to the scroll
41 at constant costs. 43 at constant costs.
42 44
43FIXME: some complain about the history buffer comsuming the
44 memory of their machines. This problem is critical
45 since the history does not behave gracefully in cases
46 where the memory is used up completely.
47
48 I put in a workaround that should handle it problem
49 now gracefully. I'm not satisfied with the solution.
50
51FIXME: Terminating the history is not properly indicated
52 in the menu. We should throw a signal.
53
54FIXME: There is noticable decrease in speed, also. Perhaps,
55 there whole feature needs to be revisited therefore.
56 Disadvantage of a more elaborated, say block-oriented
57 scheme with wrap around would be it's complexity.
58*/ 45*/
59 46
60//FIXME: tempory replacement for tmpfile
61// this is here one for debugging purpose.
62
63//#define tmpfile xTmpFile
64
65FILE* xTmpFile()
66{
67 static int fid = 0;
68 char fname[80];
69 sprintf(fname,"TmpFile.%d",fid++);
70 return fopen(fname,"w");
71}
72
73 47
74// History Buffer /////////////////////////////////////////// 48HistoryScroll::HistoryScroll()
75
76/*
77 A Row(X) data type which allows adding elements to the end.
78*/
79
80HistoryBuffer::HistoryBuffer()
81{ 49{
82 ion = -1; 50 m_lines = NULL;
83 length = 0; 51 m_max_lines = 0;
52 m_cells = NULL;
53 m_max_cells = 0;
54 m_num_lines = 0;
55 m_first_line = 0;
56 m_last_cell = 0;
57 m_start_line = 0;
84} 58}
85 59
86HistoryBuffer::~HistoryBuffer() 60HistoryScroll::~HistoryScroll()
87{ 61{
88 setScroll(FALSE); 62 setSize(0,0);
89} 63}
90 64
91void HistoryBuffer::setScroll(bool on) 65void HistoryScroll::setSize(int lines, int cells)
92{ 66{
93 if (on == hasScroll()) return; 67 // could try to preserve the existing data...
94 68 // printf("setSize(%d,%d)\n", lines, cells);
95 if (on) 69 if (m_lines) {
96 { 70 delete m_lines;
97 assert( ion < 0 ); 71 m_lines = NULL;
98 assert( length == 0);
99 FILE* tmp = tmpfile(); if (!tmp) { perror("konsole: cannot open temp file.\n"); return; }
100 ion = dup(fileno(tmp)); if (ion<0) perror("konsole: cannot dup temp file.\n");
101 fclose(tmp);
102 } 72 }
103 else 73 if (m_cells) {
104 { 74 delete m_cells;
105 assert( ion >= 0 ); 75 m_cells = NULL;
106 close(ion);
107 ion = -1;
108 length = 0;
109 } 76 }
77 m_max_lines = m_max_cells = 0;
78 if (lines > 0 && cells > 0) {
79 m_max_lines = lines;
80 m_lines = new int[m_max_lines];
81 m_lines[0] = 0;
82 m_max_cells = cells;
83 m_cells = new ca[m_max_cells];
84 }
85 m_first_line = 0;
86 m_num_lines = 0;
87 m_last_cell = 0;
88 m_start_line = 0;
110} 89}
111 90
112bool HistoryBuffer::hasScroll()
113{
114 return ion >= 0;
115}
116
117void HistoryBuffer::add(const unsigned char* bytes, int len)
118{ int rc;
119 assert(hasScroll());
120 rc = lseek( ion, length, SEEK_SET);
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; }
124 length += rc;
125}
126
127void HistoryBuffer::get(unsigned char* bytes, int len, int loc) {
128 int rc;
129 assert(hasScroll());
130// qDebug("history get len %d, loc %d, length %d", len, loc, length);
131 if (loc < 0 || len < 0 || loc + len > length)
132 fprintf(stderr,"getHist(...,%d,%d): invalid args.\n",len,loc);
133
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; }
138}
139
140int HistoryBuffer::len()
141{
142 return length;
143}
144
145// History Scroll //////////////////////////////////////
146
147/*
148 The history scroll makes a Row(Row(Cell)) from
149 two history buffers. The index buffer contains
150 start of line positions which refere to the cells
151 buffer.
152
153 Note that index[0] addresses the second line
154 (line #1), while the first line (line #0) starts
155 at 0 in cells.
156*/
157
158HistoryScroll::HistoryScroll()
159{
160}
161
162HistoryScroll::~HistoryScroll()
163{
164}
165
166void HistoryScroll::setScroll(bool on) 91void HistoryScroll::setScroll(bool on)
167{ 92{
168 index.setScroll(on); 93 Config cfg("Qkonsole");
169 cells.setScroll(on); 94 cfg.setGroup("History");
95 // printf("setScroll(%d)\n", on);
96 if (on) {
97 int lines = cfg.readNumEntry("history_lines",300);
98 int avg_line = cfg.readNumEntry("avg_line_length",60);
99 int cells = lines * avg_line;
100 setSize(lines,cells);
101 } else {
102 setSize(0,0);
103 }
170} 104}
171 105
172bool HistoryScroll::hasScroll() 106bool HistoryScroll::hasScroll()
173{ 107{
174 return index.hasScroll() && cells.hasScroll(); 108 return (m_max_lines > 0);
175} 109}
176 110
177int HistoryScroll::getLines() 111int HistoryScroll::getLines()
178{ 112{
179 if (!hasScroll()) return 0; 113 return(m_num_lines);
180 return index.len() / sizeof(int);
181} 114}
182 115
183int HistoryScroll::getLineLen(int lineno) 116int HistoryScroll::getLineLen(int lineno)
184{ 117{
185 if (!hasScroll()) return 0; 118 if (!hasScroll()) return 0;
186 return (startOfLine(lineno+1) - startOfLine(lineno)) / sizeof(ca); 119 if (lineno >= m_num_lines) {
120 // printf("getLineLen(%d) out of range %d\n", lineno, m_num_lines);
121 return(0);
122 }
123 int len = startOfLine(lineno+1) - startOfLine(lineno);
124 if (len < 0) {
125 len += m_max_cells;
126 }
127 // printf("getLineLen(%d) = %d\n", lineno, len);
128 return(len);
187} 129}
188 130
189int HistoryScroll::startOfLine(int lineno) 131int HistoryScroll::startOfLine(int lineno)
190{ 132{
191 if (lineno <= 0) return 0; 133 // printf("startOfLine(%d) =", lineno);
192 if (!hasScroll()) return 0; 134 if (!hasScroll()) return 0;
193 if (lineno <= getLines()) 135 assert(lineno >= 0 && lineno <= m_num_lines);
194 { int res; 136 if (lineno < m_num_lines) {
195 index.get((unsigned char*)&res,sizeof(int),(lineno-1)*sizeof(int)); 137 int index = lineno + m_first_line;
196 return res; 138 if (index >= m_max_lines)
139 index -= m_max_lines;
140 // printf("%d\n", m_lines[index]);
141 return(m_lines[index]);
142 } else {
143 // printf("last %d\n", m_last_cell);
144 return(m_last_cell);
197 } 145 }
198 return cells.len();
199} 146}
200 147
201void HistoryScroll::getCells(int lineno, int colno, int count, ca res[]) 148void HistoryScroll::getCells(int lineno, int colno, int count, ca *res)
202{ 149{
150 // printf("getCells(%d,%d,%d) num_lines=%d\n", lineno, colno, count, m_num_lines);
203 assert(hasScroll()); 151 assert(hasScroll());
204//get(unsigned char* bytes, int len, int loc) 152 assert(lineno >= 0 && lineno < m_num_lines);
205 cells.get( (unsigned char*)res, count * sizeof(ca), startOfLine( lineno) + colno * sizeof(ca) ); 153 int index = lineno + m_first_line;
154 if (index >= m_max_lines)
155 index -= m_max_lines;
156 assert(index >= 0 && index < m_max_lines);
157 index = m_lines[index] + colno;
158 assert(index >= 0 && index < m_max_cells);
159 while(count-- > 0) {
160 *res++ = m_cells[index];
161 if (++index >= m_max_cells) {
162 index = 0;
163 }
164 }
206} 165}
207 166
208void HistoryScroll::addCells(ca text[], int count) 167void HistoryScroll::addCells(ca *text, int count)
209{ 168{
210 if (!hasScroll()) return; 169 if (!hasScroll()) return;
211 cells.add((unsigned char*)text,count*sizeof(ca)); 170 int start_cell = m_last_cell;
171 // printf("addCells count=%d start=%d first_line=%d first_cell=%d lines=%d\n",
172 // count, start_cell, m_first_line, m_lines[m_first_line], m_num_lines);
173 if (count <= 0) {
174 return;
175 }
176 while(count-- > 0) {
177 assert (m_last_cell >= 0 && m_last_cell < m_max_cells );
178 m_cells[m_last_cell] = *text++;
179 if (++m_last_cell >= m_max_cells) {
180 m_last_cell = 0;
181 }
182 }
183 if (m_num_lines > 1) {
184 if (m_last_cell > start_cell) {
185 while(m_num_lines > 0
186 && m_lines[m_first_line] >= start_cell
187 && m_lines[m_first_line] < m_last_cell) {
188 // printf("A remove %d>%d && %d<%d first_line=%d num_lines=%d\n",
189 // m_lines[m_first_line], start_cell, m_lines[m_first_line], m_last_cell,
190 // m_first_line, m_num_lines);
191 if (++m_first_line >= m_max_lines) {
192 m_first_line = 0;
193 }
194 m_num_lines--;
195 }
196 } else {
197 while(m_num_lines > 0
198 && (m_lines[m_first_line] >= start_cell
199 || m_lines[m_first_line] < m_last_cell)) {
200 // printf("B remove %d>%d || %d<%d first_line=%d num_lines=%d\n",
201 // m_lines[m_first_line], start_cell, m_lines[m_first_line], m_last_cell,
202 // m_first_line, m_num_lines);
203 if (++m_first_line >= m_max_lines) {
204 m_first_line = 0;
205 }
206 m_num_lines--;
207 }
208 }
209 }
212} 210}
213 211
214void HistoryScroll::addLine() 212void HistoryScroll::addLine()
215{ 213{
216 if (!hasScroll()) return; 214 if (!hasScroll()) return;
217 int locn = cells.len(); 215 int index = m_first_line + m_num_lines;
218 index.add((unsigned char*)&locn,sizeof(int)); 216 if (index >= m_max_lines) {
217 index -= m_max_lines;
218 }
219 // printf("addLine line=%d cell=%d\n", index, m_last_cell);
220 assert(index >= 0 && index < m_max_lines);
221 m_lines[index] = m_start_line;
222 m_start_line = m_last_cell;
223 if (m_num_lines >= m_max_lines) {
224 if (++m_first_line >= m_num_lines) {
225 m_first_line = 0;
226 }
227 } else {
228 m_num_lines++;
229 }
219} 230}