home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: Science / Science.zip / OS2SCALC.ZIP / CURS.C < prev    next >
C/C++ Source or Header  |  1990-07-20  |  13KB  |  701 lines

  1. /**********************************************************************
  2.  *
  3.  * Tiny pseudo "curses" package (runs on U__X, VMS, OS2, or MCH_AMIGA)
  4.  *
  5.  *    v1.0    870117    DBW - D. Wecker, initial hack
  6.  *  OS/2 Modifications by Brady Flowers, 7/19/90
  7.  *
  8.  **********************************************************************/
  9.  
  10. /* ----------------------------------------------------------------------- */
  11.  
  12. #ifdef VMS
  13. #include <stsdef.h>
  14. #include <ssdef.h>
  15. #include <descrip.h>
  16. #include <iodef.h>
  17. #include <ttdef.h>
  18.  
  19. #define NIBUF   128        /* Input buffer size */
  20. #define NOBUF   1024        /* MM says bug buffers win! */
  21. #define EFN     0        /* Event flag */
  22.  
  23. char obuf[NOBUF];        /* Output buffer */
  24. int nobuf;            /* # of bytes in above */
  25. char ibuf[NIBUF];        /* Input buffer */
  26. int nibuf;            /* # of bytes in above */
  27. int ibufi;            /* Read index */
  28. int oldmode[2];            /* Old TTY mode bits */
  29. int newmode[2];            /* New TTY mode bits */
  30. short iochan;            /* TTY I/O channel */
  31. struct dsc$descriptor  idsc;
  32. struct dsc$descriptor  odsc;
  33. char oname[40];
  34. int iosb[2];
  35. int term[2];
  36. int status;
  37. #endif
  38.  
  39. /* ----------------------------------------------------------------------- */
  40.  
  41. #ifdef MCH_AMIGA
  42. extern    char        *Open();
  43. extern    long        Read(),Write();
  44. extern    void        Close();
  45. #define NEW        1006L
  46. #define AMG_MAXBUF    1024
  47. static char        *terminal = 0L;
  48. static char        scrn_tmp[AMG_MAXBUF+1];
  49. static long        scrn_tmp_p = 0L;
  50. #endif
  51.  
  52. /* ----------------------------------------------------------------------- */
  53.  
  54. #ifdef U__X
  55. #include <sys/ioctl.h>
  56. #include <sgtty.h>
  57. #include <stdio.h>
  58. struct sgttyb old_tty,new_tty;
  59. #endif
  60.  
  61. /* ----------------------------------------------------------------------- */
  62.  
  63. #ifdef OS2
  64. #include <stdio.h>
  65. #include <stdlib.h>
  66. #include <string.h>
  67. #include <stdarg.h>
  68. #include <conio.h>
  69. #define INCL_KBD
  70. #define INCL_VIO
  71. #include <os2.h>
  72. #define CURS_C
  73. #include "curs.h"
  74. #endif
  75.  
  76. /* ----------------------------------------------------------------------- */
  77.  
  78. #define NORMAL    0x00
  79. #define BOLD      0x80
  80.  
  81. #ifndef OS2
  82. char    nscrn[ROWS][COLS],
  83.     cscrn[ROWS][COLS],
  84.     row,
  85.     col,
  86.     mode;
  87. #else
  88. typedef char SCRN[COLS];
  89. SCRN *nscrn;
  90. SCRN *cscrn;
  91. char row, col, mode;
  92. USHORT usRow = 0, usCol = 0;
  93. BYTE bNormAttr = 0x07;
  94. BYTE bBoldAttr = 0x70;
  95. BYTE cell[2];
  96. #endif
  97.  
  98. char    str[256];
  99.  
  100. /* ----------------------------------------------------------------------- */
  101.  
  102. #ifdef OS2
  103.  
  104. /* OS/2 version, discover screen size, set raw keyboard mode,
  105.  * move the cursor, clear the screen, and get keystrokes
  106.  */
  107.  
  108. static void SetOS2Scr(void);
  109. static void AdvanceCurs(void);
  110. static void GetOS2Curs(void);
  111. static void SetOS2Curs(int r, int c);
  112. static void ClsOS2(void);
  113.  
  114. static void SetOS2Kbd(void);
  115. static int  GetOS2Key(void);
  116.  
  117. static int curmode(void);
  118.  
  119.  
  120. static void SetOS2Scr()
  121. {
  122.   VIOMODEINFO viomi;
  123.  
  124.   if (!fRemote)
  125.   {
  126.     VioGetMode(&viomi, 0);
  127.     PCrows = viomi.row - 1;
  128.   }
  129. }
  130.  
  131.  
  132. static void AdvanceCurs()
  133. {
  134.  
  135.   if (++usCol == COLS)
  136.   {
  137.     usCol = 0;
  138.     if (++usRow == ROWS)
  139.     {
  140.       --usRow;
  141.       cell[0] = ' ';
  142.       cell[1] = mode == BOLD ? bBoldAttr : bNormAttr;
  143.       VioScrollUp(0, 0, 0xffff, 0xffff, 1, cell, 0);
  144.     }
  145.   }
  146.   VioSetCurPos(usRow, usCol, 0);
  147. }
  148.  
  149.  
  150. static void GetOS2Curs()
  151. {
  152.  
  153.   VioGetCurPos(&usRow, &usCol, 0);
  154. }
  155.  
  156.  
  157. static void SetOS2Curs(int r, int c)
  158. {
  159.  
  160.   if (fRemote)
  161.   {
  162.         sprintf(str,"\033[%d;%dH", r+1, c+1);
  163.         fputs(str, stdout);
  164.   }
  165.   else
  166.     VioSetCurPos(usRow = r, usCol = c, 0);
  167. }
  168.  
  169.  
  170. static void ClsOS2(void)
  171. {
  172.  
  173.   if (fRemote)
  174.     fputs("\033[2J", stdout);
  175.   else
  176.   {
  177.     cell[0] = ' ';
  178.     cell[1] = mode == BOLD ? bBoldAttr : bNormAttr;
  179.     VioScrollUp(0, 0, 0xffff, 0xffff, 0xffff, cell, 0);
  180.     VioSetCurPos(usRow = 0, usCol = 0, 0);
  181.   }
  182. }
  183.  
  184.  
  185.  
  186.  
  187. static void SetOS2Kbd()
  188. {
  189.   KBDINFO kbstInfo;
  190.  
  191.   if (!fRemote)
  192.   {
  193.     kbstInfo.cb = sizeof(kbstInfo);
  194.     KbdGetStatus(&kbstInfo, 0);        /* gets current status  */
  195.     kbstInfo.fsMask =
  196.         (kbstInfo.fsMask & 0x00F7)     /* masks out ASCII mode */
  197.         | 0x0004;                      /* OR into binary mode  */
  198.     KbdSetStatus(&kbstInfo, 0);        /* sets new status      */
  199.   }
  200. }
  201.  
  202. #define EXT_KEY 224
  203. #define STDIN   0
  204.  
  205. static int GetOS2Key()
  206. {
  207.   static USHORT     pending = 0;
  208.   static KBDKEYINFO kbdi;
  209.  
  210.   if (fRemote)
  211.   {
  212.     DosRead(STDIN, &(kbdi.chChar), 1, &pending);
  213.     return kbdi.chChar;
  214.   }
  215.  
  216.   // Else, local keyboard
  217.   if (pending)
  218.   {
  219.     pending = 0;
  220.     return kbdi.chScan;
  221.   }
  222.  
  223.   KbdCharIn(&kbdi, IO_WAIT, 0);
  224.   if (kbdi.chChar == 0 || kbdi.chChar == EXT_KEY)
  225.   {
  226.     pending = 1;
  227.     return 0;
  228.   }
  229.   return kbdi.chChar;
  230. }
  231.  
  232. #else
  233. #define VOID
  234. #endif
  235.  
  236.  
  237. VOID move(y,x)
  238. int y,x;
  239. {
  240.   row = (char)y;
  241.   col = (char)x;
  242. }
  243.  
  244.  
  245.  
  246. VOID clrtoeol()
  247. {
  248.   int i;
  249.  
  250.   for (i = col; i < COLS; i++) nscrn[row][i] = (char)' ' | mode;
  251. }
  252.  
  253.  
  254.  
  255. #ifdef OS2
  256.  
  257. VOID printw(char *fmt, ... )
  258. {
  259.   va_list args;
  260.  
  261.   va_start(args, fmt);
  262.   vprintw(fmt, args);
  263. }
  264.  
  265.  
  266. VOID vprintw(char *fmt, void *args)
  267. {
  268.   int i,j;
  269.  
  270.   vsprintf(str, fmt, (va_list)args);
  271.   j = 0;
  272.   for (i = col; i < COLS && str[j] != '\000'; i++)
  273.       nscrn[row][i] = str[j++] | mode;
  274.   col = (char)i;
  275. }
  276.  
  277. #else
  278.  
  279. VOID printw(fmt,a1,a2,a3,a4,a5)
  280. char    *fmt,*a1,*a2,*a3,*a4,*a5;
  281. {
  282.   int i,j;
  283.  
  284.   sprintf(str,fmt,a1,a2,a3,a4,a5);
  285.   j = 0;
  286.   for (i = col; i < COLS && str[j] != '\000'; i++)
  287.       nscrn[row][i] = str[j++] | mode;
  288.   col = i;
  289. }
  290.  
  291. #endif
  292.  
  293.  
  294.  
  295. VOID clrtobot()
  296. {
  297.   int i,j;
  298.  
  299.   clrtoeol();
  300.   for (i = row+1; i < ROWS; i++)
  301.       for (j = 0; j < COLS; j++)
  302.         nscrn[i][j] = (char)' ' | mode;
  303. }
  304.  
  305.  
  306.  
  307. VOID standout()
  308. {
  309.  
  310.   mode = BOLD;
  311. }
  312.  
  313.  
  314.  
  315. VOID standend()
  316. {
  317.  
  318.   mode = NORMAL;
  319. }
  320.  
  321.  
  322.  
  323. static int curmode()
  324. {
  325.  
  326.   return mode;
  327. }
  328.  
  329.  
  330. VOID addstr(s)
  331. char    *s;
  332. {
  333.   printw("%s",s);
  334. }
  335.  
  336.  
  337.  
  338. VOID initscr()
  339. {
  340.   int        i,j;
  341.  
  342. #ifdef MCH_AMIGA
  343.   terminal = Open("RAW:1/1/639/199/DBW_VC (v1.0 870117)",(long)NEW);
  344. #endif
  345.  
  346. #ifdef VMS
  347.     odsc.dsc$a_pointer = "TT";
  348.     odsc.dsc$w_length = strlen(odsc.dsc$a_pointer);
  349.     odsc.dsc$b_dtype = DSC$K_DTYPE_T;
  350.     odsc.dsc$b_class = DSC$K_CLASS_S;
  351.     idsc.dsc$b_dtype = DSC$K_DTYPE_T;
  352.     idsc.dsc$b_class = DSC$K_CLASS_S;
  353.     do {
  354.     idsc.dsc$a_pointer = odsc.dsc$a_pointer;
  355.     idsc.dsc$w_length = odsc.dsc$w_length;
  356.     odsc.dsc$a_pointer = &oname[0];
  357.     odsc.dsc$w_length = sizeof(oname);
  358.     status = LIB$SYS_TRNLOG(&idsc, &odsc.dsc$w_length, &odsc);
  359.     if (status!=SS$_NORMAL && status!=SS$_NOTRAN) exit(status);
  360.     if (oname[0] == 0x1B) {
  361.         odsc.dsc$a_pointer += 4;
  362.         odsc.dsc$w_length -= 4;
  363.         }
  364.     }
  365.     while (status == SS$_NORMAL);
  366.     status = SYS$ASSIGN(&odsc, &iochan, 0, 0);
  367.     if (status != SS$_NORMAL) exit(status);
  368.     status = SYS$QIOW(EFN, iochan, IO$_SENSEMODE, iosb, 0, 0,
  369.         oldmode, sizeof(oldmode), 0, 0, 0, 0);
  370.     if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL) exit(status);
  371.     newmode[0] = oldmode[0];
  372.     newmode[1] = oldmode[1] | TT$M_PASSALL | TT$M_NOECHO;
  373.     status = SYS$QIOW(EFN, iochan, IO$_SETMODE, iosb, 0, 0,
  374.         newmode, sizeof(newmode), 0, 0, 0, 0);
  375.     if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL) exit(status);
  376. #endif
  377.  
  378. #ifdef U__X
  379.     ioctl(0,TIOCGETP,&old_tty);
  380.     ioctl(0,TIOCGETP,&new_tty);
  381.     new_tty.sg_flags |= RAW;
  382.     new_tty.sg_flags &= ~ECHO;
  383.     ioctl(0,TIOCSETP,&new_tty);
  384. #endif
  385.  
  386. #ifdef OS2
  387.   SetOS2Kbd();
  388.   SetOS2Scr();
  389.   nscrn = malloc(sizeof(char) * COLS * ROWS);
  390.   cscrn = malloc(sizeof(char) * COLS * ROWS);
  391. #endif
  392.  
  393.   row        = 0;
  394.   col        = 0;
  395.   mode    = NORMAL;
  396.   for (i = 0; i < ROWS; i++)
  397.       for (j = 0; j < COLS; j++)
  398.         nscrn[i][j] = cscrn[i][j] = ' ';
  399.  
  400. #ifdef OS2
  401.   ClsOS2();
  402. #else
  403.   ttputs("\033[2J");
  404. #endif
  405. }
  406.  
  407.  
  408.  
  409. VOID clear()
  410. {
  411.  
  412.   row = 0;
  413.   col = 0;
  414.   clrtobot();
  415. }
  416.  
  417.  
  418.  
  419. VOID endwin()
  420. {
  421.  
  422.   move(ROWS-1,0);
  423.   refresh();
  424.  
  425. #ifdef MCH_AMIGA
  426.     amg_flush();
  427.     Close(terminal);
  428. #endif
  429.  
  430. #ifdef VMS
  431.     status = SYS$QIOW(EFN, iochan, IO$_SETMODE, iosb, 0, 0,
  432.         oldmode, sizeof(oldmode), 0, 0, 0, 0);
  433.     if (status!=SS$_NORMAL || (iosb[0]&0xFFFF)!=SS$_NORMAL) exit(status);
  434.     status = SYS$DASSGN(iochan);
  435.     if (status != SS$_NORMAL) exit(status);
  436. #endif
  437.  
  438. #ifdef U__X
  439.     ioctl(0,TIOCSETP,&old_tty);
  440. #endif
  441.  
  442. }
  443.  
  444.  
  445.  
  446. char inch()
  447. {
  448.  
  449.   return(nscrn[row][col] & 0x7F);
  450. }
  451.  
  452.  
  453.  
  454. VOID touchwin()
  455. {
  456.   int i,j;
  457.  
  458.   for (i=0; i<ROWS; i++)
  459.       for (j=0; j<COLS; j++)
  460.         cscrn[i][j] = ' ';
  461.  
  462. #ifdef OS2
  463.   ClsOS2();
  464. #else
  465.   ttputs("\033[2J");
  466. #endif
  467. }
  468.  
  469.  
  470.  
  471. VOID refresh()
  472. {
  473.   int    i,j,mode,savemode,curpos;
  474.  
  475.   mode = NORMAL;
  476. #ifdef OS2
  477.   if ((savemode = curmode()) == BOLD) standend();
  478.   GetOS2Curs();
  479. #endif
  480.   for (i=0; i < ROWS; i++)
  481.   {
  482.       curpos = -1;
  483.       for (j = 0; j < COLS; j++)
  484.     {
  485.         if (nscrn[i][j] != cscrn[i][j])
  486.       {
  487.             if (curpos == -1)
  488.         {
  489. #ifdef OS2
  490.           SetOS2Curs(i, j);
  491. #else
  492.               sprintf(str,"\033[%d;%dH",i+1,j+1);
  493.               ttputs(str);
  494. #endif
  495.               curpos = j;
  496.             }
  497.             else
  498.         {
  499. #ifdef OS2
  500.           if (fRemote)
  501.           {
  502.                 sprintf(str,"\033[%dC",j-curpos);
  503.             fputs(str, stdout);
  504.           }
  505.           else
  506.             SetOS2Curs(i, j);
  507. #else
  508.               sprintf(str,"\033[%dC",j-curpos);
  509.               ttputs(str);
  510. #endif
  511.               curpos = j;
  512.             }
  513.  
  514.             while (nscrn[i][j] != cscrn[i][j])
  515.         {
  516.               if (mode == NORMAL && (nscrn[i][j] & BOLD) == BOLD)
  517.           {
  518. #ifdef OS2
  519.             if (fRemote)
  520.                     ttputs("\033[7m");
  521.             else
  522.               standout();
  523.                   mode = BOLD;
  524. #else
  525.                   ttputs("\033[7m");
  526.                   mode = BOLD;
  527. #endif
  528.                 }
  529.               else if (mode == BOLD && (nscrn[i][j] & BOLD) == NORMAL)
  530.           {
  531. #ifdef OS2
  532.             if (fRemote)
  533.                     ttputs("\033[0m");
  534.             else
  535.               standend();
  536.                   mode = NORMAL;
  537. #else
  538.                   ttputs("\033[0m");
  539.                   mode = NORMAL;
  540. #endif
  541.                 }
  542.               cscrn[i][j] = nscrn[i][j];
  543.               ttputc(nscrn[i][j] & 0x7F);
  544.               curpos++;
  545.               j++;
  546.           }
  547.           }
  548.     }
  549.   }
  550. #ifdef OS2
  551.   SetOS2Curs(row, col);
  552.   if (mode && fRemote) fputs("\033[0m", stdout);
  553.   if (mode != savemode)
  554.   {
  555.     if (savemode == NORMAL)
  556.       standend();
  557.     else
  558.       standout();
  559.   }
  560. #else
  561.   sprintf(str,"\033[%d;%dH",row+1,col+1);
  562.   ttputs(str);
  563.   if (mode) ttputs("\033[0m");
  564. #endif
  565.   ttflush();
  566. }
  567.  
  568.  
  569.  
  570. int ttgetc()
  571. {
  572.  
  573. #ifdef MCH_AMIGA
  574.     unsigned char ch[2];
  575.  
  576.     Read(terminal, ch, 1L);
  577.     return (ch[0] & 0xFF);
  578. #endif
  579.  
  580. #ifdef VMS
  581.     while (ibufi >= nibuf) {
  582.     ibufi = 0;
  583.     term[0] = 0;
  584.     term[1] = 0;
  585.     status = SYS$QIOW(EFN, iochan, IO$_READLBLK|IO$M_TIMED,
  586.     iosb, 0, 0, ibuf, NIBUF, 0, term, 0, 0);
  587.     if (status != SS$_NORMAL) exit(status);
  588.     status = iosb[0] & 0xFFFF;
  589.     if (status!=SS$_NORMAL && status!=SS$_TIMEOUT) exit(status);
  590.     nibuf = (iosb[0]>>16) + (iosb[1]>>16);
  591.     if (nibuf == 0) {
  592.         status = SYS$QIOW(EFN, iochan, IO$_READLBLK,
  593.         iosb, 0, 0, ibuf, 1, 0, term, 0, 0);
  594.         if (status != SS$_NORMAL || (status = (iosb[0]&0xFFFF)) != SS$_NORMAL)
  595.         exit(status);
  596.         nibuf = (iosb[0]>>16) + (iosb[1]>>16);
  597.         }
  598.     }
  599.     return (ibuf[ibufi++] & 0x7F);
  600. #endif
  601.  
  602. #ifdef U__X
  603.     return(getchar() & 0x7F);
  604. #endif
  605.  
  606. #ifdef OS2
  607.     return (GetOS2Key() & 0x7f);
  608. #endif
  609. }
  610.  
  611.  
  612.  
  613. VOID ttputc(c)
  614. #ifdef MCH_AMIGA
  615. char c;
  616. #endif
  617. {
  618.  
  619. #ifdef MCH_AMIGA
  620.   scrn_tmp[scrn_tmp_p++] = c;
  621.   if(scrn_tmp_p>=AMG_MAXBUF) amg_flush();
  622. #endif
  623.  
  624. #ifdef VMS
  625.   if (nobuf >= NOBUF) ttflush();
  626.   obuf[nobuf++] = c;
  627. #endif
  628.  
  629. #ifdef U__X
  630.   fputc(c, stdout);
  631. #endif
  632.  
  633. #ifdef OS2
  634.   if (fRemote)
  635.     fputc(c, stdout);
  636.   else
  637.   {
  638.     cell[0] = (BYTE)c;
  639.     cell[1] = mode != NORMAL ? bBoldAttr : bNormAttr;
  640.     VioWrtNCell(cell, 1, usRow, usCol, 0);
  641.     AdvanceCurs();
  642.   }
  643. #endif
  644. }
  645.  
  646.  
  647.  
  648. #ifdef MCH_AMIGA
  649. amg_flush()
  650.     {
  651.     if(scrn_tmp_p) Write(terminal,scrn_tmp,(long)scrn_tmp_p);
  652.     scrn_tmp_p = 0;
  653.     }
  654. #endif
  655.  
  656.  
  657.  
  658. VOID ttputs(s)
  659. char    *s;
  660. {
  661.  
  662.   while (*s) ttputc(*s++);
  663. }
  664.  
  665.  
  666.  
  667. #ifdef VMS
  668. int ttflush()
  669. #else
  670. VOID ttflush()
  671. #endif
  672. {
  673.  
  674. #ifdef MCH_AMIGA
  675.   amg_flush();
  676. #endif
  677.  
  678. #ifdef VMS
  679.   status = SS$_NORMAL;
  680.   if (nobuf != 0)
  681.   {
  682.       status = SYS$QIOW(EFN, iochan, IO$_WRITELBLK|IO$M_NOFORMAT,
  683.       iosb, 0, 0, obuf, nobuf, 0, 0, 0, 0);
  684.       if (status == SS$_NORMAL) status = iosb[0] & 0xFFFF;
  685.       nobuf = 0;
  686.     }
  687.   return (status);
  688. #endif
  689.  
  690. #ifdef U__X
  691.   fflush(stdout);
  692. #endif
  693.  
  694. #ifdef OS2
  695.   if (fRemote)
  696.     fflush(stdout);
  697. #endif
  698. }
  699.  
  700.  
  701.