[BACK]Return to term.c CVS log [TXT][DIR] Up to [local] / OpenXM_contrib / gnuplot

Annotation of OpenXM_contrib/gnuplot/term.c, Revision 1.1

1.1     ! maekawa     1: #ifndef lint
        !             2: static char *RCSid = "$Id: term.c,v 1.104 1998/06/18 14:55:19 ddenholm Exp $";
        !             3: #endif
        !             4:
        !             5: /* GNUPLOT - term.c */
        !             6:
        !             7: /*[
        !             8:  * Copyright 1986 - 1993, 1998   Thomas Williams, Colin Kelley
        !             9:  *
        !            10:  * Permission to use, copy, and distribute this software and its
        !            11:  * documentation for any purpose with or without fee is hereby granted,
        !            12:  * provided that the above copyright notice appear in all copies and
        !            13:  * that both that copyright notice and this permission notice appear
        !            14:  * in supporting documentation.
        !            15:  *
        !            16:  * Permission to modify the software is granted, but not the right to
        !            17:  * distribute the complete modified source code.  Modifications are to
        !            18:  * be distributed as patches to the released version.  Permission to
        !            19:  * distribute binaries produced by compiling modified sources is granted,
        !            20:  * provided you
        !            21:  *   1. distribute the corresponding source modifications from the
        !            22:  *    released version in the form of a patch file along with the binaries,
        !            23:  *   2. add special version identification to distinguish your version
        !            24:  *    in addition to the base release version number,
        !            25:  *   3. provide your name and address as the primary contact for the
        !            26:  *    support of your modified version, and
        !            27:  *   4. retain our contact information in regard to use of the base
        !            28:  *    software.
        !            29:  * Permission to distribute the released version of the source code along
        !            30:  * with corresponding source modifications in the form of a patch file is
        !            31:  * granted with same provisions 2 through 4 for binary distributions.
        !            32:  *
        !            33:  * This software is provided "as is" without express or implied warranty
        !            34:  * to the extent permitted by applicable law.
        !            35: ]*/
        !            36:
        !            37:
        !            38:  /* This module is responsible for looking after the terminal
        !            39:   * drivers at the lowest level. Only this module (should)
        !            40:   * know about all the various rules about interpreting
        !            41:   * the terminal capabilities exported by the terminal
        !            42:   * drivers in the table.
        !            43:   *
        !            44:   * Note that, as far as this module is concerned, a
        !            45:   * terminal session lasts only until _either_ terminal
        !            46:   * or output file changes. Before either is changed,
        !            47:   * the terminal is shut down.
        !            48:   *
        !            49:   * Entry points : (see also term/README)
        !            50:   *
        !            51:   * term_set_output() : called when  set output  invoked
        !            52:   *
        !            53:   * term_init()  : optional. Prepare the terminal for first
        !            54:   *                use. It protects itself against subsequent calls.
        !            55:   *
        !            56:   * term_start_plot() : called at start of graph output. Calls term_init
        !            57:   *                     if necessary
        !            58:   *
        !            59:   * term_apply_lp_properties() : apply linewidth settings
        !            60:   *
        !            61:   * term_end_plot() : called at the end of a plot
        !            62:   *
        !            63:   * term_reset() : called during int_error handling, to shut
        !            64:   *                terminal down cleanly
        !            65:   *
        !            66:   * term_start_multiplot() : called by   set multiplot
        !            67:   *
        !            68:   * term_end_multiplot() : called by  set nomultiplot
        !            69:   *
        !            70:   * term_check_multiplot_okay() : called just before an interactive
        !            71:   *                        prompt is issued while in multiplot mode,
        !            72:   *                        to allow terminal to suspend if necessary,
        !            73:   *                        Raises an error if interactive multiplot
        !            74:   *                       is not supported.
        !            75:   */
        !            76:
        !            77: #include "plot.h"
        !            78: #include "bitmap.h"
        !            79: #include "setshow.h"
        !            80: #include "driver.h"
        !            81:
        !            82: #ifdef _Windows
        !            83: FILE *open_printer __PROTO((void));    /* in wprinter.c */
        !            84: void close_printer __PROTO((FILE * outfile));
        !            85: # ifdef __MSC__
        !            86: #  include <malloc.h>
        !            87: # else
        !            88: #  include <alloc.h>
        !            89: # endif                                /* MSC */
        !            90: #endif /* _Windows */
        !            91:
        !            92:
        !            93: /* true if terminal has been initialized */
        !            94: static TBOOLEAN term_initialised;
        !            95:
        !            96: /* true if terminal is in graphics mode */
        !            97: static TBOOLEAN term_graphics = FALSE;
        !            98:
        !            99: /* we have suspended the driver, in multiplot mode */
        !           100: static TBOOLEAN term_suspended = FALSE;
        !           101:
        !           102: /* true if? */
        !           103: static TBOOLEAN opened_binary = FALSE;
        !           104:
        !           105: /* true if require terminal to be initialized */
        !           106: static TBOOLEAN term_force_init = FALSE;
        !           107:
        !           108: extern FILE *gpoutfile;
        !           109: extern char *outstr;
        !           110: extern float xsize, ysize;
        !           111:
        !           112: /* internal pointsize for do_point */
        !           113: static double term_pointsize;
        !           114:
        !           115: static void term_suspend __PROTO((void));
        !           116: static void term_close_output __PROTO((void));
        !           117: static void null_linewidth __PROTO((double));
        !           118:
        !           119: void do_point __PROTO((unsigned int x, unsigned int y, int number));
        !           120: void do_pointsize __PROTO((double size));
        !           121: void line_and_point __PROTO((unsigned int x, unsigned int y, int number));
        !           122: void do_arrow __PROTO((unsigned int sx, unsigned int sy, unsigned int ex, unsigned int ey, int head));
        !           123:
        !           124:
        !           125: #ifdef __ZTC__
        !           126: char *ztc_init();
        !           127: /* #undef TGIF */
        !           128: #endif
        !           129:
        !           130: #ifdef VMS
        !           131: char *vms_init();
        !           132: void vms_reset();
        !           133: void term_mode_tek();
        !           134: void term_mode_native();
        !           135: void term_pasthru();
        !           136: void term_nopasthru();
        !           137: void fflush_binary();
        !           138: # define FOPEN_BINARY(file) fopen(file, "wb", "rfm=fix", "bls=512", "mrs=512")
        !           139: #else /* !VMS */
        !           140: # define FOPEN_BINARY(file) fopen(file, "wb")
        !           141: #endif /* !VMS */
        !           142:
        !           143:
        !           144: /* This is needed because the unixplot library only writes to stdout. */
        !           145: #if defined(UNIXPLOT) || defined(GNUGRAPH)
        !           146: static FILE save_stdout;
        !           147: #endif
        !           148: static int unixplot = 0;
        !           149:
        !           150: #if defined(MTOS) || defined(ATARI)
        !           151: int aesid = -1;
        !           152: #endif
        !           153:
        !           154: #define NICE_LINE              0
        !           155: #define POINT_TYPES            6
        !           156:
        !           157: #ifndef DEFAULTTERM
        !           158: # define DEFAULTTERM NULL
        !           159: #endif
        !           160:
        !           161: /* interface to the rest of gnuplot - the rules are getting
        !           162:  * too complex for the rest of gnuplot to be allowed in
        !           163:  */
        !           164:
        !           165: #if defined(PIPES)
        !           166: static TBOOLEAN pipe_open = FALSE;
        !           167: #endif /* PIPES */
        !           168:
        !           169: static void term_close_output()
        !           170: {
        !           171:     FPRINTF((stderr, "term_close_output\n"));
        !           172:
        !           173:     opened_binary = FALSE;
        !           174:
        !           175:     if (!outstr)               /* ie using stdout */
        !           176:        return;
        !           177:
        !           178: #if defined(PIPES)
        !           179:     if (pipe_open) {
        !           180:        (void) pclose(gpoutfile);
        !           181:        pipe_open = FALSE;
        !           182:     } else
        !           183: #endif /* PIPES */
        !           184: #ifdef _Windows
        !           185:     if (stricmp(outstr, "PRN") == 0)
        !           186:        close_printer(gpoutfile);
        !           187:     else
        !           188: #endif
        !           189:        (void) fclose(gpoutfile);
        !           190:
        !           191:     gpoutfile = stdout;                /* Don't dup... */
        !           192:     free(outstr);
        !           193:     outstr = NULL;
        !           194: }
        !           195:
        !           196: #ifdef OS2
        !           197: # define POPEN_MODE ("wb")
        !           198: #else
        !           199: # define POPEN_MODE ("w")
        !           200: #endif
        !           201:
        !           202: /* assigns dest to outstr, so it must be allocated or NULL
        !           203:  * and it must not be outstr itself !
        !           204:  */
        !           205: void term_set_output(dest)
        !           206: char *dest;
        !           207: {
        !           208:     FILE *f;
        !           209:
        !           210:     FPRINTF((stderr, "term_set_output\n"));
        !           211:     assert(dest == NULL || dest != outstr);
        !           212:
        !           213:     if (multiplot) {
        !           214:        fputs("In multiplotmode you can't change the output\n", stderr);
        !           215:        return;
        !           216:     }
        !           217:     if (term && term_initialised) {
        !           218:        (*term->reset) ();
        !           219:        term_initialised = FALSE;
        !           220:     }
        !           221:     if (dest == NULL) {                /* stdout */
        !           222:        UP_redirect(4);
        !           223:        term_close_output();
        !           224:     } else {
        !           225:
        !           226: #if defined(PIPES)
        !           227:        if (*dest == '|') {
        !           228:            if ((f = popen(dest + 1, POPEN_MODE)) == (FILE *) NULL)
        !           229:                    os_error("cannot create pipe; output not changed", c_token);
        !           230:                else
        !           231:                    pipe_open = TRUE;
        !           232:        } else
        !           233: #endif /* PIPES */
        !           234:
        !           235: #ifdef _Windows
        !           236:        if (outstr && stricmp(outstr, "PRN") == 0) {
        !           237:            /* we can't call open_printer() while printer is open, so */
        !           238:            close_printer(gpoutfile);   /* close printer immediately if open */
        !           239:            gpoutfile = stdout; /* and reset output to stdout */
        !           240:            free(outstr);
        !           241:            outstr = NULL;
        !           242:        }
        !           243:        if (stricmp(dest, "PRN") == 0) {
        !           244:            if ((f = open_printer()) == (FILE *) NULL)
        !           245:                os_error("cannot open printer temporary file; output may have changed", c_token);
        !           246:        } else
        !           247: #endif
        !           248:
        !           249:        {
        !           250:            if (term && (term->flags & TERM_BINARY)) {
        !           251:                f = FOPEN_BINARY(dest);
        !           252:            } else
        !           253:                f = fopen(dest, "w");
        !           254:
        !           255:            if (f == (FILE *) NULL)
        !           256:                os_error("cannot open file; output not changed", c_token);
        !           257:        }
        !           258:        term_close_output();
        !           259:        gpoutfile = f;
        !           260:        outstr = dest;
        !           261:        opened_binary = (term && (term->flags & TERM_BINARY));
        !           262:        UP_redirect(1);
        !           263:     }
        !           264: }
        !           265:
        !           266: void term_init()
        !           267: {
        !           268:     FPRINTF((stderr, "term_init()\n"));
        !           269:
        !           270:     if (!term)
        !           271:        int_error("No terminal defined", NO_CARET);
        !           272:
        !           273:     /* check if we have opened the output file in the wrong mode
        !           274:      * (text/binary), if set term comes after set output
        !           275:      * This was originally done in change_term, but that
        !           276:      * resulted in output files being truncated
        !           277:      */
        !           278:
        !           279:     if (outstr &&
        !           280:        (((term->flags & TERM_BINARY) && !opened_binary) ||
        !           281:         ((!(term->flags & TERM_BINARY) && opened_binary)))) {
        !           282:        /* this is nasty - we cannot just term_set_output(outstr)
        !           283:         * since term_set_output will first free outstr and we
        !           284:         * end up with an invalid pointer. I think I would
        !           285:         * prefer to defer opening output file until first plot.
        !           286:         */
        !           287:        char *temp = gp_alloc(strlen(outstr) + 1, "temp file string");
        !           288:        if (temp) {
        !           289:            FPRINTF((stderr, "term_init : reopening \"%s\" as %s\n",
        !           290:                     outstr, term->flags & TERM_BINARY ? "binary" : "text"));
        !           291:            strcpy(temp, outstr);
        !           292:            term_set_output(temp);      /* will free outstr */
        !           293:        } else
        !           294:            fputs("Cannot reopen output file in binary", stderr);
        !           295:        /* and carry on, hoping for the best ! */
        !           296:     }
        !           297: #ifdef OS2
        !           298:     else if (!outstr && !interactive && (term->flags & TERM_BINARY)) {
        !           299:        /* binary (eg gif) to stdout in a non-interactive session */
        !           300:        fflush(stdout);         // _fsetmode requires an empty buffer
        !           301:
        !           302:        _fsetmode(stdout, "b");
        !           303:     }
        !           304: #endif
        !           305:
        !           306:
        !           307:     if (!term_initialised || term_force_init) {
        !           308:        FPRINTF((stderr, "- calling term->init()\n"));
        !           309:        (*term->init) ();
        !           310:        term_initialised = TRUE;
        !           311:     }
        !           312: }
        !           313:
        !           314:
        !           315: void term_start_plot()
        !           316: {
        !           317:     FPRINTF((stderr, "term_start_plot()\n"));
        !           318:
        !           319:     if (!term_initialised)
        !           320:        term_init();
        !           321:
        !           322:     if (!term_graphics) {
        !           323:        FPRINTF((stderr, "- calling term->graphics()\n"));
        !           324:        (*term->graphics) ();
        !           325:        term_graphics = TRUE;
        !           326:     } else if (multiplot && term_suspended) {
        !           327:        if (term->resume) {
        !           328:            FPRINTF((stderr, "- calling term->resume()\n"));
        !           329:            (*term->resume) ();
        !           330:        }
        !           331:        term_suspended = FALSE;
        !           332:     }
        !           333: }
        !           334:
        !           335: void term_end_plot()
        !           336: {
        !           337:     FPRINTF((stderr, "term_end_plot()\n"));
        !           338:
        !           339:     if (!term_initialised)
        !           340:        return;
        !           341:
        !           342:     if (!multiplot) {
        !           343:        FPRINTF((stderr, "- calling term->text()\n"));
        !           344:        (*term->text) ();
        !           345:        term_graphics = FALSE;
        !           346:     }
        !           347: #ifdef VMS
        !           348:     if (opened_binary)
        !           349:        fflush_binary();
        !           350:     else
        !           351: #endif /* VMS */
        !           352:
        !           353:        (void) fflush(gpoutfile);
        !           354: }
        !           355:
        !           356: void term_start_multiplot()
        !           357: {
        !           358:     FPRINTF((stderr, "term_start_multiplot()\n"));
        !           359:     if (multiplot)
        !           360:        term_end_multiplot();
        !           361:
        !           362:     multiplot = TRUE;
        !           363:     term_start_plot();
        !           364: }
        !           365:
        !           366: void term_end_multiplot()
        !           367: {
        !           368:     FPRINTF((stderr, "term_end_multiplot()\n"));
        !           369:     if (!multiplot)
        !           370:        return;
        !           371:
        !           372:     if (term_suspended) {
        !           373:        if (term->resume)
        !           374:            (*term->resume) ();
        !           375:        term_suspended = FALSE;
        !           376:     }
        !           377:     multiplot = FALSE;
        !           378:
        !           379:     term_end_plot();
        !           380: }
        !           381:
        !           382:
        !           383:
        !           384: static void term_suspend()
        !           385: {
        !           386:     FPRINTF((stderr, "term_suspend()\n"));
        !           387:     if (term_initialised && !term_suspended && term->suspend) {
        !           388:        FPRINTF((stderr, "- calling term->suspend()\n"));
        !           389:        (*term->suspend) ();
        !           390:        term_suspended = TRUE;
        !           391:     }
        !           392: }
        !           393:
        !           394: void term_reset()
        !           395: {
        !           396:     FPRINTF((stderr, "term_reset()\n"));
        !           397:
        !           398:     if (!term_initialised)
        !           399:        return;
        !           400:
        !           401:     if (term_suspended) {
        !           402:        if (term->resume) {
        !           403:            FPRINTF((stderr, "- calling term->resume()\n"));
        !           404:            (*term->resume) ();
        !           405:        }
        !           406:        term_suspended = FALSE;
        !           407:     }
        !           408:     if (term_graphics) {
        !           409:        (*term->text) ();
        !           410:        term_graphics = FALSE;
        !           411:     }
        !           412:     if (term_initialised) {
        !           413:        (*term->reset) ();
        !           414:        term_initialised = FALSE;
        !           415:     }
        !           416: }
        !           417:
        !           418: void term_apply_lp_properties(lp)
        !           419: struct lp_style_type *lp;
        !           420: {
        !           421:     /*  This function passes all the line and point properties to the
        !           422:      *  terminal driver and issues the corresponding commands.
        !           423:      *
        !           424:      *  Alas, sometimes it might be necessary to give some help to
        !           425:      *  this function by explicitly issuing additional '(*term)(...)'
        !           426:      *  commands.
        !           427:      */
        !           428:
        !           429:     if (lp->pointflag) {
        !           430:        /* change points, too
        !           431:         * Currently, there is no 'pointtype' function.  For points
        !           432:         * there is a special function also dealing with (x,y) co-
        !           433:         * ordinates.
        !           434:         */
        !           435:        (*term->pointsize) (lp->p_size);
        !           436:     }
        !           437:     /*  _first_ set the line width, _then_ set the line type !
        !           438:
        !           439:      *  The linetype might depend on the linewidth in some terminals.
        !           440:      */
        !           441:     (*term->linewidth) (lp->l_width);
        !           442:     (*term->linetype) (lp->l_type);
        !           443: }
        !           444:
        !           445:
        !           446:
        !           447: void term_check_multiplot_okay(f_interactive)
        !           448: TBOOLEAN f_interactive;
        !           449: {
        !           450:     FPRINTF((stderr, "term_multiplot_okay(%d)\n", f_interactive));
        !           451:
        !           452:     if (!term_initialised)
        !           453:        return;                 /* they've not started yet */
        !           454:
        !           455:     /* make sure that it is safe to issue an interactive prompt
        !           456:      * it is safe if
        !           457:      *   it is not an interactive read, or
        !           458:      *   the terminal supports interactive multiplot, or
        !           459:      *   we are not writing to stdout and terminal doesn't
        !           460:      *     refuse multiplot outright
        !           461:      */
        !           462:     if (!f_interactive || (term->flags & TERM_CAN_MULTIPLOT) ||
        !           463:        ((gpoutfile != stdout) && !(term->flags & TERM_CANNOT_MULTIPLOT))
        !           464:        ) {
        !           465:        /* it's okay to use multiplot here, but suspend first */
        !           466:        term_suspend();
        !           467:        return;
        !           468:     }
        !           469:     /* uh oh : they're not allowed to be in multiplot here */
        !           470:
        !           471:     term_end_multiplot();
        !           472:
        !           473:     /* at this point we know that it is interactive and that the
        !           474:      * terminal can either only do multiplot when writing to
        !           475:      * to a file, or it does not do multiplot at all
        !           476:      */
        !           477:
        !           478:     if (term->flags & TERM_CANNOT_MULTIPLOT)
        !           479:        int_error("This terminal does not support multiplot", NO_CARET);
        !           480:     else
        !           481:        int_error("Must set output to a file or put all multiplot commands on one input line", NO_CARET);
        !           482: }
        !           483:
        !           484: void do_point(x, y, number)
        !           485: unsigned int x, y;
        !           486: int number;
        !           487: {
        !           488:     register int htic, vtic;
        !           489:     register struct termentry *t = term;
        !           490:
        !           491:     if (number < 0) {          /* do dot */
        !           492:        (*t->move) (x, y);
        !           493:        (*t->vector) (x, y);
        !           494:        return;
        !           495:     }
        !           496:     number %= POINT_TYPES;
        !           497:     /* should be in term_tbl[] in later version */
        !           498:     htic = (term_pointsize * t->h_tic / 2);
        !           499:     vtic = (term_pointsize * t->v_tic / 2);
        !           500:
        !           501:     switch (number) {
        !           502:     case 0:                    /* do diamond */
        !           503:        (*t->move) (x - htic, y);
        !           504:        (*t->vector) (x, y - vtic);
        !           505:        (*t->vector) (x + htic, y);
        !           506:        (*t->vector) (x, y + vtic);
        !           507:        (*t->vector) (x - htic, y);
        !           508:        (*t->move) (x, y);
        !           509:        (*t->vector) (x, y);
        !           510:        break;
        !           511:     case 1:                    /* do plus */
        !           512:        (*t->move) (x - htic, y);
        !           513:        (*t->vector) (x - htic, y);
        !           514:        (*t->vector) (x + htic, y);
        !           515:        (*t->move) (x, y - vtic);
        !           516:        (*t->vector) (x, y - vtic);
        !           517:        (*t->vector) (x, y + vtic);
        !           518:        break;
        !           519:     case 2:                    /* do box */
        !           520:        (*t->move) (x - htic, y - vtic);
        !           521:        (*t->vector) (x - htic, y - vtic);
        !           522:        (*t->vector) (x + htic, y - vtic);
        !           523:        (*t->vector) (x + htic, y + vtic);
        !           524:        (*t->vector) (x - htic, y + vtic);
        !           525:        (*t->vector) (x - htic, y - vtic);
        !           526:        (*t->move) (x, y);
        !           527:        (*t->vector) (x, y);
        !           528:        break;
        !           529:     case 3:                    /* do X */
        !           530:        (*t->move) (x - htic, y - vtic);
        !           531:        (*t->vector) (x - htic, y - vtic);
        !           532:        (*t->vector) (x + htic, y + vtic);
        !           533:        (*t->move) (x - htic, y + vtic);
        !           534:        (*t->vector) (x - htic, y + vtic);
        !           535:        (*t->vector) (x + htic, y - vtic);
        !           536:        break;
        !           537:     case 4:                    /* do triangle */
        !           538:        (*t->move) (x, y + (4 * vtic / 3));
        !           539:        (*t->vector) (x - (4 * htic / 3), y - (2 * vtic / 3));
        !           540:        (*t->vector) (x + (4 * htic / 3), y - (2 * vtic / 3));
        !           541:        (*t->vector) (x, y + (4 * vtic / 3));
        !           542:        (*t->move) (x, y);
        !           543:        (*t->vector) (x, y);
        !           544:        break;
        !           545:     case 5:                    /* do star */
        !           546:        (*t->move) (x - htic, y);
        !           547:        (*t->vector) (x - htic, y);
        !           548:        (*t->vector) (x + htic, y);
        !           549:        (*t->move) (x, y - vtic);
        !           550:        (*t->vector) (x, y - vtic);
        !           551:        (*t->vector) (x, y + vtic);
        !           552:        (*t->move) (x - htic, y - vtic);
        !           553:        (*t->vector) (x - htic, y - vtic);
        !           554:        (*t->vector) (x + htic, y + vtic);
        !           555:        (*t->move) (x - htic, y + vtic);
        !           556:        (*t->vector) (x - htic, y + vtic);
        !           557:        (*t->vector) (x + htic, y - vtic);
        !           558:        break;
        !           559:     }
        !           560: }
        !           561:
        !           562: void do_pointsize(size)
        !           563: double size;
        !           564: {
        !           565:     term_pointsize = (size >= 0 ? size : 1);
        !           566: }
        !           567:
        !           568:
        !           569: /*
        !           570:  * general point routine
        !           571:  */
        !           572: void line_and_point(x, y, number)
        !           573: unsigned int x, y;
        !           574: int number;
        !           575: {
        !           576:     /* temporary(?) kludge to allow terminals with bad linetypes
        !           577:        to make nice marks */
        !           578:
        !           579:     (*term->linetype) (NICE_LINE);
        !           580:     do_point(x, y, number);
        !           581: }
        !           582:
        !           583: /*
        !           584:  * general arrow routine
        !           585:  *
        !           586:  * I set the angle between the arrowhead and the line 15 degree.
        !           587:  * The length of arrowhead varies depending on the line length
        !           588:  * within the the range [0.3*(the-tic-length), 2*(the-tic-length)].
        !           589:  * No head is printed if the arrow length is zero.
        !           590:  *
        !           591:  *            Yasu-hiro Yamazaki(hiro@rainbow.physics.utoronto.ca)
        !           592:  *            Jul 1, 1993
        !           593:  */
        !           594:
        !           595: #define COS15 (0.96593)                /* cos of 15 degree */
        !           596: #define SIN15 (0.25882)                /* sin of 15 degree */
        !           597:
        !           598: #define HEAD_LONG_LIMIT  (2.0) /* long  limit of arrowhead length */
        !           599: #define HEAD_SHORT_LIMIT (0.3) /* short limit of arrowhead length */
        !           600:                                /* their units are the "tic" length */
        !           601:
        !           602: #define HEAD_COEFF  (0.3)      /* default value of head/line length ratio */
        !           603:
        !           604: void do_arrow(sx, sy, ex, ey, head)
        !           605: unsigned int sx, sy;           /* start point */
        !           606: unsigned int ex, ey;           /* end point (point of arrowhead) */
        !           607: TBOOLEAN head;
        !           608: {
        !           609:     register struct termentry *t = term;
        !           610:     float len_tic = ((double) (t->h_tic + t->v_tic)) / 2.0;
        !           611:     /* average of tic sizes */
        !           612:     /* (dx,dy) : vector from end to start */
        !           613:     double dx = (double) sx - (double) ex;
        !           614:     double dy = (double) sy - (double) ey;
        !           615:     double len_arrow = sqrt(dx * dx + dy * dy);
        !           616:
        !           617:     /* draw the line for the arrow. That's easy. */
        !           618:     (*t->move) (sx, sy);
        !           619:     (*t->vector) (ex, ey);
        !           620:
        !           621:     /* no head for arrows whih length = 0
        !           622:      * or, to be more specific, length < DBL_EPSILON,
        !           623:      * because len_arrow will almost always be != 0
        !           624:      */
        !           625:     if (head && fabs(len_arrow) >= DBL_EPSILON) {
        !           626:        /* now calc the head_coeff */
        !           627:        double coeff_shortest = len_tic * HEAD_SHORT_LIMIT / len_arrow;
        !           628:        double coeff_longest = len_tic * HEAD_LONG_LIMIT / len_arrow;
        !           629:        double head_coeff = GPMAX(coeff_shortest,
        !           630:                                  GPMIN(HEAD_COEFF, coeff_longest));
        !           631:        /* now draw the arrow head. */
        !           632:        /* we put the arrowhead marks at 15 degrees to line */
        !           633:        int x, y;               /* one endpoint */
        !           634:
        !           635:        x = (int) (ex + (COS15 * dx - SIN15 * dy) * head_coeff);
        !           636:        y = (int) (ey + (SIN15 * dx + COS15 * dy) * head_coeff);
        !           637:        (*t->move) (x, y);
        !           638:        (*t->vector) (ex, ey);
        !           639:
        !           640:        x = (int) (ex + (COS15 * dx + SIN15 * dy) * head_coeff);
        !           641:        y = (int) (ey + (-SIN15 * dx + COS15 * dy) * head_coeff);
        !           642:        (*t->vector) (x, y);
        !           643:     }
        !           644: }
        !           645:
        !           646: #if 0                          /* oiginal routine */
        !           647: #define ROOT2 (1.41421)                /* sqrt of 2 */
        !           648:
        !           649: void org_do_arrow(sx, sy, ex, ey, head)
        !           650: int sx, sy;                    /* start point */
        !           651: int ex, ey;                    /* end point (point of arrowhead) */
        !           652: TBOOLEAN head;
        !           653: {
        !           654:     register struct termentry *t = term;
        !           655:     int len = (t->h_tic + t->v_tic) / 2;       /* arrowhead size = avg of tic sizes */
        !           656:
        !           657:     /* draw the line for the arrow. That's easy. */
        !           658:     (*t->move) (sx, sy);
        !           659:     (*t->vector) (ex, ey);
        !           660:
        !           661:     if (head) {
        !           662:        /* now draw the arrow head. */
        !           663:        /* we put the arrowhead marks at 45 degrees to line */
        !           664:        if (sx == ex) {
        !           665:            /* vertical line, special case */
        !           666:            int delta = ((float) len / ROOT2 + 0.5);
        !           667:            if (sy < ey)
        !           668:                delta = -delta; /* up arrow goes the other way */
        !           669:            (*t->move) (ex - delta, ey + delta);
        !           670:            (*t->vector) (ex, ey);
        !           671:            (*t->vector) (ex + delta, ey + delta);
        !           672:        } else {
        !           673:            int dx = sx - ex;
        !           674:            int dy = sy - ey;
        !           675:            double coeff = len / sqrt(2.0 * ((double) dx * (double) dx
        !           676:                                             + (double) dy * (double) dy));
        !           677:            int x, y;           /* one endpoint */
        !           678:
        !           679:            x = (int) (ex + (dx + dy) * coeff);
        !           680:            y = (int) (ey + (dy - dx) * coeff);
        !           681:            (*t->move) (x, y);
        !           682:            (*t->vector) (ex, ey);
        !           683:
        !           684:            x = (int) (ex + (dx - dy) * coeff);
        !           685:            y = (int) (ey + (dy + dx) * coeff);
        !           686:            (*t->vector) (x, y);
        !           687:        }
        !           688:     }
        !           689: }
        !           690:
        !           691: #endif /* original routine */
        !           692:
        !           693:
        !           694: #define TERM_PROTO
        !           695: #define TERM_BODY
        !           696: #define TERM_PUBLIC static
        !           697:
        !           698: #include "term.h"
        !           699:
        !           700: #undef TERM_PROTO
        !           701: #undef TERM_BODY
        !           702: #undef TERM_PUBLIC
        !           703:
        !           704:
        !           705: /* Dummy functions for unavailable features */
        !           706: /* return success if they asked for default - this simplifies code
        !           707:  * where param is passed as a param. Client can first pass it here,
        !           708:  * and only if it fails do they have to see what was trying to be done
        !           709:  */
        !           710:
        !           711: /* change angle of text.  0 is horizontal left to right.
        !           712:    * 1 is vertical bottom to top (90 deg rotate)
        !           713:  */
        !           714: int null_text_angle(ang)
        !           715: int ang;
        !           716: {
        !           717:     return (ang == 0);
        !           718: }
        !           719:
        !           720: /* change justification of text.
        !           721:  * modes are LEFT (flush left), CENTRE (centred), RIGHT (flush right)
        !           722:  */
        !           723: int null_justify_text(just)
        !           724: enum JUSTIFY just;
        !           725: {
        !           726:     return (just == LEFT);
        !           727: }
        !           728:
        !           729:
        !           730: /* Change scale of plot.
        !           731:  * Parameters are x,y scaling factors for this plot.
        !           732:  * Some terminals (eg latex) need to do scaling themselves.
        !           733:  */
        !           734: int null_scale(x, y)
        !           735: double x;
        !           736: double y;
        !           737: {
        !           738:     return FALSE;              /* can't be done */
        !           739: }
        !           740:
        !           741: int do_scale(x, y)
        !           742: double x;
        !           743: double y;
        !           744: {
        !           745:     return TRUE;               /* can be done */
        !           746: }
        !           747:
        !           748: void options_null()
        !           749: {
        !           750:     term_options[0] = '\0';    /* we have no options */
        !           751: }
        !           752:
        !           753: void UNKNOWN_null()
        !           754: {
        !           755: }
        !           756:
        !           757: void MOVE_null(x, y)
        !           758: unsigned int x, y;
        !           759: {
        !           760: }
        !           761:
        !           762: void LINETYPE_null(t)
        !           763: int t;
        !           764: {
        !           765: }
        !           766:
        !           767: void PUTTEXT_null(x, y, s)
        !           768: unsigned int x, y;
        !           769: char *s;
        !           770: {
        !           771: }
        !           772:
        !           773:
        !           774: int set_font_null(s)
        !           775: char *s;
        !           776: {
        !           777:     return FALSE;
        !           778: }
        !           779:
        !           780: static void null_linewidth(s)
        !           781: double s;
        !           782: {
        !           783: }
        !           784:
        !           785:
        !           786: /* cast to get rid of useless warnings about UNKNOWN_null */
        !           787: typedef void (*void_fp) __PROTO((void));
        !           788:
        !           789:
        !           790: /* setup the magic macros to compile in the right parts of the
        !           791:  * terminal drivers included by term.h
        !           792:  */
        !           793:
        !           794: #define TERM_TABLE
        !           795: #define TERM_TABLE_START(x) ,{
        !           796: #define TERM_TABLE_END(x)   }
        !           797:
        !           798:
        !           799: /*
        !           800:  * term_tbl[] contains an entry for each terminal.  "unknown" must be the
        !           801:  *   first, since term is initialized to 0.
        !           802:  */
        !           803: struct termentry term_tbl[] =
        !           804: {
        !           805:     {"unknown", "Unknown terminal type - not a plotting device",
        !           806:      100, 100, 1, 1,
        !           807:      1, 1, options_null, UNKNOWN_null, UNKNOWN_null,
        !           808:      UNKNOWN_null, null_scale, UNKNOWN_null, MOVE_null, MOVE_null,
        !           809:      LINETYPE_null, PUTTEXT_null}
        !           810:     ,
        !           811:     {"table", "Dump ASCII table of X Y [Z] values to output",
        !           812:      100, 100, 1, 1,
        !           813:      1, 1, options_null, UNKNOWN_null, UNKNOWN_null,
        !           814:      UNKNOWN_null, null_scale, UNKNOWN_null, MOVE_null, MOVE_null,
        !           815:      LINETYPE_null, PUTTEXT_null}
        !           816: #include "term.h"
        !           817:
        !           818: };
        !           819:
        !           820: #define TERMCOUNT (sizeof(term_tbl)/sizeof(struct termentry))
        !           821:
        !           822: void list_terms()
        !           823: {
        !           824:     register int i;
        !           825:     char line_buffer[BUFSIZ];
        !           826:
        !           827:     StartOutput();
        !           828:     sprintf(line_buffer,"\nAvailable terminal types:\n");
        !           829:     OutLine(line_buffer);
        !           830:
        !           831:     for (i = 0; i < TERMCOUNT; i++) {
        !           832:        sprintf(line_buffer,"  %15s  %s\n",
        !           833:                term_tbl[i].name, term_tbl[i].description);
        !           834:        OutLine(line_buffer);
        !           835:     }
        !           836:
        !           837:     EndOutput();
        !           838: }
        !           839:
        !           840:
        !           841: /* set_term: get terminal number from name on command line
        !           842:  * will change 'term' variable if successful
        !           843:  */
        !           844: struct termentry *
        !           845:  set_term(c_token_arg)
        !           846: int c_token_arg;
        !           847: {
        !           848:     register struct termentry *t = NULL;
        !           849:     char *input_name;
        !           850:
        !           851:     if (!token[c_token_arg].is_token)
        !           852:        int_error("terminal name expected", c_token_arg);
        !           853:     input_name = input_line + token[c_token_arg].start_index;
        !           854:     t = change_term(input_name, token[c_token_arg].length);
        !           855:     if (!t)
        !           856:        int_error("unknown or ambiguous terminal type; type just 'set terminal' for a list",
        !           857:                  c_token_arg);
        !           858:
        !           859:     /* otherwise the type was changed */
        !           860:
        !           861:     return (t);
        !           862: }
        !           863:
        !           864: /* change_term: get terminal number from name and set terminal type
        !           865:  *
        !           866:  * returns NULL for unknown or ambiguous, otherwise is terminal
        !           867:  * driver pointer
        !           868:  */
        !           869: struct termentry *
        !           870:  change_term(name, length)
        !           871: char *name;
        !           872: int length;
        !           873: {
        !           874:     int i;
        !           875:     struct termentry *t = NULL;
        !           876:
        !           877:     for (i = 0; i < TERMCOUNT; i++) {
        !           878:        if (!strncmp(name, term_tbl[i].name, length)) {
        !           879:            if (t)
        !           880:                return (NULL);  /* ambiguous */
        !           881:            t = term_tbl + i;
        !           882:        }
        !           883:     }
        !           884:
        !           885:     if (!t)                    /* unknown */
        !           886:        return (NULL);
        !           887:
        !           888:     /* Success: set terminal type now */
        !           889:
        !           890:     term = t;
        !           891:     term_initialised = FALSE;
        !           892:     name = term->name;
        !           893:
        !           894:     if (term->scale != null_scale)
        !           895:        fputs("Warning : scale interface is not null_scale - may not work with multiplot\n", stderr);
        !           896:
        !           897:     /* check that optional fields are initialised to something */
        !           898:     if (term->text_angle == 0)
        !           899:        term->text_angle = null_text_angle;
        !           900:     if (term->justify_text == 0)
        !           901:        term->justify_text = null_justify_text;
        !           902:     if (term->point == 0)
        !           903:        term->point = do_point;
        !           904:     if (term->arrow == 0)
        !           905:        term->arrow = do_arrow;
        !           906:     if (term->set_font == 0)
        !           907:        term->set_font = set_font_null;
        !           908:     if (term->pointsize == 0)
        !           909:        term->pointsize = do_pointsize;
        !           910:     if (term->linewidth == 0)
        !           911:        term->linewidth = null_linewidth;
        !           912:
        !           913:     /* Special handling for unixplot term type */
        !           914:     if (!strncmp("unixplot", name, 8)) {
        !           915:        UP_redirect(2);         /* Redirect actual stdout for unixplots */
        !           916:     } else if (unixplot) {
        !           917:        UP_redirect(3);         /* Put stdout back together again. */
        !           918:     }
        !           919:     if (interactive)
        !           920:        fprintf(stderr, "Terminal type set to '%s'\n", name);
        !           921:
        !           922:     return (t);
        !           923: }
        !           924:
        !           925: /*
        !           926:  * Routine to detect what terminal is being used (or do anything else
        !           927:  * that would be nice).  One anticipated (or allowed for) side effect
        !           928:  * is that the global ``term'' may be set.
        !           929:  * The environment variable GNUTERM is checked first; if that does
        !           930:  * not exist, then the terminal hardware is checked, if possible,
        !           931:  * and finally, we can check $TERM for some kinds of terminals.
        !           932:  * A default can be set with -DDEFAULTTERM=myterm in the Makefile
        !           933:  * or #define DEFAULTTERM myterm in term.h
        !           934:  */
        !           935: /* thanks to osupyr!alden (Dave Alden) for the original GNUTERM code */
        !           936: void init_terminal()
        !           937: {
        !           938:     char *term_name = DEFAULTTERM;
        !           939: #if (defined(__TURBOC__) && defined(MSDOS) && !defined(_Windows)) || defined(NEXT) || defined(SUN) || defined(X11)
        !           940:     char *env_term = NULL;     /* from TERM environment var */
        !           941: #endif
        !           942: #ifdef X11
        !           943:     char *display = NULL;
        !           944: #endif
        !           945:     char *gnuterm = NULL;
        !           946:
        !           947:     /* GNUTERM environment variable is primary */
        !           948:     gnuterm = getenv("GNUTERM");
        !           949:     if (gnuterm != (char *) NULL) {
        !           950:        term_name = gnuterm;
        !           951:     } else {
        !           952:
        !           953: #ifdef __ZTC__
        !           954:        term_name = ztc_init();
        !           955: #endif
        !           956:
        !           957: #ifdef VMS
        !           958:        term_name = vms_init();
        !           959: #endif /* VMS */
        !           960:
        !           961: #ifdef NEXT
        !           962:        env_term = getenv("TERM");
        !           963:        if (term_name == (char *) NULL
        !           964:            && env_term != (char *) NULL && strcmp(term, "next") == 0)
        !           965:            term_name = "next";
        !           966: #endif /* NeXT */
        !           967:
        !           968: #ifdef SUN
        !           969:        env_term = getenv("TERM");      /* try $TERM */
        !           970:        if (term_name == (char *) NULL
        !           971:            && env_term != (char *) NULL && strcmp(env_term, "sun") == 0)
        !           972:            term_name = "sun";
        !           973: #endif /* SUN */
        !           974:
        !           975: #ifdef _Windows
        !           976:        term_name = "win";
        !           977: #endif /* _Windows */
        !           978:
        !           979: #ifdef GPR
        !           980:        /* find out whether stdout is a DM pad. See term/gpr.trm */
        !           981:        if (gpr_isa_pad())
        !           982:            term_name = "gpr";
        !           983: #else
        !           984: # ifdef APOLLO
        !           985:        /* find out whether stdout is a DM pad. See term/apollo.trm */
        !           986:        if (apollo_isa_pad())
        !           987:            term_name = "apollo";
        !           988: # endif                                /* APOLLO */
        !           989: #endif /* GPR    */
        !           990:
        !           991: #ifdef X11
        !           992:        env_term = getenv("TERM");      /* try $TERM */
        !           993:        if (term_name == (char *) NULL
        !           994:            && env_term != (char *) NULL && strcmp(env_term, "xterm") == 0)
        !           995:            term_name = "x11";
        !           996:        display = getenv("DISPLAY");
        !           997:        if (term_name == (char *) NULL && display != (char *) NULL)
        !           998:            term_name = "x11";
        !           999:        if (X11_Display)
        !          1000:            term_name = "x11";
        !          1001: #endif /* x11 */
        !          1002:
        !          1003: #ifdef AMIGA
        !          1004:        term_name = "amiga";
        !          1005: #endif
        !          1006:
        !          1007: #if defined(ATARI) || defined(MTOS)
        !          1008:        term_name = "atari";
        !          1009: #endif
        !          1010:
        !          1011: #ifdef UNIXPC
        !          1012:        if (iswind() == 0) {
        !          1013:            term_name = "unixpc";
        !          1014:        }
        !          1015: #endif /* unixpc */
        !          1016:
        !          1017: #ifdef CGI
        !          1018:        if (getenv("CGIDISP") || getenv("CGIPRNT"))
        !          1019:            term_name = "cgi";
        !          1020: #endif /*CGI */
        !          1021:
        !          1022: #ifdef DJGPP
        !          1023:        term_name = "svga";
        !          1024: #endif
        !          1025:
        !          1026: #ifdef GRASS
        !          1027:        term_name = "grass";
        !          1028: #endif
        !          1029:
        !          1030: #ifdef OS2
        !          1031: /*      if (_osmode==OS2_MODE) term_name = "pm" ; else term_name = "emxvga"; */
        !          1032: # ifdef X11
        !          1033: /* This catch is hopefully ok ... */
        !          1034:        env_term = getenv("WINDOWID");
        !          1035:        display = getenv("DISPLAY");
        !          1036:        if ((env_term != (char *) NULL) && (display != (char *) NULL))
        !          1037:            term_name = "x11";
        !          1038:        else
        !          1039: # endif                                /* X11 */
        !          1040:            term_name = "pm";
        !          1041: #endif /*OS2 */
        !          1042:
        !          1043: /* set linux terminal only if LINUX_setup was successfull, if we are on X11
        !          1044:    LINUX_setup has failed, also if we are logged in by network */
        !          1045: #ifdef LINUXVGA
        !          1046:        if (LINUX_graphics_allowed)
        !          1047:            term_name = "linux";
        !          1048: #endif /* LINUXVGA */
        !          1049:     }
        !          1050:
        !          1051:     /* We have a name, try to set term type */
        !          1052:     if (term_name != NULL && *term_name != '\0') {
        !          1053:        if (change_term(term_name, (int) strlen(term_name)))
        !          1054:            return;
        !          1055:        fprintf(stderr, "Unknown or ambiguous terminal name '%s'\n", term_name);
        !          1056:     }
        !          1057:     change_term("unknown", 7);
        !          1058: }
        !          1059:
        !          1060:
        !          1061: #ifdef __ZTC__
        !          1062: char *ztc_init()
        !          1063: {
        !          1064:     int g_mode;
        !          1065:     char *term_name = NULL;
        !          1066:
        !          1067:     g_mode = fg_init();
        !          1068:
        !          1069:     switch (g_mode) {
        !          1070:     case FG_NULL:
        !          1071:        fputs("Graphics card not detected or not supported.\n", stderr);
        !          1072:        exit(1);
        !          1073:     case FG_HERCFULL:
        !          1074:        term_name = "hercules";
        !          1075:        break;
        !          1076:     case FG_EGAMONO:
        !          1077:        term_name = "egamono";
        !          1078:        break;
        !          1079:     case FG_EGAECD:
        !          1080:        term_name = "egalib";
        !          1081:        break;
        !          1082:     case FG_VGA11:
        !          1083:        term_name = "vgamono";
        !          1084:        break;
        !          1085:     case FG_VGA12:
        !          1086:        term_name = "vgalib";
        !          1087:        break;
        !          1088:     case FG_VESA6A:
        !          1089:        term_name = "svgalib";
        !          1090:        break;
        !          1091:     case FG_VESA5:
        !          1092:        term_name = "ssvgalib";
        !          1093:        break;
        !          1094:     }
        !          1095:     fg_term();
        !          1096:     return (term_name);
        !          1097: }
        !          1098: #endif /* __ZTC__ */
        !          1099:
        !          1100:
        !          1101: /*
        !          1102:    This is always defined so we don't have to have command.c know if it
        !          1103:    is there or not.
        !          1104:  */
        !          1105: #if !(defined(UNIXPLOT) || defined(GNUGRAPH))
        !          1106: void UP_redirect(caller)
        !          1107: int caller;
        !          1108: {
        !          1109:     caller = caller;           /* to stop Turbo C complaining
        !          1110:                                   * about caller not being used */
        !          1111: }
        !          1112:
        !          1113: #else /* UNIXPLOT || GNUGRAPH */
        !          1114: void UP_redirect(caller)
        !          1115: int caller;
        !          1116: /*
        !          1117:    Unixplot can't really write to gpoutfile--it wants to write to stdout.
        !          1118:    This is normally ok, but the original design of gnuplot gives us
        !          1119:    little choice.  Originally users of unixplot had to anticipate
        !          1120:    their needs and redirect all I/O to a file...  Not very gnuplot-like.
        !          1121:
        !          1122:    caller:  1 - called from SET OUTPUT "FOO.OUT"
        !          1123:    2 - called from SET TERM UNIXPLOT
        !          1124:    3 - called from SET TERM other
        !          1125:    4 - called from SET OUTPUT
        !          1126:  */
        !          1127: {
        !          1128:     switch (caller) {
        !          1129:     case 1:
        !          1130:        /* Don't save, just replace stdout w/gpoutfile (save was already done). */
        !          1131:        if (unixplot)
        !          1132:            *(stdout) = *(gpoutfile);   /* Copy FILE structure */
        !          1133:        break;
        !          1134:     case 2:
        !          1135:        if (!unixplot) {
        !          1136:            fflush(stdout);
        !          1137:            save_stdout = *(stdout);
        !          1138:            *(stdout) = *(gpoutfile);   /* Copy FILE structure */
        !          1139:            unixplot = 1;
        !          1140:        }
        !          1141:        break;
        !          1142:     case 3:
        !          1143:        /* New terminal in use--put stdout back to original. */
        !          1144: /* closepl(); *//* This is called by the term. */
        !          1145:        fflush(stdout);
        !          1146:        *(stdout) = save_stdout;        /* Copy FILE structure */
        !          1147:        unixplot = 0;
        !          1148:        break;
        !          1149:     case 4:
        !          1150:        /*  User really wants to go to normal output... */
        !          1151:        if (unixplot) {
        !          1152:            fflush(stdout);
        !          1153:            *(stdout) = save_stdout;    /* Copy FILE structure */
        !          1154:        }
        !          1155:        break;
        !          1156:     }
        !          1157: }
        !          1158: #endif /* UNIXPLOT || GNUGRAPH */
        !          1159:
        !          1160:
        !          1161: /* test terminal by drawing border and text */
        !          1162: /* called from command test */
        !          1163: void test_term()
        !          1164: {
        !          1165:     register struct termentry *t = term;
        !          1166:     char *str;
        !          1167:     int x, y, xl, yl, i;
        !          1168:     unsigned int xmax_t, ymax_t;
        !          1169:     char label[MAX_ID_LEN];
        !          1170:     int key_entry_height;
        !          1171:     int p_width;
        !          1172:
        !          1173:     term_start_plot();
        !          1174:     screen_ok = FALSE;
        !          1175:     xmax_t = (unsigned int) (t->xmax * xsize);
        !          1176:     ymax_t = (unsigned int) (t->ymax * ysize);
        !          1177:
        !          1178:     p_width = pointsize * (t->h_tic);
        !          1179:     key_entry_height = pointsize * (t->v_tic) * 1.25;
        !          1180:     if (key_entry_height < (t->v_char))
        !          1181:        key_entry_height = (t->v_char);
        !          1182:
        !          1183:     /* border linetype */
        !          1184:     (*t->linetype) (-2);
        !          1185:     (*t->move) (0, 0);
        !          1186:     (*t->vector) (xmax_t - 1, 0);
        !          1187:     (*t->vector) (xmax_t - 1, ymax_t - 1);
        !          1188:     (*t->vector) (0, ymax_t - 1);
        !          1189:     (*t->vector) (0, 0);
        !          1190:     (void) (*t->justify_text) (LEFT);
        !          1191:     (*t->put_text) (t->h_char * 5, ymax_t - t->v_char * 3, "Terminal Test");
        !          1192:     /* axis linetype */
        !          1193:     (*t->linetype) (-1);
        !          1194:     (*t->move) (xmax_t / 2, 0);
        !          1195:     (*t->vector) (xmax_t / 2, ymax_t - 1);
        !          1196:     (*t->move) (0, ymax_t / 2);
        !          1197:     (*t->vector) (xmax_t - 1, ymax_t / 2);
        !          1198:     /* test width and height of characters */
        !          1199:     (*t->linetype) (-2);
        !          1200:     (*t->move) (xmax_t / 2 - t->h_char * 10, ymax_t / 2 + t->v_char / 2);
        !          1201:     (*t->vector) (xmax_t / 2 + t->h_char * 10, ymax_t / 2 + t->v_char / 2);
        !          1202:     (*t->vector) (xmax_t / 2 + t->h_char * 10, ymax_t / 2 - t->v_char / 2);
        !          1203:     (*t->vector) (xmax_t / 2 - t->h_char * 10, ymax_t / 2 - t->v_char / 2);
        !          1204:     (*t->vector) (xmax_t / 2 - t->h_char * 10, ymax_t / 2 + t->v_char / 2);
        !          1205:     (*t->put_text) (xmax_t / 2 - t->h_char * 10, ymax_t / 2,
        !          1206:                    "12345678901234567890");
        !          1207:     /* test justification */
        !          1208:     (void) (*t->justify_text) (LEFT);
        !          1209:     (*t->put_text) (xmax_t / 2, ymax_t / 2 + t->v_char * 6, "left justified");
        !          1210:     str = "centre+d text";
        !          1211:     if ((*t->justify_text) (CENTRE))
        !          1212:        (*t->put_text) (xmax_t / 2,
        !          1213:                        ymax_t / 2 + t->v_char * 5, str);
        !          1214:     else
        !          1215:        (*t->put_text) (xmax_t / 2 - strlen(str) * t->h_char / 2,
        !          1216:                        ymax_t / 2 + t->v_char * 5, str);
        !          1217:     str = "right justified";
        !          1218:     if ((*t->justify_text) (RIGHT))
        !          1219:        (*t->put_text) (xmax_t / 2,
        !          1220:                        ymax_t / 2 + t->v_char * 4, str);
        !          1221:     else
        !          1222:        (*t->put_text) (xmax_t / 2 - strlen(str) * t->h_char,
        !          1223:                        ymax_t / 2 + t->v_char * 4, str);
        !          1224:     /* test text angle */
        !          1225:     str = "rotated ce+ntred text";
        !          1226:     if ((*t->text_angle) (1)) {
        !          1227:        if ((*t->justify_text) (CENTRE))
        !          1228:            (*t->put_text) (t->v_char,
        !          1229:                            ymax_t / 2, str);
        !          1230:        else
        !          1231:            (*t->put_text) (t->v_char,
        !          1232:                            ymax_t / 2 - strlen(str) * t->h_char / 2, str);
        !          1233:     } else {
        !          1234:        (void) (*t->justify_text) (LEFT);
        !          1235:        (*t->put_text) (t->h_char * 2, ymax_t / 2 - t->v_char * 2, "Can't rotate text");
        !          1236:     }
        !          1237:     (void) (*t->justify_text) (LEFT);
        !          1238:     (void) (*t->text_angle) (0);
        !          1239:     /* test tic size */
        !          1240:     (*t->move) ((unsigned int) (xmax_t / 2 + t->h_tic * (1 + ticscale)), (unsigned) 0);
        !          1241:     (*t->vector) ((unsigned int) (xmax_t / 2 + t->h_tic * (1 + ticscale)), (unsigned int)
        !          1242:                  (ticscale * t->v_tic));
        !          1243:     (*t->move) ((unsigned int) (xmax_t / 2), (unsigned int) (t->v_tic * (1 + ticscale)));
        !          1244:     (*t->vector) ((unsigned int) (xmax_t / 2 + ticscale * t->h_tic), (unsigned int) (t->v_tic * (1
        !          1245:                                                                                                 + ticscale)));
        !          1246:     (*t->put_text) ((unsigned int) (xmax_t / 2 - 10 * t->h_char), (unsigned int) (t->v_tic * 2 +
        !          1247:                                                                                  t->v_char / 2),
        !          1248:                    "test tics");
        !          1249:
        !          1250:     /* test line and point types */
        !          1251:     x = xmax_t - t->h_char * 6 - p_width;
        !          1252:     y = ymax_t - key_entry_height;
        !          1253:     (*t->pointsize) (pointsize);
        !          1254:     for (i = -2; y > key_entry_height; i++) {
        !          1255:        (*t->linetype) (i);
        !          1256:        /*      (void) sprintf(label,"%d",i);  Jorgen Lippert
        !          1257:           lippert@risoe.dk */
        !          1258:        (void) sprintf(label, "%d", i + 1);
        !          1259:        if ((*t->justify_text) (RIGHT))
        !          1260:            (*t->put_text) (x, y, label);
        !          1261:        else
        !          1262:            (*t->put_text) (x - strlen(label) * t->h_char, y, label);
        !          1263:        (*t->move) (x + t->h_char, y);
        !          1264:        (*t->vector) (x + t->h_char * 4, y);
        !          1265:        if (i >= -1)
        !          1266:            (*t->point) (x + t->h_char * 5 + p_width / 2, y, i);
        !          1267:        y -= key_entry_height;
        !          1268:     }
        !          1269:     /* test some arrows */
        !          1270:     (*t->linewidth) (1.0);
        !          1271:     (*t->linetype) (0);
        !          1272:     x = xmax_t / 4;
        !          1273:     y = ymax_t / 4;
        !          1274:     xl = t->h_tic * 5;
        !          1275:     yl = t->v_tic * 5;
        !          1276:     (*t->arrow) (x, y, x + xl, y, TRUE);
        !          1277:     (*t->arrow) (x, y, x + xl / 2, y + yl, TRUE);
        !          1278:     (*t->arrow) (x, y, x, y + yl, TRUE);
        !          1279:     (*t->arrow) (x, y, x - xl / 2, y + yl, FALSE);
        !          1280:     (*t->arrow) (x, y, x - xl, y, TRUE);
        !          1281:     (*t->arrow) (x, y, x - xl, y - yl, TRUE);
        !          1282:     (*t->arrow) (x, y, x, y - yl, TRUE);
        !          1283:     (*t->arrow) (x, y, x + xl, y - yl, TRUE);
        !          1284:
        !          1285:     term_end_plot();
        !          1286: }
        !          1287:
        !          1288: #if 0
        !          1289: # if defined(MSDOS)||defined(g)||defined(MTOS)||defined(OS2)||defined(_Windows)||defined(DOS386)
        !          1290: /* output for some terminal types must be binary to stop non Unix computers
        !          1291:    changing \n to \r\n.
        !          1292:    If the output is not STDOUT, the following code reopens gpoutfile
        !          1293:    with binary mode. */
        !          1294: void reopen_binary()
        !          1295: {
        !          1296:     if (outstr) {
        !          1297:        (void) fclose(gpoutfile);
        !          1298: #  ifdef _Windows
        !          1299:        if (!stricmp(outstr, "PRN")) {
        !          1300:            /* use temp file for windows */
        !          1301:            (void) strcpy(filename, win_prntmp);
        !          1302:        }
        !          1303: #  endif
        !          1304:        if ((gpoutfile = fopen(filename, "wb")) == (FILE *) NULL) {
        !          1305:            if ((gpoutfile = fopen(filename, "w")) == (FILE *) NULL) {
        !          1306:                os_error("cannot reopen file with binary type; output unknown",
        !          1307:                         NO_CARET);
        !          1308:            } else {
        !          1309:                os_error("cannot reopen file with binary type; output reset to ascii",
        !          1310:                         NO_CARET);
        !          1311:            }
        !          1312:        }
        !          1313: #  if defined(__TURBOC__) && defined(MSDOS)
        !          1314: #   ifndef _Windows
        !          1315:        if (!stricmp(outstr, "PRN")) {
        !          1316:            /* Put the printer into binary mode. */
        !          1317:            union REGS regs;
        !          1318:            regs.h.ah = 0x44;   /* ioctl */
        !          1319:            regs.h.al = 0;      /* get device info */
        !          1320:            regs.x.bx = fileno(gpoutfile);
        !          1321:            intdos(&regs, &regs);
        !          1322:            regs.h.dl |= 0x20;  /* binary (no ^Z intervention) */
        !          1323:            regs.h.dh = 0;
        !          1324:            regs.h.ah = 0x44;   /* ioctl */
        !          1325:            regs.h.al = 1;      /* set device info */
        !          1326:            intdos(&regs, &regs);
        !          1327:        }
        !          1328: #   endif                      /* !_Windows */
        !          1329: #  endif                       /* TURBOC && MSDOS */
        !          1330:     }
        !          1331: }
        !          1332:
        !          1333: # endif                                /* MSDOS || g || MTOS || ... */
        !          1334: #endif /* 0 */
        !          1335:
        !          1336: #ifdef VMS
        !          1337: /* these are needed to modify terminal characteristics */
        !          1338: # ifndef VWS_XMAX
        !          1339:    /* avoid duplicate warning; VWS includes these */
        !          1340: #  include <descrip.h>
        !          1341: #  include <ssdef.h>
        !          1342: # endif /* !VWS_MAX */
        !          1343: # include <iodef.h>
        !          1344: # include <ttdef.h>
        !          1345: # include <tt2def.h>
        !          1346: # include <dcdef.h>
        !          1347: # include <stat.h>
        !          1348: # include <fab.h>
        !          1349: /* If you use WATCOM C or a very strict ANSI compiler, you may have to
        !          1350:  * delete or comment out the following 3 lines: */
        !          1351: # ifndef TT2$M_DECCRT3         /* VT300 not defined as of VAXC v2.4 */
        !          1352: #  define TT2$M_DECCRT3 0X80000000
        !          1353: # endif
        !          1354: static unsigned short chan;
        !          1355: static int old_char_buf[3], cur_char_buf[3];
        !          1356: $DESCRIPTOR(sysoutput_desc, "SYS$OUTPUT");
        !          1357:
        !          1358: char *vms_init()
        !          1359: /*
        !          1360:  *  Look first for decw$display (decterms do regis)
        !          1361:  *  Determine if we have a regis terminal
        !          1362:  * and save terminal characteristics
        !          1363:  */
        !          1364: {
        !          1365:     /* Save terminal characteristics in old_char_buf and
        !          1366:        initialise cur_char_buf to current settings. */
        !          1367:     int i;
        !          1368:     if (getenv("DECW$DISPLAY"))
        !          1369:        return ("x11");
        !          1370:     atexit(vms_reset);
        !          1371:     sys$assign(&sysoutput_desc, &chan, 0, 0);
        !          1372:     sys$qiow(0, chan, IO$_SENSEMODE, 0, 0, 0, old_char_buf, 12, 0, 0, 0, 0);
        !          1373:     for (i = 0; i < 3; ++i)
        !          1374:        cur_char_buf[i] = old_char_buf[i];
        !          1375:     sys$dassgn(chan);
        !          1376:
        !          1377:     /* Test if terminal is regis */
        !          1378:     if ((cur_char_buf[2] & TT2$M_REGIS) == TT2$M_REGIS)
        !          1379:        return ("regis");
        !          1380:     return (NULL);
        !          1381: }
        !          1382:
        !          1383: void vms_reset()
        !          1384: /* set terminal to original state */
        !          1385: {
        !          1386:     int i;
        !          1387:     sys$assign(&sysoutput_desc, &chan, 0, 0);
        !          1388:     sys$qiow(0, chan, IO$_SETMODE, 0, 0, 0, old_char_buf, 12, 0, 0, 0, 0);
        !          1389:     for (i = 0; i < 3; ++i)
        !          1390:        cur_char_buf[i] = old_char_buf[i];
        !          1391:     sys$dassgn(chan);
        !          1392: }
        !          1393:
        !          1394: void term_mode_tek()
        !          1395: /* set terminal mode to tektronix */
        !          1396: {
        !          1397:     long status;
        !          1398:     if (gpoutfile != stdout)
        !          1399:        return;                 /* don't modify if not stdout */
        !          1400:     sys$assign(&sysoutput_desc, &chan, 0, 0);
        !          1401:     cur_char_buf[0] = 0x004A0000 | DC$_TERM | (TT$_TEK401X << 8);
        !          1402:     cur_char_buf[1] = (cur_char_buf[1] & 0x00FFFFFF) | 0x18000000;
        !          1403:
        !          1404:     cur_char_buf[1] &= ~TT$M_CRFILL;
        !          1405:     cur_char_buf[1] &= ~TT$M_ESCAPE;
        !          1406:     cur_char_buf[1] &= ~TT$M_HALFDUP;
        !          1407:     cur_char_buf[1] &= ~TT$M_LFFILL;
        !          1408:     cur_char_buf[1] &= ~TT$M_MECHFORM;
        !          1409:     cur_char_buf[1] &= ~TT$M_NOBRDCST;
        !          1410:     cur_char_buf[1] &= ~TT$M_NOECHO;
        !          1411:     cur_char_buf[1] &= ~TT$M_READSYNC;
        !          1412:     cur_char_buf[1] &= ~TT$M_REMOTE;
        !          1413:     cur_char_buf[1] |= TT$M_LOWER;
        !          1414:     cur_char_buf[1] |= TT$M_TTSYNC;
        !          1415:     cur_char_buf[1] |= TT$M_WRAP;
        !          1416:     cur_char_buf[1] &= ~TT$M_EIGHTBIT;
        !          1417:     cur_char_buf[1] &= ~TT$M_MECHTAB;
        !          1418:     cur_char_buf[1] &= ~TT$M_SCOPE;
        !          1419:     cur_char_buf[1] |= TT$M_HOSTSYNC;
        !          1420:
        !          1421:     cur_char_buf[2] &= ~TT2$M_APP_KEYPAD;
        !          1422:     cur_char_buf[2] &= ~TT2$M_BLOCK;
        !          1423:     cur_char_buf[2] &= ~TT2$M_DECCRT3;
        !          1424:     cur_char_buf[2] &= ~TT2$M_LOCALECHO;
        !          1425:     cur_char_buf[2] &= ~TT2$M_PASTHRU;
        !          1426:     cur_char_buf[2] &= ~TT2$M_REGIS;
        !          1427:     cur_char_buf[2] &= ~TT2$M_SIXEL;
        !          1428:     cur_char_buf[2] |= TT2$M_BRDCSTMBX;
        !          1429:     cur_char_buf[2] |= TT2$M_EDITING;
        !          1430:     cur_char_buf[2] |= TT2$M_INSERT;
        !          1431:     cur_char_buf[2] |= TT2$M_PRINTER;
        !          1432:     cur_char_buf[2] &= ~TT2$M_ANSICRT;
        !          1433:     cur_char_buf[2] &= ~TT2$M_AVO;
        !          1434:     cur_char_buf[2] &= ~TT2$M_DECCRT;
        !          1435:     cur_char_buf[2] &= ~TT2$M_DECCRT2;
        !          1436:     cur_char_buf[2] &= ~TT2$M_DRCS;
        !          1437:     cur_char_buf[2] &= ~TT2$M_EDIT;
        !          1438:     cur_char_buf[2] |= TT2$M_FALLBACK;
        !          1439:
        !          1440:     status = sys$qiow(0, chan, IO$_SETMODE, 0, 0, 0, cur_char_buf, 12, 0, 0, 0, 0);
        !          1441:     if (status == SS$_BADPARAM) {
        !          1442:        /* terminal fallback utility not installed on system */
        !          1443:        cur_char_buf[2] &= ~TT2$M_FALLBACK;
        !          1444:        sys$qiow(0, chan, IO$_SETMODE, 0, 0, 0, cur_char_buf, 12, 0, 0, 0, 0);
        !          1445:     } else {
        !          1446:        if (status != SS$_NORMAL)
        !          1447:            lib$signal(status, 0, 0);
        !          1448:     }
        !          1449:     sys$dassgn(chan);
        !          1450: }
        !          1451:
        !          1452: void term_mode_native()
        !          1453: /* set terminal mode back to native */
        !          1454: {
        !          1455:     int i;
        !          1456:     if (gpoutfile != stdout)
        !          1457:        return;                 /* don't modify if not stdout */
        !          1458:     sys$assign(&sysoutput_desc, &chan, 0, 0);
        !          1459:     sys$qiow(0, chan, IO$_SETMODE, 0, 0, 0, old_char_buf, 12, 0, 0, 0, 0);
        !          1460:     for (i = 0; i < 3; ++i)
        !          1461:        cur_char_buf[i] = old_char_buf[i];
        !          1462:     sys$dassgn(chan);
        !          1463: }
        !          1464:
        !          1465: void term_pasthru()
        !          1466: /* set terminal mode pasthru */
        !          1467: {
        !          1468:     if (gpoutfile != stdout)
        !          1469:        return;                 /* don't modify if not stdout */
        !          1470:     sys$assign(&sysoutput_desc, &chan, 0, 0);
        !          1471:     cur_char_buf[2] |= TT2$M_PASTHRU;
        !          1472:     sys$qiow(0, chan, IO$_SETMODE, 0, 0, 0, cur_char_buf, 12, 0, 0, 0, 0);
        !          1473:     sys$dassgn(chan);
        !          1474: }
        !          1475:
        !          1476: void term_nopasthru()
        !          1477: /* set terminal mode nopasthru */
        !          1478: {
        !          1479:     if (gpoutfile != stdout)
        !          1480:        return;                 /* don't modify if not stdout */
        !          1481:     sys$assign(&sysoutput_desc, &chan, 0, 0);
        !          1482:     cur_char_buf[2] &= ~TT2$M_PASTHRU;
        !          1483:     sys$qiow(0, chan, IO$_SETMODE, 0, 0, 0, cur_char_buf, 12, 0, 0, 0, 0);
        !          1484:     sys$dassgn(chan);
        !          1485: }
        !          1486:
        !          1487: void fflush_binary()
        !          1488: {
        !          1489:     typedef short int INT16;   /* signed 16-bit integers */
        !          1490:     register INT16 k;          /* loop index */
        !          1491:     if (gpoutfile != stdout) {
        !          1492:        /* Stupid VMS fflush() raises error and loses last data block
        !          1493:           unless it is full for a fixed-length record binary file.
        !          1494:           Pad it here with NULL characters. */
        !          1495:        for (k = (INT16) ((*gpoutfile)->_cnt); k > 0; --k)
        !          1496:            putc('\0', gpoutfile);
        !          1497:        fflush(gpoutfile);
        !          1498:     }
        !          1499: }
        !          1500: #endif /* VMS */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>