[BACK]Return to plotgnuplot.c CVS log [TXT][DIR] Up to [local] / OpenXM_contrib / pari-2.2 / src / graph

Annotation of OpenXM_contrib/pari-2.2/src/graph/plotgnuplot.c, Revision 1.2

1.2     ! noro        1: /* $Id: plotgnuplot.c,v 1.10 2002/06/29 09:31:16 karim Exp $
1.1       noro        2:
                      3: Copyright (C) 2000  The PARI group.
                      4:
                      5: This file is part of the PARI/GP package.
                      6:
                      7: PARI/GP is free software; you can redistribute it and/or modify it under the
                      8: terms of the GNU General Public License as published by the Free Software
                      9: Foundation. It is distributed in the hope that it will be useful, but WITHOUT
                     10: ANY WARRANTY WHATSOEVER.
                     11:
                     12: Check the License for details. You should have received a copy of it, along
                     13: with the package; see the file 'COPYING'. If not, write to the Free Software
                     14: Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
                     15:
                     16: /*******************************************************************/
                     17: /*                                                                 */
                     18: /*                  HI-RES PLOT. GNUPLOT INTERFACE                 */
                     19: /*                   written by Ilya Zakharevich                   */
                     20: /*                                                                 */
                     21: /*******************************************************************/
                     22: # include "pari.h"
                     23: #include "rect.h"
                     24: #define croak(str) err(talker,str)
                     25: #define SET_OPTIONS_FROM_STRING
                     26: #define GNUPLOT_OUTLINE_STDOUT
                     27: #define DONT_POLLUTE_INIT
1.2     ! noro       28:
        !            29: /* The gnuplot library may reference a function with *this* name */
        !            30: #define mys_mouse_feedback_rectangle set_mouse_feedback_rectangle
1.1       noro       31: #include "Gnuplot.h"
                     32:
                     33: #ifdef __EMX__
                     34: #  define DEF_TERM "pm"
                     35: #else
                     36: #  define DEF_TERM (getenv("DISPLAY") ? "X11" : "dumb")
                     37: #endif
                     38:
1.2     ! noro       39: #ifdef BOTH_GNUPLOT_AND_X11
        !            40: #  ifdef GNUPLOT_AND_X11_PREFER_GNUPLOT
        !            41: #    define DEFAULT_IS_BUILTIN 0
        !            42: #  else        /* !( defined GNUPLOT_AND_X11_PREFER_GNUPLOT ) */
        !            43: #    define DEFAULT_IS_BUILTIN 1
        !            44: #  endif       /* defined GNUPLOT_AND_X11_PREFER_GNUPLOT */
        !            45: #endif
        !            46:
        !            47: #  ifdef BOTH_GNUPLOT_AND_X11
        !            48: int is_builtin = DEFAULT_IS_BUILTIN;
        !            49: int X11_init;
        !            50: static void my_rectdraw0(long *w, long *x, long *y, long lw, long do_free);
        !            51: #  endif
        !            52:
1.1       noro       53: void
                     54: rectdraw0(long *w, long *x, long *y, long lw, long do_free)
1.2     ! noro       55: #  ifdef BOTH_GNUPLOT_AND_X11
        !            56: {
        !            57:     if (is_builtin) {
        !            58:        X11_rectdraw0(w, x, y, lw, do_free);
        !            59:        return;
        !            60:     }
        !            61:
        !            62:     my_rectdraw0(w, x, y, lw, do_free);
        !            63:     return;
        !            64: }
        !            65:
        !            66: static void
        !            67: my_rectdraw0(long *w, long *x, long *y, long lw, long do_free)
        !            68: #  endif       /* defined BOTH_GNUPLOT_AND_X11 */
