blob: 9cd3b9dd42f2e38fd850064c0f6dfb90eb35e1c4 [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>
Daniel Lezcano3109e162016-02-19 21:28:23 +000023#include <signal.h>
Daniel Lezcano15627482011-06-15 15:45:12 +020024#include <string.h>
Daniel Lezcano5e659d72016-02-19 20:22:12 +000025#define _GNU_SOURCE
26#include <strings.h>
27#undef _GNU_SOURCE
Daniel Lezcano15627482011-06-15 15:45:12 +020028#include <stdlib.h>
Daniel Lezcanoa12163d2011-06-21 00:57:08 +020029#include <ctype.h>
Daniel Lezcano15627482011-06-15 15:45:12 +020030#include <ncurses.h>
Daniel Lezcano5000abd2011-06-21 00:57:08 +020031#include <sys/types.h>
32#include <regex.h>
Amit Arora47fd9182010-08-24 13:26:06 +053033#include "powerdebug.h"
Daniel Lezcanodb145802011-06-21 00:57:08 +020034#include "mainloop.h"
Amit Aroraed3e5652010-10-27 12:02:53 +053035#include "display.h"
Amit Arora47fd9182010-08-24 13:26:06 +053036
Daniel Lezcanoeeb13762011-03-26 22:06:17 +010037enum { PT_COLOR_DEFAULT = 1,
38 PT_COLOR_HEADER_BAR,
39 PT_COLOR_ERROR,
40 PT_COLOR_RED,
41 PT_COLOR_YELLOW,
42 PT_COLOR_GREEN,
43 PT_COLOR_BRIGHT,
44 PT_COLOR_BLUE,
45};
46
Amit Arora47fd9182010-08-24 13:26:06 +053047static WINDOW *header_win;
Amit Arora47fd9182010-08-24 13:26:06 +053048static WINDOW *footer_win;
Daniel Lezcanoc196d432011-06-21 00:57:08 +020049static WINDOW *main_win;
Daniel Lezcanod96731a2011-06-15 15:45:12 +020050static int current_win;
Amit Arora47fd9182010-08-24 13:26:06 +053051
Daniel Lezcano2adc48d2011-06-08 23:30:01 +020052/* Number of lines in the virtual window */
53static const int maxrows = 1024;
54
Daniel Lezcano2adc48d2011-06-08 23:30:01 +020055struct rowdata {
56 int attr;
57 void *data;
58};
59
Daniel Lezcanob3e6e812011-06-15 15:45:12 +020060struct windata {
Daniel Lezcanof6656822011-06-15 15:45:12 +020061 WINDOW *pad;
Daniel Lezcanob301b082011-06-15 15:45:12 +020062 struct display_ops *ops;
Daniel Lezcanob3e6e812011-06-15 15:45:12 +020063 struct rowdata *rowdata;
64 char *name;
65 int nrdata;
66 int scrolling;
67 int cursor;
68};
69
Daniel Lezcano4120e262011-06-15 15:45:12 +020070/* Warning this is linked with the enum { CLOCK, REGULATOR, ... } */
Daniel Lezcano176e69d2011-06-15 15:45:12 +020071struct windata windata[] = {
Daniel Lezcano4120e262011-06-15 15:45:12 +020072 [CLOCK] = { .name = "Clocks" },
73 [REGULATOR] = { .name = "Regulators" },
74 [SENSOR] = { .name = "Sensors" },
Daniel Lezcano269de4f2011-08-25 15:46:13 +020075 [GPIO] = { .name = "Gpio" },
Thara Gopinath9cee8a52017-07-14 13:25:18 -040076 [GENPD] = { .name = "Powerdomains" },
Daniel Lezcanob3e6e812011-06-15 15:45:12 +020077};
Daniel Lezcano2adc48d2011-06-08 23:30:01 +020078
Daniel Lezcano3abd8b12011-03-26 22:06:15 +010079static void display_fini(void)
80{
81 endwin();
82}
83
Daniel Lezcano653cb4a2011-06-21 00:57:08 +020084static int display_show_header(int win)
Daniel Lezcano7b3da502011-06-15 15:45:12 +020085{
86 int i;
87 int curr_pointer = 0;
Daniel Lezcano4120e262011-06-15 15:45:12 +020088 size_t array_size = sizeof(windata) / sizeof(windata[0]);
Daniel Lezcano7b3da502011-06-15 15:45:12 +020089
90 wattrset(header_win, COLOR_PAIR(PT_COLOR_HEADER_BAR));
91 wbkgd(header_win, COLOR_PAIR(PT_COLOR_HEADER_BAR));
92 werase(header_win);
93
Daniel Lezcanoc757e6d2011-06-21 00:57:08 +020094 mvwprintw(header_win, 0, curr_pointer, "PowerDebug %s", VERSION);
Daniel Lezcano7b3da502011-06-15 15:45:12 +020095 curr_pointer += 20;
96
Daniel Lezcano4120e262011-06-15 15:45:12 +020097 for (i = 0; i < array_size; i++) {
Daniel Lezcano7b3da502011-06-15 15:45:12 +020098 if (win == i)
99 wattron(header_win, A_REVERSE);
100 else
101 wattroff(header_win, A_REVERSE);
102
Daniel Lezcanoc757e6d2011-06-21 00:57:08 +0200103 mvwprintw(header_win, 0, curr_pointer, " %s ", windata[i].name);
Daniel Lezcano7b3da502011-06-15 15:45:12 +0200104 curr_pointer += strlen(windata[i].name) + 2;
105 }
106 wrefresh(header_win);
Daniel Lezcano7b3da502011-06-15 15:45:12 +0200107
Daniel Lezcano653cb4a2011-06-21 00:57:08 +0200108 return 0;
109}
110
111#define footer_label " Q (Quit) R (Refresh) Other Keys: 'Left', " \
112 "'Right' , 'Up', 'Down', 'enter', , 'Esc'"
113
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200114static int display_show_footer(int win, char *string)
Daniel Lezcano653cb4a2011-06-21 00:57:08 +0200115{
116 werase(footer_win);
Daniel Lezcano7b3da502011-06-15 15:45:12 +0200117 wattron(footer_win, A_REVERSE);
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200118 mvwprintw(footer_win, 0, 0, "%s", string ? string : footer_label);
Daniel Lezcano7b3da502011-06-15 15:45:12 +0200119 wattroff(footer_win, A_REVERSE);
120 wrefresh(footer_win);
121
122 return 0;
123}
124
Daniel Lezcanod577aaa2011-06-21 00:57:08 +0200125static int display_refresh(int win, bool read)
Amit Arora47fd9182010-08-24 13:26:06 +0530126{
Daniel Lezcanodb145802011-06-21 00:57:08 +0200127 /* we are trying to refresh a window which is not showed */
128 if (win != current_win)
129 return 0;
Daniel Lezcanof6656822011-06-15 15:45:12 +0200130
Daniel Lezcanodb145802011-06-21 00:57:08 +0200131 if (windata[win].ops && windata[win].ops->display)
Daniel Lezcanod577aaa2011-06-21 00:57:08 +0200132 return windata[win].ops->display(read);
Daniel Lezcano971515a2011-06-15 15:45:12 +0200133
Daniel Lezcanocaafece2011-06-27 22:59:17 +0200134 if (werase(main_win))
135 return -1;
136
137 return wrefresh(main_win);
Daniel Lezcano971515a2011-06-15 15:45:12 +0200138}
139
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200140int display_refresh_pad(int win)
Amit Arora728e0c92010-09-14 12:06:09 +0530141{
Daniel Lezcano0a8cc582011-06-21 00:57:08 +0200142 int maxx, maxy;
143
144 getmaxyx(stdscr, maxy, maxx);
145
Daniel Lezcanof6656822011-06-15 15:45:12 +0200146 return prefresh(windata[win].pad, windata[win].scrolling,
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200147 0, 2, 0, maxy - 2, maxx);
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200148}
Amit Aroraac4e8652010-11-09 11:16:53 +0530149
Sanjay Singh Rawat83b37c32013-04-17 14:57:07 +0530150void sigwinch_handler(int signo)
151{
152 display_refresh(current_win, true);
153}
154
Daniel Lezcano28203df2011-06-15 15:45:12 +0200155static int display_show_unselection(int win, int line, bool bold)
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200156{
Daniel Lezcanof6656822011-06-15 15:45:12 +0200157 if (mvwchgat(windata[win].pad, line, 0, -1,
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200158 bold ? WA_BOLD: WA_NORMAL, 0, NULL) < 0)
159 return -1;
160
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200161 return display_refresh_pad(win);
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200162}
163
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200164void *display_get_row_data(int win)
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200165{
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200166 return windata[win].rowdata[windata[win].cursor].data;
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200167}
168
Daniel Lezcano28203df2011-06-15 15:45:12 +0200169static int display_select(void)
170{
171 if (windata[current_win].ops && windata[current_win].ops->select)
172 return windata[current_win].ops->select();
173
174 return 0;
175}
176
Shaojie Sun8ac4a2e2013-07-29 20:11:46 +0800177static int display_change(int keyvalue)
178{
179 if (!(windata[current_win].nrdata))
180 return 0;
181
182 if (windata[current_win].ops && windata[current_win].ops->change)
183 return windata[current_win].ops->change(keyvalue);
184
185 return 0;
186}
187
Daniel Lezcano28203df2011-06-15 15:45:12 +0200188static int display_next_panel(void)
189{
190 size_t array_size = sizeof(windata) / sizeof(windata[0]);
191
192 current_win++;
193 current_win %= array_size;
194
195 return current_win;
196}
197
198static int display_prev_panel(void)
199{
200 size_t array_size = sizeof(windata) / sizeof(windata[0]);
201
202 current_win--;
203 if (current_win < 0)
204 current_win = array_size - 1;
205
206 return current_win;
207}
208
209static int display_next_line(void)
210{
Daniel Lezcano83b28d02016-02-18 13:49:55 +0000211 int maxy;
Daniel Lezcano28203df2011-06-15 15:45:12 +0200212 int cursor = windata[current_win].cursor;
213 int nrdata = windata[current_win].nrdata;
214 int scrolling = windata[current_win].scrolling;
215 struct rowdata *rowdata = windata[current_win].rowdata;
216
Daniel Lezcano83b28d02016-02-18 13:49:55 +0000217 maxy = getmaxy(stdscr);
Daniel Lezcano0a8cc582011-06-21 00:57:08 +0200218
Daniel Lezcano28203df2011-06-15 15:45:12 +0200219 if (cursor >= nrdata)
220 return cursor;
221
222 display_show_unselection(current_win, cursor, rowdata[cursor].attr);
223 if (cursor < nrdata - 1) {
224 if (cursor >= (maxy - 4 + scrolling))
225 scrolling++;
226 cursor++;
227 }
228
229 windata[current_win].scrolling = scrolling;
230 windata[current_win].cursor = cursor;
231
232 return cursor;
233}
234
235static int display_prev_line(void)
236{
237 int cursor = windata[current_win].cursor;
238 int nrdata = windata[current_win].nrdata;
239 int scrolling = windata[current_win].scrolling;
240 struct rowdata *rowdata = windata[current_win].rowdata;
241
242 if (cursor >= nrdata)
243 return cursor;
244
245 display_show_unselection(current_win, cursor, rowdata[cursor].attr);
246 if (cursor > 0) {
247 if (cursor <= scrolling)
248 scrolling--;
249 cursor--;
250 }
251
252 windata[current_win].scrolling = scrolling;
253 windata[current_win].cursor = cursor;
254
255 return cursor;
256}
257
258static int display_set_row_data(int win, int line, void *data, int attr)
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200259{
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200260 struct rowdata *rowdata = windata[win].rowdata;
261
262 if (line >= windata[win].nrdata) {
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200263 rowdata = realloc(rowdata, sizeof(struct rowdata) * (line + 1));
264 if (!rowdata)
265 return -1;
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200266 windata[win].nrdata = line + 1;
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200267 }
268
269 rowdata[line].data = data;
270 rowdata[line].attr = attr;
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200271 windata[win].rowdata = rowdata;
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200272
273 return 0;
274}
275
Daniel Lezcanof6656822011-06-15 15:45:12 +0200276int display_reset_cursor(int win)
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200277{
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200278 windata[win].nrdata = 0;
Daniel Lezcanof6656822011-06-15 15:45:12 +0200279 werase(windata[win].pad);
280 return wmove(windata[win].pad, 0, 0);
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200281}
282
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200283int display_print_line(int win, int line, char *str, int bold, void *data)
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200284{
285 int attr = 0;
286
Amit Arora031263a2010-11-09 11:12:41 +0530287 if (bold)
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200288 attr |= WA_BOLD;
289
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200290 if (line == windata[win].cursor)
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200291 attr |= WA_STANDOUT;
292
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200293 if (display_set_row_data(win, line, data, attr))
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200294 return -1;
295
296 if (attr)
Daniel Lezcanof6656822011-06-15 15:45:12 +0200297 wattron(windata[win].pad, attr);
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200298
Daniel Lezcanof6656822011-06-15 15:45:12 +0200299 wprintw(windata[win].pad, "%s\n", str);
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200300
301 if (attr)
Daniel Lezcanof6656822011-06-15 15:45:12 +0200302 wattroff(windata[win].pad, attr);
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200303
304 return 0;
305}
306
Daniel Lezcanod42d7ad2016-02-22 15:02:57 +0100307int display_print_error(int window, int line, char *str)
308{
309 display_reset_cursor(window);
310 display_print_line(window, line, str, 0, NULL);
311 display_refresh_pad(window);
312
313 return 0;
314}
315
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200316static int display_find_keystroke(int fd, void *data);
317
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200318struct find_data {
319 size_t len;
320 char *string;
321 regex_t *reg;
Daniel Lezcano96a64fb2011-06-21 00:57:08 +0200322 int ocursor;
Daniel Lezcano10c86452011-06-21 00:57:08 +0200323 int oscrolling;
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200324};
325
Daniel Lezcano10c86452011-06-21 00:57:08 +0200326struct find_data *display_find_init(void)
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200327{
328 const char *regexp = "^[a-z|0-9|_|-|.]";
329 struct find_data *findd;
330 const size_t len = 64;
331 regex_t *reg;
332 char *search4;
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200333
334 reg = malloc(sizeof(*reg));
335 if (!reg)
336 return NULL;
337
338 if (regcomp(reg, regexp, REG_ICASE))
339 goto out_free_reg;
340
341 search4 = malloc(len);
342 if (!search4)
343 goto out_free_regcomp;
344 memset(search4, '\0', len);
345
346 findd = malloc(sizeof(*findd));
347 if (!findd)
348 goto out_free_search4;
349
350 findd->string = search4;
351 findd->reg = reg;
352 findd->len = len;
Daniel Lezcano96a64fb2011-06-21 00:57:08 +0200353
354 /* save the location of the cursor on the main window in order to
355 * browse the search result
356 */
357 findd->ocursor = windata[current_win].cursor;
Daniel Lezcano10c86452011-06-21 00:57:08 +0200358 findd->oscrolling = windata[current_win].scrolling;
Daniel Lezcano96a64fb2011-06-21 00:57:08 +0200359
Daniel Lezcano10c86452011-06-21 00:57:08 +0200360 windata[current_win].cursor = 0;
361 windata[current_win].scrolling = 0;
362
363 curs_set(1);
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200364out:
365 return findd;
366
367out_free_search4:
368 free(search4);
369out_free_regcomp:
370 regfree(reg);
371out_free_reg:
372 free(reg);
373
374 goto out;
375}
376
Daniel Lezcano10c86452011-06-21 00:57:08 +0200377static void display_find_fini(struct find_data *findd)
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200378{
Daniel Lezcano10c86452011-06-21 00:57:08 +0200379 windata[current_win].cursor = findd->ocursor;
380 windata[current_win].scrolling = findd->oscrolling;
381 regfree(findd->reg);
382 free(findd->string);
383 free(findd);
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200384 curs_set(0);
385}
386
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200387static int display_switch_to_find(int fd)
388{
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200389 struct find_data *findd;
390
Daniel Lezcano10c86452011-06-21 00:57:08 +0200391 findd = display_find_init();
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200392 if (!findd)
393 return -1;
394
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200395 if (mainloop_del(fd))
396 return -1;
397
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200398 if (mainloop_add(fd, display_find_keystroke, findd))
399 return -1;
400
401 if (display_show_footer(current_win, "find (esc to exit)?"))
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200402 return -1;
403
404 return 0;
405}
406
Daniel Lezcanodb145802011-06-21 00:57:08 +0200407static int display_keystroke(int fd, void *data)
Daniel Lezcano176e69d2011-06-15 15:45:12 +0200408{
Daniel Lezcano176e69d2011-06-15 15:45:12 +0200409 int keystroke = getch();
410
411 switch (keystroke) {
412
413 case KEY_RIGHT:
414 case '\t':
Daniel Lezcano372ffba2011-06-21 00:57:08 +0200415 display_show_header(display_next_panel());
Daniel Lezcano176e69d2011-06-15 15:45:12 +0200416 break;
417
418 case KEY_LEFT:
419 case KEY_BTAB:
Daniel Lezcano372ffba2011-06-21 00:57:08 +0200420 display_show_header(display_prev_panel());
Daniel Lezcano176e69d2011-06-15 15:45:12 +0200421 break;
422
423 case KEY_DOWN:
424 display_next_line();
425 break;
426
427 case KEY_UP:
428 display_prev_line();
429 break;
430
Shaojie Sunb32cbb92013-07-17 16:23:45 +0800431 case '\n':
Daniel Lezcano176e69d2011-06-15 15:45:12 +0200432 case '\r':
433 display_select();
434 break;
435
Shaojie Sun8ac4a2e2013-07-29 20:11:46 +0800436 case 'v':
437 case 'V':
438 case 'd':
439 case 'D':
440 display_change(toupper(keystroke));
441 break;
442
Daniel Lezcano176e69d2011-06-15 15:45:12 +0200443 case EOF:
444 case 'q':
445 case 'Q':
446 return 1;
447
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200448 case '/':
449 return display_switch_to_find(fd);
450
Daniel Lezcano176e69d2011-06-15 15:45:12 +0200451 case 'r':
452 case 'R':
Daniel Lezcanod577aaa2011-06-21 00:57:08 +0200453 return display_refresh(current_win, true);
Daniel Lezcanodb145802011-06-21 00:57:08 +0200454 default:
455 return 0;
Daniel Lezcano176e69d2011-06-15 15:45:12 +0200456 }
457
Daniel Lezcanod577aaa2011-06-21 00:57:08 +0200458 display_refresh(current_win, false);
Daniel Lezcanodb145802011-06-21 00:57:08 +0200459
460 return 0;
461}
462
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200463static int display_switch_to_main(int fd)
464{
465 if (mainloop_del(fd))
466 return -1;
467
468 if (mainloop_add(fd, display_keystroke, NULL))
469 return -1;
470
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200471 if (display_show_header(current_win))
472 return -1;
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200473
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200474 if (display_show_footer(current_win, NULL))
475 return -1;
476
Daniel Lezcanod577aaa2011-06-21 00:57:08 +0200477 return display_refresh(current_win, false);
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200478}
479
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200480static int display_find_keystroke(int fd, void *data)
481{
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200482 struct find_data *findd = data;
483 regex_t *reg = findd->reg;
484 char *string = findd->string;
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200485 int keystroke = getch();
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200486 char match[2] = { [0] = (char)keystroke, [1] = '\0' };
487 regmatch_t m[1];
488
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200489 switch (keystroke) {
490
491 case '\e':
Daniel Lezcano10c86452011-06-21 00:57:08 +0200492 display_find_fini(findd);
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200493 return display_switch_to_main(fd);
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200494
Daniel Lezcanoa12163d2011-06-21 00:57:08 +0200495 case KEY_DOWN:
496 display_next_line();
497 break;
498
499 case KEY_UP:
500 display_prev_line();
501 break;
502
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200503 case KEY_BACKSPACE:
504 if (strlen(string))
505 string[strlen(string) - 1] = '\0';
Daniel Lezcano10c86452011-06-21 00:57:08 +0200506
507 windata[current_win].cursor = 0;
508 windata[current_win].scrolling = 0;
509
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200510 break;
511
Shaojie Sunb32cbb92013-07-17 16:23:45 +0800512 case '\n':
Daniel Lezcano73b40022011-06-21 00:57:08 +0200513 case '\r':
514 if (!windata[current_win].ops || !windata[current_win].ops->selectf)
515 return 0;
516
517 if (windata[current_win].ops->selectf())
518 return -1;
519
Daniel Lezcanoe78bc072011-06-21 10:49:39 +0200520 windata[current_win].cursor = 0;
521 windata[current_win].scrolling = 0;
522
Daniel Lezcano73b40022011-06-21 00:57:08 +0200523 return 0;
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200524
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200525 default:
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200526
527 /* We don't want invalid characters for a name */
528 if (regexec(reg, match, 1, m, 0))
529 return 0;
530
531 if (strlen(string) < findd->len - 1)
532 string[strlen(string)] = (char)keystroke;
533
Daniel Lezcano10c86452011-06-21 00:57:08 +0200534 windata[current_win].cursor = 0;
535 windata[current_win].scrolling = 0;
536
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200537 break;
538 }
539
Daniel Lezcanoa12163d2011-06-21 00:57:08 +0200540 if (!windata[current_win].ops || !windata[current_win].ops->find)
541 return 0;
542
543 if (windata[current_win].ops->find(string))
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200544 return -1;
545
Daniel Lezcanoa12163d2011-06-21 00:57:08 +0200546 if (display_show_header(current_win))
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200547 return -1;
548
549 if (display_show_footer(current_win, strlen(string) ? string :
550 "find (esc to exit)?"))
551 return -1;
552
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200553 return 0;
554}
555
Daniel Lezcano5e659d72016-02-19 20:22:12 +0000556int display_init(struct powerdebug_options *options)
Daniel Lezcanodb145802011-06-21 00:57:08 +0200557{
Daniel Lezcano0a8cc582011-06-21 00:57:08 +0200558 int i, maxx, maxy;
Daniel Lezcanodb145802011-06-21 00:57:08 +0200559 size_t array_size = sizeof(windata) / sizeof(windata[0]);
560
Thara Gopinath1a32ec02017-07-14 13:15:48 -0400561 current_win = (ffs(options->flags & DEFAULT_OPTION) - 1);
Daniel Lezcanodb145802011-06-21 00:57:08 +0200562
Daniel Lezcano3109e162016-02-19 21:28:23 +0000563 signal(SIGWINCH, sigwinch_handler);
564
Daniel Lezcanodb145802011-06-21 00:57:08 +0200565 if (mainloop_add(0, display_keystroke, NULL))
566 return -1;
567
568 if (!initscr())
569 return -1;
570
571 start_color();
572 use_default_colors();
573
574 keypad(stdscr, TRUE);
575 noecho();
576 cbreak();
577 curs_set(0);
578 nonl();
579
Thara Gopinath569054e2017-07-14 13:15:46 -0400580 if (can_change_color()) {
581 if (init_pair(PT_COLOR_DEFAULT, COLOR_WHITE, COLOR_BLACK) ||
582 init_pair(PT_COLOR_ERROR, COLOR_BLACK, COLOR_RED) ||
583 init_pair(PT_COLOR_HEADER_BAR, COLOR_WHITE, COLOR_BLACK) ||
584 init_pair(PT_COLOR_YELLOW, COLOR_WHITE, COLOR_YELLOW) ||
585 init_pair(PT_COLOR_GREEN, COLOR_WHITE, COLOR_GREEN) ||
586 init_pair(PT_COLOR_BRIGHT, COLOR_WHITE, COLOR_BLACK) ||
587 init_pair(PT_COLOR_BLUE, COLOR_WHITE, COLOR_BLUE) ||
588 init_pair(PT_COLOR_RED, COLOR_WHITE, COLOR_RED))
589 return -1;
590 }
Daniel Lezcanodb145802011-06-21 00:57:08 +0200591
592 if (atexit(display_fini))
593 return -1;
594
595 getmaxyx(stdscr, maxy, maxx);
596
597 for (i = 0; i < array_size; i++) {
598
Daniel Lezcanoc196d432011-06-21 00:57:08 +0200599 main_win = subwin(stdscr, maxy - 2, maxx, 1, 0);
600 if (!main_win)
Daniel Lezcanodb145802011-06-21 00:57:08 +0200601 return -1;
602
603 windata[i].pad = newpad(maxrows, maxx);
604 if (!windata[i].pad)
605 return -1;
606
607 }
608
609 header_win = subwin(stdscr, 1, maxx, 0, 0);
610 if (!header_win)
611 return -1;
612
613 footer_win = subwin(stdscr, 1, maxx, maxy-1, 0);
614 if (!footer_win)
615 return -1;
616
Daniel Lezcano5e659d72016-02-19 20:22:12 +0000617 if (display_show_header(current_win))
Daniel Lezcano653cb4a2011-06-21 00:57:08 +0200618 return -1;
619
Daniel Lezcano5e659d72016-02-19 20:22:12 +0000620 if (display_show_footer(current_win, NULL))
Daniel Lezcanodb145802011-06-21 00:57:08 +0200621 return -1;
622
Daniel Lezcano5e659d72016-02-19 20:22:12 +0000623 return display_refresh(current_win, true);
Daniel Lezcanodb145802011-06-21 00:57:08 +0200624}
625
Daniel Lezcano372ffba2011-06-21 00:57:08 +0200626int display_column_name(const char *line)
Daniel Lezcanodb145802011-06-21 00:57:08 +0200627{
Daniel Lezcanoc196d432011-06-21 00:57:08 +0200628 werase(main_win);
629 wattron(main_win, A_BOLD);
Daniel Lezcanofa453332011-06-21 00:57:08 +0200630 mvwprintw(main_win, 0, 0, "%s", line);
Daniel Lezcanoc196d432011-06-21 00:57:08 +0200631 wattroff(main_win, A_BOLD);
632 wrefresh(main_win);
Daniel Lezcanodb145802011-06-21 00:57:08 +0200633
Daniel Lezcano372ffba2011-06-21 00:57:08 +0200634 return 0;
Daniel Lezcanodb145802011-06-21 00:57:08 +0200635}
636
637int display_register(int win, struct display_ops *ops)
638{
639 size_t array_size = sizeof(windata) / sizeof(windata[0]);
640
Sanjay Singh Rawat5fef0052013-04-17 15:02:01 +0530641 if (win < 0 || win >= array_size) {
642 printf("error: invalid window");
Daniel Lezcanodb145802011-06-21 00:57:08 +0200643 return -1;
Sanjay Singh Rawat5fef0052013-04-17 15:02:01 +0530644 }
Daniel Lezcanodb145802011-06-21 00:57:08 +0200645
646 windata[win].ops = ops;
647
Daniel Lezcano176e69d2011-06-15 15:45:12 +0200648 return 0;
649}