diff options
Diffstat (limited to 'drivers/tty/vt/vt.c')
-rw-r--r-- | drivers/tty/vt/vt.c | 89 |
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 | ||
1234 | struct rgb { u8 r; u8 g; u8 b; }; | ||
1235 | |||
1236 | struct 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 | |||
1256 | static 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 | |||
1273 | static 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 */ |
1235 | static void csi_m(struct vc_data *vc) | 1281 | static 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; |