summaryrefslogtreecommitdiff
path: root/noncore/apps/opie-console/history.cpp
Unidiff
Diffstat (limited to 'noncore/apps/opie-console/history.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--noncore/apps/opie-console/history.cpp218
1 files changed, 218 insertions, 0 deletions
diff --git a/noncore/apps/opie-console/history.cpp b/noncore/apps/opie-console/history.cpp
new file mode 100644
index 0000000..3b82d16
--- a/dev/null
+++ b/noncore/apps/opie-console/history.cpp
@@ -0,0 +1,218 @@
1/* -------------------------------------------------------------------------- */
2/* */
3/* [history.c] History Buffer */
4/* */
5/* -------------------------------------------------------------------------- */
6/* */
7/* Copyright (c) 1997,1998 by Lars Doelle <lars.doelle@on-line.de> */
8/* */
9/* This file is part of Konsole - an X terminal for KDE */
10/* */
11/* -------------------------------------------------------------------------- */
12 /* */
13/* Ported Konsole to Qt/Embedded */
14 /* */
15/* Copyright (C) 2000 by John Ryland <jryland@trolltech.com> */
16 /* */
17/* -------------------------------------------------------------------------- */
18 /* */
19/* Ported embedded-Konsole to opie-console */
20 /* */
21/* Copyright (C) 2002 by opie developers <opie@handhelds.org> */
22 /* */
23/* -------------------------------------------------------------------------- */
24
25#include "history.h"
26#include <stdlib.h>
27#include <assert.h>
28#include <stdio.h>
29#include <sys/types.h>
30#include <unistd.h>
31#include <errno.h>
32
33#define HERE printf("%s(%d): here\n",__FILE__,__LINE__)
34
35/*
36 An arbitrary long scroll.
37
38 One can modify the scroll only by adding either cells
39 or newlines, but access it randomly.
40
41 The model is that of an arbitrary wide typewriter scroll
42 in that the scroll is a serie of lines and each line is
43 a serie of cells with no overwriting permitted.
44
45 The implementation provides arbitrary length and numbers
46 of cells and line/column indexed read access to the scroll
47 at constant costs.
48
49FIXME: some complain about the history buffer comsuming the
50 memory of their machines. This problem is critical
51 since the history does not behave gracefully in cases
52 where the memory is used up completely.
53
54 I put in a workaround that should handle it problem
55 now gracefully. I'm not satisfied with the solution.
56
57FIXME: Terminating the history is not properly indicated
58 in the menu. We should throw a signal.
59
60FIXME: There is noticable decrease in speed, also. Perhaps,
61 there whole feature needs to be revisited therefore.
62 Disadvantage of a more elaborated, say block-oriented
63 scheme with wrap around would be it's complexity.
64*/
65
66//FIXME: tempory replacement for tmpfile
67// this is here one for debugging purpose.
68
69//#define tmpfile xTmpFile
70
71FILE* xTmpFile()
72{
73 static int fid = 0;
74 char fname[80];
75 sprintf(fname,"TmpFile.%d",fid++);
76 return fopen(fname,"w");
77}
78
79
80// History Buffer ///////////////////////////////////////////
81
82/*
83 A Row(X) data type which allows adding elements to the end.
84*/
85
86HistoryBuffer::HistoryBuffer()
87{
88 ion = -1;
89 length = 0;
90}
91
92HistoryBuffer::~HistoryBuffer()
93{
94 setScroll(FALSE);
95}
96
97void HistoryBuffer::setScroll(bool on)
98{
99 if (on == hasScroll()) return;
100
101 if (on)
102 {
103 assert( ion < 0 );
104 assert( length == 0);
105 FILE* tmp = tmpfile(); if (!tmp) { perror("konsole: cannot open temp file.\n"); return; }
106 ion = dup(fileno(tmp)); if (ion<0) perror("konsole: cannot dup temp file.\n");
107 fclose(tmp);
108 }
109 else
110 {
111 assert( ion >= 0 );
112 close(ion);
113 ion = -1;
114 length = 0;
115 }
116}
117
118bool HistoryBuffer::hasScroll()
119{
120 return ion >= 0;
121}
122
123void HistoryBuffer::add(const unsigned char* bytes, int len)
124{ int rc;
125 assert(hasScroll());
126 rc = lseek(ion,length,SEEK_SET); if (rc < 0) { perror("HistoryBuffer::add.seek"); setScroll(FALSE); return; }
127 rc = write(ion,bytes,len); if (rc < 0) { perror("HistoryBuffer::add.write"); setScroll(FALSE); return; }
128 length += rc;
129}
130
131void HistoryBuffer::get(unsigned char* bytes, int len, int loc)
132{ int rc;
133 assert(hasScroll());
134 if (loc < 0 || len < 0 || loc + len > length)
135 fprintf(stderr,"getHist(...,%d,%d): invalid args.\n",len,loc);
136 rc = lseek(ion,loc,SEEK_SET); if (rc < 0) { perror("HistoryBuffer::get.seek"); setScroll(FALSE); return; }
137 rc = read(ion,bytes,len); 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)
167{
168 index.setScroll(on);
169 cells.setScroll(on);
170}
171
172bool HistoryScroll::hasScroll()
173{
174 return index.hasScroll() && cells.hasScroll();
175}
176
177int HistoryScroll::getLines()
178{
179 if (!hasScroll()) return 0;
180 return index.len() / sizeof(int);
181}
182
183int HistoryScroll::getLineLen(int lineno)
184{
185 if (!hasScroll()) return 0;
186 return (startOfLine(lineno+1) - startOfLine(lineno)) / sizeof(Character);
187}
188
189int HistoryScroll::startOfLine(int lineno)
190{
191 if (lineno <= 0) return 0;
192 if (!hasScroll()) return 0;
193 if (lineno <= getLines())
194 { int res;
195 index.get((unsigned char*)&res,sizeof(int),(lineno-1)*sizeof(int));
196 return res;
197 }
198 return cells.len();
199}
200
201void HistoryScroll::getCells(int lineno, int colno, int count, Character res[])
202{
203 assert(hasScroll());
204 cells.get((unsigned char*)res,count*sizeof(Character),startOfLine(lineno)+colno*sizeof(Character));
205}
206
207void HistoryScroll::addCells(Character text[], int count)
208{
209 if (!hasScroll()) return;
210 cells.add((unsigned char*)text,count*sizeof(Character));
211}
212
213void HistoryScroll::addLine()
214{
215 if (!hasScroll()) return;
216 int locn = cells.len();
217 index.add((unsigned char*)&locn,sizeof(int));
218}