blob: 8712023bc34fe950eb2df0520100a832aa4e8b80 [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
Amit Arora47fd9182010-08-24 13:26:06 +053016#include "powerdebug.h"
Amit Arora17552782010-12-02 12:23:14 +053017#include "regulator.h"
Amit Aroraed3e5652010-10-27 12:02:53 +053018#include "display.h"
Amit Arora47fd9182010-08-24 13:26:06 +053019
20#define print(w, x, y, fmt, args...) do { mvwprintw(w, y, x, fmt, ##args); } while (0)
21#define NUM_FOOTER_ITEMS 5
22
Daniel Lezcanoeeb13762011-03-26 22:06:17 +010023enum { PT_COLOR_DEFAULT = 1,
24 PT_COLOR_HEADER_BAR,
25 PT_COLOR_ERROR,
26 PT_COLOR_RED,
27 PT_COLOR_YELLOW,
28 PT_COLOR_GREEN,
29 PT_COLOR_BRIGHT,
30 PT_COLOR_BLUE,
31};
32
Amit Arora47fd9182010-08-24 13:26:06 +053033static WINDOW *header_win;
34static WINDOW *regulator_win;
Daniel Lezcano2adc48d2011-06-08 23:30:01 +020035static WINDOW *clock_pad;
36static WINDOW *clock_labels;
Amit Arora728e0c92010-09-14 12:06:09 +053037static WINDOW *sensor_win;
Amit Arora47fd9182010-08-24 13:26:06 +053038static WINDOW *footer_win;
39
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 Lezcano68500e82011-06-08 23:30:00 +020045static char footer_items[NUM_FOOTER_ITEMS][64];
Amit Arora47fd9182010-08-24 13:26:06 +053046
Daniel Lezcano2adc48d2011-06-08 23:30:01 +020047struct rowdata {
48 int attr;
49 void *data;
50};
51
Daniel Lezcanob3e6e812011-06-15 15:45:12 +020052struct windata {
53 struct rowdata *rowdata;
54 char *name;
55 int nrdata;
56 int scrolling;
57 int cursor;
58};
59
60struct windata windata[TOTAL_FEATURE_WINS] = {
61 { .name = "Clocks" },
62 { .name = "Regulators" },
63 { .name = "Sensors" },
64};
Daniel Lezcano2adc48d2011-06-08 23:30:01 +020065
Daniel Lezcano3abd8b12011-03-26 22:06:15 +010066static void display_fini(void)
67{
68 endwin();
69}
70
Daniel Lezcanoca17a722011-03-26 22:06:16 +010071int display_init(void)
Amit Arora47fd9182010-08-24 13:26:06 +053072{
Daniel Lezcanoca17a722011-03-26 22:06:16 +010073 if (!initscr())
74 return -1;
75
Amit Arora6e774cd2010-10-28 11:31:24 +053076 start_color();
Daniel Lezcanoca17a722011-03-26 22:06:16 +010077 use_default_colors();
78
Amit Arora6e774cd2010-10-28 11:31:24 +053079 keypad(stdscr, TRUE);
80 noecho();
81 cbreak();
82 curs_set(0);
83 nonl();
Amit Arora47fd9182010-08-24 13:26:06 +053084
Daniel Lezcanoca17a722011-03-26 22:06:16 +010085 if (init_pair(PT_COLOR_DEFAULT, COLOR_WHITE, COLOR_BLACK) ||
86 init_pair(PT_COLOR_ERROR, COLOR_BLACK, COLOR_RED) ||
87 init_pair(PT_COLOR_HEADER_BAR, COLOR_WHITE, COLOR_BLACK) ||
88 init_pair(PT_COLOR_YELLOW, COLOR_WHITE, COLOR_YELLOW) ||
89 init_pair(PT_COLOR_GREEN, COLOR_WHITE, COLOR_GREEN) ||
90 init_pair(PT_COLOR_BRIGHT, COLOR_WHITE, COLOR_BLACK) ||
91 init_pair(PT_COLOR_BLUE, COLOR_WHITE, COLOR_BLUE) ||
92 init_pair(PT_COLOR_RED, COLOR_WHITE, COLOR_RED))
93 return -1;
Amit Arora47fd9182010-08-24 13:26:06 +053094
Daniel Lezcano1c25df92011-06-08 23:30:00 +020095 if (atexit(display_fini))
96 return -1;
97
98 getmaxyx(stdscr, maxy, maxx);
99
100 regulator_win = subwin(stdscr, maxy - 2, maxx, 1, 0);
101 if (!regulator_win)
102 return -1;
103
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200104 clock_labels = subwin(stdscr, maxy - 2, maxx, 1, 0);
105 if (!clock_labels)
106 return -1;
107
108 clock_pad = newpad(maxrows, maxx);
109 if (!clock_pad)
Daniel Lezcano1c25df92011-06-08 23:30:00 +0200110 return -1;
111
112 sensor_win = subwin(stdscr, maxy - 2, maxx, 1, 0);
113 if (!sensor_win)
114 return -1;
115
116 header_win = subwin(stdscr, 1, maxx, 0, 0);
117 if (!header_win)
118 return -1;
119
120 footer_win = subwin(stdscr, 1, maxx, maxy-1, 0);
121 if (!footer_win)
122 return -1;
123
124 return 0;
Amit Arora47fd9182010-08-24 13:26:06 +0530125}
126
Daniel Lezcano558a6d52011-03-23 14:37:41 +0100127void create_windows(int selectedwindow)
Amit Arora47fd9182010-08-24 13:26:06 +0530128{
Amit Arora47fd9182010-08-24 13:26:06 +0530129 strcpy(footer_items[0], " Q (Quit) ");
130 strcpy(footer_items[1], " R (Refresh) ");
131
Amit Arora83ae6cb2010-12-02 12:22:19 +0530132 if (selectedwindow == CLOCK)
133 strcpy(footer_items[2], " Other Keys: 'Left', 'Right', 'Up', 'Down', 'enter', "
Amit Kucheriaa0adae42011-01-12 10:54:23 -0600134 " '/', 'Esc' ");
Amit Arora83ae6cb2010-12-02 12:22:19 +0530135 else
136 strcpy(footer_items[2], " Other Keys: 'Left', 'Right' ");
137
138 strcpy(footer_items[3], "");
139
Amit Arora47fd9182010-08-24 13:26:06 +0530140 werase(stdscr);
141 refresh();
142
143}
144
Daniel Lezcano558a6d52011-03-23 14:37:41 +0100145void create_selectedwindow(int selectedwindow)
Amit Arora728e0c92010-09-14 12:06:09 +0530146{
Amit Arora6e774cd2010-10-28 11:31:24 +0530147 switch (selectedwindow) {
Daniel Lezcano1c25df92011-06-08 23:30:00 +0200148 case REGULATOR:
149 wrefresh(regulator_win);
Amit Kucheriaa0adae42011-01-12 10:54:23 -0600150 break;
Amit Arora728e0c92010-09-14 12:06:09 +0530151
Daniel Lezcano1c25df92011-06-08 23:30:00 +0200152 case SENSOR:
153 wrefresh(sensor_win);
Amit Kucheriaa0adae42011-01-12 10:54:23 -0600154 break;
Amit Arora6e774cd2010-10-28 11:31:24 +0530155 }
Amit Arora728e0c92010-09-14 12:06:09 +0530156}
Amit Arora47fd9182010-08-24 13:26:06 +0530157
Daniel Lezcano558a6d52011-03-23 14:37:41 +0100158void show_header(int selectedwindow)
Amit Arora47fd9182010-08-24 13:26:06 +0530159{
160 int i, j = 0;
Amit Kucheria0a4d0192011-01-12 04:54:37 +0530161 int curr_pointer = 0;
Amit Arora47fd9182010-08-24 13:26:06 +0530162
163 wattrset(header_win, COLOR_PAIR(PT_COLOR_HEADER_BAR));
164 wbkgd(header_win, COLOR_PAIR(PT_COLOR_HEADER_BAR));
165 werase(header_win);
166
Amit Kucheria0a4d0192011-01-12 04:54:37 +0530167 print(header_win, curr_pointer, 0, "PowerDebug %s", VERSION);
168 curr_pointer += 20;
Amit Arora47fd9182010-08-24 13:26:06 +0530169
Amit Arora6e774cd2010-10-28 11:31:24 +0530170 for (i = 0; i < TOTAL_FEATURE_WINS; i++) {
171 if (selectedwindow == i)
172 wattron(header_win, A_REVERSE);
173 else
174 wattroff(header_win, A_REVERSE);
Amit Arorac93e0712010-10-07 13:51:53 +0530175
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200176 print(header_win, curr_pointer, 0, " %s ", windata[i].name);
177 curr_pointer += strlen(windata[i].name) + 2;
Amit Arora6e774cd2010-10-28 11:31:24 +0530178 }
179 wrefresh(header_win);
Amit Arora47fd9182010-08-24 13:26:06 +0530180 werase(footer_win);
181
Amit Kucheriaa0adae42011-01-12 10:54:23 -0600182 for (i = 0; i < NUM_FOOTER_ITEMS; i++) {
183 if (strlen(footer_items[i]) == 0)
Amit Arora47fd9182010-08-24 13:26:06 +0530184 continue;
185 wattron(footer_win, A_REVERSE);
186 print(footer_win, j, 0, "%s", footer_items[i]);
187 wattroff(footer_win, A_REVERSE);
188 j+= strlen(footer_items[i])+1;
189 }
190 wrefresh(footer_win);
191}
192
193
Daniel Lezcano833b63a2011-03-26 22:06:00 +0100194void show_regulator_info(struct regulator_info *reg_info, int nr_reg, int verbose)
Amit Arora47fd9182010-08-24 13:26:06 +0530195{
Amit Arorac93e0712010-10-07 13:51:53 +0530196 int i, count = 1;
Amit Arora47fd9182010-08-24 13:26:06 +0530197
Amit Arora6e774cd2010-10-28 11:31:24 +0530198 (void)verbose;
Amit Arorabf50db92010-10-07 14:09:05 +0530199
Amit Arora47fd9182010-08-24 13:26:06 +0530200 werase(regulator_win);
201 wattron(regulator_win, A_BOLD);
Amit Arorac93e0712010-10-07 13:51:53 +0530202 print(regulator_win, 0, 0, "Name");
203 print(regulator_win, 12, 0, "Status");
204 print(regulator_win, 24, 0, "State");
205 print(regulator_win, 36, 0, "Type");
206 print(regulator_win, 48, 0, "Users");
207 print(regulator_win, 60, 0, "Microvolts");
208 print(regulator_win, 72, 0, "Min u-volts");
209 print(regulator_win, 84, 0, "Max u-volts");
Amit Arora47fd9182010-08-24 13:26:06 +0530210 wattroff(regulator_win, A_BOLD);
211
Daniel Lezcano833b63a2011-03-26 22:06:00 +0100212 for (i = 0; i < nr_reg; i++) {
Amit Arora47fd9182010-08-24 13:26:06 +0530213 int col = 0;
214
Amit Kucheriaa0adae42011-01-12 10:54:23 -0600215 if ((i + 2) > (maxy-2))
Amit Arora47fd9182010-08-24 13:26:06 +0530216 break;
217
Daniel Lezcano3bd64f02011-03-26 22:05:56 +0100218 if (reg_info[i].num_users > 0)
Amit Arora6e774cd2010-10-28 11:31:24 +0530219 wattron(regulator_win, WA_BOLD);
220 else
221 wattroff(regulator_win, WA_BOLD);
222
Amit Arora47fd9182010-08-24 13:26:06 +0530223 print(regulator_win, col, count, "%s",
Daniel Lezcano3bd64f02011-03-26 22:05:56 +0100224 reg_info[i].name);
Amit Arora47fd9182010-08-24 13:26:06 +0530225 col += 12;
226 print(regulator_win, col, count, "%s",
Daniel Lezcano3bd64f02011-03-26 22:05:56 +0100227 reg_info[i].status);
Amit Arora47fd9182010-08-24 13:26:06 +0530228 col += 12;
229 print(regulator_win, col, count, "%s",
Daniel Lezcano3bd64f02011-03-26 22:05:56 +0100230 reg_info[i].state);
Amit Arora47fd9182010-08-24 13:26:06 +0530231 col += 12;
232 print(regulator_win, col, count, "%s",
Daniel Lezcano3bd64f02011-03-26 22:05:56 +0100233 reg_info[i].type);
Amit Arora47fd9182010-08-24 13:26:06 +0530234 col += 12;
235 print(regulator_win, col, count, "%d",
Daniel Lezcano3bd64f02011-03-26 22:05:56 +0100236 reg_info[i].num_users);
Amit Arora6a943ec2010-10-07 11:49:25 +0530237 col += 12;
238 print(regulator_win, col, count, "%d",
Daniel Lezcano3bd64f02011-03-26 22:05:56 +0100239 reg_info[i].microvolts);
Amit Arora47fd9182010-08-24 13:26:06 +0530240 col += 12;
241 print(regulator_win, col, count, "%d",
Daniel Lezcano3bd64f02011-03-26 22:05:56 +0100242 reg_info[i].min_microvolts);
Amit Arora47fd9182010-08-24 13:26:06 +0530243 col += 12;
244 print(regulator_win, col, count, "%d",
Daniel Lezcano3bd64f02011-03-26 22:05:56 +0100245 reg_info[i].max_microvolts);
Amit Arora47fd9182010-08-24 13:26:06 +0530246
247 count++;
248 }
249 wrefresh(regulator_win);
250}
251
Amit Arora728e0c92010-09-14 12:06:09 +0530252
Amit Aroraac4e8652010-11-09 11:16:53 +0530253void print_clock_header(void)
Amit Arora728e0c92010-09-14 12:06:09 +0530254{
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200255 werase(clock_labels);
256 wattron(clock_labels, A_BOLD);
257 print(clock_labels, 0, 0, "Name");
258 print(clock_labels, 56, 0, "Flags");
259 print(clock_labels, 75, 0, "Rate");
260 print(clock_labels, 88, 0, "Usecount");
261 print(clock_labels, 98, 0, "Children");
262 wattroff(clock_labels, A_BOLD);
263 wrefresh(clock_labels);
Amit Arora728e0c92010-09-14 12:06:09 +0530264}
265
266void print_sensor_header(void)
267{
Amit Arora6e774cd2010-10-28 11:31:24 +0530268 werase(sensor_win);
269 wattron(sensor_win, A_BOLD);
270 print(sensor_win, 0, 0, "Name");
271 print(sensor_win, 36, 0, "Temperature");
272 wattroff(sensor_win, A_BOLD);
273 wattron(sensor_win, A_BLINK);
274 print(sensor_win, 0, 1, "Currently Sensor information available"
Amit Kucheriaa0adae42011-01-12 10:54:23 -0600275 " only in Dump mode!");
Amit Arora6e774cd2010-10-28 11:31:24 +0530276 wattroff(sensor_win, A_BLINK);
Amit Arora728e0c92010-09-14 12:06:09 +0530277 wrefresh(sensor_win);
278}
279
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200280int display_refresh_pad(int win)
Amit Arora728e0c92010-09-14 12:06:09 +0530281{
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200282 return prefresh(clock_pad, windata[win].scrolling,
283 0, 2, 0, maxy - 2, maxx);
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200284}
Amit Aroraac4e8652010-11-09 11:16:53 +0530285
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200286static int inline display_clock_un_select(int win, int line,
287 bool highlight, bool bold)
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200288{
289 if (mvwchgat(clock_pad, line, 0, -1,
290 highlight ? WA_STANDOUT :
291 bold ? WA_BOLD: WA_NORMAL, 0, NULL) < 0)
292 return -1;
293
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200294 return display_refresh_pad(win);
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200295}
296
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200297int display_select(int win, int line)
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200298{
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200299 return display_clock_un_select(win, line, true, false);
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200300}
301
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200302int display_unselect(int win, int line, bool bold)
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200303{
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200304 return display_clock_un_select(win, line, false, bold);
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200305}
306
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200307void *display_get_row_data(int win)
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200308{
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200309 return windata[win].rowdata[windata[win].cursor].data;
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200310}
311
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200312int display_set_row_data(int win, int line, void *data, int attr)
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200313{
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200314 struct rowdata *rowdata = windata[win].rowdata;
315
316 if (line >= windata[win].nrdata) {
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200317 rowdata = realloc(rowdata, sizeof(struct rowdata) * (line + 1));
318 if (!rowdata)
319 return -1;
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200320 windata[win].nrdata = line + 1;
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200321 }
322
323 rowdata[line].data = data;
324 rowdata[line].attr = attr;
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200325 windata[win].rowdata = rowdata;
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200326
327 return 0;
328}
329
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200330int display_reset_cursor(win)
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200331{
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200332 windata[win].nrdata = 0;
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200333 werase(clock_pad);
334 return wmove(clock_pad, 0, 0);
335}
336
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200337int display_print_line(int win, int line, char *str, int bold, void *data)
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200338{
339 int attr = 0;
340
Amit Arora031263a2010-11-09 11:12:41 +0530341 if (bold)
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200342 attr |= WA_BOLD;
343
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200344 if (line == windata[win].cursor)
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200345 attr |= WA_STANDOUT;
346
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200347 if (display_set_row_data(win, line, data, attr))
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200348 return -1;
349
350 if (attr)
351 wattron(clock_pad, attr);
352
353 wprintw(clock_pad, "%s\n", str);
354
355 if (attr)
356 wattroff(clock_pad, attr);
357
358 return 0;
359}
360
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200361int display_next_line(int win)
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200362{
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200363 int cursor = windata[win].cursor;
364 int nrdata = windata[win].nrdata;
365 int scrolling = windata[win].scrolling;
366 struct rowdata *rowdata = windata[win].rowdata;
367
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200368 if (cursor >= nrdata)
369 return cursor;
370
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200371 display_unselect(win, cursor, rowdata[cursor].attr);
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200372 if (cursor < nrdata - 1) {
373 if (cursor >= (maxy - 4 + scrolling))
374 scrolling++;
375 cursor++;
376 }
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200377 display_select(win, cursor);
378
379 windata[win].scrolling = scrolling;
380 windata[win].cursor = cursor;
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200381
382 return cursor;
383}
384
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200385int display_prev_line(int win)
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200386{
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200387 int cursor = windata[win].cursor;
388 int nrdata = windata[win].nrdata;
389 int scrolling = windata[win].scrolling;
390 struct rowdata *rowdata = windata[win].rowdata;
391
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200392 if (cursor >= nrdata)
393 return cursor;
394
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200395 display_unselect(win, cursor, rowdata[cursor].attr);
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200396 if (cursor > 0) {
397 if (cursor <= scrolling)
398 scrolling--;
399 cursor--;
400 }
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200401 display_select(win, cursor);
402
403 windata[win].scrolling = scrolling;
404 windata[win].cursor = cursor;
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200405
406 return cursor;
Amit Arora728e0c92010-09-14 12:06:09 +0530407}