]> ncurses.scripts.mit.edu Git - ncurses.git/blobdiff - test/ins_wide.c
ncurses 5.4
[ncurses.git] / test / ins_wide.c
diff --git a/test/ins_wide.c b/test/ins_wide.c
new file mode 100644 (file)
index 0000000..6f3573f
--- /dev/null
@@ -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 <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