Пример #1
0
/* Request Terminal State Report */
static int
tst_DECRQTSR(MENU_ARGS)
{
  char *report;
  const char *show;

  vt_move(1, 1);
  println("Testing Terminal State Reports (DECRQTSR/DECTSR)");

  set_tty_raw(TRUE);
  set_tty_echo(FALSE);

  do_csi("1$u");
  report = get_reply();

  vt_move(3, 10);
  chrprint(report);

  if ((report = skip_dcs(report)) != 0
      && strip_terminator(report)
      && !strncmp(report, "1$s", (size_t) 3)) {
    show = SHOW_SUCCESS;
  } else {
    show = SHOW_FAILURE;
  }
  show_result("%s", show);

  restore_ttymodes();
  vt_move(max_lines - 1, 1);
  return MENU_HOLD;
}
Пример #2
0
int
any_DSR(MENU_ARGS, const char *text, void (*explain) (char *report))
{
    char *report;
    unsigned pmode = (unsigned) ((*text == '?') ? 1 : 0);

    vt_move(1, 1);
    printf("Testing DSR: %s\n", the_title);

    set_tty_raw(TRUE);
    set_tty_echo(FALSE);

    do_csi("%s", text);
    report = get_reply();
    vt_move(3, 10);
    chrprint(report);
    if ((report = skip_csi(report)) != 0
            && strlen(report) > (1 + pmode)
            && (!pmode || (*report++ == '?'))) {
        if (explain != 0)
            (*explain) (report);
        else
            show_result(SHOW_SUCCESS);
    } else {
        show_result(SHOW_FAILURE);
    }

    restore_ttymodes();
    vt_move(max_lines - 1, 1);
    return MENU_HOLD;
}
Пример #3
0
/* Test Window Report - VT340, VT420 */
static int
tst_DECRQDE(MENU_ARGS)
{
  char *report;
  char chr;
  int Ph, Pw, Pml, Pmt, Pmp;

  vt_move(1, 1);
  println("Testing DECRQDE/DECRPDE Window Report");

  set_tty_raw(TRUE);
  set_tty_echo(FALSE);

  do_csi("\"v");
  report = get_reply();
  vt_move(3, 10);
  chrprint(report);

  if ((report = skip_csi(report)) != 0
      && sscanf(report, "%d;%d;%d;%d;%d\"%c",
                &Ph, &Pw, &Pml, &Pmt, &Pmp, &chr) == 6
      && chr == 'w') {
    vt_move(5, 10);
    show_result("lines:%d, cols:%d, left col:%d, top line:%d, page %d",
                Ph, Pw, Pml, Pmt, Pmp);
  } else {
    show_result(SHOW_FAILURE);
  }

  restore_ttymodes();
  vt_move(max_lines - 1, 1);
  return MENU_HOLD;
}
Пример #4
0
/* Test User-Preferred Supplemental Set - VT320 */
static int
tst_DECRQUPSS(MENU_ARGS)
{
  char *report;
  const char *show;

  __(vt_move(1, 1), println("Testing DECRQUPSS/DECAUPSS Window Report"));

  set_tty_raw(TRUE);
  set_tty_echo(FALSE);

  do_csi("&u");
  report = get_reply();
  vt_move(3, 10);
  chrprint(report);
  if ((report = skip_dcs(report)) != 0
      && strip_terminator(report)) {
    if (!strcmp(report, "0!u%5"))
      show = "DEC Supplemental Graphic";
    else if (!strcmp(report, "1!uA"))
      show = "ISO Latin-1 supplemental";
    else
      show = "unknown";
  } else {
    show = SHOW_FAILURE;
  }
  show_result("%s", show);

  restore_ttymodes();
  vt_move(max_lines - 1, 1);
  return MENU_HOLD;
}
Пример #5
0
static void
check_rc(int row, int col)
{
    char *report;
    char *params;
    char expected[80];

    sprintf(expected, "%d;%dR", row, col);

    set_tty_raw(TRUE);
    set_tty_echo(FALSE);
    do_csi("6n");
    report = get_reply();
    restore_ttymodes();

    vt_move(row, 1);
    el(2);
    if ((params = skip_csi(report)) == 0
            || strcmp(params, expected) != 0) {
        printf("cursor save/restore %s, got \"%s\", expected \"%s\"",
               SHOW_FAILURE, params, expected);
    } else {
        printf("cursor save/restore %s", SHOW_SUCCESS);
    }
}
Пример #6
0
/* VT220 & up.
 */
