]> rtime.felk.cvut.cz Git - l4.git/blob - kernel/fiasco/src/jdb/jdb_table.cpp
ba22d8507aea3729caa4d3e2baf13866a83b23cd
[l4.git] / kernel / fiasco / src / jdb / jdb_table.cpp
1 INTERFACE:
2
3 class Jdb_table
4 {
5 public:
6   enum
7   {
8     Nothing = 0,
9     Handled,
10     Redraw,
11     Edit,
12     Back,
13     Exit,
14   };
15   
16   virtual unsigned col_width(unsigned col) const = 0;
17   virtual unsigned long cols() const = 0;
18   virtual unsigned long rows() const = 0;
19   virtual char col_sep(unsigned col) const;
20   virtual void draw_entry(unsigned long row, unsigned long col) = 0;
21   virtual unsigned key_pressed(int key, unsigned long &row, unsigned long &col);
22   virtual void print_statline(unsigned long row, unsigned long col) = 0;
23   virtual bool has_row_labels() const;
24   virtual bool has_col_labels() const;
25   virtual unsigned width() const;
26   virtual unsigned height() const;
27
28   virtual bool edit_entry(unsigned long row, unsigned long col, unsigned cx, unsigned cy);
29 };
30
31
32 IMPLEMENTATION:
33
34 #include <cstdio>
35 #include "jdb.h"
36 #include "jdb_screen.h"
37 #include "kernel_console.h"
38 #include "keycodes.h"
39 #include "simpleio.h"
40
41 IMPLEMENT
42 bool
43 Jdb_table::edit_entry(unsigned long, unsigned long, unsigned, unsigned)
44 { return false; }
45
46 IMPLEMENT
47 bool 
48 Jdb_table::has_row_labels() const
49 { return true; }
50
51 IMPLEMENT
52 bool 
53 Jdb_table::has_col_labels() const
54 { return false; }
55
56
57 IMPLEMENT
58 unsigned 
59 Jdb_table::key_pressed(int, unsigned long &, unsigned long &)
60 { return Nothing; }
61
62 IMPLEMENT
63 char
64 Jdb_table::col_sep(unsigned col) const
65 { return col?' ':':'; }
66
67 IMPLEMENT
68 unsigned 
69 Jdb_table::width() const
70 { return Jdb_screen::width(); }
71
72 IMPLEMENT
73 unsigned 
74 Jdb_table::height() const
75 { return Jdb_screen::height()-1; } 
76
77 PRIVATE
78 unsigned long
79 Jdb_table::vis_cols(unsigned long first_col, unsigned long *w)
80 {
81   unsigned c = 0;
82   *w = 0;
83   unsigned const max_w = width();
84   for (;c<cols(); ++c)
85     {
86       unsigned cw;
87       if (c == 0 && has_row_labels())
88         cw = col_width(0);
89       else
90         cw = col_width(first_col + c);
91
92       if (*w + cw > max_w)
93         return c;
94
95       *w += cw;
96       if (*w == max_w)
97         return c + 1;
98       else
99         *w += 1;
100     }
101   return c;
102 }
103
104 PRIVATE
105 unsigned
106 Jdb_table::col_ofs(unsigned long first_col, unsigned long col)
107 {
108   unsigned long c = 0;
109   unsigned long w = 0;
110   for (;c<col; ++c)
111     {
112       if (c == 0 && has_row_labels())
113         w += col_width(0) + 1;
114       else
115         w += col_width(first_col + col) + 1;
116     }
117
118   return w;
119 }
120
121 PUBLIC
122 bool
123 Jdb_table::show(unsigned long crow, unsigned long ccol)
124 {
125   unsigned long tmp;
126   unsigned long absr = 0, absc = 0;
127   unsigned long old_absc = 1, old_absr = 1;
128   unsigned long dcols, drows;        // drawn columns and rows
129   drows = height();
130   dcols = vis_cols(absc, &tmp);
131   if (drows>rows()) drows = rows();
132
133   unsigned long max_absr = 0, max_absc = 0;
134   if (rows() > drows) max_absr = rows() - drows;
135   if (cols() > dcols) max_absc = cols() - dcols;
136
137   unsigned long min_row, min_col;
138   min_row = has_col_labels()?1:0;
139   min_col = has_row_labels()?1:0;
140
141   absr = crow;
142   absc = ccol;
143
144   if (absr>max_absr) absr = max_absr;
145   if (absc>max_absc) absc = max_absc;
146
147   bool redraw = true;
148
149   while(1)
150     {
151 screen:
152       if (crow >= rows()) crow = rows()-1;
153       if (ccol >= cols()) ccol = cols()-1;
154       if (crow < min_row) crow = min_row;
155       if (ccol < min_col) ccol = min_col;
156
157       if (redraw || old_absc != absc || old_absr != absr)
158         {
159           dcols = vis_cols(absc, &tmp);
160           old_absr = absr;
161           old_absc = absc;
162           Jdb::cursor(); // go home
163           draw_table(absr, absc, drows, dcols);
164           redraw = false;
165         }
166
167       print_statline(crow, ccol);
168
169       Jdb::cursor(crow - absr + 1, 
170                   col_ofs(absc, ccol)+1);
171
172       int c = Kconsole::console()->getchar();
173
174       unsigned long nrow = crow;
175       unsigned long ncol = ccol;
176       unsigned kp = key_pressed(c, nrow, ncol);
177       if (ncol > ccol)
178         {
179           ccol = ncol;
180           if (ccol - absc >= dcols)
181             absc = ccol - dcols + 1;
182         }
183       else if (ncol < ccol)
184         {
185           ccol = ncol;
186           if (ccol < absc)
187             absc = ccol;
188         }
189       
190       if (nrow > crow)
191         {
192           crow = nrow;
193           if (crow - absr >= drows)
194             absr = crow - drows + 1;
195         }
196       else if (nrow < crow)
197         {
198           crow = nrow;
199           if (crow < absr)
200             absr = crow;
201         }
202
203       switch (kp)
204         {
205         case Redraw:
206           redraw = true;
207           goto screen;
208         case Exit:
209           return false;
210         case Back:
211           return true;
212         case Handled:
213           goto screen;
214         case Edit:
215             {
216               unsigned col_o = col_ofs(absc, ccol) + 1;
217               if (edit_entry(crow, ccol, col_o,
218                              crow - absr + 1))
219                 {
220                   Jdb::cursor(crow - absr + 1, col_o);
221                   draw_entry(crow,ccol);
222                   Jdb::cursor(crow - absr + 1, col_o);
223                 }
224             }
225           goto screen; 
226           
227         default:
228           break;
229         }
230
231       switch (c)
232         {
233         case KEY_CURSOR_HOME:
234         case 'H':
235           crow = absr = min_row;
236           ccol = absc = min_col;
237           break;
238         case KEY_CURSOR_END:
239         case 'L':
240           absr = max_absr;
241           absc = max_absc;
242           crow = rows() - 1;
243           ccol = cols() - 1;
244           break;
245         case KEY_CURSOR_LEFT:
246         case 'h':
247           if (ccol > min_col)
248             {
249               --ccol;
250               if (ccol < absc)
251                 absc = ccol;
252             }
253           else if (crow > min_row)
254             {
255               ccol = cols() -1;
256               if (ccol - absc > dcols)
257                 absc = ccol - dcols;
258               --crow;
259               if (crow < absr)
260                 absr = crow;
261             }
262           break;
263         case KEY_CURSOR_RIGHT:
264         case 'l':
265           if (ccol + 1 < cols())
266             {
267               ++ccol;
268               if (ccol - absc > dcols)
269                 absc = ccol - dcols;
270             }
271           else if (crow + 1 < rows())
272             {
273               absc = ccol = min_col;
274               ++crow;
275               if (crow - absr >= drows)
276                 absr = crow - drows + 1;
277             }
278           break;
279         case KEY_CURSOR_UP:
280         case 'k':
281           if (crow > min_row)
282             {
283               --crow;
284               if (crow < absr)
285                 absr = crow;
286             }
287           break;
288         case KEY_CURSOR_DOWN:
289         case 'j':
290           if (crow + 1 < rows())
291             {
292               ++crow;
293               if (crow - absr >= drows)
294                 absr = crow - drows + 1;
295             }
296           break;
297         case KEY_PAGE_UP:
298         case 'K':
299           if (crow >= drows + min_row)
300             {
301               crow -= drows;
302               if (absr >= drows)
303                 absr -= drows;
304               else
305                 absr = 0;
306             }
307           else
308             {
309               crow = min_row;
310               absr = 0;
311             }
312           break;
313         case KEY_PAGE_DOWN:
314         case 'J':
315           if (crow + 1 + drows < rows())
316             {
317               crow += drows;
318               if (absr + drows <= max_absr)
319                 absr += drows;
320               else
321                 absr = max_absr;
322             }
323           else
324             {
325               crow = rows() -1;
326               absr = max_absr;
327             }
328           break;
329         case KEY_ESC:
330           Jdb::abort_command();
331           return false;
332         default:
333           if (Jdb::is_toplevel_cmd(c))   
334             return false;
335           break;
336         }
337
338       if (absc > max_absc) absc = max_absc;
339       if (absr > max_absr) absr = max_absr;
340     }
341 }
342
343 PUBLIC
344 void
345 Jdb_table::draw_table(unsigned long row, unsigned long col, 
346                       unsigned lines, unsigned columns)
347 {
348   for (unsigned long y = 0; y < lines; ++y)
349     {
350       unsigned long w = 0;
351       unsigned long r;
352       if (has_col_labels() && y == 0)
353         r = 0;
354       else
355         r = row + y;
356       
357       Kconsole::console()->getchar_chance();
358       for (unsigned long x = 0; x < columns; ++x)
359         {
360           unsigned long c;
361           if (has_row_labels() && x == 0)
362             c = 0;
363           else
364             c = col + x;
365           
366           draw_entry(r, c);
367           w += col_width(c);
368           if (x+1<columns)
369             {
370               putchar(col_sep(c));
371               ++w;
372             }
373         }
374
375       if (w < width())
376         {
377           if (width() == Jdb_screen::width())
378             putstr("\033[K");
379           else
380             printf("\033[%ldX", width()-w); // some consoles don't support this
381         }
382       putchar('\n');
383     }
384 }