home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / me34exe.zip / me / misc / emx2io.c < prev    next >
C/C++ Source or Header  |  1995-01-21  |  9KB  |  364 lines

  1. /*
  2.  * OS2IO.C: Terminal IO for OS/2
  3.  * J Burnell    3/92    Public Domain
  4.  * P McPhee    1/95    Use EMX's termio and video libraries, for DOS support
  5.  */
  6.  
  7. /*
  8.  * The functions in this file negotiate with the operating system for
  9.  * characters, and write characters in a barely buffered fashion on the
  10.  * display.
  11.  */
  12.  
  13. #include <io.h>
  14. #include <stdio.h>
  15. #include <sys/types.h>
  16. #include <sys/time.h>
  17. #include "ed.h"
  18. #include "term.h"
  19. #include <signal.h>
  20. #include <termio.h>
  21. #include <string.h>
  22.  
  23. /* for EMX */
  24. #include <sys/video.h>        /* video library */
  25.  
  26. #include "me2.h"
  27. #include "config.h"
  28.  
  29. void t_eeol ();
  30.  
  31. static struct termio oldtio, tio;
  32. static struct {
  33.   int start, end;
  34. } oldcurs, curs;
  35.  
  36. /*
  37.  * This function is called once to set up the terminal device streams.
  38.  * It's also called after a spawn.
  39.  */
  40. void ttopen()
  41. {
  42.    /* ignore some signals */
  43.    signal(SIGBREAK, SIG_IGN);
  44.    signal(SIGINT, SIG_IGN);
  45.  
  46.   ioctl(0, TCSETA, &tio);
  47.   v_ctype(curs.start, curs.end);
  48. }
  49.  
  50. /*
  51.  * This function gets called just before we go back home to the command
  52.  *   interpreter.
  53.  */
  54. void t_close()
  55. {
  56.   /* close the keyboard */
  57.   ioctl(0, TCSETA, &oldtio);
  58.  
  59.   /* restore the cursor scan lines */
  60.   v_ctype(oldcurs.start, oldcurs.end);
  61. }
  62.  
  63. int t_nrow = 24, t_ncol = 0;
  64.  
  65. /*
  66.  * Write a character to the display.
  67.  * Use the rawest console output routine that handles backspace, \r and \n.
  68.  * On MS-DOS terminal I/O is unbuffered, so we just write the byte out.
  69.  */
  70. void t_putchar(c) unsigned char c;
  71. {
  72.   if (c == '\010')
  73.     v_backsp(1);
  74.   else if (c == '\r')
  75.     v_gotoxy(0, t_nrow);
  76.   else
  77.     v_putc(c);
  78. }
  79.  
  80. /*
  81.  * Flush terminal buffer.  Does real work where the terminal output is
  82.  *   buffered up.  A no-operation on systems where byte-at-a-time terminal
  83.  *   I/O is done.
  84.  */
  85. void t_flush() {}
  86.  
  87. /*
  88.  * Read a character from the terminal, performing no editing and doing no
  89.  *   echo at all.
  90.  * Map terminal softkeys, etc to ME keys.  Do *NOT* map control keys.
  91.  */
  92. EKeyCode t_getchar()
  93. {
  94.    EKeyCode keycode;
  95.    unsigned char c;
  96.  
  97.    read(0, &c, 1);
  98.    if (c == 0) {
  99.      read(0, &c, 1);
  100.      map_key(c, &keycode);
  101.      return keycode;
  102.      }
  103.    else
  104.      return (EKeyCode)c;
  105. }
  106.  
  107. /*
  108.  * Check to see is a key is waiting.
  109.  * Used to interrupt processing if input is pending or to detect if a soft
  110.  *   key has been hit (the terminal sends multiple characters for each
  111.  *   softkey).
  112.  * Don't use function B because it checks for ^C.
  113.  */
  114. int keywaiting()
  115. {
  116.   return wait_for_key(0);
  117. }
  118.  
  119.    /* Wait for a key to be pressed for no more than sec seconds.
  120.     * Use 0 seconds to check to see if a key is in the input que.
  121.     * Warning:  This rouine is only good for 32K seconds (about 9 hours).
  122.     *   If sec is a long the limit is still 24 hours.
  123.     */
  124. static struct _fd_set rdfds;
  125. wait_for_key(int sec)
  126. {
  127.    struct timeval tv;
  128.  
  129.    tv.tv_sec = sec;
  130.    tv.tv_usec = 0;
  131.  
  132.    return select(1, &rdfds, NULL, NULL, &tv) > 0;
  133. }
  134.  
  135.   /* Things to note about FastVideo:
  136.    *   putline() will do all of the writing to the text area (except for
  137.    *     help messages).
  138.    *   t_eeol() will only be called for the message line or for help
  139.    *     messages.
  140.    *   t_eeop() need only clear the message line.  It should use t_eeol() to
  141.    *     do this.
  142.    *   t_putchar() will only write to the message line, help messages or
  143.    *     (puts "message").
  144.    * So, this means that the message line is really seprate from the text
  145.    *   areas and t_putchar() and t_eeol() should use the same color (others
  146.    *   will use tcolor and mcolor).  Default for the message line would be
  147.    *   tcolor.  Help and (puts ...)  messages will be written in message
  148.    *   color (which is (I hope) reasonable).
  149.    * PC note:  Due to the way the BIOS is done, it is easier to have
  150.    *   t_putchar() and t_eeol() use the BIOS character attribute as the
  151.    *   color.
  152.    */
  153.  
  154. int tcolor = 7, mcolor = 96;    /* text, modeline color defaults */
  155. int zcolor = 7;
  156. static unsigned char *lbuf;
  157.  
  158.  /*
  159.   * Called to set up the terminal.
  160.   */
  161. void t_open()
  162. {
  163.   int display_type;
  164.  
  165.   /* set up the keyboard */
  166.   ioctl(0, TCGETA, &oldtio);
  167.   tio = oldtio;
  168.   tio.c_lflag &= ~(ICANON | ISIG | ECHO | ECHOE | ECHOK | IDEFAULT);
  169.   tio.c_iflag &= ~(ICRNL | INLCR | IUCLC | IXON | /*IXOFF |*/ IXANY | BRKINT);
  170.   tio.c_cc[VMIN] = 1;
  171.   tio.c_cc[VTIME] = 0;    /* no timeout by default */
  172.  
  173.   /* for select() in wait_for_key() */
  174.   FD_ZERO(&rdfds);
  175.   FD_SET(0, &rdfds);
  176.  
  177.   /* initialise video library */
  178.   v_init();
  179.  
  180.   v_getattr();
  181.  
  182.   display_type = v_hardware();
  183.   curs.start = 0;
  184.   curs.end = display_type == V_COLOR_8 ? 8 : 12;
  185.  
  186.   /* capture signals, set up keyboard, set cursor */
  187.   ttopen();
  188.  
  189.   v_dimen(&t_ncol, &t_nrow);
  190.   t_nrow--;    /* leave room for mini-buffer */
  191.   lbuf = malloc(t_ncol*2);
  192. }
  193.  
  194.  
  195. void putline(row, buf, attr)    /* note: row is 0 relative */
  196.   int row,attr; char *buf;
  197. {
  198.   register int i;
  199.   for (i = 0; i < t_ncol; i++) {
  200.     lbuf[i*2] = buf[i];
  201.     lbuf[i*2+1] = attr;
  202.   }
  203.   v_putline(lbuf, 0, row, t_ncol);
  204. }
  205.  
  206.  /* Erase to end of page or screen.
  207.   * For fast video, each line of the screen (except for the message line)
  208.   *   will be completely filled by putline() so all this routine needs to
  209.   *   clear is the message (last) line of the screen.
  210.   */
  211. void t_eeop() { v_gotoxy(0, t_nrow); v_clreol(); }
  212.  
  213.   /* Ring the bell.  beeper controls the volume:  0 (don't beep), n (some
  214.    *   volume value).
  215.    */
  216. void t_beep()
  217. {
  218.   extern int beeper;
  219.  
  220.   if (!beeper)
  221.     return;
  222.   putchar('\b');
  223. }
  224.  
  225. void t_move(row,col) int row, col;  /* move cursor to (row,col) */
  226. {
  227.   v_gotoxy(col, row);
  228. }
  229.  
  230. void t_eeol()       /* erase from cursor to end of line */
  231. {
  232.   v_clreol();
  233. }
  234.  
  235. #include "driver.h"
  236.  
  237. #define RGB_BITS(bits)        ((bits) & 0xF)
  238. #define FOREGROUND_BITS(bits)    ((bits) & 0xF)
  239. #define BACKGROUND_BITS(bits)    (((bits) >> 4) & 0x7)
  240. #define MAKE_RGB(fg, bg)    ( ((fg) & 0xF) | (((bg) & 7) << 4) )
  241.  
  242. static char *pc_color[] =
  243. {            /* IRGB   I can be 1 for forground colors only */
  244.   "black",        /* 0000 ==  0 */
  245.   "blue",        /* 0001 ==  1 */
  246.   "green",        /* 0010 ==  2 */
  247.   "cyan",        /* 0011 ==  3 */
  248.   "red",        /* 0100 ==  4 */
  249.   "magenta",        /* 0101 ==  5 */
  250.   "brown",        /* 0110 ==  6 */
  251.   "lightgrey",        /* 0111 ==  7 */
  252.   "darkgrey",        /* 1000 ==  8 */
  253.   "lightblue",        /* 1001 ==  9 */
  254.   "lightgreen",        /* 1010 == 10 */
  255.   "lightcyan",        /* 1011 == 11 */
  256.   "lightred",        /* 1100 == 12 */
  257.   "lightmagenta",    /* 1101 == 13 */
  258.   "yellow",        /* 1110 == 14 */
  259.   "white",        /* 1111 == 15 */
  260. };
  261.  
  262. static int color_to_rgb(color_name, rgb, foreground)
  263.   char *color_name; int *rgb;
  264. {
  265.   int i, max;
  266.  
  267.   strlwr(color_name);
  268.   max = foreground ? NITEMS(pc_color) : (NITEMS(pc_color) + 1)/2;
  269.   for (i = 0; i < max; i++)
  270.     if (0 == strcmp(pc_color[i], color_name))
  271.     {
  272.       *rgb = i;
  273.       return TRUE;
  274.     }
  275.   return FALSE;
  276. }
  277.  
  278. static char *rgb_to_color(rgb)
  279. {
  280.   return pc_color[RGB_BITS(rgb)];
  281. }
  282.  
  283. static void do_cursor(char * cursor_shape, int set);
  284.  
  285.     /* "forground:background"
  286.      *   ":"      => no change
  287.      *   "color"  => only change foreground
  288.      *   "color:" => only change foreground
  289.      *   ":color" => only change background
  290.      * Input:
  291.      *   color : name of color.
  292.      *   rgb : current color (incase name of new color is bogus)
  293.      * Returns:
  294.      *   New rgb bits.
  295.      */
  296. static int set_color(color, rgb) char *color;
  297. {
  298.   char *ptr, buf[100];
  299.   int fg, bg;
  300.  
  301.   strcpy(buf, color);
  302.   if (ptr = strchr(buf, ':')) *ptr++ = '\0';
  303.   if (!color_to_rgb(buf, &fg, TRUE))        fg = FOREGROUND_BITS(rgb);
  304.   if (!ptr || !color_to_rgb(ptr, &bg, FALSE))    bg = BACKGROUND_BITS(rgb);
  305.   return MAKE_RGB(fg, bg);
  306. }
  307.  
  308. static void get_color(buf,rgb) char *buf;
  309. {
  310.   strcpy(buf, rgb_to_color(FOREGROUND_BITS(rgb)));
  311.   strcat(buf, ":");
  312.   strcat(buf, rgb_to_color(BACKGROUND_BITS(rgb)));
  313. }
  314.  
  315. int do_color(which, color, set) char *color;
  316. {
  317.   int *c;
  318.  
  319.   switch(which)
  320.   {
  321.     case TEXT_COLOR:     c = &tcolor; break;        /* text color */
  322.     case MODELINE_COLOR: c = &mcolor; break;        /* modeline color */
  323.     case CURSOR_COLOR:                    /* cursor color */
  324.       if (set) return FALSE;    /* can't change cursor color */
  325.       c = &tcolor;        /* it is always the text color */
  326.       break;
  327.     case CURSOR_SHAPE: do_cursor(color, set); return TRUE;
  328.     default: return FALSE;            /* boo boo */
  329.   }
  330.   if (set)
  331.   {
  332.     int x = *c;
  333.     return (x != (*c = set_color(color, x)));
  334.   }
  335.   else get_color(color, *c);
  336.  
  337.   return FALSE;
  338. }
  339.  
  340. static void do_cursor(cursor_shape, set) char *cursor_shape;
  341. {
  342.   if (set)
  343.   {
  344.     char *ptr, buf[100];
  345.  
  346.     strcpy(buf, cursor_shape);
  347.     if (ptr = strchr(buf, ':')) *ptr++ = '\0';
  348.     curs.start = (atoi(buf) & 0xF);
  349.     curs.end = ptr ? (atoi(ptr) & 0xF) : 15;
  350.  
  351.     v_ctype(curs.start, curs.end);
  352.     return;
  353.   }
  354.  
  355.   sprintf(cursor_shape, "%d:%d", curs.start, curs.end);
  356. }
  357.  
  358. static MouseInfo mouse_info;    /* !!!??? initialize? */
  359.  
  360. MouseInfo *get_mouse_info()
  361. {
  362.   return &mouse_info;
  363. }
  364.