GNU Octave 7.1.0
A high-level interpreted language, primarily intended for numerical computations, mostly compatible with Matlab
__init_gnuplot__.cc
Go to the documentation of this file.
1////////////////////////////////////////////////////////////////////////
2//
3// Copyright (C) 2007-2022 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 "parse.h"
55#include "utils.h"
56#include "variables.h"
57
58// PKG_ADD: if (__have_gnuplot__ ()) register_graphics_toolkit ("gnuplot"); endif
59
60OCTAVE_NAMESPACE_BEGIN
61
63{
64public:
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 ~gnuplot_graphics_toolkit (void) = default;
90
91 bool is_valid (void) const { return true; }
92
93 bool initialize (const graphics_object& go)
94 {
95 return go.isa ("figure");
96 }
97
98 void finalize (const graphics_object& go)
99 {
100 if (go.isa ("figure"))
101 {
102 const figure::properties& props
103 = dynamic_cast<const figure::properties&> (go.get_properties ());
104
105 send_quit (props.get___plot_stream__ ());
106 }
107 }
108
109 void update (const graphics_object& go, int id)
110 {
111 if (go.isa ("figure"))
112 {
113 graphics_object obj (go);
114
115 figure::properties& props
116 = dynamic_cast<figure::properties&> (obj.get_properties ());
117
118 switch (id)
119 {
120 case base_properties::ID_VISIBLE:
121 if (! props.is_visible ())
122 {
123 send_quit (props.get___plot_stream__ ());
124 props.set___plot_stream__ (Matrix ());
125 props.set_graphicssmoothing (false);
126 }
127 break;
128 }
129 }
130 }
131
132 void redraw_figure (const graphics_object& go) const
133 {
134 static bool drawnow_executing = false;
135
136 // Prevent recursion
137 if (! drawnow_executing)
138 {
139 octave::unwind_protect_var<bool> restore_var (drawnow_executing, true);
140
142 args(0) = go.get_handle ().as_octave_value ();
143 octave::feval ("__gnuplot_drawnow__", args);
144 }
145 }
146
147 void print_figure (const graphics_object& go, const std::string& term,
148 const std::string& file,
149 const std::string& debug_file) const
150 {
152 if (! debug_file.empty ())
153 args(3) = debug_file;
154 args(2) = file;
155 args(1) = term;
156 args(0) = go.get_handle ().as_octave_value ();
157 octave::feval ("__gnuplot_drawnow__", args);
158 }
159
161 {
162 Matrix sz (1, 2, 0.0);
163 return sz;
164 }
165
166 double get_screen_resolution (void) const
167 { return 72.0; }
168
170 { return Matrix (1, 2, 0.0); }
171
172 void close (void)
173 {
174 if (m_interpreter.mislocked ("__init_gnuplot__"))
175 m_interpreter.munlock ("__init_gnuplot__");
176 }
177
178private:
179
180 void send_quit (const octave_value& pstream) const
181 {
182 if (! pstream.isempty ())
183 {
185 Matrix fids = pstream.matrix_value ();
186
187 octave::Ffputs (m_interpreter, ovl (fids(0), "\nquit;\n"));
188
189 octave::Ffflush (m_interpreter, ovl (fids(0)));
190 octave::Fpclose (m_interpreter, ovl (fids(0)));
191
192 if (fids.numel () > 1)
193 {
194 octave::Fpclose (m_interpreter, ovl (fids(1)));
195
196 if (fids.numel () > 2)
197 octave::Fwaitpid (ovl (fids(2)));
198 }
199 }
200 }
201
202 octave::interpreter& m_interpreter;
203};
204
205static bool
207{
208 const std::string exeext = octave::build_env::EXEEXT;
209 const std::string path = octave::sys::env::getenv ("PATH");
210 bool retval = false;
211
212 try
213 {
215 = octave::feval ("gnuplot_binary", octave_value_list ());
216
217 if (tmp(0).is_string () && ! tmp(0).isempty ())
218 {
219 std::string gnuplot_binary = tmp(0).string_value ();
220
221 string_vector args (gnuplot_binary);
222 std::string gnuplot_path = octave::search_path_for_file (path, args);
223
224 octave::sys::file_stat fs (gnuplot_path);
225
226 if (! fs.exists () && ! exeext.empty ())
227 {
228 args[0] += exeext;
229
230 gnuplot_path = octave::search_path_for_file (path, args);
231
232 fs = octave::sys::file_stat (gnuplot_path);
233 }
234
235 retval = fs.exists ();
236 }
237 }
238 catch (const octave::execution_exception&)
239 {
240 octave::interpreter& interp
241 = octave::__get_interpreter__ ("have_gnuplot_binary");
242
243 interp.recover_from_exception ();
244 }
245
246 return retval;
247}
248
249// Initialize the gnuplot graphics toolkit.
250
251DEFMETHOD_DLD (__init_gnuplot__, interp, , ,
252 doc: /* -*- texinfo -*-
253@deftypefn {} {} __init_gnuplot__ ()
254Undocumented internal function.
255@end deftypefn */)
256{
257 if (! have_gnuplot_binary ())
258 error ("__init_gnuplot__: the gnuplot program is not available, see 'gnuplot_binary'");
259 else if (! interp.mislocked ("__init_gnuplot__"))
260 {
261 gtk_manager& gtk_mgr = interp.get_gtk_manager ();
262
263 graphics_toolkit tk (new gnuplot_graphics_toolkit (interp));
264 gtk_mgr.load_toolkit (tk);
265
266 interp.mlock ();
267 }
268
269 return octave_value_list ();
270}
271
272DEFUN_DLD (__have_gnuplot__, , ,
273 doc: /* -*- texinfo -*-
274@deftypefn {} {@var{gnuplot_available} =} __have_gnuplot__ ()
275Undocumented internal function.
276@end deftypefn */)
277{
278 return ovl (have_gnuplot_binary ());
279}
280
281/*
282## No test needed for internal helper function.
283%!assert (1)
284*/
285
286OCTAVE_NAMESPACE_END
static bool have_gnuplot_binary(void)
octave_idx_type numel(void) const
Number of elements in the array.
Definition: Array.h:411
Definition: dMatrix.h:42
void redraw_figure(const graphics_object &go) const
Matrix get_screen_size(void) const
void print_figure(const graphics_object &go, const std::string &term, const std::string &file, const std::string &debug_file) const
octave::interpreter & m_interpreter
gnuplot_graphics_toolkit(octave::interpreter &interp)
double get_screen_resolution(void) const
Matrix get_canvas_size(const graphics_handle &) const
void finalize(const graphics_object &go)
void update(const graphics_object &go, int id)
bool initialize(const graphics_object &go)
~gnuplot_graphics_toolkit(void)=default
void send_quit(const octave_value &pstream) const
base_graphics_toolkit(const std::string &nm)
bool exists(void) const
Definition: file-stat.h:147
static std::string getenv(const std::string &name)
Definition: oct-env.cc:294
bool isempty(void) const
Definition: ov.h:646
Matrix matrix_value(bool frc_str_conv=false) const
Definition: ov.h:898
#define DEFUN_DLD(name, args_name, nargout_name, doc)
Macro to define an at run time dynamically loadable builtin function.
Definition: defun-dld.h:61
#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:1070
void error(const char *fmt,...)
Definition: error.cc:980
OCTAVE_EXPORT octave_value_list Fpclose(octave::interpreter &interp, const octave_value_list &args, int)
Definition: file-io.cc:2846
OCTAVE_EXPORT octave_value_list Ffflush(octave::interpreter &interp, const octave_value_list &args, int)
Definition: file-io.cc:235
OCTAVE_EXPORT octave_value_list Ffputs(octave::interpreter &interp, const octave_value_list &args, int)
Definition: file-io.cc:901
QString path
class OCTAVE_API Matrix
Definition: mx-fwd.h:31
T::properties & properties(graphics_object obj)
OCTINTERP_API const char * EXEEXT
OCTINTERP_API octave_value_list feval(const char *name, const octave_value_list &args=octave_value_list(), int nargout=0)
interpreter & __get_interpreter__(const std::string &who)
octave_value_list ovl(const OV_Args &... args)
Construct an octave_value_list with less typing.
Definition: ovl.h:211
OCTAVE_EXPORT octave_value_list Fwaitpid(const octave_value_list &args, int)
Definition: syscalls.cc:1228
std::string search_path_for_file(const std::string &path, const string_vector &names)
Definition: utils.cc:510