1/* 2** Copyright (C) 1991, 1997 Free Software Foundation, Inc. 3** 4** This file is part of TACK. 5** 6** TACK is free software; you can redistribute it and/or modify 7** it under the terms of the GNU General Public License as published by 8** the Free Software Foundation; either version 2, or (at your option) 9** any later version. 10** 11** TACK is distributed in the hope that it will be useful, 12** but WITHOUT ANY WARRANTY; without even the implied warranty of 13** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14** GNU General Public License for more details. 15** 16** You should have received a copy of the GNU General Public License 17** along with TACK; see the file COPYING. If not, write to 18** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 19** Boston, MA 02110-1301, USA 20*/ 21 22#include <tack.h> 23 24MODULE_ID("$Id: crum.c,v 1.4 2005/09/17 19:49:16 tom Exp $") 25 26/* 27 * Test cursor movement. 28 */ 29 30static void crum_clear(struct test_list *t, int *state, int *ch); 31static void crum_home(struct test_list *t, int *state, int *ch); 32static void crum_ll(struct test_list *t, int *state, int *ch); 33static void crum_move(struct test_list *t, int *state, int *ch); 34static void crum_os(struct test_list *t, int *state, int *ch); 35 36static char crum_text[5][80]; 37 38struct test_list crum_test_list[] = { 39 {0, 0, 0, 0, "e) edit terminfo", 0, &edit_menu}, 40 {MENU_NEXT, 0, "clear", 0, 0, crum_clear, 0}, 41 {MENU_NEXT, 0, "home", 0, 0, crum_home, 0}, 42 {MENU_NEXT, 0, "ll", 0, 0, crum_ll, 0}, 43 {MENU_NEXT, 0, crum_text[0], "home cuu1", 0, crum_move, 0}, 44 {MENU_NEXT + 1, 0, crum_text[1], "cub1 cud1 cuf1 cuu1", 0, crum_move, 0}, 45 {MENU_NEXT + 2, 0, crum_text[2], "cub cud cuf cuu", 0, crum_move, 0}, 46 {MENU_NEXT + 3, 0, crum_text[3], "vpa hpa", 0, crum_move, 0}, 47 {MENU_NEXT + 4, 0, crum_text[4], "cup", 0, crum_move, 0}, 48 {MENU_NEXT, 0, "cup", "os", 0, crum_os, 0}, 49 {MENU_LAST, 0, 0, 0, 0, 0, 0} 50}; 51 52/* 53** move_to(from-row, from-column, to-row, to-column, selection) 54** 55** move the cursor from (rf, cf) to (rt, ct) using sel 56*/ 57static void 58move_to( 59 int rf, 60 int cf, 61 int rt, 62 int ct, 63 int sel) 64{ 65 char *s; 66 67 if (sel & 16) { /* use (cup) */ 68 s = tparm(cursor_address, rt, ct); 69 tputs(s, lines, tc_putch); 70 return; 71 } 72 if (sel & 8) { /* use (hpa) (vpa) */ 73 if (column_address) { 74 s = tparm(column_address, ct); 75 tputs(s, 1, tc_putch); 76 cf = ct; 77 } 78 if (row_address) { 79 s = tparm(row_address, rt); 80 tputs(s, 1, tc_putch); 81 rf = rt; 82 } 83 } 84 if (sel & 4) { /* parameterized relative cursor movement */ 85 if (parm_right_cursor) 86 if (cf < ct) { 87 s = tparm(parm_right_cursor, ct - cf); 88 tputs(s, ct - cf, tc_putch); 89 cf = ct; 90 } 91 if (parm_left_cursor) 92 if (cf > ct) { 93 s = tparm(parm_left_cursor, cf - ct); 94 tputs(s, cf - ct, tc_putch); 95 cf = ct; 96 } 97 if (parm_down_cursor) 98 if (rf < rt) { 99 s = tparm(parm_down_cursor, rt - rf); 100 tputs(s, rt - rf, tc_putch); 101 rf = rt; 102 } 103 if (parm_up_cursor) 104 if (rf > rt) { 105 s = tparm(parm_up_cursor, rf - rt); 106 tputs(s, rf - rt, tc_putch); 107 rf = rt; 108 } 109 } 110 if (sel & 2) { 111 if (cursor_left) 112 while (cf > ct) { 113 tc_putp(cursor_left); 114 cf--; 115 } 116 /* 117 do vertical motion next. Just in case cursor_down has a 118 side effect of changing the column. This could happen if 119 the tty handler translates NL to CRNL. 120 */ 121 if (cursor_down) 122 while (rf < rt) { 123 tc_putp(cursor_down); 124 rf++; 125 } 126 if (cursor_up) 127 while (rf > rt) { 128 tc_putp(cursor_up); 129 rf--; 130 } 131 if (cursor_right) 132 while (cf < ct) { 133 tc_putp(cursor_right); 134 cf++; 135 } 136 } 137 /* last chance */ 138 if (rf > rt) { 139 if (can_go_home) { /* a bit drastic but ... */ 140 go_home(); 141 cf = 0; 142 rf = 0; 143 } else if (cursor_up) { 144 while (rf > rt) { 145 tc_putp(cursor_up); 146 rf--; 147 } 148 } 149 } 150 if (ct == 0 && rt > rf) { 151 put_crlf(); 152 cf = 0; 153 rf++; 154 } 155 if (ct == 0 && cf != 0) { 156 put_cr(); 157 cf = 0; 158 } 159 while (rf < rt) { 160 put_lf(); 161 rf++; 162 } 163 while (cf > ct) { 164 put_str("\b"); 165 cf--; 166 } 167 if (cursor_right) { 168 while (cf < ct) { 169 tc_putp(cursor_right); 170 cf++; 171 } 172 } else { 173 /* go ahead and trash my display */ 174 while (cf < ct) { 175 putchp(' '); 176 cf++; 177 } 178 } 179} 180 181/* 182** display_it(selection, text) 183** 184** print the display using sel 185*/ 186static void 187display_it( 188 int sel, 189 char *txt) 190{ 191 int i, done_line; 192 193 put_clear(); 194 go_home(); 195 put_newlines(2); 196 ptextln(" The top line should be alternating <'s and >'s"); 197 ptextln(" The left side should be alternating A's and V's"); 198 ptext(" Testing "); 199 ptext(txt); 200 put_cr(); 201 202 /* horizontal */ 203 move_to(done_line = line_count, 0, 0, 2, sel); 204 for (i = 4; i < columns - 2; i += 2) { 205 putchp('>'); 206 move_to(0, i - 1, 0, i, sel); 207 } 208 putchp('>'); 209 i -= 2; 210 move_to(0, i + 1, 0, i - 1, sel); 211 for (; i > 2; i -= 2) { 212 putchp('<'); 213 move_to(0, i, 0, i - 3, sel); 214 } 215 putchp('<'); 216 217 /* vertical */ 218 move_to(0, 2, 0, 0, sel); 219 for (i = 2; i < lines - 1; i += 2) { 220 putchp('V'); 221 move_to(i - 2, 1, i, 0, sel); 222 } 223 putchp('V'); 224 i -= 2; 225 move_to(i, 1, i + 1, 0, sel); 226 for (; i > 0; i -= 2) { 227 putchp('A'); 228 move_to(i + 1, 1, i - 1, 0, sel); 229 } 230 putchp('A'); 231 move_to(i + 1, 1, 0, 0, sel); /* go home first */ 232 move_to(0, 0, done_line + 1, 3, sel); 233 put_str(txt); 234 put_str(" Done. "); 235} 236 237/* 238** crum_clear(test_list, status, ch) 239** 240** (clear) test Clear screen 241*/ 242static void 243crum_clear( 244 struct test_list *t, 245 int *state, 246 int *ch) 247{ 248 int i; 249 250 if (clear_screen) { 251 for (i = lines; i > 1; i--) { 252 putln("garbage"); 253 } 254 put_clear(); 255 ptextln("This line should start in the home position."); 256 ptext("The rest of the screen should be clear. "); 257 } else { 258 ptextln("(clear) Clear screen is not defined. "); 259 } 260 generic_done_message(t, state, ch); 261} 262 263/* 264** crum_home(test_list, status, ch) 265** 266** (home) test Home cursor 267*/ 268static void 269crum_home( 270 struct test_list *t, 271 int *state, 272 int *ch) 273{ 274 if (cursor_home) { 275 put_clear(); 276 put_newlines(lines / 2); 277 go_home(); 278 put_crlf(); 279 ptext("The bottom line should have text."); 280 go_home(); 281 put_newlines(lines - 1); 282 ptext("This line is on the bottom."); 283 go_home(); 284 ptextln("This line starts in the home position."); 285 put_crlf(); 286 } else { 287 ptextln("(home) Home cursor is not defined. "); 288 } 289 generic_done_message(t, state, ch); 290} 291 292/* 293** crum_ll(test_list, status, ch) 294** 295** (ll) test Last line 296*/ 297static void 298crum_ll( 299 struct test_list *t, 300 int *state, 301 int *ch) 302{ 303 /* 304 (ll) may be simulated with (cup). Don't complain if (cup) is present. 305 */ 306 if (cursor_to_ll) { 307 put_clear(); 308 put_str("This line could be anywhere."); 309 tc_putp(cursor_to_ll); 310 ptext("This line should be on the bottom"); 311 go_home(); 312 put_crlf(); 313 } else 314 if (cursor_address) { 315 return; 316 } else { 317 ptextln("(ll) Move to last line is not defined. "); 318 } 319 generic_done_message(t, state, ch); 320} 321 322/* 323** crum_move(test_list, status, ch) 324** 325** (*) test all cursor move commands 326*/ 327static void 328crum_move( 329 struct test_list *t, 330 int *state, 331 int *ch) 332{ 333 char buf[80]; 334 int n; 335 336 switch (n = (t->flags & 15)) { 337 case 0: 338 sprintf(buf, " (cr) (nel) (cub1)%s", 339 cursor_home ? " (home)" : (cursor_up ? " (cuu1)" : "")); 340 break; 341 case 1: 342 sprintf(buf, "%s%s%s%s", cursor_left ? " (cub1)" : "", 343 cursor_down ? " (cud1)" : "", cursor_right ? " (cuf1)" : "", 344 cursor_up ? " (cuu1)" : ""); 345 if (buf[0] == '\0') { 346 ptext(" (cub1) (cud1) (cuf1) (cuu1) not defined."); 347 } 348 break; 349 case 2: 350 sprintf(buf, "%s%s%s%s", parm_left_cursor ? " (cub)" : "", 351 parm_down_cursor ? " (cud)" : "", 352 parm_right_cursor ? " (cuf)" : "", 353 parm_up_cursor ? " (cuu)" : ""); 354 if (buf[0] == '\0') { 355 ptext(" (cub) (cud) (cuf) (cuu) not defined."); 356 } 357 break; 358 case 3: 359 sprintf(buf, "%s%s", row_address ? " (vpa)" : "", 360 column_address ? " (hpa)" : ""); 361 if (buf[0] == '\0') { 362 ptext(" (vpa) (hpa) not defined."); 363 } 364 break; 365 case 4: 366 if (!cursor_address) { 367 ptext(" (cup) not defined. "); 368 generic_done_message(t, state, ch); 369 return; 370 } 371 strcpy(buf, " (cup)"); 372 break; 373 } 374 if (buf[0] == '\0') { 375 put_str(" Done. "); 376 } else { 377 can_test(buf, FLAG_TESTED); 378 strcpy(crum_text[n], &buf[2]); 379 crum_text[n][strlen(buf) - 3] = '\0'; 380 381 display_it(1 << n, buf); 382 } 383 *ch = wait_here(); 384 if (*ch != 'r') { 385 put_clear(); 386 } 387} 388 389/* 390** crum_os(test_list, status, ch) 391** 392** (cup) test Cursor position on overstrike terminals 393*/ 394static void 395crum_os( 396 struct test_list *t, 397 int *state, 398 int *ch) 399{ 400 int i; 401 402 if (cursor_address && over_strike) { 403 put_clear(); 404 for (i = 0; i < columns - 2; i++) { 405 tc_putch('|'); 406 } 407 for (i = 1; i < lines - 2; i++) { 408 put_crlf(); 409 tc_putch('_'); 410 } 411 for (i = 0; i < columns - 2; i++) { 412 tputs(tparm(cursor_address, 0, i), lines, tc_putch); 413 tc_putch('+'); 414 } 415 for (i = 0; i < lines - 2; i++) { 416 tputs(tparm(cursor_address, i, 0), lines, tc_putch); 417 tc_putch(']'); 418 tc_putch('_'); 419 } 420 go_home(); 421 put_newlines(3); 422 ptext(" All the characters should look the same. "); 423 generic_done_message(t, state, ch); 424 put_clear(); 425 } 426} 427