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