| 
							- /*
 -   ZynAddSubFX - a software synthesizer
 - 
 -   main.cpp  -  Main file of the synthesizer
 -   Copyright (C) 2002-2005 Nasca Octavian Paul
 -   Copyright (C) 2012-2017 Mark McCurry
 - 
 -   This program is free software; you can redistribute it and/or
 -   modify it under the terms of the GNU General Public License
 -   as published by the Free Software Foundation; either version 2
 -   of the License, or (at your option) any later version.
 - */
 - 
 - 
 - #include <iostream>
 - #include <fstream>
 - #include <map>
 - #include <cmath>
 - #include <cctype>
 - #include <ctime>
 - #include <algorithm>
 - #include <signal.h>
 - 
 - #ifndef WIN32
 - #include <err.h>
 - #endif
 - #include <unistd.h>
 - #include <pthread.h>
 - 
 - #include <getopt.h>
 - 
 - #include <rtosc/rtosc.h>
 - #include <rtosc/ports.h>
 - #include <rtosc/thread-link.h>
 - #include "Params/PADnoteParameters.h"
 - 
 - #include "DSP/FFTwrapper.h"
 - #include "Misc/PresetExtractor.h"
 - #include "Misc/Master.h"
 - #include "Misc/Part.h"
 - #include "Misc/Util.h"
 - #include "zyn-version.h"
 - 
 - //Nio System
 - #include "Nio/Nio.h"
 - #include "Nio/InMgr.h"
 - 
 - //GUI System
 - #include "UI/Connection.h"
 - GUI::ui_handle_t gui;
 - 
 - #ifdef ZEST_GUI
 - #ifndef WIN32
 - #include <sys/wait.h>
 - #endif
 - #endif
 - 
 - //Glue Layer
 - #include "Misc/MiddleWare.h"
 - 
 - using namespace std;
 - using namespace zyncarla;
 - 
 - MiddleWare *middleware;
 - 
 - Master   *master;
 - int       swaplr = 0; //1 for left-right swapping
 - 
 - // forward declarations of namespace zyncarla
 - namespace zyncarla
 - {
 -     extern int Pexitprogram;     //if the UI set this to 1, the program will exit
 -     void dump_json(std::ostream &o,
 -                    const rtosc::Ports &p);
 - }
 - 
 - #if LASH
 - #include "Misc/LASHClient.h"
 - LASHClient *lash = NULL;
 - #endif
 - 
 - #if USE_NSM
 - #include "UI/NSM.H"
 - 
 - NSM_Client *nsm = 0;
 - #endif
 - 
 - char *instance_name = 0;
 - 
 - void exitprogram(const Config &config);
 - 
 - 
 - //cleanup on signaled exit
 - void sigterm_exit(int /*sig*/)
 - {
 -     if(Pexitprogram)
 -         exit(1);
 -     Pexitprogram = 1;
 - }
 - 
 - /*
 -  * Program initialisation
 -  */
 - void initprogram(SYNTH_T synth, Config* config, int prefered_port)
 - {
 -     middleware = new MiddleWare(std::move(synth), config, prefered_port);
 -     master = middleware->spawnMaster();
 -     master->swaplr = swaplr;
 - 
 -     signal(SIGINT, sigterm_exit);
 -     signal(SIGTERM, sigterm_exit);
 -     Nio::init(master->synth, config->cfg.oss_devs, master);
 - }
 - 
 - /*
 -  * Program exit
 -  */
 - void exitprogram(const Config& config)
 - {
 -     Nio::stop();
 -     config.save();
 -     middleware->removeAutoSave();
 - 
 -     GUI::destroyUi(gui);
 -     delete middleware;
 - #if LASH
 -     if(lash)
 -         delete lash;
 - #endif
 - #if USE_NSM
 -     if(nsm)
 -         delete nsm;
 - #endif
 - 
 -     FFT_cleanup();
 - }
 - 
 - //Windows MIDI OH WHAT A HACK...
 - #ifdef WIN32
 - #include <windows.h>
 - #include <mmsystem.h>
 - namespace zyncarla{
 - extern InMgr  *in;
 - }
 - HMIDIIN winmidiinhandle = 0;
 - 
 - void CALLBACK WinMidiInProc(HMIDIIN hMidiIn,UINT wMsg,DWORD dwInstance,
 -                             DWORD dwParam1,DWORD dwParam2)
 - {
 -     int midicommand=0;
 -     if (wMsg==MIM_DATA) {
 -         int cmd,par1,par2;
 -         cmd=dwParam1&0xff;
 -         if (cmd==0xfe) return;
 -         par1=(dwParam1>>8)&0xff;
 -         par2=dwParam1>>16;
 -         int cmdchan=cmd&0x0f;
 -         int cmdtype=(cmd>>4)&0x0f;
 - 
 -         int tmp=0;
 -         MidiEvent ev;
 -         switch (cmdtype) {
 -             case(0x8)://noteon
 -                 ev.type = 1;
 -                 ev.num = par1;
 -                 ev.channel = cmdchan;
 -                 ev.value = 0;
 -                 in->putEvent(ev);
 -                 break;
 -             case(0x9)://noteoff
 -                 ev.type = 1;
 -                 ev.num = par1;
 -                 ev.channel = cmdchan;
 -                 ev.value = par2&0xff;
 -                 in->putEvent(ev);
 -                 break;
 -             case(0xb)://controller
 -                 ev.type = 2;
 -                 ev.num = par1;
 -                 ev.channel = cmdchan;
 -                 ev.value = par2&0xff;
 -                 in->putEvent(ev);
 -                 break;
 -             case(0xe)://pitch wheel
 -                 //tmp=(par1+par2*(long int) 128)-8192;
 -                 //winmaster->SetController(cmdchan,C_pitchwheel,tmp);
 -                 break;
 -             default:
 -                 break;
 -         };
 - 
 -     };
 - };
 - 
 - void InitWinMidi(int midi)
 - {
 - (void)midi;
 -     for(int i=0; i<10; ++i) {
 -         long int res=midiInOpen(&winmidiinhandle,i,(DWORD_PTR)(void*)WinMidiInProc,0,CALLBACK_FUNCTION);
 -         if(res == MMSYSERR_NOERROR) {
 -             res=midiInStart(winmidiinhandle);
 -             printf("[INFO] Starting Windows MIDI At %d with code %d(noerror=%d)\n", i, res, MMSYSERR_NOERROR);
 -             if(res == 0)
 -                 return;
 -         } else
 -             printf("[INFO] No Windows MIDI Device At id %d\n", i);
 -     }
 - };
 - 
 - //void StopWinMidi()
 - //{
 - //    midiInStop(winmidiinhandle);
 - //    midiInClose(winmidiinhandle);
 - //};
 - #else
 - void InitWinMidi(int) {}
 - #endif
 - 
 - 
 - int main(int argc, char *argv[])
 - {
 -     SYNTH_T synth;
 -     Config config;
 -     int noui = 0;
 -     cerr
 -     << "\nZynAddSubFX - Copyright (c) 2002-2013 Nasca Octavian Paul and others"
 -     << endl;
 -     cerr
 -     << "                Copyright (c) 2009-2017 Mark McCurry [active maintainer]"
 -     << endl;
 -     cerr << "Compiled: " << __DATE__ << " " << __TIME__ << endl;
 -     cerr << "This program is free software (GNU GPL v2 or later) and \n";
 -     cerr << "it comes with ABSOLUTELY NO WARRANTY.\n" << endl;
 -     if(argc == 1)
 -         cerr << "Try 'zynaddsubfx --help' for command-line options." << endl;
 - 
 -     /* Get the settings from the Config*/
 -     synth.samplerate = config.cfg.SampleRate;
 -     synth.buffersize = config.cfg.SoundBufferSize;
 -     synth.oscilsize  = config.cfg.OscilSize;
 -     swaplr = config.cfg.SwapStereo;
 - 
 -     Nio::preferedSampleRate(synth.samplerate);
 - 
 -     synth.alias(); //build aliases
 - 
 -     sprng(time(NULL));
 - 
 -     /* Parse command-line options */
 -     struct option opts[] = {
 -         {
 -             "load", 2, NULL, 'l'
 -         },
 -         {
 -             "load-instrument", 2, NULL, 'L'
 -         },
 -         {
 -             "midi-learn", 2, NULL, 'M'
 -         },
 -         {
 -             "sample-rate", 2, NULL, 'r'
 -         },
 -         {
 -             "buffer-size", 2, NULL, 'b'
 -         },
 -         {
 -             "oscil-size", 2, NULL, 'o'
 -         },
 -         {
 -             "swap", 2, NULL, 'S'
 -         },
 -         {
 -             "no-gui", 0, NULL, 'U'
 -         },
 -         {
 -             "dummy", 2, NULL, 'Y'
 -         },
 -         {
 -             "help", 2, NULL, 'h'
 -         },
 -         {
 -             "version", 2, NULL, 'v'
 -         },
 -         {
 -             "named", 1, NULL, 'N'
 -         },
 -         {
 -             "auto-connect", 0, NULL, 'a'
 -         },
 -         {
 -             "auto-save", 0, NULL, 'A'
 -         },
 -         {
 -             "pid-in-client-name", 0, NULL, 'p'
 -         },
 -         {
 -             "prefered-port", 1, NULL, 'P',
 -         },
 -         {
 -             "output", 1, NULL, 'O'
 -         },
 -         {
 -             "input", 1, NULL, 'I'
 -         },
 -         {
 -             "exec-after-init", 1, NULL, 'e'
 -         },
 -         {
 -             "dump-oscdoc", 2, NULL, 'd'
 -         },
 -         {
 -             "dump-json-schema", 2, NULL, 'D'
 -         },
 -         {
 -             0, 0, 0, 0
 -         }
 -     };
 -     opterr = 0;
 -     int option_index = 0, opt, exitwithhelp = 0, exitwithversion = 0;
 -     int prefered_port = -1;
 -     int auto_save_interval = 0;
 - int wmidi = -1;
 - 
 -     string loadfile, loadinstrument, execAfterInit, loadmidilearn;
 - 
 -     while(1) {
 -         int tmp = 0;
 - 
 -         /**\todo check this process for a small memory leak*/
 -         opt = getopt_long(argc,
 -                           argv,
 -                           "l:L:M:r:b:o:I:O:N:e:P:A:d:D:hvapSDUYZ",
 -                           opts,
 -                           &option_index);
 -         char *optarguments = optarg;
 - 
 - #define GETOP(x) if(optarguments) \
 -         x = optarguments
 - #define GETOPNUM(x) if(optarguments) \
 -         x = atoi(optarguments)
 - 
 - 
 -         if(opt == -1)
 -             break;
 - 
 -         switch(opt) {
 -             case 'h':
 -                 exitwithhelp = 1;
 -                 break;
 -             case 'v':
 -                 exitwithversion = 1;
 -                 break;
 -             case 'Y': /* this command a dummy command (has NO effect)
 -                         and is used because I need for NSIS installer
 -                         (NSIS sometimes forces a command line for a
 -                         program, even if I don't need that; eg. when
 -                         I want to add a icon to a shortcut.
 -                      */
 -                 break;
 -             case 'U':
 -                 noui = 1;
 -                 break;
 -             case 'l':
 -                 GETOP(loadfile);
 -                 break;
 -             case 'L':
 -                 GETOP(loadinstrument);
 -                 break;
 -             case 'M':
 -                 GETOP(loadmidilearn);
 -                 break;
 -             case 'r':
 -                 GETOPNUM(synth.samplerate);
 -                 if(synth.samplerate < 4000) {
 -                     cerr << "ERROR:Incorrect sample rate: " << optarguments
 -                          << endl;
 -                     exit(1);
 -                 }
 -                 break;
 -             case 'b':
 -                 GETOPNUM(synth.buffersize);
 -                 if(synth.buffersize < 2) {
 -                     cerr << "ERROR:Incorrect buffer size: " << optarguments
 -                          << endl;
 -                     exit(1);
 -                 }
 -                 break;
 -             case 'o':
 -                 if(optarguments)
 -                     synth.oscilsize = tmp = atoi(optarguments);
 -                 if(synth.oscilsize < MAX_AD_HARMONICS * 2)
 -                     synth.oscilsize = MAX_AD_HARMONICS * 2;
 -                 synth.oscilsize =
 -                     (int) powf(2,
 -                                ceil(logf(synth.oscilsize - 1.0f) / logf(2.0f)));
 -                 if(tmp != synth.oscilsize)
 -                     cerr
 -                     <<
 -                     "synth.oscilsize is wrong (must be 2^n) or too small. Adjusting to "
 -                     << synth.oscilsize << "." << endl;
 -                 break;
 -             case 'S':
 -                 swaplr = 1;
 -                 break;
 -             case 'N':
 -                 Nio::setPostfix(optarguments);
 -                 break;
 -             case 'I':
 -                 if(optarguments)
 -                     Nio::setDefaultSource(optarguments);
 -                 break;
 -             case 'O':
 -                 if(optarguments)
 -                     Nio::setDefaultSink(optarguments);
 -                 break;
 -             case 'a':
 -                 Nio::autoConnect = true;
 -                 break;
 -             case 'p':
 -                 Nio::pidInClientName = true;
 -                 break;
 -             case 'P':
 -                 if(optarguments)
 -                     prefered_port = atoi(optarguments);
 -                 break;
 -             case 'A':
 -                 if(optarguments)
 -                     auto_save_interval = atoi(optarguments);
 -                 break;
 -             case 'e':
 -                 GETOP(execAfterInit);
 -                 break;
 -             case 'd':
 -                 if(optarguments)
 -                 {
 -                     rtosc::OscDocFormatter s;
 -                     ofstream outfile(optarguments);
 -                     s.prog_name    = "ZynAddSubFX";
 -                     s.p            = &Master::ports;
 -                     s.uri          = "http://example.com/fake/";
 -                     s.doc_origin   = "http://example.com/fake/url.xml";
 -                     s.author_first = "Mark";
 -                     s.author_last  = "McCurry";
 -                     outfile << s;
 -                 }
 -                 break;
 -             case 'D':
 -                 if(optarguments)
 -                 {
 -                     ofstream outfile(optarguments);
 -                     dump_json(outfile, Master::ports);
 -                 }
 -                 break;
 -             case 'Z':
 -                 if(optarguments)
 -                     wmidi = atoi(optarguments);
 -                 break;
 -             case '?':
 -                 cerr << "ERROR:Bad option or parameter.\n" << endl;
 -                 exitwithhelp = 1;
 -                 break;
 -         }
 -     }
 - 
 -     synth.alias();
 - 
 -     if(exitwithversion) {
 -         cout << "Version: " << version << endl;
 -         return 0;
 -     }
 -     if(exitwithhelp != 0) {
 -         cout << "Usage: zynaddsubfx [OPTION]\n\n"
 -              << "  -h , --help \t\t\t\t Display command-line help and exit\n"
 -              << "  -v , --version \t\t\t Display version and exit\n"
 -              << "  -l file, --load=FILE\t\t\t Loads a .xmz file\n"
 -              << "  -L file, --load-instrument=FILE\t Loads a .xiz file\n"
 -              << "  -M file, --midi-learn=FILE\t\t Loads a .xlz file\n"
 -              << "  -r SR, --sample-rate=SR\t\t Set the sample rate SR\n"
 -              <<
 -         "  -b BS, --buffer-size=SR\t\t Set the buffer size (granularity)\n"
 -              << "  -o OS, --oscil-size=OS\t\t Set the ADsynth oscil. size\n"
 -              << "  -S , --swap\t\t\t\t Swap Left <--> Right\n"
 -              <<
 -         "  -U , --no-gui\t\t\t\t Run ZynAddSubFX without user interface\n"
 -              << "  -N , --named\t\t\t\t Postfix IO Name when possible\n"
 -              << "  -a , --auto-connect\t\t\t AutoConnect when using JACK\n"
 -              << "  -A , --auto-save=INTERVAL\t\t Automatically save at interval\n"
 -              << "\t\t\t\t\t (disabled with 0 interval)\n"
 -              << "  -p , --pid-in-client-name\t\t Append PID to (JACK) "
 -                 "client name\n"
 -              << "  -P , --preferred-port\t\t\t Preferred OSC Port\n"
 -              << "  -O , --output\t\t\t\t Set Output Engine\n"
 -              << "  -I , --input\t\t\t\t Set Input Engine\n"
 -              << "  -e , --exec-after-init\t\t Run post-initialization script\n"
 -              << "  -d , --dump-oscdoc=FILE\t\t Dump oscdoc xml to file\n"
 -              << "  -D , --dump-json-schema=FILE\t\t Dump osc schema (.json) to file\n"
 -              << endl;
 - 
 -         return 0;
 -     }
 - 
 -     cerr.precision(1);
 -     cerr << std::fixed;
 -     cerr << "\nSample Rate = \t\t" << synth.samplerate << endl;
 -     cerr << "Sound Buffer Size = \t" << synth.buffersize << " samples" << endl;
 -     cerr << "Internal latency = \t" << synth.dt() * 1000.0f << " ms" << endl;
 -     cerr << "ADsynth Oscil.Size = \t" << synth.oscilsize << " samples" << endl;
 - 
 -     initprogram(std::move(synth), &config, prefered_port);
 - 
 -     bool altered_master = false;
 -     if(!loadfile.empty()) {
 -         altered_master = true;
 -         const char *filename = loadfile.c_str();
 -         int tmp = master->loadXML(filename);
 -         if(tmp < 0) {
 -             cerr << "ERROR: Could not load master file " << loadfile
 -                  << "." << endl;
 -             exit(1);
 -         }
 -         else {
 -             strncpy(master->last_xmz, filename, XMZ_PATH_MAX);
 -             master->last_xmz[XMZ_PATH_MAX-1] = 0;
 -             master->applyparameters();
 -             cout << "Master file loaded." << endl;
 -         }
 -     }
 - 
 -     if(!loadinstrument.empty()) {
 -         altered_master = true;
 -         int loadtopart = 0;
 -         int tmp = master->part[loadtopart]->loadXMLinstrument(
 -             loadinstrument.c_str());
 -         if(tmp < 0) {
 -             cerr << "ERROR: Could not load instrument file "
 -                  << loadinstrument << '.' << endl;
 -             exit(1);
 -         }
 -         else {
 -             master->part[loadtopart]->applyparameters();
 -             master->part[loadtopart]->initialize_rt();
 -             cout << "Instrument file loaded." << endl;
 -         }
 -     }
 - 
 -     if(!loadmidilearn.empty()) {
 -         char msg[1024];
 -         rtosc_message(msg, sizeof(msg), "/load_xlz",
 -                 "s", loadmidilearn.c_str());
 -         middleware->transmitMsg(msg);
 -     }
 - 
 -     if(altered_master)
 -         middleware->updateResources(master);
 - 
 -     //Run the Nio system
 -     printf("[INFO] Nio::start()\n");
 -     bool ioGood = Nio::start();
 - 
 -     printf("[INFO] exec-after-init\n");
 -     if(!execAfterInit.empty()) {
 -         cout << "Executing user supplied command: " << execAfterInit << endl;
 -         if(system(execAfterInit.c_str()) == -1)
 -             cerr << "Command Failed..." << endl;
 -     }
 - 
 -     InitWinMidi(wmidi);
 - 
 - 
 -     gui = NULL;
 - 
 -     //Capture Startup Responses
 -     printf("[INFO] startup OSC\n");
 -     typedef std::vector<const char *> wait_t;
 -     wait_t msg_waitlist;
 -     middleware->setUiCallback([](void*v,const char*msg) {
 -             wait_t &wait = *(wait_t*)v;
 -             size_t len = rtosc_message_length(msg, -1);
 -             char *copy = new char[len];
 -             memcpy(copy, msg, len);
 -             wait.push_back(copy);
 -             }, &msg_waitlist);
 - 
 -     printf("[INFO] UI calbacks\n");
 -     if(!noui)
 -         gui = GUI::createUi(middleware->spawnUiApi(), &Pexitprogram);
 -     middleware->setUiCallback(GUI::raiseUi, gui);
 -     middleware->setIdleCallback([](void*){GUI::tickUi(gui);}, NULL);
 - 
 -     //Replay Startup Responses
 -     printf("[INFO] OSC replay\n");
 -     for(auto msg:msg_waitlist) {
 -         GUI::raiseUi(gui, msg);
 -         delete [] msg;
 -     }
 - 
 -     if(!noui)
 -     {
 -         GUI::raiseUi(gui, "/show",  "i", config.cfg.UserInterfaceMode);
 -         if(!ioGood)
 -             GUI::raiseUi(gui, "/alert", "s",
 -                     "Default IO did not initialize.\nDefaulting to NULL backend.");
 -     }
 - 
 -     printf("[INFO] auto_save setup\n");
 -     if(auto_save_interval > 0) {
 -         int old_save = middleware->checkAutoSave();
 -         if(old_save > 0)
 -             GUI::raiseUi(gui, "/alert-reload", "i", old_save);
 -         middleware->enableAutoSave(auto_save_interval);
 -     }
 -     printf("[INFO] NSM Stuff\n");
 - 
 -     //TODO move this stuff into Cmake
 - #if USE_NSM && defined(WIN32)
 - #undef USE_NSM
 - #define USE_NSM 0
 - #endif
 - 
 - #if LASH && defined(WIN32)
 - #undef LASH
 - #define LASH 0
 - #endif
 - 
 - #if USE_NSM
 -     char *nsm_url = getenv("NSM_URL");
 - 
 -     if(nsm_url) {
 -         nsm = new NSM_Client(middleware);
 - 
 -         if(!nsm->init(nsm_url))
 -             nsm->announce("ZynAddSubFX", ":switch:", argv[0]);
 -         else {
 -             delete nsm;
 -             nsm = NULL;
 -         }
 -     }
 - #endif
 - 
 -     printf("[INFO] LASH Stuff\n");
 - #if USE_NSM
 -     if(!nsm)
 - #endif
 -     {
 - #if LASH
 -         lash = new LASHClient(&argc, &argv);
 -         GUI::raiseUi(gui, "/session-type", "s", "LASH");
 - #endif
 -     }
 - 
 - #ifdef ZEST_GUI
 - #ifndef WIN32
 -     pid_t gui_pid = 0;
 - #endif
 -     if(!noui) {
 -         printf("[INFO] Launching Zyn-Fusion...\n");
 -         const char *addr = middleware->getServerAddress();
 - #ifndef WIN32
 -         gui_pid = fork();
 -         if(gui_pid == 0) {
 -             execlp("zyn-fusion", "zyn-fusion", addr, "--builtin", "--no-hotload",  0);
 -             execlp("./zyn-fusion", "zyn-fusion", addr, "--builtin", "--no-hotload",  0);
 - 
 -             err(1,"Failed to launch Zyn-Fusion");
 -         }
 - #else
 -         STARTUPINFO si;
 - PROCESS_INFORMATION pi;
 - memset(&si, 0, sizeof(si));
 - memset(&pi, 0, sizeof(pi));
 - char *why_windows = strrchr(addr, ':');
 - char *seriously_why = why_windows + 1;
 - char start_line[256] = {0};
 - if(why_windows)
 -     snprintf(start_line, sizeof(start_line), "zyn-fusion.exe osc.udp://127.0.0.1:%s", seriously_why);
 - else {
 -     printf("COULD NOT PARSE <%s>\n", addr);
 -     exit(1);
 - }
 - printf("[INFO] starting subprocess via <%s>\n", start_line);
 - if(!CreateProcess(NULL, start_line,
 - NULL, NULL, 0, 0, NULL, NULL, &si, &pi)) {
 -     printf("Failed to launch Zyn-Fusion...\n");
 -     exit(1);
 - }
 - 
 - #endif
 -     }
 - #endif
 - 
 -     printf("[INFO] Main Loop...\n");
 -     while(Pexitprogram == 0) {
 - #ifndef WIN32
 - #if USE_NSM
 -         if(nsm) {
 -             nsm->check();
 -             goto done;
 -         }
 - #endif
 - #if LASH
 -         {
 -             string filename;
 -             switch(lash->checkevents(filename)) {
 -                 case LASHClient::Save:
 -                     GUI::raiseUi(gui, "/save-master", "s", filename.c_str());
 -                     lash->confirmevent(LASHClient::Save);
 -                     break;
 -                 case LASHClient::Restore:
 -                     GUI::raiseUi(gui, "/load-master", "s", filename.c_str());
 -                     lash->confirmevent(LASHClient::Restore);
 -                     break;
 -                 case LASHClient::Quit:
 -                     Pexitprogram = 1;
 -                 default:
 -                     break;
 -             }
 -         }
 - #endif //LASH
 - 
 - #if USE_NSM
 - done:
 - #endif
 -         GUI::tickUi(gui);
 - #endif
 -         middleware->tick();
 - #ifdef WIN32
 -         Sleep(1);
 - #endif
 - 
 - #ifdef ZEST_GUI
 - #ifndef WIN32
 -         if(!noui) {
 -             int status = 0;
 -             int ret = waitpid(gui_pid, &status, WNOHANG);
 -             if(ret == gui_pid)
 -                 Pexitprogram = 1;
 -         }
 - #endif
 - #endif
 -     }
 - 
 -     exitprogram(config);
 -     return 0;
 - }
 
 
  |