aboutsummaryrefslogtreecommitdiff
path: root/win32
diff options
context:
space:
mode:
Diffstat (limited to 'win32')
-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;