// Start plot static void popup_plot_shell(PlotWindowInfo *plot) { if (!plot->active && plot->plotter != 0) { // We have the plot plot->plotter->removeHandler(Died, PlotterNotFoundHP, (void *)plot); // Fetch plot settings configure_plot(plot); // Command and export dialogs are not needed (yet) if (plot->command_dialog != 0) XtUnmanageChild(plot->command_dialog); if (plot->export_dialog != 0) XtUnmanageChild(plot->export_dialog); // Pop down working dialog if (plot->working_dialog != 0) XtUnmanageChild(plot->working_dialog); // Pop up shell XtSetSensitive(plot->shell, True); XtPopup(plot->shell, XtGrabNone); wait_until_mapped(plot->shell); plot->active = true; } }
void raise_shell(Widget w) { if (w == 0 || !XtIsRealized(w)) return; // Place current shell on top Widget shell = findShellParent(w); if (shell != 0 && XtIsRealized(shell)) { XRaiseWindow(XtDisplay(w), XtWindow(shell)); #if 0 wait_until_mapped(w); // Get focus XSetInputFocus(XtDisplay(w), XtWindow(w), RevertToParent, XtLastTimestampProcessed(XtDisplay(w))); #endif // Try this one XmProcessTraversal(w, XmTRAVERSE_CURRENT); } }
// Create a separate tty window; return its name in TTYNAME, its // process id in PID, its terminal type in TERM, and its window id in // WINDOWID. static void launch_separate_tty(string& ttyname, pid_t& pid, string& term, Window& windowid, Widget origin) { // If we're already running, all is done. if (pid > 0 && (remote_gdb() || kill(pid, 0) == 0)) return; string term_command = app_data.term_command; term_command.gsub("@FONT@", make_font(app_data, FixedWidthDDDFont)); static bool canceled; canceled = false; static Widget dialog = 0; if (dialog == 0) { Arg args[10]; Cardinal arg = 0; XtSetArg(args[arg], XmNdialogStyle, XmDIALOG_FULL_APPLICATION_MODAL); arg++; dialog = verify(XmCreateWorkingDialog(find_shell(origin), XMST("launch_tty_dialog"), args, arg)); XtUnmanageChild(XmMessageBoxGetChild(dialog, XmDIALOG_OK_BUTTON)); XtUnmanageChild(XmMessageBoxGetChild(dialog, XmDIALOG_HELP_BUTTON)); XtAddCallback(dialog, XmNcancelCallback, CancelTTYCB, XtPointer(&canceled)); } string base = term_command; if (base.contains(' ')) base = base.before(' '); MString msg = rm("Starting ") + tt(base) + rm("..."); XtVaSetValues(dialog, XmNmessageString, msg.xmstring(), XtPointer(0)); manage_and_raise(dialog); wait_until_mapped(dialog); StatusDelay delay("Starting execution window"); // Fill in defaults ttyname = ""; pid = -1; string command = // Set up a temporary file in TMP. "tmp=${TMPDIR-/tmp}/ddd$$; export tmp; " // Be sure to remove it when exiting... "trap \"rm -f $tmp\" 0; " // ... or being interrupted. "trap 'exit 1' 1 2 15; " // Now execute the xterm command + term_command + // which saves TTY, PID, TERM, and WINDOWID in TMP and goes to // sleep forever. Signal 2 (SIGINT) is blocked for two // reasons: first, we don't want ^C to kill the tty window; // second, later invocations will send us SIGINT to find out // whether we're still alive. " '" "echo `tty` $$ $TERM $WINDOWID >$tmp; " "trap \"\" 2; " "while true; do sleep 3600; done" "' " // The whole thing is redirected and in the background such // that rsh won't wait for us. ">/dev/null </dev/null 2>&1 & " // The main file waits for TMP to be created... "while test ! -s $tmp; do sleep 1; done; " // ...and sends TMP's contents to stdout, where DDD is waiting. "cat $tmp"; if (pid > 0 && remote_gdb()) { // We're already running. Don't start a new tty // if the old one is still running. std::ostringstream os; os << "kill -2 " << pid << " 2>/dev/null" << " || ( " << command << " )"; command = string(os); } command = sh_command(command); { XtAppContext app_context = XtWidgetToApplicationContext(dialog); LiterateAgent tty(app_context, command); string reply = ""; tty.addHandler(Input, GotReplyHP, (void *)&reply); tty.start(); while (!reply.contains('\n') && !canceled && tty.running()) XtAppProcessEvent(app_context, XtIMAll); if (reply.length() > 2) { std::istringstream is(reply.chars()); is >> ttyname >> pid >> term >> windowid; } tty.terminate(); }
// Create a new plot window PlotAgent *new_plotter(const string& name, DispValue *source) { static int tics = 1; string cmd = app_data.plot_command; cmd.gsub("@FONT@", make_font(app_data, FixedWidthDDDFont)); string window_name = ddd_NAME "plot" + itostring(tics++); if (cmd.contains("@NAME@")) cmd.gsub("@NAME@", window_name); else cmd += " -name " + window_name; // Create shell PlotWindowInfo *plot = new_decoration(name); if (plot == 0) return 0; plot->source = source; plot->window_name = window_name; XtVaSetValues(plot->shell, XmNuserData, XtPointer(True), XtPointer(0)); // Pop up a working dialog static Widget dialog = 0; if (dialog == 0) { Arg args[10]; Cardinal arg = 0; dialog = verify(XmCreateWorkingDialog(find_shell(), XMST("launch_plot_dialog"), args, arg)); XtUnmanageChild(XmMessageBoxGetChild(dialog, XmDIALOG_OK_BUTTON)); XtUnmanageChild(XmMessageBoxGetChild(dialog, XmDIALOG_HELP_BUTTON)); } XtRemoveAllCallbacks(dialog, XmNcancelCallback); XtAddCallback(dialog, XmNcancelCallback, CancelPlotCB, XtPointer(plot)); plot->working_dialog = dialog; string base = cmd; if (base.contains(' ')) base = cmd.before(' '); MString msg = rm("Starting ") + tt(base) + rm("..."); XtVaSetValues(dialog, XmNmessageString, msg.xmstring(), XtPointer(0)); manage_and_raise(dialog); wait_until_mapped(dialog); // Invoke plot process PlotAgent *plotter = new PlotAgent(XtWidgetToApplicationContext(plot->shell), cmd); XtAddCallback(plot->shell, XtNpopdownCallback, CancelPlotCB, XtPointer(plot)); if (plot->area != 0) { XtAddCallback(plot->area->widget(), XmNexposeCallback, ExposePlotAreaCB, XtPointer(plot)); XtAddCallback(plot->area->widget(), XmNresizeCallback, ResizePlotAreaCB, XtPointer(plot)); } string init = app_data.plot_init_commands; init.prepend("set term " + string(app_data.plot_term_type) + "\n"); if (!init.empty() && !init.contains('\n', -1)) init += '\n'; // Add trace handlers plotter->addHandler(Input, TraceInputHP); // Gnuplot => DDD plotter->addHandler(Output, TraceOutputHP); // DDD => Gnuplot plotter->addHandler(Error, TraceErrorHP); // Gnuplot Errors => DDD // Show Gnuplot Errors in status line plotter->addHandler(Error, SetStatusHP, (void *)plot); // Handle death plotter->addHandler(Died, PlotterNotFoundHP, (void *)plot); plotter->addHandler(Died, DeletePlotterHP, (void *)plot); if (plot->area != 0) plotter->addHandler(Plot, GetPlotHP, (void *)plot); plotter->start_with(init); plot->plotter = plotter; return plotter; }