lib/pb-config: Implement config_set
[petitboot] / ui / ncurses / nc-scr.c
1 /*
2  *  Copyright (C) 2009 Sony Computer Entertainment Inc.
3  *  Copyright 2009 Sony Corp.
4  *
5  *  This program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; version 2 of the License.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with this program; if not, write to the Free Software
16  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17  */
18
19 #include "config.h"
20
21 #define _GNU_SOURCE
22
23 #include <assert.h>
24 #include <stdarg.h>
25 #include <string.h>
26
27 #include "log/log.h"
28 #include "talloc/talloc.h"
29
30 #include "nc-scr.h"
31
32 void nc_start(void)
33 {
34         initscr();                      /* Initialize ncurses. */
35         cbreak();                       /* Disable line buffering. */
36         noecho();                       /* Disable getch() echo. */
37         keypad(stdscr, TRUE);           /* Enable num keypad keys. */
38         nonl();                         /* Disable new-line translation. */
39         intrflush(stdscr, FALSE);       /* Disable interrupt flush. */
40         curs_set(0);                    /* Make cursor invisible */
41         nodelay(stdscr, TRUE);          /* Enable non-blocking getch() */
42
43         /* We may be operating with an incorrect $TERM type; in this case
44          * the keymappings will be slightly broken. We want at least
45          * backspace to work though, so we'll define both DEL and ^H to
46          * map to backspace */
47         define_key("\x7f", KEY_BACKSPACE);
48         define_key("\x08", KEY_BACKSPACE);
49
50         while (getch() != ERR)          /* flush stdin */
51                 (void)0;
52 }
53
54 void nc_atexit(void)
55 {
56         clear();
57         refresh();
58         endwin();
59 }
60
61 static void nc_scr_status_clear(struct nc_scr *scr)
62 {
63         mvwhline(scr->main_ncw, LINES - nc_scr_pos_status, 0, ' ', COLS);
64 }
65
66 static void nc_scr_status_draw(struct nc_scr *scr)
67 {
68         mvwaddstr(scr->main_ncw, LINES - nc_scr_pos_status, 1,
69                 scr->frame.status);
70 }
71
72 void nc_scr_frame_draw(struct nc_scr *scr)
73 {
74         int ltitle_len, rtitle_len;
75
76         DBGS("ltitle '%s'\n", scr->frame.ltitle);
77         DBGS("rtitle '%s'\n", scr->frame.rtitle);
78         DBGS("help '%s'\n", scr->frame.help);
79         DBGS("status '%s'\n", scr->frame.status);
80
81         ltitle_len = strlen(scr->frame.ltitle);
82         rtitle_len = scr->frame.rtitle ? strlen(scr->frame.rtitle) : 0;
83
84         /* if both ltitle and rtitle don't fit, trim rtitle */
85         if (ltitle_len + rtitle_len + nc_scr_pos_lrtitle_space > COLS - 2)
86                 rtitle_len = COLS - 2 - ltitle_len - nc_scr_pos_lrtitle_space;
87
88         mvwaddstr(scr->main_ncw, nc_scr_pos_title, 1, scr->frame.ltitle);
89         mvwaddnstr(scr->main_ncw, nc_scr_pos_title, COLS - rtitle_len - 1,
90                         scr->frame.rtitle, rtitle_len);
91         mvwhline(scr->main_ncw, nc_scr_pos_title_sep, 1, ACS_HLINE, COLS - 2);
92
93         mvwhline(scr->main_ncw, LINES - nc_scr_pos_help_sep, 1, ACS_HLINE,
94                 COLS - 2);
95         mvwaddstr(scr->main_ncw, LINES - nc_scr_pos_help, 1, scr->frame.help);
96         nc_scr_status_draw(scr);
97 }
98
99 void nc_scr_status_free(struct nc_scr *scr)
100 {
101         talloc_free(scr->frame.status);
102         scr->frame.status = NULL;
103         nc_scr_status_clear(scr);
104 }
105
106 /**
107  * nc_scr_status_printf - Set the text of the scr status using sprintf.
108  * @scr: The scr to opperate on.
109  * @text: The status text.
110  *
111  * The caller is reponsible for calling scr_draw() to update the display.
112  */
113
114 void nc_scr_status_printf(struct nc_scr *scr, const char *format, ...)
115 {
116         va_list ap;
117
118         nc_scr_status_free(scr);
119
120         va_start(ap, format);
121         scr->frame.status = talloc_vasprintf(scr, format, ap);
122         va_end(ap);
123
124         nc_scr_status_draw(scr);
125         wrefresh(scr->main_ncw);
126 }
127
128 int nc_scr_init(struct nc_scr *scr, enum pb_nc_sig sig, int begin_x,
129         void *ui_ctx,
130         void (*process_key)(struct nc_scr *, int),
131         int (*post)(struct nc_scr *),
132         int (*unpost)(struct nc_scr *),
133         void (*resize)(struct nc_scr *))
134 {
135         scr->sig = sig;
136         scr->ui_ctx = ui_ctx;
137         scr->process_key = process_key;
138         scr->post = post;
139         scr->unpost = unpost;
140         scr->resize = resize;
141
142         scr->main_ncw = newwin(LINES, COLS, 0, 0);
143
144         scr->sub_ncw = derwin(scr->main_ncw,
145                 LINES - nc_scr_frame_lines,
146                 COLS - 1 - begin_x,
147                 nc_scr_pos_sub,
148                 begin_x);
149
150         assert(scr->main_ncw);
151         assert(scr->sub_ncw);
152
153         return scr->main_ncw && scr->sub_ncw;
154 }