1 /****************************************************************************
2 * Copyright (c) 1998-2010,2011 Free Software Foundation, Inc. *
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: *
12 * The above copyright notice and this permission notice shall be included *
13 * in all copies or substantial portions of the Software. *
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. *
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 *
27 ****************************************************************************/
28 /****************************************************************************
31 ncurses.c --- ncurses library exerciser
37 An interactive test module for the ncurses library.
40 Author: Eric S. Raymond <esr@snark.thyrsus.com> 1993
41 Thomas E. Dickey (beginning revision 1.27 in 1996).
43 $Id: ncurses.c,v 1.365 2011/01/22 19:48:33 tom Exp $
45 ***************************************************************************/
47 #include <test.priv.h>
50 #undef mvwdelch /* HPUX 11.23 macro will not compile */
54 #if HAVE_SYS_TIME_H && HAVE_SYS_TIME_SELECT
58 #include <sys/select.h>
74 #ifdef NCURSES_VERSION
76 #define NCURSES_CONST_PARAM const void
79 static unsigned save_trace
= TRACE_ORDINARY
| TRACE_ICALLS
| TRACE_CALLS
;
80 extern unsigned _nc_tracing
;
85 #define NCURSES_CONST_PARAM char
87 #define mmask_t chtype /* not specified in XSI */
90 #ifdef CURSES_ACS_ARRAY
91 #define ACS_S3 (CURSES_ACS_ARRAY['p']) /* scan line 3 */
92 #define ACS_S7 (CURSES_ACS_ARRAY['r']) /* scan line 7 */
93 #define ACS_LEQUAL (CURSES_ACS_ARRAY['y']) /* less/equal */
94 #define ACS_GEQUAL (CURSES_ACS_ARRAY['z']) /* greater/equal */
95 #define ACS_PI (CURSES_ACS_ARRAY['{']) /* Pi */
96 #define ACS_NEQUAL (CURSES_ACS_ARRAY['|']) /* not equal */
97 #define ACS_STERLING (CURSES_ACS_ARRAY['}']) /* UK pound sign */
99 #define ACS_S3 (A_ALTCHARSET + 'p') /* scan line 3 */
100 #define ACS_S7 (A_ALTCHARSET + 'r') /* scan line 7 */
101 #define ACS_LEQUAL (A_ALTCHARSET + 'y') /* less/equal */
102 #define ACS_GEQUAL (A_ALTCHARSET + 'z') /* greater/equal */
103 #define ACS_PI (A_ALTCHARSET + '{') /* Pi */
104 #define ACS_NEQUAL (A_ALTCHARSET + '|') /* not equal */
105 #define ACS_STERLING (A_ALTCHARSET + '}') /* UK pound sign */
110 #ifdef CURSES_WACS_ARRAY
111 #define WACS_S3 (&(CURSES_WACS_ARRAY['p'])) /* scan line 3 */
112 #define WACS_S7 (&(CURSES_WACS_ARRAY['r'])) /* scan line 7 */
113 #define WACS_LEQUAL (&(CURSES_WACS_ARRAY['y'])) /* less/equal */
114 #define WACS_GEQUAL (&(CURSES_WACS_ARRAY['z'])) /* greater/equal */
115 #define WACS_PI (&(CURSES_WACS_ARRAY['{'])) /* Pi */
116 #define WACS_NEQUAL (&(CURSES_WACS_ARRAY['|'])) /* not equal */
117 #define WACS_STERLING (&(CURSES_WACS_ARRAY['}'])) /* UK pound sign */
124 #define count_wchars(src, len, state) wcsrtombs(0, &src, len, state)
125 #define trans_wchars(dst, src, len, state) wcsrtombs(dst, &src, len, state)
126 #define reset_wchars(state) init_mb(state)
127 #elif HAVE_WCSTOMBS && HAVE_MBTOWC && HAVE_MBLEN
128 #define count_wchars(src, len, state) wcstombs(0, src, len)
129 #define trans_wchars(dst, src, len, state) wcstombs(dst, src, len)
130 #define reset_wchars(state) IGNORE_RC(mblen(NULL, 0)), IGNORE_RC(mbtowc(NULL, NULL, 0))
135 #define count_mbytes(src, len, state) mbsrtowcs(0, &src, len, state)
136 #define trans_mbytes(dst, src, len, state) mbsrtowcs(dst, &src, len, state)
137 #define reset_mbytes(state) init_mb(state)
138 #elif HAVE_MBSTOWCS && HAVE_MBTOWC && HAVE_MBLEN
139 #define count_mbytes(src, len, state) mbstowcs(0, src, len)
140 #define trans_mbytes(dst, src, len, state) mbstowcs(dst, src, len)
141 #define reset_mbytes(state) IGNORE_RC(mblen(NULL, 0)), IGNORE_RC(mbtowc(NULL, NULL, 0))
145 #define ToggleAcs(temp,real) temp = ((temp == real) ? 0 : real)
147 #define P(string) printw("%s\n", string)
149 #define BLANK ' ' /* this is the background character */
152 static int max_colors
; /* the actual number of colors we'll use */
153 static int min_colors
; /* the minimum color code */
154 static bool use_colors
; /* true if we use colors */
157 static int max_pairs
; /* ...and the number of color pairs */
165 static RGB_DATA
*all_colors
;
167 static void main_menu(bool);
169 /* The behavior of mvhline, mvvline for negative/zero length is unspecified,
170 * though we can rely on negative x/y values to stop the macro.
173 do_h_line(int y
, int x
, chtype c
, int to
)
176 MvHLine(y
, x
, c
, (to
) - (x
));
180 do_v_line(int y
, int x
, chtype c
, int to
)
183 MvVLine(y
, x
, c
, (to
) - (y
));
197 return ((c
) == QUIT
|| (c
) == ESCAPE
);
199 #define case_QUIT QUIT: case ESCAPE
201 /* Common function to allow ^T to toggle trace-mode in the middle of a test
202 * so that trace-files can be made smaller.
205 wGetchar(WINDOW
*win
)
209 while ((c
= wgetch(win
)) == CTRL('T')) {
211 save_trace
= _nc_tracing
;
212 Trace(("TOGGLE-TRACING OFF"));
215 _nc_tracing
= save_trace
;
219 Trace(("TOGGLE-TRACING ON"));
226 #define Getchar() wGetchar(stdscr)
228 /* replaces wgetnstr(), since we want to be able to edit values */
230 wGetstring(WINDOW
*win
, char *buffer
, int limit
)
237 (void) wattrset(win
, A_REVERSE
);
239 x
= (int) strlen(buffer
);
241 if (x
> (int) strlen(buffer
))
242 x
= (int) strlen(buffer
);
244 wprintw(win
, "%-*s", limit
, buffer
);
245 wmove(win
, y0
, x0
+ x
);
246 switch (ch
= wGetchar(win
)) {
259 for (j
= --x
; (buffer
[j
] = buffer
[j
+ 1]) != '\0'; ++j
) {
277 if (!isprint(ch
) || ch
>= KEY_MIN
) {
279 } else if ((int) strlen(buffer
) < limit
) {
281 for (j
= (int) strlen(buffer
) + 1; j
> x
; --j
) {
282 buffer
[j
] = buffer
[j
- 1];
284 buffer
[x
++] = (char) ch
;
291 wattroff(win
, A_REVERSE
);
296 #if USE_WIDEC_SUPPORT
300 return (ch
+ 0xff10 - '0');
304 make_fullwidth_text(wchar_t *target
, const char *source
)
307 while ((ch
= *source
++) != 0) {
308 *target
++ = fullwidth_of(ch
);
314 make_narrow_text(wchar_t *target
, const char *source
)
317 while ((ch
= *source
++) != 0) {
325 make_fullwidth_digit(cchar_t
*target
, int digit
)
329 source
[0] = fullwidth_of(digit
+ '0');
331 setcchar(target
, source
, A_NORMAL
, 0, 0);
336 wGet_wchar(WINDOW
*win
, wint_t *result
)
340 while ((c
= wget_wch(win
, result
)) == CTRL('T')) {
342 save_trace
= _nc_tracing
;
343 Trace(("TOGGLE-TRACING OFF"));
346 _nc_tracing
= save_trace
;
350 Trace(("TOGGLE-TRACING ON"));
353 c
= wget_wch(win
, result
);
357 #define Get_wchar(result) wGet_wchar(stdscr, result)
359 /* replaces wgetn_wstr(), since we want to be able to edit values */
361 wGet_wstring(WINDOW
*win
, wchar_t *buffer
, int limit
)
370 (void) wattrset(win
, A_REVERSE
);
372 x
= (int) wcslen(buffer
);
374 if (x
> (int) wcslen(buffer
))
375 x
= (int) wcslen(buffer
);
377 /* clear the "window' */
379 wprintw(win
, "%*s", limit
, " ");
381 /* write the existing buffer contents */
383 waddnwstr(win
, buffer
, limit
);
385 /* positions the cursor past character 'x' */
387 waddnwstr(win
, buffer
, x
);
389 switch (wGet_wchar(win
, &ch
)) {
429 for (j
= --x
; (buffer
[j
] = buffer
[j
+ 1]) != '\0'; ++j
) {
449 } else if ((int) wcslen(buffer
) < limit
) {
451 for (j
= (int) wcslen(buffer
) + 1; j
> x
; --j
) {
452 buffer
[j
] = buffer
[j
- 1];
454 buffer
[x
++] = (wchar_t) ch
;
461 wattroff(win
, A_REVERSE
);
472 addstr("Press any key to continue... ");
477 Cannot(const char *what
)
479 printw("\nThis %s terminal %s\n\n", getenv("TERM"), what
);
484 ShellOut(bool message
)
487 addstr("Shelling out...");
496 addstr("returned from shellout.\n");
500 #ifdef NCURSES_MOUSE_VERSION
502 * This function is the same as _tracemouse(), but we cannot count on that
503 * being available in the non-debug library.
506 mouse_decode(MEVENT
const *ep
)
508 static char buf
[80 + (5 * 10) + (32 * 15)];
510 (void) sprintf(buf
, "id %2d at (%2d, %2d, %d) state %4lx = {",
511 ep
->id
, ep
->x
, ep
->y
, ep
->z
, (unsigned long) ep
->bstate
);
513 #define SHOW(m, s) if ((ep->bstate & m)==m) {strcat(buf,s); strcat(buf, ", ");}
515 SHOW(BUTTON1_RELEASED
, "release-1");
516 SHOW(BUTTON1_PRESSED
, "press-1");
517 SHOW(BUTTON1_CLICKED
, "click-1");
518 SHOW(BUTTON1_DOUBLE_CLICKED
, "doubleclick-1");
519 SHOW(BUTTON1_TRIPLE_CLICKED
, "tripleclick-1");
520 #if NCURSES_MOUSE_VERSION == 1
521 SHOW(BUTTON1_RESERVED_EVENT
, "reserved-1");
524 SHOW(BUTTON2_RELEASED
, "release-2");
525 SHOW(BUTTON2_PRESSED
, "press-2");
526 SHOW(BUTTON2_CLICKED
, "click-2");
527 SHOW(BUTTON2_DOUBLE_CLICKED
, "doubleclick-2");
528 SHOW(BUTTON2_TRIPLE_CLICKED
, "tripleclick-2");
529 #if NCURSES_MOUSE_VERSION == 1
530 SHOW(BUTTON2_RESERVED_EVENT
, "reserved-2");
533 SHOW(BUTTON3_RELEASED
, "release-3");
534 SHOW(BUTTON3_PRESSED
, "press-3");
535 SHOW(BUTTON3_CLICKED
, "click-3");
536 SHOW(BUTTON3_DOUBLE_CLICKED
, "doubleclick-3");
537 SHOW(BUTTON3_TRIPLE_CLICKED
, "tripleclick-3");
538 #if NCURSES_MOUSE_VERSION == 1
539 SHOW(BUTTON3_RESERVED_EVENT
, "reserved-3");
542 SHOW(BUTTON4_RELEASED
, "release-4");
543 SHOW(BUTTON4_PRESSED
, "press-4");
544 SHOW(BUTTON4_CLICKED
, "click-4");
545 SHOW(BUTTON4_DOUBLE_CLICKED
, "doubleclick-4");
546 SHOW(BUTTON4_TRIPLE_CLICKED
, "tripleclick-4");
547 #if NCURSES_MOUSE_VERSION == 1
548 SHOW(BUTTON4_RESERVED_EVENT
, "reserved-4");
551 #if NCURSES_MOUSE_VERSION == 2
552 SHOW(BUTTON5_RELEASED
, "release-5");
553 SHOW(BUTTON5_PRESSED
, "press-5");
554 SHOW(BUTTON5_CLICKED
, "click-5");
555 SHOW(BUTTON5_DOUBLE_CLICKED
, "doubleclick-5");
556 SHOW(BUTTON5_TRIPLE_CLICKED
, "tripleclick-5");
559 SHOW(BUTTON_CTRL
, "ctrl");
560 SHOW(BUTTON_SHIFT
, "shift");
561 SHOW(BUTTON_ALT
, "alt");
562 SHOW(ALL_MOUSE_EVENTS
, "all-events");
563 SHOW(REPORT_MOUSE_POSITION
, "position");
567 if (buf
[strlen(buf
) - 1] == ' ')
568 buf
[strlen(buf
) - 2] = '\0';
569 (void) strcat(buf
, "}");
574 show_mouse(WINDOW
*win
)
582 outside
= !wenclose(win
, event
.y
, event
.x
);
585 (void) wstandout(win
);
586 waddstr(win
, "KEY_MOUSE");
587 (void) wstandend(win
);
589 waddstr(win
, "KEY_MOUSE");
591 wprintw(win
, ", %s", mouse_decode(&event
));
596 show_loc
= wmouse_trafo(win
, &event
.y
, &event
.x
, FALSE
);
600 wmove(win
, event
.y
, event
.x
);
608 #endif /* NCURSES_MOUSE_VERSION */
610 /****************************************************************************
612 * Character input test
614 ****************************************************************************/
616 #define NUM_GETCH_FLAGS 256
617 typedef bool GetchFlags
[NUM_GETCH_FLAGS
];
620 setup_getch(WINDOW
*win
, GetchFlags flags
)
622 keypad(win
, flags
['k']); /* should be redundant, but for testing */
623 meta(win
, flags
['m']); /* force this to a known state */
631 init_getch(WINDOW
*win
, GetchFlags flags
)
633 memset(flags
, FALSE
, NUM_GETCH_FLAGS
);
634 flags
[UChar('k')] = (win
== stdscr
);
635 flags
[UChar('m')] = TRUE
;
637 setup_getch(win
, flags
);
641 wgetch_help(WINDOW
*win
, GetchFlags flags
)
643 static const char *help
[] =
645 "e -- toggle echo mode"
646 ,"g -- triggers a getstr test"
647 ,"k -- toggle keypad/literal mode"
648 ,"m -- toggle meta (7-bit/8-bit) mode"
651 ,"w -- create a new window"
653 ,"z -- suspend this process"
657 unsigned chk
= ((SIZEOF(help
) + 1) / 2);
662 printw("Type any key to see its %s value. Also:\n",
663 flags
['k'] ? "keypad" : "literal");
664 for (n
= 0; n
< SIZEOF(help
); ++n
) {
665 int row
= 1 + (int) (n
% chk
);
666 int col
= (n
>= chk
) ? COLS
/ 2 : 0;
667 int flg
= ((strstr(help
[n
], "toggle") != 0)
668 && (flags
[UChar(*help
[n
])] != FALSE
));
671 MvPrintw(row
, col
, "%s", help
[n
]);
682 wgetch_wrap(WINDOW
*win
, int first_y
)
684 int last_y
= getmaxy(win
) - 1;
685 int y
= getcury(win
) + 1;
693 #if defined(KEY_RESIZE) && HAVE_WRESIZE
699 static WINSTACK
*winstack
= 0;
700 static unsigned len_winstack
= 0;
713 remember_boxes(unsigned level
, WINDOW
*txt_win
, WINDOW
*box_win
)
715 unsigned need
= (level
+ 1) * 2;
717 assert(level
< (unsigned) COLS
);
721 winstack
= typeMalloc(WINSTACK
, len_winstack
);
722 } else if (need
>= len_winstack
) {
724 winstack
= typeRealloc(WINSTACK
, len_winstack
, winstack
);
726 winstack
[level
].text
= txt_win
;
727 winstack
[level
].frame
= box_win
;
730 #if USE_SOFTKEYS && (defined(NCURSES_VERSION_PATCH) && NCURSES_VERSION_PATCH < 20071229) && NCURSES_EXT_FUNCS
734 /* this chunk is now done in resize_term() */
741 #define slk_repaint() /* nothing */
744 #if defined(NCURSES_VERSION) && defined(KEY_RESIZE) && HAVE_WRESIZE
746 * For wgetch_test(), we create pairs of windows - one for a box, one for text.
747 * Resize both and paint the box in the parent.
750 resize_boxes(unsigned level
, WINDOW
*win
)
754 int high
= LINES
- base
;
758 wnoutrefresh(stdscr
);
762 for (n
= 0; n
< level
; ++n
) {
763 wresize(winstack
[n
].frame
, high
, wide
);
764 wresize(winstack
[n
].text
, high
- 2, wide
- 2);
767 werase(winstack
[n
].text
);
768 box(winstack
[n
].frame
, 0, 0);
769 wnoutrefresh(winstack
[n
].frame
);
770 wprintw(winstack
[n
].text
,
772 getmaxy(winstack
[n
].text
),
773 getmaxx(winstack
[n
].text
));
774 wnoutrefresh(winstack
[n
].text
);
775 if (winstack
[n
].text
== win
)
780 #endif /* resize_boxes */
782 #define forget_boxes() /* nothing */
783 #define remember_boxes(level,text,frame) /* nothing */
787 wgetch_test(unsigned level
, WINDOW
*win
, int delay
)
790 int first_y
, first_x
;
794 bool blocking
= (delay
< 0);
796 init_getch(win
, flags
);
797 wtimeout(win
, delay
);
798 getyx(win
, first_y
, first_x
);
800 wgetch_help(win
, flags
);
801 wsetscrreg(win
, first_y
, getmaxy(win
) - 1);
805 while ((c
= wGetchar(win
)) == ERR
) {
808 (void) wprintw(win
, "%05d: input error", incount
);
811 (void) wprintw(win
, "%05d: input timed out", incount
);
813 wgetch_wrap(win
, first_y
);
815 if (c
== ERR
&& blocking
) {
817 wgetch_wrap(win
, first_y
);
818 } else if (isQuit(c
)) {
820 } else if (c
== 'e') {
821 flags
[UChar('e')] = !flags
[UChar('e')];
822 setup_getch(win
, flags
);
823 wgetch_help(win
, flags
);
824 } else if (c
== 'g') {
825 waddstr(win
, "getstr test: ");
827 wgetnstr(win
, buf
, sizeof(buf
) - 1);
829 wprintw(win
, "I saw %d characters:\n\t`%s'.", (int) strlen(buf
), buf
);
831 wgetch_wrap(win
, first_y
);
832 } else if (c
== 'k') {
833 flags
[UChar('k')] = !flags
[UChar('k')];
834 setup_getch(win
, flags
);
835 wgetch_help(win
, flags
);
836 } else if (c
== 'm') {
837 flags
[UChar('m')] = !flags
[UChar('m')];
838 setup_getch(win
, flags
);
839 wgetch_help(win
, flags
);
840 } else if (c
== 's') {
842 } else if (c
== 'w') {
843 int high
= getmaxy(win
) - 1 - first_y
+ 1;
844 int wide
= getmaxx(win
) - first_x
;
846 int new_y
= first_y
+ getbegy(win
);
847 int new_x
= first_x
+ getbegx(win
);
849 getyx(win
, old_y
, old_x
);
850 if (high
> 2 && wide
> 2) {
851 WINDOW
*wb
= newwin(high
, wide
, new_y
, new_x
);
852 WINDOW
*wi
= newwin(high
- 2, wide
- 2, new_y
+ 1, new_x
+ 1);
857 remember_boxes(level
, wi
, wb
);
858 wgetch_test(level
+ 1, wi
, delay
);
862 wgetch_help(win
, flags
);
863 wmove(win
, old_y
, old_x
);
869 } else if (c
== 'z') {
870 kill(getpid(), SIGTSTP
);
873 wprintw(win
, "Key pressed: %04o ", c
);
874 #ifdef NCURSES_MOUSE_VERSION
875 if (c
== KEY_MOUSE
) {
878 #endif /* NCURSES_MOUSE_VERSION */
880 #if defined(NCURSES_VERSION) && defined(KEY_RESIZE) && HAVE_WRESIZE
881 if (c
== KEY_RESIZE
) {
882 resize_boxes(level
, win
);
885 (void) waddstr(win
, keyname(c
));
886 } else if (c
>= 0x80) {
887 unsigned c2
= (unsigned) c
;
888 #if !(defined(NCURSES_VERSION) || defined(_XOPEN_CURSES))
889 /* at least Solaris SVR4 curses breaks unctrl(128), etc. */
893 (void) wprintw(win
, "%c", UChar(c
));
894 else if (c2
!= UChar(c
))
895 (void) wprintw(win
, "M-%s", unctrl(c2
));
897 (void) wprintw(win
, "%s", unctrl(c2
));
898 waddstr(win
, " (high-half character)");
901 (void) wprintw(win
, "%c (ASCII printable character)", c
);
903 (void) wprintw(win
, "%s (ASCII control character)",
906 wgetch_wrap(win
, first_y
);
913 init_getch(win
, flags
);
917 begin_getch_test(void)
924 #ifdef NCURSES_MOUSE_VERSION
925 mousemask(ALL_MOUSE_EVENTS
, (mmask_t
*) 0);
928 (void) printw("Delay in 10ths of a second (<CR> for blocking input)? ");
930 getnstr(buf
, sizeof(buf
) - 1);
934 if (isdigit(UChar(buf
[0]))) {
935 delay
= atoi(buf
) * 100;
945 finish_getch_test(void)
947 #ifdef NCURSES_MOUSE_VERSION
948 mousemask(0, (mmask_t
*) 0);
959 int delay
= begin_getch_test();
962 wgetch_test(0, stdscr
, delay
);
968 #if USE_WIDEC_SUPPORT
970 * For wget_wch_test(), we create pairs of windows - one for a box, one for text.
971 * Resize both and paint the box in the parent.
973 #if defined(KEY_RESIZE) && HAVE_WRESIZE
975 resize_wide_boxes(unsigned level
, WINDOW
*win
)
979 int high
= LINES
- base
;
983 wnoutrefresh(stdscr
);
987 for (n
= 0; n
< level
; ++n
) {
988 wresize(winstack
[n
].frame
, high
, wide
);
989 wresize(winstack
[n
].text
, high
- 2, wide
- 2);
992 werase(winstack
[n
].text
);
993 box_set(winstack
[n
].frame
, 0, 0);
994 wnoutrefresh(winstack
[n
].frame
);
995 wprintw(winstack
[n
].text
,
997 getmaxy(winstack
[n
].text
),
998 getmaxx(winstack
[n
].text
));
999 wnoutrefresh(winstack
[n
].text
);
1000 if (winstack
[n
].text
== win
)
1005 #endif /* KEY_RESIZE */
1008 wcstos(const wchar_t *src
)
1012 const wchar_t *tmp
= src
;
1013 #ifndef state_unused
1017 reset_wchars(state
);
1018 if ((need
= (int) count_wchars(tmp
, 0, &state
)) > 0) {
1019 unsigned have
= (unsigned) need
;
1020 if ((result
= typeCalloc(char, have
+ 1)) != 0) {
1022 if (trans_wchars(result
, tmp
, have
, &state
) != have
) {
1032 wget_wch_test(unsigned level
, WINDOW
*win
, int delay
)
1034 wchar_t wchar_buf
[BUFSIZ
];
1035 wint_t wint_buf
[BUFSIZ
];
1036 int first_y
, first_x
;
1040 bool blocking
= (delay
< 0);
1044 init_getch(win
, flags
);
1045 wtimeout(win
, delay
);
1046 getyx(win
, first_y
, first_x
);
1048 wgetch_help(win
, flags
);
1049 wsetscrreg(win
, first_y
, getmaxy(win
) - 1);
1050 scrollok(win
, TRUE
);
1053 while ((code
= wGet_wchar(win
, &c
)) == ERR
) {
1056 (void) wprintw(win
, "%05d: input error", incount
);
1059 (void) wprintw(win
, "%05d: input timed out", incount
);
1061 wgetch_wrap(win
, first_y
);
1063 if (code
== ERR
&& blocking
) {
1064 wprintw(win
, "ERR");
1065 wgetch_wrap(win
, first_y
);
1066 } else if (isQuit((int) c
)) {
1068 } else if (c
== 'e') {
1069 flags
[UChar('e')] = !flags
[UChar('e')];
1070 setup_getch(win
, flags
);
1071 wgetch_help(win
, flags
);
1072 } else if (c
== 'g') {
1073 waddstr(win
, "getstr test: ");
1075 code
= wgetn_wstr(win
, wint_buf
, sizeof(wint_buf
) - 1);
1078 wprintw(win
, "wgetn_wstr returns an error.");
1081 for (n
= 0; (wchar_buf
[n
] = (wchar_t) wint_buf
[n
]) != 0; ++n
) {
1084 if ((temp
= wcstos(wchar_buf
)) != 0) {
1085 wprintw(win
, "I saw %d characters:\n\t`%s'.",
1086 (int) wcslen(wchar_buf
), temp
);
1089 wprintw(win
, "I saw %d characters (cannot convert).",
1090 (int) wcslen(wchar_buf
));
1094 wgetch_wrap(win
, first_y
);
1095 } else if (c
== 'k') {
1096 flags
[UChar('k')] = !flags
[UChar('k')];
1097 setup_getch(win
, flags
);
1098 wgetch_help(win
, flags
);
1099 } else if (c
== 'm') {
1100 flags
[UChar('m')] = !flags
[UChar('m')];
1101 setup_getch(win
, flags
);
1102 wgetch_help(win
, flags
);
1103 } else if (c
== 's') {
1105 } else if (c
== 'w') {
1106 int high
= getmaxy(win
) - 1 - first_y
+ 1;
1107 int wide
= getmaxx(win
) - first_x
;
1109 int new_y
= first_y
+ getbegy(win
);
1110 int new_x
= first_x
+ getbegx(win
);
1112 getyx(win
, old_y
, old_x
);
1113 if (high
> 2 && wide
> 2) {
1114 WINDOW
*wb
= newwin(high
, wide
, new_y
, new_x
);
1115 WINDOW
*wi
= newwin(high
- 2, wide
- 2, new_y
+ 1, new_x
+ 1);
1120 remember_boxes(level
, wi
, wb
);
1121 wget_wch_test(level
+ 1, wi
, delay
);
1125 wgetch_help(win
, flags
);
1126 wmove(win
, old_y
, old_x
);
1131 } else if (c
== 'z') {
1132 kill(getpid(), SIGTSTP
);
1135 wprintw(win
, "Key pressed: %04o ", (int) c
);
1136 #ifdef NCURSES_MOUSE_VERSION
1137 if (c
== KEY_MOUSE
) {
1140 #endif /* NCURSES_MOUSE_VERSION */
1141 if (code
== KEY_CODE_YES
) {
1142 #if defined(KEY_RESIZE) && HAVE_WRESIZE
1143 if (c
== KEY_RESIZE
) {
1144 resize_wide_boxes(level
, win
);
1147 (void) waddstr(win
, keyname((wchar_t) c
));
1149 (void) waddstr(win
, key_name((wchar_t) c
));
1150 if (c
< 256 && iscntrl(c
)) {
1151 (void) wprintw(win
, " (control character)");
1153 (void) wprintw(win
, " = %#x (printable character)",
1157 wgetch_wrap(win
, first_y
);
1164 init_getch(win
, flags
);
1170 int delay
= begin_getch_test();
1173 wget_wch_test(0, stdscr
, delay
);
1175 finish_getch_test();
1180 /****************************************************************************
1182 * Character attributes test
1184 ****************************************************************************/
1186 #if HAVE_SETUPTERM || HAVE_TGETENT
1187 #define get_ncv() TIGETNUM("ncv","NC")
1188 #define get_xmc() TIGETNUM("xmc","sg")
1190 #define get_ncv() -1
1191 #define get_xmc() -1
1198 static int first
= TRUE
;
1199 static chtype result
= 0;
1205 char *area_pointer
= parsed
;
1207 tgetent(buffer
, getenv("TERM"));
1210 if (TIGETSTR("smso", "so"))
1211 result
|= A_STANDOUT
;
1212 if (TIGETSTR("smul", "us"))
1213 result
|= A_UNDERLINE
;
1214 if (TIGETSTR("rev", "mr"))
1215 result
|= A_REVERSE
;
1216 if (TIGETSTR("blink", "mb"))
1218 if (TIGETSTR("dim", "mh"))
1220 if (TIGETSTR("bold", "md"))
1222 if (TIGETSTR("smacs", "ac"))
1223 result
|= A_ALTCHARSET
;
1229 #define termattrs() my_termattrs()
1232 #define MAX_ATTRSTRING 31
1233 #define LEN_ATTRSTRING 26
1235 static char attr_test_string
[MAX_ATTRSTRING
+ 1];
1238 attr_legend(WINDOW
*helpwin
)
1243 MvWPrintw(helpwin
, row
++, col
,
1245 MvWPrintw(helpwin
, row
++, col
,
1248 MvWPrintw(helpwin
, row
++, col
,
1249 "Modify the test strings:");
1250 MvWPrintw(helpwin
, row
++, col
,
1251 " A digit sets gaps on each side of displayed attributes");
1252 MvWPrintw(helpwin
, row
++, col
,
1253 " </> shifts the text left/right. ");
1255 MvWPrintw(helpwin
, row
++, col
,
1258 MvWPrintw(helpwin
, row
++, col
,
1259 " f/F/b/F toggle foreground/background background color");
1260 MvWPrintw(helpwin
, row
++, col
,
1261 " t/T toggle text/background color attribute");
1263 MvWPrintw(helpwin
, row
++, col
,
1264 " a/A toggle ACS (alternate character set) mapping");
1265 MvWPrintw(helpwin
, row
, col
,
1266 " v/V toggle video attribute to combine with each line");
1270 show_color_attr(int fg
, int bg
, int tx
)
1273 printw(" Colors (fg %d, bg %d", fg
, bg
);
1275 printw(", text %d", tx
);
1281 cycle_color_attr(int ch
, short *fg
, short *bg
, short *tx
)
1288 *fg
= (short) (*fg
+ 1);
1291 *fg
= (short) (*fg
- 1);
1294 *bg
= (short) (*bg
+ 1);
1297 *bg
= (short) (*bg
- 1);
1300 *tx
= (short) (*tx
+ 1);
1303 *tx
= (short) (*tx
- 1);
1311 *fg
= (short) min_colors
;
1312 if (*fg
< min_colors
)
1313 *fg
= (short) (COLORS
- 1);
1315 *bg
= (short) min_colors
;
1316 if (*bg
< min_colors
)
1317 *bg
= (short) (COLORS
- 1);
1321 *tx
= (short) (COLORS
- 1);
1330 adjust_attr_string(int adjust
)
1332 int first
= ((int) UChar(attr_test_string
[0])) + adjust
;
1333 int last
= first
+ LEN_ATTRSTRING
;
1335 if (first
>= ' ' && last
<= '~') { /* 32..126 */
1337 for (j
= 0, k
= first
; j
< MAX_ATTRSTRING
&& k
<= last
; ++j
, ++k
) {
1338 attr_test_string
[j
] = (char) k
;
1339 if (((k
+ 1 - first
) % 5) == 0) {
1340 if (++j
>= MAX_ATTRSTRING
)
1342 attr_test_string
[j
] = ' ';
1345 while (j
< MAX_ATTRSTRING
)
1346 attr_test_string
[j
++] = ' ';
1347 attr_test_string
[j
] = '\0';
1354 init_attr_string(void)
1356 attr_test_string
[0] = 'a';
1357 adjust_attr_string(0);
1361 show_attr(int row
, int skip
, bool arrow
, chtype attr
, const char *name
)
1363 int ncv
= get_ncv();
1364 chtype test
= attr
& (chtype
) (~A_ALTCHARSET
);
1367 MvPrintw(row
, 5, "-->");
1368 MvPrintw(row
, 8, "%s mode:", name
);
1369 MvPrintw(row
, 24, "|");
1371 printw("%*s", skip
, " ");
1373 * Just for testing, write text using the alternate character set one
1374 * character at a time (to pass its rendition directly), and use the
1375 * string operation for the other attributes.
1377 if (attr
& A_ALTCHARSET
) {
1381 for (s
= attr_test_string
; *s
!= '\0'; ++s
) {
1386 (void) attrset(attr
);
1387 addstr(attr_test_string
);
1391 printw("%*s", skip
, " ");
1393 if (test
!= A_NORMAL
) {
1394 if (!(termattrs() & test
)) {
1397 if (ncv
> 0 && (getbkgd(stdscr
) & A_COLOR
)) {
1398 static const chtype table
[] =
1414 for (n
= 0; n
< SIZEOF(table
); n
++) {
1415 if ((table
[n
] & attr
) != 0
1416 && ((1 << n
) & ncv
) != 0) {
1424 if ((termattrs() & test
) != test
)
1431 static const struct {
1433 NCURSES_CONST
char * name
;
1434 } attrs_to_test
[] = {
1435 { A_STANDOUT
, "STANDOUT" },
1436 { A_REVERSE
, "REVERSE" },
1438 { A_UNDERLINE
, "UNDERLINE" },
1440 { A_BLINK
, "BLINK" },
1441 { A_PROTECT
, "PROTECT" },
1443 { A_INVIS
, "INVISIBLE" },
1445 { A_NORMAL
, "NORMAL" },
1450 attr_getc(int *skip
, short *fg
, short *bg
, short *tx
, int *ac
, unsigned *kc
)
1460 if (ch
< 256 && isdigit(ch
)) {
1468 if ((helpwin
= newwin(LINES
- 1, COLS
- 2, 0, 0)) != 0) {
1470 attr_legend(helpwin
);
1483 *kc
= SIZEOF(attrs_to_test
) - 1;
1489 if (*kc
>= SIZEOF(attrs_to_test
))
1493 adjust_attr_string(-1);
1496 adjust_attr_string(1);
1502 error
= cycle_color_attr(ch
, fg
, bg
, tx
);
1512 /* test text attributes */
1515 int skip
= get_xmc();
1516 short fg
= COLOR_BLACK
; /* color pair 0 is special */
1517 short bg
= COLOR_BLACK
;
1525 n
= skip
; /* make it easy */
1526 k
= SIZEOF(attrs_to_test
) - 1;
1531 chtype normal
= A_NORMAL
| BLANK
;
1532 chtype extras
= (chtype
) ac
;
1535 short pair
= (short) (fg
!= COLOR_BLACK
|| bg
!= COLOR_BLACK
);
1538 if (init_pair(pair
, fg
, bg
) == ERR
) {
1541 normal
|= (chtype
) COLOR_PAIR(pair
);
1546 if (init_pair(pair
, tx
, bg
) == ERR
) {
1549 extras
|= (chtype
) COLOR_PAIR(pair
);
1558 MvAddStr(0, 20, "Character attribute test display");
1560 for (j
= 0; j
< SIZEOF(attrs_to_test
); ++j
) {
1561 bool arrow
= (j
== k
);
1562 row
= show_attr(row
, n
, arrow
,
1564 attrs_to_test
[j
].attr
|
1565 attrs_to_test
[k
].attr
,
1566 attrs_to_test
[j
].name
);
1570 "This terminal does %shave the magic-cookie glitch",
1571 get_xmc() > -1 ? "" : "not ");
1572 MvPrintw(row
+ 1, 8, "Enter '?' for help.");
1573 show_color_attr(fg
, bg
, tx
);
1574 printw(" ACS (%d)", ac
!= 0);
1577 } while (attr_getc(&n
, &fg
, &bg
, &tx
, &ac
, &k
));
1579 bkgdset(A_NORMAL
| BLANK
);
1584 #if USE_WIDEC_SUPPORT
1585 static wchar_t wide_attr_test_string
[MAX_ATTRSTRING
+ 1];
1588 wide_adjust_attr_string(int adjust
)
1590 int first
= ((int) UChar(wide_attr_test_string
[0])) + adjust
;
1591 int last
= first
+ LEN_ATTRSTRING
;
1593 if (first
>= ' ' && last
<= '~') { /* 32..126 */
1595 for (j
= 0, k
= first
; j
< MAX_ATTRSTRING
&& k
<= last
; ++j
, ++k
) {
1596 wide_attr_test_string
[j
] = k
;
1597 if (((k
+ 1 - first
) % 5) == 0) {
1598 if (++j
>= MAX_ATTRSTRING
)
1600 wide_attr_test_string
[j
] = ' ';
1603 while (j
< MAX_ATTRSTRING
)
1604 wide_attr_test_string
[j
++] = ' ';
1605 wide_attr_test_string
[j
] = '\0';
1612 wide_init_attr_string(void)
1614 wide_attr_test_string
[0] = 'a';
1615 wide_adjust_attr_string(0);
1619 set_wide_background(short pair
)
1626 setcchar(&normal
, blank
, A_NORMAL
, pair
, 0);
1632 get_wide_background(void)
1634 attr_t result
= A_NORMAL
;
1640 if (getbkgrnd(&ch
) != ERR
) {
1641 if (getcchar(&ch
, wch
, &attr
, &pair
, 0) != ERR
) {
1649 wide_show_attr(int row
, int skip
, bool arrow
, chtype attr
, short pair
, const char *name
)
1651 int ncv
= get_ncv();
1652 chtype test
= attr
& ~WA_ALTCHARSET
;
1655 MvPrintw(row
, 5, "-->");
1656 MvPrintw(row
, 8, "%s mode:", name
);
1657 MvPrintw(row
, 24, "|");
1659 printw("%*s", skip
, " ");
1662 * Just for testing, write text using the alternate character set one
1663 * character at a time (to pass its rendition directly), and use the
1664 * string operation for the other attributes.
1666 if (attr
& WA_ALTCHARSET
) {
1670 for (s
= wide_attr_test_string
; *s
!= L
'\0'; ++s
) {
1674 setcchar(&ch
, fill
, attr
, pair
, 0);
1681 (void) attr_get(&old_attr
, &old_pair
, 0);
1682 (void) attr_set(attr
, pair
, 0);
1683 addwstr(wide_attr_test_string
);
1684 (void) attr_set(old_attr
, old_pair
, 0);
1687 printw("%*s", skip
, " ");
1689 if (test
!= A_NORMAL
) {
1690 if (!(term_attrs() & test
)) {
1693 if (ncv
> 0 && (get_wide_background() & A_COLOR
)) {
1694 static const attr_t table
[] =
1708 for (n
= 0; n
< SIZEOF(table
); n
++) {
1709 if ((table
[n
] & attr
) != 0
1710 && ((1 << n
) & ncv
) != 0) {
1718 if ((term_attrs() & test
) != test
)
1726 wide_attr_getc(int *skip
, short *fg
, short *bg
, short *tx
, int *ac
, unsigned *kc
)
1736 if (ch
< 256 && isdigit(ch
)) {
1744 if ((helpwin
= newwin(LINES
- 1, COLS
- 2, 0, 0)) != 0) {
1745 box_set(helpwin
, 0, 0);
1746 attr_legend(helpwin
);
1759 *kc
= SIZEOF(attrs_to_test
) - 1;
1765 if (*kc
>= SIZEOF(attrs_to_test
))
1769 wide_adjust_attr_string(-1);
1772 wide_adjust_attr_string(1);
1778 error
= cycle_color_attr(ch
, fg
, bg
, tx
);
1787 wide_attr_test(void)
1788 /* test text attributes using wide-character calls */
1791 int skip
= get_xmc();
1792 short fg
= COLOR_BLACK
; /* color pair 0 is special */
1793 short bg
= COLOR_BLACK
;
1801 n
= skip
; /* make it easy */
1802 k
= SIZEOF(attrs_to_test
) - 1;
1803 wide_init_attr_string();
1811 pair
= (short) (fg
!= COLOR_BLACK
|| bg
!= COLOR_BLACK
);
1814 if (init_pair(pair
, fg
, bg
) == ERR
) {
1821 if (init_pair(extras
, tx
, bg
) == ERR
) {
1826 set_wide_background(pair
);
1829 box_set(stdscr
, 0, 0);
1830 MvAddStr(0, 20, "Character attribute test display");
1832 for (j
= 0; j
< SIZEOF(attrs_to_test
); ++j
) {
1833 row
= wide_show_attr(row
, n
, j
== k
,
1835 attrs_to_test
[j
].attr
|
1836 attrs_to_test
[k
].attr
),
1838 attrs_to_test
[j
].name
);
1842 "This terminal does %shave the magic-cookie glitch",
1843 get_xmc() > -1 ? "" : "not ");
1844 MvPrintw(row
+ 1, 8, "Enter '?' for help.");
1845 show_color_attr(fg
, bg
, tx
);
1846 printw(" ACS (%d)", ac
!= 0);
1849 } while (wide_attr_getc(&n
, &fg
, &bg
, &tx
, &ac
, &k
));
1851 set_wide_background(0);
1857 /****************************************************************************
1859 * Color support tests
1861 ****************************************************************************/
1863 static NCURSES_CONST
char *the_color_names
[] =
1884 show_color_name(int y
, int x
, int color
, bool wide
)
1886 if (move(y
, x
) != ERR
) {
1891 sprintf(temp
, "%02d", color
);
1893 } else if (color
>= 8) {
1894 sprintf(temp
, "[%02d]", color
);
1895 } else if (color
< 0) {
1896 strcpy(temp
, "default");
1898 strcpy(temp
, the_color_names
[color
]);
1900 printw("%-*.*s", width
, width
, temp
);
1905 color_legend(WINDOW
*helpwin
, bool wide
)
1910 MvWPrintw(helpwin
, row
++, col
,
1913 MvWPrintw(helpwin
, row
++, col
,
1914 "Use up/down arrow to scroll through the display if it is");
1915 MvWPrintw(helpwin
, row
++, col
,
1916 "longer than one screen. Control/N and Control/P can be used");
1917 MvWPrintw(helpwin
, row
++, col
,
1918 "in place of up/down arrow. Use pageup/pagedown to scroll a");
1919 MvWPrintw(helpwin
, row
++, col
,
1920 "full screen; control/B and control/F can be used here.");
1922 MvWPrintw(helpwin
, row
++, col
,
1924 MvWPrintw(helpwin
, row
++, col
,
1925 " a/A toggle altcharset off/on");
1926 MvWPrintw(helpwin
, row
++, col
,
1927 " b/B toggle bold off/on");
1928 MvWPrintw(helpwin
, row
++, col
,
1929 " n/N toggle text/number on/off");
1930 MvWPrintw(helpwin
, row
++, col
,
1931 " r/R toggle reverse on/off");
1932 MvWPrintw(helpwin
, row
++, col
,
1933 " w/W toggle width between 8/16 colors");
1934 #if USE_WIDEC_SUPPORT
1936 MvWPrintw(helpwin
, row
++, col
,
1937 "Wide characters:");
1938 MvWPrintw(helpwin
, row
, col
,
1939 " x/X toggle text between ASCII and wide-character");
1946 #define set_color_test(name, value) if (name != value) { name = value; base_row = 0; }
1948 /* generate a color test pattern */
1955 int grid_top
= top
+ 3;
1956 int page_size
= (LINES
- grid_top
);
1957 int pairs_max
= PAIR_NUMBER(A_COLOR
) + 1;
1963 bool opt_acsc
= FALSE
;
1964 bool opt_bold
= FALSE
;
1965 bool opt_revs
= FALSE
;
1966 bool opt_nums
= FALSE
;
1967 bool opt_wide
= FALSE
;
1970 if (COLORS
* COLORS
== COLOR_PAIRS
) {
1971 int limit
= (COLORS
- min_colors
) * (COLORS
- min_colors
);
1972 if (pairs_max
> limit
)
1975 if (pairs_max
> COLOR_PAIRS
)
1976 pairs_max
= COLOR_PAIRS
;
1982 /* this assumes an 80-column line */
1986 per_row
= (COLORS
> 8) ? 16 : 8;
1992 per_row
-= min_colors
;
1994 row_limit
= (pairs_max
+ per_row
- 1) / per_row
;
1997 (void) printw("There are %d color pairs and %d colors%s\n",
1999 min_colors
? " besides 'default'" : "");
2002 MvPrintw(top
+ 1, 0,
2003 "%dx%d matrix of foreground/background colors, bold *%s*\n",
2006 opt_bold
? "on" : "off");
2008 /* show color names/numbers across the top */
2009 for (i
= 0; i
< per_row
; i
++)
2010 show_color_name(top
+ 2, (i
+ 1) * width
, i
+ min_colors
, opt_wide
);
2012 /* show a grid of colors, with color names/ numbers on the left */
2013 for (i
= (short) (base_row
* per_row
); i
< pairs_max
; i
++) {
2014 int row
= grid_top
+ (i
/ per_row
) - base_row
;
2015 int col
= (i
% per_row
+ 1) * width
;
2018 #define InxToFG(i) (short) ((i % (COLORS - min_colors)) + min_colors)
2019 #define InxToBG(i) (short) ((i / (COLORS - min_colors)) + min_colors)
2020 if (row
>= 0 && move(row
, col
) != ERR
) {
2021 short fg
= InxToFG(i
);
2022 short bg
= InxToBG(i
);
2024 init_pair(pair
, fg
, bg
);
2025 attron((attr_t
) COLOR_PAIR(pair
));
2027 attron((attr_t
) A_ALTCHARSET
);
2029 attron((attr_t
) A_BOLD
);
2031 attron((attr_t
) A_REVERSE
);
2034 sprintf(numbered
, "{%02X}", i
);
2037 printw("%-*.*s", width
, width
, hello
);
2038 (void) attrset(A_NORMAL
);
2040 if ((i
% per_row
) == 0 && InxToFG(i
) == min_colors
) {
2041 show_color_name(row
, 0, InxToBG(i
), opt_wide
);
2049 switch (wGetchar(stdscr
)) {
2078 set_color_test(opt_wide
, FALSE
);
2081 set_color_test(opt_wide
, TRUE
);
2085 if (base_row
<= 0) {
2093 if (base_row
+ page_size
>= row_limit
) {
2102 if (base_row
<= 0) {
2105 base_row
-= (page_size
- 1);
2113 if (base_row
+ page_size
>= row_limit
) {
2116 base_row
+= page_size
- 1;
2117 if (base_row
+ page_size
>= row_limit
) {
2118 base_row
= row_limit
- page_size
- 1;
2123 if ((helpwin
= newwin(LINES
- 1, COLS
- 2, 0, 0)) != 0) {
2125 color_legend(helpwin
, FALSE
);
2140 #if USE_WIDEC_SUPPORT
2141 /* generate a color test pattern */
2143 wide_color_test(void)
2148 int grid_top
= top
+ 3;
2149 int page_size
= (LINES
- grid_top
);
2150 int pairs_max
= (unsigned short) (-1);
2156 bool opt_acsc
= FALSE
;
2157 bool opt_bold
= FALSE
;
2158 bool opt_revs
= FALSE
;
2159 bool opt_wide
= FALSE
;
2160 bool opt_nums
= FALSE
;
2161 bool opt_xchr
= FALSE
;
2165 if (COLORS
* COLORS
== COLOR_PAIRS
) {
2166 int limit
= (COLORS
- min_colors
) * (COLORS
- min_colors
);
2167 if (pairs_max
> limit
)
2170 if (pairs_max
> COLOR_PAIRS
)
2171 pairs_max
= COLOR_PAIRS
;
2177 /* this assumes an 80-column line */
2181 per_row
= (COLORS
> 8) ? 16 : 8;
2187 per_row
-= min_colors
;
2190 make_fullwidth_text(buffer
, hello
);
2194 make_narrow_text(buffer
, hello
);
2197 row_limit
= (pairs_max
+ per_row
- 1) / per_row
;
2200 (void) printw("There are %d color pairs and %d colors%s\n",
2202 min_colors
? " besides 'default'" : "");
2205 MvPrintw(top
+ 1, 0,
2206 "%dx%d matrix of foreground/background colors, bold *%s*\n",
2209 opt_bold
? "on" : "off");
2211 /* show color names/numbers across the top */
2212 for (i
= 0; i
< per_row
; i
++)
2213 show_color_name(top
+ 2, (i
+ 1) * width
, i
+ min_colors
, opt_wide
);
2215 /* show a grid of colors, with color names/ numbers on the left */
2216 for (i
= (base_row
* per_row
); i
< pairs_max
; i
++) {
2217 int row
= grid_top
+ (i
/ per_row
) - base_row
;
2218 int col
= (i
% per_row
+ 1) * width
;
2219 short pair
= (short) i
;
2221 if (row
>= 0 && move(row
, col
) != ERR
) {
2222 init_pair(pair
, InxToFG(i
), InxToBG(i
));
2223 color_set(pair
, NULL
);
2225 attr_on((attr_t
) A_ALTCHARSET
, NULL
);
2227 attr_on((attr_t
) A_BOLD
, NULL
);
2229 attr_on((attr_t
) A_REVERSE
, NULL
);
2232 sprintf(numbered
, "{%02X}", i
);
2234 make_fullwidth_text(buffer
, numbered
);
2236 make_narrow_text(buffer
, numbered
);
2239 addnwstr(buffer
, width
);
2240 (void) attr_set(A_NORMAL
, 0, NULL
);
2242 if ((i
% per_row
) == 0 && InxToFG(i
) == min_colors
) {
2243 show_color_name(row
, 0, InxToBG(i
), opt_wide
);
2251 switch (wGetchar(stdscr
)) {
2280 set_color_test(opt_wide
, FALSE
);
2283 set_color_test(opt_wide
, TRUE
);
2293 if (base_row
<= 0) {
2301 if (base_row
+ page_size
>= row_limit
) {
2310 if (base_row
<= 0) {
2313 base_row
-= (page_size
- 1);
2321 if (base_row
+ page_size
>= row_limit
) {
2324 base_row
+= page_size
- 1;
2325 if (base_row
+ page_size
>= row_limit
) {
2326 base_row
= row_limit
- page_size
- 1;
2331 if ((helpwin
= newwin(LINES
- 1, COLS
- 2, 0, 0)) != 0) {
2333 color_legend(helpwin
, TRUE
);
2347 #endif /* USE_WIDEC_SUPPORT */
2350 change_color(short current
, int field
, int value
, int usebase
)
2352 short red
, green
, blue
;
2354 color_content(current
, &red
, &green
, &blue
);
2358 red
= (short) (usebase
? (red
+ value
) : value
);
2361 green
= (short) (usebase
? (green
+ value
) : value
);
2364 blue
= (short) (usebase
? (blue
+ value
) : value
);
2368 if (init_color(current
, red
, green
, blue
) == ERR
)
2373 init_all_colors(void)
2377 for (c
= 0; c
< COLORS
; ++c
)
2380 all_colors
[c
].green
,
2381 all_colors
[c
].blue
);
2384 #define scaled_rgb(n) ((255 * (n)) / 1000)
2388 /* display the color test pattern, without trying to edit colors */
2392 int this_c
= 0, value
= 0, field
= 0;
2395 int page_size
= (LINES
- 6);
2400 for (i
= 0; i
< max_colors
; i
++)
2401 init_pair((short) i
, (short) COLOR_WHITE
, (short) i
);
2403 MvPrintw(LINES
- 2, 0, "Number: %d", value
);
2406 short red
, green
, blue
;
2409 MvAddStr(0, 20, "Color RGB Value Editing");
2412 for (i
= (short) top_color
;
2413 (i
- top_color
< page_size
)
2414 && (i
< max_colors
); i
++) {
2417 sprintf(numeric
, "[%d]", i
);
2418 MvPrintw(2 + i
- top_color
, 0, "%c %-8s:",
2419 (i
== current
? '>' : ' '),
2420 (i
< (int) SIZEOF(the_color_names
)
2421 ? the_color_names
[i
] : numeric
));
2422 (void) attrset((attr_t
) COLOR_PAIR(i
));
2424 (void) attrset(A_NORMAL
);
2426 color_content((short) i
, &red
, &green
, &blue
);
2428 if (current
== i
&& field
== 0)
2430 printw("%04d", red
);
2431 if (current
== i
&& field
== 0)
2432 (void) attrset(A_NORMAL
);
2434 if (current
== i
&& field
== 1)
2436 printw("%04d", green
);
2437 if (current
== i
&& field
== 1)
2438 (void) attrset(A_NORMAL
);
2440 if (current
== i
&& field
== 2)
2442 printw("%04d", blue
);
2443 if (current
== i
&& field
== 2)
2444 (void) attrset(A_NORMAL
);
2445 (void) attrset(A_NORMAL
);
2446 printw(" ( %3d %3d %3d )",
2452 MvAddStr(LINES
- 3, 0,
2453 "Use up/down to select a color, left/right to change fields.");
2454 MvAddStr(LINES
- 2, 0,
2455 "Modify field by typing nnn=, nnn-, or nnn+. ? for help.");
2457 move(2 + current
- top_color
, 0);
2461 if (this_c
< 256 && isdigit(this_c
) && !isdigit(last_c
))
2468 current
-= (page_size
- 1);
2475 if (current
< (max_colors
- 1))
2476 current
+= (page_size
- 1);
2483 current
= (current
== 0 ? (max_colors
- 1) : current
- 1);
2488 current
= (current
== (max_colors
- 1) ? 0 : current
+ 1);
2492 field
= (field
== 2 ? 0 : field
+ 1);
2496 field
= (field
== 0 ? 2 : field
- 1);
2509 value
= value
* 10 + (this_c
- '0');
2513 change_color((short) current
, field
, value
, 1);
2517 change_color((short) current
, field
, -value
, 1);
2521 change_color((short) current
, field
, value
, 0);
2526 P(" RGB Value Editing Help");
2528 P("You are in the RGB value editor. Use the arrow keys to select one of");
2529 P("the fields in one of the RGB triples of the current colors; the one");
2530 P("currently selected will be reverse-video highlighted.");
2532 P("To change a field, enter the digits of the new value; they are echoed");
2533 P("as entered. Finish by typing `='. The change will take effect instantly.");
2534 P("To increment or decrement a value, use the same procedure, but finish");
2535 P("with a `+' or `-'.");
2537 P("Press 'm' to invoke the top-level menu with the current color settings.");
2538 P("To quit, do ESC");
2547 for (i
= 0; i
< max_colors
; i
++)
2548 init_pair((short) i
, (short) COLOR_WHITE
, (short) i
);
2562 if (current
>= max_colors
)
2563 current
= max_colors
- 1;
2564 if (current
< top_color
)
2565 top_color
= current
;
2566 if (current
- top_color
>= page_size
)
2567 top_color
= current
- (page_size
- 1);
2569 MvPrintw(LINES
- 1, 0, "Number: %d", value
);
2577 * ncurses does not reset each color individually when calling endwin().
2584 /****************************************************************************
2586 * Alternate character-set stuff
2588 ****************************************************************************/
2593 } attrs_to_cycle
[] = {
2594 { A_NORMAL
, "normal" },
2596 { A_BLINK
, "blink" },
2597 { A_REVERSE
, "reverse" },
2598 { A_UNDERLINE
, "underline" },
2603 cycle_attr(int ch
, unsigned *at_code
, chtype
*attr
)
2609 if ((*at_code
+= 1) >= SIZEOF(attrs_to_cycle
))
2614 *at_code
= SIZEOF(attrs_to_cycle
) - 1;
2623 *attr
= attrs_to_cycle
[*at_code
].attr
;
2628 cycle_colors(int ch
, int *fg
, int *bg
, short *pair
)
2630 bool result
= FALSE
;
2640 if ((*fg
+= 1) >= COLORS
)
2648 if ((*bg
+= 1) >= COLORS
)
2656 *pair
= (short) (*fg
!= COLOR_BLACK
|| *bg
!= COLOR_BLACK
);
2659 if (init_pair(*pair
, (short) *fg
, (short) *bg
) == ERR
) {
2668 /****************************************************************************
2670 * Soft-key label test
2672 ****************************************************************************/
2677 #define SLK_WORK (SLK_HELP + 3)
2682 static const char *table
[] =
2684 "Available commands are:"
2686 ,"^L -- repaint this message and activate soft keys"
2687 ,"a/d -- activate/disable soft keys"
2688 ,"c -- set centered format for labels"
2689 ,"l -- set left-justified format for labels"
2690 ,"r -- set right-justified format for labels"
2691 ,"[12345678] -- set label; labels are numbered 1 through 8"
2692 ,"e -- erase stdscr (should not erase labels)"
2693 ,"s -- test scrolling of shortened screen"
2694 ,"v/V -- cycle through video attributes"
2696 ,"F/f/B/b -- cycle through foreground/background colors"
2698 ,"ESC -- return to main menu"
2700 ,"Note: if activating the soft keys causes your terminal to scroll up"
2701 ,"one line, your terminal auto-scrolls when anything is written to the"
2702 ,"last screen position. The ncurses code does not yet handle this"
2708 for (j
= 0; j
< SIZEOF(table
); ++j
) {
2716 call_slk_color(int fg
, int bg
)
2718 init_pair(1, (short) bg
, (short) fg
);
2720 MvPrintw(SLK_WORK
, 0, "Colors %d/%d\n", fg
, bg
);
2730 /* exercise the soft keys */
2735 chtype attr
= A_NORMAL
;
2736 unsigned at_code
= 0;
2738 int fg
= COLOR_BLACK
;
2739 int bg
= COLOR_WHITE
;
2746 call_slk_color(fg
, bg
);
2756 MvAddStr(0, 20, "Soft Key Exerciser");
2771 MvPrintw(SLK_WORK
, 0, "Press Q to stop the scrolling-test: ");
2772 while ((c
= Getchar()) != 'Q' && (c
!= ERR
))
2800 MvAddStr(SLK_WORK
, 0, "Please enter the label value: ");
2802 if ((s
= slk_label(c
- '0')) != 0) {
2805 wGetstring(stdscr
, buf
, 8);
2806 slk_set((c
- '0'), buf
, fmt
);
2815 #if defined(NCURSES_VERSION) && defined(KEY_RESIZE) && HAVE_WRESIZE
2817 wnoutrefresh(stdscr
);
2822 if (cycle_attr(c
, &at_code
, &attr
)) {
2829 if (cycle_colors(c
, &fg
, &bg
, &pair
)) {
2831 call_slk_color(fg
, bg
);
2841 } while (!isQuit(c
= Getchar()));
2849 #if USE_WIDEC_SUPPORT
2853 /* exercise the soft keys */
2856 wchar_t buf
[SLKLEN
+ 1];
2858 chtype attr
= A_NORMAL
;
2859 unsigned at_code
= 0;
2860 int fg
= COLOR_BLACK
;
2861 int bg
= COLOR_WHITE
;
2866 call_slk_color(fg
, bg
);
2873 attr_on(WA_BOLD
, NULL
);
2874 MvAddStr(0, 20, "Soft Key Exerciser");
2875 attr_off(WA_BOLD
, NULL
);
2889 MvPrintw(SLK_WORK
, 0, "Press Q to stop the scrolling-test: ");
2890 while ((c
= Getchar()) != 'Q' && (c
!= ERR
))
2918 MvAddStr(SLK_WORK
, 0, "Please enter the label value: ");
2920 if ((s
= slk_label(c
- '0')) != 0) {
2921 char *temp
= strdup(s
);
2922 size_t used
= strlen(temp
);
2923 size_t want
= SLKLEN
;
2925 #ifndef state_unused
2930 while (want
> 0 && used
!= 0) {
2931 const char *base
= s
;
2932 reset_mbytes(state
);
2933 test
= count_mbytes(base
, 0, &state
);
2934 if (test
== (size_t) -1) {
2936 } else if (test
> want
) {
2939 reset_mbytes(state
);
2940 trans_mbytes(buf
, base
, want
, &state
);
2946 wGet_wstring(stdscr
, buf
, SLKLEN
);
2947 slk_wset((c
- '0'), buf
, fmt
);
2958 fg
= (short) ((fg
+ 1) % COLORS
);
2959 call_slk_color(fg
, bg
);
2964 bg
= (short) ((bg
+ 1) % COLORS
);
2965 call_slk_color(fg
, bg
);
2968 #if defined(NCURSES_VERSION) && defined(KEY_RESIZE) && HAVE_WRESIZE
2970 wnoutrefresh(stdscr
);
2974 if (cycle_attr(c
, &at_code
, &attr
)) {
2975 slk_attr_set(attr
, (fg
|| bg
), NULL
);
2981 if (cycle_colors(c
, &fg
, &bg
, &pair
)) {
2983 call_slk_color(fg
, bg
);
2993 } while (!isQuit(c
= Getchar()));
3001 #endif /* SLK_INIT */
3003 /* ISO 6429: codes 0x80 to 0x9f may be control characters that cause the
3004 * terminal to perform functions. The remaining codes can be graphic.
3007 show_upper_chars(unsigned first
, int repeat
, attr_t attr
, short pair
)
3009 bool C1
= (first
== 128);
3011 unsigned last
= first
+ 31;
3016 MvPrintw(0, 20, "Display of %s Character Codes %d to %d",
3017 C1
? "C1" : "GR", first
, last
);
3021 for (code
= first
; code
<= last
; code
++) {
3023 int row
= 2 + ((int) (code
- first
) % 16);
3024 int col
= ((int) (code
- first
) / 16) * COLS
/ 2;
3026 sprintf(tmp
, "%3u (0x%x)", code
, code
);
3027 MvPrintw(row
, col
, "%*s: ", COLS
/ 4, tmp
);
3031 nodelay(stdscr
, TRUE
);
3032 echochar(colored_chtype(code
, attr
, pair
));
3034 /* (yes, this _is_ crude) */
3035 while ((reply
= Getchar()) != ERR
) {
3036 addch(UChar(reply
));
3039 nodelay(stdscr
, FALSE
);
3041 } while (--count
> 0);
3048 show_pc_chars(int repeat
, attr_t attr
, short pair
)
3054 MvPrintw(0, 20, "Display of PC Character Codes");
3058 for (code
= 0; code
< 16; ++code
) {
3059 MvPrintw(2, (int) code
* PC_COLS
+ 8, "%X", code
);
3061 for (code
= 0; code
< 256; code
++) {
3063 int row
= 3 + (int) (code
/ 16) + (code
>= 128);
3064 int col
= 8 + (int) (code
% 16) * PC_COLS
;
3065 if ((code
% 16) == 0)
3066 MvPrintw(row
, 0, "0x%02x:", code
);
3077 * Skip the ones that do not work.
3081 addch(colored_chtype(code
, A_ALTCHARSET
| attr
, pair
));
3084 } while (--count
> 0);
3089 show_box_chars(int repeat
, attr_t attr
, short pair
)
3093 attr
|= (attr_t
) COLOR_PAIR(pair
);
3097 MvAddStr(0, 20, "Display of the ACS Line-Drawing Set");
3102 colored_chtype(ACS_VLINE
, attr
, pair
),
3103 colored_chtype(ACS_VLINE
, attr
, pair
),
3104 colored_chtype(ACS_HLINE
, attr
, pair
),
3105 colored_chtype(ACS_HLINE
, attr
, pair
),
3106 colored_chtype(ACS_ULCORNER
, attr
, pair
),
3107 colored_chtype(ACS_URCORNER
, attr
, pair
),
3108 colored_chtype(ACS_LLCORNER
, attr
, pair
),
3109 colored_chtype(ACS_LRCORNER
, attr
, pair
));
3110 MvHLine(LINES
/ 2, 0, colored_chtype(ACS_HLINE
, attr
, pair
), COLS
);
3111 MvVLine(0, COLS
/ 2, colored_chtype(ACS_VLINE
, attr
, pair
), LINES
);
3112 MvAddCh(0, COLS
/ 2, colored_chtype(ACS_TTEE
, attr
, pair
));
3113 MvAddCh(LINES
/ 2, COLS
/ 2, colored_chtype(ACS_PLUS
, attr
, pair
));
3114 MvAddCh(LINES
- 1, COLS
/ 2, colored_chtype(ACS_BTEE
, attr
, pair
));
3115 MvAddCh(LINES
/ 2, 0, colored_chtype(ACS_LTEE
, attr
, pair
));
3116 MvAddCh(LINES
/ 2, COLS
- 1, colored_chtype(ACS_RTEE
, attr
, pair
));
3122 show_1_acs(int n
, int repeat
, const char *name
, chtype code
)
3124 const int height
= 16;
3125 int row
= 2 + (n
% height
);
3126 int col
= (n
/ height
) * COLS
/ 2;
3128 MvPrintw(row
, col
, "%*s : ", COLS
/ 4, name
);
3131 } while (--repeat
> 0);
3136 show_acs_chars(int repeat
, attr_t attr
, short pair
)
3137 /* display the ACS character set */
3141 #define BOTH(name) #name, colored_chtype(name, attr, (chtype) pair)
3145 MvAddStr(0, 20, "Display of the ACS Character Set");
3149 n
= show_1_acs(0, repeat
, BOTH(ACS_ULCORNER
));
3150 n
= show_1_acs(n
, repeat
, BOTH(ACS_URCORNER
));
3151 n
= show_1_acs(n
, repeat
, BOTH(ACS_LLCORNER
));
3152 n
= show_1_acs(n
, repeat
, BOTH(ACS_LRCORNER
));
3154 n
= show_1_acs(n
, repeat
, BOTH(ACS_LTEE
));
3155 n
= show_1_acs(n
, repeat
, BOTH(ACS_RTEE
));
3156 n
= show_1_acs(n
, repeat
, BOTH(ACS_TTEE
));
3157 n
= show_1_acs(n
, repeat
, BOTH(ACS_BTEE
));
3159 n
= show_1_acs(n
, repeat
, BOTH(ACS_HLINE
));
3160 n
= show_1_acs(n
, repeat
, BOTH(ACS_VLINE
));
3163 * HPUX's ACS definitions are broken here. Just give up.
3165 #if !(defined(__hpux) && !defined(NCURSES_VERSION))
3166 n
= show_1_acs(n
, repeat
, BOTH(ACS_LARROW
));
3167 n
= show_1_acs(n
, repeat
, BOTH(ACS_RARROW
));
3168 n
= show_1_acs(n
, repeat
, BOTH(ACS_UARROW
));
3169 n
= show_1_acs(n
, repeat
, BOTH(ACS_DARROW
));
3171 n
= show_1_acs(n
, repeat
, BOTH(ACS_BLOCK
));
3172 n
= show_1_acs(n
, repeat
, BOTH(ACS_BOARD
));
3173 n
= show_1_acs(n
, repeat
, BOTH(ACS_LANTERN
));
3174 n
= show_1_acs(n
, repeat
, BOTH(ACS_BULLET
));
3175 n
= show_1_acs(n
, repeat
, BOTH(ACS_CKBOARD
));
3176 n
= show_1_acs(n
, repeat
, BOTH(ACS_DEGREE
));
3177 n
= show_1_acs(n
, repeat
, BOTH(ACS_DIAMOND
));
3178 n
= show_1_acs(n
, repeat
, BOTH(ACS_PLMINUS
));
3179 n
= show_1_acs(n
, repeat
, BOTH(ACS_PLUS
));
3181 n
= show_1_acs(n
, repeat
, BOTH(ACS_GEQUAL
));
3182 n
= show_1_acs(n
, repeat
, BOTH(ACS_NEQUAL
));
3183 n
= show_1_acs(n
, repeat
, BOTH(ACS_LEQUAL
));
3185 n
= show_1_acs(n
, repeat
, BOTH(ACS_STERLING
));
3186 n
= show_1_acs(n
, repeat
, BOTH(ACS_PI
));
3187 n
= show_1_acs(n
, repeat
, BOTH(ACS_S1
));
3188 n
= show_1_acs(n
, repeat
, BOTH(ACS_S3
));
3189 n
= show_1_acs(n
, repeat
, BOTH(ACS_S7
));
3190 (void) show_1_acs(n
, repeat
, BOTH(ACS_S9
));
3198 char *term
= getenv("TERM");
3199 const char *pch_kludge
= ((term
!= 0 && strstr(term
, "linux"))
3202 chtype attr
= A_NORMAL
;
3205 int fg
= COLOR_BLACK
;
3206 int bg
= COLOR_BLACK
;
3207 unsigned at_code
= 0;
3209 void (*last_show_acs
) (int, attr_t
, short) = 0;
3217 ToggleAcs(last_show_acs
, show_acs_chars
);
3221 ToggleAcs(last_show_acs
, show_pc_chars
);
3226 ToggleAcs(last_show_acs
, show_box_chars
);
3252 if (repeat
< (COLS
/ 4))
3260 if (cycle_attr(c
, &at_code
, &attr
)
3261 || cycle_colors(c
, &fg
, &bg
, &pair
)) {
3268 if (last_show_acs
!= 0)
3269 last_show_acs(repeat
, attr
, pair
);
3271 show_upper_chars((unsigned) (digit
* 32 + 128), repeat
, attr
, pair
);
3273 MvPrintw(LINES
- 3, 0,
3274 "Note: ANSI terminals may not display C1 characters.");
3275 MvPrintw(LINES
- 2, 0,
3276 "Select: a=ACS, x=box, %s0=C1, 1-3,+/- non-ASCII, </> repeat, ESC=quit",
3279 MvPrintw(LINES
- 1, 0,
3280 "v/V, f/F, b/B cycle through video attributes (%s) and color %d/%d.",
3281 attrs_to_cycle
[at_code
].name
,
3284 MvPrintw(LINES
- 1, 0,
3285 "v/V cycles through video attributes (%s).",
3286 attrs_to_cycle
[at_code
].name
);
3289 } while (!isQuit(c
= Getchar()));
3296 #if USE_WIDEC_SUPPORT
3298 merge_wide_attr(cchar_t
*dst
, const cchar_t
*src
, attr_t attr
, short pair
)
3304 TEST_CCHAR(src
, count
, {
3305 attr
|= (test_attrs
& A_ALTCHARSET
);
3306 setcchar(dst
, test_wch
, attr
, pair
, NULL
);
3316 show_upper_widechars(int first
, int repeat
, int space
, attr_t attr
, short pair
)
3320 int last
= first
+ 31;
3324 MvPrintw(0, 20, "Display of Character Codes %d to %d", first
, last
);
3327 for (code
= first
; (int) code
<= last
; code
++) {
3328 int row
= 2 + ((code
- first
) % 16);
3329 int col
= ((code
- first
) / 16) * COLS
/ 2;
3335 memset(&codes
, 0, sizeof(codes
));
3337 sprintf(tmp
, "%3ld (0x%lx)", (long) code
, (long) code
);
3338 MvPrintw(row
, col
, "%*s: ", COLS
/ 4, tmp
);
3339 setcchar(&temp
, codes
, attr
, pair
, 0);
3342 * Give non-spacing characters something to combine with. If we
3343 * don't, they'll bunch up in a heap on the space after the ":".
3344 * Mark them with reverse-video to make them simpler to find on
3347 if (wcwidth(code
) == 0) {
3348 addch((chtype
) space
|
3349 (A_REVERSE
^ attr
) |
3350 (attr_t
) COLOR_PAIR(pair
));
3353 * This could use add_wch(), but is done for comparison with the
3354 * normal 'f' test (and to make a test-case for echo_wchar()).
3355 * The screen will flicker because the erase() at the top of the
3356 * function is met by the builtin refresh() in echo_wchar().
3360 * The repeat-count may make text wrap - avoid that.
3362 getyx(stdscr
, y
, x
);
3363 if (x
>= col
+ (COLS
/ 2) - 2)
3365 } while (--count
> 0);
3370 show_1_wacs(int n
, int repeat
, const char *name
, const cchar_t
*code
)
3372 const int height
= 16;
3373 int row
= 2 + (n
% height
);
3374 int col
= (n
/ height
) * COLS
/ 2;
3376 MvPrintw(row
, col
, "%*s : ", COLS
/ 4, name
);
3377 while (--repeat
>= 0) {
3383 #define MERGE_ATTR(wch) merge_wide_attr(&temp, wch, attr, pair)
3386 show_wacs_chars(int repeat
, attr_t attr
, short pair
)
3387 /* display the wide-ACS character set */
3393 /*#define BOTH2(name) #name, &(name) */
3394 #define BOTH2(name) #name, MERGE_ATTR(name)
3398 MvAddStr(0, 20, "Display of the Wide-ACS Character Set");
3402 n
= show_1_wacs(0, repeat
, BOTH2(WACS_ULCORNER
));
3403 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_URCORNER
));
3404 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_LLCORNER
));
3405 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_LRCORNER
));
3407 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_LTEE
));
3408 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_RTEE
));
3409 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_TTEE
));
3410 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_BTEE
));
3412 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_HLINE
));
3413 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_VLINE
));
3415 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_LARROW
));
3416 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_RARROW
));
3417 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_UARROW
));
3418 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_DARROW
));
3420 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_BLOCK
));
3421 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_BOARD
));
3422 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_LANTERN
));
3423 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_BULLET
));
3424 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_CKBOARD
));
3425 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_DEGREE
));
3426 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_DIAMOND
));
3427 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_PLMINUS
));
3428 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_PLUS
));
3430 #ifdef CURSES_WACS_ARRAY
3431 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_GEQUAL
));
3432 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_NEQUAL
));
3433 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_LEQUAL
));
3435 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_STERLING
));
3436 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_PI
));
3437 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_S1
));
3438 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_S3
));
3439 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_S7
));
3440 (void) show_1_wacs(n
, repeat
, BOTH2(WACS_S9
));
3446 show_wacs_chars_double(int repeat
, attr_t attr
, short pair
)
3447 /* display the wide-ACS character set */
3453 /*#define BOTH2(name) #name, &(name) */
3454 #define BOTH2(name) #name, MERGE_ATTR(name)
3458 MvAddStr(0, 20, "Display of the Wide-ACS Character Set");
3462 n
= show_1_wacs(0, repeat
, BOTH2(WACS_D_ULCORNER
));
3463 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_D_URCORNER
));
3464 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_D_LLCORNER
));
3465 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_D_LRCORNER
));
3467 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_D_LTEE
));
3468 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_D_RTEE
));
3469 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_D_TTEE
));
3470 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_D_BTEE
));
3472 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_D_HLINE
));
3473 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_D_VLINE
));
3475 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_LARROW
));
3476 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_RARROW
));
3477 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_UARROW
));
3478 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_DARROW
));
3480 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_BLOCK
));
3481 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_BOARD
));
3482 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_LANTERN
));
3483 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_BULLET
));
3484 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_CKBOARD
));
3485 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_DEGREE
));
3486 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_DIAMOND
));
3487 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_PLMINUS
));
3488 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_PLUS
));
3490 #ifdef CURSES_WACS_ARRAY
3491 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_GEQUAL
));
3492 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_NEQUAL
));
3493 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_LEQUAL
));
3495 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_STERLING
));
3496 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_PI
));
3497 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_S1
));
3498 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_S3
));
3499 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_S7
));
3500 (void) show_1_wacs(n
, repeat
, BOTH2(WACS_S9
));
3507 show_wacs_chars_thick(int repeat
, attr_t attr
, short pair
)
3508 /* display the wide-ACS character set */
3514 /*#define BOTH2(name) #name, &(name) */
3515 #define BOTH2(name) #name, MERGE_ATTR(name)
3519 MvAddStr(0, 20, "Display of the Wide-ACS Character Set");
3523 n
= show_1_wacs(0, repeat
, BOTH2(WACS_T_ULCORNER
));
3524 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_T_URCORNER
));
3525 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_T_LLCORNER
));
3526 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_T_LRCORNER
));
3528 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_T_LTEE
));
3529 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_T_RTEE
));
3530 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_T_TTEE
));
3531 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_T_BTEE
));
3533 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_T_HLINE
));
3534 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_T_VLINE
));
3536 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_LARROW
));
3537 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_RARROW
));
3538 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_UARROW
));
3539 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_DARROW
));
3541 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_BLOCK
));
3542 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_BOARD
));
3543 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_LANTERN
));
3544 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_BULLET
));
3545 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_CKBOARD
));
3546 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_DEGREE
));
3547 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_DIAMOND
));
3548 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_PLMINUS
));
3549 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_PLUS
));
3551 #ifdef CURSES_WACS_ARRAY
3552 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_GEQUAL
));
3553 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_NEQUAL
));
3554 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_LEQUAL
));
3556 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_STERLING
));
3557 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_PI
));
3558 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_S1
));
3559 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_S3
));
3560 n
= show_1_wacs(n
, repeat
, BOTH2(WACS_S7
));
3561 (void) show_1_wacs(n
, repeat
, BOTH2(WACS_S9
));
3568 #define MERGE_ATTR(n,wch) merge_wide_attr(&temp[n], wch, attr, pair)
3571 show_wbox_chars(int repeat
, attr_t attr
, short pair
)
3578 MvAddStr(0, 20, "Display of the Wide-ACS Line-Drawing Set");
3583 MERGE_ATTR(0, WACS_VLINE
),
3584 MERGE_ATTR(1, WACS_VLINE
),
3585 MERGE_ATTR(2, WACS_HLINE
),
3586 MERGE_ATTR(3, WACS_HLINE
),
3587 MERGE_ATTR(4, WACS_ULCORNER
),
3588 MERGE_ATTR(5, WACS_URCORNER
),
3589 MERGE_ATTR(6, WACS_LLCORNER
),
3590 MERGE_ATTR(7, WACS_LRCORNER
));
3592 (void) mvhline_set(LINES
/ 2, 0, MERGE_ATTR(0, WACS_HLINE
), COLS
);
3593 (void) mvvline_set(0, COLS
/ 2, MERGE_ATTR(0, WACS_VLINE
), LINES
);
3594 (void) mvadd_wch(0, COLS
/ 2, MERGE_ATTR(0, WACS_TTEE
));
3595 (void) mvadd_wch(LINES
/ 2, COLS
/ 2, MERGE_ATTR(0, WACS_PLUS
));
3596 (void) mvadd_wch(LINES
- 1, COLS
/ 2, MERGE_ATTR(0, WACS_BTEE
));
3597 (void) mvadd_wch(LINES
/ 2, 0, MERGE_ATTR(0, WACS_LTEE
));
3598 (void) mvadd_wch(LINES
/ 2, COLS
- 1, MERGE_ATTR(0, WACS_RTEE
));
3606 show_2_wacs(int n
, const char *name
, const char *code
, attr_t attr
, short pair
)
3608 const int height
= 16;
3609 int row
= 2 + (n
% height
);
3610 int col
= (n
/ height
) * COLS
/ 2;
3613 MvPrintw(row
, col
, "%*s : ", COLS
/ 4, name
);
3614 (void) attr_set(attr
, pair
, 0);
3615 addstr(strcpy(temp
, code
));
3616 (void) attr_set(A_NORMAL
, 0, 0);
3620 #define SHOW_UTF8(n, name, code) show_2_wacs(n, name, code, attr, pair)
3623 show_utf8_chars(int repeat
, attr_t attr
, short pair
)
3630 MvAddStr(0, 20, "Display of the Wide-ACS Character Set");
3634 n
= SHOW_UTF8(0, "WACS_ULCORNER", "\342\224\214");
3635 n
= SHOW_UTF8(n
, "WACS_URCORNER", "\342\224\220");
3636 n
= SHOW_UTF8(n
, "WACS_LLCORNER", "\342\224\224");
3637 n
= SHOW_UTF8(n
, "WACS_LRCORNER", "\342\224\230");
3639 n
= SHOW_UTF8(n
, "WACS_LTEE", "\342\224\234");
3640 n
= SHOW_UTF8(n
, "WACS_RTEE", "\342\224\244");
3641 n
= SHOW_UTF8(n
, "WACS_TTEE", "\342\224\254");
3642 n
= SHOW_UTF8(n
, "WACS_BTEE", "\342\224\264");
3644 n
= SHOW_UTF8(n
, "WACS_HLINE", "\342\224\200");
3645 n
= SHOW_UTF8(n
, "WACS_VLINE", "\342\224\202");
3647 n
= SHOW_UTF8(n
, "WACS_LARROW", "\342\206\220");
3648 n
= SHOW_UTF8(n
, "WACS_RARROW", "\342\206\222");
3649 n
= SHOW_UTF8(n
, "WACS_UARROW", "\342\206\221");
3650 n
= SHOW_UTF8(n
, "WACS_DARROW", "\342\206\223");
3652 n
= SHOW_UTF8(n
, "WACS_BLOCK", "\342\226\256");
3653 n
= SHOW_UTF8(n
, "WACS_BOARD", "\342\226\222");
3654 n
= SHOW_UTF8(n
, "WACS_LANTERN", "\342\230\203");
3655 n
= SHOW_UTF8(n
, "WACS_BULLET", "\302\267");
3656 n
= SHOW_UTF8(n
, "WACS_CKBOARD", "\342\226\222");
3657 n
= SHOW_UTF8(n
, "WACS_DEGREE", "\302\260");
3658 n
= SHOW_UTF8(n
, "WACS_DIAMOND", "\342\227\206");
3659 n
= SHOW_UTF8(n
, "WACS_PLMINUS", "\302\261");
3660 n
= SHOW_UTF8(n
, "WACS_PLUS", "\342\224\274");
3661 n
= SHOW_UTF8(n
, "WACS_GEQUAL", "\342\211\245");
3662 n
= SHOW_UTF8(n
, "WACS_NEQUAL", "\342\211\240");
3663 n
= SHOW_UTF8(n
, "WACS_LEQUAL", "\342\211\244");
3665 n
= SHOW_UTF8(n
, "WACS_STERLING", "\302\243");
3666 n
= SHOW_UTF8(n
, "WACS_PI", "\317\200");
3667 n
= SHOW_UTF8(n
, "WACS_S1", "\342\216\272");
3668 n
= SHOW_UTF8(n
, "WACS_S3", "\342\216\273");
3669 n
= SHOW_UTF8(n
, "WACS_S7", "\342\216\274");
3670 (void) SHOW_UTF8(n
, "WACS_S9", "\342\216\275");
3675 /* display the wide-ACS character set */
3677 wide_acs_display(void)
3683 chtype attr
= A_NORMAL
;
3684 int fg
= COLOR_BLACK
;
3685 int bg
= COLOR_BLACK
;
3686 unsigned at_code
= 0;
3688 void (*last_show_wacs
) (int, attr_t
, short) = 0;
3696 ToggleAcs(last_show_wacs
, show_wacs_chars
);
3700 ToggleAcs(last_show_wacs
, show_wacs_chars_double
);
3705 ToggleAcs(last_show_wacs
, show_wacs_chars_thick
);
3709 ToggleAcs(last_show_wacs
, show_wbox_chars
);
3712 ToggleAcs(last_show_wacs
, show_utf8_chars
);
3715 if (c
< 256 && isdigit(c
)) {
3718 } else if (c
== '+') {
3721 } else if (c
== '-' && digit
> 0) {
3724 } else if (c
== '>' && repeat
< (COLS
/ 4)) {
3726 } else if (c
== '<' && repeat
> 1) {
3728 } else if (c
== '_') {
3729 space
= (space
== ' ') ? '_' : ' ';
3731 } else if (cycle_attr(c
, &at_code
, &attr
)
3732 || cycle_colors(c
, &fg
, &bg
, &pair
)) {
3733 if (last_show_wacs
!= 0)
3741 if (last_show_wacs
!= 0)
3742 last_show_wacs(repeat
, attr
, pair
);
3744 show_upper_widechars(digit
* 32 + 128, repeat
, space
, attr
, pair
);
3746 MvPrintw(LINES
- 3, 0,
3747 "Select: a/d/t WACS, x box, u UTF-8, 0-9,+/- non-ASCII, </> repeat, ESC=quit");
3749 MvPrintw(LINES
- 2, 0,
3750 "v/V, f/F, b/B cycle through video attributes (%s) and color %d/%d.",
3751 attrs_to_cycle
[at_code
].name
,
3754 MvPrintw(LINES
- 2, 0,
3755 "v/V cycles through video attributes (%s).",
3756 attrs_to_cycle
[at_code
].name
);
3759 } while (!isQuit(c
= Getchar()));
3769 * Graphic-rendition test (adapted from vttest)
3772 test_sgr_attributes(void)
3776 for (pass
= 0; pass
< 2; pass
++) {
3777 chtype normal
= ((pass
== 0 ? A_NORMAL
: A_REVERSE
)) | BLANK
;
3779 /* Use non-default colors if possible to exercise bce a little */
3781 init_pair(1, COLOR_WHITE
, COLOR_BLUE
);
3782 normal
|= COLOR_PAIR(1);
3786 MvPrintw(1, 20, "Graphic rendition test pattern:");
3788 MvPrintw(4, 1, "vanilla");
3790 #define set_sgr(mask) bkgdset((normal^(mask)));
3792 MvPrintw(4, 40, "bold");
3794 set_sgr(A_UNDERLINE
);
3795 MvPrintw(6, 6, "underline");
3797 set_sgr(A_BOLD
| A_UNDERLINE
);
3798 MvPrintw(6, 45, "bold underline");
3801 MvPrintw(8, 1, "blink");
3803 set_sgr(A_BLINK
| A_BOLD
);
3804 MvPrintw(8, 40, "bold blink");
3806 set_sgr(A_UNDERLINE
| A_BLINK
);
3807 MvPrintw(10, 6, "underline blink");
3809 set_sgr(A_BOLD
| A_UNDERLINE
| A_BLINK
);
3810 MvPrintw(10, 45, "bold underline blink");
3813 MvPrintw(12, 1, "negative");
3815 set_sgr(A_BOLD
| A_REVERSE
);
3816 MvPrintw(12, 40, "bold negative");
3818 set_sgr(A_UNDERLINE
| A_REVERSE
);
3819 MvPrintw(14, 6, "underline negative");
3821 set_sgr(A_BOLD
| A_UNDERLINE
| A_REVERSE
);
3822 MvPrintw(14, 45, "bold underline negative");
3824 set_sgr(A_BLINK
| A_REVERSE
);
3825 MvPrintw(16, 1, "blink negative");
3827 set_sgr(A_BOLD
| A_BLINK
| A_REVERSE
);
3828 MvPrintw(16, 40, "bold blink negative");
3830 set_sgr(A_UNDERLINE
| A_BLINK
| A_REVERSE
);
3831 MvPrintw(18, 6, "underline blink negative");
3833 set_sgr(A_BOLD
| A_UNDERLINE
| A_BLINK
| A_REVERSE
);
3834 MvPrintw(18, 45, "bold underline blink negative");
3837 MvPrintw(LINES
- 2, 1, "%s background. ", pass
== 0 ? "Dark" :
3843 bkgdset(A_NORMAL
| BLANK
);
3848 /****************************************************************************
3850 * Windows and scrolling tester.
3852 ****************************************************************************/
3854 #define BOTLINES 4 /* number of line stolen from screen bottom */
3860 #define FRAME struct frame
3869 #if defined(NCURSES_VERSION)
3870 #if (NCURSES_VERSION_PATCH < 20070331) && NCURSES_EXT_FUNCS
3871 #define is_keypad(win) (win)->_use_keypad
3872 #define is_scrollok(win) (win)->_scroll
3873 #elif !defined(is_keypad)
3874 #define is_keypad(win) FALSE
3875 #define is_scrollok(win) FALSE
3878 #define is_keypad(win) FALSE
3879 #define is_scrollok(win) FALSE
3883 frame_win(FRAME
* curp
)
3885 return (curp
!= 0) ? curp
->wind
: stdscr
;
3888 /* We need to know if these flags are actually set, so don't look in FRAME.
3889 * These names are known to work with SVr4 curses as well as ncurses. The
3890 * _use_keypad name does not work with Solaris 8.
3893 HaveKeypad(FRAME
* curp
)
3895 WINDOW
*win
= frame_win(curp
);
3897 return is_keypad(win
);
3901 HaveScroll(FRAME
* curp
)
3903 WINDOW
*win
= frame_win(curp
);
3905 return is_scrollok(win
);
3909 newwin_legend(FRAME
* curp
)
3911 static const struct {
3916 "^C = create window", 0
3919 "^N = next window", 0
3922 "^P = previous window", 0
3925 "^F = scroll forward", 0
3928 "^B = scroll backward", 0
3931 "^K = keypad(%s)", 1
3934 "^S = scrollok(%s)", 2
3937 "^W = save window to file", 0
3940 "^R = restore window", 0
3953 bool do_keypad
= HaveKeypad(curp
);
3954 bool do_scroll
= HaveScroll(curp
);
3958 for (n
= 0; n
< SIZEOF(legend
); n
++) {
3959 switch (legend
[n
].code
) {
3961 strcpy(buf
, legend
[n
].msg
);
3964 sprintf(buf
, legend
[n
].msg
, do_keypad
? "yes" : "no");
3967 sprintf(buf
, legend
[n
].msg
, do_scroll
? "yes" : "no");
3970 sprintf(buf
, legend
[n
].msg
, do_keypad
? "/ESC" : "");
3973 x
= getcurx(stdscr
);
3974 addstr((COLS
< (x
+ 3 + (int) strlen(buf
))) ? "\n" : (n
? ", " : ""));
3981 transient(FRAME
* curp
, NCURSES_CONST
char *msg
)
3983 newwin_legend(curp
);
3985 MvAddStr(LINES
- 1, 0, msg
);
3991 printw("%s characters are echoed, window should %sscroll.",
3992 HaveKeypad(curp
) ? "Non-arrow" : "All other",
3993 HaveScroll(curp
) ? "" : "not ");
3998 newwin_report(FRAME
* curp
)
3999 /* report on the cursor's current position, then restore it */
4001 WINDOW
*win
= frame_win(curp
);
4005 transient(curp
, (char *) 0);
4007 move(LINES
- 1, COLS
- 17);
4008 printw("Y = %2d X = %2d", y
, x
);
4016 selectcell(int uli
, int ulj
, int lri
, int lrj
)
4017 /* arrows keys move cursor, return location at current on non-arrow key */
4019 static pair res
; /* result cell */
4020 int si
= lri
- uli
+ 1; /* depth of the select area */
4021 int sj
= lrj
- ulj
+ 1; /* width of the select area */
4022 int i
= 0, j
= 0; /* offsets into the select area */
4027 move(uli
+ i
, ulj
+ j
);
4028 newwin_report((FRAME
*) 0);
4030 switch (Getchar()) {
4044 return ((pair
*) 0);
4045 #ifdef NCURSES_MOUSE_VERSION
4051 if (event
.y
> uli
&& event
.x
> ulj
) {
4072 outerbox(pair ul
, pair lr
, bool onoff
)
4073 /* draw or erase a box *outside* the given pair of corners */
4075 MvAddCh(ul
.y
- 1, lr
.x
- 1, onoff
? ACS_ULCORNER
: ' ');
4076 MvAddCh(ul
.y
- 1, lr
.x
+ 1, onoff
? ACS_URCORNER
: ' ');
4077 MvAddCh(lr
.y
+ 1, lr
.x
+ 1, onoff
? ACS_LRCORNER
: ' ');
4078 MvAddCh(lr
.y
+ 1, ul
.x
- 1, onoff
? ACS_LLCORNER
: ' ');
4079 move(ul
.y
- 1, ul
.x
);
4080 hline(onoff
? ACS_HLINE
: ' ', lr
.x
- ul
.x
+ 1);
4081 move(ul
.y
, ul
.x
- 1);
4082 vline(onoff
? ACS_VLINE
: ' ', lr
.y
- ul
.y
+ 1);
4083 move(lr
.y
+ 1, ul
.x
);
4084 hline(onoff
? ACS_HLINE
: ' ', lr
.x
- ul
.x
+ 1);
4085 move(ul
.y
, lr
.x
+ 1);
4086 vline(onoff
? ACS_VLINE
: ' ', lr
.y
- ul
.y
+ 1);
4091 /* Ask user for a window definition */
4098 addstr("Use arrows to move cursor, anything else to mark corner 1");
4100 if ((tmp
= selectcell(2, 1, LINES
- BOTLINES
- 2, COLS
- 2)) == (pair
*) 0)
4101 return ((WINDOW
*) 0);
4102 memcpy(&ul
, tmp
, sizeof(pair
));
4103 MvAddCh(ul
.y
- 1, ul
.x
- 1, ACS_ULCORNER
);
4106 addstr("Use arrows to move cursor, anything else to mark corner 2");
4108 if ((tmp
= selectcell(ul
.y
, ul
.x
, LINES
- BOTLINES
- 2, COLS
- 2)) ==
4110 return ((WINDOW
*) 0);
4111 memcpy(&lr
, tmp
, sizeof(pair
));
4113 rwindow
= subwin(stdscr
, lr
.y
- ul
.y
+ 1, lr
.x
- ul
.x
+ 1, ul
.y
, ul
.x
);
4115 outerbox(ul
, lr
, TRUE
);
4126 newwin_move(FRAME
* curp
, int dy
, int dx
)
4128 WINDOW
*win
= frame_win(curp
);
4132 getyx(win
, cur_y
, cur_x
);
4133 getmaxyx(win
, max_y
, max_x
);
4134 if ((cur_x
+= dx
) < 0)
4136 else if (cur_x
>= max_x
)
4138 if ((cur_y
+= dy
) < 0)
4140 else if (cur_y
>= max_y
)
4142 wmove(win
, cur_y
, cur_x
);
4146 delete_framed(FRAME
* fp
, bool showit
)
4151 fp
->last
->next
= fp
->next
;
4152 fp
->next
->last
= fp
->last
;
4160 np
= (fp
== fp
->next
) ? 0 : fp
->next
;
4167 acs_and_scroll(void)
4168 /* Demonstrate windows */
4171 FRAME
*current
= (FRAME
*) 0, *neww
;
4173 #if HAVE_PUTWIN && HAVE_GETWIN
4177 #define DUMPFILE "screendump"
4179 #ifdef NCURSES_MOUSE_VERSION
4180 mousemask(BUTTON1_CLICKED
, (mmask_t
*) 0);
4185 transient((FRAME
*) 0, (char *) 0);
4188 if ((neww
= typeCalloc(FRAME
, 1)) == 0) {
4191 if ((neww
->wind
= getwindow()) == (WINDOW
*) 0) {
4196 if (current
== 0) { /* First element, */
4197 neww
->next
= neww
; /* so point it at itself */
4200 neww
->next
= current
->next
;
4201 neww
->last
= current
;
4202 neww
->last
->next
= neww
;
4203 neww
->next
->last
= neww
;
4206 /* SVr4 curses sets the keypad on all newly-created windows to
4207 * false. Someone reported that PDCurses makes new windows inherit
4208 * this flag. Remove the following 'keypad()' call to test this
4210 keypad(current
->wind
, TRUE
);
4211 current
->do_keypad
= HaveKeypad(current
);
4212 current
->do_scroll
= HaveScroll(current
);
4215 case CTRL('N'): /* go to next window */
4217 current
= current
->next
;
4220 case CTRL('P'): /* go to previous window */
4222 current
= current
->last
;
4225 case CTRL('F'): /* scroll current window forward */
4227 wscrl(frame_win(current
), 1);
4230 case CTRL('B'): /* scroll current window backwards */
4232 wscrl(frame_win(current
), -1);
4235 case CTRL('K'): /* toggle keypad mode for current */
4237 current
->do_keypad
= !current
->do_keypad
;
4238 keypad(current
->wind
, current
->do_keypad
);
4244 current
->do_scroll
= !current
->do_scroll
;
4245 scrollok(current
->wind
, current
->do_scroll
);
4249 #if HAVE_PUTWIN && HAVE_GETWIN
4250 case CTRL('W'): /* save and delete window */
4251 if ((current
!= 0) && (current
== current
->next
)) {
4252 transient(current
, "Will not save/delete ONLY window");
4254 } else if ((fp
= fopen(DUMPFILE
, "w")) == (FILE *) 0) {
4255 transient(current
, "Can't open screen dump file");
4257 (void) putwin(frame_win(current
), fp
);
4260 current
= delete_framed(current
, TRUE
);
4264 case CTRL('R'): /* restore window */
4265 if ((fp
= fopen(DUMPFILE
, "r")) == (FILE *) 0) {
4266 transient(current
, "Can't open screen dump file");
4268 if ((neww
= typeCalloc(FRAME
, 1)) != 0) {
4270 neww
->next
= current
? current
->next
: 0;
4271 neww
->last
= current
;
4272 neww
->last
->next
= neww
;
4273 neww
->next
->last
= neww
;
4275 neww
->wind
= getwin(fp
);
4277 wrefresh(neww
->wind
);
4285 case CTRL('X'): /* resize window */
4292 addstr("Use arrows to move cursor, anything else to mark new corner");
4295 getbegyx(current
->wind
, ul
.y
, ul
.x
);
4297 tmp
= selectcell(ul
.y
, ul
.x
, LINES
- BOTLINES
- 2, COLS
- 2);
4298 if (tmp
== (pair
*) 0) {
4303 getmaxyx(current
->wind
, lr
.y
, lr
.x
);
4306 outerbox(ul
, lr
, FALSE
);
4307 wnoutrefresh(stdscr
);
4309 /* strictly cosmetic hack for the test */
4310 getmaxyx(current
->wind
, my
, mx
);
4311 if (my
> tmp
->y
- ul
.y
) {
4312 getyx(current
->wind
, lr
.y
, lr
.x
);
4313 wmove(current
->wind
, tmp
->y
- ul
.y
+ 1, 0);
4314 wclrtobot(current
->wind
);
4315 wmove(current
->wind
, lr
.y
, lr
.x
);
4317 if (mx
> tmp
->x
- ul
.x
)
4318 for (i
= 0; i
< my
; i
++) {
4319 wmove(current
->wind
, i
, tmp
->x
- ul
.x
+ 1);
4320 wclrtoeol(current
->wind
);
4322 wnoutrefresh(current
->wind
);
4324 memcpy(&lr
, tmp
, sizeof(pair
));
4325 (void) wresize(current
->wind
, lr
.y
- ul
.y
+ 0, lr
.x
- ul
.x
+ 0);
4327 getbegyx(current
->wind
, ul
.y
, ul
.x
);
4328 getmaxyx(current
->wind
, lr
.y
, lr
.x
);
4331 outerbox(ul
, lr
, TRUE
);
4332 wnoutrefresh(stdscr
);
4334 wnoutrefresh(current
->wind
);
4340 #endif /* HAVE_WRESIZE */
4342 case KEY_F(10): /* undocumented --- use this to test area clears */
4343 selectcell(0, 0, LINES
- 1, COLS
- 1);
4349 newwin_move(current
, -1, 0);
4352 newwin_move(current
, 1, 0);
4355 newwin_move(current
, 0, -1);
4358 newwin_move(current
, 0, 1);
4366 getyx(frame_win(current
), y
, x
);
4370 x
= getmaxx(frame_win(current
)) - 1;
4372 (void) mvwdelch(frame_win(current
), y
, x
);
4382 waddch(current
->wind
, (chtype
) c
);
4387 newwin_report(current
);
4388 usescr
= frame_win(current
);
4391 (!isQuit(c
= wGetchar(usescr
))
4395 while (current
!= 0)
4396 current
= delete_framed(current
, FALSE
);
4398 scrollok(stdscr
, TRUE
); /* reset to driver's default */
4399 #ifdef NCURSES_MOUSE_VERSION
4400 mousemask(0, (mmask_t
*) 0);
4407 /****************************************************************************
4411 ****************************************************************************/
4414 static int nap_msec
= 1;
4416 static NCURSES_CONST
char *mod
[] =
4426 /*+-------------------------------------------------------------------------
4428 --------------------------------------------------------------------------*/
4430 wait_a_while(int msec GCC_UNUSED
)
4440 else if (msec
> 1000)
4441 sleep((unsigned) msec
/ 1000);
4445 } /* end of wait_a_while */
4447 /*+-------------------------------------------------------------------------
4449 --------------------------------------------------------------------------*/
4451 saywhat(NCURSES_CONST
char *text
)
4453 wmove(stdscr
, LINES
- 1, 0);
4455 if (text
!= 0 && *text
!= '\0') {
4456 waddstr(stdscr
, text
);
4457 waddstr(stdscr
, "; ");
4459 waddstr(stdscr
, "press any key to continue");
4460 } /* end of saywhat */
4462 /*+-------------------------------------------------------------------------
4463 mkpanel(rows,cols,tly,tlx) - alloc a win and panel and associate them
4464 --------------------------------------------------------------------------*/
4466 mkpanel(short color
, int rows
, int cols
, int tly
, int tlx
)
4471 if ((win
= newwin(rows
, cols
, tly
, tlx
)) != 0) {
4472 if ((pan
= new_panel(win
)) == 0) {
4474 } else if (use_colors
) {
4475 short fg
= (short) ((color
== COLOR_BLUE
) ? COLOR_WHITE
: COLOR_BLACK
);
4478 init_pair(color
, fg
, bg
);
4479 wbkgdset(win
, (attr_t
) (COLOR_PAIR(color
) | ' '));
4481 wbkgdset(win
, A_BOLD
| ' ');
4485 } /* end of mkpanel */
4487 /*+-------------------------------------------------------------------------
4489 --------------------------------------------------------------------------*/
4491 rmpanel(PANEL
* pan
)
4493 WINDOW
*win
= panel_window(pan
);
4496 } /* end of rmpanel */
4498 /*+-------------------------------------------------------------------------
4500 --------------------------------------------------------------------------*/
4506 } /* end of pflush */
4508 /*+-------------------------------------------------------------------------
4510 --------------------------------------------------------------------------*/
4516 for (y
= 0; y
< LINES
- 1; y
++) {
4517 for (x
= 0; x
< COLS
; x
++)
4518 wprintw(stdscr
, "%d", (y
+ x
) % 10);
4523 fill_panel(PANEL
* pan
)
4525 WINDOW
*win
= panel_window(pan
);
4526 const char *userptr
= (const char *) panel_userptr(pan
);
4527 int num
= (userptr
&& *userptr
) ? userptr
[1] : '?';
4531 wprintw(win
, "-pan%c-", num
);
4534 for (y
= 2; y
< getmaxy(win
) - 1; y
++) {
4535 for (x
= 1; x
< getmaxx(win
) - 1; x
++) {
4537 waddch(win
, UChar(num
));
4542 #if USE_WIDEC_SUPPORT
4544 init_wide_panel(void)
4549 for (digit
= 0; digit
< 10; ++digit
)
4550 make_fullwidth_digit(&temp
[digit
], digit
);
4554 getyx(stdscr
, y
, x
);
4555 digit
= (y
+ x
/ 2) % 10;
4556 } while (add_wch(&temp
[digit
]) != ERR
);
4560 fill_wide_panel(PANEL
* pan
)
4562 WINDOW
*win
= panel_window(pan
);
4563 const char *userptr
= (const char *) panel_userptr(pan
);
4564 int num
= (userptr
&& *userptr
) ? userptr
[1] : '?';
4568 wprintw(win
, "-pan%c-", num
);
4571 for (y
= 2; y
< getmaxy(win
) - 1; y
++) {
4572 for (x
= 1; x
< getmaxx(win
) - 1; x
++) {
4574 waddch(win
, UChar(num
));
4580 #define MAX_PANELS 5
4583 canned_panel(PANEL
* px
[MAX_PANELS
+ 1], NCURSES_CONST
char *cmd
)
4585 int which
= cmd
[1] - '0';
4590 hide_panel(px
[which
]);
4593 show_panel(px
[which
]);
4596 top_panel(px
[which
]);
4599 bottom_panel(px
[which
]);
4606 wait_a_while(nap_msec
);
4610 demo_panels(void (*InitPanel
) (void), void (*FillPanel
) (PANEL
*))
4614 PANEL
*px
[MAX_PANELS
+ 1];
4616 scrollok(stdscr
, FALSE
); /* we don't want stdscr to scroll! */
4620 for (count
= 0; count
< 5; count
++) {
4621 px
[1] = mkpanel(COLOR_RED
,
4626 set_panel_userptr(px
[1], (NCURSES_CONST
void *) "p1");
4628 px
[2] = mkpanel(COLOR_GREEN
,
4633 set_panel_userptr(px
[2], (NCURSES_CONST
void *) "p2");
4635 px
[3] = mkpanel(COLOR_YELLOW
,
4640 set_panel_userptr(px
[3], (NCURSES_CONST
void *) "p3");
4642 px
[4] = mkpanel(COLOR_BLUE
,
4647 set_panel_userptr(px
[4], (NCURSES_CONST
void *) "p4");
4649 px
[5] = mkpanel(COLOR_MAGENTA
,
4654 set_panel_userptr(px
[5], (NCURSES_CONST
void *) "p5");
4666 wait_a_while(nap_msec
);
4668 saywhat("h3 s1 s2 s4 s5");
4669 move_panel(px
[1], 0, 0);
4676 wait_a_while(nap_msec
);
4678 canned_panel(px
, "s1");
4679 canned_panel(px
, "s2");
4682 move_panel(px
[2], LINES
/ 3 + 1, COLS
/ 8);
4684 wait_a_while(nap_msec
);
4686 canned_panel(px
, "s3");
4689 move_panel(px
[3], LINES
/ 4 + 1, COLS
/ 15);
4691 wait_a_while(nap_msec
);
4693 canned_panel(px
, "b3");
4694 canned_panel(px
, "s4");
4695 canned_panel(px
, "s5");
4696 canned_panel(px
, "t3");
4697 canned_panel(px
, "t1");
4698 canned_panel(px
, "t2");
4699 canned_panel(px
, "t3");
4700 canned_panel(px
, "t4");
4702 for (itmp
= 0; itmp
< 6; itmp
++) {
4703 WINDOW
*w4
= panel_window(px
[4]);
4704 WINDOW
*w5
= panel_window(px
[5]);
4707 wmove(w4
, LINES
/ 8, 1);
4708 waddstr(w4
, mod
[itmp
]);
4709 move_panel(px
[4], LINES
/ 6, itmp
* (COLS
/ 8));
4710 wmove(w5
, LINES
/ 6, 1);
4711 waddstr(w5
, mod
[itmp
]);
4713 wait_a_while(nap_msec
);
4716 wmove(w4
, LINES
/ 6, 1);
4717 waddstr(w4
, mod
[itmp
]);
4718 move_panel(px
[5], LINES
/ 3 - 1, (itmp
* 10) + 6);
4719 wmove(w5
, LINES
/ 8, 1);
4720 waddstr(w5
, mod
[itmp
]);
4722 wait_a_while(nap_msec
);
4726 move_panel(px
[4], LINES
/ 6, itmp
* (COLS
/ 8));
4728 wait_a_while(nap_msec
);
4730 canned_panel(px
, "t5");
4731 canned_panel(px
, "t2");
4732 canned_panel(px
, "t1");
4733 canned_panel(px
, "d2");
4734 canned_panel(px
, "h3");
4735 canned_panel(px
, "d1");
4736 canned_panel(px
, "d4");
4737 canned_panel(px
, "d5");
4738 canned_panel(px
, "d3");
4740 wait_a_while(nap_msec
);
4749 #endif /* USE_LIBPANEL */
4751 /****************************************************************************
4755 ****************************************************************************/
4759 static bool pending_pan
= FALSE
;
4760 static bool show_panner_legend
= TRUE
;
4763 panner_legend(int line
)
4765 static const char *const legend
[] =
4767 "Use arrow keys (or U,D,L,R) to pan, ESC to quit, ! to shell-out.",
4768 "Use +,- (or j,k) to grow/shrink the panner vertically.",
4769 "Use <,> (or h,l) to grow/shrink the panner horizontally.",
4770 "Number repeats. Toggle legend:? filler:a timer:t scrollmark:s."
4772 int n
= ((int) SIZEOF(legend
) - (LINES
- line
));
4774 if (move(line
, 0) != ERR
) {
4775 if (show_panner_legend
)
4776 printw("%s", legend
[n
]);
4778 return show_panner_legend
;
4785 panner_h_cleanup(int from_y
, int from_x
, int to_x
)
4787 if (!panner_legend(from_y
))
4788 do_h_line(from_y
, from_x
, ' ', to_x
);
4792 panner_v_cleanup(int from_y
, int from_x
, int to_y
)
4794 if (!panner_legend(from_y
))
4795 do_v_line(from_y
, from_x
, ' ', to_y
);
4799 fill_pad(WINDOW
*panpad
, bool pan_lines
)
4802 unsigned gridcount
= 0;
4804 wmove(panpad
, 0, 0);
4805 for (y
= 0; y
< getmaxy(panpad
); y
++) {
4806 for (x
= 0; x
< getmaxx(panpad
); x
++) {
4807 if (y
% GRIDSIZE
== 0 && x
% GRIDSIZE
== 0) {
4808 if (y
== 0 && x
== 0)
4809 waddch(panpad
, pan_lines
? ACS_ULCORNER
: '+');
4811 waddch(panpad
, pan_lines
? ACS_TTEE
: '+');
4812 else if (y
== 0 || x
== 0)
4813 waddch(panpad
, pan_lines
? ACS_LTEE
: '+');
4815 waddch(panpad
, (chtype
) ((pan_lines
? 'a' : 'A') +
4816 (int) (gridcount
++ % 26)));
4817 } else if (y
% GRIDSIZE
== 0)
4818 waddch(panpad
, pan_lines
? ACS_HLINE
: '-');
4819 else if (x
% GRIDSIZE
== 0)
4820 waddch(panpad
, pan_lines
? ACS_VLINE
: '|');
4822 waddch(panpad
, ' ');
4829 int top_x
, int top_y
, int porty
, int portx
,
4830 int (*pgetc
) (WINDOW
*))
4832 #if HAVE_GETTIMEOFDAY
4833 struct timeval before
, after
;
4836 bool pan_lines
= FALSE
;
4837 bool scrollers
= TRUE
;
4840 int pxmax
, pymax
, lowend
, highend
, c
;
4842 getmaxyx(pad
, pymax
, pxmax
);
4843 scrollok(stdscr
, FALSE
); /* we don't want stdscr to scroll! */
4847 #ifdef NCURSES_VERSION
4849 * During shell-out, the user may have resized the window. Adjust
4850 * the port size of the pad to accommodate this. Ncurses automatically
4851 * resizes all of the normal windows to fit on the new screen.
4869 show_panner_legend
= !show_panner_legend
;
4870 panner_legend(LINES
- 4);
4871 panner_legend(LINES
- 3);
4872 panner_legend(LINES
- 2);
4873 panner_legend(LINES
- 1);
4876 pan_lines
= !pan_lines
;
4877 fill_pad(pad
, pan_lines
);
4878 pending_pan
= FALSE
;
4881 #if HAVE_GETTIMEOFDAY
4885 panner_legend(LINES
- 1);
4889 scrollers
= !scrollers
;
4892 /* Move the top-left corner of the pad, keeping the bottom-right
4895 case 'h': /* increase-columns: move left edge to left */
4899 panner_v_cleanup(top_y
, top_x
, porty
);
4904 case 'j': /* decrease-lines: move top-edge down */
4908 panner_h_cleanup(top_y
- 1, top_x
- (top_x
> 0), portx
);
4913 case 'k': /* increase-lines: move top-edge up */
4918 panner_h_cleanup(top_y
, top_x
, portx
);
4922 case 'l': /* decrease-columns: move left-edge to right */
4926 panner_v_cleanup(top_y
- (top_y
> 0), top_x
- 1, porty
);
4931 /* Move the bottom-right corner of the pad, keeping the top-left
4934 case KEY_IC
: /* increase-columns: move right-edge to right */
4935 if (portx
>= pxmax
|| portx
>= COLS
)
4938 panner_v_cleanup(top_y
- (top_y
> 0), portx
- 1, porty
);
4943 case KEY_IL
: /* increase-lines: move bottom-edge down */
4944 if (porty
>= pymax
|| porty
>= LINES
)
4947 panner_h_cleanup(porty
- 1, top_x
- (top_x
> 0), portx
);
4952 case KEY_DC
: /* decrease-columns: move bottom edge up */
4957 panner_v_cleanup(top_y
- (top_y
> 0), portx
, porty
);
4961 case KEY_DL
: /* decrease-lines */
4966 panner_h_cleanup(porty
, top_x
- (top_x
> 0), portx
);
4970 case KEY_LEFT
: /* pan leftwards */
4977 case KEY_RIGHT
: /* pan rightwards */
4978 if (basex
+ portx
- (pymax
> porty
) < pxmax
)
4984 case KEY_UP
: /* pan upwards */
4991 case KEY_DOWN
: /* pan downwards */
4992 if (basey
+ porty
- (pxmax
> portx
) < pymax
)
5007 basey
= pymax
- porty
;
5017 MvAddCh(top_y
- 1, top_x
- 1, ACS_ULCORNER
);
5018 do_v_line(top_y
, top_x
- 1, ACS_VLINE
, porty
);
5019 do_h_line(top_y
- 1, top_x
, ACS_HLINE
, portx
);
5021 if (scrollers
&& (pxmax
> portx
- 1)) {
5022 int length
= (portx
- top_x
- 1);
5023 float ratio
= ((float) length
) / ((float) pxmax
);
5025 lowend
= (int) ((float) top_x
+ ((float) basex
* ratio
));
5026 highend
= (int) ((float) top_x
+ ((float) (basex
+ length
) * ratio
));
5028 do_h_line(porty
- 1, top_x
, ACS_HLINE
, lowend
);
5029 if (highend
< portx
) {
5031 do_h_line(porty
- 1, lowend
, ' ', highend
+ 1);
5033 do_h_line(porty
- 1, highend
+ 1, ACS_HLINE
, portx
);
5036 do_h_line(porty
- 1, top_x
, ACS_HLINE
, portx
);
5038 if (scrollers
&& (pymax
> porty
- 1)) {
5039 int length
= (porty
- top_y
- 1);
5040 float ratio
= ((float) length
) / ((float) pymax
);
5042 lowend
= (int) ((float) top_y
+ ((float) basey
* ratio
));
5043 highend
= (int) ((float) top_y
+ ((float) (basey
+ length
) * ratio
));
5045 do_v_line(top_y
, portx
- 1, ACS_VLINE
, lowend
);
5046 if (highend
< porty
) {
5048 do_v_line(lowend
, portx
- 1, ' ', highend
+ 1);
5050 do_v_line(highend
+ 1, portx
- 1, ACS_VLINE
, porty
);
5053 do_v_line(top_y
, portx
- 1, ACS_VLINE
, porty
);
5055 MvAddCh(top_y
- 1, portx
- 1, ACS_URCORNER
);
5056 MvAddCh(porty
- 1, top_x
- 1, ACS_LLCORNER
);
5057 MvAddCh(porty
- 1, portx
- 1, ACS_LRCORNER
);
5060 #if HAVE_GETTIMEOFDAY
5061 gettimeofday(&before
, 0);
5063 wnoutrefresh(stdscr
);
5068 porty
- (pxmax
> portx
) - 1,
5069 portx
- (pymax
> porty
) - 1);
5072 #if HAVE_GETTIMEOFDAY
5073 #define TIMEVAL2S(data) ((double) data.tv_sec + ((double) data.tv_usec / 1.0e6))
5076 gettimeofday(&after
, 0);
5077 elapsed
= (TIMEVAL2S(after
) - TIMEVAL2S(before
));
5078 move(LINES
- 1, COLS
- 12);
5079 printw("Secs: %2.03f", elapsed
);
5086 ((c
= pgetc(pad
)) != KEY_EXIT
);
5088 scrollok(stdscr
, TRUE
); /* reset to driver's default */
5092 padgetch(WINDOW
*win
)
5098 if ((pending_pan
= (count
> 0)) != FALSE
) {
5100 pending_pan
= (count
!= 0);
5103 switch (c
= wGetchar(win
)) {
5139 case ERR
: /* FALLTHRU */
5145 if (c
>= '0' && c
<= '9') {
5146 count
= count
* 10 + (c
- '0');
5160 #define PAD_HIGH 200
5161 #define PAD_WIDE 200
5165 /* Demonstrate pads. */
5167 WINDOW
*panpad
= newpad(PAD_HIGH
, PAD_WIDE
);
5170 Cannot("cannot create requested pad");
5174 fill_pad(panpad
, FALSE
);
5176 panner_legend(LINES
- 4);
5177 panner_legend(LINES
- 3);
5178 panner_legend(LINES
- 2);
5179 panner_legend(LINES
- 1);
5181 keypad(panpad
, TRUE
);
5183 /* Make the pad (initially) narrow enough that a trace file won't wrap.
5184 * We'll still be able to widen it during a test, since that's required
5185 * for testing boundaries.
5187 panner(panpad
, 2, 2, LINES
- 5, COLS
- 15, padgetch
);
5194 /****************************************************************************
5196 * Tests from John Burnell's PDCurses tester
5198 ****************************************************************************/
5201 Continue(WINDOW
*win
)
5205 MvWAddStr(win
, 10, 1, " Press any key to continue");
5211 flushinp_test(WINDOW
*win
)
5212 /* Input test, adapted from John Burnell's PDCurses tester */
5214 int w
, h
, bx
, by
, sw
, sh
, i
;
5219 getmaxyx(win
, h
, w
);
5220 getbegyx(win
, by
, bx
);
5223 if ((subWin
= subwin(win
, sh
, sw
, by
+ h
- sh
- 2, bx
+ w
- sw
- 2)) == 0)
5228 init_pair(2, COLOR_CYAN
, COLOR_BLUE
);
5229 wbkgd(subWin
, COLOR_PAIR(2) | ' ');
5232 (void) wattrset(subWin
, A_BOLD
);
5233 box(subWin
, ACS_VLINE
, ACS_HLINE
);
5234 MvWAddStr(subWin
, 2, 1, "This is a subwindow");
5238 * This used to set 'nocbreak()'. However, Alexander Lukyanov says that
5239 * it only happened to "work" on SVr4 because that implementation does not
5240 * emulate nocbreak+noecho mode, whereas ncurses does. To get the desired
5241 * test behavior, we're using 'cbreak()', which will allow a single
5242 * character to return without needing a newline. - T.Dickey 1997/10/11.
5245 MvWAddStr(win
, 0, 1, "This is a test of the flushinp() call.");
5247 MvWAddStr(win
, 2, 1, "Type random keys for 5 seconds.");
5248 MvWAddStr(win
, 3, 1,
5249 "These should be discarded (not echoed) after the subwindow goes away.");
5252 for (i
= 0; i
< 5; i
++) {
5253 MvWPrintw(subWin
, 1, 1, "Time = %d", i
);
5265 MvWAddStr(win
, 2, 1,
5266 "If you were still typing when the window timer expired,");
5267 MvWAddStr(win
, 3, 1,
5268 "or else you typed nothing at all while it was running,");
5269 MvWAddStr(win
, 4, 1,
5270 "test was invalid. You'll see garbage or nothing at all. ");
5271 MvWAddStr(win
, 6, 1, "Press a key");
5277 MvWAddStr(win
, 12, 0,
5278 "If you see any key other than what you typed, flushinp() is broken.");
5287 "What you typed should now have been deleted; if not, wdelch() failed.");
5293 /****************************************************************************
5297 ****************************************************************************/
5305 menu_virtualize(int c
)
5307 if (c
== '\n' || c
== KEY_EXIT
)
5308 return (MAX_COMMAND
+ 1);
5310 return (REQ_SCR_ULINE
);
5312 return (REQ_SCR_DLINE
);
5313 else if (c
== 'b' || c
== KEY_NPAGE
)
5314 return (REQ_SCR_UPAGE
);
5315 else if (c
== 'f' || c
== KEY_PPAGE
)
5316 return (REQ_SCR_DPAGE
);
5317 else if (c
== 'n' || c
== KEY_DOWN
)
5318 return (REQ_NEXT_ITEM
);
5319 else if (c
== 'p' || c
== KEY_UP
)
5320 return (REQ_PREV_ITEM
);
5322 return (REQ_TOGGLE_ITEM
);
5330 static CONST_MENUS
char *animals
[] =
5343 "Lions, Tigers, Bears, (Oh my!), Newts, Platypi, Lemurs",
5344 "Lions, Tigers, Bears, (Oh my!), Newts, Platypi, Lemurs, Lions, Tigers, Bears, (Oh my!), Newts, Platypi, Lemurs",
5352 ITEM
*items
[SIZEOF(animals
)];
5354 CONST_MENUS
char **ap
;
5355 int mrows
, mcols
, c
;
5358 #ifdef NCURSES_MOUSE_VERSION
5359 mousemask(ALL_MOUSE_EVENTS
, (mmask_t
*) 0);
5361 MvAddStr(0, 0, "This is the menu test:");
5362 MvAddStr(2, 0, " Use up and down arrow to move the select bar.");
5363 MvAddStr(3, 0, " 'n' and 'p' act like arrows.");
5365 " 'b' and 'f' scroll up/down (page), 'u' and 'd' (line).");
5366 MvAddStr(5, 0, " Press return to exit.");
5369 for (ap
= animals
; *ap
; ap
++) {
5370 if ((*ip
= new_item(*ap
, "")) != 0)
5375 m
= new_menu(items
);
5377 set_menu_format(m
, (SIZEOF(animals
) + 1) / 2, 1);
5378 scale_menu(m
, &mrows
, &mcols
);
5380 menuwin
= newwin(mrows
+ 2, mcols
+ 2, MENU_Y
, MENU_X
);
5381 set_menu_win(m
, menuwin
);
5382 keypad(menuwin
, TRUE
);
5385 set_menu_sub(m
, derwin(menuwin
, mrows
, mcols
, 1, 1));
5389 while ((c
= menu_driver(m
, menu_virtualize(wGetchar(menuwin
)))) != E_UNKNOWN_COMMAND
) {
5390 if (c
== E_NOT_POSTED
)
5392 if (c
== E_REQUEST_DENIED
)
5397 MvPrintw(LINES
- 2, 0,
5398 "You chose: %s\n", item_name(current_item(m
)));
5399 (void) addstr("Press any key to continue...");
5406 for (ip
= items
; *ip
; ip
++)
5408 #ifdef NCURSES_MOUSE_VERSION
5409 mousemask(0, (mmask_t
*) 0);
5414 #define T_TBL(name) { #name, name }
5420 T_TBL(TRACE_DISABLE
),
5423 T_TBL(TRACE_UPDATE
),
5425 T_TBL(TRACE_CHARPUT
),
5426 T_TBL(TRACE_ORDINARY
),
5428 T_TBL(TRACE_VIRTPUT
),
5429 T_TBL(TRACE_IEVENT
),
5431 T_TBL(TRACE_ICALLS
),
5432 T_TBL(TRACE_CCALLS
),
5433 T_TBL(TRACE_DATABASE
),
5435 T_TBL(TRACE_MAXIMUM
),
5442 tracetrace(unsigned tlevel
)
5449 for (n
= 0; t_tbl
[n
].name
!= 0; n
++)
5450 need
+= strlen(t_tbl
[n
].name
) + 2;
5451 buf
= typeMalloc(char, need
);
5453 sprintf(buf
, "0x%02x = {", tlevel
);
5455 sprintf(buf
+ strlen(buf
), "%s, ", t_tbl
[0].name
);
5457 for (n
= 1; t_tbl
[n
].name
!= 0; n
++)
5458 if ((tlevel
& t_tbl
[n
].mask
) == t_tbl
[n
].mask
) {
5459 strcat(buf
, t_tbl
[n
].name
);
5463 if (buf
[strlen(buf
) - 2] == ',')
5464 buf
[strlen(buf
) - 2] = '\0';
5465 return (strcat(buf
, "}"));
5468 /* fake a dynamically reconfigurable menu using the 0th entry to deselect
5472 run_trace_menu(MENU
* m
)
5478 bool changed
= FALSE
;
5479 switch (menu_driver(m
, menu_virtualize(wGetchar(menu_win(m
))))) {
5480 case E_UNKNOWN_COMMAND
:
5483 items
= menu_items(m
);
5484 i
= current_item(m
);
5485 if (i
== items
[0]) {
5486 if (item_value(i
)) {
5487 for (p
= items
+ 1; *p
!= 0; p
++)
5488 if (item_value(*p
)) {
5489 set_item_value(*p
, FALSE
);
5494 for (p
= items
+ 1; *p
!= 0; p
++)
5495 if (item_value(*p
)) {
5496 set_item_value(items
[0], FALSE
);
5509 /* interactively set the trace level */
5512 ITEM
*items
[SIZEOF(t_tbl
)];
5519 MvAddStr(0, 0, "Interactively set trace level:");
5520 MvAddStr(2, 0, " Press space bar to toggle a selection.");
5521 MvAddStr(3, 0, " Use up and down arrow to move the select bar.");
5522 MvAddStr(4, 0, " Press return to set the trace level.");
5523 MvPrintw(6, 0, "(Current trace level is %s)", tracetrace(_nc_tracing
));
5527 for (n
= 0; t_tbl
[n
].name
!= 0; n
++) {
5528 if ((*ip
= new_item(t_tbl
[n
].name
, "")) != 0) {
5534 m
= new_menu(items
);
5536 set_menu_format(m
, 0, 2);
5537 scale_menu(m
, &mrows
, &mcols
);
5539 menu_opts_off(m
, O_ONEVALUE
);
5540 menuwin
= newwin(mrows
+ 2, mcols
+ 2, MENU_Y
, MENU_X
);
5541 set_menu_win(m
, menuwin
);
5542 keypad(menuwin
, TRUE
);
5545 set_menu_sub(m
, derwin(menuwin
, mrows
, mcols
, 1, 1));
5549 for (ip
= menu_items(m
); *ip
; ip
++) {
5550 unsigned mask
= t_tbl
[item_index(*ip
)].mask
;
5552 set_item_value(*ip
, _nc_tracing
== 0);
5553 else if ((mask
& _nc_tracing
) == mask
)
5554 set_item_value(*ip
, TRUE
);
5557 while (run_trace_menu(m
))
5561 for (ip
= menu_items(m
); *ip
; ip
++)
5562 if (item_value(*ip
))
5563 newtrace
|= t_tbl
[item_index(*ip
)].mask
;
5565 Trace(("trace level interactively set to %s", tracetrace(_nc_tracing
)));
5567 MvPrintw(LINES
- 2, 0,
5568 "Trace level is %s\n", tracetrace(_nc_tracing
));
5569 (void) addstr("Press any key to continue...");
5576 for (ip
= items
; *ip
; ip
++)
5580 #endif /* USE_LIBMENU */
5582 /****************************************************************************
5586 ****************************************************************************/
5589 make_label(int frow
, int fcol
, NCURSES_CONST
char *label
)
5591 FIELD
*f
= new_field(1, (int) strlen(label
), frow
, fcol
, 0, 0);
5594 set_field_buffer(f
, 0, label
);
5595 set_field_opts(f
, (int) ((unsigned) field_opts(f
) & ~O_ACTIVE
));
5601 make_field(int frow
, int fcol
, int rows
, int cols
, bool secure
)
5603 FIELD
*f
= new_field(rows
, cols
, frow
, fcol
, 0, secure
? 1 : 0);
5606 set_field_back(f
, A_UNDERLINE
);
5607 set_field_userptr(f
, (void *) 0);
5613 display_form(FORM
* f
)
5618 scale_form(f
, &rows
, &cols
);
5620 if ((w
= newwin(rows
+ 2, cols
+ 4, 0, 0)) != (WINDOW
*) 0) {
5622 set_form_sub(f
, derwin(w
, rows
, cols
, 1, 2));
5627 if (post_form(f
) != E_OK
)
5632 erase_form(FORM
* f
)
5634 WINDOW
*w
= form_win(f
);
5635 WINDOW
*s
= form_sub(f
);
5645 edit_secure(FIELD
* me
, int c
)
5647 int rows
, cols
, frow
, fcol
, nrow
, nbuf
;
5649 if (field_info(me
, &rows
, &cols
, &frow
, &fcol
, &nrow
, &nbuf
) == E_OK
5651 char *source
= field_buffer(me
, 1);
5655 strcpy(temp
, source
? source
: "");
5656 len
= (long) (char *) field_userptr(me
);
5658 if (isgraph(c
) && (len
+ 1) < (int) sizeof(temp
)) {
5659 temp
[len
++] = (char) c
;
5661 set_field_buffer(me
, 1, temp
);
5681 case REQ_RIGHT_CHAR
:
5683 c
= 0; /* we don't want to do inline editing */
5688 set_field_buffer(me
, 1, temp
);
5695 set_field_buffer(me
, 1, temp
);
5700 set_field_userptr(me
, (void *) len
);
5706 form_virtualize(FORM
* f
, WINDOW
*w
)
5709 static const struct {
5713 { CTRL('A'), REQ_NEXT_CHOICE
},
5714 { CTRL('B'), REQ_PREV_WORD
},
5715 { CTRL('C'), REQ_CLR_EOL
},
5716 { CTRL('D'), REQ_DOWN_FIELD
},
5717 { CTRL('E'), REQ_END_FIELD
},
5718 { CTRL('F'), REQ_NEXT_PAGE
},
5719 { CTRL('G'), REQ_DEL_WORD
},
5720 { CTRL('H'), REQ_DEL_PREV
},
5721 { CTRL('I'), REQ_INS_CHAR
},
5722 { CTRL('K'), REQ_CLR_EOF
},
5723 { CTRL('L'), REQ_LEFT_FIELD
},
5724 { CTRL('M'), REQ_NEW_LINE
},
5725 { CTRL('N'), REQ_NEXT_FIELD
},
5726 { CTRL('O'), REQ_INS_LINE
},
5727 { CTRL('P'), REQ_PREV_FIELD
},
5728 { CTRL('R'), REQ_RIGHT_FIELD
},
5729 { CTRL('S'), REQ_BEG_FIELD
},
5730 { CTRL('U'), REQ_UP_FIELD
},
5731 { CTRL('V'), REQ_DEL_CHAR
},
5732 { CTRL('W'), REQ_NEXT_WORD
},
5733 { CTRL('X'), REQ_CLR_FIELD
},
5734 { CTRL('Y'), REQ_DEL_LINE
},
5735 { CTRL('Z'), REQ_PREV_CHOICE
},
5736 { ESCAPE
, MAX_FORM_COMMAND
+ 1 },
5737 { KEY_BACKSPACE
, REQ_DEL_PREV
},
5738 { KEY_DOWN
, REQ_DOWN_CHAR
},
5739 { KEY_END
, REQ_LAST_FIELD
},
5740 { KEY_HOME
, REQ_FIRST_FIELD
},
5741 { KEY_LEFT
, REQ_LEFT_CHAR
},
5742 { KEY_LL
, REQ_LAST_FIELD
},
5743 { KEY_NEXT
, REQ_NEXT_FIELD
},
5744 { KEY_NPAGE
, REQ_NEXT_PAGE
},
5745 { KEY_PPAGE
, REQ_PREV_PAGE
},
5746 { KEY_PREVIOUS
, REQ_PREV_FIELD
},
5747 { KEY_RIGHT
, REQ_RIGHT_CHAR
},
5748 { KEY_UP
, REQ_UP_CHAR
},
5749 { QUIT
, MAX_FORM_COMMAND
+ 1 }
5753 static int mode
= REQ_INS_MODE
;
5754 int c
= wGetchar(w
);
5756 FIELD
*me
= current_field(f
);
5757 bool current
= TRUE
;
5759 if (c
== CTRL(']')) {
5760 if (mode
== REQ_INS_MODE
) {
5761 mode
= REQ_OVL_MODE
;
5763 mode
= REQ_INS_MODE
;
5767 for (n
= 0; n
< SIZEOF(lookup
); n
++) {
5768 if (lookup
[n
].code
== c
) {
5769 c
= lookup
[n
].result
;
5774 MvPrintw(0, COLS
- 6, "(%s)", mode
== REQ_INS_MODE
? "INS" : "OVL");
5777 * Force the field that the user is typing into to be in reverse video,
5778 * while the other fields are shown underlined.
5793 case REQ_LEFT_FIELD
:
5795 case REQ_RIGHT_CHAR
:
5799 current
= (c
< KEY_MAX
);
5803 c
= edit_secure(me
, c
);
5804 set_field_back(me
, A_REVERSE
);
5806 c
= edit_secure(me
, c
);
5807 set_field_back(me
, A_UNDERLINE
);
5813 my_form_driver(FORM
* form
, int c
)
5815 if (c
== (MAX_FORM_COMMAND
+ 1)
5816 && form_driver(form
, REQ_VALIDATION
) == E_OK
)
5824 #ifdef NCURSES_VERSION
5825 #define FIELDCHECK_CB(func) bool func(FIELD * fld, const void * data GCC_UNUSED)
5826 #define CHAR_CHECK_CB(func) bool func(int ch, const void *data GCC_UNUSED)
5828 #define FIELDCHECK_CB(func) int func(FIELD * fld, char * data GCC_UNUSED)
5829 #define CHAR_CHECK_CB(func) int func(int ch, char *data GCC_UNUSED)
5833 * Allow a middle initial, optionally with a '.' to end it.
5836 FIELDCHECK_CB(mi_field_check
)
5838 char *s
= field_buffer(fld
, 0);
5842 for (n
= 0; s
[n
] != '\0'; ++n
) {
5849 } else if (isspace(UChar(s
[n
]))) {
5854 if (!isspace(UChar(s
[n
])))
5860 /* force the form to display a leading capital */
5861 if (islower(UChar(s
[0]))) {
5862 s
[0] = (char) toupper(UChar(s
[0]));
5863 set_field_buffer(fld
, 0, s
);
5869 CHAR_CHECK_CB(mi_char_check
)
5871 return ((isalpha(ch
) || ch
== '.') ? TRUE
: FALSE
);
5875 * Passwords should be at least 6 characters.
5878 FIELDCHECK_CB(pw_field_check
)
5880 char *s
= field_buffer(fld
, 0);
5883 for (n
= 0; s
[n
] != '\0'; ++n
) {
5884 if (isspace(UChar(s
[n
]))) {
5893 CHAR_CHECK_CB(pw_char_check
)
5895 return (isgraph(ch
) ? TRUE
: FALSE
);
5903 FIELD
*f
[12], *secure
;
5904 FIELDTYPE
*fty_middle
= new_fieldtype(mi_field_check
, mi_char_check
);
5905 FIELDTYPE
*fty_passwd
= new_fieldtype(pw_field_check
, pw_char_check
);
5906 int finished
= 0, c
;
5909 #ifdef NCURSES_MOUSE_VERSION
5910 mousemask(ALL_MOUSE_EVENTS
, (mmask_t
*) 0);
5914 addstr("Defined edit/traversal keys: ^Q/ESC- exit form\n");
5915 addstr("^N -- go to next field ^P -- go to previous field\n");
5916 addstr("Home -- go to first field End -- go to last field\n");
5917 addstr("^L -- go to field to left ^R -- go to field to right\n");
5918 addstr("^U -- move upward to field ^D -- move downward to field\n");
5919 addstr("^W -- go to next word ^B -- go to previous word\n");
5920 addstr("^S -- go to start of field ^E -- go to end of field\n");
5921 addstr("^H -- delete previous char ^Y -- delete line\n");
5922 addstr("^G -- delete current word ^C -- clear to end of line\n");
5923 addstr("^K -- clear to end of field ^X -- clear field\n");
5924 addstr("Arrow keys move within a field as you would expect. ^] toggles overlay mode.");
5926 MvAddStr(4, 57, "Forms Entry Test");
5930 /* describe the form */
5931 memset(f
, 0, sizeof(f
));
5932 f
[n
++] = make_label(0, 15, "Sample Form");
5934 f
[n
++] = make_label(2, 0, "Last Name");
5935 f
[n
++] = make_field(3, 0, 1, 18, FALSE
);
5936 set_field_type(f
[n
- 1], TYPE_ALPHA
, 1);
5938 f
[n
++] = make_label(2, 20, "First Name");
5939 f
[n
++] = make_field(3, 20, 1, 12, FALSE
);
5940 set_field_type(f
[n
- 1], TYPE_ALPHA
, 1);
5942 f
[n
++] = make_label(2, 34, "Middle Name");
5943 f
[n
++] = make_field(3, 34, 1, 12, FALSE
);
5944 set_field_type(f
[n
- 1], fty_middle
);
5946 f
[n
++] = make_label(5, 0, "Comments");
5947 f
[n
++] = make_field(6, 0, 4, 46, FALSE
);
5949 f
[n
++] = make_label(5, 20, "Password:");
5951 f
[n
++] = make_field(5, 30, 1, 9, TRUE
);
5952 set_field_type(f
[n
- 1], fty_passwd
);
5955 if ((form
= new_form(f
)) != 0) {
5961 nonl(); /* lets us read ^M's */
5963 switch (form_driver(form
, c
= form_virtualize(form
, w
))) {
5965 MvAddStr(5, 57, field_buffer(secure
, 1));
5969 case E_UNKNOWN_COMMAND
:
5970 finished
= my_form_driver(form
, c
);
5982 for (c
= 0; f
[c
] != 0; c
++)
5984 free_fieldtype(fty_middle
);
5985 free_fieldtype(fty_passwd
);
5989 #ifdef NCURSES_MOUSE_VERSION
5990 mousemask(ALL_MOUSE_EVENTS
, (mmask_t
*) 0);
5993 #endif /* USE_LIBFORM */
5995 /****************************************************************************
5999 ****************************************************************************/
6002 fillwin(WINDOW
*win
, char ch
)
6007 getmaxyx(win
, y1
, x1
);
6008 for (y
= 0; y
< y1
; y
++) {
6010 for (x
= 0; x
< x1
; x
++)
6011 waddch(win
, UChar(ch
));
6016 crosswin(WINDOW
*win
, char ch
)
6021 getmaxyx(win
, y1
, x1
);
6022 for (y
= 0; y
< y1
; y
++) {
6023 for (x
= 0; x
< x1
; x
++)
6024 if (((x
> (x1
- 1) / 3) && (x
<= (2 * (x1
- 1)) / 3))
6025 || (((y
> (y1
- 1) / 3) && (y
<= (2 * (y1
- 1)) / 3)))) {
6027 waddch(win
, UChar(ch
));
6032 #define OVERLAP_FLAVORS 5
6035 overlap_helpitem(int state
, int item
, char *message
)
6037 int row
= (item
/ 2);
6038 int col
= ((item
% 2) ? COLS
/ 2 : 0);
6040 move(LINES
- 6 + row
, col
);
6041 printw("%c%c = %s", state
== row
? '>' : ' ', 'a' + item
, message
);
6046 overlap_test_1_attr(WINDOW
*win
, int flavor
, int col
)
6048 short cpair
= (short) (1 + (flavor
* 2) + col
);
6052 (void) wattrset(win
, A_NORMAL
);
6055 (void) wattrset(win
, A_BOLD
);
6058 init_pair(cpair
, COLOR_BLUE
, COLOR_WHITE
);
6059 (void) wattrset(win
, (attr_t
) COLOR_PAIR(cpair
) | A_NORMAL
);
6062 init_pair(cpair
, COLOR_WHITE
, COLOR_BLUE
);
6063 (void) wattrset(win
, (attr_t
) COLOR_PAIR(cpair
) | A_BOLD
);
6069 overlap_test_2_attr(WINDOW
*win
, int flavor
, int col
)
6071 short cpair
= (short) (9 + (flavor
* 2) + col
);
6081 init_pair(cpair
, COLOR_RED
, COLOR_GREEN
);
6082 wbkgdset(win
, colored_chtype(' ', A_BLINK
, cpair
));
6085 wbkgdset(win
, ' ' | A_NORMAL
);
6091 overlap_help(int state
, int flavors
[OVERLAP_FLAVORS
])
6096 const char *ths
, *tht
;
6100 state
+= OVERLAP_FLAVORS
;
6101 state
= state
% OVERLAP_FLAVORS
;
6102 assert(state
>= 0 && state
< OVERLAP_FLAVORS
);
6104 for (item
= 0; item
< (2 * OVERLAP_FLAVORS
); ++item
) {
6107 ths
= col
? "B" : "A";
6108 tht
= col
? "A" : "B";
6113 sprintf(msg
, "refresh %s, then %s, then doupdate.", ths
, tht
);
6121 overlap_test_1_attr(stdscr
, flavors
[row
], col
);
6122 sprintf(msg
, "fill window %s with letter %s.", ths
, ths
);
6130 switch (flavors
[row
]) {
6132 sprintf(msg
, "cross pattern in window %s.", ths
);
6135 sprintf(msg
, "draw box in window %s.", ths
);
6138 sprintf(msg
, "set background of window %s.", ths
);
6141 sprintf(msg
, "reset background of window %s.", ths
);
6147 sprintf(msg
, "clear window %s.", ths
);
6151 switch (flavors
[row
]) {
6153 sprintf(msg
, "overwrite %s onto %s.", ths
, tht
);
6156 sprintf(msg
, "copywin(FALSE) %s onto %s.", ths
, tht
);
6159 sprintf(msg
, "copywin(TRUE) %s onto %s.", ths
, tht
);
6162 sprintf(msg
, "overlay %s onto %s.", ths
, tht
);
6167 overlap_helpitem(state
, item
, msg
);
6168 (void) wattrset(stdscr
, A_NORMAL
);
6169 wbkgdset(stdscr
, ' ' | A_NORMAL
);
6172 printw("^Q/ESC = terminate test. Up/down/space select test variations (%d %d).",
6173 state
, flavors
[state
]);
6179 overlap_test_0(WINDOW
*a
, WINDOW
*b
)
6189 overlap_test_1(int flavor
, int col
, WINDOW
*a
, char fill
)
6191 overlap_test_1_attr(a
, flavor
, col
);
6193 (void) wattrset(a
, A_NORMAL
);
6197 overlap_test_2(int flavor
, int col
, WINDOW
*a
, char fill
)
6199 overlap_test_2_attr(a
, flavor
, col
);
6208 /* done in overlap_test_2_attr */
6211 /* done in overlap_test_2_attr */
6217 overlap_test_3(WINDOW
*a
)
6224 overlap_test_4(int flavor
, WINDOW
*a
, WINDOW
*b
)
6231 copywin(a
, b
, 0, 0, 0, 0, getmaxy(b
), getmaxx(b
), FALSE
);
6234 copywin(a
, b
, 0, 0, 0, 0, getmaxy(b
), getmaxx(b
), TRUE
);
6242 /* test effects of overlapping windows */
6247 int state
, flavor
[OVERLAP_FLAVORS
];
6249 WINDOW
*win1
= newwin(9, 20, 3, 3);
6250 WINDOW
*win2
= newwin(9, 20, 9, 16);
6256 printw("This test shows the behavior of wnoutrefresh() with respect to\n");
6257 printw("the shared region of two overlapping windows A and B. The cross\n");
6258 printw("pattern in each window does not overlap the other.\n");
6260 memset(flavor
, 0, sizeof(flavor
));
6261 state
= overlap_help(0, flavor
);
6263 while (!isQuit(ch
= Getchar()))
6265 case 'a': /* refresh window A first, then B */
6266 overlap_test_0(win1
, win2
);
6269 case 'b': /* refresh window B first, then A */
6270 overlap_test_0(win2
, win1
);
6273 case 'c': /* fill window A so it's visible */
6274 overlap_test_1(flavor
[1], 0, win1
, 'A');
6277 case 'd': /* fill window B so it's visible */
6278 overlap_test_1(flavor
[1], 1, win2
, 'B');
6281 case 'e': /* cross test pattern in window A */
6282 overlap_test_2(flavor
[2], 0, win1
, 'A');
6285 case 'f': /* cross test pattern in window A */
6286 overlap_test_2(flavor
[2], 1, win2
, 'B');
6289 case 'g': /* clear window A */
6290 overlap_test_3(win1
);
6293 case 'h': /* clear window B */
6294 overlap_test_3(win2
);
6297 case 'i': /* overwrite A onto B */
6298 overlap_test_4(flavor
[4], win1
, win2
);
6301 case 'j': /* overwrite B onto A */
6302 overlap_test_4(flavor
[4], win2
, win1
);
6307 state
= overlap_help(state
+ 1, flavor
);
6312 state
= overlap_help(state
- 1, flavor
);
6317 state
= overlap_help(state
, flavor
);
6321 state
= overlap_help(state
, flavor
);
6336 /****************************************************************************
6340 ****************************************************************************/
6343 do_single_test(const char c
)
6344 /* perform a single specified test */
6351 #if USE_WIDEC_SUPPORT
6361 #if USE_WIDEC_SUPPORT
6369 Cannot("does not support color.");
6374 #if USE_WIDEC_SUPPORT
6377 Cannot("does not support color.");
6385 Cannot("does not support color.");
6386 else if (!can_change_color())
6387 Cannot("has hardwired color values.");
6397 #if USE_WIDEC_SUPPORT
6408 #if USE_WIDEC_SUPPORT
6416 demo_panels(init_panel
, fill_panel
);
6420 #if USE_WIDEC_SUPPORT && USE_LIBPANEL
6422 demo_panels(init_wide_panel
, fill_wide_panel
);
6431 flushinp_test(stdscr
);
6435 test_sgr_attributes();
6458 #if USE_LIBMENU && defined(TRACE)
6477 static const char *const tbl
[] =
6479 "Usage: ncurses [options]"
6482 #ifdef NCURSES_VERSION
6483 ," -a f,b set default-colors (assumed white-on-black)"
6484 ," -d use default-colors if terminal supports them"
6487 ," -e fmt specify format for soft-keys test (e)"
6490 ," -f rip-off footer line (can repeat)"
6491 ," -h rip-off header line (can repeat)"
6493 ," -m do not use colors"
6494 ," -p file rgb values to use in 'd' rather than ncurses's builtin"
6496 ," -s msec specify nominal time for panel-demo (default: 1, to hold)"
6499 ," -t mask specify default trace-level (may toggle with ^T)"
6503 for (n
= 0; n
< SIZEOF(tbl
); n
++)
6504 fprintf(stderr
, "%s\n", tbl
[n
]);
6505 ExitProgram(EXIT_FAILURE
);
6509 set_terminal_modes(void)
6514 scrollok(stdscr
, TRUE
);
6515 idlok(stdscr
, TRUE
);
6516 keypad(stdscr
, TRUE
);
6521 announce_sig(int sig
)
6523 (void) fprintf(stderr
, "Handled signal %d\r\n", sig
);
6529 rip_footer(WINDOW
*win
, int cols
)
6531 wbkgd(win
, A_REVERSE
);
6534 wprintw(win
, "footer: window %p, %d columns", (void *) win
, cols
);
6540 rip_header(WINDOW
*win
, int cols
)
6542 wbkgd(win
, A_REVERSE
);
6545 wprintw(win
, "header: window %p, %d columns", (void *) win
, cols
);
6549 #endif /* HAVE_RIPOFFLINE */
6557 (void) puts("This is the ncurses main menu");
6558 (void) puts("a = keyboard and mouse input test");
6559 #if USE_WIDEC_SUPPORT
6560 (void) puts("A = wide-character keyboard and mouse input test");
6562 (void) puts("b = character attribute test");
6563 #if USE_WIDEC_SUPPORT
6564 (void) puts("B = wide-character attribute test");
6566 (void) puts("c = color test pattern");
6567 #if USE_WIDEC_SUPPORT
6568 (void) puts("C = color test pattern using wide-character calls");
6571 (void) puts("d = edit RGB color values");
6573 (void) puts("e = exercise soft keys");
6574 #if USE_WIDEC_SUPPORT
6575 (void) puts("E = exercise soft keys using wide-characters");
6578 (void) puts("f = display ACS characters");
6579 #if USE_WIDEC_SUPPORT
6580 (void) puts("F = display Wide-ACS characters");
6582 (void) puts("g = display windows and scrolling");
6583 (void) puts("i = test of flushinp()");
6584 (void) puts("k = display character attributes");
6586 (void) puts("m = menu code test");
6589 (void) puts("o = exercise panels library");
6590 #if USE_WIDEC_SUPPORT
6591 (void) puts("O = exercise panels with wide-characters");
6594 (void) puts("p = exercise pad features");
6595 (void) puts("q = quit");
6597 (void) puts("r = exercise forms code");
6599 (void) puts("s = overlapping-refresh test");
6600 #if USE_LIBMENU && defined(TRACE)
6601 (void) puts("t = set trace level");
6603 (void) puts("? = repeat this command summary");
6605 (void) fputs("> ", stdout
);
6606 (void) fflush(stdout
); /* necessary under SVr4 curses */
6609 * This used to be an 'fgets()' call (until 1996/10). However with
6610 * some runtime libraries, mixing stream I/O and 'read()' causes the
6611 * input stream to be flushed when switching between the two.
6616 if (read(fileno(stdin
), &ch
, 1) <= 0) {
6620 } else if (command
== 0 && !isspace(UChar(ch
))) {
6622 } else if (ch
== '\n' || ch
== '\r') {
6623 if ((command
== 'd') && !top
) {
6624 (void) fputs("Do not nest test-d\n", stdout
);
6629 (void) fputs("> ", stdout
);
6630 (void) fflush(stdout
);
6634 if (do_single_test(command
)) {
6636 * This may be overkill; it's intended to reset everything back
6637 * to the initial terminal modes so that tests don't get in
6641 set_terminal_modes();
6646 if (command
== '?') {
6647 (void) puts("This is the ncurses capability tester.");
6649 puts("You may select a test from the main menu by typing the");
6651 puts("key letter of the choice (the letter to left of the =)");
6653 puts("at the > prompt. Type `q' to exit.");
6661 /*+-------------------------------------------------------------------------
6663 --------------------------------------------------------------------------*/
6665 #define okCOLOR(n) ((n) >= 0 && (n) < max_colors)
6666 #define okRGB(n) ((n) >= 0 && (n) <= 1000)
6669 main(int argc
, char *argv
[])
6673 #ifdef NCURSES_VERSION
6674 int default_fg
= COLOR_WHITE
;
6675 int default_bg
= COLOR_BLACK
;
6676 bool assumed_colors
= FALSE
;
6677 bool default_colors
= FALSE
;
6679 char *palette_file
= 0;
6680 bool monochrome
= FALSE
;
6682 setlocale(LC_ALL
, "");
6684 while ((c
= getopt(argc
, argv
, "a:de:fhmp:s:t:")) != -1) {
6686 #ifdef NCURSES_VERSION
6688 assumed_colors
= TRUE
;
6689 sscanf(optarg
, "%d,%d", &default_fg
, &default_bg
);
6692 default_colors
= TRUE
;
6696 my_e_param
= atoi(optarg
);
6697 #ifdef NCURSES_VERSION
6698 if (my_e_param
> 3) /* allow extended layouts */
6707 ripoffline(-1, rip_footer
);
6710 ripoffline(1, rip_header
);
6712 #endif /* HAVE_RIPOFFLINE */
6717 palette_file
= optarg
;
6721 nap_msec
= (int) atol(optarg
);
6726 save_trace
= (unsigned) strtol(optarg
, 0, 0);
6735 * If there's no menus (unlikely for ncurses!), then we'll have to set
6736 * tracing on initially, just in case the user wants to test something that
6737 * doesn't involve wGetchar.
6740 /* enable debugging */
6744 if (!isatty(fileno(stdin
)))
6746 #endif /* USE_LIBMENU */
6750 /* tell it we're going to play with soft keys */
6751 slk_init(my_e_param
);
6755 /* set up null signal catcher so we can see what interrupts to getch do */
6756 signal(SIGUSR1
, announce_sig
);
6759 /* we must initialize the curses data structure only once */
6763 /* tests, in general, will want these modes */
6764 use_colors
= monochrome
? FALSE
: has_colors();
6768 #ifdef NCURSES_VERSION_PATCH
6769 max_colors
= COLORS
; /* was > 16 ? 16 : COLORS */
6770 #if HAVE_USE_DEFAULT_COLORS
6771 if (default_colors
) {
6772 use_default_colors();
6775 #if NCURSES_VERSION_PATCH >= 20000708
6777 assume_default_colors(default_fg
, default_bg
);
6780 #else /* normal SVr4 curses */
6781 max_colors
= COLORS
; /* was > 8 ? 8 : COLORS */
6783 max_pairs
= COLOR_PAIRS
; /* was > 256 ? 256 : COLOR_PAIRS */
6785 if (can_change_color()) {
6787 all_colors
= typeMalloc(RGB_DATA
, (unsigned) max_colors
);
6788 for (cp
= 0; cp
< max_colors
; ++cp
) {
6790 &all_colors
[cp
].red
,
6791 &all_colors
[cp
].green
,
6792 &all_colors
[cp
].blue
);
6794 if (palette_file
!= 0) {
6795 FILE *fp
= fopen(palette_file
, "r");
6797 char buffer
[BUFSIZ
];
6798 int red
, green
, blue
;
6800 while (fgets(buffer
, sizeof(buffer
), fp
) != 0) {
6801 if (sscanf(buffer
, "scale:%d", &c
) == 1) {
6803 } else if (sscanf(buffer
, "%d:%d %d %d",
6812 all_colors
[c
].red
= (short) ((red
* 1000) / scale
);
6813 all_colors
[c
].green
= (short) ((green
* 1000) / scale
);
6814 all_colors
[c
].blue
= (short) ((blue
* 1000) / scale
);
6822 set_terminal_modes();
6826 * Return to terminal mode, so we're guaranteed of being able to
6827 * select terminal commands even if the capabilities are wrong.
6831 #if HAVE_CURSES_VERSION
6832 (void) printf("Welcome to %s. Press ? for help.\n", curses_version());
6833 #elif defined(NCURSES_VERSION_MAJOR) && defined(NCURSES_VERSION_MINOR) && defined(NCURSES_VERSION_PATCH)
6834 (void) printf("Welcome to ncurses %d.%d.%d. Press ? for help.\n",
6835 NCURSES_VERSION_MAJOR
,
6836 NCURSES_VERSION_MINOR
,
6837 NCURSES_VERSION_PATCH
);
6839 (void) puts("Welcome to ncurses. Press ? for help.");
6844 ExitProgram(EXIT_SUCCESS
);
6847 /* ncurses.c ends here */