Fluid STR 3460.D: Shell commands are now saved in the .fl file (user option)

The shell properties toolbox is completely redesigned:

This dialog box offers a field for a command line and three check buttons
 to generate and save various files before the command is run.

 If the fourth checkbox, "use settings in .fl design files" is checked,
 all shell settings will be store in the current .fl file, and they will
 be read and restored when the .fl is loaded again.

 Fluid will save different shell settings for different operating system as
 it is common that a different OS requires a different shell command.

 Fluid comes with default shell settings. Pressing the "save as default" button
 will store the current setting in the Fluid app settings and are used for new
 designs, or if the "use settings..." box is not checked.

 Fluid app settings are saved per user and per machine.
This commit is contained in:
Matthias Melcher 2021-12-09 02:43:57 +01:00
parent 1be158a840
commit 4f2febd801
8 changed files with 450 additions and 179 deletions

View File

@ -39,6 +39,7 @@ copied or otherwise examined.
#include "code.h"
#include "undo.h"
#include "pixmaps.h"
#include "shell_command.h"
#include <FL/Fl.H>
#include <FL/Fl_Browser_.H>
@ -167,8 +168,10 @@ void delete_all(int selected_only) {
if(!selected_only) {
include_H_from_C=1;
use_FL_COMMAND=0;
// reset the setting for the external shell command
shell_prefs_get();
shell_settings_write();
}
selection_changed(0);
}

View File

