| @@ -205,19 +205,19 @@ void Fl_DeviceGUI::Setup(const DeviceGUIInfo& Info, bool FirstTime) | |||||
| int PortDist=10; | int PortDist=10; | ||||
| int PortNum=0; | int PortNum=0; | ||||
| m_MiniHeight=Info.Height+TitleBarHeight; | |||||
| m_MiniHeight=m_Info.Height+TitleBarHeight; | |||||
| bool Maximised = (m_PluginWindow && m_PluginWindow->visible()); | bool Maximised = (m_PluginWindow && m_PluginWindow->visible()); | ||||
| if (!Maximised) | if (!Maximised) | ||||
| { | { | ||||
| h(m_MiniHeight); | h(m_MiniHeight); | ||||
| OutputX=x()+PortGroupWidth+Info.Width+4; | |||||
| OutputX=x()+PortGroupWidth+m_Info.Width+4; | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| OutputX=x()+w()-8; | OutputX=x()+w()-8; | ||||
| } | } | ||||
| for (int n=0; n<Info.NumInputs; n++) | |||||
| for (int n=0; n<m_Info.NumInputs; n++) | |||||
| { | { | ||||
| Fl_PortButton* NewInput = new Fl_PortButton(InputX,StartY+PortDist*n,PortSize,PortSize,""); | Fl_PortButton* NewInput = new Fl_PortButton(InputX,StartY+PortDist*n,PortSize,PortSize,""); | ||||
| NewInput->type(1); | NewInput->type(1); | ||||
| @@ -226,7 +226,7 @@ void Fl_DeviceGUI::Setup(const DeviceGUIInfo& Info, bool FirstTime) | |||||
| NewInput->box(FL_ROUNDED_BOX); | NewInput->box(FL_ROUNDED_BOX); | ||||
| Fl_Color col = (Fl_Color) WIRE_COL0; | Fl_Color col = (Fl_Color) WIRE_COL0; | ||||
| switch (Info.PortTypes[n]) { | |||||
| switch (m_Info.PortTypes[n]) { | |||||
| case 0: col = (Fl_Color) WIRE_COL0; | case 0: col = (Fl_Color) WIRE_COL0; | ||||
| break; | break; | ||||
| case 1: col = (Fl_Color) WIRE_COL1; | case 1: col = (Fl_Color) WIRE_COL1; | ||||
| @@ -242,14 +242,14 @@ void Fl_DeviceGUI::Setup(const DeviceGUIInfo& Info, bool FirstTime) | |||||
| NewInput->selection_color(col); | NewInput->selection_color(col); | ||||
| NewInput->down_box(FL_ROUNDED_BOX); | NewInput->down_box(FL_ROUNDED_BOX); | ||||
| NewInput->tooltip(Info.PortTips[n].c_str()); | |||||
| NewInput->tooltip(m_Info.PortTips[n].c_str()); | |||||
| NewInput->callback((Fl_Callback*)cb_Port,(void*)&Numbers[PortNum]); | NewInput->callback((Fl_Callback*)cb_Port,(void*)&Numbers[PortNum]); | ||||
| m_PortVec.push_back(NewInput); | m_PortVec.push_back(NewInput); | ||||
| add(NewInput); | add(NewInput); | ||||
| PortNum++; | PortNum++; | ||||
| } | } | ||||
| for (int n=0; n<Info.NumOutputs; n++) | |||||
| for (int n=0; n<m_Info.NumOutputs; n++) | |||||
| { | { | ||||
| Fl_PortButton* NewOutput= NewOutput = new Fl_PortButton(OutputX,StartY+PortDist*n,PortSize,PortSize,""); | Fl_PortButton* NewOutput= NewOutput = new Fl_PortButton(OutputX,StartY+PortDist*n,PortSize,PortSize,""); | ||||
| NewOutput->type(1); | NewOutput->type(1); | ||||
| @@ -258,7 +258,7 @@ void Fl_DeviceGUI::Setup(const DeviceGUIInfo& Info, bool FirstTime) | |||||
| NewOutput->box(FL_ROUNDED_BOX); | NewOutput->box(FL_ROUNDED_BOX); | ||||
| Fl_Color col = (Fl_Color) WIRE_COL0; | Fl_Color col = (Fl_Color) WIRE_COL0; | ||||
| switch (Info.PortTypes[n+Info.NumInputs]) { | |||||
| switch (m_Info.PortTypes[n+m_Info.NumInputs]) { | |||||
| case 0: col = (Fl_Color) WIRE_COL0; | case 0: col = (Fl_Color) WIRE_COL0; | ||||
| break; | break; | ||||
| case 1: col = (Fl_Color) WIRE_COL1; | case 1: col = (Fl_Color) WIRE_COL1; | ||||
| @@ -274,7 +274,7 @@ void Fl_DeviceGUI::Setup(const DeviceGUIInfo& Info, bool FirstTime) | |||||
| NewOutput->selection_color(col); | NewOutput->selection_color(col); | ||||
| NewOutput->down_box(FL_ROUNDED_BOX); | NewOutput->down_box(FL_ROUNDED_BOX); | ||||
| NewOutput->tooltip(Info.PortTips[n+Info.NumInputs].c_str()); | |||||
| NewOutput->tooltip(m_Info.PortTips[n+m_Info.NumInputs].c_str()); | |||||
| NewOutput->callback((Fl_Callback*)cb_Port,(void*)&Numbers[PortNum]); | NewOutput->callback((Fl_Callback*)cb_Port,(void*)&Numbers[PortNum]); | ||||
| m_PortVec.push_back(NewOutput); | m_PortVec.push_back(NewOutput); | ||||
| add(NewOutput); | add(NewOutput); | ||||
| @@ -136,8 +136,21 @@ SpiralGUIType *OutputPlugin::CreateGUI() | |||||
| return new OutputPluginGUI(m_PluginInfo.Width, m_PluginInfo.Height, this, m_AudioCH, m_HostInfo); | return new OutputPluginGUI(m_PluginInfo.Width, m_PluginInfo.Height, this, m_AudioCH, m_HostInfo); | ||||
| } | } | ||||
| bool OutputPlugin::Kill() | |||||
| { | |||||
| m_IsDead=true; | |||||
| OSSOutput::Get()->Kill(); | |||||
| m_Mode=CLOSED; | |||||
| cb_Blocking(m_Parent,false); | |||||
| return true; | |||||
| } | |||||
| void OutputPlugin::Execute() | void OutputPlugin::Execute() | ||||
| { | { | ||||
| if (m_IsDead) | |||||
| return; | |||||
| if (m_Mode==NO_MODE && m_RefCount==1) | if (m_Mode==NO_MODE && m_RefCount==1) | ||||
| { | { | ||||
| if (OSSOutput::Get()->OpenWrite()) | if (OSSOutput::Get()->OpenWrite()) | ||||
| @@ -148,44 +161,9 @@ void OutputPlugin::Execute() | |||||
| } | } | ||||
| } | } | ||||
| //if (m_Mode==NO_MODE || m_Mode==CLOSED) cb_Blocking(m_Parent,false); | |||||
| //else cb_Blocking(m_Parent,true); | |||||
| if (m_Mode==OUTPUT || m_Mode==DUPLEX) | if (m_Mode==OUTPUT || m_Mode==DUPLEX) | ||||
| { | { | ||||
| OSSOutput::Get()->SendStereo(GetInput(0),GetInput(1)); | OSSOutput::Get()->SendStereo(GetInput(0),GetInput(1)); | ||||
| // can't open GUI stuff here | |||||
| /* for (int n=0; n<m_HostInfo->BUFSIZE;n++) | |||||
| { | |||||
| // can't open GUI stuff here | |||||
| if (GetInput(2,n)!=0) | |||||
| { | |||||
| if (! m_CheckedAlready) | |||||
| { | |||||
| m_CheckedAlready=true; | |||||
| // an experimental line, should *theoretically* cut down on CPU time. | |||||
| n=m_HostInfo->BUFSIZE; | |||||
| if (! m_Recmode) | |||||
| { | |||||
| char *fn=fl_file_chooser("Pick a Wav file to save to", "*.wav", NULL); | |||||
| if (fn && fn!="") | |||||
| { | |||||
| OSSOutput::Get()->WavOpen(fn); | |||||
| } | |||||
| m_Recmode=true; | |||||
| } | |||||
| else | |||||
| { | |||||
| OSSOutput::Get()->WavClose(); | |||||
| m_Recmode=false; | |||||
| } | |||||
| } | |||||
| } | |||||
| else | |||||
| m_CheckedAlready=false; | |||||
| }*/ | |||||
| } | } | ||||
| if (m_Mode==INPUT || m_Mode==DUPLEX) | if (m_Mode==INPUT || m_Mode==DUPLEX) | ||||
| @@ -194,8 +172,10 @@ void OutputPlugin::Execute() | |||||
| void OutputPlugin::ExecuteCommands() | void OutputPlugin::ExecuteCommands() | ||||
| { | { | ||||
| // Only Play() once per set of plugins | |||||
| if (m_IsDead) | |||||
| return; | |||||
| // Only Play() once per set of plugins | |||||
| m_NoExecuted--; | m_NoExecuted--; | ||||
| if (m_NoExecuted<=0) | if (m_NoExecuted<=0) | ||||
| { | { | ||||
| @@ -254,7 +234,9 @@ m_Amp(0.5), | |||||
| m_Channels(2), | m_Channels(2), | ||||
| m_ReadBufferNum(0), | m_ReadBufferNum(0), | ||||
| m_WriteBufferNum(0), | m_WriteBufferNum(0), | ||||
| m_OutputOk(false) | |||||
| m_OutputOk(false), | |||||
| m_IsDead(false) | |||||
| { | { | ||||
| m_Buffer[0]=NULL; | m_Buffer[0]=NULL; | ||||
| m_Buffer[1]=NULL; | m_Buffer[1]=NULL; | ||||
| @@ -267,6 +249,7 @@ m_OutputOk(false) | |||||
| OSSOutput::~OSSOutput() | OSSOutput::~OSSOutput() | ||||
| { | { | ||||
| Close(); | Close(); | ||||
| DeallocateBuffer(); | |||||
| } | } | ||||
| ////////////////////////////////////////////////////////////////////// | ////////////////////////////////////////////////////////////////////// | ||||
| @@ -287,6 +270,20 @@ void OSSOutput::AllocateBuffer() | |||||
| m_Wav.SetSamplerate(host->SAMPLERATE); | m_Wav.SetSamplerate(host->SAMPLERATE); | ||||
| } | } | ||||
| void OSSOutput::DeallocateBuffer() | |||||
| { | |||||
| if (m_Buffer[0]!=NULL) | |||||
| { | |||||
| m_BufSizeBytes=0; | |||||
| // initialise for stereo | |||||
| free(m_Buffer[0]); | |||||
| free(m_Buffer[1]); | |||||
| free(m_InBuffer[0]); | |||||
| free(m_InBuffer[1]); | |||||
| } | |||||
| } | |||||
| ////////////////////////////////////////////////////////////////////// | ////////////////////////////////////////////////////////////////////// | ||||
| void OSSOutput::SendStereo(const Sample *ldata,const Sample *rdata) | void OSSOutput::SendStereo(const Sample *ldata,const Sample *rdata) | ||||
| @@ -297,6 +294,8 @@ void OSSOutput::SendStereo(const Sample *ldata,const Sample *rdata) | |||||
| float t; | float t; | ||||
| for (int n=0; n<host->BUFSIZE; n++) | for (int n=0; n<host->BUFSIZE; n++) | ||||
| { | { | ||||
| if (m_IsDead) return; | |||||
| // stereo channels - interleave | // stereo channels - interleave | ||||
| if (ldata) | if (ldata) | ||||
| { | { | ||||
| @@ -354,6 +353,8 @@ void OSSOutput::GetStereo(Sample *ldata,Sample *rdata) | |||||
| int on=0; | int on=0; | ||||
| for (int n=0; n<host->BUFSIZE; n++) | for (int n=0; n<host->BUFSIZE; n++) | ||||
| { | { | ||||
| if (m_IsDead) return; | |||||
| // stereo channels - interleave | // stereo channels - interleave | ||||
| if (ldata) ldata->Set(n,(m_InBuffer[m_ReadBufferNum][on]*m_Amp)/(float)SHRT_MAX); | if (ldata) ldata->Set(n,(m_InBuffer[m_ReadBufferNum][on]*m_Amp)/(float)SHRT_MAX); | ||||
| on++; | on++; | ||||
| @@ -31,6 +31,7 @@ public: | |||||
| ~OSSOutput(); | ~OSSOutput(); | ||||
| void AllocateBuffer(); | void AllocateBuffer(); | ||||
| void DeallocateBuffer(); | |||||
| void SendStereo(const Sample *ldata,const Sample *rdata); | void SendStereo(const Sample *ldata,const Sample *rdata); | ||||
| void GetStereo(Sample *ldata,Sample *rdata); | void GetStereo(Sample *ldata,Sample *rdata); | ||||
| void SetVolume(float s) {m_Amp=s;} | void SetVolume(float s) {m_Amp=s;} | ||||
| @@ -46,7 +47,7 @@ public: | |||||
| bool OpenWrite(); | bool OpenWrite(); | ||||
| bool OpenRead(); | bool OpenRead(); | ||||
| bool Close(); | bool Close(); | ||||
| void Kill() { m_IsDead = true; m_OutputOk=false; PackUpAndGoHome(); } | |||||
| private: | private: | ||||
| static OSSOutput* m_Singleton; | static OSSOutput* m_Singleton; | ||||
| @@ -62,6 +63,7 @@ private: | |||||
| int m_ReadBufferNum; | int m_ReadBufferNum; | ||||
| int m_WriteBufferNum; | int m_WriteBufferNum; | ||||
| bool m_OutputOk; | bool m_OutputOk; | ||||
| bool m_IsDead; | |||||
| }; | }; | ||||
| @@ -76,6 +78,7 @@ public: | |||||
| virtual PluginInfo& Initialise(const HostInfo *Host); | virtual PluginInfo& Initialise(const HostInfo *Host); | ||||
| virtual SpiralGUIType* CreateGUI(); | virtual SpiralGUIType* CreateGUI(); | ||||
| virtual void Execute(); | virtual void Execute(); | ||||
| virtual bool Kill(); | |||||
| virtual void ExecuteCommands(); | virtual void ExecuteCommands(); | ||||
| virtual void StreamOut(std::ostream &s) {} | virtual void StreamOut(std::ostream &s) {} | ||||
| virtual void StreamIn(std::istream &s) {} | virtual void StreamIn(std::istream &s) {} | ||||
| @@ -33,7 +33,7 @@ SpiralPlugin::SpiralPlugin() | |||||
| m_Parent=NULL; | m_Parent=NULL; | ||||
| m_HostID=-1; | m_HostID=-1; | ||||
| m_IsTerminal=false; | m_IsTerminal=false; | ||||
| m_IsDead=false; | |||||
| m_AudioCH = new ChannelHandler; | m_AudioCH = new ChannelHandler; | ||||
| } | } | ||||
| @@ -77,6 +77,8 @@ public: | |||||
| // execute the audio | // execute the audio | ||||
| virtual void Execute()=0; | virtual void Execute()=0; | ||||
| virtual bool Kill() {m_IsDead = true; return true;} | |||||
| // run the commands from the GUI | // run the commands from the GUI | ||||
| virtual void ExecuteCommands() {} | virtual void ExecuteCommands() {} | ||||
| // create the GUI, do not store the pointer - it wont be threadsafe to use it | // create the GUI, do not store the pointer - it wont be threadsafe to use it | ||||
| @@ -110,6 +112,7 @@ public: | |||||
| void UpdateChannelHandler(); | void UpdateChannelHandler(); | ||||
| // is the plugin connected to an external device (oss/alsa/jack) | // is the plugin connected to an external device (oss/alsa/jack) | ||||
| bool IsTerminal() { return m_IsTerminal; } | bool IsTerminal() { return m_IsTerminal; } | ||||
| bool IsDead() { return m_IsDead; } | |||||
| ChannelHandler *GetChannelHandler() { return m_AudioCH; } | ChannelHandler *GetChannelHandler() { return m_AudioCH; } | ||||
| @@ -161,6 +164,7 @@ protected: | |||||
| void (*cb_Blocking)(void*o ,bool m); | void (*cb_Blocking)(void*o ,bool m); | ||||
| bool m_IsTerminal; | bool m_IsTerminal; | ||||
| bool m_IsDead; | |||||
| private: | private: | ||||
| @@ -115,13 +115,15 @@ void SynthModular::ClearUp() | |||||
| for(map<int,DeviceWin*>::iterator i=m_DeviceWinMap.begin(); | for(map<int,DeviceWin*>::iterator i=m_DeviceWinMap.begin(); | ||||
| i!=m_DeviceWinMap.end(); i++) | i!=m_DeviceWinMap.end(); i++) | ||||
| { | { | ||||
| if (i->second->m_Device->Kill()); | |||||
| i->second->m_DeviceGUI->Clear(); | |||||
| if (i->second->m_DeviceGUI->GetPluginWindow()) | if (i->second->m_DeviceGUI->GetPluginWindow()) | ||||
| { | { | ||||
| i->second->m_DeviceGUI->GetPluginWindow()->hide(); | i->second->m_DeviceGUI->GetPluginWindow()->hide(); | ||||
| //m_MainWindow->remove(i->second->m_DeviceGUI->GetPluginWindow()); | |||||
| } | } | ||||
| // deleted by Canvas::Remove()? seems to cause random crashes | |||||
| //delete i->second->m_DeviceGUI; | |||||
| //Delete Device | |||||
| delete i->second->m_Device; | delete i->second->m_Device; | ||||
| i->second->m_Device=NULL; | i->second->m_Device=NULL; | ||||
| } | } | ||||
| @@ -134,7 +136,6 @@ void SynthModular::ClearUp() | |||||
| } | } | ||||
| ////////////////////////////////////////////////////////// | ////////////////////////////////////////////////////////// | ||||
| void SynthModular::Update() | void SynthModular::Update() | ||||
| { | { | ||||
| m_CH.UpdateDataNow(); | m_CH.UpdateDataNow(); | ||||
| @@ -145,7 +146,16 @@ void SynthModular::Update() | |||||
| for(map<int,DeviceWin*>::iterator i=m_DeviceWinMap.begin(); | for(map<int,DeviceWin*>::iterator i=m_DeviceWinMap.begin(); | ||||
| i!=m_DeviceWinMap.end(); i++) | i!=m_DeviceWinMap.end(); i++) | ||||
| { | { | ||||
| if (i->second->m_Device) // if it's not a comment | |||||
| if (i->second->m_Device && i->second->m_Device->IsDead()) | |||||
| { | |||||
| //Delete Device | |||||
| delete i->second->m_Device; | |||||
| i->second->m_Device=NULL; | |||||
| //Erase Device from DeviceWinMap | |||||
| m_DeviceWinMap.erase(i); | |||||
| } | |||||
| else if (i->second->m_Device) // if it's not a comment | |||||
| { | { | ||||
| #ifdef DEBUG_PLUGINS | #ifdef DEBUG_PLUGINS | ||||
| cerr<<"Updating channelhandler of plugin "<<i->second->m_PluginID<<endl; | cerr<<"Updating channelhandler of plugin "<<i->second->m_PluginID<<endl; | ||||
| @@ -170,7 +180,7 @@ void SynthModular::Update() | |||||
| { | { | ||||
| // use the graphsort order to remove internal latency | // use the graphsort order to remove internal latency | ||||
| map<int,DeviceWin*>::iterator di=m_DeviceWinMap.find(*i); | map<int,DeviceWin*>::iterator di=m_DeviceWinMap.find(*i); | ||||
| if (di!=m_DeviceWinMap.end() && di->second->m_Device) | |||||
| if (di!=m_DeviceWinMap.end() && di->second->m_Device && (! di->second->m_Device->IsDead())) | |||||
| { | { | ||||
| #ifdef DEBUG_PLUGINS | #ifdef DEBUG_PLUGINS | ||||
| cerr<<"Executing plugin "<<di->second->m_PluginID<<endl; | cerr<<"Executing plugin "<<di->second->m_PluginID<<endl; | ||||
| @@ -193,15 +203,25 @@ void SynthModular::UpdatePluginGUIs() | |||||
| for (map<int,DeviceWin*>::iterator i=m_DeviceWinMap.begin(); | for (map<int,DeviceWin*>::iterator i=m_DeviceWinMap.begin(); | ||||
| i!=m_DeviceWinMap.end(); i++) | i!=m_DeviceWinMap.end(); i++) | ||||
| { | { | ||||
| if (i->second->m_DeviceGUI->GetPluginWindow()) | |||||
| if (i->second->m_DeviceGUI && i->second->m_DeviceGUI->GetPluginWindow()) | |||||
| { | { | ||||
| SpiralPluginGUI *GUI=(SpiralPluginGUI *)i->second->m_DeviceGUI->GetPluginWindow(); | SpiralPluginGUI *GUI=(SpiralPluginGUI *)i->second->m_DeviceGUI->GetPluginWindow(); | ||||
| GUI->Update(); | GUI->Update(); | ||||
| } | } | ||||
| if (i->second->m_DeviceGUI->Killed()) | |||||
| if (i->second->m_DeviceGUI && i->second->m_DeviceGUI->Killed()) | |||||
| { | { | ||||
| PauseAudio(); | |||||
| bool erase = true; | |||||
| //Stop processing of audio if any | |||||
| if (i->second->m_Device) | |||||
| { | |||||
| if (i->second->m_Device->Kill()); | |||||
| erase = false; | |||||
| } | |||||
| //Clear GUI Device | |||||
| i->second->m_DeviceGUI->Clear(); | |||||
| // Hide Device GUI FIRST | // Hide Device GUI FIRST | ||||
| if (i->second->m_DeviceGUI->GetPluginWindow()) | if (i->second->m_DeviceGUI->GetPluginWindow()) | ||||
| @@ -209,28 +229,16 @@ void SynthModular::UpdatePluginGUIs() | |||||
| i->second->m_DeviceGUI->GetPluginWindow()->hide(); | i->second->m_DeviceGUI->GetPluginWindow()->hide(); | ||||
| } | } | ||||
| // Clear and remove Device GUI from canvas | |||||
| i->second->m_DeviceGUI->Clear(); | |||||
| //Remove Device GUI from canvas | |||||
| m_Canvas->RemoveDevice(i->second->m_DeviceGUI); | m_Canvas->RemoveDevice(i->second->m_DeviceGUI); | ||||
| // Delete Device GUI - must delete here or sometimes plugin will randomly crash | |||||
| // SOMETIMES AT THIS POINT THE WHOLE THING JUST LOCKS UP | |||||
| // In the previous version of this code this next line was commented out | |||||
| // with the comment "deleted by Canvas::Remove()? seems to cause random crashes" | |||||
| //Delete Device GUI - must delete here or sometimes plugin will randomly crash | |||||
| delete i->second->m_DeviceGUI; | delete i->second->m_DeviceGUI; | ||||
| i->second->m_DeviceGUI = NULL; | |||||
| // Delete Device Sometimes deleting audio before GUI causes an odd crash, so do it afterword | |||||
| if (i->second->m_Device) | |||||
| { | |||||
| delete i->second->m_Device; | |||||
| i->second->m_Device=NULL; | |||||
| } | |||||
| // Erase Device from DeviceWinMap | |||||
| m_DeviceWinMap.erase(i); | |||||
| ResumeAudio(); | |||||
| break; | |||||
| //Erase from winmap if no audio to do it | |||||
| if (erase) | |||||
| m_DeviceWinMap.erase(i); | |||||
| } | } | ||||
| } | } | ||||
| @@ -912,49 +920,52 @@ ostream &operator<<(ostream &s, SynthModular &o) | |||||
| for(map<int,DeviceWin*>::iterator i=o.m_DeviceWinMap.begin(); | for(map<int,DeviceWin*>::iterator i=o.m_DeviceWinMap.begin(); | ||||
| i!=o.m_DeviceWinMap.end(); i++) | i!=o.m_DeviceWinMap.end(); i++) | ||||
| { | |||||
| s<<endl; | |||||
| s<<"Device "; | |||||
| s<<i->first<<" "; // save the id | |||||
| s<<"Plugin "; | |||||
| s<<i->second->m_PluginID<<endl; | |||||
| s<<i->second->m_DeviceGUI->x()<<" "; | |||||
| s<<i->second->m_DeviceGUI->y()<<" "; | |||||
| s<<i->second->m_DeviceGUI->GetName().size()<<" "; | |||||
| s<<i->second->m_DeviceGUI->GetName()<<" "; | |||||
| if (i->second->m_DeviceGUI->GetPluginWindow()) | |||||
| { | |||||
| s<<i->second->m_DeviceGUI->GetPluginWindow()->visible()<<" "; | |||||
| s<<i->second->m_DeviceGUI->GetPluginWindow()->x()<<" "; | |||||
| s<<i->second->m_DeviceGUI->GetPluginWindow()->y()<<" "; | |||||
| } | |||||
| else | |||||
| { | |||||
| s<<0<<" "<<0<<" "<<0; | |||||
| } | |||||
| s<<endl; | |||||
| if (i->second->m_PluginID==COMMENT_ID) | |||||
| { | |||||
| // save the comment gui | |||||
| ((Fl_CommentGUI*)(i->second->m_DeviceGUI))->StreamOut(s); | |||||
| } | |||||
| else | |||||
| { | |||||
| // save the plugin | |||||
| i->second->m_Device->StreamOut(s); | |||||
| } | |||||
| s<<endl; | |||||
| // save external files | |||||
| if (i->second->m_Device && i->second->m_Device->SaveExternalFiles(o.m_FilePath+"_files/")) | |||||
| { | |||||
| if (i->second->m_DeviceGUI && i->second->m_Device) | |||||
| { | { | ||||
| ExternalDirUsed=true; | |||||
| s<<endl; | |||||
| s<<"Device "; | |||||
| s<<i->first<<" "; // save the id | |||||
| s<<"Plugin "; | |||||
| s<<i->second->m_PluginID<<endl; | |||||
| s<<i->second->m_DeviceGUI->x()<<" "; | |||||
| s<<i->second->m_DeviceGUI->y()<<" "; | |||||
| s<<i->second->m_DeviceGUI->GetName().size()<<" "; | |||||
| s<<i->second->m_DeviceGUI->GetName()<<" "; | |||||
| if (i->second->m_DeviceGUI->GetPluginWindow()) | |||||
| { | |||||
| s<<i->second->m_DeviceGUI->GetPluginWindow()->visible()<<" "; | |||||
| s<<i->second->m_DeviceGUI->GetPluginWindow()->x()<<" "; | |||||
| s<<i->second->m_DeviceGUI->GetPluginWindow()->y()<<" "; | |||||
| } | |||||
| else | |||||
| { | |||||
| s<<0<<" "<<0<<" "<<0; | |||||
| } | |||||
| s<<endl; | |||||
| if (i->second->m_PluginID==COMMENT_ID) | |||||
| { | |||||
| // save the comment gui | |||||
| ((Fl_CommentGUI*)(i->second->m_DeviceGUI))->StreamOut(s); | |||||
| } | |||||
| else | |||||
| { | |||||
| // save the plugin | |||||
| i->second->m_Device->StreamOut(s); | |||||
| } | |||||
| s<<endl; | |||||
| // save external files | |||||
| if (i->second->m_Device && i->second->m_Device->SaveExternalFiles(o.m_FilePath+"_files/")) | |||||
| { | |||||
| ExternalDirUsed=true; | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| s<<endl<<*o.m_Canvas<<endl; | s<<endl<<*o.m_Canvas<<endl; | ||||
| // remove it if it wasn't used | // remove it if it wasn't used | ||||