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  * $Id: extended_color.c,v 1.15 2020/02/02 23:34:34 tom Exp $
31  */
32 
33 #include <test.priv.h>
34 
35 #if USE_EXTENDED_COLOR
36 
37 #define SHOW(n) ((n) == ERR ? "ERR" : "OK")
38 
39 #if USE_SP_FUNCS
40 static bool opt_s = FALSE;
41 #define if_opt_s(a,b) (opt_s ? (a) : (b))
42 #else
43 #define if_opt_s(a,b) (b)
44 #endif
45 
46 static void
failed(const char * name)47 failed(const char *name)
48 {
49     printw("...%s failed", name);
50     getch();
51     endwin();
52     ExitProgram(EXIT_FAILURE);
53 }
54 
55 static void
do_pair_content(SCREEN * sp,int pair)56 do_pair_content(SCREEN *sp, int pair)
57 {
58     int i, f, b;
59 
60     (void) sp;
61     i = if_opt_s(extended_pair_content_sp(sp, pair, &f, &b),
62 		 extended_pair_content(0, &f, &b));
63     if (i != OK)
64 	failed("pair_content");
65     printw("pair %d contains (%d,%d)\n", pair, f, b);
66     getch();
67 }
68 
69 static void
do_init_pair(SCREEN * sp,int pair,int fg,int bg)70 do_init_pair(SCREEN *sp, int pair, int fg, int bg)
71 {
72     int i;
73 
74     (void) sp;
75     i = if_opt_s(init_extended_pair_sp(sp, pair, fg, bg),
76 		 init_extended_pair(pair, fg, bg));
77     if (i != OK)
78 	failed("init_pair");
79 }
80 
81 static void
do_init_color(SCREEN * sp,int color,int adjust)82 do_init_color(SCREEN *sp, int color, int adjust)
83 {
84     int r, g, b;
85     int i;
86 
87     (void) sp;
88     i = if_opt_s(extended_color_content_sp(sp, color, &r, &g, &b),
89 		 extended_color_content(color, &r, &g, &b));
90     if (i != OK)
91 	failed("color_content");
92 
93     r = (adjust + 1000 + r) % 1000;
94     g = (adjust + 1000 + g) % 1000;
95     b = (adjust + 1000 + b) % 1000;
96 
97     i = if_opt_s(init_extended_color_sp(sp, color, r, g, b),
98 		 init_extended_color(color, r, g, b));
99     if (i != OK)
100 	failed("init_color");
101 }
102 
103 static void
do_color_set(const char * expected,int pair)104 do_color_set(const char *expected, int pair)
105 {
106     int i = color_set((short) pair, (void *) &pair);
107     printw("%s (%s)\n", expected, SHOW(i));
108     if (i != OK)
109 	failed("color_set");
110     getch();
111 }
112 
113 static void
show_1_rgb(SCREEN * sp,const char * name,int color,int y,int x)114 show_1_rgb(SCREEN *sp, const char *name, int color, int y, int x)
115 {
116     int r, g, b;
117     int i;
118 
119     (void) sp;
120     i = if_opt_s(extended_color_content_sp(sp, color, &r, &g, &b),
121 		 extended_color_content(color, &r, &g, &b));
122     wmove(stdscr, y, x);
123     if (i == OK) {
124 	printw("%-8s %3d/%3d/%3d", name, r, g, b);
125     } else {
126 	printw("%-8s %s", name, SHOW(i));
127     }
128 }
129 
130 static void
show_rgb(SCREEN * sp)131 show_rgb(SCREEN *sp)
132 {
133     int y, x;
134     getyx(stdscr, y, x);
135     show_1_rgb(sp, "RED", COLOR_RED, y + 1, x);
136     show_1_rgb(sp, "GREEN", COLOR_GREEN, y + 2, x);
137     show_1_rgb(sp, "BLUE", COLOR_BLUE, y + 3, x);
138     wmove(stdscr, y, x);
139 }
140 
141 static void
usage(void)142 usage(void)
143 {
144     static const char *tbl[] =
145     {
146 	"Usage: extended_color",
147 	"",
148 	"Options:",
149 	" -s   use sp-funcs",
150 	NULL
151     };
152     size_t n;
153     for (n = 0; n < SIZEOF(tbl); ++n) {
154 	fprintf(stderr, "%s\n", tbl[n]);
155     }
156     ExitProgram(EXIT_FAILURE);
157 }
158 
159 int
main(int argc GCC_UNUSED,char * argv[]GCC_UNUSED)160 main(int argc GCC_UNUSED, char *argv[]GCC_UNUSED)
161 {
162     int i;
163     SCREEN *sp;
164 
165     while ((i = getopt(argc, argv, "s")) != -1) {
166 	switch (i) {
167 #if USE_SP_FUNCS
168 	case 's':
169 	    opt_s = TRUE;
170 	    break;
171 #endif
172 	default:
173 	    usage();
174 	    /* NOTREACHED */
175 	}
176     }
177 
178     slk_init(1);
179     sp = newterm(NULL, stdout, stdin);
180     cbreak();
181     noecho();
182 
183     if (!has_colors()) {
184 	endwin();
185 	fprintf(stderr, "This demo requires a color terminal\n");
186 	ExitProgram(EXIT_FAILURE);
187     }
188 
189     start_color();
190 
191     do_pair_content(sp, 0);
192 
193     printw("Initializing pair 1 to red/black\n");
194     do_init_pair(sp, 1, COLOR_RED, COLOR_BLACK);
195     do_color_set("RED/BLACK", 1);
196 
197     printw("Initializing pair 2 to white/blue\n");
198     do_init_pair(sp, 2, COLOR_WHITE, COLOR_BLUE);
199     do_color_set("WHITE/BLUE", 2);
200 
201     printw("Initializing pair 3 to green/black\n");
202     do_init_pair(sp, 3, COLOR_GREEN, COLOR_BLACK);
203     do_color_set("GREEN/BLACK", 3);
204 
205     printw("Resetting colors to pair 0\n");
206     do_color_set("Default Colors", 0);
207 
208     printw("Resetting colors to pair 1\n");
209     do_color_set("RED/BLACK", 1);
210 
211     printw("Drawing soft-key tabs with pair 2\n");
212     slk_attrset(A_BOLD);	/* reverse-video is hard to see */
213     (void) if_opt_s(extended_slk_color_sp(sp, 2),
214 		    extended_slk_color(2));
215     for (i = 1; i <= 8; ++i) {
216 	char temp[80];
217 	_nc_SPRINTF(temp, _nc_SLIMIT(sizeof(temp)) "(SLK-%d)", i);
218 	slk_set(i, temp, 0);
219     }
220     slk_touch();
221     slk_noutrefresh();
222 
223     i = if_opt_s(can_change_color_sp(sp),
224 		 can_change_color());
225     if (i) {
226 	do_color_set("Default Colors", 0);
227 	printw("Press any key to stop...\n");
228 	nodelay(stdscr, TRUE);
229 	while (getch() == ERR) {
230 	    show_rgb(sp);
231 	    do_init_color(sp, COLOR_RED, 1);
232 	    do_init_color(sp, COLOR_BLUE, -1);
233 	    napms(50);
234 	}
235 	printw("...done");
236 	nodelay(stdscr, FALSE);
237 	getch();
238     }
239 
240     endwin();
241 
242     ExitProgram(EXIT_SUCCESS);
243 }
244 
245 #else
246 int
main(void)247 main(void)
248 {
249     printf("This program requires the ncurses extended color/pair functions\n");
250     ExitProgram(EXIT_FAILURE);
251 }
252 #endif
253