blob: 3c79737a64e0d906295a67da0e4ae0e24e2a3d26 [file] [log] [blame]
Amit Arora39f29542010-09-14 12:03:22 +05301/*******************************************************************************
Amit Kucheriac0e17fc2011-01-17 09:35:52 +02002 * Copyright (C) 2010, Linaro Limited.
Amit Arora39f29542010-09-14 12:03:22 +05303 *
4 * This file is part of PowerDebug.
5 *
6 * All rights reserved. This program and the accompanying materials
7 * are made available under the terms of the Eclipse Public License v1.0
8 * which accompanies this distribution, and is available at
9 * http://www.eclipse.org/legal/epl-v10.html
10 *
11 * Contributors:
12 * Amit Arora <amit.arora@linaro.org> (IBM Corporation)
13 * - initial API and implementation
14 *******************************************************************************/
15
Daniel Lezcano15627482011-06-15 15:45:12 +020016#include <stdio.h>
17#include <string.h>
18#include <stdlib.h>
19#include <ncurses.h>
Amit Arora47fd9182010-08-24 13:26:06 +053020#include "powerdebug.h"
Amit Arora17552782010-12-02 12:23:14 +053021#include "regulator.h"
Amit Aroraed3e5652010-10-27 12:02:53 +053022#include "display.h"
Amit Arora47fd9182010-08-24 13:26:06 +053023
24#define print(w, x, y, fmt, args...) do { mvwprintw(w, y, x, fmt, ##args); } while (0)
Amit Arora47fd9182010-08-24 13:26:06 +053025
Daniel Lezcanoeeb13762011-03-26 22:06:17 +010026enum { PT_COLOR_DEFAULT = 1,
27 PT_COLOR_HEADER_BAR,
28 PT_COLOR_ERROR,
29 PT_COLOR_RED,
30 PT_COLOR_YELLOW,
31 PT_COLOR_GREEN,
32 PT_COLOR_BRIGHT,
33 PT_COLOR_BLUE,
34};
35
Amit Arora47fd9182010-08-24 13:26:06 +053036static WINDOW *header_win;
Amit Arora47fd9182010-08-24 13:26:06 +053037static WINDOW *footer_win;
Daniel Lezcanod96731a2011-06-15 15:45:12 +020038static int current_win;
Amit Arora47fd9182010-08-24 13:26:06 +053039
40int maxx, maxy;
Daniel Lezcano2adc48d2011-06-08 23:30:01 +020041
42/* Number of lines in the virtual window */
43static const int maxrows = 1024;
44
Daniel Lezcano7b3da502011-06-15 15:45:12 +020045#define footer_label " Q (Quit) R (Refresh) Other Keys: 'Left', " \
46 "'Right' , 'Up', 'Down', 'enter', , 'Esc'"
Amit Arora47fd9182010-08-24 13:26:06 +053047
Daniel Lezcano2adc48d2011-06-08 23:30:01 +020048struct rowdata {
49 int attr;
50 void *data;
51};
52
Daniel Lezcanob3e6e812011-06-15 15:45:12 +020053struct windata {
Daniel Lezcanof6656822011-06-15 15:45:12 +020054 WINDOW *win;
55 WINDOW *pad;
Daniel Lezcanob301b082011-06-15 15:45:12 +020056 struct display_ops *ops;
Daniel Lezcanob3e6e812011-06-15 15:45:12 +020057 struct rowdata *rowdata;
58 char *name;
59 int nrdata;
60 int scrolling;
61 int cursor;
62};
63
64struct windata windata[TOTAL_FEATURE_WINS] = {
65 { .name = "Clocks" },
66 { .name = "Regulators" },
67 { .name = "Sensors" },
68};
Daniel Lezcano2adc48d2011-06-08 23:30:01 +020069
Daniel Lezcano3abd8b12011-03-26 22:06:15 +010070static void display_fini(void)
71{
72 endwin();
73}
74
Daniel Lezcano7b3da502011-06-15 15:45:12 +020075static int show_header_footer(int win)
76{
77 int i;
78 int curr_pointer = 0;
79
80 wattrset(header_win, COLOR_PAIR(PT_COLOR_HEADER_BAR));
81 wbkgd(header_win, COLOR_PAIR(PT_COLOR_HEADER_BAR));
82 werase(header_win);
83
84 print(header_win, curr_pointer, 0, "PowerDebug %s", VERSION);
85 curr_pointer += 20;
86
87 for (i = 0; i < TOTAL_FEATURE_WINS; i++) {
88 if (win == i)
89 wattron(header_win, A_REVERSE);
90 else
91 wattroff(header_win, A_REVERSE);
92
93 print(header_win, curr_pointer, 0, " %s ", windata[i].name);
94 curr_pointer += strlen(windata[i].name) + 2;
95 }
96 wrefresh(header_win);
97 werase(footer_win);
98
99 wattron(footer_win, A_REVERSE);
100 print(footer_win, 0, 0, "%s", footer_label);
101 wattroff(footer_win, A_REVERSE);
102 wrefresh(footer_win);
103
104 return 0;
105}
106
107int display_init(int wdefault)
Amit Arora47fd9182010-08-24 13:26:06 +0530108{
Daniel Lezcanof6656822011-06-15 15:45:12 +0200109 int i;
110 size_t array_size = sizeof(windata) / sizeof(windata[0]);
111
Daniel Lezcanod96731a2011-06-15 15:45:12 +0200112 current_win = wdefault;
113
Daniel Lezcanoca17a722011-03-26 22:06:16 +0100114 if (!initscr())
115 return -1;
116
Amit Arora6e774cd2010-10-28 11:31:24 +0530117 start_color();
Daniel Lezcanoca17a722011-03-26 22:06:16 +0100118 use_default_colors();
119
Amit Arora6e774cd2010-10-28 11:31:24 +0530120 keypad(stdscr, TRUE);
121 noecho();
122 cbreak();
123 curs_set(0);
124 nonl();
Amit Arora47fd9182010-08-24 13:26:06 +0530125
Daniel Lezcanoca17a722011-03-26 22:06:16 +0100126 if (init_pair(PT_COLOR_DEFAULT, COLOR_WHITE, COLOR_BLACK) ||
127 init_pair(PT_COLOR_ERROR, COLOR_BLACK, COLOR_RED) ||
128 init_pair(PT_COLOR_HEADER_BAR, COLOR_WHITE, COLOR_BLACK) ||
129 init_pair(PT_COLOR_YELLOW, COLOR_WHITE, COLOR_YELLOW) ||
130 init_pair(PT_COLOR_GREEN, COLOR_WHITE, COLOR_GREEN) ||
131 init_pair(PT_COLOR_BRIGHT, COLOR_WHITE, COLOR_BLACK) ||
132 init_pair(PT_COLOR_BLUE, COLOR_WHITE, COLOR_BLUE) ||
133 init_pair(PT_COLOR_RED, COLOR_WHITE, COLOR_RED))
134 return -1;
Amit Arora47fd9182010-08-24 13:26:06 +0530135
Daniel Lezcano1c25df92011-06-08 23:30:00 +0200136 if (atexit(display_fini))
137 return -1;
138
139 getmaxyx(stdscr, maxy, maxx);
140
Daniel Lezcanof6656822011-06-15 15:45:12 +0200141 for (i = 0; i < array_size; i++) {
Daniel Lezcano1c25df92011-06-08 23:30:00 +0200142
Daniel Lezcanof6656822011-06-15 15:45:12 +0200143 windata[i].win = subwin(stdscr, maxy - 2, maxx, 1, 0);
144 if (!windata[i].win)
145 return -1;
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200146
Daniel Lezcanof6656822011-06-15 15:45:12 +0200147 windata[i].pad = newpad(maxrows, maxx);
148 if (!windata[i].pad)
149 return -1;
Daniel Lezcano1c25df92011-06-08 23:30:00 +0200150
Daniel Lezcanof6656822011-06-15 15:45:12 +0200151 }
Daniel Lezcano1c25df92011-06-08 23:30:00 +0200152
153 header_win = subwin(stdscr, 1, maxx, 0, 0);
154 if (!header_win)
155 return -1;
156
157 footer_win = subwin(stdscr, 1, maxx, maxy-1, 0);
158 if (!footer_win)
159 return -1;
160
Daniel Lezcano7b3da502011-06-15 15:45:12 +0200161 return show_header_footer(wdefault);
Amit Arora47fd9182010-08-24 13:26:06 +0530162}
163
Daniel Lezcanob25be4a2011-06-15 15:45:12 +0200164void print_regulator_header(void)
Amit Arora47fd9182010-08-24 13:26:06 +0530165{
Daniel Lezcanof6656822011-06-15 15:45:12 +0200166 WINDOW *regulator_win = windata[REGULATOR].win;
167
Amit Arora47fd9182010-08-24 13:26:06 +0530168 werase(regulator_win);
169 wattron(regulator_win, A_BOLD);
Amit Arorac93e0712010-10-07 13:51:53 +0530170 print(regulator_win, 0, 0, "Name");
171 print(regulator_win, 12, 0, "Status");
172 print(regulator_win, 24, 0, "State");
173 print(regulator_win, 36, 0, "Type");
174 print(regulator_win, 48, 0, "Users");
175 print(regulator_win, 60, 0, "Microvolts");
176 print(regulator_win, 72, 0, "Min u-volts");
177 print(regulator_win, 84, 0, "Max u-volts");
Amit Arora47fd9182010-08-24 13:26:06 +0530178 wattroff(regulator_win, A_BOLD);
Daniel Lezcanob25be4a2011-06-15 15:45:12 +0200179 wrefresh(regulator_win);
Daniel Lezcano7b3da502011-06-15 15:45:12 +0200180
181 show_header_footer(REGULATOR);
Daniel Lezcanob25be4a2011-06-15 15:45:12 +0200182}
183
184void print_clock_header(void)
185{
Daniel Lezcanof6656822011-06-15 15:45:12 +0200186 WINDOW *clock_win = windata[CLOCK].win;
187
188 werase(clock_win);
189 wattron(clock_win, A_BOLD);
190 print(clock_win, 0, 0, "Name");
191 print(clock_win, 56, 0, "Flags");
192 print(clock_win, 75, 0, "Rate");
193 print(clock_win, 88, 0, "Usecount");
194 print(clock_win, 98, 0, "Children");
195 wattroff(clock_win, A_BOLD);
196 wrefresh(clock_win);
Daniel Lezcano7b3da502011-06-15 15:45:12 +0200197
198 show_header_footer(CLOCK);
Daniel Lezcanob25be4a2011-06-15 15:45:12 +0200199}
200
Amit Arora728e0c92010-09-14 12:06:09 +0530201void print_sensor_header(void)
202{
Daniel Lezcanof6656822011-06-15 15:45:12 +0200203 WINDOW *sensor_win = windata[SENSOR].win;
204
Amit Arora6e774cd2010-10-28 11:31:24 +0530205 werase(sensor_win);
206 wattron(sensor_win, A_BOLD);
207 print(sensor_win, 0, 0, "Name");
Daniel Lezcano2e9df762011-06-15 15:45:12 +0200208 print(sensor_win, 36, 0, "Value");
Amit Arora6e774cd2010-10-28 11:31:24 +0530209 wattroff(sensor_win, A_BOLD);
Amit Arora728e0c92010-09-14 12:06:09 +0530210 wrefresh(sensor_win);
Daniel Lezcano7b3da502011-06-15 15:45:12 +0200211
212 show_header_footer(SENSOR);
Amit Arora728e0c92010-09-14 12:06:09 +0530213}
214
Daniel Lezcanob301b082011-06-15 15:45:12 +0200215int display_register(int win, struct display_ops *ops)
216{
217 if (win < 0 || win >= TOTAL_FEATURE_WINS)
218 return -1;
219
220 windata[win].ops = ops;
221
222 return 0;
223}
224
Daniel Lezcano971515a2011-06-15 15:45:12 +0200225int display_refresh(void)
226{
227 if (windata[current_win].ops && windata[current_win].ops->display)
228 return windata[current_win].ops->display();
229
230 return 0;
231}
232
233int display_select(void)
234{
235 if (windata[current_win].ops && windata[current_win].ops->select)
236 return windata[current_win].ops->select();
237
238 return 0;
239}
240
Daniel Lezcanod96731a2011-06-15 15:45:12 +0200241int display_next_panel(void)
242{
243 current_win++;
244 current_win %= TOTAL_FEATURE_WINS;
245
246 return current_win;
247}
248
249int display_prev_panel(void)
250{
251 current_win--;
252 if (current_win < 0)
253 current_win = TOTAL_FEATURE_WINS - 1;
254
255 return current_win;
256}
257
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200258int display_refresh_pad(int win)
Amit Arora728e0c92010-09-14 12:06:09 +0530259{
Daniel Lezcanof6656822011-06-15 15:45:12 +0200260 return prefresh(windata[win].pad, windata[win].scrolling,
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200261 0, 2, 0, maxy - 2, maxx);
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200262}
Amit Aroraac4e8652010-11-09 11:16:53 +0530263
Daniel Lezcano971515a2011-06-15 15:45:12 +0200264static int inline display_show_un_selection(int win, int line,
265 bool highlight, bool bold)
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200266{
Daniel Lezcanof6656822011-06-15 15:45:12 +0200267 if (mvwchgat(windata[win].pad, line, 0, -1,
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200268 highlight ? WA_STANDOUT :
269 bold ? WA_BOLD: WA_NORMAL, 0, NULL) < 0)
270 return -1;
271
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200272 return display_refresh_pad(win);
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200273}
274
Daniel Lezcano971515a2011-06-15 15:45:12 +0200275int display_show_selection(int win, int line)
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200276{
Daniel Lezcano971515a2011-06-15 15:45:12 +0200277 return display_show_un_selection(win, line, true, false);
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200278}
279
Daniel Lezcano971515a2011-06-15 15:45:12 +0200280int display_show_unselection(int win, int line, bool bold)
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200281{
Daniel Lezcano971515a2011-06-15 15:45:12 +0200282 return display_show_un_selection(win, line, false, bold);
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200283}
284
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200285void *display_get_row_data(int win)
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200286{
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200287 return windata[win].rowdata[windata[win].cursor].data;
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200288}
289
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200290int display_set_row_data(int win, int line, void *data, int attr)
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200291{
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200292 struct rowdata *rowdata = windata[win].rowdata;
293
294 if (line >= windata[win].nrdata) {
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200295 rowdata = realloc(rowdata, sizeof(struct rowdata) * (line + 1));
296 if (!rowdata)
297 return -1;
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200298 windata[win].nrdata = line + 1;
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200299 }
300
301 rowdata[line].data = data;
302 rowdata[line].attr = attr;
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200303 windata[win].rowdata = rowdata;
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200304
305 return 0;
306}
307
Daniel Lezcanof6656822011-06-15 15:45:12 +0200308int display_reset_cursor(int win)
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200309{
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200310 windata[win].nrdata = 0;
Daniel Lezcanof6656822011-06-15 15:45:12 +0200311 werase(windata[win].pad);
312 return wmove(windata[win].pad, 0, 0);
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200313}
314
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200315int display_print_line(int win, int line, char *str, int bold, void *data)
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200316{
317 int attr = 0;
318
Amit Arora031263a2010-11-09 11:12:41 +0530319 if (bold)
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200320 attr |= WA_BOLD;
321
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200322 if (line == windata[win].cursor)
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200323 attr |= WA_STANDOUT;
324
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200325 if (display_set_row_data(win, line, data, attr))
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200326 return -1;
327
328 if (attr)
Daniel Lezcanof6656822011-06-15 15:45:12 +0200329 wattron(windata[win].pad, attr);
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200330
Daniel Lezcanof6656822011-06-15 15:45:12 +0200331 wprintw(windata[win].pad, "%s\n", str);
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200332
333 if (attr)
Daniel Lezcanof6656822011-06-15 15:45:12 +0200334 wattroff(windata[win].pad, attr);
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200335
336 return 0;
337}
338
Daniel Lezcanod96731a2011-06-15 15:45:12 +0200339int display_next_line(void)
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200340{
Daniel Lezcanod96731a2011-06-15 15:45:12 +0200341 int cursor = windata[current_win].cursor;
342 int nrdata = windata[current_win].nrdata;
343 int scrolling = windata[current_win].scrolling;
344 struct rowdata *rowdata = windata[current_win].rowdata;
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200345
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200346 if (cursor >= nrdata)
347 return cursor;
348
Daniel Lezcano971515a2011-06-15 15:45:12 +0200349 display_show_unselection(current_win, cursor, rowdata[cursor].attr);
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200350 if (cursor < nrdata - 1) {
351 if (cursor >= (maxy - 4 + scrolling))
352 scrolling++;
353 cursor++;
354 }
Daniel Lezcano971515a2011-06-15 15:45:12 +0200355 display_show_selection(current_win, cursor);
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200356
Daniel Lezcanod96731a2011-06-15 15:45:12 +0200357 windata[current_win].scrolling = scrolling;
358 windata[current_win].cursor = cursor;
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200359
360 return cursor;
361}
362
Daniel Lezcanod96731a2011-06-15 15:45:12 +0200363int display_prev_line(void)
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200364{
Daniel Lezcanod96731a2011-06-15 15:45:12 +0200365 int cursor = windata[current_win].cursor;
366 int nrdata = windata[current_win].nrdata;
367 int scrolling = windata[current_win].scrolling;
368 struct rowdata *rowdata = windata[current_win].rowdata;
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200369
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200370 if (cursor >= nrdata)
371 return cursor;
372
Daniel Lezcano971515a2011-06-15 15:45:12 +0200373 display_show_unselection(current_win, cursor, rowdata[cursor].attr);
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200374 if (cursor > 0) {
375 if (cursor <= scrolling)
376 scrolling--;
377 cursor--;
378 }
Daniel Lezcano971515a2011-06-15 15:45:12 +0200379 display_show_selection(current_win, cursor);
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200380
Daniel Lezcanod96731a2011-06-15 15:45:12 +0200381 windata[current_win].scrolling = scrolling;
382 windata[current_win].cursor = cursor;
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200383
384 return cursor;
Amit Arora728e0c92010-09-14 12:06:09 +0530385}