1.1       noro       69: {
                     70:   double *ptx,*pty;
                     71:   long i,j,x0,y0, hjust, vjust, hgap, vgap, hgapsize, vgapsize;
                     72:   long good, seen_graph = 0;
                     73:   int point_type = -1, line_type = 0;
                     74:   PariRect *e;
                     75:   RectObj *p1;
                     76:   int strdir = RoSTdirLEFT, can_justify = 1, shift = 0, xstart, xend;
                     77:
                     78:   (void)do_free;
                     79:   PARI_get_plot(0);
                     80:
                     81:   hgapsize = h_unit;  vgapsize = v_unit;
                     82:   if (hgapsize == 1)
                     83:     hgapsize = 2;      /* Vertical direction is subjectively different! */
                     84:   /* Find the info about the *actual* x and y-coords of the
                     85:      rectangles.  Use the first rectangle with has_graph attribute. */
                     86:
                     87:   for(i=0;i<lw;i++) {
                     88:       e=rectgraph[w[i]];
                     89:       if (RHasGraph(e)) {
                     90:          set_mouse_feedback_rectangle(
                     91:                x[i], x[i] + RXsize(e) - 1,
                     92:                w_height - 1 - y[i] - (RYsize(e) - 1), w_height - 1 - y[i],
                     93:                (0 - RXshift(e))/RXscale(e),
                     94:                (RXsize(e) - 1 - RXshift(e))/RXscale(e),
                     95:                (RYsize(e) - 1 - RYshift(e))/RYscale(e),
                     96:                (0 - RYshift(e))/RYscale(e)
                     97:          );
                     98:          seen_graph = 1;
                     99:          break;
                    100:       }
                    101:   }
                    102:   if (!seen_graph)                     /* Put some reasonable values */
                    103:          set_mouse_feedback_rectangle( 0, w_width - 1, 0, w_height - 1,
                    104:                                        0, 0, 0, 0);
                    105:
                    106: #if 0
                    107:   graphics();                          /* Switch on terminal. */
                    108: #else
                    109:   term_start_plot();                   /* Switch on terminal. */
                    110: #endif
                    111:   linetype(line_type);                 /* X does not work otherwise. */
                    112:   setpointsize(pointsize);
                    113:
                    114:   for(i=0;i<lw;i++)
                    115:   {
                    116:     e=rectgraph[w[i]]; p1=RHead(e); x0=x[i]; y0=y[i];
                    117:     while(p1)
                    118:     {
                    119:       switch(RoType(p1))
                    120:       {
                    121:        case ROt_PT:
                    122:          point(DTOL(RoPTx(p1)+x0), w_height - 1 - DTOL(RoPTy(p1) + y0),
                    123:                point_type);
                    124:          break;
                    125:        case ROt_LN:
                    126:          move(DTOL(RoLNx1(p1)+x0), w_height - 1 - DTOL(RoLNy1(p1) + y0));
                    127:          vector(DTOL(RoLNx2(p1)+x0), w_height - 1 - DTOL(RoLNy2(p1) + y0));
                    128:          break;
                    129:        case ROt_BX:
                    130:          move(DTOL(RoBXx1(p1)+x0), w_height - 1 - DTOL(RoBXy1(p1) + y0));
                    131:          vector(DTOL(RoBXx2(p1)+x0), w_height - 1 - DTOL(RoBXy1(p1) + y0));
                    132:          vector(DTOL(RoBXx2(p1)+x0), w_height - 1 - DTOL(RoBXy2(p1) + y0));
                    133:          vector(DTOL(RoBXx1(p1)+x0), w_height - 1 - DTOL(RoBXy2(p1) + y0));
                    134:          vector(DTOL(RoBXx1(p1)+x0), w_height - 1 - DTOL(RoBXy1(p1) + y0));
                    135:          break;
                    136:        case ROt_MP:
                    137:          ptx=RoMPxs(p1);
                    138:          pty=RoMPys(p1);
                    139:          for(j=0;j<RoMPcnt(p1);j++)
                    140:          {
                    141:            point(DTOL(ptx[j] + x0),  w_height - 1 - DTOL(pty[j] + y0),
                    142:                  point_type);
                    143:          }
                    144:          break;
                    145:        case ROt_ML:
                    146:          ptx=RoMLxs(p1);
                    147:          pty=RoMLys(p1);
                    148:          j = 0;
                    149:          if (DTOL(ptx[j]+x0) < 0 || DTOL(ptx[j]+x0) >= w_width
                    150:              || DTOL(pty[j] + y0) < 0 || DTOL(pty[j] + y0) >= w_height) {
                    151:            good = 0;
                    152:          } else {
                    153:            move(DTOL(ptx[j]+x0), w_height - 1 - DTOL(pty[j] + y0));
                    154:            good = 1;
                    155:          }
                    156:          for(j=1;j<RoMLcnt(p1);j++)
                    157:          {
                    158:            if (good) {
                    159:              if (DTOL(ptx[j] + x0) < 0 || DTOL(ptx[j]+x0) >= w_width
                    160:                  || DTOL(pty[j] + y0) < 0 || DTOL(pty[j] + y0) >= w_height) {
                    161:                good = 0;
                    162:              } else {
                    163:                vector(DTOL(ptx[j] + x0), w_height - 1 - DTOL(pty[j] + y0));
                    164:              }
                    165:            } else {
                    166:              if (DTOL(ptx[j] + x0) < 0 || DTOL(ptx[j] + x0) >= w_width
                    167:                  || DTOL(pty[j] + y0) < 0 || DTOL(pty[j] + y0) >= w_height) {
                    168:              } else {
                    169:                move(DTOL(ptx[j]+x0), w_height - 1 - DTOL(pty[j] + y0));
                    170:                good = 1;
                    171:              }
                    172:            }
                    173:          }
                    174:          break;
                    175:        case ROt_ST:
                    176:          hjust = RoSTdir(p1) & RoSTdirHPOS_mask;
                    177:          vjust = RoSTdir(p1) & RoSTdirVPOS_mask;
                    178:          hgap = RoSTdir(p1) & RoSTdirHGAP;
                    179:          if (hgap)
                    180:            hgap = (hjust == RoSTdirLEFT) ? hgapsize : -hgapsize;
                    181:          vgap = RoSTdir(p1) & RoSTdirVGAP;
                    182:          if (vgap)
                    183:            vgap = (vjust == RoSTdirBOTTOM) ? vgapsize : -vgapsize;
                    184:          if (vjust != RoSTdirVCENTER)
                    185:            vgap += ((vjust == RoSTdirTOP) ? -1 : 1) * (f_height - 1)/2;
                    186:          if (strdir != hjust) {
                    187:              shift = (hjust == RoSTdirLEFT ? 0 :
                    188:                       (hjust == RoSTdirRIGHT ? 2 : 1));
                    189:              can_justify = justify_text(shift); /* 1 for LEFT */
                    190:              strdir = RoSTdir(p1);
                    191:          }
                    192:          xstart = DTOL(RoSTx(p1) + x0) + hgap
                    193:              - (can_justify ? 0
                    194:                 : ((RoSTl(p1) * pari_plot.fwidth - 1) * shift / 2));
                    195:          xend = xstart + (can_justify ? 0 : RoSTl(p1) * pari_plot.fwidth - 1);
                    196:          if (xstart < 0 || xend >= w_width
                    197:              || DTOL(RoSTy(p1) + y0) < 0
                    198:              || DTOL(RoSTy(p1) + y0) >= w_height) {
                    199:          } else {
                    200:              put_text(xstart,
                    201:                       w_height - 1 - DTOL(RoSTy(p1) + y0) + vgap,
                    202:                       RoSTs(p1));
                    203:          }
                    204:          break;
                    205:        case ROt_PTT:
                    206:          point_type = RoPTTpen(p1);
                    207:          break;
                    208:        case ROt_PTS:
                    209:          pointsize = RoPTSsize(p1);
                    210:          setpointsize(pointsize);
                    211:          break;
                    212:        case ROt_LNT:
                    213:          linetype(RoLNTpen(p1));
                    214:          break;
                    215:        default: break;
                    216:       }
                    217:       p1=RoNext(p1);
                    218:     }
                    219:   }
                    220: #if 0
                    221:   text();                              /* Reset terminal */
                    222: #else
                    223:   term_end_plot();                     /* Reset terminal. */
                    224: #endif
                    225: }
                    226:
                    227: void
                    228: PARI_get_plot(long fatal)
                    229: {
1.2     ! noro      230: #ifdef BOTH_GNUPLOT_AND_X11
        !           231:   if (is_builtin) {
        !           232:       if (X11_init)
        !           233:          return;
        !           234:       if (getenv("DISPLAY")) {
        !           235:          X11_PARI_get_plot(fatal);
        !           236:          X11_init = 1;
        !           237:          return;
        !           238:       }
        !           239:       is_builtin = 0;                  /* Don't defaut to X11 if no DISPLAY */
        !           240:   }
        !           241: #endif /* defined BOTH_GNUPLOT_AND_X11 */
        !           242:   if (pari_plot.init)
1.1       noro      243:     return;
                    244:   term_set( DEF_TERM );
1.2     ! noro      245:   (void)fatal;
1.1       noro      246: }
                    247:
                    248:
                    249: long
                    250: term_set(char *s)
                    251: {
                    252:   char *t, *size = NULL;
                    253:   double x, y;
                    254:   static int had_error;
                    255:
1.2     ! noro      256: #ifdef BOTH_GNUPLOT_AND_X11
        !           257:   if (is_builtin) {
        !           258:       if (!strcmp(s,"builtin")) {
        !           259:          if (!getenv("DISPLAY"))
        !           260:              goto complain;
        !           261:          return X11_term_set(s);
        !           262:       }
        !           263:       is_builtin = 0;
        !           264:       /* The following line may switch on Gnuplot's X11 term first: */
        !           265:       /* PARI_get_plot(1); */
        !           266:   } else if (!strcmp(s,"builtin")) {
        !           267: /*      if (!X11_init) {*/
        !           268:          if (!getenv("DISPLAY")) {
        !           269:            complain:
        !           270:              croak("The builtin-X11 plotting requires DISPLAY environment variable set");
        !           271:          }
        !           272:          /* Restore the safe state by switching to a do-little terminal */
        !           273:          if (pari_plot.init && strcmp(pari_plot.name, "dumb"))
        !           274:              term_set("dumb");
        !           275:          is_builtin = 1;
        !           276:          X11_PARI_get_plot(1);
        !           277:          X11_init = 1;
        !           278: /*      }*/
        !           279:       return X11_term_set(s);
        !           280:   }
        !           281: #endif /* defined BOTH_GNUPLOT_AND_X11     */
1.1       noro      282:   setup_gpshim();
                    283:   if (*s == 0)
                    284:       s = pari_plot.name;
                    285:   t = s;
                    286:   if (t[1] == '\0' && t[0] == '?') {
                    287:      list_terms();
                    288:      return 1;
                    289:   }
                    290:   while (*t && !(*t == ' ' || *t == '\t' || *t == '\n' || *t == '='))
                    291:        t++;
                    292:   if ((t-s) > PLOT_NAME_LEN)
                    293:       err(talker,"name \"%s\" for terminal too long", s);
                    294:   if (*pari_plot.name && !had_error
                    295:       && (strlen(pari_plot.name) != t - s /* As strcmp() without \0 at end */
                    296:          || (strncmp(pari_plot.name, s, t-s) != 0)) )
                    297:        reset();
                    298:   strncpy(pari_plot.name,s,t-s);
                    299:   pari_plot.name[t-s] = '\0';
                    300:
                    301:   had_error = 1;
                    302:   if (!termset( pari_plot.name ))
                    303:       err(talker,"error setting terminal \"%s\"", pari_plot.name);
                    304:   had_error = 0;
                    305:
                    306:   if (*t == '=') {
                    307:     size = ++t;
                    308:     x = atof(size);
                    309:     while (*t && !(*t == ' ' || *t == '\t' || *t == '\n' || *t == ','))
                    310:        t++;
                    311:     if (*t != ',')
                    312:       err(talker, "Terminal size directive without ','");
                    313:     y = atof(++t);
                    314:     while (*t && !(*t == ' ' || *t == '\t' || *t == '\n'))
                    315:        t++;
                    316:     plotsizes_scale(x*(1 + 1e-6)/termprop(xmax),
                    317:                    y*(1 + 1e-6)/termprop(ymax)); /* Later - truncated! */
                    318:   } else {
                    319:     plotsizes_scale(1,1);
                    320:   }
                    321:
                    322:   /* *Needed*, say, by gif output: */
                    323:   set_options_from(t);
                    324:
                    325: #if 0
                    326:   gptable_init();                      /* Init terminal. */
                    327: #else
                    328:   term_init();
                    329: #endif
                    330:
                    331:   setpointsize(pointsize);
                    332:
                    333:   w_width = scaled_xmax();
                    334:   w_height = scaled_ymax();
                    335:   f_height = termprop(v_char);
                    336:   f_width = termprop(h_char);
                    337:   h_unit = termprop(h_tic);
                    338:   v_unit = termprop(v_tic);
                    339:   pari_plot.init = 1;
                    340:
                    341:   return 1;
                    342: }
                    343:
                    344: long