static int
tst_S8C1T(MENU_ARGS)
{
    char *report;
    int flag = input_8bits;
    int pass;

    vt_move(1, 1);
    println(the_title);

    vt_move(5, 1);
    println("This tests the VT200+ control sequence to direct the terminal to emit 8-bit");
    println("control-sequences instead of <esc> sequences.");

    set_tty_raw(TRUE);
    set_tty_echo(FALSE);

    for (pass = 0; pass < 2; pass++) {
        flag = !flag;
        s8c1t(flag);
        cup(1, 1);
        dsr(6);
        report = instr();
        vt_move(10 + pass * 3, 1);
        printf("8-bit controls %s: ", flag ? "enabled" : "disabled");
        chrprint(report);
        report_ok("1;1R", report);
    }

    restore_ttymodes();
    vt_move(max_lines - 1, 1);
    return MENU_HOLD;
}
Пример #7
0
static int
tst_display(MENU_ARGS)
{
  int d, c = -1;

  vt_move(1, 1);
  display_head(stdout);
  println("");
  println("Press any key to display its soft-character.  Repeat a key to quit.");

  set_tty_raw(TRUE);
  set_tty_echo(FALSE);

  do {
    d = c;
    c = inchar();
    vt_move(6, 1);
    vt_clear(0);
    if (display_char(stdout, c)) {
      println("");
      printf("Render: %cN%c", ESC, c);  /* use SS2 to invoke G2 into GL */
    }
  } while (c != d);

  restore_ttymodes();
  return MENU_NOHOLD;
}
Пример #8
0
static int
test_report_ops(MENU_ARGS)
{
    char *report;
    int row = 3;
    int col = 10;

    vt_move(1,1);
    println("Test of Window reporting.");
    set_tty_raw(TRUE);
    set_tty_echo(FALSE);

    vt_move(row++,1);
    println("Report icon label:");
    vt_move(row, col);
    brc(20, 't'); /* report icon label */
    report = instr();
    row = chrprint2(report, row, col);

    vt_move(row++,1);
    println("Report window label:");
    vt_move(row, col);
    brc(21, 't'); /* report window label */
    report = instr();
    row = chrprint2(report, row, col);

    vt_move(row++,1);
    println("Report size of window (chars):");
    vt_move(row++, col);
    brc(18, 't'); /* report window's text-size */
    report = instr();
    chrprint(report);

    vt_move(row++,1);
    println("Report size of window (pixels):");
    vt_move(row++, col);
    brc(14, 't'); /* report window's pixel-size */
    report = instr();
    chrprint(report);

    vt_move(row++,1);
    println("Report position of window (pixels):");
    vt_move(row++, col);
    brc(13, 't'); /* report window's pixel-size */
    report = instr();
    chrprint(report);

    vt_move(row++,1);
    println("Report state of window (normal/iconified):");
    vt_move(row, col);
    brc(11, 't'); /* report window's pixel-size */
    report = instr();
    chrprint(report);

    vt_move(20,1);
    restore_ttymodes();
    return MENU_HOLD;
}
Пример #9
0
static int
check_8bit_toggle(void)
{
  char *report;

  set_tty_raw(TRUE);
  cup(1,1); dsr(6);
  padding(5); /* FIXME: may not be needed */
  report = get_reply();
  restore_ttymodes();

  if ((report = skip_csi(report)) != 0
   && !strcmp(report, "1;1R"))
    return TRUE;
  return FALSE;
}
Пример #10
0
static int
toggle_DECSCL(MENU_ARGS)
{
  int request = cur_level;

  if (max_level <= 1) {
    vt_move(1,1);
    printf("Sorry, terminal supports only VT%d", terminal_id());
    vt_move(max_lines-1,1);
    return MENU_HOLD;
  }

  if (++request > max_level)
    request = 1;
  set_level(request);

  restore_ttymodes();
  return MENU_NOHOLD;
}
Пример #11
0
/*
 * Determine the current and maximum operating levels of the terminal
 */
