blob: ed010b37c3b32ea871bfa3e07d47b1f6581ba1b4 [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 Aroraed3e5652010-10-27 12:02:53 +053031#include "display.h"
Amit Arora47fd9182010-08-24 13:26:06 +053032
Daniel Lezcanoeeb13762011-03-26 22:06:17 +010033enum { PT_COLOR_DEFAULT = 1,
34 PT_COLOR_HEADER_BAR,
35 PT_COLOR_ERROR,
36 PT_COLOR_RED,
37 PT_COLOR_YELLOW,
38 PT_COLOR_GREEN,
39 PT_COLOR_BRIGHT,
40 PT_COLOR_BLUE,
41};
42
Amit Arora47fd9182010-08-24 13:26:06 +053043static WINDOW *header_win;
Amit Arora47fd9182010-08-24 13:26:06 +053044static WINDOW *footer_win;
Daniel Lezcanoc196d432011-06-21 00:57:08 +020045static WINDOW *main_win;
Daniel Lezcanod96731a2011-06-15 15:45:12 +020046static int current_win;
Amit Arora47fd9182010-08-24 13:26:06 +053047
Daniel Lezcano2adc48d2011-06-08 23:30:01 +020048/* Number of lines in the virtual window */
49static const int maxrows = 1024;
50
Daniel Lezcano2adc48d2011-06-08 23:30:01 +020051struct rowdata {
52 int attr;
53 void *data;
54};
55
Daniel Lezcanob3e6e812011-06-15 15:45:12 +020056struct windata {
Daniel Lezcanof6656822011-06-15 15:45:12 +020057 WINDOW *pad;
Daniel Lezcanob301b082011-06-15 15:45:12 +020058 struct display_ops *ops;
Daniel Lezcanob3e6e812011-06-15 15:45:12 +020059 struct rowdata *rowdata;
60 char *name;
61 int nrdata;
62 int scrolling;
63 int cursor;
64};
65
Daniel Lezcano4120e262011-06-15 15:45:12 +020066/* Warning this is linked with the enum { CLOCK, REGULATOR, ... } */
Daniel Lezcano176e69d2011-06-15 15:45:12 +020067struct windata windata[] = {
Daniel Lezcano4120e262011-06-15 15:45:12 +020068 [CLOCK] = { .name = "Clocks" },
69 [REGULATOR] = { .name = "Regulators" },
70 [SENSOR] = { .name = "Sensors" },
Daniel Lezcano269de4f2011-08-25 15:46:13 +020071 [GPIO] = { .name = "Gpio" },
Daniel Lezcanob3e6e812011-06-15 15:45:12 +020072};
Daniel Lezcano2adc48d2011-06-08 23:30:01 +020073
Daniel Lezcano3abd8b12011-03-26 22:06:15 +010074static void display_fini(void)
75{
76 endwin();
77}
78
Daniel Lezcano653cb4a2011-06-21 00:57:08 +020079static int display_show_header(int win)
Daniel Lezcano7b3da502011-06-15 15:45:12 +020080{
81 int i;
82 int curr_pointer = 0;
Daniel Lezcano4120e262011-06-15 15:45:12 +020083 size_t array_size = sizeof(windata) / sizeof(windata[0]);
Daniel Lezcano7b3da502011-06-15 15:45:12 +020084
85 wattrset(header_win, COLOR_PAIR(PT_COLOR_HEADER_BAR));
86 wbkgd(header_win, COLOR_PAIR(PT_COLOR_HEADER_BAR));
87 werase(header_win);
88
Daniel Lezcanoc757e6d2011-06-21 00:57:08 +020089 mvwprintw(header_win, 0, curr_pointer, "PowerDebug %s", VERSION);
Daniel Lezcano7b3da502011-06-15 15:45:12 +020090 curr_pointer += 20;
91
Daniel Lezcano4120e262011-06-15 15:45:12 +020092 for (i = 0; i < array_size; i++) {
Daniel Lezcano7b3da502011-06-15 15:45:12 +020093 if (win == i)
94 wattron(header_win, A_REVERSE);
95 else
96 wattroff(header_win, A_REVERSE);
97
Daniel Lezcanoc757e6d2011-06-21 00:57:08 +020098 mvwprintw(header_win, 0, curr_pointer, " %s ", windata[i].name);
Daniel Lezcano7b3da502011-06-15 15:45:12 +020099 curr_pointer += strlen(windata[i].name) + 2;
100 }
101 wrefresh(header_win);
Daniel Lezcano7b3da502011-06-15 15:45:12 +0200102
Daniel Lezcano653cb4a2011-06-21 00:57:08 +0200103 return 0;
104}
105
106#define footer_label " Q (Quit) R (Refresh) Other Keys: 'Left', " \
107 "'Right' , 'Up', 'Down', 'enter', , 'Esc'"
108
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200109static int display_show_footer(int win, char *string)
Daniel Lezcano653cb4a2011-06-21 00:57:08 +0200110{
111 werase(footer_win);
Daniel Lezcano7b3da502011-06-15 15:45:12 +0200112 wattron(footer_win, A_REVERSE);
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200113 mvwprintw(footer_win, 0, 0, "%s", string ? string : footer_label);
Daniel Lezcano7b3da502011-06-15 15:45:12 +0200114 wattroff(footer_win, A_REVERSE);
115 wrefresh(footer_win);
116
117 return 0;
118}
119
Daniel Lezcanod577aaa2011-06-21 00:57:08 +0200120static int display_refresh(int win, bool read)
Amit Arora47fd9182010-08-24 13:26:06 +0530121{
Daniel Lezcanodb145802011-06-21 00:57:08 +0200122 /* we are trying to refresh a window which is not showed */
123 if (win != current_win)
124 return 0;
Daniel Lezcanof6656822011-06-15 15:45:12 +0200125
Daniel Lezcanodb145802011-06-21 00:57:08 +0200126 if (windata[win].ops && windata[win].ops->display)
Daniel Lezcanod577aaa2011-06-21 00:57:08 +0200127 return windata[win].ops->display(read);
Daniel Lezcano971515a2011-06-15 15:45:12 +0200128
Daniel Lezcanocaafece2011-06-27 22:59:17 +0200129 if (werase(main_win))
130 return -1;
131
132 return wrefresh(main_win);
Daniel Lezcano971515a2011-06-15 15:45:12 +0200133}
134
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200135int display_refresh_pad(int win)
Amit Arora728e0c92010-09-14 12:06:09 +0530136{
Daniel Lezcano0a8cc582011-06-21 00:57:08 +0200137 int maxx, maxy;
138
139 getmaxyx(stdscr, maxy, maxx);
140
Daniel Lezcanof6656822011-06-15 15:45:12 +0200141 return prefresh(windata[win].pad, windata[win].scrolling,
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200142 0, 2, 0, maxy - 2, maxx);
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200143}
Amit Aroraac4e8652010-11-09 11:16:53 +0530144
Sanjay Singh Rawat83b37c32013-04-17 14:57:07 +0530145void sigwinch_handler(int signo)
146{
147 display_refresh(current_win, true);
148}
149
Daniel Lezcano28203df2011-06-15 15:45:12 +0200150static int display_show_unselection(int win, int line, bool bold)
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200151{
Daniel Lezcanof6656822011-06-15 15:45:12 +0200152 if (mvwchgat(windata[win].pad, line, 0, -1,
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200153 bold ? WA_BOLD: WA_NORMAL, 0, NULL) < 0)
154 return -1;
155
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200156 return display_refresh_pad(win);
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200157}
158
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200159void *display_get_row_data(int win)
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200160{
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200161 return windata[win].rowdata[windata[win].cursor].data;
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200162}
163
Daniel Lezcano28203df2011-06-15 15:45:12 +0200164static int display_select(void)
165{
166 if (windata[current_win].ops && windata[current_win].ops->select)
167 return windata[current_win].ops->select();
168
169 return 0;
170}
171
Shaojie Sun8ac4a2e2013-07-29 20:11:46 +0800172static int display_change(int keyvalue)
173{
174 if (!(windata[current_win].nrdata))
175 return 0;
176
177 if (windata[current_win].ops && windata[current_win].ops->change)
178 return windata[current_win].ops->change(keyvalue);
179
180 return 0;
181}
182
Daniel Lezcano28203df2011-06-15 15:45:12 +0200183static int display_next_panel(void)
184{
185 size_t array_size = sizeof(windata) / sizeof(windata[0]);
186
187 current_win++;
188 current_win %= array_size;
189
190 return current_win;
191}
192
193static int display_prev_panel(void)
194{
195 size_t array_size = sizeof(windata) / sizeof(windata[0]);
196
197 current_win--;
198 if (current_win < 0)
199 current_win = array_size - 1;
200
201 return current_win;
202}
203
204static int display_next_line(void)
205{
Daniel Lezcano83b28d02016-02-18 13:49:55 +0000206 int maxy;
Daniel Lezcano28203df2011-06-15 15:45:12 +0200207 int cursor = windata[current_win].cursor;
208 int nrdata = windata[current_win].nrdata;
209 int scrolling = windata[current_win].scrolling;
210 struct rowdata *rowdata = windata[current_win].rowdata;
211
Daniel Lezcano83b28d02016-02-18 13:49:55 +0000212 maxy = getmaxy(stdscr);
Daniel Lezcano0a8cc582011-06-21 00:57:08 +0200213
Daniel Lezcano28203df2011-06-15 15:45:12 +0200214 if (cursor >= nrdata)
215 return cursor;
216
217 display_show_unselection(current_win, cursor, rowdata[cursor].attr);
218 if (cursor < nrdata - 1) {
219 if (cursor >= (maxy - 4 + scrolling))
220 scrolling++;
221 cursor++;
222 }
223
224 windata[current_win].scrolling = scrolling;
225 windata[current_win].cursor = cursor;
226
227 return cursor;
228}
229
230static int display_prev_line(void)
231{
232 int cursor = windata[current_win].cursor;
233 int nrdata = windata[current_win].nrdata;
234 int scrolling = windata[current_win].scrolling;
235 struct rowdata *rowdata = windata[current_win].rowdata;
236
237 if (cursor >= nrdata)
238 return cursor;
239
240 display_show_unselection(current_win, cursor, rowdata[cursor].attr);
241 if (cursor > 0) {
242 if (cursor <= scrolling)
243 scrolling--;
244 cursor--;
245 }
246
247 windata[current_win].scrolling = scrolling;
248 windata[current_win].cursor = cursor;
249
250 return cursor;
251}
252
253static int display_set_row_data(int win, int line, void *data, int attr)
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200254{
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200255 struct rowdata *rowdata = windata[win].rowdata;
256
257 if (line >= windata[win].nrdata) {
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200258 rowdata = realloc(rowdata, sizeof(struct rowdata) * (line + 1));
259 if (!rowdata)
260 return -1;
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200261 windata[win].nrdata = line + 1;
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200262 }
263
264 rowdata[line].data = data;
265 rowdata[line].attr = attr;
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200266 windata[win].rowdata = rowdata;
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200267
268 return 0;
269}
270
Daniel Lezcanof6656822011-06-15 15:45:12 +0200271int display_reset_cursor(int win)
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200272{
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200273 windata[win].nrdata = 0;
Daniel Lezcanof6656822011-06-15 15:45:12 +0200274 werase(windata[win].pad);
275 return wmove(windata[win].pad, 0, 0);
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200276}
277
Sanjay Singh Rawat96f6e052014-05-26 11:35:02 +0530278void display_message(int win, char *buf)
279{
280 display_reset_cursor(win);
281 wattron(windata[win].pad, WA_BOLD);
282 wprintw(windata[win].pad, "%s\n", buf);
283 wattroff(windata[win].pad, WA_BOLD);
284 display_refresh_pad(win);
285}
286
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200287int display_print_line(int win, int line, char *str, int bold, void *data)
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200288{
289 int attr = 0;
290
Amit Arora031263a2010-11-09 11:12:41 +0530291 if (bold)
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200292 attr |= WA_BOLD;
293
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200294 if (line == windata[win].cursor)
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200295 attr |= WA_STANDOUT;
296
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200297 if (display_set_row_data(win, line, data, attr))
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200298 return -1;
299
300 if (attr)
Daniel Lezcanof6656822011-06-15 15:45:12 +0200301 wattron(windata[win].pad, attr);
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200302
Daniel Lezcanof6656822011-06-15 15:45:12 +0200303 wprintw(windata[win].pad, "%s\n", str);
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200304
305 if (attr)
Daniel Lezcanof6656822011-06-15 15:45:12 +0200306 wattroff(windata[win].pad, attr);
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200307
308 return 0;
309}
310
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200311static int display_find_keystroke(int fd, void *data);
312
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200313struct find_data {
314 size_t len;
315 char *string;
316 regex_t *reg;
Daniel Lezcano96a64fb2011-06-21 00:57:08 +0200317 int ocursor;
Daniel Lezcano10c86452011-06-21 00:57:08 +0200318 int oscrolling;
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200319};
320
Daniel Lezcano10c86452011-06-21 00:57:08 +0200321struct find_data *display_find_init(void)
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200322{
323 const char *regexp = "^[a-z|0-9|_|-|.]";
324 struct find_data *findd;
325 const size_t len = 64;
326 regex_t *reg;
327 char *search4;
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200328
329 reg = malloc(sizeof(*reg));
330 if (!reg)
331 return NULL;
332
333 if (regcomp(reg, regexp, REG_ICASE))
334 goto out_free_reg;
335
336 search4 = malloc(len);
337 if (!search4)
338 goto out_free_regcomp;
339 memset(search4, '\0', len);
340
341 findd = malloc(sizeof(*findd));
342 if (!findd)
343 goto out_free_search4;
344
345 findd->string = search4;
346 findd->reg = reg;
347 findd->len = len;
Daniel Lezcano96a64fb2011-06-21 00:57:08 +0200348
349 /* save the location of the cursor on the main window in order to
350 * browse the search result
351 */
352 findd->ocursor = windata[current_win].cursor;
Daniel Lezcano10c86452011-06-21 00:57:08 +0200353 findd->oscrolling = windata[current_win].scrolling;
Daniel Lezcano96a64fb2011-06-21 00:57:08 +0200354
Daniel Lezcano10c86452011-06-21 00:57:08 +0200355 windata[current_win].cursor = 0;
356 windata[current_win].scrolling = 0;
357
358 curs_set(1);
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200359out:
360 return findd;
361
362out_free_search4:
363 free(search4);
364out_free_regcomp:
365 regfree(reg);
366out_free_reg:
367 free(reg);
368
369 goto out;
370}
371
Daniel Lezcano10c86452011-06-21 00:57:08 +0200372static void display_find_fini(struct find_data *findd)
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200373{
Daniel Lezcano10c86452011-06-21 00:57:08 +0200374 windata[current_win].cursor = findd->ocursor;
375 windata[current_win].scrolling = findd->oscrolling;
376 regfree(findd->reg);
377 free(findd->string);
378 free(findd);
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200379 curs_set(0);
380}
381
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200382static int display_switch_to_find(int fd)
383{
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200384 struct find_data *findd;
385
Daniel Lezcano10c86452011-06-21 00:57:08 +0200386 findd = display_find_init();
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200387 if (!findd)
388 return -1;
389
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200390 if (mainloop_del(fd))
391 return -1;
392
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200393 if (mainloop_add(fd, display_find_keystroke, findd))
394 return -1;
395
396 if (display_show_footer(current_win, "find (esc to exit)?"))
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200397 return -1;
398
399 return 0;
400}
401
Daniel Lezcanodb145802011-06-21 00:57:08 +0200402static int display_keystroke(int fd, void *data)
Daniel Lezcano176e69d2011-06-15 15:45:12 +0200403{
Daniel Lezcano176e69d2011-06-15 15:45:12 +0200404 int keystroke = getch();
405
406 switch (keystroke) {
407
408 case KEY_RIGHT:
409 case '\t':
Daniel Lezcano372ffba2011-06-21 00:57:08 +0200410 display_show_header(display_next_panel());
Daniel Lezcano176e69d2011-06-15 15:45:12 +0200411 break;
412
413 case KEY_LEFT:
414 case KEY_BTAB:
Daniel Lezcano372ffba2011-06-21 00:57:08 +0200415 display_show_header(display_prev_panel());
Daniel Lezcano176e69d2011-06-15 15:45:12 +0200416 break;
417
418 case KEY_DOWN:
419 display_next_line();
420 break;
421
422 case KEY_UP:
423 display_prev_line();
424 break;
425
Shaojie Sunb32cbb92013-07-17 16:23:45 +0800426 case '\n':
Daniel Lezcano176e69d2011-06-15 15:45:12 +0200427 case '\r':
428 display_select();
429 break;
430
Shaojie Sun8ac4a2e2013-07-29 20:11:46 +0800431 case 'v':
432 case 'V':
433 case 'd':
434 case 'D':
435 display_change(toupper(keystroke));
436 break;
437
Daniel Lezcano176e69d2011-06-15 15:45:12 +0200438 case EOF:
439 case 'q':
440 case 'Q':
441 return 1;
442
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200443 case '/':
444 return display_switch_to_find(fd);
445
Daniel Lezcano176e69d2011-06-15 15:45:12 +0200446 case 'r':
447 case 'R':
Daniel Lezcanod577aaa2011-06-21 00:57:08 +0200448 return display_refresh(current_win, true);
Daniel Lezcanodb145802011-06-21 00:57:08 +0200449 default:
450 return 0;
Daniel Lezcano176e69d2011-06-15 15:45:12 +0200451 }
452
Daniel Lezcanod577aaa2011-06-21 00:57:08 +0200453 display_refresh(current_win, false);
Daniel Lezcanodb145802011-06-21 00:57:08 +0200454
455 return 0;
456}
457
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200458static int display_switch_to_main(int fd)
459{
460 if (mainloop_del(fd))
461 return -1;
462
463 if (mainloop_add(fd, display_keystroke, NULL))
464 return -1;
465
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200466 if (display_show_header(current_win))
467 return -1;
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200468
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200469 if (display_show_footer(current_win, NULL))
470 return -1;
471
Daniel Lezcanod577aaa2011-06-21 00:57:08 +0200472 return display_refresh(current_win, false);
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200473}
474
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200475static int display_find_keystroke(int fd, void *data)
476{
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200477 struct find_data *findd = data;
478 regex_t *reg = findd->reg;
479 char *string = findd->string;
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200480 int keystroke = getch();
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200481 char match[2] = { [0] = (char)keystroke, [1] = '\0' };
482 regmatch_t m[1];
483
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200484 switch (keystroke) {
485
486 case '\e':
Daniel Lezcano10c86452011-06-21 00:57:08 +0200487 display_find_fini(findd);
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200488 return display_switch_to_main(fd);
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200489
Daniel Lezcanoa12163d2011-06-21 00:57:08 +0200490 case KEY_DOWN:
491 display_next_line();
492 break;
493
494 case KEY_UP:
495 display_prev_line();
496 break;
497
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200498 case KEY_BACKSPACE:
499 if (strlen(string))
500 string[strlen(string) - 1] = '\0';
Daniel Lezcano10c86452011-06-21 00:57:08 +0200501
502 windata[current_win].cursor = 0;
503 windata[current_win].scrolling = 0;
504
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200505 break;
506
Shaojie Sunb32cbb92013-07-17 16:23:45 +0800507 case '\n':
Daniel Lezcano73b40022011-06-21 00:57:08 +0200508 case '\r':
509 if (!windata[current_win].ops || !windata[current_win].ops->selectf)
510 return 0;
511
512 if (windata[current_win].ops->selectf())
513 return -1;
514
Daniel Lezcanoe78bc072011-06-21 10:49:39 +0200515 windata[current_win].cursor = 0;
516 windata[current_win].scrolling = 0;
517
Daniel Lezcano73b40022011-06-21 00:57:08 +0200518 return 0;
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200519
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200520 default:
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200521
522 /* We don't want invalid characters for a name */
523 if (regexec(reg, match, 1, m, 0))
524 return 0;
525
526 if (strlen(string) < findd->len - 1)
527 string[strlen(string)] = (char)keystroke;
528
Daniel Lezcano10c86452011-06-21 00:57:08 +0200529 windata[current_win].cursor = 0;
530 windata[current_win].scrolling = 0;
531
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200532 break;
533 }
534
Daniel Lezcanoa12163d2011-06-21 00:57:08 +0200535 if (!windata[current_win].ops || !windata[current_win].ops->find)
536 return 0;
537
538 if (windata[current_win].ops->find(string))
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200539 return -1;
540
Daniel Lezcanoa12163d2011-06-21 00:57:08 +0200541 if (display_show_header(current_win))
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200542 return -1;
543
544 if (display_show_footer(current_win, strlen(string) ? string :
545 "find (esc to exit)?"))
546 return -1;
547
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200548 return 0;
549}
550
Daniel Lezcanodb145802011-06-21 00:57:08 +0200551int display_init(int wdefault)
552{
Daniel Lezcano0a8cc582011-06-21 00:57:08 +0200553 int i, maxx, maxy;
Daniel Lezcanodb145802011-06-21 00:57:08 +0200554 size_t array_size = sizeof(windata) / sizeof(windata[0]);
555
556 current_win = wdefault;
557
558 if (mainloop_add(0, display_keystroke, NULL))
559 return -1;
560
561 if (!initscr())
562 return -1;
563
564 start_color();
565 use_default_colors();
566
567 keypad(stdscr, TRUE);
568 noecho();
569 cbreak();
570 curs_set(0);
571 nonl();
572
573 if (init_pair(PT_COLOR_DEFAULT, COLOR_WHITE, COLOR_BLACK) ||
574 init_pair(PT_COLOR_ERROR, COLOR_BLACK, COLOR_RED) ||
575 init_pair(PT_COLOR_HEADER_BAR, COLOR_WHITE, COLOR_BLACK) ||
576 init_pair(PT_COLOR_YELLOW, COLOR_WHITE, COLOR_YELLOW) ||
577 init_pair(PT_COLOR_GREEN, COLOR_WHITE, COLOR_GREEN) ||
578 init_pair(PT_COLOR_BRIGHT, COLOR_WHITE, COLOR_BLACK) ||
579 init_pair(PT_COLOR_BLUE, COLOR_WHITE, COLOR_BLUE) ||
580 init_pair(PT_COLOR_RED, COLOR_WHITE, COLOR_RED))
581 return -1;
582
583 if (atexit(display_fini))
584 return -1;
585
586 getmaxyx(stdscr, maxy, maxx);
587
588 for (i = 0; i < array_size; i++) {
589
Daniel Lezcanoc196d432011-06-21 00:57:08 +0200590 main_win = subwin(stdscr, maxy - 2, maxx, 1, 0);
591 if (!main_win)
Daniel Lezcanodb145802011-06-21 00:57:08 +0200592 return -1;
593
594 windata[i].pad = newpad(maxrows, maxx);
595 if (!windata[i].pad)
596 return -1;
597
598 }
599
600 header_win = subwin(stdscr, 1, maxx, 0, 0);
601 if (!header_win)
602 return -1;
603
604 footer_win = subwin(stdscr, 1, maxx, maxy-1, 0);
605 if (!footer_win)
606 return -1;
607
Daniel Lezcano653cb4a2011-06-21 00:57:08 +0200608 if (display_show_header(wdefault))
609 return -1;
610
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200611 if (display_show_footer(wdefault, NULL))
Daniel Lezcanodb145802011-06-21 00:57:08 +0200612 return -1;
613
Daniel Lezcanod577aaa2011-06-21 00:57:08 +0200614 return display_refresh(wdefault, true);
Daniel Lezcanodb145802011-06-21 00:57:08 +0200615}
616
Daniel Lezcano372ffba2011-06-21 00:57:08 +0200617int display_column_name(const char *line)
Daniel Lezcanodb145802011-06-21 00:57:08 +0200618{
Daniel Lezcanoc196d432011-06-21 00:57:08 +0200619 werase(main_win);
620 wattron(main_win, A_BOLD);
Daniel Lezcanofa453332011-06-21 00:57:08 +0200621 mvwprintw(main_win, 0, 0, "%s", line);
Daniel Lezcanoc196d432011-06-21 00:57:08 +0200622 wattroff(main_win, A_BOLD);
623 wrefresh(main_win);
Daniel Lezcanodb145802011-06-21 00:57:08 +0200624
Daniel Lezcano372ffba2011-06-21 00:57:08 +0200625 return 0;
Daniel Lezcanodb145802011-06-21 00:57:08 +0200626}
627
628int display_register(int win, struct display_ops *ops)
629{
630 size_t array_size = sizeof(windata) / sizeof(windata[0]);
631
Sanjay Singh Rawat5fef0052013-04-17 15:02:01 +0530632 if (win < 0 || win >= array_size) {
633 printf("error: invalid window");
Daniel Lezcanodb145802011-06-21 00:57:08 +0200634 return -1;
Sanjay Singh Rawat5fef0052013-04-17 15:02:01 +0530635 }
Daniel Lezcanodb145802011-06-21 00:57:08 +0200636
637 windata[win].ops = ops;
638
Daniel Lezcano176e69d2011-06-15 15:45:12 +0200639 return 0;
640}