+
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ (void) mvaddstr(SLK_WORK, 0, "Please enter the label value: ");
+ *buf = 0;
+ if ((s = slk_label(c - '0')) != 0) {
+ char *temp = strdup(s);
+ size_t used = strlen(temp);
+ size_t want = SLKLEN;
+ size_t test;
+ mbstate_t state;
+
+ buf[0] = L'\0';
+ while (want > 0 && used != 0) {
+ const char *base = s;
+ memset(&state, 0, sizeof(state));
+ test = mbsrtowcs(0, &base, 0, &state);
+ if (test == (size_t) -1) {
+ temp[--used] = 0;
+ } else if (test > want) {
+ temp[--used] = 0;
+ } else {
+ memset(&state, 0, sizeof(state));
+ mbsrtowcs(buf, &base, want, &state);
+ break;
+ }
+ }
+ free(temp);
+ }
+ wGet_wstring(stdscr, buf, SLKLEN);
+ slk_wset((c - '0'), buf, fmt);
+ slk_refresh();
+ move(SLK_WORK, 0);
+ clrtobot();
+ break;
+
+ case case_QUIT:
+ goto done;
+
+ case 'F':
+ if (use_colors) {
+ fg = (fg + 1) % COLORS;
+ call_slk_color(fg, bg);
+ }
+ break;
+ case 'B':
+ if (use_colors) {
+ bg = (bg + 1) % COLORS;
+ call_slk_color(fg, bg);
+ }
+ break;
+#if defined(NCURSES_VERSION) && defined(KEY_RESIZE) && HAVE_WRESIZE
+ case KEY_RESIZE:
+ wnoutrefresh(stdscr);
+ break;
+#endif
+ default:
+ beep();
+ }
+ } while (!isQuit(c = Getchar()));
+
+ done:
+ slk_clear();
+ erase();
+ endwin();
+}
+#endif
+#endif /* SLK_INIT */
+
+/****************************************************************************
+ *
+ * Alternate character-set stuff
+ *
+ ****************************************************************************/
+/* *INDENT-OFF* */
+static struct {
+ chtype attr;
+ const char *name;
+} attrs_to_cycle[] = {
+ { A_NORMAL, "normal" },
+ { A_BOLD, "bold" },
+ { A_REVERSE, "reverse" },
+ { A_UNDERLINE, "underline" },
+};
+/* *INDENT-ON* */
+
+static bool
+cycle_attr(int ch, unsigned *at_code, chtype *attr)
+{
+ bool result = TRUE;
+
+ switch (ch) {
+ case 'v':
+ if ((*at_code += 1) >= SIZEOF(attrs_to_cycle))
+ *at_code = 0;
+ break;
+ case 'V':
+ if (*at_code == 1)
+ *at_code = SIZEOF(attrs_to_cycle) - 1;
+ else
+ *at_code -= 1;
+ break;
+ default:
+ result = FALSE;
+ break;
+ }
+ if (result)
+ *attr = attrs_to_cycle[*at_code].attr;
+ return result;
+}
+
+static bool
+cycle_colors(int ch, int *fg, int *bg, short *pair)
+{
+ bool result = FALSE;
+
+ if (use_colors) {
+ result = TRUE;
+ switch (ch) {
+ case 'F':
+ if ((*fg -= 1) < 0)
+ *fg = COLORS - 1;
+ break;
+ case 'f':
+ if ((*fg += 1) >= COLORS)
+ *fg = 0;
+ break;
+ case 'B':
+ if ((*bg -= 1) < 0)
+ *bg = COLORS - 1;
+ break;
+ case 'b':
+ if ((*bg += 1) >= COLORS)
+ *bg = 0;
+ break;
+ default:
+ result = FALSE;
+ break;
+ }
+ if (result) {
+ *pair = (*fg != COLOR_BLACK || *bg != COLOR_BLACK);
+ if (*pair != 0) {
+ *pair = 1;
+ if (init_pair(*pair, *fg, *bg) == ERR) {
+ result = FALSE;
+ }
+ }
+ }
+ }
+ return result;
+}
+
+/* ISO 6429: codes 0x80 to 0x9f may be control characters that cause the
+ * terminal to perform functions. The remaining codes can be graphic.
+ */
+static void
+show_upper_chars(unsigned first, int repeat, attr_t attr, short pair)
+{
+ bool C1 = (first == 128);
+ unsigned code;
+ unsigned last = first + 31;
+ int reply;
+
+ erase();
+ attron(A_BOLD);
+ mvprintw(0, 20, "Display of %s Character Codes %d to %d",
+ C1 ? "C1" : "GR", first, last);
+ attroff(A_BOLD);
+ refresh();
+
+ for (code = first; code <= last; code++) {
+ int count = repeat;
+ int row = 2 + ((code - first) % 16);
+ int col = ((code - first) / 16) * COLS / 2;
+ char tmp[80];
+ sprintf(tmp, "%3u (0x%x)", code, code);
+ mvprintw(row, col, "%*s: ", COLS / 4, tmp);
+
+ do {
+ if (C1)
+ nodelay(stdscr, TRUE);
+ echochar(code | attr | COLOR_PAIR(pair));
+ if (C1) {
+ /* (yes, this _is_ crude) */
+ while ((reply = Getchar()) != ERR) {
+ addch(UChar(reply));
+ napms(10);
+ }
+ nodelay(stdscr, FALSE);
+ }
+ } while (--count > 0);
+ }
+}
+
+#define PC_COLS 4
+
+static void
+show_pc_chars(int repeat, attr_t attr, short pair)
+{
+ unsigned code;
+
+ erase();
+ attron(A_BOLD);
+ mvprintw(0, 20, "Display of PC Character Codes");
+ attroff(A_BOLD);
+ refresh();
+
+ for (code = 0; code < 16; ++code) {
+ mvprintw(2, (int) code * PC_COLS + 8, "%X", code);
+ }
+ for (code = 0; code < 256; code++) {
+ int count = repeat;
+ int row = 3 + (code / 16) + (code >= 128);
+ int col = 8 + (code % 16) * PC_COLS;
+ if ((code % 16) == 0)
+ mvprintw(row, 0, "0x%02x:", code);
+ move(row, col);
+ do {
+ switch (code) {
+ case '\n':
+ case '\r':
+ case '\b':
+ case '\f':
+ case '\033':
+ case 0x9b:
+ /*
+ * Skip the ones that do not work.
+ */
+ break;
+ default:
+ addch(code | A_ALTCHARSET | attr | COLOR_PAIR(pair));
+ break;
+ }
+ } while (--count > 0);
+ }
+}
+
+static void
+show_box_chars(int repeat, attr_t attr, short pair)
+{
+ (void) repeat;
+ attr |= COLOR_PAIR(pair);
+
+ erase();
+ attron(A_BOLD);
+ mvaddstr(0, 20, "Display of the ACS Line-Drawing Set");
+ attroff(A_BOLD);
+ refresh();
+ box(stdscr, 0, 0);
+ /* *INDENT-OFF* */
+ mvhline(LINES / 2, 0, ACS_HLINE | attr, COLS);
+ mvvline(0, COLS / 2, ACS_VLINE | attr, LINES);
+ mvaddch(0, COLS / 2, ACS_TTEE | attr);
+ mvaddch(LINES / 2, COLS / 2, ACS_PLUS | attr);
+ mvaddch(LINES - 1, COLS / 2, ACS_BTEE | attr);
+ mvaddch(LINES / 2, 0, ACS_LTEE | attr);
+ mvaddch(LINES / 2, COLS - 1, ACS_RTEE | attr);
+ /* *INDENT-ON* */
+
+}
+
+static int
+show_1_acs(int n, int repeat, const char *name, chtype code)
+{
+ const int height = 16;
+ int row = 2 + (n % height);
+ int col = (n / height) * COLS / 2;
+
+ mvprintw(row, col, "%*s : ", COLS / 4, name);
+ do {
+ addch(code);
+ } while (--repeat > 0);
+ return n + 1;
+}
+
+static void
+show_acs_chars(int repeat, attr_t attr, short pair)
+/* display the ACS character set */
+{
+ int n;
+
+#define BOTH(name) #name, (name | attr | COLOR_PAIR(pair))
+
+ erase();
+ attron(A_BOLD);
+ mvaddstr(0, 20, "Display of the ACS Character Set");
+ attroff(A_BOLD);
+ refresh();
+
+ n = show_1_acs(0, repeat, BOTH(ACS_ULCORNER));
+ n = show_1_acs(n, repeat, BOTH(ACS_URCORNER));
+ n = show_1_acs(n, repeat, BOTH(ACS_LLCORNER));
+ n = show_1_acs(n, repeat, BOTH(ACS_LRCORNER));
+
+ n = show_1_acs(n, repeat, BOTH(ACS_LTEE));
+ n = show_1_acs(n, repeat, BOTH(ACS_RTEE));
+ n = show_1_acs(n, repeat, BOTH(ACS_TTEE));
+ n = show_1_acs(n, repeat, BOTH(ACS_BTEE));
+
+ n = show_1_acs(n, repeat, BOTH(ACS_HLINE));
+ n = show_1_acs(n, repeat, BOTH(ACS_VLINE));
+
+ /*
+ * HPUX's ACS definitions are broken here. Just give up.
+ */
+#if !(defined(__hpux) && !defined(NCURSES_VERSION))
+ n = show_1_acs(n, repeat, BOTH(ACS_LARROW));
+ n = show_1_acs(n, repeat, BOTH(ACS_RARROW));
+ n = show_1_acs(n, repeat, BOTH(ACS_UARROW));
+ n = show_1_acs(n, repeat, BOTH(ACS_DARROW));
+
+ n = show_1_acs(n, repeat, BOTH(ACS_BLOCK));
+ n = show_1_acs(n, repeat, BOTH(ACS_BOARD));
+ n = show_1_acs(n, repeat, BOTH(ACS_LANTERN));
+ n = show_1_acs(n, repeat, BOTH(ACS_BULLET));
+ n = show_1_acs(n, repeat, BOTH(ACS_CKBOARD));
+ n = show_1_acs(n, repeat, BOTH(ACS_DEGREE));
+ n = show_1_acs(n, repeat, BOTH(ACS_DIAMOND));
+ n = show_1_acs(n, repeat, BOTH(ACS_PLMINUS));
+ n = show_1_acs(n, repeat, BOTH(ACS_PLUS));
+
+ n = show_1_acs(n, repeat, BOTH(ACS_GEQUAL));
+ n = show_1_acs(n, repeat, BOTH(ACS_NEQUAL));
+ n = show_1_acs(n, repeat, BOTH(ACS_LEQUAL));
+
+ n = show_1_acs(n, repeat, BOTH(ACS_STERLING));
+ n = show_1_acs(n, repeat, BOTH(ACS_PI));
+ n = show_1_acs(n, repeat, BOTH(ACS_S1));
+ n = show_1_acs(n, repeat, BOTH(ACS_S3));
+ n = show_1_acs(n, repeat, BOTH(ACS_S7));
+ n = show_1_acs(n, repeat, BOTH(ACS_S9));
+#endif
+}
+
+static void
+acs_display(void)
+{
+ int c = 'a';
+ char *term = getenv("TERM");
+ const char *pch_kludge = ((term != 0 && strstr(term, "linux"))
+ ? "p=PC, "
+ : "");
+ chtype attr = A_NORMAL;
+ int digit = 0;
+ int repeat = 1;
+ int fg = COLOR_BLACK;
+ int bg = COLOR_BLACK;
+ unsigned at_code = 0;
+ short pair = 0;
+ void (*last_show_acs) (int, attr_t, short) = 0;
+
+ do {
+ switch (c) {
+ case CTRL('L'):
+ Repaint();
+ break;
+ case 'a':
+ ToggleAcs(last_show_acs, show_acs_chars);
+ break;
+ case 'p':
+ if (*pch_kludge)
+ ToggleAcs(last_show_acs, show_pc_chars);
+ else
+ beep();
+ break;
+ case 'x':
+ ToggleAcs(last_show_acs, show_box_chars);
+ break;
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ digit = (c - '0');
+ last_show_acs = 0;
+ break;
+ case '-':
+ if (digit > 0) {
+ --digit;
+ last_show_acs = 0;
+ } else {
+ beep();
+ }
+ break;
+ case '+':
+ if (digit < 3) {
+ ++digit;
+ last_show_acs = 0;
+ } else {
+ beep();
+ }
+ break;
+ case '>':
+ if (repeat < (COLS / 4))
+ ++repeat;
+ break;
+ case '<':
+ if (repeat > 1)
+ --repeat;
+ break;
+ default:
+ if (cycle_attr(c, &at_code, &attr)
+ || cycle_colors(c, &fg, &bg, &pair)) {
+ break;
+ } else {
+ beep();
+ }