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