home *** CD-ROM | disk | FTP | other *** search
/ Garbo / Garbo.cdr / pc / memacs / ue311c.arc / OS2NPM.C < prev    next >
C/C++ Source or Header  |  1991-02-22  |  15KB  |  571 lines

  1. /*
  2.  * OS2NONPM.C
  3.  *
  4.  * The routines in this file provide video and keyboard support using the
  5.  * OS/2 Vio and Kbd functions (not the presentation manager).
  6.  *
  7.  * The os2putc, os2eeol and os2eeop routines modify the logical video
  8.  * buffer.  Os2flush calls VioShowBuf to update the physical video buffer.
  9.  * An earlier version used VioWrtTTy with ANSI processing (easy to do, but
  10.  * sloooow).  A later version using VioWrtNCell was better, but not as
  11.  * good as manipulating the logical buffer.
  12.  */
  13.  
  14. #define INCL_BASE
  15. #include    <os2.h>
  16.  
  17. #define    termdef    1            /* don't define "term" external */
  18.  
  19. #include    <stdio.h>
  20.  
  21. #undef    PASCAL
  22. #undef    NEAR
  23. #undef    HIBYTE
  24.  
  25. #include    "estruct.h"
  26. #include    "eproto.h"
  27. #include    "edef.h"
  28. #include    "elang.h"
  29.  
  30. #if     OS2NPM
  31. /*
  32.  * Os2def.h defines COLOR, but no MSC stuff needs it.
  33.  * We need COLOR as defined in estruct.h, so edit it out of os2def.h.
  34.  */
  35. #include    <conio.h>
  36.  
  37. #define    NROW    50        /* Screen size.                 */
  38. #define    NCOL    80        /* Edit if you want to.         */
  39. #define    MARGIN    8        /* size of minimim margin and    */
  40. #define    SCRSIZ    64        /* scroll size for extended lines */
  41. #define    NPAUSE    100        /* # times thru update to pause */
  42.  
  43. #define CDCGA    0        /* color graphics adapter    */
  44. #define CDMONO    1        /* monochrome display adapter    */
  45. #define CDEGA    2        /* EGA                */
  46. #define CDVGA    3        /* VGA                */
  47.  
  48. #define NDRIVE    4        /* number of video modes    */
  49.  
  50. int dtype = -1;                /* current video mode    */
  51. char drvname[][8] = {            /* names of video modes    */
  52.     "CGA", "MONO", "EGA", "VGA"
  53. };
  54.  
  55. /* Forward references.          */
  56.  
  57. PASCAL NEAR os2move();
  58. PASCAL NEAR os2eeol();
  59. PASCAL NEAR os2eeop();
  60. PASCAL NEAR os2beep();
  61. PASCAL NEAR os2open();
  62. PASCAL NEAR os2close();
  63. PASCAL NEAR os2getc();
  64. PASCAL NEAR os2putc();
  65. PASCAL NEAR os2flush();
  66. PASCAL NEAR os2rev();
  67. PASCAL NEAR os2kclose();
  68. PASCAL NEAR os2kopen();
  69. PASCAL NEAR os2cres();
  70. PASCAL NEAR os2parm();
  71. #if    COLOR
  72. PASCAL NEAR os2fcol();
  73. PASCAL NEAR os2bcol();
  74. #endif
  75.  
  76. struct {            /* Current screen attribute for ORing    */
  77.     BYTE    filler;        /* with character to be displayed.    */
  78.     BYTE    attr;
  79. } os2cell = {0, 0x07};
  80.  
  81. struct {            /* Current reverse screen attribute for    */
  82.     BYTE    filler;        /* ORing with character to be displayed.*/
  83.     BYTE    attr;
  84. } os2rcell = {0, 0x07};
  85.  
  86. static struct {                /* initial states        */
  87.     USHORT        ansiState;    /* ANSI translation        */
  88.     VIOCONFIGINFO    vioConfigInfo;    /* video configuration        */
  89.     VIOMODEINFO    vioModeInfo;    /* video mode            */
  90.     KBDINFO        kbdInfo;    /* keyboard info        */
  91. } initial;
  92.  
  93. static int    cfcolor = -1;        /* current foreground color    */
  94. static int    cbcolor = -1;        /* current background color    */
  95. static int    ctrans[] =    /* ansi to ibm color translation table    */
  96.     {0, 4, 2, 6, 1, 5, 3, 7,
  97.      8, 12, 10, 14, 9, 13, 11, 15};
  98.  
  99. static short     os2row;        /* current cursor row    */
  100. static short     os2col;        /* current cursor col    */
  101.  
  102. int revflag = FALSE;            /* are we currently in rev video? */
  103.  
  104. /*
  105.  * To minimize the amount of buffer that VioShowBuf has to update, we
  106.  * keep track of the lowest and highest bytes in the logical video
  107.  * buffer which have been modified.
  108.  */
  109. static USHORT    *lvb;            /* logical video buffer    */
  110. static USHORT     lvbLen;        /* length of buffer    */
  111. static USHORT     lvbMin;        /* min index of modified byte    */
  112. static USHORT     lvbMax;        /* max index of modified byte    */
  113.  
  114. /*
  115.  * Standard terminal interface dispatch table.
  116.  */
  117. TERM    term    = {
  118.     NROW-1,
  119.     NROW-1,
  120.     NCOL,
  121.     NCOL,
  122.     MARGIN,
  123.     SCRSIZ,
  124.     NPAUSE,
  125.     os2open,
  126.     os2close,
  127.     os2kopen,
  128.     os2kclose,
  129.     os2getc,
  130.     os2putc,
  131.     os2flush,
  132.     os2move,
  133.     os2eeol,
  134.     os2eeop,
  135.     os2beep,
  136.     os2rev,
  137.     os2cres
  138. #if    COLOR
  139.     , os2fcol,
  140.     os2bcol
  141. #endif
  142. };
  143.  
  144.  
  145. #if    COLOR
  146. /*----------------------------------------------------------------------*/
  147. /*    os2fcol()                            */
  148. /* Set the current foreground color.                    */
  149. /*----------------------------------------------------------------------*/
  150.  
  151. PASCAL NEAR os2fcol(
  152.     int color)            /* color to set */
  153. {
  154.     if (dtype != CDMONO)
  155.         cfcolor = ctrans[color];
  156.     else
  157.         cfcolor = 7;
  158.  
  159.     /* set the normal attribute */
  160.     os2cell.attr &= 0xF0;
  161.     os2cell.attr |= cfcolor;
  162.  
  163.     /* set the reverse attribute */
  164.     os2rcell.attr &= 0x07;
  165.     os2rcell.attr |= cfcolor << 4;    
  166. }
  167.  
  168. /*----------------------------------------------------------------------*/
  169. /*    os2bcol()                            */
  170. /* Set the current background color.                    */
  171. /*----------------------------------------------------------------------*/
  172.  
  173. PASCAL NEAR os2bcol(
  174.     int color)        /* color to set */
  175. {
  176.     if (dtype != CDMONO)
  177.         cbcolor = ctrans[color];
  178.     else
  179.         cbcolor = 0;
  180.  
  181.     /* set normal background attribute */
  182.     os2cell.attr &= 0x0F;
  183.     os2cell.attr |= cbcolor << 4;
  184.  
  185.     /* set reverse background attribute */
  186.     os2rcell.attr &= 0x70;
  187.     os2rcell.attr |= cbcolor;
  188. }
  189. #endif
  190.  
  191.  
  192. /*----------------------------------------------------------------------*/
  193. /*    os2move()                            */
  194. /* Move the cursor.                            */
  195. /*----------------------------------------------------------------------*/
  196.  
  197. PASCAL NEAR os2move(
  198.     int row,
  199.     int col)
  200. {
  201.     os2row = row;
  202.     os2col = col;
  203.     VioSetCurPos(os2row, os2col, 0);
  204. }
  205.  
  206.  
  207. /*----------------------------------------------------------------------*/
  208. /*    os2flush()                            */
  209. /* Update the physical video buffer from the logical video buffer.    */
  210. /*----------------------------------------------------------------------*/
  211.  
  212. PASCAL NEAR os2flush(void)
  213. {
  214.     if (lvbMin <= lvbMax) {        /* did anything change?    */
  215.         VioShowBuf(lvbMin * 2, (lvbMax - lvbMin + 1) * 2, 0);
  216.         VioSetCurPos(os2row, os2col, 0);
  217.     }
  218.     lvbMin = lvbLen;
  219.     lvbMax = 0;
  220. }
  221.  
  222.  
  223. /*----------------------------------------------------------------------*/
  224. /*    os2getc()                            */
  225. /* Get a character from the keyboard.                    */
  226. /* Function keys, editing keys and alt- keys take two consecutive calls    */
  227. /* to os2getc().  The first returns zero and the second returns the    */
  228. /* key's scan code.                            */
  229. /* Nextc holds the scan code until we are called again.            */
  230. /*----------------------------------------------------------------------*/
  231.  
  232. PASCAL NEAR os2getc()
  233. {
  234.     KBDKEYINFO    keyInfo;
  235.     static int    nextc = -1;  /* -1 when not holding a scan code    */
  236.     static int  event = -1;  /* -1 when not holding an event byte */
  237.  
  238.     if (nextc != -1) {
  239.         keyInfo.chChar = (char)(nextc >> 8);    /* prefix byte */
  240.         event = nextc;
  241.         nextc = -1;
  242.         return keyInfo.chChar;        /* return the scan code    */
  243.     }
  244.     
  245.     if (event != -1) {
  246.         keyInfo.chChar = (char)(event & 255);    /* event code byte */
  247.         event = -1;
  248.         return keyInfo.chChar;        /* return the scan code    */
  249.     }
  250.  
  251.     KbdCharIn(&keyInfo, IO_WAIT, 0);    /* get a character    */
  252.  
  253.     /* Function, edit or alt- key?    */
  254.     if (keyInfo.chChar == 0  ||  keyInfo.chChar == 0xE0) {
  255.         nextc = extcode(keyInfo.chScan);        /* hold on to scan code    */
  256.         return 0;
  257.     }
  258.     return (keyInfo.chChar & 255);
  259. }
  260.  
  261.  
  262. #if    TYPEAH
  263. /*----------------------------------------------------------------------*/
  264. /*    typahead()                            */
  265. /* Returns true if a key has been pressed.                */
  266. /*----------------------------------------------------------------------*/
  267.  
  268. PASCAL NEAR typahead()
  269.  
  270. {
  271.     return kbhit();
  272. }
  273. #endif
  274.  
  275.  
  276. /*----------------------------------------------------------------------*/
  277. /*    os2putc()                            */
  278. /* Put a character at the current position in the current colors.    */
  279. /* Note that this does not behave the same as putc() or VioWrtTTy().    */
  280. /* This routine does nothing with returns and linefeeds.  For backspace */
  281. /* it puts a space in the previous column and moves the cursor to the    */
  282. /* previous column.  For all other characters, it will display the    */
  283. /* graphic representation of the character and put the cursor in the    */
  284. /* next column (even if that is off the screen.  In practice this isn't    */
  285. /* a problem.                                */
  286. /*----------------------------------------------------------------------*/
  287.  
  288. PASCAL NEAR os2putc(int c)
  289. {
  290.     USHORT    cell;
  291.     USHORT    i;
  292.  
  293.     if (c == '\n' || c == '\r') {        /* returns and linefeeds */
  294.         return;
  295.     }
  296.     if (c == '\b') {            /* backspace        */
  297.         cell = ' ' | (revflag ? *(USHORT *)&os2rcell : *(USHORT *)&os2cell);
  298.         --os2col;            /* move cursor back    */
  299.         i = os2row * term.t_ncol + os2col;
  300.     }
  301.     else {
  302.         cell = (0x00ff & c) | (revflag ? *(USHORT *)&os2rcell : *(USHORT *)&os2cell);
  303.         i = os2row * term.t_ncol + os2col;
  304.         ++os2col;            /* move cursor forward    */
  305.     }
  306.     lvb[i] = cell;
  307.     if (i < lvbMin)
  308.         lvbMin = i;
  309.     if (i > lvbMax)
  310.         lvbMax = i;
  311. }
  312.  
  313.  
  314. /*----------------------------------------------------------------------*/
  315. /*    os2eeol()                            */
  316. /* Erase to end of line.                        */
  317. /*----------------------------------------------------------------------*/
  318.  
  319. PASCAL NEAR os2eeol()
  320. {
  321.     USHORT    cell = ' ';
  322.     USHORT  i;
  323.  
  324.     cell |= (revflag ? *(USHORT *)&os2rcell : *(USHORT *)&os2cell);
  325.     
  326.     i = os2row * term.t_ncol + os2col;  /* current cursor position    */
  327.     if (i < lvbMin)
  328.         lvbMin = i;
  329.     while (i < os2row * term.t_ncol + term.t_ncol)
  330.         lvb[ i++] = cell;
  331.     if (--i > lvbMax)
  332.         lvbMax = i;
  333. }
  334.  
  335.  
  336. /*----------------------------------------------------------------------*/
  337. /*    os2eeop()                            */
  338. /* Erase to end of page.                        */
  339. /*----------------------------------------------------------------------*/
  340.  
  341. PASCAL NEAR os2eeop()
  342. {
  343.     USHORT    cell = ' ';
  344.     USHORT  i;
  345.  
  346. #if COLOR
  347.     if (dtype != CDMONO)
  348.         cell |= (ctrans[gbcolor] << 4 | ctrans[gfcolor]) << 8;
  349.     else
  350.         cell |= 0x0700;
  351. #else
  352.     cell |= 0x0700;
  353. #endif
  354.  
  355.     i = os2row * term.t_ncol + os2col;  /* current cursor position    */
  356.     if (i < lvbMin)
  357.         lvbMin = i;
  358.     while (i < term.t_nrow * term.t_ncol + term.t_ncol)
  359.         lvb[ i++] = cell;
  360.     if (--i > lvbMax)
  361.         lvbMax = i;
  362. }
  363.  
  364. /*----------------------------------------------------------------------*/
  365. /*    os2rev()                            */
  366. /* Change reverse video state.                      */
  367. /*----------------------------------------------------------------------*/
  368.  
  369. PASCAL NEAR os2rev(state)
  370.  
  371. int state;    /* TRUE = reverse, FALSE = normal */
  372.  
  373. {
  374.     revflag = state;
  375. }
  376.  
  377. /*----------------------------------------------------------------------*/
  378. /*    os2cres()                            */
  379. /* Change the screen resolution.                    */
  380. /*----------------------------------------------------------------------*/
  381.  
  382. PASCAL NEAR os2cres(char *res)        /* name of desired video mode    */
  383. {
  384.     USHORT    err;
  385.     int    type;            /* video mode type    */
  386.     VIOMODEINFO vioModeInfo;
  387.  
  388.     vioModeInfo = initial.vioModeInfo;
  389.     
  390.     /* From the name, find the type of video mode.    */
  391.     for (type = 0; type < NDRIVE; type++) {
  392.         if (strcmp(res, drvname[type]) == 0)
  393.             break;
  394.     }
  395.     if (type == NDRIVE)
  396.         return(FALSE);    /* not a mode we know about    */
  397.  
  398.         
  399.     switch (type) {
  400.         case CDMONO:
  401.         case CDCGA:
  402.             vioModeInfo.row = 25;
  403.             break;
  404.         case CDEGA:
  405.             vioModeInfo.row = 43;
  406.             break;
  407.         case CDVGA:
  408.             vioModeInfo.row = 50;
  409.             break;
  410.     }
  411.     
  412.     if (VioSetMode(&vioModeInfo, 0))    /* change modes     */
  413.         return(FALSE);            /* couldn't do it    */
  414.  
  415.     newsize(TRUE, vioModeInfo.row);
  416.  
  417.     /* reset the $sres environment variable */
  418.     strcpy(sres, drvname[type]);
  419.     dtype = type;                /* set the current mode    */
  420.     
  421.     return TRUE;
  422. }
  423.  
  424.  
  425. /*----------------------------------------------------------------------*/
  426. /*    spal()                                */
  427. /* Change pallette settings.  (Does nothing.)                */
  428. /*----------------------------------------------------------------------*/
  429.  
  430. PASCAL NEAR spal(char *dummy)
  431. {
  432. }
  433.  
  434.  
  435. /*----------------------------------------------------------------------*/
  436. /*    os2beep()                            */
  437. /*----------------------------------------------------------------------*/
  438.  
  439. PASCAL NEAR os2beep()
  440. {
  441.     DosBeep(1200, 175);
  442. }
  443.  
  444.  
  445. /*----------------------------------------------------------------------*/
  446. /*    os2open()                            */
  447. /* Find out what kind of video adapter we have and the current video    */
  448. /* mode.  Even if the adapter supports a higher resolution mode than is */
  449. /* in use, we still use the current mode.                */
  450. /*----------------------------------------------------------------------*/
  451.  
  452. PASCAL NEAR os2open()
  453. {
  454.     initial.vioConfigInfo.cb = 0x0A;
  455.     VioGetConfig(0, &initial.vioConfigInfo, 0);
  456.     switch (initial.vioConfigInfo.adapter) {
  457.         case 3:
  458.             dtype = CDVGA;
  459.             break;
  460.         case 2:
  461.             dtype = CDEGA;
  462.             break;
  463.         case 1:
  464.             dtype = CDCGA;
  465.             break;
  466.         case 0:
  467.         default:
  468.             dtype = CDMONO;
  469.     }
  470.     strcpy(sres, drvname[dtype]);
  471.  
  472.     initial.vioModeInfo.cb = 0x0E;
  473.     VioGetMode(&initial.vioModeInfo, 0);
  474.     newsize(TRUE, initial.vioModeInfo.row);
  475.             
  476.     VioGetAnsi(&initial.ansiState, 0);
  477.     VioGetBuf((PULONG)&lvb, &lvbLen, 0);
  478.     lvbMin = lvbLen;
  479.     lvbMax = 0;
  480.  
  481.     revexist = TRUE;
  482.     revflag = FALSE;
  483. }
  484.  
  485.  
  486. /*----------------------------------------------------------------------*/
  487. /*    os2close()                            */
  488. /* Restore the original video settings.                    */
  489. /*----------------------------------------------------------------------*/
  490.  
  491. PASCAL NEAR os2close()
  492. {
  493.     VioSetAnsi(initial.ansiState, 0);
  494.     VioSetMode(&initial.vioModeInfo, 0);
  495.     VioSetCurPos(initial.vioModeInfo.row - 1,
  496.              initial.vioModeInfo.col - 1, 0);
  497. }
  498.  
  499. /*----------------------------------------------------------------------*/
  500. /*    os2kopen()                            */
  501. /* Open the keyboard.                            */
  502. /*----------------------------------------------------------------------*/
  503.  
  504. PASCAL NEAR os2kopen()
  505. {
  506.     KBDINFO    kbdInfo;
  507.  
  508.     initial.kbdInfo.cb = 0x000A;
  509.     KbdGetStatus(&initial.kbdInfo, 0);    
  510.     kbdInfo = initial.kbdInfo;
  511.     kbdInfo.fsMask &= ~0x0001;        /* not echo on        */
  512.     kbdInfo.fsMask |= 0x0002;        /* echo off        */
  513.     kbdInfo.fsMask &= ~0x0008;        /* cooked mode off    */
  514.     kbdInfo.fsMask |= 0x0004;        /* raw mode        */
  515.     kbdInfo.fsMask &= ~0x0100;        /* shift report    off    */
  516.     KbdSetStatus(&kbdInfo, 0);
  517. }
  518.  
  519.  
  520. /*----------------------------------------------------------------------*/
  521. /*    os2kclose()                            */
  522. /* Close the keyboard.                            */
  523. /*----------------------------------------------------------------------*/
  524.  
  525. PASCAL NEAR os2kclose()
  526. {
  527.     KbdSetStatus(&initial.kbdInfo, 0); /* restore original state    */
  528. }
  529.  
  530. #if    FLABEL
  531. PASCAL NEAR fnclabel(f, n)    /* label a function key */
  532.  
  533. int f,n;    /* default flag, numeric argument [unused] */
  534.  
  535. {
  536.     /* on machines with no function keys...don't bother */
  537.     return(TRUE);
  538. }
  539. #endif
  540.  
  541. #if 0
  542. /*----------------------------------------------------------------------*/
  543. /*    scwrite()                            */
  544. /* Write a line to the screen.
  545. /* I tried using this routine with MEMMAP = 1, but there were too many    */
  546. /* problems with the cursor and flushing the buffer.            */
  547. /*----------------------------------------------------------------------*/
  548.  
  549. scwrite(
  550.     int     row,    /* row of screen to place outstr on */
  551.     char    *outstr,/* string to write out (must be term.t_ncol long) */
  552.     int     forg,    /* foreground color of string to write */
  553.     int     bacg,    /* background color */
  554. {
  555.     USHORT     attr;
  556.     int     i;
  557.  
  558.     attr = (((ctrans[bacg] & 15) << 4) | (forg & 15)) << 8;
  559.  
  560.     for (i = row * term.t_ncol;  i < (row + 1) * term.t_ncol;  i++)
  561.         lvb[i] = attr | *(outstr++);
  562.  
  563.     if (i < lvbMin)
  564.         lvbMin = i;
  565.     if (i > lvbMax)
  566.         lvbMax = i;
  567. }
  568. #endif
  569. #endif
  570.  
  571.