ncurses 5.0
[ncurses.git] / tack / crum.c
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., 59 Temple Place - Suite 330,
19 ** Boston, MA 02111-1307, USA.
20 */
21
22 #include <tack.h>
23
24 MODULE_ID("$Id: crum.c,v 1.2 1999/08/21 23:09:08 tom Exp $")
25
26 /*
27  * Test cursor movement.
28  */
29
30 static void crum_clear(struct test_list *t, int *state, int *ch);
31 static void crum_home(struct test_list *t, int *state, int *ch);
32 static void crum_ll(struct test_list *t, int *state, int *ch);
33 static void crum_move(struct test_list *t, int *state, int *ch);
34 static void crum_os(struct test_list *t, int *state, int *ch);
35
36 static char crum_text[5][80];
37
38 struct 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 */
57 static void
58 move_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) {  /* paramiterized 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 */
186 static void
187 display_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 */
242 static void
243 crum_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 */
268 static void
269 crum_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 */
297 static void
298 crum_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 */
327 static void
328 crum_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 */
394 static void
395 crum_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 }