ok, below is the code. That's about as small as I can make it from what I know. Again, I'm a beginner.
I want it to work like this:
Selecting something from the menu will construct a command for popen. I haven't implemented that in this code because I don't know how to yet.
Once the command is made in the callback, it is stored in a string. when I want to actually run that command, I'll select "run command" from the menu. All of the popen stuff happens in the area labled "Console Output" in the main window. I'd like it all to be within one window.
Here are a few problems I've been having with this kind of setup:
1) I can't do the "Fl::add_fd(fileno(G_fp), HandleFD, (void*)&brow);" command from anywhere except where the browser is initialized.
2) I can't run the window form a callback because I can't have "return Fl::run();" in there of course
3)I can't open a browser inside the text editor window (section in the code on line 111)
4)I can't change the command sent to popen.
5) the popen command must be there before the "Fl::add_fd(fileno(G_fp), HandleFD, (void*)&brow);" command of course.
The code below shows the only way I've gotten it to successfully run so far. Believe me, today is not the only time I've worked on this.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#ifdef __MWERKS__
# define FL_DLL
#endif
#include <FL/Fl.H>
#include <FL/Fl_Group.H>
#include <FL/Fl_Double_Window.H>
#include <FL/Fl_File_Chooser.H>
#include <FL/Fl_Menu_Bar.H>
#include <FL/Fl_Text_Buffer.H>
#include <FL/Fl_Text_Editor.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_Multi_Browser.H>
int changed = 0;
char filename[256] = "";
char title[256];
Fl_Text_Buffer *textbuf = 0;
#ifdef _WIN32
#include <windows.h>
#define popen _popen
#define pclose _pclose
#else
#include <unistd.h>
#endif
FILE *G_fp = NULL;
void HandleFD(int fd, void *data);
void
style_unfinished_cb(int, void*) {
}
class EditorWindow : public Fl_Double_Window {
public:
EditorWindow(int w, int h, const char* t);
~EditorWindow();
Fl_Text_Editor *editor;
char search[256];
};
EditorWindow::EditorWindow(int w, int h, const char* t) : Fl_Double_Window(w, h, t) {
}
EditorWindow::~EditorWindow() {
}
int loading = 0;
void load_file(char *newfile, int ipos) {
loading = 1;
int insert = (ipos != -1);
changed = insert;
if (!insert) strcpy(filename, "");
int r;
if (!insert) r = textbuf->loadfile(newfile);
else r = textbuf->insertfile(newfile, ipos);
if (r)
fl_alert("Error reading from file \'%s\':\n%s.", newfile, strerror(errno));
else
if (!insert) strcpy(filename, newfile);
loading = 0;
textbuf->call_modify_callbacks();
}
int num_windows = 0;
void do_cb()
{
//This callback constructs a string that is to be sent to popen
}
void do_cb2()
{
//This callback constructs another string that is to be sent to popen
}
void run_cb()
{
/*This is where I'd like to run the command from the above callbacks using popen,
but the "Fl::add_fd(fileno(G_fp), HandleFD, (void*)&brow);" won't run here.*/
}
Fl_Window* new_view();
void view_cb(Fl_Widget*, void*) {
Fl_Window* w = new_view();
w->show();
}
Fl_Menu_Item menuitems[] = {
{ "&do", 0, 0, 0, FL_SUBMENU },
{ "do", FL_CTRL + 's', (Fl_Callback *)do_cb },
{ "do2", FL_CTRL + 'a', (Fl_Callback *)do_cb2 },
{ "Run command", FL_CTRL + 'r', (Fl_Callback *)run_cb },
{ 0 },
{ 0 }
};
Fl_Window* new_view() {
EditorWindow* w = new EditorWindow(660, 600, title);
w->begin();
Fl_Menu_Bar* m = new Fl_Menu_Bar(0, 0, 660, 30);
m->copy(menuitems, w);
w->editor = new Fl_Text_Editor(0, 400, 655, 197,"Console Output"); /*<-- I'd like the popen stuff to run in this area,
tho popen stuff should only be run after
the command is made in one of the callbacks
such as "do_cb" and "do_cb2"*/
w->editor = new Fl_Text_Editor(0, 30, 655, 350);
w->editor->buffer(textbuf);
w->editor->textfont(FL_COURIER);
w->end();
w->resizable(w->editor);
textbuf->call_modify_callbacks();
num_windows++;
return w;
}
void HandleFD(int fd, void *data) {
Fl_Multi_Browser *brow = (Fl_Multi_Browser*)data;
char s[1024];
if ( fgets(s, 1023, G_fp) == NULL ) {
Fl::remove_fd(fileno(G_fp));
pclose(G_fp);
return;
}
brow->add(s);
}
int main(int argc, char **argv) {
textbuf = new Fl_Text_Buffer;
Fl_Window* window = new_view();
window->show(1, argv);
if (argc > 1) load_file(argv[1], -1);
// this is the Popen window stuff:
Fl_Window win(600,600);
Fl_Multi_Browser brow(10,10,580,580);
G_fp = popen("netstat -an 2>&1","r");
Fl::add_fd(fileno(G_fp), HandleFD, (void*)&brow); /*<- This is the root to one of my main problems.
it MUST have somethign in G_fp and can't be called
from the callback since "brow" isn't defined there*/
win.resizable(brow);
win.show();
return Fl::run();
}