--- /dev/null
+/* Hello, Emacs, this is -*-C-*-
+ * $Id: unixpc.trm,v 1.14 2006/07/21 02:35:48 sfeam Exp $
+ *
+ */
+
+/* GNUPLOT - unixpc.trm */
+
+/*[
+ * Copyright 1990 - 1993, 1998, 2004
+ *
+ * Permission to use, copy, and distribute this software and its
+ * documentation for any purpose with or without fee is hereby granted,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.
+ *
+ * Permission to modify the software is granted, but not the right to
+ * distribute the complete modified source code. Modifications are to
+ * be distributed as patches to the released version. Permission to
+ * distribute binaries produced by compiling modified sources is granted,
+ * provided you
+ * 1. distribute the corresponding source modifications from the
+ * released version in the form of a patch file along with the binaries,
+ * 2. add special version identification to distinguish your version
+ * in addition to the base release version number,
+ * 3. provide your name and address as the primary contact for the
+ * support of your modified version, and
+ * 4. retain our contact information in regard to use of the base
+ * software.
+ * Permission to distribute the released version of the source code along
+ * with corresponding source modifications in the form of a patch file is
+ * granted with same provisions 2 through 4 for binary distributions.
+ *
+ * This software is provided "as is" without express or implied warranty
+ * to the extent permitted by applicable law.
+]*/
+
+/*
+ * This file is included by ../term.c.
+ *
+ * This terminal driver supports:
+ * Unix PC's (ATT 3b1)
+ *
+ * AUTHORS
+ * John Campbell
+ *
+ * send your comments or suggestions to (gnuplot-info@lists.sourceforge.net).
+ *
+ */
+
+/*
+>From: John Campbell (...!arizona!naucse!jdc)
+
+I originally ported gnuplot to the ATT 3b1 (ATT7300) on 12/4/88, and then
+added the minimal code needed to bring it up to 2.0 level on 1/28/90. The
+3b1, as I view it, is a 720x300 bitmapped, monochrome display (often people
+don't use the top 12 scan lines and thus the effective size is 720x288). I
+tried to maximize the size of the graph area, by using these top 12 lines
+(normally reserved) and set up a signal handler to restore them upon exit,
+abort, etc.
+
+Line styles were "fudged" (they do not know the aspect ratio). The same
+line style may look different depending upon the slope of the curve. Due to
+this only 4 line styles were implemented. While more line types are possible,
+the current styles were chosen as distinguishable.
+
+The 3b1 has 4 "special" rows at the bottom that I could not use in graphics
+mode. It has been suggested that we use these lines for command prompting.
+Others have requested that we have a graphics window and a command window.
+My experience with gnuplot only includes relatively dumb graphics devices--
+hence gnuplot "looks and feels" normal to me the way I implemented it.
+I welcome either of these changes from someone else, however.
+*/
+
+/*
+ * adapted to the new terminal layout by Stefan Bodewig (Dec. 1995)
+ */
+
+#include "driver.h"
+
+#ifdef TERM_REGISTER
+register_term(unixpc)
+#endif
+
+#ifdef TERM_PROTO
+TERM_PUBLIC void uPC_init __PROTO((void));
+TERM_PUBLIC void uPC_graphics __PROTO((void));
+TERM_PUBLIC void uPC_text __PROTO((void));
+TERM_PUBLIC void uPC_linetype __PROTO((int linetype));
+TERM_PUBLIC void uPC_move __PROTO((unsigned int x, unsigned int y));
+TERM_PUBLIC void uPC_vector __PROTO((unsigned int x, unsigned int y));
+TERM_PUBLIC void uPC_put_text __PROTO((unsigned int x, unsigned int y, const char str[]));
+TERM_PUBLIC int uPC_text_angle __PROTO((int ang));
+TERM_PUBLIC void uPC_reset __PROTO((void));
+#define uPC_XMAX 720
+#define uPC_YMAX 300
+#define uPC_VCHAR FNT5X9_VCHAR
+#define uPC_HCHAR FNT5X9_HCHAR
+#define uPC_VTIC uPC_VCHAR/2 /* Was 8 */
+#define uPC_HTIC uPC_HCHAR /* Was 12 */
+#endif /* TERM_PROTO */
+
+#ifndef TERM_PROTO_ONLY
+#ifdef TERM_BODY
+void uPC_fixwind __PROTO((int signo));
+void uPC_putc __PROTO((unsigned int x, unsigned int y, int c, int angle));
+void uPC_plot_word __PROTO((unsigned short *a, unsigned short b));
+#include <sys/window.h> /* Started with tam.h--too much trouble. */
+#include <sys/signal.h>
+#include <errno.h>
+
+#define uPC_HIGH_BIT (0x8000)
+
+typedef unsigned short Scr_type;
+typedef unsigned char Scr_kluge;
+
+
+#define uPC_XSIZE 45 /* Short ints. */
+#define uPC_YSIZE uPC_YMAX
+
+Scr_type uPC_display[uPC_YSIZE][uPC_XSIZE];
+int uPC_width = 2 * uPC_XSIZE;
+int uPC_sx = 0, uPC_sy = 0;
+int uPC_cur_linetype = 0;
+int uPC_angle = 0;
+unsigned short uPC_raster_count = 0;
+static Scr_type lookup[] =
+{
+ 0x0001, 0x0002, 0x0004, 0x0008,
+ 0x0010, 0x0020, 0x0040, 0x0080,
+ 0x0100, 0x0200, 0x0400, 0x0800,
+ 0x1000, 0x2000, 0x4000, 0x8000,
+};
+
+#define uPC_XLAST (uPC_XMAX - 1)
+#define uPC_YLAST (uPC_YMAX - 1)
+
+
+static struct urdata uPC_ur = {
+ (unsigned short *) uPC_display,
+ 2 * uPC_XSIZE, 0, 0, 0, 0, 0, 0,
+ uPC_XMAX, uPC_YMAX, SRCSRC, DSTOR, 0
+};
+
+#define IfErrOut(e1,e2,s1,s2) if (e1 e2) { \
+ fprintf(stderr, "%s:: %s %s\n", sys_errlist[errno], s1, s2); \
+ uPC_fixwind(0); \
+ exit(-1); \
+}
+
+TERM_PUBLIC void
+uPC_init()
+{
+ /* This routine will ioctl to change 0 size */
+ int i;
+ struct uwdata uw;
+ int uPC_fixwind();
+ short gw;
+
+ /* Check that we are on the bitmapped window. */
+ if (iswind() != 0) {
+ fputs("Sorry--must run from the bitmapped terminal\n", stderr);
+ exit(-1);
+ }
+ for (i = 1; i <= 16; i++) {
+ if (i != SIGINT && i != SIGFPE) /* Two are caught in plot.c */
+ signal(i, uPC_fixwind);
+ }
+
+/* Increase the screen size */
+ uw.uw_x = 0;
+ uw.uw_y = 0; /* Leave room for top status line. */
+ uw.uw_width = uPC_XMAX; /* 720 */
+ uw.uw_height = uPC_YMAX; /* 288 normal--we clobber 12 (top row) */
+ uw.uw_uflags = 1; /* Creates with no border */
+
+ IfErrOut(ioctl(1, WIOCSETD, &uw), <0, "ioctl failed on", "WIOCSETD");
+}
+
+
+TERM_PUBLIC void
+uPC_graphics()
+{
+/* This routine will clear the uPC_display buffer and window. */
+ register Scr_type *j;
+ register int i;
+
+ j = (Scr_type *) uPC_display;
+ i = uPC_YSIZE * uPC_XSIZE + 1;
+
+ while (--i)
+ *j++ = 0;
+ /* Position the cursor to the bottom of the screen so when we come back to
+ * text mode we are just below the graph.
+ */
+ fputs("\033[25;1H", stdout);
+
+ uPC_ur.ur_dstop = DSTSRC; /* replace (clear screen). */
+ IfErrOut(ioctl(1, WIOCRASTOP, &uPC_ur), <0,
+ "ioctl failed", "WIOCRASTOP");
+ uPC_ur.ur_dstop = DSTOR; /* Or in (show text) */
+}
+
+
+TERM_PUBLIC void
+uPC_text()
+{
+/* This routine will flush the display. */
+
+ IfErrOut(ioctl(1, WIOCRASTOP, &uPC_ur), <0,
+ "ioctl failed", "WIOCRASTOP");
+}
+
+
+TERM_PUBLIC void
+uPC_linetype(int linetype)
+{
+/* This routine records the current linetype. */
+ if (uPC_cur_linetype != linetype) {
+ uPC_raster_count = 0;
+ uPC_cur_linetype = linetype;
+ }
+}
+
+
+TERM_PUBLIC void
+uPC_move(unsigned int x, unsigned int y)
+{
+/* This routine just records x and y in uPC_sx, uPC_sy */
+ uPC_sx = x;
+ uPC_sy = y;
+}
+
+
+/* Was just (*(a)|=(b)) */
+#define uPC_PLOT(a,b) (uPC_cur_linetype != 0 ? uPC_plot_word (a,b) :\
+ (*(a)|=(b)))
+
+/*
+ Weak attempt to make line styles. The real problem is the aspect
+ ratio. This routine is called only when a bit is to be turned on in
+ a horizontal word. A better line style routine would know something
+ about the slope of the line around the current point (in order to
+ change weighting).
+
+ This yields 3 working linetypes plus a usable axis line type.
+*/
+void
+uPC_plot_word(Scr_type *a, Scr_type b)
+{
+ /* Various line types */
+ switch (uPC_cur_linetype) {
+ case LT_AXIS:
+ /* Distinguish between horizontal and vertical axis. */
+ if (uPC_sx > uPC_XMAX / 8 && uPC_sx < 7 * uPC_XMAX / 8) {
+ /* Fuzzy tolerance because we don't know exactly where the y axis is */
+ if (++uPC_raster_count % 2 == 0)
+ *(a) |= b;
+ } else {
+ /* Due to aspect ratio, take every other y pixel and every third x. */
+ *(a) |= (b & 0x9999);
+ }
+ break;
+ case 1:
+ case 5:
+ /* Make a | |----| |----| type of line. */
+ if ((1 << uPC_raster_count) & 0xF0F0)
+ *(a) |= b;
+ if (++uPC_raster_count > 15)
+ uPC_raster_count = 0;
+ break;
+ case 2:
+ case 6:
+ /* Make a |----|----|----|--- | | type of line. */
+ if ((1 << uPC_raster_count) & 0x0EFFF)
+ *(a) |= b;
+ if (++uPC_raster_count > 19)
+ uPC_raster_count = 0;
+ break;
+ case 3:
+ case 7:
+ /* Make a | - | - | - | - | type of line. */
+ if ((1 << uPC_raster_count) & 0x4444)
+ *(a) |= b;
+ if (++uPC_raster_count > 15)
+ uPC_raster_count = 0;
+ break;
+ case 4:
+ case 8:
+ default:
+ *(a) |= b;
+ break;
+ }
+}
+
+TERM_PUBLIC void
+uPC_vector(unsigned int x, unsigned int y)
+{
+/* This routine calls line with x,y */
+ int x1 = uPC_sx, y1 = uPC_sy, x2 = x, y2 = y;
+ register int c, e, dx, dy, width;
+ register Scr_type mask, *a;
+
+/* Record new sx, sy for next call to the vector routine. */
+ uPC_sx = x2;
+ uPC_sy = y2;
+
+ a = &uPC_display[(uPC_YSIZE - 1) - y1][x1 >> 4];
+ mask = lookup[x1 & 0x0f];
+ width = uPC_width;
+
+ if ((dx = x2 - x1) > 0) {
+ if ((dy = y2 - y1) > 0) {
+ if (dx > dy) { /* dx > 0, dy > 0, dx > dy */
+ dy <<= 1;
+ e = dy - dx;
+ c = dx + 2;
+ dx <<= 1;
+
+ while (--c) {
+ uPC_PLOT(a, mask);
+ if (e >= 0) {
+ (Scr_kluge *) a -= width;
+ e -= dx;
+ }
+ if (mask & uPC_HIGH_BIT) {
+ mask = 1;
+ a++;
+ } else
+ mask <<= 1;
+ e += dy;
+ }
+ } else { /* dx > 0, dy > 0, dx <= dy */
+ dx <<= 1;
+ e = dx - dy;
+ c = dy + 2;
+ dy <<= 1;
+
+ while (--c) {
+ uPC_PLOT(a, mask);
+ if (e >= 0) {
+ if (mask & uPC_HIGH_BIT) {
+ mask = 1;
+ a++;
+ } else
+ mask <<= 1;
+ e -= dy;
+ }
+ (Scr_kluge *) a -= width;
+ e += dx;
+ }
+ }
+ } else {
+ dy = -dy;
+ if (dx > dy) { /* dx > 0, dy <= 0, dx > dy */
+ dy <<= 1;
+ e = dy - dx;
+ c = dx + 2;
+ dx <<= 1;
+
+ while (--c) {
+ uPC_PLOT(a, mask);
+ if (e >= 0) {
+ (Scr_kluge *) a += width;
+ e -= dx;
+ }
+ if (mask & uPC_HIGH_BIT) {
+ mask = 1;
+ a++;
+ } else
+ mask <<= 1;
+ e += dy;
+ }
+ } else { /* dx > 0, dy <= 0, dx <= dy */
+ dx <<= 1;
+ e = dx - dy;
+ c = dy + 2;
+ dy <<= 1;
+
+ while (--c) {
+ uPC_PLOT(a, mask);
+ if (e >= 0) {
+ if (mask & uPC_HIGH_BIT) {
+ mask = 1;
+ a++;
+ } else
+ mask <<= 1;
+ e -= dy;
+ }
+ (Scr_kluge *) a += width;
+ e += dx;
+ }
+ }
+ }
+ } else {
+ dx = -dx;
+ if ((dy = y2 - y1) > 0) {
+ if (dx > dy) { /* dx <= 0, dy > 0, dx > dy */
+ dy <<= 1;
+ e = dy - dx;
+ c = dx + 2;
+ dx <<= 1;
+
+ while (--c) {
+ uPC_PLOT(a, mask);
+ if (e >= 0) {
+ (Scr_kluge *) a -= width;
+ e -= dx;
+ }
+ if (mask & 1) {
+ mask = uPC_HIGH_BIT;
+ a--;
+ } else
+ mask >>= 1;
+ e += dy;
+ }
+ } else { /* dx <= 0, dy > 0, dx <= dy */
+ dx <<= 1;
+ e = dx - dy;
+ c = dy + 2;
+ dy <<= 1;
+
+ while (--c) {
+ uPC_PLOT(a, mask);
+ if (e >= 0) {
+ if (mask & 1) {
+ mask = uPC_HIGH_BIT;
+ a--;
+ } else
+ mask >>= 1;
+ e -= dy;
+ }
+ (Scr_kluge *) a -= width;
+ e += dx;
+ }
+ }
+ } else {
+ dy = -dy;
+ if (dx > dy) { /* dx <= 0, dy <= 0, dx > dy */
+ dy <<= 1;
+ e = dy - dx;
+ c = dx + 2;
+ dx <<= 1;
+
+ while (--c) {
+ uPC_PLOT(a, mask);
+ if (e >= 0) {
+ (Scr_kluge *) a += width;
+ e -= dx;
+ }
+ if (mask & 1) {
+ mask = uPC_HIGH_BIT;
+ a--;
+ } else
+ mask >>= 1;
+ e += dy;
+ }
+ } else { /* dx <= 0, dy <= 0, dx <= dy */
+ dx <<= 1;
+ e = dx - dy;
+ c = dy + 2;
+ dy <<= 1;
+
+ while (--c) {
+ uPC_PLOT(a, mask);
+ if (e >= 0) {
+ if (mask & 1) {
+ mask = uPC_HIGH_BIT;
+ a--;
+ } else
+ mask >>= 1;
+ e -= dy;
+ }
+ (Scr_kluge *) a += width;
+ e += dx;
+ }
+ }
+ }
+ }
+}
+
+
+#ifdef uPC_NOT_USED
+
+/* Added by Russell Lang, eln272v@monu1.cc.monash.oz
+ This placement to the nearest character cell worked, and I'm leaving
+ it here so the calculations involved won't be lost! (jdc)
+*/
+TERM_PUBLIC void
+uPC_put_text(unsigned int x, unsigned int y, const char str[])
+{
+ /* This routine puts the text at the cursor location nearest
+ to (x,y). Obviously the exact postion would look better */
+
+ /* Just use the ANSI escape sequence CUP (iswind said that was ok!) */
+ printf("\033[%d;%dH%s\033[25;1H",
+ (int) (24 - (y - uPC_VCHAR / 2) * 25 / uPC_YMAX),
+ (int) (x * 80 / uPC_XMAX), str);
+ fflush(stdout);
+}
+
+#endif
+
+
+TERM_PUBLIC void
+uPC_put_text(unsigned int x, unsigned int y, const char str[])
+{
+ if (uPC_angle == 1)
+ x += uPC_VCHAR / 2;
+ else
+ y -= uPC_VCHAR / 2;
+
+ switch (uPC_angle) {
+ case 0:
+ for (; *str; ++str, x += uPC_HCHAR)
+ uPC_putc(x, y, *str, uPC_angle);
+ break;
+ case 1:
+ for (; *str; ++str, y += uPC_HCHAR)
+ uPC_putc(x, y, *str, uPC_angle);
+ break;
+ }
+}
+
+
+/*
+ Put a character at an x,y location in the bit map (using the fnt5x9
+ array. This is mostly just copied from the bitmap.c driver.
+*/
+void
+uPC_putc(unsigned int x, unsigned int y, int c, int angle)
+{
+ int i, j, k;
+ register Scr_type mask, *a;
+ char_row fc;
+ unsigned int pixelon;
+
+ i = c - ' ';
+ for (j = 0; j < FNT5X9_VBITS; j++) {
+ fc = fnt5x9[i][j];
+ for (k = 0; k < FNT5X9_HBITS; k++) {
+ pixelon = ((unsigned int) (fc)) >> k & 1;
+ if (pixelon) {
+ switch (angle) {
+ case 0:
+ mask = lookup[x + k + 1 & 0x0f];
+ a = &uPC_display[(uPC_YSIZE - 1) - (y + j)][(x + k + 1) >> 4];
+ break;
+ case 1:
+ mask = lookup[x - j & 0x0f];
+ a = &uPC_display[(uPC_YSIZE - 1) - (y + k + 1)][(x - j) >> 4];
+ break;
+ }
+ *(a) |= (mask); /* see uPC_PLOT macro */
+ }
+ }
+ }
+}
+
+
+TERM_PUBLIC int
+uPC_text_angle(int ang)
+{
+ uPC_angle = (ang ? 1 : 0);
+ return TRUE;
+}
+
+
+TERM_PUBLIC void
+uPC_reset()
+{
+ /* Reset window to normal size. */
+ uPC_fixwind(0);
+}
+
+
+
+void
+uPC_fixwind(int signo)
+{
+ static struct uwdata wreset =
+ {0, 12, 720, 288, 0x1};
+ struct utdata ut;
+
+/* Reset the window to the right size. */
+ ioctl(1, WIOCSETD, &wreset); /* 0, not wncur here! */
+
+/* Scroll the screen once. (avoids typing over the same line) */
+ putc('\n', stderr);
+
+ if (signo) {
+ if (signo == SIGILL || signo == SIGTRAP || signo == SIGPWR)
+ signal(signo, SIG_DFL);
+ kill(0, signo); /* Redo the signal (as if we never trapped it). */
+ }
+}
+#endif /* TERM_BODY */
+
+#ifdef TERM_TABLE
+
+TERM_TABLE_START(unixpc_driver)
+ "unixpc", "AT&T 3b1 or AT&T 7300 Unix PC",
+ uPC_XMAX, uPC_YMAX, uPC_VCHAR, uPC_HCHAR,
+ uPC_VTIC, uPC_HTIC, options_null, uPC_init, uPC_reset,
+ uPC_text, null_scale, uPC_graphics, uPC_move, uPC_vector,
+ uPC_linetype, uPC_put_text, uPC_text_angle,
+ null_justify_text, line_and_point, do_arrow, set_font_null
+TERM_TABLE_END(unixpc_driver)
+
+#undef LAST_TERM
+#define LAST_TERM unixpc_driver
+
+#endif /* TERM_TABLE */
+#endif /* TERM_PROTO_ONLY */
+
+#ifdef TERM_HELP
+START_HELP(unixpc)
+"1 unixpc",
+"?commands set terminal unixpc",
+"?set terminal unixpc",
+"?set term unixpc",
+"?terminal unixpc",
+"?term unixpc",
+"?unixpc",
+" The `unixpc` terminal driver supports AT&T 3b1 and AT&T 7300 Unix PC. It has",
+" no options."
+END_HELP(unixpc)
+#endif /* TERM_HELP */