home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / vile-src.zip / vile-8.1 / os2vio.c < prev    next >
C/C++ Source or Header  |  1998-09-28  |  12KB  |  634 lines

  1. /*
  2.  * OS/2 VIO (character-mode) console routines.
  3.  * Modified from a really old version of "borland.c" (before the VIO
  4.  * stuff went in there.)
  5.  *
  6.  * $Header: /usr/build/vile/vile/RCS/os2vio.c,v 1.20 1998/09/29 02:22:03 tom Exp $
  7.  */
  8.  
  9. #include "estruct.h"
  10. #include "edef.h"
  11.  
  12. #if !SYS_OS2
  13. #error Configuration error:  OS/2 is required for VIO support.
  14. #endif
  15.  
  16. #define INCL_WIN
  17. #define INCL_BASE
  18. #define INCL_MOU
  19. #define INCL_VIO
  20. #define INCL_DOSPROCESS
  21. #define INCL_NOPMAPI
  22. #include <os2.h>
  23.  
  24. #include <conio.h>
  25.  
  26. #if DISP_VIO
  27.  
  28. #define SCROLLCODE        1
  29.  
  30. /* The code to control the cursor shape isn't complete.  No big loss. */
  31. #define CURSOR_SHAPE 0
  32.  
  33. #define NROW    60            /* Max Screen size.        */
  34. #define NCOL    80            /* Edit if you want to.         */
  35. #define    MARGIN    8            /* size of minimum margin and    */
  36. #define    SCRSIZ    64            /* scroll size for extended lines */
  37. #define    NPAUSE    200            /* # times thru update to pause */
  38. #define    SPACE    32            /* space character        */
  39.  
  40. #define    AttrColor(b, f)    ((((UINT)ctrans[b] & 15) << 4) | ((UINT)ctrans[f] & 15))
  41.  
  42. static    void    vio_move   (int,int);
  43. static    void    vio_eeol   (void);
  44. static    void    vio_eeop   (void);
  45. static    void    vio_beep   (void);
  46. static    void    vio_open   (void);
  47. #if OPT_VIDEO_ATTRS
  48. static    void    vio_attr   (UINT);
  49. #else
  50. static    void    vio_rev    (UINT);
  51. #endif    /* OPT_VIDEO_ATTRS */
  52. static    int    vio_cres   (const char *);
  53. static    void    vio_close  (void);
  54. static    int    vio_getc   (void);
  55. static    void    vio_putc   (int);
  56. static    void    vio_kopen  (void);
  57. static    void    vio_kclose (void);
  58. static    void    vio_flush  (void);
  59.  
  60. #if OPT_COLOR
  61. static    void    vio_fcol   (int);
  62. static    void    vio_bcol   (int);
  63. #define vio_spal   set_ctrans
  64. #else
  65. #define    vio_fcol   null_t_setfor
  66. #define    vio_bcol   null_t_setback
  67. #define vio_spal   null_t_setpal
  68. #endif
  69.  
  70. #if    SCROLLCODE
  71. static    void    vio_scroll (int,int,int);
  72. #else
  73. #define    vio_scroll null_t_scroll
  74. #endif
  75.  
  76. #if    OPT_TITLE
  77. static    void    vio_title (char *);
  78. #endif
  79.  
  80. static    int    scinit     (int);
  81.  
  82. int    cfcolor = -1;        /* current foreground color */
  83. int    cbcolor = -1;        /* current background color */
  84.  
  85. static    const char *initpalettestr = "0 4 2 6 1 5 3 7 8 12 10 14 9 13 11 15";
  86.  
  87. /*
  88.  * Standard terminal interface dispatch table. Most of the fields point into
  89.  * "termio" code.
  90.  */
  91. TERM term = {
  92.     NROW - 1,
  93.     NROW - 1,
  94.     NCOL,
  95.     NCOL,
  96.     MARGIN,
  97.     SCRSIZ,
  98.     NPAUSE,
  99.     vio_open,
  100.     vio_close,
  101.     vio_kopen,
  102.     vio_kclose,
  103.     vio_getc,
  104.     vio_putc,
  105.     tttypahead,
  106.     vio_flush,
  107.     vio_move,
  108.     vio_eeol,
  109.     vio_eeop,
  110.     vio_beep,
  111. #if OPT_VIDEO_ATTRS
  112.     vio_attr,
  113. #else
  114.     vio_rev,
  115. #endif    /* OPT_VIDEO_ATTRS */
  116.     vio_cres,
  117.     vio_fcol,
  118.     vio_bcol,
  119.     set_ctrans,
  120.     vio_scroll,
  121.     null_t_pflush,
  122.     null_t_icursor,
  123. #if OPT_TITLE
  124.     vio_title,
  125. #else
  126.     null_t_title,
  127. #endif
  128.     null_t_watchfd,
  129.     null_t_unwatchfd,
  130. };
  131.  
  132. #include "os2keys.h"
  133.  
  134. #define    TEXT_BUFFER_SIZE        256
  135.  
  136. static char  TextBuf[TEXT_BUFFER_SIZE];
  137. static int   TextFree;
  138. static char *TextOut;
  139. static int   TextRow, TextColumn;
  140. static BYTE  TextAttr;
  141. static int   MaxRows, MaxColumns;
  142. static int   CursorRow, CursorColumn;
  143. static BYTE  BlankCell[2] = { SPACE, 0 };
  144. static HMOU  hmou;
  145.  
  146. #define blank_cell()    ( BlankCell[1] = TextAttr, BlankCell )
  147.  
  148. #define flush_if_necessary() \
  149.     { if (TextOut > TextBuf) vio_flush(); }
  150.  
  151. #if CURSOR_SHAPE
  152. static void
  153. set_cursor(int cmode)
  154. {
  155.     VIOCURSORINFO cinfo;
  156.  
  157.     cinfo.cx = 0;            /* Width of character cell */
  158.     cinfo.cEnd = -100;        /* Cursor ends at bottom of cell */
  159.     cinfo.attr = 0;            /* Visible cursor */
  160.  
  161.     switch (cmode) {
  162.     case 0:
  163.         /* Hidden cursor. */
  164.         cinfo.attr = -1;
  165.         break;
  166.  
  167.     case 1:
  168.         /* Block cursor. */
  169.         cinfo.yStart = 0;
  170.         break;
  171.  
  172.     case 2:
  173.         /* 'Normal' cursor. */
  174.         cinfo.yStart = -75;
  175.         break;
  176.     }
  177.  
  178.     (void) VioSetCurType(&cinfo, 0);
  179. }
  180. #endif /* CURSOR_SHAPE */
  181.  
  182. #if OPT_COLOR
  183. /*
  184.  * Set the current foreground colour.  'color' specifies an ANSI colour
  185.  * index.
  186.  */
  187. static void
  188. vio_fcol(int color)
  189. {
  190.     /* Flush any old text that needs to be written using the old colour. */
  191.     flush_if_necessary();
  192.  
  193.     cfcolor  = color;
  194.     TextAttr = AttrColor(cbcolor, cfcolor);
  195. }
  196.  
  197. /*
  198.  * Set the current background colour.  'color' specifies an ANSI colour
  199.  * index.
  200.  */
  201. static void
  202. vio_bcol(int color)
  203. {
  204.     /* Flush any old text that needs to be written using the old colour. */
  205.     flush_if_necessary();
  206.  
  207.     cbcolor  = color;
  208.     TextAttr = AttrColor(cbcolor, cfcolor);
  209. }
  210. #endif
  211.  
  212. static void
  213. vio_move(int row, int col)
  214. {
  215.     flush_if_necessary();
  216.  
  217.     TextRow    = row;
  218.     TextColumn = col;
  219. }
  220.  
  221. /* erase to the end of the line */
  222. static void
  223. vio_eeol(void)
  224. {
  225.     int length;
  226.  
  227.     flush_if_necessary();
  228.  
  229.     if ((length = MaxColumns - TextColumn) > 0)
  230.     {
  231.         (void) VioWrtNCell(blank_cell(), length, TextRow, TextColumn, 0);
  232.     }
  233. }
  234.  
  235. static int
  236. decode_mouse_state(USHORT state)
  237. {
  238.     int button = 0;
  239.     if (state & MOUSE_MOTION_WITH_BN1_DOWN
  240.      || state & MOUSE_BN1_DOWN) {
  241.         button = 1;
  242.     }
  243.     if (state & MOUSE_MOTION_WITH_BN2_DOWN
  244.      || state & MOUSE_BN2_DOWN) {
  245.         button = 2;
  246.     }
  247.     if (state & MOUSE_MOTION_WITH_BN3_DOWN
  248.      || state & MOUSE_BN3_DOWN) {
  249.         button = 3;
  250.     }
  251.     return button;
  252. }
  253.  
  254. /* If we have a mouse event, process it.  Otherwise, read a character. */
  255. static int
  256. vio_getc(void)
  257. {
  258.     MOUEVENTINFO mouev;
  259.     USHORT    nowait = MOU_NOWAIT;
  260.     USHORT    rc;
  261.     int    button = 0;
  262.  
  263.     do {
  264.         rc = MouReadEventQue(&mouev, &nowait, hmou);
  265.         if (rc == 0 && mouev.fs != 0) {
  266.             if (button) {
  267.                 int last = button;
  268.                 button = decode_mouse_state(mouev.fs);
  269.                 if (button) {
  270.                     if (last == button) {
  271.                         if (!setcursor(mouev.row, mouev.col))
  272.                             continue;
  273.                         if (!sel_extend(TRUE, TRUE))
  274.                             continue;
  275.                     } else {
  276.                         sel_release();
  277.                     }
  278.                     (void)update(TRUE);
  279.                 } else {
  280.                     sel_yank(0);
  281.                 }
  282.             } else {
  283.                 button = decode_mouse_state(mouev.fs);
  284.                 if (button == 1) {
  285.                     if (!setcursor(mouev.row, mouev.col))
  286.                         continue;
  287.                     (void)sel_begin();
  288.                     (void)update(TRUE);
  289.                 }
  290.             }
  291.         }
  292.     } while (!kbhit());
  293.  
  294.     return getch();
  295. }
  296.  
  297. /* put a character at the current position in the current colors */
  298. static void
  299. vio_putc(int ch)
  300. {
  301.     BYTE b;
  302.  
  303.     if (TextFree <= 0)
  304.         vio_flush();
  305.  
  306.     /*
  307.      * Control character kludges.  Sigh.
  308.      */
  309.     switch (ch)
  310.     {
  311.         case '\b':
  312.             flush_if_necessary();
  313.             TextColumn--;
  314.             break;
  315.  
  316.         case '\n':
  317.         case '\r':
  318.             flush_if_necessary();
  319.             b = ch;
  320.             VioWrtTTY(&b, 1, 0);
  321.             break;
  322.  
  323.         default:
  324.             *TextOut++ = ch;
  325.             TextFree--;
  326.             break;
  327.     }
  328. }
  329.  
  330. static void
  331. vio_flush(void)
  332. {
  333.     int length = TextOut - TextBuf;
  334.  
  335.     if (length > 0)
  336.     {
  337.         (void) VioWrtCharStrAtt(TextBuf, length, TextRow, TextColumn,
  338.             &TextAttr, 0);
  339.         TextColumn += length;
  340.     }
  341.     TextOut  = TextBuf;
  342.     TextFree = TEXT_BUFFER_SIZE;
  343.  
  344.     /* Make the cursor 'catch up', if necessary. */
  345.     if (CursorColumn != TextColumn || CursorRow != TextRow)
  346.     {
  347.         (void) VioSetCurPos(TextRow, TextColumn, 0);
  348.         CursorRow = TextRow;
  349.         CursorColumn = TextColumn;
  350.     }
  351. }
  352.  
  353. static void
  354. vio_eeop(void)
  355. {
  356.     int length;
  357.  
  358.     flush_if_necessary();
  359.  
  360.     length = (MaxRows * MaxColumns)
  361.            - (TextRow * MaxColumns + TextColumn);
  362.     if (length > 0)
  363.         (void) VioWrtNCell(blank_cell(), length, TextRow, TextColumn, 0);
  364. }
  365.  
  366. #if OPT_VIDEO_ATTRS
  367. static void
  368. vio_attr(UINT attr)
  369. {
  370.     attr = VATTRIB(attr);
  371.     attr &= ~(VAML|VAMLFOC);
  372.  
  373.     flush_if_necessary();
  374.  
  375. #if OPT_COLOR
  376.     if (attr & VACOLOR)
  377.         vio_fcol(VCOLORNUM(attr));
  378.     else
  379.         vio_fcol(gfcolor);
  380. #endif
  381.     if (attr & (VAREV|VASEL))
  382.         TextAttr = AttrColor(cfcolor, cbcolor);
  383.     else
  384.         TextAttr = AttrColor(cbcolor, cfcolor);
  385.  
  386.     if (attr & VABOLD)
  387.         TextAttr |= 0x8;
  388. }
  389.  
  390. #else    /* highlighting is a minimum attribute */
  391.  
  392. /*
  393.  * Choose the text attributes for reverse or normal video.  Reverse video
  394.  * is selected if 'reverse' is TRUE, and normal video otherwise.
  395.  */
  396. static void
  397. vio_rev(UINT reverse)
  398. {
  399.     flush_if_necessary();
  400.  
  401.     if (reverse)
  402.         TextAttr = AttrColor(cfcolor, cbcolor);
  403.     else
  404.         TextAttr = AttrColor(cbcolor, cfcolor);
  405. }
  406. #endif    /* OPT_VIDEO_ATTRS */
  407.  
  408. static int
  409. vio_cres(const char *res) /* change screen resolution */
  410.             /* resolution to change to */
  411. {
  412.     return scinit(-1);
  413. }
  414.  
  415. #if    OPT_FLASH
  416. static void
  417. flash_display(void)
  418. {
  419.     VIOMODEINFO data;
  420.     UINT cellsize;
  421.     BYTE *buf1;
  422.     BYTE *buf2;
  423.     USHORT got, length;
  424.  
  425.     data.cb = sizeof(data);
  426.     VioGetMode(&data, 0);
  427.     cellsize = 1 + data.attrib;
  428.  
  429.     buf1 = malloc(data.full_length);
  430.     buf2 = malloc(data.full_length);
  431.  
  432.     length = data.full_length;
  433.     VioReadCellStr(buf1, &length, 0, 0, 0);
  434.  
  435.     length = data.full_length;
  436.     VioReadCellStr(buf2, &length, 0, 0, 0);
  437.  
  438.     for (got = 0; got < data.full_length; got += cellsize) {
  439.         buf2[got + 1] ^= 8;
  440.     }
  441.     VioWrtCellStr(buf2, data.full_length, 0, 0, 0);
  442.     DosSleep(200);
  443.     VioWrtCellStr(buf1, data.full_length, 0, 0, 0);
  444.  
  445.     free(buf1);
  446.     free(buf2);
  447. }
  448. #endif
  449.  
  450. static void
  451. vio_beep()
  452. {
  453. #if    OPT_FLASH
  454.     if (global_g_val(GMDFLASH)) {
  455.         flash_display();
  456.         return;
  457.     }
  458. #endif
  459.     /* A nice, brief beep. */
  460.     DosBeep(440, 50);
  461. }
  462.  
  463. static void
  464. vio_open(void)
  465. {
  466.     int i;
  467.  
  468.     /* Initialize output buffer. */
  469.     TextRow = 0;
  470.     TextColumn = 0;
  471.     TextOut = TextBuf;
  472.     TextFree = TEXT_BUFFER_SIZE;
  473.  
  474.     for (i = 0; i < sizeof(VIO_KeyMap) / sizeof(VIO_KeyMap[0]); i++)
  475.     {
  476.         addtosysmap(VIO_KeyMap[i].seq, 2, VIO_KeyMap[i].code);
  477.     }
  478.  
  479. #if OPT_COLOR
  480.     {
  481.         VIOINTENSITY intense;
  482.         intense.cb   = sizeof(intense);
  483.         intense.type = 2;
  484.         intense.fs   = 1;    /* ask for bright colors, not blink */
  485.         VioSetState(&intense, 0);
  486.     }
  487.     set_palette(initpalettestr);
  488.     vio_fcol(gfcolor);
  489.     vio_bcol(gbcolor);
  490. #endif
  491.  
  492. #if CURSOR_SHAPE
  493.     set_cursor(1);
  494. #endif
  495.  
  496.     if (!vio_cres(current_res_name))
  497.         (void) scinit(-1);
  498. }
  499.  
  500. static void
  501. vio_close(void)
  502. {
  503. #if CURSOR_SHAPE
  504.     set_cursor(2);
  505. #endif
  506.     vio_move(MaxRows-1, 0);
  507.     TTeeop();
  508. }
  509.  
  510. static void
  511. vio_kopen()    /* open the keyboard */
  512. {
  513.     MouOpen(NULL, &hmou);
  514.     MouDrawPtr(hmou);
  515.     return;
  516. }
  517.  
  518. static void
  519. vio_kclose()    /* close the keyboard */
  520. {
  521.     MouClose(hmou);
  522.     return;
  523. }
  524.  
  525. static int
  526. scinit(int rows)    /* initialize the screen head pointers */
  527. {
  528.     VIOMODEINFO vinfo;
  529.  
  530.     vinfo.cb = sizeof(vinfo);
  531.     (void) VioGetMode(&vinfo, 0);
  532.  
  533.     MaxRows = vinfo.row;
  534.     MaxColumns = vinfo.col;
  535.     newscreensize(MaxRows, MaxColumns);
  536.  
  537.     return TRUE;
  538. }
  539.  
  540. #if SCROLLCODE
  541. /*
  542.  * Move 'n' lines starting at 'from' to 'to'
  543.  *
  544.  * OPT_PRETTIER_SCROLL is prettier but slower -- it scrolls a line at a time
  545.  * instead of all at once.
  546.  */
  547.  
  548. static void
  549. vio_scroll(int from, int to, int n)
  550. {
  551.     /* Ignore single-line scrolling regions. */
  552.     if (to == from)
  553.         return;
  554.  
  555. #if OPT_PRETTIER_SCROLL
  556.     /* Easier for the eye to follow, but slower. */
  557.     if (absol(from-to) > 1) {
  558.         vio_scroll(from, (from < to) ? to - 1 : to + 1, n);
  559.         if (from < to)
  560.             from = to-1;
  561.         else
  562.             from = to+1;
  563.     }
  564. #endif
  565.  
  566.     if (to < from)
  567.     {
  568.         (void) VioScrollUp(to, 0, from + n - 1, MaxColumns - 1,
  569.             from - to, blank_cell(), 0);
  570. /*
  571.         vio_move(to + n, 0);
  572. */
  573.     }
  574.     else
  575.     {
  576.         (void) VioScrollDn(from, 0, to + n - 1, MaxColumns - 1,
  577.             to - from, blank_cell(), 0);
  578. /*
  579.         vio_move(to + n, 0);
  580. */
  581.     }
  582. }
  583. #endif    /* SCROLLCODE */
  584.  
  585. #if OPT_TITLE
  586. /*
  587.  * This sets the title in the window-list, but doesn't work for the
  588.  * actual window title.  It's adapted from a standalone code example
  589.  * that uses
  590.  *    WinSetWindowText(hwndActive, swcntrl.szSwtitle);
  591.  * before
  592.  *    WinChangeSwitchEntry(hSwitch, &swcntrl);
  593.  *
  594.  * The standalone example is linked for PM versus this program's VIO mode.
  595.  */
  596. static void
  597. vio_title(char *title)        /* set the current window title */
  598. {
  599.       HAB  hab = WinInitialize( 0 );
  600.       HMQ  hmq = WinCreateMsgQueue( hab, 0 );
  601.       HWND hwndActive = WinQueryActiveWindow(HWND_DESKTOP);
  602.       HWND hwndFrame = WinQueryWindow(hwndActive, QW_PARENT);
  603.       char temp[24];
  604.       BOOL ok;
  605.       LONG nn;
  606.  
  607.       WinQuerySessionTitle(hab, 0, temp, sizeof(temp));
  608.  
  609.       if (strlen(title))
  610.       {
  611.          HSWITCH hSwitch;
  612.          SWCNTRL swcntrl;
  613.  
  614.          if (hSwitch = WinQuerySwitchHandle(hwndActive, (PID)0L))
  615.          {
  616.             if (!WinQuerySwitchEntry(hSwitch, &swcntrl))
  617.             {
  618.                strncpy(swcntrl.szSwtitle, title, MAXNAMEL);
  619.                swcntrl.szSwtitle[MAXNAMEL] = '\0';
  620. #if 0
  621.                WinSetWindowText(hwndActive, swcntrl.szSwtitle);
  622. #endif
  623.                WinChangeSwitchEntry(hSwitch, &swcntrl);
  624.             }
  625.          }
  626.       }
  627.  
  628.       WinDestroyMsgQueue( hmq );
  629.       WinTerminate( hab );
  630. }
  631. #endif /* OPT_TITLE */
  632.  
  633. #endif /* DISP_VIO */
  634.