home *** CD-ROM | disk | FTP | other *** search
- /* $Id: tek.c,v 1.32 1994/08/26 19:21:55 mjl Exp $
- * $Log: tek.c,v $
- * Revision 1.32 1994/08/26 19:21:55 mjl
- * Added support for the Conex vt320 Tek4010/4014/4105 terminal emulator (DOS).
- * Much cleaning up and optimizations. Contributed by Mark Olesen.
- *
- * Revision 1.31 1994/07/23 04:44:27 mjl
- * Added conditional compilation of atexit() code based on STDC_HEADERS.
- *
- * Revision 1.30 1994/07/22 22:21:28 mjl
- * Eliminated a gcc -Wall warning.
- *
- * Revision 1.29 1994/07/19 22:30:29 mjl
- * All device drivers: enabling macro renamed to PLD_<driver>, where <driver>
- * is xwin, ps, etc. See plDevs.h for more detail.
- *
- * Revision 1.28 1994/06/30 17:52:35 mjl
- * Made another pass to eliminate warnings when using gcc -Wall, especially
- * those created by changing a PLINT from a long to an int.
- *
- * Revision 1.27 1994/06/24 04:38:35 mjl
- * Greatly reworked the POSIX_TTY code that puts the terminal into cbreak
- * mode. Now, initially both the original and modified terminal states are
- * saved. When the terminal goes into graphics mode, it is also put into
- * cbreak mode. This ensures that the program gets character-at-a-time
- * input, which is good for quitting <Q> PLplot or for paging in plrender.
- * When the terminal goes into text mode, the original terminal state
- * (canonical input, typically) is restored, which is good for reading user
- * input or command interpreters. Just make sure you use plgra() and
- * pltext() for switching; if you switch the terminal locally it may get
- * confused until the next plgra() or pltext().
- *
- * Revision 1.26 1994/06/23 22:32:07 mjl
- * Now ensures that device is in graphics mode before issuing any graphics
- * instruction.
- */
-
- /* tek.c
-
- PLPLOT tektronix device & emulators driver.
- */
- #include "plDevs.h"
-
- #if defined(PLD_xterm) || /* xterm */ \
- defined(PLD_tek4010) || /* TEK 4010 */ \
- defined(PLD_tek4107) || /* TEK 4107 */ \
- defined(PLD_mskermit) || /* MS-kermit emulator */ \
- defined(PLD_versaterm) || /* Versaterm emulator */ \
- defined(PLD_vlt) || /* VLT emulator */ \
- defined(PLD_conex) /* conex emulator 4010/4014/4105 */
-
- #include "plplotP.h"
- #include "drivers.h"
- #include "plevent.h"
-
- #include <ctype.h>
-
- /* Static function prototypes */
-
- static void WaitForPage (PLStream *pls);
- static void EventHandler (PLStream *pls, int input_char);
- static void tek_init (PLStream *pls);
- static void tek_text (PLStream *pls);
- static void tek_graph (PLStream *pls);
- static void fill_polygon (PLStream *pls);
- static void encode_int (char *c, int i);
- static void encode_vector (char *c, int x, int y);
- static void tek_vector (PLStream *pls, int x, int y);
- static void scolor (int icol, int r, int g, int b);
- static void setcmap (PLStream *pls);
-
- /* Stuff for handling tty cbreak mode */
-
- #ifdef POSIX_TTY
-
- #include <termios.h>
- #include <unistd.h>
-
- static struct termios termios_cbreak, termios_reset;
- static enum { RESET, CBREAK } ttystate = RESET;
-
- static void tty_atexit (void);
- static void tty_setup (void);
- static int tty_cbreak (void);
- static int tty_reset (void);
- #endif
-
- /* Pixel settings */
-
- #define TEKX 1023
- #define TEKY 779
-
- /* Graphics control characters. */
-
- #define BEL_CHAR '\007' /* BEL char = ^G = 7 */
- #define CLEAR_VIEW "\033\f" /* clear the view = ESC FF */
-
- #define ALPHA_MODE "\037" /* Enter Alpha mode = US */
- #define VECTOR_MODE "\035" /* Enter Vector mode = GS */
- #define GIN_MODE "\033\032" /* Enter GIN mode = ESC SUB */
- #define XTERM_VTMODE "\033\003" /* End Tek mode (xterm) = ESC ETX */
-
- /* Static vars */
-
- enum {tek4010, tek4105, tek4107, xterm, mskermit, vlt, versaterm};
-
- static exit_eventloop = 0;
- static int curcolor;
-
- /* color for MS-DOS Kermit v2.31 (and up) tektronix emulator
- * 0 = normal, 1 = bright
- * foreground color (30-37) = 30 + colors
- * where colors are 1=red, 2=green, 4=blue
- */
- #ifdef PLD_mskermit
- static char *kermit_color[15]= {
- "0;30","0;37",
- "0;32","0;36","0;31","0;35",
- "1;34","1;33","1;31","1;37",
- "1;35","1;32","1;36","0;34",
- "0;33"};
- #endif
- /*----------------------------------------------------------------------*\
- * plD_init_xterm() xterm
- * plD_init_tekt() Tek 4010 terminal
- * plD_init_tekf() Tek 4010 file
- * plD_init_tek4107t() Tek 4105/4107 terminal
- * plD_init_tek4107f() Tek 4105/4107 file
- * plD_init_mskermit() MS-Kermit emulator (DOS)
- * plD_init_vlt() VLT emulator (Amiga)
- * plD_init_versaterm() VersaTerm emulator (Mac)
- * plD_init_conex() Conex vt320/Tek 4105 emulator (DOS)
- *
- * Initialize device. These just set attributes for the particular
- * tektronix device, then call tek_init(). The following attributes can
- * be set:
- *
- * pls->termin if a terminal device
- * pls->color if color (1), if only fixed colors (2)
- * pls->dev_fill0 if can handle solid area fill
- * pls->dev_fill1 if can handle pattern area fill
- *
- \*----------------------------------------------------------------------*/
-
- #ifdef PLD_xterm
- void
- plD_init_xterm(PLStream *pls)
- {
- pls->dev_minor = xterm;
- pls->termin = 1;
- tek_init(pls);
- }
- #endif /* xterm */
-
- #if defined (PLD_tek4010)
- void
- plD_init_tekt(PLStream *pls)
- {
- pls->termin = 1;
- plD_init_tekf(pls);
- }
-
- void
- plD_init_tekf(PLStream *pls)
- {
- pls->dev_minor = tek4010;
- tek_init(pls);
- }
- #endif /* PLD_tek4010 (term & file) */
-
-
- #if defined (PLD_tek4107)
- void
- plD_init_tek4107t(PLStream *pls)
- {
- pls->termin = 1;
- plD_init_tek4107f(pls);
- }
-
- void
- plD_init_tek4107f(PLStream *pls)
- {
- pls->dev_minor = tek4107;
- pls->color = 1;
- pls->dev_fill0 = 1;
- tek_init(pls);
- }
- #endif /* PLD_tek4107 (term & file) */
-
- #ifdef PLD_mskermit
- void
- plD_init_mskermit(PLStream *pls)
- {
- pls->dev_minor = mskermit;
- pls->termin = 1;
- pls->color = 1;
- pls->dev_fill0 = 1;
- tek_init(pls);
- }
- #endif /* PLD_mskermit */
-
- #ifdef PLD_vlt
- void
- plD_init_vlt(PLStream *pls)
- {
- pls->dev_minor = vlt;
- pls->termin = 1;
- pls->color = 1;
- pls->dev_fill0 = 1;
- tek_init(pls);
- }
- #endif /* PLD_vlt */
-
- #ifdef PLD_versaterm
- void
- plD_init_versaterm(PLStream *pls)
- {
- pls->dev_minor = versaterm;
- pls->termin = 1;
- pls->color = 1;
- pls->dev_fill0 = 1;
- tek_init(pls);
- }
- #endif /* PLD_versaterm */
-
- #ifdef PLD_conex
- void
- plD_init_conex(PLStream *pls)
- {
- pls->dev_minor = xterm; /* responds to xterm escape codes */
- pls->termin = 1;
- pls->color = 2; /* only fixed colours */
- tek_init(pls);
- }
- #endif /* PLD_conex */
-
- /*----------------------------------------------------------------------*\
- * tek_init()
- *
- * Generic tektronix device initialization.
- \*----------------------------------------------------------------------*/
-
- static void
- tek_init(PLStream *pls)
- {
- PLDev *dev;
-
- pls->icol0 = 1;
- pls->width = 1;
- pls->bytecnt = 0;
- pls->page = 0;
- pls->graphx = TEXT_MODE;
- curcolor = 1;
-
- /* Allocate and initialize device-specific data */
-
- dev = plAllocDev(pls);
-
- dev->xold = UNDEFINED;
- dev->yold = UNDEFINED;
- dev->xmin = 0;
- dev->ymin = 0;
- dev->xmax = TEKX * 16;
- dev->ymax = TEKY * 16;
- dev->pxlx = 4.771 * 16;
- dev->pxly = 4.653 * 16;
-
- plP_setpxl(dev->pxlx, dev->pxly);
- plP_setphy(dev->xmin, dev->xmax, dev->ymin, dev->ymax);
-
- /* Terminal/file initialization */
-
- if (pls->termin) {
- pls->OutFile = stdout;
- #ifdef POSIX_TTY
- tty_setup();
- #endif
- }
- else {
- plFamInit(pls);
- plOpenFile(pls);
- }
-
- switch (pls->dev_minor) {
- #ifdef PLD_tek4107
- case tek4107:
- pls->graphx = GRAPHICS_MODE;
- fprintf(pls->OutFile, "\033%%!0"); /* set tek mode */
- fprintf(pls->OutFile, "\033KN1"); /* clear the view */
- fprintf(pls->OutFile, "\033LZ"); /* clear dialog buffer */
- fprintf(pls->OutFile, "\033ML1"); /* set default color */
- break;
- #endif /* PLD_tek4107 */
-
- /* A sneaky hack: VLT sometimes has leftover panel information, causing
- * garbage at the beginning of a sequence of color fills. Since
- * there is no clear panel command, instead I set the fill color to the
- * same as background and issue an end panel command.
- */
- #ifdef PLD_vlt
- case vlt:{
- char fillcol[4];
- tek_graph(pls);
- encode_int(fillcol, 0);
- fprintf(pls->OutFile, "\033MP%s\033LE", fillcol);
- break;
- }
- #endif /* PLD_vlt */
-
- default:
- tek_graph(pls);
- }
-
- /* Initialize palette */
-
- if ( pls->color & 0x01 ) {
- printf("\033TM111"); /* Switch to RGB colors */
- setcmap(pls);
- }
-
- /* Finish initialization */
-
- fprintf(pls->OutFile, VECTOR_MODE); /* Enter vector mode */
- if (pls->termin)
- fprintf(pls->OutFile, CLEAR_VIEW);/* erase and home */
-
- fflush(pls->OutFile);
- }
-
- /*----------------------------------------------------------------------*\
- * plD_line_tek()
- *
- * Draw a line from (x1,y1) to (x2,y2).
- \*----------------------------------------------------------------------*/
-
- void
- plD_line_tek(PLStream *pls, short x1a, short y1a, short x2a, short y2a)
- {
- PLDev *dev = (PLDev *) pls->dev;
- short x1 = x1a >> 4,
- y1 = y1a >> 4,
- x2 = x2a >> 4,
- y2 = y2a >> 4;
-
- tek_graph(pls);
-
- /* If continuation of previous line just send new point */
-
- if (x1 != dev->xold || y1 != dev->yold) {
- fprintf(pls->OutFile, VECTOR_MODE);
- pls->bytecnt++;
- tek_vector(pls, x1, y1);
- }
- tek_vector(pls, x2, y2);
-
- dev->xold = x2;
- dev->yold = y2;
- }
-
- /*----------------------------------------------------------------------*\
- * plD_polyline_tek()
- *
- * Draw a polyline in the current color.
- \*----------------------------------------------------------------------*/
-
- void
- plD_polyline_tek(PLStream *pls, short *xa, short *ya, PLINT npts)
- {
- PLINT i;
- PLDev *dev = (PLDev *) pls->dev;
- short x = xa[0] >> 4, y = ya[0] >> 4;
-
- tek_graph(pls);
-
- /* If continuation of previous line just send new point */
-
- if ( x != dev->xold || y != dev->yold ) {
- fprintf(pls->OutFile, VECTOR_MODE);
- pls->bytecnt++;
- tek_vector(pls, x, y);
- }
- for (i = 1; i < npts; i++) {
- tek_vector(pls, xa[i] >> 4, ya[i] >> 4 );
- }
-
- dev->xold = xa[npts -1] >> 4;
- dev->yold = ya[npts -1] >> 4;
- }
-
- /*----------------------------------------------------------------------*\
- * plD_eop_tek()
- *
- * End of page. User must hit a <CR> to continue (terminal output).
- \*----------------------------------------------------------------------*/
-
- void
- plD_eop_tek(PLStream *pls)
- {
- tek_graph(pls);
-
- if (pls->termin) {
- if ( ! pls->nopause)
- WaitForPage(pls);
- }
- fprintf(pls->OutFile, CLEAR_VIEW); /* erase and home */
- }
-
- /*----------------------------------------------------------------------*\
- * plD_bop_tek()
- *
- * Set up for the next page. Advance to next family file if necessary
- * (file output). Devices that share graphics/alpha screens need a page
- * clear.
- \*----------------------------------------------------------------------*/
-
- void
- plD_bop_tek(PLStream *pls)
- {
- PLDev *dev = (PLDev *) pls->dev;
-
- dev->xold = UNDEFINED;
- dev->yold = UNDEFINED;
-
- if (pls->termin) {
- switch (pls->dev_minor) {
- case mskermit:
- fprintf(pls->OutFile, CLEAR_VIEW); /* erase and home */
- break;
- }
- } else {
- plGetFam(pls);
- }
- pls->page++;
-
- /* Initialize palette */
-
- if ( pls->color & 0x01 )
- setcmap(pls);
- }
-
- /*----------------------------------------------------------------------*\
- * plD_tidy_tek()
- *
- * Close graphics file or otherwise clean up.
- \*----------------------------------------------------------------------*/
-
- void
- plD_tidy_tek(PLStream *pls)
- {
- if ( ! pls->termin) {
- fclose(pls->OutFile);
- } else {
- tek_text(pls);
- fflush(pls->OutFile);
- }
- }
-
- /*----------------------------------------------------------------------*\
- * plD_state_tek()
- *
- * Handle change in PLStream state (color, pen width, fill attribute,
- * etc).
- \*----------------------------------------------------------------------*/
-
- void
- plD_state_tek(PLStream *pls, PLINT op)
- {
- switch (op) {
-
- case PLSTATE_WIDTH:
- break;
-
- case PLSTATE_COLOR0:
- if (pls->color) {
- int icol0 = pls->icol0;
- tek_graph(pls);
- if (icol0 != PL_RGB_COLOR) {
- curcolor = icol0;
- switch (pls->dev_minor) {
- #ifdef PLD_mskermit
- case mskermit:
- fprintf(pls->OutFile, "\033[%sm",
- kermit_color[icol0 % 14] );
- break;
- #endif /* PLD_mskermit */
-
- default:
- fprintf(pls->OutFile, "\033ML%c", icol0 + '0');
- }
- }
- }
- break;
-
- case PLSTATE_COLOR1:
- if (pls->color) {
- int icol1, ncol1;
- tek_graph(pls);
- if ((ncol1 = MIN(16 - pls->ncol0, pls->ncol1)) < 1)
- break;
-
- icol1 = pls->ncol0 + (pls->icol1 * (ncol1-1)) / (pls->ncol1-1);
- curcolor = icol1;
- fprintf(pls->OutFile, "\033ML%c", icol1 + '0');
- }
- break;
-
- case PLSTATE_CMAP0:
- case PLSTATE_CMAP1:
- if ( pls->color & 0x01 )
- setcmap(pls);
-
- break;
- }
- }
-
- /*----------------------------------------------------------------------*\
- * plD_esc_tek()
- *
- * Escape function.
- \*----------------------------------------------------------------------*/
-
- void
- plD_esc_tek(PLStream *pls, PLINT op, void *ptr)
- {
- switch (op) {
-
- case PLESC_TEXT:
- tek_text(pls);
- break;
-
- case PLESC_GRAPH:
- tek_graph(pls);
- break;
-
- case PLESC_FILL:
- fill_polygon(pls);
- break;
- }
- }
-
- /*----------------------------------------------------------------------*\
- * fill_polygon()
- *
- * Fill polygon described in points pls->dev_x[] and pls->dev_y[].
- \*----------------------------------------------------------------------*/
-
- static void
- fill_polygon(PLStream *pls)
- {
- int i;
- char fillcol[4], firstpoint[5];
-
- if (pls->dev_npts < 1)
- return;
-
- tek_graph(pls);
-
- encode_int(fillcol, -curcolor);
- encode_vector(firstpoint, pls->dev_x[0]>>4, pls->dev_y[0]>>4);
-
- /* Select the fill pattern */
-
- fprintf(pls->OutFile, "\033MP%s", fillcol);
-
- /* Begin panel boundary */
- /* Change %s0 to %s1 to see the boundary of each fill box -- cool! */
-
- fprintf(pls->OutFile, "\033LP%s0", firstpoint);
-
- /* Specify boundary (use vector mode) */
-
- fprintf(pls->OutFile, VECTOR_MODE);
- pls->bytecnt++;
- for (i = 1; i < pls->dev_npts; i++) {
- tek_vector(pls, pls->dev_x[i]>>4, pls->dev_y[i]>>4);
- }
-
- /* End panel */
-
- fprintf(pls->OutFile, "\033LE");
- }
-
- /*----------------------------------------------------------------------*\
- * tek_text()
- *
- * Switch to text screen (or alpha mode, for vanilla tek's). Restore
- * terminal to its original state, to better handle user input if
- * necessary.
- *
- * Note: xterm behaves strangely in the following circumstance: switch to
- * the text screen, print a string, and switch to the graphics screen, all
- * done in quick succession. The first character of the printed string
- * usually comes out blank -- but only apparently so, because if you force
- * a refresh of the screen in this area it will reappear. This is a
- * reproducible bug on the HP 720 under X11R5. If you insert a sleep(1)
- * after the switch to text screen or before the switch to graphics
- * screen, the string is printed correctly. I've been unable to find a
- * workaround for this problem (and I've tried, you can believe eet man).
- \*----------------------------------------------------------------------*/
-
- static void
- tek_text(PLStream *pls)
- {
- if (pls->termin && (pls->graphx == GRAPHICS_MODE)) {
- #ifdef POSIX_TTY
- tty_reset();
- #endif
- pls->graphx = TEXT_MODE;
- switch (pls->dev_minor) {
- case xterm:
- printf("\033\003"); /* vt100 mode (xterm) = ESC ETX */
- break;
-
- case mskermit:
- case vlt:
- printf("\033[?38l"); /* vt100 screen */
- break;
-
- case versaterm:
- printf("\033%%!2"); /* vt100 screen */
- break;
-
- case tek4107:
- printf("\033LV1"); /* set dialog visible */
- printf("\033%%!1"); /* set ansi mode */
- break;
-
- default:
- printf(ALPHA_MODE); /* enter alpha mode */
- }
- }
- }
-
- /*----------------------------------------------------------------------*\
- * tek_graph()
- *
- * Switch to graphics screen (or vector mode, for vanilla tek's). Also
- * switch terminal to cbreak mode, to allow single keystrokes to govern
- * actions at end of page.
- \*----------------------------------------------------------------------*/
-
- static void
- tek_graph(PLStream *pls)
- {
- if (pls->termin && (pls->graphx == TEXT_MODE)) {
- #ifdef POSIX_TTY
- tty_cbreak();
- #endif
- pls->graphx = GRAPHICS_MODE;
- switch (pls->dev_minor) {
- case xterm:
- case mskermit:
- case vlt:
- printf("\033[?38h"); /* switch to tek screen */
- break;
-
- case versaterm:
- printf("\033%%!0"); /* switch to tek4107 screen */
- break;
-
- case tek4107:
- printf("\033%%!0"); /* set tek mode */
- printf(CLEAR_VIEW); /* clear screen */
- printf("\033LV0"); /* set dialog invisible */
- break;
-
- default:
- printf(VECTOR_MODE); /* enter vector mode */
- }
- }
- }
-
- /*----------------------------------------------------------------------*\
- * encode_int()
- *
- * Encodes a single int into standard tek integer format, storing into a
- * NULL-terminated character string (must be length 4 or greater). This
- * scheme does not work for negative integers less than 15.
- \*----------------------------------------------------------------------*/
-
- static void
- encode_int(char *c, int i)
- {
- int negative = 0;
-
- if (i > 0) {
- if (i & 0x7C00) /* are any of bits 10-14 set?*/
- *c++ = ((i >> 10) & 0x1F) | 0x40;
- if (i & 0x03F0) /* are any of bits 4-9 set? */
- *c++ = ((i >> 4) & 0x3F) | 0x40;
- } else {
- i = -i;
- negative = 1;
- }
-
- if (i & 0x000F) /* are any of bits 0-3 set? */
- *c = (i & 0x0F) | 0x20;
- else /* if not, put in a space */
- *c = 0x20;
-
- if ( ! negative) /* if positive, set sign bit */
- *c |= 0x10;
-
- c++; *c = '\0'; /* NULL-terminate */
- return;
- }
-
- /*----------------------------------------------------------------------*\
- * encode_vector()
- *
- * Encodes an xy vector (2 ints) into standard tek vector format, storing
- * into a NULL-terminated character string of length 5. Note that the y
- * coordinate always comes first.
- \*----------------------------------------------------------------------*/
-
- static void
- encode_vector(char *c, int x, int y)
- {
- c[0] = (y >> 5) + 0x20; /* hy */
- c[1] = (y & 0x1f) + 0x60; /* ly */
- c[2] = (x >> 5) + 0x20; /* hx */
- c[3] = (x & 0x1f) + 0x40; /* lx */
- c[4] = '\0'; /* NULL */
- }
-
- /*----------------------------------------------------------------------*\
- * tek_vector()
- *
- * Issues a vector draw command, assuming we are in vector plot mode. XY
- * coordinates are encoded according to the standard xy encoding scheme.
- \*----------------------------------------------------------------------*/
-
- static void
- tek_vector(PLStream *pls, int x, int y)
- {
- char c[5];
- c[0] = (y >> 5) + 0x20; /* hy */
- c[1] = (y & 0x1f) + 0x60; /* ly */
- c[2] = (x >> 5) + 0x20; /* hx */
- c[3] = (x & 0x1f) + 0x40; /* lx */
- c[4] = '\0'; /* NULL */
-
- fprintf( pls->OutFile, "%s", c );
- pls->bytecnt += 4;
- }
-
- /*----------------------------------------------------------------------*\
- * scolor()
- *
- * Sets a color by tek-encoded RGB values. Need to convert PLPLOT RGB
- * color range (0 to 255) to Tek RGB color range (0 to 100).
- \*----------------------------------------------------------------------*/
-
- static void
- scolor(int icol, int r, int g, int b)
- {
- char tek_col[4], tek_r[4], tek_g[4], tek_b[4];
-
- encode_int(tek_col, icol);
- encode_int(tek_r, (100*r)/255);
- encode_int(tek_g, (100*g)/255);
- encode_int(tek_b, (100*b)/255);
-
- printf("\033TG14%s%s%s%s", tek_col, tek_r, tek_g, tek_b);
- }
-
- /*----------------------------------------------------------------------*\
- * setcmap()
- *
- * Sets up color palette.
- \*----------------------------------------------------------------------*/
-
- static void
- setcmap(PLStream *pls)
- {
- int i, ncol1 = MIN(16 - pls->ncol0, pls->ncol1);
- PLColor cmap1col;
-
- tek_graph(pls);
-
- /* Initialize cmap 0 colors */
-
- for (i = 0; i < pls->ncol0; i++)
- scolor(i, pls->cmap0[i].r, pls->cmap0[i].g, pls->cmap0[i].b);
-
- /* Initialize any remaining slots for cmap1 */
-
- for (i = 0; i < ncol1; i++) {
- plcol_interp(pls, &cmap1col, i, ncol1);
- scolor(i + pls->ncol0, cmap1col.r, cmap1col.g, cmap1col.b);
- }
- }
-
- /*----------------------------------------------------------------------*\
- * WaitForPage()
- *
- * This routine waits for the user to advance the plot, while handling
- * all other events.
- \*----------------------------------------------------------------------*/
-
- static void
- WaitForPage(PLStream *pls)
- {
- int input_char;
-
- putchar(BEL_CHAR);
- fflush(stdout);
-
- while ( ! exit_eventloop) {
- input_char = getchar();
- EventHandler(pls, input_char);
- }
- exit_eventloop = FALSE;
- }
-
- /*----------------------------------------------------------------------*\
- * EventHandler()
- *
- * Event handler routine for xterm. Just reacts to keyboard input.
- \*----------------------------------------------------------------------*/
-
- static void
- EventHandler(PLStream *pls, int input_char)
- {
- PLKey key;
-
- key.code = 0;
- key.string[0] = '\0';
-
- /* Translate keystroke into a PLKey */
-
- if ( ! isprint(input_char)) {
- switch (input_char) {
- case 0x0A:
- key.code = PLK_Linefeed;
- break;
-
- case 0x0D:
- key.code = PLK_Return;
- break;
-
- case 0x08:
- key.code = PLK_BackSpace;
- break;
-
- case 0x7F:
- key.code = PLK_Delete;
- break;
- }
- } else {
- key.string[0] = input_char;
- key.string[1] = '\0';
- }
-
- #ifdef DEBUG
- pltext();
- fprintf(stderr, "Input char %x, Keycode %x, string: %s\n",
- input_char, key.code, key.string);
- plgra();
- #endif
-
- /* Call user event handler.
- * Since this is called first, the user can disable all plplot internal
- * event handling by setting key.code to 0 and key.string to '\0'.
- */
-
- if (pls->KeyEH != NULL)
- (*pls->KeyEH) (&key, pls->KeyEH_data, &exit_eventloop);
-
- /* Handle internal events */
-
- /* Advance to next page (i.e. terminate event loop) on a <eol> */
-
- if (key.code == PLK_Linefeed)
- exit_eventloop = TRUE;
-
- /* Terminate on a 'Q' (not 'q', since it's too easy to hit by mistake) */
-
- if (key.string[0] == 'Q') {
- pls->nopause = TRUE;
- plexit("");
- }
-
- /* Some test code, don't rely on it. */
-
- if (key.string[0] == 't') {
- fprintf(stderr, "Entering GIN mode..\n");
-
- printf(GIN_MODE); /* Enter GIN mode */
- fflush(stdout);
- }
- }
-
- /*----------------------------------------------------------------------*\
- * tty cbreak-mode handlers
- *
- * Taken from "Advanced Programming in the UNIX(R) Environment",
- * by W. Richard Stevens.
- \*----------------------------------------------------------------------*/
-
- #ifdef POSIX_TTY
-
- static void
- tty_setup(void) /* setup for terminal operations */
- {
- if (tcgetattr(STDIN_FILENO, &termios_reset) < 0) {
- fprintf(stderr, "Unable to set up cbreak mode.\n");
- return;
- }
-
- termios_cbreak = termios_reset; /* structure copy */
-
- termios_cbreak.c_lflag &= ~(ICANON); /* canonical mode off */
- termios_cbreak.c_cc[VMIN] = 1; /* 1 byte at a time */
- termios_cbreak.c_cc[VTIME] = 0; /* no timer */
-
- #ifdef STDC_HEADERS
- if (atexit(tty_atexit))
- fprintf(stderr, "Unable to set up atexit handler.\n");
- #endif
- return;
- }
-
- static int
- tty_cbreak(void) /* put terminal into a cbreak mode */
- {
- if (ttystate != CBREAK) {
- if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &termios_cbreak) < 0)
- return -1;
-
- ttystate = CBREAK;
- }
- return 0;
- }
-
- static int
- tty_reset(void) /* restore terminal's mode */
- {
- if (ttystate != RESET) {
- if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &termios_reset) < 0)
- return -1;
-
- ttystate = RESET;
- }
- return 0;
- }
-
- static void
- tty_atexit(void) /* exit handler */
- {
- tty_reset();
- }
-
- #endif /* POSIX_TTY */
-
- #else
- int pldummy_tek() {return 0;}
-
- #endif /* defined(PLD_xterm) || ... */
-