1.2     ! noro      345: plot_outfile_set(char *s)
        !           346: {
1.1       noro      347:     int normal = (strcmp(s,"-") == 0);
                    348:
1.2     ! noro      349:     /* Intentionally no check for is_builtin, let it always affect gnuplot:
        !           350:        this way one can set the outfile before switching the terminal... */
        !           351:
1.1       noro      352:     setup_gpshim();
                    353:     /* Delegate all the hard work to term_set_output() */
                    354:
                    355:     if (normal)
                    356:        term_set_output(NULL);
                    357:     else {                             /* term_set_output() needs
                    358:                                           a malloced string */
                    359:        char *s1 = (char*) malloc(strlen(s) + 1);
                    360:
                    361:        strcpy(s1,s);
                    362:        term_set_output(s1);
                    363:     }
                    364:     return 1;
                    365: }
                    366:
                    367: void
                    368: set_pointsize(double d)
                    369: {
1.2     ! noro      370: #ifdef BOTH_GNUPLOT_AND_X11
        !           371:     if (is_builtin) {
        !           372:        X11_set_pointsize(d);
        !           373:        return;
        !           374:     }
        !           375: #endif /* defined BOTH_GNUPLOT_AND_X11     */
1.1       noro      376:     pointsize = d;
                    377:     if (pari_plot.init)
                    378:        setpointsize(d);
                    379: }
                    380:
