/* prototypes for this file are in unixpc.trm-proto */ /* GNUPLOT - unixpc.trm */ /* * Copyright (C) 1990 * * 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 modified code. Modifications are to be distributed * as patches to released version. * * This software is provided "as is" without express or implied warranty. * * 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 (pixar!info-gnuplot@sun.com). * */ #include /* Started with tam.h--too much trouble. */ #include #include #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; 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) #define uPC_VCHAR FNT5X9_VCHAR #define uPC_HCHAR FNT5X9_HCHAR #define uPC_VTIC 8 #define uPC_HTIC 12 extern errno, sys_nerr; extern char *sys_errlist[]; static struct urdata uPC_ur = {(?1, ?1, ?1, ?1, ?1, ?1, ?1, ?1, ?1, ?1, ?1, ?1) #define IfErrOut(e1, e2, s1, s2) if (e1 e2) {\ fprintf(stderr, "%s:: %s %s\n", sys_errlist[errno], s1, s2);\ exit(-1);} int uPC_init(void) { /* 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(1, WIOCSETD, &uw), <0, "ioctl failed on", "WIOCSETD"); } int uPC_graphics(void) { /* 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. */ printf ("\033[25;1H"); 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) */ } int uPC_text(void) { /* This routine will flush the display. */ IfErrOut (ioctl(1, WIOCRASTOP, &uPC_ur), <0, "ioctl failed", "WIOCRASTOP"); } int uPC_linetype(int linetype) { /* This routine records the current linetype. */ if (uPC_cur_linetype != linetype) { uPC_raster_count = 0; uPC_cur_linetype = linetype; } } int uPC_move(int x, 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)) int uPC_plot_word(Scr_type *a, Scr_type b) { /* */ /* 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< 15) uPC_raster_count = 0; break; case 2: case 6: /* Make a |----|----|----|--- | | type of line. */ if ((1< 19) uPC_raster_count = 0; break; case 3: case 7: /* Make a | - | - | - | - | type of line. */ if ((1< 15) uPC_raster_count = 0; break; case 4: case 8: default: *(a) |= b; break; } } int uPC_vector(int x, 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) */ int uPC_put_text(int x, int y, 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 int uPC_put_text(int x, int y, 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; } } uPC_putc (int x, int y, int c, int angle) { /* */ int i, j, k; register Scr_type mask, *a; char_row fc; int pixelon; i = c - ' '; for (j=0; j>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 */ } } } } uPC_text_angle (int ang) { uPC_angle = ang; return TRUE; } int uPC_reset(void) { /* Reset window to normal size. */ uPC_fixwind (0); } int 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) */ 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). */ } }