|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T h
Length: 11742 (0x2dde)
Types: TextFile
Names: »hacks.c«
└─⟦87ddcff64⟧ Bits:30001253 CPHDIST85 Tape, 1985 Autumn Conference Copenhagen
└─⟦this⟧ »cph85dist/wm/hacks.c«
/*
*************
* 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