GNU Octave  8.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-2023 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 
28 To 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 
61 
63 {
64 public:
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\
76 The gnuplot graphics toolkit is not actively maintained and has a number\n\
77 of limitations that are unlikely to be fixed. Communication with gnuplot\n\
78 uses a one-directional pipe and limited information is passed back to the\n\
79 Octave interpreter so most changes made interactively in the plot window\n\
80 will not be reflected in the graphics properties managed by Octave. For\n\
81 example, if the plot window is closed with a mouse click, Octave will not\n\
82 be notified and will not update its internal list of open figure windows.\n\
83 The 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 
141  octave_value_list args;
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  {
151  octave_value_list args;
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 
169  Matrix get_screen_size (void) const
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 
178 private:
179 
180  void send_quit (const octave_value& pstream) const
181  {
182  if (! pstream.isempty ())
183  {
184  octave_value_list args;
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 
205 static 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 = octave::__get_interpreter__ ();
241 
242  interp.recover_from_exception ();
243  }
244 
245  return retval;
246 }
247 
248 // Initialize the gnuplot graphics toolkit.
249 
250 DEFMETHOD_DLD (__init_gnuplot__, interp, , ,
251  doc: /* -*- texinfo -*-
252 @deftypefn {} {} __init_gnuplot__ ()
253 Undocumented internal function.
254 @end deftypefn */)
255 {
256  if (! have_gnuplot_binary ())
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 
271 DEFUN_DLD (__have_gnuplot__, , ,
272  doc: /* -*- texinfo -*-
273 @deftypefn {} {@var{gnuplot_available} =} __have_gnuplot__ ()
274 Undocumented internal function.
275 @end deftypefn */)
276 {
277  return ovl (have_gnuplot_binary ());
278 }
279 
280 /*
281 ## No test needed for internal helper function.
282 %!assert (1)
283 */
284 
OCTAVE_END_NAMESPACE(octave)
static bool have_gnuplot_binary(void)
OCTINTERP_API const char * EXEEXT
OCTARRAY_OVERRIDABLE_FUNC_API octave_idx_type numel(void) const
Number of elements in the array.
Definition: Array.h:414
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
void load_toolkit(const graphics_toolkit &tk)
Definition: gtk-manager.h:57
bool isempty(void) const
Definition: ov.h:646
Matrix matrix_value(bool frc_str_conv=false) const
Definition: ov.h:898
OCTAVE_BEGIN_NAMESPACE(octave) static octave_value daspk_fcn
#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:1069
void error(const char *fmt,...)
Definition: error.cc:979
OCTAVE_EXPORT octave_value_list Fpclose(octave::interpreter &interp, const octave_value_list &args, int)
Definition: file-io.cc:2883
OCTAVE_EXPORT octave_value_list Ffflush(octave::interpreter &interp, const octave_value_list &args, int)
Definition: file-io.cc:232
OCTAVE_EXPORT octave_value_list Ffputs(octave::interpreter &interp, const octave_value_list &args, int)
Definition: file-io.cc:904
interpreter & __get_interpreter__(void)
class OCTAVE_API Matrix
Definition: mx-fwd.h:31
T::properties & properties(graphics_object obj)
octave_value_list feval(const char *name, const octave_value_list &args, int nargout)
Evaluate an Octave function (built-in or interpreted) and return the list of result values.
Definition: oct-parse.cc:10370
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:511