X-Git-Url: http://ncurses.scripts.mit.edu/?p=ncurses.git;a=blobdiff_plain;f=test%2Fins_wide.c;fp=test%2Fins_wide.c;h=6f3573f47bf3416e84c03989a88a0e888e9664b6;hp=0000000000000000000000000000000000000000;hb=a8987e73ec254703634802b4f7ee30d3a485524d;hpb=46722468f47c2b77b3987729b4bcf2321cccfd01 diff --git a/test/ins_wide.c b/test/ins_wide.c new file mode 100644 index 00000000..6f3573f4 --- /dev/null +++ b/test/ins_wide.c @@ -0,0 +1,218 @@ +/* + * $Id: ins_wide.c,v 1.3 2003/08/09 22:07:23 tom Exp $ + * + * Demonstrate the wins_wstr() and wins_wch functions. + * Thomas Dickey - 2002/11/23 + * + * Note: to provide inputs for *ins_wch(), we use setcchar(). A quirk of the + * X/Open definition for that function is that the string contains no + * characters with negative width. Any control character (such as tab) falls + * into that category. So it follows that *ins_wch() cannot render a tab + * character because there is no legal way to construct a cchar_t containing + * one. X/Open does not document this, and it would be logical to assume that + * *ins_wstr() has the same limitation, but it uses a wchar_t string directly, + * and does not document how tabs are handled. + */ + +#include + +#define TABSIZE 8 + +#if USE_WIDEC_SUPPORT +static int margin = (2 * TABSIZE) - 1; + +static void +legend(WINDOW *win, wchar_t * buffer, int length) +{ + wmove(win, 0, 0); + wprintw(win, + "The Strings/Chars displays should match. Enter any characters.\n"); + wprintw(win, + "Use down-arrow or ^N to repeat on the next line, 'q' to exit.\n"); + wclrtoeol(win); + wprintw(win, "Inserted %d characters <", length); + waddwstr(win, buffer); + waddstr(win, ">"); +} + +static int +ColOf(wchar_t * buffer, int length) +{ + int n; + int result; + + for (n = 0, result = margin + 1; n < length; ++n) { + int ch = buffer[n]; + switch (ch) { + case '\n': + /* actually newline should clear the remainder of the line + * and move to the next line - but that seems a little awkward + * in this example. + */ + case '\r': + result = 0; + break; + case '\b': + if (result > 0) + --result; + break; + case '\t': + result += (TABSIZE - (result % TABSIZE)); + break; + case '\177': + result += 2; + break; + default: + ++result; + if (ch < 32) + ++result; + break; + } + } + return result; +} + +int +main(int argc GCC_UNUSED, char *argv[]GCC_UNUSED) +{ + cchar_t tmp_cchar; + wchar_t tmp_wchar[2]; + wint_t ch; + int code; + int limit; + int row = 1; + int col; + int length; + wchar_t buffer[BUFSIZ]; + WINDOW *work; + WINDOW *show; + + putenv("TABSIZE=8"); + initscr(); + (void) cbreak(); /* take input chars one at a time, no wait for \n */ + (void) noecho(); /* don't echo input */ + keypad(stdscr, TRUE); + + limit = LINES - 5; + work = newwin(limit, COLS, 0, 0); + show = newwin(4, COLS, limit + 1, 0); + keypad(work, TRUE); + + for (col = margin + 1; col < COLS; col += TABSIZE) + mvwvline(work, row, col, '.', limit - 2); + + box(work, 0, 0); + mvwvline(work, row, margin, ACS_VLINE, limit - 2); + mvwvline(work, row, margin + 1, ACS_VLINE, limit - 2); + limit /= 2; + + mvwaddstr(work, 1, 2, "String"); + mvwaddstr(work, limit + 1, 2, "Chars"); + wnoutrefresh(work); + + buffer[length = 0] = '\0'; + legend(show, buffer, length); + wnoutrefresh(show); + + doupdate(); + + /* + * Show the characters inserted in color, to distinguish from those that + * are shifted. + */ + if (has_colors()) { + start_color(); + init_pair(1, COLOR_WHITE, COLOR_BLUE); + wbkgdset(work, COLOR_PAIR(1) | ' '); + } + + while ((code = wget_wch(work, &ch)) != ERR) { + + switch (code) { + case KEY_CODE_YES: + switch (ch) { + case KEY_DOWN: + ch = CTRL('N'); + break; + case KEY_BACKSPACE: + ch = '\b'; + break; + default: + beep(); + continue; + } + break; + } + if (ch == 'q') + break; + + wmove(work, row, margin + 1); + if (ch == CTRL('N')) { + if (row < limit) { + ++row; + /* put the whole string in, all at once */ + mvwins_wstr(work, row, margin + 1, buffer); + + /* do the corresponding single-character insertion */ + for (col = 0; col < length; ++col) { + memset(&tmp_cchar, 0, sizeof(tmp_cchar)); + if (setcchar(&tmp_cchar, + &(buffer[col]), + A_NORMAL, + 0, + (void *) 0) != ERR) { + mvwins_wch(work, limit + row, ColOf(buffer, col), &tmp_cchar); + } else { + beep(); /* even for tabs! */ + mvwinsch(work, + limit + row, + ColOf(buffer, col), buffer[col]); + } + } + } else { + beep(); + } + } else { + buffer[length++] = ch; + buffer[length] = '\0'; + /* put the string in, one character at a time */ + mvwins_wstr(work, + row, + ColOf(buffer, length - 1), buffer + length - 1); + + /* do the corresponding single-character insertion */ + tmp_wchar[0] = ch; + tmp_wchar[1] = 0; + if (setcchar(&tmp_cchar, + tmp_wchar, + A_NORMAL, + 0, + (void *) 0) != ERR) { + mvwins_wch(work, + limit + row, + ColOf(buffer, length - 1), &tmp_cchar); + } else { + beep(); /* even for tabs! */ + mvwinsch(work, + limit + row, + ColOf(buffer, length - 1), ch); + } + wnoutrefresh(work); + + legend(show, buffer, length); + wnoutrefresh(show); + + doupdate(); + } + } + endwin(); + ExitProgram(EXIT_SUCCESS); +} +#else +int +main(void) +{ + printf("This program requires the wide-ncurses library\n"); + ExitProgram(EXIT_FAILURE); +} +#endif