aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty/vt/vt.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/tty/vt/vt.c')
-rw-r--r--drivers/tty/vt/vt.c89
1 files changed, 80 insertions, 9 deletions
diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index 3ad0b61e35b4..5e0f6ff2e2f5 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -735,7 +735,7 @@ static void visual_init(struct vc_data *vc, int num, int init)
735 vc->vc_num = num; 735 vc->vc_num = num;
736 vc->vc_display_fg = &master_display_fg; 736 vc->vc_display_fg = &master_display_fg;
737 vc->vc_uni_pagedir_loc = &vc->vc_uni_pagedir; 737 vc->vc_uni_pagedir_loc = &vc->vc_uni_pagedir;
738 vc->vc_uni_pagedir = 0; 738 vc->vc_uni_pagedir = NULL;
739 vc->vc_hi_font_mask = 0; 739 vc->vc_hi_font_mask = 0;
740 vc->vc_complement_mask = 0; 740 vc->vc_complement_mask = 0;
741 vc->vc_can_do_color = 0; 741 vc->vc_can_do_color = 0;
@@ -1231,6 +1231,52 @@ static void default_attr(struct vc_data *vc)
1231 vc->vc_color = vc->vc_def_color; 1231 vc->vc_color = vc->vc_def_color;
1232} 1232}
1233 1233
1234struct rgb { u8 r; u8 g; u8 b; };
1235
1236struct rgb rgb_from_256(int i)
1237{
1238 struct rgb c;
1239 if (i < 8) { /* Standard colours. */
1240 c.r = i&1 ? 0xaa : 0x00;
1241 c.g = i&2 ? 0xaa : 0x00;
1242 c.b = i&4 ? 0xaa : 0x00;
1243 } else if (i < 16) {
1244 c.r = i&1 ? 0xff : 0x55;
1245 c.g = i&2 ? 0xff : 0x55;
1246 c.b = i&4 ? 0xff : 0x55;
1247 } else if (i < 232) { /* 6x6x6 colour cube. */
1248 c.r = (i - 16) / 36 * 85 / 2;
1249 c.g = (i - 16) / 6 % 6 * 85 / 2;
1250 c.b = (i - 16) % 6 * 85 / 2;
1251 } else /* Grayscale ramp. */
1252 c.r = c.g = c.b = i * 10 - 2312;
1253 return c;
1254}
1255
1256static void rgb_foreground(struct vc_data *vc, struct rgb c)
1257{
1258 u8 hue, max = c.r;
1259 if (c.g > max)
1260 max = c.g;
1261 if (c.b > max)
1262 max = c.b;
1263 hue = (c.r > max/2 ? 4 : 0)
1264 | (c.g > max/2 ? 2 : 0)
1265 | (c.b > max/2 ? 1 : 0);
1266 if (hue == 7 && max <= 0x55)
1267 hue = 0, vc->vc_intensity = 2;
1268 else
1269 vc->vc_intensity = (max > 0xaa) + 1;
1270 vc->vc_color = (vc->vc_color & 0xf0) | hue;
1271}
1272
1273static void rgb_background(struct vc_data *vc, struct rgb c)
1274{
1275 /* For backgrounds, err on the dark side. */
1276 vc->vc_color = (vc->vc_color & 0x0f)
1277 | (c.r&0x80) >> 1 | (c.g&0x80) >> 2 | (c.b&0x80) >> 3;
1278}
1279
1234/* console_lock is held */ 1280/* console_lock is held */
1235static void csi_m(struct vc_data *vc) 1281static void csi_m(struct vc_data *vc)
1236{ 1282{
@@ -1302,8 +1348,7 @@ static void csi_m(struct vc_data *vc)
1302 case 27: 1348 case 27:
1303 vc->vc_reverse = 0; 1349 vc->vc_reverse = 0;
1304 break; 1350 break;
1305 case 38: 1351 case 38: /* ITU T.416
1306 case 48: /* ITU T.416
1307 * Higher colour modes. 1352 * Higher colour modes.
1308 * They break the usual properties of SGR codes 1353 * They break the usual properties of SGR codes
1309 * and thus need to be detected and ignored by 1354 * and thus need to be detected and ignored by
@@ -1315,15 +1360,41 @@ static void csi_m(struct vc_data *vc)
1315 i++; 1360 i++;
1316 if (i > vc->vc_npar) 1361 if (i > vc->vc_npar)
1317 break; 1362 break;
1318 if (vc->vc_par[i] == 5) /* 256 colours */ 1363 if (vc->vc_par[i] == 5 && /* 256 colours */
1319 i++; /* ubiquitous */ 1364 i < vc->vc_npar) { /* ubiquitous */
1320 else if (vc->vc_par[i] == 2) /* 24 bit colours */ 1365 i++;
1321 i += 3; /* extremely rare */ 1366 rgb_foreground(vc,
1367 rgb_from_256(vc->vc_par[i]));
1368 } else if (vc->vc_par[i] == 2 && /* 24 bit */
1369 i <= vc->vc_npar + 3) {/* extremely rare */
1370 struct rgb c = {r:vc->vc_par[i+1],
1371 g:vc->vc_par[i+2],
1372 b:vc->vc_par[i+3]};
1373 rgb_foreground(vc, c);
1374 i += 3;
1375 }
1322 /* Subcommands 3 (CMY) and 4 (CMYK) are so insane 1376 /* Subcommands 3 (CMY) and 4 (CMYK) are so insane
1323 * that detecting them is not worth the few extra 1377 * there's no point in supporting them.
1324 * bytes of kernel's size.
1325 */ 1378 */
1326 break; 1379 break;
1380 case 48:
1381 i++;
1382 if (i > vc->vc_npar)
1383 break;
1384 if (vc->vc_par[i] == 5 && /* 256 colours */
1385 i < vc->vc_npar) {
1386 i++;
1387 rgb_background(vc,
1388 rgb_from_256(vc->vc_par[i]));
1389 } else if (vc->vc_par[i] == 2 && /* 24 bit */
1390 i <= vc->vc_npar + 3) {
1391 struct rgb c = {r:vc->vc_par[i+1],
1392 g:vc->vc_par[i+2],
1393 b:vc->vc_par[i+3]};
1394 rgb_background(vc, c);
1395 i += 3;
1396 }
1397 break;
1327 case 39: 1398 case 39:
1328 vc->vc_color = (vc->vc_def_color & 0x0f) | (vc->vc_color & 0xf0); 1399 vc->vc_color = (vc->vc_def_color & 0x0f) | (vc->vc_color & 0xf0);
1329 break; 1400 break;