Annotation of OpenXM_contrib/gnuplot/term/unixpc.trm, Revision 1.1
1.1 ! maekawa 1: /*
! 2: * $Id: unixpc.trm,v 1.14 1998/04/14 00:18:12 drd Exp $
! 3: *
! 4: */
! 5:
! 6: /* GNUPLOT - unixpc.trm */
! 7:
! 8: /*[
! 9: * Copyright 1990 - 1993, 1998
! 10: *
! 11: * Permission to use, copy, and distribute this software and its
! 12: * documentation for any purpose with or without fee is hereby granted,
! 13: * provided that the above copyright notice appear in all copies and
! 14: * that both that copyright notice and this permission notice appear
! 15: * in supporting documentation.
! 16: *
! 17: * Permission to modify the software is granted, but not the right to
! 18: * distribute the complete modified source code. Modifications are to
! 19: * be distributed as patches to the released version. Permission to
! 20: * distribute binaries produced by compiling modified sources is granted,
! 21: * provided you
! 22: * 1. distribute the corresponding source modifications from the
! 23: * released version in the form of a patch file along with the binaries,
! 24: * 2. add special version identification to distinguish your version
! 25: * in addition to the base release version number,
! 26: * 3. provide your name and address as the primary contact for the
! 27: * support of your modified version, and
! 28: * 4. retain our contact information in regard to use of the base
! 29: * software.
! 30: * Permission to distribute the released version of the source code along
! 31: * with corresponding source modifications in the form of a patch file is
! 32: * granted with same provisions 2 through 4 for binary distributions.
! 33: *
! 34: * This software is provided "as is" without express or implied warranty
! 35: * to the extent permitted by applicable law.
! 36: ]*/
! 37:
! 38: /*
! 39: * This file is included by ../term.c.
! 40: *
! 41: * This terminal driver supports:
! 42: * Unix PC's (ATT 3b1)
! 43: *
! 44: * AUTHORS
! 45: * John Campbell
! 46: *
! 47: * send your comments or suggestions to (info-gnuplot@dartmouth.edu).
! 48: *
! 49: */
! 50:
! 51: /*
! 52: >From: John Campbell (...!arizona!naucse!jdc)
! 53:
! 54: I originally ported gnuplot to the ATT 3b1 (ATT7300) on 12/4/88, and then
! 55: added the minimal code needed to bring it up to 2.0 level on 1/28/90. The
! 56: 3b1, as I view it, is a 720x300 bitmapped, monochrome display (often people
! 57: don't use the top 12 scan lines and thus the effective size is 720x288). I
! 58: tried to maximize the size of the graph area, by using these top 12 lines
! 59: (normally reserved) and set up a signal handler to restore them upon exit,
! 60: abort, etc.
! 61:
! 62: Line styles were "fudged" (they do not know the aspect ratio). The same
! 63: line style may look different depending upon the slope of the curve. Due to
! 64: this only 4 line styles were implemented. While more line types are possible,
! 65: the current styles were chosen as distinguishable.
! 66:
! 67: The 3b1 has 4 "special" rows at the bottom that I could not use in graphics
! 68: mode. It has been suggested that we use these lines for command prompting.
! 69: Others have requested that we have a graphics window and a command window.
! 70: My experience with gnuplot only includes relatively dumb graphics devices--
! 71: hence gnuplot "looks and feels" normal to me the way I implemented it.
! 72: I welcome either of these changes from someone else, however.
! 73: */
! 74:
! 75: /*
! 76: * adapted to the new terminal layout by Stefan Bodewig (Dec. 1995)
! 77: */
! 78:
! 79: #include "driver.h"
! 80:
! 81: #ifdef TERM_REGISTER
! 82: register_term(unixpc)
! 83: #endif
! 84:
! 85: #ifdef TERM_PROTO
! 86: TERM_PUBLIC void uPC_init __PROTO((void));
! 87: TERM_PUBLIC void uPC_graphics __PROTO((void));
! 88: TERM_PUBLIC void uPC_text __PROTO((void));
! 89: TERM_PUBLIC void uPC_linetype __PROTO((int linetype));
! 90: TERM_PUBLIC void uPC_move __PROTO((unsigned int x, unsigned int y));
! 91: TERM_PUBLIC void uPC_vector __PROTO((unsigned int x, unsigned int y));
! 92: TERM_PUBLIC void uPC_put_text __PROTO((unsigned int x, unsigned int y, char str[]));
! 93: TERM_PUBLIC int uPC_text_angle __PROTO((int ang));
! 94: TERM_PUBLIC void uPC_reset __PROTO((void));
! 95: #define uPC_XMAX 720
! 96: #define uPC_YMAX 300
! 97: #define uPC_VCHAR FNT5X9_VCHAR
! 98: #define uPC_HCHAR FNT5X9_HCHAR
! 99: #define uPC_VTIC uPC_VCHAR/2 /* Was 8 */
! 100: #define uPC_HTIC uPC_HCHAR /* Was 12 */
! 101: #endif /* TERM_PROTO */
! 102:
! 103: #ifndef TERM_PROTO_ONLY
! 104: #ifdef TERM_BODY
! 105: void uPC_fixwind __PROTO((int signo));
! 106: void uPC_putc __PROTO((unsigned int x, unsigned int y, int c, int angle));
! 107: void uPC_plot_word __PROTO((unsigned short *a, unsigned short b));
! 108: #include <sys/window.h> /* Started with tam.h--too much trouble. */
! 109: #include <sys/signal.h>
! 110: #include <errno.h>
! 111:
! 112: #define uPC_HIGH_BIT (0x8000)
! 113:
! 114: typedef unsigned short Scr_type;
! 115: typedef unsigned char Scr_kluge;
! 116:
! 117:
! 118: #define uPC_XSIZE 45 /* Short ints. */
! 119: #define uPC_YSIZE uPC_YMAX
! 120:
! 121: Scr_type uPC_display[uPC_YSIZE][uPC_XSIZE];
! 122: int uPC_width = 2 * uPC_XSIZE;
! 123: int uPC_sx = 0, uPC_sy = 0;
! 124: int uPC_cur_linetype = 0;
! 125: int uPC_angle = 0;
! 126: unsigned short uPC_raster_count = 0;
! 127: static Scr_type lookup[] =
! 128: {
! 129: 0x0001, 0x0002, 0x0004, 0x0008,
! 130: 0x0010, 0x0020, 0x0040, 0x0080,
! 131: 0x0100, 0x0200, 0x0400, 0x0800,
! 132: 0x1000, 0x2000, 0x4000, 0x8000,
! 133: };
! 134:
! 135: #define uPC_XLAST (uPC_XMAX - 1)
! 136: #define uPC_YLAST (uPC_YMAX - 1)
! 137:
! 138:
! 139: static struct urdata uPC_ur = { (unsigned short *) uPC_display,
! 140: 2 * uPC_XSIZE, 0, 0, 0, 0, 0, 0,
! 141: uPC_XMAX, uPC_YMAX, SRCSRC, DSTOR, 0
! 142: };
! 143:
! 144: #define IfErrOut(e1,e2,s1,s2) if (e1 e2) {\
! 145: fprintf(stderr, "%s:: %s %s\n", sys_errlist[errno], s1, s2);\
! 146: uPC_fixwind(0);\
! 147: exit(-1);}
! 148:
! 149: TERM_PUBLIC void uPC_init()
! 150: {
! 151: /* This routine will ioctl to change 0 size */
! 152: int i;
! 153: struct uwdata uw;
! 154: int uPC_fixwind();
! 155: short gw;
! 156:
! 157: /* Check that we are on the bitmapped window. */
! 158: if (iswind() != 0) {
! 159: fputs("Sorry--must run from the bitmapped terminal\n", stderr);
! 160: exit(-1);
! 161: }
! 162: for (i = 1; i <= 16; i++) {
! 163: if (i != SIGINT && i != SIGFPE) /* Two are caught in plot.c */
! 164: signal(i, uPC_fixwind);
! 165: }
! 166:
! 167: /* Increase the screen size */
! 168: uw.uw_x = 0;
! 169: uw.uw_y = 0; /* Leave room for top status line. */
! 170: uw.uw_width = uPC_XMAX; /* 720 */
! 171: uw.uw_height = uPC_YMAX; /* 288 normal--we clobber 12 (top row) */
! 172: uw.uw_uflags = 1; /* Creates with no border */
! 173:
! 174: IfErrOut(ioctl(1, WIOCSETD, &uw), <0, "ioctl failed on", "WIOCSETD");
! 175: }
! 176:
! 177:
! 178: TERM_PUBLIC void uPC_graphics()
! 179: {
! 180: /* This routine will clear the uPC_display buffer and window. */
! 181: register Scr_type *j;
! 182: register int i;
! 183:
! 184: j = (Scr_type *) uPC_display;
! 185: i = uPC_YSIZE * uPC_XSIZE + 1;
! 186:
! 187: while (--i)
! 188: *j++ = 0;
! 189: /* Position the cursor to the bottom of the screen so when we come back to
! 190: * text mode we are just below the graph.
! 191: */
! 192: fputs("\033[25;1H", stdout);
! 193:
! 194: uPC_ur.ur_dstop = DSTSRC; /* replace (clear screen). */
! 195: IfErrOut(ioctl(1, WIOCRASTOP, &uPC_ur), <0,
! 196: "ioctl failed", "WIOCRASTOP");
! 197: uPC_ur.ur_dstop = DSTOR; /* Or in (show text) */
! 198: }
! 199:
! 200:
! 201: TERM_PUBLIC void uPC_text()
! 202: {
! 203: /* This routine will flush the display. */
! 204:
! 205: IfErrOut(ioctl(1, WIOCRASTOP, &uPC_ur), <0,
! 206: "ioctl failed", "WIOCRASTOP");
! 207: }
! 208:
! 209:
! 210: TERM_PUBLIC void uPC_linetype(linetype)
! 211: int linetype;
! 212: {
! 213: /* This routine records the current linetype. */
! 214: if (uPC_cur_linetype != linetype) {
! 215: uPC_raster_count = 0;
! 216: uPC_cur_linetype = linetype;
! 217: }
! 218: }
! 219:
! 220:
! 221: TERM_PUBLIC void uPC_move(x, y)
! 222: unsigned int x, y;
! 223: {
! 224: /* This routine just records x and y in uPC_sx, uPC_sy */
! 225: uPC_sx = x;
! 226: uPC_sy = y;
! 227: }
! 228:
! 229:
! 230: /* Was just (*(a)|=(b)) */
! 231: #define uPC_PLOT(a,b) (uPC_cur_linetype != 0 ? uPC_plot_word (a,b) :\
! 232: (*(a)|=(b)))
! 233:
! 234: void uPC_plot_word(a, b)
! 235: Scr_type *a, b;
! 236: /*
! 237: Weak attempt to make line styles. The real problem is the aspect
! 238: ratio. This routine is called only when a bit is to be turned on in
! 239: a horizontal word. A better line style routine would know something
! 240: about the slope of the line around the current point (in order to
! 241: change weighting).
! 242:
! 243: This yields 3 working linetypes plus a usable axis line type.
! 244: */
! 245: {
! 246: /* Various line types */
! 247: switch (uPC_cur_linetype) {
! 248: case -1:
! 249: /* Distinguish between horizontal and vertical axis. */
! 250: if (uPC_sx > uPC_XMAX / 8 && uPC_sx < 7 * uPC_XMAX / 8) {
! 251: /* Fuzzy tolerance because we don't know exactly where the y axis is */
! 252: if (++uPC_raster_count % 2 == 0)
! 253: *(a) |= b;
! 254: } else {
! 255: /* Due to aspect ratio, take every other y pixel and every third x. */
! 256: *(a) |= (b & 0x9999);
! 257: }
! 258: break;
! 259: case 1:
! 260: case 5:
! 261: /* Make a | |----| |----| type of line. */
! 262: if ((1 << uPC_raster_count) & 0xF0F0)
! 263: *(a) |= b;
! 264: if (++uPC_raster_count > 15)
! 265: uPC_raster_count = 0;
! 266: break;
! 267: case 2:
! 268: case 6:
! 269: /* Make a |----|----|----|--- | | type of line. */
! 270: if ((1 << uPC_raster_count) & 0x0EFFF)
! 271: *(a) |= b;
! 272: if (++uPC_raster_count > 19)
! 273: uPC_raster_count = 0;
! 274: break;
! 275: case 3:
! 276: case 7:
! 277: /* Make a | - | - | - | - | type of line. */
! 278: if ((1 << uPC_raster_count) & 0x4444)
! 279: *(a) |= b;
! 280: if (++uPC_raster_count > 15)
! 281: uPC_raster_count = 0;
! 282: break;
! 283: case 4:
! 284: case 8:
! 285: default:
! 286: *(a) |= b;
! 287: break;
! 288: }
! 289: }
! 290:
! 291: TERM_PUBLIC void uPC_vector(x, y)
! 292: unsigned int x, y;
! 293: {
! 294: /* This routine calls line with x,y */
! 295: int x1 = uPC_sx, y1 = uPC_sy, x2 = x, y2 = y;
! 296: register int c, e, dx, dy, width;
! 297: register Scr_type mask, *a;
! 298:
! 299: /* Record new sx, sy for next call to the vector routine. */
! 300: uPC_sx = x2;
! 301: uPC_sy = y2;
! 302:
! 303: a = &uPC_display[(uPC_YSIZE - 1) - y1][x1 >> 4];
! 304: mask = lookup[x1 & 0x0f];
! 305: width = uPC_width;
! 306:
! 307: if ((dx = x2 - x1) > 0) {
! 308: if ((dy = y2 - y1) > 0) {
! 309: if (dx > dy) { /* dx > 0, dy > 0, dx > dy */
! 310: dy <<= 1;
! 311: e = dy - dx;
! 312: c = dx + 2;
! 313: dx <<= 1;
! 314:
! 315: while (--c) {
! 316: uPC_PLOT(a, mask);
! 317: if (e >= 0) {
! 318: (Scr_kluge *) a -= width;
! 319: e -= dx;
! 320: }
! 321: if (mask & uPC_HIGH_BIT) {
! 322: mask = 1;
! 323: a++;
! 324: } else
! 325: mask <<= 1;
! 326: e += dy;
! 327: }
! 328: } else { /* dx > 0, dy > 0, dx <= dy */
! 329: dx <<= 1;
! 330: e = dx - dy;
! 331: c = dy + 2;
! 332: dy <<= 1;
! 333:
! 334: while (--c) {
! 335: uPC_PLOT(a, mask);
! 336: if (e >= 0) {
! 337: if (mask & uPC_HIGH_BIT) {
! 338: mask = 1;
! 339: a++;
! 340: } else
! 341: mask <<= 1;
! 342: e -= dy;
! 343: }
! 344: (Scr_kluge *) a -= width;
! 345: e += dx;
! 346: }
! 347: }
! 348: } else {
! 349: dy = -dy;
! 350: if (dx > dy) { /* dx > 0, dy <= 0, dx > dy */
! 351: dy <<= 1;
! 352: e = dy - dx;
! 353: c = dx + 2;
! 354: dx <<= 1;
! 355:
! 356: while (--c) {
! 357: uPC_PLOT(a, mask);
! 358: if (e >= 0) {
! 359: (Scr_kluge *) a += width;
! 360: e -= dx;
! 361: }
! 362: if (mask & uPC_HIGH_BIT) {
! 363: mask = 1;
! 364: a++;
! 365: } else
! 366: mask <<= 1;
! 367: e += dy;
! 368: }
! 369: } else { /* dx > 0, dy <= 0, dx <= dy */
! 370: dx <<= 1;
! 371: e = dx - dy;
! 372: c = dy + 2;
! 373: dy <<= 1;
! 374:
! 375: while (--c) {
! 376: uPC_PLOT(a, mask);
! 377: if (e >= 0) {
! 378: if (mask & uPC_HIGH_BIT) {
! 379: mask = 1;
! 380: a++;
! 381: } else
! 382: mask <<= 1;
! 383: e -= dy;
! 384: }
! 385: (Scr_kluge *) a += width;
! 386: e += dx;
! 387: }
! 388: }
! 389: }
! 390: } else {
! 391: dx = -dx;
! 392: if ((dy = y2 - y1) > 0) {
! 393: if (dx > dy) { /* dx <= 0, dy > 0, dx > dy */
! 394: dy <<= 1;
! 395: e = dy - dx;
! 396: c = dx + 2;
! 397: dx <<= 1;
! 398:
! 399: while (--c) {
! 400: uPC_PLOT(a, mask);
! 401: if (e >= 0) {
! 402: (Scr_kluge *) a -= width;
! 403: e -= dx;
! 404: }
! 405: if (mask & 1) {
! 406: mask = uPC_HIGH_BIT;
! 407: a--;
! 408: } else
! 409: mask >>= 1;
! 410: e += dy;
! 411: }
! 412: } else { /* dx <= 0, dy > 0, dx <= dy */
! 413: dx <<= 1;
! 414: e = dx - dy;
! 415: c = dy + 2;
! 416: dy <<= 1;
! 417:
! 418: while (--c) {
! 419: uPC_PLOT(a, mask);
! 420: if (e >= 0) {
! 421: if (mask & 1) {
! 422: mask = uPC_HIGH_BIT;
! 423: a--;
! 424: } else
! 425: mask >>= 1;
! 426: e -= dy;
! 427: }
! 428: (Scr_kluge *) a -= width;
! 429: e += dx;
! 430: }
! 431: }
! 432: } else {
! 433: dy = -dy;
! 434: if (dx > dy) { /* dx <= 0, dy <= 0, dx > dy */
! 435: dy <<= 1;
! 436: e = dy - dx;
! 437: c = dx + 2;
! 438: dx <<= 1;
! 439:
! 440: while (--c) {
! 441: uPC_PLOT(a, mask);
! 442: if (e >= 0) {
! 443: (Scr_kluge *) a += width;
! 444: e -= dx;
! 445: }
! 446: if (mask & 1) {
! 447: mask = uPC_HIGH_BIT;
! 448: a--;
! 449: } else
! 450: mask >>= 1;
! 451: e += dy;
! 452: }
! 453: } else { /* dx <= 0, dy <= 0, dx <= dy */
! 454: dx <<= 1;
! 455: e = dx - dy;
! 456: c = dy + 2;
! 457: dy <<= 1;
! 458:
! 459: while (--c) {
! 460: uPC_PLOT(a, mask);
! 461: if (e >= 0) {
! 462: if (mask & 1) {
! 463: mask = uPC_HIGH_BIT;
! 464: a--;
! 465: } else
! 466: mask >>= 1;
! 467: e -= dy;
! 468: }
! 469: (Scr_kluge *) a += width;
! 470: e += dx;
! 471: }
! 472: }
! 473: }
! 474: }
! 475: }
! 476:
! 477:
! 478: #ifdef uPC_NOT_USED
! 479: /* Added by Russell Lang, eln272v@monu1.cc.monash.oz
! 480: This placement to the nearest character cell worked, and I'm leaving
! 481: it here so the calculations involved won't be lost! (jdc)
! 482: */
! 483: TERM_PUBLIC void uPC_put_text(x, y, str)
! 484: unsigned int x, y;
! 485: char str[];
! 486: {
! 487: /* This routine puts the text at the cursor location nearest
! 488: to (x,y). Obviously the exact postion would look better */
! 489:
! 490: /* Just use the ANSI escape sequence CUP (iswind said that was ok!) */
! 491: printf("\033[%d;%dH%s\033[25;1H",
! 492: (int) (24 - (y - uPC_VCHAR / 2) * 25 / uPC_YMAX),
! 493: (int) (x * 80 / uPC_XMAX), str);
! 494: fflush(stdout);
! 495: }
! 496:
! 497: #endif
! 498:
! 499:
! 500: TERM_PUBLIC void uPC_put_text(x, y, str)
! 501: unsigned int x, y;
! 502: char str[];
! 503: {
! 504: if (uPC_angle == 1)
! 505: x += uPC_VCHAR / 2;
! 506: else
! 507: y -= uPC_VCHAR / 2;
! 508:
! 509: switch (uPC_angle) {
! 510: case 0:
! 511: for (; *str; ++str, x += uPC_HCHAR)
! 512: uPC_putc(x, y, *str, uPC_angle);
! 513: break;
! 514: case 1:
! 515: for (; *str; ++str, y += uPC_HCHAR)
! 516: uPC_putc(x, y, *str, uPC_angle);
! 517: break;
! 518: }
! 519: }
! 520:
! 521:
! 522: void uPC_putc(x, y, c, angle)
! 523: unsigned int x, y;
! 524: int c, angle;
! 525: /*
! 526: Put a character at an x,y location in the bit map (using the fnt5x9
! 527: array. This is mostly just copied from the bitmap.c driver.
! 528: */
! 529: {
! 530: int i, j, k;
! 531: register Scr_type mask, *a;
! 532: char_row fc;
! 533: unsigned int pixelon;
! 534:
! 535: i = c - ' ';
! 536: for (j = 0; j < FNT5X9_VBITS; j++) {
! 537: fc = fnt5x9[i][j];
! 538: for (k = 0; k < FNT5X9_HBITS; k++) {
! 539: pixelon = ((unsigned int) (fc)) >> k & 1;
! 540: if (pixelon) {
! 541: switch (angle) {
! 542: case 0:
! 543: mask = lookup[x + k + 1 & 0x0f];
! 544: a = &uPC_display[(uPC_YSIZE - 1) - (y + j)][(x + k + 1) >> 4];
! 545: break;
! 546: case 1:
! 547: mask = lookup[x - j & 0x0f];
! 548: a = &uPC_display[(uPC_YSIZE - 1) - (y + k + 1)][(x - j) >> 4];
! 549: break;
! 550: }
! 551: *(a) |= (mask); /* see uPC_PLOT macro */
! 552: }
! 553: }
! 554: }
! 555: }
! 556:
! 557:
! 558: TERM_PUBLIC int uPC_text_angle(ang)
! 559: int ang;
! 560: {
! 561: uPC_angle = ang;
! 562: return TRUE;
! 563: }
! 564:
! 565:
! 566: TERM_PUBLIC void uPC_reset()
! 567: {
! 568: /* Reset window to normal size. */
! 569: uPC_fixwind(0);
! 570: }
! 571:
! 572:
! 573:
! 574: void uPC_fixwind(signo)
! 575: int signo;
! 576: {
! 577: static struct uwdata wreset =
! 578: {0, 12, 720, 288, 0x1};
! 579: struct utdata ut;
! 580:
! 581: /* Reset the window to the right size. */
! 582: ioctl(1, WIOCSETD, &wreset); /* 0, not wncur here! */
! 583:
! 584: /* Scroll the screen once. (avoids typing over the same line) */
! 585: putc('\n', stderr);
! 586:
! 587: if (signo) {
! 588: if (signo == SIGILL || signo == SIGTRAP || signo == SIGPWR)
! 589: signal(signo, SIG_DFL);
! 590: kill(0, signo); /* Redo the signal (as if we never trapped it). */
! 591: }
! 592: }
! 593: #endif /* TERM_BODY */
! 594:
! 595: #ifdef TERM_TABLE
! 596:
! 597: TERM_TABLE_START(unixpc_driver)
! 598: "unixpc", "AT&T 3b1 or AT&T 7300 Unix PC",
! 599: uPC_XMAX, uPC_YMAX, uPC_VCHAR, uPC_HCHAR,
! 600: uPC_VTIC, uPC_HTIC, options_null, uPC_init, uPC_reset,
! 601: uPC_text, null_scale, uPC_graphics, uPC_move, uPC_vector,
! 602: uPC_linetype, uPC_put_text, uPC_text_angle,
! 603: null_justify_text, line_and_point, do_arrow, set_font_null
! 604: TERM_TABLE_END(unixpc_driver)
! 605:
! 606: #undef LAST_TERM
! 607: #define LAST_TERM unixpc_driver
! 608:
! 609: #endif /* TERM_TABLE */
! 610: #endif /* TERM_PROTO_ONLY */
! 611:
! 612: #ifdef TERM_HELP
! 613: START_HELP(unixpc)
! 614: "1 unixpc",
! 615: "?commands set terminal unixpc",
! 616: "?set terminal unixpc",
! 617: "?set term unixpc",
! 618: "?terminal unixpc",
! 619: "?term unixpc",
! 620: "?unixpc",
! 621: " The `unixpc` terminal driver supports AT&T 3b1 and AT&T 7300 Unix PC. It has",
! 622: " no options."
! 623: END_HELP(unixpc)
! 624: #endif /* TERM_HELP */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>