aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2021-02-03 14:00:14 +0000
committerRon Yorston <rmy@pobox.com>2021-02-03 14:00:14 +0000
commitb108c7bb2181186a5d95d10a6f187c28b4c753f4 (patch)
treeeb6f5e904d2240eb18d249baf594c35de5aade8a
parentab7a10870d7347056d86eed03f6aca62aaf4d083 (diff)
downloadbusybox-w32-b108c7bb2181186a5d95d10a6f187c28b4c753f4.tar.gz
busybox-w32-b108c7bb2181186a5d95d10a6f187c28b4c753f4.tar.bz2
busybox-w32-b108c7bb2181186a5d95d10a6f187c28b4c753f4.zip
winansi: extend ANSI emulation
Extend ANSI emulation to include: ESC[38;2;R;G;Bm 24-bit foreground colour ESC[48;2;R;G;Bm 24-bit background colour ESC[38;5;Nm 8-bit foreground colour ESC[48;5;Nm 8-bit background colour The colours are selected from the 16 standard console colours. This is unlikely to be aesthetically pleasing but at least it's better than raw escape sequences. Also, add ESC[9m (strike through) as a known but unsupported sequence.
-rw-r--r--win32/winansi.c226
1 files changed, 177 insertions, 49 deletions
diff --git a/win32/winansi.c b/win32/winansi.c
index 59292efc3..eda65e62d 100644
--- a/win32/winansi.c
+++ b/win32/winansi.c
@@ -262,12 +262,174 @@ static void move_cursor(int x, int y)
262 SetConsoleCursorPosition(console, pos); 262 SetConsoleCursorPosition(console, pos);
263} 263}
264 264
265/* 24-bit colour */
266static char *process_fg_24bit(char *str, WORD *attr)
267{
268 int count = 0;
269 int val[3] = {0, 0, 0};
270 int dark, bright = 0;
271
272 do {
273 val[count++] = strtol(str, (char **)&str, 10);
274 ++str;
275 } while (*(str-1) == ';' && count < 3);
276
277 *attr &= ~(FOREGROUND_ALL|FOREGROUND_INTENSITY);
278 if (val[0] > 127) {
279 *attr |= FOREGROUND_RED;
280 ++bright;
281 }
282 if (val[1] > 127) {
283 *attr |= FOREGROUND_GREEN;
284 ++bright;
285 }
286 if (val[2] > 127) {
287 *attr |= FOREGROUND_BLUE;
288 ++bright;
289 }
290
291 /* increase intensity if all components are either bright or
292 * dark and at least one is bright */
293 dark = (val[0] <= 63) + (val[1] <= 63) + (val[2] <= 63);
294 if (bright + dark == 3 && dark != 3) {
295 *attr |= FOREGROUND_INTENSITY;
296 }
297
298 return str;
299}
300
301static char *process_bg_24bit(char *str, WORD *attr)
302{
303 WORD t = 0;
304 char *s = process_fg_24bit(str, &t);
305
306 *attr &= ~(BACKGROUND_ALL|BACKGROUND_INTENSITY);
307 *attr |= t << 4;
308
309 return s;
310}
311
312static unsigned char colour_1bit[8] = {
313 /* Black */ 0,
314 /* Red */ FOREGROUND_RED,
315 /* Green */ FOREGROUND_GREEN,
316 /* Yellow */ FOREGROUND_RED | FOREGROUND_GREEN,
317 /* Blue */ FOREGROUND_BLUE,
318 /* Magenta */ FOREGROUND_RED | FOREGROUND_BLUE,
319 /* Cyan */ FOREGROUND_GREEN | FOREGROUND_BLUE,
320 /* White */ FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE
321};
322
323/* 8-bit colour */
324static char *process_fg_8bit(char *str, WORD *attr)
325{
326 int dark, bright = 0;
327 int val = strtol(str, &str, 10);
328 int r, g, b;
329
330 *attr &= ~(FOREGROUND_ALL|FOREGROUND_INTENSITY);
331 if (val < 16) {
332 *attr |= colour_1bit[val % 8];
333 if (val > 8)
334 *attr |= FOREGROUND_INTENSITY;
335 }
336 else if (val < 232) {
337 val -= 16;
338 r = val / 36 % 6;
339 g = val / 6 % 6;
340 b = val % 6;
341
342 if (r >= 3) {
343 *attr |= FOREGROUND_RED;
344 ++bright;
345 }
346 if (g >= 3) {
347 *attr |= FOREGROUND_GREEN;
348 ++bright;
349 }
350 if (b >= 3) {
351 *attr |= FOREGROUND_BLUE;
352 ++bright;
353 }
354
355 /* increase intensity if all components are either bright or
356 * dark and at least one is bright */
357 dark = (r <= 1) + (g <= 1) + (b <= 1);
358 if (bright + dark == 3 && dark != 3) {
359 *attr |= FOREGROUND_INTENSITY;
360 }
361 }
362 else if (val < 238) {
363 /* black */
364 }
365 else if (val < 244) {
366 /* bright black */
367 *attr |= FOREGROUND_INTENSITY;
368 }
369 else if (val < 250) {
370 /* white */
371 *attr |= FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE;
372 }
373 else {
374 /* bright white */
375 *attr |= FOREGROUND_INTENSITY;
376 *attr |= FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE;
377 }
378
379 return str;
380}
381
382static char *process_bg_8bit(char *str, WORD *attr)
383{
384 WORD t = 0;
385 char *s = process_fg_8bit(str, &t);
386
387 *attr &= ~(BACKGROUND_ALL|BACKGROUND_INTENSITY);
388 *attr |= t << 4;
389
390 return s;
391}
392
393static char *process_fg(char *str, WORD *attr)
394{
395 long val = strtol(str, (char **)&str, 10);
396 switch (val) {
397 case 2:
398 str = process_fg_24bit(++str, attr);
399 break;
400 case 5:
401 str = process_fg_8bit(++str, attr);
402 break;
403 default:
404 break;
405 }
406
407 return str;
408}
409
410static char *process_bg(char *str, WORD *attr)
411{
412 long val = strtol(str, (char **)&str, 10);
413 switch (val) {
414 case 2:
415 str = process_bg_24bit(++str, attr);
416 break;
417 case 5:
418 str = process_bg_8bit(++str, attr);
419 break;
420 default:
421 break;
422 }
423
424 return str;
425}
426
265/* On input pos points to the start of a suspected escape sequence. 427/* On input pos points to the start of a suspected escape sequence.
266 * If a valid sequence is found return a pointer to the character 428 * If a valid sequence is found return a pointer to the character
267 * following it, otherwise return the original pointer. */ 429 * following it, otherwise return the original pointer. */
268static char *process_escape(char *pos) 430static char *process_escape(char *pos)
269{ 431{
270 const char *str, *func; 432 char *str, *func;
271 char *bel; 433 char *bel;
272 size_t len; 434 size_t len;
273 WORD attr = get_console_attr(); 435 WORD attr = get_console_attr();
@@ -341,85 +503,51 @@ static char *process_escape(char *pos)
341 inverse = 0; 503 inverse = 0;
342 break; 504 break;
343 case 8: /* conceal */ 505 case 8: /* conceal */
506 case 9: /* strike through */
344 case 28: /* reveal */ 507 case 28: /* reveal */
345 /* Unsupported */ 508 /* Unsupported */
346 break; 509 break;
510
511 /* Foreground colours */
347 case 30: /* Black */ 512 case 30: /* Black */
348 attr &= ~FOREGROUND_ALL;
349 break;
350 case 31: /* Red */ 513 case 31: /* Red */
351 attr &= ~FOREGROUND_ALL;
352 attr |= FOREGROUND_RED;
353 break;
354 case 32: /* Green */ 514 case 32: /* Green */
355 attr &= ~FOREGROUND_ALL;
356 attr |= FOREGROUND_GREEN;
357 break;
358 case 33: /* Yellow */ 515 case 33: /* Yellow */
359 attr &= ~FOREGROUND_ALL;
360 attr |= FOREGROUND_RED | FOREGROUND_GREEN;
361 break;
362 case 34: /* Blue */ 516 case 34: /* Blue */
363 attr &= ~FOREGROUND_ALL;
364 attr |= FOREGROUND_BLUE;
365 break;
366 case 35: /* Magenta */ 517 case 35: /* Magenta */
367 attr &= ~FOREGROUND_ALL;
368 attr |= FOREGROUND_RED | FOREGROUND_BLUE;
369 break;
370 case 36: /* Cyan */ 518 case 36: /* Cyan */
371 attr &= ~FOREGROUND_ALL;
372 attr |= FOREGROUND_GREEN | FOREGROUND_BLUE;
373 break;
374 case 37: /* White */ 519 case 37: /* White */
375 attr |= FOREGROUND_RED | 520 attr &= ~FOREGROUND_ALL;
376 FOREGROUND_GREEN | 521 attr |= colour_1bit[val - 30];
377 FOREGROUND_BLUE;
378 break; 522 break;
379 case 38: /* Unknown */ 523 case 38: /* 8/24 bit */
524 str = process_fg(++str, &attr);
380 break; 525 break;
381 case 39: /* reset */ 526 case 39: /* reset */
382 attr &= ~FOREGROUND_ALL; 527 attr &= ~FOREGROUND_ALL;
383 attr |= (plain_attr & FOREGROUND_ALL); 528 attr |= (plain_attr & FOREGROUND_ALL);
384 break; 529 break;
530
531 /* Background colours */
385 case 40: /* Black */ 532 case 40: /* Black */
386 attr &= ~BACKGROUND_ALL;
387 break;
388 case 41: /* Red */ 533 case 41: /* Red */
389 attr &= ~BACKGROUND_ALL;
390 attr |= BACKGROUND_RED;
391 break;
392 case 42: /* Green */ 534 case 42: /* Green */
393 attr &= ~BACKGROUND_ALL;
394 attr |= BACKGROUND_GREEN;
395 break;
396 case 43: /* Yellow */ 535 case 43: /* Yellow */
397 attr &= ~BACKGROUND_ALL;
398 attr |= BACKGROUND_RED | BACKGROUND_GREEN;
399 break;
400 case 44: /* Blue */ 536 case 44: /* Blue */
401 attr &= ~BACKGROUND_ALL;
402 attr |= BACKGROUND_BLUE;
403 break;
404 case 45: /* Magenta */ 537 case 45: /* Magenta */
405 attr &= ~BACKGROUND_ALL;
406 attr |= BACKGROUND_RED | BACKGROUND_BLUE;
407 break;
408 case 46: /* Cyan */ 538 case 46: /* Cyan */
409 attr &= ~BACKGROUND_ALL;
410 attr |= BACKGROUND_GREEN | BACKGROUND_BLUE;
411 break;
412 case 47: /* White */ 539 case 47: /* White */
413 attr |= BACKGROUND_RED | 540 attr &= ~BACKGROUND_ALL;
414 BACKGROUND_GREEN | 541 attr |= colour_1bit[val - 40] << 4;
415 BACKGROUND_BLUE;
416 break; 542 break;
417 case 48: /* Unknown */ 543 case 48: /* 8/24 bit */
544 str = process_bg(++str, &attr);
418 break; 545 break;
419 case 49: /* reset */ 546 case 49: /* reset */
420 attr &= ~BACKGROUND_ALL; 547 attr &= ~BACKGROUND_ALL;
421 attr |= (plain_attr & BACKGROUND_ALL); 548 attr |= (plain_attr & BACKGROUND_ALL);
422 break; 549 break;
550
423 default: 551 default:
424 /* Unsupported code */ 552 /* Unsupported code */
425 return pos; 553 return pos;