home *** CD-ROM | disk | FTP | other *** search
- /*
- From: John Campbell (...!arizona!naucse!jdc)
-
- I ported gnuplot to the ATT 3b1 (ATT7300) on 12/4/88. 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. I chose to use these lines for the plot scale--normally found at the
- bottom right corner of the plot. I wanted to use the four bottom lines as
- prompt/command lines, but did not find a way to do this. If someone ever
- writes a device driver to "open" these rows as a small separate window, I
- could implement my original idea.
- */
-
- #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_XMAX 720
- #define uPC_YMAX 300
-
- #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;
- unsigned short uPC_raster_count=0;
-
- #define uPC_XLAST (uPC_XMAX - 1)
- #define uPC_YLAST (uPC_YMAX - 1)
-
- #define uPC_VCHAR 12
- #define uPC_HCHAR 9
- #define uPC_VTIC 8
- #define uPC_HTIC 12
-
- extern errno, sys_nerr;
- extern char *sys_errlist[];
-
- 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);}
-
- 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) {
- fprintf (stderr, "Sorry--must run from the bitmapped terminal\n");
- 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(0, WIOCSETD, &uw), <0, "ioctl failed on", "WIOCSETD");
- }
-
-
- 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;
-
- uPC_ur.ur_dstop = DSTSRC; /* replace (clear screen). */
- IfErrOut (ioctl(0, WIOCRASTOP, &uPC_ur), <0,
- "ioctl failed", "WIOCRASTOP");
- uPC_ur.ur_dstop = DSTOR; /* Or in (show text) */
- }
-
-
- uPC_text()
- {
- /* This routine will flush the display. */
-
- IfErrOut (ioctl(0, WIOCRASTOP, &uPC_ur), <0,
- "ioctl failed", "WIOCRASTOP");
- /* Now position the cursor at the second to the last row--better later? */
- wgoto (0, 24, 0);
- }
-
-
- uPC_linetype(linetype)
- int linetype;
- {
- /* This routine records the current linetype. */
- if (uPC_cur_linetype != linetype) {
- uPC_raster_count = 0;
- uPC_cur_linetype = linetype;
- }
- }
-
-
- uPC_move(x,y)
- unsigned int x,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))
-
- uPC_plot_word(a,b)
- Scr_type *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.
- */
- {
- /* Various line types */
- switch (uPC_cur_linetype) {
- case -1:
- /* 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;
- }
- }
-
- uPC_vector(x,y)
- unsigned int x,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;
- static Scr_type lookup[] = {
- 0x0001, 0x0002, 0x0004, 0x0008,
- 0x0010, 0x0020, 0x0040, 0x0080,
- 0x0100, 0x0200, 0x0400, 0x0800,
- 0x1000, 0x2000, 0x4000, 0x8000,
- };
-
- /* 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;
- }
- }
- }
- }
- }
-
-
- uPC_lrput_text(row,str)
- unsigned int row;
- char str[];
- {
- int col = 80-strlen(str), num, i;
- struct utdata ut;
- char *txt=ut.ut_text;
-
- /* Fill in the pad. */
- for (i = 0; i < col; i++)
- txt[i] = ' ';
- /* Then stick in the text. */
- txt[i] = '\0';
- strcat (txt, str);
-
- if (row > 2)
- puts (txt);
- else {
- /* This will fit on the 2 bottom "non-graphic" lines. */
- switch (row) {
- case 0: ut.ut_num = WTXTSLK1; break;
- case 1: ut.ut_num = WTXTSLK2; break;
- }
- ioctl (0, WIOCSETTEXT, &ut);
- }
- wgoto (1, 24, 0);
- }
-
- uPC_ulput_text(row,str)
- unsigned int row;
- char str[];
- {
- /* This routine puts the text in the upper left corner. */
-
- /* Just use the ANSI escape sequence CUP (iswind said that was ok!) */
- printf ("\033[%d;%dH%s\033[25;1H", row+2, 2, str); /* +1 +2 ? */
- fflush (stdout);
- }
-
-
- uPC_reset()
- {
- /* Reset window to normal size. */
- uPC_fixwind (0);
- }
-
-
-
- uPC_fixwind(signo)
- int signo;
- {
- static struct uwdata wreset = { 0, 12, 720, 288, 0x1};
- struct utdata ut;
-
- /* Reset the window to the right size. */
- ioctl(0, WIOCSETD, &wreset); /* 0, not wncur here! */
-
- /* Clear the lines affected by an _lrput_text. */
- ut.ut_text[0] = '\0';
- ut.ut_num = WTXTSLK1;
- ioctl(0, WIOCSETTEXT, &ut);
- ut.ut_num = WTXTSLK2;
- ioctl(0, WIOCSETTEXT, &ut);
- /* Scroll the screen once. (avoids typing over the same line) */
- fprintf (stderr, "\n");
-
- 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). */
- }
- }
-