1 | /****************************************************************************
|
---|
2 | * Copyright (c) 1998-2004,2005 Free Software Foundation, Inc. *
|
---|
3 | * *
|
---|
4 | * Permission is hereby granted, free of charge, to any person obtaining a *
|
---|
5 | * copy of this software and associated documentation files (the *
|
---|
6 | * "Software"), to deal in the Software without restriction, including *
|
---|
7 | * without limitation the rights to use, copy, modify, merge, publish, *
|
---|
8 | * distribute, distribute with modifications, sublicense, and/or sell *
|
---|
9 | * copies of the Software, and to permit persons to whom the Software is *
|
---|
10 | * furnished to do so, subject to the following conditions: *
|
---|
11 | * *
|
---|
12 | * The above copyright notice and this permission notice shall be included *
|
---|
13 | * in all copies or substantial portions of the Software. *
|
---|
14 | * *
|
---|
15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS *
|
---|
16 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF *
|
---|
17 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. *
|
---|
18 | * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, *
|
---|
19 | * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR *
|
---|
20 | * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR *
|
---|
21 | * THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
---|
22 | * *
|
---|
23 | * Except as contained in this notice, the name(s) of the above copyright *
|
---|
24 | * holders shall not be used in advertising or otherwise to promote the *
|
---|
25 | * sale, use or other dealings in this Software without prior written *
|
---|
26 | * authorization. *
|
---|
27 | ****************************************************************************/
|
---|
28 | /****************************************************************************
|
---|
29 |
|
---|
30 | NAME
|
---|
31 | ncurses.c --- ncurses library exerciser
|
---|
32 |
|
---|
33 | SYNOPSIS
|
---|
34 | ncurses
|
---|
35 |
|
---|
36 | DESCRIPTION
|
---|
37 | An interactive test module for the ncurses library.
|
---|
38 |
|
---|
39 | AUTHOR
|
---|
40 | Author: Eric S. Raymond <esr@snark.thyrsus.com> 1993
|
---|
41 | Thomas E. Dickey (beginning revision 1.27 in 1996).
|
---|
42 |
|
---|
43 | $Id: ncurses.c,v 1.253 2005/10/01 16:00:56 tom Exp $
|
---|
44 |
|
---|
45 | ***************************************************************************/
|
---|
46 |
|
---|
47 | #include <test.priv.h>
|
---|
48 |
|
---|
49 | #if HAVE_GETTIMEOFDAY
|
---|
50 | #if HAVE_SYS_TIME_H && HAVE_SYS_TIME_SELECT
|
---|
51 | #include <sys/time.h>
|
---|
52 | #endif
|
---|
53 | #if HAVE_SYS_SELECT_H
|
---|
54 | #include <sys/select.h>
|
---|
55 | #endif
|
---|
56 | #endif
|
---|
57 |
|
---|
58 | #if USE_LIBPANEL
|
---|
59 | #include <panel.h>
|
---|
60 | #endif
|
---|
61 |
|
---|
62 | #if USE_LIBMENU
|
---|
63 | #include <menu.h>
|
---|
64 | #endif
|
---|
65 |
|
---|
66 | #if USE_LIBFORM
|
---|
67 | #include <form.h>
|
---|
68 | #endif
|
---|
69 |
|
---|
70 | #ifdef NCURSES_VERSION
|
---|
71 |
|
---|
72 | #ifdef TRACE
|
---|
73 | static unsigned save_trace = TRACE_ORDINARY | TRACE_CALLS;
|
---|
74 | extern unsigned _nc_tracing;
|
---|
75 | #endif
|
---|
76 |
|
---|
77 | #else
|
---|
78 |
|
---|
79 | #define mmask_t chtype /* not specified in XSI */
|
---|
80 |
|
---|
81 | #ifdef CURSES_ACS_ARRAY
|
---|
82 | #define ACS_S3 (CURSES_ACS_ARRAY['p']) /* scan line 3 */
|
---|
83 | #define ACS_S7 (CURSES_ACS_ARRAY['r']) /* scan line 7 */
|
---|
84 | #define ACS_LEQUAL (CURSES_ACS_ARRAY['y']) /* less/equal */
|
---|
85 | #define ACS_GEQUAL (CURSES_ACS_ARRAY['z']) /* greater/equal */
|
---|
86 | #define ACS_PI (CURSES_ACS_ARRAY['{']) /* Pi */
|
---|
87 | #define ACS_NEQUAL (CURSES_ACS_ARRAY['|']) /* not equal */
|
---|
88 | #define ACS_STERLING (CURSES_ACS_ARRAY['}']) /* UK pound sign */
|
---|
89 | #else
|
---|
90 | #define ACS_S3 (A_ALTCHARSET + 'p') /* scan line 3 */
|
---|
91 | #define ACS_S7 (A_ALTCHARSET + 'r') /* scan line 7 */
|
---|
92 | #define ACS_LEQUAL (A_ALTCHARSET + 'y') /* less/equal */
|
---|
93 | #define ACS_GEQUAL (A_ALTCHARSET + 'z') /* greater/equal */
|
---|
94 | #define ACS_PI (A_ALTCHARSET + '{') /* Pi */
|
---|
95 | #define ACS_NEQUAL (A_ALTCHARSET + '|') /* not equal */
|
---|
96 | #define ACS_STERLING (A_ALTCHARSET + '}') /* UK pound sign */
|
---|
97 | #endif
|
---|
98 |
|
---|
99 | #ifdef CURSES_WACS_ARRAY
|
---|
100 | #define WACS_S3 (&(CURSES_WACS_ARRAY['p'])) /* scan line 3 */
|
---|
101 | #define WACS_S7 (&(CURSES_WACS_ARRAY['r'])) /* scan line 7 */
|
---|
102 | #define WACS_LEQUAL (&(CURSES_WACS_ARRAY['y'])) /* less/equal */
|
---|
103 | #define WACS_GEQUAL (&(CURSES_WACS_ARRAY['z'])) /* greater/equal */
|
---|
104 | #define WACS_PI (&(CURSES_WACS_ARRAY['{'])) /* Pi */
|
---|
105 | #define WACS_NEQUAL (&(CURSES_WACS_ARRAY['|'])) /* not equal */
|
---|
106 | #define WACS_STERLING (&(CURSES_WACS_ARRAY['}'])) /* UK pound sign */
|
---|
107 | #endif
|
---|
108 |
|
---|
109 | #endif
|
---|
110 |
|
---|
111 | #define P(string) printw("%s\n", string)
|
---|
112 |
|
---|
113 | #define BLANK ' ' /* this is the background character */
|
---|
114 |
|
---|
115 | #undef max_colors
|
---|
116 | static int max_colors; /* the actual number of colors we'll use */
|
---|
117 | static int min_colors; /* the minimum color code */
|
---|
118 |
|
---|
119 | #undef max_pairs
|
---|
120 | static int max_pairs; /* ...and the number of color pairs */
|
---|
121 |
|
---|
122 | typedef struct {
|
---|
123 | short red;
|
---|
124 | short green;
|
---|
125 | short blue;
|
---|
126 | } RGB_DATA;
|
---|
127 |
|
---|
128 | static RGB_DATA *all_colors;
|
---|
129 |
|
---|
130 | static void main_menu(bool);
|
---|
131 |
|
---|
132 | /* The behavior of mvhline, mvvline for negative/zero length is unspecified,
|
---|
133 | * though we can rely on negative x/y values to stop the macro.
|
---|
134 | */
|
---|
135 | static void
|
---|
136 | do_h_line(int y, int x, chtype c, int to)
|
---|
137 | {
|
---|
138 | if ((to) > (x))
|
---|
139 | mvhline(y, x, c, (to) - (x));
|
---|
140 | }
|
---|
141 |
|
---|
142 | static void
|
---|
143 | do_v_line(int y, int x, chtype c, int to)
|
---|
144 | {
|
---|
145 | if ((to) > (y))
|
---|
146 | mvvline(y, x, c, (to) - (y));
|
---|
147 | }
|
---|
148 |
|
---|
149 | static void
|
---|
150 | Repaint(void)
|
---|
151 | {
|
---|
152 | touchwin(stdscr);
|
---|
153 | touchwin(curscr);
|
---|
154 | wrefresh(curscr);
|
---|
155 | }
|
---|
156 |
|
---|
157 | /* Common function to allow ^T to toggle trace-mode in the middle of a test
|
---|
158 | * so that trace-files can be made smaller.
|
---|
159 | */
|
---|
160 | static int
|
---|
161 | wGetchar(WINDOW *win)
|
---|
162 | {
|
---|
163 | int c;
|
---|
164 | #ifdef TRACE
|
---|
165 | while ((c = wgetch(win)) == CTRL('T')) {
|
---|
166 | if (_nc_tracing) {
|
---|
167 | save_trace = _nc_tracing;
|
---|
168 | _tracef("TOGGLE-TRACING OFF");
|
---|
169 | _nc_tracing = 0;
|
---|
170 | } else {
|
---|
171 | _nc_tracing = save_trace;
|
---|
172 | }
|
---|
173 | trace(_nc_tracing);
|
---|
174 | if (_nc_tracing)
|
---|
175 | _tracef("TOGGLE-TRACING ON");
|
---|
176 | }
|
---|
177 | #else
|
---|
178 | c = wgetch(win);
|
---|
179 | #endif
|
---|
180 | return c;
|
---|
181 | }
|
---|
182 | #define Getchar() wGetchar(stdscr)
|
---|
183 |
|
---|
184 | /* replaces wgetnstr(), since we want to be able to edit values */
|
---|
185 | static void
|
---|
186 | wGetstring(WINDOW *win, char *buffer, int limit)
|
---|
187 | {
|
---|
188 | int y0, x0, x, ch;
|
---|
189 | bool done = FALSE;
|
---|
190 |
|
---|
191 | echo();
|
---|
192 | getyx(win, y0, x0);
|
---|
193 | wattrset(win, A_REVERSE);
|
---|
194 |
|
---|
195 | x = strlen(buffer);
|
---|
196 | while (!done) {
|
---|
197 | if (x > (int) strlen(buffer))
|
---|
198 | x = (int) strlen(buffer);
|
---|
199 | wmove(win, y0, x0);
|
---|
200 | wprintw(win, "%-*s", limit, buffer);
|
---|
201 | wmove(win, y0, x0 + x);
|
---|
202 | switch (ch = wGetchar(win)) {
|
---|
203 | case '\n':
|
---|
204 | case KEY_ENTER:
|
---|
205 | done = TRUE;
|
---|
206 | break;
|
---|
207 | case CTRL('U'):
|
---|
208 | *buffer = '\0';
|
---|
209 | break;
|
---|
210 | case '\b':
|
---|
211 | case KEY_BACKSPACE:
|
---|
212 | case KEY_DC:
|
---|
213 | if (x > 0) {
|
---|
214 | int j;
|
---|
215 | for (j = --x; (buffer[j] = buffer[j + 1]) != '\0'; ++j) {
|
---|
216 | ;
|
---|
217 | }
|
---|
218 | } else {
|
---|
219 | beep();
|
---|
220 | }
|
---|
221 | break;
|
---|
222 | case KEY_LEFT:
|
---|
223 | if (x > 0) {
|
---|
224 | --x;
|
---|
225 | } else {
|
---|
226 | flash();
|
---|
227 | }
|
---|
228 | break;
|
---|
229 | case KEY_RIGHT:
|
---|
230 | ++x;
|
---|
231 | break;
|
---|
232 | default:
|
---|
233 | if (!isprint(ch) || ch >= KEY_MIN) {
|
---|
234 | beep();
|
---|
235 | } else if ((int) strlen(buffer) < limit) {
|
---|
236 | int j;
|
---|
237 | for (j = strlen(buffer) + 1; j > x; --j) {
|
---|
238 | buffer[j] = buffer[j - 1];
|
---|
239 | }
|
---|
240 | buffer[x++] = ch;
|
---|
241 | } else {
|
---|
242 | flash();
|
---|
243 | }
|
---|
244 | }
|
---|
245 | }
|
---|
246 |
|
---|
247 | wattroff(win, A_REVERSE);
|
---|
248 | wmove(win, y0, x0);
|
---|
249 | noecho();
|
---|
250 | }
|
---|
251 |
|
---|
252 | #if USE_WIDEC_SUPPORT
|
---|
253 | static int
|
---|
254 | wGet_wchar(WINDOW *win, wint_t *result)
|
---|
255 | {
|
---|
256 | int c;
|
---|
257 | #ifdef TRACE
|
---|
258 | while ((c = wget_wch(win, result)) == CTRL('T')) {
|
---|
259 | if (_nc_tracing) {
|
---|
260 | save_trace = _nc_tracing;
|
---|
261 | _tracef("TOGGLE-TRACING OFF");
|
---|
262 | _nc_tracing = 0;
|
---|
263 | } else {
|
---|
264 | _nc_tracing = save_trace;
|
---|
265 | }
|
---|
266 | trace(_nc_tracing);
|
---|
267 | if (_nc_tracing)
|
---|
268 | _tracef("TOGGLE-TRACING ON");
|
---|
269 | }
|
---|
270 | #else
|
---|
271 | c = wget_wch(win, result);
|
---|
272 | #endif
|
---|
273 | return c;
|
---|
274 | }
|
---|
275 | #define Get_wchar(result) wGet_wchar(stdscr, result)
|
---|
276 |
|
---|
277 | /* replaces wgetn_wstr(), since we want to be able to edit values */
|
---|
278 | static void
|
---|
279 | wGet_wstring(WINDOW *win, wchar_t *buffer, int limit)
|
---|
280 | {
|
---|
281 | int y0, x0, x;
|
---|
282 | wint_t ch;
|
---|
283 | bool done = FALSE;
|
---|
284 | bool fkey = FALSE;
|
---|
285 |
|
---|
286 | echo();
|
---|
287 | getyx(win, y0, x0);
|
---|
288 | wattrset(win, A_REVERSE);
|
---|
289 |
|
---|
290 | x = wcslen(buffer);
|
---|
291 | while (!done) {
|
---|
292 | if (x > (int) wcslen(buffer))
|
---|
293 | x = (int) wcslen(buffer);
|
---|
294 |
|
---|
295 | /* clear the "window' */
|
---|
296 | wmove(win, y0, x0);
|
---|
297 | wprintw(win, "%*s", limit, " ");
|
---|
298 |
|
---|
299 | /* write the existing buffer contents */
|
---|
300 | wmove(win, y0, x0);
|
---|
301 | waddnwstr(win, buffer, limit);
|
---|
302 |
|
---|
303 | /* positions the cursor past character 'x' */
|
---|
304 | wmove(win, y0, x0);
|
---|
305 | waddnwstr(win, buffer, x);
|
---|
306 |
|
---|
307 | switch (wGet_wchar(win, &ch)) {
|
---|
308 | case KEY_CODE_YES:
|
---|
309 | fkey = TRUE;
|
---|
310 | switch (ch) {
|
---|
311 | case KEY_ENTER:
|
---|
312 | ch = '\n';
|
---|
313 | fkey = FALSE;
|
---|
314 | break;
|
---|
315 | case KEY_BACKSPACE:
|
---|
316 | case KEY_DC:
|
---|
317 | ch = '\b';
|
---|
318 | fkey = FALSE;
|
---|
319 | break;
|
---|
320 | case KEY_LEFT:
|
---|
321 | case KEY_RIGHT:
|
---|
322 | break;
|
---|
323 | default:
|
---|
324 | ch = (wint_t) -1;
|
---|
325 | break;
|
---|
326 | }
|
---|
327 | break;
|
---|
328 | case OK:
|
---|
329 | fkey = FALSE;
|
---|
330 | break;
|
---|
331 | default:
|
---|
332 | ch = (wint_t) -1;
|
---|
333 | fkey = TRUE;
|
---|
334 | break;
|
---|
335 | }
|
---|
336 |
|
---|
337 | switch (ch) {
|
---|
338 | case '\n':
|
---|
339 | done = TRUE;
|
---|
340 | break;
|
---|
341 | case CTRL('U'):
|
---|
342 | *buffer = '\0';
|
---|
343 | break;
|
---|
344 | case '\b':
|
---|
345 | if (x > 0) {
|
---|
346 | int j;
|
---|
347 | for (j = --x; (buffer[j] = buffer[j + 1]) != '\0'; ++j) {
|
---|
348 | ;
|
---|
349 | }
|
---|
350 | } else {
|
---|
351 | beep();
|
---|
352 | }
|
---|
353 | break;
|
---|
354 | case KEY_LEFT:
|
---|
355 | if (x > 0) {
|
---|
356 | --x;
|
---|
357 | } else {
|
---|
358 | beep();
|
---|
359 | }
|
---|
360 | break;
|
---|
361 | case KEY_RIGHT:
|
---|
362 | ++x;
|
---|
363 | break;
|
---|
364 | default:
|
---|
365 | if (fkey) {
|
---|
366 | beep();
|
---|
367 | } else if ((int) wcslen(buffer) < limit) {
|
---|
368 | int j;
|
---|
369 | for (j = wcslen(buffer) + 1; j > x; --j) {
|
---|
370 | buffer[j] = buffer[j - 1];
|
---|
371 | }
|
---|
372 | buffer[x++] = ch;
|
---|
373 | } else {
|
---|
374 | beep();
|
---|
375 | }
|
---|
376 | }
|
---|
377 | }
|
---|
378 |
|
---|
379 | wattroff(win, A_REVERSE);
|
---|
380 | wmove(win, y0, x0);
|
---|
381 | noecho();
|
---|
382 | }
|
---|
383 |
|
---|
384 | #endif
|
---|
385 |
|
---|
386 | static void
|
---|
387 | Pause(void)
|
---|
388 | {
|
---|
389 | move(LINES - 1, 0);
|
---|
390 | addstr("Press any key to continue... ");
|
---|
391 | (void) Getchar();
|
---|
392 | }
|
---|
393 |
|
---|
394 | static void
|
---|
395 | Cannot(const char *what)
|
---|
396 | {
|
---|
397 | printw("\nThis %s terminal %s\n\n", getenv("TERM"), what);
|
---|
398 | Pause();
|
---|
399 | }
|
---|
400 |
|
---|
401 | static void
|
---|
402 | ShellOut(bool message)
|
---|
403 | {
|
---|
404 | if (message)
|
---|
405 | addstr("Shelling out...");
|
---|
406 | def_prog_mode();
|
---|
407 | endwin();
|
---|
408 | system("sh");
|
---|
409 | if (message)
|
---|
410 | addstr("returned from shellout.\n");
|
---|
411 | refresh();
|
---|
412 | }
|
---|
413 |
|
---|
414 | #ifdef NCURSES_MOUSE_VERSION
|
---|
415 | /*
|
---|
416 | * This function is the same as _tracemouse(), but we cannot count on that
|
---|
417 | * being available in the non-debug library.
|
---|
418 | */
|
---|
419 | static const char *
|
---|
420 | mouse_decode(MEVENT const *ep)
|
---|
421 | {
|
---|
422 | static char buf[80 + (5 * 10) + (32 * 15)];
|
---|
423 |
|
---|
424 | (void) sprintf(buf, "id %2d at (%2d, %2d, %2d) state %4lx = {",
|
---|
425 | ep->id, ep->x, ep->y, ep->z, (unsigned long) ep->bstate);
|
---|
426 |
|
---|
427 | #define SHOW(m, s) if ((ep->bstate & m)==m) {strcat(buf,s); strcat(buf, ", ");}
|
---|
428 |
|
---|
429 | SHOW(BUTTON1_RELEASED, "release-1");
|
---|
430 | SHOW(BUTTON1_PRESSED, "press-1");
|
---|
431 | SHOW(BUTTON1_CLICKED, "click-1");
|
---|
432 | SHOW(BUTTON1_DOUBLE_CLICKED, "doubleclick-1");
|
---|
433 | SHOW(BUTTON1_TRIPLE_CLICKED, "tripleclick-1");
|
---|
434 | #if NCURSES_MOUSE_VERSION == 1
|
---|
435 | SHOW(BUTTON1_RESERVED_EVENT, "reserved-1");
|
---|
436 | #endif
|
---|
437 |
|
---|
438 | SHOW(BUTTON2_RELEASED, "release-2");
|
---|
439 | SHOW(BUTTON2_PRESSED, "press-2");
|
---|
440 | SHOW(BUTTON2_CLICKED, "click-2");
|
---|
441 | SHOW(BUTTON2_DOUBLE_CLICKED, "doubleclick-2");
|
---|
442 | SHOW(BUTTON2_TRIPLE_CLICKED, "tripleclick-2");
|
---|
443 | #if NCURSES_MOUSE_VERSION == 1
|
---|
444 | SHOW(BUTTON2_RESERVED_EVENT, "reserved-2");
|
---|
445 | #endif
|
---|
446 |
|
---|
447 | SHOW(BUTTON3_RELEASED, "release-3");
|
---|
448 | SHOW(BUTTON3_PRESSED, "press-3");
|
---|
449 | SHOW(BUTTON3_CLICKED, "click-3");
|
---|
450 | SHOW(BUTTON3_DOUBLE_CLICKED, "doubleclick-3");
|
---|
451 | SHOW(BUTTON3_TRIPLE_CLICKED, "tripleclick-3");
|
---|
452 | #if NCURSES_MOUSE_VERSION == 1
|
---|
453 | SHOW(BUTTON3_RESERVED_EVENT, "reserved-3");
|
---|
454 | #endif
|
---|
455 |
|
---|
456 | SHOW(BUTTON4_RELEASED, "release-4");
|
---|
457 | SHOW(BUTTON4_PRESSED, "press-4");
|
---|
458 | SHOW(BUTTON4_CLICKED, "click-4");
|
---|
459 | SHOW(BUTTON4_DOUBLE_CLICKED, "doubleclick-4");
|
---|
460 | SHOW(BUTTON4_TRIPLE_CLICKED, "tripleclick-4");
|
---|
461 | #if NCURSES_MOUSE_VERSION == 1
|
---|
462 | SHOW(BUTTON4_RESERVED_EVENT, "reserved-4");
|
---|
463 | #endif
|
---|
464 |
|
---|
465 | #if NCURSES_MOUSE_VERSION == 2
|
---|
466 | SHOW(BUTTON5_RELEASED, "release-5");
|
---|
467 | SHOW(BUTTON5_PRESSED, "press-5");
|
---|
468 | SHOW(BUTTON5_CLICKED, "click-5");
|
---|
469 | SHOW(BUTTON5_DOUBLE_CLICKED, "doubleclick-5");
|
---|
470 | SHOW(BUTTON5_TRIPLE_CLICKED, "tripleclick-5");
|
---|
471 | #endif
|
---|
472 |
|
---|
473 | SHOW(BUTTON_CTRL, "ctrl");
|
---|
474 | SHOW(BUTTON_SHIFT, "shift");
|
---|
475 | SHOW(BUTTON_ALT, "alt");
|
---|
476 | SHOW(ALL_MOUSE_EVENTS, "all-events");
|
---|
477 | SHOW(REPORT_MOUSE_POSITION, "position");
|
---|
478 |
|
---|
479 | #undef SHOW
|
---|
480 |
|
---|
481 | if (buf[strlen(buf) - 1] == ' ')
|
---|
482 | buf[strlen(buf) - 2] = '\0';
|
---|
483 | (void) strcat(buf, "}");
|
---|
484 | return (buf);
|
---|
485 | }
|
---|
486 | #endif /* NCURSES_MOUSE_VERSION */
|
---|
487 |
|
---|
488 | /****************************************************************************
|
---|
489 | *
|
---|
490 | * Character input test
|
---|
491 | *
|
---|
492 | ****************************************************************************/
|
---|
493 |
|
---|
494 | static void
|
---|
495 | setup_getch(WINDOW *win, bool flags[])
|
---|
496 | {
|
---|
497 | keypad(win, flags['k']); /* should be redundant, but for testing */
|
---|
498 | meta(win, flags['m']); /* force this to a known state */
|
---|
499 | if (flags['e'])
|
---|
500 | echo();
|
---|
501 | else
|
---|
502 | noecho();
|
---|
503 | }
|
---|
504 |
|
---|
505 | static void
|
---|
506 | wgetch_help(WINDOW *win, bool flags[])
|
---|
507 | {
|
---|
508 | static const char *help[] =
|
---|
509 | {
|
---|
510 | "e -- toggle echo mode"
|
---|
511 | ,"g -- triggers a getstr test"
|
---|
512 | ,"k -- toggle keypad/literal mode"
|
---|
513 | ,"m -- toggle meta (7-bit/8-bit) mode"
|
---|
514 | ,"q -- quit (x also exits)"
|
---|
515 | ,"s -- shell out\n"
|
---|
516 | ,"w -- create a new window"
|
---|
517 | #ifdef SIGTSTP
|
---|
518 | ,"z -- suspend this process"
|
---|
519 | #endif
|
---|
520 | };
|
---|
521 | int y, x;
|
---|
522 | unsigned chk = ((SIZEOF(help) + 1) / 2);
|
---|
523 | unsigned n;
|
---|
524 |
|
---|
525 | getyx(win, y, x);
|
---|
526 | move(0, 0);
|
---|
527 | printw("Type any key to see its %s value. Also:\n",
|
---|
528 | flags['k'] ? "keypad" : "literal");
|
---|
529 | for (n = 0; n < SIZEOF(help); ++n) {
|
---|
530 | int row = 1 + (n % chk);
|
---|
531 | int col = (n >= chk) ? COLS / 2 : 0;
|
---|
532 | int flg = ((strstr(help[n], "toggle") != 0)
|
---|
533 | && (flags[UChar(*help[n])] != FALSE));
|
---|
534 | if (flg)
|
---|
535 | standout();
|
---|
536 | mvprintw(row, col, "%s", help[n]);
|
---|
537 | if (col == 0)
|
---|
538 | clrtoeol();
|
---|
539 | if (flg)
|
---|
540 | standend();
|
---|
541 | }
|
---|
542 | wrefresh(stdscr);
|
---|
543 | wmove(win, y, x);
|
---|
544 | }
|
---|
545 |
|
---|
546 | static void
|
---|
547 | wgetch_wrap(WINDOW *win, int first_y)
|
---|
548 | {
|
---|
549 | int last_y = getmaxy(win) - 1;
|
---|
550 | int y = getcury(win) + 1;
|
---|
551 |
|
---|
552 | if (y >= last_y)
|
---|
553 | y = first_y;
|
---|
554 | wmove(win, y, 0);
|
---|
555 | wclrtoeol(win);
|
---|
556 | }
|
---|
557 |
|
---|
558 | #if defined(NCURSES_VERSION) && defined(KEY_RESIZE) && HAVE_WRESIZE
|
---|
559 | typedef struct {
|
---|
560 | WINDOW *text;
|
---|
561 | WINDOW *frame;
|
---|
562 | } WINSTACK;
|
---|
563 |
|
---|
564 | static WINSTACK *winstack = 0;
|
---|
565 | static unsigned len_winstack = 0;
|
---|
566 |
|
---|
567 | static void
|
---|
568 | remember_boxes(unsigned level, WINDOW *txt_win, WINDOW *box_win)
|
---|
569 | {
|
---|
570 | unsigned need = (level + 1) * 2;
|
---|
571 |
|
---|
572 | if (winstack == 0) {
|
---|
573 | len_winstack = 20;
|
---|
574 | winstack = (WINSTACK *) malloc(len_winstack * sizeof(WINSTACK));
|
---|
575 | } else if (need >= len_winstack) {
|
---|
576 | len_winstack = need;
|
---|
577 | winstack = (WINSTACK *) realloc(winstack, len_winstack * sizeof(WINSTACK));
|
---|
578 | }
|
---|
579 | winstack[level].text = txt_win;
|
---|
580 | winstack[level].frame = box_win;
|
---|
581 | }
|
---|
582 |
|
---|
583 | /*
|
---|
584 | * For wgetch_test(), we create pairs of windows - one for a box, one for text.
|
---|
585 | * Resize both and paint the box in the parent.
|
---|
586 | */
|
---|
587 | static void
|
---|
588 | resize_boxes(unsigned level, WINDOW *win)
|
---|
589 | {
|
---|
590 | unsigned n;
|
---|
591 | int base = 5;
|
---|
592 | int high = LINES - base;
|
---|
593 | int wide = COLS;
|
---|
594 |
|
---|
595 | touchwin(stdscr);
|
---|
596 | wnoutrefresh(stdscr);
|
---|
597 |
|
---|
598 | /* FIXME: this chunk should be done in resizeterm() */
|
---|
599 | slk_touch();
|
---|
600 | slk_clear();
|
---|
601 | slk_noutrefresh();
|
---|
602 |
|
---|
603 | for (n = 0; n < level; ++n) {
|
---|
604 | wresize(winstack[n].frame, high, wide);
|
---|
605 | wresize(winstack[n].text, high - 2, wide - 2);
|
---|
606 | high -= 2;
|
---|
607 | wide -= 2;
|
---|
608 | werase(winstack[n].text);
|
---|
609 | box(winstack[n].frame, 0, 0);
|
---|
610 | wnoutrefresh(winstack[n].frame);
|
---|
611 | wprintw(winstack[n].text,
|
---|
612 | "size %dx%d\n",
|
---|
613 | getmaxy(winstack[n].text),
|
---|
614 | getmaxx(winstack[n].text));
|
---|
615 | wnoutrefresh(winstack[n].text);
|
---|
616 | if (winstack[n].text == win)
|
---|
617 | break;
|
---|
618 | }
|
---|
619 | doupdate();
|
---|
620 | }
|
---|
621 | #else
|
---|
622 | #define remember_boxes(level,text,frame) /* nothing */
|
---|
623 | #endif
|
---|
624 |
|
---|
625 | static void
|
---|
626 | wgetch_test(unsigned level, WINDOW *win, int delay)
|
---|
627 | {
|
---|
628 | char buf[BUFSIZ];
|
---|
629 | int first_y, first_x;
|
---|
630 | int c;
|
---|
631 | int incount = 0;
|
---|
632 | bool flags[256];
|
---|
633 | bool blocking = (delay < 0);
|
---|
634 |
|
---|
635 | memset(flags, FALSE, sizeof(flags));
|
---|
636 | flags[UChar('k')] = (win == stdscr);
|
---|
637 |
|
---|
638 | setup_getch(win, flags);
|
---|
639 | wtimeout(win, delay);
|
---|
640 | getyx(win, first_y, first_x);
|
---|
641 |
|
---|
642 | wgetch_help(win, flags);
|
---|
643 | wsetscrreg(win, first_y, getmaxy(win) - 1);
|
---|
644 | scrollok(win, TRUE);
|
---|
645 |
|
---|
646 | for (;;) {
|
---|
647 | while ((c = wGetchar(win)) == ERR) {
|
---|
648 | incount++;
|
---|
649 | if (blocking) {
|
---|
650 | (void) wprintw(win, "%05d: input error", incount);
|
---|
651 | break;
|
---|
652 | } else {
|
---|
653 | (void) wprintw(win, "%05d: input timed out", incount);
|
---|
654 | }
|
---|
655 | wgetch_wrap(win, first_y);
|
---|
656 | }
|
---|
657 | if (c == ERR && blocking) {
|
---|
658 | wprintw(win, "ERR");
|
---|
659 | wgetch_wrap(win, first_y);
|
---|
660 | } else if (c == 'x' || c == 'q') {
|
---|
661 | break;
|
---|
662 | } else if (c == 'e') {
|
---|
663 | flags[UChar('e')] = !flags[UChar('e')];
|
---|
664 | setup_getch(win, flags);
|
---|
665 | wgetch_help(win, flags);
|
---|
666 | } else if (c == 'g') {
|
---|
667 | waddstr(win, "getstr test: ");
|
---|
668 | echo();
|
---|
669 | wgetnstr(win, buf, sizeof(buf) - 1);
|
---|
670 | noecho();
|
---|
671 | wprintw(win, "I saw %d characters:\n\t`%s'.", (int) strlen(buf), buf);
|
---|
672 | wclrtoeol(win);
|
---|
673 | wgetch_wrap(win, first_y);
|
---|
674 | } else if (c == 'k') {
|
---|
675 | flags[UChar('k')] = !flags[UChar('k')];
|
---|
676 | setup_getch(win, flags);
|
---|
677 | wgetch_help(win, flags);
|
---|
678 | } else if (c == 'm') {
|
---|
679 | flags[UChar('m')] = !flags[UChar('m')];
|
---|
680 | setup_getch(win, flags);
|
---|
681 | wgetch_help(win, flags);
|
---|
682 | } else if (c == 's') {
|
---|
683 | ShellOut(TRUE);
|
---|
684 | } else if (c == 'w') {
|
---|
685 | int high = getmaxy(win) - 1 - first_y + 1;
|
---|
686 | int wide = getmaxx(win) - first_x;
|
---|
687 | int old_y, old_x;
|
---|
688 | int new_y = first_y + getbegy(win);
|
---|
689 | int new_x = first_x + getbegx(win);
|
---|
690 |
|
---|
691 | getyx(win, old_y, old_x);
|
---|
692 | if (high > 2 && wide > 2) {
|
---|
693 | WINDOW *wb = newwin(high, wide, new_y, new_x);
|
---|
694 | WINDOW *wi = newwin(high - 2, wide - 2, new_y + 1, new_x + 1);
|
---|
695 |
|
---|
696 | box(wb, 0, 0);
|
---|
697 | wrefresh(wb);
|
---|
698 | wmove(wi, 0, 0);
|
---|
699 | remember_boxes(level, wi, wb);
|
---|
700 | wgetch_test(level + 1, wi, delay);
|
---|
701 | delwin(wi);
|
---|
702 | delwin(wb);
|
---|
703 |
|
---|
704 | wgetch_help(win, flags);
|
---|
705 | wmove(win, old_y, old_x);
|
---|
706 | touchwin(win);
|
---|
707 | wrefresh(win);
|
---|
708 | doupdate();
|
---|
709 | }
|
---|
710 | #ifdef SIGTSTP
|
---|
711 | } else if (c == 'z') {
|
---|
712 | kill(getpid(), SIGTSTP);
|
---|
713 | #endif
|
---|
714 | } else {
|
---|
715 | wprintw(win, "Key pressed: %04o ", c);
|
---|
716 | #ifdef NCURSES_MOUSE_VERSION
|
---|
717 | if (c == KEY_MOUSE) {
|
---|
718 | int y, x;
|
---|
719 | MEVENT event;
|
---|
720 |
|
---|
721 | getmouse(&event);
|
---|
722 | wprintw(win, "KEY_MOUSE, %s", mouse_decode(&event));
|
---|
723 | getyx(win, y, x);
|
---|
724 | move(event.y, event.x);
|
---|
725 | addch('*');
|
---|
726 | wmove(win, y, x);
|
---|
727 | } else
|
---|
728 | #endif /* NCURSES_MOUSE_VERSION */
|
---|
729 | if (c >= KEY_MIN) {
|
---|
730 | #if defined(NCURSES_VERSION) && defined(KEY_RESIZE) && HAVE_WRESIZE
|
---|
731 | if (c == KEY_RESIZE) {
|
---|
732 | resize_boxes(level, win);
|
---|
733 | }
|
---|
734 | #endif
|
---|
735 | (void) waddstr(win, keyname(c));
|
---|
736 | } else if (c > 0x80) {
|
---|
737 | unsigned c2 = (c & 0x7f);
|
---|
738 | if (isprint(c2))
|
---|
739 | (void) wprintw(win, "M-%c", UChar(c2));
|
---|
740 | else
|
---|
741 | (void) wprintw(win, "M-%s", unctrl(c2));
|
---|
742 | waddstr(win, " (high-half character)");
|
---|
743 | } else {
|
---|
744 | if (isprint(c))
|
---|
745 | (void) wprintw(win, "%c (ASCII printable character)", c);
|
---|
746 | else
|
---|
747 | (void) wprintw(win, "%s (ASCII control character)",
|
---|
748 | unctrl(UChar(c)));
|
---|
749 | }
|
---|
750 | wgetch_wrap(win, first_y);
|
---|
751 | }
|
---|
752 | }
|
---|
753 |
|
---|
754 | wtimeout(win, -1);
|
---|
755 | }
|
---|
756 |
|
---|
757 | static int
|
---|
758 | begin_getch_test(void)
|
---|
759 | {
|
---|
760 | char buf[BUFSIZ];
|
---|
761 | int delay;
|
---|
762 |
|
---|
763 | refresh();
|
---|
764 |
|
---|
765 | #ifdef NCURSES_MOUSE_VERSION
|
---|
766 | mousemask(ALL_MOUSE_EVENTS, (mmask_t *) 0);
|
---|
767 | #endif
|
---|
768 |
|
---|
769 | (void) printw("Delay in 10ths of a second (<CR> for blocking input)? ");
|
---|
770 | echo();
|
---|
771 | getnstr(buf, sizeof(buf) - 1);
|
---|
772 | noecho();
|
---|
773 | nonl();
|
---|
774 |
|
---|
775 | if (isdigit(UChar(buf[0]))) {
|
---|
776 | delay = atoi(buf) * 100;
|
---|
777 | } else {
|
---|
778 | delay = -1;
|
---|
779 | }
|
---|
780 | raw();
|
---|
781 | move(5, 0);
|
---|
782 | return delay;
|
---|
783 | }
|
---|
784 |
|
---|
785 | static void
|
---|
786 | finish_getch_test(void)
|
---|
787 | {
|
---|
788 | #ifdef NCURSES_MOUSE_VERSION
|
---|
789 | mousemask(0, (mmask_t *) 0);
|
---|
790 | #endif
|
---|
791 | erase();
|
---|
792 | noraw();
|
---|
793 | nl();
|
---|
794 | endwin();
|
---|
795 | }
|
---|
796 |
|
---|
797 | static void
|
---|
798 | getch_test(void)
|
---|
799 | {
|
---|
800 | int delay = begin_getch_test();
|
---|
801 | wgetch_test(0, stdscr, delay);
|
---|
802 | finish_getch_test();
|
---|
803 | }
|
---|
804 |
|
---|
805 | #if USE_WIDEC_SUPPORT
|
---|
806 | /*
|
---|
807 | * For wgetch_test(), we create pairs of windows - one for a box, one for text.
|
---|
808 | * Resize both and paint the box in the parent.
|
---|
809 | */
|
---|
810 | #ifdef KEY_RESIZE
|
---|
811 | static void
|
---|
812 | resize_wide_boxes(unsigned level, WINDOW *win)
|
---|
813 | {
|
---|
814 | unsigned n;
|
---|
815 | int base = 5;
|
---|
816 | int high = LINES - base;
|
---|
817 | int wide = COLS;
|
---|
818 |
|
---|
819 | touchwin(stdscr);
|
---|
820 | wnoutrefresh(stdscr);
|
---|
821 |
|
---|
822 | /* FIXME: this chunk should be done in resizeterm() */
|
---|
823 | slk_touch();
|
---|
824 | slk_clear();
|
---|
825 | slk_noutrefresh();
|
---|
826 |
|
---|
827 | for (n = 0; n < level; ++n) {
|
---|
828 | wresize(winstack[n].frame, high, wide);
|
---|
829 | wresize(winstack[n].text, high - 2, wide - 2);
|
---|
830 | high -= 2;
|
---|
831 | wide -= 2;
|
---|
832 | werase(winstack[n].text);
|
---|
833 | box_set(winstack[n].frame, 0, 0);
|
---|
834 | wnoutrefresh(winstack[n].frame);
|
---|
835 | wprintw(winstack[n].text,
|
---|
836 | "size %dx%d\n",
|
---|
837 | getmaxy(winstack[n].text),
|
---|
838 | getmaxx(winstack[n].text));
|
---|
839 | wnoutrefresh(winstack[n].text);
|
---|
840 | if (winstack[n].text == win)
|
---|
841 | break;
|
---|
842 | }
|
---|
843 | doupdate();
|
---|
844 | }
|
---|
845 | #endif /* KEY_RESIZE */
|
---|
846 |
|
---|
847 | static char *
|
---|
848 | wcstos(const wchar_t *src)
|
---|
849 | {
|
---|
850 | int need;
|
---|
851 | mbstate_t state;
|
---|
852 | char *result = 0;
|
---|
853 | const wchar_t *tmp = src;
|
---|
854 |
|
---|
855 | memset(&state, 0, sizeof(state));
|
---|
856 | if ((need = wcsrtombs(0, &tmp, 0, &state)) > 0) {
|
---|
857 | unsigned have = need;
|
---|
858 | result = (char *) calloc(have + 1, 1);
|
---|
859 | tmp = src;
|
---|
860 | if (wcsrtombs(result, &tmp, have, &state) != have) {
|
---|
861 | free(result);
|
---|
862 | result = 0;
|
---|
863 | }
|
---|
864 | }
|
---|
865 | return result;
|
---|
866 | }
|
---|
867 |
|
---|
868 | static void
|
---|
869 | wget_wch_test(unsigned level, WINDOW *win, int delay)
|
---|
870 | {
|
---|
871 | wchar_t wchar_buf[BUFSIZ];
|
---|
872 | wint_t wint_buf[BUFSIZ];
|
---|
873 | int first_y, first_x;
|
---|
874 | wint_t c;
|
---|
875 | int incount = 0;
|
---|
876 | bool flags[256];
|
---|
877 | bool blocking = (delay < 0);
|
---|
878 | int y, x, code;
|
---|
879 | char *temp;
|
---|
880 |
|
---|
881 | memset(flags, FALSE, sizeof(flags));
|
---|
882 | flags[UChar('k')] = (win == stdscr);
|
---|
883 |
|
---|
884 | setup_getch(win, flags);
|
---|
885 | wtimeout(win, delay);
|
---|
886 | getyx(win, first_y, first_x);
|
---|
887 |
|
---|
888 | wgetch_help(win, flags);
|
---|
889 | wsetscrreg(win, first_y, getmaxy(win) - 1);
|
---|
890 | scrollok(win, TRUE);
|
---|
891 |
|
---|
892 | for (;;) {
|
---|
893 | while ((code = wGet_wchar(win, &c)) == ERR) {
|
---|
894 | incount++;
|
---|
895 | if (blocking) {
|
---|
896 | (void) wprintw(win, "%05d: input error", incount);
|
---|
897 | break;
|
---|
898 | } else {
|
---|
899 | (void) wprintw(win, "%05d: input timed out", incount);
|
---|
900 | }
|
---|
901 | wgetch_wrap(win, first_y);
|
---|
902 | }
|
---|
903 | if (code == ERR && blocking) {
|
---|
904 | wprintw(win, "ERR");
|
---|
905 | wgetch_wrap(win, first_y);
|
---|
906 | } else if (c == 'x' || c == 'q') {
|
---|
907 | break;
|
---|
908 | } else if (c == 'e') {
|
---|
909 | flags[UChar('e')] = !flags[UChar('e')];
|
---|
910 | setup_getch(win, flags);
|
---|
911 | wgetch_help(win, flags);
|
---|
912 | } else if (c == 'g') {
|
---|
913 | waddstr(win, "getstr test: ");
|
---|
914 | echo();
|
---|
915 | code = wgetn_wstr(win, wint_buf, sizeof(wint_buf) - 1);
|
---|
916 | noecho();
|
---|
917 | if (code == ERR) {
|
---|
918 | wprintw(win, "wgetn_wstr returns an error.");
|
---|
919 | } else {
|
---|
920 | int n;
|
---|
921 | for (n = 0; (wchar_buf[n] = wint_buf[n]) != 0; ++n) ;
|
---|
922 | if ((temp = wcstos(wchar_buf)) != 0) {
|
---|
923 | wprintw(win, "I saw %d characters:\n\t`%s'.",
|
---|
924 | wcslen(wchar_buf), temp);
|
---|
925 | free(temp);
|
---|
926 | } else {
|
---|
927 | wprintw(win, "I saw %d characters (cannot convert).",
|
---|
928 | wcslen(wchar_buf));
|
---|
929 | }
|
---|
930 | }
|
---|
931 | wclrtoeol(win);
|
---|
932 | wgetch_wrap(win, first_y);
|
---|
933 | } else if (c == 'k') {
|
---|
934 | flags[UChar('k')] = !flags[UChar('k')];
|
---|
935 | setup_getch(win, flags);
|
---|
936 | wgetch_help(win, flags);
|
---|
937 | } else if (c == 'm') {
|
---|
938 | flags[UChar('m')] = !flags[UChar('m')];
|
---|
939 | setup_getch(win, flags);
|
---|
940 | wgetch_help(win, flags);
|
---|
941 | } else if (c == 's') {
|
---|
942 | ShellOut(TRUE);
|
---|
943 | } else if (c == 'w') {
|
---|
944 | int high = getmaxy(win) - 1 - first_y + 1;
|
---|
945 | int wide = getmaxx(win) - first_x;
|
---|
946 | int old_y, old_x;
|
---|
947 | int new_y = first_y + getbegy(win);
|
---|
948 | int new_x = first_x + getbegx(win);
|
---|
949 |
|
---|
950 | getyx(win, old_y, old_x);
|
---|
951 | if (high > 2 && wide > 2) {
|
---|
952 | WINDOW *wb = newwin(high, wide, new_y, new_x);
|
---|
953 | WINDOW *wi = newwin(high - 2, wide - 2, new_y + 1, new_x + 1);
|
---|
954 |
|
---|
955 | box_set(wb, 0, 0);
|
---|
956 | wrefresh(wb);
|
---|
957 | wmove(wi, 0, 0);
|
---|
958 | remember_boxes(level, wi, wb);
|
---|
959 | wget_wch_test(level + 1, wi, delay);
|
---|
960 | delwin(wi);
|
---|
961 | delwin(wb);
|
---|
962 |
|
---|
963 | wgetch_help(win, flags);
|
---|
964 | wmove(win, old_y, old_x);
|
---|
965 | touchwin(win);
|
---|
966 | wrefresh(win);
|
---|
967 | }
|
---|
968 | #ifdef SIGTSTP
|
---|
969 | } else if (c == 'z') {
|
---|
970 | kill(getpid(), SIGTSTP);
|
---|
971 | #endif
|
---|
972 | } else {
|
---|
973 | wprintw(win, "Key pressed: %04o ", c);
|
---|
974 | #ifdef NCURSES_MOUSE_VERSION
|
---|
975 | if (c == KEY_MOUSE) {
|
---|
976 | MEVENT event;
|
---|
977 |
|
---|
978 | getmouse(&event);
|
---|
979 | wprintw(win, "KEY_MOUSE, %s", mouse_decode(&event));
|
---|
980 | getyx(win, y, x);
|
---|
981 | move(event.y, event.x);
|
---|
982 | addch('*');
|
---|
983 | wmove(win, y, x);
|
---|
984 | } else
|
---|
985 | #endif /* NCURSES_MOUSE_VERSION */
|
---|
986 | if (code == KEY_CODE_YES) {
|
---|
987 | #ifdef KEY_RESIZE
|
---|
988 | if (c == KEY_RESIZE) {
|
---|
989 | resize_wide_boxes(level, win);
|
---|
990 | }
|
---|
991 | #endif
|
---|
992 | (void) waddstr(win, key_name((wchar_t) c));
|
---|
993 | } else {
|
---|
994 | if (c < 256 && iscntrl(c)) {
|
---|
995 | (void) wprintw(win, "%s (control character)", unctrl(c));
|
---|
996 | } else {
|
---|
997 | wchar_t c2 = c;
|
---|
998 | waddnwstr(win, &c2, 1);
|
---|
999 | (void) wprintw(win, " = %#x (printable character)", c);
|
---|
1000 | }
|
---|
1001 | }
|
---|
1002 | wgetch_wrap(win, first_y);
|
---|
1003 | }
|
---|
1004 | }
|
---|
1005 |
|
---|
1006 | wtimeout(win, -1);
|
---|
1007 | }
|
---|
1008 |
|
---|
1009 | static void
|
---|
1010 | get_wch_test(void)
|
---|
1011 | {
|
---|
1012 | int delay = begin_getch_test();
|
---|
1013 | wget_wch_test(0, stdscr, delay);
|
---|
1014 | finish_getch_test();
|
---|
1015 | }
|
---|
1016 | #endif
|
---|
1017 |
|
---|
1018 | /****************************************************************************
|
---|
1019 | *
|
---|
1020 | * Character attributes test
|
---|
1021 | *
|
---|
1022 | ****************************************************************************/
|
---|
1023 |
|
---|
1024 | #define MAX_ATTRSTRING 31
|
---|
1025 | #define LEN_ATTRSTRING 26
|
---|
1026 |
|
---|
1027 | static char attr_test_string[MAX_ATTRSTRING + 1];
|
---|
1028 |
|
---|
1029 | static void
|
---|
1030 | attr_legend(WINDOW *helpwin)
|
---|
1031 | {
|
---|
1032 | int row = 1;
|
---|
1033 | int col = 1;
|
---|
1034 |
|
---|
1035 | mvwprintw(helpwin, row++, col,
|
---|
1036 | "q or ESC to exit.");
|
---|
1037 | mvwprintw(helpwin, row++, col,
|
---|
1038 | "^L repaints.");
|
---|
1039 | ++row;
|
---|
1040 | mvwprintw(helpwin, row++, col,
|
---|
1041 | "Modify the test strings:");
|
---|
1042 | mvwprintw(helpwin, row++, col,
|
---|
1043 | " A digit sets gaps on each side of displayed attributes");
|
---|
1044 | mvwprintw(helpwin, row++, col,
|
---|
1045 | " </> shifts the text left/right. ");
|
---|
1046 | ++row;
|
---|
1047 | mvwprintw(helpwin, row++, col,
|
---|
1048 | "Toggles:");
|
---|
1049 | if (has_colors()) {
|
---|
1050 | mvwprintw(helpwin, row++, col,
|
---|
1051 | " f/F/b/F toggle foreground/background background color");
|
---|
1052 | mvwprintw(helpwin, row++, col,
|
---|
1053 | " t/T toggle text/background color attribute");
|
---|
1054 | }
|
---|
1055 | mvwprintw(helpwin, row++, col,
|
---|
1056 | " a/A toggle ACS (alternate character set) mapping");
|
---|
1057 | mvwprintw(helpwin, row++, col,
|
---|
1058 | " v/V toggle video attribute to combine with each line");
|
---|
1059 | }
|
---|
1060 |
|
---|
1061 | static void
|
---|
1062 | show_color_attr(int fg, int bg, int tx)
|
---|
1063 | {
|
---|
1064 | if (has_colors()) {
|
---|
1065 | printw(" Colors (fg %d, bg %d", fg, bg);
|
---|
1066 | if (tx >= 0)
|
---|
1067 | printw(", text %d", tx);
|
---|
1068 | printw("),");
|
---|
1069 | }
|
---|
1070 | }
|
---|
1071 |
|
---|
1072 | static bool
|
---|
1073 | cycle_color_attr(int ch, int *fg, int *bg, int *tx)
|
---|
1074 | {
|
---|
1075 | bool error = FALSE;
|
---|
1076 |
|
---|
1077 | if (has_colors()) {
|
---|
1078 | switch (ch) {
|
---|
1079 | case 'f':
|
---|
1080 | *fg = (*fg + 1);
|
---|
1081 | break;
|
---|
1082 | case 'F':
|
---|
1083 | *fg = (*fg - 1);
|
---|
1084 | break;
|
---|
1085 | case 'b':
|
---|
1086 | *bg = (*bg + 1);
|
---|
1087 | break;
|
---|
1088 | case 'B':
|
---|
1089 | *bg = (*bg - 1);
|
---|
1090 | break;
|
---|
1091 | case 't':
|
---|
1092 | *tx = (*tx + 1);
|
---|
1093 | break;
|
---|
1094 | case 'T':
|
---|
1095 | *tx = (*tx - 1);
|
---|
1096 | break;
|
---|
1097 | default:
|
---|
1098 | beep();
|
---|
1099 | error = TRUE;
|
---|
1100 | break;
|
---|
1101 | }
|
---|
1102 | if (*fg >= COLORS)
|
---|
1103 | *fg = min_colors;
|
---|
1104 | if (*fg < min_colors)
|
---|
1105 | *fg = COLORS - 1;
|
---|
1106 | if (*bg >= COLORS)
|
---|
1107 | *bg = min_colors;
|
---|
1108 | if (*bg < min_colors)
|
---|
1109 | *bg = COLORS - 1;
|
---|
1110 | if (*tx >= COLORS)
|
---|
1111 | *tx = -1;
|
---|
1112 | if (*tx < -1)
|
---|
1113 | *tx = COLORS - 1;
|
---|
1114 | } else {
|
---|
1115 | beep();
|
---|
1116 | error = TRUE;
|
---|
1117 | }
|
---|
1118 | return error;
|
---|
1119 | }
|
---|
1120 |
|
---|
1121 | static void
|
---|
1122 | adjust_attr_string(int adjust)
|
---|
1123 | {
|
---|
1124 | int first = ((int) UChar(attr_test_string[0])) + adjust;
|
---|
1125 | int last = first + LEN_ATTRSTRING;
|
---|
1126 |
|
---|
1127 | if (first >= ' ' && last <= '~') { /* 32..126 */
|
---|
1128 | int j, k;
|
---|
1129 | for (j = 0, k = first; j < MAX_ATTRSTRING && k <= last; ++j, ++k) {
|
---|
1130 | attr_test_string[j] = k;
|
---|
1131 | if (((k + 1 - first) % 5) == 0) {
|
---|
1132 | ++j;
|
---|
1133 | if (j < MAX_ATTRSTRING)
|
---|
1134 | attr_test_string[j] = ' ';
|
---|
1135 | }
|
---|
1136 | }
|
---|
1137 | while (j < MAX_ATTRSTRING)
|
---|
1138 | attr_test_string[j++] = ' ';
|
---|
1139 | attr_test_string[j] = '\0';
|
---|
1140 | } else {
|
---|
1141 | beep();
|
---|
1142 | }
|
---|
1143 | }
|
---|
1144 |
|
---|
1145 | static void
|
---|
1146 | init_attr_string(void)
|
---|
1147 | {
|
---|
1148 | attr_test_string[0] = 'a';
|
---|
1149 | adjust_attr_string(0);
|
---|
1150 | }
|
---|
1151 |
|
---|
1152 | static int
|
---|
1153 | show_attr(int row, int skip, bool arrow, chtype attr, const char *name)
|
---|
1154 | {
|
---|
1155 | int ncv = tigetnum("ncv");
|
---|
1156 | chtype test = attr & (chtype) (~A_ALTCHARSET);
|
---|
1157 |
|
---|
1158 | if (arrow)
|
---|
1159 | mvprintw(row, 5, "-->");
|
---|
1160 | mvprintw(row, 8, "%s mode:", name);
|
---|
1161 | mvprintw(row, 24, "|");
|
---|
1162 | if (skip)
|
---|
1163 | printw("%*s", skip, " ");
|
---|
1164 | /*
|
---|
1165 | * Just for testing, write text using the alternate character set one
|
---|
1166 | * character at a time (to pass its rendition directly), and use the
|
---|
1167 | * string operation for the other attributes.
|
---|
1168 | */
|
---|
1169 | if (attr & A_ALTCHARSET) {
|
---|
1170 | const char *s;
|
---|
1171 | chtype ch;
|
---|
1172 |
|
---|
1173 | for (s = attr_test_string; *s != '\0'; ++s) {
|
---|
1174 | ch = UChar(*s);
|
---|
1175 | addch(ch | attr);
|
---|
1176 | }
|
---|
1177 | } else {
|
---|
1178 | attrset(attr);
|
---|
1179 | addstr(attr_test_string);
|
---|
1180 | attroff(attr);
|
---|
1181 | }
|
---|
1182 | if (skip)
|
---|
1183 | printw("%*s", skip, " ");
|
---|
1184 | printw("|");
|
---|
1185 | if (test != A_NORMAL) {
|
---|
1186 | if (!(termattrs() & test)) {
|
---|
1187 | printw(" (N/A)");
|
---|
1188 | } else {
|
---|
1189 | if (ncv > 0 && (getbkgd(stdscr) & A_COLOR)) {
|
---|
1190 | static const chtype table[] =
|
---|
1191 | {
|
---|
1192 | A_STANDOUT,
|
---|
1193 | A_UNDERLINE,
|
---|
1194 | A_REVERSE,
|
---|
1195 | A_BLINK,
|
---|
1196 | A_DIM,
|
---|
1197 | A_BOLD,
|
---|
1198 | A_INVIS,
|
---|
1199 | A_PROTECT,
|
---|
1200 | A_ALTCHARSET
|
---|
1201 | };
|
---|
1202 | unsigned n;
|
---|
1203 | bool found = FALSE;
|
---|
1204 | for (n = 0; n < SIZEOF(table); n++) {
|
---|
1205 | if ((table[n] & attr) != 0
|
---|
1206 | && ((1 << n) & ncv) != 0) {
|
---|
1207 | found = TRUE;
|
---|
1208 | break;
|
---|
1209 | }
|
---|
1210 | }
|
---|
1211 | if (found)
|
---|
1212 | printw(" (NCV)");
|
---|
1213 | }
|
---|
1214 | if ((termattrs() & test) != test)
|
---|
1215 | printw(" (Part)");
|
---|
1216 | }
|
---|
1217 | }
|
---|
1218 | return row + 2;
|
---|
1219 | }
|
---|
1220 | /* *INDENT-OFF* */
|
---|
1221 | static const struct {
|
---|
1222 | attr_t attr;
|
---|
1223 | NCURSES_CONST char * name;
|
---|
1224 | } attrs_to_test[] = {
|
---|
1225 | { A_STANDOUT, "STANDOUT" },
|
---|
1226 | { A_REVERSE, "REVERSE" },
|
---|
1227 | { A_BOLD, "BOLD" },
|
---|
1228 | { A_UNDERLINE, "UNDERLINE" },
|
---|
1229 | { A_DIM, "DIM" },
|
---|
1230 | { A_BLINK, "BLINK" },
|
---|
1231 | { A_PROTECT, "PROTECT" },
|
---|
1232 | { A_INVIS, "INVISIBLE" },
|
---|
1233 | { A_NORMAL, "NORMAL" },
|
---|
1234 | };
|
---|
1235 | /* *INDENT-ON* */
|
---|
1236 |
|
---|
1237 | static bool
|
---|
1238 | attr_getc(int *skip, int *fg, int *bg, int *tx, int *ac, unsigned *kc)
|
---|
1239 | {
|
---|
1240 | bool result = TRUE;
|
---|
1241 | bool error = FALSE;
|
---|
1242 | WINDOW *helpwin;
|
---|
1243 |
|
---|
1244 | do {
|
---|
1245 | int ch = Getchar();
|
---|
1246 |
|
---|
1247 | error = FALSE;
|
---|
1248 | if (ch < 256 && isdigit(ch)) {
|
---|
1249 | *skip = (ch - '0');
|
---|
1250 | } else {
|
---|
1251 | switch (ch) {
|
---|
1252 | case CTRL('L'):
|
---|
1253 | Repaint();
|
---|
1254 | break;
|
---|
1255 | case '?':
|
---|
1256 | if ((helpwin = newwin(LINES - 1, COLS - 2, 0, 0)) != 0) {
|
---|
1257 | box(helpwin, 0, 0);
|
---|
1258 | attr_legend(helpwin);
|
---|
1259 | wGetchar(helpwin);
|
---|
1260 | delwin(helpwin);
|
---|
1261 | }
|
---|
1262 | break;
|
---|
1263 | case 'a':
|
---|
1264 | *ac = 0;
|
---|
1265 | break;
|
---|
1266 | case 'A':
|
---|
1267 | *ac = A_ALTCHARSET;
|
---|
1268 | break;
|
---|
1269 | case 'v':
|
---|
1270 | if (*kc == 0)
|
---|
1271 | *kc = SIZEOF(attrs_to_test) - 1;
|
---|
1272 | else
|
---|
1273 | *kc -= 1;
|
---|
1274 | break;
|
---|
1275 | case 'V':
|
---|
1276 | *kc += 1;
|
---|
1277 | if (*kc >= SIZEOF(attrs_to_test))
|
---|
1278 | *kc = 0;
|
---|
1279 | break;
|
---|
1280 | case '<':
|
---|
1281 | adjust_attr_string(-1);
|
---|
1282 | break;
|
---|
1283 | case '>':
|
---|
1284 | adjust_attr_string(1);
|
---|
1285 | break;
|
---|
1286 | case 'q':
|
---|
1287 | case ESCAPE:
|
---|
1288 | result = FALSE;
|
---|
1289 | break;
|
---|
1290 | default:
|
---|
1291 | error = cycle_color_attr(ch, fg, bg, tx);
|
---|
1292 | break;
|
---|
1293 | }
|
---|
1294 | }
|
---|
1295 | } while (error);
|
---|
1296 | return result;
|
---|
1297 | }
|
---|
1298 |
|
---|
1299 | static void
|
---|
1300 | attr_test(void)
|
---|
1301 | /* test text attributes */
|
---|
1302 | {
|
---|
1303 | int n;
|
---|
1304 | int skip = tigetnum("xmc");
|
---|
1305 | int fg = COLOR_BLACK; /* color pair 0 is special */
|
---|
1306 | int bg = COLOR_BLACK;
|
---|
1307 | int tx = -1;
|
---|
1308 | int ac = 0;
|
---|
1309 | unsigned j, k;
|
---|
1310 |
|
---|
1311 | if (skip < 0)
|
---|
1312 | skip = 0;
|
---|
1313 |
|
---|
1314 | n = skip; /* make it easy */
|
---|
1315 | k = SIZEOF(attrs_to_test) - 1;
|
---|
1316 | init_attr_string();
|
---|
1317 |
|
---|
1318 | do {
|
---|
1319 | int row = 2;
|
---|
1320 | chtype normal = A_NORMAL | BLANK;
|
---|
1321 | chtype extras = ac;
|
---|
1322 |
|
---|
1323 | if (has_colors()) {
|
---|
1324 | int pair = (fg != COLOR_BLACK || bg != COLOR_BLACK);
|
---|
1325 | if (pair != 0) {
|
---|
1326 | pair = 1;
|
---|
1327 | if (init_pair(pair, fg, bg) == ERR) {
|
---|
1328 | beep();
|
---|
1329 | } else {
|
---|
1330 | normal |= COLOR_PAIR(pair);
|
---|
1331 | }
|
---|
1332 | }
|
---|
1333 | if (tx >= 0) {
|
---|
1334 | pair = 2;
|
---|
1335 | if (init_pair(pair, tx, bg) == ERR) {
|
---|
1336 | beep();
|
---|
1337 | } else {
|
---|
1338 | extras |= COLOR_PAIR(pair);
|
---|
1339 | }
|
---|
1340 | }
|
---|
1341 | }
|
---|
1342 | bkgd(normal);
|
---|
1343 | bkgdset(normal);
|
---|
1344 | erase();
|
---|
1345 |
|
---|
1346 | box(stdscr, 0, 0);
|
---|
1347 | mvaddstr(0, 20, "Character attribute test display");
|
---|
1348 |
|
---|
1349 | for (j = 0; j < SIZEOF(attrs_to_test); ++j) {
|
---|
1350 | row = show_attr(row, n, j == k,
|
---|
1351 | extras |
|
---|
1352 | attrs_to_test[j].attr |
|
---|
1353 | attrs_to_test[k].attr,
|
---|
1354 | attrs_to_test[j].name);
|
---|
1355 | }
|
---|
1356 |
|
---|
1357 | mvprintw(row, 8,
|
---|
1358 | "This terminal does %shave the magic-cookie glitch",
|
---|
1359 | tigetnum("xmc") > -1 ? "" : "not ");
|
---|
1360 | mvprintw(row + 1, 8, "Enter '?' for help.");
|
---|
1361 | show_color_attr(fg, bg, tx);
|
---|
1362 | printw(" ACS (%d)", ac != 0);
|
---|
1363 |
|
---|
1364 | refresh();
|
---|
1365 | } while (attr_getc(&n, &fg, &bg, &tx, &ac, &k));
|
---|
1366 |
|
---|
1367 | bkgdset(A_NORMAL | BLANK);
|
---|
1368 | erase();
|
---|
1369 | endwin();
|
---|
1370 | }
|
---|
1371 |
|
---|
1372 | #if USE_WIDEC_SUPPORT
|
---|
1373 | static wchar_t wide_attr_test_string[MAX_ATTRSTRING + 1];
|
---|
1374 |
|
---|
1375 | static void
|
---|
1376 | wide_adjust_attr_string(int adjust)
|
---|
1377 | {
|
---|
1378 | int first = ((int) UChar(wide_attr_test_string[0])) + adjust;
|
---|
1379 | int last = first + LEN_ATTRSTRING;
|
---|
1380 |
|
---|
1381 | if (first >= ' ' && last <= '~') { /* 32..126 */
|
---|
1382 | int j, k;
|
---|
1383 | for (j = 0, k = first; j < MAX_ATTRSTRING && k <= last; ++j, ++k) {
|
---|
1384 | wide_attr_test_string[j] = k;
|
---|
1385 | if (((k + 1 - first) % 5) == 0) {
|
---|
1386 | ++j;
|
---|
1387 | if (j < MAX_ATTRSTRING)
|
---|
1388 | wide_attr_test_string[j] = ' ';
|
---|
1389 | }
|
---|
1390 | }
|
---|
1391 | while (j < MAX_ATTRSTRING)
|
---|
1392 | wide_attr_test_string[j++] = ' ';
|
---|
1393 | wide_attr_test_string[j] = '\0';
|
---|
1394 | } else {
|
---|
1395 | beep();
|
---|
1396 | }
|
---|
1397 | }
|
---|
1398 |
|
---|
1399 | static void
|
---|
1400 | wide_init_attr_string(void)
|
---|
1401 | {
|
---|
1402 | wide_attr_test_string[0] = 'a';
|
---|
1403 | wide_adjust_attr_string(0);
|
---|
1404 | }
|
---|
1405 |
|
---|
1406 | static void
|
---|
1407 | set_wide_background(short pair)
|
---|
1408 | {
|
---|
1409 | cchar_t normal;
|
---|
1410 | wchar_t blank[2];
|
---|
1411 |
|
---|
1412 | blank[0] = ' ';
|
---|
1413 | blank[1] = 0;
|
---|
1414 | setcchar(&normal, blank, A_NORMAL, pair, 0);
|
---|
1415 | bkgrnd(&normal);
|
---|
1416 | bkgrndset(&normal);
|
---|
1417 | }
|
---|
1418 |
|
---|
1419 | static attr_t
|
---|
1420 | get_wide_background(void)
|
---|
1421 | {
|
---|
1422 | attr_t result = A_NORMAL;
|
---|
1423 | attr_t attr;
|
---|
1424 | cchar_t ch;
|
---|
1425 | short pair;
|
---|
1426 | wchar_t wch;
|
---|
1427 |
|
---|
1428 | if (getbkgrnd(&ch) != ERR) {
|
---|
1429 | if (getcchar(&ch, &wch, &attr, &pair, 0) != ERR) {
|
---|
1430 | result = attr;
|
---|
1431 | }
|
---|
1432 | }
|
---|
1433 | return result;
|
---|
1434 | }
|
---|
1435 |
|
---|
1436 | static int
|
---|
1437 | wide_show_attr(int row, int skip, bool arrow, chtype attr, short pair, const char *name)
|
---|
1438 | {
|
---|
1439 | int ncv = tigetnum("ncv");
|
---|
1440 | chtype test = attr & ~WA_ALTCHARSET;
|
---|
1441 |
|
---|
1442 | if (arrow)
|
---|
1443 | mvprintw(row, 5, "-->");
|
---|
1444 | mvprintw(row, 8, "%s mode:", name);
|
---|
1445 | mvprintw(row, 24, "|");
|
---|
1446 | if (skip)
|
---|
1447 | printw("%*s", skip, " ");
|
---|
1448 |
|
---|
1449 | /*
|
---|
1450 | * Just for testing, write text using the alternate character set one
|
---|
1451 | * character at a time (to pass its rendition directly), and use the
|
---|
1452 | * string operation for the other attributes.
|
---|
1453 | */
|
---|
1454 | if (attr & WA_ALTCHARSET) {
|
---|
1455 | const wchar_t *s;
|
---|
1456 | cchar_t ch;
|
---|
1457 |
|
---|
1458 | for (s = wide_attr_test_string; *s != L'\0'; ++s) {
|
---|
1459 | wchar_t fill[2];
|
---|
1460 | fill[0] = *s;
|
---|
1461 | fill[1] = L'\0';
|
---|
1462 | setcchar(&ch, fill, attr, pair, 0);
|
---|
1463 | add_wch(&ch);
|
---|
1464 | }
|
---|
1465 | } else {
|
---|
1466 | attr_t old_attr;
|
---|
1467 | short old_pair;
|
---|
1468 |
|
---|
1469 | attr_get(&old_attr, &old_pair, 0);
|
---|
1470 | attr_set(attr, pair, 0);
|
---|
1471 | addwstr(wide_attr_test_string);
|
---|
1472 | attr_set(old_attr, old_pair, 0);
|
---|
1473 | }
|
---|
1474 | if (skip)
|
---|
1475 | printw("%*s", skip, " ");
|
---|
1476 | printw("|");
|
---|
1477 | if (test != A_NORMAL) {
|
---|
1478 | if (!(term_attrs() & test)) {
|
---|
1479 | printw(" (N/A)");
|
---|
1480 | } else {
|
---|
1481 | if (ncv > 0 && (get_wide_background() & A_COLOR)) {
|
---|
1482 | static const attr_t table[] =
|
---|
1483 | {
|
---|
1484 | WA_STANDOUT,
|
---|
1485 | WA_UNDERLINE,
|
---|
1486 | WA_REVERSE,
|
---|
1487 | WA_BLINK,
|
---|
1488 | WA_DIM,
|
---|
1489 | WA_BOLD,
|
---|
1490 | WA_INVIS,
|
---|
1491 | WA_PROTECT,
|
---|
1492 | WA_ALTCHARSET
|
---|
1493 | };
|
---|
1494 | unsigned n;
|
---|
1495 | bool found = FALSE;
|
---|
1496 | for (n = 0; n < SIZEOF(table); n++) {
|
---|
1497 | if ((table[n] & attr) != 0
|
---|
1498 | && ((1 << n) & ncv) != 0) {
|
---|
1499 | found = TRUE;
|
---|
1500 | break;
|
---|
1501 | }
|
---|
1502 | }
|
---|
1503 | if (found)
|
---|
1504 | printw(" (NCV)");
|
---|
1505 | }
|
---|
1506 | if ((term_attrs() & test) != test)
|
---|
1507 | printw(" (Part)");
|
---|
1508 | }
|
---|
1509 | }
|
---|
1510 | return row + 2;
|
---|
1511 | }
|
---|
1512 |
|
---|
1513 | static bool
|
---|
1514 | wide_attr_getc(int *skip, int *fg, int *bg, int *tx, int *ac, unsigned *kc)
|
---|
1515 | {
|
---|
1516 | bool result = TRUE;
|
---|
1517 | bool error = FALSE;
|
---|
1518 | WINDOW *helpwin;
|
---|
1519 |
|
---|
1520 | do {
|
---|
1521 | int ch = Getchar();
|
---|
1522 |
|
---|
1523 | error = FALSE;
|
---|
1524 | if (ch < 256 && isdigit(ch)) {
|
---|
1525 | *skip = (ch - '0');
|
---|
1526 | } else {
|
---|
1527 | switch (ch) {
|
---|
1528 | case CTRL('L'):
|
---|
1529 | Repaint();
|
---|
1530 | break;
|
---|
1531 | case '?':
|
---|
1532 | if ((helpwin = newwin(LINES - 1, COLS - 2, 0, 0)) != 0) {
|
---|
1533 | box_set(helpwin, 0, 0);
|
---|
1534 | attr_legend(helpwin);
|
---|
1535 | wGetchar(helpwin);
|
---|
1536 | delwin(helpwin);
|
---|
1537 | }
|
---|
1538 | break;
|
---|
1539 | case 'a':
|
---|
1540 | *ac = 0;
|
---|
1541 | break;
|
---|
1542 | case 'A':
|
---|
1543 | *ac = A_ALTCHARSET;
|
---|
1544 | break;
|
---|
1545 | case 'v':
|
---|
1546 | if (*kc == 0)
|
---|
1547 | *kc = SIZEOF(attrs_to_test) - 1;
|
---|
1548 | else
|
---|
1549 | *kc -= 1;
|
---|
1550 | break;
|
---|
1551 | case 'V':
|
---|
1552 | *kc += 1;
|
---|
1553 | if (*kc >= SIZEOF(attrs_to_test))
|
---|
1554 | *kc = 0;
|
---|
1555 | break;
|
---|
1556 | case '<':
|
---|
1557 | wide_adjust_attr_string(-1);
|
---|
1558 | break;
|
---|
1559 | case '>':
|
---|
1560 | wide_adjust_attr_string(1);
|
---|
1561 | break;
|
---|
1562 | case 'q':
|
---|
1563 | case ESCAPE:
|
---|
1564 | result = FALSE;
|
---|
1565 | break;
|
---|
1566 | default:
|
---|
1567 | error = cycle_color_attr(ch, fg, bg, tx);
|
---|
1568 | break;
|
---|
1569 | }
|
---|
1570 | }
|
---|
1571 | } while (error);
|
---|
1572 | return result;
|
---|
1573 | }
|
---|
1574 |
|
---|
1575 | static void
|
---|
1576 | wide_attr_test(void)
|
---|
1577 | /* test text attributes using wide-character calls */
|
---|
1578 | {
|
---|
1579 | int n;
|
---|
1580 | int skip = tigetnum("xmc");
|
---|
1581 | int fg = COLOR_BLACK; /* color pair 0 is special */
|
---|
1582 | int bg = COLOR_BLACK;
|
---|
1583 | int tx = -1;
|
---|
1584 | int ac = 0;
|
---|
1585 | unsigned j, k;
|
---|
1586 |
|
---|
1587 | if (skip < 0)
|
---|
1588 | skip = 0;
|
---|
1589 |
|
---|
1590 | n = skip; /* make it easy */
|
---|
1591 | k = SIZEOF(attrs_to_test) - 1;
|
---|
1592 | wide_init_attr_string();
|
---|
1593 |
|
---|
1594 | do {
|
---|
1595 | int row = 2;
|
---|
1596 | short pair = 0;
|
---|
1597 | short extras = 0;
|
---|
1598 |
|
---|
1599 | if (has_colors()) {
|
---|
1600 | pair = (fg != COLOR_BLACK || bg != COLOR_BLACK);
|
---|
1601 | if (pair != 0) {
|
---|
1602 | pair = 1;
|
---|
1603 | if (init_pair(pair, fg, bg) == ERR) {
|
---|
1604 | beep();
|
---|
1605 | }
|
---|
1606 | }
|
---|
1607 | extras = pair;
|
---|
1608 | if (tx >= 0) {
|
---|
1609 | extras = 2;
|
---|
1610 | if (init_pair(extras, tx, bg) == ERR) {
|
---|
1611 | beep();
|
---|
1612 | }
|
---|
1613 | }
|
---|
1614 | }
|
---|
1615 | set_wide_background(pair);
|
---|
1616 | erase();
|
---|
1617 |
|
---|
1618 | box_set(stdscr, 0, 0);
|
---|
1619 | mvaddstr(0, 20, "Character attribute test display");
|
---|
1620 |
|
---|
1621 | for (j = 0; j < SIZEOF(attrs_to_test); ++j) {
|
---|
1622 | row = wide_show_attr(row, n, j == k,
|
---|
1623 | ac |
|
---|
1624 | attrs_to_test[j].attr |
|
---|
1625 | attrs_to_test[k].attr,
|
---|
1626 | extras,
|
---|
1627 | attrs_to_test[j].name);
|
---|
1628 | }
|
---|
1629 |
|
---|
1630 | mvprintw(row, 8,
|
---|
1631 | "This terminal does %shave the magic-cookie glitch",
|
---|
1632 | tigetnum("xmc") > -1 ? "" : "not ");
|
---|
1633 | mvprintw(row + 1, 8, "Enter '?' for help.");
|
---|
1634 | show_color_attr(fg, bg, tx);
|
---|
1635 | printw(" ACS (%d)", ac != 0);
|
---|
1636 |
|
---|
1637 | refresh();
|
---|
1638 | } while (wide_attr_getc(&n, &fg, &bg, &tx, &ac, &k));
|
---|
1639 |
|
---|
1640 | set_wide_background(0);
|
---|
1641 | erase();
|
---|
1642 | endwin();
|
---|
1643 | }
|
---|
1644 | #endif
|
---|
1645 |
|
---|
1646 | /****************************************************************************
|
---|
1647 | *
|
---|
1648 | * Color support tests
|
---|
1649 | *
|
---|
1650 | ****************************************************************************/
|
---|
1651 |
|
---|
1652 | static NCURSES_CONST char *the_color_names[] =
|
---|
1653 | {
|
---|
1654 | "black",
|
---|
1655 | "red",
|
---|
1656 | "green",
|
---|
1657 | "yellow",
|
---|
1658 | "blue",
|
---|
1659 | "magenta",
|
---|
1660 | "cyan",
|
---|
1661 | "white",
|
---|
1662 | "BLACK",
|
---|
1663 | "RED",
|
---|
1664 | "GREEN",
|
---|
1665 | "YELLOW",
|
---|
1666 | "BLUE",
|
---|
1667 | "MAGENTA",
|
---|
1668 | "CYAN",
|
---|
1669 | "WHITE"
|
---|
1670 | };
|
---|
1671 |
|
---|
1672 | static void
|
---|
1673 | show_color_name(int y, int x, int color, bool wide)
|
---|
1674 | {
|
---|
1675 | if (move(y, x) != ERR) {
|
---|
1676 | char temp[80];
|
---|
1677 | int width = 8;
|
---|
1678 |
|
---|
1679 | if (wide) {
|
---|
1680 | sprintf(temp, "%02d", color);
|
---|
1681 | width = 4;
|
---|
1682 | } else if (color >= 8) {
|
---|
1683 | sprintf(temp, "[%02d]", color);
|
---|
1684 | } else {
|
---|
1685 | strcpy(temp, the_color_names[color]);
|
---|
1686 | }
|
---|
1687 | printw("%-*.*s", width, width, temp);
|
---|
1688 | }
|
---|
1689 | }
|
---|
1690 |
|
---|
1691 | static void
|
---|
1692 | color_legend(WINDOW *helpwin)
|
---|
1693 | {
|
---|
1694 | int row = 1;
|
---|
1695 | int col = 1;
|
---|
1696 |
|
---|
1697 | mvwprintw(helpwin, row++, col,
|
---|
1698 | "q or ESC to exit.");
|
---|
1699 | ++row;
|
---|
1700 | mvwprintw(helpwin, row++, col,
|
---|
1701 | "Use up/down arrow to scroll through the display if it is");
|
---|
1702 | mvwprintw(helpwin, row++, col,
|
---|
1703 | "longer than one screen. Control/N and Control/P can be used");
|
---|
1704 | mvwprintw(helpwin, row++, col,
|
---|
1705 | "in place up up/down arrow. Use pageup/pagedown to scroll a");
|
---|
1706 | mvwprintw(helpwin, row++, col,
|
---|
1707 | "full screen; control/B and control/F can be used here.");
|
---|
1708 | ++row;
|
---|
1709 | mvwprintw(helpwin, row++, col,
|
---|
1710 | "Toggles:");
|
---|
1711 | mvwprintw(helpwin, row++, col,
|
---|
1712 | " b/B toggle bold off/on");
|
---|
1713 | mvwprintw(helpwin, row++, col,
|
---|
1714 | " n/N toggle text/number on/off");
|
---|
1715 | mvwprintw(helpwin, row++, col,
|
---|
1716 | " w/W toggle width between 8/16 colors");
|
---|
1717 | }
|
---|
1718 |
|
---|
1719 | #define set_color_test(name, value) if (name != value) { name = value; base_row = 0; }
|
---|
1720 |
|
---|
1721 | /* generate a color test pattern */
|
---|
1722 | static void
|
---|
1723 | color_test(void)
|
---|
1724 | {
|
---|
1725 | int c;
|
---|
1726 | int i;
|
---|
1727 | int top = 0, width;
|
---|
1728 | int base_row = 0;
|
---|
1729 | int grid_top = top + 3;
|
---|
1730 | int page_size = (LINES - grid_top);
|
---|
1731 | int pairs_max = PAIR_NUMBER(A_COLOR) + 1;
|
---|
1732 | int row_limit;
|
---|
1733 | int per_row;
|
---|
1734 | char numbered[80];
|
---|
1735 | const char *hello;
|
---|
1736 | bool done = FALSE;
|
---|
1737 | bool opt_bold = FALSE;
|
---|
1738 | bool opt_wide = FALSE;
|
---|
1739 | bool opt_nums = FALSE;
|
---|
1740 | WINDOW *helpwin;
|
---|
1741 |
|
---|
1742 | if (pairs_max > COLOR_PAIRS)
|
---|
1743 | pairs_max = COLOR_PAIRS;
|
---|
1744 |
|
---|
1745 | while (!done) {
|
---|
1746 | int shown = 0;
|
---|
1747 |
|
---|
1748 | /* this assumes an 80-column line */
|
---|
1749 | if (opt_wide) {
|
---|
1750 | width = 4;
|
---|
1751 | hello = "Test";
|
---|
1752 | per_row = (COLORS > 8) ? 16 : 8;
|
---|
1753 | } else {
|
---|
1754 | width = 8;
|
---|
1755 | hello = "Hello";
|
---|
1756 | per_row = 8;
|
---|
1757 | }
|
---|
1758 |
|
---|
1759 | row_limit = (pairs_max + per_row - 1) / per_row;
|
---|
1760 |
|
---|
1761 | move(0, 0);
|
---|
1762 | (void) printw("There are %d color pairs and %d colors\n",
|
---|
1763 | pairs_max, COLORS);
|
---|
1764 |
|
---|
1765 | clrtobot();
|
---|
1766 | (void) mvprintw(top + 1, 0,
|
---|
1767 | "%dx%d matrix of foreground/background colors, bold *%s*\n",
|
---|
1768 | row_limit,
|
---|
1769 | per_row,
|
---|
1770 | opt_bold ? "on" : "off");
|
---|
1771 |
|
---|
1772 | /* show color names/numbers across the top */
|
---|
1773 | for (i = 0; i < per_row; i++)
|
---|
1774 | show_color_name(top + 2, (i + 1) * width, i, opt_wide);
|
---|
1775 |
|
---|
1776 | /* show a grid of colors, with color names/ numbers on the left */
|
---|
1777 | for (i = (base_row * per_row); i < pairs_max; i++) {
|
---|
1778 | int row = grid_top + (i / per_row) - base_row;
|
---|
1779 | int col = (i % per_row + 1) * width;
|
---|
1780 | int pair = i;
|
---|
1781 |
|
---|
1782 | if (row >= 0 && move(row, col) != ERR) {
|
---|
1783 | init_pair(pair, i % COLORS, i / COLORS);
|
---|
1784 | attron((attr_t) COLOR_PAIR(pair));
|
---|
1785 | if (opt_bold)
|
---|
1786 | attron((attr_t) A_BOLD);
|
---|
1787 |
|
---|
1788 | if (opt_nums) {
|
---|
1789 | sprintf(numbered, "{%02X}", i);
|
---|
1790 | hello = numbered;
|
---|
1791 | }
|
---|
1792 | printw("%-*.*s", width, width, hello);
|
---|
1793 | attrset(A_NORMAL);
|
---|
1794 |
|
---|
1795 | if ((i % per_row) == 0 && (i % COLORS) == 0) {
|
---|
1796 | show_color_name(row, 0, i / COLORS, opt_wide);
|
---|
1797 | }
|
---|
1798 | ++shown;
|
---|
1799 | } else if (shown) {
|
---|
1800 | break;
|
---|
1801 | }
|
---|
1802 | }
|
---|
1803 |
|
---|
1804 | switch (c = wGetchar(stdscr)) {
|
---|
1805 | case 'b':
|
---|
1806 | opt_bold = FALSE;
|
---|
1807 | break;
|
---|
1808 | case 'B':
|
---|
1809 | opt_bold = TRUE;
|
---|
1810 | break;
|
---|
1811 | case 'n':
|
---|
1812 | opt_nums = FALSE;
|
---|
1813 | break;
|
---|
1814 | case 'N':
|
---|
1815 | opt_nums = TRUE;
|
---|
1816 | break;
|
---|
1817 | case ESCAPE:
|
---|
1818 | case 'q':
|
---|
1819 | done = TRUE;
|
---|
1820 | continue;
|
---|
1821 | case 'w':
|
---|
1822 | set_color_test(opt_wide, FALSE);
|
---|
1823 | break;
|
---|
1824 | case 'W':
|
---|
1825 | set_color_test(opt_wide, TRUE);
|
---|
1826 | break;
|
---|
1827 | case CTRL('p'):
|
---|
1828 | case KEY_UP:
|
---|
1829 | if (base_row <= 0) {
|
---|
1830 | beep();
|
---|
1831 | } else {
|
---|
1832 | base_row -= 1;
|
---|
1833 | }
|
---|
1834 | break;
|
---|
1835 | case CTRL('n'):
|
---|
1836 | case KEY_DOWN:
|
---|
1837 | if (base_row + page_size >= row_limit) {
|
---|
1838 | beep();
|
---|
1839 | } else {
|
---|
1840 | base_row += 1;
|
---|
1841 | }
|
---|
1842 | break;
|
---|
1843 | case CTRL('b'):
|
---|
1844 | case KEY_PREVIOUS:
|
---|
1845 | case KEY_PPAGE:
|
---|
1846 | if (base_row <= 0) {
|
---|
1847 | beep();
|
---|
1848 | } else {
|
---|
1849 | base_row -= (page_size - 1);
|
---|
1850 | if (base_row < 0)
|
---|
1851 | base_row = 0;
|
---|
1852 | }
|
---|
1853 | break;
|
---|
1854 | case CTRL('f'):
|
---|
1855 | case KEY_NEXT:
|
---|
1856 | case KEY_NPAGE:
|
---|
1857 | if (base_row + page_size >= row_limit) {
|
---|
1858 | beep();
|
---|
1859 | } else {
|
---|
1860 | base_row += page_size - 1;
|
---|
1861 | if (base_row + page_size >= row_limit) {
|
---|
1862 | base_row = row_limit - page_size - 1;
|
---|
1863 | }
|
---|
1864 | }
|
---|
1865 | break;
|
---|
1866 | case '?':
|
---|
1867 | if ((helpwin = newwin(LINES - 1, COLS - 2, 0, 0)) != 0) {
|
---|
1868 | box(helpwin, 0, 0);
|
---|
1869 | color_legend(helpwin);
|
---|
1870 | wGetchar(helpwin);
|
---|
1871 | delwin(helpwin);
|
---|
1872 | }
|
---|
1873 | break;
|
---|
1874 | default:
|
---|
1875 | beep();
|
---|
1876 | continue;
|
---|
1877 | }
|
---|
1878 | }
|
---|
1879 |
|
---|
1880 | erase();
|
---|
1881 | endwin();
|
---|
1882 | }
|
---|
1883 |
|
---|
1884 | #if USE_WIDEC_SUPPORT
|
---|
1885 | /* generate a color test pattern */
|
---|
1886 | static void
|
---|
1887 | wide_color_test(void)
|
---|
1888 | {
|
---|
1889 | int c;
|
---|
1890 | int i;
|
---|
1891 | int top = 0, width;
|
---|
1892 | int base_row = 0;
|
---|
1893 | int grid_top = top + 3;
|
---|
1894 | int page_size = (LINES - grid_top);
|
---|
1895 | int pairs_max = COLOR_PAIRS;
|
---|
1896 | int row_limit;
|
---|
1897 | int per_row;
|
---|
1898 | char numbered[80];
|
---|
1899 | const char *hello;
|
---|
1900 | bool done = FALSE;
|
---|
1901 | bool opt_bold = FALSE;
|
---|
1902 | bool opt_wide = FALSE;
|
---|
1903 | bool opt_nums = FALSE;
|
---|
1904 | WINDOW *helpwin;
|
---|
1905 |
|
---|
1906 | while (!done) {
|
---|
1907 | int shown = 0;
|
---|
1908 |
|
---|
1909 | /* this assumes an 80-column line */
|
---|
1910 | if (opt_wide) {
|
---|
1911 | width = 4;
|
---|
1912 | hello = "Test";
|
---|
1913 | per_row = (COLORS > 8) ? 16 : 8;
|
---|
1914 | } else {
|
---|
1915 | width = 8;
|
---|
1916 | hello = "Hello";
|
---|
1917 | per_row = 8;
|
---|
1918 | }
|
---|
1919 |
|
---|
1920 | row_limit = (pairs_max + per_row - 1) / per_row;
|
---|
1921 |
|
---|
1922 | move(0, 0);
|
---|
1923 | (void) printw("There are %d color pairs and %d colors\n",
|
---|
1924 | pairs_max, COLORS);
|
---|
1925 |
|
---|
1926 | clrtobot();
|
---|
1927 | (void) mvprintw(top + 1, 0,
|
---|
1928 | "%dx%d matrix of foreground/background colors, bold *%s*\n",
|
---|
1929 | row_limit,
|
---|
1930 | per_row,
|
---|
1931 | opt_bold ? "on" : "off");
|
---|
1932 |
|
---|
1933 | /* show color names/numbers across the top */
|
---|
1934 | for (i = 0; i < per_row; i++)
|
---|
1935 | show_color_name(top + 2, (i + 1) * width, i, opt_wide);
|
---|
1936 |
|
---|
1937 | /* show a grid of colors, with color names/ numbers on the left */
|
---|
1938 | for (i = (base_row * per_row); i < pairs_max; i++) {
|
---|
1939 | int row = grid_top + (i / per_row) - base_row;
|
---|
1940 | int col = (i % per_row + 1) * width;
|
---|
1941 | int pair = i;
|
---|
1942 |
|
---|
1943 | if (row >= 0 && move(row, col) != ERR) {
|
---|
1944 | init_pair(pair, i % COLORS, i / COLORS);
|
---|
1945 | color_set(pair, NULL);
|
---|
1946 | if (opt_bold)
|
---|
1947 | attr_on((attr_t) A_BOLD, NULL);
|
---|
1948 |
|
---|
1949 | if (opt_nums) {
|
---|
1950 | sprintf(numbered, "{%02X}", i);
|
---|
1951 | hello = numbered;
|
---|
1952 | }
|
---|
1953 | printw("%-*.*s", width, width, hello);
|
---|
1954 | attr_set(A_NORMAL, 0, NULL);
|
---|
1955 |
|
---|
1956 | if ((i % per_row) == 0 && (i % COLORS) == 0) {
|
---|
1957 | show_color_name(row, 0, i / COLORS, opt_wide);
|
---|
1958 | }
|
---|
1959 | ++shown;
|
---|
1960 | } else if (shown) {
|
---|
1961 | break;
|
---|
1962 | }
|
---|
1963 | }
|
---|
1964 |
|
---|
1965 | switch (c = wGetchar(stdscr)) {
|
---|
1966 | case 'b':
|
---|
1967 | opt_bold = FALSE;
|
---|
1968 | break;
|
---|
1969 | case 'B':
|
---|
1970 | opt_bold = TRUE;
|
---|
1971 | break;
|
---|
1972 | case 'n':
|
---|
1973 | opt_nums = FALSE;
|
---|
1974 | break;
|
---|
1975 | case 'N':
|
---|
1976 | opt_nums = TRUE;
|
---|
1977 | break;
|
---|
1978 | case ESCAPE:
|
---|
1979 | case 'q':
|
---|
1980 | done = TRUE;
|
---|
1981 | continue;
|
---|
1982 | case 'w':
|
---|
1983 | set_color_test(opt_wide, FALSE);
|
---|
1984 | break;
|
---|
1985 | case 'W':
|
---|
1986 | set_color_test(opt_wide, TRUE);
|
---|
1987 | break;
|
---|
1988 | case CTRL('p'):
|
---|
1989 | case KEY_UP:
|
---|
1990 | if (base_row <= 0) {
|
---|
1991 | beep();
|
---|
1992 | } else {
|
---|
1993 | base_row -= 1;
|
---|
1994 | }
|
---|
1995 | break;
|
---|
1996 | case CTRL('n'):
|
---|
1997 | case KEY_DOWN:
|
---|
1998 | if (base_row + page_size >= row_limit) {
|
---|
1999 | beep();
|
---|
2000 | } else {
|
---|
2001 | base_row += 1;
|
---|
2002 | }
|
---|
2003 | break;
|
---|
2004 | case CTRL('b'):
|
---|
2005 | case KEY_PREVIOUS:
|
---|
2006 | case KEY_PPAGE:
|
---|
2007 | if (base_row <= 0) {
|
---|
2008 | beep();
|
---|
2009 | } else {
|
---|
2010 | base_row -= (page_size - 1);
|
---|
2011 | if (base_row < 0)
|
---|
2012 | base_row = 0;
|
---|
2013 | }
|
---|
2014 | break;
|
---|
2015 | case CTRL('f'):
|
---|
2016 | case KEY_NEXT:
|
---|
2017 | case KEY_NPAGE:
|
---|
2018 | if (base_row + page_size >= row_limit) {
|
---|
2019 | beep();
|
---|
2020 | } else {
|
---|
2021 | base_row += page_size - 1;
|
---|
2022 | if (base_row + page_size >= row_limit) {
|
---|
2023 | base_row = row_limit - page_size - 1;
|
---|
2024 | }
|
---|
2025 | }
|
---|
2026 | break;
|
---|
2027 | case '?':
|
---|
2028 | if ((helpwin = newwin(LINES - 1, COLS - 2, 0, 0)) != 0) {
|
---|
2029 | box(helpwin, 0, 0);
|
---|
2030 | color_legend(helpwin);
|
---|
2031 | wGetchar(helpwin);
|
---|
2032 | delwin(helpwin);
|
---|
2033 | }
|
---|
2034 | break;
|
---|
2035 | default:
|
---|
2036 | beep();
|
---|
2037 | continue;
|
---|
2038 | }
|
---|
2039 | }
|
---|
2040 |
|
---|
2041 | erase();
|
---|
2042 | endwin();
|
---|
2043 | }
|
---|
2044 | #endif /* USE_WIDEC_SUPPORT */
|
---|
2045 |
|
---|
2046 | static void
|
---|
2047 | change_color(int current, int field, int value, int usebase)
|
---|
2048 | {
|
---|
2049 | short red, green, blue;
|
---|
2050 |
|
---|
2051 | if (usebase)
|
---|
2052 | color_content(current, &red, &green, &blue);
|
---|
2053 | else
|
---|
2054 | red = green = blue = 0;
|
---|
2055 |
|
---|
2056 | switch (field) {
|
---|
2057 | case 0:
|
---|
2058 | red += value;
|
---|
2059 | break;
|
---|
2060 | case 1:
|
---|
2061 | green += value;
|
---|
2062 | break;
|
---|
2063 | case 2:
|
---|
2064 | blue += value;
|
---|
2065 | break;
|
---|
2066 | }
|
---|
2067 |
|
---|
2068 | if (init_color(current, red, green, blue) == ERR)
|
---|
2069 | beep();
|
---|
2070 | }
|
---|
2071 |
|
---|
2072 | static void
|
---|
2073 | init_all_colors(void)
|
---|
2074 | {
|
---|
2075 | int c;
|
---|
2076 | for (c = 0; c < COLORS; ++c)
|
---|
2077 | init_color(c,
|
---|
2078 | all_colors[c].red,
|
---|
2079 | all_colors[c].green,
|
---|
2080 | all_colors[c].blue);
|
---|
2081 | }
|
---|
2082 |
|
---|
2083 | #define scaled_rgb(n) ((255 * (n)) / 1000)
|
---|
2084 |
|
---|
2085 | static void
|
---|
2086 | color_edit(void)
|
---|
2087 | /* display the color test pattern, without trying to edit colors */
|
---|
2088 | {
|
---|
2089 | int i, this_c = 0, value = 0, current = 0, field = 0;
|
---|
2090 | int last_c;
|
---|
2091 | int top_color = 0;
|
---|
2092 | int page_size = (LINES - 6);
|
---|
2093 |
|
---|
2094 | init_all_colors();
|
---|
2095 | refresh();
|
---|
2096 |
|
---|
2097 | for (i = 0; i < max_colors; i++)
|
---|
2098 | init_pair(i, COLOR_WHITE, i);
|
---|
2099 |
|
---|
2100 | mvprintw(LINES - 2, 0, "Number: %d", value);
|
---|
2101 |
|
---|
2102 | do {
|
---|
2103 | short red, green, blue;
|
---|
2104 |
|
---|
2105 | attron(A_BOLD);
|
---|
2106 | mvaddstr(0, 20, "Color RGB Value Editing");
|
---|
2107 | attroff(A_BOLD);
|
---|
2108 |
|
---|
2109 | for (i = top_color;
|
---|
2110 | (i - top_color < page_size)
|
---|
2111 | && (i < max_colors); i++) {
|
---|
2112 | char numeric[80];
|
---|
2113 | sprintf(numeric, "[%d]", i);
|
---|
2114 | mvprintw(2 + i - top_color, 0, "%c %-8s:",
|
---|
2115 | (i == current ? '>' : ' '),
|
---|
2116 | (i < (int) SIZEOF(the_color_names)
|
---|
2117 | ? the_color_names[i] : numeric));
|
---|
2118 | attrset(COLOR_PAIR(i));
|
---|
2119 | addstr(" ");
|
---|
2120 | attrset(A_NORMAL);
|
---|
2121 |
|
---|
2122 | color_content(i, &red, &green, &blue);
|
---|
2123 | addstr(" R = ");
|
---|
2124 | if (current == i && field == 0)
|
---|
2125 | attron(A_STANDOUT);
|
---|
2126 | printw("%04d", red);
|
---|
2127 | if (current == i && field == 0)
|
---|
2128 | attrset(A_NORMAL);
|
---|
2129 | addstr(", G = ");
|
---|
2130 | if (current == i && field == 1)
|
---|
2131 | attron(A_STANDOUT);
|
---|
2132 | printw("%04d", green);
|
---|
2133 | if (current == i && field == 1)
|
---|
2134 | attrset(A_NORMAL);
|
---|
2135 | addstr(", B = ");
|
---|
2136 | if (current == i && field == 2)
|
---|
2137 | attron(A_STANDOUT);
|
---|
2138 | printw("%04d", blue);
|
---|
2139 | if (current == i && field == 2)
|
---|
2140 | attrset(A_NORMAL);
|
---|
2141 | attrset(A_NORMAL);
|
---|
2142 | printw(" ( %3d %3d %3d )",
|
---|
2143 | scaled_rgb(red),
|
---|
2144 | scaled_rgb(green),
|
---|
2145 | scaled_rgb(blue));
|
---|
2146 | }
|
---|
2147 |
|
---|
2148 | mvaddstr(LINES - 3, 0,
|
---|
2149 | "Use up/down to select a color, left/right to change fields.");
|
---|
2150 | mvaddstr(LINES - 2, 0,
|
---|
2151 | "Modify field by typing nnn=, nnn-, or nnn+. ? for help.");
|
---|
2152 |
|
---|
2153 | move(2 + current - top_color, 0);
|
---|
2154 |
|
---|
2155 | last_c = this_c;
|
---|
2156 | this_c = Getchar();
|
---|
2157 | if (this_c < 256 && isdigit(this_c) && !isdigit(last_c))
|
---|
2158 | value = 0;
|
---|
2159 |
|
---|
2160 | switch (this_c) {
|
---|
2161 | case CTRL('b'):
|
---|
2162 | case KEY_PPAGE:
|
---|
2163 | if (current > 0)
|
---|
2164 | current -= (page_size - 1);
|
---|
2165 | else
|
---|
2166 | beep();
|
---|
2167 | break;
|
---|
2168 |
|
---|
2169 | case CTRL('f'):
|
---|
2170 | case KEY_NPAGE:
|
---|
2171 | if (current < (max_colors - 1))
|
---|
2172 | current += (page_size - 1);
|
---|
2173 | else
|
---|
2174 | beep();
|
---|
2175 | break;
|
---|
2176 |
|
---|
2177 | case CTRL('p'):
|
---|
2178 | case KEY_UP:
|
---|
2179 | current = (current == 0 ? (max_colors - 1) : current - 1);
|
---|
2180 | break;
|
---|
2181 |
|
---|
2182 | case CTRL('n'):
|
---|
2183 | case KEY_DOWN:
|
---|
2184 | current = (current == (max_colors - 1) ? 0 : current + 1);
|
---|
2185 | break;
|
---|
2186 |
|
---|
2187 | case KEY_RIGHT:
|
---|
2188 | field = (field == 2 ? 0 : field + 1);
|
---|
2189 | break;
|
---|
2190 |
|
---|
2191 | case KEY_LEFT:
|
---|
2192 | field = (field == 0 ? 2 : field - 1);
|
---|
2193 | break;
|
---|
2194 |
|
---|
2195 | case '0':
|
---|
2196 | case '1':
|
---|
2197 | case '2':
|
---|
2198 | case '3':
|
---|
2199 | case '4':
|
---|
2200 | case '5':
|
---|
2201 | case '6':
|
---|
2202 | case '7':
|
---|
2203 | case '8':
|
---|
2204 | case '9':
|
---|
2205 | value = value * 10 + (this_c - '0');
|
---|
2206 | break;
|
---|
2207 |
|
---|
2208 | case '+':
|
---|
2209 | change_color(current, field, value, 1);
|
---|
2210 | break;
|
---|
2211 |
|
---|
2212 | case '-':
|
---|
2213 | change_color(current, field, -value, 1);
|
---|
2214 | break;
|
---|
2215 |
|
---|
2216 | case '=':
|
---|
2217 | change_color(current, field, value, 0);
|
---|
2218 | break;
|
---|
2219 |
|
---|
2220 | case '?':
|
---|
2221 | erase();
|
---|
2222 | P(" RGB Value Editing Help");
|
---|
2223 | P("");
|
---|
2224 | P("You are in the RGB value editor. Use the arrow keys to select one of");
|
---|
2225 | P("the fields in one of the RGB triples of the current colors; the one");
|
---|
2226 | P("currently selected will be reverse-video highlighted.");
|
---|
2227 | P("");
|
---|
2228 | P("To change a field, enter the digits of the new value; they are echoed");
|
---|
2229 | P("as entered. Finish by typing `='. The change will take effect instantly.");
|
---|
2230 | P("To increment or decrement a value, use the same procedure, but finish");
|
---|
2231 | P("with a `+' or `-'.");
|
---|
2232 | P("");
|
---|
2233 | P("Press 'm' to invoke the top-level menu with the current color settings.");
|
---|
2234 | P("To quit, do `x' or 'q'");
|
---|
2235 |
|
---|
2236 | Pause();
|
---|
2237 | erase();
|
---|
2238 | break;
|
---|
2239 |
|
---|
2240 | case 'm':
|
---|
2241 | endwin();
|
---|
2242 | main_menu(FALSE);
|
---|
2243 | refresh();
|
---|
2244 | break;
|
---|
2245 |
|
---|
2246 | case 'x':
|
---|
2247 | case 'q':
|
---|
2248 | break;
|
---|
2249 |
|
---|
2250 | default:
|
---|
2251 | beep();
|
---|
2252 | break;
|
---|
2253 | }
|
---|
2254 |
|
---|
2255 | if (current < 0)
|
---|
2256 | current = 0;
|
---|
2257 | if (current >= max_colors)
|
---|
2258 | current = max_colors - 1;
|
---|
2259 | if (current < top_color)
|
---|
2260 | top_color = current;
|
---|
2261 | if (current - top_color >= page_size)
|
---|
2262 | top_color = current - (page_size - 1);
|
---|
2263 |
|
---|
2264 | mvprintw(LINES - 1, 0, "Number: %d", value);
|
---|
2265 | clrtoeol();
|
---|
2266 | } while
|
---|
2267 | (this_c != 'x' && this_c != 'q');
|
---|
2268 |
|
---|
2269 | erase();
|
---|
2270 |
|
---|
2271 | /*
|
---|
2272 | * ncurses does not reset each color individually when calling endwin().
|
---|
2273 | */
|
---|
2274 | init_all_colors();
|
---|
2275 |
|
---|
2276 | endwin();
|
---|
2277 | }
|
---|
2278 |
|
---|
2279 | /****************************************************************************
|
---|
2280 | *
|
---|
2281 | * Soft-key label test
|
---|
2282 | *
|
---|
2283 | ****************************************************************************/
|
---|
2284 |
|
---|
2285 | #define SLK_HELP 17
|
---|
2286 | #define SLK_WORK (SLK_HELP + 3)
|
---|
2287 |
|
---|
2288 | static void
|
---|
2289 | slk_help(void)
|
---|
2290 | {
|
---|
2291 | static const char *table[] =
|
---|
2292 | {
|
---|
2293 | "Available commands are:"
|
---|
2294 | ,""
|
---|
2295 | ,"^L -- repaint this message and activate soft keys"
|
---|
2296 | ,"a/d -- activate/disable soft keys"
|
---|
2297 | ,"c -- set centered format for labels"
|
---|
2298 | ,"l -- set left-justified format for labels"
|
---|
2299 | ,"r -- set right-justified format for labels"
|
---|
2300 | ,"[12345678] -- set label; labels are numbered 1 through 8"
|
---|
2301 | ,"e -- erase stdscr (should not erase labels)"
|
---|
2302 | ,"s -- test scrolling of shortened screen"
|
---|
2303 | #if HAVE_SLK_COLOR
|
---|
2304 | ,"F/B -- cycle through foreground/background colors"
|
---|
2305 | #endif
|
---|
2306 | ,"x, q -- return to main menu"
|
---|
2307 | ,""
|
---|
2308 | ,"Note: if activating the soft keys causes your terminal to scroll up"
|
---|
2309 | ,"one line, your terminal auto-scrolls when anything is written to the"
|
---|
2310 | ,"last screen position. The ncurses code does not yet handle this"
|
---|
2311 | ,"gracefully."
|
---|
2312 | };
|
---|
2313 | unsigned j;
|
---|
2314 |
|
---|
2315 | move(2, 0);
|
---|
2316 | for (j = 0; j < SIZEOF(table); ++j) {
|
---|
2317 | P(table[j]);
|
---|
2318 | }
|
---|
2319 | refresh();
|
---|
2320 | }
|
---|
2321 |
|
---|
2322 | static void
|
---|
2323 | slk_test(void)
|
---|
2324 | /* exercise the soft keys */
|
---|
2325 | {
|
---|
2326 | int c, fmt = 1;
|
---|
2327 | char buf[9];
|
---|
2328 | char *s;
|
---|
2329 | #if HAVE_SLK_COLOR
|
---|
2330 | short fg = COLOR_BLACK;
|
---|
2331 | short bg = COLOR_WHITE;
|
---|
2332 | bool new_color = FALSE;
|
---|
2333 | #endif
|
---|
2334 |
|
---|
2335 | c = CTRL('l');
|
---|
2336 | #if HAVE_SLK_COLOR
|
---|
2337 | if (has_colors()) {
|
---|
2338 | new_color = TRUE;
|
---|
2339 | }
|
---|
2340 | #endif
|
---|
2341 |
|
---|
2342 | do {
|
---|
2343 | #if HAVE_SLK_COLOR
|
---|
2344 | if (new_color) {
|
---|
2345 | init_pair(1, bg, fg);
|
---|
2346 | slk_color(1);
|
---|
2347 | new_color = FALSE;
|
---|
2348 | mvprintw(SLK_WORK, 0, "Colors %d/%d\n", fg, bg);
|
---|
2349 | refresh();
|
---|
2350 | }
|
---|
2351 | #endif
|
---|
2352 | move(0, 0);
|
---|
2353 | switch (c) {
|
---|
2354 | case CTRL('l'):
|
---|
2355 | erase();
|
---|
2356 | attron(A_BOLD);
|
---|
2357 | mvaddstr(0, 20, "Soft Key Exerciser");
|
---|
2358 | attroff(A_BOLD);
|
---|
2359 |
|
---|
2360 | slk_help();
|
---|
2361 | /* fall through */
|
---|
2362 |
|
---|
2363 | case 'a':
|
---|
2364 | slk_restore();
|
---|
2365 | break;
|
---|
2366 |
|
---|
2367 | case 'e':
|
---|
2368 | wclear(stdscr);
|
---|
2369 | break;
|
---|
2370 |
|
---|
2371 | case 's':
|
---|
2372 | mvprintw(SLK_WORK, 0, "Press Q to stop the scrolling-test: ");
|
---|
2373 | while ((c = Getchar()) != 'Q' && (c != ERR))
|
---|
2374 | addch((chtype) c);
|
---|
2375 | break;
|
---|
2376 |
|
---|
2377 | case 'd':
|
---|
2378 | slk_clear();
|
---|
2379 | break;
|
---|
2380 |
|
---|
2381 | case 'l':
|
---|
2382 | fmt = 0;
|
---|
2383 | break;
|
---|
2384 |
|
---|
2385 | case 'c':
|
---|
2386 | fmt = 1;
|
---|
2387 | break;
|
---|
2388 |
|
---|
2389 | case 'r':
|
---|
2390 | fmt = 2;
|
---|
2391 | break;
|
---|
2392 |
|
---|
2393 | case '1':
|
---|
2394 | case '2':
|
---|
2395 | case '3':
|
---|
2396 | case '4':
|
---|
2397 | case '5':
|
---|
2398 | case '6':
|
---|
2399 | case '7':
|
---|
2400 | case '8':
|
---|
2401 | (void) mvaddstr(SLK_WORK, 0, "Please enter the label value: ");
|
---|
2402 | strcpy(buf, "");
|
---|
2403 | if ((s = slk_label(c - '0')) != 0) {
|
---|
2404 | strncpy(buf, s, 8);
|
---|
2405 | }
|
---|
2406 | wGetstring(stdscr, buf, 8);
|
---|
2407 | slk_set((c - '0'), buf, fmt);
|
---|
2408 | slk_refresh();
|
---|
2409 | move(SLK_WORK, 0);
|
---|
2410 | clrtobot();
|
---|
2411 | break;
|
---|
2412 |
|
---|
2413 | case 'x':
|
---|
2414 | case 'q':
|
---|
2415 | goto done;
|
---|
2416 |
|
---|
2417 | #if HAVE_SLK_COLOR
|
---|
2418 | case 'F':
|
---|
2419 | if (has_colors()) {
|
---|
2420 | fg = (fg + 1) % COLORS;
|
---|
2421 | new_color = TRUE;
|
---|
2422 | }
|
---|
2423 | break;
|
---|
2424 | case 'B':
|
---|
2425 | if (has_colors()) {
|
---|
2426 | bg = (bg + 1) % COLORS;
|
---|
2427 | new_color = TRUE;
|
---|
2428 | }
|
---|
2429 | break;
|
---|
2430 | #endif
|
---|
2431 |
|
---|
2432 | default:
|
---|
2433 | beep();
|
---|
2434 | }
|
---|
2435 | } while
|
---|
2436 | ((c = Getchar()) != EOF);
|
---|
2437 |
|
---|
2438 | done:
|
---|
2439 | erase();
|
---|
2440 | endwin();
|
---|
2441 | }
|
---|
2442 |
|
---|
2443 | #if USE_WIDEC_SUPPORT
|
---|
2444 | #define SLKLEN 8
|
---|
2445 | static void
|
---|
2446 | wide_slk_test(void)
|
---|
2447 | /* exercise the soft keys */
|
---|
2448 | {
|
---|
2449 | int c, fmt = 1;
|
---|
2450 | wchar_t buf[SLKLEN + 1];
|
---|
2451 | char *s;
|
---|
2452 | short fg = COLOR_BLACK;
|
---|
2453 | short bg = COLOR_WHITE;
|
---|
2454 | bool new_color = FALSE;
|
---|
2455 |
|
---|
2456 | c = CTRL('l');
|
---|
2457 | if (has_colors()) {
|
---|
2458 | new_color = TRUE;
|
---|
2459 | }
|
---|
2460 | do {
|
---|
2461 | if (new_color) {
|
---|
2462 | init_pair(1, bg, fg);
|
---|
2463 | slk_color(1);
|
---|
2464 | new_color = FALSE;
|
---|
2465 | mvprintw(SLK_WORK, 0, "Colors %d/%d\n", fg, bg);
|
---|
2466 | refresh();
|
---|
2467 | }
|
---|
2468 | move(0, 0);
|
---|
2469 | switch (c) {
|
---|
2470 | case CTRL('l'):
|
---|
2471 | erase();
|
---|
2472 | attr_on(WA_BOLD, NULL);
|
---|
2473 | mvaddstr(0, 20, "Soft Key Exerciser");
|
---|
2474 | attr_off(WA_BOLD, NULL);
|
---|
2475 |
|
---|
2476 | slk_help();
|
---|
2477 | /* fall through */
|
---|
2478 |
|
---|
2479 | case 'a':
|
---|
2480 | slk_restore();
|
---|
2481 | break;
|
---|
2482 |
|
---|
2483 | case 'e':
|
---|
2484 | wclear(stdscr);
|
---|
2485 | break;
|
---|
2486 |
|
---|
2487 | case 's':
|
---|
2488 | mvprintw(SLK_WORK, 0, "Press Q to stop the scrolling-test: ");
|
---|
2489 | while ((c = Getchar()) != 'Q' && (c != ERR))
|
---|
2490 | addch((chtype) c);
|
---|
2491 | break;
|
---|
2492 |
|
---|
2493 | case 'd':
|
---|
2494 | slk_clear();
|
---|
2495 | break;
|
---|
2496 |
|
---|
2497 | case 'l':
|
---|
2498 | fmt = 0;
|
---|
2499 | break;
|
---|
2500 |
|
---|
2501 | case 'c':
|
---|
2502 | fmt = 1;
|
---|
2503 | break;
|
---|
2504 |
|
---|
2505 | case 'r':
|
---|
2506 | fmt = 2;
|
---|
2507 | break;
|
---|
2508 |
|
---|
2509 | case '1':
|
---|
2510 | case '2':
|
---|
2511 | case '3':
|
---|
2512 | case '4':
|
---|
2513 | case '5':
|
---|
2514 | case '6':
|
---|
2515 | case '7':
|
---|
2516 | case '8':
|
---|
2517 | (void) mvaddstr(SLK_WORK, 0, "Please enter the label value: ");
|
---|
2518 | *buf = 0;
|
---|
2519 | if ((s = slk_label(c - '0')) != 0) {
|
---|
2520 | char *temp = strdup(s);
|
---|
2521 | size_t used = strlen(temp);
|
---|
2522 | size_t want = SLKLEN;
|
---|
2523 | size_t test;
|
---|
2524 | mbstate_t state;
|
---|
2525 |
|
---|
2526 | buf[0] = L'\0';
|
---|
2527 | while (want > 0 && used != 0) {
|
---|
2528 | const char *base = s;
|
---|
2529 | memset(&state, 0, sizeof(state));
|
---|
2530 | test = mbsrtowcs(0, &base, 0, &state);
|
---|
2531 | if (test == (size_t) -1) {
|
---|
2532 | temp[--used] = 0;
|
---|
2533 | } else if (test > want) {
|
---|
2534 | temp[--used] = 0;
|
---|
2535 | } else {
|
---|
2536 | memset(&state, 0, sizeof(state));
|
---|
2537 | mbsrtowcs(buf, &base, want, &state);
|
---|
2538 | break;
|
---|
2539 | }
|
---|
2540 | }
|
---|
2541 | free(temp);
|
---|
2542 | }
|
---|
2543 | wGet_wstring(stdscr, buf, SLKLEN);
|
---|
2544 | slk_wset((c - '0'), buf, fmt);
|
---|
2545 | slk_refresh();
|
---|
2546 | move(SLK_WORK, 0);
|
---|
2547 | clrtobot();
|
---|
2548 | break;
|
---|
2549 |
|
---|
2550 | case 'x':
|
---|
2551 | case 'q':
|
---|
2552 | goto done;
|
---|
2553 |
|
---|
2554 | case 'F':
|
---|
2555 | if (has_colors()) {
|
---|
2556 | fg = (fg + 1) % COLORS;
|
---|
2557 | new_color = TRUE;
|
---|
2558 | }
|
---|
2559 | break;
|
---|
2560 | case 'B':
|
---|
2561 | if (has_colors()) {
|
---|
2562 | bg = (bg + 1) % COLORS;
|
---|
2563 | new_color = TRUE;
|
---|
2564 | }
|
---|
2565 | break;
|
---|
2566 |
|
---|
2567 | default:
|
---|
2568 | beep();
|
---|
2569 | }
|
---|
2570 | } while
|
---|
2571 | ((c = Getchar()) != EOF);
|
---|
2572 |
|
---|
2573 | done:
|
---|
2574 | erase();
|
---|
2575 | endwin();
|
---|
2576 | }
|
---|
2577 | #endif
|
---|
2578 |
|
---|
2579 | /****************************************************************************
|
---|
2580 | *
|
---|
2581 | * Alternate character-set stuff
|
---|
2582 | *
|
---|
2583 | ****************************************************************************/
|
---|
2584 |
|
---|
2585 | /* ISO 6429: codes 0x80 to 0x9f may be control characters that cause the
|
---|
2586 | * terminal to perform functions. The remaining codes can be graphic.
|
---|
2587 | */
|
---|
2588 | static void
|
---|
2589 | show_upper_chars(unsigned first)
|
---|
2590 | {
|
---|
2591 | bool C1 = (first == 128);
|
---|
2592 | unsigned code;
|
---|
2593 | unsigned last = first + 31;
|
---|
2594 | int reply;
|
---|
2595 |
|
---|
2596 | erase();
|
---|
2597 | attron(A_BOLD);
|
---|
2598 | mvprintw(0, 20, "Display of %s Character Codes %d to %d",
|
---|
2599 | C1 ? "C1" : "GR", first, last);
|
---|
2600 | attroff(A_BOLD);
|
---|
2601 | refresh();
|
---|
2602 |
|
---|
2603 | for (code = first; code <= last; code++) {
|
---|
2604 | int row = 4 + ((code - first) % 16);
|
---|
2605 | int col = ((code - first) / 16) * COLS / 2;
|
---|
2606 | char tmp[80];
|
---|
2607 | sprintf(tmp, "%3u (0x%x)", code, code);
|
---|
2608 | mvprintw(row, col, "%*s: ", COLS / 4, tmp);
|
---|
2609 | if (C1)
|
---|
2610 | nodelay(stdscr, TRUE);
|
---|
2611 | echochar(code);
|
---|
2612 | if (C1) {
|
---|
2613 | /* (yes, this _is_ crude) */
|
---|
2614 | while ((reply = Getchar()) != ERR) {
|
---|
2615 | addch(UChar(reply));
|
---|
2616 | napms(10);
|
---|
2617 | }
|
---|
2618 | nodelay(stdscr, FALSE);
|
---|
2619 | }
|
---|
2620 | }
|
---|
2621 | }
|
---|
2622 |
|
---|
2623 | static void
|
---|
2624 | show_box_chars(void)
|
---|
2625 | {
|
---|
2626 | erase();
|
---|
2627 | attron(A_BOLD);
|
---|
2628 | mvaddstr(0, 20, "Display of the ACS Line-Drawing Set");
|
---|
2629 | attroff(A_BOLD);
|
---|
2630 | refresh();
|
---|
2631 | box(stdscr, 0, 0);
|
---|
2632 | /* *INDENT-OFF* */
|
---|
2633 | mvhline(LINES / 2, 0, ACS_HLINE, COLS);
|
---|
2634 | mvvline(0, COLS / 2, ACS_VLINE, LINES);
|
---|
2635 | mvaddch(0, COLS / 2, ACS_TTEE);
|
---|
2636 | mvaddch(LINES / 2, COLS / 2, ACS_PLUS);
|
---|
2637 | mvaddch(LINES - 1, COLS / 2, ACS_BTEE);
|
---|
2638 | mvaddch(LINES / 2, 0, ACS_LTEE);
|
---|
2639 | mvaddch(LINES / 2, COLS - 1, ACS_RTEE);
|
---|
2640 | /* *INDENT-ON* */
|
---|
2641 |
|
---|
2642 | }
|
---|
2643 |
|
---|
2644 | static int
|
---|
2645 | show_1_acs(int n, const char *name, chtype code)
|
---|
2646 | {
|
---|
2647 | const int height = 16;
|
---|
2648 | int row = 4 + (n % height);
|
---|
2649 | int col = (n / height) * COLS / 2;
|
---|
2650 | mvprintw(row, col, "%*s : ", COLS / 4, name);
|
---|
2651 | addch(code);
|
---|
2652 | return n + 1;
|
---|
2653 | }
|
---|
2654 |
|
---|
2655 | static void
|
---|
2656 | show_acs_chars(void)
|
---|
2657 | /* display the ACS character set */
|
---|
2658 | {
|
---|
2659 | int n;
|
---|
2660 |
|
---|
2661 | #define BOTH(name) #name, name
|
---|
2662 |
|
---|
2663 | erase();
|
---|
2664 | attron(A_BOLD);
|
---|
2665 | mvaddstr(0, 20, "Display of the ACS Character Set");
|
---|
2666 | attroff(A_BOLD);
|
---|
2667 | refresh();
|
---|
2668 |
|
---|
2669 | n = show_1_acs(0, BOTH(ACS_ULCORNER));
|
---|
2670 | n = show_1_acs(n, BOTH(ACS_URCORNER));
|
---|
2671 | n = show_1_acs(n, BOTH(ACS_LLCORNER));
|
---|
2672 | n = show_1_acs(n, BOTH(ACS_LRCORNER));
|
---|
2673 |
|
---|
2674 | n = show_1_acs(n, BOTH(ACS_LTEE));
|
---|
2675 | n = show_1_acs(n, BOTH(ACS_RTEE));
|
---|
2676 | n = show_1_acs(n, BOTH(ACS_TTEE));
|
---|
2677 | n = show_1_acs(n, BOTH(ACS_BTEE));
|
---|
2678 |
|
---|
2679 | n = show_1_acs(n, BOTH(ACS_HLINE));
|
---|
2680 | n = show_1_acs(n, BOTH(ACS_VLINE));
|
---|
2681 |
|
---|
2682 | n = show_1_acs(n, BOTH(ACS_LARROW));
|
---|
2683 | n = show_1_acs(n, BOTH(ACS_RARROW));
|
---|
2684 | n = show_1_acs(n, BOTH(ACS_UARROW));
|
---|
2685 | n = show_1_acs(n, BOTH(ACS_DARROW));
|
---|
2686 |
|
---|
2687 | n = show_1_acs(n, BOTH(ACS_BLOCK));
|
---|
2688 | n = show_1_acs(n, BOTH(ACS_BOARD));
|
---|
2689 | n = show_1_acs(n, BOTH(ACS_LANTERN));
|
---|
2690 | n = show_1_acs(n, BOTH(ACS_BULLET));
|
---|
2691 | n = show_1_acs(n, BOTH(ACS_CKBOARD));
|
---|
2692 | n = show_1_acs(n, BOTH(ACS_DEGREE));
|
---|
2693 | n = show_1_acs(n, BOTH(ACS_DIAMOND));
|
---|
2694 | n = show_1_acs(n, BOTH(ACS_PLMINUS));
|
---|
2695 | n = show_1_acs(n, BOTH(ACS_PLUS));
|
---|
2696 |
|
---|
2697 | n = show_1_acs(n, BOTH(ACS_GEQUAL));
|
---|
2698 | n = show_1_acs(n, BOTH(ACS_NEQUAL));
|
---|
2699 | n = show_1_acs(n, BOTH(ACS_LEQUAL));
|
---|
2700 |
|
---|
2701 | n = show_1_acs(n, BOTH(ACS_STERLING));
|
---|
2702 | n = show_1_acs(n, BOTH(ACS_PI));
|
---|
2703 | n = show_1_acs(n, BOTH(ACS_S1));
|
---|
2704 | n = show_1_acs(n, BOTH(ACS_S3));
|
---|
2705 | n = show_1_acs(n, BOTH(ACS_S7));
|
---|
2706 | n = show_1_acs(n, BOTH(ACS_S9));
|
---|
2707 | }
|
---|
2708 |
|
---|
2709 | static void
|
---|
2710 | acs_display(void)
|
---|
2711 | {
|
---|
2712 | int c = 'a';
|
---|
2713 |
|
---|
2714 | do {
|
---|
2715 | switch (c) {
|
---|
2716 | case CTRL('L'):
|
---|
2717 | Repaint();
|
---|
2718 | break;
|
---|
2719 | case 'a':
|
---|
2720 | show_acs_chars();
|
---|
2721 | break;
|
---|
2722 | case 'b':
|
---|
2723 | show_box_chars();
|
---|
2724 | break;
|
---|
2725 | case '0':
|
---|
2726 | case '1':
|
---|
2727 | case '2':
|
---|
2728 | case '3':
|
---|
2729 | show_upper_chars((unsigned) ((c - '0') * 32 + 128));
|
---|
2730 | break;
|
---|
2731 | }
|
---|
2732 | mvprintw(LINES - 3, 0,
|
---|
2733 | "Note: ANSI terminals may not display C1 characters.");
|
---|
2734 | mvprintw(LINES - 2, 0,
|
---|
2735 | "Select: a=ACS, b=box, 0=C1, 1,2,3=GR characters, q=quit");
|
---|
2736 | refresh();
|
---|
2737 | } while ((c = Getchar()) != 'x' && c != 'q');
|
---|
2738 |
|
---|
2739 | Pause();
|
---|
2740 | erase();
|
---|
2741 | endwin();
|
---|
2742 | }
|
---|
2743 |
|
---|
2744 | #if USE_WIDEC_SUPPORT
|
---|
2745 | static void
|
---|
2746 | show_upper_widechars(int first, int repeat, int space)
|
---|
2747 | {
|
---|
2748 | cchar_t temp;
|
---|
2749 | wchar_t code;
|
---|
2750 | int last = first + 31;
|
---|
2751 |
|
---|
2752 | erase();
|
---|
2753 | attron(A_BOLD);
|
---|
2754 | mvprintw(0, 20, "Display of Character Codes %d to %d", first, last);
|
---|
2755 | attroff(A_BOLD);
|
---|
2756 |
|
---|
2757 | for (code = first; code <= last; code++) {
|
---|
2758 | int row = 4 + ((code - first) % 16);
|
---|
2759 | int col = ((code - first) / 16) * COLS / 2;
|
---|
2760 | wchar_t codes[10];
|
---|
2761 | attr_t attrs = A_NORMAL;
|
---|
2762 | char tmp[80];
|
---|
2763 | int count = repeat;
|
---|
2764 |
|
---|
2765 | memset(&codes, 0, sizeof(codes));
|
---|
2766 | codes[0] = code;
|
---|
2767 | sprintf(tmp, "%3ld (0x%lx)", (long) code, (long) code);
|
---|
2768 | mvprintw(row, col, "%*s: ", COLS / 4, tmp);
|
---|
2769 | setcchar(&temp, codes, attrs, 0, 0);
|
---|
2770 | do {
|
---|
2771 | /*
|
---|
2772 | * Give non-spacing characters something to combine with. If we
|
---|
2773 | * don't, they'll bunch up in a heap on the space after the ":".
|
---|
2774 | * Mark them with reverse-video to make them simpler to find on
|
---|
2775 | * the display.
|
---|
2776 | */
|
---|
2777 | if (wcwidth(code) == 0)
|
---|
2778 | addch(space | A_REVERSE);
|
---|
2779 | /*
|
---|
2780 | * This could use add_wch(), but is done for comparison with the
|
---|
2781 | * normal 'f' test (and to make a test-case for echo_wchar()).
|
---|
2782 | * The screen will flicker because the erase() at the top of the
|
---|
2783 | * function is met by the builtin refresh() in echo_wchar().
|
---|
2784 | */
|
---|
2785 | echo_wchar(&temp);
|
---|
2786 | } while (--count > 0);
|
---|
2787 | }
|
---|
2788 | }
|
---|
2789 |
|
---|
2790 | static int
|
---|
2791 | show_1_wacs(int n, const char *name, const cchar_t *code)
|
---|
2792 | {
|
---|
2793 | const int height = 16;
|
---|
2794 | int row = 4 + (n % height);
|
---|
2795 | int col = (n / height) * COLS / 2;
|
---|
2796 | mvprintw(row, col, "%*s : ", COLS / 4, name);
|
---|
2797 | add_wchnstr(code, 1);
|
---|
2798 | return n + 1;
|
---|
2799 | }
|
---|
2800 |
|
---|
2801 | static void
|
---|
2802 | show_wacs_chars(void)
|
---|
2803 | /* display the wide-ACS character set */
|
---|
2804 | {
|
---|
2805 | int n;
|
---|
2806 |
|
---|
2807 | /*#define BOTH2(name) #name, &(name) */
|
---|
2808 | #define BOTH2(name) #name, name
|
---|
2809 |
|
---|
2810 | erase();
|
---|
2811 | attron(A_BOLD);
|
---|
2812 | mvaddstr(0, 20, "Display of the Wide-ACS Character Set");
|
---|
2813 | attroff(A_BOLD);
|
---|
2814 | refresh();
|
---|
2815 |
|
---|
2816 | n = show_1_wacs(0, BOTH2(WACS_ULCORNER));
|
---|
2817 | n = show_1_wacs(n, BOTH2(WACS_URCORNER));
|
---|
2818 | n = show_1_wacs(n, BOTH2(WACS_LLCORNER));
|
---|
2819 | n = show_1_wacs(n, BOTH2(WACS_LRCORNER));
|
---|
2820 |
|
---|
2821 | n = show_1_wacs(n, BOTH2(WACS_LTEE));
|
---|
2822 | n = show_1_wacs(n, BOTH2(WACS_RTEE));
|
---|
2823 | n = show_1_wacs(n, BOTH2(WACS_TTEE));
|
---|
2824 | n = show_1_wacs(n, BOTH2(WACS_BTEE));
|
---|
2825 |
|
---|
2826 | n = show_1_wacs(n, BOTH2(WACS_HLINE));
|
---|
2827 | n = show_1_wacs(n, BOTH2(WACS_VLINE));
|
---|
2828 |
|
---|
2829 | n = show_1_wacs(n, BOTH2(WACS_LARROW));
|
---|
2830 | n = show_1_wacs(n, BOTH2(WACS_RARROW));
|
---|
2831 | n = show_1_wacs(n, BOTH2(WACS_UARROW));
|
---|
2832 | n = show_1_wacs(n, BOTH2(WACS_DARROW));
|
---|
2833 |
|
---|
2834 | n = show_1_wacs(n, BOTH2(WACS_BLOCK));
|
---|
2835 | n = show_1_wacs(n, BOTH2(WACS_BOARD));
|
---|
2836 | n = show_1_wacs(n, BOTH2(WACS_LANTERN));
|
---|
2837 | n = show_1_wacs(n, BOTH2(WACS_BULLET));
|
---|
2838 | n = show_1_wacs(n, BOTH2(WACS_CKBOARD));
|
---|
2839 | n = show_1_wacs(n, BOTH2(WACS_DEGREE));
|
---|
2840 | n = show_1_wacs(n, BOTH2(WACS_DIAMOND));
|
---|
2841 | n = show_1_wacs(n, BOTH2(WACS_PLMINUS));
|
---|
2842 | n = show_1_wacs(n, BOTH2(WACS_PLUS));
|
---|
2843 |
|
---|
2844 | #ifdef CURSES_WACS_ARRAY
|
---|
2845 | n = show_1_wacs(n, BOTH2(WACS_GEQUAL));
|
---|
2846 | n = show_1_wacs(n, BOTH2(WACS_NEQUAL));
|
---|
2847 | n = show_1_wacs(n, BOTH2(WACS_LEQUAL));
|
---|
2848 |
|
---|
2849 | n = show_1_wacs(n, BOTH2(WACS_STERLING));
|
---|
2850 | n = show_1_wacs(n, BOTH2(WACS_PI));
|
---|
2851 | n = show_1_wacs(n, BOTH2(WACS_S1));
|
---|
2852 | n = show_1_wacs(n, BOTH2(WACS_S3));
|
---|
2853 | n = show_1_wacs(n, BOTH2(WACS_S7));
|
---|
2854 | n = show_1_wacs(n, BOTH2(WACS_S9));
|
---|
2855 | #endif
|
---|
2856 | }
|
---|
2857 |
|
---|
2858 | static void
|
---|
2859 | show_wbox_chars(void)
|
---|
2860 | {
|
---|
2861 | erase();
|
---|
2862 | attron(A_BOLD);
|
---|
2863 | mvaddstr(0, 20, "Display of the Wide-ACS Line-Drawing Set");
|
---|
2864 | attroff(A_BOLD);
|
---|
2865 | refresh();
|
---|
2866 | box_set(stdscr, 0, 0);
|
---|
2867 | /* *INDENT-OFF* */
|
---|
2868 | mvhline_set(LINES / 2, 0, WACS_HLINE, COLS);
|
---|
2869 | mvvline_set(0, COLS / 2, WACS_VLINE, LINES);
|
---|
2870 | mvadd_wch(0, COLS / 2, WACS_TTEE);
|
---|
2871 | mvadd_wch(LINES / 2, COLS / 2, WACS_PLUS);
|
---|
2872 | mvadd_wch(LINES - 1, COLS / 2, WACS_BTEE);
|
---|
2873 | mvadd_wch(LINES / 2, 0, WACS_LTEE);
|
---|
2874 | mvadd_wch(LINES / 2, COLS - 1, WACS_RTEE);
|
---|
2875 | /* *INDENT-ON* */
|
---|
2876 |
|
---|
2877 | }
|
---|
2878 |
|
---|
2879 | static int
|
---|
2880 | show_2_wacs(int n, const char *name, const char *code)
|
---|
2881 | {
|
---|
2882 | const int height = 16;
|
---|
2883 | int row = 4 + (n % height);
|
---|
2884 | int col = (n / height) * COLS / 2;
|
---|
2885 | char temp[80];
|
---|
2886 |
|
---|
2887 | mvprintw(row, col, "%*s : ", COLS / 4, name);
|
---|
2888 | addstr(strcpy(temp, code));
|
---|
2889 | return n + 1;
|
---|
2890 | }
|
---|
2891 |
|
---|
2892 | static void
|
---|
2893 | show_utf8_chars(void)
|
---|
2894 | /* display the wide-ACS character set */
|
---|
2895 | {
|
---|
2896 | int n;
|
---|
2897 |
|
---|
2898 | erase();
|
---|
2899 | attron(A_BOLD);
|
---|
2900 | mvaddstr(0, 20, "Display of the Wide-ACS Character Set");
|
---|
2901 | attroff(A_BOLD);
|
---|
2902 | refresh();
|
---|
2903 | /* *INDENT-OFF* */
|
---|
2904 | n = show_2_wacs(0, "WACS_ULCORNER", "\342\224\214");
|
---|
2905 | n = show_2_wacs(n, "WACS_URCORNER", "\342\224\220");
|
---|
2906 | n = show_2_wacs(n, "WACS_LLCORNER", "\342\224\224");
|
---|
2907 | n = show_2_wacs(n, "WACS_LRCORNER", "\342\224\230");
|
---|
2908 |
|
---|
2909 | n = show_2_wacs(n, "WACS_LTEE", "\342\224\234");
|
---|
2910 | n = show_2_wacs(n, "WACS_RTEE", "\342\224\244");
|
---|
2911 | n = show_2_wacs(n, "WACS_TTEE", "\342\224\254");
|
---|
2912 | n = show_2_wacs(n, "WACS_BTEE", "\342\224\264");
|
---|
2913 |
|
---|
2914 | n = show_2_wacs(n, "WACS_HLINE", "\342\224\200");
|
---|
2915 | n = show_2_wacs(n, "WACS_VLINE", "\342\224\202");
|
---|
2916 |
|
---|
2917 | n = show_2_wacs(n, "WACS_LARROW", "\342\206\220");
|
---|
2918 | n = show_2_wacs(n, "WACS_RARROW", "\342\206\222");
|
---|
2919 | n = show_2_wacs(n, "WACS_UARROW", "\342\206\221");
|
---|
2920 | n = show_2_wacs(n, "WACS_DARROW", "\342\206\223");
|
---|
2921 |
|
---|
2922 | n = show_2_wacs(n, "WACS_BLOCK", "\342\226\256");
|
---|
2923 | n = show_2_wacs(n, "WACS_BOARD", "\342\226\222");
|
---|
2924 | n = show_2_wacs(n, "WACS_LANTERN", "\342\230\203");
|
---|
2925 | n = show_2_wacs(n, "WACS_BULLET", "\302\267");
|
---|
2926 | n = show_2_wacs(n, "WACS_CKBOARD", "\342\226\222");
|
---|
2927 | n = show_2_wacs(n, "WACS_DEGREE", "\302\260");
|
---|
2928 | n = show_2_wacs(n, "WACS_DIAMOND", "\342\227\206");
|
---|
2929 | n = show_2_wacs(n, "WACS_PLMINUS", "\302\261");
|
---|
2930 | n = show_2_wacs(n, "WACS_PLUS", "\342\224\274");
|
---|
2931 | n = show_2_wacs(n, "WACS_GEQUAL", "\342\211\245");
|
---|
2932 | n = show_2_wacs(n, "WACS_NEQUAL", "\342\211\240");
|
---|
2933 | n = show_2_wacs(n, "WACS_LEQUAL", "\342\211\244");
|
---|
2934 |
|
---|
2935 | n = show_2_wacs(n, "WACS_STERLING", "\302\243");
|
---|
2936 | n = show_2_wacs(n, "WACS_PI", "\317\200");
|
---|
2937 | n = show_2_wacs(n, "WACS_S1", "\342\216\272");
|
---|
2938 | n = show_2_wacs(n, "WACS_S3", "\342\216\273");
|
---|
2939 | n = show_2_wacs(n, "WACS_S7", "\342\216\274");
|
---|
2940 | n = show_2_wacs(n, "WACS_S9", "\342\216\275");
|
---|
2941 | /* *INDENT-ON* */
|
---|
2942 |
|
---|
2943 | }
|
---|
2944 |
|
---|
2945 | static void
|
---|
2946 | wide_acs_display(void)
|
---|
2947 | {
|
---|
2948 | int c = 'a';
|
---|
2949 | int digit = 0;
|
---|
2950 | int repeat = 0;
|
---|
2951 | int space = ' ';
|
---|
2952 |
|
---|
2953 | do {
|
---|
2954 | switch (c) {
|
---|
2955 | case CTRL('L'):
|
---|
2956 | Repaint();
|
---|
2957 | break;
|
---|
2958 | case 'a':
|
---|
2959 | show_wacs_chars();
|
---|
2960 | break;
|
---|
2961 | case 'b':
|
---|
2962 | show_wbox_chars();
|
---|
2963 | break;
|
---|
2964 | case 'u':
|
---|
2965 | show_utf8_chars();
|
---|
2966 | break;
|
---|
2967 | default:
|
---|
2968 | if (c < 256 && isdigit(c))
|
---|
2969 | digit = (c - '0');
|
---|
2970 | else if (c == '+')
|
---|
2971 | ++digit;
|
---|
2972 | else if (c == '-' && digit > 0)
|
---|
2973 | --digit;
|
---|
2974 | else if (c == '>')
|
---|
2975 | ++repeat;
|
---|
2976 | else if (c == '<' && repeat > 0)
|
---|
2977 | --repeat;
|
---|
2978 | else if (c == '_')
|
---|
2979 | space = (space == ' ') ? '_' : ' ';
|
---|
2980 | else {
|
---|
2981 | beep();
|
---|
2982 | break;
|
---|
2983 | }
|
---|
2984 | show_upper_widechars(digit * 32 + 128, repeat, space);
|
---|
2985 | break;
|
---|
2986 | }
|
---|
2987 | mvprintw(LINES - 2, 0,
|
---|
2988 | "Select: a WACS, b box, u UTF-8, 0-9,+/- non-ASCII, </> repeat, q=quit");
|
---|
2989 | refresh();
|
---|
2990 | } while ((c = Getchar()) != 'x' && c != 'q');
|
---|
2991 |
|
---|
2992 | Pause();
|
---|
2993 | erase();
|
---|
2994 | endwin();
|
---|
2995 | }
|
---|
2996 |
|
---|
2997 | #endif
|
---|
2998 |
|
---|
2999 | /*
|
---|
3000 | * Graphic-rendition test (adapted from vttest)
|
---|
3001 | */
|
---|
3002 | static void
|
---|
3003 | test_sgr_attributes(void)
|
---|
3004 | {
|
---|
3005 | int pass;
|
---|
3006 |
|
---|
3007 | for (pass = 0; pass < 2; pass++) {
|
---|
3008 | chtype normal = ((pass == 0 ? A_NORMAL : A_REVERSE)) | BLANK;
|
---|
3009 |
|
---|
3010 | /* Use non-default colors if possible to exercise bce a little */
|
---|
3011 | if (has_colors()) {
|
---|
3012 | init_pair(1, COLOR_WHITE, COLOR_BLUE);
|
---|
3013 | normal |= COLOR_PAIR(1);
|
---|
3014 | }
|
---|
3015 | bkgdset(normal);
|
---|
3016 | erase();
|
---|
3017 | mvprintw(1, 20, "Graphic rendition test pattern:");
|
---|
3018 |
|
---|
3019 | mvprintw(4, 1, "vanilla");
|
---|
3020 |
|
---|
3021 | #define set_sgr(mask) bkgdset((normal^(mask)));
|
---|
3022 | set_sgr(A_BOLD);
|
---|
3023 | mvprintw(4, 40, "bold");
|
---|
3024 |
|
---|
3025 | set_sgr(A_UNDERLINE);
|
---|
3026 | mvprintw(6, 6, "underline");
|
---|
3027 |
|
---|
3028 | set_sgr(A_BOLD | A_UNDERLINE);
|
---|
3029 | mvprintw(6, 45, "bold underline");
|
---|
3030 |
|
---|
3031 | set_sgr(A_BLINK);
|
---|
3032 | mvprintw(8, 1, "blink");
|
---|
3033 |
|
---|
3034 | set_sgr(A_BLINK | A_BOLD);
|
---|
3035 | mvprintw(8, 40, "bold blink");
|
---|
3036 |
|
---|
3037 | set_sgr(A_UNDERLINE | A_BLINK);
|
---|
3038 | mvprintw(10, 6, "underline blink");
|
---|
3039 |
|
---|
3040 | set_sgr(A_BOLD | A_UNDERLINE | A_BLINK);
|
---|
3041 | mvprintw(10, 45, "bold underline blink");
|
---|
3042 |
|
---|
3043 | set_sgr(A_REVERSE);
|
---|
3044 | mvprintw(12, 1, "negative");
|
---|
3045 |
|
---|
3046 | set_sgr(A_BOLD | A_REVERSE);
|
---|
3047 | mvprintw(12, 40, "bold negative");
|
---|
3048 |
|
---|
3049 | set_sgr(A_UNDERLINE | A_REVERSE);
|
---|
3050 | mvprintw(14, 6, "underline negative");
|
---|
3051 |
|
---|
3052 | set_sgr(A_BOLD | A_UNDERLINE | A_REVERSE);
|
---|
3053 | mvprintw(14, 45, "bold underline negative");
|
---|
3054 |
|
---|
3055 | set_sgr(A_BLINK | A_REVERSE);
|
---|
3056 | mvprintw(16, 1, "blink negative");
|
---|
3057 |
|
---|
3058 | set_sgr(A_BOLD | A_BLINK | A_REVERSE);
|
---|
3059 | mvprintw(16, 40, "bold blink negative");
|
---|
3060 |
|
---|
3061 | set_sgr(A_UNDERLINE | A_BLINK | A_REVERSE);
|
---|
3062 | mvprintw(18, 6, "underline blink negative");
|
---|
3063 |
|
---|
3064 | set_sgr(A_BOLD | A_UNDERLINE | A_BLINK | A_REVERSE);
|
---|
3065 | mvprintw(18, 45, "bold underline blink negative");
|
---|
3066 |
|
---|
3067 | bkgdset(normal);
|
---|
3068 | mvprintw(LINES - 2, 1, "%s background. ", pass == 0 ? "Dark" :
|
---|
3069 | "Light");
|
---|
3070 | clrtoeol();
|
---|
3071 | Pause();
|
---|
3072 | }
|
---|
3073 |
|
---|
3074 | bkgdset(A_NORMAL | BLANK);
|
---|
3075 | erase();
|
---|
3076 | endwin();
|
---|
3077 | }
|
---|
3078 |
|
---|
3079 | /****************************************************************************
|
---|
3080 | *
|
---|
3081 | * Windows and scrolling tester.
|
---|
3082 | *
|
---|
3083 | ****************************************************************************/
|
---|
3084 |
|
---|
3085 | #define BOTLINES 4 /* number of line stolen from screen bottom */
|
---|
3086 |
|
---|
3087 | typedef struct {
|
---|
3088 | int y, x;
|
---|
3089 | } pair;
|
---|
3090 |
|
---|
3091 | #define FRAME struct frame
|
---|
3092 | FRAME
|
---|
3093 | {
|
---|
3094 | FRAME *next, *last;
|
---|
3095 | bool do_scroll;
|
---|
3096 | bool do_keypad;
|
---|
3097 | WINDOW *wind;
|
---|
3098 | };
|
---|
3099 |
|
---|
3100 | #ifdef NCURSES_VERSION
|
---|
3101 | #define keypad_active(win) (win)->_use_keypad
|
---|
3102 | #define scroll_active(win) (win)->_scroll
|
---|
3103 | #else
|
---|
3104 | #define keypad_active(win) FALSE
|
---|
3105 | #define scroll_active(win) FALSE
|
---|
3106 | #endif
|
---|
3107 |
|
---|
3108 | /* We need to know if these flags are actually set, so don't look in FRAME.
|
---|
3109 | * These names are known to work with SVr4 curses as well as ncurses. The
|
---|
3110 | * _use_keypad name does not work with Solaris 8.
|
---|
3111 | */
|
---|
3112 | static bool
|
---|
3113 | HaveKeypad(FRAME * curp)
|
---|
3114 | {
|
---|
3115 | WINDOW *win = (curp ? curp->wind : stdscr);
|
---|
3116 | return keypad_active(win);
|
---|
3117 | }
|
---|
3118 |
|
---|
3119 | static bool
|
---|
3120 | HaveScroll(FRAME * curp)
|
---|
3121 | {
|
---|
3122 | WINDOW *win = (curp ? curp->wind : stdscr);
|
---|
3123 | return scroll_active(win);
|
---|
3124 | }
|
---|
3125 |
|
---|
3126 | static void
|
---|
3127 | newwin_legend(FRAME * curp)
|
---|
3128 | {
|
---|
3129 | static const struct {
|
---|
3130 | const char *msg;
|
---|
3131 | int code;
|
---|
3132 | } legend[] = {
|
---|
3133 | {
|
---|
3134 | "^C = create window", 0
|
---|
3135 | },
|
---|
3136 | {
|
---|
3137 | "^N = next window", 0
|
---|
3138 | },
|
---|
3139 | {
|
---|
3140 | "^P = previous window", 0
|
---|
3141 | },
|
---|
3142 | {
|
---|
3143 | "^F = scroll forward", 0
|
---|
3144 | },
|
---|
3145 | {
|
---|
3146 | "^B = scroll backward", 0
|
---|
3147 | },
|
---|
3148 | {
|
---|
3149 | "^K = keypad(%s)", 1
|
---|
3150 | },
|
---|
3151 | {
|
---|
3152 | "^S = scrollok(%s)", 2
|
---|
3153 | },
|
---|
3154 | {
|
---|
3155 | "^W = save window to file", 0
|
---|
3156 | },
|
---|
3157 | {
|
---|
3158 | "^R = restore window", 0
|
---|
3159 | },
|
---|
3160 | #if HAVE_WRESIZE
|
---|
3161 | {
|
---|
3162 | "^X = resize", 0
|
---|
3163 | },
|
---|
3164 | #endif
|
---|
3165 | {
|
---|
3166 | "^Q%s = exit", 3
|
---|
3167 | }
|
---|
3168 | };
|
---|
3169 | size_t n;
|
---|
3170 | int x;
|
---|
3171 | bool do_keypad = HaveKeypad(curp);
|
---|
3172 | bool do_scroll = HaveScroll(curp);
|
---|
3173 | char buf[BUFSIZ];
|
---|
3174 |
|
---|
3175 | move(LINES - 4, 0);
|
---|
3176 | for (n = 0; n < SIZEOF(legend); n++) {
|
---|
3177 | switch (legend[n].code) {
|
---|
3178 | default:
|
---|
3179 | strcpy(buf, legend[n].msg);
|
---|
3180 | break;
|
---|
3181 | case 1:
|
---|
3182 | sprintf(buf, legend[n].msg, do_keypad ? "yes" : "no");
|
---|
3183 | break;
|
---|
3184 | case 2:
|
---|
3185 | sprintf(buf, legend[n].msg, do_scroll ? "yes" : "no");
|
---|
3186 | break;
|
---|
3187 | case 3:
|
---|
3188 | sprintf(buf, legend[n].msg, do_keypad ? "/ESC" : "");
|
---|
3189 | break;
|
---|
3190 | }
|
---|
3191 | x = getcurx(stdscr);
|
---|
3192 | addstr((COLS < (x + 3 + (int) strlen(buf))) ? "\n" : (n ? ", " : ""));
|
---|
3193 | addstr(buf);
|
---|
3194 | }
|
---|
3195 | clrtoeol();
|
---|
3196 | }
|
---|
3197 |
|
---|
3198 | static void
|
---|
3199 | transient(FRAME * curp, NCURSES_CONST char *msg)
|
---|
3200 | {
|
---|
3201 | newwin_legend(curp);
|
---|
3202 | if (msg) {
|
---|
3203 | mvaddstr(LINES - 1, 0, msg);
|
---|
3204 | refresh();
|
---|
3205 | napms(1000);
|
---|
3206 | }
|
---|
3207 |
|
---|
3208 | move(LINES - 1, 0);
|
---|
3209 | printw("%s characters are echoed, window should %sscroll.",
|
---|
3210 | HaveKeypad(curp) ? "Non-arrow" : "All other",
|
---|
3211 | HaveScroll(curp) ? "" : "not ");
|
---|
3212 | clrtoeol();
|
---|
3213 | }
|
---|
3214 |
|
---|
3215 | static void
|
---|
3216 | newwin_report(FRAME * curp)
|
---|
3217 | /* report on the cursor's current position, then restore it */
|
---|
3218 | {
|
---|
3219 | WINDOW *win = (curp != 0) ? curp->wind : stdscr;
|
---|
3220 | int y, x;
|
---|
3221 |
|
---|
3222 | if (win != stdscr)
|
---|
3223 | transient(curp, (char *) 0);
|
---|
3224 | getyx(win, y, x);
|
---|
3225 | move(LINES - 1, COLS - 17);
|
---|
3226 | printw("Y = %2d X = %2d", y, x);
|
---|
3227 | if (win != stdscr)
|
---|
3228 | refresh();
|
---|
3229 | else
|
---|
3230 | wmove(win, y, x);
|
---|
3231 | }
|
---|
3232 |
|
---|
3233 | static pair *
|
---|
3234 | selectcell(int uli, int ulj, int lri, int lrj)
|
---|
3235 | /* arrows keys move cursor, return location at current on non-arrow key */
|
---|
3236 | {
|
---|
3237 | static pair res; /* result cell */
|
---|
3238 | int si = lri - uli + 1; /* depth of the select area */
|
---|
3239 | int sj = lrj - ulj + 1; /* width of the select area */
|
---|
3240 | int i = 0, j = 0; /* offsets into the select area */
|
---|
3241 |
|
---|
3242 | res.y = uli;
|
---|
3243 | res.x = ulj;
|
---|
3244 | for (;;) {
|
---|
3245 | move(uli + i, ulj + j);
|
---|
3246 | newwin_report((FRAME *) 0);
|
---|
3247 |
|
---|
3248 | switch (Getchar()) {
|
---|
3249 | case KEY_UP:
|
---|
3250 | i += si - 1;
|
---|
3251 | break;
|
---|
3252 | case KEY_DOWN:
|
---|
3253 | i++;
|
---|
3254 | break;
|
---|
3255 | case KEY_LEFT:
|
---|
3256 | j += sj - 1;
|
---|
3257 | break;
|
---|
3258 | case KEY_RIGHT:
|
---|
3259 | j++;
|
---|
3260 | break;
|
---|
3261 | case QUIT:
|
---|
3262 | case ESCAPE:
|
---|
3263 | return ((pair *) 0);
|
---|
3264 | #ifdef NCURSES_MOUSE_VERSION
|
---|
3265 | case KEY_MOUSE:
|
---|
3266 | {
|
---|
3267 | MEVENT event;
|
---|
3268 |
|
---|
3269 | getmouse(&event);
|
---|
3270 | if (event.y > uli && event.x > ulj) {
|
---|
3271 | i = event.y - uli;
|
---|
3272 | j = event.x - ulj;
|
---|
3273 | } else {
|
---|
3274 | beep();
|
---|
3275 | break;
|
---|
3276 | }
|
---|
3277 | }
|
---|
3278 | /* FALLTHRU */
|
---|
3279 | #endif
|
---|
3280 | default:
|
---|
3281 | res.y = uli + i;
|
---|
3282 | res.x = ulj + j;
|
---|
3283 | return (&res);
|
---|
3284 | }
|
---|
3285 | i %= si;
|
---|
3286 | j %= sj;
|
---|
3287 | }
|
---|
3288 | }
|
---|
3289 |
|
---|
3290 | static void
|
---|
3291 | outerbox(pair ul, pair lr, bool onoff)
|
---|
3292 | /* draw or erase a box *outside* the given pair of corners */
|
---|
3293 | {
|
---|
3294 | mvaddch(ul.y - 1, lr.x - 1, onoff ? ACS_ULCORNER : ' ');
|
---|
3295 | mvaddch(ul.y - 1, lr.x + 1, onoff ? ACS_URCORNER : ' ');
|
---|
3296 | mvaddch(lr.y + 1, lr.x + 1, onoff ? ACS_LRCORNER : ' ');
|
---|
3297 | mvaddch(lr.y + 1, ul.x - 1, onoff ? ACS_LLCORNER : ' ');
|
---|
3298 | move(ul.y - 1, ul.x);
|
---|
3299 | hline(onoff ? ACS_HLINE : ' ', lr.x - ul.x + 1);
|
---|
3300 | move(ul.y, ul.x - 1);
|
---|
3301 | vline(onoff ? ACS_VLINE : ' ', lr.y - ul.y + 1);
|
---|
3302 | move(lr.y + 1, ul.x);
|
---|
3303 | hline(onoff ? ACS_HLINE : ' ', lr.x - ul.x + 1);
|
---|
3304 | move(ul.y, lr.x + 1);
|
---|
3305 | vline(onoff ? ACS_VLINE : ' ', lr.y - ul.y + 1);
|
---|
3306 | }
|
---|
3307 |
|
---|
3308 | static WINDOW *
|
---|
3309 | getwindow(void)
|
---|
3310 | /* Ask user for a window definition */
|
---|
3311 | {
|
---|
3312 | WINDOW *rwindow;
|
---|
3313 | pair ul, lr, *tmp;
|
---|
3314 |
|
---|
3315 | move(0, 0);
|
---|
3316 | clrtoeol();
|
---|
3317 | addstr("Use arrows to move cursor, anything else to mark corner 1");
|
---|
3318 | refresh();
|
---|
3319 | if ((tmp = selectcell(2, 1, LINES - BOTLINES - 2, COLS - 2)) == (pair *) 0)
|
---|
3320 | return ((WINDOW *) 0);
|
---|
3321 | memcpy(&ul, tmp, sizeof(pair));
|
---|
3322 | mvaddch(ul.y - 1, ul.x - 1, ACS_ULCORNER);
|
---|
3323 | move(0, 0);
|
---|
3324 | clrtoeol();
|
---|
3325 | addstr("Use arrows to move cursor, anything else to mark corner 2");
|
---|
3326 | refresh();
|
---|
3327 | if ((tmp = selectcell(ul.y, ul.x, LINES - BOTLINES - 2, COLS - 2)) ==
|
---|
3328 | (pair *) 0)
|
---|
3329 | return ((WINDOW *) 0);
|
---|
3330 | memcpy(&lr, tmp, sizeof(pair));
|
---|
3331 |
|
---|
3332 | rwindow = subwin(stdscr, lr.y - ul.y + 1, lr.x - ul.x + 1, ul.y, ul.x);
|
---|
3333 |
|
---|
3334 | outerbox(ul, lr, TRUE);
|
---|
3335 | refresh();
|
---|
3336 |
|
---|
3337 | wrefresh(rwindow);
|
---|
3338 |
|
---|
3339 | move(0, 0);
|
---|
3340 | clrtoeol();
|
---|
3341 | return (rwindow);
|
---|
3342 | }
|
---|
3343 |
|
---|
3344 | static void
|
---|
3345 | newwin_move(FRAME * curp, int dy, int dx)
|
---|
3346 | {
|
---|
3347 | WINDOW *win = (curp != 0) ? curp->wind : stdscr;
|
---|
3348 | int cur_y, cur_x;
|
---|
3349 | int max_y, max_x;
|
---|
3350 |
|
---|
3351 | getyx(win, cur_y, cur_x);
|
---|
3352 | getmaxyx(win, max_y, max_x);
|
---|
3353 | if ((cur_x += dx) < 0)
|
---|
3354 | cur_x = 0;
|
---|
3355 | else if (cur_x >= max_x)
|
---|
3356 | cur_x = max_x - 1;
|
---|
3357 | if ((cur_y += dy) < 0)
|
---|
3358 | cur_y = 0;
|
---|
3359 | else if (cur_y >= max_y)
|
---|
3360 | cur_y = max_y - 1;
|
---|
3361 | wmove(win, cur_y, cur_x);
|
---|
3362 | }
|
---|
3363 |
|
---|
3364 | static FRAME *
|
---|
3365 | delete_framed(FRAME * fp, bool showit)
|
---|
3366 | {
|
---|
3367 | FRAME *np;
|
---|
3368 |
|
---|
3369 | fp->last->next = fp->next;
|
---|
3370 | fp->next->last = fp->last;
|
---|
3371 |
|
---|
3372 | if (showit) {
|
---|
3373 | werase(fp->wind);
|
---|
3374 | wrefresh(fp->wind);
|
---|
3375 | }
|
---|
3376 | delwin(fp->wind);
|
---|
3377 |
|
---|
3378 | np = (fp == fp->next) ? 0 : fp->next;
|
---|
3379 | free(fp);
|
---|
3380 | return np;
|
---|
3381 | }
|
---|
3382 |
|
---|
3383 | static void
|
---|
3384 | acs_and_scroll(void)
|
---|
3385 | /* Demonstrate windows */
|
---|
3386 | {
|
---|
3387 | int c, i;
|
---|
3388 | FILE *fp;
|
---|
3389 | FRAME *current = (FRAME *) 0, *neww;
|
---|
3390 | WINDOW *usescr = stdscr;
|
---|
3391 |
|
---|
3392 | #define DUMPFILE "screendump"
|
---|
3393 |
|
---|
3394 | #ifdef NCURSES_MOUSE_VERSION
|
---|
3395 | mousemask(BUTTON1_CLICKED, (mmask_t *) 0);
|
---|
3396 | #endif
|
---|
3397 | c = CTRL('C');
|
---|
3398 | raw();
|
---|
3399 | do {
|
---|
3400 | transient((FRAME *) 0, (char *) 0);
|
---|
3401 | switch (c) {
|
---|
3402 | case CTRL('C'):
|
---|
3403 | neww = (FRAME *) calloc(1, sizeof(FRAME));
|
---|
3404 | if ((neww->wind = getwindow()) == (WINDOW *) 0)
|
---|
3405 | goto breakout;
|
---|
3406 |
|
---|
3407 | if (current == 0) { /* First element, */
|
---|
3408 | neww->next = neww; /* so point it at itself */
|
---|
3409 | neww->last = neww;
|
---|
3410 | } else {
|
---|
3411 | neww->next = current->next;
|
---|
3412 | neww->last = current;
|
---|
3413 | neww->last->next = neww;
|
---|
3414 | neww->next->last = neww;
|
---|
3415 | }
|
---|
3416 | current = neww;
|
---|
3417 | /* SVr4 curses sets the keypad on all newly-created windows to
|
---|
3418 | * false. Someone reported that PDCurses makes new windows inherit
|
---|
3419 | * this flag. Remove the following 'keypad()' call to test this
|
---|
3420 | */
|
---|
3421 | keypad(current->wind, TRUE);
|
---|
3422 | current->do_keypad = HaveKeypad(current);
|
---|
3423 | current->do_scroll = HaveScroll(current);
|
---|
3424 | break;
|
---|
3425 |
|
---|
3426 | case CTRL('N'): /* go to next window */
|
---|
3427 | if (current)
|
---|
3428 | current = current->next;
|
---|
3429 | break;
|
---|
3430 |
|
---|
3431 | case CTRL('P'): /* go to previous window */
|
---|
3432 | if (current)
|
---|
3433 | current = current->last;
|
---|
3434 | break;
|
---|
3435 |
|
---|
3436 | case CTRL('F'): /* scroll current window forward */
|
---|
3437 | if (current)
|
---|
3438 | wscrl(current->wind, 1);
|
---|
3439 | break;
|
---|
3440 |
|
---|
3441 | case CTRL('B'): /* scroll current window backwards */
|
---|
3442 | if (current)
|
---|
3443 | wscrl(current->wind, -1);
|
---|
3444 | break;
|
---|
3445 |
|
---|
3446 | case CTRL('K'): /* toggle keypad mode for current */
|
---|
3447 | if (current) {
|
---|
3448 | current->do_keypad = !current->do_keypad;
|
---|
3449 | keypad(current->wind, current->do_keypad);
|
---|
3450 | }
|
---|
3451 | break;
|
---|
3452 |
|
---|
3453 | case CTRL('S'):
|
---|
3454 | if (current) {
|
---|
3455 | current->do_scroll = !current->do_scroll;
|
---|
3456 | scrollok(current->wind, current->do_scroll);
|
---|
3457 | }
|
---|
3458 | break;
|
---|
3459 |
|
---|
3460 | case CTRL('W'): /* save and delete window */
|
---|
3461 | if (current == current->next) {
|
---|
3462 | transient(current, "Will not save/delete ONLY window");
|
---|
3463 | break;
|
---|
3464 | } else if ((fp = fopen(DUMPFILE, "w")) == (FILE *) 0) {
|
---|
3465 | transient(current, "Can't open screen dump file");
|
---|
3466 | } else {
|
---|
3467 | (void) putwin(current->wind, fp);
|
---|
3468 | (void) fclose(fp);
|
---|
3469 |
|
---|
3470 | current = delete_framed(current, TRUE);
|
---|
3471 | }
|
---|
3472 | break;
|
---|
3473 |
|
---|
3474 | case CTRL('R'): /* restore window */
|
---|
3475 | if ((fp = fopen(DUMPFILE, "r")) == (FILE *) 0) {
|
---|
3476 | transient(current, "Can't open screen dump file");
|
---|
3477 | } else {
|
---|
3478 | neww = (FRAME *) calloc(1, sizeof(FRAME));
|
---|
3479 |
|
---|
3480 | neww->next = current->next;
|
---|
3481 | neww->last = current;
|
---|
3482 | neww->last->next = neww;
|
---|
3483 | neww->next->last = neww;
|
---|
3484 |
|
---|
3485 | neww->wind = getwin(fp);
|
---|
3486 | (void) fclose(fp);
|
---|
3487 |
|
---|
3488 | wrefresh(neww->wind);
|
---|
3489 | }
|
---|
3490 | break;
|
---|
3491 |
|
---|
3492 | #if HAVE_WRESIZE
|
---|
3493 | case CTRL('X'): /* resize window */
|
---|
3494 | if (current) {
|
---|
3495 | pair *tmp, ul, lr;
|
---|
3496 | int mx, my;
|
---|
3497 |
|
---|
3498 | move(0, 0);
|
---|
3499 | clrtoeol();
|
---|
3500 | addstr("Use arrows to move cursor, anything else to mark new corner");
|
---|
3501 | refresh();
|
---|
3502 |
|
---|
3503 | getbegyx(current->wind, ul.y, ul.x);
|
---|
3504 |
|
---|
3505 | tmp = selectcell(ul.y, ul.x, LINES - BOTLINES - 2, COLS - 2);
|
---|
3506 | if (tmp == (pair *) 0) {
|
---|
3507 | beep();
|
---|
3508 | break;
|
---|
3509 | }
|
---|
3510 |
|
---|
3511 | getmaxyx(current->wind, lr.y, lr.x);
|
---|
3512 | lr.y += (ul.y - 1);
|
---|
3513 | lr.x += (ul.x - 1);
|
---|
3514 | outerbox(ul, lr, FALSE);
|
---|
3515 | wnoutrefresh(stdscr);
|
---|
3516 |
|
---|
3517 | /* strictly cosmetic hack for the test */
|
---|
3518 | getmaxyx(current->wind, my, mx);
|
---|
3519 | if (my > tmp->y - ul.y) {
|
---|
3520 | getyx(current->wind, lr.y, lr.x);
|
---|
3521 | wmove(current->wind, tmp->y - ul.y + 1, 0);
|
---|
3522 | wclrtobot(current->wind);
|
---|
3523 | wmove(current->wind, lr.y, lr.x);
|
---|
3524 | }
|
---|
3525 | if (mx > tmp->x - ul.x)
|
---|
3526 | for (i = 0; i < my; i++) {
|
---|
3527 | wmove(current->wind, i, tmp->x - ul.x + 1);
|
---|
3528 | wclrtoeol(current->wind);
|
---|
3529 | }
|
---|
3530 | wnoutrefresh(current->wind);
|
---|
3531 |
|
---|
3532 | memcpy(&lr, tmp, sizeof(pair));
|
---|
3533 | (void) wresize(current->wind, lr.y - ul.y + 0, lr.x - ul.x + 0);
|
---|
3534 |
|
---|
3535 | getbegyx(current->wind, ul.y, ul.x);
|
---|
3536 | getmaxyx(current->wind, lr.y, lr.x);
|
---|
3537 | lr.y += (ul.y - 1);
|
---|
3538 | lr.x += (ul.x - 1);
|
---|
3539 | outerbox(ul, lr, TRUE);
|
---|
3540 | wnoutrefresh(stdscr);
|
---|
3541 |
|
---|
3542 | wnoutrefresh(current->wind);
|
---|
3543 | move(0, 0);
|
---|
3544 | clrtoeol();
|
---|
3545 | doupdate();
|
---|
3546 | }
|
---|
3547 | break;
|
---|
3548 | #endif /* HAVE_WRESIZE */
|
---|
3549 |
|
---|
3550 | case KEY_F(10): /* undocumented --- use this to test area clears */
|
---|
3551 | selectcell(0, 0, LINES - 1, COLS - 1);
|
---|
3552 | clrtobot();
|
---|
3553 | refresh();
|
---|
3554 | break;
|
---|
3555 |
|
---|
3556 | case KEY_UP:
|
---|
3557 | newwin_move(current, -1, 0);
|
---|
3558 | break;
|
---|
3559 | case KEY_DOWN:
|
---|
3560 | newwin_move(current, 1, 0);
|
---|
3561 | break;
|
---|
3562 | case KEY_LEFT:
|
---|
3563 | newwin_move(current, 0, -1);
|
---|
3564 | break;
|
---|
3565 | case KEY_RIGHT:
|
---|
3566 | newwin_move(current, 0, 1);
|
---|
3567 | break;
|
---|
3568 |
|
---|
3569 | case KEY_BACKSPACE:
|
---|
3570 | /* FALLTHROUGH */
|
---|
3571 | case KEY_DC:
|
---|
3572 | {
|
---|
3573 | int y, x;
|
---|
3574 | getyx(current->wind, y, x);
|
---|
3575 | if (--x < 0) {
|
---|
3576 | if (--y < 0)
|
---|
3577 | break;
|
---|
3578 | x = getmaxx(current->wind) - 1;
|
---|
3579 | }
|
---|
3580 | mvwdelch(current->wind, y, x);
|
---|
3581 | }
|
---|
3582 | break;
|
---|
3583 |
|
---|
3584 | case '\r':
|
---|
3585 | c = '\n';
|
---|
3586 | /* FALLTHROUGH */
|
---|
3587 |
|
---|
3588 | default:
|
---|
3589 | if (current)
|
---|
3590 | waddch(current->wind, (chtype) c);
|
---|
3591 | else
|
---|
3592 | beep();
|
---|
3593 | break;
|
---|
3594 | }
|
---|
3595 | newwin_report(current);
|
---|
3596 | usescr = (current ? current->wind : stdscr);
|
---|
3597 | wrefresh(usescr);
|
---|
3598 | } while
|
---|
3599 | ((c = wGetchar(usescr)) != QUIT
|
---|
3600 | && !((c == ESCAPE) && (keypad_active(usescr)))
|
---|
3601 | && (c != ERR));
|
---|
3602 |
|
---|
3603 | breakout:
|
---|
3604 | while (current != 0)
|
---|
3605 | current = delete_framed(current, FALSE);
|
---|
3606 |
|
---|
3607 | scrollok(stdscr, TRUE); /* reset to driver's default */
|
---|
3608 | #ifdef NCURSES_MOUSE_VERSION
|
---|
3609 | mousemask(0, (mmask_t *) 0);
|
---|
3610 | #endif
|
---|
3611 | noraw();
|
---|
3612 | erase();
|
---|
3613 | endwin();
|
---|
3614 | }
|
---|
3615 |
|
---|
3616 | /****************************************************************************
|
---|
3617 | *
|
---|
3618 | * Panels tester
|
---|
3619 | *
|
---|
3620 | ****************************************************************************/
|
---|
3621 |
|
---|
3622 | #if USE_LIBPANEL
|
---|
3623 | static int nap_msec = 1;
|
---|
3624 |
|
---|
3625 | static NCURSES_CONST char *mod[] =
|
---|
3626 | {
|
---|
3627 | "test ",
|
---|
3628 | "TEST ",
|
---|
3629 | "(**) ",
|
---|
3630 | "*()* ",
|
---|
3631 | "<--> ",
|
---|
3632 | "LAST "
|
---|
3633 | };
|
---|
3634 |
|
---|
3635 | /*+-------------------------------------------------------------------------
|
---|
3636 | wait_a_while(msec)
|
---|
3637 | --------------------------------------------------------------------------*/
|
---|
3638 | static void
|
---|
3639 | wait_a_while(int msec GCC_UNUSED)
|
---|
3640 | {
|
---|
3641 | #if HAVE_NAPMS
|
---|
3642 | if (nap_msec == 1)
|
---|
3643 | wGetchar(stdscr);
|
---|
3644 | else
|
---|
3645 | napms(nap_msec);
|
---|
3646 | #else
|
---|
3647 | if (nap_msec == 1)
|
---|
3648 | wGetchar(stdscr);
|
---|
3649 | else if (msec > 1000)
|
---|
3650 | sleep((unsigned) msec / 1000);
|
---|
3651 | else
|
---|
3652 | sleep(1);
|
---|
3653 | #endif
|
---|
3654 | } /* end of wait_a_while */
|
---|
3655 |
|
---|
3656 | /*+-------------------------------------------------------------------------
|
---|
3657 | saywhat(text)
|
---|
3658 | --------------------------------------------------------------------------*/
|
---|
3659 | static void
|
---|
3660 | saywhat(NCURSES_CONST char *text)
|
---|
3661 | {
|
---|
3662 | wmove(stdscr, LINES - 1, 0);
|
---|
3663 | wclrtoeol(stdscr);
|
---|
3664 | waddstr(stdscr, text);
|
---|
3665 | } /* end of saywhat */
|
---|
3666 |
|
---|
3667 | /*+-------------------------------------------------------------------------
|
---|
3668 | mkpanel(rows,cols,tly,tlx) - alloc a win and panel and associate them
|
---|
3669 | --------------------------------------------------------------------------*/
|
---|
3670 | static PANEL *
|
---|
3671 | mkpanel(unsigned color, int rows, int cols, int tly, int tlx)
|
---|
3672 | {
|
---|
3673 | WINDOW *win;
|
---|
3674 | PANEL *pan = 0;
|
---|
3675 |
|
---|
3676 | if ((win = newwin(rows, cols, tly, tlx)) != 0) {
|
---|
3677 | if ((pan = new_panel(win)) == 0) {
|
---|
3678 | delwin(win);
|
---|
3679 | } else if (has_colors()) {
|
---|
3680 | int fg = (color == COLOR_BLUE) ? COLOR_WHITE : COLOR_BLACK;
|
---|
3681 | int bg = color;
|
---|
3682 | init_pair(color, fg, bg);
|
---|
3683 | wbkgdset(win, COLOR_PAIR(color) | ' ');
|
---|
3684 | } else {
|
---|
3685 | wbkgdset(win, A_BOLD | ' ');
|
---|
3686 | }
|
---|
3687 | }
|
---|
3688 | return pan;
|
---|
3689 | } /* end of mkpanel */
|
---|
3690 |
|
---|
3691 | /*+-------------------------------------------------------------------------
|
---|
3692 | rmpanel(pan)
|
---|
3693 | --------------------------------------------------------------------------*/
|
---|
3694 | static void
|
---|
3695 | rmpanel(PANEL * pan)
|
---|
3696 | {
|
---|
3697 | WINDOW *win = panel_window(pan);
|
---|
3698 | del_panel(pan);
|
---|
3699 | delwin(win);
|
---|
3700 | } /* end of rmpanel */
|
---|
3701 |
|
---|
3702 | /*+-------------------------------------------------------------------------
|
---|
3703 | pflush()
|
---|
3704 | --------------------------------------------------------------------------*/
|
---|
3705 | static void
|
---|
3706 | pflush(void)
|
---|
3707 | {
|
---|
3708 | update_panels();
|
---|
3709 | doupdate();
|
---|
3710 | } /* end of pflush */
|
---|
3711 |
|
---|
3712 | /*+-------------------------------------------------------------------------
|
---|
3713 | fill_panel(win)
|
---|
3714 | --------------------------------------------------------------------------*/
|
---|
3715 | static void
|
---|
3716 | fill_panel(PANEL * pan)
|
---|
3717 | {
|
---|
3718 | WINDOW *win = panel_window(pan);
|
---|
3719 | int num = ((const char *) panel_userptr(pan))[1];
|
---|
3720 | int y, x;
|
---|
3721 |
|
---|
3722 | wmove(win, 1, 1);
|
---|
3723 | wprintw(win, "-pan%c-", num);
|
---|
3724 | wclrtoeol(win);
|
---|
3725 | box(win, 0, 0);
|
---|
3726 | for (y = 2; y < getmaxy(win) - 1; y++) {
|
---|
3727 | for (x = 1; x < getmaxx(win) - 1; x++) {
|
---|
3728 | wmove(win, y, x);
|
---|
3729 | waddch(win, UChar(num));
|
---|
3730 | }
|
---|
3731 | }
|
---|
3732 | } /* end of fill_panel */
|
---|
3733 |
|
---|
3734 | static void
|
---|
3735 | demo_panels(void)
|
---|
3736 | {
|
---|
3737 | int itmp;
|
---|
3738 | register int y, x;
|
---|
3739 |
|
---|
3740 | refresh();
|
---|
3741 |
|
---|
3742 | for (y = 0; y < LINES - 1; y++) {
|
---|
3743 | for (x = 0; x < COLS; x++)
|
---|
3744 | wprintw(stdscr, "%d", (y + x) % 10);
|
---|
3745 | }
|
---|
3746 | for (y = 0; y < 5; y++) {
|
---|
3747 | PANEL *p1;
|
---|
3748 | PANEL *p2;
|
---|
3749 | PANEL *p3;
|
---|
3750 | PANEL *p4;
|
---|
3751 | PANEL *p5;
|
---|
3752 |
|
---|
3753 | p1 = mkpanel(COLOR_RED,
|
---|
3754 | LINES / 2 - 2,
|
---|
3755 | COLS / 8 + 1,
|
---|
3756 | 0,
|
---|
3757 | 0);
|
---|
3758 | set_panel_userptr(p1, (NCURSES_CONST void *) "p1");
|
---|
3759 |
|
---|
3760 | p2 = mkpanel(COLOR_GREEN,
|
---|
3761 | LINES / 2 + 1,
|
---|
3762 | COLS / 7,
|
---|
3763 | LINES / 4,
|
---|
3764 | COLS / 10);
|
---|
3765 | set_panel_userptr(p2, (NCURSES_CONST void *) "p2");
|
---|
3766 |
|
---|
3767 | p3 = mkpanel(COLOR_YELLOW,
|
---|
3768 | LINES / 4,
|
---|
3769 | COLS / 10,
|
---|
3770 | LINES / 2,
|
---|
3771 | COLS / 9);
|
---|
3772 | set_panel_userptr(p3, (NCURSES_CONST void *) "p3");
|
---|
3773 |
|
---|
3774 | p4 = mkpanel(COLOR_BLUE,
|
---|
3775 | LINES / 2 - 2,
|
---|
3776 | COLS / 8,
|
---|
3777 | LINES / 2 - 2,
|
---|
3778 | COLS / 3);
|
---|
3779 | set_panel_userptr(p4, (NCURSES_CONST void *) "p4");
|
---|
3780 |
|
---|
3781 | p5 = mkpanel(COLOR_MAGENTA,
|
---|
3782 | LINES / 2 - 2,
|
---|
3783 | COLS / 8,
|
---|
3784 | LINES / 2,
|
---|
3785 | COLS / 2 - 2);
|
---|
3786 | set_panel_userptr(p5, (NCURSES_CONST void *) "p5");
|
---|
3787 |
|
---|
3788 | fill_panel(p1);
|
---|
3789 | fill_panel(p2);
|
---|
3790 | fill_panel(p3);
|
---|
3791 | fill_panel(p4);
|
---|
3792 | fill_panel(p5);
|
---|
3793 | hide_panel(p4);
|
---|
3794 | hide_panel(p5);
|
---|
3795 | pflush();
|
---|
3796 | saywhat("press any key to continue");
|
---|
3797 | wait_a_while(nap_msec);
|
---|
3798 |
|
---|
3799 | saywhat("h3 s1 s2 s4 s5; press any key to continue");
|
---|
3800 | move_panel(p1, 0, 0);
|
---|
3801 | hide_panel(p3);
|
---|
3802 | show_panel(p1);
|
---|
3803 | show_panel(p2);
|
---|
3804 | show_panel(p4);
|
---|
3805 | show_panel(p5);
|
---|
3806 | pflush();
|
---|
3807 | wait_a_while(nap_msec);
|
---|
3808 |
|
---|
3809 | saywhat("s1; press any key to continue");
|
---|
3810 | show_panel(p1);
|
---|
3811 | pflush();
|
---|
3812 | wait_a_while(nap_msec);
|
---|
3813 |
|
---|
3814 | saywhat("s2; press any key to continue");
|
---|
3815 | show_panel(p2);
|
---|
3816 | pflush();
|
---|
3817 | wait_a_while(nap_msec);
|
---|
3818 |
|
---|
3819 | saywhat("m2; press any key to continue");
|
---|
3820 | move_panel(p2, LINES / 3 + 1, COLS / 8);
|
---|
3821 | pflush();
|
---|
3822 | wait_a_while(nap_msec);
|
---|
3823 |
|
---|
3824 | saywhat("s3;");
|
---|
3825 | show_panel(p3);
|
---|
3826 | pflush();
|
---|
3827 | wait_a_while(nap_msec);
|
---|
3828 |
|
---|
3829 | saywhat("m3; press any key to continue");
|
---|
3830 | move_panel(p3, LINES / 4 + 1, COLS / 15);
|
---|
3831 | pflush();
|
---|
3832 | wait_a_while(nap_msec);
|
---|
3833 |
|
---|
3834 | saywhat("b3; press any key to continue");
|
---|
3835 | bottom_panel(p3);
|
---|
3836 | pflush();
|
---|
3837 | wait_a_while(nap_msec);
|
---|
3838 |
|
---|
3839 | saywhat("s4; press any key to continue");
|
---|
3840 | show_panel(p4);
|
---|
3841 | pflush();
|
---|
3842 | wait_a_while(nap_msec);
|
---|
3843 |
|
---|
3844 | saywhat("s5; press any key to continue");
|
---|
3845 | show_panel(p5);
|
---|
3846 | pflush();
|
---|
3847 | wait_a_while(nap_msec);
|
---|
3848 |
|
---|
3849 | saywhat("t3; press any key to continue");
|
---|
3850 | top_panel(p3);
|
---|
3851 | pflush();
|
---|
3852 | wait_a_while(nap_msec);
|
---|
3853 |
|
---|
3854 | saywhat("t1; press any key to continue");
|
---|
3855 | top_panel(p1);
|
---|
3856 | pflush();
|
---|
3857 | wait_a_while(nap_msec);
|
---|
3858 |
|
---|
3859 | saywhat("t2; press any key to continue");
|
---|
3860 | top_panel(p2);
|
---|
3861 | pflush();
|
---|
3862 | wait_a_while(nap_msec);
|
---|
3863 |
|
---|
3864 | saywhat("t3; press any key to continue");
|
---|
3865 | top_panel(p3);
|
---|
3866 | pflush();
|
---|
3867 | wait_a_while(nap_msec);
|
---|
3868 |
|
---|
3869 | saywhat("t4; press any key to continue");
|
---|
3870 | top_panel(p4);
|
---|
3871 | pflush();
|
---|
3872 | wait_a_while(nap_msec);
|
---|
3873 |
|
---|
3874 | for (itmp = 0; itmp < 6; itmp++) {
|
---|
3875 | WINDOW *w4 = panel_window(p4);
|
---|
3876 | WINDOW *w5 = panel_window(p5);
|
---|
3877 |
|
---|
3878 | saywhat("m4; press any key to continue");
|
---|
3879 | wmove(w4, LINES / 8, 1);
|
---|
3880 | waddstr(w4, mod[itmp]);
|
---|
3881 | move_panel(p4, LINES / 6, itmp * (COLS / 8));
|
---|
3882 | wmove(w5, LINES / 6, 1);
|
---|
3883 | waddstr(w5, mod[itmp]);
|
---|
3884 | pflush();
|
---|
3885 | wait_a_while(nap_msec);
|
---|
3886 |
|
---|
3887 | saywhat("m5; press any key to continue");
|
---|
3888 | wmove(w4, LINES / 6, 1);
|
---|
3889 | waddstr(w4, mod[itmp]);
|
---|
3890 | move_panel(p5, LINES / 3 - 1, (itmp * 10) + 6);
|
---|
3891 | wmove(w5, LINES / 8, 1);
|
---|
3892 | waddstr(w5, mod[itmp]);
|
---|
3893 | pflush();
|
---|
3894 | wait_a_while(nap_msec);
|
---|
3895 | }
|
---|
3896 |
|
---|
3897 | saywhat("m4; press any key to continue");
|
---|
3898 | move_panel(p4, LINES / 6, itmp * (COLS / 8));
|
---|
3899 | pflush();
|
---|
3900 | wait_a_while(nap_msec);
|
---|
3901 |
|
---|
3902 | saywhat("t5; press any key to continue");
|
---|
3903 | top_panel(p5);
|
---|
3904 | pflush();
|
---|
3905 | wait_a_while(nap_msec);
|
---|
3906 |
|
---|
3907 | saywhat("t2; press any key to continue");
|
---|
3908 | top_panel(p2);
|
---|
3909 | pflush();
|
---|
3910 | wait_a_while(nap_msec);
|
---|
3911 |
|
---|
3912 | saywhat("t1; press any key to continue");
|
---|
3913 | top_panel(p1);
|
---|
3914 | pflush();
|
---|
3915 | wait_a_while(nap_msec);
|
---|
3916 |
|
---|
3917 | saywhat("d2; press any key to continue");
|
---|
3918 | rmpanel(p2);
|
---|
3919 | pflush();
|
---|
3920 | wait_a_while(nap_msec);
|
---|
3921 |
|
---|
3922 | saywhat("h3; press any key to continue");
|
---|
3923 | hide_panel(p3);
|
---|
3924 | pflush();
|
---|
3925 | wait_a_while(nap_msec);
|
---|
3926 |
|
---|
3927 | saywhat("d1; press any key to continue");
|
---|
3928 | rmpanel(p1);
|
---|
3929 | pflush();
|
---|
3930 | wait_a_while(nap_msec);
|
---|
3931 |
|
---|
3932 | saywhat("d4; press any key to continue");
|
---|
3933 | rmpanel(p4);
|
---|
3934 | pflush();
|
---|
3935 | wait_a_while(nap_msec);
|
---|
3936 |
|
---|
3937 | saywhat("d5; press any key to continue");
|
---|
3938 | rmpanel(p5);
|
---|
3939 | pflush();
|
---|
3940 |
|
---|
3941 | rmpanel(p3);
|
---|
3942 | pflush();
|
---|
3943 |
|
---|
3944 | wait_a_while(nap_msec);
|
---|
3945 | if (nap_msec == 1)
|
---|
3946 | break;
|
---|
3947 | nap_msec = 100L;
|
---|
3948 | }
|
---|
3949 |
|
---|
3950 | erase();
|
---|
3951 | endwin();
|
---|
3952 | }
|
---|
3953 |
|
---|
3954 | /****************************************************************************
|
---|
3955 | *
|
---|
3956 | * Pad tester
|
---|
3957 | *
|
---|
3958 | ****************************************************************************/
|
---|
3959 |
|
---|
3960 | #define GRIDSIZE 3
|
---|
3961 |
|
---|
3962 | static bool pending_pan = FALSE;
|
---|
3963 | static bool show_panner_legend = TRUE;
|
---|
3964 |
|
---|
3965 | static int
|
---|
3966 | panner_legend(int line)
|
---|
3967 | {
|
---|
3968 | static const char *const legend[] =
|
---|
3969 | {
|
---|
3970 | "Use arrow keys (or U,D,L,R) to pan, q to quit, ! to shell-out.",
|
---|
3971 | "Use +,- (or j,k) to grow/shrink the panner vertically.",
|
---|
3972 | "Use <,> (or h,l) to grow/shrink the panner horizontally.",
|
---|
3973 | "Number repeats. Toggle legend:? filler:a timer:t scrollmark:s."
|
---|
3974 | };
|
---|
3975 | int n = (SIZEOF(legend) - (LINES - line));
|
---|
3976 | if (line < LINES && (n >= 0)) {
|
---|
3977 | move(line, 0);
|
---|
3978 | if (show_panner_legend)
|
---|
3979 | printw("%s", legend[n]);
|
---|
3980 | clrtoeol();
|
---|
3981 | return show_panner_legend;
|
---|
3982 | }
|
---|
3983 | return FALSE;
|
---|
3984 | }
|
---|
3985 |
|
---|
3986 | static void
|
---|
3987 | panner_h_cleanup(int from_y, int from_x, int to_x)
|
---|
3988 | {
|
---|
3989 | if (!panner_legend(from_y))
|
---|
3990 | do_h_line(from_y, from_x, ' ', to_x);
|
---|
3991 | }
|
---|
3992 |
|
---|
3993 | static void
|
---|
3994 | panner_v_cleanup(int from_y, int from_x, int to_y)
|
---|
3995 | {
|
---|
3996 | if (!panner_legend(from_y))
|
---|
3997 | do_v_line(from_y, from_x, ' ', to_y);
|
---|
3998 | }
|
---|
3999 |
|
---|
4000 | static void
|
---|
4001 | fill_pad(WINDOW *panpad, bool pan_lines)
|
---|
4002 | {
|
---|
4003 | int y, x;
|
---|
4004 | unsigned gridcount = 0;
|
---|
4005 |
|
---|
4006 | wmove(panpad, 0, 0);
|
---|
4007 | for (y = 0; y < getmaxy(panpad); y++) {
|
---|
4008 | for (x = 0; x < getmaxx(panpad); x++) {
|
---|
4009 | if (y % GRIDSIZE == 0 && x % GRIDSIZE == 0) {
|
---|
4010 | if (y == 0 && x == 0)
|
---|
4011 | waddch(panpad, pan_lines ? ACS_ULCORNER : '+');
|
---|
4012 | else if (y == 0)
|
---|
4013 | waddch(panpad, pan_lines ? ACS_TTEE : '+');
|
---|
4014 | else if (y == 0 || x == 0)
|
---|
4015 | waddch(panpad, pan_lines ? ACS_LTEE : '+');
|
---|
4016 | else
|
---|
4017 | waddch(panpad, (chtype) ((pan_lines ? 'a' : 'A') +
|
---|
4018 | (gridcount++ % 26)));
|
---|
4019 | } else if (y % GRIDSIZE == 0)
|
---|
4020 | waddch(panpad, pan_lines ? ACS_HLINE : '-');
|
---|
4021 | else if (x % GRIDSIZE == 0)
|
---|
4022 | waddch(panpad, pan_lines ? ACS_VLINE : '|');
|
---|
4023 | else
|
---|
4024 | waddch(panpad, ' ');
|
---|
4025 | }
|
---|
4026 | }
|
---|
4027 | }
|
---|
4028 |
|
---|
4029 | static void
|
---|
4030 | panner(WINDOW *pad,
|
---|
4031 | int top_x, int top_y, int porty, int portx,
|
---|
4032 | int (*pgetc) (WINDOW *))
|
---|
4033 | {
|
---|
4034 | #if HAVE_GETTIMEOFDAY
|
---|
4035 | struct timeval before, after;
|
---|
4036 | bool timing = TRUE;
|
---|
4037 | #endif
|
---|
4038 | bool pan_lines = FALSE;
|
---|
4039 | bool scrollers = TRUE;
|
---|
4040 | int basex = 0;
|
---|
4041 | int basey = 0;
|
---|
4042 | int pxmax, pymax, lowend, highend, c;
|
---|
4043 |
|
---|
4044 | getmaxyx(pad, pymax, pxmax);
|
---|
4045 | scrollok(stdscr, FALSE); /* we don't want stdscr to scroll! */
|
---|
4046 |
|
---|
4047 | c = KEY_REFRESH;
|
---|
4048 | do {
|
---|
4049 | #ifdef NCURSES_VERSION
|
---|
4050 | /*
|
---|
4051 | * During shell-out, the user may have resized the window. Adjust
|
---|
4052 | * the port size of the pad to accommodate this. Ncurses automatically
|
---|
4053 | * resizes all of the normal windows to fit on the new screen.
|
---|
4054 | */
|
---|
4055 | if (top_x > COLS)
|
---|
4056 | top_x = COLS;
|
---|
4057 | if (portx > COLS)
|
---|
4058 | portx = COLS;
|
---|
4059 | if (top_y > LINES)
|
---|
4060 | top_y = LINES;
|
---|
4061 | if (porty > LINES)
|
---|
4062 | porty = LINES;
|
---|
4063 | #endif
|
---|
4064 | switch (c) {
|
---|
4065 | case KEY_REFRESH:
|
---|
4066 | erase();
|
---|
4067 |
|
---|
4068 | /* FALLTHRU */
|
---|
4069 | case '?':
|
---|
4070 | if (c == '?')
|
---|
4071 | show_panner_legend = !show_panner_legend;
|
---|
4072 | panner_legend(LINES - 4);
|
---|
4073 | panner_legend(LINES - 3);
|
---|
4074 | panner_legend(LINES - 2);
|
---|
4075 | panner_legend(LINES - 1);
|
---|
4076 | break;
|
---|
4077 | case 'a':
|
---|
4078 | pan_lines = !pan_lines;
|
---|
4079 | fill_pad(pad, pan_lines);
|
---|
4080 | pending_pan = FALSE;
|
---|
4081 | break;
|
---|
4082 |
|
---|
4083 | #if HAVE_GETTIMEOFDAY
|
---|
4084 | case 't':
|
---|
4085 | timing = !timing;
|
---|
4086 | if (!timing)
|
---|
4087 | panner_legend(LINES - 1);
|
---|
4088 | break;
|
---|
4089 | #endif
|
---|
4090 | case 's':
|
---|
4091 | scrollers = !scrollers;
|
---|
4092 | break;
|
---|
4093 |
|
---|
4094 | /* Move the top-left corner of the pad, keeping the bottom-right
|
---|
4095 | * corner fixed.
|
---|
4096 | */
|
---|
4097 | case 'h': /* increase-columns: move left edge to left */
|
---|
4098 | if (top_x <= 0)
|
---|
4099 | beep();
|
---|
4100 | else {
|
---|
4101 | panner_v_cleanup(top_y, top_x, porty);
|
---|
4102 | top_x--;
|
---|
4103 | }
|
---|
4104 | break;
|
---|
4105 |
|
---|
4106 | case 'j': /* decrease-lines: move top-edge down */
|
---|
4107 | if (top_y >= porty)
|
---|
4108 | beep();
|
---|
4109 | else {
|
---|
4110 | panner_h_cleanup(top_y - 1, top_x - (top_x > 0), portx);
|
---|
4111 | top_y++;
|
---|
4112 | }
|
---|
4113 | break;
|
---|
4114 |
|
---|
4115 | case 'k': /* increase-lines: move top-edge up */
|
---|
4116 | if (top_y <= 0)
|
---|
4117 | beep();
|
---|
4118 | else {
|
---|
4119 | top_y--;
|
---|
4120 | panner_h_cleanup(top_y, top_x, portx);
|
---|
4121 | }
|
---|
4122 | break;
|
---|
4123 |
|
---|
4124 | case 'l': /* decrease-columns: move left-edge to right */
|
---|
4125 | if (top_x >= portx)
|
---|
4126 | beep();
|
---|
4127 | else {
|
---|
4128 | panner_v_cleanup(top_y - (top_y > 0), top_x - 1, porty);
|
---|
4129 | top_x++;
|
---|
4130 | }
|
---|
4131 | break;
|
---|
4132 |
|
---|
4133 | /* Move the bottom-right corner of the pad, keeping the top-left
|
---|
4134 | * corner fixed.
|
---|
4135 | */
|
---|
4136 | case KEY_IC: /* increase-columns: move right-edge to right */
|
---|
4137 | if (portx >= pxmax || portx >= COLS)
|
---|
4138 | beep();
|
---|
4139 | else {
|
---|
4140 | panner_v_cleanup(top_y - (top_y > 0), portx - 1, porty);
|
---|
4141 | ++portx;
|
---|
4142 | }
|
---|
4143 | break;
|
---|
4144 |
|
---|
4145 | case KEY_IL: /* increase-lines: move bottom-edge down */
|
---|
4146 | if (porty >= pymax || porty >= LINES)
|
---|
4147 | beep();
|
---|
4148 | else {
|
---|
4149 | panner_h_cleanup(porty - 1, top_x - (top_x > 0), portx);
|
---|
4150 | ++porty;
|
---|
4151 | }
|
---|
4152 | break;
|
---|
4153 |
|
---|
4154 | case KEY_DC: /* decrease-columns: move bottom edge up */
|
---|
4155 | if (portx <= top_x)
|
---|
4156 | beep();
|
---|
4157 | else {
|
---|
4158 | portx--;
|
---|
4159 | panner_v_cleanup(top_y - (top_y > 0), portx, porty);
|
---|
4160 | }
|
---|
4161 | break;
|
---|
4162 |
|
---|
4163 | case KEY_DL: /* decrease-lines */
|
---|
4164 | if (porty <= top_y)
|
---|
4165 | beep();
|
---|
4166 | else {
|
---|
4167 | porty--;
|
---|
4168 | panner_h_cleanup(porty, top_x - (top_x > 0), portx);
|
---|
4169 | }
|
---|
4170 | break;
|
---|
4171 |
|
---|
4172 | case KEY_LEFT: /* pan leftwards */
|
---|
4173 | if (basex > 0)
|
---|
4174 | basex--;
|
---|
4175 | else
|
---|
4176 | beep();
|
---|
4177 | break;
|
---|
4178 |
|
---|
4179 | case KEY_RIGHT: /* pan rightwards */
|
---|
4180 | if (basex + portx - (pymax > porty) < pxmax)
|
---|
4181 | basex++;
|
---|
4182 | else
|
---|
4183 | beep();
|
---|
4184 | break;
|
---|
4185 |
|
---|
4186 | case KEY_UP: /* pan upwards */
|
---|
4187 | if (basey > 0)
|
---|
4188 | basey--;
|
---|
4189 | else
|
---|
4190 | beep();
|
---|
4191 | break;
|
---|
4192 |
|
---|
4193 | case KEY_DOWN: /* pan downwards */
|
---|
4194 | if (basey + porty - (pxmax > portx) < pymax)
|
---|
4195 | basey++;
|
---|
4196 | else
|
---|
4197 | beep();
|
---|
4198 | break;
|
---|
4199 |
|
---|
4200 | case 'H':
|
---|
4201 | case KEY_HOME:
|
---|
4202 | case KEY_FIND:
|
---|
4203 | basey = 0;
|
---|
4204 | break;
|
---|
4205 |
|
---|
4206 | case 'E':
|
---|
4207 | case KEY_END:
|
---|
4208 | case KEY_SELECT:
|
---|
4209 | basey = pymax - porty;
|
---|
4210 | if (basey < 0)
|
---|
4211 | basey = 0;
|
---|
4212 | break;
|
---|
4213 |
|
---|
4214 | default:
|
---|
4215 | beep();
|
---|
4216 | break;
|
---|
4217 | }
|
---|
4218 |
|
---|
4219 | mvaddch(top_y - 1, top_x - 1, ACS_ULCORNER);
|
---|
4220 | do_v_line(top_y, top_x - 1, ACS_VLINE, porty);
|
---|
4221 | do_h_line(top_y - 1, top_x, ACS_HLINE, portx);
|
---|
4222 |
|
---|
4223 | if (scrollers && (pxmax > portx - 1)) {
|
---|
4224 | int length = (portx - top_x - 1);
|
---|
4225 | float ratio = ((float) length) / ((float) pxmax);
|
---|
4226 |
|
---|
4227 | lowend = (int) (top_x + (basex * ratio));
|
---|
4228 | highend = (int) (top_x + ((basex + length) * ratio));
|
---|
4229 |
|
---|
4230 | do_h_line(porty - 1, top_x, ACS_HLINE, lowend);
|
---|
4231 | if (highend < portx) {
|
---|
4232 | attron(A_REVERSE);
|
---|
4233 | do_h_line(porty - 1, lowend, ' ', highend + 1);
|
---|
4234 | attroff(A_REVERSE);
|
---|
4235 | do_h_line(porty - 1, highend + 1, ACS_HLINE, portx);
|
---|
4236 | }
|
---|
4237 | } else
|
---|
4238 | do_h_line(porty - 1, top_x, ACS_HLINE, portx);
|
---|
4239 |
|
---|
4240 | if (scrollers && (pymax > porty - 1)) {
|
---|
4241 | int length = (porty - top_y - 1);
|
---|
4242 | float ratio = ((float) length) / ((float) pymax);
|
---|
4243 |
|
---|
4244 | lowend = (int) (top_y + (basey * ratio));
|
---|
4245 | highend = (int) (top_y + ((basey + length) * ratio));
|
---|
4246 |
|
---|
4247 | do_v_line(top_y, portx - 1, ACS_VLINE, lowend);
|
---|
4248 | if (highend < porty) {
|
---|
4249 | attron(A_REVERSE);
|
---|
4250 | do_v_line(lowend, portx - 1, ' ', highend + 1);
|
---|
4251 | attroff(A_REVERSE);
|
---|
4252 | do_v_line(highend + 1, portx - 1, ACS_VLINE, porty);
|
---|
4253 | }
|
---|
4254 | } else
|
---|
4255 | do_v_line(top_y, portx - 1, ACS_VLINE, porty);
|
---|
4256 |
|
---|
4257 | mvaddch(top_y - 1, portx - 1, ACS_URCORNER);
|
---|
4258 | mvaddch(porty - 1, top_x - 1, ACS_LLCORNER);
|
---|
4259 | mvaddch(porty - 1, portx - 1, ACS_LRCORNER);
|
---|
4260 |
|
---|
4261 | if (!pending_pan) {
|
---|
4262 | #if HAVE_GETTIMEOFDAY
|
---|
4263 | gettimeofday(&before, 0);
|
---|
4264 | #endif
|
---|
4265 | wnoutrefresh(stdscr);
|
---|
4266 |
|
---|
4267 | pnoutrefresh(pad,
|
---|
4268 | basey, basex,
|
---|
4269 | top_y, top_x,
|
---|
4270 | porty - (pxmax > portx) - 1,
|
---|
4271 | portx - (pymax > porty) - 1);
|
---|
4272 |
|
---|
4273 | doupdate();
|
---|
4274 | #if HAVE_GETTIMEOFDAY
|
---|
4275 | if (timing) {
|
---|
4276 | double elapsed;
|
---|
4277 | gettimeofday(&after, 0);
|
---|
4278 | elapsed = (after.tv_sec + after.tv_usec / 1.0e6)
|
---|
4279 | - (before.tv_sec + before.tv_usec / 1.0e6);
|
---|
4280 | move(LINES - 1, COLS - 12);
|
---|
4281 | printw("Secs: %2.03f", elapsed);
|
---|
4282 | refresh();
|
---|
4283 | }
|
---|
4284 | #endif
|
---|
4285 | }
|
---|
4286 |
|
---|
4287 | } while
|
---|
4288 | ((c = pgetc(pad)) != KEY_EXIT);
|
---|
4289 |
|
---|
4290 | scrollok(stdscr, TRUE); /* reset to driver's default */
|
---|
4291 | }
|
---|
4292 |
|
---|
4293 | static int
|
---|
4294 | padgetch(WINDOW *win)
|
---|
4295 | {
|
---|
4296 | static int count;
|
---|
4297 | static int last;
|
---|
4298 | int c;
|
---|
4299 |
|
---|
4300 | if ((pending_pan = (count > 0)) != FALSE) {
|
---|
4301 | count--;
|
---|
4302 | pending_pan = (count != 0);
|
---|
4303 | } else {
|
---|
4304 | for (;;) {
|
---|
4305 | switch (c = wGetchar(win)) {
|
---|
4306 | case '!':
|
---|
4307 | ShellOut(FALSE);
|
---|
4308 | /* FALLTHRU */
|
---|
4309 | case CTRL('r'):
|
---|
4310 | endwin();
|
---|
4311 | refresh();
|
---|
4312 | c = KEY_REFRESH;
|
---|
4313 | break;
|
---|
4314 | case CTRL('l'):
|
---|
4315 | c = KEY_REFRESH;
|
---|
4316 | break;
|
---|
4317 | case 'U':
|
---|
4318 | c = KEY_UP;
|
---|
4319 | break;
|
---|
4320 | case 'D':
|
---|
4321 | c = KEY_DOWN;
|
---|
4322 | break;
|
---|
4323 | case 'R':
|
---|
4324 | c = KEY_RIGHT;
|
---|
4325 | break;
|
---|
4326 | case 'L':
|
---|
4327 | c = KEY_LEFT;
|
---|
4328 | break;
|
---|
4329 | case '+':
|
---|
4330 | c = KEY_IL;
|
---|
4331 | break;
|
---|
4332 | case '-':
|
---|
4333 | c = KEY_DL;
|
---|
4334 | break;
|
---|
4335 | case '>':
|
---|
4336 | c = KEY_IC;
|
---|
4337 | break;
|
---|
4338 | case '<':
|
---|
4339 | c = KEY_DC;
|
---|
4340 | break;
|
---|
4341 | case ERR: /* FALLTHRU */
|
---|
4342 | case 'q':
|
---|
4343 | count = 0;
|
---|
4344 | c = KEY_EXIT;
|
---|
4345 | break;
|
---|
4346 | default:
|
---|
4347 | if (c >= '0' && c <= '9') {
|
---|
4348 | count = count * 10 + (c - '0');
|
---|
4349 | continue;
|
---|
4350 | }
|
---|
4351 | break;
|
---|
4352 | }
|
---|
4353 | last = c;
|
---|
4354 | break;
|
---|
4355 | }
|
---|
4356 | if (count > 0)
|
---|
4357 | count--;
|
---|
4358 | }
|
---|
4359 | return (last);
|
---|
4360 | }
|
---|
4361 |
|
---|
4362 | #define PAD_HIGH 200
|
---|
4363 | #define PAD_WIDE 200
|
---|
4364 |
|
---|
4365 | static void
|
---|
4366 | demo_pad(void)
|
---|
4367 | /* Demonstrate pads. */
|
---|
4368 | {
|
---|
4369 | WINDOW *panpad = newpad(PAD_HIGH, PAD_WIDE);
|
---|
4370 |
|
---|
4371 | if (panpad == 0) {
|
---|
4372 | Cannot("cannot create requested pad");
|
---|
4373 | return;
|
---|
4374 | }
|
---|
4375 |
|
---|
4376 | fill_pad(panpad, FALSE);
|
---|
4377 |
|
---|
4378 | panner_legend(LINES - 4);
|
---|
4379 | panner_legend(LINES - 3);
|
---|
4380 | panner_legend(LINES - 2);
|
---|
4381 | panner_legend(LINES - 1);
|
---|
4382 |
|
---|
4383 | keypad(panpad, TRUE);
|
---|
4384 |
|
---|
4385 | /* Make the pad (initially) narrow enough that a trace file won't wrap.
|
---|
4386 | * We'll still be able to widen it during a test, since that's required
|
---|
4387 | * for testing boundaries.
|
---|
4388 | */
|
---|
4389 | panner(panpad, 2, 2, LINES - 5, COLS - 15, padgetch);
|
---|
4390 |
|
---|
4391 | delwin(panpad);
|
---|
4392 | endwin();
|
---|
4393 | erase();
|
---|
4394 | }
|
---|
4395 | #endif /* USE_LIBPANEL */
|
---|
4396 |
|
---|
4397 | /****************************************************************************
|
---|
4398 | *
|
---|
4399 | * Tests from John Burnell's PDCurses tester
|
---|
4400 | *
|
---|
4401 | ****************************************************************************/
|
---|
4402 |
|
---|
4403 | static void
|
---|
4404 | Continue(WINDOW *win)
|
---|
4405 | {
|
---|
4406 | noecho();
|
---|
4407 | wmove(win, 10, 1);
|
---|
4408 | mvwaddstr(win, 10, 1, " Press any key to continue");
|
---|
4409 | wrefresh(win);
|
---|
4410 | wGetchar(win);
|
---|
4411 | }
|
---|
4412 |
|
---|
4413 | static void
|
---|
4414 | flushinp_test(WINDOW *win)
|
---|
4415 | /* Input test, adapted from John Burnell's PDCurses tester */
|
---|
4416 | {
|
---|
4417 | int w, h, bx, by, sw, sh, i;
|
---|
4418 |
|
---|
4419 | WINDOW *subWin;
|
---|
4420 | wclear(win);
|
---|
4421 |
|
---|
4422 | getmaxyx(win, h, w);
|
---|
4423 | getbegyx(win, by, bx);
|
---|
4424 | sw = w / 3;
|
---|
4425 | sh = h / 3;
|
---|
4426 | if ((subWin = subwin(win, sh, sw, by + h - sh - 2, bx + w - sw - 2)) == 0)
|
---|
4427 | return;
|
---|
4428 |
|
---|
4429 | #ifdef A_COLOR
|
---|
4430 | if (has_colors()) {
|
---|
4431 | init_pair(2, COLOR_CYAN, COLOR_BLUE);
|
---|
4432 | wbkgd(subWin, COLOR_PAIR(2) | ' ');
|
---|
4433 | }
|
---|
4434 | #endif
|
---|
4435 | wattrset(subWin, A_BOLD);
|
---|
4436 | box(subWin, ACS_VLINE, ACS_HLINE);
|
---|
4437 | mvwaddstr(subWin, 2, 1, "This is a subwindow");
|
---|
4438 | wrefresh(win);
|
---|
4439 |
|
---|
4440 | /*
|
---|
4441 | * This used to set 'nocbreak()'. However, Alexander Lukyanov says that
|
---|
4442 | * it only happened to "work" on SVr4 because that implementation does not
|
---|
4443 | * emulate nocbreak+noecho mode, whereas ncurses does. To get the desired
|
---|
4444 | * test behavior, we're using 'cbreak()', which will allow a single
|
---|
4445 | * character to return without needing a newline. - T.Dickey 1997/10/11.
|
---|
4446 | */
|
---|
4447 | cbreak();
|
---|
4448 | mvwaddstr(win, 0, 1, "This is a test of the flushinp() call.");
|
---|
4449 |
|
---|
4450 | mvwaddstr(win, 2, 1, "Type random keys for 5 seconds.");
|
---|
4451 | mvwaddstr(win, 3, 1,
|
---|
4452 | "These should be discarded (not echoed) after the subwindow goes away.");
|
---|
4453 | wrefresh(win);
|
---|
4454 |
|
---|
4455 | for (i = 0; i < 5; i++) {
|
---|
4456 | mvwprintw(subWin, 1, 1, "Time = %d", i);
|
---|
4457 | wrefresh(subWin);
|
---|
4458 | napms(1000);
|
---|
4459 | flushinp();
|
---|
4460 | }
|
---|
4461 |
|
---|
4462 | delwin(subWin);
|
---|
4463 | werase(win);
|
---|
4464 | flash();
|
---|
4465 | wrefresh(win);
|
---|
4466 | napms(1000);
|
---|
4467 |
|
---|
4468 | mvwaddstr(win, 2, 1,
|
---|
4469 | "If you were still typing when the window timer expired,");
|
---|
4470 | mvwaddstr(win, 3, 1,
|
---|
4471 | "or else you typed nothing at all while it was running,");
|
---|
4472 | mvwaddstr(win, 4, 1,
|
---|
4473 | "test was invalid. You'll see garbage or nothing at all. ");
|
---|
4474 | mvwaddstr(win, 6, 1, "Press a key");
|
---|
4475 | wmove(win, 9, 10);
|
---|
4476 | wrefresh(win);
|
---|
4477 | echo();
|
---|
4478 | wGetchar(win);
|
---|
4479 | flushinp();
|
---|
4480 | mvwaddstr(win, 12, 0,
|
---|
4481 | "If you see any key other than what you typed, flushinp() is broken.");
|
---|
4482 | Continue(win);
|
---|
4483 |
|
---|
4484 | wmove(win, 9, 10);
|
---|
4485 | wdelch(win);
|
---|
4486 | wrefresh(win);
|
---|
4487 | wmove(win, 12, 0);
|
---|
4488 | clrtoeol();
|
---|
4489 | waddstr(win,
|
---|
4490 | "What you typed should now have been deleted; if not, wdelch() failed.");
|
---|
4491 | Continue(win);
|
---|
4492 |
|
---|
4493 | cbreak();
|
---|
4494 | }
|
---|
4495 |
|
---|
4496 | /****************************************************************************
|
---|
4497 | *
|
---|
4498 | * Menu test
|
---|
4499 | *
|
---|
4500 | ****************************************************************************/
|
---|
4501 |
|
---|
4502 | #if USE_LIBMENU
|
---|
4503 |
|
---|
4504 | #define MENU_Y 8
|
---|
4505 | #define MENU_X 8
|
---|
4506 |
|
---|
4507 | static int
|
---|
4508 | menu_virtualize(int c)
|
---|
4509 | {
|
---|
4510 | if (c == '\n' || c == KEY_EXIT)
|
---|
4511 | return (MAX_COMMAND + 1);
|
---|
4512 | else if (c == 'u')
|
---|
4513 | return (REQ_SCR_ULINE);
|
---|
4514 | else if (c == 'd')
|
---|
4515 | return (REQ_SCR_DLINE);
|
---|
4516 | else if (c == 'b' || c == KEY_NPAGE)
|
---|
4517 | return (REQ_SCR_UPAGE);
|
---|
4518 | else if (c == 'f' || c == KEY_PPAGE)
|
---|
4519 | return (REQ_SCR_DPAGE);
|
---|
4520 | else if (c == 'n' || c == KEY_DOWN)
|
---|
4521 | return (REQ_NEXT_ITEM);
|
---|
4522 | else if (c == 'p' || c == KEY_UP)
|
---|
4523 | return (REQ_PREV_ITEM);
|
---|
4524 | else if (c == ' ')
|
---|
4525 | return (REQ_TOGGLE_ITEM);
|
---|
4526 | else {
|
---|
4527 | if (c != KEY_MOUSE)
|
---|
4528 | beep();
|
---|
4529 | return (c);
|
---|
4530 | }
|
---|
4531 | }
|
---|
4532 |
|
---|
4533 | static const char *animals[] =
|
---|
4534 | {
|
---|
4535 | "Lions",
|
---|
4536 | "Tigers",
|
---|
4537 | "Bears",
|
---|
4538 | "(Oh my!)",
|
---|
4539 | "Newts",
|
---|
4540 | "Platypi",
|
---|
4541 | "Lemurs",
|
---|
4542 | "(Oh really?!)",
|
---|
4543 | "Leopards",
|
---|
4544 | "Panthers",
|
---|
4545 | "Pumas",
|
---|
4546 | "Lions, Tigers, Bears, (Oh my!), Newts, Platypi, Lemurs",
|
---|
4547 | "Lions, Tigers, Bears, (Oh my!), Newts, Platypi, Lemurs, Lions, Tigers, Bears, (Oh my!), Newts, Platypi, Lemurs",
|
---|
4548 | (char *) 0
|
---|
4549 | };
|
---|
4550 |
|
---|
4551 | static void
|
---|
4552 | menu_test(void)
|
---|
4553 | {
|
---|
4554 | MENU *m;
|
---|
4555 | ITEM *items[SIZEOF(animals)];
|
---|
4556 | ITEM **ip = items;
|
---|
4557 | const char **ap;
|
---|
4558 | int mrows, mcols, c;
|
---|
4559 | WINDOW *menuwin;
|
---|
4560 |
|
---|
4561 | #ifdef NCURSES_MOUSE_VERSION
|
---|
4562 | mousemask(ALL_MOUSE_EVENTS, (mmask_t *) 0);
|
---|
4563 | #endif
|
---|
4564 | mvaddstr(0, 0, "This is the menu test:");
|
---|
4565 | mvaddstr(2, 0, " Use up and down arrow to move the select bar.");
|
---|
4566 | mvaddstr(3, 0, " 'n' and 'p' act like arrows.");
|
---|
4567 | mvaddstr(4, 0,
|
---|
4568 | " 'b' and 'f' scroll up/down (page), 'u' and 'd' (line).");
|
---|
4569 | mvaddstr(5, 0, " Press return to exit.");
|
---|
4570 | refresh();
|
---|
4571 |
|
---|
4572 | for (ap = animals; *ap; ap++)
|
---|
4573 | *ip++ = new_item(*ap, "");
|
---|
4574 | *ip = (ITEM *) 0;
|
---|
4575 |
|
---|
4576 | m = new_menu(items);
|
---|
4577 |
|
---|
4578 | set_menu_format(m, (SIZEOF(animals) + 1) / 2, 1);
|
---|
4579 | scale_menu(m, &mrows, &mcols);
|
---|
4580 |
|
---|
4581 | menuwin = newwin(mrows + 2, mcols + 2, MENU_Y, MENU_X);
|
---|
4582 | set_menu_win(m, menuwin);
|
---|
4583 | keypad(menuwin, TRUE);
|
---|
4584 | box(menuwin, 0, 0);
|
---|
4585 |
|
---|
4586 | set_menu_sub(m, derwin(menuwin, mrows, mcols, 1, 1));
|
---|
4587 |
|
---|
4588 | post_menu(m);
|
---|
4589 |
|
---|
4590 | while ((c = menu_driver(m, menu_virtualize(wGetchar(menuwin)))) != E_UNKNOWN_COMMAND) {
|
---|
4591 | if (c == E_NOT_POSTED)
|
---|
4592 | break;
|
---|
4593 | if (c == E_REQUEST_DENIED)
|
---|
4594 | beep();
|
---|
4595 | continue;
|
---|
4596 | }
|
---|
4597 |
|
---|
4598 | (void) mvprintw(LINES - 2, 0,
|
---|
4599 | "You chose: %s\n", item_name(current_item(m)));
|
---|
4600 | (void) addstr("Press any key to continue...");
|
---|
4601 | wGetchar(stdscr);
|
---|
4602 |
|
---|
4603 | unpost_menu(m);
|
---|
4604 | delwin(menuwin);
|
---|
4605 |
|
---|
4606 | free_menu(m);
|
---|
4607 | for (ip = items; *ip; ip++)
|
---|
4608 | free_item(*ip);
|
---|
4609 | #ifdef NCURSES_MOUSE_VERSION
|
---|
4610 | mousemask(0, (mmask_t *) 0);
|
---|
4611 | #endif
|
---|
4612 | }
|
---|
4613 |
|
---|
4614 | #ifdef TRACE
|
---|
4615 | #define T_TBL(name) { #name, name }
|
---|
4616 | static struct {
|
---|
4617 | const char *name;
|
---|
4618 | unsigned mask;
|
---|
4619 | } t_tbl[] = {
|
---|
4620 |
|
---|
4621 | T_TBL(TRACE_DISABLE),
|
---|
4622 | T_TBL(TRACE_TIMES),
|
---|
4623 | T_TBL(TRACE_TPUTS),
|
---|
4624 | T_TBL(TRACE_UPDATE),
|
---|
4625 | T_TBL(TRACE_MOVE),
|
---|
4626 | T_TBL(TRACE_CHARPUT),
|
---|
4627 | T_TBL(TRACE_ORDINARY),
|
---|
4628 | T_TBL(TRACE_CALLS),
|
---|
4629 | T_TBL(TRACE_VIRTPUT),
|
---|
4630 | T_TBL(TRACE_IEVENT),
|
---|
4631 | T_TBL(TRACE_BITS),
|
---|
4632 | T_TBL(TRACE_ICALLS),
|
---|
4633 | T_TBL(TRACE_CCALLS),
|
---|
4634 | T_TBL(TRACE_DATABASE),
|
---|
4635 | T_TBL(TRACE_ATTRS),
|
---|
4636 | T_TBL(TRACE_MAXIMUM),
|
---|
4637 | {
|
---|
4638 | (char *) 0, 0
|
---|
4639 | }
|
---|
4640 | };
|
---|
4641 |
|
---|
4642 | static char *
|
---|
4643 | tracetrace(unsigned tlevel)
|
---|
4644 | {
|
---|
4645 | static char *buf;
|
---|
4646 | int n;
|
---|
4647 |
|
---|
4648 | if (buf == 0) {
|
---|
4649 | size_t need = 12;
|
---|
4650 | for (n = 0; t_tbl[n].name != 0; n++)
|
---|
4651 | need += strlen(t_tbl[n].name) + 2;
|
---|
4652 | buf = (char *) malloc(need);
|
---|
4653 | }
|
---|
4654 | sprintf(buf, "0x%02x = {", tlevel);
|
---|
4655 | if (tlevel == 0) {
|
---|
4656 | sprintf(buf + strlen(buf), "%s, ", t_tbl[0].name);
|
---|
4657 | } else {
|
---|
4658 | for (n = 1; t_tbl[n].name != 0; n++)
|
---|
4659 | if ((tlevel & t_tbl[n].mask) == t_tbl[n].mask) {
|
---|
4660 | strcat(buf, t_tbl[n].name);
|
---|
4661 | strcat(buf, ", ");
|
---|
4662 | }
|
---|
4663 | }
|
---|
4664 | if (buf[strlen(buf) - 2] == ',')
|
---|
4665 | buf[strlen(buf) - 2] = '\0';
|
---|
4666 | return (strcat(buf, "}"));
|
---|
4667 | }
|
---|
4668 |
|
---|
4669 | /* fake a dynamically reconfigurable menu using the 0th entry to deselect
|
---|
4670 | * the others
|
---|
4671 | */
|
---|
4672 | static int
|
---|
4673 | run_trace_menu(MENU * m)
|
---|
4674 | {
|
---|
4675 | ITEM **items;
|
---|
4676 | ITEM *i, **p;
|
---|
4677 |
|
---|
4678 | for (;;) {
|
---|
4679 | bool changed = FALSE;
|
---|
4680 | switch (menu_driver(m, menu_virtualize(wGetchar(menu_win(m))))) {
|
---|
4681 | case E_UNKNOWN_COMMAND:
|
---|
4682 | return FALSE;
|
---|
4683 | default:
|
---|
4684 | items = menu_items(m);
|
---|
4685 | i = current_item(m);
|
---|
4686 | if (i == items[0]) {
|
---|
4687 | if (item_value(i)) {
|
---|
4688 | for (p = items + 1; *p != 0; p++)
|
---|
4689 | if (item_value(*p)) {
|
---|
4690 | set_item_value(*p, FALSE);
|
---|
4691 | changed = TRUE;
|
---|
4692 | }
|
---|
4693 | }
|
---|
4694 | } else {
|
---|
4695 | for (p = items + 1; *p != 0; p++)
|
---|
4696 | if (item_value(*p)) {
|
---|
4697 | set_item_value(items[0], FALSE);
|
---|
4698 | changed = TRUE;
|
---|
4699 | break;
|
---|
4700 | }
|
---|
4701 | }
|
---|
4702 | if (!changed)
|
---|
4703 | return TRUE;
|
---|
4704 | }
|
---|
4705 | }
|
---|
4706 | }
|
---|
4707 |
|
---|
4708 | static void
|
---|
4709 | trace_set(void)
|
---|
4710 | /* interactively set the trace level */
|
---|
4711 | {
|
---|
4712 | MENU *m;
|
---|
4713 | ITEM *items[SIZEOF(t_tbl)];
|
---|
4714 | ITEM **ip = items;
|
---|
4715 | int mrows, mcols;
|
---|
4716 | unsigned newtrace;
|
---|
4717 | int n;
|
---|
4718 | WINDOW *menuwin;
|
---|
4719 |
|
---|
4720 | mvaddstr(0, 0, "Interactively set trace level:");
|
---|
4721 | mvaddstr(2, 0, " Press space bar to toggle a selection.");
|
---|
4722 | mvaddstr(3, 0, " Use up and down arrow to move the select bar.");
|
---|
4723 | mvaddstr(4, 0, " Press return to set the trace level.");
|
---|
4724 | mvprintw(6, 0, "(Current trace level is %s)", tracetrace(_nc_tracing));
|
---|
4725 |
|
---|
4726 | refresh();
|
---|
4727 |
|
---|
4728 | for (n = 0; t_tbl[n].name != 0; n++)
|
---|
4729 | *ip++ = new_item(t_tbl[n].name, "");
|
---|
4730 | *ip = (ITEM *) 0;
|
---|
4731 |
|
---|
4732 | m = new_menu(items);
|
---|
4733 |
|
---|
4734 | set_menu_format(m, 0, 2);
|
---|
4735 | scale_menu(m, &mrows, &mcols);
|
---|
4736 |
|
---|
4737 | menu_opts_off(m, O_ONEVALUE);
|
---|
4738 | menuwin = newwin(mrows + 2, mcols + 2, MENU_Y, MENU_X);
|
---|
4739 | set_menu_win(m, menuwin);
|
---|
4740 | keypad(menuwin, TRUE);
|
---|
4741 | box(menuwin, 0, 0);
|
---|
4742 |
|
---|
4743 | set_menu_sub(m, derwin(menuwin, mrows, mcols, 1, 1));
|
---|
4744 |
|
---|
4745 | post_menu(m);
|
---|
4746 |
|
---|
4747 | for (ip = menu_items(m); *ip; ip++) {
|
---|
4748 | unsigned mask = t_tbl[item_index(*ip)].mask;
|
---|
4749 | if (mask == 0)
|
---|
4750 | set_item_value(*ip, _nc_tracing == 0);
|
---|
4751 | else if ((mask & _nc_tracing) == mask)
|
---|
4752 | set_item_value(*ip, TRUE);
|
---|
4753 | }
|
---|
4754 |
|
---|
4755 | while (run_trace_menu(m))
|
---|
4756 | continue;
|
---|
4757 |
|
---|
4758 | newtrace = 0;
|
---|
4759 | for (ip = menu_items(m); *ip; ip++)
|
---|
4760 | if (item_value(*ip))
|
---|
4761 | newtrace |= t_tbl[item_index(*ip)].mask;
|
---|
4762 | trace(newtrace);
|
---|
4763 | _tracef("trace level interactively set to %s", tracetrace(_nc_tracing));
|
---|
4764 |
|
---|
4765 | (void) mvprintw(LINES - 2, 0,
|
---|
4766 | "Trace level is %s\n", tracetrace(_nc_tracing));
|
---|
4767 | (void) addstr("Press any key to continue...");
|
---|
4768 | wGetchar(stdscr);
|
---|
4769 |
|
---|
4770 | unpost_menu(m);
|
---|
4771 | delwin(menuwin);
|
---|
4772 |
|
---|
4773 | free_menu(m);
|
---|
4774 | for (ip = items; *ip; ip++)
|
---|
4775 | free_item(*ip);
|
---|
4776 | }
|
---|
4777 | #endif /* TRACE */
|
---|
4778 | #endif /* USE_LIBMENU */
|
---|
4779 |
|
---|
4780 | /****************************************************************************
|
---|
4781 | *
|
---|
4782 | * Forms test
|
---|
4783 | *
|
---|
4784 | ****************************************************************************/
|
---|
4785 | #if USE_LIBFORM
|
---|
4786 | static FIELD *
|
---|
4787 | make_label(int frow, int fcol, NCURSES_CONST char *label)
|
---|
4788 | {
|
---|
4789 | FIELD *f = new_field(1, (int) strlen(label), frow, fcol, 0, 0);
|
---|
4790 |
|
---|
4791 | if (f) {
|
---|
4792 | set_field_buffer(f, 0, label);
|
---|
4793 | set_field_opts(f, (int) (field_opts(f) & ~O_ACTIVE));
|
---|
4794 | }
|
---|
4795 | return (f);
|
---|
4796 | }
|
---|
4797 |
|
---|
4798 | static FIELD *
|
---|
4799 | make_field(int frow, int fcol, int rows, int cols, bool secure)
|
---|
4800 | {
|
---|
4801 | FIELD *f = new_field(rows, cols, frow, fcol, 0, secure ? 1 : 0);
|
---|
4802 |
|
---|
4803 | if (f) {
|
---|
4804 | set_field_back(f, A_UNDERLINE);
|
---|
4805 | set_field_userptr(f, (void *) 0);
|
---|
4806 | }
|
---|
4807 | return (f);
|
---|
4808 | }
|
---|
4809 |
|
---|
4810 | static void
|
---|
4811 | display_form(FORM * f)
|
---|
4812 | {
|
---|
4813 | WINDOW *w;
|
---|
4814 | int rows, cols;
|
---|
4815 |
|
---|
4816 | scale_form(f, &rows, &cols);
|
---|
4817 |
|
---|
4818 | if ((w = newwin(rows + 2, cols + 4, 0, 0)) != (WINDOW *) 0) {
|
---|
4819 | set_form_win(f, w);
|
---|
4820 | set_form_sub(f, derwin(w, rows, cols, 1, 2));
|
---|
4821 | box(w, 0, 0);
|
---|
4822 | keypad(w, TRUE);
|
---|
4823 | }
|
---|
4824 |
|
---|
4825 | if (post_form(f) != E_OK)
|
---|
4826 | wrefresh(w);
|
---|
4827 | }
|
---|
4828 |
|
---|
4829 | static void
|
---|
4830 | erase_form(FORM * f)
|
---|
4831 | {
|
---|
4832 | WINDOW *w = form_win(f);
|
---|
4833 | WINDOW *s = form_sub(f);
|
---|
4834 |
|
---|
4835 | unpost_form(f);
|
---|
4836 | werase(w);
|
---|
4837 | wrefresh(w);
|
---|
4838 | delwin(s);
|
---|
4839 | delwin(w);
|
---|
4840 | }
|
---|
4841 |
|
---|
4842 | static int
|
---|
4843 | edit_secure(FIELD * me, int c)
|
---|
4844 | {
|
---|
4845 | int rows, cols, frow, fcol, nrow, nbuf;
|
---|
4846 |
|
---|
4847 | if (field_info(me, &rows, &cols, &frow, &fcol, &nrow, &nbuf) == E_OK
|
---|
4848 | && nbuf > 0) {
|
---|
4849 | char temp[80];
|
---|
4850 | long len;
|
---|
4851 |
|
---|
4852 | strcpy(temp, field_buffer(me, 1));
|
---|
4853 | len = (long) (char *) field_userptr(me);
|
---|
4854 | if (c <= KEY_MAX) {
|
---|
4855 | if (isgraph(c) && (len + 1) < (int) sizeof(temp)) {
|
---|
4856 | temp[len++] = c;
|
---|
4857 | temp[len] = 0;
|
---|
4858 | set_field_buffer(me, 1, temp);
|
---|
4859 | c = '*';
|
---|
4860 | } else {
|
---|
4861 | c = 0;
|
---|
4862 | }
|
---|
4863 | } else {
|
---|
4864 | switch (c) {
|
---|
4865 | case REQ_BEG_FIELD:
|
---|
4866 | case REQ_CLR_EOF:
|
---|
4867 | case REQ_CLR_EOL:
|
---|
4868 | case REQ_DEL_LINE:
|
---|
4869 | case REQ_DEL_WORD:
|
---|
4870 | case REQ_DOWN_CHAR:
|
---|
4871 | case REQ_END_FIELD:
|
---|
4872 | case REQ_INS_CHAR:
|
---|
4873 | case REQ_INS_LINE:
|
---|
4874 | case REQ_LEFT_CHAR:
|
---|
4875 | case REQ_NEW_LINE:
|
---|
4876 | case REQ_NEXT_WORD:
|
---|
4877 | case REQ_PREV_WORD:
|
---|
4878 | case REQ_RIGHT_CHAR:
|
---|
4879 | case REQ_UP_CHAR:
|
---|
4880 | c = 0; /* we don't want to do inline editing */
|
---|
4881 | break;
|
---|
4882 | case REQ_CLR_FIELD:
|
---|
4883 | if (len) {
|
---|
4884 | temp[0] = 0;
|
---|
4885 | set_field_buffer(me, 1, temp);
|
---|
4886 | }
|
---|
4887 | break;
|
---|
4888 | case REQ_DEL_CHAR:
|
---|
4889 | case REQ_DEL_PREV:
|
---|
4890 | if (len) {
|
---|
4891 | temp[--len] = 0;
|
---|
4892 | set_field_buffer(me, 1, temp);
|
---|
4893 | }
|
---|
4894 | break;
|
---|
4895 | }
|
---|
4896 | }
|
---|
4897 | set_field_userptr(me, (void *) len);
|
---|
4898 | }
|
---|
4899 | return c;
|
---|
4900 | }
|
---|
4901 |
|
---|
4902 | static int
|
---|
4903 | form_virtualize(FORM * f, WINDOW *w)
|
---|
4904 | {
|
---|
4905 | static const struct {
|
---|
4906 | int code;
|
---|
4907 | int result;
|
---|
4908 | } lookup[] = {
|
---|
4909 | {
|
---|
4910 | CTRL('A'), REQ_NEXT_CHOICE
|
---|
4911 | },
|
---|
4912 | {
|
---|
4913 | CTRL('B'), REQ_PREV_WORD
|
---|
4914 | },
|
---|
4915 | {
|
---|
4916 | CTRL('C'), REQ_CLR_EOL
|
---|
4917 | },
|
---|
4918 | {
|
---|
4919 | CTRL('D'), REQ_DOWN_FIELD
|
---|
4920 | },
|
---|
4921 | {
|
---|
4922 | CTRL('E'), REQ_END_FIELD
|
---|
4923 | },
|
---|
4924 | {
|
---|
4925 | CTRL('F'), REQ_NEXT_PAGE
|
---|
4926 | },
|
---|
4927 | {
|
---|
4928 | CTRL('G'), REQ_DEL_WORD
|
---|
4929 | },
|
---|
4930 | {
|
---|
4931 | CTRL('H'), REQ_DEL_PREV
|
---|
4932 | },
|
---|
4933 | {
|
---|
4934 | CTRL('I'), REQ_INS_CHAR
|
---|
4935 | },
|
---|
4936 | {
|
---|
4937 | CTRL('K'), REQ_CLR_EOF
|
---|
4938 | },
|
---|
4939 | {
|
---|
4940 | CTRL('L'), REQ_LEFT_FIELD
|
---|
4941 | },
|
---|
4942 | {
|
---|
4943 | CTRL('M'), REQ_NEW_LINE
|
---|
4944 | },
|
---|
4945 | {
|
---|
4946 | CTRL('N'), REQ_NEXT_FIELD
|
---|
4947 | },
|
---|
4948 | {
|
---|
4949 | CTRL('O'), REQ_INS_LINE
|
---|
4950 | },
|
---|
4951 | {
|
---|
4952 | CTRL('P'), REQ_PREV_FIELD
|
---|
4953 | },
|
---|
4954 | {
|
---|
4955 | CTRL('R'), REQ_RIGHT_FIELD
|
---|
4956 | },
|
---|
4957 | {
|
---|
4958 | CTRL('S'), REQ_BEG_FIELD
|
---|
4959 | },
|
---|
4960 | {
|
---|
4961 | CTRL('U'), REQ_UP_FIELD
|
---|
4962 | },
|
---|
4963 | {
|
---|
4964 | CTRL('V'), REQ_DEL_CHAR
|
---|
4965 | },
|
---|
4966 | {
|
---|
4967 | CTRL('W'), REQ_NEXT_WORD
|
---|
4968 | },
|
---|
4969 | {
|
---|
4970 | CTRL('X'), REQ_CLR_FIELD
|
---|
4971 | },
|
---|
4972 | {
|
---|
4973 | CTRL('Y'), REQ_DEL_LINE
|
---|
4974 | },
|
---|
4975 | {
|
---|
4976 | CTRL('Z'), REQ_PREV_CHOICE
|
---|
4977 | },
|
---|
4978 | {
|
---|
4979 | ESCAPE, MAX_FORM_COMMAND + 1
|
---|
4980 | },
|
---|
4981 | {
|
---|
4982 | KEY_BACKSPACE, REQ_DEL_PREV
|
---|
4983 | },
|
---|
4984 | {
|
---|
4985 | KEY_DOWN, REQ_DOWN_CHAR
|
---|
4986 | },
|
---|
4987 | {
|
---|
4988 | KEY_END, REQ_LAST_FIELD
|
---|
4989 | },
|
---|
4990 | {
|
---|
4991 | KEY_HOME, REQ_FIRST_FIELD
|
---|
4992 | },
|
---|
4993 | {
|
---|
4994 | KEY_LEFT, REQ_LEFT_CHAR
|
---|
4995 | },
|
---|
4996 | {
|
---|
4997 | KEY_LL, REQ_LAST_FIELD
|
---|
4998 | },
|
---|
4999 | {
|
---|
5000 | KEY_NEXT, REQ_NEXT_FIELD
|
---|
5001 | },
|
---|
5002 | {
|
---|
5003 | KEY_NPAGE, REQ_NEXT_PAGE
|
---|
5004 | },
|
---|
5005 | {
|
---|
5006 | KEY_PPAGE, REQ_PREV_PAGE
|
---|
5007 | },
|
---|
5008 | {
|
---|
5009 | KEY_PREVIOUS, REQ_PREV_FIELD
|
---|
5010 | },
|
---|
5011 | {
|
---|
5012 | KEY_RIGHT, REQ_RIGHT_CHAR
|
---|
5013 | },
|
---|
5014 | {
|
---|
5015 | KEY_UP, REQ_UP_CHAR
|
---|
5016 | },
|
---|
5017 | {
|
---|
5018 | QUIT, MAX_FORM_COMMAND + 1
|
---|
5019 | }
|
---|
5020 | };
|
---|
5021 |
|
---|
5022 | static int mode = REQ_INS_MODE;
|
---|
5023 | int c = wGetchar(w);
|
---|
5024 | unsigned n;
|
---|
5025 | FIELD *me = current_field(f);
|
---|
5026 | bool current = TRUE;
|
---|
5027 |
|
---|
5028 | if (c == CTRL(']')) {
|
---|
5029 | if (mode == REQ_INS_MODE) {
|
---|
5030 | mode = REQ_OVL_MODE;
|
---|
5031 | } else {
|
---|
5032 | mode = REQ_INS_MODE;
|
---|
5033 | }
|
---|
5034 | c = mode;
|
---|
5035 | } else {
|
---|
5036 | for (n = 0; n < SIZEOF(lookup); n++) {
|
---|
5037 | if (lookup[n].code == c) {
|
---|
5038 | c = lookup[n].result;
|
---|
5039 | break;
|
---|
5040 | }
|
---|
5041 | }
|
---|
5042 | }
|
---|
5043 | mvprintw(0, COLS - 6, "(%s)", mode == REQ_INS_MODE ? "INS" : "OVL");
|
---|
5044 |
|
---|
5045 | /*
|
---|
5046 | * Force the field that the user is typing into to be in reverse video,
|
---|
5047 | * while the other fields are shown underlined.
|
---|
5048 | */
|
---|
5049 | switch (c) {
|
---|
5050 | case REQ_BEG_FIELD:
|
---|
5051 | case REQ_CLR_EOF:
|
---|
5052 | case REQ_CLR_EOL:
|
---|
5053 | case REQ_CLR_FIELD:
|
---|
5054 | case REQ_DEL_CHAR:
|
---|
5055 | case REQ_DEL_LINE:
|
---|
5056 | case REQ_DEL_PREV:
|
---|
5057 | case REQ_DEL_WORD:
|
---|
5058 | case REQ_END_FIELD:
|
---|
5059 | case REQ_INS_CHAR:
|
---|
5060 | case REQ_INS_LINE:
|
---|
5061 | case REQ_LEFT_CHAR:
|
---|
5062 | case REQ_LEFT_FIELD:
|
---|
5063 | case REQ_NEXT_WORD:
|
---|
5064 | case REQ_RIGHT_CHAR:
|
---|
5065 | current = TRUE;
|
---|
5066 | break;
|
---|
5067 | default:
|
---|
5068 | current = (c < KEY_MAX);
|
---|
5069 | break;
|
---|
5070 | }
|
---|
5071 | if (current) {
|
---|
5072 | c = edit_secure(me, c);
|
---|
5073 | set_field_back(me, A_REVERSE);
|
---|
5074 | } else {
|
---|
5075 | c = edit_secure(me, c);
|
---|
5076 | set_field_back(me, A_UNDERLINE);
|
---|
5077 | }
|
---|
5078 | return c;
|
---|
5079 | }
|
---|
5080 |
|
---|
5081 | static int
|
---|
5082 | my_form_driver(FORM * form, int c)
|
---|
5083 | {
|
---|
5084 | if (c == (MAX_FORM_COMMAND + 1)
|
---|
5085 | && form_driver(form, REQ_VALIDATION) == E_OK)
|
---|
5086 | return (TRUE);
|
---|
5087 | else {
|
---|
5088 | beep();
|
---|
5089 | return (FALSE);
|
---|
5090 | }
|
---|
5091 | }
|
---|
5092 |
|
---|
5093 | /*
|
---|
5094 | * Allow a middle initial, optionally with a '.' to end it.
|
---|
5095 | */
|
---|
5096 | static bool
|
---|
5097 | mi_field_check(FIELD * fld, const void *data GCC_UNUSED)
|
---|
5098 | {
|
---|
5099 | char *s = field_buffer(fld, 0);
|
---|
5100 | int state = 0;
|
---|
5101 | int n;
|
---|
5102 |
|
---|
5103 | for (n = 0; s[n] != '\0'; ++n) {
|
---|
5104 | switch (state) {
|
---|
5105 | case 0:
|
---|
5106 | if (s[n] == '.') {
|
---|
5107 | if (n != 1)
|
---|
5108 | return FALSE;
|
---|
5109 | state = 2;
|
---|
5110 | } else if (isspace(UChar(s[n]))) {
|
---|
5111 | state = 2;
|
---|
5112 | }
|
---|
5113 | break;
|
---|
5114 | case 2:
|
---|
5115 | if (!isspace(UChar(s[n])))
|
---|
5116 | return FALSE;
|
---|
5117 | break;
|
---|
5118 | }
|
---|
5119 | }
|
---|
5120 |
|
---|
5121 | /* force the form to display a leading capital */
|
---|
5122 | if (islower(UChar(s[0]))) {
|
---|
5123 | s[0] = toupper(UChar(s[0]));
|
---|
5124 | set_field_buffer(fld, 0, s);
|
---|
5125 | }
|
---|
5126 | return TRUE;
|
---|
5127 | }
|
---|
5128 |
|
---|
5129 | static bool
|
---|
5130 | mi_char_check(int ch, const void *data GCC_UNUSED)
|
---|
5131 | {
|
---|
5132 | return ((isalpha(ch) || ch == '.') ? TRUE : FALSE);
|
---|
5133 | }
|
---|
5134 |
|
---|
5135 | /*
|
---|
5136 | * Passwords should be at least 6 characters.
|
---|
5137 | */
|
---|
5138 | static bool
|
---|
5139 | pw_field_check(FIELD * fld, const void *data GCC_UNUSED)
|
---|
5140 | {
|
---|
5141 | char *s = field_buffer(fld, 0);
|
---|
5142 | int n;
|
---|
5143 |
|
---|
5144 | for (n = 0; s[n] != '\0'; ++n) {
|
---|
5145 | if (isspace(UChar(s[n]))) {
|
---|
5146 | if (n < 6)
|
---|
5147 | return FALSE;
|
---|
5148 | }
|
---|
5149 | }
|
---|
5150 | return TRUE;
|
---|
5151 | }
|
---|
5152 |
|
---|
5153 | static bool
|
---|
5154 | pw_char_check(int ch, const void *data GCC_UNUSED)
|
---|
5155 | {
|
---|
5156 | return (isgraph(ch) ? TRUE : FALSE);
|
---|
5157 | }
|
---|
5158 |
|
---|
5159 | static void
|
---|
5160 | demo_forms(void)
|
---|
5161 | {
|
---|
5162 | WINDOW *w;
|
---|
5163 | FORM *form;
|
---|
5164 | FIELD *f[12], *secure;
|
---|
5165 | FIELDTYPE *fty_middle = new_fieldtype(mi_field_check, mi_char_check);
|
---|
5166 | FIELDTYPE *fty_passwd = new_fieldtype(pw_field_check, pw_char_check);
|
---|
5167 | int finished = 0, c;
|
---|
5168 | unsigned n = 0;
|
---|
5169 |
|
---|
5170 | move(18, 0);
|
---|
5171 | addstr("Defined edit/traversal keys: ^Q/ESC- exit form\n");
|
---|
5172 | addstr("^N -- go to next field ^P -- go to previous field\n");
|
---|
5173 | addstr("Home -- go to first field End -- go to last field\n");
|
---|
5174 | addstr("^L -- go to field to left ^R -- go to field to right\n");
|
---|
5175 | addstr("^U -- move upward to field ^D -- move downward to field\n");
|
---|
5176 | addstr("^W -- go to next word ^B -- go to previous word\n");
|
---|
5177 | addstr("^S -- go to start of field ^E -- go to end of field\n");
|
---|
5178 | addstr("^H -- delete previous char ^Y -- delete line\n");
|
---|
5179 | addstr("^G -- delete current word ^C -- clear to end of line\n");
|
---|
5180 | addstr("^K -- clear to end of field ^X -- clear field\n");
|
---|
5181 | addstr("Arrow keys move within a field as you would expect. ^] toggles overlay mode.");
|
---|
5182 |
|
---|
5183 | mvaddstr(4, 57, "Forms Entry Test");
|
---|
5184 |
|
---|
5185 | refresh();
|
---|
5186 |
|
---|
5187 | /* describe the form */
|
---|
5188 | f[n++] = make_label(0, 15, "Sample Form");
|
---|
5189 |
|
---|
5190 | f[n++] = make_label(2, 0, "Last Name");
|
---|
5191 | f[n++] = make_field(3, 0, 1, 18, FALSE);
|
---|
5192 | set_field_type(f[n - 1], TYPE_ALPHA, 1);
|
---|
5193 |
|
---|
5194 | f[n++] = make_label(2, 20, "First Name");
|
---|
5195 | f[n++] = make_field(3, 20, 1, 12, FALSE);
|
---|
5196 | set_field_type(f[n - 1], TYPE_ALPHA, 1);
|
---|
5197 |
|
---|
5198 | f[n++] = make_label(2, 34, "Middle Name");
|
---|
5199 | f[n++] = make_field(3, 34, 1, 12, FALSE);
|
---|
5200 | set_field_type(f[n - 1], fty_middle);
|
---|
5201 |
|
---|
5202 | f[n++] = make_label(5, 0, "Comments");
|
---|
5203 | f[n++] = make_field(6, 0, 4, 46, FALSE);
|
---|
5204 |
|
---|
5205 | f[n++] = make_label(5, 20, "Password:");
|
---|
5206 | secure =
|
---|
5207 | f[n++] = make_field(5, 30, 1, 9, TRUE);
|
---|
5208 | set_field_type(f[n - 1], fty_passwd);
|
---|
5209 | f[n++] = (FIELD *) 0;
|
---|
5210 |
|
---|
5211 | form = new_form(f);
|
---|
5212 |
|
---|
5213 | display_form(form);
|
---|
5214 |
|
---|
5215 | w = form_win(form);
|
---|
5216 | raw();
|
---|
5217 | nonl(); /* lets us read ^M's */
|
---|
5218 | while (!finished) {
|
---|
5219 | switch (form_driver(form, c = form_virtualize(form, w))) {
|
---|
5220 | case E_OK:
|
---|
5221 | mvaddstr(5, 57, field_buffer(secure, 1));
|
---|
5222 | clrtoeol();
|
---|
5223 | refresh();
|
---|
5224 | break;
|
---|
5225 | case E_UNKNOWN_COMMAND:
|
---|
5226 | finished = my_form_driver(form, c);
|
---|
5227 | break;
|
---|
5228 | default:
|
---|
5229 | beep();
|
---|
5230 | break;
|
---|
5231 | }
|
---|
5232 | }
|
---|
5233 |
|
---|
5234 | erase_form(form);
|
---|
5235 |
|
---|
5236 | free_form(form);
|
---|
5237 | for (c = 0; f[c] != 0; c++)
|
---|
5238 | free_field(f[c]);
|
---|
5239 | free_fieldtype(fty_middle);
|
---|
5240 | free_fieldtype(fty_passwd);
|
---|
5241 | noraw();
|
---|
5242 | nl();
|
---|
5243 | }
|
---|
5244 | #endif /* USE_LIBFORM */
|
---|
5245 |
|
---|
5246 | /****************************************************************************
|
---|
5247 | *
|
---|
5248 | * Overlap test
|
---|
5249 | *
|
---|
5250 | ****************************************************************************/
|
---|
5251 |
|
---|
5252 | static void
|
---|
5253 | fillwin(WINDOW *win, char ch)
|
---|
5254 | {
|
---|
5255 | int y, x;
|
---|
5256 | int y1, x1;
|
---|
5257 |
|
---|
5258 | getmaxyx(win, y1, x1);
|
---|
5259 | for (y = 0; y < y1; y++) {
|
---|
5260 | wmove(win, y, 0);
|
---|
5261 | for (x = 0; x < x1; x++)
|
---|
5262 | waddch(win, UChar(ch));
|
---|
5263 | }
|
---|
5264 | }
|
---|
5265 |
|
---|
5266 | static void
|
---|
5267 | crosswin(WINDOW *win, char ch)
|
---|
5268 | {
|
---|
5269 | int y, x;
|
---|
5270 | int y1, x1;
|
---|
5271 |
|
---|
5272 | getmaxyx(win, y1, x1);
|
---|
5273 | for (y = 0; y < y1; y++) {
|
---|
5274 | for (x = 0; x < x1; x++)
|
---|
5275 | if (((x > (x1 - 1) / 3) && (x <= (2 * (x1 - 1)) / 3))
|
---|
5276 | || (((y > (y1 - 1) / 3) && (y <= (2 * (y1 - 1)) / 3)))) {
|
---|
5277 | wmove(win, y, x);
|
---|
5278 | waddch(win, UChar(ch));
|
---|
5279 | }
|
---|
5280 | }
|
---|
5281 | }
|
---|
5282 |
|
---|
5283 | static void
|
---|
5284 | overlap_test(void)
|
---|
5285 | /* test effects of overlapping windows */
|
---|
5286 | {
|
---|
5287 | int ch;
|
---|
5288 |
|
---|
5289 | WINDOW *win1 = newwin(9, 20, 3, 3);
|
---|
5290 | WINDOW *win2 = newwin(9, 20, 9, 16);
|
---|
5291 |
|
---|
5292 | raw();
|
---|
5293 | refresh();
|
---|
5294 | move(0, 0);
|
---|
5295 | printw("This test shows the behavior of wnoutrefresh() with respect to\n");
|
---|
5296 | printw("the shared region of two overlapping windows A and B. The cross\n");
|
---|
5297 | printw("pattern in each window does not overlap the other.\n");
|
---|
5298 |
|
---|
5299 | move(18, 0);
|
---|
5300 | printw("a = refresh A, then B, then doupdate. b = refresh B, then A, then doupdaute\n");
|
---|
5301 | printw("c = fill window A with letter A. d = fill window B with letter B.\n");
|
---|
5302 | printw("e = cross pattern in window A. f = cross pattern in window B.\n");
|
---|
5303 | printw("g = clear window A. h = clear window B.\n");
|
---|
5304 | printw("i = overwrite A onto B. j = overwrite B onto A.\n");
|
---|
5305 | printw("^Q/ESC = terminate test.");
|
---|
5306 |
|
---|
5307 | while ((ch = Getchar()) != QUIT && ch != ESCAPE)
|
---|
5308 | switch (ch) {
|
---|
5309 | case 'a': /* refresh window A first, then B */
|
---|
5310 | wnoutrefresh(win1);
|
---|
5311 | wnoutrefresh(win2);
|
---|
5312 | doupdate();
|
---|
5313 | break;
|
---|
5314 |
|
---|
5315 | case 'b': /* refresh window B first, then A */
|
---|
5316 | wnoutrefresh(win2);
|
---|
5317 | wnoutrefresh(win1);
|
---|
5318 | doupdate();
|
---|
5319 | break;
|
---|
5320 |
|
---|
5321 | case 'c': /* fill window A so it's visible */
|
---|
5322 | fillwin(win1, 'A');
|
---|
5323 | break;
|
---|
5324 |
|
---|
5325 | case 'd': /* fill window B so it's visible */
|
---|
5326 | fillwin(win2, 'B');
|
---|
5327 | break;
|
---|
5328 |
|
---|
5329 | case 'e': /* cross test pattern in window A */
|
---|
5330 | crosswin(win1, 'A');
|
---|
5331 | break;
|
---|
5332 |
|
---|
5333 | case 'f': /* cross test pattern in window A */
|
---|
5334 | crosswin(win2, 'B');
|
---|
5335 | break;
|
---|
5336 |
|
---|
5337 | case 'g': /* clear window A */
|
---|
5338 | wclear(win1);
|
---|
5339 | wmove(win1, 0, 0);
|
---|
5340 | break;
|
---|
5341 |
|
---|
5342 | case 'h': /* clear window B */
|
---|
5343 | wclear(win2);
|
---|
5344 | wmove(win2, 0, 0);
|
---|
5345 | break;
|
---|
5346 |
|
---|
5347 | case 'i': /* overwrite A onto B */
|
---|
5348 | overwrite(win1, win2);
|
---|
5349 | break;
|
---|
5350 |
|
---|
5351 | case 'j': /* overwrite B onto A */
|
---|
5352 | overwrite(win2, win1);
|
---|
5353 | break;
|
---|
5354 | }
|
---|
5355 |
|
---|
5356 | delwin(win2);
|
---|
5357 | delwin(win1);
|
---|
5358 | erase();
|
---|
5359 | endwin();
|
---|
5360 | }
|
---|
5361 |
|
---|
5362 | /****************************************************************************
|
---|
5363 | *
|
---|
5364 | * Main sequence
|
---|
5365 | *
|
---|
5366 | ****************************************************************************/
|
---|
5367 |
|
---|
5368 | static bool
|
---|
5369 | do_single_test(const char c)
|
---|
5370 | /* perform a single specified test */
|
---|
5371 | {
|
---|
5372 | switch (c) {
|
---|
5373 | case 'a':
|
---|
5374 | getch_test();
|
---|
5375 | break;
|
---|
5376 |
|
---|
5377 | #if USE_WIDEC_SUPPORT
|
---|
5378 | case 'A':
|
---|
5379 | get_wch_test();
|
---|
5380 | break;
|
---|
5381 | #endif
|
---|
5382 |
|
---|
5383 | case 'b':
|
---|
5384 | attr_test();
|
---|
5385 | break;
|
---|
5386 |
|
---|
5387 | #if USE_WIDEC_SUPPORT
|
---|
5388 | case 'B':
|
---|
5389 | wide_attr_test();
|
---|
5390 | break;
|
---|
5391 | #endif
|
---|
5392 |
|
---|
5393 | case 'c':
|
---|
5394 | if (!has_colors())
|
---|
5395 | Cannot("does not support color.");
|
---|
5396 | else
|
---|
5397 | color_test();
|
---|
5398 | break;
|
---|
5399 |
|
---|
5400 | #if USE_WIDEC_SUPPORT
|
---|
5401 | case 'C':
|
---|
5402 | if (!has_colors())
|
---|
5403 | Cannot("does not support color.");
|
---|
5404 | else
|
---|
5405 | wide_color_test();
|
---|
5406 | break;
|
---|
5407 | #endif
|
---|
5408 |
|
---|
5409 | case 'd':
|
---|
5410 | if (!has_colors())
|
---|
5411 | Cannot("does not support color.");
|
---|
5412 | else if (!can_change_color())
|
---|
5413 | Cannot("has hardwired color values.");
|
---|
5414 | else
|
---|
5415 | color_edit();
|
---|
5416 | break;
|
---|
5417 |
|
---|
5418 | case 'e':
|
---|
5419 | slk_test();
|
---|
5420 | break;
|
---|
5421 |
|
---|
5422 | #if USE_WIDEC_SUPPORT
|
---|
5423 | case 'E':
|
---|
5424 | wide_slk_test();
|
---|
5425 | break;
|
---|
5426 | #endif
|
---|
5427 | case 'f':
|
---|
5428 | acs_display();
|
---|
5429 | break;
|
---|
5430 |
|
---|
5431 | #if USE_WIDEC_SUPPORT
|
---|
5432 | case 'F':
|
---|
5433 | wide_acs_display();
|
---|
5434 | break;
|
---|
5435 | #endif
|
---|
5436 |
|
---|
5437 | #if USE_LIBPANEL
|
---|
5438 | case 'o':
|
---|
5439 | demo_panels();
|
---|
5440 | break;
|
---|
5441 | #endif
|
---|
5442 |
|
---|
5443 | case 'g':
|
---|
5444 | acs_and_scroll();
|
---|
5445 | break;
|
---|
5446 |
|
---|
5447 | case 'i':
|
---|
5448 | flushinp_test(stdscr);
|
---|
5449 | break;
|
---|
5450 |
|
---|
5451 | case 'k':
|
---|
5452 | test_sgr_attributes();
|
---|
5453 | break;
|
---|
5454 |
|
---|
5455 | #if USE_LIBMENU
|
---|
5456 | case 'm':
|
---|
5457 | menu_test();
|
---|
5458 | break;
|
---|
5459 | #endif
|
---|
5460 |
|
---|
5461 | #if USE_LIBPANEL
|
---|
5462 | case 'p':
|
---|
5463 | demo_pad();
|
---|
5464 | break;
|
---|
5465 | #endif
|
---|
5466 |
|
---|
5467 | #if USE_LIBFORM
|
---|
5468 | case 'r':
|
---|
5469 | demo_forms();
|
---|
5470 | break;
|
---|
5471 | #endif
|
---|
5472 |
|
---|
5473 | case 's':
|
---|
5474 | overlap_test();
|
---|
5475 | break;
|
---|
5476 |
|
---|
5477 | #if USE_LIBMENU && defined(TRACE)
|
---|
5478 | case 't':
|
---|
5479 | trace_set();
|
---|
5480 | break;
|
---|
5481 | #endif
|
---|
5482 |
|
---|
5483 | case '?':
|
---|
5484 | break;
|
---|
5485 |
|
---|
5486 | default:
|
---|
5487 | return FALSE;
|
---|
5488 | }
|
---|
5489 |
|
---|
5490 | return TRUE;
|
---|
5491 | }
|
---|
5492 |
|
---|
5493 | static void
|
---|
5494 | usage(void)
|
---|
5495 | {
|
---|
5496 | static const char *const tbl[] =
|
---|
5497 | {
|
---|
5498 | "Usage: ncurses [options]"
|
---|
5499 | ,""
|
---|
5500 | ,"Options:"
|
---|
5501 | #ifdef NCURSES_VERSION
|
---|
5502 | ," -a f,b set default-colors (assumed white-on-black)"
|
---|
5503 | ," -d use default-colors if terminal supports them"
|
---|
5504 | #endif
|
---|
5505 | ," -e fmt specify format for soft-keys test (e)"
|
---|
5506 | ," -f rip-off footer line (can repeat)"
|
---|
5507 | ," -h rip-off header line (can repeat)"
|
---|
5508 | ," -p file rgb values to use in 'd' rather than ncurses's builtin"
|
---|
5509 | #if USE_LIBPANEL
|
---|
5510 | ," -s msec specify nominal time for panel-demo (default: 1, to hold)"
|
---|
5511 | #endif
|
---|
5512 | #ifdef TRACE
|
---|
5513 | ," -t mask specify default trace-level (may toggle with ^T)"
|
---|
5514 | #endif
|
---|
5515 | };
|
---|
5516 | size_t n;
|
---|
5517 | for (n = 0; n < SIZEOF(tbl); n++)
|
---|
5518 | fprintf(stderr, "%s\n", tbl[n]);
|
---|
5519 | ExitProgram(EXIT_FAILURE);
|
---|
5520 | }
|
---|
5521 |
|
---|
5522 | static void
|
---|
5523 | set_terminal_modes(void)
|
---|
5524 | {
|
---|
5525 | noraw();
|
---|
5526 | cbreak();
|
---|
5527 | noecho();
|
---|
5528 | scrollok(stdscr, TRUE);
|
---|
5529 | idlok(stdscr, TRUE);
|
---|
5530 | keypad(stdscr, TRUE);
|
---|
5531 | }
|
---|
5532 |
|
---|
5533 | #ifdef SIGUSR1
|
---|
5534 | static RETSIGTYPE
|
---|
5535 | announce_sig(int sig)
|
---|
5536 | {
|
---|
5537 | (void) fprintf(stderr, "Handled signal %d\r\n", sig);
|
---|
5538 | }
|
---|
5539 | #endif
|
---|
5540 |
|
---|
5541 | static int
|
---|
5542 | rip_footer(WINDOW *win, int cols)
|
---|
5543 | {
|
---|
5544 | wbkgd(win, A_REVERSE);
|
---|
5545 | werase(win);
|
---|
5546 | wmove(win, 0, 0);
|
---|
5547 | wprintw(win, "footer: %d columns", cols);
|
---|
5548 | wnoutrefresh(win);
|
---|
5549 | return OK;
|
---|
5550 | }
|
---|
5551 |
|
---|
5552 | static int
|
---|
5553 | rip_header(WINDOW *win, int cols)
|
---|
5554 | {
|
---|
5555 | wbkgd(win, A_REVERSE);
|
---|
5556 | werase(win);
|
---|
5557 | wmove(win, 0, 0);
|
---|
5558 | wprintw(win, "header: %d columns", cols);
|
---|
5559 | wnoutrefresh(win);
|
---|
5560 | return OK;
|
---|
5561 | }
|
---|
5562 |
|
---|
5563 | static void
|
---|
5564 | main_menu(bool top)
|
---|
5565 | {
|
---|
5566 | int command;
|
---|
5567 |
|
---|
5568 | do {
|
---|
5569 | (void) puts("This is the ncurses main menu");
|
---|
5570 | (void) puts("a = keyboard and mouse input test");
|
---|
5571 | #if USE_WIDEC_SUPPORT
|
---|
5572 | (void) puts("A = wide-character keyboard and mouse input test");
|
---|
5573 | #endif
|
---|
5574 | (void) puts("b = character attribute test");
|
---|
5575 | #if USE_WIDEC_SUPPORT
|
---|
5576 | (void) puts("B = wide-character attribute test");
|
---|
5577 | #endif
|
---|
5578 | (void) puts("c = color test pattern");
|
---|
5579 | #if USE_WIDEC_SUPPORT
|
---|
5580 | (void) puts("C = color test pattern using wide-character calls");
|
---|
5581 | #endif
|
---|
5582 | if (top)
|
---|
5583 | (void) puts("d = edit RGB color values");
|
---|
5584 | (void) puts("e = exercise soft keys");
|
---|
5585 | #if USE_WIDEC_SUPPORT
|
---|
5586 | (void) puts("E = exercise soft keys using wide-characters");
|
---|
5587 | #endif
|
---|
5588 | (void) puts("f = display ACS characters");
|
---|
5589 | #if USE_WIDEC_SUPPORT
|
---|
5590 | (void) puts("F = display Wide-ACS characters");
|
---|
5591 | #endif
|
---|
5592 | (void) puts("g = display windows and scrolling");
|
---|
5593 | (void) puts("i = test of flushinp()");
|
---|
5594 | (void) puts("k = display character attributes");
|
---|
5595 | #if USE_LIBMENU
|
---|
5596 | (void) puts("m = menu code test");
|
---|
5597 | #endif
|
---|
5598 | #if USE_LIBPANEL
|
---|
5599 | (void) puts("o = exercise panels library");
|
---|
5600 | (void) puts("p = exercise pad features");
|
---|
5601 | (void) puts("q = quit");
|
---|
5602 | #endif
|
---|
5603 | #if USE_LIBFORM
|
---|
5604 | (void) puts("r = exercise forms code");
|
---|
5605 | #endif
|
---|
5606 | (void) puts("s = overlapping-refresh test");
|
---|
5607 | #if USE_LIBMENU && defined(TRACE)
|
---|
5608 | (void) puts("t = set trace level");
|
---|
5609 | #endif
|
---|
5610 | (void) puts("? = repeat this command summary");
|
---|
5611 |
|
---|
5612 | (void) fputs("> ", stdout);
|
---|
5613 | (void) fflush(stdout); /* necessary under SVr4 curses */
|
---|
5614 |
|
---|
5615 | /*
|
---|
5616 | * This used to be an 'fgets()' call. However (on Linux, at least)
|
---|
5617 | * mixing stream I/O and 'read()' (used in the library) causes the
|
---|
5618 | * input stream to be flushed when switching between the two.
|
---|
5619 | */
|
---|
5620 | command = 0;
|
---|
5621 | for (;;) {
|
---|
5622 | char ch;
|
---|
5623 | if (read(fileno(stdin), &ch, 1) <= 0) {
|
---|
5624 | if (command == 0)
|
---|
5625 | command = 'q';
|
---|
5626 | break;
|
---|
5627 | } else if (command == 0 && !isspace(UChar(ch))) {
|
---|
5628 | command = ch;
|
---|
5629 | } else if (ch == '\n' || ch == '\r') {
|
---|
5630 | if ((command == 'd') && !top) {
|
---|
5631 | (void) fputs("Do not nest test-d\n", stdout);
|
---|
5632 | command = 0;
|
---|
5633 | }
|
---|
5634 | if (command != 0)
|
---|
5635 | break;
|
---|
5636 | (void) fputs("> ", stdout);
|
---|
5637 | (void) fflush(stdout);
|
---|
5638 | }
|
---|
5639 | }
|
---|
5640 |
|
---|
5641 | if (do_single_test(command)) {
|
---|
5642 | /*
|
---|
5643 | * This may be overkill; it's intended to reset everything back
|
---|
5644 | * to the initial terminal modes so that tests don't get in
|
---|
5645 | * each other's way.
|
---|
5646 | */
|
---|
5647 | flushinp();
|
---|
5648 | set_terminal_modes();
|
---|
5649 | reset_prog_mode();
|
---|
5650 | clear();
|
---|
5651 | refresh();
|
---|
5652 | endwin();
|
---|
5653 | if (command == '?') {
|
---|
5654 | (void) puts("This is the ncurses capability tester.");
|
---|
5655 | (void)
|
---|
5656 | puts("You may select a test from the main menu by typing the");
|
---|
5657 | (void)
|
---|
5658 | puts("key letter of the choice (the letter to left of the =)");
|
---|
5659 | (void)
|
---|
5660 | puts("at the > prompt. The commands `x' or `q' will exit.");
|
---|
5661 | }
|
---|
5662 | continue;
|
---|
5663 | }
|
---|
5664 | } while
|
---|
5665 | (command != 'q');
|
---|
5666 | }
|
---|
5667 |
|
---|
5668 | /*+-------------------------------------------------------------------------
|
---|
5669 | main(argc,argv)
|
---|
5670 | --------------------------------------------------------------------------*/
|
---|
5671 |
|
---|
5672 | #define okCOLOR(n) ((n) >= 0 && (n) < max_colors)
|
---|
5673 | #define okRGB(n) ((n) >= 0 && (n) <= 1000)
|
---|
5674 |
|
---|
5675 | int
|
---|
5676 | main(int argc, char *argv[])
|
---|
5677 | {
|
---|
5678 | int c;
|
---|
5679 | int my_e_param = 1;
|
---|
5680 | #ifdef NCURSES_VERSION
|
---|
5681 | int default_fg = COLOR_WHITE;
|
---|
5682 | int default_bg = COLOR_BLACK;
|
---|
5683 | bool assumed_colors = FALSE;
|
---|
5684 | bool default_colors = FALSE;
|
---|
5685 | #endif
|
---|
5686 | char *palette_file = 0;
|
---|
5687 |
|
---|
5688 | setlocale(LC_ALL, "");
|
---|
5689 |
|
---|
5690 | while ((c = getopt(argc, argv, "a:de:fhp:s:t:")) != EOF) {
|
---|
5691 | switch (c) {
|
---|
5692 | #ifdef NCURSES_VERSION
|
---|
5693 | case 'a':
|
---|
5694 | assumed_colors = TRUE;
|
---|
5695 | sscanf(optarg, "%d,%d", &default_fg, &default_bg);
|
---|
5696 | break;
|
---|
5697 | case 'd':
|
---|
5698 | default_colors = TRUE;
|
---|
5699 | break;
|
---|
5700 | #endif
|
---|
5701 | case 'e':
|
---|
5702 | my_e_param = atoi(optarg);
|
---|
5703 | #ifdef NCURSES_VERSION
|
---|
5704 | if (my_e_param > 3) /* allow extended layouts */
|
---|
5705 | usage();
|
---|
5706 | #else
|
---|
5707 | if (my_e_param > 1)
|
---|
5708 | usage();
|
---|
5709 | #endif
|
---|
5710 | break;
|
---|
5711 | case 'f':
|
---|
5712 | ripoffline(-1, rip_footer);
|
---|
5713 | break;
|
---|
5714 | case 'h':
|
---|
5715 | ripoffline(1, rip_header);
|
---|
5716 | break;
|
---|
5717 | case 'p':
|
---|
5718 | palette_file = optarg;
|
---|
5719 | break;
|
---|
5720 | #if USE_LIBPANEL
|
---|
5721 | case 's':
|
---|
5722 | nap_msec = atol(optarg);
|
---|
5723 | break;
|
---|
5724 | #endif
|
---|
5725 | #ifdef TRACE
|
---|
5726 | case 't':
|
---|
5727 | save_trace = strtol(optarg, 0, 0);
|
---|
5728 | break;
|
---|
5729 | #endif
|
---|
5730 | default:
|
---|
5731 | usage();
|
---|
5732 | }
|
---|
5733 | }
|
---|
5734 |
|
---|
5735 | /*
|
---|
5736 | * If there's no menus (unlikely for ncurses!), then we'll have to set
|
---|
5737 | * tracing on initially, just in case the user wants to test something that
|
---|
5738 | * doesn't involve wGetchar.
|
---|
5739 | */
|
---|
5740 | #ifdef TRACE
|
---|
5741 | /* enable debugging */
|
---|
5742 | #if !USE_LIBMENU
|
---|
5743 | trace(save_trace);
|
---|
5744 | #else
|
---|
5745 | if (!isatty(fileno(stdin)))
|
---|
5746 | trace(save_trace);
|
---|
5747 | #endif /* USE_LIBMENU */
|
---|
5748 | #endif /* TRACE */
|
---|
5749 |
|
---|
5750 | /* tell it we're going to play with soft keys */
|
---|
5751 | slk_init(my_e_param);
|
---|
5752 |
|
---|
5753 | #ifdef SIGUSR1
|
---|
5754 | /* set up null signal catcher so we can see what interrupts to getch do */
|
---|
5755 | signal(SIGUSR1, announce_sig);
|
---|
5756 | #endif
|
---|
5757 |
|
---|
5758 | /* we must initialize the curses data structure only once */
|
---|
5759 | initscr();
|
---|
5760 | bkgdset(BLANK);
|
---|
5761 |
|
---|
5762 | /* tests, in general, will want these modes */
|
---|
5763 | if (has_colors()) {
|
---|
5764 | start_color();
|
---|
5765 | #ifdef NCURSES_VERSION_PATCH
|
---|
5766 | max_colors = COLORS; /* was > 16 ? 16 : COLORS */
|
---|
5767 | #if HAVE_USE_DEFAULT_COLORS
|
---|
5768 | if (default_colors) {
|
---|
5769 | use_default_colors();
|
---|
5770 | min_colors = -1;
|
---|
5771 | }
|
---|
5772 | #if NCURSES_VERSION_PATCH >= 20000708
|
---|
5773 | else if (assumed_colors)
|
---|
5774 | assume_default_colors(default_fg, default_bg);
|
---|
5775 | #endif
|
---|
5776 | #endif
|
---|
5777 | #else /* normal SVr4 curses */
|
---|
5778 | max_colors = COLORS; /* was > 8 ? 8 : COLORS */
|
---|
5779 | #endif
|
---|
5780 | max_pairs = COLOR_PAIRS; /* was > 256 ? 256 : COLOR_PAIRS */
|
---|
5781 |
|
---|
5782 | if (can_change_color()) {
|
---|
5783 | all_colors = (RGB_DATA *) malloc(max_colors * sizeof(RGB_DATA));
|
---|
5784 | for (c = 0; c < max_colors; ++c) {
|
---|
5785 | color_content(c,
|
---|
5786 | &all_colors[c].red,
|
---|
5787 | &all_colors[c].green,
|
---|
5788 | &all_colors[c].blue);
|
---|
5789 | }
|
---|
5790 | if (palette_file != 0) {
|
---|
5791 | FILE *fp = fopen(palette_file, "r");
|
---|
5792 | if (fp != 0) {
|
---|
5793 | char buffer[BUFSIZ];
|
---|
5794 | int red, green, blue;
|
---|
5795 | int scale = 1000;
|
---|
5796 | while (fgets(buffer, sizeof(buffer), fp) != 0) {
|
---|
5797 | if (sscanf(buffer, "scale:%d", &c) == 1) {
|
---|
5798 | scale = c;
|
---|
5799 | } else if (sscanf(buffer, "%d:%d %d %d",
|
---|
5800 | &c,
|
---|
5801 | &red,
|
---|
5802 | &green,
|
---|
5803 | &blue) == 4
|
---|
5804 | && okCOLOR(c)
|
---|
5805 | && okRGB(red)
|
---|
5806 | && okRGB(green)
|
---|
5807 | && okRGB(blue)) {
|
---|
5808 | all_colors[c].red = (red * 1000) / scale;
|
---|
5809 | all_colors[c].green = (green * 1000) / scale;
|
---|
5810 | all_colors[c].blue = (blue * 1000) / scale;
|
---|
5811 | }
|
---|
5812 | }
|
---|
5813 | fclose(fp);
|
---|
5814 | }
|
---|
5815 | }
|
---|
5816 | }
|
---|
5817 | }
|
---|
5818 | set_terminal_modes();
|
---|
5819 | def_prog_mode();
|
---|
5820 |
|
---|
5821 | /*
|
---|
5822 | * Return to terminal mode, so we're guaranteed of being able to
|
---|
5823 | * select terminal commands even if the capabilities are wrong.
|
---|
5824 | */
|
---|
5825 | endwin();
|
---|
5826 |
|
---|
5827 | #if HAVE_CURSES_VERSION
|
---|
5828 | (void) printf("Welcome to %s. Press ? for help.\n", curses_version());
|
---|
5829 | #elif defined(NCURSES_VERSION_MAJOR) && defined(NCURSES_VERSION_MINOR) && defined(NCURSES_VERSION_PATCH)
|
---|
5830 | (void) printf("Welcome to ncurses %d.%d.%d. Press ? for help.\n",
|
---|
5831 | NCURSES_VERSION_MAJOR,
|
---|
5832 | NCURSES_VERSION_MINOR,
|
---|
5833 | NCURSES_VERSION_PATCH);
|
---|
5834 | #else
|
---|
5835 | (void) puts("Welcome to ncurses. Press ? for help.");
|
---|
5836 | #endif
|
---|
5837 |
|
---|
5838 | main_menu(TRUE);
|
---|
5839 |
|
---|
5840 | ExitProgram(EXIT_SUCCESS);
|
---|
5841 | }
|
---|
5842 |
|
---|
5843 | /* ncurses.c ends here */
|
---|