]> ncurses.scripts.mit.edu Git - ncurses.git/blob - test/color_content.c
ncurses 6.3 - patch 20221210
[ncurses.git] / test / color_content.c
1 /****************************************************************************
2  * Copyright 2018-2020,2022 Thomas E. Dickey                                *
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  * $Id: color_content.c,v 1.18 2022/12/10 22:28:50 tom Exp $
30  */
31
32 #define NEED_TIME_H
33 #include <test.priv.h>
34
35 #if USE_EXTENDED_COLOR
36 typedef int my_color_t;
37 #else
38 typedef NCURSES_COLOR_T my_color_t;
39 #endif
40
41 typedef struct {
42     my_color_t r;
43     my_color_t g;
44     my_color_t b;
45 } MYCOLOR;
46
47 static int f_opt;
48 static int i_opt;
49 static int l_opt;
50 static int n_opt;
51 static int p_opt;
52 static int r_opt;
53 static int s_opt;
54
55 #if USE_EXTENDED_COLOR
56 static int x_opt;
57 #endif
58
59 static MYCOLOR *expected;
60
61 #if HAVE_GETTIMEOFDAY
62 static struct timeval initial_time;
63 static struct timeval finish_time;
64 #endif
65
66 static void
67 failed(const char *msg)
68 {
69     printw("%s", msg);
70     getch();
71     endwin();
72     ExitProgram(EXIT_FAILURE);
73 }
74
75 #if USE_EXTENDED_COLOR
76 static int
77 InitColor(int pair, int r, int g, int b)
78 {
79     int rc;
80     if (x_opt) {
81         rc = init_extended_color(pair, r, g, b);
82     } else {
83         rc = init_color((NCURSES_PAIRS_T) pair,
84                         (NCURSES_COLOR_T) r,
85                         (NCURSES_COLOR_T) g,
86                         (NCURSES_COLOR_T) b);
87     }
88     return rc;
89 }
90
91 static int
92 ColorContent(int color, int *rp, int *gp, int *bp)
93 {
94     int rc;
95     if (x_opt) {
96         rc = extended_color_content(color, rp, gp, bp);
97     } else {
98         NCURSES_COLOR_T r, g, b;
99         if ((rc = color_content((NCURSES_COLOR_T) color, &r, &g, &b)) == OK) {
100             *rp = r;
101             *gp = g;
102             *bp = b;
103         }
104     }
105     return rc;
106 }
107 #else
108 #define InitColor(color,r,g,b)       init_color((NCURSES_COLOR_T)color,(NCURSES_COLOR_T)r,(NCURSES_COLOR_T)g,(NCURSES_COLOR_T)b)
109 #define ColorContent(color,rp,gp,bp) color_content((NCURSES_COLOR_T)color,rp,gp,bp)
110 #endif
111
112 static my_color_t
113 random_color(void)
114 {
115     return (my_color_t) (rand() % 1000);
116 }
117
118 static void
119 setup_test(void)
120 {
121     setlocale(LC_ALL, "");
122     initscr();
123     cbreak();
124     noecho();
125     scrollok(stdscr, TRUE);
126     if (has_colors()) {
127         start_color();
128         if (!can_change_color() && !p_opt)
129             failed("this terminal cannot initialize colors");
130
131         if (!f_opt)
132             f_opt = 0;
133         if (!l_opt)
134             l_opt = COLORS;
135         if (l_opt <= 0)
136             failed("color limit must be greater than zero");
137
138         if (!n_opt) {
139             int color;
140             size_t need = (size_t) ((l_opt > COLORS) ? l_opt : COLORS) + 1;
141
142             expected = typeCalloc(MYCOLOR, need);
143             if (s_opt) {
144                 int r;
145                 int g;
146                 int b;
147                 color = f_opt;
148                 for (r = 0; r < 1000; ++r) {
149                     for (g = 0; g < 1000; ++g) {
150                         for (b = 0; b < 1000; ++b) {
151                             if (color < l_opt) {
152                                 InitColor(color, r, g, b);
153                                 expected[color].r = (my_color_t) r;
154                                 expected[color].g = (my_color_t) g;
155                                 expected[color].b = (my_color_t) b;
156                                 ++color;
157                             } else {
158                                 break;
159                             }
160                         }
161                     }
162                 }
163             } else {
164                 for (color = f_opt; color < l_opt; ++color) {
165                     expected[color].r = random_color();
166                     expected[color].g = random_color();
167                     expected[color].b = random_color();
168                     InitColor(color,
169                               expected[color].r,
170                               expected[color].g,
171                               expected[color].b);
172                 }
173             }
174         }
175     } else {
176         failed("This demo requires a color terminal");
177     }
178 #if HAVE_GETTIMEOFDAY
179     gettimeofday(&initial_time, 0);
180 #endif
181 }
182
183 static void
184 run_test(void)
185 {
186     int color;
187     bool success = TRUE;
188     for (color = f_opt; color < l_opt; ++color) {
189         my_color_t r;
190         my_color_t g;
191         my_color_t b;
192         if (ColorContent(color, &r, &g, &b) == OK) {
193             if (expected != 0) {
194                 if (r != expected[color].r)
195                     success = FALSE;
196                 if (g != expected[color].g)
197                     success = FALSE;
198                 if (b != expected[color].b)
199                     success = FALSE;
200             }
201         }
202     }
203     if (i_opt) {
204         addch(success ? '.' : '?');
205         refresh();
206     }
207 }
208
209 static void
210 finish_test(void)
211 {
212     getch();
213     endwin();
214 }
215
216 #if HAVE_GETTIMEOFDAY
217 static double
218 seconds(struct timeval *mark)
219 {
220     double result = (double) mark->tv_sec;
221     result += ((double) mark->tv_usec / 1e6);
222     return result;
223 }
224 #endif
225
226 static void
227 usage(int ok)
228 {
229     static const char *msg[] =
230     {
231         "Usage: color_content [options]"
232         ,""
233         ,USAGE_COMMON
234         ,"Options:"
235         ," -f COLOR first color value to test (default: 0)"
236         ," -i       interactive, showing test-progress"
237         ," -l COLOR last color value to test (default: max_colors-1)"
238         ," -n       do not initialize color pairs"
239         ," -p       print data for color content instead of testing"
240         ," -r COUNT repeat for given count"
241         ," -s       initialize pairs sequentially rather than random"
242 #if USE_EXTENDED_COLOR
243         ," -x       use extended color pairs/values"
244 #endif
245     };
246     size_t n;
247     for (n = 0; n < SIZEOF(msg); n++)
248         fprintf(stderr, "%s\n", msg[n]);
249     ExitProgram(ok ? EXIT_SUCCESS : EXIT_FAILURE);
250 }
251 /* *INDENT-OFF* */
252 VERSION_COMMON()
253 /* *INDENT-ON* */
254
255 int
256 main(int argc, char *argv[])
257 {
258     int ch;
259
260     while ((ch = getopt(argc, argv, OPTS_COMMON "f:il:npr:sx")) != -1) {
261         switch (ch) {
262         case 'f':
263             if ((f_opt = atoi(optarg)) <= 0)
264                 usage(FALSE);
265             break;
266         case 'i':
267             i_opt = 1;
268             break;
269         case 'l':
270             if ((l_opt = atoi(optarg)) <= 0)
271                 usage(FALSE);
272             break;
273         case 'n':
274             n_opt = 1;
275             break;
276         case 'p':
277             p_opt = 1;
278             break;
279         case 'r':
280             if ((r_opt = atoi(optarg)) <= 0)
281                 usage(FALSE);
282             break;
283         case 's':
284             s_opt = 1;
285             break;
286 #if USE_EXTENDED_COLOR
287         case 'x':
288             x_opt = 1;
289             break;
290 #endif
291         case OPTS_VERSION:
292             show_version(argv);
293             ExitProgram(EXIT_SUCCESS);
294         default:
295             usage(ch == OPTS_USAGE);
296             /* NOTREACHED */
297         }
298     }
299     if (optind < argc)
300         usage(FALSE);
301     if (r_opt <= 0)
302         r_opt = 1;
303
304     setup_test();
305     if (p_opt) {
306         int i;
307         endwin();
308         for (i = 0; i < COLORS; ++i) {
309             my_color_t r, g, b;
310             if (ColorContent(i, &r, &g, &b) == OK) {
311                 printf("%d: %d %d %d\n", i, r, g, b);
312             } else {
313                 printf("%d: ? ?\n", i);
314             }
315         }
316     } else {
317         int repeat;
318
319         for (repeat = 0; repeat < r_opt; ++repeat) {
320             run_test();
321             if (i_opt) {
322                 addch('.');
323                 refresh();
324             }
325         }
326
327         if (i_opt) {
328             addch('\n');
329         }
330         printw("DONE: ");
331 #if HAVE_GETTIMEOFDAY
332         gettimeofday(&finish_time, 0);
333         printw("%.03f seconds",
334                seconds(&finish_time)
335                - seconds(&initial_time));
336 #endif
337         finish_test();
338     }
339
340     free(expected);
341     ExitProgram(EXIT_SUCCESS);
342 }