You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ansi_screen.c 2.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. #include <stdio.h>
  2. #include <curses.h>
  3. #include <ipxe/ansicol.h>
  4. #include <ipxe/console.h>
  5. FILE_LICENCE ( GPL2_OR_LATER );
  6. static void ansiscr_reset(struct _curses_screen *scr) __nonnull;
  7. static void ansiscr_movetoyx(struct _curses_screen *scr,
  8. unsigned int y, unsigned int x) __nonnull;
  9. static void ansiscr_putc(struct _curses_screen *scr, chtype c) __nonnull;
  10. static unsigned int saved_usage;
  11. static void ansiscr_attrs ( struct _curses_screen *scr, attr_t attrs ) {
  12. int bold = ( attrs & A_BOLD );
  13. attr_t cpair = PAIR_NUMBER ( attrs );
  14. if ( scr->attrs != attrs ) {
  15. scr->attrs = attrs;
  16. /* Reset attributes and set/clear bold as appropriate */
  17. printf ( "\033[0;%dm", ( bold ? 1 : 22 ) );
  18. /* Set foreground and background colours */
  19. ansicol_set_pair ( cpair );
  20. }
  21. }
  22. static void ansiscr_reset ( struct _curses_screen *scr ) {
  23. /* Reset terminal attributes and clear screen */
  24. scr->attrs = 0;
  25. scr->curs_x = 0;
  26. scr->curs_y = 0;
  27. printf ( "\0330m" );
  28. ansicol_set_pair ( CPAIR_DEFAULT );
  29. printf ( "\033[2J" );
  30. }
  31. static void ansiscr_init ( struct _curses_screen *scr ) {
  32. saved_usage = console_set_usage ( CONSOLE_USAGE_TUI );
  33. ansiscr_reset ( scr );
  34. }
  35. static void ansiscr_exit ( struct _curses_screen *scr ) {
  36. ansiscr_reset ( scr );
  37. console_set_usage ( saved_usage );
  38. }
  39. static void ansiscr_erase ( struct _curses_screen *scr, attr_t attrs ) {
  40. ansiscr_attrs ( scr, attrs );
  41. printf ( "\033[2J" );
  42. }
  43. static void ansiscr_movetoyx ( struct _curses_screen *scr,
  44. unsigned int y, unsigned int x ) {
  45. if ( ( x != scr->curs_x ) || ( y != scr->curs_y ) ) {
  46. /* ANSI escape sequence to update cursor position */
  47. printf ( "\033[%d;%dH", ( y + 1 ), ( x + 1 ) );
  48. scr->curs_x = x;
  49. scr->curs_y = y;
  50. }
  51. }
  52. static void ansiscr_putc ( struct _curses_screen *scr, chtype c ) {
  53. unsigned int character = ( c & A_CHARTEXT );
  54. attr_t attrs = ( c & ( A_ATTRIBUTES | A_COLOR ) );
  55. /* Update attributes if changed */
  56. ansiscr_attrs ( scr, attrs );
  57. /* Print the actual character */
  58. putchar ( character );
  59. /* Update expected cursor position */
  60. if ( ++(scr->curs_x) == COLS ) {
  61. scr->curs_x = 0;
  62. ++scr->curs_y;
  63. }
  64. }
  65. static int ansiscr_getc ( struct _curses_screen *scr __unused ) {
  66. return getchar();
  67. }
  68. static bool ansiscr_peek ( struct _curses_screen *scr __unused ) {
  69. return iskey();
  70. }
  71. static void ansiscr_cursor ( struct _curses_screen *scr __unused,
  72. int visibility ) {
  73. printf ( "\033[?25%c", ( visibility ? 'h' : 'l' ) );
  74. }
  75. SCREEN _ansi_screen = {
  76. .init = ansiscr_init,
  77. .exit = ansiscr_exit,
  78. .erase = ansiscr_erase,
  79. .movetoyx = ansiscr_movetoyx,
  80. .putc = ansiscr_putc,
  81. .getc = ansiscr_getc,
  82. .peek = ansiscr_peek,
  83. .cursor = ansiscr_cursor,
  84. };