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