DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - download
Index: ┃ T h

⟦114e5f4eb⟧ TextFile

    Length: 11742 (0x2dde)
    Types: TextFile
    Names: »hacks.c«

Derivation

└─⟦87ddcff64⟧ Bits:30001253 CPHDIST85 Tape, 1985 Autumn Conference Copenhagen
    └─ ⟦this⟧ »cph85dist/wm/hacks.c« 

TextFile

/*
 *************
 * 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