e3558b0d77bbf95b56f5332da6e06a2afc233f99
[ncurses.git] / test / railroad.c
1 /****************************************************************************
2  * Copyright 2019,2020 Thomas E. Dickey                                     *
3  * Copyright 2000-2013,2017 Free Software Foundation, Inc.                  *
4  *                                                                          *
5  * Permission is hereby granted, free of charge, to any person obtaining a  *
6  * copy of this software and associated documentation files (the            *
7  * "Software"), to deal in the Software without restriction, including      *
8  * without limitation the rights to use, copy, modify, merge, publish,      *
9  * distribute, distribute with modifications, sublicense, and/or sell       *
10  * copies of the Software, and to permit persons to whom the Software is    *
11  * furnished to do so, subject to the following conditions:                 *
12  *                                                                          *
13  * The above copyright notice and this permission notice shall be included  *
14  * in all copies or substantial portions of the Software.                   *
15  *                                                                          *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS  *
17  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF               *
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.   *
19  * IN NO EVENT SHALL THE ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,   *
20  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR    *
21  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR    *
22  * THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               *
23  *                                                                          *
24  * Except as contained in this notice, the name(s) of the above copyright   *
25  * holders shall not be used in advertising or otherwise to promote the     *
26  * sale, use or other dealings in this Software without prior written       *
27  * authorization.                                                           *
28  ****************************************************************************/
29
30 /*
31  * Author: Thomas E. Dickey - 2000
32  *
33  * $Id: railroad.c,v 1.24 2020/02/02 23:34:34 tom Exp $
34  *
35  * A simple demo of the termcap interface.
36  */
37 #define USE_TINFO
38 #include <test.priv.h>
39
40 #if HAVE_TGETENT
41
42 static char *wipeit;
43 static char *moveit;
44 static int length;
45 static int height;
46
47 static char *finisC;
48 static char *finisS;
49 static char *finisU;
50
51 static char *startC;
52 static char *startS;
53 static char *startU;
54
55 static char *backup;
56
57 static bool interrupted = FALSE;
58
59 static
60 TPUTS_PROTO(outc, c)
61 {
62     int rc = OK;
63
64     if (interrupted) {
65         char tmp = (char) c;
66         if (write(STDOUT_FILENO, &tmp, (size_t) 1) == -1)
67             rc = ERR;
68     } else {
69         if (putc(c, stdout) == EOF)
70             rc = ERR;
71     }
72     TPUTS_RETURN(rc);
73 }
74
75 static void
76 PutChar(int ch)
77 {
78     putchar(ch);
79     fflush(stdout);
80     napms(moveit ? 10 : 50);    /* not really termcap... */
81 }
82
83 static void
84 Backup(void)
85 {
86     tputs(backup != 0 ? backup : "\b", 1, outc);
87 }
88
89 static void
90 MyShowCursor(int flag)
91 {
92     if (startC != 0 && finisC != 0) {
93         tputs(flag ? startC : finisC, 1, outc);
94     }
95 }
96
97 static void
98 StandOut(int flag)
99 {
100     if (startS != 0 && finisS != 0) {
101         tputs(flag ? startS : finisS, 1, outc);
102     }
103 }
104
105 static void
106 Underline(int flag)
107 {
108     if (startU != 0 && finisU != 0) {
109         tputs(flag ? startU : finisU, 1, outc);
110     }
111 }
112
113 static void
114 ShowSign(char *string)
115 {
116     char *base = string;
117     int first, last;
118
119     if (moveit != 0) {
120         tputs(tgoto(moveit, 0, height - 1), 1, outc);
121         tputs(wipeit, 1, outc);
122     }
123
124     while (*string != 0) {
125         int ch = *string;
126         if (ch != ' ') {
127             if (moveit != 0) {
128                 for (first = length - 2; first >= (string - base); first--) {
129                     if (first < length - 1) {
130                         tputs(tgoto(moveit, first + 1, height - 1), 1, outc);
131                         PutChar(' ');
132                     }
133                     tputs(tgoto(moveit, first, height - 1), 1, outc);
134                     PutChar(ch);
135                 }
136             } else {
137                 last = ch;
138                 if (isalpha(ch)) {
139                     first = isupper(ch) ? 'A' : 'a';
140                 } else if (isdigit(ch)) {
141                     first = '0';
142                 } else {
143                     first = ch;
144                 }
145                 if (first < last) {
146                     Underline(1);
147                     while (first < last) {
148                         PutChar(first);
149                         Backup();
150                         first++;
151                     }
152                     Underline(0);
153                 }
154             }
155             if (moveit != 0)
156                 Backup();
157         }
158         StandOut(1);
159         PutChar(ch);
160         StandOut(0);
161         fflush(stdout);
162         string++;
163     }
164     if (moveit != 0)
165         tputs(wipeit, 1, outc);
166     putchar('\n');
167 }
168
169 static void
170 cleanup(void)
171 {
172     Underline(0);
173     StandOut(0);
174     MyShowCursor(1);
175 }
176
177 static void
178 onsig(int n GCC_UNUSED)
179 {
180     interrupted = TRUE;
181     cleanup();
182     ExitProgram(EXIT_FAILURE);
183 }
184
185 static void
186 railroad(char **args)
187 {
188     NCURSES_CONST char *name = getenv("TERM");
189     char buffer[1024];
190     char area[1024], *ap = area;
191     int z;
192
193     if (name == 0)
194         name = "dumb";
195
196     InitAndCatch(z = tgetent(buffer, name), onsig);
197     if (z >= 0) {
198
199         wipeit = tgetstr("ce", &ap);
200         height = tgetnum("li");
201         length = tgetnum("co");
202         moveit = tgetstr("cm", &ap);
203
204         if (wipeit == 0
205             || moveit == 0
206             || height <= 0
207             || length <= 0) {
208             wipeit = 0;
209             moveit = 0;
210             height = 0;
211             length = 0;
212         }
213
214         startS = tgetstr("so", &ap);
215         finisS = tgetstr("se", &ap);
216
217         startU = tgetstr("us", &ap);
218         finisU = tgetstr("ue", &ap);
219
220         backup = tgetstr("le", &ap);
221
222         startC = tgetstr("ve", &ap);
223         finisC = tgetstr("vi", &ap);
224
225         MyShowCursor(0);
226
227         while (*args) {
228             ShowSign(*args++);
229         }
230         MyShowCursor(1);
231     }
232 }
233
234 int
235 main(int argc, char *argv[])
236 {
237     if (argc > 1) {
238         railroad(argv + 1);
239     } else {
240         static char world[] = "Hello World";
241         static char *hello[] =
242         {world, 0};
243         railroad(hello);
244     }
245     ExitProgram(EXIT_SUCCESS);
246 }
247
248 #else
249 int
250 main(int argc GCC_UNUSED,
251      char *argv[]GCC_UNUSED)
252 {
253     printf("This program requires termcap\n");
254     exit(EXIT_FAILURE);
255 }
256 #endif