]> ncurses.scripts.mit.edu Git - ncurses.git/blob - test/color_content.c
6ed0ecf2e7323f8ce35c7a9a633b7558c55d4711
[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.13 2022/04/16 18:26:40 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(void)
228 {
229     static const char *msg[] =
230     {
231         "Usage: color_content [options]"
232         ,""
233         ,"Options:"
234         ," -f COLOR first color value to test (default: 0)"
235         ," -i       interactive, showing test-progress"
236         ," -l COLOR last color value to test (default: max_colors-1)"
237         ," -n       do not initialize color pairs"
238         ," -p       print data for color content instead of testing"
239         ," -r COUNT repeat for given count"
240         ," -s       initialize pairs sequentially rather than random"
241 #if USE_EXTENDED_COLOR
242         ," -x       use extended color pairs/values"
243 #endif
244     };
245     size_t n;
246     for (n = 0; n < SIZEOF(msg); n++)
247         fprintf(stderr, "%s\n", msg[n]);
248     ExitProgram(EXIT_FAILURE);
249 }
250
251 int
252 main(int argc GCC_UNUSED, char *argv[]GCC_UNUSED)
253 {
254     int i;
255
256     while ((i = getopt(argc, argv, "f:il:npr:sx")) != -1) {
257         switch (i) {
258         case 'f':
259             if ((f_opt = atoi(optarg)) <= 0)
260                 usage();
261             break;
262         case 'i':
263             i_opt = 1;
264             break;
265         case 'l':
266             if ((l_opt = atoi(optarg)) <= 0)
267                 usage();
268             break;
269         case 'n':
270             n_opt = 1;
271             break;
272         case 'p':
273             p_opt = 1;
274             break;
275         case 'r':
276             if ((r_opt = atoi(optarg)) <= 0)
277                 usage();
278             break;
279         case 's':
280             s_opt = 1;
281             break;
282 #if USE_EXTENDED_COLOR
283         case 'x':
284             x_opt = 1;
285             break;
286 #endif
287         default:
288             usage();
289         }
290     }
291     if (optind < argc)
292         usage();
293     if (r_opt <= 0)
294         r_opt = 1;
295
296     setup_test();
297     if (p_opt) {
298         endwin();
299         for (i = 0; i < COLORS; ++i) {
300             my_color_t r, g, b;
301             if (ColorContent(i, &r, &g, &b) == OK) {
302                 printf("%d: %d %d %d\n", i, r, g, b);
303             } else {
304                 printf("%d: ? ?\n", i);
305             }
306         }
307     } else {
308         int repeat;
309
310         for (repeat = 0; repeat < r_opt; ++repeat) {
311             run_test();
312             if (i_opt) {
313                 addch('.');
314                 refresh();
315             }
316         }
317
318         if (i_opt) {
319             addch('\n');
320         }
321         printw("DONE: ");
322 #if HAVE_GETTIMEOFDAY
323         gettimeofday(&finish_time, 0);
324         printw("%.03f seconds",
325                seconds(&finish_time)
326                - seconds(&initial_time));
327 #endif
328         finish_test();
329     }
330
331     ExitProgram(EXIT_SUCCESS);
332 }