1 /*
2     window.c:
3 
4     Copyright (C) 1991 Barry Vercoe, John ffitch
5 
6     This file is part of Csound.
7 
8     The Csound Library is free software; you can redistribute it
9     and/or modify it under the terms of the GNU Lesser General Public
10     License as published by the Free Software Foundation; either
11     version 2.1 of the License, or (at your option) any later version.
12 
13     Csound is distributed in the hope that it will be useful,
14     but WITHOUT ANY WARRANTY; without even the implied warranty of
15     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16     GNU Lesser General Public License for more details.
17 
18     You should have received a copy of the GNU Lesser General Public
19     License along with Csound; if not, write to the Free Software
20     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21     02110-1301 USA
22 */
23 
24 #include "csoundCore.h"                         /*      WINDOW.C        */
25 #include "cwindow.h"                            /*  graph window mgr    */
26 #include "winEPS.h"                             /* PostSCript routines  */
27                                                 /*  dpwe 16may90        */
28 
29 extern OENTRY* find_opcode_new(CSOUND*, char*, char*, char*);
30 
31 extern void MakeAscii(CSOUND *, WINDAT *, const char *);
32 extern void DrawAscii(CSOUND *, WINDAT *);
33 extern void KillAscii(CSOUND *, WINDAT *);
34 
35 /* somewhere to invoke for no display */
36 
DummyFn1(CSOUND * csound,WINDAT * p,const char * s)37 static void DummyFn1(CSOUND *csound, WINDAT *p, const char *s)
38 {
39     IGN(csound); IGN(p); IGN(s);
40 }
41 
42 /* somewhere to invoke for no display */
43 
DummyFn2(CSOUND * csound,WINDAT * p)44 static void DummyFn2(CSOUND *csound, WINDAT *p)
45 {
46     IGN(csound); IGN(p);
47 }
48 
49 /* somewhere to invoke that returns 1 (!) for dummy exit fn */
50 /* Used to be 1 but seems silly (MR/JPff) */
51 
DummyFn3(CSOUND * csound)52 static int DummyFn3(CSOUND *csound)
53 {
54     IGN(csound);
55     return 0;
56 }
57 
58 /* initial proportions */
59 
60 
61 /* called once on initialisation of program to */
62 /*  choose between teletype or bitmap graphics */
63 
dispinit(CSOUND * csound)64 void dispinit(CSOUND *csound)
65 {
66       OPARMS  O;
67       csound->GetOParms(csound, &O);
68 
69     if (O.displays && !(O.graphsoff || O.postscript)) {
70       if (!csound->isGraphable_)
71       find_opcode_new(csound, "FLrun", NULL, NULL); /* load FLTK for displays */
72       if (csound->isGraphable_)
73         return;         /* provided by window driver: is this session able? */
74     }
75     if (!O.displays) {
76       csound->Message(csound, Str("displays suppressed\n"));
77       csound->csoundMakeGraphCallback_ = DummyFn1;
78       csound->csoundDrawGraphCallback_ = DummyFn2;
79       csound->csoundKillGraphCallback_ = DummyFn2;
80     }
81     else {
82       if (csound->csoundDrawGraphCallback_ == NULL){
83         // if callbacks are not set by host
84         csound->Message(csound, Str("graphics %s, ascii substituted\n"),
85                         ((O.graphsoff || O.postscript) ?
86                          Str("suppressed")
87                          : Str("not supported on this terminal")));
88         csound->csoundMakeGraphCallback_ = MakeAscii;
89         csound->csoundDrawGraphCallback_ = DrawAscii;
90         csound->csoundKillGraphCallback_ = KillAscii;
91       }
92     }
93     csound->csoundExitGraphCallback_ = DummyFn3;
94 }
95 
dispset(CSOUND * csound,WINDAT * wdptr,MYFLT * fdata,int32 npts,char * caption,int waitflg,char * label)96 void dispset(CSOUND *csound,            /* setup a new window       */
97              WINDAT *wdptr,             /*   & init the data struct */
98              MYFLT  *fdata,
99              int32  npts,
100              char   *caption,
101              int    waitflg,
102              char   *label)
103 {
104     OPARMS  O;
105     char *s = caption;
106     char *t = wdptr->caption;
107     char *tlim = t + CAPSIZE - 1;
108 
109 
110     csound->GetOParms(csound, &O);
111     if (!O.displays) return;    // return if displays disabled
112     wdptr->fdata    = fdata;            // init remainder of data structure
113     wdptr->npts     = npts;
114     while (*s != '\0' && t < tlim)
115       *t++ = *s++;                      //  (copy the caption)
116     *t = '\0';
117     // if no window defined for this str, create one
118     if (!wdptr->windid && csound->csoundMakeGraphCallback_ != NULL) {
119       csound->csoundMakeGraphCallback_(csound, wdptr, label);
120       if (O.postscript)
121         PS_MakeGraph(csound, wdptr, label);
122     }
123 
124     wdptr->waitflg  = waitflg;
125     wdptr->polarity = (int16)NOPOL;
126     wdptr->max      = FL(0.0);
127     wdptr->min      = FL(0.0);
128     wdptr->absmax   = FL(0.0);
129     wdptr->oabsmax  = FL(0.0);
130     wdptr->danflag  = 0;
131 
132 }
133 
dispexit(CSOUND * csound)134 int dispexit(CSOUND *csound)
135 {
136     OPARMS  O;
137     csound->GetOParms(csound, &O);
138     if (O.postscript)
139       PS_ExitGraph(csound);     /* Write trailer to PostScript file  */
140     /* prompt for exit from last active window */
141     int ret = -1;
142     if (csound->csoundExitGraphCallback_) {
143         ret = csound->csoundExitGraphCallback_(csound);
144     }
145     return ret;
146 }
147 
display(CSOUND * csound,WINDAT * wdptr)148 void display(CSOUND *csound, WINDAT *wdptr)   /* prepare a MYFLT array, then  */
149                                               /*   call the graphing fn       */
150 {
151     MYFLT   *fp, *fplim;
152     MYFLT   max, min, absmax, fval;
153     int     pol;
154     OPARMS  O;
155     csound->GetOParms(csound, &O);
156 
157     if (!O.displays)  return;   /* displays disabled? return */
158     fp = wdptr->fdata;
159     if(fp == NULL) return;
160     fplim = fp + wdptr->npts;
161     for (max = *fp++, min = max; fp < fplim; ) {  /* find max & min values */
162       if ((fval = *fp++) > max)       max = fval;
163       else if (fval < min)            min = fval;
164     }
165     absmax = (-min > max )? (-min):max;
166     wdptr->max    = max;                 /* record most pos and most */
167     wdptr->min    = min;                 /*  neg this array of data  */
168     wdptr->absmax = absmax;              /* record absmax this data  */
169     /* VL: absmax needs to be updated at every display in some cases */
170     if (wdptr->absflag  || absmax > wdptr->oabsmax)
171       wdptr->oabsmax = absmax;           /* & absmax over life of win */
172     pol = wdptr->polarity;     /* adjust polarity flg for life of win */
173     if (pol == (int16)NOPOL)  {
174       if (max > FL(0.0) && min < FL(0.0))      pol = (int16)BIPOL;
175       else if (max <= FL(0.0) && min <FL(0.0)) pol = (int16)NEGPOL;
176       else                                     pol = (int16)POSPOL;
177     }
178     else if (pol == (int16)POSPOL && min < FL(0.0)) pol = (int16)BIPOL;
179     else if (pol == (int16)NEGPOL && max > FL(0.0)) pol = (int16)BIPOL;
180     wdptr->polarity = pol;
181 
182     if (O.odebug) csound->Message(csound, " calling draw callback \n");
183     /* now graph the function */
184     csound->csoundDrawGraphCallback_(csound, wdptr);
185 
186 
187     /* Write postscript code */
188     if (O.postscript)
189       PS_DrawGraph(csound, wdptr);
190 }
191