GNU Octave  6.2.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-2021 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 {
62 public:
64  : octave::base_graphics_toolkit ("gnuplot"), m_interpreter (interp) { }
65 
66  ~gnuplot_graphics_toolkit (void) = default;
67 
68  bool is_valid (void) const { return true; }
69 
70  bool initialize (const graphics_object& go)
71  {
72  return go.isa ("figure");
73  }
74 
75  void finalize (const graphics_object& go)
76  {
77  if (go.isa ("figure"))
78  {
79  const figure::properties& props
80  = dynamic_cast<const figure::properties&> (go.get_properties ());
81 
82  send_quit (props.get___plot_stream__ ());
83  }
84  }
85 
86  void update (const graphics_object& go, int id)
87  {
88  if (go.isa ("figure"))
89  {
90  graphics_object obj (go);
91 
92  figure::properties& props
93  = dynamic_cast<figure::properties&> (obj.get_properties ());
94 
95  switch (id)
96  {
97  case base_properties::ID_VISIBLE:
98  if (! props.is_visible ())
99  {
100  send_quit (props.get___plot_stream__ ());
101  props.set___plot_stream__ (Matrix ());
102  props.set_graphicssmoothing (false);
103  }
104  break;
105  }
106  }
107  }
108 
109  void redraw_figure (const graphics_object& go) const
110  {
111  static bool drawnow_executing = false;
112 
113  // Prevent recursion
114  if (! drawnow_executing)
115  {
117  frame.protect_var (drawnow_executing);
118 
119  drawnow_executing = true;
120  octave_value_list args;
121  args(0) = go.get_handle ().as_octave_value ();
122  octave::feval ("__gnuplot_drawnow__", args);
123  }
124  }
125 
126  void print_figure (const graphics_object& go, const std::string& term,
127  const std::string& file,
128  const std::string& debug_file) const
129  {
130  octave_value_list args;
131  if (! debug_file.empty ())
132  args(3) = debug_file;
133  args(2) = file;
134  args(1) = term;
135  args(0) = go.get_handle ().as_octave_value ();
136  octave::feval ("__gnuplot_drawnow__", args);
137  }
138 
140  {
141  Matrix sz (1, 2, 0.0);
142  return sz;
143  }
144 
145  double get_screen_resolution (void) const
146  { return 72.0; }
147 
148  Matrix get_screen_size (void) const
149  { return Matrix (1, 2, 0.0); }
150 
151  void close (void)
152  {
153  if (m_interpreter.mislocked ("__init_gnuplot__"))
154  m_interpreter.munlock ("__init_gnuplot__");
155  }
156 
157 private:
158 
159  void send_quit (const octave_value& pstream) const
160  {
161  if (! pstream.isempty ())
162  {
163  octave_value_list args;
164  Matrix fids = pstream.matrix_value ();
165 
166  Ffputs (m_interpreter, ovl (fids(0), "\nquit;\n"));
167 
168  Ffflush (m_interpreter, ovl (fids(0)));
169  Fpclose (m_interpreter, ovl (fids(0)));
170 
171  if (fids.numel () > 1)
172  {
173  Fpclose (m_interpreter, ovl (fids(1)));
174 
175  if (fids.numel () > 2)
176  Fwaitpid (ovl (fids(2)));
177  }
178  }
179  }
180 
182 };
183 
184 static bool
186 {
187  const std::string exeext = octave::build_env::EXEEXT;
188  const std::string path = octave::sys::env::getenv ("PATH");
189  bool retval = false;
190 
191  try
192  {
194  = octave::feval ("gnuplot_binary", octave_value_list ());
195 
196  if (tmp(0).is_string () && ! tmp(0).isempty ())
197  {
198  std::string gnuplot_binary = tmp(0).string_value ();
199 
200  string_vector args (gnuplot_binary);
201  std::string gnuplot_path = octave::search_path_for_file (path, args);
202 
203  octave::sys::file_stat fs (gnuplot_path);
204 
205  if (! fs.exists () && ! exeext.empty ())
206  {
207  args[0] += exeext;
208 
209  gnuplot_path = octave::search_path_for_file (path, args);
210 
211  fs = octave::sys::file_stat (gnuplot_path);
212  }
213 
214  retval = fs.exists ();
215  }
216  }
217  catch (octave::execution_exception&)
218  {
219  octave::interpreter& interp
220  = octave::__get_interpreter__ ("have_gnuplot_binary");
221 
222  interp.recover_from_exception ();
223  }
224 
225  return retval;
226 }
227 
228 // Initialize the gnuplot graphics toolkit.
229 
230 DEFMETHOD_DLD (__init_gnuplot__, interp, , ,
231  doc: /* -*- texinfo -*-
232 @deftypefn {} {} __init_gnuplot__ ()
233 Undocumented internal function.
234 @end deftypefn */)
235 {
236  if (! have_gnuplot_binary ())
237  error ("__init_gnuplot__: the gnuplot program is not available, see 'gnuplot_binary'");
238  else if (! interp.mislocked ("__init_gnuplot__"))
239  {
240  octave::gtk_manager& gtk_mgr = interp.get_gtk_manager ();
241 
243  gtk_mgr.load_toolkit (tk);
244 
245  interp.mlock ();
246  }
247 
248  return octave_value_list ();
249 }
250 
251 DEFUN_DLD (__have_gnuplot__, , ,
252  doc: /* -*- texinfo -*-
253 @deftypefn {} {@var{gnuplot_available} =} __have_gnuplot__ ()
254 Undocumented internal function.
255 @end deftypefn */)
256 {
257  return ovl (have_gnuplot_binary ());
258 }
259 
260 /*
261 ## No test needed for internal helper function.
262 %!assert (1)
263 */
static bool have_gnuplot_binary(void)
octave_idx_type numel(void) const
Number of elements in the array.
Definition: Array.h:377
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
bool isa(const std::string &go_name) const
Definition: graphics.in.h:2827
base_properties & get_properties(void)
Definition: graphics.in.h:2829
graphics_handle get_handle(void) const
Definition: graphics.in.h:2815
void load_toolkit(const graphics_toolkit &tk)
Definition: gtk-manager.h:57
bool mislocked(bool skip_first=false) const
void recover_from_exception(void)
void munlock(bool skip_first=false) const
bool exists(void) const
Definition: file-stat.h:147
static std::string getenv(const std::string &name)
Definition: oct-env.cc:271
octave_value as_octave_value(void) const
Definition: oct-handle.h:80
bool isempty(void) const
Definition: ov.h:557
Matrix matrix_value(bool frc_str_conv=false) const
Definition: ov.h:806
#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 error(const char *fmt,...)
Definition: error.cc:968
OCTAVE_EXPORT octave_value_list Fpclose(octave::interpreter &interp, const octave_value_list &args, int)
Definition: file-io.cc:2801
OCTAVE_EXPORT octave_value_list Ffflush(octave::interpreter &interp, const octave_value_list &args, int)
Definition: file-io.cc:233
OCTAVE_EXPORT octave_value_list Ffputs(octave::interpreter &interp, const octave_value_list &args, int)
Definition: file-io.cc:897
QString path
const char * EXEEXT
interpreter & __get_interpreter__(const std::string &who)
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:9580
std::string search_path_for_file(const std::string &path, const string_vector &names)
Definition: utils.cc:360
octave_value::octave_value(const Array< char > &chm, char type) return retval
Definition: ov.cc:811
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:1169