Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / ipxe / src / core / ansicoldef.c
1 /*
2  * Copyright (C) 2013 Michael Brown <mbrown@fensystems.co.uk>.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA.
18  */
19
20 FILE_LICENCE ( GPL2_OR_LATER );
21
22 #include <stdio.h>
23 #include <errno.h>
24 #include <ipxe/ansiesc.h>
25 #include <ipxe/ansicol.h>
26 #include <config/colour.h>
27
28 /** @file
29  *
30  * ANSI colour definitions
31  *
32  */
33
34 /**
35  * Construct ANSI colour definition
36  *
37  * @v basic             Basic colour
38  * @v rgb               24-bit RGB value (or ANSICOL_NO_RGB)
39  * @ret ansicol         ANSI colour definition
40  */
41 #define ANSICOL_DEFINE( basic, rgb ) ( ( (basic) << 28 ) | (rgb) )
42
43 /**
44  * Extract basic colour from ANSI colour definition
45  *
46  * @v ansicol           ANSI colour definition
47  * @ret basic           Basic colour
48  */
49 #define ANSICOL_BASIC( ansicol ) ( (ansicol) >> 28 )
50
51 /**
52  * Extract 24-bit RGB value from ANSI colour definition
53  *
54  * @v ansicol           ANSI colour definition
55  * @ret rgb             24-bit RGB value
56  */
57 #define ANSICOL_RGB( ansicol ) ( ( (ansicol) >> 0 ) & 0xffffffUL )
58
59 /**
60  * Extract 24-bit RGB value red component from ANSI colour definition
61  *
62  * @v ansicol           ANSI colour definition
63  * @ret red             Red component
64  */
65 #define ANSICOL_RED( ansicol ) ( ( (ansicol) >> 16 ) & 0xff )
66
67 /**
68  * Extract 24-bit RGB value green component from ANSI colour definition
69  *
70  * @v ansicol           ANSI colour definition
71  * @ret green           Green component
72  */
73 #define ANSICOL_GREEN( ansicol ) ( ( (ansicol) >> 8 ) & 0xff )
74
75 /**
76  * Extract 24-bit RGB value blue component from ANSI colour definition
77  *
78  * @v ansicol           ANSI colour definition
79  * @ret blue            Blue component
80  */
81 #define ANSICOL_BLUE( ansicol ) ( ( (ansicol) >> 0 ) & 0xff )
82
83 /**
84  * Construct default ANSI colour definition
85  *
86  * @v basic             Basic colour
87  * @ret ansicol         ANSI colour definition
88  *
89  * Colours default to being just a basic colour.  If the colour
90  * matches the normal UI text background colour, then its basic colour
91  * value is set to @c ANSICOL_MAGIC.
92  */
93 #define ANSICOL_DEFAULT( basic )                                        \
94         ANSICOL_DEFINE ( ( ( (basic) == COLOR_NORMAL_BG ) ?             \
95                            ANSICOL_MAGIC : (basic) ),                   \
96                          ANSICOL_NO_RGB )
97
98 /** ANSI colour definitions */
99 static uint32_t ansicols[] = {
100         [COLOR_BLACK]   = ANSICOL_DEFAULT ( COLOR_BLACK ),
101         [COLOR_RED]     = ANSICOL_DEFAULT ( COLOR_RED ),
102         [COLOR_GREEN]   = ANSICOL_DEFAULT ( COLOR_GREEN ),
103         [COLOR_YELLOW]  = ANSICOL_DEFAULT ( COLOR_YELLOW ),
104         [COLOR_BLUE]    = ANSICOL_DEFAULT ( COLOR_BLUE ),
105         [COLOR_MAGENTA] = ANSICOL_DEFAULT ( COLOR_MAGENTA ),
106         [COLOR_CYAN]    = ANSICOL_DEFAULT ( COLOR_CYAN ),
107         [COLOR_WHITE]   = ANSICOL_DEFAULT ( COLOR_WHITE ),
108 };
109
110 /** Magic basic colour */
111 static uint8_t ansicol_magic = COLOR_NORMAL_BG;
112
113 /**
114  * Define ANSI colour
115  *
116  * @v colour            Colour index
117  * @v basic             Basic colour
118  * @v rgb               24-bit RGB value (or ANSICOL_NO_RGB)
119  * @ret rc              Return status code
120  */
121 int ansicol_define ( unsigned int colour, unsigned int basic, uint32_t rgb ) {
122         uint32_t ansicol;
123
124         /* Fail if colour index is out of range */
125         if ( colour >= ( sizeof ( ansicols ) / sizeof ( ansicols[0] ) ) )
126                 return -EINVAL;
127
128         /* Update colour definition */
129         ansicol = ANSICOL_DEFINE ( basic, rgb );
130         ansicols[colour] = ansicol;
131         DBGC ( &ansicols[0], "ANSICOL redefined colour %d as basic %d RGB "
132                "%#06lx%s\n", colour, ANSICOL_BASIC ( ansicol ),
133                ANSICOL_RGB ( ansicol ),
134                ( ( ansicol & ANSICOL_NO_RGB ) ? " [norgb]" : "" ) );
135
136         return 0;
137 }
138
139 /**
140  * Set ANSI colour (using colour definitions)
141  *
142  * @v colour            Colour index
143  * @v which             Foreground/background selector
144  */
145 void ansicol_set ( unsigned int colour, unsigned int which ) {
146         uint32_t ansicol;
147         unsigned int basic;
148
149         /* Use default colour if colour index is out of range */
150         if ( colour < ( sizeof ( ansicols ) / sizeof ( ansicols[0] ) ) ) {
151                 ansicol = ansicols[colour];
152         } else {
153                 ansicol = ANSICOL_DEFINE ( COLOUR_DEFAULT, ANSICOL_NO_RGB );
154         }
155
156         /* If basic colour is out of range, use the magic colour */
157         basic = ANSICOL_BASIC ( ansicol );
158         if ( basic >= 10 )
159                 basic = ansicol_magic;
160
161         /* Set basic colour first */
162         printf ( CSI "%c%dm", which, basic );
163
164         /* Set 24-bit RGB colour, if applicable */
165         if ( ! ( ansicol & ANSICOL_NO_RGB ) ) {
166                 printf ( CSI "%c8;2;%d;%d;%dm", which, ANSICOL_RED ( ansicol ),
167                          ANSICOL_GREEN ( ansicol ), ANSICOL_BLUE ( ansicol ) );
168         }
169 }
170
171 /**
172  * Reset magic colour
173  *
174  */
175 void ansicol_reset_magic ( void ) {
176
177         /* Set to the compile-time default background colour */
178         ansicol_magic = COLOR_NORMAL_BG;
179 }
180
181 /**
182  * Set magic colour to transparent
183  *
184  */
185 void ansicol_set_magic_transparent ( void ) {
186
187         /* Set to the console default colour (which will give a
188          * transparent background on the framebuffer console).
189          */
190         ansicol_magic = COLOR_DEFAULT;
191 }