|
|
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
Length: 17850 (0x45ba)
Types: TextFile
Names: »Tplot.c«
└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki
└─⟦526ad3590⟧ »EUUGD11/gnu-31mar87/X.V10.R4.tar.Z«
└─⟦2109abc41⟧
└─⟦this⟧ »./X.V10R4/obsolete/xterm/Tplot.c«
#include <X/mit-copyright.h>
/* Copyright 1984, 1985 Massachusetts Institute of Technology */
/* Tplot.c */
#ifndef lint
static char *rcsid_Tplot_c = "$Header: Tplot.c,v 10.12 86/06/06 16:56:54 wesommer Exp $";
#endif lint
#include <X/Xlib.h>
#include <X/Xkeyboard.h>
#include "ptyx.h"
#undef CTRL
#include <stdio.h>
#include <sys/file.h>
#include <sgtty.h>
#ifndef vms
#include <pwd.h>
#endif vms
#undef CTRL
extern debug;
static int bplot[5];
static int nplot;
static int ipchr;
static int refresh;
static int LoYSet;
#define MAX_PTS 150
#define MAX_VTX 300
static Vertex Tline[MAX_VTX];
static Vertex *line_pt;
static FILE *rfile, *wfile;
static TekLink *TekBuf = NULL;
TekLink *tb_end_link = NULL; /* world accessible for TekBufPut */
int tb_end = TEK_LINK_BLOCK_SIZE; /* world accessible for TekBufPut */
static TekLink *tb_pt_link = NULL;
static int tb_pt = TEK_LINK_BLOCK_SIZE;
#include "../cursors/bcross.cursor"
#include "../cursors/bcross_mask.cursor"
TekErase (term)
/* Reset buffer pointer for display list to start of buffer */
Terminal *term;
{
register Screen *screen = &term->screen;
register struct _TekLink *pnt;
register struct _TekLink *next;
pnt = (struct _TekLink *) TekBuf;
/* free stored list */
while (pnt)
{
next = pnt->next;
free ((char *)pnt);
pnt = next;
}
/* reset pointers */
TekBuf = tb_end_link = tb_pt_link = NULL;
tb_end = tb_pt = TEK_LINK_BLOCK_SIZE;
refresh = 0;
screen->cur_x = 0;
screen->cur_y = 0;
screen->TekGMode = 0;
screen->TekAMode = 0;
LoYSet = 0;
if (debug) wfile = fopen ("testbufw","w");
return;
}
TekRefresh (term)
/* Redisplay graphics screen, including positioned alpha strings */
register Terminal *term;
{
register Screen *screen = &term->screen;
Window window = screen->window;
Font fnt = screen->fnt_norm;
int chr, nstr;
register int ch;
unsigned char str[257];
int modeG = screen->TekGMode, modeA = screen->TekAMode,
modeI = screen->TekIMode, modeP = screen->TekPMode;
if (Icon(screen)) return;
TekBufResetPt ();
if (TekBufEmpty ()) return;
if (debug) rfile = fopen ("testbufr","w");
refresh = 1;
TekAlph (term,0);
screen->cur_x = screen->cur_y = 0;
while (TekBufGet (&chr) != -1)
{
ch = chr; /* lets get the char into a register */
if (screen->TekGMode)
{
if (ch > 31)
{
if (screen->TekIMode) TekPoint (term,ch);
else TekPlot (term,ch);
}
else if (ch > 27 && ch < 31) TekInit (term,ch);
else if (ch == 31 || ch < 28) TekAlph (term,0);
continue;
}
if (ch > 27 && ch < 31)
{
TekInit (term, ch);
continue;
}
if (ch > (unsigned) 128)
{
nstr = ch - (unsigned) 128;
if (debug)
{
fprintf (rfile,"alpha mode %d chars\n",nstr);
fflush (rfile);
}
if (nstr > 256) exit (77);
TekBufGetString (str, nstr);
*(str + nstr) = NULL;
XTextMask ( window,
TCursorX(screen), TCursorY(screen),
str, nstr, fnt, screen->foreground);
screen->cur_X += (nstr * screen->f_width);
screen->cur_x +=
(nstr * screen->f_width / screen->TekScale);
}
}
if (nplot > 0) TekFlush (term);
refresh = 0;
screen->TekGMode = modeG;
screen->TekAMode = modeA;
screen->TekIMode = modeI;
screen->TekPMode = modeP;
}
TekString (term, str, nchr)
/* Display positioned alphanumeric string, saving it in display list */
register Terminal *term;
unsigned char *str;
int nchr;
{
register Screen *screen = &term->screen;
Window window = screen->window;
Font fnt = screen->fnt_norm;
TekBufPut (128 + nchr);
if (debug)
{
fprintf (wfile,"alpha mode %d character string\n",nchr);
fflush (wfile);
}
TekBufPutString (str, nchr);
XTextMask (window,
TCursorX(screen), TCursorY(screen),
str, nchr, fnt, screen->foreground);
screen->cur_X = screen->cur_X + (nchr * screen->f_width);
screen->cur_x = screen->cur_x +
(nchr * screen->f_width / screen->TekScale);
}
TekBufResetPt ()
/* set pt to point to beginning of buffer */
{
tb_pt_link = TekBuf;
tb_pt = 0;
}
TekBufEmpty ()
/* return nonzero iff TekBuf is empty */
{
return (((tb_end & ~TEK_LINK_BLOCK_SIZE) == 0)
&& (tb_end_link == TekBuf));
}
/* Extend display buffer */
TekBufExtend ()
{
/* if TekBuf is NULL then must initialize */
if (!TekBuf)
{
TekBuf = (TekLink *) malloc (sizeof (TekLink));
TekBuf->next = NULL;
tb_end_link = TekBuf;
tb_end = 0;
}
else
{
tb_end_link->next =
(struct _TekLink *) malloc (sizeof (TekLink));
tb_end_link = (TekLink *) tb_end_link->next;
tb_end_link->next = NULL;
tb_end = 0;
}
}
/*
effect: puts len bytes at str into display buffer
*/
TekBufPutString (str, len)
register unsigned char *str;
register int len;
{
register int amount;
while (len)
{
if (tb_end & TEK_LINK_BLOCK_SIZE) TekBufExtend ();
amount = TEK_LINK_BLOCK_SIZE - tb_end;
if (amount > len) amount = len;
bcopy (str, tb_end_link->data + tb_end, amount);
str += amount;
len -= amount;
tb_end += amount;
}
}
/* Read character from display list */
int TekBufGet (chr)
register unsigned int *chr;
{
if (tb_pt & TEK_LINK_BLOCK_SIZE)
/* if tb_pt_link is NULL then check for a TekBuf */
if (!tb_pt_link)
{
if (!TekBuf) return (-1);
tb_pt_link = TekBuf;
tb_pt = 0;
}
else
if (tb_pt_link->next == NULL) return (-1);
else
{
tb_pt_link = (TekLink *) tb_pt_link->next;
tb_pt = 0;
}
if ((tb_pt_link == tb_end_link) && (tb_pt >= tb_end)) return (-1);
*chr = tb_pt_link->data [tb_pt++];
return (0);
}
/* store next len characters of TekBuf in str, advancing tb_pt */
TekBufGetString (str, len)
register char *str;
register int len;
{
register int n;
while (len)
{
n = TEK_LINK_BLOCK_SIZE - tb_pt;
n = (n < len) ? n : len;
bcopy (tb_pt_link->data + tb_pt, str, n);
tb_pt += n;
len -= n;
str += n;
if (tb_pt == TEK_LINK_BLOCK_SIZE)
{
if (tb_pt_link->next == NULL) return;
tb_pt_link = (TekLink *) tb_pt_link->next;
tb_pt = 0;
}
}
}
/* Switch to graphics mode and initialize byte and point counters */
TekInit (term,chr)
Terminal *term;
register int chr;
{
register Screen *screen = &term->screen;
if (debug)
if (!refresh)
{
fprintf (wfile,"switching to graphics mode %d\n",chr);
fflush (wfile);
}
else
{
fprintf (rfile,"switching to graphics mode %d\n",chr);
fflush (rfile);
}
if (!screen->TekGMode && nplot > 0) TekFlush (term);
screen->pen = 0;
ipchr = 0;
screen->TekPMode = 0;
screen->TekIMode = 0;
if (chr == 28) screen->TekPMode = 1;
if (chr == 30) screen->TekIMode = 1;
if (!refresh) TekBufPut (chr);
if (screen->TekGMode) return;
nplot = 0;
screen->TekGMode = 1;
screen->TekAMode = 1;
/*
* screen->cur_row = 0;
* screen->cur_col = 0;
*/
line_pt = Tline;
}
TekAlph (term,chr)
/* Switch back to alphanumeric mode from graphics mode */
Terminal *term;
int chr;
{
register Screen *screen = &term->screen;
if (!screen->TekGMode) return;
if (debug)
if (!refresh)
{
fprintf (wfile,"switching to alpha mode %d\n",chr);
fflush (wfile);
}
else
{
fprintf (rfile,"switching to alpha mode %d\n",chr);
fflush (rfile);
}
if (!refresh) TekBufPut (chr);
if (nplot > 0) TekFlush (term);
screen->TekGMode = 0;
screen->TekPMode = 0;
screen->TekIMode = 0;
if (chr>0 && chr != 31) TekReset(term);
return;
}
TekReset (term)
/* Switch back to vt100 alphanumeric mode from Tektronix alphanumeric mode
* This allows alphanumeric strings to be positioned by graphics commands,
* but reenables scrolling after CR or LF. */
Terminal *term;
{
register Screen *screen = &term->screen;
int fh = screen->f_height;
int fw = screen->f_width;
screen->TekAMode = 0;
if (debug)
if (!refresh)
{
fprintf (wfile,"resetting to alpha mode\n");
fflush (wfile);
}
else
{
fprintf (rfile,"resetting to alpha mode\n");
fflush (rfile);
}
if (screen->cur_Y > 0)
{
screen->cur_row = (screen->cur_Y - (fh >> 1)) / fh;
if (screen->cur_row > screen->max_row)
screen->cur_row = screen->max_row;
screen->cur_Y = 0;
}
if (screen->cur_X > 0)
{
screen->cur_col = (screen->cur_X + (fw >> 1)) / fw;
if (screen->cur_col > screen->max_col)
screen->cur_col = screen->max_col;
screen->cur_X = 0;
}
screen->cur_x = 0;
screen->cur_y = 0;
return;
}
TekCursor (term)
/* Reads position of mouse cursor when a character is typed and returns
* it in Tektronix-format coordinates */
Terminal *term;
{
register Screen *screen = &term->screen;
Keyboard *keyboard = &term->keyboard;
register Window window = screen->window;
int MouseX, MouseY;
XEvent reply;
XEvent *rep = &reply;
Window subw;
int pty = screen->respond;
int keycode, event, shifts, keydet;
int dmask, charkey;
short c;
char cplot [6];
extern int wflush ();
int x, y;
Cursor cursor;
char *string = " ";
int nbytes;
TekAlph (term, 0);
TekReset (term);
/* Set cross-hair cursor raster array */
cursor = XCreateCursor(bcross_width, bcross_height,
bcross_mask_bits, bcross_bits, bcross_x_hot, bcross_y_hot,
(term->flags & REVERSE_VIDEO) ?
screen->background : screen->mousecolor,
(term->flags & REVERSE_VIDEO) ?
screen->mousecolor : screen->foreground,
GXcopy);
/* Display cross-hair cursor */
XDefineCursor(window, cursor);
/* reselect input. Must be careful not to leave stray button
* events upon return since handle buttons would be invoked */
XSelectInput (window, ButtonReleased | KeyPressed);
/* Wait for keyboard entry */
XWindowEvent (window, KeyPressed | ButtonReleased, &reply);
/* Get current mouse position and translate to screen coordinates */
XUpdateMouse (window, &MouseX, &MouseY, &subw);
screen->cur_X = MouseX;
screen->cur_Y = MouseY;
/* Translate window coordinates to Tektronix coordinates */
x = (((MouseX - screen->border) << 14) / screen->TekScale) - 1;
x = (x + 2) >> 2;
y = 3128 - (((MouseY - screen->border) << 14) / screen->TekScale);
y = (y + 2) >> 2;
/* Translate x and y to Tektronix code */
cplot[1] = 32 + (x >> 5);
cplot[2] = 32 + (x & 31);
cplot[3] = 32 + (y >> 5);
cplot[4] = 32 + (y & 31);
/* Translate keyboard entry and return one byte from terminal */
keydet = ((XKeyOrButtonEvent *)rep)->detail;
keycode = keydet & ValueMask;
event = reply.type;
charkey = IsTypewriterKey(keycode);
if (event == KeyPressed)
{
/* Wait for legitimate keyboard entry */
while (charkey == 0)
{
XWindowEvent (window, KeyPressed, &reply);
keydet = ((XKeyPressedEvent *)rep)->detail;
keycode = keydet & ValueMask;
charkey = IsTypewriterKey(keycode);
}
string = XLookupMapping ((XKeyPressedEvent *)rep, &nbytes);
c = *string;
}
else c = 48 + keycode;
cplot[0] = c;
/* Return encode screen coordinates */
if (screen->TekCursCR == 1)
{
cplot[5] = 13;
write (pty, cplot, 6 * sizeof (char));
}
else
{
write (pty, cplot, 5 * sizeof (char));
}
/* Reset cursor and return */
XFreeCursor(cursor);
XDefineCursor(window,
(term->flags & INVERSE) ? screen->rcurs : screen->curs);
TekInit (term,0);
XSelectInput (window, KeyPressed | ExposeWindow | ExposeRegion |
ExposeCopy | ButtonPressed | ButtonReleased);
}
TekPlot (term,chr)
/* Translates Tektronix byte-encoded screen coordinates to integer screen
* coordinates each time the final byte of a coordinate set is encountered. */
Terminal *term;
register int chr;
{
register Screen *screen = &term->screen;
register int *bp = bplot;
register int x, y;
ipchr++;
if (ipchr > 5)
{
TekAlph (term,chr);
return;
}
/* decode Tektronix byte position codes */
if (chr < 64)
{
if (LoYSet) /* 4st byte */
{
bp[3] = chr & ~32;
}
else /* 1st byte */
{
bp[0] = chr & ~32;
bp[1] = 0;
}
}
else if (chr > 95)
{
if (LoYSet) /* 2nd byte */
{ /* 3rd if 2nd present */
bp[1] = bp[2];
bp[2] = chr & ~96;
}
else /* 3rd byte */
{
bp[2] = chr & ~96;
bp[1] = 0;
LoYSet = 1;
}
}
else /* 5th byte */
{
bp[4] = chr & ~64;
ipchr = 0;
LoYSet = 0;
/* compute screen x and y coordinates ignoring extended
* precision byte */
y = (bp[0] << 7) + (bp[2] << 2);
x = (bp[3] << 7) + (bp[4] << 2);
/* add in 4014 extended precision byte */
if (bp[1] > 0)
{
x += (bp [1] & 3);
y += ((bp [1] & 12) >> 2);
}
/* Check to make sure screen limits are not exceeded */
if (y > 3127) y = 3127;
/* transfer this point to vertex array */
if (screen->TekPMode)
{
TekDraw (0, x, y, term);
TekDraw (1, x, y, term);
}
else
{
TekDraw (screen->pen, x, y, term);
screen->pen = 1;
}
}
}
TekPoint (term,chr)
/* Translates Tektronix byte-encoded incremental plot commands to screen
* coordinates and writes them to the vector buffer */
register Terminal *term;
register int chr;
{
Screen *screen = &term->screen;
register int pen,x,y;
x = screen->cur_x;
y = screen->cur_y;
pen = screen->pen;
if (nplot == 0) TekDraw (0,x,y,term);
switch (chr)
{
case ' ': screen->pen = 0;
break;
case 'P': screen->pen = 1;
break;
case 'D': TekDraw (pen, x, ++y, term);
break;
case 'E': TekDraw (pen, ++x, ++y, term);
break;
case 'A': TekDraw (pen, ++x, y, term);
break;
case 'I': TekDraw (pen, ++x, --y, term);
break;
case 'H': TekDraw (pen, x, --y, term);
break;
case 'J': TekDraw (pen, --x, --y, term);
break;
case 'B': TekDraw (pen, --x, y, term);
break;
case 'F': TekDraw (pen, --x, ++y, term);
break;
}
}
TekDraw (pen, x, y, term)
/* Translates Tektronix screen coordinates to X screen
* coordinates, drawing them to the screen when a buffer is filled */
int x,y,pen;
Terminal *term;
{
register Screen *screen = &term->screen;
register Vertex *lp = line_pt;
screen->cur_x = x;
screen->cur_y = y;
/* convert to X window coordinates */
screen->cur_X = ((((x + 1) * screen->TekScale) + 8192) >> 14)
+ screen->border;
screen->cur_Y = ((((3128 - y) * screen->TekScale) + 8192) >> 14)
+ screen->border;
#ifdef notdef
/* Alternative method when division is faster than multiple shifts */
screen->cur_X = ((((x + 1) * screen->TekScale) + 5000) / 10000)
+ screen->border;
screen->cur_Y = ((((3128 - y) * screen->TekScale) + 5000) / 10000)
+ screen->border;
#endif notdef
/* write to plot buffer */
lp->x = screen->cur_X;
lp->y = screen->cur_Y;
if (pen) lp->flags = VertexDrawLastPoint;
else lp->flags = VertexDontDraw;
lp = ++line_pt;
nplot++;
if (debug)
if (refresh) fprintf (rfile,"%d: %d %d,%d -> %d,%d\n",
nplot,pen,x,y,screen->cur_X,screen->cur_Y);
else fprintf (wfile,"%d: %d %d,%d -> %d,%d\n",
nplot,pen,x,y,screen->cur_X,screen->cur_Y);
if (debug)
if (refresh) fflush (rfile);
else fflush (wfile);
/* draw line if buffer limit has been reached */
if (nplot >= MAX_PTS)
{
TekFlush (term);
lp = line_pt;
lp->x = screen->cur_X;
lp->y = screen->cur_Y;
lp->flags = VertexDontDraw;
line_pt++;
nplot++;
}
}
TekFlush (term)
register Terminal *term;
{
Window window = term->screen.window;
XDraw (window, Tline, nplot, 1, 1, term->screen.foreground, GXcopy,
AllPlanes);
nplot = 0;
line_pt = Tline;
}
TekInq (term)
/* Reports position of cursor in Tektronix-format coordinates */
Terminal *term;
{
register Screen *screen = &term->screen;
int pty = screen->respond;
char cplot [5];
int x, y;
/* Translate window coordinates to Tektronix coordinates */
x = (((screen->cur_X - screen->border) << 14) / screen->TekScale) - 1;
x = (x + 2) >> 2;
y = 3128 - (((screen->cur_Y - screen->border) << 14) / screen->TekScale);
y = (y + 2) >> 2;
/* Translate x and y to Tektronix code */
cplot[1] = 32 + (x >> 5);
cplot[2] = 32 + (x & 31);
cplot[3] = 32 + (y >> 5);
cplot[4] = 32 + (y & 31);
cplot[0] = '%'; /* standard hardware config */
/* Return encoded screen coordinates */
write (pty, cplot, 5 * sizeof (char));
}
#ifdef ENABLE_PRINT
#include <signal.h>
TekPrint (screen)
/* Dump graphics screen, including positioned alpha strings */
Screen *screen
{
int chr, pid, uid, i;
char c;
FILE *tekfile;
char *uname, tekfile_name[40];
struct passwd *upasswd;
int temp_tb_pt = tb_pt;
TekLink *temp_tb_pt_link = tb_pt_link;
char *prntcom = "imtek.2";
/* If no command set, return */
if (prntcom[0] == 0) return;
/* If nothing in display list, return */
TekBufResetPt ();
if (TekBufEmpty ()) return;
/* Create temporary file name */
pid = getpid ();
uid = getuid ();
upasswd = getpwuid (uid);
sprintf (tekfile_name,"/tmp/vst%d\.%s\0",pid,upasswd->pw_name);
/* Dump display list to file */
tekfile = fopen (tekfile_name,"w");
while (TekBufGet (&chr) != -1)
{
c = chr;
if (chr < 128) putc (c,tekfile);
}
tb_pt = temp_tb_pt;
tb_pt_link = temp_tb_pt_link;
fclose (tekfile);
/* Fork off hard copy command */
if (debug) printf ("attempting fork\n");
switch (fork ())
{
case -1: Error ();
break;
case 0: for (i= 0; i < _NFILE; i++) close (i);
signal(SIGCHLD, SIG_DFL);
signal(SIGTERM, SIG_DFL);
signal(SIGHUP, SIG_IGN);
execlp(prntcom, prntcom, "-x",tekfile_name, 0);
exit (1);
break;
default:
break;
}
}
#endif