GNU Octave 10.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
 
Loading...
Searching...
No Matches
__init_gnuplot__.cc
Go to the documentation of this file.
1////////////////////////////////////////////////////////////////////////
2//
3// Copyright (C) 2007-2025 The Octave Project Developers
4//
5// See the file COPYRIGHT.md in the top-level directory of this
6// distribution or <https://octave.org/copyright/>.
7//
8// This file is part of Octave.
9//
10// Octave is free software: you can redistribute it and/or modify it
11// under the terms of the GNU General Public License as published by
12// the Free Software Foundation, either version 3 of the License, or
13// (at your option) any later version.
14//
15// Octave is distributed in the hope that it will be useful, but
16// WITHOUT ANY WARRANTY; without even the implied warranty of
17// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18// GNU General Public License for more details.
19//
20// You should have received a copy of the GNU General Public License
21// along with Octave; see the file COPYING. If not, see
22// <https://www.gnu.org/licenses/>.
23//
24////////////////////////////////////////////////////////////////////////
25
26/*
27
28To initialize:
29
30 graphics_toolkit ("gnuplot");
31 plot (randn (1e3, 1));
32
33*/
34
35#if defined (HAVE_CONFIG_H)
36# include "config.h"
37#endif
38
39#include <string>
40
41#include "dMatrix.h"
42#include "file-stat.h"
43#include "oct-env.h"
44
45#include "build-env.h"
46#include "builtin-defun-decls.h"
47#include "defun-dld.h"
48#include "error.h"
49#include "graphics.h"
50#include "interpreter-private.h"
51#include "interpreter.h"
52#include "ov.h"
53#include "ovl.h"
54#include "utils.h"
55#include "variables.h"
56
57// PKG_ADD: if (__have_gnuplot__ ()) register_graphics_toolkit ("gnuplot"); endif
58
60
61class gnuplot_graphics_toolkit : public octave::base_graphics_toolkit
62{
63public:
64
65 gnuplot_graphics_toolkit (octave::interpreter& interp)
66 : octave::base_graphics_toolkit ("gnuplot"), m_interpreter (interp)
67 {
68 static bool warned = false;
69
70 if (! warned)
71 {
73 ("Octave:gnuplot-graphics",
74 "using the gnuplot graphics toolkit is discouraged\n\
75\n\
76The gnuplot graphics toolkit is not actively maintained and has a number\n\
77of limitations that are unlikely to be fixed. Communication with gnuplot\n\
78uses a one-directional pipe and limited information is passed back to the\n\
79Octave interpreter so most changes made interactively in the plot window\n\
80will not be reflected in the graphics properties managed by Octave. For\n\
81example, if the plot window is closed with a mouse click, Octave will not\n\
82be notified and will not update its internal list of open figure windows.\n\
83The qt toolkit is recommended instead.\n");
84
85 warned = true;
86 }
87 }
88
89 OCTAVE_DISABLE_CONSTRUCT_COPY_MOVE (gnuplot_graphics_toolkit)
90
91 ~gnuplot_graphics_toolkit () = default;
92
93 bool is_valid () const { return true; }
94
95 bool initialize (const graphics_object& go)
96 {
97 return go.isa ("figure");
98 }
99
100 void finalize (const graphics_object& go)
101 {
102 if (go.isa ("figure"))
103 {
104 const figure::properties& props
105 = dynamic_cast<const figure::properties&> (go.get_properties ());
106
107 send_quit (props.get___plot_stream__ ());
108 }
109 }
110
111 void update (const graphics_object& go, int id)
112 {
113 if (go.isa ("figure"))
114 {
115 graphics_object obj (go);
116
117 figure::properties& props
118 = dynamic_cast<figure::properties&> (obj.get_properties ());
119
120 switch (id)
121 {
122 case base_properties::ID_VISIBLE:
123 if (! props.is_visible ())
124 {
125 send_quit (props.get___plot_stream__ ());
126 props.set___plot_stream__ (Matrix ());
127 props.set_graphicssmoothing (false);
128 }
129 break;
130 }
131 }
132 }
133
134 void redraw_figure (const graphics_object& go) const
135 {
136 static bool drawnow_executing = false;
137
138 // Prevent recursion
139 if (! drawnow_executing)
140 {
141 octave::unwind_protect_var<bool> restore_var (drawnow_executing, true);
142
144 args(0) = go.get_handle ().as_octave_value ();
145 m_interpreter.feval ("__gnuplot_drawnow__", args);
146 }
147 }
148
149 void print_figure (const graphics_object& go, const std::string& term,
150 const std::string& file,
151 const std::string& debug_file) const
152 {
154 if (! debug_file.empty ())
155 args(3) = debug_file;
156 args(2) = file;
157 args(1) = term;
158 args(0) = go.get_handle ().as_octave_value ();
159 m_interpreter.feval ("__gnuplot_drawnow__", args);
160 }
161
162 Matrix get_canvas_size (const graphics_handle&) const
163 {
164 Matrix sz (1, 2, 0.0);
165 return sz;
166 }
167
168 double get_screen_resolution () const
169 { return 72.0; }
170
171 Matrix get_screen_size () const
172 { return Matrix (1, 2, 0.0); }
173
174 void close ()
175 {
176 if (m_interpreter.mislocked ("__init_gnuplot__"))
177 m_interpreter.munlock ("__init_gnuplot__");
178 }
179
180private:
181
182 void send_quit (const octave_value& pstream) const
183 {
184 if (! pstream.isempty ())
185 {
187 Matrix fids = pstream.matrix_value ();
188
189 octave::Ffputs (m_interpreter, ovl (fids(0), "\nquit;\n"));
190
191 octave::Ffflush (m_interpreter, ovl (fids(0)));
192 octave::Fpclose (m_interpreter, ovl (fids(0)));
193
194 if (fids.numel () > 1)
195 {
196 octave::Fpclose (m_interpreter, ovl (fids(1)));
197
198 if (fids.numel () > 2)
199 octave::Fwaitpid (ovl (fids(2)));
200 }
201 }
202 }
203
204 octave::interpreter& m_interpreter;
205};
206
207static bool
208have_gnuplot_binary (interpreter& interp)
209{
210 const std::string exeext = octave::build_env::EXEEXT;
211 const std::string path = octave::sys::env::getenv ("PATH");
212 bool retval = false;
213
214 try
215 {
217 = interp.feval ("gnuplot_binary", octave_value_list ());
218
219 if (tmp(0).is_string () && ! tmp(0).isempty ())
220 {
221 std::string gnuplot_binary = tmp(0).string_value ();
222
223 string_vector args (gnuplot_binary);
224 std::string gnuplot_path = octave::search_path_for_file (path, args);
225
226 octave::sys::file_stat fs (gnuplot_path);
227
228 if (! fs.exists () && ! exeext.empty ())
229 {
230 args[0] += exeext;
231
232 gnuplot_path = octave::search_path_for_file (path, args);
233
234 fs = octave::sys::file_stat (gnuplot_path);
235 }
236
237 retval = fs.exists ();
238 }
239 }
240 catch (const octave::execution_exception&)
241 {
242 interp.recover_from_exception ();
243 }
244
245 return retval;
246}
247
248// Initialize the gnuplot graphics toolkit.
249
250DEFMETHOD_DLD (__init_gnuplot__, interp, , ,
251 doc: /* -*- texinfo -*-
252@deftypefn {} {} __init_gnuplot__ ()
253Undocumented internal function.
254@end deftypefn */)
255{
256 if (! have_gnuplot_binary (interp))
257 error ("__init_gnuplot__: the gnuplot program is not available, see 'gnuplot_binary'");
258 else if (! interp.mislocked ("__init_gnuplot__"))
259 {
260 gtk_manager& gtk_mgr = interp.get_gtk_manager ();
261
262 graphics_toolkit tk (new gnuplot_graphics_toolkit (interp));
263 gtk_mgr.load_toolkit (tk);
264
265 interp.mlock ();
266 }
267
268 return octave_value_list ();
269}
270
271DEFMETHOD_DLD (__have_gnuplot__, interp, , ,
272 doc: /* -*- texinfo -*-
273@deftypefn {} {@var{gnuplot_available} =} __have_gnuplot__ ()
274Undocumented internal function.
275@end deftypefn */)
276{
277 return ovl (have_gnuplot_binary (interp));
278}
279
280/*
281## No test needed for internal helper function.
282%!assert (1)
283*/
284
285OCTAVE_END_NAMESPACE(octave)
octave_idx_type numel() const
Number of elements in the array.
Definition Array.h:418
void load_toolkit(const graphics_toolkit &tk)
Definition gtk-manager.h:61
void mlock(bool skip_first=false) const
gtk_manager & get_gtk_manager()
bool mislocked(bool skip_first=false) const
octave_value_list feval(const char *name, const octave_value_list &args=octave_value_list(), int nargout=0)
Evaluate an Octave function (built-in or interpreted) and return the list of result values.
void recover_from_exception()
bool isempty() const
Definition ov.h:601
Matrix matrix_value(bool frc_str_conv=false) const
Definition ov.h:859
OCTAVE_BEGIN_NAMESPACE(octave) static octave_value daspk_fcn
#define DEFMETHOD_DLD(name, interp_name, args_name, nargout_name, doc)
Macro to define an at run time dynamically loadable builtin method.
Definition defun-dld.h:99
void warning_with_id(const char *id, const char *fmt,...)
Definition error.cc:1093
void error(const char *fmt,...)
Definition error.cc:1003
octave_value_list ovl(const OV_Args &... args)
Construct an octave_value_list with less typing.
Definition ovl.h:217