blob: eada839cdc22fb28690313f83ba9c15072c63ac7 [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>
Daniel Lezcano5e659d72016-02-19 20:22:12 +000024#define _GNU_SOURCE
25#include <strings.h>
26#undef _GNU_SOURCE
Daniel Lezcano15627482011-06-15 15:45:12 +020027#include <stdlib.h>
Daniel Lezcanoa12163d2011-06-21 00:57:08 +020028#include <ctype.h>
Daniel Lezcano15627482011-06-15 15:45:12 +020029#include <ncurses.h>
Daniel Lezcano5000abd2011-06-21 00:57:08 +020030#include <sys/types.h>
31#include <regex.h>
Amit Arora47fd9182010-08-24 13:26:06 +053032#include "powerdebug.h"
Daniel Lezcanodb145802011-06-21 00:57:08 +020033#include "mainloop.h"
Amit Aroraed3e5652010-10-27 12:02:53 +053034#include "display.h"
Amit Arora47fd9182010-08-24 13:26:06 +053035
Daniel Lezcanoeeb13762011-03-26 22:06:17 +010036enum { PT_COLOR_DEFAULT = 1,
37 PT_COLOR_HEADER_BAR,
38 PT_COLOR_ERROR,
39 PT_COLOR_RED,
40 PT_COLOR_YELLOW,
41 PT_COLOR_GREEN,
42 PT_COLOR_BRIGHT,
43 PT_COLOR_BLUE,
44};
45
Amit Arora47fd9182010-08-24 13:26:06 +053046static WINDOW *header_win;
Amit Arora47fd9182010-08-24 13:26:06 +053047static WINDOW *footer_win;
Daniel Lezcanoc196d432011-06-21 00:57:08 +020048static WINDOW *main_win;
Daniel Lezcanod96731a2011-06-15 15:45:12 +020049static int current_win;
Amit Arora47fd9182010-08-24 13:26:06 +053050
Daniel Lezcano2adc48d2011-06-08 23:30:01 +020051/* Number of lines in the virtual window */
52static const int maxrows = 1024;
53
Daniel Lezcano2adc48d2011-06-08 23:30:01 +020054struct rowdata {
55 int attr;
56 void *data;
57};
58
Daniel Lezcanob3e6e812011-06-15 15:45:12 +020059struct windata {
Daniel Lezcanof6656822011-06-15 15:45:12 +020060 WINDOW *pad;
Daniel Lezcanob301b082011-06-15 15:45:12 +020061 struct display_ops *ops;
Daniel Lezcanob3e6e812011-06-15 15:45:12 +020062 struct rowdata *rowdata;
63 char *name;
64 int nrdata;
65 int scrolling;
66 int cursor;
67};
68
Daniel Lezcano4120e262011-06-15 15:45:12 +020069/* Warning this is linked with the enum { CLOCK, REGULATOR, ... } */
Daniel Lezcano176e69d2011-06-15 15:45:12 +020070struct windata windata[] = {
Daniel Lezcano4120e262011-06-15 15:45:12 +020071 [CLOCK] = { .name = "Clocks" },
72 [REGULATOR] = { .name = "Regulators" },
73 [SENSOR] = { .name = "Sensors" },
Daniel Lezcano269de4f2011-08-25 15:46:13 +020074 [GPIO] = { .name = "Gpio" },
Daniel Lezcanob3e6e812011-06-15 15:45:12 +020075};
Daniel Lezcano2adc48d2011-06-08 23:30:01 +020076
Daniel Lezcano3abd8b12011-03-26 22:06:15 +010077static void display_fini(void)
78{
79 endwin();
80}
81
Daniel Lezcano653cb4a2011-06-21 00:57:08 +020082static int display_show_header(int win)
Daniel Lezcano7b3da502011-06-15 15:45:12 +020083{
84 int i;
85 int curr_pointer = 0;
Daniel Lezcano4120e262011-06-15 15:45:12 +020086 size_t array_size = sizeof(windata) / sizeof(windata[0]);
Daniel Lezcano7b3da502011-06-15 15:45:12 +020087
88 wattrset(header_win, COLOR_PAIR(PT_COLOR_HEADER_BAR));
89 wbkgd(header_win, COLOR_PAIR(PT_COLOR_HEADER_BAR));
90 werase(header_win);
91
Daniel Lezcanoc757e6d2011-06-21 00:57:08 +020092 mvwprintw(header_win, 0, curr_pointer, "PowerDebug %s", VERSION);
Daniel Lezcano7b3da502011-06-15 15:45:12 +020093 curr_pointer += 20;
94
Daniel Lezcano4120e262011-06-15 15:45:12 +020095 for (i = 0; i < array_size; i++) {
Daniel Lezcano7b3da502011-06-15 15:45:12 +020096 if (win == i)
97 wattron(header_win, A_REVERSE);
98 else
99 wattroff(header_win, A_REVERSE);
100
Daniel Lezcanoc757e6d2011-06-21 00:57:08 +0200101 mvwprintw(header_win, 0, curr_pointer, " %s ", windata[i].name);
Daniel Lezcano7b3da502011-06-15 15:45:12 +0200102 curr_pointer += strlen(windata[i].name) + 2;
103 }
104 wrefresh(header_win);
Daniel Lezcano7b3da502011-06-15 15:45:12 +0200105
Daniel Lezcano653cb4a2011-06-21 00:57:08 +0200106 return 0;
107}
108
109#define footer_label " Q (Quit) R (Refresh) Other Keys: 'Left', " \
110 "'Right' , 'Up', 'Down', 'enter', , 'Esc'"
111
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200112static int display_show_footer(int win, char *string)
Daniel Lezcano653cb4a2011-06-21 00:57:08 +0200113{
114 werase(footer_win);
Daniel Lezcano7b3da502011-06-15 15:45:12 +0200115 wattron(footer_win, A_REVERSE);
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200116 mvwprintw(footer_win, 0, 0, "%s", string ? string : footer_label);
Daniel Lezcano7b3da502011-06-15 15:45:12 +0200117 wattroff(footer_win, A_REVERSE);
118 wrefresh(footer_win);
119
120 return 0;
121}
122
Daniel Lezcanod577aaa2011-06-21 00:57:08 +0200123static int display_refresh(int win, bool read)
Amit Arora47fd9182010-08-24 13:26:06 +0530124{
Daniel Lezcanodb145802011-06-21 00:57:08 +0200125 /* we are trying to refresh a window which is not showed */
126 if (win != current_win)
127 return 0;
Daniel Lezcanof6656822011-06-15 15:45:12 +0200128
Daniel Lezcanodb145802011-06-21 00:57:08 +0200129 if (windata[win].ops && windata[win].ops->display)
Daniel Lezcanod577aaa2011-06-21 00:57:08 +0200130 return windata[win].ops->display(read);
Daniel Lezcano971515a2011-06-15 15:45:12 +0200131
Daniel Lezcanocaafece2011-06-27 22:59:17 +0200132 if (werase(main_win))
133 return -1;
134
135 return wrefresh(main_win);
Daniel Lezcano971515a2011-06-15 15:45:12 +0200136}
137
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200138int display_refresh_pad(int win)
Amit Arora728e0c92010-09-14 12:06:09 +0530139{
Daniel Lezcano0a8cc582011-06-21 00:57:08 +0200140 int maxx, maxy;
141
142 getmaxyx(stdscr, maxy, maxx);
143
Daniel Lezcanof6656822011-06-15 15:45:12 +0200144 return prefresh(windata[win].pad, windata[win].scrolling,
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200145 0, 2, 0, maxy - 2, maxx);
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200146}
Amit Aroraac4e8652010-11-09 11:16:53 +0530147
Sanjay Singh Rawat83b37c32013-04-17 14:57:07 +0530148void sigwinch_handler(int signo)
149{
150 display_refresh(current_win, true);
151}
152
Daniel Lezcano28203df2011-06-15 15:45:12 +0200153static int display_show_unselection(int win, int line, bool bold)
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200154{
Daniel Lezcanof6656822011-06-15 15:45:12 +0200155 if (mvwchgat(windata[win].pad, line, 0, -1,
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200156 bold ? WA_BOLD: WA_NORMAL, 0, NULL) < 0)
157 return -1;
158
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200159 return display_refresh_pad(win);
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200160}
161
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200162void *display_get_row_data(int win)
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200163{
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200164 return windata[win].rowdata[windata[win].cursor].data;
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200165}
166
Daniel Lezcano28203df2011-06-15 15:45:12 +0200167static int display_select(void)
168{
169 if (windata[current_win].ops && windata[current_win].ops->select)
170 return windata[current_win].ops->select();
171
172 return 0;
173}
174
Shaojie Sun8ac4a2e2013-07-29 20:11:46 +0800175static int display_change(int keyvalue)
176{
177 if (!(windata[current_win].nrdata))
178 return 0;
179
180 if (windata[current_win].ops && windata[current_win].ops->change)
181 return windata[current_win].ops->change(keyvalue);
182
183 return 0;
184}
185
Daniel Lezcano28203df2011-06-15 15:45:12 +0200186static int display_next_panel(void)
187{
188 size_t array_size = sizeof(windata) / sizeof(windata[0]);
189
190 current_win++;
191 current_win %= array_size;
192
193 return current_win;
194}
195
196static int display_prev_panel(void)
197{
198 size_t array_size = sizeof(windata) / sizeof(windata[0]);
199
200 current_win--;
201 if (current_win < 0)
202 current_win = array_size - 1;
203
204 return current_win;
205}
206
207static int display_next_line(void)
208{
Daniel Lezcano83b28d02016-02-18 13:49:55 +0000209 int maxy;
Daniel Lezcano28203df2011-06-15 15:45:12 +0200210 int cursor = windata[current_win].cursor;
211 int nrdata = windata[current_win].nrdata;
212 int scrolling = windata[current_win].scrolling;
213 struct rowdata *rowdata = windata[current_win].rowdata;
214
Daniel Lezcano83b28d02016-02-18 13:49:55 +0000215 maxy = getmaxy(stdscr);
Daniel Lezcano0a8cc582011-06-21 00:57:08 +0200216
Daniel Lezcano28203df2011-06-15 15:45:12 +0200217 if (cursor >= nrdata)
218 return cursor;
219
220 display_show_unselection(current_win, cursor, rowdata[cursor].attr);
221 if (cursor < nrdata - 1) {
222 if (cursor >= (maxy - 4 + scrolling))
223 scrolling++;
224 cursor++;
225 }
226
227 windata[current_win].scrolling = scrolling;
228 windata[current_win].cursor = cursor;
229
230 return cursor;
231}
232
233static int display_prev_line(void)
234{
235 int cursor = windata[current_win].cursor;
236 int nrdata = windata[current_win].nrdata;
237 int scrolling = windata[current_win].scrolling;
238 struct rowdata *rowdata = windata[current_win].rowdata;
239
240 if (cursor >= nrdata)
241 return cursor;
242
243 display_show_unselection(current_win, cursor, rowdata[cursor].attr);
244 if (cursor > 0) {
245 if (cursor <= scrolling)
246 scrolling--;
247 cursor--;
248 }
249
250 windata[current_win].scrolling = scrolling;
251 windata[current_win].cursor = cursor;
252
253 return cursor;
254}
255
256static int display_set_row_data(int win, int line, void *data, int attr)
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200257{
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200258 struct rowdata *rowdata = windata[win].rowdata;
259
260 if (line >= windata[win].nrdata) {
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200261 rowdata = realloc(rowdata, sizeof(struct rowdata) * (line + 1));
262 if (!rowdata)
263 return -1;
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200264 windata[win].nrdata = line + 1;
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200265 }
266
267 rowdata[line].data = data;
268 rowdata[line].attr = attr;
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200269 windata[win].rowdata = rowdata;
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200270
271 return 0;
272}
273
Daniel Lezcanof6656822011-06-15 15:45:12 +0200274int display_reset_cursor(int win)
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200275{
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200276 windata[win].nrdata = 0;
Daniel Lezcanof6656822011-06-15 15:45:12 +0200277 werase(windata[win].pad);
278 return wmove(windata[win].pad, 0, 0);
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200279}
280
Sanjay Singh Rawat96f6e052014-05-26 11:35:02 +0530281void display_message(int win, char *buf)
282{
283 display_reset_cursor(win);
284 wattron(windata[win].pad, WA_BOLD);
285 wprintw(windata[win].pad, "%s\n", buf);
286 wattroff(windata[win].pad, WA_BOLD);
287 display_refresh_pad(win);
288}
289
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200290int display_print_line(int win, int line, char *str, int bold, void *data)
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200291{
292 int attr = 0;
293
Amit Arora031263a2010-11-09 11:12:41 +0530294 if (bold)
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200295 attr |= WA_BOLD;
296
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200297 if (line == windata[win].cursor)
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200298 attr |= WA_STANDOUT;
299
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200300 if (display_set_row_data(win, line, data, attr))
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200301 return -1;
302
303 if (attr)
Daniel Lezcanof6656822011-06-15 15:45:12 +0200304 wattron(windata[win].pad, attr);
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200305
Daniel Lezcanof6656822011-06-15 15:45:12 +0200306 wprintw(windata[win].pad, "%s\n", str);
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200307
308 if (attr)
Daniel Lezcanof6656822011-06-15 15:45:12 +0200309 wattroff(windata[win].pad, attr);
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200310
311 return 0;
312}
313
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200314static int display_find_keystroke(int fd, void *data);
315
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200316struct find_data {
317 size_t len;
318 char *string;
319 regex_t *reg;
Daniel Lezcano96a64fb2011-06-21 00:57:08 +0200320 int ocursor;
Daniel Lezcano10c86452011-06-21 00:57:08 +0200321 int oscrolling;
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200322};
323
Daniel Lezcano10c86452011-06-21 00:57:08 +0200324struct find_data *display_find_init(void)
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200325{
326 const char *regexp = "^[a-z|0-9|_|-|.]";
327 struct find_data *findd;
328 const size_t len = 64;
329 regex_t *reg;
330 char *search4;
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200331
332 reg = malloc(sizeof(*reg));
333 if (!reg)
334 return NULL;
335
336 if (regcomp(reg, regexp, REG_ICASE))
337 goto out_free_reg;
338
339 search4 = malloc(len);
340 if (!search4)
341 goto out_free_regcomp;
342 memset(search4, '\0', len);
343
344 findd = malloc(sizeof(*findd));
345 if (!findd)
346 goto out_free_search4;
347
348 findd->string = search4;
349 findd->reg = reg;
350 findd->len = len;
Daniel Lezcano96a64fb2011-06-21 00:57:08 +0200351
352 /* save the location of the cursor on the main window in order to
353 * browse the search result
354 */
355 findd->ocursor = windata[current_win].cursor;
Daniel Lezcano10c86452011-06-21 00:57:08 +0200356 findd->oscrolling = windata[current_win].scrolling;
Daniel Lezcano96a64fb2011-06-21 00:57:08 +0200357
Daniel Lezcano10c86452011-06-21 00:57:08 +0200358 windata[current_win].cursor = 0;
359 windata[current_win].scrolling = 0;
360
361 curs_set(1);
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200362out:
363 return findd;
364
365out_free_search4:
366 free(search4);
367out_free_regcomp:
368 regfree(reg);
369out_free_reg:
370 free(reg);
371
372 goto out;
373}
374
Daniel Lezcano10c86452011-06-21 00:57:08 +0200375static void display_find_fini(struct find_data *findd)
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200376{
Daniel Lezcano10c86452011-06-21 00:57:08 +0200377 windata[current_win].cursor = findd->ocursor;
378 windata[current_win].scrolling = findd->oscrolling;
379 regfree(findd->reg);
380 free(findd->string);
381 free(findd);
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200382 curs_set(0);
383}
384
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200385static int display_switch_to_find(int fd)
386{
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200387 struct find_data *findd;
388
Daniel Lezcano10c86452011-06-21 00:57:08 +0200389 findd = display_find_init();
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200390 if (!findd)
391 return -1;
392
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200393 if (mainloop_del(fd))
394 return -1;
395
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200396 if (mainloop_add(fd, display_find_keystroke, findd))
397 return -1;
398
399 if (display_show_footer(current_win, "find (esc to exit)?"))
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200400 return -1;
401
402 return 0;
403}
404
Daniel Lezcanodb145802011-06-21 00:57:08 +0200405static int display_keystroke(int fd, void *data)
Daniel Lezcano176e69d2011-06-15 15:45:12 +0200406{
Daniel Lezcano176e69d2011-06-15 15:45:12 +0200407 int keystroke = getch();
408
409 switch (keystroke) {
410
411 case KEY_RIGHT:
412 case '\t':
Daniel Lezcano372ffba2011-06-21 00:57:08 +0200413 display_show_header(display_next_panel());
Daniel Lezcano176e69d2011-06-15 15:45:12 +0200414 break;
415
416 case KEY_LEFT:
417 case KEY_BTAB:
Daniel Lezcano372ffba2011-06-21 00:57:08 +0200418 display_show_header(display_prev_panel());
Daniel Lezcano176e69d2011-06-15 15:45:12 +0200419 break;
420
421 case KEY_DOWN:
422 display_next_line();
423 break;
424
425 case KEY_UP:
426 display_prev_line();
427 break;
428
Shaojie Sunb32cbb92013-07-17 16:23:45 +0800429 case '\n':
Daniel Lezcano176e69d2011-06-15 15:45:12 +0200430 case '\r':
431 display_select();
432 break;
433
Shaojie Sun8ac4a2e2013-07-29 20:11:46 +0800434 case 'v':
435 case 'V':
436 case 'd':
437 case 'D':
438 display_change(toupper(keystroke));
439 break;
440
Daniel Lezcano176e69d2011-06-15 15:45:12 +0200441 case EOF:
442 case 'q':
443 case 'Q':
444 return 1;
445
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200446 case '/':
447 return display_switch_to_find(fd);
448
Daniel Lezcano176e69d2011-06-15 15:45:12 +0200449 case 'r':
450 case 'R':
Daniel Lezcanod577aaa2011-06-21 00:57:08 +0200451 return display_refresh(current_win, true);
Daniel Lezcanodb145802011-06-21 00:57:08 +0200452 default:
453 return 0;
Daniel Lezcano176e69d2011-06-15 15:45:12 +0200454 }
455
Daniel Lezcanod577aaa2011-06-21 00:57:08 +0200456 display_refresh(current_win, false);
Daniel Lezcanodb145802011-06-21 00:57:08 +0200457
458 return 0;
459}
460
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200461static int display_switch_to_main(int fd)
462{
463 if (mainloop_del(fd))
464 return -1;
465
466 if (mainloop_add(fd, display_keystroke, NULL))
467 return -1;
468
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200469 if (display_show_header(current_win))
470 return -1;
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200471
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200472 if (display_show_footer(current_win, NULL))
473 return -1;
474
Daniel Lezcanod577aaa2011-06-21 00:57:08 +0200475 return display_refresh(current_win, false);
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200476}
477
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200478static int display_find_keystroke(int fd, void *data)
479{
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200480 struct find_data *findd = data;
481 regex_t *reg = findd->reg;
482 char *string = findd->string;
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200483 int keystroke = getch();
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200484 char match[2] = { [0] = (char)keystroke, [1] = '\0' };
485 regmatch_t m[1];
486
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200487 switch (keystroke) {
488
489 case '\e':
Daniel Lezcano10c86452011-06-21 00:57:08 +0200490 display_find_fini(findd);
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200491 return display_switch_to_main(fd);
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200492
Daniel Lezcanoa12163d2011-06-21 00:57:08 +0200493 case KEY_DOWN:
494 display_next_line();
495 break;
496
497 case KEY_UP:
498 display_prev_line();
499 break;
500
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200501 case KEY_BACKSPACE:
502 if (strlen(string))
503 string[strlen(string) - 1] = '\0';
Daniel Lezcano10c86452011-06-21 00:57:08 +0200504
505 windata[current_win].cursor = 0;
506 windata[current_win].scrolling = 0;
507
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200508 break;
509
Shaojie Sunb32cbb92013-07-17 16:23:45 +0800510 case '\n':
Daniel Lezcano73b40022011-06-21 00:57:08 +0200511 case '\r':
512 if (!windata[current_win].ops || !windata[current_win].ops->selectf)
513 return 0;
514
515 if (windata[current_win].ops->selectf())
516 return -1;
517
Daniel Lezcanoe78bc072011-06-21 10:49:39 +0200518 windata[current_win].cursor = 0;
519 windata[current_win].scrolling = 0;
520
Daniel Lezcano73b40022011-06-21 00:57:08 +0200521 return 0;
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200522
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200523 default:
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200524
525 /* We don't want invalid characters for a name */
526 if (regexec(reg, match, 1, m, 0))
527 return 0;
528
529 if (strlen(string) < findd->len - 1)
530 string[strlen(string)] = (char)keystroke;
531
Daniel Lezcano10c86452011-06-21 00:57:08 +0200532 windata[current_win].cursor = 0;
533 windata[current_win].scrolling = 0;
534
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200535 break;
536 }
537
Daniel Lezcanoa12163d2011-06-21 00:57:08 +0200538 if (!windata[current_win].ops || !windata[current_win].ops->find)
539 return 0;
540
541 if (windata[current_win].ops->find(string))
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200542 return -1;
543
Daniel Lezcanoa12163d2011-06-21 00:57:08 +0200544 if (display_show_header(current_win))
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200545 return -1;
546
547 if (display_show_footer(current_win, strlen(string) ? string :
548 "find (esc to exit)?"))
549 return -1;
550
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200551 return 0;
552}
553
Daniel Lezcano5e659d72016-02-19 20:22:12 +0000554int display_init(struct powerdebug_options *options)
Daniel Lezcanodb145802011-06-21 00:57:08 +0200555{
Daniel Lezcano0a8cc582011-06-21 00:57:08 +0200556 int i, maxx, maxy;
Daniel Lezcanodb145802011-06-21 00:57:08 +0200557 size_t array_size = sizeof(windata) / sizeof(windata[0]);
558
Daniel Lezcano5e659d72016-02-19 20:22:12 +0000559 current_win = 1 << (ffs(options->flags & DEFAULT_OPTION) - 1);
Daniel Lezcanodb145802011-06-21 00:57:08 +0200560
561 if (mainloop_add(0, display_keystroke, NULL))
562 return -1;
563
564 if (!initscr())
565 return -1;
566
567 start_color();
568 use_default_colors();
569
570 keypad(stdscr, TRUE);
571 noecho();
572 cbreak();
573 curs_set(0);
574 nonl();
575
576 if (init_pair(PT_COLOR_DEFAULT, COLOR_WHITE, COLOR_BLACK) ||
577 init_pair(PT_COLOR_ERROR, COLOR_BLACK, COLOR_RED) ||
578 init_pair(PT_COLOR_HEADER_BAR, COLOR_WHITE, COLOR_BLACK) ||
579 init_pair(PT_COLOR_YELLOW, COLOR_WHITE, COLOR_YELLOW) ||
580 init_pair(PT_COLOR_GREEN, COLOR_WHITE, COLOR_GREEN) ||
581 init_pair(PT_COLOR_BRIGHT, COLOR_WHITE, COLOR_BLACK) ||
582 init_pair(PT_COLOR_BLUE, COLOR_WHITE, COLOR_BLUE) ||
583 init_pair(PT_COLOR_RED, COLOR_WHITE, COLOR_RED))
584 return -1;
585
586 if (atexit(display_fini))
587 return -1;
588
589 getmaxyx(stdscr, maxy, maxx);
590
591 for (i = 0; i < array_size; i++) {
592
Daniel Lezcanoc196d432011-06-21 00:57:08 +0200593 main_win = subwin(stdscr, maxy - 2, maxx, 1, 0);
594 if (!main_win)
Daniel Lezcanodb145802011-06-21 00:57:08 +0200595 return -1;
596
597 windata[i].pad = newpad(maxrows, maxx);
598 if (!windata[i].pad)
599 return -1;
600
601 }
602
603 header_win = subwin(stdscr, 1, maxx, 0, 0);
604 if (!header_win)
605 return -1;
606
607 footer_win = subwin(stdscr, 1, maxx, maxy-1, 0);
608 if (!footer_win)
609 return -1;
610
Daniel Lezcano5e659d72016-02-19 20:22:12 +0000611 if (display_show_header(current_win))
Daniel Lezcano653cb4a2011-06-21 00:57:08 +0200612 return -1;
613
Daniel Lezcano5e659d72016-02-19 20:22:12 +0000614 if (display_show_footer(current_win, NULL))
Daniel Lezcanodb145802011-06-21 00:57:08 +0200615 return -1;
616
Daniel Lezcano5e659d72016-02-19 20:22:12 +0000617 return display_refresh(current_win, true);
Daniel Lezcanodb145802011-06-21 00:57:08 +0200618}
619
Daniel Lezcano372ffba2011-06-21 00:57:08 +0200620int display_column_name(const char *line)
Daniel Lezcanodb145802011-06-21 00:57:08 +0200621{
Daniel Lezcanoc196d432011-06-21 00:57:08 +0200622 werase(main_win);
623 wattron(main_win, A_BOLD);
Daniel Lezcanofa453332011-06-21 00:57:08 +0200624 mvwprintw(main_win, 0, 0, "%s", line);
Daniel Lezcanoc196d432011-06-21 00:57:08 +0200625 wattroff(main_win, A_BOLD);
626 wrefresh(main_win);
Daniel Lezcanodb145802011-06-21 00:57:08 +0200627
Daniel Lezcano372ffba2011-06-21 00:57:08 +0200628 return 0;
Daniel Lezcanodb145802011-06-21 00:57:08 +0200629}
630
631int display_register(int win, struct display_ops *ops)
632{
633 size_t array_size = sizeof(windata) / sizeof(windata[0]);
634
Sanjay Singh Rawat5fef0052013-04-17 15:02:01 +0530635 if (win < 0 || win >= array_size) {
636 printf("error: invalid window");
Daniel Lezcanodb145802011-06-21 00:57:08 +0200637 return -1;
Sanjay Singh Rawat5fef0052013-04-17 15:02:01 +0530638 }
Daniel Lezcanodb145802011-06-21 00:57:08 +0200639
640 windata[win].ops = ops;
641
Daniel Lezcano176e69d2011-06-15 15:45:12 +0200642 return 0;
643}