NEURON
ivoc.cpp
Go to the documentation of this file.
1 #include <../../nrnconf.h>
2 
3 #include <OS/list.h>
4 #include <ocnotify.h>
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <nrnmutdec.h>
8 #include "oc2iv.h"
9 #include "ocfunc.h"
10 
11 extern Object** (*nrnpy_gui_helper_)(const char* name, Object* obj);
12 extern double (*nrnpy_object_to_double_)(Object*);
13 
14 #if HAVE_IV
15 #include "utility.h"
16 #include "ivoc.h"
17 #endif
18 
19 #include "bimap.hpp"
20 
21 #if USE_PTHREAD
22 static MUTDEC
23 #endif
24 
25 typedef void (*PF)(void*, int);
26 declareList(FList, PF);
27 implementList(FList, PF);
28 
29 static FList* f_list;
30 
33 
34 // fast insert, find, and remove of (double*, Observer*) using either as
35 // a key. Use pair of multimap since there can be many observers of the
36 // same double. And perhaps one Observer is watching several double*. Also
37 // the double* being watched is removed when the array (pd*, size) it is
38 // a part of is freed. So the upper_bound property is needed
39 
41 
42 
43 void* (*nrnpy_save_thread)();
45 
46 void nrn_notify_freed(PF pf) {
47  if (!f_list) {
48  f_list = new FList;
49  }
50  f_list->append(pf);
51 // printf("appended to f_list in ivoc.cpp\n");
52 }
53 
55  MUTLOCK
56  if (!pvob) {
58  }
59  pvob->insert(p, ob);
60  MUTUNLOCK
61 }
62 
64  MUTLOCK
65  if (!pdob) {
67  }
68  pdob->insert(p, ob);
69  MUTUNLOCK
70 }
71 
73  MUTLOCK
74  if (pvob) {
75  pvob->obremove(ob);
76  }
77  if (pdob) {
78  pdob->obremove(ob);
79  }
80  MUTUNLOCK
81 }
82 
83 void notify_pointer_freed(void* pt) {
84  if (pvob) {
85  MUTLOCK
86  void* pv;
87  Observer* ob;
88  while(pvob->find(pt, pv, ob)) {
89  ob->update(NULL);
90  pvob->remove(pv, ob);
91  }
92  MUTUNLOCK
93  }
94 }
95 void notify_freed(void* p) {
96  if (f_list) {
97  long i, n=f_list->count();
98  for (i=0; i < n; ++i) {
99  (*f_list->item(i))(p, 1);
100  }
101  }
103 }
104 void notify_freed_val_array(double* p, size_t size) {
105  if (f_list) {
106  long i, n=f_list->count();
107  for (i=0; i < n; ++i) {
108  (*f_list->item(i))((void*)p, size);
109  }
110  }
111  if (pdob) {
112  double* pp;
113  Observer* ob;
114  while(pdob->find(p, size, pp, ob)) {
115 //printf("notify_freed_val_array %d %ld\n", size, j);
116  ob->update(NULL);
117  pdob->remove(pp, ob);
118  }
119  }
120 }
121 
122 char* cxx_char_alloc(size_t sz) {
123  char* cp = new char[sz];
124  return cp;
125 }
126 
127 
128 #ifndef MINGW // actual implementation in ivocwin.cpp
129 void nrniv_bind_thread(void);
131  hoc_pushx(1.);
132  hoc_ret();
133 }
134 #endif
135 
136 void nrn_err_dialog(const char* mes) {
137 #if HAVE_IV
138 IFGUI
139  if (nrn_err_dialog_active_ && !Session::instance()->done()) {
140  char m[1024];
141  sprintf(m, "%s (See terminal window)", mes);
142  continue_dialog(m);
143  }
144 ENDGUI
145 #endif
146 }
147 
148 #if HAVE_IV // to end of file
149 
150 #if defined(MINGW)
151 #undef CYGWIN
152 #endif
153 
154 #include <InterViews/event.h>
155 #include <InterViews/reqerr.h>
156 #include <InterViews/style.h>
157 #include <IV-look/kit.h>
158 
159 #include "xmenu.h"
160 
161 /*
162  * Interface between oc and interviews.
163  *
164  * The normal command driven oc can be simultaneously event driven if
165  * instead of blocking on a terminal read, run_til_stdin() is called.
166  * This runs the interviews event loop until something is typed in the
167  * window from which oc was run.
168  */
169 
170  extern void hoc_main1_init(const char* pname, const char** env);
171  extern int hoc_oc(const char*);
172  extern int hoc_interviews;
173  extern Symbol* hoc_parse_expr(const char*, Symlist**);
174  extern double hoc_run_expr(Symbol*);
175  extern int hoc_execerror_messages;
176  extern void hoc_ret();
177  extern void hoc_pushx(double);
178  extern FILE* hoc_fin;
179  extern void ivoc_cleanup();
180  extern "C" void nrn_shape_update();
181  extern int bbs_poll_;
182  extern void bbs_handle();
183 
184  int run_til_stdin();
185  void single_event_run();
186  void hoc_notify_iv();
187 
188  extern int hoc_print_first_instance;
189  void ivoc_style();
190 
191 // because NEURON can no longer maintain its own copy of dialogs.cpp
192 // we communicate with the InterViews version through a callback.
193 extern bool (*IVDialog_setAcceptInput)(bool);
194 bool setAcceptInputCallback(bool);
195 bool setAcceptInputCallback(bool b) {
196  Oc oc;
197  return oc.setAcceptInput(b);
198 }
199 
200 void ivoc_style() {
201  TRY_GUI_REDIRECT_DOUBLE("ivoc_style", NULL);
202  IFGUI
203  if (Session::instance()) {
204  Style* s = Session::instance()->style();
205  s->remove_attribute(gargstr(1));
206  s->attribute(gargstr(1), gargstr(2), -5);
207  }
208 #if 0
209 String s;
210 if (WidgetKit::instance()->style()->find_attribute(gargstr(1)+1, s)) {
211  printf("ivoc_style %s: %s\n", gargstr(1), s.string());
212 }else{
213  printf("couldn't find %s\n", gargstr(1));
214 }
215 #endif
216 ENDGUI
217  hoc_ret();
218  hoc_pushx(1.);
219 }
220 
221 #if !defined(WIN32) && !defined(MAC) && !defined(CYGWIN) && !defined(carbon)
222 /*static*/ class ReqErr1 : public ReqErr {
223 public:
224  ReqErr1();
225  virtual void Error();
226  virtual int count() { return count_;}
227 private:
228  int count_;
229  int r_;
230 };
231 
232 ReqErr1::ReqErr1() {
233  count_ = 0;
234  r_ = 0;
235 }
236 
237 void ReqErr1::Error() {
238  if (!count_ || code != r_) {
239  if (!r_) {
240  r_ = code;
241  }
242  fprintf(stderr, "X Error of failed request: %s\n", message);
243  if (r_ == code) {
244 fprintf(stderr, "Further messages for error code %d will not be shown\n", r_);
245  }
246  }
247  ++count_;
248 }
249 
250 static ReqErr1* reqerr1;
251 #endif
252 
253 #if MAC
254 static HandleStdin* hsd_;
255 #endif
256 
257 #if defined(WIN32) && !defined(CYGWIN)
258 static HandleStdin* hsd_;
259 void winio_key_press() {
260  hsd_->inputReady(1);
261 }
262 
263 #endif
264 
265 Oc::Oc() {
266  MUTLOCK
267  ++refcnt_;
268  MUTUNLOCK
269 }
270 
271 bool Oc::helpmode_;
272 
273 Oc::Oc(Session *s, const char* pname, const char** env) {
274  if (session_) return;
275  refcnt_++;
276  session_ = s;
277  IVDialog_setAcceptInput = setAcceptInputCallback;
278  notify_change_ = new Observable();
279  if (s) {
280  helpmode_ = false;
281 #if (defined(WIN32) && !defined(CYGWIN)) || defined(MAC)
282  hsd_ = handleStdin_ = new HandleStdin;
283 #else
284 #if !defined(CYGWIN) && !defined(carbon)
285  reqerr1 = new ReqErr1;
286  reqerr1->Install();
287 #endif
288  handleStdin_ = new HandleStdin;
289  Dispatcher::instance().link(0, Dispatcher::ReadMask, handleStdin_);
290  Dispatcher::instance().link(0, Dispatcher::ExceptMask, handleStdin_);
291 #endif
292  hoc_interviews = 1;
293 #if MAC
295 #endif
296  String str;
297  if (session_->style()->find_attribute("first_instance_message", str)) {
298  if (str == "on") {
300  }else{
302  }
303  }
304  }
305  MUTCONSTRUCT(1)
306  hoc_main1_init(pname, env);
307 }
308 
309 Oc::~Oc() {
310  MUTLOCK
311  if (--refcnt_ == 0) {
312 #if !defined(WIN32) && !defined(MAC) && !defined(CYGWIN) && !defined(carbon)
313  if (reqerr1 && reqerr1->count()) {
314  fprintf(stderr, "total X Errors: %d\n", reqerr1->count());
315  }
316 #endif
317  }
318  MUTUNLOCK
319 }
320 
321 
322 Session* Oc::getSession() { return session_;}
323 
324 int Oc::run(int argc, const char** argv) {
325  return hoc_main1(argc, argv, 0);
326 }
327 
328 int Oc::run(const char* buf, bool show_err_mes) {
329  hoc_execerror_messages = show_err_mes;
330  return hoc_oc(buf);
331 }
332 
333 Symbol* Oc::parseExpr(const char* expr, Symlist** ps) {
334  return hoc_parse_expr(expr, ps);
335 }
336 
337 double Oc::runExpr(Symbol* sym) {
338  return hoc_run_expr(sym);
339 }
340 
341 const char* Oc::name(Symbol* sym) {
342  return sym->name;
343 }
344 
345 bool Oc::setAcceptInput(bool b) {
346  bool old = handleStdin_->acceptInput_;
347  handleStdin_->acceptInput_ = b;
348  return old;
349 }
350 
351 void Oc::notify_freed(PF pf) {
352  nrn_notify_freed(pf);
353 }
354 
355 void Oc::notify_when_freed(void* p, Observer* ob) {
357 }
358 
359 void Oc::notify_when_freed(double* p, Observer* ob) {
361 }
362 
365 }
366 
368  stdinSeen_ = false;
369  acceptInput_ = true;
370 }
371 
372 int HandleStdin::inputReady(int fd) {
373  stdinSeen_ = 1;
374  if(fd){;}
375  if (acceptInput_) {
376  Oc::getSession()->quit();
377  }
378  return 0;
379 }
380 
381 int HandleStdin::exceptionRaised(int fd) {
382  hoc_interviews = 0;
383  if(fd){;}
384  stdinSeen_ = 1;
385  Oc::getSession()->quit();
386  return 0;
387 }
388 
389 void ivoc_cleanup() {
390 }
391 
392 int run_til_stdin() {
393  Session* session = Oc::getSession();
394 #if defined(WIN32) || MAC
395  Oc oc;
396  oc.notify();
397 #endif
398 #if !defined(WIN32) || defined(CYGWIN)
399  Oc::setStdinSeen(false);
400 #endif
401  session->run();
402  WinDismiss::dismiss_defer(); // in case window was dismissed
403 #if MAC && !defined(carbon)
404  extern Boolean IVOCGoodLine;
405  if(IVOCGoodLine){
406  return 1;
407  } else {
408  return 0;
409  }
410 #endif
411 #if defined(WIN32) && !defined(CYGWIN)
412  return 0;
413 #else
414  return Oc::getStdinSeen(); //MAC should not reach this point
415 #endif
416 }
417 
418 void single_event_run() {
419  Resource::flush();
420  Session* session = Oc::getSession();
421  Event e;
422  // actually run till no more events
423  Oc::setAcceptInput(false);
424 #if MAC
425  extern bool read_if_pending(Event&);
426  while ( !session->done() && read_if_pending(e)) {
427  e.handle();
428  }
429 #else
430  bool dsav = session->done();
431  session->unquit();
432  while (session->pending() && !session->done()) {
433  session->read(e);
434  e.handle();
435  }
436  if (dsav) {
437  session->quit();
438  }
439 #endif
440  Oc::setAcceptInput(true);;
441  HocPanel::keep_updated();
442 #if MAC
443  Session::instance()->screen_update();
444 #endif
445  WinDismiss::dismiss_defer(); // in case window was dismissed
446 }
447 
448 #ifdef MINGW
449 extern void nrniv_bind_call(void);
450 #endif
451 
452 void hoc_notify_iv() {
453  IFGUI
454 #ifdef MINGW
455  if (!nrn_is_gui_thread()) {
456  // allow gui thread to run
457  nrnpy_pass();
458  hoc_pushx(0.); hoc_ret(); return;
459  }
460  nrniv_bind_call();
461 #endif
462  Resource::flush();
463  Oc oc;
464  oc.notify();
466 ENDGUI
467  hoc_pushx(1.);
468  hoc_ret();
469 }
470 
472 
473 void Oc::notify() { // merely a possible change
475  notifyHocValue();
476  notify_change_->notify();
477  if (bbs_poll_ > 0) bbs_handle();
478  WinDismiss::dismiss_defer(); // in case window was dismissed
479 }
481  notify_change_->attach(o);
482 }
483 void Oc::notify_detach(Observer* o) {
484  notify_change_->detach(o);
485 }
486 #endif
o
Definition: seclist.cpp:180
int bbs_poll_
Definition: datapath.cpp:27
Definition: hocdec.h:84
int run_til_stdin()
Definition: ivocmain.cpp:890
static void dismiss_defer()
virtual int inputReady(int fd)
virtual int exceptionRaised(int fd)
int hoc_interviews
Definition: hoc.cpp:1665
bool find(T const &p, size_t n, T &, O &)
Definition: bimap.hpp:67
Definition: ivoc.h:36
virtual ~Oc()
#define MUTLOCK
Definition: nrnmutdec.h:32
void
size_t p
void notify_freed_val_array(double *p, size_t size)
Definition: ivoc.cpp:104
double runExpr(Symbol *)
void nrn_notify_when_void_freed(void *p, Observer *ob)
Definition: ivoc.cpp:54
char * name
Definition: model.h:72
#define MUTUNLOCK
Definition: nrnmutdec.h:33
static Session * getSession()
static nrn::tool::bimap< void *, Observer * > * pvob
Definition: ivoc.cpp:31
void notify()
sprintf(buf," if (secondorder) {\ " int _i;\" " for(_i=0;_i< %d;++_i) {\" " _p[_slist%d[_i]]+=dt *_p[_dlist%d[_i]];\" " }}\", numeqn, listnum, listnum)
void notify_freed(void(*pf)(void *, int))
#define e
Definition: passive0.cpp:24
#define gargstr
Definition: hocdec.h:14
const char * string() const
Definition: string.h:139
int nrn_err_dialog_active_
Definition: ivoc.cpp:40
Symbol * parseExpr(const char *, Symlist **=NULL)
void hoc_ret()
Symbol * hoc_parse_expr(const char *str, Symlist **psymlist)
Definition: code2.cpp:630
static double done(void *v)
Definition: ocbbs.cpp:280
const char * name(Symbol *)
void ivoc_style()
Definition: ocnoiv1.cpp:169
void obremove(O const &)
Definition: bimap.hpp:51
static bool helpmode_
Definition: ivoc.h:77
int const size_t const size_t n
Definition: nrngsl.h:12
int hoc_execerror_messages
Definition: hoc.cpp:666
#define TRY_GUI_REDIRECT_DOUBLE(name, obj)
Definition: gui-redirect.h:54
int hoc_print_first_instance
Definition: hoc_oop.cpp:50
void(* nrnpy_restore_thread)(void *)
Definition: ivoc.cpp:44
void notify_pointer_disconnect(Observer *)
_CONST char * s
Definition: system.cpp:74
void nrniv_bind_thread(void)
Definition: ivoc.cpp:130
static nrn::tool::bimap< double *, Observer * > * pdob
Definition: ivoc.cpp:32
void notify_detach(Observer *)
#define MUTDEC
Definition: nrnmutdec.h:28
void notify_freed(void *p)
Definition: ivoc.cpp:95
void insert(T const &, O const &)
Definition: bimap.hpp:45
#define printf
Definition: mwprefix.h:26
void nrn_shape_update()
Definition: treeset.cpp:932
static int getStdinSeen()
Definition: ivoc.h:63
static Observable * notify_change_
Definition: ivoc.h:80
int
Definition: nrnmusic.cpp:71
void single_event_run()
int hoc_oc(const char *buf)
Definition: hoc.cpp:1491
double hoc_run_expr(Symbol *sym)
Definition: code2.cpp:622
#define ENDGUI
Definition: hocdec.h:352
FILE * hoc_fin
fprintf(stderr, "Don't know the location of params at %p\, pp)
Definition: model.h:57
static char * env[]
Definition: inithoc.cpp:228
void(* PF)(void *, int)
Definition: ivoc.cpp:25
char * name
Definition: init.cpp:16
void hoc_notify_iv()
Definition: ocnoiv1.cpp:20
void notify_pointer_freed(void *pt)
Definition: ivoc.cpp:83
void notify_attach(Observer *)
#define Event
Definition: _defines.h:107
void nrn_notify_freed(PF pf)
Definition: ivoc.cpp:46
void hoc_pushx(double)
#define MUTCONSTRUCT(mkmut)
Definition: nrnmutdec.h:30
char * cxx_char_alloc(size_t sz)
Definition: ivoc.cpp:122
void nrn_notify_when_double_freed(double *p, Observer *ob)
Definition: ivoc.cpp:63
void notify_when_freed(void *p, Observer *)
void ivoc_cleanup()
Definition: ocnoiv1.cpp:17
double(* nrnpy_object_to_double_)(Object *)
Definition: xmenu.cpp:14
void continue_dialog(const char *label, Window *w=NULL, Coord x=400., Coord y=400.)
Definition: hocdec.h:226
#define i
Definition: md1redef.h:12
static bool setAcceptInput(bool)
Definition: string.h:34
void nrnpy_pass()
Definition: fileio.cpp:882
static void setStdinSeen(bool i)
Definition: ivoc.h:64
void remove(T const &, O const &)
Definition: bimap.hpp:61
void nrn_notify_pointer_disconnect(Observer *ob)
Definition: ivoc.cpp:72
char buf[512]
Definition: init.cpp:13
#define Style
Definition: _defines.h:281
#define ReqErr
Definition: _defines.h:223
static FList * f_list
Definition: ivoc.cpp:29
int hoc_main1(int, const char **, const char **)
Definition: hoc.cpp:972
declareList(FList, PF)
#define Observable
Definition: _defines.h:190
Oc()
void nrn_err_dialog(const char *mes)
Definition: ivoc.cpp:136
void hoc_main1_init(const char *, const char **)
Definition: hoc.cpp:875
static const char ** pname(void *v)
Definition: ocpointer.cpp:69
static int argc
Definition: inithoc.cpp:53
void bbs_handle()
Definition: datapath.cpp:29
static Symbol * pv[4]
Definition: partial.cpp:80
#define IFGUI
Definition: hocdec.h:351
int run(int argc, const char **argv)
implementList(FList, PF)
#define Session
Definition: ivocmain.cpp:7
static void flush()
Definition: resource.cpp:110
return NULL
Definition: cabcode.cpp:461
static char ** argv
Definition: inithoc.cpp:54
virtual void update(Observable *)
Definition: observe.cpp:86