1 /* This file is part of the GNU plotutils package. Copyright (C) 1995,
2 1996, 1997, 1998, 1999, 2000, 2005, 2008, Free Software Foundation, Inc.
3
4 The GNU plotutils package is free software. You may redistribute it
5 and/or modify it under the terms of the GNU General Public License as
6 published by the Free Software foundation; either version 2, or (at your
7 option) any later version.
8
9 The GNU plotutils package is distributed in the hope that it will be
10 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 General Public License for more details.
13
14 You should have received a copy of the GNU General Public License along
15 with the GNU plotutils package; see the file COPYING. If not, write to
16 the Free Software Foundation, Inc., 51 Franklin St., Fifth Floor,
17 Boston, MA 02110-1301, USA. */
18
19 /* This file is specific to libplot, rather than libplotter. It defines
20 the new (i.e., thread-safe) C API. The new C API contains wrappers
21 around the operations that may be applied to any Plotter object, plus
22 two additional functions (pl_newpl_r, pl_deletepl_r) that are specific
23 to libplot.
24
25 pl_newpl_r/pl_deletepl_r construct and destroy Plotter instances. Their
26 names resemble the C++ operations `new' and `delete'. When a new
27 Plotter of any type is constructed, the appropriate `default_init'
28 structure, which contains function pointers, is copied into it. Then
29 its `initialize' method is invoked. Before the Plotter is destroyed,
30 its `terminate' method is invoked similarly.
31
32 The C API also includes the functions pl_newplparams/pl_deleteplparams,
33 which create/destroy PlotterParams instances, and wrappers around the
34 methods that may be applied to any PlotterParams object. A pointer to a
35 PlotterParams object is passed to pl_newpl_r(). It specifies the
36 device-driver parameters of the Plotter that will be created. */
37
38 #include "sys-defines.h"
39 #include "extern.h"
40 #include "plot.h" /* header file for C API */
41
42 /* Known Plotter types, indexed into by a short mnemonic case-insensitive
43 string: "generic"=generic (i.e. base Plotter class), "bitmap"=bitmap,
44 "meta"=metafile, "tek"=Tektronix, "regis"=ReGIS, "hpgl"=HP-GL/2,
45 "pcl"=PCL 5, "fig"=xfig, "cgm"=CGM, "ps"=PS, "ai"="AI", "svg"=SVG,
46 "gif"=GIF, "pnm"=PNM (i.e. PBM/PGM/PPM), "z"=PNG, "X"=X11,
47 "Xdrawable"=X11Drawable. */
48
49 typedef struct
50 {
51 const char *name;
52 const Plotter *default_init;
53 }
54 Plotter_data;
55
56 /* Initializations for the function-pointer part of each type of Plotter.
57 Each of the initializing structures listed here is defined in the
58 corresponding ?_defplot.c file. */
59 static const Plotter_data _plotter_data[] =
60 {
61 {"generic", &_pl_g_default_plotter},
62 {"bitmap", &_pl_b_default_plotter},
63 {"meta", &_pl_m_default_plotter},
64 {"tek", &_pl_t_default_plotter},
65 {"regis", &_pl_r_default_plotter},
66 {"hpgl", &_pl_h_default_plotter},
67 {"pcl", &_pl_q_default_plotter},
68 {"fig", &_pl_f_default_plotter},
69 {"cgm", &_pl_c_default_plotter},
70 {"ps", &_pl_p_default_plotter},
71 {"ai", &_pl_a_default_plotter},
72 {"svg", &_pl_s_default_plotter},
73 {"gif", &_pl_i_default_plotter},
74 {"pnm", &_pl_n_default_plotter},
75 #ifdef INCLUDE_PNG_SUPPORT
76 {"png", &_pl_z_default_plotter},
77 #endif
78 #ifndef X_DISPLAY_MISSING
79 {"Xdrawable", &_pl_x_default_plotter},
80 {"X", &_pl_y_default_plotter},
81 #endif /* not X_DISPLAY_MISSING */
82 {(const char *)NULL, (const Plotter *)NULL}
83 };
84
85 /* forward references */
86 static bool _string_to_plotter_data (const char *type, int *position);
87 static void _api_warning (const char *msg);
88
89 /* These are two user-callable functions that are specific to the new
90 (i.e., thread-safe) C binding: pl_newpl_r, pl_deletepl_r. */
91
92 Plotter *
pl_newpl_r(const char * type,FILE * infile,FILE * outfile,FILE * errfile,const PlotterParams * plotter_params)93 pl_newpl_r (const char *type, FILE *infile, FILE *outfile, FILE *errfile, const PlotterParams *plotter_params)
94 {
95 bool found;
96 int position;
97 Plotter *_plotter;
98
99 /* determine initialization for specified plotter type */
100 found = _string_to_plotter_data (type, &position);
101 if (!found)
102 {
103 _api_warning ("ignoring request to create plotter of unknown type");
104 return NULL;
105 }
106
107 /* create Plotter, copy function pointers to it */
108 _plotter = (Plotter *)_pl_xmalloc (sizeof(Plotter));
109 memcpy (_plotter, _plotter_data[position].default_init, sizeof(Plotter));
110
111 /* create PlotterData structure, install it in Plotter */
112 _plotter->data = (plPlotterData *)_pl_xmalloc (sizeof(plPlotterData));
113
114 /* copy parameters to it */
115 _plotter->data->infp = infile;
116 _plotter->data->outfp = outfile;
117 _plotter->data->errfp = errfile;
118 _pl_g_copy_params_to_plotter (_plotter, plotter_params);
119
120 /* do any additional needed initializiations of the Plotter (e.g.,
121 initialize data members of the PlotterData structure in a
122 device-dependent way); also add the Plotter to the _plotters[] array */
123 _plotter->initialize (_plotter);
124
125 return _plotter;
126 }
127
128 /* utility function, used above; keys into table of Plotter types by a
129 short mnemonic string */
130 static bool
_string_to_plotter_data(const char * type,int * position)131 _string_to_plotter_data (const char *type, int *position)
132 {
133 const Plotter_data *p = _plotter_data;
134 bool found = false;
135 int i = 0;
136
137 /* search table of known plotter type mnemonics */
138 while (p->name)
139 {
140 if (strcasecmp ((char *)type, (char *)p->name) == 0)
141 {
142 found = true;
143 break;
144 }
145 p++;
146 i++;
147 }
148 /* return pointer to plotter data through pointer */
149 if (found)
150 *position = i;
151 return found;
152 }
153
154 int
pl_deletepl_r(Plotter * _plotter)155 pl_deletepl_r (Plotter *_plotter)
156 {
157 if (_plotter == NULL)
158 {
159 _api_warning ("ignoring request to delete a null Plotter");
160 return -1;
161 }
162
163 /* if luser left the Plotter open, close it */
164 if (_plotter->data->open)
165 _API_closepl (_plotter);
166
167 /* Invoke an internal Plotter method before deletion. At a minimum, this
168 private `terminate' method, frees instance-specific copies of class
169 parameters, and also removes the pointer to the Plotter instance from
170 the _plotters[] array.
171
172 Also, it writes any unwritten graphics to the Plotter's output stream.
173 This is the case for PSPlotters in particular, which write graphics
174 only when they are deleted. For a PSPlotter, the terminate method
175 emits the Plotter's pages of graphics to its output stream and then
176 deallocates associated storage. For an XPlotter, this method kills
177 the forked-off processes that are maintaining its popped-up windows
178 (if any), provided that the VANISH_ON_DELETE parameter is set. */
179 _plotter->terminate (_plotter);
180
181 /* tear down the PlotterData structure */
182 free (_plotter->data);
183
184 /* tear down the Plotter itself */
185 free (_plotter);
186
187 return 0;
188 }
189
190
191 /* function used in this file to print warning messages */
192 static void
_api_warning(const char * msg)193 _api_warning (const char *msg)
194 {
195 if (pl_libplot_warning_handler != NULL)
196 (*pl_libplot_warning_handler)(msg);
197 else
198 fprintf (stderr, "libplot: %s\n", msg);
199 }
200
201
202 /* These are two user-callable functions that are specific to the new
203 (i.e., thread-safe) C binding: pl_newplparams, pl_deleteplparams,
204 pl_copyplparams. */
205
206 PlotterParams *
pl_newplparams(void)207 pl_newplparams (void)
208 {
209 int i;
210 PlotterParams *_plotter_params_p;
211
212 /* create PlotterParams, copy function pointers to it */
213 _plotter_params_p = (PlotterParams *)_pl_xmalloc (sizeof(PlotterParams));
214 memcpy (_plotter_params_p, &_default_plotter_params, sizeof(PlotterParams));
215
216 /* null out all parameters */
217 for (i = 0; i < NUM_PLOTTER_PARAMETERS; i++)
218 _plotter_params_p->plparams[i] = (void *)NULL;
219
220 return _plotter_params_p;
221 }
222
223 int
pl_deleteplparams(PlotterParams * _plotter_params_p)224 pl_deleteplparams (PlotterParams *_plotter_params_p)
225 {
226 int i;
227
228 /* free all copied strings, and the structure itself */
229 for (i = 0; i < NUM_PLOTTER_PARAMETERS; i++)
230 if (_known_params[i].is_string && _plotter_params_p->plparams[i] != NULL)
231 free (_plotter_params_p->plparams[i]);
232 free (_plotter_params_p);
233
234 return 0;
235 }
236
237 PlotterParams *
pl_copyplparams(const PlotterParams * _plotter_params_p)238 pl_copyplparams (const PlotterParams *_plotter_params_p)
239 {
240 int i;
241 PlotterParams *new_plotter_params_p;
242
243 /* create PlotterParams, copy function pointers to it */
244 new_plotter_params_p = (PlotterParams *)_pl_xmalloc (sizeof(PlotterParams));
245 memcpy (new_plotter_params_p, &_default_plotter_params, sizeof(PlotterParams));
246
247 /* copy all parameters */
248 for (i = 0; i < NUM_PLOTTER_PARAMETERS; i++)
249 new_plotter_params_p->plparams[i] = _plotter_params_p->plparams[i];
250
251 return new_plotter_params_p;
252 }
253
254 /* The following are C wrappers around the public functions in the
255 PlotterParams class. Together with the preceding functions, they are
256 part of the new (i.e., thread-safe) C API. */
257
258 int
pl_setplparam(PlotterParams * plotter_params,const char * parameter,void * value)259 pl_setplparam (PlotterParams *plotter_params, const char *parameter, void * value)
260 {
261 return plotter_params->setplparam (plotter_params, parameter, value);
262 }
263
264 /* END OF WRAPPERS AROUND PLOTTERPARAMS METHODS */
265