1.2     ! noro      381: #ifdef HAS_DLOPEN
1.1       noro      382: #include <dlfcn.h>
                    383:
                    384: get_term_ftable_t *
                    385: get_term_ftable_get(void) /* Establish runtime link with gnuplot engine */
                    386: {
1.2     ! noro      387:     char *s = getenv("GNUPLOT_DRAW_DLL"), *s1, buf[4096];
1.1       noro      388:     void *h, *f;
                    389:     int mode = RTLD_LAZY;
1.2     ! noro      390:     char fbuf[2048];
1.1       noro      391:
                    392: #ifdef RTLD_GLOBAL
                    393:        mode |= RTLD_GLOBAL;
                    394: #endif
                    395:
1.2     ! noro      396: #ifdef DYNAMIC_PLOTTING_RUNTIME_LINK
1.1       noro      397:     if (!s)
                    398:        s = DYNAMIC_PLOTTING_RUNTIME_LINK;
1.2     ! noro      399: #endif
        !           400: #ifndef DYNAMIC_PLOTTING_RUNTIME_LINK_NO_PERL
        !           401:     /* Allow user disabling by setting GNUPLOT_DRAW_DLL_NO_PERL=1 */
        !           402:     if (!s && (!(s1 = getenv("GNUPLOT_DRAW_DLL_NO_PERL")) || !atoi(s1))) {
        !           403:        char cmdbuf[256];
        !           404:        FILE *p;
        !           405:        char ext[256];
        !           406:        char *sub;
        !           407:        char name[256];
        !           408:        char *n = "Gnuplot";
        !           409:
        !           410:        /* Make 2 runs of Perl to shorten the command length */
        !           411:        /* Find the directory of the Term::Gnuplot's PM and DLL extension */
        !           412:        sprintf(cmdbuf, "perl -MTerm::Gnuplot -MConfig -wle %c"
        !           413:                "print $INC{qq(Term/Gnuplot.pm)};print $Config{dlext}%c",
        !           414:                SHELL_Q, SHELL_Q);
        !           415:        p = popen(cmdbuf, "r");
        !           416:        if (!p || !fgets(fbuf, sizeof(fbuf), p) || !fgets(ext, sizeof(ext), p))
        !           417:            goto end_find;
        !           418:        pclose(p);
        !           419:        /* Find the directory of the DLL file */
        !           420:        sub = strrchr(fbuf,'/');
        !           421:        if (!sub)
        !           422:            goto end_find;
        !           423:        /* Do as XSLoader */
        !           424:        sub[0] = 0;
        !           425:        sub = strrchr(fbuf,'/');
        !           426:        if (!sub)
        !           427:            goto end_find;
        !           428:        if (sub - fbuf >= 9 && !strncmp(sub - 9, "/blib/lib",9)) {
        !           429:            strcpy(sub - 3,"arch/"); /* Uninstalled module */
        !           430:            sub++;
        !           431:        }
        !           432:        strcpy(sub + 1,"auto/Term/Gnuplot/");
        !           433:        /* Find the name of the DLL file */
        !           434:        sprintf(cmdbuf, "perl -MDynaLoader -we %c"
        !           435:                "package DynaLoader; "
        !           436:                "print mod2fname([qw(Term Gnuplot)]) if defined &mod2fname%c",
        !           437:                SHELL_Q, SHELL_Q);
        !           438:        p = popen(cmdbuf, "r");
        !           439:        if (p) {
        !           440:            if (fgets(name, sizeof(name), p))
        !           441:                n = name;
        !           442:            pclose(p);
        !           443:        }
        !           444:        if (strlen(fbuf) + 10 + strlen(n) + strlen(ext) > sizeof(fbuf))
        !           445:            croak("Buffer overflow finding gnuplot DLL");
        !           446:        strcpy(sub + strlen(sub), n);
        !           447:        strcpy(sub + strlen(sub), ".");
        !           448:        strcpy(sub + strlen(sub), ext);
        !           449:        sub[strlen(sub)-1] = 0; /* Trailing \n of ext */
        !           450:        s = fbuf;
        !           451:     }
        !           452:   end_find:
        !           453: #endif
        !           454:     if (!s)    /* The trailing \n is important: one may put . to the command */
        !           455:        croak("Can't find Gnuplot drawing engine DLL,\n\t"
        !           456:              "set GNUPLOT_DRAW_DLL environment variable"
        !           457:              " to the name of the DLL,\n\t"
        !           458:              "or install Perl module Term::Gnuplot, e.g., by running\n\t\t"
        !           459:              "perl -MCPAN -e \"install Term::Gnuplot\"\n");
1.1       noro      460:     h = dlopen(s, mode);
                    461:     if (!h) {
                    462:        sprintf(buf,"Can't load Gnuplot drawing engine from '%s': %s", s, dlerror());
                    463:        croak(buf);
                    464:        return 0;
                    465:     }
                    466:     f = dlsym(h, "get_term_ftable");
                    467:     if (f)
                    468:        return (get_term_ftable_t *)f;
                    469:     sprintf(buf, "Can't resolve 'get_term_ftable' function from Gnuplot drawing engine '%s': %s", s, dlerror());
                    470:     croak(buf);
                    471:     return 0;
                    472: }
1.2     ! noro      473: #else  /* !( defined HAS_DLOPEN ) */
        !           474:
        !           475: get_term_ftable_t *
        !           476: get_term_ftable_get(void) /* Establish runtime link with gnuplot engine */
        !           477: {
        !           478:     croak("No dlopen() support present, required for dynamic gnuplot-DLL link");
        !           479:     return NULL;
        !           480: }
        !           481:
        !           482: #endif /* defined HAS_DLOPEN */

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