Diffstat (limited to 'noncore/apps/opie-console/TEHistory.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r-- | noncore/apps/opie-console/TEHistory.cpp | 27 |
1 files changed, 24 insertions, 3 deletions
diff --git a/noncore/apps/opie-console/TEHistory.cpp b/noncore/apps/opie-console/TEHistory.cpp index 317ce57..e2be42a 100644 --- a/noncore/apps/opie-console/TEHistory.cpp +++ b/noncore/apps/opie-console/TEHistory.cpp | |||
@@ -1,212 +1,233 @@ | |||
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 <sys/stat.h> | ||
24 | #include <unistd.h> | 25 | #include <unistd.h> |
25 | #include <errno.h> | 26 | #include <errno.h> |
26 | 27 | ||
27 | #define HERE printf("%s(%d): here\n",__FILE__,__LINE__) | 28 | #define HERE printf("%s(%d): here\n",__FILE__,__LINE__) |
28 | 29 | ||
29 | /* | 30 | /* |
30 | An arbitrary long scroll. | 31 | An arbitrary long scroll. |
31 | 32 | ||
32 | One can modify the scroll only by adding either cells | 33 | One can modify the scroll only by adding either cells |
33 | or newlines, but access it randomly. | 34 | or newlines, but access it randomly. |
34 | 35 | ||
35 | The model is that of an arbitrary wide typewriter scroll | 36 | The model is that of an arbitrary wide typewriter scroll |
36 | in that the scroll is a serie of lines and each line is | 37 | in that the scroll is a serie of lines and each line is |
37 | a serie of cells with no overwriting permitted. | 38 | a serie of cells with no overwriting permitted. |
38 | 39 | ||
39 | The implementation provides arbitrary length and numbers | 40 | The implementation provides arbitrary length and numbers |
40 | of cells and line/column indexed read access to the scroll | 41 | of cells and line/column indexed read access to the scroll |
41 | at constant costs. | 42 | at constant costs. |
42 | 43 | ||
43 | FIXME: some complain about the history buffer comsuming the | 44 | FIXME: some complain about the history buffer comsuming the |
44 | memory of their machines. This problem is critical | 45 | memory of their machines. This problem is critical |
45 | since the history does not behave gracefully in cases | 46 | since the history does not behave gracefully in cases |
46 | where the memory is used up completely. | 47 | where the memory is used up completely. |
47 | 48 | ||
48 | I put in a workaround that should handle it problem | 49 | I put in a workaround that should handle it problem |
49 | now gracefully. I'm not satisfied with the solution. | 50 | now gracefully. I'm not satisfied with the solution. |
50 | 51 | ||
51 | FIXME: Terminating the history is not properly indicated | 52 | FIXME: Terminating the history is not properly indicated |
52 | in the menu. We should throw a signal. | 53 | in the menu. We should throw a signal. |
53 | 54 | ||
54 | FIXME: There is noticable decrease in speed, also. Perhaps, | 55 | FIXME: There is noticable decrease in speed, also. Perhaps, |
55 | there whole feature needs to be revisited therefore. | 56 | there whole feature needs to be revisited therefore. |
56 | Disadvantage of a more elaborated, say block-oriented | 57 | Disadvantage of a more elaborated, say block-oriented |
57 | scheme with wrap around would be it's complexity. | 58 | scheme with wrap around would be it's complexity. |
58 | */ | 59 | */ |
59 | 60 | ||
60 | //FIXME: tempory replacement for tmpfile | 61 | //FIXME: tempory replacement for tmpfile |
61 | // this is here one for debugging purpose. | 62 | // this is here one for debugging purpose. |
62 | 63 | ||
63 | //#define tmpfile xTmpFile | 64 | //#define tmpfile xTmpFile |
64 | 65 | ||
65 | FILE* xTmpFile() | 66 | FILE* xTmpFile() |
66 | { | 67 | { |
67 | static int fid = 0; | 68 | static int fid = 0; |
68 | char fname[80]; | 69 | char fname[80]; |
69 | sprintf(fname,"TmpFile.%d",fid++); | 70 | sprintf(fname,"TmpFile.%d",fid++); |
70 | return fopen(fname,"w"); | 71 | return fopen(fname,"w"); |
71 | } | 72 | } |
72 | 73 | ||
73 | 74 | ||
74 | // History Buffer /////////////////////////////////////////// | 75 | // History Buffer /////////////////////////////////////////// |
75 | 76 | ||
76 | /* | 77 | /* |
77 | A Row(X) data type which allows adding elements to the end. | 78 | A Row(X) data type which allows adding elements to the end. |
78 | */ | 79 | */ |
79 | 80 | ||
80 | HistoryBuffer::HistoryBuffer() | 81 | HistoryBuffer::HistoryBuffer() |
81 | { | 82 | { |
82 | ion = -1; | 83 | ion = -1; |
83 | length = 0; | 84 | length = 0; |
84 | } | 85 | } |
85 | 86 | ||
86 | HistoryBuffer::~HistoryBuffer() | 87 | HistoryBuffer::~HistoryBuffer() |
87 | { | 88 | { |
88 | setScroll(FALSE); | 89 | setScroll(FALSE); |
89 | } | 90 | } |
90 | 91 | ||
91 | void HistoryBuffer::setScroll(bool on) | 92 | void HistoryBuffer::setScroll(bool on) |
92 | { | 93 | { |
93 | if (on == hasScroll()) return; | 94 | if (on == hasScroll()) return; |
94 | 95 | ||
95 | if (on) | 96 | if (on) |
96 | { | 97 | { |
97 | assert( ion < 0 ); | 98 | assert( ion < 0 ); |
98 | assert( length == 0); | 99 | assert( length == 0); |
99 | FILE* tmp = tmpfile(); if (!tmp) { perror("konsole: cannot open temp file.\n"); return; } | 100 | char* tmpDir = getenv("TMPDIR"); |
100 | ion = dup(fileno(tmp)); if (ion<0) perror("konsole: cannot dup temp file.\n"); | 101 | char* tmpFilePath = 0; |
101 | fclose(tmp); | 102 | if (tmpDir && *tmpDir != '\0') { |
103 | tmpFilePath = new char[strlen(tmpDir) + strlen("/opie-console-HistoryBuffer-XXXXXX") + 1]; | ||
104 | strcpy(tmpFilePath, tmpDir); | ||
105 | free(tmpDir); | ||
106 | } else { | ||
107 | tmpFilePath = new char[strlen("/tmp/opie-console-HistoryBuffer-XXXXXX") + 1]; | ||
108 | strcpy(tmpFilePath, "/tmp"); | ||
109 | } | ||
110 | strcat(tmpFilePath, "/opie-console-HistoryBuffer-XXXXXX"); | ||
111 | mode_t currUmask = umask(S_IRWXO | S_IRWXG); | ||
112 | int tmpfd = mkstemp(tmpFilePath); | ||
113 | delete [] tmpFilePath; | ||
114 | umask(currUmask); | ||
115 | if (tmpfd == -1) { | ||
116 | perror("konsole: cannot open temp file.\n"); | ||
117 | return; | ||
118 | } | ||
119 | ion = dup(tmpfd); | ||
120 | if (ion<0) | ||
121 | perror("konsole: cannot dup temp file.\n"); | ||
122 | close(tmpfd); | ||
102 | } | 123 | } |
103 | else | 124 | else |
104 | { | 125 | { |
105 | assert( ion >= 0 ); | 126 | assert( ion >= 0 ); |
106 | close(ion); | 127 | close(ion); |
107 | ion = -1; | 128 | ion = -1; |
108 | length = 0; | 129 | length = 0; |
109 | } | 130 | } |
110 | } | 131 | } |
111 | 132 | ||
112 | bool HistoryBuffer::hasScroll() | 133 | bool HistoryBuffer::hasScroll() |
113 | { | 134 | { |
114 | return ion >= 0; | 135 | return ion >= 0; |
115 | } | 136 | } |
116 | 137 | ||
117 | void HistoryBuffer::add(const unsigned char* bytes, int len) | 138 | void HistoryBuffer::add(const unsigned char* bytes, int len) |
118 | { int rc; | 139 | { int rc; |
119 | assert(hasScroll()); | 140 | assert(hasScroll()); |
120 | rc = lseek(ion,length,SEEK_SET); if (rc < 0) { perror("HistoryBuffer::add.seek"); setScroll(FALSE); return; } | 141 | rc = lseek(ion,length,SEEK_SET); if (rc < 0) { perror("HistoryBuffer::add.seek"); setScroll(FALSE); return; } |
121 | rc = write(ion,bytes,len); if (rc < 0) { perror("HistoryBuffer::add.write"); setScroll(FALSE); return; } | 142 | rc = write(ion,bytes,len); if (rc < 0) { perror("HistoryBuffer::add.write"); setScroll(FALSE); return; } |
122 | length += rc; | 143 | length += rc; |
123 | } | 144 | } |
124 | 145 | ||
125 | void HistoryBuffer::get(unsigned char* bytes, int len, int loc) | 146 | void HistoryBuffer::get(unsigned char* bytes, int len, int loc) |
126 | { int rc; | 147 | { int rc; |
127 | assert(hasScroll()); | 148 | assert(hasScroll()); |
128 | if (loc < 0 || len < 0 || loc + len > length) | 149 | if (loc < 0 || len < 0 || loc + len > length) |
129 | fprintf(stderr,"getHist(...,%d,%d): invalid args.\n",len,loc); | 150 | 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; } | 151 | rc = lseek(ion,loc,SEEK_SET); if (rc < 0) { perror("HistoryBuffer::get.seek"); setScroll(FALSE); return; } |
131 | rc = read(ion,bytes,len); if (rc < 0) { perror("HistoryBuffer::get.read"); setScroll(FALSE); return; } | 152 | rc = read(ion,bytes,len); if (rc < 0) { perror("HistoryBuffer::get.read"); setScroll(FALSE); return; } |
132 | } | 153 | } |
133 | 154 | ||
134 | int HistoryBuffer::len() | 155 | int HistoryBuffer::len() |
135 | { | 156 | { |
136 | return length; | 157 | return length; |
137 | } | 158 | } |
138 | 159 | ||
139 | // History Scroll ////////////////////////////////////// | 160 | // History Scroll ////////////////////////////////////// |
140 | 161 | ||
141 | /* | 162 | /* |
142 | The history scroll makes a Row(Row(Cell)) from | 163 | The history scroll makes a Row(Row(Cell)) from |
143 | two history buffers. The index buffer contains | 164 | two history buffers. The index buffer contains |
144 | start of line positions which refere to the cells | 165 | start of line positions which refere to the cells |
145 | buffer. | 166 | buffer. |
146 | 167 | ||
147 | Note that index[0] addresses the second line | 168 | Note that index[0] addresses the second line |
148 | (line #1), while the first line (line #0) starts | 169 | (line #1), while the first line (line #0) starts |
149 | at 0 in cells. | 170 | at 0 in cells. |
150 | */ | 171 | */ |
151 | 172 | ||
152 | HistoryScroll::HistoryScroll() | 173 | HistoryScroll::HistoryScroll() |
153 | { | 174 | { |
154 | } | 175 | } |
155 | 176 | ||
156 | HistoryScroll::~HistoryScroll() | 177 | HistoryScroll::~HistoryScroll() |
157 | { | 178 | { |
158 | } | 179 | } |
159 | 180 | ||
160 | void HistoryScroll::setScroll(bool on) | 181 | void HistoryScroll::setScroll(bool on) |
161 | { | 182 | { |
162 | index.setScroll(on); | 183 | index.setScroll(on); |
163 | cells.setScroll(on); | 184 | cells.setScroll(on); |
164 | } | 185 | } |
165 | 186 | ||
166 | bool HistoryScroll::hasScroll() | 187 | bool HistoryScroll::hasScroll() |
167 | { | 188 | { |
168 | return index.hasScroll() && cells.hasScroll(); | 189 | return index.hasScroll() && cells.hasScroll(); |
169 | } | 190 | } |
170 | 191 | ||
171 | int HistoryScroll::getLines() | 192 | int HistoryScroll::getLines() |
172 | { | 193 | { |
173 | if (!hasScroll()) return 0; | 194 | if (!hasScroll()) return 0; |
174 | return index.len() / sizeof(int); | 195 | return index.len() / sizeof(int); |
175 | } | 196 | } |
176 | 197 | ||
177 | int HistoryScroll::getLineLen(int lineno) | 198 | int HistoryScroll::getLineLen(int lineno) |
178 | { | 199 | { |
179 | if (!hasScroll()) return 0; | 200 | if (!hasScroll()) return 0; |
180 | return (startOfLine(lineno+1) - startOfLine(lineno)) / sizeof(ca); | 201 | return (startOfLine(lineno+1) - startOfLine(lineno)) / sizeof(ca); |
181 | } | 202 | } |
182 | 203 | ||
183 | int HistoryScroll::startOfLine(int lineno) | 204 | int HistoryScroll::startOfLine(int lineno) |
184 | { | 205 | { |
185 | if (lineno <= 0) return 0; | 206 | if (lineno <= 0) return 0; |
186 | if (!hasScroll()) return 0; | 207 | if (!hasScroll()) return 0; |
187 | if (lineno <= getLines()) | 208 | if (lineno <= getLines()) |
188 | { int res; | 209 | { int res; |
189 | index.get((unsigned char*)&res,sizeof(int),(lineno-1)*sizeof(int)); | 210 | index.get((unsigned char*)&res,sizeof(int),(lineno-1)*sizeof(int)); |
190 | return res; | 211 | return res; |
191 | } | 212 | } |
192 | return cells.len(); | 213 | return cells.len(); |
193 | } | 214 | } |
194 | 215 | ||
195 | void HistoryScroll::getCells(int lineno, int colno, int count, ca res[]) | 216 | void HistoryScroll::getCells(int lineno, int colno, int count, ca res[]) |
196 | { | 217 | { |
197 | assert(hasScroll()); | 218 | assert(hasScroll()); |
198 | cells.get((unsigned char*)res,count*sizeof(ca),startOfLine(lineno)+colno*sizeof(ca)); | 219 | cells.get((unsigned char*)res,count*sizeof(ca),startOfLine(lineno)+colno*sizeof(ca)); |
199 | } | 220 | } |
200 | 221 | ||
201 | void HistoryScroll::addCells(ca text[], int count) | 222 | void HistoryScroll::addCells(ca text[], int count) |
202 | { | 223 | { |
203 | if (!hasScroll()) return; | 224 | if (!hasScroll()) return; |
204 | cells.add((unsigned char*)text,count*sizeof(ca)); | 225 | cells.add((unsigned char*)text,count*sizeof(ca)); |
205 | } | 226 | } |
206 | 227 | ||
207 | void HistoryScroll::addLine() | 228 | void HistoryScroll::addLine() |
208 | { | 229 | { |
209 | if (!hasScroll()) return; | 230 | if (!hasScroll()) return; |
210 | int locn = cells.len(); | 231 | int locn = cells.len(); |
211 | index.add((unsigned char*)&locn,sizeof(int)); | 232 | index.add((unsigned char*)&locn,sizeof(int)); |
212 | } | 233 | } |