blob: 8aafc3219238001f2b4dfd3207c980a11e112006 [file] [log] [blame]
Daniel Lezcano7c15fad2016-02-18 15:57:43 +00001/*
2 * Power debug tool (powerdebug)
Amit Arora39f29542010-09-14 12:03:22 +05303 *
Daniel Lezcano7c15fad2016-02-18 15:57:43 +00004 * Copyright (C) 2016, Linaro Limited.
Amit Arora39f29542010-09-14 12:03:22 +05305 *
Daniel Lezcano7c15fad2016-02-18 15:57:43 +00006 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
Amit Arora39f29542010-09-14 12:03:22 +053010 *
Daniel Lezcano7c15fad2016-02-18 15:57:43 +000011 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 *
20 */
Amit Arora39f29542010-09-14 12:03:22 +053021
Daniel Lezcano15627482011-06-15 15:45:12 +020022#include <stdio.h>
23#include <string.h>
24#include <stdlib.h>
Daniel Lezcanoa12163d2011-06-21 00:57:08 +020025#include <ctype.h>
Daniel Lezcano15627482011-06-15 15:45:12 +020026#include <ncurses.h>
Daniel Lezcano5000abd2011-06-21 00:57:08 +020027#include <sys/types.h>
28#include <regex.h>
Amit Arora47fd9182010-08-24 13:26:06 +053029#include "powerdebug.h"
Daniel Lezcanodb145802011-06-21 00:57:08 +020030#include "mainloop.h"
Amit Arora17552782010-12-02 12:23:14 +053031#include "regulator.h"
Amit Aroraed3e5652010-10-27 12:02:53 +053032#include "display.h"
Amit Arora47fd9182010-08-24 13:26:06 +053033
Daniel Lezcanoeeb13762011-03-26 22:06:17 +010034enum { PT_COLOR_DEFAULT = 1,
35 PT_COLOR_HEADER_BAR,
36 PT_COLOR_ERROR,
37 PT_COLOR_RED,
38 PT_COLOR_YELLOW,
39 PT_COLOR_GREEN,
40 PT_COLOR_BRIGHT,
41 PT_COLOR_BLUE,
42};
43
Amit Arora47fd9182010-08-24 13:26:06 +053044static WINDOW *header_win;
Amit Arora47fd9182010-08-24 13:26:06 +053045static WINDOW *footer_win;
Daniel Lezcanoc196d432011-06-21 00:57:08 +020046static WINDOW *main_win;
Daniel Lezcanod96731a2011-06-15 15:45:12 +020047static int current_win;
Amit Arora47fd9182010-08-24 13:26:06 +053048
Daniel Lezcano2adc48d2011-06-08 23:30:01 +020049/* Number of lines in the virtual window */
50static const int maxrows = 1024;
51
Daniel Lezcano2adc48d2011-06-08 23:30:01 +020052struct rowdata {
53 int attr;
54 void *data;
55};
56
Daniel Lezcanob3e6e812011-06-15 15:45:12 +020057struct windata {
Daniel Lezcanof6656822011-06-15 15:45:12 +020058 WINDOW *pad;
Daniel Lezcanob301b082011-06-15 15:45:12 +020059 struct display_ops *ops;
Daniel Lezcanob3e6e812011-06-15 15:45:12 +020060 struct rowdata *rowdata;
61 char *name;
62 int nrdata;
63 int scrolling;
64 int cursor;
65};
66
Daniel Lezcano4120e262011-06-15 15:45:12 +020067/* Warning this is linked with the enum { CLOCK, REGULATOR, ... } */
Daniel Lezcano176e69d2011-06-15 15:45:12 +020068struct windata windata[] = {
Daniel Lezcano4120e262011-06-15 15:45:12 +020069 [CLOCK] = { .name = "Clocks" },
70 [REGULATOR] = { .name = "Regulators" },
71 [SENSOR] = { .name = "Sensors" },
Daniel Lezcano269de4f2011-08-25 15:46:13 +020072 [GPIO] = { .name = "Gpio" },
Daniel Lezcanob3e6e812011-06-15 15:45:12 +020073};
Daniel Lezcano2adc48d2011-06-08 23:30:01 +020074
Daniel Lezcano3abd8b12011-03-26 22:06:15 +010075static void display_fini(void)
76{
77 endwin();
78}
79
Daniel Lezcano653cb4a2011-06-21 00:57:08 +020080static int display_show_header(int win)
Daniel Lezcano7b3da502011-06-15 15:45:12 +020081{
82 int i;
83 int curr_pointer = 0;
Daniel Lezcano4120e262011-06-15 15:45:12 +020084 size_t array_size = sizeof(windata) / sizeof(windata[0]);
Daniel Lezcano7b3da502011-06-15 15:45:12 +020085
86 wattrset(header_win, COLOR_PAIR(PT_COLOR_HEADER_BAR));
87 wbkgd(header_win, COLOR_PAIR(PT_COLOR_HEADER_BAR));
88 werase(header_win);
89
Daniel Lezcanoc757e6d2011-06-21 00:57:08 +020090 mvwprintw(header_win, 0, curr_pointer, "PowerDebug %s", VERSION);
Daniel Lezcano7b3da502011-06-15 15:45:12 +020091 curr_pointer += 20;
92
Daniel Lezcano4120e262011-06-15 15:45:12 +020093 for (i = 0; i < array_size; i++) {
Daniel Lezcano7b3da502011-06-15 15:45:12 +020094 if (win == i)
95 wattron(header_win, A_REVERSE);
96 else
97 wattroff(header_win, A_REVERSE);
98
Daniel Lezcanoc757e6d2011-06-21 00:57:08 +020099 mvwprintw(header_win, 0, curr_pointer, " %s ", windata[i].name);
Daniel Lezcano7b3da502011-06-15 15:45:12 +0200100 curr_pointer += strlen(windata[i].name) + 2;
101 }
102 wrefresh(header_win);
Daniel Lezcano7b3da502011-06-15 15:45:12 +0200103
Daniel Lezcano653cb4a2011-06-21 00:57:08 +0200104 return 0;
105}
106
107#define footer_label " Q (Quit) R (Refresh) Other Keys: 'Left', " \
108 "'Right' , 'Up', 'Down', 'enter', , 'Esc'"
109
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200110static int display_show_footer(int win, char *string)
Daniel Lezcano653cb4a2011-06-21 00:57:08 +0200111{
112 werase(footer_win);
Daniel Lezcano7b3da502011-06-15 15:45:12 +0200113 wattron(footer_win, A_REVERSE);
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200114 mvwprintw(footer_win, 0, 0, "%s", string ? string : footer_label);
Daniel Lezcano7b3da502011-06-15 15:45:12 +0200115 wattroff(footer_win, A_REVERSE);
116 wrefresh(footer_win);
117
118 return 0;
119}
120
Daniel Lezcanod577aaa2011-06-21 00:57:08 +0200121static int display_refresh(int win, bool read)
Amit Arora47fd9182010-08-24 13:26:06 +0530122{
Daniel Lezcanodb145802011-06-21 00:57:08 +0200123 /* we are trying to refresh a window which is not showed */
124 if (win != current_win)
125 return 0;
Daniel Lezcanof6656822011-06-15 15:45:12 +0200126
Daniel Lezcanodb145802011-06-21 00:57:08 +0200127 if (windata[win].ops && windata[win].ops->display)
Daniel Lezcanod577aaa2011-06-21 00:57:08 +0200128 return windata[win].ops->display(read);
Daniel Lezcano971515a2011-06-15 15:45:12 +0200129
Daniel Lezcanocaafece2011-06-27 22:59:17 +0200130 if (werase(main_win))
131 return -1;
132
133 return wrefresh(main_win);
Daniel Lezcano971515a2011-06-15 15:45:12 +0200134}
135
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200136int display_refresh_pad(int win)
Amit Arora728e0c92010-09-14 12:06:09 +0530137{
Daniel Lezcano0a8cc582011-06-21 00:57:08 +0200138 int maxx, maxy;
139
140 getmaxyx(stdscr, maxy, maxx);
141
Daniel Lezcanof6656822011-06-15 15:45:12 +0200142 return prefresh(windata[win].pad, windata[win].scrolling,
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200143 0, 2, 0, maxy - 2, maxx);
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200144}
Amit Aroraac4e8652010-11-09 11:16:53 +0530145
Sanjay Singh Rawat83b37c32013-04-17 14:57:07 +0530146void sigwinch_handler(int signo)
147{
148 display_refresh(current_win, true);
149}
150
Daniel Lezcano28203df2011-06-15 15:45:12 +0200151static int display_show_unselection(int win, int line, bool bold)
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200152{
Daniel Lezcanof6656822011-06-15 15:45:12 +0200153 if (mvwchgat(windata[win].pad, line, 0, -1,
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200154 bold ? WA_BOLD: WA_NORMAL, 0, NULL) < 0)
155 return -1;
156
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200157 return display_refresh_pad(win);
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200158}
159
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200160void *display_get_row_data(int win)
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200161{
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200162 return windata[win].rowdata[windata[win].cursor].data;
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200163}
164
Daniel Lezcano28203df2011-06-15 15:45:12 +0200165static int display_select(void)
166{
167 if (windata[current_win].ops && windata[current_win].ops->select)
168 return windata[current_win].ops->select();
169
170 return 0;
171}
172
Shaojie Sun8ac4a2e2013-07-29 20:11:46 +0800173static int display_change(int keyvalue)
174{
175 if (!(windata[current_win].nrdata))
176 return 0;
177
178 if (windata[current_win].ops && windata[current_win].ops->change)
179 return windata[current_win].ops->change(keyvalue);
180
181 return 0;
182}
183
Daniel Lezcano28203df2011-06-15 15:45:12 +0200184static int display_next_panel(void)
185{
186 size_t array_size = sizeof(windata) / sizeof(windata[0]);
187
188 current_win++;
189 current_win %= array_size;
190
191 return current_win;
192}
193
194static int display_prev_panel(void)
195{
196 size_t array_size = sizeof(windata) / sizeof(windata[0]);
197
198 current_win--;
199 if (current_win < 0)
200 current_win = array_size - 1;
201
202 return current_win;
203}
204
205static int display_next_line(void)
206{
Daniel Lezcano83b28d02016-02-18 13:49:55 +0000207 int maxy;
Daniel Lezcano28203df2011-06-15 15:45:12 +0200208 int cursor = windata[current_win].cursor;
209 int nrdata = windata[current_win].nrdata;
210 int scrolling = windata[current_win].scrolling;
211 struct rowdata *rowdata = windata[current_win].rowdata;
212
Daniel Lezcano83b28d02016-02-18 13:49:55 +0000213 maxy = getmaxy(stdscr);
Daniel Lezcano0a8cc582011-06-21 00:57:08 +0200214
Daniel Lezcano28203df2011-06-15 15:45:12 +0200215 if (cursor >= nrdata)
216 return cursor;
217
218 display_show_unselection(current_win, cursor, rowdata[cursor].attr);
219 if (cursor < nrdata - 1) {
220 if (cursor >= (maxy - 4 + scrolling))
221 scrolling++;
222 cursor++;
223 }
224
225 windata[current_win].scrolling = scrolling;
226 windata[current_win].cursor = cursor;
227
228 return cursor;
229}
230
231static int display_prev_line(void)
232{
233 int cursor = windata[current_win].cursor;
234 int nrdata = windata[current_win].nrdata;
235 int scrolling = windata[current_win].scrolling;
236 struct rowdata *rowdata = windata[current_win].rowdata;
237
238 if (cursor >= nrdata)
239 return cursor;
240
241 display_show_unselection(current_win, cursor, rowdata[cursor].attr);
242 if (cursor > 0) {
243 if (cursor <= scrolling)
244 scrolling--;
245 cursor--;
246 }
247
248 windata[current_win].scrolling = scrolling;
249 windata[current_win].cursor = cursor;
250
251 return cursor;
252}
253
254static int display_set_row_data(int win, int line, void *data, int attr)
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200255{
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200256 struct rowdata *rowdata = windata[win].rowdata;
257
258 if (line >= windata[win].nrdata) {
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200259 rowdata = realloc(rowdata, sizeof(struct rowdata) * (line + 1));
260 if (!rowdata)
261 return -1;
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200262 windata[win].nrdata = line + 1;
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200263 }
264
265 rowdata[line].data = data;
266 rowdata[line].attr = attr;
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200267 windata[win].rowdata = rowdata;
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200268
269 return 0;
270}
271
Daniel Lezcanof6656822011-06-15 15:45:12 +0200272int display_reset_cursor(int win)
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200273{
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200274 windata[win].nrdata = 0;
Daniel Lezcanof6656822011-06-15 15:45:12 +0200275 werase(windata[win].pad);
276 return wmove(windata[win].pad, 0, 0);
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200277}
278
Sanjay Singh Rawat96f6e052014-05-26 11:35:02 +0530279void display_message(int win, char *buf)
280{
281 display_reset_cursor(win);
282 wattron(windata[win].pad, WA_BOLD);
283 wprintw(windata[win].pad, "%s\n", buf);
284 wattroff(windata[win].pad, WA_BOLD);
285 display_refresh_pad(win);
286}
287
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200288int display_print_line(int win, int line, char *str, int bold, void *data)
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200289{
290 int attr = 0;
291
Amit Arora031263a2010-11-09 11:12:41 +0530292 if (bold)
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200293 attr |= WA_BOLD;
294
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200295 if (line == windata[win].cursor)
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200296 attr |= WA_STANDOUT;
297
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200298 if (display_set_row_data(win, line, data, attr))
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200299 return -1;
300
301 if (attr)
Daniel Lezcanof6656822011-06-15 15:45:12 +0200302 wattron(windata[win].pad, attr);
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200303
Daniel Lezcanof6656822011-06-15 15:45:12 +0200304 wprintw(windata[win].pad, "%s\n", str);
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200305
306 if (attr)
Daniel Lezcanof6656822011-06-15 15:45:12 +0200307 wattroff(windata[win].pad, attr);
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200308
309 return 0;
310}
311
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200312static int display_find_keystroke(int fd, void *data);
313
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200314struct find_data {
315 size_t len;
316 char *string;
317 regex_t *reg;
Daniel Lezcano96a64fb2011-06-21 00:57:08 +0200318 int ocursor;
Daniel Lezcano10c86452011-06-21 00:57:08 +0200319 int oscrolling;
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200320};
321
Daniel Lezcano10c86452011-06-21 00:57:08 +0200322struct find_data *display_find_init(void)
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200323{
324 const char *regexp = "^[a-z|0-9|_|-|.]";
325 struct find_data *findd;
326 const size_t len = 64;
327 regex_t *reg;
328 char *search4;
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200329
330 reg = malloc(sizeof(*reg));
331 if (!reg)
332 return NULL;
333
334 if (regcomp(reg, regexp, REG_ICASE))
335 goto out_free_reg;
336
337 search4 = malloc(len);
338 if (!search4)
339 goto out_free_regcomp;
340 memset(search4, '\0', len);
341
342 findd = malloc(sizeof(*findd));
343 if (!findd)
344 goto out_free_search4;
345
346 findd->string = search4;
347 findd->reg = reg;
348 findd->len = len;
Daniel Lezcano96a64fb2011-06-21 00:57:08 +0200349
350 /* save the location of the cursor on the main window in order to
351 * browse the search result
352 */
353 findd->ocursor = windata[current_win].cursor;
Daniel Lezcano10c86452011-06-21 00:57:08 +0200354 findd->oscrolling = windata[current_win].scrolling;
Daniel Lezcano96a64fb2011-06-21 00:57:08 +0200355
Daniel Lezcano10c86452011-06-21 00:57:08 +0200356 windata[current_win].cursor = 0;
357 windata[current_win].scrolling = 0;
358
359 curs_set(1);
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200360out:
361 return findd;
362
363out_free_search4:
364 free(search4);
365out_free_regcomp:
366 regfree(reg);
367out_free_reg:
368 free(reg);
369
370 goto out;
371}
372
Daniel Lezcano10c86452011-06-21 00:57:08 +0200373static void display_find_fini(struct find_data *findd)
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200374{
Daniel Lezcano10c86452011-06-21 00:57:08 +0200375 windata[current_win].cursor = findd->ocursor;
376 windata[current_win].scrolling = findd->oscrolling;
377 regfree(findd->reg);
378 free(findd->string);
379 free(findd);
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200380 curs_set(0);
381}
382
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200383static int display_switch_to_find(int fd)
384{
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200385 struct find_data *findd;
386
Daniel Lezcano10c86452011-06-21 00:57:08 +0200387 findd = display_find_init();
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200388 if (!findd)
389 return -1;
390
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200391 if (mainloop_del(fd))
392 return -1;
393
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200394 if (mainloop_add(fd, display_find_keystroke, findd))
395 return -1;
396
397 if (display_show_footer(current_win, "find (esc to exit)?"))
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200398 return -1;
399
400 return 0;
401}
402
Daniel Lezcanodb145802011-06-21 00:57:08 +0200403static int display_keystroke(int fd, void *data)
Daniel Lezcano176e69d2011-06-15 15:45:12 +0200404{
Daniel Lezcano176e69d2011-06-15 15:45:12 +0200405 int keystroke = getch();
406
407 switch (keystroke) {
408
409 case KEY_RIGHT:
410 case '\t':
Daniel Lezcano372ffba2011-06-21 00:57:08 +0200411 display_show_header(display_next_panel());
Daniel Lezcano176e69d2011-06-15 15:45:12 +0200412 break;
413
414 case KEY_LEFT:
415 case KEY_BTAB:
Daniel Lezcano372ffba2011-06-21 00:57:08 +0200416 display_show_header(display_prev_panel());
Daniel Lezcano176e69d2011-06-15 15:45:12 +0200417 break;
418
419 case KEY_DOWN:
420 display_next_line();
421 break;
422
423 case KEY_UP:
424 display_prev_line();
425 break;
426
Shaojie Sunb32cbb92013-07-17 16:23:45 +0800427 case '\n':
Daniel Lezcano176e69d2011-06-15 15:45:12 +0200428 case '\r':
429 display_select();
430 break;
431
Shaojie Sun8ac4a2e2013-07-29 20:11:46 +0800432 case 'v':
433 case 'V':
434 case 'd':
435 case 'D':
436 display_change(toupper(keystroke));
437 break;
438
Daniel Lezcano176e69d2011-06-15 15:45:12 +0200439 case EOF:
440 case 'q':
441 case 'Q':
442 return 1;
443
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200444 case '/':
445 return display_switch_to_find(fd);
446
Daniel Lezcano176e69d2011-06-15 15:45:12 +0200447 case 'r':
448 case 'R':
Daniel Lezcanod577aaa2011-06-21 00:57:08 +0200449 return display_refresh(current_win, true);
Daniel Lezcanodb145802011-06-21 00:57:08 +0200450 default:
451 return 0;
Daniel Lezcano176e69d2011-06-15 15:45:12 +0200452 }
453
Daniel Lezcanod577aaa2011-06-21 00:57:08 +0200454 display_refresh(current_win, false);
Daniel Lezcanodb145802011-06-21 00:57:08 +0200455
456 return 0;
457}
458
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200459static int display_switch_to_main(int fd)
460{
461 if (mainloop_del(fd))
462 return -1;
463
464 if (mainloop_add(fd, display_keystroke, NULL))
465 return -1;
466
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200467 if (display_show_header(current_win))
468 return -1;
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200469
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200470 if (display_show_footer(current_win, NULL))
471 return -1;
472
Daniel Lezcanod577aaa2011-06-21 00:57:08 +0200473 return display_refresh(current_win, false);
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200474}
475
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200476static int display_find_keystroke(int fd, void *data)
477{
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200478 struct find_data *findd = data;
479 regex_t *reg = findd->reg;
480 char *string = findd->string;
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200481 int keystroke = getch();
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200482 char match[2] = { [0] = (char)keystroke, [1] = '\0' };
483 regmatch_t m[1];
484
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200485 switch (keystroke) {
486
487 case '\e':
Daniel Lezcano10c86452011-06-21 00:57:08 +0200488 display_find_fini(findd);
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200489 return display_switch_to_main(fd);
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200490
Daniel Lezcanoa12163d2011-06-21 00:57:08 +0200491 case KEY_DOWN:
492 display_next_line();
493 break;
494
495 case KEY_UP:
496 display_prev_line();
497 break;
498
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200499 case KEY_BACKSPACE:
500 if (strlen(string))
501 string[strlen(string) - 1] = '\0';
Daniel Lezcano10c86452011-06-21 00:57:08 +0200502
503 windata[current_win].cursor = 0;
504 windata[current_win].scrolling = 0;
505
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200506 break;
507
Shaojie Sunb32cbb92013-07-17 16:23:45 +0800508 case '\n':
Daniel Lezcano73b40022011-06-21 00:57:08 +0200509 case '\r':
510 if (!windata[current_win].ops || !windata[current_win].ops->selectf)
511 return 0;
512
513 if (windata[current_win].ops->selectf())
514 return -1;
515
Daniel Lezcanoe78bc072011-06-21 10:49:39 +0200516 windata[current_win].cursor = 0;
517 windata[current_win].scrolling = 0;
518
Daniel Lezcano73b40022011-06-21 00:57:08 +0200519 return 0;
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200520
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200521 default:
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200522
523 /* We don't want invalid characters for a name */
524 if (regexec(reg, match, 1, m, 0))
525 return 0;
526
527 if (strlen(string) < findd->len - 1)
528 string[strlen(string)] = (char)keystroke;
529
Daniel Lezcano10c86452011-06-21 00:57:08 +0200530 windata[current_win].cursor = 0;
531 windata[current_win].scrolling = 0;
532
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200533 break;
534 }
535
Daniel Lezcanoa12163d2011-06-21 00:57:08 +0200536 if (!windata[current_win].ops || !windata[current_win].ops->find)
537 return 0;
538
539 if (windata[current_win].ops->find(string))
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200540 return -1;
541
Daniel Lezcanoa12163d2011-06-21 00:57:08 +0200542 if (display_show_header(current_win))
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200543 return -1;
544
545 if (display_show_footer(current_win, strlen(string) ? string :
546 "find (esc to exit)?"))
547 return -1;
548
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200549 return 0;
550}
551
Daniel Lezcanodb145802011-06-21 00:57:08 +0200552int display_init(int wdefault)
553{
Daniel Lezcano0a8cc582011-06-21 00:57:08 +0200554 int i, maxx, maxy;
Daniel Lezcanodb145802011-06-21 00:57:08 +0200555 size_t array_size = sizeof(windata) / sizeof(windata[0]);
556
557 current_win = wdefault;
558
559 if (mainloop_add(0, display_keystroke, NULL))
560 return -1;
561
562 if (!initscr())
563 return -1;
564
565 start_color();
566 use_default_colors();
567
568 keypad(stdscr, TRUE);
569 noecho();
570 cbreak();
571 curs_set(0);
572 nonl();
573
574 if (init_pair(PT_COLOR_DEFAULT, COLOR_WHITE, COLOR_BLACK) ||
575 init_pair(PT_COLOR_ERROR, COLOR_BLACK, COLOR_RED) ||
576 init_pair(PT_COLOR_HEADER_BAR, COLOR_WHITE, COLOR_BLACK) ||
577 init_pair(PT_COLOR_YELLOW, COLOR_WHITE, COLOR_YELLOW) ||
578 init_pair(PT_COLOR_GREEN, COLOR_WHITE, COLOR_GREEN) ||
579 init_pair(PT_COLOR_BRIGHT, COLOR_WHITE, COLOR_BLACK) ||
580 init_pair(PT_COLOR_BLUE, COLOR_WHITE, COLOR_BLUE) ||
581 init_pair(PT_COLOR_RED, COLOR_WHITE, COLOR_RED))
582 return -1;
583
584 if (atexit(display_fini))
585 return -1;
586
587 getmaxyx(stdscr, maxy, maxx);
588
589 for (i = 0; i < array_size; i++) {
590
Daniel Lezcanoc196d432011-06-21 00:57:08 +0200591 main_win = subwin(stdscr, maxy - 2, maxx, 1, 0);
592 if (!main_win)
Daniel Lezcanodb145802011-06-21 00:57:08 +0200593 return -1;
594
595 windata[i].pad = newpad(maxrows, maxx);
596 if (!windata[i].pad)
597 return -1;
598
599 }
600
601 header_win = subwin(stdscr, 1, maxx, 0, 0);
602 if (!header_win)
603 return -1;
604
605 footer_win = subwin(stdscr, 1, maxx, maxy-1, 0);
606 if (!footer_win)
607 return -1;
608
Daniel Lezcano653cb4a2011-06-21 00:57:08 +0200609 if (display_show_header(wdefault))
610 return -1;
611
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200612 if (display_show_footer(wdefault, NULL))
Daniel Lezcanodb145802011-06-21 00:57:08 +0200613 return -1;
614
Daniel Lezcanod577aaa2011-06-21 00:57:08 +0200615 return display_refresh(wdefault, true);
Daniel Lezcanodb145802011-06-21 00:57:08 +0200616}
617
Daniel Lezcano372ffba2011-06-21 00:57:08 +0200618int display_column_name(const char *line)
Daniel Lezcanodb145802011-06-21 00:57:08 +0200619{
Daniel Lezcanoc196d432011-06-21 00:57:08 +0200620 werase(main_win);
621 wattron(main_win, A_BOLD);
Daniel Lezcanofa453332011-06-21 00:57:08 +0200622 mvwprintw(main_win, 0, 0, "%s", line);
Daniel Lezcanoc196d432011-06-21 00:57:08 +0200623 wattroff(main_win, A_BOLD);
624 wrefresh(main_win);
Daniel Lezcanodb145802011-06-21 00:57:08 +0200625
Daniel Lezcano372ffba2011-06-21 00:57:08 +0200626 return 0;
Daniel Lezcanodb145802011-06-21 00:57:08 +0200627}
628
629int display_register(int win, struct display_ops *ops)
630{
631 size_t array_size = sizeof(windata) / sizeof(windata[0]);
632
Sanjay Singh Rawat5fef0052013-04-17 15:02:01 +0530633 if (win < 0 || win >= array_size) {
634 printf("error: invalid window");
Daniel Lezcanodb145802011-06-21 00:57:08 +0200635 return -1;
Sanjay Singh Rawat5fef0052013-04-17 15:02:01 +0530636 }
Daniel Lezcanodb145802011-06-21 00:57:08 +0200637
638 windata[win].ops = ops;
639
Daniel Lezcano176e69d2011-06-15 15:45:12 +0200640 return 0;
641}