home *** CD-ROM | disk | FTP | other *** search
/ Dream 52 / Amiga_Dream_52.iso / OS2 / gnuinfo.zip / lib / ntansi.c < prev    next >
C/C++ Source or Header  |  1997-12-29  |  12KB  |  393 lines

  1. /*
  2.     Copyright (C) 1995-1997
  3.         Rainer Schnitker, Heeper Str. 283, 33607 Bielefeld
  4.         email: rainer@mathematik.uni-bielefeld.de
  5.  
  6.     All rights reserved
  7. */
  8.  
  9. #ifdef __RSXNT__
  10.  
  11. #define WIN32_LEAN_AND_MEAN
  12. #define STRICT
  13. #include <windows.h>
  14.  
  15. #include <string.h>
  16.  
  17. #define FG2BG(i) (i<<4)
  18. #define BG2FG(i) (i>>4)
  19.  
  20. #define BG_WHITE    (BACKGROUND_GREEN|BACKGROUND_BLUE|BACKGROUND_RED)
  21. #define BG_RED      (BACKGROUND_RED)
  22. #define BG_GREEN    (BACKGROUND_GREEN)
  23. #define BG_YELLOW   (BACKGROUND_GREEN|BACKGROUND_RED)
  24. #define BG_BLUE     (BACKGROUND_BLUE)
  25. #define BG_MAGNETA  (BACKGROUND_BLUE|BACKGROUND_RED)
  26. #define BG_CYAN     (BACKGROUND_GREEN|BACKGROUND_BLUE)
  27. #define BG_BLACK    (0)
  28. #define BG_DEFAULT  BG_BLACK
  29. #define BG_INTENS   BACKGROUND_INTENSITY
  30.  
  31. #define FG_WHITE    (FOREGROUND_GREEN|FOREGROUND_BLUE|FOREGROUND_RED)
  32. #define FG_RED      (FOREGROUND_RED)
  33. #define FG_GREEN    (FOREGROUND_GREEN)
  34. #define FG_YELLOW   (FOREGROUND_GREEN|FOREGROUND_RED)
  35. #define FG_BLUE     (FOREGROUND_BLUE)
  36. #define FG_MAGNETA  (FOREGROUND_BLUE|FOREGROUND_RED)
  37. #define FG_CYAN     (FOREGROUND_GREEN|FOREGROUND_BLUE)
  38. #define FG_BLACK    (0)
  39. #define FG_DEFAULT  FG_WHITE
  40. #define FG_INTENS   FOREGROUND_INTENSITY
  41.  
  42. static short BgColor[8] =
  43. {
  44.     BG_BLACK,
  45.     BG_RED,
  46.     BG_GREEN,
  47.     BG_YELLOW,
  48.     BG_BLUE,
  49.     BG_MAGNETA,
  50.     BG_CYAN,
  51.     BG_WHITE
  52. };
  53.  
  54. static short FgColor[8] =
  55. {
  56.     FG_BLACK,
  57.     FG_RED,
  58.     FG_GREEN,
  59.     FG_YELLOW,
  60.     FG_BLUE,
  61.     FG_MAGNETA,
  62.     FG_CYAN,
  63.     FG_WHITE
  64. };
  65.  
  66. static void clear_line(int x, int y, int size, WORD ColorB)
  67. {
  68.     static COORD src_size;
  69.     static COORD src_pos;
  70.     CHAR_INFO ci[256];
  71.     SMALL_RECT srect;
  72.     int i;
  73.  
  74.     for (i = 0; i < size; ++i) {
  75.         ci[i].Char.AsciiChar = ' ';
  76.         ci[i].Attributes = (char) (ColorB | BG2FG(ColorB));
  77.     }
  78.     src_size.X = 256;
  79.     src_size.Y = 1;
  80.     src_pos.X = 0;
  81.     src_pos.Y = 0;
  82.     srect.Left = x;
  83.     srect.Top = y;
  84.     srect.Right = x + size - 1;
  85.     srect.Bottom = y;
  86.     WriteConsoleOutput(GetStdHandle(STD_OUTPUT_HANDLE),
  87.                         ci, src_size, src_pos, &srect);
  88. }
  89.  
  90. static void clear_lines(int from, int to, int size, WORD ColorB)
  91. {
  92.     int y;
  93.  
  94.     for (y = from; y <= to; ++y)
  95.         clear_line(0, y, size, ColorB);
  96. }
  97.  
  98. static void GetConsoleCursorPosition(HANDLE handle, COORD *coord)
  99. {
  100.     CONSOLE_SCREEN_BUFFER_INFO scbi;
  101.  
  102.     GetConsoleScreenBufferInfo(handle, &scbi);
  103.     coord->X = scbi.dwCursorPosition.X;
  104.     coord->Y = scbi.dwCursorPosition.Y;
  105. }
  106.  
  107. static void GetConsoleWindow(HANDLE handle, COORD *coord)
  108. {
  109.     CONSOLE_SCREEN_BUFFER_INFO scbi;
  110.  
  111.     GetConsoleScreenBufferInfo(handle, &scbi);
  112.     coord->X = scbi.dwSize.X;
  113.     coord->Y = scbi.dwSize.Y;
  114. }
  115.  
  116. static int rsxio_ansi(const char *lpBuf, int size)
  117. {
  118.     static POINT CursorSave;            // Cursor ansi save
  119.     static char  tBreakLine;            // Termcap mode
  120.     static char  ColorMode;             // Color ansi mode
  121.     static WORD  ColorF = FG_DEFAULT;   // Color ansi mode
  122.     static WORD  ColorB = BG_DEFAULT;   // Color ansi mode
  123.  
  124.     int p[4];                           // parameter
  125.     int pn;                             // no of parmameter
  126.     int n,i;                            // offset buffer
  127.     int bexit = 1;                      // exit flag
  128.     char c;
  129.     COORD cc;
  130.     COORD cw;
  131.     HANDLE console_handle;
  132.  
  133.     if (lpBuf[1] != '[')
  134.         return 0;
  135.  
  136.     console_handle = GetStdHandle(STD_OUTPUT_HANDLE);
  137.     GetConsoleWindow(console_handle, &cw);
  138.  
  139.     pn = p[0] = p[1] = p[2] = p[3] = 0;
  140.  
  141.     n = 2;
  142.     while (bexit && n <= size) {
  143.         c = lpBuf[n];
  144.  
  145.         switch (c) {
  146.             case '0':
  147.             case '1':
  148.             case '2':
  149.             case '3':
  150.             case '4':
  151.             case '5':
  152.             case '6':
  153.             case '7':
  154.             case '8':
  155.             case '9':
  156.                 p[pn] *= 10;
  157.                 p[pn] += c - '0';
  158.                 break;
  159.  
  160.             case ';':
  161.                 ++pn;
  162.                 if (pn >= 4)
  163.                     pn = 0;
  164.                 break;
  165.  
  166.             case 'A':               // cursor up
  167.                 if (!p[0])
  168.                     p[0] = 1;
  169.                 GetConsoleCursorPosition(console_handle, &cc);
  170.                 cc.Y -= p[0];
  171.                 if (cc.Y < 0)
  172.                     cc.Y = 0;
  173.                 SetConsoleCursorPosition(console_handle, cc);
  174.                 bexit = 0;
  175.                 break;
  176.  
  177.             case 'B':               // cursor down
  178.                 if (!p[0])
  179.                     p[0] = 1;
  180.                 GetConsoleCursorPosition(console_handle, &cc);
  181.                 cc.Y += p[0];
  182.                 if (cc.Y >= cw.Y)
  183.                     cc.Y = cw.Y - 1;
  184.                 SetConsoleCursorPosition(console_handle, cc);
  185.                 bexit = 0;
  186.                 break;
  187.  
  188.             case 'C':               // cursor right
  189.                 if (!p[0])
  190.                     p[0] = 1;
  191.                 GetConsoleCursorPosition(console_handle, &cc);
  192.                 cc.X += p[0];
  193.                 if (cc.X >= cw.X)
  194.                     cc.X = cw.X - 1;
  195.                 SetConsoleCursorPosition(console_handle, cc);
  196.                 bexit = 0;
  197.                 break;
  198.  
  199.             case 'D':               // cursor left
  200.                 if (!p[0])
  201.                     p[0] = 1;
  202.                 GetConsoleCursorPosition(console_handle, &cc);
  203.                 cc.X -= p[0];
  204.                 if (cc.X < 0)
  205.                     cc.X = 0;
  206.                 SetConsoleCursorPosition(console_handle, cc);
  207.                 bexit = 0;
  208.                 break;
  209.  
  210.             case 'f':
  211.             case 'H':               // cursor position
  212.                 if (pn != 1) {
  213.                     p[0] = 0;
  214.                     p[1] = 0;
  215.                 } else {    // home = 1,1 ; screen = 0,0
  216.                     p[1]--;
  217.                     p[0]--;
  218.                 }
  219.                 cc.Y = p[0];
  220.                 cc.X = p[1];
  221.                 SetConsoleCursorPosition(console_handle, cc);
  222.                 bexit = 0;
  223.                 break;
  224.  
  225.             case 'n':               // cursor pos in keyb buf
  226.                 if (p[0] == 6) {
  227.                     static char keyin[8];      // ESC [ y y ; x x R
  228.                     int t;
  229.                     int bytes = 0;
  230.  
  231.                     GetConsoleCursorPosition(console_handle, &cc);
  232.                     keyin[bytes++] = 27;
  233.                     keyin[bytes++] = '[';
  234.                     t = cc.Y + 1;
  235.                     if ((keyin[bytes] = t / 10 + '0') != '0')
  236.                         bytes++;
  237.                     keyin[bytes++] = t % 10 + '0';
  238.                     keyin[bytes++] = ';';
  239.                     t = cc.X + 1;
  240.                     if ((keyin[bytes] = t / 10 + '0') != '0')
  241.                         bytes++;
  242.                     keyin[bytes++] = t % 10 + '0';
  243.                     keyin[bytes++] = 'R';
  244.                 }
  245.                 bexit = 0;
  246.                 break;
  247.  
  248.             case 's':               // save cursor position
  249.                 GetConsoleCursorPosition(console_handle, &cc);
  250.                 CursorSave.y = cc.Y;
  251.                 CursorSave.x = cc.X;
  252.                 bexit = 0;
  253.                 break;
  254.  
  255.             case 'u':               // restore cursor position
  256.                 cc.Y = CursorSave.y;
  257.                 cc.X = CursorSave.x;
  258.                 SetConsoleCursorPosition(console_handle, cc);
  259.                 bexit = 0;
  260.                 break;
  261.  
  262.             case 'J':               // erase in display
  263.                 switch (p[0]) {
  264.                 case 0:             // erase from cursor to end of screen
  265.                     GetConsoleCursorPosition(console_handle, &cc);
  266.                     clear_lines(cc.Y, cw.Y - 1, cw.X, ColorB);
  267.                     break;
  268.                 case 1:             // erase from start to cursor
  269.                     clear_lines(0, cc.Y, cw.X, ColorB);
  270.                     break;
  271.                 case 2:             // erase screen
  272.                     clear_lines(0, cw.Y - 1, cw.X, ColorB);
  273.                     break;
  274.                 default:
  275.                     break;
  276.                 }
  277.                 bexit = 0;
  278.                 break;
  279.  
  280.             case 'K':               // erase in line
  281.                 GetConsoleCursorPosition(console_handle, &cc);
  282.                 switch (p[0]) {
  283.                 case 0:             // erase to end of line
  284.                     clear_line(cc.X, cc.Y, cw.X - cc.X, ColorB);
  285.                     break;
  286.                 case 1:             // erase to beginning of line
  287.                     clear_line(0, cc.Y, cc.X + 1, ColorB);
  288.                     break;
  289.                 case 2:             // erase whole line
  290.                     clear_line(0, cc.Y, cw.X, ColorB);
  291.                     break;
  292.                 default:
  293.                     break;
  294.                 }
  295.                 bexit = 0;
  296.                 break;
  297.  
  298.             case 'L':               // insert n lines preceding current line
  299.                 bexit = 0;
  300.                 break;
  301.  
  302.             case 'M':               // delete n lines from current position down
  303.                 bexit = 0;
  304.                 break;
  305.  
  306.             case 'P':               // delete n chars from cursor to the left
  307.                 bexit = 0;
  308.                 break;
  309.  
  310.             case 'l':               // reset mode (begin termcap)
  311.                 if (p[0] == 7)
  312.                     tBreakLine = FALSE;
  313.                 bexit = 0;
  314.                 break;
  315.  
  316.             case 'h':               // set mode (end termcap)
  317.                 if (p[0] == 7)
  318.                     tBreakLine = TRUE;
  319.                 bexit = 0;
  320.                 break;
  321.  
  322.             case 'm':               // colors, attributes
  323.                 for (i = 0; i <= pn; i++) {
  324.                     if (p[i] == 0) { // reset mode
  325.                         ColorF = FG_DEFAULT;
  326.                         ColorB = BG_DEFAULT;
  327.                         ColorMode = 0;
  328.                         SetConsoleTextAttribute(console_handle, ColorF | ColorB);
  329.                     }
  330.                     else if (p[i] <= 8)
  331.                         ColorMode = p[i];
  332.                     else if (p[i] >= 30 && p[i] <= 37) {
  333.                         ColorF = FgColor[p[i] - 30];
  334.                         if (ColorMode == 1)
  335.                             ColorF |= FG_INTENS;
  336.                     }
  337.                     else if (p[i] >= 40 && p[i] <= 47) {
  338.                         ColorB = BgColor[p[i] - 40];
  339.                         //if (ColorMode == 1)
  340.                         //    ColorB |= BG_INTENS;
  341.                     }
  342.                 }
  343.                 if (ColorMode == 7) {
  344.                     WORD FG, BG;
  345.                     FG = ColorB >> 4;
  346.                     BG = ColorF << 4;
  347.                     SetConsoleTextAttribute(console_handle, FG | BG);
  348.                 }
  349.                 else
  350.                     SetConsoleTextAttribute(console_handle, ColorF | ColorB);
  351.                 bexit = 0;
  352.                 break;
  353.  
  354.             case '=':    // termcap
  355.                 break;
  356.  
  357.             default:
  358.                 bexit = 0;
  359.                 break;
  360.         } // switch (c)
  361.  
  362.         n++;
  363.  
  364.     } // while(bexit)
  365.  
  366.     return n;
  367. }
  368.  
  369. int _rsxnt_write_with_ansi(const char *buf, size_t size)
  370. {
  371.     int i, n;
  372.     char c;
  373.     DWORD ret;
  374.     HANDLE console_handle = GetStdHandle(STD_OUTPUT_HANDLE);
  375.  
  376.     for (i = 0; i < size; i++) {
  377.         c = buf[i];
  378.         if (c == 27) {  // ESC
  379.             n = rsxio_ansi(buf + i, size - i);
  380.             if (n > 0) {
  381.                 i += n - 1;
  382.                 continue;
  383.             }
  384.         }
  385.         else
  386.             WriteFile(console_handle, &c, 1, &ret, NULL);
  387.     }
  388.     return size;
  389. }
  390.  
  391. #endif
  392.  
  393.