1 /* $Id: vt52.c,v 1.19 2018/07/26 00:42:11 tom Exp $ */
2 
3 #include <vttest.h>
4 #include <ttymodes.h>
5 #include <esc.h>
6 
7 static int
testing(const char * name,int row)8 testing(const char *name, int row)
9 {
10   char buffer[1024];
11 
12   sprintf(buffer,
13           "Testing %s. "
14           "A real VT%d will not recognize %s at this point",
15           name, terminal_id(), name);
16   println(buffer);
17   return row + 1;
18 }
19 
20 static int
isreturn(const char * reply)21 isreturn(const char *reply)
22 {
23   return (*reply == '\r' || *reply == '\n');
24 }
25 
26 int
tst_vt52(MENU_ARGS)27 tst_vt52(MENU_ARGS)
28 {
29   /* *INDENT-OFF* */
30   static struct {
31       const char *rcode;
32       const char *rmsg;
33   } resptable[] = {
34       { "\033/A", " -- OK (VT50)" },
35       { "\033/C", " -- OK (VT55)" },
36       { "\033/H", " -- OK (VT50H without copier)" },
37       { "\033/J", " -- OK (VT50H with copier)" },
38       { "\033/K", " -- OK (means Standard VT52)" },
39       { "\033/L", " -- OK (VT52 with copier)" },
40       { "\033/Z", " -- OK (means VT100 emulating VT52)" },
41       { "",       " -- Unknown response"}
42   };
43   /* *INDENT-ON* */
44 
45   int i, j;
46   char *response;
47   VTLEVEL save;
48 
49   save_level(&save);
50   set_level(0); /* Reset ANSI (VT100) mode, Set VT52 mode  */
51   vt52home();   /* Cursor home     */
52   vt52ed();     /* Erase to end of screen  */
53   vt52home();   /* Cursor home     */
54   for (i = 0; i <= max_lines - 1; i++) {
55     for (j = 0; j <= 9; j++)
56       printf("%s", "FooBar ");
57     println("Bletch");
58   }
59   vt52home();   /* Cursor home     */
60   vt52ed();     /* Erase to end of screen  */
61 
62   vt52cup(7, 47);
63   printf("nothing more.");
64   for (i = 1; i <= 10; i++)
65     printf("THIS SHOULD GO AWAY! ");
66   for (i = 1; i <= 5; i++) {
67     vt52cup(1, 1);
68     printf("%s", "Back scroll (this should go away)");
69     vt52ri();   /* Reverse LineFeed (with backscroll!)  */
70   }
71   vt52cup(12, 60);
72   vt52ed();     /* Erase to end of screen  */
73   for (i = 2; i <= 6; i++) {
74     vt52cup(i, 1);
75     vt52el();   /* Erase to end of line */
76   }
77 
78   for (i = 2; i <= max_lines - 1; i++) {
79     vt52cup(i, 70);
80     printf("%s", "**Foobar");
81   }
82   vt52cup(max_lines - 1, 10);
83   for (i = max_lines - 1; i >= 2; i--) {
84     printf("%s", "*");
85     printf("%c", 8);  /* BS */
86     vt52ri();   /* Reverse LineFeed (LineStarve)        */
87   }
88   vt52cup(1, 70);
89   for (i = 70; i >= 10; i--) {
90     printf("%s", "*");
91     vt52cub1();
92     vt52cub1(); /* Cursor Left */
93   }
94   vt52cup(max_lines, 10);
95   for (i = 10; i <= 70; i++) {
96     printf("%s", "*");
97     printf("%c", 8);  /* BS */
98     vt52cuf1(); /* Cursor Right */
99   }
100   vt52cup(2, 11);
101   for (i = 2; i <= max_lines - 1; i++) {
102     printf("%s", "!");
103     printf("%c", 8);  /* BS */
104     vt52cud1(); /* Cursor Down  */
105   }
106   vt52cup(max_lines - 1, 69);
107   for (i = max_lines - 1; i >= 2; i--) {
108     printf("%s", "!");
109     printf("%c", 8);  /* BS */
110     vt52cuu1(); /* Cursor Up    */
111   }
112   for (i = 2; i <= max_lines - 1; i++) {
113     vt52cup(i, 71);
114     vt52el();   /* Erase to end of line */
115   }
116 
117   vt52cup(10, 16);
118   printf("%s", "The screen should be cleared, and have a centered");
119   vt52cup(11, 16);
120   printf("%s", "rectangle of \"*\"s with \"!\"s on the inside to the");
121   vt52cup(12, 16);
122   printf("%s", "left and right. Only this, and");
123   vt52cup(13, 16);
124   holdit();
125 
126   vt52home();   /* Cursor home     */
127   vt52ed();     /* Erase to end of screen  */
128   printf("%s", "This is the normal character set:");
129   for (j = 0; j <= 1; j++) {
130     vt52cup(3 + j, 16);
131     for (i = 0; i <= 47; i++)
132       printf("%c", 32 + i + 48 * j);
133   }
134   vt52cup(6, 1);
135   printf("%s", "This is the special graphics character set:");
136   esc("F");     /* Select Special Graphics character set        */
137   for (j = 0; j <= 1; j++) {
138     vt52cup(8 + j, 16);
139     for (i = 0; i <= 47; i++)
140       printf("%c", 32 + i + 48 * j);
141   }
142   esc("G");     /* Select ASCII character set   */
143   vt52cup(12, 1);
144   holdit();
145 
146   vt52home();   /* Cursor home     */
147   vt52ed();     /* Erase to end of screen  */
148   println("Test of terminal response to IDENTIFY command");
149 
150   /*
151    * According to J.Altman, DECID isn't recognized by VT5xx terminals.  Real
152    * DEC terminals through VT420 do, though it isn't recommended.  VT420's
153    * emulation of VT52 does not recognize DA -- so we use DECID in this case.
154    */
155   set_tty_raw(TRUE);
156   decid();      /* Identify     */
157   response = get_reply();
158   println("");
159 
160   restore_level(&save);
161   restore_ttymodes();
162   padding(10);  /* some terminals miss part of the response otherwise */
163 
164   printf("Response was ");
165   chrprint2(response, 2, 13);
166   for (i = 0; resptable[i].rcode[0] != '\0'; i++) {
167     if (!strcmp(response, resptable[i].rcode)) {
168       show_result("%s", resptable[i].rmsg);
169       break;
170     }
171   }
172   println("");
173   println("");
174 
175   /*
176    * Verify whether returning to ANSI mode restores the previous operating
177    * level.  If it was a VT220, we can check this by seeing if 8-bit controls
178    * work; if a VT420 we can check the value of DECSCL.  A real VT420 goes to
179    * VT100 mode.
180    */
181   if (terminal_id() >= 200) {
182     int row, col;
183 
184     row = 8;
185     set_level(0);   /* Reset ANSI (VT100) mode, Set VT52 mode  */
186     println("Verify operating level after restoring ANSI mode");
187     esc("<");   /* Enter ANSI mode (VT100 mode) */
188     set_tty_raw(TRUE);
189     if (save.cur_level >= 3) {  /* VT340 implements DECRQSS */
190       vt_move(row, 1);
191       row = testing("DECSCL", row);
192       println("You should have to press return to continue:");
193       println("");
194       decrqss("\"p");
195       response = get_reply();
196       vt_move(++row, col = 10);
197       printf("Response was");
198       chrprint2(response, row, col);
199       if (isreturn(response)) {
200         show_result(SHOW_SUCCESS);
201       } else {
202         if (parse_decrqss(response, "\"p") > 0)
203           printf("DECSCL recognized --");
204         show_result(SHOW_FAILURE);
205       }
206       println("");
207       row++;
208     }
209 
210     if (save.cur_level >= 2) {
211       const char *temp;
212 
213       vt_move(++row, 1);
214       row = testing("S8C1T", row);
215       s8c1t(1);
216       cup(1, 1);
217       dsr(6);
218       response = instr();
219       vt_move(row, col = 10);
220       printf("Response to CUP(1,1)/DSR(6)");
221       chrprint2(response, row, col);
222       if ((temp = skip_prefix(csi_input(), response)) != 0) {
223         if (!strcmp("1;1R", temp)) {
224           printf("S8C1T recognized --");
225           show_result(SHOW_FAILURE);
226         } else {
227           printf("unknown response --");
228           show_result(SHOW_FAILURE);
229         }
230       } else {
231         input_8bits = FALSE;  /* we expect this anyway */
232         if ((temp = skip_prefix(csi_input(), response)) != 0
233             && !strcmp("1;1R", temp)) {
234           show_result(SHOW_SUCCESS);
235         } else {
236           printf("unknown response --");
237           show_result(SHOW_FAILURE);
238         }
239       }
240     }
241     restore_level(&save);
242     restore_ttymodes();
243     println("");
244     println("");
245   }
246   return MENU_HOLD;
247 }
248