@ -326,30 +326,32 @@ Fl_Double_Window *shell_window=(Fl_Double_Window *)0;
Fl_Input *shell_command_input=(Fl_Input *)0;
static void cb_shell_command_input(Fl_Input*, void*) {
fluid_prefs.set("shell_command", shell_command_input->value());
}
Fl_Check_Button *shell_savefl_button=(Fl_Check_Button *)0;
Fl_Check_Button *shell_writecode_button=(Fl_Check_Button *)0;
static void cb_shell_writecode_button(Fl_Check_Button*, void*) {
fluid_prefs.set("shell_writecode", shell_writecode_button->value());
}
Fl_Check_Button *shell_writemsgs_button=(Fl_Check_Button *)0;
static void cb_shell_writemsgs_button(Fl_Check_Button*, void*) {
fluid_prefs.set("shell_writemsgs", shell_writemsgs_button->value());
Fl_Check_Button *shell_use_fl_button=(Fl_Check_Button *)0;
static void cb_shell_use_fl_button(Fl_Check_Button*, void*) {
g_shell_use_fl_settings = shell_use_fl_button->value();
fluid_prefs.set("shell_use_fl", g_shell_use_fl_settings);
}
Fl_Check_Button *shell_savefl_button=(Fl_Check_Button *)0;
static void cb_save(Fl_Button*, void*) {
apply_shell_window();
shell_prefs_set();
}
static void cb_shell_savefl_button(Fl_Check_Button*, void*) {
fluid_prefs.set("shell_savefl", shell_savefl_button->value());
static void cb_Run(Fl_Return_Button*, void*) {
apply_shell_window();
do_shell_command(NULL, NULL);
}
static void cb_Cancel(Fl_Button*, void*) {
shell_window->hide();
shell_command_input->value(g_shell_command);
shell_window->hide();
}
Fl_Double_Window *shell_run_window=(Fl_Double_Window *)0;
@ -368,42 +370,72 @@ shell_run_window->hide();
}
Fl_Double_Window* make_shell_window() {
{ shell_window = new Fl_Double_Window(365, 125, "Shell Command");
{ shell_command_input = new Fl_Input(10, 27, 347, 25, "Command:");
{ shell_window = new Fl_Double_Window(365, 200, "Shell Command");
{ Fl_Group* o = new Fl_Group(0, 0, 365, 165);
{ shell_command_input = new Fl_Input(82, 14, 277, 20, "Command:");
shell_command_input->tooltip("external shell command");
shell_command_input->labelfont(1);
shell_command_input->callback((Fl_Callback*)cb_shell_command_input);
shell_command_input->align(Fl_Align(FL_ALIGN_TOP_LEFT));
char buf[1024];
fluid_prefs.get("shell_command", buf, "", sizeof(buf));
shell_command_input->value(buf);
shell_command_input->labelsize(12);
shell_command_input->textfont(4);
shell_command_input->textsize(12);
Fl_Group::current()->resizable(shell_command_input);
} // Fl_Input* shell_command_input
{ shell_writecode_button = new Fl_Check_Button(128, 61, 93, 19, "Write Code");
shell_writecode_button->down_box(FL_DOWN_BOX);
shell_writecode_button->callback((Fl_Callback*)cb_shell_writecode_button);
int b;
fluid_prefs.get("shell_writecode", b, 1);
shell_writecode_button->value(b);
} // Fl_Check_Button* shell_writecode_button
{ shell_writemsgs_button = new Fl_Check_Button(231, 61, 126, 19, "Write Messages");
shell_writemsgs_button->down_box(FL_DOWN_BOX);
shell_writemsgs_button->callback((Fl_Callback*)cb_shell_writemsgs_button);
int b;
fluid_prefs.get("shell_writemsgs", b, 0);
shell_writemsgs_button->value(b);
} // Fl_Check_Button* shell_writemsgs_button
{ shell_savefl_button = new Fl_Check_Button(10, 62, 108, 19, "Save .FL File");
{ shell_savefl_button = new Fl_Check_Button(82, 39, 136, 19, "save .fl design file");
shell_savefl_button->tooltip("save the design to the .fl file before running the command");
shell_savefl_button->down_box(FL_DOWN_BOX);
shell_savefl_button->callback((Fl_Callback*)cb_shell_savefl_button);
int b;
fluid_prefs.get("shell_savefl", b, 1);
shell_savefl_button->value(b);
shell_savefl_button->labelsize(12);
} // Fl_Check_Button* shell_savefl_button
{ Fl_Return_Button* o = new Fl_Return_Button(132, 90, 143, 25, "Run Command");
o->callback((Fl_Callback*)do_shell_command);
{ shell_writecode_button = new Fl_Check_Button(82, 59, 120, 19, "save source code");
shell_writecode_button->tooltip("generate the source code and header file before running the command");
shell_writecode_button->down_box(FL_DOWN_BOX);
shell_writecode_button->labelsize(12);
} // Fl_Check_Button* shell_writecode_button
{ shell_writemsgs_button = new Fl_Check_Button(82, 79, 126, 19, "save i18n strings");
shell_writemsgs_button->tooltip("save the internationalisation string before running the command");
shell_writemsgs_button->down_box(FL_DOWN_BOX);
shell_writemsgs_button->labelsize(12);
} // Fl_Check_Button* shell_writemsgs_button
{ shell_use_fl_button = new Fl_Check_Button(82, 110, 180, 19, "use settings in .fl design files");
shell_use_fl_button->tooltip("check to read and write shell command from and to .fl files");
shell_use_fl_button->down_box(FL_DOWN_BOX);
shell_use_fl_button->labelsize(12);
shell_use_fl_button->callback((Fl_Callback*)cb_shell_use_fl_button);
} // Fl_Check_Button* shell_use_fl_button
{ Fl_Box* o = new Fl_Box(82, 103, 275, 1);
o->box(FL_BORDER_FRAME);
o->color(FL_FOREGROUND_COLOR);
} // Fl_Box* o
{ Fl_Group* o = new Fl_Group(82, 134, 273, 20);
{ Fl_Button* o = new Fl_Button(82, 134, 104, 20, "save as default");
o->tooltip("update the Fluid app settings for external shell commands to the current sett\
ings");
o->labelsize(12);
o->callback((Fl_Callback*)cb_save);
} // Fl_Button* o
{ Fl_Box* o = new Fl_Box(186, 136, 169, 15);
Fl_Group::current()->resizable(o);
} // Fl_Box* o
o->end();
} // Fl_Group* o
o->end();
} // Fl_Group* o
{ Fl_Group* o = new Fl_Group(0, 160, 365, 40);
{ Fl_Box* o = new Fl_Box(10, 167, 135, 25);
Fl_Group::current()->resizable(o);
} // Fl_Box* o
{ Fl_Return_Button* o = new Fl_Return_Button(145, 167, 100, 25, "Run");
o->tooltip("save selected files and run the command");
o->labelsize(12);
o->callback((Fl_Callback*)cb_Run);
} // Fl_Return_Button* o
{ Fl_Button* o = new Fl_Button(285, 90, 72, 25, "Cancel");
{ Fl_Button* o = new Fl_Button(255, 167, 100, 25, "Cancel");
o->labelsize(12);
o->callback((Fl_Callback*)cb_Cancel);
} // Fl_Button* o
o->end();
} // Fl_Group* o
shell_window->set_modal();
shell_window->size_range(365, 200, 365, 200);
shell_window->end();
} // Fl_Double_Window* shell_window
{ shell_run_window = new Fl_Double_Window(555, 430, "Shell Command Output");

View File

@ -2,6 +2,8 @@
version 1.0400
header_name {.h}
code_name {.cxx}
mac_shell_cmd {echo "I love Fluid"}
mac_shell_flags 3
comment {//
// Setting and shell dialogs for the Fast Light Tool Kit (FLTK).
//
@ -26,6 +28,9 @@ decl {\#include "fluid.h"} {public global
decl {\#include "widget_browser.h"} {public global
}
decl {\#include "shell_command.h"} {public global
}
decl {\#include <FL/Fl_Text_Buffer.H>} {public local
}
@ -281,53 +286,72 @@ Examples:
}
}
Function {make_shell_window()} {open selected
Function {make_shell_window()} {open
} {
Fl_Window shell_window {
label {Shell Command}
xywh {873 248 365 125} type Double visible
label {Shell Command} open
xywh {469 233 365 200} type Double modal size_range {365 200 365 200} visible
} {
Fl_Group {} {open
xywh {0 0 365 165}
} {
Fl_Input shell_command_input {
label {Command:}
callback {fluid_prefs.set("shell_command", shell_command_input->value());}
xywh {10 27 347 25} labelfont 1 align 5
code0 {char buf[1024];}
code1 {fluid_prefs.get("shell_command", buf, "", sizeof(buf));}
code2 {shell_command_input->value(buf);}
}
Fl_Check_Button shell_writecode_button {
label {Write Code}
callback {fluid_prefs.set("shell_writecode", shell_writecode_button->value());}
xywh {128 61 93 19} down_box DOWN_BOX
code0 {int b;}
code1 {fluid_prefs.get("shell_writecode", b, 1);}
code2 {shell_writecode_button->value(b);}
}
Fl_Check_Button shell_writemsgs_button {
label {Write Messages}
callback {fluid_prefs.set("shell_writemsgs", shell_writemsgs_button->value());}
xywh {231 61 126 19} down_box DOWN_BOX
code0 {int b;}
code1 {fluid_prefs.get("shell_writemsgs", b, 0);}
code2 {shell_writemsgs_button->value(b);}
tooltip {external shell command} xywh {82 14 277 20} labelfont 1 labelsize 12 textfont 4 textsize 12 resizable
}
Fl_Check_Button shell_savefl_button {
label {Save .FL File}
callback {fluid_prefs.set("shell_savefl", shell_savefl_button->value());}
xywh {10 62 108 19} down_box DOWN_BOX
code0 {int b;}
code1 {fluid_prefs.get("shell_savefl", b, 1);}
code2 {shell_savefl_button->value(b);}
label {save .fl design file}
tooltip {save the design to the .fl file before running the command} xywh {82 39 136 19} down_box DOWN_BOX labelsize 12
}
Fl_Check_Button shell_writecode_button {
label {save source code}
tooltip {generate the source code and header file before running the command} xywh {82 59 120 19} down_box DOWN_BOX labelsize 12
}
Fl_Check_Button shell_writemsgs_button {
label {save i18n strings}
tooltip {save the internationalisation string before running the command} xywh {82 79 126 19} down_box DOWN_BOX labelsize 12
}
Fl_Check_Button shell_use_fl_button {
label {use settings in .fl design files}
callback {g_shell_use_fl_settings = shell_use_fl_button->value();
fluid_prefs.set("shell_use_fl", g_shell_use_fl_settings);}
tooltip {check to read and write shell command from and to .fl files} xywh {82 110 180 19} down_box DOWN_BOX labelsize 12
}
Fl_Box {} {
xywh {82 103 275 1} box BORDER_FRAME color 0
}
Fl_Group {} {open
xywh {82 134 273 20}
} {
Fl_Button {} {
label {save as default}
callback {apply_shell_window();
shell_prefs_set();} selected
tooltip {update the Fluid app settings for external shell commands to the current settings} xywh {82 134 104 20} labelsize 12
}
Fl_Box {} {
xywh {186 136 169 15} resizable
}
}
}
Fl_Group {} {open
xywh {0 160 365 40}
} {
Fl_Box {} {
xywh {10 167 135 25} resizable
}
Fl_Return_Button {} {
label {Run Command}
callback do_shell_command
xywh {132 90 143 25}
label Run
callback {apply_shell_window();
do_shell_command(NULL, NULL);}
tooltip {save selected files and run the command} xywh {145 167 100 25} labelsize 12
}
Fl_Button {} {
label Cancel
callback {shell_window->hide();}
xywh {285 90 72 25}
callback {shell_command_input->value(g_shell_command);
shell_window->hide();}
xywh {255 167 100 25} labelsize 12
}
}
}
Fl_Window shell_run_window {

View File

@ -21,6 +21,7 @@
#include <FL/Fl.H>
#include "fluid.h"
#include "widget_browser.h"
#include "shell_command.h"
#include <FL/Fl_Text_Buffer.H>
#include <FL/Fl_Text_Display.H>
#include <FL/filename.H>
@ -73,11 +74,11 @@ Fl_Double_Window* make_settings_window();
extern Fl_Menu_Item menu_scheme_choice[];
extern Fl_Double_Window *shell_window;
extern Fl_Input *shell_command_input;
extern Fl_Check_Button *shell_savefl_button;
extern Fl_Check_Button *shell_writecode_button;
extern Fl_Check_Button *shell_writemsgs_button;
extern Fl_Check_Button *shell_savefl_button;
extern Fl_Check_Button *shell_use_fl_button;
#include <FL/Fl_Return_Button.H>
extern void do_shell_command(Fl_Return_Button*, void*);
extern Fl_Double_Window *shell_run_window;
#include <FL/Fl_Simple_Terminal.H>
extern Fl_Simple_Terminal *shell_run_terminal;

View File

@ -28,6 +28,7 @@
#include "Fl_Window_Type.h"
#include "alignment_panel.h"
#include "widget_browser.h"
#include "shell_command.h"
#include "code.h"
#include <FL/Fl.H>
@ -392,9 +393,23 @@ int write_file(const char *filename, int selected_only) {
break;
}
}
shell_settings_write();
if (!selected_only) {
write_string("\nheader_name"); write_word(header_file_name);
write_string("\ncode_name"); write_word(code_file_name);
if (shell_settings_windows.command) {
write_string("\nwin_shell_cmd"); write_word(shell_settings_windows.command);
write_string("\nwin_shell_flags"); write_string("%d", shell_settings_windows.flags);
}
if (shell_settings_linux.command) {
write_string("\nlinux_shell_cmd"); write_word(shell_settings_linux.command);
write_string("\nlinux_shell_flags"); write_string("%d", shell_settings_linux.flags);
}
if (shell_settings_macos.command) {
write_string("\nmac_shell_cmd"); write_word(shell_settings_macos.command);
write_string("\nmac_shell_flags"); write_string("%d", shell_settings_macos.flags);
}
}
for (Fl_Type *p = Fl_Type::first; p;) {
if (!selected_only || p->selected) {
@ -413,9 +428,16 @@ int write_file(const char *filename, int selected_only) {
// read all the objects out of the input file:
/**
Read child node in the .fl design file.
Recursively read child nodes in the .fl design file.
If this is the first call, also read the global settings for this design.
\param[in] p parent node or NULL
\param[in] paste if set, merge into existing design, else replace design
\param[in] options_read this is set if the options were already found in
a previous call
*/
static void read_children(Fl_Type *p, int paste) {
static void read_children(Fl_Type *p, int paste, char options_read=0) {
Fl_Type::current = p;
for (;;) {
const char *c = read_word();
@ -430,6 +452,8 @@ static void read_children(Fl_Type *p, int paste) {
break;
}
// Make sure that we don;t go through the list of options for child nodes
if (!options_read) {
// this is the first word in a .fd file:
if (!strcmp(c,"Magic:")) {
read_fdesign();
@ -509,6 +533,26 @@ static void read_children(Fl_Type *p, int paste) {
goto CONTINUE;
}
if (strcmp(c, "win_shell_cmd")==0) {
if (shell_settings_windows.command)
free((void*)shell_settings_windows.command);
shell_settings_windows.command = fl_strdup(read_word());
} else if (strcmp(c, "win_shell_flags")==0) {
shell_settings_windows.flags = atoi(read_word());
} else if (strcmp(c, "linux_shell_cmd")==0) {
if (shell_settings_linux.command)
free((void*)shell_settings_linux.command);
shell_settings_linux.command = fl_strdup(read_word());
} else if (strcmp(c, "linux_shell_flags")==0) {
shell_settings_linux.flags = atoi(read_word());
} else if (strcmp(c, "mac_shell_cmd")==0) {
if (shell_settings_macos.command)
free((void*)shell_settings_macos.command);
shell_settings_macos.command = fl_strdup(read_word());
} else if (strcmp(c, "mac_shell_flags")==0) {
shell_settings_macos.flags = atoi(read_word());
}
}
{
Fl_Type *t = Fl_Type_make(c);
if (!t) {
@ -517,6 +561,9 @@ static void read_children(Fl_Type *p, int paste) {
}
t->name(read_word());
// After reading the first widget, we no longer need to look for options
options_read = 1;
c = read_word(1);
if (strcmp(c,"{") && t->is_class()) { // <prefix> <name>
((Fl_Class_Type*)t)->prefix(t->name());
@ -542,7 +589,7 @@ static void read_children(Fl_Type *p, int paste) {
read_error("Missing child list for %s\n",t->title());
goto REUSE_C;
}
read_children(t, 0);
read_children(t, 0, options_read);
}
Fl_Type::current = p;
@ -560,16 +607,25 @@ static void read_children(Fl_Type *p, int paste) {
int read_file(const char *filename, int merge) {
Fl_Type *o;
read_version = 0.0;
if (!open_read(filename)) return 0;
if (merge) deselect(); else delete_all();
if (!open_read(filename))
return 0;
if (merge)
deselect();
else
delete_all();
read_children(Fl_Type::current, merge);
Fl_Type::current = 0;
// Force menu items to be rebuilt...
for (o = Fl_Type::first; o; o = o->next)
if (o->is_menu_button()) o->add_child(0,0);
if (o->is_menu_button())
o->add_child(0,0);
for (o = Fl_Type::first; o; o = o->next)
if (o->selected) {Fl_Type::current = o; break;}
if (o->selected) {
Fl_Type::current = o;
break;
}
selection_changed(Fl_Type::current);
shell_settings_read();
return close_read();
}

View File

@ -1409,6 +1409,7 @@ void make_main_window() {
fluid_prefs.get("show_guides", show_guides, 0);
fluid_prefs.get("widget_size", Fl_Widget_Type::default_size, 14);
fluid_prefs.get("show_comments", show_comments, 1);
shell_prefs_get();
make_layout_window();
make_shell_window();
}

View File

@ -26,6 +26,102 @@
static Fl_Process s_proc;
/// Shell settings in the .fl file
Shell_Settings shell_settings_windows = { };
Shell_Settings shell_settings_linux = { };
Shell_Settings shell_settings_macos = { };
/// Current shell command, stored in .fl file for each platform, and in app prefs
char *g_shell_command = NULL;
/// Save .fl file before running, stored in .fl file for each platform, and in app prefs
int g_shell_save_fl = 1;
/// Save code file before running, stored in .fl file for each platform, and in app prefs
int g_shell_save_code = 1;
/// Save strings file before running, stored in .fl file for each platform, and in app prefs
int g_shell_save_strings = 0;
/// Use these settings from .fl files, stored in app prefs
int g_shell_use_fl_settings = 1;
/**
Read the default shell settings from the app preferences.
*/
void shell_prefs_get()
{
fluid_prefs.get("shell_command", g_shell_command, "echo \"Custom Shell Command\"");
fluid_prefs.get("shell_savefl", g_shell_save_fl, 1);
fluid_prefs.get("shell_writecode", g_shell_save_code, 1);
fluid_prefs.get("shell_writemsgs", g_shell_save_strings, 0);
fluid_prefs.get("shell_use_fl", g_shell_use_fl_settings, 1);
}
/**
Write the current shell settings to the app preferences.
*/
void shell_prefs_set()
{
fluid_prefs.set("shell_command", g_shell_command);
fluid_prefs.set("shell_savefl", g_shell_save_fl);
fluid_prefs.set("shell_writecode", g_shell_save_code);
fluid_prefs.set("shell_writemsgs", g_shell_save_strings);
fluid_prefs.set("shell_use_fl", g_shell_use_fl_settings);
}
/**
Copy shell settings from the .fl buffer if use_fl_settings is set.
*/
void shell_settings_read()
{
if (g_shell_use_fl_settings==0)
return;
#if defined(_WIN32)
Shell_Settings &shell_settings = shell_settings_windows;
#elif defined(__APPLE__)
Shell_Settings &shell_settings = shell_settings_macos;
#else
Shell_Settings &shell_settings = shell_settings_linux;
#endif
if (g_shell_command)
free((void*)g_shell_command);
g_shell_command = NULL;
if (shell_settings.command)
g_shell_command = strdup(shell_settings.command);
g_shell_save_fl = ((shell_settings.flags&1)==1);
g_shell_save_code = ((shell_settings.flags&2)==2);
g_shell_save_strings = ((shell_settings.flags&4)==4);
}
/**
Copy current shell settings to the .fl buffer if use_fl_settings is set.
*/
void shell_settings_write()
{
if (g_shell_use_fl_settings==0)
return;
#if defined(_WIN32)
Shell_Settings &shell_settings = shell_settings_windows;
#elif defined(__APPLE__)
Shell_Settings &shell_settings = shell_settings_macos;
#else
Shell_Settings &shell_settings = shell_settings_linux;
#endif
if (shell_settings.command)
free((void*)shell_settings.command);
shell_settings.command = NULL;
if (g_shell_command)
shell_settings.command = strdup(g_shell_command);
shell_settings.flags = 0;
if (g_shell_save_fl)
shell_settings.flags |= 1;
if (g_shell_save_code)
shell_settings.flags |= 2;
if (g_shell_save_strings)
shell_settings.flags |= 4;
}
/** \class Fl_Process
\todo Explain.
*/
@ -153,17 +249,17 @@ static bool prepare_shell_command(const char * &command) { // common pre-shell
fl_alert("Previous shell command still running!");
return false;
}
if ((command = shell_command_input->value()) == NULL || !*command) {
if ((command = g_shell_command) == NULL || !*command) {
fl_alert("No shell command entered!");
return false;
}
if (shell_savefl_button->value()) {
if (g_shell_save_fl) {
save_cb(0, 0);
}
if (shell_writecode_button->value()) {
if (g_shell_save_code) {
write_code_files();
}
if (shell_writemsgs_button->value()) {
if (g_shell_save_strings) {
write_strings_cb(0, 0);
}
return true;
@ -226,9 +322,44 @@ void do_shell_command(Fl_Return_Button*, void*) {
/**
Show a dialog box to run an external shell command.
Copies the current settings into the dialog box.
This dialog box offers a field for a command line and three check buttons
to generate and save various files before the command is run.
If the fourth checkbox, "use settings in .fl design files" is checked,
all shell settings will be store in the current .fl file, and they will
be read and restored when the .fl is loaded again.
Fluid will save different shell settings for different operating system as
it is common that a different OS requires a different shell command.
Fluid comes with default shell settings. Pressing the "save as default" button
will store the current setting in the Fluid app settings and are used for new
designs, or if the "use settings..." box is not checked.
Fluid app settings are saved per user and per machine.
*/
void show_shell_window() {
shell_command_input->value(g_shell_command);
shell_savefl_button->value(g_shell_save_fl);
shell_writecode_button->value(g_shell_save_code);
shell_writemsgs_button->value(g_shell_save_strings);
shell_use_fl_button->value(g_shell_use_fl_settings);
shell_window->hotspot(shell_command_input);
shell_window->show();
}
/**
Copy the sshe;l settings from the dialog box into the variables.
*/
void apply_shell_window() {
if (g_shell_command)
free((void*)g_shell_command);
g_shell_command = strdup(shell_command_input->value());
g_shell_save_fl = shell_savefl_button->value();
g_shell_save_code = shell_writecode_button->value();
g_shell_save_strings = shell_writemsgs_button->value();
}

View File

@ -32,6 +32,29 @@
#endif
void show_shell_window();
void apply_shell_window();
void do_shell_command(class Fl_Return_Button*, void*);
typedef struct {
char *command;
int flags;
} Shell_Settings;
extern Shell_Settings shell_settings_windows;
extern Shell_Settings shell_settings_linux;
extern Shell_Settings shell_settings_macos;
extern char *g_shell_command;
extern int g_shell_save_fl;
extern int g_shell_save_code;
extern int g_shell_save_strings;
extern int g_shell_use_fl_settings;
void shell_prefs_get();
void shell_prefs_set();
void shell_settings_read();
void shell_settings_write();
class Fl_Process {
public: