home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / UE311C.ZIP / OS2NPM.C < prev    next >
C/C++ Source or Header  |  1991-10-29  |  15KB  |  574 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.     0, 0,
  123.     MARGIN,
  124.     SCRSIZ,
  125.     NPAUSE,
  126.     os2open,
  127.     os2close,
  128.     os2kopen,
  129.     os2kclose,
  130.     os2getc,
  131.     os2putc,
  132.     os2flush,
  133.     os2move,
  134.     os2eeol,
  135.     os2eeop,
  136.     os2eeop,
  137.     os2beep,
  138.     os2rev,
  139.     os2cres
  140. #if    COLOR
  141.     , os2fcol,
  142.     os2bcol
  143. #endif
  144. };
  145.  
  146.  
  147. #if    COLOR
  148. /*----------------------------------------------------------------------*/
  149. /*    os2fcol()                            */
  150. /* Set the current foreground color.                    */
  151. /*----------------------------------------------------------------------*/
  152.  
  153. PASCAL NEAR os2fcol(
  154.     int color)            /* color to set */
  155. {
  156.     if (dtype != CDMONO)
  157.         cfcolor = ctrans[color];
  158.     else
  159.         cfcolor = 7;
  160.  
  161.     /* set the normal attribute */
  162.     os2cell.attr &= 0xF0;
  163.     os2cell.attr |= cfcolor;
  164.  
  165.     /* set the reverse attribute */
  166.     os2rcell.attr &= 0x07;
  167.     os2rcell.attr |= cfcolor << 4;    
  168. }
  169.  
  170. /*----------------------------------------------------------------------*/
  171. /*    os2bcol()                            */
  172. /* Set the current background color.                    */
  173. /*----------------------------------------------------------------------*/
  174.  
  175. PASCAL NEAR os2bcol(
  176.     int color)        /* color to set */
  177. {
  178.     if (dtype != CDMONO)
  179.         cbcolor = ctrans[color];
  180.     else
  181.         cbcolor = 0;
  182.  
  183.     /* set normal background attribute */
  184.     os2cell.attr &= 0x0F;
  185.     os2cell.attr |= cbcolor << 4;
  186.  
  187.     /* set reverse background attribute */
  188.     os2rcell.attr &= 0x70;
  189.     os2rcell.attr |= cbcolor;
  190. }
  191. #endif
  192.  
  193.  
  194. /*----------------------------------------------------------------------*/
  195. /*    os2move()                            */
  196. /* Move the cursor.                            */
  197. /*----------------------------------------------------------------------*/
  198.  
  199. PASCAL NEAR os2move(
  200.     int row,
  201.     int col)
  202. {
  203.     os2row = row;
  204.     os2col = col;
  205.     VioSetCurPos(os2row, os2col, 0);
  206. }
  207.  
  208.  
  209. /*----------------------------------------------------------------------*/
  210. /*    os2flush()                            */
  211. /* Update the physical video buffer from the logical video buffer.    */
  212. /*----------------------------------------------------------------------*/
  213.  
  214. PASCAL NEAR os2flush(void)
  215. {
  216.     if (lvbMin <= lvbMax) {        /* did anything change?    */
  217.         VioShowBuf(lvbMin * 2, (lvbMax - lvbMin + 1) * 2, 0);
  218.         VioSetCurPos(os2row, os2col, 0);
  219.     }
  220.     lvbMin = lvbLen;
  221.     lvbMax = 0;
  222. }
  223.  
  224.  
  225. /*----------------------------------------------------------------------*/
  226. /*    os2getc()                            */
  227. /* Get a character from the keyboard.                    */
  228. /* Function keys, editing keys and alt- keys take two consecutive calls    */
  229. /* to os2getc().  The first returns zero and the second returns the    */
  230. /* key's scan code.                            */
  231. /* Nextc holds the scan code until we are called again.            */
  232. /*----------------------------------------------------------------------*/
  233.  
  234. PASCAL NEAR os2getc()
  235. {
  236.     KBDKEYINFO keyInfo;
  237.     static unsigned nextc = -1;  /* -1 when not holding a scan code */
  238.     static unsigned event = -1;  /* -1 when not holding an event byte */
  239.  
  240.     /* holding an extended character code? */
  241.     if (nextc != -1) {
  242.         keyInfo.chChar = (char)(nextc >> 8);    /* prefix byte */
  243.         event = nextc;
  244.         nextc = -1;
  245.         return(keyInfo.chChar);    /* return the prefix code    */
  246.     }
  247.     
  248.     /* holding second byte of an extended character code? */
  249.     if (event != -1) {
  250.         keyInfo.chChar = (char)(event & 255);    /* event code byte */
  251.         event = -1;
  252.         return(keyInfo.chChar);    /* return the event code    */
  253.     }
  254.  
  255.     KbdCharIn(&keyInfo, IO_WAIT, 0);    /* get a character    */
  256.  
  257.     /* Function, edit or alt- key?    */
  258.     if (keyInfo.chChar == 0  ||  keyInfo.chChar == 0xE0) {
  259.         nextc = extcode(keyInfo.chScan); /* hold on to scan code */
  260.         return(0);
  261.     }
  262.     return(keyInfo.chChar & 255);
  263. }
  264.  
  265. #if    TYPEAH
  266. /*----------------------------------------------------------------------*/
  267. /*    typahead()                            */
  268. /* Returns true if a key has been pressed.                */
  269. /*----------------------------------------------------------------------*/
  270.  
  271. PASCAL NEAR typahead()
  272.  
  273. {
  274.     return kbhit();
  275. }
  276. #endif
  277.  
  278.  
  279. /*----------------------------------------------------------------------*/
  280. /*    os2putc()                            */
  281. /* Put a character at the current position in the current colors.    */
  282. /* Note that this does not behave the same as putc() or VioWrtTTy().    */
  283. /* This routine does nothing with returns and linefeeds.  For backspace */
  284. /* it puts a space in the previous column and moves the cursor to the    */
  285. /* previous column.  For all other characters, it will display the    */
  286. /* graphic representation of the character and put the cursor in the    */
  287. /* next column (even if that is off the screen.  In practice this isn't    */
  288. /* a problem.                                */
  289. /*----------------------------------------------------------------------*/
  290.  
  291. PASCAL NEAR os2putc(int c)
  292. {
  293.     USHORT    cell;
  294.     USHORT    i;
  295.  
  296.     if (c == '\n' || c == '\r') {        /* returns and linefeeds */
  297.         return;
  298.     }
  299.     if (c == '\b') {            /* backspace        */
  300.         cell = ' ' | (revflag ? *(USHORT *)&os2rcell : *(USHORT *)&os2cell);
  301.         --os2col;            /* move cursor back    */
  302.         i = os2row * term.t_ncol + os2col;
  303.     }
  304.     else {
  305.         cell = (0x00ff & c) | (revflag ? *(USHORT *)&os2rcell : *(USHORT *)&os2cell);
  306.         i = os2row * term.t_ncol + os2col;
  307.         ++os2col;            /* move cursor forward    */
  308.     }
  309.     lvb[i] = cell;
  310.     if (i < lvbMin)
  311.         lvbMin = i;
  312.     if (i > lvbMax)
  313.         lvbMax = i;
  314. }
  315.  
  316.  
  317. /*----------------------------------------------------------------------*/
  318. /*    os2eeol()                            */
  319. /* Erase to end of line.                        */
  320. /*----------------------------------------------------------------------*/
  321.  
  322. PASCAL NEAR os2eeol()
  323. {
  324.     USHORT    cell = ' ';
  325.     USHORT  i;
  326.  
  327.     cell |= (revflag ? *(USHORT *)&os2rcell : *(USHORT *)&os2cell);
  328.     
  329.     i = os2row * term.t_ncol + os2col;  /* current cursor position    */
  330.     if (i < lvbMin)
  331.         lvbMin = i;
  332.     while (i < os2row * term.t_ncol + term.t_ncol)
  333.         lvb[ i++] = cell;
  334.     if (--i > lvbMax)
  335.         lvbMax = i;
  336. }
  337.  
  338.  
  339. /*----------------------------------------------------------------------*/
  340. /*    os2eeop()                            */
  341. /* Erase to end of page.                        */
  342. /*----------------------------------------------------------------------*/
  343.  
  344. PASCAL NEAR os2eeop()
  345. {
  346.     USHORT    cell = ' ';
  347.     USHORT  i;
  348.  
  349. #if COLOR
  350.     if (dtype != CDMONO)
  351.         cell |= (ctrans[gbcolor] << 4 | ctrans[gfcolor]) << 8;
  352.     else
  353.         cell |= 0x0700;
  354. #else
  355.     cell |= 0x0700;
  356. #endif
  357.  
  358.     i = os2row * term.t_ncol + os2col;  /* current cursor position    */
  359.     if (i < lvbMin)
  360.         lvbMin = i;
  361.     while (i < term.t_nrow * term.t_ncol + term.t_ncol)
  362.         lvb[ i++] = cell;
  363.     if (--i > lvbMax)
  364.         lvbMax = i;
  365. }
  366.  
  367. /*----------------------------------------------------------------------*/
  368. /*    os2rev()                            */
  369. /* Change reverse video state.                      */
  370. /*----------------------------------------------------------------------*/
  371.  
  372. PASCAL NEAR os2rev(state)
  373.  
  374. int state;    /* TRUE = reverse, FALSE = normal */
  375.  
  376. {
  377.     revflag = state;
  378. }
  379.  
  380. /*----------------------------------------------------------------------*/
  381. /*    os2cres()                            */
  382. /* Change the screen resolution.                    */
  383. /*----------------------------------------------------------------------*/
  384.  
  385. PASCAL NEAR os2cres(char *res)        /* name of desired video mode    */
  386. {
  387.     USHORT    err;
  388.     int    type;            /* video mode type    */
  389.     VIOMODEINFO vioModeInfo;
  390.  
  391.     vioModeInfo = initial.vioModeInfo;
  392.     
  393.     /* From the name, find the type of video mode.    */
  394.     for (type = 0; type < NDRIVE; type++) {
  395.         if (strcmp(res, drvname[type]) == 0)
  396.             break;
  397.     }
  398.     if (type == NDRIVE)
  399.         return(FALSE);    /* not a mode we know about    */
  400.  
  401.         
  402.     switch (type) {
  403.         case CDMONO:
  404.         case CDCGA:
  405.             vioModeInfo.row = 25;
  406.             break;
  407.         case CDEGA:
  408.             vioModeInfo.row = 43;
  409.             break;
  410.         case CDVGA:
  411.             vioModeInfo.row = 50;
  412.             break;
  413.     }
  414.     
  415.     if (VioSetMode(&vioModeInfo, 0))    /* change modes     */
  416.         return(FALSE);            /* couldn't do it    */
  417.  
  418.     newsize(TRUE, vioModeInfo.row);
  419.  
  420.     /* reset the $sres environment variable */
  421.     strcpy(sres, drvname[type]);
  422.     dtype = type;                /* set the current mode    */
  423.     
  424.     return TRUE;
  425. }
  426.  
  427.  
  428. /*----------------------------------------------------------------------*/
  429. /*    spal()                                */
  430. /* Change pallette settings.  (Does nothing.)                */
  431. /*----------------------------------------------------------------------*/
  432.  
  433. PASCAL NEAR spal(char *dummy)
  434. {
  435. }
  436.  
  437.  
  438. /*----------------------------------------------------------------------*/
  439. /*    os2beep()                            */
  440. /*----------------------------------------------------------------------*/
  441.  
  442. PASCAL NEAR os2beep()
  443. {
  444.     DosBeep(1200, 175);
  445. }
  446.  
  447.  
  448. /*----------------------------------------------------------------------*/
  449. /*    os2open()                            */
  450. /* Find out what kind of video adapter we have and the current video    */
  451. /* mode.  Even if the adapter supports a higher resolution mode than is */
  452. /* in use, we still use the current mode.                */
  453. /*----------------------------------------------------------------------*/
  454.  
  455. PASCAL NEAR os2open()
  456. {
  457.     initial.vioConfigInfo.cb = 0x0A;
  458.     VioGetConfig(0, &initial.vioConfigInfo, 0);
  459.     switch (initial.vioConfigInfo.adapter) {
  460.         case 3:
  461.             dtype = CDVGA;
  462.             break;
  463.         case 2:
  464.             dtype = CDEGA;
  465.             break;
  466.         case 1:
  467.             dtype = CDCGA;
  468.             break;
  469.         case 0:
  470.         default:
  471.             dtype = CDMONO;
  472.     }
  473.     strcpy(sres, drvname[dtype]);
  474.  
  475.     initial.vioModeInfo.cb = 0x0E;
  476.     VioGetMode(&initial.vioModeInfo, 0);
  477.     newsize(TRUE, initial.vioModeInfo.row);
  478.             
  479.     VioGetAnsi(&initial.ansiState, 0);
  480.     VioGetBuf((PULONG)&lvb, &lvbLen, 0);
  481.     lvbMin = lvbLen;
  482.     lvbMax = 0;
  483.  
  484.     revexist = TRUE;
  485.     revflag = FALSE;
  486. }
  487.  
  488.  
  489. /*----------------------------------------------------------------------*/
  490. /*    os2close()                            */
  491. /* Restore the original video settings.                    */
  492. /*----------------------------------------------------------------------*/
  493.  
  494. PASCAL NEAR os2close()
  495. {
  496.     VioSetAnsi(initial.ansiState, 0);
  497.     VioSetMode(&initial.vioModeInfo, 0);
  498.     VioSetCurPos(initial.vioModeInfo.row - 1,
  499.              initial.vioModeInfo.col - 1, 0);
  500. }
  501.  
  502. /*----------------------------------------------------------------------*/
  503. /*    os2kopen()                            */
  504. /* Open the keyboard.                            */
  505. /*----------------------------------------------------------------------*/
  506.  
  507. PASCAL NEAR os2kopen()
  508. {
  509.     KBDINFO    kbdInfo;
  510.  
  511.     initial.kbdInfo.cb = 0x000A;
  512.     KbdGetStatus(&initial.kbdInfo, 0);    
  513.     kbdInfo = initial.kbdInfo;
  514.     kbdInfo.fsMask &= ~0x0001;        /* not echo on        */
  515.     kbdInfo.fsMask |= 0x0002;        /* echo off        */
  516.     kbdInfo.fsMask &= ~0x0008;        /* cooked mode off    */
  517.     kbdInfo.fsMask |= 0x0004;        /* raw mode        */
  518.     kbdInfo.fsMask &= ~0x0100;        /* shift report    off    */
  519.     KbdSetStatus(&kbdInfo, 0);
  520. }
  521.  
  522.  
  523. /*----------------------------------------------------------------------*/
  524. /*    os2kclose()                            */
  525. /* Close the keyboard.                            */
  526. /*----------------------------------------------------------------------*/
  527.  
  528. PASCAL NEAR os2kclose()
  529. {
  530.     KbdSetStatus(&initial.kbdInfo, 0); /* restore original state    */
  531. }
  532.  
  533. #if    FLABEL
  534. PASCAL NEAR fnclabel(f, n)    /* label a function key */
  535.  
  536. int f,n;    /* default flag, numeric argument [unused] */
  537.  
  538. {
  539.     /* on machines with no function keys...don't bother */
  540.     return(TRUE);
  541. }
  542. #endif
  543.  
  544. #if 0
  545. /*----------------------------------------------------------------------*/
  546. /*    scwrite()                            */
  547. /* Write a line to the screen.
  548. /* I tried using this routine with MEMMAP = 1, but there were too many    */
  549. /* problems with the cursor and flushing the buffer.            */
  550. /*----------------------------------------------------------------------*/
  551.  
  552. scwrite(
  553.     int     row,    /* row of screen to place outstr on */
  554.     char    *outstr,/* string to write out (must be term.t_ncol long) */
  555.     int     forg,    /* foreground color of string to write */
  556.     int     bacg,    /* background color */
  557. {
  558.     USHORT     attr;
  559.     int     i;
  560.  
  561.     attr = (((ctrans[bacg] & 15) << 4) | (forg & 15)) << 8;
  562.  
  563.     for (i = row * term.t_ncol;  i < (row + 1) * term.t_ncol;  i++)
  564.         lvb[i] = attr | *(outstr++);
  565.  
  566.     if (i < lvbMin)
  567.         lvbMin = i;
  568.     if (i > lvbMax)
  569.         lvbMax = i;
  570. }
  571. #endif
  572. #endif
  573.  
  574.