ncurses 6.2 - patch 20200321
[ncurses.git] / test / dots_xcurses.c
1 /****************************************************************************
2  * Copyright 2018-2019,2020 Thomas E. Dickey                                *
3  * Copyright 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
32  *
33  * $Id: dots_xcurses.c,v 1.19 2020/02/02 23:34:34 tom Exp $
34  *
35  * A simple demo of the wide-curses interface used for comparison with termcap.
36  */
37 #include <test.priv.h>
38
39 #if !defined(_WIN32)
40 #include <sys/time.h>
41 #endif
42
43 #include <time.h>
44
45 #if USE_WIDEC_SUPPORT
46
47 #if HAVE_ALLOC_PAIR
48 #define NewPair(n) x_option ? ((void *)&(n)) : NULL
49 #else
50 #define NewPair(n) NULL
51 #endif
52
53 #define InitPair(p,fg,bg) init_pair((short) (p), (short) (fg), (short) (bg))
54
55 static bool interrupted = FALSE;
56 static long total_chars = 0;
57 static time_t started;
58
59 #if HAVE_ALLOC_PAIR
60 static bool x_option = FALSE;
61 #endif
62
63 static void
64 cleanup(void)
65 {
66     endwin();
67
68     printf("\n\n%ld total cells, rate %.2f/sec\n",
69            total_chars,
70            ((double) (total_chars) / (double) (time((time_t *) 0) - started)));
71 }
72
73 static void
74 onsig(int n GCC_UNUSED)
75 {
76     interrupted = TRUE;
77 }
78
79 static double
80 ranf(void)
81 {
82     long r = (rand() & 077777);
83     return ((double) r / 32768.);
84 }
85
86 static int
87 mypair(int fg, int bg)
88 {
89     int result;
90 #if HAVE_ALLOC_PAIR
91     if (x_option) {
92         result = alloc_pair(fg, bg);
93     } else
94 #endif
95     {
96         int pair = (fg * COLORS) + bg;
97         result = (pair >= COLOR_PAIRS) ? -1 : pair;
98     }
99     return result;
100 }
101
102 static void
103 set_colors(int fg, int bg)
104 {
105     int pair = mypair(fg, bg);
106     if (pair > 0) {
107         (void) color_set((short) pair, NewPair(pair));
108     }
109 }
110
111 static void
112 usage(void)
113 {
114     static const char *msg[] =
115     {
116         "Usage: dots_xcurses [options]"
117         ,""
118         ,"Options:"
119         ," -T TERM  override $TERM"
120 #if HAVE_USE_DEFAULT_COLORS
121         ," -d       invoke use_default_colors()"
122 #endif
123 #if HAVE_USE_ENV
124         ," -e       allow environment $LINES / $COLUMNS"
125 #endif
126         ," -m SIZE  set margin (default: 2)"
127         ," -s MSECS delay 1% of the time (default: 1 msecs)"
128 #if HAVE_ALLOC_PAIR
129         ," -x       use alloc_pair() rather than init_pair()"
130 #endif
131     };
132     size_t n;
133
134     for (n = 0; n < SIZEOF(msg); n++)
135         fprintf(stderr, "%s\n", msg[n]);
136
137     ExitProgram(EXIT_FAILURE);
138 }
139
140 int
141 main(int argc, char *argv[])
142 {
143     int fg, bg, ch;
144     wchar_t wch[2];
145     double r;
146     double c;
147 #if HAVE_USE_DEFAULT_COLORS
148     bool d_option = FALSE;
149 #endif
150     int m_option = 2;
151     int s_option = 1;
152     size_t need;
153     char *my_env;
154
155     while ((ch = getopt(argc, argv, "T:dem:s:x")) != -1) {
156         switch (ch) {
157         case 'T':
158             need = 6 + strlen(optarg);
159             my_env = malloc(need);
160             _nc_SPRINTF(my_env, _nc_SLIMIT(need) "TERM=%s", optarg);
161             putenv(my_env);
162             break;
163 #if HAVE_USE_DEFAULT_COLORS
164         case 'd':
165             d_option = TRUE;
166             break;
167 #endif
168 #if HAVE_USE_ENV
169         case 'e':
170             use_env(TRUE);
171             break;
172 #endif
173         case 'm':
174             m_option = atoi(optarg);
175             break;
176         case 's':
177             s_option = atoi(optarg);
178             break;
179 #if HAVE_ALLOC_PAIR
180         case 'x':
181             x_option = TRUE;
182             break;
183 #endif
184         default:
185             usage();
186             break;
187         }
188     }
189
190     srand((unsigned) time(0));
191
192     InitAndCatch(initscr(), onsig);
193     if (has_colors()) {
194         start_color();
195 #if HAVE_USE_DEFAULT_COLORS
196         if (d_option)
197             use_default_colors();
198 #endif
199 #if HAVE_ALLOC_PAIR
200         if (x_option) {
201             ;                   /* nothing */
202         } else
203 #endif
204         {
205             for (fg = 0; fg < COLORS; fg++) {
206                 for (bg = 0; bg < COLORS; bg++) {
207                     int pair;
208                     if (interrupted) {
209                         cleanup();
210                         ExitProgram(EXIT_FAILURE);
211                     }
212                     pair = mypair(fg, bg);
213                     if (pair > 0) {
214                         InitPair(pair, fg, bg);
215                     }
216                 }
217             }
218         }
219     }
220
221     r = (double) (LINES - (2 * m_option));
222     c = (double) (COLS - (2 * m_option));
223     started = time((time_t *) 0);
224
225     fg = COLOR_WHITE;
226     bg = COLOR_BLACK;
227     wch[1] = 0;
228     while (!interrupted) {
229         int x = (int) (c * ranf()) + m_option;
230         int y = (int) (r * ranf()) + m_option;
231         int p = (ranf() > 0.9) ? '*' : ' ';
232
233         move(y, x);
234         if (has_colors()) {
235             int z = (int) (ranf() * COLORS);
236             if (ranf() > 0.01) {
237                 set_colors(fg = z, bg);
238             } else {
239                 set_colors(fg, bg = z);
240                 napms(s_option);
241             }
242         } else {
243             if (ranf() <= 0.01) {
244                 if (ranf() > 0.6) {
245                     attr_on(WA_REVERSE, NULL);
246                 } else {
247                     attr_off(WA_REVERSE, NULL);
248                 }
249                 napms(s_option);
250             }
251         }
252         wch[0] = (wchar_t) p;
253         addnwstr(wch, 1);
254         refresh();
255         ++total_chars;
256     }
257     cleanup();
258     ExitProgram(EXIT_SUCCESS);
259 }
260
261 #else
262 int
263 main(void)
264 {
265     printf("This program requires the wide-ncurses library\n");
266     ExitProgram(EXIT_FAILURE);
267 }
268 #endif