|
|
1.1 root 1: #include <X/mit-copyright.h>
2:
3: /* Copyright 1984, 1985 Massachusetts Institute of Technology */
4: /* Tplot.c */
5:
6: #ifndef lint
7: static char *rcsid_Tplot_c = "$Header: Tplot.c,v 10.8 86/02/01 16:05:23 tony Rel $";
8: #endif lint
9:
10: #include <X/Xlib.h>
11: #include "ptyx.h"
12: #undef CTRL
13: #include <stdio.h>
14: #include <sys/file.h>
15: #include <sgtty.h>
16: #include <pwd.h>
17: #undef CTRL
18:
19: extern debug;
20:
21: static int bplot[5];
22: static int nplot;
23: static int ipchr;
24: static int refresh;
25: static int LoYSet;
26:
27: #define MAX_PTS 150
28: #define MAX_VTX 300
29: static Vertex Tline[MAX_VTX];
30: static Vertex *line_pt;
31:
32: static FILE *rfile, *wfile;
33:
34: static TekLink *TekBuf = NULL;
35: TekLink *tb_end_link = NULL; /* world accessible for TekBufPut */
36: int tb_end = TEK_LINK_BLOCK_SIZE; /* world accessible for TekBufPut */
37: static TekLink *tb_pt_link = NULL;
38: static int tb_pt = TEK_LINK_BLOCK_SIZE;
39:
40: #include "../cursors/tcross.cursor"
41: #include "../cursors/tcross_mask.cursor"
42:
43: TekErase (term)
44:
45: /* Reset buffer pointer for display list to start of buffer */
46:
47: Terminal *term;
48: {
49: register Screen *screen = &term->screen;
50: register struct _TekLink *pnt;
51: register struct _TekLink *next;
52:
53: pnt = (struct _TekLink *) TekBuf;
54:
55: /* free stored list */
56: while (pnt)
57: {
58: next = pnt->next;
59: free (pnt);
60: pnt = next;
61: }
62:
63: /* reset pointers */
64: TekBuf = tb_end_link = tb_pt_link = NULL;
65: tb_end = tb_pt = TEK_LINK_BLOCK_SIZE;
66:
67: refresh = 0;
68: screen->cur_x = 0;
69: screen->cur_y = 0;
70: screen->TekGMode = 0;
71: screen->TekAMode = 0;
72: LoYSet = 0;
73:
74: if (debug) wfile = fopen ("testbufw","w");
75:
76: return;
77: }
78:
79:
80: TekRefresh (term)
81:
82: /* Redisplay graphics screen, including positioned alpha strings */
83:
84: register Terminal *term;
85: {
86: register Screen *screen = &term->screen;
87: Window window = screen->window;
88: Font fnt = screen->fnt_norm;
89: int chr, nstr;
90: register int ch;
91: unsigned char str[257];
92: int modeG = screen->TekGMode, modeA = screen->TekAMode,
93: modeI = screen->TekIMode, modeP = screen->TekPMode;
94:
95: TekBufResetPt ();
96:
97: if (TekBufEmpty ()) return;
98:
99: if (debug) rfile = fopen ("testbufr","w");
100:
101: refresh = 1;
102: TekAlph (term,0);
103: screen->cur_x = screen->cur_y = 0;
104:
105: while (TekBufGet (&chr) != -1)
106: {
107: ch = chr; /* lets get the char into a register */
108: if (screen->TekGMode)
109: {
110: if (ch > 31)
111: {
112: if (screen->TekIMode) TekPoint (term,ch);
113: else TekPlot (term,ch);
114: }
115: else if (ch > 27 && ch < 31) TekInit (term,ch);
116: else if (ch == 31 || ch < 28) TekAlph (term,0);
117: continue;
118: }
119:
120: if (ch > 27 && ch < 31)
121: {
122: TekInit (term, ch);
123: continue;
124: }
125:
126: if (ch > (unsigned) 128)
127: {
128: nstr = ch - (unsigned) 128;
129:
130: if (debug)
131: {
132: fprintf (rfile,"alpha mode %d chars\n",nstr);
133: fflush (rfile);
134: }
135:
136: if (nstr > 256) exit (77);
137: TekBufGetString (str, nstr);
138: *(str + nstr) = NULL;
139:
140: XTextMask ( window,
141: TCursorX(screen), TCursorY(screen),
142: str, nstr, fnt, screen->foreground);
143:
144: screen->cur_X += (nstr * screen->f_width);
145: screen->cur_x +=
146: (nstr * screen->f_width / screen->TekScale);
147: }
148: }
149:
150: if (nplot > 0) TekFlush (term);
151: refresh = 0;
152:
153: screen->TekGMode = modeG;
154: screen->TekAMode = modeA;
155: screen->TekIMode = modeI;
156: screen->TekPMode = modeP;
157: }
158:
159:
160: TekString (term, str, nchr)
161:
162: /* Display positioned alphanumeric string, saving it in display list */
163:
164: register Terminal *term;
165: unsigned char *str;
166: int nchr;
167: {
168: register Screen *screen = &term->screen;
169: Window window = screen->window;
170: Font fnt = screen->fnt_norm;
171:
172: TekBufPut (128 + nchr);
173: if (debug)
174: {
175: fprintf (wfile,"alpha mode %d character string\n",nchr);
176: fflush (wfile);
177: }
178:
179: TekBufPutString (str, nchr);
180:
181: XTextMask (window,
182: TCursorX(screen), TCursorY(screen),
183: str, nchr, fnt, screen->foreground);
184:
185: screen->cur_X = screen->cur_X + (nchr * screen->f_width);
186: screen->cur_x = screen->cur_x +
187: (nchr * screen->f_width / screen->TekScale);
188: }
189:
190: TekBufResetPt ()
191: /* set pt to point to beginning of buffer */
192: {
193: tb_pt_link = TekBuf;
194: tb_pt = 0;
195: }
196:
197: TekBufEmpty ()
198: /* return nonzero iff TekBuf is empty */
199: {
200: return (((tb_end & ~TEK_LINK_BLOCK_SIZE) == 0)
201: && (tb_end_link == TekBuf));
202: }
203:
204:
205: /* Extend display buffer */
206: TekBufExtend ()
207: {
208:
209: /* if TekBuf is NULL then must initialize */
210: if (!TekBuf)
211: {
212: TekBuf = (TekLink *) malloc (sizeof (TekLink));
213: TekBuf->next = NULL;
214: tb_end_link = TekBuf;
215: tb_end = 0;
216: }
217: else
218: {
219: tb_end_link->next =
220: (struct _TekLink *) malloc (sizeof (TekLink));
221: tb_end_link = (TekLink *) tb_end_link->next;
222: tb_end_link->next = NULL;
223: tb_end = 0;
224: }
225: }
226:
227: /*
228: effect: puts len bytes at str into display buffer
229: */
230: TekBufPutString (str, len)
231: register unsigned char *str;
232: register int len;
233: {
234: register int amount;
235:
236: while (len)
237: {
238: if (tb_end & TEK_LINK_BLOCK_SIZE) TekBufExtend ();
239:
240: amount = TEK_LINK_BLOCK_SIZE - tb_end;
241: if (amount > len) amount = len;
242:
243: bcopy (str, tb_end_link->data + tb_end, amount);
244: str += amount;
245: len -= amount;
246: tb_end += amount;
247: }
248: }
249:
250:
251: /* Read character from display list */
252:
253: int TekBufGet (chr)
254: register unsigned int *chr;
255: {
256: if (tb_pt & TEK_LINK_BLOCK_SIZE)
257:
258: /* if tb_pt_link is NULL then check for a TekBuf */
259: if (!tb_pt_link)
260: {
261: if (!TekBuf) return (-1);
262: tb_pt_link = TekBuf;
263: tb_pt = 0;
264: }
265: else
266: if (tb_pt_link->next == NULL) return (-1);
267: else
268: {
269: tb_pt_link = (TekLink *) tb_pt_link->next;
270: tb_pt = 0;
271: }
272:
273: if ((tb_pt_link == tb_end_link) && (tb_pt >= tb_end)) return (-1);
274:
275: *chr = tb_pt_link->data [tb_pt++];
276: return (0);
277: }
278:
279: /* store next len characters of TekBuf in str, advancing tb_pt */
280: TekBufGetString (str, len)
281: register char *str;
282: register int len;
283: {
284: register int n;
285:
286: while (len)
287: {
288: n = TEK_LINK_BLOCK_SIZE - tb_pt;
289: n = (n < len) ? n : len;
290:
291: bcopy (tb_pt_link->data + tb_pt, str, n);
292: tb_pt += n;
293: len -= n;
294: str += n;
295:
296: if (tb_pt == TEK_LINK_BLOCK_SIZE)
297: {
298: if (tb_pt_link->next == NULL) return;
299: tb_pt_link = (TekLink *) tb_pt_link->next;
300: tb_pt = 0;
301: }
302: }
303: }
304:
305: /* Switch to graphics mode and initialize byte and point counters */
306:
307: TekInit (term,chr)
308: Terminal *term;
309: register int chr;
310: {
311: register Screen *screen = &term->screen;
312:
313: if (debug)
314: if (!refresh)
315: {
316: fprintf (wfile,"switching to graphics mode %d\n",chr);
317: fflush (wfile);
318: }
319: else
320: {
321: fprintf (rfile,"switching to graphics mode %d\n",chr);
322: fflush (rfile);
323: }
324:
325: if (!screen->TekGMode && nplot > 0) TekFlush (term);
326:
327: screen->pen = 0;
328: ipchr = 0;
329: screen->TekPMode = 0;
330: screen->TekIMode = 0;
331: if (chr == 28) screen->TekPMode = 1;
332: if (chr == 30) screen->TekIMode = 1;
333:
334: if (!refresh) TekBufPut (chr);
335: if (screen->TekGMode) return;
336:
337: nplot = 0;
338: screen->TekGMode = 1;
339: screen->TekAMode = 1;
340: /*
341: * screen->cur_row = 0;
342: * screen->cur_col = 0;
343: */
344: line_pt = Tline;
345: }
346:
347: TekAlph (term,chr)
348:
349: /* Switch back to alphanumeric mode from graphics mode */
350:
351: Terminal *term;
352: int chr;
353: {
354: register Screen *screen = &term->screen;
355:
356: if (!screen->TekGMode) return;
357:
358: if (debug)
359: if (!refresh)
360: {
361: fprintf (wfile,"switching to alpha mode %d\n",chr);
362: fflush (wfile);
363: }
364: else
365: {
366: fprintf (rfile,"switching to alpha mode %d\n",chr);
367: fflush (rfile);
368: }
369:
370: if (!refresh) TekBufPut (chr);
371: if (nplot > 0) TekFlush (term);
372:
373: screen->TekGMode = 0;
374: screen->TekPMode = 0;
375: screen->TekIMode = 0;
376: if (chr>0 && chr != 31) TekReset(term);
377: return;
378: }
379:
380:
381: TekReset (term)
382:
383: /* Switch back to vt100 alphanumeric mode from Tektronix alphanumeric mode
384: * This allows alphanumeric strings to be positioned by graphics commands,
385: * but reenables scrolling after CR or LF. */
386:
387: Terminal *term;
388: {
389: register Screen *screen = &term->screen;
390: int fh = screen->f_height;
391: int fw = screen->f_width;
392:
393: screen->TekAMode = 0;
394:
395: if (debug)
396: if (!refresh)
397: {
398: fprintf (wfile,"resetting to alpha mode\n");
399: fflush (wfile);
400: }
401: else
402: {
403: fprintf (rfile,"resetting to alpha mode\n");
404: fflush (rfile);
405: }
406:
407: if (screen->cur_Y > 0)
408: {
409: screen->cur_row = (screen->cur_Y - (fh >> 1)) / fh;
410: if (screen->cur_row > screen->max_row)
411: screen->cur_row = screen->max_row;
412: screen->cur_Y = 0;
413: }
414: if (screen->cur_X > 0)
415: {
416: screen->cur_col = (screen->cur_X + (fw >> 1)) / fw;
417: if (screen->cur_col > screen->max_col)
418: screen->cur_col = screen->max_col;
419: screen->cur_X = 0;
420: }
421: screen->cur_x = 0;
422: screen->cur_y = 0;
423:
424: return;
425: }
426:
427:
428: TekCursor (term)
429:
430: /* Reads position of mouse cursor when a character is typed and returns
431: * it in Tektronix-format coordinates */
432:
433: Terminal *term;
434: {
435: register Screen *screen = &term->screen;
436: Keyboard *keyboard = &term->keyboard;
437: register Window window = screen->window;
438: int MouseX, MouseY;
439: XEvent reply;
440: XEvent *rep = &reply;
441: Window subw;
442: int pty = screen->respond;
443: int keycode, event, shifts;
444: short c;
445: char cplot [5];
446: extern int wflush ();
447: int x, y;
448: Cursor cursor;
449: char *string = " ";
450: int nbytes;
451:
452: TekAlph (term, 0);
453: TekReset (term);
454:
455: /* Set cross-hair cursor raster array */
456: cursor = XCreateCursor(tcross_width, tcross_height,
457: tcross_bits, tcross_bits, 7, 7,
458: screen->foreground, screen->background, GXxor);
459:
460: /* Display cross-hair cursor */
461: XDefineCursor(window, cursor);
462:
463: /* reselect input. Must be careful not to leave stray button
464: * events upon return since handle buttons would be invoked */
465:
466: XSelectInput (window, ButtonReleased | KeyPressed);
467:
468: /* Wait for keyboard entry */
469: XWindowEvent (window, KeyPressed | ButtonReleased, &reply);
470:
471: keycode = ((XKeyOrButtonEvent *)rep)->detail;
472: event = reply.type;
473:
474: /* Get current mouse position and translate to screen coordinates */
475: XUpdateMouse (window, &MouseX, &MouseY, &subw);
476:
477: x = ((MouseX - screen->border) << 1);
478: y = 782 - ((MouseY - screen->border) << 1);
479: screen->cur_X = MouseX;
480: screen->cur_Y = MouseY;
481:
482: /* Translate x and y to Tektronix code */
483: cplot[1] = 32 + (x >> 5);
484: cplot[2] = 32 + (x & 31);
485: cplot[3] = 32 + (y >> 5);
486: cplot[4] = 32 + (y & 31);
487:
488: /* Translate keyboard entry and return one byte from terminal */
489: if (event == KeyPressed)
490: {
491: string = XLookupMapping ((XKeyPressedEvent *)& reply, &nbytes);
492: c = *string;
493: }
494: else c = keycode + 48;
495:
496: cplot[0] = c;
497:
498: /* Return encode screen coordinates */
499: write (pty, cplot, 5 * sizeof (char));
500:
501: /* Reset cursor and return */
502:
503: XFreeCursor(cursor);
504: XDefineCursor(window,
505: (term->flags & INVERSE) ? screen->rcurs : screen->curs);
506:
507:
508: TekInit (term,0);
509:
510: XSelectInput (window, KeyPressed | ExposeWindow | ExposeRegion |
511: ExposeCopy | ButtonPressed | ButtonReleased);
512: }
513:
514:
515: TekPlot (term,chr)
516:
517: /* Translates Tektronix byte-encoded screen coordinates to integer screen
518: * coordinates each time the final byte of a coordinate set is encountered. */
519:
520: Terminal *term;
521: register int chr;
522: {
523: register Screen *screen = &term->screen;
524: register int *bp = bplot;
525: register int x, y;
526:
527: ipchr++;
528: if (ipchr > 5)
529: {
530: TekAlph (term,chr);
531: return;
532: }
533:
534: /* decode Tektronix byte position codes */
535:
536: if (chr < 64)
537: {
538: if (LoYSet) /* 4st byte */
539: {
540: bp[3] = chr & ~32;
541: }
542: else /* 1st byte */
543: {
544: bp[0] = chr & ~32;
545: bp[1] = 0;
546: }
547: }
548: else if (chr > 95)
549: {
550: if (LoYSet) /* 2nd byte */
551: { /* 3rd if 2nd present */
552: bp[1] = bp[2];
553: bp[2] = chr & ~96;
554: }
555: else /* 3rd byte */
556: {
557: bp[2] = chr & ~96;
558: bp[1] = 0;
559: LoYSet = 1;
560: }
561: }
562: else /* 5th byte */
563: {
564: bp[4] = chr & ~64;
565: ipchr = 0;
566: LoYSet = 0;
567:
568: /* compute screen x and y coordinates ignoring extended
569: * precision byte */
570:
571: y = (bp[0] << 7) + (bp[2] << 2);
572: x = (bp[3] << 7) + (bp[4] << 2);
573:
574: /* add in 4014 extended precision byte */
575: if (bp[1] > 0)
576: {
577: x += (bp [1] & 3);
578: y += ((bp [1] & 12) >> 2);
579: }
580:
581: /* Check to make sure screen limits are not exceeded */
582: if (y > 3127) y = 3127;
583:
584: /* transfer this point to vertex array */
585: if (screen->TekPMode)
586: {
587: TekDraw (0, x, y, term);
588: TekDraw (1, x, y, term);
589: }
590: else
591: {
592: TekDraw (screen->pen, x, y, term);
593: screen->pen = 1;
594: }
595: }
596: }
597:
598:
599: TekPoint (term,chr)
600:
601: /* Translates Tektronix byte-encoded incremental plot commands to screen
602: * coordinates and writes them to the vector buffer */
603:
604: register Terminal *term;
605: register int chr;
606: {
607: Screen *screen = &term->screen;
608: register int pen,x,y;
609:
610: x = screen->cur_x;
611: y = screen->cur_y;
612: pen = screen->pen;
613:
614: if (nplot == 0) TekDraw (0,x,y,term);
615:
616: switch (chr)
617: {
618: case ' ': screen->pen = 0;
619: break;
620:
621: case 'P': screen->pen = 1;
622: break;
623:
624: case 'D': TekDraw (pen, x, ++y, term);
625: break;
626:
627: case 'E': TekDraw (pen, ++x, ++y, term);
628: break;
629:
630: case 'A': TekDraw (pen, ++x, y, term);
631: break;
632:
633: case 'I': TekDraw (pen, ++x, --y, term);
634: break;
635:
636: case 'H': TekDraw (pen, x, --y, term);
637: break;
638:
639: case 'J': TekDraw (pen, --x, --y, term);
640: break;
641:
642: case 'B': TekDraw (pen, --x, y, term);
643: break;
644:
645: case 'F': TekDraw (pen, --x, ++y, term);
646: break;
647:
648: }
649: }
650:
651:
652: TekDraw (pen, x, y, term)
653:
654: /* Translates Tektronix screen coordinates to vs100 screen
655: * coordinates, drawing them to the screen when a buffer is filled */
656:
657: int x,y,pen;
658: Terminal *term;
659: {
660: register Screen *screen = &term->screen;
661: register Vertex *lp = line_pt;
662:
663: screen->cur_x = x;
664: screen->cur_y = y;
665:
666: /* convert to vs100 window coordinates */
667: screen->cur_X = (x + 1) * screen->TekScale + screen->border;
668: screen->cur_Y = (3128 - y) * screen->TekScale + screen->border;
669:
670: /* write to plot buffer */
671: lp->x = screen->cur_X;
672: lp->y = screen->cur_Y;
673:
674: if (pen) lp->flags = VertexDrawLastPoint;
675: else lp->flags = VertexDontDraw;
676:
677: lp = ++line_pt;
678: nplot++;
679:
680: if (debug)
681: if (refresh) fprintf (rfile,"%d: %d %d,%d -> %d,%d\n",
682: nplot,pen,x,y,screen->cur_X,screen->cur_Y);
683: else fprintf (wfile,"%d: %d %d,%d -> %d,%d\n",
684: nplot,pen,x,y,screen->cur_X,screen->cur_Y);
685: if (debug)
686: if (refresh) fflush (rfile);
687: else fflush (wfile);
688:
689: /* draw line if buffer limit has been reached */
690: if (nplot >= MAX_PTS)
691: {
692: TekFlush (term);
693: lp = line_pt;
694: lp->x = screen->cur_X;
695: lp->y = screen->cur_Y;
696: lp->flags = VertexDontDraw;
697: line_pt++;
698: nplot++;
699: }
700: }
701:
702:
703: TekFlush (term)
704:
705: register Terminal *term;
706: {
707: Window window = term->screen.window;
708:
709: XDraw (window, Tline, nplot, 1, 1, term->screen.foreground, GXcopy,
710: AllPlanes);
711: nplot = 0;
712:
713: line_pt = Tline;
714: }
715:
716: TekInq (term)
717: /* Reports position of cursor in Tektronix-format coordinates */
718: Terminal *term;
719: {
720: register Screen *screen = &term->screen;
721: int pty = screen->respond;
722: char cplot [5];
723: int x, y;
724: x = ((screen->cur_X - screen->border) << 1);
725: y = 782 - ((screen->cur_Y - screen->border) << 1);
726: /* Translate x and y to Tektronix code */
727: cplot[1] = 32 + (x >> 5);
728: cplot[2] = 32 + (x & 31);
729: cplot[3] = 32 + (y >> 5);
730: cplot[4] = 32 + (y & 31);
731: cplot[0] = '%'; /* standard hardware config */
732: /* Return encoded screen coordinates */
733: write (pty, cplot, 5 * sizeof (char));
734: }
735:
736: #ifdef ENABLE_PRINT
737:
738: #include <signal.h>
739:
740: TekPrint ()
741:
742: /* Dump graphics screen, including positioned alpha strings */
743:
744: {
745: int chr, pid, uid, i;
746: char c;
747: FILE *tekfile;
748: char *uname, tekfile_name[40];
749: struct passwd *upasswd;
750: int temp_tb_pt = tb_pt;
751: TekLink *temp_tb_pt_link = tb_pt_link;
752:
753: TekBufResetPt ();
754: if (TekBufEmpty ()) return;
755:
756: pid = getpid ();
757: uid = getuid ();
758: upasswd = getpwuid (uid);
759: sprintf (tekfile_name,"/tmp/vst%d\.%s\0",pid,upasswd->pw_name);
760:
761: tekfile = fopen (tekfile_name,"w");
762:
763: while (TekBufGet (&chr) != -1)
764: {
765: c = chr;
766: if (chr < 128) putc (c,tekfile);
767: }
768:
769: tb_pt = temp_tb_pt;
770: tb_pt_link = temp_tb_pt_link;
771:
772: fclose (tekfile);
773:
774: if (debug) printf ("attempting fork\n");
775:
776: switch (fork ())
777: {
778: case -1: Error ();
779: break;
780:
781: case 0: for (i= 0; i < _NFILE; i++) close (i);
782: signal(SIGCHLD, SIG_DFL);
783: signal(SIGTERM, SIG_DFL);
784: signal(SIGHUP, SIG_IGN);
785: execlp("imtek", "imtek", "-x",tekfile_name, 0);
786: exit (1);
787: break;
788:
789: default:
790: break;
791: }
792: }
793:
794: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.