1 /* Visually check 256 color capability of terminal
3 * (C) 2008 Nelson Ferreira
5 * This program is free software; you can redistribute it and/or modify it
6 * under a BSD-like licence.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are met:
10 * Redistributions of source code must retain the above copyright notice, this
11 * list of conditions and the following disclaimer.
12 * Redistributions in binary form must reproduce the above copyright notice,
13 * this list of conditions and the following disclaimer in the documentation
14 * and/or other materials provided with the distribution.
15 * Neither the name of the Technical University of Berlin nor the names of its
16 * contributors may be used to endorse or promote products derived from this
17 * software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
41 * For the terminal info
43 static char term_buffer[8192];
46 * For the capabilities
71 * Initialize the terminal info
73 void init_terminal_data ()
75 char *termtype = getenv ("TERM");
79 fprintf(stderr,"Specify a terminal type with `setenv TERM <yourtype>'.\n");
83 success = tgetent (term_buffer, termtype);
85 fprintf(stderr,"Could not access the termcap data base.\n");
89 fprintf(stderr,"Terminal type `%s' is not defined.\n", termtype);
95 * Print a band with background of all available colors
97 void colormap( int do_boldstand )
100 for( back = 0; back < maxcolors; back++ ) {
102 strB = strdup(tparm(setback,back));
103 printf("%s %s",strB,resetcolor);
108 for( back = 0; back < maxcolors; back++ ) {
110 strB = strdup(tparm(setfore,back));
111 printf("%s%s%s %s%s%s",bold,standstr,strB,resetcolor,
112 exit_stand,exit_attr);
117 for ( back = 0; back < maxcolors; back++ ) {
119 strB = strdup(tparm(setfore,back));
120 printf("%sXXXXXXXX%s",strB,resetcolor);
125 for ( back = 0; back < maxcolors; back++ ) {
127 strB = strdup(tparm(setfore,back));
128 printf("%s%sXXXXXXXX%s%s",bold,strB,resetcolor,exit_attr);
136 /*********************
137 * Print a table with all the fore and background
138 * color combinations, with bold and optionally standout
140 void combinations_of_colors(int do_standout, int do_boldstand)
143 for( fore = 0; fore < maxcolors; fore ++ )
144 for( back = 0; back < maxcolors; back ++ ) {
147 strB = strdup(tparm(setback,back));
148 strF = strdup(tparm(setfore,fore));
149 printf( "%s%s%s [%3d|%3d]%s%s", "",strF,strB,fore,back,resetcolor,"");
151 printf( "%s%s%sB[%3d|%3d]%s%s", bold,strF,strB,fore,back,resetcolor,exit_attr);
152 /* Standout usually does not work good... do only if asked for */
153 /* Since standout usually reverses, we'll reverse the fore and back too */
154 sstrB = strdup(tparm(setback,fore));
155 sstrF = strdup(tparm(setfore,back));
157 printf( "%s%s%sS[%3d|%3d]%s%s",standstr,sstrF,sstrB,fore,back,resetcolor,exit_stand);
159 printf( "%s%s%s%sS[%3d|%3d]%s%s%s",bold,standstr,sstrF,sstrB,fore,back,resetcolor,exit_stand,exit_attr);
167 /** Query and assign a capability
169 void capability(char**buf,char*code,char**var,char*message)
171 char *val = tgetstr(code,buf);
174 printf("%s\n",message);
181 /****************************
182 * Retrieve the capabilities
184 void get_capabilities()
186 char buffer[2500]="", *buf=buffer;
189 * Get the capabilities
191 maxcolors = tgetnum("Co");
192 if ( maxcolors <= 0 ) {
193 printf("I am sorry, your terminal does not show color in the capabilities\n");
195 maxpairs = tgetnum("pa");
196 if (maxpairs <= 0 ) {
197 printf("I am sorry, your terminal does not have the max color pairs information\n");
200 capability(&buf,"AF",&setfore,
201 "I am sorry, your terminal does not have the set foreground color string in the capabilities");
202 capability(&buf,"AB",&setback,
203 "I am sorry, your terminal does not have the set background color string in the capabilities");
204 capability(&buf,"op",&resetcolor,
205 "I am sorry, your terminal does not have the reset current color string in the capabilities");
206 capability(&buf,"md",&bold,
207 "I am sorry, your terminal does not have the bold string in the capabilities");
208 capability(&buf,"mh",&dim,
209 "I am sorry, your terminal does not have the dim string in the capabilities");
210 capability(&buf,"mr",&reverse,
211 "I am sorry, your terminal does not have the reverse string in the capabilities");
212 capability(&buf,"mb",&blinking,
213 "I am sorry, your terminal does not have the blinking string in the capabilities");
214 capability(&buf,"so",&standstr,
215 "I am sorry, your terminal does not have the standout string in the capabilities");
216 capability(&buf,"se",&exit_stand,
217 "I am sorry, your terminal does not have the exit standout string in the capabilities");
218 capability(&buf,"me",&exit_attr,
219 "I am sorry, your terminal does not have the exit attribute string in the capabilities");
220 capability(&buf,"Ic",&inicolor_str,
221 "I am sorry, your terminal does not have the init color string in the capabilities");
222 capability(&buf,"Yw",&clrnames,
223 "I am sorry, your terminal does not have the color names string in the capabilities");
224 capability(&buf,"op",&opair,
225 "I am sorry, your terminal does not have the original pairs string in the capabilities");
229 /********************
234 int i, fd=fileno(stdin);
238 if ( ! isatty(fd) || ! isatty(fileno(stdout)) )
239 printf("Sorry, but stdin and/or stdout is not the terminal tty so I cannot query it\n");
241 if ( ! inicolor_str )
242 printf("According to your terminal info this terminal rgb query will hang. Press ^C to abort the query.\n");
245 * We need to do the equivalent of cbreak()
248 mode=ts.c_lflag; /* Save mode so we can restore afterwards */
249 ts.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN);
250 tcsetattr(fd, TCSANOW,&ts);
253 /* Ask for the colors */
254 for ( i = 0 ; 1 ; i ++ ) {
257 *end=buffer+sizeof(buffer)-1;
260 /* This is a string retrieved from Noah
261 * Friedmans xterm-frobs.el. I could not find
262 * any termcap entry that verifies it
264 printf("\e]4;%d;?;\e\\",i);
266 memset(buffer,0,sizeof(buffer));
268 fd_set fdsr, fdse,fdsw;
273 t.tv_usec = 100000; /* 100ms */
280 fds = select(fd+1,&fdsr,&fdsw,&fdse,&t);
282 tcsetattr(fd, TCSANOW,&ts);
285 if ( ! FD_ISSET(fd, &fdsr) ) {
286 tcsetattr(fd, TCSANOW,&ts);
291 /* The response sequence ends with the only "\"
296 if ( *buf == '
\ 3' ) {
298 If the terminal did not reply, chances are
299 this is not supported and the user used ^C
309 /* Extract the rgb values */
310 buf=strstr(buffer,"rgb:");
313 char *end = strstr(buf,"\e\\");
317 buf="Did not find info";
319 printf("Color %d: %s\n",i,buf);
323 /* Restore terminal settings */
324 tcsetattr(fd, TCSANOW,&ts);
330 * Fake the capabilities the ansi terminal info
335 if ( ! (maxcolors > 0) ) {
337 printf("WARNING: Forcing ANSI testing, 8 colors\n");
339 if ( maxcolors == 8 && do_force_16 ) {
341 printf("WARNING: Forcing 16 color testing\n");
344 setfore="\e[3%p1%dm";
345 printf("WARNING: Forcing ANSI set foreground: ^[%s\n", setfore+1);
348 setback="\e[4%p1%dm";
349 printf("WARNING: Forcing ANSI set background: ^[%s\n", setback+1);
351 if ( ! resetcolor ) {
352 resetcolor="\e[39;49m";
353 printf("WARNING: Forcing ANSI reset colour : ^[%s\n", resetcolor+1);
360 main( int argc, char *argv[] )
368 { /* Process arguments */
371 for( i = 1; i < argc; i++ ) {
372 if( ! strcmp(argv[i],"-m") )
374 if( ! strcmp(argv[i],"-c") )
376 if ( ! strcmp(argv[i], "-f" ) )
378 if( ! strcmp(argv[i],"-s") )
380 if( ! strcmp(argv[i],"-bs") )
382 if( ! strcmp(argv[i],"-q") )
387 init_terminal_data();
392 * Report the capabilities
394 printf("\n\nTerminal: %s\n",getenv("TERM"));
396 printf("You've got %d colours\n",maxcolors);
398 printf("You've got %d pairs of colors possible\n",maxpairs);
400 if ( setfore ) printf("To set foreground: ^[%s\n", setfore+1);
401 if ( setback ) printf("To set background: ^[%s\n", setback+1);
402 if ( resetcolor ) printf("To reset colours : ^[%s\n", resetcolor+1);
403 if ( standstr ) printf("To standout : ^[%s\n", standstr+1);
404 if ( bold ) printf("To bold : ^[%s\n", bold+1);
405 if ( dim ) printf("To dim : ^[%s\n", dim+1);
406 if ( reverse ) printf("To reverse : ^[%s\n", reverse+1);
407 if ( blinking ) printf("To blinking : ^[%s\n", blinking+1);
408 if ( exit_stand ) printf("To exit standout : ^[%s\n", exit_stand+1);
409 if ( exit_attr ) printf("To exit attribute: ^[%s\n", exit_attr+1);
410 if ( inicolor_str ) printf("To init color : ^[%s\n", inicolor_str+1);
411 if ( clrnames ) printf("To color names : ^[%s\n", clrnames+1);
412 if ( opair ) printf("To original pairs: ^[%s\n", opair+1);
417 * Let's try the ANSI defaults
419 if ( do_colormap || do_combinations ) {
424 printf("\nQuery the RGB from the terminal:\n");
429 printf("\nColormap:\n");
430 colormap( do_boldstand );
433 if ( do_combinations ) {
434 printf("\nColor combinations:\n");
435 combinations_of_colors( do_standout,