blob: 5665ed53741c5463efd555b06c6b92271e336f2a [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" },
Daniel Lezcanob3e6e812011-06-15 15:45:12 +020076};
Daniel Lezcano2adc48d2011-06-08 23:30:01 +020077
Daniel Lezcano3abd8b12011-03-26 22:06:15 +010078static void display_fini(void)
79{
80 endwin();
81}
82
Daniel Lezcano653cb4a2011-06-21 00:57:08 +020083static int display_show_header(int win)
Daniel Lezcano7b3da502011-06-15 15:45:12 +020084{
85 int i;
86 int curr_pointer = 0;
Daniel Lezcano4120e262011-06-15 15:45:12 +020087 size_t array_size = sizeof(windata) / sizeof(windata[0]);
Daniel Lezcano7b3da502011-06-15 15:45:12 +020088
89 wattrset(header_win, COLOR_PAIR(PT_COLOR_HEADER_BAR));
90 wbkgd(header_win, COLOR_PAIR(PT_COLOR_HEADER_BAR));
91 werase(header_win);
92
Daniel Lezcanoc757e6d2011-06-21 00:57:08 +020093 mvwprintw(header_win, 0, curr_pointer, "PowerDebug %s", VERSION);
Daniel Lezcano7b3da502011-06-15 15:45:12 +020094 curr_pointer += 20;
95
Daniel Lezcano4120e262011-06-15 15:45:12 +020096 for (i = 0; i < array_size; i++) {
Daniel Lezcano7b3da502011-06-15 15:45:12 +020097 if (win == i)
98 wattron(header_win, A_REVERSE);
99 else
100 wattroff(header_win, A_REVERSE);
101
Daniel Lezcanoc757e6d2011-06-21 00:57:08 +0200102 mvwprintw(header_win, 0, curr_pointer, " %s ", windata[i].name);
Daniel Lezcano7b3da502011-06-15 15:45:12 +0200103 curr_pointer += strlen(windata[i].name) + 2;
104 }
105 wrefresh(header_win);
Daniel Lezcano7b3da502011-06-15 15:45:12 +0200106
Daniel Lezcano653cb4a2011-06-21 00:57:08 +0200107 return 0;
108}
109
110#define footer_label " Q (Quit) R (Refresh) Other Keys: 'Left', " \
111 "'Right' , 'Up', 'Down', 'enter', , 'Esc'"
112
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200113static int display_show_footer(int win, char *string)
Daniel Lezcano653cb4a2011-06-21 00:57:08 +0200114{
115 werase(footer_win);
Daniel Lezcano7b3da502011-06-15 15:45:12 +0200116 wattron(footer_win, A_REVERSE);
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200117 mvwprintw(footer_win, 0, 0, "%s", string ? string : footer_label);
Daniel Lezcano7b3da502011-06-15 15:45:12 +0200118 wattroff(footer_win, A_REVERSE);
119 wrefresh(footer_win);
120
121 return 0;
122}
123
Daniel Lezcanod577aaa2011-06-21 00:57:08 +0200124static int display_refresh(int win, bool read)
Amit Arora47fd9182010-08-24 13:26:06 +0530125{
Daniel Lezcanodb145802011-06-21 00:57:08 +0200126 /* we are trying to refresh a window which is not showed */
127 if (win != current_win)
128 return 0;
Daniel Lezcanof6656822011-06-15 15:45:12 +0200129
Daniel Lezcanodb145802011-06-21 00:57:08 +0200130 if (windata[win].ops && windata[win].ops->display)
Daniel Lezcanod577aaa2011-06-21 00:57:08 +0200131 return windata[win].ops->display(read);
Daniel Lezcano971515a2011-06-15 15:45:12 +0200132
Daniel Lezcanocaafece2011-06-27 22:59:17 +0200133 if (werase(main_win))
134 return -1;
135
136 return wrefresh(main_win);
Daniel Lezcano971515a2011-06-15 15:45:12 +0200137}
138
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200139int display_refresh_pad(int win)
Amit Arora728e0c92010-09-14 12:06:09 +0530140{
Daniel Lezcano0a8cc582011-06-21 00:57:08 +0200141 int maxx, maxy;
142
143 getmaxyx(stdscr, maxy, maxx);
144
Daniel Lezcanof6656822011-06-15 15:45:12 +0200145 return prefresh(windata[win].pad, windata[win].scrolling,
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200146 0, 2, 0, maxy - 2, maxx);
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200147}
Amit Aroraac4e8652010-11-09 11:16:53 +0530148
Sanjay Singh Rawat83b37c32013-04-17 14:57:07 +0530149void sigwinch_handler(int signo)
150{
151 display_refresh(current_win, true);
152}
153
Daniel Lezcano28203df2011-06-15 15:45:12 +0200154static int display_show_unselection(int win, int line, bool bold)
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200155{
Daniel Lezcanof6656822011-06-15 15:45:12 +0200156 if (mvwchgat(windata[win].pad, line, 0, -1,
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200157 bold ? WA_BOLD: WA_NORMAL, 0, NULL) < 0)
158 return -1;
159
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200160 return display_refresh_pad(win);
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200161}
162
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200163void *display_get_row_data(int win)
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200164{
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200165 return windata[win].rowdata[windata[win].cursor].data;
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200166}
167
Daniel Lezcano28203df2011-06-15 15:45:12 +0200168static int display_select(void)
169{
170 if (windata[current_win].ops && windata[current_win].ops->select)
171 return windata[current_win].ops->select();
172
173 return 0;
174}
175
Shaojie Sun8ac4a2e2013-07-29 20:11:46 +0800176static int display_change(int keyvalue)
177{
178 if (!(windata[current_win].nrdata))
179 return 0;
180
181 if (windata[current_win].ops && windata[current_win].ops->change)
182 return windata[current_win].ops->change(keyvalue);
183
184 return 0;
185}
186
Daniel Lezcano28203df2011-06-15 15:45:12 +0200187static int display_next_panel(void)
188{
189 size_t array_size = sizeof(windata) / sizeof(windata[0]);
190
191 current_win++;
192 current_win %= array_size;
193
194 return current_win;
195}
196
197static int display_prev_panel(void)
198{
199 size_t array_size = sizeof(windata) / sizeof(windata[0]);
200
201 current_win--;
202 if (current_win < 0)
203 current_win = array_size - 1;
204
205 return current_win;
206}
207
208static int display_next_line(void)
209{
Daniel Lezcano83b28d02016-02-18 13:49:55 +0000210 int maxy;
Daniel Lezcano28203df2011-06-15 15:45:12 +0200211 int cursor = windata[current_win].cursor;
212 int nrdata = windata[current_win].nrdata;
213 int scrolling = windata[current_win].scrolling;
214 struct rowdata *rowdata = windata[current_win].rowdata;
215
Daniel Lezcano83b28d02016-02-18 13:49:55 +0000216 maxy = getmaxy(stdscr);
Daniel Lezcano0a8cc582011-06-21 00:57:08 +0200217
Daniel Lezcano28203df2011-06-15 15:45:12 +0200218 if (cursor >= nrdata)
219 return cursor;
220
221 display_show_unselection(current_win, cursor, rowdata[cursor].attr);
222 if (cursor < nrdata - 1) {
223 if (cursor >= (maxy - 4 + scrolling))
224 scrolling++;
225 cursor++;
226 }
227
228 windata[current_win].scrolling = scrolling;
229 windata[current_win].cursor = cursor;
230
231 return cursor;
232}
233
234static int display_prev_line(void)
235{
236 int cursor = windata[current_win].cursor;
237 int nrdata = windata[current_win].nrdata;
238 int scrolling = windata[current_win].scrolling;
239 struct rowdata *rowdata = windata[current_win].rowdata;
240
241 if (cursor >= nrdata)
242 return cursor;
243
244 display_show_unselection(current_win, cursor, rowdata[cursor].attr);
245 if (cursor > 0) {
246 if (cursor <= scrolling)
247 scrolling--;
248 cursor--;
249 }
250
251 windata[current_win].scrolling = scrolling;
252 windata[current_win].cursor = cursor;
253
254 return cursor;
255}
256
257static int display_set_row_data(int win, int line, void *data, int attr)
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200258{
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200259 struct rowdata *rowdata = windata[win].rowdata;
260
261 if (line >= windata[win].nrdata) {
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200262 rowdata = realloc(rowdata, sizeof(struct rowdata) * (line + 1));
263 if (!rowdata)
264 return -1;
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200265 windata[win].nrdata = line + 1;
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200266 }
267
268 rowdata[line].data = data;
269 rowdata[line].attr = attr;
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200270 windata[win].rowdata = rowdata;
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200271
272 return 0;
273}
274
Daniel Lezcanof6656822011-06-15 15:45:12 +0200275int display_reset_cursor(int win)
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200276{
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200277 windata[win].nrdata = 0;
Daniel Lezcanof6656822011-06-15 15:45:12 +0200278 werase(windata[win].pad);
279 return wmove(windata[win].pad, 0, 0);
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200280}
281
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200282int display_print_line(int win, int line, char *str, int bold, void *data)
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200283{
284 int attr = 0;
285
Amit Arora031263a2010-11-09 11:12:41 +0530286 if (bold)
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200287 attr |= WA_BOLD;
288
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200289 if (line == windata[win].cursor)
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200290 attr |= WA_STANDOUT;
291
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200292 if (display_set_row_data(win, line, data, attr))
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200293 return -1;
294
295 if (attr)
Daniel Lezcanof6656822011-06-15 15:45:12 +0200296 wattron(windata[win].pad, attr);
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200297
Daniel Lezcanof6656822011-06-15 15:45:12 +0200298 wprintw(windata[win].pad, "%s\n", str);
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200299
300 if (attr)
Daniel Lezcanof6656822011-06-15 15:45:12 +0200301 wattroff(windata[win].pad, attr);
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200302
303 return 0;
304}
305
Daniel Lezcanod42d7ad2016-02-22 15:02:57 +0100306int display_print_error(int window, int line, char *str)
307{
308 display_reset_cursor(window);
309 display_print_line(window, line, str, 0, NULL);
310 display_refresh_pad(window);
311
312 return 0;
313}
314
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200315static int display_find_keystroke(int fd, void *data);
316
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200317struct find_data {
318 size_t len;
319 char *string;
320 regex_t *reg;
Daniel Lezcano96a64fb2011-06-21 00:57:08 +0200321 int ocursor;
Daniel Lezcano10c86452011-06-21 00:57:08 +0200322 int oscrolling;
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200323};
324
Daniel Lezcano10c86452011-06-21 00:57:08 +0200325struct find_data *display_find_init(void)
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200326{
327 const char *regexp = "^[a-z|0-9|_|-|.]";
328 struct find_data *findd;
329 const size_t len = 64;
330 regex_t *reg;
331 char *search4;
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200332
333 reg = malloc(sizeof(*reg));
334 if (!reg)
335 return NULL;
336
337 if (regcomp(reg, regexp, REG_ICASE))
338 goto out_free_reg;
339
340 search4 = malloc(len);
341 if (!search4)
342 goto out_free_regcomp;
343 memset(search4, '\0', len);
344
345 findd = malloc(sizeof(*findd));
346 if (!findd)
347 goto out_free_search4;
348
349 findd->string = search4;
350 findd->reg = reg;
351 findd->len = len;
Daniel Lezcano96a64fb2011-06-21 00:57:08 +0200352
353 /* save the location of the cursor on the main window in order to
354 * browse the search result
355 */
356 findd->ocursor = windata[current_win].cursor;
Daniel Lezcano10c86452011-06-21 00:57:08 +0200357 findd->oscrolling = windata[current_win].scrolling;
Daniel Lezcano96a64fb2011-06-21 00:57:08 +0200358
Daniel Lezcano10c86452011-06-21 00:57:08 +0200359 windata[current_win].cursor = 0;
360 windata[current_win].scrolling = 0;
361
362 curs_set(1);
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200363out:
364 return findd;
365
366out_free_search4:
367 free(search4);
368out_free_regcomp:
369 regfree(reg);
370out_free_reg:
371 free(reg);
372
373 goto out;
374}
375
Daniel Lezcano10c86452011-06-21 00:57:08 +0200376static void display_find_fini(struct find_data *findd)
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200377{
Daniel Lezcano10c86452011-06-21 00:57:08 +0200378 windata[current_win].cursor = findd->ocursor;
379 windata[current_win].scrolling = findd->oscrolling;
380 regfree(findd->reg);
381 free(findd->string);
382 free(findd);
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200383 curs_set(0);
384}
385
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200386static int display_switch_to_find(int fd)
387{
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200388 struct find_data *findd;
389
Daniel Lezcano10c86452011-06-21 00:57:08 +0200390 findd = display_find_init();
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200391 if (!findd)
392 return -1;
393
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200394 if (mainloop_del(fd))
395 return -1;
396
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200397 if (mainloop_add(fd, display_find_keystroke, findd))
398 return -1;
399
400 if (display_show_footer(current_win, "find (esc to exit)?"))
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200401 return -1;
402
403 return 0;
404}
405
Daniel Lezcanodb145802011-06-21 00:57:08 +0200406static int display_keystroke(int fd, void *data)
Daniel Lezcano176e69d2011-06-15 15:45:12 +0200407{
Daniel Lezcano176e69d2011-06-15 15:45:12 +0200408 int keystroke = getch();
409
410 switch (keystroke) {
411
412 case KEY_RIGHT:
413 case '\t':
Daniel Lezcano372ffba2011-06-21 00:57:08 +0200414 display_show_header(display_next_panel());
Daniel Lezcano176e69d2011-06-15 15:45:12 +0200415 break;
416
417 case KEY_LEFT:
418 case KEY_BTAB:
Daniel Lezcano372ffba2011-06-21 00:57:08 +0200419 display_show_header(display_prev_panel());
Daniel Lezcano176e69d2011-06-15 15:45:12 +0200420 break;
421
422 case KEY_DOWN:
423 display_next_line();
424 break;
425
426 case KEY_UP:
427 display_prev_line();
428 break;
429
Shaojie Sunb32cbb92013-07-17 16:23:45 +0800430 case '\n':
Daniel Lezcano176e69d2011-06-15 15:45:12 +0200431 case '\r':
432 display_select();
433 break;
434
Shaojie Sun8ac4a2e2013-07-29 20:11:46 +0800435 case 'v':
436 case 'V':
437 case 'd':
438 case 'D':
439 display_change(toupper(keystroke));
440 break;
441
Daniel Lezcano176e69d2011-06-15 15:45:12 +0200442 case EOF:
443 case 'q':
444 case 'Q':
445 return 1;
446
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200447 case '/':
448 return display_switch_to_find(fd);
449
Daniel Lezcano176e69d2011-06-15 15:45:12 +0200450 case 'r':
451 case 'R':
Daniel Lezcanod577aaa2011-06-21 00:57:08 +0200452 return display_refresh(current_win, true);
Daniel Lezcanodb145802011-06-21 00:57:08 +0200453 default:
454 return 0;
Daniel Lezcano176e69d2011-06-15 15:45:12 +0200455 }
456
Daniel Lezcanod577aaa2011-06-21 00:57:08 +0200457 display_refresh(current_win, false);
Daniel Lezcanodb145802011-06-21 00:57:08 +0200458
459 return 0;
460}
461
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200462static int display_switch_to_main(int fd)
463{
464 if (mainloop_del(fd))
465 return -1;
466
467 if (mainloop_add(fd, display_keystroke, NULL))
468 return -1;
469
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200470 if (display_show_header(current_win))
471 return -1;
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200472
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200473 if (display_show_footer(current_win, NULL))
474 return -1;
475
Daniel Lezcanod577aaa2011-06-21 00:57:08 +0200476 return display_refresh(current_win, false);
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200477}
478
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200479static int display_find_keystroke(int fd, void *data)
480{
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200481 struct find_data *findd = data;
482 regex_t *reg = findd->reg;
483 char *string = findd->string;
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200484 int keystroke = getch();
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200485 char match[2] = { [0] = (char)keystroke, [1] = '\0' };
486 regmatch_t m[1];
487
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200488 switch (keystroke) {
489
490 case '\e':
Daniel Lezcano10c86452011-06-21 00:57:08 +0200491 display_find_fini(findd);
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200492 return display_switch_to_main(fd);
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200493
Daniel Lezcanoa12163d2011-06-21 00:57:08 +0200494 case KEY_DOWN:
495 display_next_line();
496 break;
497
498 case KEY_UP:
499 display_prev_line();
500 break;
501
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200502 case KEY_BACKSPACE:
503 if (strlen(string))
504 string[strlen(string) - 1] = '\0';
Daniel Lezcano10c86452011-06-21 00:57:08 +0200505
506 windata[current_win].cursor = 0;
507 windata[current_win].scrolling = 0;
508
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200509 break;
510
Shaojie Sunb32cbb92013-07-17 16:23:45 +0800511 case '\n':
Daniel Lezcano73b40022011-06-21 00:57:08 +0200512 case '\r':
513 if (!windata[current_win].ops || !windata[current_win].ops->selectf)
514 return 0;
515
516 if (windata[current_win].ops->selectf())
517 return -1;
518
Daniel Lezcanoe78bc072011-06-21 10:49:39 +0200519 windata[current_win].cursor = 0;
520 windata[current_win].scrolling = 0;
521
Daniel Lezcano73b40022011-06-21 00:57:08 +0200522 return 0;
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200523
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200524 default:
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200525
526 /* We don't want invalid characters for a name */
527 if (regexec(reg, match, 1, m, 0))
528 return 0;
529
530 if (strlen(string) < findd->len - 1)
531 string[strlen(string)] = (char)keystroke;
532
Daniel Lezcano10c86452011-06-21 00:57:08 +0200533 windata[current_win].cursor = 0;
534 windata[current_win].scrolling = 0;
535
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200536 break;
537 }
538
Daniel Lezcanoa12163d2011-06-21 00:57:08 +0200539 if (!windata[current_win].ops || !windata[current_win].ops->find)
540 return 0;
541
542 if (windata[current_win].ops->find(string))
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200543 return -1;
544
Daniel Lezcanoa12163d2011-06-21 00:57:08 +0200545 if (display_show_header(current_win))
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200546 return -1;
547
548 if (display_show_footer(current_win, strlen(string) ? string :
549 "find (esc to exit)?"))
550 return -1;
551
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200552 return 0;
553}
554
Daniel Lezcano5e659d72016-02-19 20:22:12 +0000555int display_init(struct powerdebug_options *options)
Daniel Lezcanodb145802011-06-21 00:57:08 +0200556{
Daniel Lezcano0a8cc582011-06-21 00:57:08 +0200557 int i, maxx, maxy;
Daniel Lezcanodb145802011-06-21 00:57:08 +0200558 size_t array_size = sizeof(windata) / sizeof(windata[0]);
559
Thara Gopinath1a32ec02017-07-14 13:15:48 -0400560 current_win = (ffs(options->flags & DEFAULT_OPTION) - 1);
Daniel Lezcanodb145802011-06-21 00:57:08 +0200561
Daniel Lezcano3109e162016-02-19 21:28:23 +0000562 signal(SIGWINCH, sigwinch_handler);
563
Daniel Lezcanodb145802011-06-21 00:57:08 +0200564 if (mainloop_add(0, display_keystroke, NULL))
565 return -1;
566
567 if (!initscr())
568 return -1;
569
570 start_color();
571 use_default_colors();
572
573 keypad(stdscr, TRUE);
574 noecho();
575 cbreak();
576 curs_set(0);
577 nonl();
578
Thara Gopinath569054e2017-07-14 13:15:46 -0400579 if (can_change_color()) {
580 if (init_pair(PT_COLOR_DEFAULT, COLOR_WHITE, COLOR_BLACK) ||
581 init_pair(PT_COLOR_ERROR, COLOR_BLACK, COLOR_RED) ||
582 init_pair(PT_COLOR_HEADER_BAR, COLOR_WHITE, COLOR_BLACK) ||
583 init_pair(PT_COLOR_YELLOW, COLOR_WHITE, COLOR_YELLOW) ||
584 init_pair(PT_COLOR_GREEN, COLOR_WHITE, COLOR_GREEN) ||
585 init_pair(PT_COLOR_BRIGHT, COLOR_WHITE, COLOR_BLACK) ||
586 init_pair(PT_COLOR_BLUE, COLOR_WHITE, COLOR_BLUE) ||
587 init_pair(PT_COLOR_RED, COLOR_WHITE, COLOR_RED))
588 return -1;
589 }
Daniel Lezcanodb145802011-06-21 00:57:08 +0200590
591 if (atexit(display_fini))
592 return -1;
593
594 getmaxyx(stdscr, maxy, maxx);
595
596 for (i = 0; i < array_size; i++) {
597
Daniel Lezcanoc196d432011-06-21 00:57:08 +0200598 main_win = subwin(stdscr, maxy - 2, maxx, 1, 0);
599 if (!main_win)
Daniel Lezcanodb145802011-06-21 00:57:08 +0200600 return -1;
601
602 windata[i].pad = newpad(maxrows, maxx);
603 if (!windata[i].pad)
604 return -1;
605
606 }
607
608 header_win = subwin(stdscr, 1, maxx, 0, 0);
609 if (!header_win)
610 return -1;
611
612 footer_win = subwin(stdscr, 1, maxx, maxy-1, 0);
613 if (!footer_win)
614 return -1;
615
Daniel Lezcano5e659d72016-02-19 20:22:12 +0000616 if (display_show_header(current_win))
Daniel Lezcano653cb4a2011-06-21 00:57:08 +0200617 return -1;
618
Daniel Lezcano5e659d72016-02-19 20:22:12 +0000619 if (display_show_footer(current_win, NULL))
Daniel Lezcanodb145802011-06-21 00:57:08 +0200620 return -1;
621
Daniel Lezcano5e659d72016-02-19 20:22:12 +0000622 return display_refresh(current_win, true);
Daniel Lezcanodb145802011-06-21 00:57:08 +0200623}
624
Daniel Lezcano372ffba2011-06-21 00:57:08 +0200625int display_column_name(const char *line)
Daniel Lezcanodb145802011-06-21 00:57:08 +0200626{
Daniel Lezcanoc196d432011-06-21 00:57:08 +0200627 werase(main_win);
628 wattron(main_win, A_BOLD);
Daniel Lezcanofa453332011-06-21 00:57:08 +0200629 mvwprintw(main_win, 0, 0, "%s", line);
Daniel Lezcanoc196d432011-06-21 00:57:08 +0200630 wattroff(main_win, A_BOLD);
631 wrefresh(main_win);
Daniel Lezcanodb145802011-06-21 00:57:08 +0200632
Daniel Lezcano372ffba2011-06-21 00:57:08 +0200633 return 0;
Daniel Lezcanodb145802011-06-21 00:57:08 +0200634}
635
636int display_register(int win, struct display_ops *ops)
637{
638 size_t array_size = sizeof(windata) / sizeof(windata[0]);
639
Sanjay Singh Rawat5fef0052013-04-17 15:02:01 +0530640 if (win < 0 || win >= array_size) {
641 printf("error: invalid window");
Daniel Lezcanodb145802011-06-21 00:57:08 +0200642 return -1;
Sanjay Singh Rawat5fef0052013-04-17 15:02:01 +0530643 }
Daniel Lezcanodb145802011-06-21 00:57:08 +0200644
645 windata[win].ops = ops;
646
Daniel Lezcano176e69d2011-06-15 15:45:12 +0200647 return 0;
648}