1 /* Hello, Emacs, this is -*-C-*-
2 * $Id: unixpc.trm,v 1.14 2006/07/21 02:35:48 sfeam Exp $
6 /* GNUPLOT - unixpc.trm */
9 * Copyright 1990 - 1993, 1998, 2004
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.
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,
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
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.
34 * This software is provided "as is" without express or implied warranty
35 * to the extent permitted by applicable law.
39 * This file is included by ../term.c.
41 * This terminal driver supports:
47 * send your comments or suggestions to (gnuplot-info@lists.sourceforge.net).
52 >From: John Campbell (...!arizona!naucse!jdc)
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,
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.
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.
76 * adapted to the new terminal layout by Stefan Bodewig (Dec. 1995)
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, const char str[]));
93 TERM_PUBLIC int uPC_text_angle __PROTO((int ang));
94 TERM_PUBLIC void uPC_reset __PROTO((void));
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 */
103 #ifndef TERM_PROTO_ONLY
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>
112 #define uPC_HIGH_BIT (0x8000)
114 typedef unsigned short Scr_type;
115 typedef unsigned char Scr_kluge;
118 #define uPC_XSIZE 45 /* Short ints. */
119 #define uPC_YSIZE uPC_YMAX
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;
126 unsigned short uPC_raster_count = 0;
127 static Scr_type lookup[] =
129 0x0001, 0x0002, 0x0004, 0x0008,
130 0x0010, 0x0020, 0x0040, 0x0080,
131 0x0100, 0x0200, 0x0400, 0x0800,
132 0x1000, 0x2000, 0x4000, 0x8000,
135 #define uPC_XLAST (uPC_XMAX - 1)
136 #define uPC_YLAST (uPC_YMAX - 1)
139 static struct urdata uPC_ur = {
140 (unsigned short *) uPC_display,
141 2 * uPC_XSIZE, 0, 0, 0, 0, 0, 0,
142 uPC_XMAX, uPC_YMAX, SRCSRC, DSTOR, 0
145 #define IfErrOut(e1,e2,s1,s2) if (e1 e2) { \
146 fprintf(stderr, "%s:: %s %s\n", sys_errlist[errno], s1, s2); \
154 /* This routine will ioctl to change 0 size */
160 /* Check that we are on the bitmapped window. */
162 fputs("Sorry--must run from the bitmapped terminal\n", stderr);
165 for (i = 1; i <= 16; i++) {
166 if (i != SIGINT && i != SIGFPE) /* Two are caught in plot.c */
167 signal(i, uPC_fixwind);
170 /* Increase the screen size */
172 uw.uw_y = 0; /* Leave room for top status line. */
173 uw.uw_width = uPC_XMAX; /* 720 */
174 uw.uw_height = uPC_YMAX; /* 288 normal--we clobber 12 (top row) */
175 uw.uw_uflags = 1; /* Creates with no border */
177 IfErrOut(ioctl(1, WIOCSETD, &uw), <0, "ioctl failed on", "WIOCSETD");
184 /* This routine will clear the uPC_display buffer and window. */
185 register Scr_type *j;
188 j = (Scr_type *) uPC_display;
189 i = uPC_YSIZE * uPC_XSIZE + 1;
193 /* Position the cursor to the bottom of the screen so when we come back to
194 * text mode we are just below the graph.
196 fputs("\033[25;1H", stdout);
198 uPC_ur.ur_dstop = DSTSRC; /* replace (clear screen). */
199 IfErrOut(ioctl(1, WIOCRASTOP, &uPC_ur), <0,
200 "ioctl failed", "WIOCRASTOP");
201 uPC_ur.ur_dstop = DSTOR; /* Or in (show text) */
208 /* This routine will flush the display. */
210 IfErrOut(ioctl(1, WIOCRASTOP, &uPC_ur), <0,
211 "ioctl failed", "WIOCRASTOP");
216 uPC_linetype(int linetype)
218 /* This routine records the current linetype. */
219 if (uPC_cur_linetype != linetype) {
220 uPC_raster_count = 0;
221 uPC_cur_linetype = linetype;
227 uPC_move(unsigned int x, unsigned int y)
229 /* This routine just records x and y in uPC_sx, uPC_sy */
235 /* Was just (*(a)|=(b)) */
236 #define uPC_PLOT(a,b) (uPC_cur_linetype != 0 ? uPC_plot_word (a,b) :\
240 Weak attempt to make line styles. The real problem is the aspect
241 ratio. This routine is called only when a bit is to be turned on in
242 a horizontal word. A better line style routine would know something
243 about the slope of the line around the current point (in order to
246 This yields 3 working linetypes plus a usable axis line type.
249 uPC_plot_word(Scr_type *a, Scr_type b)
251 /* Various line types */
252 switch (uPC_cur_linetype) {
254 /* Distinguish between horizontal and vertical axis. */
255 if (uPC_sx > uPC_XMAX / 8 && uPC_sx < 7 * uPC_XMAX / 8) {
256 /* Fuzzy tolerance because we don't know exactly where the y axis is */
257 if (++uPC_raster_count % 2 == 0)
260 /* Due to aspect ratio, take every other y pixel and every third x. */
261 *(a) |= (b & 0x9999);
266 /* Make a | |----| |----| type of line. */
267 if ((1 << uPC_raster_count) & 0xF0F0)
269 if (++uPC_raster_count > 15)
270 uPC_raster_count = 0;
274 /* Make a |----|----|----|--- | | type of line. */
275 if ((1 << uPC_raster_count) & 0x0EFFF)
277 if (++uPC_raster_count > 19)
278 uPC_raster_count = 0;
282 /* Make a | - | - | - | - | type of line. */
283 if ((1 << uPC_raster_count) & 0x4444)
285 if (++uPC_raster_count > 15)
286 uPC_raster_count = 0;
297 uPC_vector(unsigned int x, unsigned int y)
299 /* This routine calls line with x,y */
300 int x1 = uPC_sx, y1 = uPC_sy, x2 = x, y2 = y;
301 register int c, e, dx, dy, width;
302 register Scr_type mask, *a;
304 /* Record new sx, sy for next call to the vector routine. */
308 a = &uPC_display[(uPC_YSIZE - 1) - y1][x1 >> 4];
309 mask = lookup[x1 & 0x0f];
312 if ((dx = x2 - x1) > 0) {
313 if ((dy = y2 - y1) > 0) {
314 if (dx > dy) { /* dx > 0, dy > 0, dx > dy */
323 (Scr_kluge *) a -= width;
326 if (mask & uPC_HIGH_BIT) {
333 } else { /* dx > 0, dy > 0, dx <= dy */
342 if (mask & uPC_HIGH_BIT) {
349 (Scr_kluge *) a -= width;
355 if (dx > dy) { /* dx > 0, dy <= 0, dx > dy */
364 (Scr_kluge *) a += width;
367 if (mask & uPC_HIGH_BIT) {
374 } else { /* dx > 0, dy <= 0, dx <= dy */
383 if (mask & uPC_HIGH_BIT) {
390 (Scr_kluge *) a += width;
397 if ((dy = y2 - y1) > 0) {
398 if (dx > dy) { /* dx <= 0, dy > 0, dx > dy */
407 (Scr_kluge *) a -= width;
417 } else { /* dx <= 0, dy > 0, dx <= dy */
433 (Scr_kluge *) a -= width;
439 if (dx > dy) { /* dx <= 0, dy <= 0, dx > dy */
448 (Scr_kluge *) a += width;
458 } else { /* dx <= 0, dy <= 0, dx <= dy */
474 (Scr_kluge *) a += width;
485 /* Added by Russell Lang, eln272v@monu1.cc.monash.oz
486 This placement to the nearest character cell worked, and I'm leaving
487 it here so the calculations involved won't be lost! (jdc)
490 uPC_put_text(unsigned int x, unsigned int y, const char str[])
492 /* This routine puts the text at the cursor location nearest
493 to (x,y). Obviously the exact postion would look better */
495 /* Just use the ANSI escape sequence CUP (iswind said that was ok!) */
496 printf("\033[%d;%dH%s\033[25;1H",
497 (int) (24 - (y - uPC_VCHAR / 2) * 25 / uPC_YMAX),
498 (int) (x * 80 / uPC_XMAX), str);
506 uPC_put_text(unsigned int x, unsigned int y, const char str[])
515 for (; *str; ++str, x += uPC_HCHAR)
516 uPC_putc(x, y, *str, uPC_angle);
519 for (; *str; ++str, y += uPC_HCHAR)
520 uPC_putc(x, y, *str, uPC_angle);
527 Put a character at an x,y location in the bit map (using the fnt5x9
528 array. This is mostly just copied from the bitmap.c driver.
531 uPC_putc(unsigned int x, unsigned int y, int c, int angle)
534 register Scr_type mask, *a;
536 unsigned int pixelon;
539 for (j = 0; j < FNT5X9_VBITS; j++) {
541 for (k = 0; k < FNT5X9_HBITS; k++) {
542 pixelon = ((unsigned int) (fc)) >> k & 1;
546 mask = lookup[x + k + 1 & 0x0f];
547 a = &uPC_display[(uPC_YSIZE - 1) - (y + j)][(x + k + 1) >> 4];
550 mask = lookup[x - j & 0x0f];
551 a = &uPC_display[(uPC_YSIZE - 1) - (y + k + 1)][(x - j) >> 4];
554 *(a) |= (mask); /* see uPC_PLOT macro */
562 uPC_text_angle(int ang)
564 uPC_angle = (ang ? 1 : 0);
572 /* Reset window to normal size. */
579 uPC_fixwind(int signo)
581 static struct uwdata wreset =
582 {0, 12, 720, 288, 0x1};
585 /* Reset the window to the right size. */
586 ioctl(1, WIOCSETD, &wreset); /* 0, not wncur here! */
588 /* Scroll the screen once. (avoids typing over the same line) */
592 if (signo == SIGILL || signo == SIGTRAP || signo == SIGPWR)
593 signal(signo, SIG_DFL);
594 kill(0, signo); /* Redo the signal (as if we never trapped it). */
597 #endif /* TERM_BODY */
601 TERM_TABLE_START(unixpc_driver)
602 "unixpc", "AT&T 3b1 or AT&T 7300 Unix PC",
603 uPC_XMAX, uPC_YMAX, uPC_VCHAR, uPC_HCHAR,
604 uPC_VTIC, uPC_HTIC, options_null, uPC_init, uPC_reset,
605 uPC_text, null_scale, uPC_graphics, uPC_move, uPC_vector,
606 uPC_linetype, uPC_put_text, uPC_text_angle,
607 null_justify_text, line_and_point, do_arrow, set_font_null
608 TERM_TABLE_END(unixpc_driver)
611 #define LAST_TERM unixpc_driver
613 #endif /* TERM_TABLE */
614 #endif /* TERM_PROTO_ONLY */
619 "?commands set terminal unixpc",
620 "?set terminal unixpc",
625 " The `unixpc` terminal driver supports AT&T 3b1 and AT&T 7300 Unix PC. It has",
628 #endif /* TERM_HELP */