home *** CD-ROM | disk | FTP | other *** search
- /*
- *************
- * DISTRIBUTION NOTICE July 30 1985
- * A Revised Edition of WM, by Matt Lennon and Tom Truscott,
- * Research Triangle Institute, (919) 541-7005.
- * Based on the original by Robert Jacob (decvax!nrl-css!jacob),
- * Naval Research Laboratory, (202) 767-3365.
- * No claims or warranties of any sort are made for this distribution.
- * General permission is granted to copy, but not for profit,
- * any of this distribution, provided that this notice
- * is always included in the copies.
- *************
- */
- /*
- * hacks.c
- * curses-package routines missing in one version or another,
- * or corrections for routines in one version or another,
- * or whatever.
- */
- #include "wm.h"
-
- /*
- * Special redefinitions. We get right into the dirt here.
- */
- #ifndef TERMINFO
- #define _line _y
- #define chtype char
- #define _firstchar _firstch
- #define _lastchar _lastch
- #endif
-
- /*
- * Move physical cursor to (y,x).
- * If y is past the end of the screen, scroll the screen up.
- * This is an ugly routine in either version of curses,
- * perhaps because no one worried about this sort of thing.
- * (It would be nice to be able to request 'anywhere on line y',
- * or 'anywhere in column x', since more optimizations are then possible.)
- */
- movecursor(y,x)
- register int y, x;
- {
- if (cursrow() == y && curscol() == x)
- return(0);
- #ifdef TERMINFO
- if (y >= LINES) {
- (void) movecursor(y-1,x);
- vidattr(A_NORMAL);
- putp(scroll_forward);
- return(1);
- }
- Untouchwin(stdscr);
- leaveok(stdscr, FALSE);
- wmove(stdscr, y, x);
- wrefresh(stdscr);
- leaveok(stdscr, TRUE);
- #else
- /* Couldn't mvcur handle the move_standout_mode problem? */
- if ((curscr->_flags&_STANDOUT) && !move_standout_mode) {
- putp(exit_standout_mode);
- curscr->_flags &= ~_STANDOUT;
- }
- /* speed hack: short circuit mvcur for simple scrolling */
- if (y == LINES && curscol() == x && cursrow()+2 == y && cursor_down) {
- putp(cursor_down);
- putp(scroll_forward);
- }
- else
- mvcur(cursrow(), curscol(), y, x);
- /* Couldn't mvcur update curscr's current (y,x) coordinate? */
- if (y >= LINES)
- y = LINES-1;
- cursrow() = y; curscol() = x;
- #endif
- return(1);
- }
-
- /*
- * Make it appear that every location on the window is unchanged.
- */
- untouchwin(wp)
- register WINDOW *wp;
- {
- register int i;
-
- for (i=0; i<wlines(wp); i++) {
- wp->_firstchar[i] = _NOCHANGE;
- #ifdef TERMINFO
- wp->_lastchar[i] = _NOCHANGE;
- wp->_numchngd[i] = 0;
- #endif
- }
- }
-
- /*
- * This is a replacement overwrite() routine for both curses versions.
- * The termcap version is slow and has some minor bugs.
- * The terminfo version aligns the two windows at their origins,
- * rather than on the virtual screen, making it less useful
- * as one cannot use 'mvwin' &etc to paint one window at an
- * arbitrary place on another.
- * Neither version documents what is done with 'standout' information.
- * This version copies the standout information for each character
- * so that a truly identical copy is made, which is handy for painting.
- */
- /*********************************************************************
- * COPYRIGHT NOTICE *
- **********************************************************************
- * This software is copyright (C) 1982 by Pavel Curtis *
- * *
- * Permission is granted to reproduce and distribute *
- * this file by any means so long as no fee is charged *
- * above a nominal handling fee and so long as this *
- * notice is always included in the copies. *
- * *
- * Other rights are reserved except as explicitly granted *
- * by written permission of the author. *
- * Pavel Curtis *
- * Computer Science Dept. *
- * 405 Upson Hall *
- * Cornell University *
- * Ithaca, NY 14853 *
- * *
- * Ph- (607) 256-4934 *
- * *
- * Pavel.Cornell@Udel-Relay (ARPAnet) *
- * decvax!cornell!pavel (UUCPnet) *
- *********************************************************************/
-
- /*
- **
- ** overwrite(win1, win2)
- **
- **
- ** overwrite() writes win1 on win2 destructively.
- **
- **/
-
- overwrite(win1, win2)
- WINDOW *win1, *win2;
- {
- register chtype *w1ptr, *w2ptr;
- register int col, end_col;
- int line, offset_line, offset_col, start_line, start_col, end_line;
- short *firstchar, *lastchar;
-
- #ifdef TRACE
- if (_tracing)
- _tracef("overwrite(%o, %o) called", win1, win2);
- #endif
-
- offset_line = wbegy(win1) - wbegy(win2);
- offset_col = wbegx(win1) - wbegx(win2);
- start_line = MAX(offset_line, 0);
- start_col = MAX(offset_col, 0);
- end_line = offset_line + wlines(win1) - wlines(win2);
- end_line = wlines(win2) + MIN(end_line, 0);
- end_col = offset_col + wcols(win1) - wcols(win2);
- end_col = wcols(win2) + MIN(end_col, 0);
- firstchar = &win2->_firstchar[start_line];
- lastchar = &win2->_lastchar[start_line];
-
- for(line = start_line; line < end_line; line++)
- {
- short fc, lc;
-
- w1ptr = &win1->_line[line-offset_line][start_col-offset_col];
- w2ptr = &win2->_line[line][start_col];
- fc = lc = _NOCHANGE;
-
- for(col = start_col; col < end_col; col++)
- {
- if (*w1ptr != *w2ptr)
- {
- *w2ptr = *w1ptr;
- if (fc == _NOCHANGE)
- fc = col;
- lc = col;
- }
-
- w1ptr++;
- w2ptr++;
- }
-
- if (*firstchar == _NOCHANGE)
- {
- *firstchar = fc;
- *lastchar = lc;
- }
- else if (fc != _NOCHANGE)
- {
- if (fc < *firstchar)
- *firstchar = fc;
-
- if (lc > *lastchar)
- *lastchar = lc;
- }
-
- firstchar++;
- lastchar++;
- }
- }
-
- #ifndef TERMINFO
- /*
- * Emulators for terminfo curses procedures.
- */
-
- #ifdef SET_WINDOW
- /*
- * tparm.c (Copyright Pavel Curtis, copyright notice above applies)
- */
- /*
- * char *
- * tparm(string, parms)
- *
- * Substitute the given parameters into the given string.
- */
-
- #define STACKSIZE 20
-
- #define npush(x) if (stack_ptr < STACKSIZE) {stack[stack_ptr].num = x;\
- stack_ptr++;\
- }
- #define npop() (stack_ptr > 0 ? stack[--stack_ptr].num : 0)
- #define spop() (stack_ptr > 0 ? stack[--stack_ptr].str : (char *) 0)
-
- typedef union
- {
- unsigned int num;
- char *str;
- } stack_frame;
-
- stack_frame stack[STACKSIZE];
- static int stack_ptr;
- static char buffer[256];
- static int *param;
- static char *bufptr;
- static int variable[26];
-
- /*VARARGS1*/
- char *
- tparm(string, parms)
- char *string;
- int parms;
- {
- char len;
- int number;
- int level;
- int x, y;
-
- param = &parms;
-
- stack_ptr = 0;
- bufptr = buffer;
-
- while (*string)
- {
- if (*string != '%')
- *(bufptr++) = *string;
- else
- {
- string++;
- switch (*string)
- {
- default:
- break;
-
- case '%':
- *(bufptr++) = '%';
- break;
-
- case 'd':
- (void) sprintf(bufptr, "%d", npop());
- bufptr += strlen(bufptr);
- break;
-
- case '0':
- string++;
- len = *string;
- if ((len == '2' || len == '3') && *++string == 'd')
- {
- if (len == '2')
- (void) sprintf(bufptr, "%02d", npop());
- else
- (void) sprintf(bufptr, "%03d", npop());
-
- bufptr += strlen(bufptr);
- }
- break;
-
- case '2':
- string++;
- if (*string == 'd')
- {
- (void) sprintf(bufptr, "%2d", npop());
- bufptr += strlen(bufptr);
- }
- break;
-
- case '3':
- string++;
- if (*string == 'd')
- {
- (void) sprintf(bufptr, "%3d", npop());
- bufptr += strlen(bufptr);
- }
- break;
-
- case 'c':
- *(bufptr++) = (char) npop();
- break;
-
- case 's':
- strcpy(bufptr, spop());
- bufptr += strlen(bufptr);
- break;
-
- case 'p':
- string++;
- if (*string >= '1' && *string <= '9')
- npush(param[*string - '1']);
- break;
-
- case 'P':
- string++;
- if (*string >= 'a' && *string <= 'z')
- variable[*string - 'a'] = npop();
- break;
-
- case 'g':
- string++;
- if (*string >= 'a' && *string <= 'z')
- npush(variable[*string - 'a']);
- break;
-
- case '\'':
- string++;
- npush(*string);
- string++;
- break;
-
- case '{':
- number = 0;
- string++;
- while (*string >= '0' && *string <= '9')
- {
- number = number * 10 + *string - '0';
- string++;
- }
- npush(number);
- break;
-
- case '+':
- y = npop();
- x = npop();
- npush(x + y);
- break;
-
- case '-':
- y = npop();
- x = npop();
- npush(x - y);
- break;
-
- case '*':
- y = npop();
- x = npop();
- npush(x * y);
- break;
-
- case '/':
- y = npop();
- x = npop();
- npush(x / y);
- break;
-
- case 'm':
- y = npop();
- x = npop();
- npush(x % y);
- break;
-
- case '&':
- y = npop();
- x = npop();
- npush(x & y);
- break;
-
- case '|':
- y = npop();
- x = npop();
- npush(x | y);
- break;
-
- case '^':
- y = npop();
- x = npop();
- npush(x ^ y);
- break;
-
- case '=':
- y = npop();
- x = npop();
- npush(x == y);
- break;
-
- case '<':
- y = npop();
- x = npop();
- npush(x < y);
- break;
-
- case '>':
- y = npop();
- x = npop();
- npush(x > y);
- break;
-
- case '!':
- x = npop();
- npush(! x);
- break;
-
- case '~':
- x = npop();
- npush(~ x);
- break;
-
- case 'i':
- param[0]++;
- param[1]++;
- break;
-
- case '?':
- break;
-
- case 't':
- x = npop();
- if (x)
- {
- /* do nothing; keep executing */
- }
- else
- {
- /* scan forward for %e or %; at level zero */
- string++;
- level = 0;
- while (*string)
- {
- if (*string == '%')
- {
- string++;
- if (*string == '?')
- level++;
- else if (*string == ';')
- {
- if (level > 0)
- level--;
- else
- break;
- }
- else if (*string == 'e' && level == 0)
- break;
- }
-
- if (*string)
- string++;
- }
- }
- break;
-
- case 'e':
- /* scan forward for a %; at level zero */
- string++;
- level = 0;
- while (*string)
- {
- if (*string == '%')
- {
- string++;
- if (*string == '?')
- level++;
- else if (*string == ';')
- {
- if (level > 0)
- level--;
- else
- break;
- }
- }
-
- if (*string)
- string++;
- }
- break;
-
- case ';':
- break;
-
- } /* endswitch (*string) */
- } /* endelse (*string == '%') */
-
- if (*string == '\0')
- break;
-
- string++;
- } /* endwhile (*string) */
-
- *bufptr = '\0';
- return(buffer);
- }
- #endif
-
- /*
- * Ring Bell.
- */
- beep()
- {
- putchar('\007');
- }
-
- /*
- * 'Ring' visual bell if available, otherwise audible bell.
- */
- flash()
- {
- /* If you get a syntax error on this routine,
- * you are not using the new curses.h! Put
- * it in this directory or in /usr/include (saving the old one).
- * And double check that you are linking with the new libcurses.a
- */
- if (flash_screen)
- putp(flash_screen);
- else
- beep();
- }
-
- /*
- * Return the baud rate of the current terminal.
- */
- baudrate()
- {
- #ifdef B9600
- if (_tty.sg_ospeed >= B9600)
- return(9600);
- #endif
- #ifdef B4800
- if (_tty.sg_ospeed >= B4800)
- return(4800);
- #endif
- return(1200);
- }
-
- erasechar() { return(_tty.sg_erase); }
- killchar() { return(_tty.sg_kill); }
- #endif
-