diff options
Diffstat (limited to 'win32')
-rw-r--r-- | win32/winansi.c | 226 |
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 */ | ||
266 | static 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 | |||
301 | static 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 | |||
312 | static 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 */ | ||
324 | static 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 | |||
382 | static 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 | |||
393 | static 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 | |||
410 | static 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. */ |
268 | static char *process_escape(char *pos) | 430 | static 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; |