static void
find_levels(void)
{
  char *report;

  set_tty_raw(TRUE);
  set_tty_echo(FALSE);

  da();
  report = get_reply();
  if (!strcmp(report, "\033/Z")) {
    cur_level =
    max_level = 0; /* must be a VT52 */
  } else if ((report = skip_csi(report)) == 0
   || strncmp(report, "?6", 2)
   || !isdigit(report[2])
   || report[3] != ';') {
    cur_level =
    max_level = 1; /* must be a VT100 */
  } else { /* "CSI ? 6 x ; ..." */
    cur_level =
    max_level = report[2] - '0'; /* VT220=2, VT320=3, VT420=4 */
    if (max_level >= 4) {
      decrqss("\"p");
      report = get_reply();
      if ((report = skip_dcs(report)) != 0
       && isdigit(*report++) /* 0 or 1 (by observation, though 1 is an err) */
       && *report++ == '$'
       && *report++ == 'r'
       && *report++ == '6'
       && isdigit(*report))
          cur_level = *report - '0';
    }
  }

  if (LOG_ENABLED) {
    fprintf(log_fp, "Max Operating Level: %d\n", max_level);
    fprintf(log_fp, "Cur Operating Level: %d\n", cur_level);
  }

  restore_ttymodes();
}
Пример #12
0
int
any_decrqpsr(MENU_ARGS, int Ps)
{
  char *report;

  vt_move(1, 1);
  printf("Testing DECRQPSR: %s\n", the_title);

  set_tty_raw(TRUE);
  set_tty_echo(FALSE);

  do_csi("%d$w", Ps);
  report = get_reply();
  vt_move(3, 10);
  chrprint(report);
  if ((report = skip_dcs(report)) != 0) {
    if (strip_terminator(report)
        && *report == Ps + '0'
        && !strncmp(report + 1, "$u", (size_t) 2)) {
      show_result("%s (valid request)", SHOW_SUCCESS);
      switch (Ps) {
      case 1:
        show_DECCIR(report);
        break;
      case 2:
        show_DECTABSR(report);
        break;
      }
    } else {
      show_result(SHOW_FAILURE);
    }
  } else {
    show_result(SHOW_FAILURE);
  }

  restore_ttymodes();
  vt_move(max_lines - 1, 1);
  return MENU_HOLD;
}
Пример #13
0
static void
disable_control_chars(TTY *modes)
{
# if USE_POSIX_TERMIOS
    int n;
    int temp;
#   ifdef HAVE_POSIX_VDISABLE
    temp = _POSIX_VDISABLE;
#   else
    errno = 0;
    temp = fpathconf(0, _PC_VDISABLE);
    if (temp == -1) {
      if (errno != 0) {
        restore_ttymodes();
        fprintf(stderr, "Cannot disable special characters!\n");
        exit(EXIT_FAILURE);
      }
      temp = 0377;
    }
#   endif
    for (n = 0; n < NCCS; n++)
      modes->c_cc[n] = temp;
# else  /* USE_TERMIO */
#   ifdef       VSWTCH
    modes->c_cc[VSWTCH] = VDISABLE;
#   endif
    modes->c_cc[VSUSP]  = VDISABLE;
#   if defined (VDSUSP) && defined(NCCS) && VDSUSP < NCCS
    modes->c_cc[VDSUSP] = VDISABLE;
#   endif
    modes->c_cc[VSTART] = VDISABLE;
    modes->c_cc[VSTOP]  = VDISABLE;
# endif
    modes->c_cc[VMIN]  = 1;
    modes->c_cc[VTIME] = 0;
}
Пример #14
0
int
tst_screen(MENU_ARGS)
{
  /* Test of:
     - DECSTBM (Set Top and Bottom Margins)
     - TBC     (Tabulation Clear)
     - HTS     (Horizontal Tabulation Set)
     - SM RM   (Set/Reset mode): - 80/132 chars
     .                           - Origin: Relative/absolute
     .                           - Scroll: Smooth/jump
     .                           - Wraparound
     - SGR     (Select Graphic Rendition)
     - SM RM   (Set/Reset Mode) - Inverse
     - DECSC   (Save Cursor)
     - DECRC   (Restore Cursor)
   */

  int i, j, cset, row, col, background;

  static const char *tststr = "*qx`";
  static const char *attr[5] =
  {
    ";0", ";1", ";4", ";5", ";7"
  };

  set_tty_crmod(TRUE);  /* want to disable tab/space conversion */

  cup(1, 1);
  decawm(TRUE); /* DECAWM: Wrap Around ON */
  for (col = 1; col <= min_cols * 2; col++)
    printf("*");
  decawm(FALSE);  /* DECAWM: Wrap Around OFF */
  cup(3, 1);
  for (col = 1; col <= min_cols * 2; col++)
    printf("*");
  decawm(TRUE); /* DECAWM: Wrap Around ON */
  cup(5, 1);
  println("This should be three identical lines of *'s completely filling");
  println("the top of the screen without any empty lines between.");
  println("(Test of WRAP AROUND mode setting.)");
  holdit();

  ed(2);
  tbc(3);
  cup(1, 1);
  for (col = 1; col <= min_cols - 2; col += 3) {
    cuf(3);
    hts();
  }
  cup(1, 4);
  for (col = 4; col <= min_cols - 2; col += 6) {
    tbc(0);
    cuf(6);
  }
  cup(1, 7);
  tbc(1);
  tbc(2);       /* no-op */
  cup(1, 1);
  for (col = 1; col <= min_cols - 2; col += 6)
    printf("%c*", TAB);
  cup(2, 2);
  for (col = 2; col <= min_cols - 2; col += 6)
    printf("     *");
  cup(4, 1);
  println("Test of TAB setting/resetting. These two lines");
  printf("should look the same. ");
  holdit();
  for (background = 0; background <= 1; background++) {
    if (background)
      decscnm(FALSE);
    else
      decscnm(TRUE);
    deccolm(TRUE);  /* 132 cols */
    ed(2);      /* VT100 clears screen on SM3/RM3, but not obviously, so... */
    cup(1, 1);
    tbc(3);
    for (col = 1; col <= max_cols; col += TABWIDTH) {
      cuf(TABWIDTH);
      hts();
    }
    cup(1, 1);
    for (col = 1; col <= max_cols; col += 10)
      printf("%.*s", (max_cols > col) ? (max_cols - col) : 10, "1234567890");
    for (row = 3; row <= 20; row++) {
      cup(row, row);
      printf("This is %d column mode, %s background.", max_cols,
             background ? "dark" : "light");
    }
    holdit();
    deccolm(FALSE);   /* 80 cols */
    ed(2);      /* VT100 clears screen on SM3/RM3, but not obviously, so... */
    cup(1, 1);
    for (col = 1; col <= min_cols; col += 10)
      printf("%.*s", (min_cols > col) ? (min_cols - col) : 10, "1234567890");
    for (row = 3; row <= 20; row++) {
      cup(row, row);
      printf("This is %d column mode, %s background.", min_cols,
             background ? "dark" : "light");
    }
    holdit();
  }
  do_scrolling();
  ed(2);
  decstbm(max_lines - 1, max_lines);
  printf(
          "\nOrigin mode test. This line should be at the bottom of the screen.");
  cup(1, 1);
  printf("%s",
         "This line should be the one above the bottom of the screen. ");
  holdit();
  ed(2);
  decom(FALSE); /* Origin mode (absolute) */
  cup(max_lines, 1);
  printf(
          "Origin mode test. This line should be at the bottom of the screen.");
  cup(1, 1);
  printf("%s", "This line should be at the top of the screen. ");
  holdit();
  decstbm(1, max_lines);

  ed(2);
  /* *INDENT-OFF* */
  cup( 1,20); printf("Graphic rendition test pattern:");
  cup( 4, 1); sgr("0");         printf("vanilla");
  cup( 4,40); sgr("0;1");       printf("bold");
  cup( 6, 6); sgr(";4");        printf("underline");
  cup( 6,45);sgr(";1");sgr("4");printf("bold underline");
  cup( 8, 1); sgr("0;5");       printf("blink");
  cup( 8,40); sgr("0;5;1");     printf("bold blink");
  cup(10, 6); sgr("0;4;5");     printf("underline blink");
  cup(10,45); sgr("0;1;4;5");   printf("bold underline blink");
  cup(12, 1); sgr("1;4;5;0;7"); printf("negative");
  cup(12,40); sgr("0;1;7");     printf("bold negative");
  cup(14, 6); sgr("0;4;7");     printf("underline negative");
  cup(14,45); sgr("0;1;4;7");   printf("bold underline negative");
  cup(16, 1); sgr("1;4;;5;7");  printf("blink negative");
  cup(16,40); sgr("0;1;5;7");   printf("bold blink negative");
  cup(18, 6); sgr("0;4;5;7");   printf("underline blink negative");
  cup(18,45); sgr("0;1;4;5;7"); printf("bold underline blink negative");
  /* *INDENT-ON* */

  sgr("");

  decscnm(FALSE);   /* Inverse video off */
  cup(max_lines - 1, 1);
  el(0);
  printf("Dark background. ");
  holdit();

  decscnm(TRUE);  /* Inverse video */
  cup(max_lines - 1, 1);
  el(0);
  printf("Light background. ");
  holdit();

  decscnm(FALSE);

  ed(2);
  /* *INDENT-OFF* */
  cup(8,12); printf("normal");
  cup(8,24); printf("bold");
  cup(8,36); printf("underscored");
  cup(8,48); printf("blinking");
  cup(8,60); printf("reversed");
  cup(10,1); printf("stars:");
  cup(12,1); printf("line:");
  cup(14,1); printf("x'es:");
  cup(16,1); printf("diamonds:");
  /* *INDENT-ON* */

  for (cset = 0; cset <= 3; cset++) {
    for (i = 0; i <= 4; i++) {
      cup(10 + 2 * cset, 12 + 12 * i);
      sgr(attr[i]);
      if (cset == 0 || cset == 2)
        scs_normal();
      else
        scs_graphics();
      for (j = 0; j <= 4; j++) {
        printf("%c", tststr[cset]);
      }
      decsc();
      cup(cset + 1, i + 1);
      sgr("");
      scs_normal();
      printf("A");
      decrc();
      for (j = 0; j <= 4; j++) {
        printf("%c", tststr[cset]);
      }
    }
  }

  sgr("0");
  scs_normal();
  cup(21, 1);
  println("Test of the SAVE/RESTORE CURSOR feature. There should");
  println("be ten characters of each flavour, and a rectangle");
  println("of 5 x 4 A's filling the top left of the screen.");

  restore_ttymodes();
  return MENU_HOLD;
}
Пример #15
0
void
close_tty(void)
{
  restore_ttymodes();
}
Пример #16
0
static int
tst_DECUDK(MENU_ARGS)
{
    int key;
  /* *INDENT-OFF* */
  static struct {
    int code;
    const char *name;
  } keytable[] = {
    /* xterm programs these: */
    { 11, "F1" },
    { 12, "F2" },
    { 13, "F3" },
    { 14, "F4" },
    { 15, "F5" },
    /* vt420 programs these: */
    { 17, "F6" },
    { 18, "F7" },
    { 19, "F8" },
    { 20, "F9" },
    { 21, "F10" },
    { 23, "F11" },
    { 24, "F12" },
    { 25, "F13" },
    { 26, "F14" },
    { 28, "F15" },
    { 29, "F16" },
    { 31, "F17" },
    { 32, "F18" },
    { 33, "F19" },
    { 34, "F20" } };
  /* *INDENT-ON* */

    for (key = 0; key < TABLESIZE(keytable); key++) {
        char temp[80];
        const char *s;
        temp[0] = '\0';
        for (s = keytable[key].name; *s; s++)
            sprintf(temp + strlen(temp), "%02x", *s & 0xff);
        do_dcs("1;1|%d/%s", keytable[key].code, temp);
    }

    vt_move(1, 1);
    println(the_title);
    println("Press 'q' to quit.  Function keys should echo their labels.");
    println("(On a DEC terminal you must press SHIFT as well).");

    set_tty_raw(TRUE);
    set_tty_echo(FALSE);

    for (;;) {
        char *report = instr();
        if (*report == 'q')
            break;
        vt_move(5, 10);
        vt_clear(0);
        chrprint(report);
    }

    do_dcs("0");  /* clear all keys */

    restore_ttymodes();
    vt_move(max_lines - 1, 1);
    return MENU_HOLD;
}
Пример #17
0
int
tst_movements(MENU_ARGS)
{
  /* Test of:
     CUF (Cursor Forward)
     CUB (Cursor Backward)
     CUD (Cursor Down)      IND (Index)  NEL (Next Line)
     CUU (Cursor Up)        RI  (Reverse Index)
     CUP (Cursor Position)  HVP (Horizontal and Vertical Position)
     ED  (Erase in Display)
     EL  (Erase in Line)
     DECALN (Screen Alignment Display)
     DECAWM (Autowrap)
     <CR> <BS>
     Cursor control characters inside CSI sequences
   */

  int i, row, col, pass, width, hlfxtra;
  const char *ctext = "This is a correct sentence";

  set_tty_crmod(TRUE);  /* want to disable tab/space conversion */

  for (pass = 0; pass <= 1; pass++) {
    int inner_l, inner_r;

    if (pass == 0) {
      deccolm(FALSE);
      width = min_cols;
    } else {
      deccolm(TRUE);
      width = max_cols;
    }

    /* Compute left/right columns for a 60-column box centered in 'width' */
    inner_l = (width - 60) / 2;
    inner_r = 61 + inner_l;
    hlfxtra = (width - 80) / 2;

    if (LOG_ENABLED)
      fprintf(log_fp, "tst_movements box(%d cols)\n", pass ? max_cols : min_cols);

    decaln();
    cup(9, inner_l);
    ed(1);
    cup(18, 60 + hlfxtra);
    ed(0);
    el(1);
    cup(9, inner_r);
    el(0);
    /* 132: 36..97 */
    /*  80: 10..71 */
    for (row = 10; row <= 16; row++) {
      cup(row, inner_l);
      el(1);
      cup(row, inner_r);
      el(0);
    }
    cup(17, 30);
    el(2);
    for (col = 1; col <= width; col++) {
      hvp(max_lines, col);
      printf("*");
      hvp(1, col);
      printf("*");
    }
    cup(2, 2);
    for (row = 2; row <= max_lines - 1; row++) {
      printf("+");
      cub(1);
      ind();
    }
    cup(max_lines - 1, width - 1);
    for (row = max_lines - 1; row >= 2; row--) {
      printf("+");
      cub(1);
      ri();
    }
    cup(2, 1);
    for (row = 2; row <= max_lines - 1; row++) {
      printf("*");
      cup(row, width);
      printf("*");
      cub(10);
      if (row < 10)
        nel();
      else
        printf("\n");
    }
    cup(2, 10);
    cub(42 + hlfxtra);
    cuf(2);
    for (col = 3; col <= width - 2; col++) {
      printf("+");
      cuf(0);
      cub(2);
      cuf(1);
    }
    cup(max_lines - 1, inner_r - 1);
    cuf(42 + hlfxtra);
    cub(2);
    for (col = width - 2; col >= 3; col--) {
      printf("+");
      cub(1);
      cuf(1);
      cub(0);
      printf("%c", 8);
    }
    cup(1, 1);
    cuu(10);
    cuu(1);
    cuu(0);
    cup(max_lines, width);
    cud(10);
    cud(1);
    cud(0);

    cup(10, 2 + inner_l);
    for (row = 10; row <= 15; row++) {
      for (col = 2 + inner_l; col <= inner_r - 2; col++)
        printf(" ");
      cud(1);
      cub(58);
    }
    cuu(5);
    cuf(1);
    printf("The screen should be cleared,  and have an unbroken bor-");
    cup(12, inner_l + 3);
    printf("der of *'s and +'s around the edge,   and exactly in the");
    cup(13, inner_l + 3);
    printf("middle  there should be a frame of E's around this  text");
    cup(14, inner_l + 3);
    printf("with  one (1) free position around it.    ");
    holdit();
  }
  deccolm(FALSE);

  /* DECAWM demo */
  for (pass = 0; pass <= 1; pass++) {
    static char on_left[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    static char on_right[] = "abcdefghijklmnopqrstuvwxyz";
    int height = sizeof(on_left) - 1;
    int region = max_lines - 6;

    if (LOG_ENABLED)
      fprintf(log_fp, "tst_movements wrap(%d cols)\n", pass ? max_cols : min_cols);

    /* note: DECCOLM clears the screen */
    if (pass == 0) {
      deccolm(FALSE);
      width = min_cols;
    } else {
      deccolm(TRUE);
      width = max_cols;
    }

    println("Test of autowrap, mixing control and print characters.");
    println("The left/right margins should have letters in order:");

    decstbm(3, region + 3);
    decom(TRUE);  /* this also homes the cursor */
    for (i = 0; i < height; ++i) {
      switch (i % 4) {
      case 0:
        /* draw characters as-is, for reference */
        __(cup(region + 1, 1), printf("%c", on_left[i]));
        __(cup(region + 1, width), printf("%c", on_right[i]));
        printf("\n");
        break;
      case 1:
        /* simple wrapping */
        __(cup(region, width), printf("%c%c", on_right[i - 1], on_left[i]));
        /* backspace at right margin */
        __(cup(region + 1, width), printf("%c%c %c",
                                          on_left[i], BS, on_right[i]));
        printf("\n");
        break;
      case 2:
        /* tab to right margin */
        __(cup(region + 1, width), printf("%c%c%c%c%c%c",
                                          on_left[i], BS, BS,
                                          TAB, TAB, on_right[i]));
        __(cup(region + 1, 2), printf("%c%c\n", BS, on_left[i]));
        break;
      default:
        /* newline at right margin */
        __(cup(region + 1, width), printf("\n"));
        __(cup(region, 1), printf("%c", on_left[i]));
        __(cup(region, width), printf("%c", on_right[i]));
        break;
      }
    }
    decom(FALSE);
    decstbm(0, 0);
    cup(max_lines - 2, 1);
    holdit();
  }
  deccolm(FALSE);   /* 80 cols */

  if (LOG_ENABLED)
    fprintf(log_fp, "tst_movements cursor-controls in ESC sequences\n");

  vt_clear(2);
  vt_move(1, 1);
  println("Test of cursor-control characters inside ESC sequences.");
  println("Below should be four identical lines:");
  println("");
  println("A B C D E F G H I");
  for (i = 1; i < 10; i++) {
    printf("%c", '@' + i);
    do_csi("2%cC", BS);   /* Two forward, one backspace */
  }
  println("");
  /* Now put CR in CUF sequence. */
  printf("A ");
  for (i = 2; i < 10; i++)
    printf("%s%c%dC%c", csi_output(), CR, 2 * i - 2, '@' + i);
  println("");
  /* Now put VT in CUU sequence. */
  rm("20");
  for (i = 1; i < 10; i++) {
    printf("%c ", '@' + i);
    do_csi("1\013A");
  }
  println("");
  println("");
  holdit();

  if (LOG_ENABLED)
    fprintf(log_fp, "tst_movements leading zeros in ESC sequences\n");

  vt_clear(2);
  vt_move(1, 1);
  println("Test of leading zeros in ESC sequences.");
  printf("Two lines below you should see the sentence \"%s\".", ctext);
  for (col = 1; *ctext; col++)
    printf("%s00000000004;00000000%dH%c", csi_output(), col, *ctext++);
  cup(20, 1);

  restore_ttymodes();
  return MENU_HOLD;
}