Chameleon

Chameleon Svn Source Tree

Root/tags/2.0/i386/config/textbox.c

Source at commit 1808 created 12 years 3 months ago.
By blackosx, Revise layout of package installer 'Welcome' file so it looks cleaner. Change the copyright notice to begin from 2009 as seen in the Chameleon 2.0 r431 installer. Should this date be set earlier?
1/*
2 * textbox.c -- implements the text box
3 *
4 * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
5 * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#include "dialog.h"
23
24static void back_lines(int n);
25static void print_page(WINDOW * win, int height, int width);
26static void print_line(WINDOW * win, int row, int width);
27static char *get_line(void);
28static void print_position(WINDOW * win);
29
30static int hscroll;
31static int begin_reached, end_reached, page_length;
32static const char *buf;
33static const char *page;
34
35/*
36 * refresh window content
37 */
38static void refresh_text_box(WINDOW *dialog, WINDOW *box, int boxh, int boxw,
39 int cur_y, int cur_x)
40{
41print_page(box, boxh, boxw);
42print_position(dialog);
43wmove(dialog, cur_y, cur_x);/* Restore cursor position */
44wrefresh(dialog);
45}
46
47
48/*
49 * Display text from a file in a dialog box.
50 */
51int dialog_textbox(const char *title, const char *tbuf,
52 int initial_height, int initial_width)
53{
54int i, x, y, cur_x, cur_y, key = 0;
55int height, width, boxh, boxw;
56int passed_end;
57WINDOW *dialog, *box;
58
59begin_reached = 1;
60end_reached = 0;
61page_length = 0;
62hscroll = 0;
63buf = tbuf;
64page = buf;/* page is pointer to start of page to be displayed */
65
66do_resize:
67getmaxyx(stdscr, height, width);
68if (height < 8 || width < 8)
69return -ERRDISPLAYTOOSMALL;
70if (initial_height != 0)
71height = initial_height;
72else
73if (height > 4)
74height -= 4;
75else
76height = 0;
77if (initial_width != 0)
78width = initial_width;
79else
80if (width > 5)
81width -= 5;
82else
83width = 0;
84
85/* center dialog box on screen */
86x = (COLS - width) / 2;
87y = (LINES - height) / 2;
88
89draw_shadow(stdscr, y, x, height, width);
90
91dialog = newwin(height, width, y, x);
92keypad(dialog, TRUE);
93
94/* Create window for box region, used for scrolling text */
95boxh = height - 4;
96boxw = width - 2;
97box = subwin(dialog, boxh, boxw, y + 1, x + 1);
98wattrset(box, dlg.dialog.atr);
99wbkgdset(box, dlg.dialog.atr & A_COLOR);
100
101keypad(box, TRUE);
102
103/* register the new window, along with its borders */
104draw_box(dialog, 0, 0, height, width,
105 dlg.dialog.atr, dlg.border.atr);
106
107wattrset(dialog, dlg.border.atr);
108mvwaddch(dialog, height - 3, 0, ACS_LTEE);
109for (i = 0; i < width - 2; i++)
110waddch(dialog, ACS_HLINE);
111wattrset(dialog, dlg.dialog.atr);
112wbkgdset(dialog, dlg.dialog.atr & A_COLOR);
113waddch(dialog, ACS_RTEE);
114
115print_title(dialog, title, width);
116
117print_button(dialog, gettext(" Exit "), height - 2, width / 2 - 4, TRUE);
118wnoutrefresh(dialog);
119getyx(dialog, cur_y, cur_x);/* Save cursor position */
120
121/* Print first page of text */
122attr_clear(box, boxh, boxw, dlg.dialog.atr);
123refresh_text_box(dialog, box, boxh, boxw, cur_y, cur_x);
124
125while ((key != KEY_ESC) && (key != '\n')) {
126key = wgetch(dialog);
127switch (key) {
128case 'E':/* Exit */
129case 'e':
130case 'X':
131case 'x':
132delwin(box);
133delwin(dialog);
134return 0;
135case 'g':/* First page */
136case KEY_HOME:
137if (!begin_reached) {
138begin_reached = 1;
139page = buf;
140refresh_text_box(dialog, box, boxh, boxw,
141 cur_y, cur_x);
142}
143break;
144case 'G':/* Last page */
145case KEY_END:
146
147end_reached = 1;
148/* point to last char in buf */
149page = buf + strlen(buf);
150back_lines(boxh);
151refresh_text_box(dialog, box, boxh, boxw,
152 cur_y, cur_x);
153break;
154case 'K':/* Previous line */
155case 'k':
156case KEY_UP:
157if (!begin_reached) {
158back_lines(page_length + 1);
159
160/* We don't call print_page() here but use
161 * scrolling to ensure faster screen update.
162 * However, 'end_reached' and 'page_length'
163 * should still be updated, and 'page' should
164 * point to start of next page. This is done
165 * by calling get_line() in the following
166 * 'for' loop. */
167scrollok(box, TRUE);
168wscrl(box, -1);/* Scroll box region down one line */
169scrollok(box, FALSE);
170page_length = 0;
171passed_end = 0;
172for (i = 0; i < boxh; i++) {
173if (!i) {
174/* print first line of page */
175print_line(box, 0, boxw);
176wnoutrefresh(box);
177} else
178/* Called to update 'end_reached' and 'page' */
179get_line();
180if (!passed_end)
181page_length++;
182if (end_reached && !passed_end)
183passed_end = 1;
184}
185
186print_position(dialog);
187wmove(dialog, cur_y, cur_x);/* Restore cursor position */
188wrefresh(dialog);
189}
190break;
191case 'B':/* Previous page */
192case 'b':
193case KEY_PPAGE:
194if (begin_reached)
195break;
196back_lines(page_length + boxh);
197refresh_text_box(dialog, box, boxh, boxw,
198 cur_y, cur_x);
199break;
200case 'J':/* Next line */
201case 'j':
202case KEY_DOWN:
203if (!end_reached) {
204begin_reached = 0;
205scrollok(box, TRUE);
206scroll(box);/* Scroll box region up one line */
207scrollok(box, FALSE);
208print_line(box, boxh - 1, boxw);
209wnoutrefresh(box);
210print_position(dialog);
211wmove(dialog, cur_y, cur_x);/* Restore cursor position */
212wrefresh(dialog);
213}
214break;
215case KEY_NPAGE:/* Next page */
216case ' ':
217if (end_reached)
218break;
219
220begin_reached = 0;
221refresh_text_box(dialog, box, boxh, boxw,
222 cur_y, cur_x);
223break;
224case '0':/* Beginning of line */
225case 'H':/* Scroll left */
226case 'h':
227case KEY_LEFT:
228if (hscroll <= 0)
229break;
230
231if (key == '0')
232hscroll = 0;
233else
234hscroll--;
235/* Reprint current page to scroll horizontally */
236back_lines(page_length);
237refresh_text_box(dialog, box, boxh, boxw,
238 cur_y, cur_x);
239break;
240case 'L':/* Scroll right */
241case 'l':
242case KEY_RIGHT:
243if (hscroll >= MAX_LEN)
244break;
245hscroll++;
246/* Reprint current page to scroll horizontally */
247back_lines(page_length);
248refresh_text_box(dialog, box, boxh, boxw,
249 cur_y, cur_x);
250break;
251case KEY_ESC:
252key = on_key_esc(dialog);
253break;
254case KEY_RESIZE:
255back_lines(height);
256delwin(box);
257delwin(dialog);
258on_key_resize();
259goto do_resize;
260}
261}
262delwin(box);
263delwin(dialog);
264return key;/* ESC pressed */
265}
266
267/*
268 * Go back 'n' lines in text. Called by dialog_textbox().
269 * 'page' will be updated to point to the desired line in 'buf'.
270 */
271static void back_lines(int n)
272{
273int i;
274
275begin_reached = 0;
276/* Go back 'n' lines */
277for (i = 0; i < n; i++) {
278if (*page == '\0') {
279if (end_reached) {
280end_reached = 0;
281continue;
282}
283}
284if (page == buf) {
285begin_reached = 1;
286return;
287}
288page--;
289do {
290if (page == buf) {
291begin_reached = 1;
292return;
293}
294page--;
295} while (*page != '\n');
296page++;
297}
298}
299
300/*
301 * Print a new page of text. Called by dialog_textbox().
302 */
303static void print_page(WINDOW * win, int height, int width)
304{
305int i, passed_end = 0;
306
307page_length = 0;
308for (i = 0; i < height; i++) {
309print_line(win, i, width);
310if (!passed_end)
311page_length++;
312if (end_reached && !passed_end)
313passed_end = 1;
314}
315wnoutrefresh(win);
316}
317
318/*
319 * Print a new line of text. Called by dialog_textbox() and print_page().
320 */
321static void print_line(WINDOW * win, int row, int width)
322{
323int y, x;
324char *line;
325
326line = get_line();
327line += MIN(strlen(line), hscroll);/* Scroll horizontally */
328wmove(win, row, 0);/* move cursor to correct line */
329waddch(win, ' ');
330waddnstr(win, line, MIN(strlen(line), width - 2));
331
332getyx(win, y, x);
333/* Clear 'residue' of previous line */
334#if OLD_NCURSES
335{
336int i;
337for (i = 0; i < width - x; i++)
338waddch(win, ' ');
339}
340#else
341wclrtoeol(win);
342#endif
343}
344
345/*
346 * Return current line of text. Called by dialog_textbox() and print_line().
347 * 'page' should point to start of current line before calling, and will be
348 * updated to point to start of next line.
349 */
350static char *get_line(void)
351{
352int i = 0;
353static char line[MAX_LEN + 1];
354
355end_reached = 0;
356while (*page != '\n') {
357if (*page == '\0') {
358if (!end_reached) {
359end_reached = 1;
360break;
361}
362} else if (i < MAX_LEN)
363line[i++] = *(page++);
364else {
365/* Truncate lines longer than MAX_LEN characters */
366if (i == MAX_LEN)
367line[i++] = '\0';
368page++;
369}
370}
371if (i <= MAX_LEN)
372line[i] = '\0';
373if (!end_reached)
374page++;/* move pass '\n' */
375
376return line;
377}
378
379/*
380 * Print current position
381 */
382static void print_position(WINDOW * win)
383{
384int percent;
385
386wattrset(win, dlg.position_indicator.atr);
387wbkgdset(win, dlg.position_indicator.atr & A_COLOR);
388percent = (page - buf) * 100 / strlen(buf);
389wmove(win, getmaxy(win) - 3, getmaxx(win) - 9);
390wprintw(win, "(%3d%%)", percent);
391}
392

Archive Download this file

Revision: 1808