ncursesw-morphos/test/ins_wide.c

219 lines
4.9 KiB
C
Raw Normal View History

2004-02-09 10:15:26 +08:00
/*
* $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 <test.priv.h>
#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