]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/vt/colors/vt_termcolors.c
Add IOMMU_BUSWIDE ahci quirk.
[FreeBSD/FreeBSD.git] / sys / dev / vt / colors / vt_termcolors.c
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Copyright (c) 2013 The FreeBSD Foundation
5  * All rights reserved.
6  *
7  * This software was developed by Aleksandr Rybalko under sponsorship from the
8  * FreeBSD Foundation.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20  * 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 AUTHOR OR CONTRIBUTORS BE LIABLE
23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29  * SUCH DAMAGE.
30  */
31
32 #include <sys/cdefs.h>
33 __FBSDID("$FreeBSD$");
34
35 #include <sys/param.h>
36 #include <sys/kernel.h>
37 #include <sys/libkern.h>
38
39 #include <dev/vt/colors/vt_termcolors.h>
40
41 static struct {
42         unsigned char r;        /* Red percentage value. */
43         unsigned char g;        /* Green percentage value. */
44         unsigned char b;        /* Blue percentage value. */
45 } color_def[NCOLORS] = {
46         {0,     0,      0},     /* black */
47         {50,    0,      0},     /* dark red */
48         {0,     50,     0},     /* dark green */
49         {77,    63,     0},     /* dark yellow */
50         {20,    40,     64},    /* dark blue */
51         {50,    0,      50},    /* dark magenta */
52         {0,     50,     50},    /* dark cyan */
53         {75,    75,     75},    /* light gray */
54
55         {18,    20,     21},    /* dark gray */
56         {100,   0,      0},     /* light red */
57         {0,     100,    0},     /* light green */
58         {100,   100,    0},     /* light yellow */
59         {45,    62,     81},    /* light blue */
60         {100,   0,      100},   /* light magenta */
61         {0,     100,    100},   /* light cyan */
62         {100,   100,    100},   /* white */
63 };
64
65 static int
66 vt_parse_rgb_triplet(const char *rgb, unsigned char *r,
67     unsigned char *g, unsigned char *b)
68 {
69         unsigned long v;
70         const char *ptr;
71         char *endptr;
72
73         ptr = rgb;
74
75         /* Handle #rrggbb case */
76         if (*ptr == '#') {
77                 if (strlen(ptr) != 7)
78                         return (-1);
79                 v = strtoul(ptr + 1, &endptr, 16);
80                 if (*endptr != '\0')
81                         return (-1);
82
83                 *r = (v >> 16) & 0xff;
84                 *g = (v >>  8) & 0xff;
85                 *b = v & 0xff;
86
87                 return (0);
88         }
89
90         /* "r, g, b" case */
91         v = strtoul(ptr, &endptr, 10);
92         if (ptr == endptr)
93                 return (-1);
94         if (v > 255)
95                 return (-1);
96         *r = v & 0xff;
97         ptr = endptr;
98
99         /* skip separator */
100         while (*ptr == ',' || *ptr == ' ')
101                 ptr++;
102
103         v = strtoul(ptr, &endptr, 10);
104         if (ptr == endptr)
105                 return (-1);
106         if (v > 255)
107                 return (-1);
108         *g = v & 0xff;
109         ptr = endptr;
110
111         /* skip separator */
112         while (*ptr == ',' || *ptr == ' ')
113                 ptr++;
114
115         v = strtoul(ptr, &endptr, 10);
116         if (ptr == endptr)
117                 return (-1);
118         if (v > 255)
119                 return (-1);
120         *b = v & 0xff;
121         ptr = endptr;
122
123         /* skip trailing spaces */
124         while (*ptr == ' ')
125                 ptr++;
126
127         /* unexpected characters at the end of the string */
128         if (*ptr != 0)
129                 return (-1);
130
131         return (0);
132 }
133
134 static void
135 vt_palette_init(void)
136 {
137         int i;
138         char rgb[32];
139         char tunable[32];
140         unsigned char r, g, b;
141
142         for (i = 0; i < NCOLORS; i++) {
143                 snprintf(tunable, sizeof(tunable),
144                     "kern.vt.color.%d.rgb", i);
145                 if (TUNABLE_STR_FETCH(tunable, rgb, sizeof(rgb))) {
146                         if (vt_parse_rgb_triplet(rgb, &r, &g, &b) == 0) {
147                                 /* convert to percentages */
148                                 color_def[i].r = r*100/255;
149                                 color_def[i].g = g*100/255;
150                                 color_def[i].b = b*100/255;
151                         }
152                 }
153         }
154 }
155
156 int
157 vt_generate_cons_palette(uint32_t *palette, int format, uint32_t rmax,
158     int roffset, uint32_t gmax, int goffset, uint32_t bmax, int boffset)
159 {
160         int i;
161
162         switch (format) {
163         case COLOR_FORMAT_VGA:
164                 for (i = 0; i < NCOLORS; i++)
165                         palette[i] = cons_to_vga_colors[i];
166                 break;
167         case COLOR_FORMAT_RGB:
168                 vt_palette_init();
169 #define CF(_f, _i) ((_f ## max * color_def[(_i)]._f / 100) << _f ## offset)
170                 for (i = 0; i < NCOLORS; i++)
171                         palette[i] = CF(r, i) | CF(g, i) | CF(b, i);
172 #undef  CF
173                 break;
174         default:
175                 return (ENODEV);
176         }
177
178         return (0);
179 }