home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume2 / window / part2 / hacks.c < prev    next >
Encoding:
C/C++ Source or Header  |  1986-11-30  |  11.5 KB  |  558 lines

  1. /*
  2.  *************
  3.  * DISTRIBUTION NOTICE  July 30 1985
  4.  * A Revised Edition of WM, by Matt Lennon and Tom Truscott,
  5.  *        Research Triangle Institute, (919) 541-7005.
  6.  * Based on the original by Robert Jacob (decvax!nrl-css!jacob),
  7.  *        Naval Research Laboratory, (202) 767-3365.
  8.  * No claims or warranties of any sort are made for this distribution.
  9.  * General permission is granted to copy, but not for profit,
  10.  * any of this distribution, provided that this notice
  11.  * is always included in the copies.
  12.  *************
  13.  */
  14. /*
  15.  * hacks.c
  16.  * curses-package routines missing in one version or another,
  17.  * or corrections for routines in one version or another,
  18.  * or whatever.
  19.  */
  20. #include "wm.h"
  21.  
  22. /*
  23.  * Special redefinitions.  We get right into the dirt here.
  24.  */
  25. #ifndef TERMINFO
  26. #define    _line        _y
  27. #define    chtype        char
  28. #define    _firstchar    _firstch
  29. #define    _lastchar    _lastch
  30. #endif
  31.  
  32. /*
  33.  * Move physical cursor to (y,x).
  34.  * If y is past the end of the screen, scroll the screen up.
  35.  * This is an ugly routine in either version of curses,
  36.  * perhaps because no one worried about this sort of thing.
  37.  * (It would be nice to be able to request 'anywhere on line y',
  38.  * or 'anywhere in column x', since more optimizations are then possible.)
  39.  */
  40. movecursor(y,x)
  41. register int y, x;
  42. {
  43.     if (cursrow() == y && curscol() == x)
  44.     return(0);
  45. #ifdef TERMINFO
  46.     if (y >= LINES) {
  47.     (void) movecursor(y-1,x);
  48.     vidattr(A_NORMAL);
  49.     putp(scroll_forward);
  50.     return(1);
  51.     }
  52.     Untouchwin(stdscr);
  53.     leaveok(stdscr, FALSE);
  54.     wmove(stdscr, y, x);
  55.     wrefresh(stdscr);
  56.     leaveok(stdscr, TRUE);
  57. #else
  58.     /* Couldn't mvcur handle the move_standout_mode problem? */
  59.     if ((curscr->_flags&_STANDOUT) && !move_standout_mode) {
  60.     putp(exit_standout_mode);
  61.     curscr->_flags &= ~_STANDOUT;
  62.     }
  63.     /* speed hack: short circuit mvcur for simple scrolling */
  64.     if (y == LINES && curscol() == x && cursrow()+2 == y && cursor_down) {
  65.     putp(cursor_down);
  66.     putp(scroll_forward);
  67.     }
  68.     else
  69.     mvcur(cursrow(), curscol(), y, x);
  70.     /* Couldn't mvcur update curscr's current (y,x) coordinate? */
  71.     if (y >= LINES)
  72.     y = LINES-1;
  73.     cursrow() = y; curscol() = x;
  74. #endif
  75.     return(1);
  76. }
  77.  
  78. /*
  79.  * Make it appear that every location on the window is unchanged.
  80.  */
  81. untouchwin(wp)
  82. register WINDOW *wp;
  83. {
  84.     register int i;
  85.  
  86.     for (i=0; i<wlines(wp); i++) {
  87.     wp->_firstchar[i] = _NOCHANGE;
  88. #ifdef TERMINFO
  89.     wp->_lastchar[i] = _NOCHANGE;
  90.     wp->_numchngd[i] = 0;
  91. #endif
  92.     }
  93. }
  94.  
  95. /*
  96.  * This is a replacement overwrite() routine for both curses versions.
  97.  * The termcap version is slow and has some minor bugs.
  98.  * The terminfo version aligns the two windows at their origins,
  99.  * rather than on the virtual screen, making it less useful
  100.  * as one cannot use 'mvwin' &etc to paint one window at an
  101.  * arbitrary place on another.
  102.  * Neither version documents what is done with 'standout' information.
  103.  * This version copies the standout information for each character
  104.  * so that a truly identical copy is made, which is handy for painting.
  105.  */
  106. /*********************************************************************
  107. *                         COPYRIGHT NOTICE                           *
  108. **********************************************************************
  109. *        This software is copyright (C) 1982 by Pavel Curtis         *
  110. *                                                                    *
  111. *        Permission is granted to reproduce and distribute           *
  112. *        this file by any means so long as no fee is charged         *
  113. *        above a nominal handling fee and so long as this            *
  114. *        notice is always included in the copies.                    *
  115. *                                                                    *
  116. *        Other rights are reserved except as explicitly granted      *
  117. *        by written permission of the author.                        *
  118. *                Pavel Curtis                                        *
  119. *                Computer Science Dept.                              *
  120. *                405 Upson Hall                                      *
  121. *                Cornell University                                  *
  122. *                Ithaca, NY 14853                                    *
  123. *                                                                    *
  124. *                Ph- (607) 256-4934                                  *
  125. *                                                                    *
  126. *                Pavel.Cornell@Udel-Relay   (ARPAnet)                *
  127. *                decvax!cornell!pavel       (UUCPnet)                *
  128. *********************************************************************/
  129.  
  130. /*
  131. **
  132. **    overwrite(win1, win2)
  133. **
  134. **
  135. **    overwrite() writes win1 on win2 destructively.
  136. **
  137. **/
  138.  
  139. overwrite(win1, win2)
  140. WINDOW    *win1, *win2;
  141. {
  142.     register chtype    *w1ptr, *w2ptr;
  143.     register int col, end_col;
  144.     int line, offset_line, offset_col, start_line, start_col, end_line;
  145.     short   *firstchar, *lastchar;
  146.  
  147. #ifdef TRACE
  148.     if (_tracing)
  149.         _tracef("overwrite(%o, %o) called", win1, win2);
  150. #endif
  151.     
  152.     offset_line = wbegy(win1) - wbegy(win2);
  153.     offset_col = wbegx(win1) - wbegx(win2);
  154.     start_line = MAX(offset_line, 0);
  155.     start_col = MAX(offset_col, 0);
  156.     end_line = offset_line + wlines(win1) - wlines(win2);
  157.     end_line = wlines(win2) + MIN(end_line, 0);
  158.     end_col = offset_col + wcols(win1) - wcols(win2);
  159.     end_col = wcols(win2) + MIN(end_col, 0);
  160.     firstchar = &win2->_firstchar[start_line];
  161.     lastchar = &win2->_lastchar[start_line];
  162.  
  163.     for(line = start_line;  line < end_line;  line++)
  164.     {
  165.         short   fc, lc;
  166.         
  167.         w1ptr = &win1->_line[line-offset_line][start_col-offset_col];
  168.         w2ptr = &win2->_line[line][start_col];
  169.         fc = lc = _NOCHANGE;
  170.  
  171.         for(col = start_col;  col < end_col;  col++)
  172.         {
  173.         if (*w1ptr != *w2ptr)
  174.         {
  175.             *w2ptr = *w1ptr;
  176.             if (fc == _NOCHANGE)
  177.             fc = col;
  178.             lc = col;
  179.         }
  180.  
  181.         w1ptr++;
  182.         w2ptr++;
  183.         }
  184.  
  185.         if (*firstchar == _NOCHANGE)
  186.         {
  187.         *firstchar = fc;
  188.         *lastchar = lc;
  189.         }
  190.         else if (fc != _NOCHANGE)
  191.         {
  192.         if (fc < *firstchar)
  193.             *firstchar = fc;
  194.  
  195.         if (lc > *lastchar)
  196.             *lastchar = lc;
  197.         }
  198.         
  199.         firstchar++;
  200.         lastchar++;
  201.     }
  202. }
  203.  
  204. #ifndef TERMINFO
  205. /*
  206.  * Emulators for terminfo curses procedures.
  207.  */
  208.  
  209. #ifdef SET_WINDOW
  210. /*
  211.  *    tparm.c (Copyright Pavel Curtis, copyright notice above applies)
  212.  */
  213. /*
  214.  *    char *
  215.  *    tparm(string, parms)
  216.  *
  217.  *    Substitute the given parameters into the given string.
  218.  */
  219.  
  220. #define STACKSIZE    20
  221.  
  222. #define npush(x)    if (stack_ptr < STACKSIZE) {stack[stack_ptr].num = x;\
  223.                                                 stack_ptr++;\
  224.                                                }
  225. #define npop()       (stack_ptr > 0  ?  stack[--stack_ptr].num  :  0)
  226. #define spop()       (stack_ptr > 0  ?  stack[--stack_ptr].str  :  (char *) 0)
  227.  
  228. typedef union
  229. {
  230.     unsigned int    num;
  231.     char        *str;
  232. }        stack_frame;
  233.  
  234. stack_frame    stack[STACKSIZE];
  235. static    int    stack_ptr;
  236. static    char    buffer[256];
  237. static    int    *param;
  238. static    char    *bufptr;
  239. static    int    variable[26];
  240.  
  241. /*VARARGS1*/
  242. char *
  243. tparm(string, parms)
  244. char    *string;
  245. int    parms;
  246. {
  247.     char    len;
  248.     int    number;
  249.     int    level;
  250.     int    x, y;
  251.  
  252.     param = &parms;
  253.  
  254.     stack_ptr = 0;
  255.     bufptr = buffer;
  256.  
  257.     while (*string)
  258.     {
  259.         if (*string != '%')
  260.         *(bufptr++) = *string;
  261.         else
  262.         {
  263.         string++;
  264.         switch (*string)
  265.         {
  266.             default:
  267.             break;
  268.  
  269.             case '%':
  270.             *(bufptr++) = '%';
  271.             break;
  272.  
  273.             case 'd':
  274.             (void) sprintf(bufptr, "%d", npop());
  275.             bufptr += strlen(bufptr);
  276.             break;
  277.  
  278.             case '0':
  279.             string++;
  280.             len = *string;
  281.             if ((len == '2'  ||  len == '3')  &&  *++string == 'd')
  282.             {
  283.                 if (len == '2')
  284.                 (void) sprintf(bufptr, "%02d", npop());
  285.                 else
  286.                 (void) sprintf(bufptr, "%03d", npop());
  287.                 
  288.                 bufptr += strlen(bufptr);
  289.             }
  290.             break;
  291.  
  292.             case '2':
  293.             string++;
  294.             if (*string == 'd')
  295.             {
  296.                 (void) sprintf(bufptr, "%2d", npop());
  297.                 bufptr += strlen(bufptr);
  298.             }
  299.             break;
  300.  
  301.             case '3':
  302.             string++;
  303.             if (*string == 'd')
  304.             {
  305.                 (void) sprintf(bufptr, "%3d", npop());
  306.                 bufptr += strlen(bufptr);
  307.             }
  308.             break;
  309.  
  310.             case 'c':
  311.             *(bufptr++) = (char) npop();
  312.             break;
  313.  
  314.             case 's':
  315.             strcpy(bufptr, spop());
  316.             bufptr += strlen(bufptr);
  317.             break;
  318.  
  319.             case 'p':
  320.             string++;
  321.             if (*string >= '1'  &&  *string <= '9')
  322.                 npush(param[*string - '1']);
  323.             break;
  324.  
  325.             case 'P':
  326.             string++;
  327.             if (*string >= 'a'  &&  *string <= 'z')
  328.                 variable[*string - 'a'] = npop();
  329.             break;
  330.  
  331.             case 'g':
  332.             string++;
  333.             if (*string >= 'a'  &&  *string <= 'z')
  334.                 npush(variable[*string - 'a']);
  335.             break;
  336.  
  337.             case '\'':
  338.             string++;
  339.             npush(*string);
  340.             string++;
  341.             break;
  342.  
  343.             case '{':
  344.             number = 0;
  345.             string++;
  346.             while (*string >= '0'  &&  *string <= '9')
  347.             {
  348.                 number = number * 10 + *string - '0';
  349.                 string++;
  350.             }
  351.             npush(number);
  352.             break;
  353.  
  354.             case '+':
  355.             y = npop();
  356.             x = npop();
  357.             npush(x + y);
  358.             break;
  359.  
  360.             case '-':
  361.             y = npop();
  362.             x = npop();
  363.             npush(x - y);
  364.             break;
  365.  
  366.             case '*':
  367.             y = npop();
  368.             x = npop();
  369.             npush(x * y);
  370.             break;
  371.  
  372.             case '/':
  373.             y = npop();
  374.             x = npop();
  375.             npush(x / y);
  376.             break;
  377.  
  378.             case 'm':
  379.             y = npop();
  380.             x = npop();
  381.             npush(x % y);
  382.             break;
  383.  
  384.             case '&':
  385.             y = npop();
  386.             x = npop();
  387.             npush(x & y);
  388.             break;
  389.  
  390.             case '|':
  391.             y = npop();
  392.             x = npop();
  393.             npush(x | y);
  394.             break;
  395.  
  396.             case '^':
  397.             y = npop();
  398.             x = npop();
  399.             npush(x ^ y);
  400.             break;
  401.  
  402.             case '=':
  403.             y = npop();
  404.             x = npop();
  405.             npush(x == y);
  406.             break;
  407.  
  408.             case '<':
  409.             y = npop();
  410.             x = npop();
  411.             npush(x < y);
  412.             break;
  413.  
  414.             case '>':
  415.             y = npop();
  416.             x = npop();
  417.             npush(x > y);
  418.             break;
  419.  
  420.             case '!':
  421.             x = npop();
  422.             npush(! x);
  423.             break;
  424.  
  425.             case '~':
  426.             x = npop();
  427.             npush(~ x);
  428.             break;
  429.  
  430.             case 'i':
  431.             param[0]++;
  432.             param[1]++;
  433.             break;
  434.  
  435.             case '?':
  436.             break;
  437.  
  438.             case 't':
  439.             x = npop();
  440.             if (x)
  441.             {
  442.                 /* do nothing; keep executing */
  443.             }
  444.             else
  445.             {
  446.                 /* scan forward for %e or %; at level zero */
  447.                 string++;
  448.                 level = 0;
  449.                 while (*string)
  450.                 {
  451.                     if (*string == '%')
  452.                     {
  453.                     string++;
  454.                     if (*string == '?')
  455.                         level++;
  456.                     else if (*string == ';')
  457.                     {
  458.                         if (level > 0)
  459.                         level--;
  460.                         else
  461.                         break;
  462.                     }
  463.                     else if (*string == 'e'  && level == 0)
  464.                         break;
  465.                     }
  466.  
  467.                     if (*string)
  468.                     string++;
  469.                 }
  470.             }
  471.             break;
  472.  
  473.             case 'e':
  474.             /* scan forward for a %; at level zero */
  475.                 string++;
  476.                 level = 0;
  477.                 while (*string)
  478.                 {
  479.                 if (*string == '%')
  480.                 {
  481.                     string++;
  482.                     if (*string == '?')
  483.                     level++;
  484.                     else if (*string == ';')
  485.                     {
  486.                     if (level > 0)
  487.                         level--;
  488.                     else
  489.                         break;
  490.                     }
  491.                 }
  492.  
  493.                 if (*string)
  494.                     string++;
  495.                 }
  496.             break;
  497.  
  498.             case ';':
  499.             break;
  500.  
  501.         } /* endswitch (*string) */
  502.         } /* endelse (*string == '%') */
  503.  
  504.         if (*string == '\0')
  505.         break;
  506.         
  507.         string++;
  508.     } /* endwhile (*string) */
  509.  
  510.     *bufptr = '\0';
  511.     return(buffer);
  512. }
  513. #endif
  514.  
  515. /*
  516.  * Ring Bell.
  517.  */
  518. beep()
  519. {
  520.     putchar('\007');
  521. }
  522.  
  523. /*
  524.  * 'Ring' visual bell if available, otherwise audible bell.
  525.  */
  526. flash()
  527. {
  528.     /* If you get a syntax error on this routine,
  529.      * you are not using the new curses.h!  Put
  530.      * it in this directory or in /usr/include (saving the old one).
  531.      * And double check that you are linking with the new libcurses.a
  532.      */
  533.     if (flash_screen)
  534.     putp(flash_screen);
  535.     else
  536.     beep();
  537. }
  538.  
  539. /*
  540.  * Return the baud rate of the current terminal.
  541.  */
  542. baudrate()
  543. {
  544. #ifdef    B9600
  545.     if (_tty.sg_ospeed >= B9600)
  546.     return(9600);
  547. #endif
  548. #ifdef    B4800
  549.     if (_tty.sg_ospeed >= B4800)
  550.     return(4800);
  551. #endif
  552.     return(1200);
  553. }
  554.  
  555. erasechar() { return(_tty.sg_erase); }
  556. killchar() { return(_tty.sg_kill); }
  557. #endif
  558.