diff options
Diffstat (limited to 'scripts/kconfig/lxdialog/textbox.c')
-rw-r--r-- | scripts/kconfig/lxdialog/textbox.c | 177 |
1 files changed, 97 insertions, 80 deletions
diff --git a/scripts/kconfig/lxdialog/textbox.c b/scripts/kconfig/lxdialog/textbox.c index c704712d022..a48bb93e090 100644 --- a/scripts/kconfig/lxdialog/textbox.c +++ b/scripts/kconfig/lxdialog/textbox.c | |||
@@ -22,23 +22,25 @@ | |||
22 | #include "dialog.h" | 22 | #include "dialog.h" |
23 | 23 | ||
24 | static void back_lines(int n); | 24 | static void back_lines(int n); |
25 | static void print_page(WINDOW * win, int height, int width); | 25 | static void print_page(WINDOW *win, int height, int width, update_text_fn |
26 | static void print_line(WINDOW * win, int row, int width); | 26 | update_text, void *data); |
27 | static void print_line(WINDOW *win, int row, int width); | ||
27 | static char *get_line(void); | 28 | static char *get_line(void); |
28 | static void print_position(WINDOW * win); | 29 | static void print_position(WINDOW * win); |
29 | 30 | ||
30 | static int hscroll; | 31 | static int hscroll; |
31 | static int begin_reached, end_reached, page_length; | 32 | static int begin_reached, end_reached, page_length; |
32 | static const char *buf; | 33 | static char *buf; |
33 | static const char *page; | 34 | static char *page; |
34 | 35 | ||
35 | /* | 36 | /* |
36 | * refresh window content | 37 | * refresh window content |
37 | */ | 38 | */ |
38 | static void refresh_text_box(WINDOW *dialog, WINDOW *box, int boxh, int boxw, | 39 | static void refresh_text_box(WINDOW *dialog, WINDOW *box, int boxh, int boxw, |
39 | int cur_y, int cur_x) | 40 | int cur_y, int cur_x, update_text_fn update_text, |
41 | void *data) | ||
40 | { | 42 | { |
41 | print_page(box, boxh, boxw); | 43 | print_page(box, boxh, boxw, update_text, data); |
42 | print_position(dialog); | 44 | print_position(dialog); |
43 | wmove(dialog, cur_y, cur_x); /* Restore cursor position */ | 45 | wmove(dialog, cur_y, cur_x); /* Restore cursor position */ |
44 | wrefresh(dialog); | 46 | wrefresh(dialog); |
@@ -47,14 +49,18 @@ static void refresh_text_box(WINDOW *dialog, WINDOW *box, int boxh, int boxw, | |||
47 | 49 | ||
48 | /* | 50 | /* |
49 | * Display text from a file in a dialog box. | 51 | * Display text from a file in a dialog box. |
52 | * | ||
53 | * keys is a null-terminated array | ||
54 | * update_text() may not add or remove any '\n' or '\0' in tbuf | ||
50 | */ | 55 | */ |
51 | int dialog_textbox(const char *title, const char *tbuf, | 56 | int dialog_textbox(const char *title, char *tbuf, int initial_height, |
52 | int initial_height, int initial_width) | 57 | int initial_width, int *keys, int *_vscroll, int *_hscroll, |
58 | update_text_fn update_text, void *data) | ||
53 | { | 59 | { |
54 | int i, x, y, cur_x, cur_y, key = 0; | 60 | int i, x, y, cur_x, cur_y, key = 0; |
55 | int height, width, boxh, boxw; | 61 | int height, width, boxh, boxw; |
56 | int passed_end; | ||
57 | WINDOW *dialog, *box; | 62 | WINDOW *dialog, *box; |
63 | bool done = false; | ||
58 | 64 | ||
59 | begin_reached = 1; | 65 | begin_reached = 1; |
60 | end_reached = 0; | 66 | end_reached = 0; |
@@ -63,6 +69,15 @@ int dialog_textbox(const char *title, const char *tbuf, | |||
63 | buf = tbuf; | 69 | buf = tbuf; |
64 | page = buf; /* page is pointer to start of page to be displayed */ | 70 | page = buf; /* page is pointer to start of page to be displayed */ |
65 | 71 | ||
72 | if (_vscroll && *_vscroll) { | ||
73 | begin_reached = 0; | ||
74 | |||
75 | for (i = 0; i < *_vscroll; i++) | ||
76 | get_line(); | ||
77 | } | ||
78 | if (_hscroll) | ||
79 | hscroll = *_hscroll; | ||
80 | |||
66 | do_resize: | 81 | do_resize: |
67 | getmaxyx(stdscr, height, width); | 82 | getmaxyx(stdscr, height, width); |
68 | if (height < 8 || width < 8) | 83 | if (height < 8 || width < 8) |
@@ -120,25 +135,28 @@ do_resize: | |||
120 | 135 | ||
121 | /* Print first page of text */ | 136 | /* Print first page of text */ |
122 | attr_clear(box, boxh, boxw, dlg.dialog.atr); | 137 | attr_clear(box, boxh, boxw, dlg.dialog.atr); |
123 | refresh_text_box(dialog, box, boxh, boxw, cur_y, cur_x); | 138 | refresh_text_box(dialog, box, boxh, boxw, cur_y, cur_x, update_text, |
139 | data); | ||
124 | 140 | ||
125 | while ((key != KEY_ESC) && (key != '\n')) { | 141 | while (!done) { |
126 | key = wgetch(dialog); | 142 | key = wgetch(dialog); |
127 | switch (key) { | 143 | switch (key) { |
128 | case 'E': /* Exit */ | 144 | case 'E': /* Exit */ |
129 | case 'e': | 145 | case 'e': |
130 | case 'X': | 146 | case 'X': |
131 | case 'x': | 147 | case 'x': |
132 | delwin(box); | 148 | case 'q': |
133 | delwin(dialog); | 149 | case '\n': |
134 | return 0; | 150 | done = true; |
151 | break; | ||
135 | case 'g': /* First page */ | 152 | case 'g': /* First page */ |
136 | case KEY_HOME: | 153 | case KEY_HOME: |
137 | if (!begin_reached) { | 154 | if (!begin_reached) { |
138 | begin_reached = 1; | 155 | begin_reached = 1; |
139 | page = buf; | 156 | page = buf; |
140 | refresh_text_box(dialog, box, boxh, boxw, | 157 | refresh_text_box(dialog, box, boxh, boxw, |
141 | cur_y, cur_x); | 158 | cur_y, cur_x, update_text, |
159 | data); | ||
142 | } | 160 | } |
143 | break; | 161 | break; |
144 | case 'G': /* Last page */ | 162 | case 'G': /* Last page */ |
@@ -148,78 +166,48 @@ do_resize: | |||
148 | /* point to last char in buf */ | 166 | /* point to last char in buf */ |
149 | page = buf + strlen(buf); | 167 | page = buf + strlen(buf); |
150 | back_lines(boxh); | 168 | back_lines(boxh); |
151 | refresh_text_box(dialog, box, boxh, boxw, | 169 | refresh_text_box(dialog, box, boxh, boxw, cur_y, |
152 | cur_y, cur_x); | 170 | cur_x, update_text, data); |
153 | break; | 171 | break; |
154 | case 'K': /* Previous line */ | 172 | case 'K': /* Previous line */ |
155 | case 'k': | 173 | case 'k': |
156 | case KEY_UP: | 174 | case KEY_UP: |
157 | if (!begin_reached) { | 175 | if (begin_reached) |
158 | back_lines(page_length + 1); | 176 | break; |
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. */ | ||
167 | scrollok(box, TRUE); | ||
168 | wscrl(box, -1); /* Scroll box region down one line */ | ||
169 | scrollok(box, FALSE); | ||
170 | page_length = 0; | ||
171 | passed_end = 0; | ||
172 | for (i = 0; i < boxh; i++) { | ||
173 | if (!i) { | ||
174 | /* print first line of page */ | ||
175 | print_line(box, 0, boxw); | ||
176 | wnoutrefresh(box); | ||
177 | } else | ||
178 | /* Called to update 'end_reached' and 'page' */ | ||
179 | get_line(); | ||
180 | if (!passed_end) | ||
181 | page_length++; | ||
182 | if (end_reached && !passed_end) | ||
183 | passed_end = 1; | ||
184 | } | ||
185 | 177 | ||
186 | print_position(dialog); | 178 | back_lines(page_length + 1); |
187 | wmove(dialog, cur_y, cur_x); /* Restore cursor position */ | 179 | refresh_text_box(dialog, box, boxh, boxw, cur_y, |
188 | wrefresh(dialog); | 180 | cur_x, update_text, data); |
189 | } | ||
190 | break; | 181 | break; |
191 | case 'B': /* Previous page */ | 182 | case 'B': /* Previous page */ |
192 | case 'b': | 183 | case 'b': |
184 | case 'u': | ||
193 | case KEY_PPAGE: | 185 | case KEY_PPAGE: |
194 | if (begin_reached) | 186 | if (begin_reached) |
195 | break; | 187 | break; |
196 | back_lines(page_length + boxh); | 188 | back_lines(page_length + boxh); |
197 | refresh_text_box(dialog, box, boxh, boxw, | 189 | refresh_text_box(dialog, box, boxh, boxw, cur_y, |
198 | cur_y, cur_x); | 190 | cur_x, update_text, data); |
199 | break; | 191 | break; |
200 | case 'J': /* Next line */ | 192 | case 'J': /* Next line */ |
201 | case 'j': | 193 | case 'j': |
202 | case KEY_DOWN: | 194 | case KEY_DOWN: |
203 | if (!end_reached) { | 195 | if (end_reached) |
204 | begin_reached = 0; | 196 | break; |
205 | scrollok(box, TRUE); | 197 | |
206 | scroll(box); /* Scroll box region up one line */ | 198 | back_lines(page_length - 1); |
207 | scrollok(box, FALSE); | 199 | refresh_text_box(dialog, box, boxh, boxw, cur_y, |
208 | print_line(box, boxh - 1, boxw); | 200 | cur_x, update_text, data); |
209 | wnoutrefresh(box); | ||
210 | print_position(dialog); | ||
211 | wmove(dialog, cur_y, cur_x); /* Restore cursor position */ | ||
212 | wrefresh(dialog); | ||
213 | } | ||
214 | break; | 201 | break; |
215 | case KEY_NPAGE: /* Next page */ | 202 | case KEY_NPAGE: /* Next page */ |
216 | case ' ': | 203 | case ' ': |
204 | case 'd': | ||
217 | if (end_reached) | 205 | if (end_reached) |
218 | break; | 206 | break; |
219 | 207 | ||
220 | begin_reached = 0; | 208 | begin_reached = 0; |
221 | refresh_text_box(dialog, box, boxh, boxw, | 209 | refresh_text_box(dialog, box, boxh, boxw, cur_y, |
222 | cur_y, cur_x); | 210 | cur_x, update_text, data); |
223 | break; | 211 | break; |
224 | case '0': /* Beginning of line */ | 212 | case '0': /* Beginning of line */ |
225 | case 'H': /* Scroll left */ | 213 | case 'H': /* Scroll left */ |
@@ -234,8 +222,8 @@ do_resize: | |||
234 | hscroll--; | 222 | hscroll--; |
235 | /* Reprint current page to scroll horizontally */ | 223 | /* Reprint current page to scroll horizontally */ |
236 | back_lines(page_length); | 224 | back_lines(page_length); |
237 | refresh_text_box(dialog, box, boxh, boxw, | 225 | refresh_text_box(dialog, box, boxh, boxw, cur_y, |
238 | cur_y, cur_x); | 226 | cur_x, update_text, data); |
239 | break; | 227 | break; |
240 | case 'L': /* Scroll right */ | 228 | case 'L': /* Scroll right */ |
241 | case 'l': | 229 | case 'l': |
@@ -245,11 +233,12 @@ do_resize: | |||
245 | hscroll++; | 233 | hscroll++; |
246 | /* Reprint current page to scroll horizontally */ | 234 | /* Reprint current page to scroll horizontally */ |
247 | back_lines(page_length); | 235 | back_lines(page_length); |
248 | refresh_text_box(dialog, box, boxh, boxw, | 236 | refresh_text_box(dialog, box, boxh, boxw, cur_y, |
249 | cur_y, cur_x); | 237 | cur_x, update_text, data); |
250 | break; | 238 | break; |
251 | case KEY_ESC: | 239 | case KEY_ESC: |
252 | key = on_key_esc(dialog); | 240 | if (on_key_esc(dialog) == KEY_ESC) |
241 | done = true; | ||
253 | break; | 242 | break; |
254 | case KEY_RESIZE: | 243 | case KEY_RESIZE: |
255 | back_lines(height); | 244 | back_lines(height); |
@@ -257,11 +246,31 @@ do_resize: | |||
257 | delwin(dialog); | 246 | delwin(dialog); |
258 | on_key_resize(); | 247 | on_key_resize(); |
259 | goto do_resize; | 248 | goto do_resize; |
249 | default: | ||
250 | for (i = 0; keys[i]; i++) { | ||
251 | if (key == keys[i]) { | ||
252 | done = true; | ||
253 | break; | ||
254 | } | ||
255 | } | ||
260 | } | 256 | } |
261 | } | 257 | } |
262 | delwin(box); | 258 | delwin(box); |
263 | delwin(dialog); | 259 | delwin(dialog); |
264 | return key; /* ESC pressed */ | 260 | if (_vscroll) { |
261 | const char *s; | ||
262 | |||
263 | s = buf; | ||
264 | *_vscroll = 0; | ||
265 | back_lines(page_length); | ||
266 | while (s < page && (s = strchr(s, '\n'))) { | ||
267 | (*_vscroll)++; | ||
268 | s++; | ||
269 | } | ||
270 | } | ||
271 | if (_hscroll) | ||
272 | *_hscroll = hscroll; | ||
273 | return key; | ||
265 | } | 274 | } |
266 | 275 | ||
267 | /* | 276 | /* |
@@ -298,12 +307,23 @@ static void back_lines(int n) | |||
298 | } | 307 | } |
299 | 308 | ||
300 | /* | 309 | /* |
301 | * Print a new page of text. Called by dialog_textbox(). | 310 | * Print a new page of text. |
302 | */ | 311 | */ |
303 | static void print_page(WINDOW * win, int height, int width) | 312 | static void print_page(WINDOW *win, int height, int width, update_text_fn |
313 | update_text, void *data) | ||
304 | { | 314 | { |
305 | int i, passed_end = 0; | 315 | int i, passed_end = 0; |
306 | 316 | ||
317 | if (update_text) { | ||
318 | char *end; | ||
319 | |||
320 | for (i = 0; i < height; i++) | ||
321 | get_line(); | ||
322 | end = page; | ||
323 | back_lines(height); | ||
324 | update_text(buf, page - buf, end - buf, data); | ||
325 | } | ||
326 | |||
307 | page_length = 0; | 327 | page_length = 0; |
308 | for (i = 0; i < height; i++) { | 328 | for (i = 0; i < height; i++) { |
309 | print_line(win, i, width); | 329 | print_line(win, i, width); |
@@ -316,11 +336,10 @@ static void print_page(WINDOW * win, int height, int width) | |||
316 | } | 336 | } |
317 | 337 | ||
318 | /* | 338 | /* |
319 | * Print a new line of text. Called by dialog_textbox() and print_page(). | 339 | * Print a new line of text. |
320 | */ | 340 | */ |
321 | static void print_line(WINDOW * win, int row, int width) | 341 | static void print_line(WINDOW * win, int row, int width) |
322 | { | 342 | { |
323 | int y, x; | ||
324 | char *line; | 343 | char *line; |
325 | 344 | ||
326 | line = get_line(); | 345 | line = get_line(); |
@@ -329,10 +348,10 @@ static void print_line(WINDOW * win, int row, int width) | |||
329 | waddch(win, ' '); | 348 | waddch(win, ' '); |
330 | waddnstr(win, line, MIN(strlen(line), width - 2)); | 349 | waddnstr(win, line, MIN(strlen(line), width - 2)); |
331 | 350 | ||
332 | getyx(win, y, x); | ||
333 | /* Clear 'residue' of previous line */ | 351 | /* Clear 'residue' of previous line */ |
334 | #if OLD_NCURSES | 352 | #if OLD_NCURSES |
335 | { | 353 | { |
354 | int x = getcurx(win); | ||
336 | int i; | 355 | int i; |
337 | for (i = 0; i < width - x; i++) | 356 | for (i = 0; i < width - x; i++) |
338 | waddch(win, ' '); | 357 | waddch(win, ' '); |
@@ -355,10 +374,8 @@ static char *get_line(void) | |||
355 | end_reached = 0; | 374 | end_reached = 0; |
356 | while (*page != '\n') { | 375 | while (*page != '\n') { |
357 | if (*page == '\0') { | 376 | if (*page == '\0') { |
358 | if (!end_reached) { | 377 | end_reached = 1; |
359 | end_reached = 1; | 378 | break; |
360 | break; | ||
361 | } | ||
362 | } else if (i < MAX_LEN) | 379 | } else if (i < MAX_LEN) |
363 | line[i++] = *(page++); | 380 | line[i++] = *(page++); |
364 | else { | 381 | else { |
@@ -371,7 +388,7 @@ static char *get_line(void) | |||
371 | if (i <= MAX_LEN) | 388 | if (i <= MAX_LEN) |
372 | line[i] = '\0'; | 389 | line[i] = '\0'; |
373 | if (!end_reached) | 390 | if (!end_reached) |
374 | page++; /* move pass '\n' */ | 391 | page++; /* move past '\n' */ |
375 | 392 | ||
376 | return line; | 393 | return line; |
377 | } | 394 | } |