2 * Copyright (C) 2013 IBM Corporation
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; version 2 of the License.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 #if defined(HAVE_CONFIG_H)
24 #include <talloc/talloc.h>
25 #include <types/types.h>
27 #include <fold/fold.h>
28 #include <util/util.h>
29 #include <i18n/i18n.h>
32 #include "nc-textscreen.h"
34 struct text_screen *text_screen_from_scr(struct nc_scr *scr)
36 struct text_screen *text_screen;
37 assert(scr->sig == pb_text_screen_sig);
38 text_screen = container_of(scr, struct text_screen, scr);
42 void text_screen_draw(struct text_screen *screen)
44 int max_y, max_x, i, len;
46 max_y = getmaxy(screen->scr.sub_ncw);
47 max_x = getmaxx(screen->scr.sub_ncw) - 1;
49 max_y = min(max_y, screen->scroll_y + screen->n_lines);
51 for (i = screen->scroll_y; i < max_y; i++) {
52 len = strncols(screen->lines[i]) > max_x ? max_x : -1;
53 mvwaddnstr(screen->scr.sub_ncw, i, 1, screen->lines[i], len);
56 wrefresh(screen->scr.sub_ncw);
59 static void text_screen_scroll(struct text_screen *screen, int key)
61 int win_lines = getmaxy(screen->scr.sub_ncw);
62 int win_cols = getmaxx(screen->scr.sub_ncw) - 1;
67 else if (key == KEY_DOWN)
72 if (screen->scroll_y + delta < 0)
74 if (screen->scroll_y + delta + win_lines > screen->n_lines)
77 screen->scroll_y += delta;
78 wscrl(screen->scr.sub_ncw, delta);
82 i = screen->scroll_y + win_lines - 1;
83 len = strncols(screen->lines[i]) > win_cols ? win_cols : -1;
84 mvwaddnstr(screen->scr.sub_ncw, win_lines - 1, 1,
85 screen->lines[i], len);
86 } else if (delta < 0) {
88 len = strncols(screen->lines[i]) > win_cols ? win_cols : -1;
89 mvwaddnstr(screen->scr.sub_ncw, 0, 1, screen->lines[i], len);
92 wrefresh(screen->scr.sub_ncw);
95 void text_screen_clear(struct text_screen *screen)
97 talloc_free(screen->lines);
99 screen->n_alloc_lines = 16;
100 screen->lines = talloc_array(screen, const char *,
101 screen->n_alloc_lines);
104 static void __text_screen_append_line(struct text_screen *screen,
107 if (screen->n_lines == screen->n_alloc_lines) {
108 screen->n_alloc_lines *= 2;
109 screen->lines = talloc_realloc(screen, screen->lines,
111 screen->n_alloc_lines);
114 screen->lines[screen->n_lines] = line;
118 void text_screen_append_line(struct text_screen *screen, const char *fmt, ...)
125 line = talloc_vasprintf(screen->lines, fmt, ap);
131 __text_screen_append_line(screen, line);
134 static int text_screen_fold_cb(void *arg, const char *buf, int len)
136 struct text_screen *screen = arg;
138 buf = len ? talloc_strndup(screen->lines, buf, len) : "";
139 __text_screen_append_line(screen, buf);
144 void text_screen_set_text(struct text_screen *screen, const char *text)
146 fold_text(text, getmaxx(screen->scr.sub_ncw) - 1, text_screen_fold_cb,
150 void text_screen_process_key(struct nc_scr *scr, int key)
152 struct text_screen *screen = text_screen_from_scr(scr);
157 screen->on_exit(screen->cui);
161 text_screen_scroll(screen, key);
164 if (screen->help_text)
165 cui_show_help(screen->cui, screen->help_title,
173 static void text_screen_resize(struct nc_scr *scr)
175 struct text_screen *screen = text_screen_from_scr(scr);
176 text_screen_draw(screen);
179 struct nc_scr *text_screen_scr(struct text_screen *screen)
184 void text_screen_set_help(struct text_screen *screen, const char *title,
185 const struct help_text *text)
187 screen->help_title = title;
188 screen->help_text = text;
189 screen->scr.frame.help = _("x=exit, h=help");
192 static int text_screen_post(struct nc_scr *scr)
194 struct text_screen *screen = text_screen_from_scr(scr);
196 if (screen->need_update) {
197 text_screen_draw(screen);
198 screen->need_update = false;
201 nc_scr_frame_draw(scr);
202 redrawwin(scr->main_ncw);
203 wrefresh(scr->main_ncw);
207 void text_screen_init(struct text_screen *screen, struct cui *cui,
208 const char *title, void (*on_exit)(struct cui *))
210 nc_scr_init(&screen->scr, pb_text_screen_sig, 0,
211 cui, text_screen_process_key,
212 text_screen_post, NULL, text_screen_resize);
214 /* this will establish our array of lines */
215 screen->lines = NULL;
216 text_screen_clear(screen);
219 screen->on_exit = on_exit;
220 screen->need_update = false;
222 screen->scr.frame.ltitle = talloc_strdup(screen, title);
223 screen->scr.frame.rtitle = NULL;
224 screen->scr.frame.help = _("x=exit");
225 scrollok(screen->scr.sub_ncw, true);