blob: 12eb052efa03f36b1b7dacea17d3f9cccfd50bf1 [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>
Daniel Lezcano5000abd2011-06-21 00:57:08 +020020#include <sys/types.h>
21#include <regex.h>
Amit Arora47fd9182010-08-24 13:26:06 +053022#include "powerdebug.h"
Daniel Lezcanodb145802011-06-21 00:57:08 +020023#include "mainloop.h"
Amit Arora17552782010-12-02 12:23:14 +053024#include "regulator.h"
Amit Aroraed3e5652010-10-27 12:02:53 +053025#include "display.h"
Amit Arora47fd9182010-08-24 13:26:06 +053026
Daniel Lezcanoeeb13762011-03-26 22:06:17 +010027enum { PT_COLOR_DEFAULT = 1,
28 PT_COLOR_HEADER_BAR,
29 PT_COLOR_ERROR,
30 PT_COLOR_RED,
31 PT_COLOR_YELLOW,
32 PT_COLOR_GREEN,
33 PT_COLOR_BRIGHT,
34 PT_COLOR_BLUE,
35};
36
Amit Arora47fd9182010-08-24 13:26:06 +053037static WINDOW *header_win;
Amit Arora47fd9182010-08-24 13:26:06 +053038static WINDOW *footer_win;
Daniel Lezcanoc196d432011-06-21 00:57:08 +020039static WINDOW *main_win;
Daniel Lezcanod96731a2011-06-15 15:45:12 +020040static int current_win;
Amit Arora47fd9182010-08-24 13:26:06 +053041
Daniel Lezcano2adc48d2011-06-08 23:30:01 +020042/* Number of lines in the virtual window */
43static const int maxrows = 1024;
44
Daniel Lezcano2adc48d2011-06-08 23:30:01 +020045struct rowdata {
46 int attr;
47 void *data;
48};
49
Daniel Lezcanob3e6e812011-06-15 15:45:12 +020050struct windata {
Daniel Lezcanof6656822011-06-15 15:45:12 +020051 WINDOW *pad;
Daniel Lezcanob301b082011-06-15 15:45:12 +020052 struct display_ops *ops;
Daniel Lezcanob3e6e812011-06-15 15:45:12 +020053 struct rowdata *rowdata;
54 char *name;
55 int nrdata;
56 int scrolling;
57 int cursor;
58};
59
Daniel Lezcano4120e262011-06-15 15:45:12 +020060/* Warning this is linked with the enum { CLOCK, REGULATOR, ... } */
Daniel Lezcano176e69d2011-06-15 15:45:12 +020061struct windata windata[] = {
Daniel Lezcano4120e262011-06-15 15:45:12 +020062 [CLOCK] = { .name = "Clocks" },
63 [REGULATOR] = { .name = "Regulators" },
64 [SENSOR] = { .name = "Sensors" },
Daniel Lezcanob3e6e812011-06-15 15:45:12 +020065};
Daniel Lezcano2adc48d2011-06-08 23:30:01 +020066
Daniel Lezcano3abd8b12011-03-26 22:06:15 +010067static void display_fini(void)
68{
69 endwin();
70}
71
Daniel Lezcano653cb4a2011-06-21 00:57:08 +020072static int display_show_header(int win)
Daniel Lezcano7b3da502011-06-15 15:45:12 +020073{
74 int i;
75 int curr_pointer = 0;
Daniel Lezcano4120e262011-06-15 15:45:12 +020076 size_t array_size = sizeof(windata) / sizeof(windata[0]);
Daniel Lezcano7b3da502011-06-15 15:45:12 +020077
78 wattrset(header_win, COLOR_PAIR(PT_COLOR_HEADER_BAR));
79 wbkgd(header_win, COLOR_PAIR(PT_COLOR_HEADER_BAR));
80 werase(header_win);
81
Daniel Lezcanoc757e6d2011-06-21 00:57:08 +020082 mvwprintw(header_win, 0, curr_pointer, "PowerDebug %s", VERSION);
Daniel Lezcano7b3da502011-06-15 15:45:12 +020083 curr_pointer += 20;
84
Daniel Lezcano4120e262011-06-15 15:45:12 +020085 for (i = 0; i < array_size; i++) {
Daniel Lezcano7b3da502011-06-15 15:45:12 +020086 if (win == i)
87 wattron(header_win, A_REVERSE);
88 else
89 wattroff(header_win, A_REVERSE);
90
Daniel Lezcanoc757e6d2011-06-21 00:57:08 +020091 mvwprintw(header_win, 0, curr_pointer, " %s ", windata[i].name);
Daniel Lezcano7b3da502011-06-15 15:45:12 +020092 curr_pointer += strlen(windata[i].name) + 2;
93 }
94 wrefresh(header_win);
Daniel Lezcano7b3da502011-06-15 15:45:12 +020095
Daniel Lezcano653cb4a2011-06-21 00:57:08 +020096 return 0;
97}
98
99#define footer_label " Q (Quit) R (Refresh) Other Keys: 'Left', " \
100 "'Right' , 'Up', 'Down', 'enter', , 'Esc'"
101
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200102static int display_show_footer(int win, char *string)
Daniel Lezcano653cb4a2011-06-21 00:57:08 +0200103{
104 werase(footer_win);
Daniel Lezcano7b3da502011-06-15 15:45:12 +0200105 wattron(footer_win, A_REVERSE);
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200106 mvwprintw(footer_win, 0, 0, "%s", string ? string : footer_label);
Daniel Lezcano7b3da502011-06-15 15:45:12 +0200107 wattroff(footer_win, A_REVERSE);
108 wrefresh(footer_win);
109
110 return 0;
111}
112
Daniel Lezcanodb145802011-06-21 00:57:08 +0200113int display_refresh(int win)
Amit Arora47fd9182010-08-24 13:26:06 +0530114{
Daniel Lezcanodb145802011-06-21 00:57:08 +0200115 /* we are trying to refresh a window which is not showed */
116 if (win != current_win)
117 return 0;
Daniel Lezcanof6656822011-06-15 15:45:12 +0200118
Daniel Lezcanodb145802011-06-21 00:57:08 +0200119 if (windata[win].ops && windata[win].ops->display)
120 return windata[win].ops->display();
Daniel Lezcano971515a2011-06-15 15:45:12 +0200121
122 return 0;
123}
124
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200125int display_refresh_pad(int win)
Amit Arora728e0c92010-09-14 12:06:09 +0530126{
Daniel Lezcano0a8cc582011-06-21 00:57:08 +0200127 int maxx, maxy;
128
129 getmaxyx(stdscr, maxy, maxx);
130
Daniel Lezcanof6656822011-06-15 15:45:12 +0200131 return prefresh(windata[win].pad, windata[win].scrolling,
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200132 0, 2, 0, maxy - 2, maxx);
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200133}
Amit Aroraac4e8652010-11-09 11:16:53 +0530134
Daniel Lezcano28203df2011-06-15 15:45:12 +0200135static int display_show_unselection(int win, int line, bool bold)
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200136{
Daniel Lezcanof6656822011-06-15 15:45:12 +0200137 if (mvwchgat(windata[win].pad, line, 0, -1,
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200138 bold ? WA_BOLD: WA_NORMAL, 0, NULL) < 0)
139 return -1;
140
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200141 return display_refresh_pad(win);
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200142}
143
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200144void *display_get_row_data(int win)
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200145{
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200146 return windata[win].rowdata[windata[win].cursor].data;
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200147}
148
Daniel Lezcano28203df2011-06-15 15:45:12 +0200149static int display_select(void)
150{
151 if (windata[current_win].ops && windata[current_win].ops->select)
152 return windata[current_win].ops->select();
153
154 return 0;
155}
156
157static int display_next_panel(void)
158{
159 size_t array_size = sizeof(windata) / sizeof(windata[0]);
160
161 current_win++;
162 current_win %= array_size;
163
164 return current_win;
165}
166
167static int display_prev_panel(void)
168{
169 size_t array_size = sizeof(windata) / sizeof(windata[0]);
170
171 current_win--;
172 if (current_win < 0)
173 current_win = array_size - 1;
174
175 return current_win;
176}
177
178static int display_next_line(void)
179{
Daniel Lezcano0a8cc582011-06-21 00:57:08 +0200180 int maxx, maxy;
Daniel Lezcano28203df2011-06-15 15:45:12 +0200181 int cursor = windata[current_win].cursor;
182 int nrdata = windata[current_win].nrdata;
183 int scrolling = windata[current_win].scrolling;
184 struct rowdata *rowdata = windata[current_win].rowdata;
185
Daniel Lezcano0a8cc582011-06-21 00:57:08 +0200186 getmaxyx(stdscr, maxy, maxx);
187
Daniel Lezcano28203df2011-06-15 15:45:12 +0200188 if (cursor >= nrdata)
189 return cursor;
190
191 display_show_unselection(current_win, cursor, rowdata[cursor].attr);
192 if (cursor < nrdata - 1) {
193 if (cursor >= (maxy - 4 + scrolling))
194 scrolling++;
195 cursor++;
196 }
197
198 windata[current_win].scrolling = scrolling;
199 windata[current_win].cursor = cursor;
200
201 return cursor;
202}
203
204static int display_prev_line(void)
205{
206 int cursor = windata[current_win].cursor;
207 int nrdata = windata[current_win].nrdata;
208 int scrolling = windata[current_win].scrolling;
209 struct rowdata *rowdata = windata[current_win].rowdata;
210
211 if (cursor >= nrdata)
212 return cursor;
213
214 display_show_unselection(current_win, cursor, rowdata[cursor].attr);
215 if (cursor > 0) {
216 if (cursor <= scrolling)
217 scrolling--;
218 cursor--;
219 }
220
221 windata[current_win].scrolling = scrolling;
222 windata[current_win].cursor = cursor;
223
224 return cursor;
225}
226
227static int display_set_row_data(int win, int line, void *data, int attr)
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200228{
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200229 struct rowdata *rowdata = windata[win].rowdata;
230
231 if (line >= windata[win].nrdata) {
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200232 rowdata = realloc(rowdata, sizeof(struct rowdata) * (line + 1));
233 if (!rowdata)
234 return -1;
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200235 windata[win].nrdata = line + 1;
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200236 }
237
238 rowdata[line].data = data;
239 rowdata[line].attr = attr;
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200240 windata[win].rowdata = rowdata;
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200241
242 return 0;
243}
244
Daniel Lezcanof6656822011-06-15 15:45:12 +0200245int display_reset_cursor(int win)
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200246{
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200247 windata[win].nrdata = 0;
Daniel Lezcanof6656822011-06-15 15:45:12 +0200248 werase(windata[win].pad);
249 return wmove(windata[win].pad, 0, 0);
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200250}
251
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200252int display_print_line(int win, int line, char *str, int bold, void *data)
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200253{
254 int attr = 0;
255
Amit Arora031263a2010-11-09 11:12:41 +0530256 if (bold)
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200257 attr |= WA_BOLD;
258
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200259 if (line == windata[win].cursor)
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200260 attr |= WA_STANDOUT;
261
Daniel Lezcanob3e6e812011-06-15 15:45:12 +0200262 if (display_set_row_data(win, line, data, attr))
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200263 return -1;
264
265 if (attr)
Daniel Lezcanof6656822011-06-15 15:45:12 +0200266 wattron(windata[win].pad, attr);
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200267
Daniel Lezcanof6656822011-06-15 15:45:12 +0200268 wprintw(windata[win].pad, "%s\n", str);
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200269
270 if (attr)
Daniel Lezcanof6656822011-06-15 15:45:12 +0200271 wattroff(windata[win].pad, attr);
Daniel Lezcano2adc48d2011-06-08 23:30:01 +0200272
273 return 0;
274}
275
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200276static int display_find_keystroke(int fd, void *data);
277
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200278struct find_data {
279 size_t len;
280 char *string;
281 regex_t *reg;
282};
283
284struct find_data *display_find_form_init(void)
285{
286 const char *regexp = "^[a-z|0-9|_|-|.]";
287 struct find_data *findd;
288 const size_t len = 64;
289 regex_t *reg;
290 char *search4;
291 int maxx, maxy;
292
293 getmaxyx(stdscr, maxy, maxx);
294
295 reg = malloc(sizeof(*reg));
296 if (!reg)
297 return NULL;
298
299 if (regcomp(reg, regexp, REG_ICASE))
300 goto out_free_reg;
301
302 search4 = malloc(len);
303 if (!search4)
304 goto out_free_regcomp;
305 memset(search4, '\0', len);
306
307 findd = malloc(sizeof(*findd));
308 if (!findd)
309 goto out_free_search4;
310
311 findd->string = search4;
312 findd->reg = reg;
313 findd->len = len;
314out:
315 return findd;
316
317out_free_search4:
318 free(search4);
319out_free_regcomp:
320 regfree(reg);
321out_free_reg:
322 free(reg);
323
324 goto out;
325}
326
327static void display_find_form_fini(struct find_data *fd)
328{
329 regfree(fd->reg);
330 free(fd->string);
331 free(fd);
332 curs_set(0);
333}
334
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200335static int display_switch_to_find(int fd)
336{
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200337 struct find_data *findd;
338
339 findd = display_find_form_init();
340 if (!findd)
341 return -1;
342
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200343 if (mainloop_del(fd))
344 return -1;
345
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200346 if (mainloop_add(fd, display_find_keystroke, findd))
347 return -1;
348
349 if (display_show_footer(current_win, "find (esc to exit)?"))
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200350 return -1;
351
352 return 0;
353}
354
Daniel Lezcanodb145802011-06-21 00:57:08 +0200355static int display_keystroke(int fd, void *data)
Daniel Lezcano176e69d2011-06-15 15:45:12 +0200356{
Daniel Lezcano176e69d2011-06-15 15:45:12 +0200357 int keystroke = getch();
358
359 switch (keystroke) {
360
361 case KEY_RIGHT:
362 case '\t':
Daniel Lezcano372ffba2011-06-21 00:57:08 +0200363 display_show_header(display_next_panel());
Daniel Lezcano176e69d2011-06-15 15:45:12 +0200364 break;
365
366 case KEY_LEFT:
367 case KEY_BTAB:
Daniel Lezcano372ffba2011-06-21 00:57:08 +0200368 display_show_header(display_prev_panel());
Daniel Lezcano176e69d2011-06-15 15:45:12 +0200369 break;
370
371 case KEY_DOWN:
372 display_next_line();
373 break;
374
375 case KEY_UP:
376 display_prev_line();
377 break;
378
379 case '\r':
380 display_select();
381 break;
382
383 case EOF:
384 case 'q':
385 case 'Q':
386 return 1;
387
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200388 case '/':
389 return display_switch_to_find(fd);
390
Daniel Lezcano176e69d2011-06-15 15:45:12 +0200391 case 'r':
392 case 'R':
Daniel Lezcanodb145802011-06-21 00:57:08 +0200393 /* refresh will be done after */
Daniel Lezcano176e69d2011-06-15 15:45:12 +0200394 break;
Daniel Lezcanodb145802011-06-21 00:57:08 +0200395 default:
396 return 0;
Daniel Lezcano176e69d2011-06-15 15:45:12 +0200397 }
398
Daniel Lezcanodb145802011-06-21 00:57:08 +0200399 display_refresh(current_win);
400
401 return 0;
402}
403
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200404static int display_switch_to_main(int fd)
405{
406 if (mainloop_del(fd))
407 return -1;
408
409 if (mainloop_add(fd, display_keystroke, NULL))
410 return -1;
411
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200412 if (display_show_header(current_win))
413 return -1;
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200414
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200415 if (display_show_footer(current_win, NULL))
416 return -1;
417
418 return display_refresh(current_win);
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200419}
420
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200421static int display_find_keystroke(int fd, void *data)
422{
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200423 struct find_data *findd = data;
424 regex_t *reg = findd->reg;
425 char *string = findd->string;
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200426 int keystroke = getch();
427
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200428 char match[2] = { [0] = (char)keystroke, [1] = '\0' };
429 regmatch_t m[1];
430
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200431 switch (keystroke) {
432
433 case '\e':
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200434 display_find_form_fini(findd);
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200435 return display_switch_to_main(fd);
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200436
437 case KEY_BACKSPACE:
438 if (strlen(string))
439 string[strlen(string) - 1] = '\0';
440 break;
441
442 case KEY_ENTER:
443 /* next patch */
444 break;
445
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200446 default:
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200447
448 /* We don't want invalid characters for a name */
449 if (regexec(reg, match, 1, m, 0))
450 return 0;
451
452 if (strlen(string) < findd->len - 1)
453 string[strlen(string)] = (char)keystroke;
454
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200455 break;
456 }
457
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200458 if (display_show_header(current_win))
459 return -1;
460
461 if (display_refresh(current_win))
462 return -1;
463
464 if (display_show_footer(current_win, strlen(string) ? string :
465 "find (esc to exit)?"))
466 return -1;
467
Daniel Lezcanoe64c48e2011-06-21 00:57:08 +0200468 return 0;
469}
470
Daniel Lezcanodb145802011-06-21 00:57:08 +0200471int display_init(int wdefault)
472{
Daniel Lezcano0a8cc582011-06-21 00:57:08 +0200473 int i, maxx, maxy;
Daniel Lezcanodb145802011-06-21 00:57:08 +0200474 size_t array_size = sizeof(windata) / sizeof(windata[0]);
475
476 current_win = wdefault;
477
478 if (mainloop_add(0, display_keystroke, NULL))
479 return -1;
480
481 if (!initscr())
482 return -1;
483
484 start_color();
485 use_default_colors();
486
487 keypad(stdscr, TRUE);
488 noecho();
489 cbreak();
490 curs_set(0);
491 nonl();
492
493 if (init_pair(PT_COLOR_DEFAULT, COLOR_WHITE, COLOR_BLACK) ||
494 init_pair(PT_COLOR_ERROR, COLOR_BLACK, COLOR_RED) ||
495 init_pair(PT_COLOR_HEADER_BAR, COLOR_WHITE, COLOR_BLACK) ||
496 init_pair(PT_COLOR_YELLOW, COLOR_WHITE, COLOR_YELLOW) ||
497 init_pair(PT_COLOR_GREEN, COLOR_WHITE, COLOR_GREEN) ||
498 init_pair(PT_COLOR_BRIGHT, COLOR_WHITE, COLOR_BLACK) ||
499 init_pair(PT_COLOR_BLUE, COLOR_WHITE, COLOR_BLUE) ||
500 init_pair(PT_COLOR_RED, COLOR_WHITE, COLOR_RED))
501 return -1;
502
503 if (atexit(display_fini))
504 return -1;
505
506 getmaxyx(stdscr, maxy, maxx);
507
508 for (i = 0; i < array_size; i++) {
509
Daniel Lezcanoc196d432011-06-21 00:57:08 +0200510 main_win = subwin(stdscr, maxy - 2, maxx, 1, 0);
511 if (!main_win)
Daniel Lezcanodb145802011-06-21 00:57:08 +0200512 return -1;
513
514 windata[i].pad = newpad(maxrows, maxx);
515 if (!windata[i].pad)
516 return -1;
517
518 }
519
520 header_win = subwin(stdscr, 1, maxx, 0, 0);
521 if (!header_win)
522 return -1;
523
524 footer_win = subwin(stdscr, 1, maxx, maxy-1, 0);
525 if (!footer_win)
526 return -1;
527
Daniel Lezcano653cb4a2011-06-21 00:57:08 +0200528 if (display_show_header(wdefault))
529 return -1;
530
Daniel Lezcano5000abd2011-06-21 00:57:08 +0200531 if (display_show_footer(wdefault, NULL))
Daniel Lezcanodb145802011-06-21 00:57:08 +0200532 return -1;
533
534 return display_refresh(wdefault);
535}
536
Daniel Lezcano372ffba2011-06-21 00:57:08 +0200537int display_column_name(const char *line)
Daniel Lezcanodb145802011-06-21 00:57:08 +0200538{
Daniel Lezcanoc196d432011-06-21 00:57:08 +0200539 werase(main_win);
540 wattron(main_win, A_BOLD);
Daniel Lezcanofa453332011-06-21 00:57:08 +0200541 mvwprintw(main_win, 0, 0, "%s", line);
Daniel Lezcanoc196d432011-06-21 00:57:08 +0200542 wattroff(main_win, A_BOLD);
543 wrefresh(main_win);
Daniel Lezcanodb145802011-06-21 00:57:08 +0200544
Daniel Lezcano372ffba2011-06-21 00:57:08 +0200545 return 0;
Daniel Lezcanodb145802011-06-21 00:57:08 +0200546}
547
548int display_register(int win, struct display_ops *ops)
549{
550 size_t array_size = sizeof(windata) / sizeof(windata[0]);
551
552 if (win < 0 || win >= array_size)
553 return -1;
554
555 windata[win].ops = ops;
556
Daniel Lezcano176e69d2011-06-15 15:45:12 +0200557 return 0;
558}