#include #include #include #include #include #include #include #include #include #include #include "cmGlobal.h" #include "cmFloatTypes.h" #include "cmRpt.h" #include "cmErr.h" #include "cmCtx.h" #include "cmMem.h" #include "cmMallocDebug.h" #include "cmThread.h" #include "cmJson.h" #include "cmTime.h" #include "cmAudioPort.h" #include "cmMidi.h" #include "cmMidiPort.h" #include "cmUdpPort.h" #include "cmRtSysMsg.h" #include "cmRtNet.h" #include "cmRtSys.h" #include "cmDevCfg.h" #include "Fl_DevCfgGroup.h" #define DEVCFG_NONE_STR "None" Fl_DevCfgGroup::Fl_DevCfgGroup(cmDevCfgH_t dcH, int xx, int yy, int ww, int hh, const char* label ) : Fl_Group(xx,yy,ww,hh,label), _dcH(dcH) { typedef enum { kInvalidTId, kLabelTId, kBtnTId, kMenuBtnTId, kChkBtnTId, kInputTId, kValueTId } type_t; typedef struct { unsigned id; type_t tid; int x; int y; int w; int h; int flags; const char* label; } recd_t; const int r = -1; // current row const int rn = -2; // next row const int cn = -1; // next column int r00 = 50; int c0 = 2; int c3 = 400; int c4 = 650; int lw = 250; // device/port/preset label widths int vw = 75; // value widths int iw = 125; int dw = 400; int w = 100; int h = 25; int fl = 0; int fl1 = FL_WHEN_CHANGED; recd_t a[] = { { kLocLabelCId, kLabelTId, c0,r00, w, h, fl, "Location:" }, { kLocMenuCId, kMenuBtnTId, c0, rn, lw, h, fl, NULL }, { kLocDeleteBtnCId, kBtnTId, cn, r, w, h, fl, "Delete" }, { kLocStringCId, kInputTId, c0, rn, lw, h, fl1, NULL }, { kLocStoreBtnCId, kBtnTId, cn, r, w, h, fl, "Create" }, { kMidiLabelCId, kLabelTId, c0, rn, w, h, fl, "MIDI:" }, { kMidiCfgMenuCId, kMenuBtnTId, c0, rn, lw, h, fl, NULL }, { kMidiDeleteBtnCId, kBtnTId, cn, r, w, h, fl, "Delete" }, { kMidiCfgDescCId, kLabelTId, c0, rn, dw, h, fl, NULL }, { kMidiCfgStringCId, kInputTId, c0, rn, lw, h, fl1, NULL }, { kMidiApplyBtnCId, kBtnTId, cn, r, w, h, fl, "Store" }, { kMidiDevMenuCId, kMenuBtnTId, c0, rn, lw, h, fl1, NULL }, { kMidiDevLabelCId, kLabelTId, cn, r, w, h, fl, "MIDI Device"}, { kMidiPortMenuCId, kMenuBtnTId, c0, rn, lw, h, fl1, NULL }, { kMidiPortLabelCId, kLabelTId, cn, r, w, h, fl, "MIDI Port"}, { kMidiInputCheckCId, kChkBtnTId, c0, rn, w, h, fl1, "Input"}, { kAudioLabelCId, kLabelTId, c3,r00, w, h, fl, "Audio:" }, { kAudioCfgMenuCId, kMenuBtnTId, c3, rn, lw, h, fl, NULL }, { kAudioDeleteBtnCId, kBtnTId, cn, r, w, h, fl, "Delete" }, { kAudioCfgDescCId, kLabelTId, c3, rn, dw, h*2,fl, NULL }, { kAudioCfgStringCId, kInputTId, c3, rn, lw, h, fl1, NULL }, { kAudioApplyBtnCId, kBtnTId, cn, r, w, h, fl, "Store" }, { kAudioInDevMenuCId, kMenuBtnTId, c3, rn, lw, h, fl1, NULL }, { kAudioInDevLabelCId, kLabelTId, cn, r, w, h, fl, "Audio Input"}, { kAudioOutDevMenuCId, kMenuBtnTId, c3, rn, lw, h, fl1, NULL }, { kAudioOutDevLabelCId, kLabelTId, cn, r, w, h, fl1, "Audio Output"}, { kAudioMsgQueSizeValCId,kValueTId, c3, rn, vw, h, fl1, "Msg Queue Bytes" }, { kAudioDevFpCValCId, kValueTId, c4, r, vw, h, fl1, "Audio Frames" }, { kAudioDspFpCValCId, kValueTId, c3, rn, vw, h, fl1, "DSP Frames" }, { kAudioBufCntValCId, kValueTId, c4, r, vw, h, fl1, "Buffer Count" }, { kAudioSrateMenuCId, kMenuBtnTId, c3, rn, w, h, fl1, "Rate" }, { kAudioSyncInCheckCId, kChkBtnTId, c4, r, w, h, fl1, "Sync to Input"}, { kAudioNetNodeStringCId,kInputTId, c3, rn, vw, h, fl1, "Net Node Label"}, { kAudioBcastAddrStringCId,kInputTId, c4, r, iw, h, fl1, "Bcast Address"}, { kAudioIpAddrStringCId, kInputTId, c3, rn, iw, h, fl1, "IP Address"}, { kAudioIpPortValCId, kValueTId, c4, r, vw, h, fl1, "IP Port"}, { kAudioActiveCheckCId, kChkBtnTId, c3, rn, w, h, fl1, "Active"}, /* { kNetLabelCId, kLabelTId, c3, rn, w, h, fl, "Remote Network Nodes:" }, { kNetCfgMenuCId, kMenuBtnTId, c3, rn, lw, h, fl, NULL }, { kNetDeleteBtnCId, kBtnTId, cn, r, w, h, fl, "Delete" }, { kNetCfgDescCId, kLabelTId, c3, rn, dw, h, fl, NULL }, { kNetCfgStringCId, kInputTId, c3, rn, lw, h, fl, NULL }, { kNetApplyBtnCId, kBtnTId, cn, r, w, h, fl, "Store" }, { kNetSockAddrStringCId, kInputTId, c3, rn, w, h, fl1, "IP Address" }, { kNetPortNumbValCId, kValueTId, c4, r, vw, h, fl1, "IP Port" }, { kNetLocalCheckCId, kChkBtnTId, c3, rn, w, h, fl1, "Local"}, { kNetActiveCheckCId, kChkBtnTId, cn, r, vw, h, fl1, "Active"}, */ { kInvalidCId, kInvalidTId, 0, 0, 0, 0, 0, NULL } }; const recd_t* d = a; int y = r00; int x = c0; int ny = 0; int nx = 0; for(; d->id != kInvalidCId; ++d) { Fl_Widget* wp = NULL; ctl_t* c = new ctl_t; c->id = d->id; c->p = this; switch( d->y ) { case r: break; case rn: y = ny; break; default: y = d->y; break; } switch( d->x ) { case cn: x = nx; break; default: x = d->x; break; } switch( d->tid ) { case kLabelTId: wp = c->u.box = new Fl_Box(x,y,d->w,d->h,d->label); wp->align(FL_ALIGN_LEFT | FL_ALIGN_INSIDE); break; case kBtnTId: wp = c->u.btn = new Fl_Button(x,y,d->w,d->h,d->label); break; case kMenuBtnTId: wp = c->u.mbt = new Fl_Menu_Button(x,y,d->w,d->h,d->label); break; case kChkBtnTId: wp = c->u.chk = new Fl_Check_Button(x,y,d->w,d->h,d->label); break; case kInputTId: wp = c->u.inp = new Fl_Input(x,y,d->w,d->h,d->label); wp->align(FL_ALIGN_RIGHT); break; case kValueTId: wp = c->u.val = new Fl_Value_Input(x,y,d->w,d->h,d->label); wp->align(FL_ALIGN_RIGHT); break; default: break; } if( wp != NULL ) { if( cmIsFlag(d->flags,FL_WHEN_CHANGED) ) wp->when(FL_WHEN_CHANGED); ny = y + d->h + 2; nx = x + d->w + 2; wp->callback(Fl_DevCfgGroup::_s_ctl_cb,c); _ctlV.push_back(c); } } //_loadMenuButtons(); _syncLoc(); } Fl_DevCfgGroup::~Fl_DevCfgGroup() { unsigned i; for(i=0; i<_ctlV.size(); ++i) delete _ctlV[i]; } void Fl_DevCfgGroup::onEnableAudio( bool enableFl ) { if( enableFl ) { deactivate(); } else { activate(); parent()->redraw(); } } bool Fl_DevCfgGroup::_loadLocBtn() { ctl_t* c; if((c = _idToCtl(kLocMenuCId)) == NULL ) return false; int val = c->u.mbt->value(); c->u.mbt->clear(); unsigned i; for(i=0; iu.mbt->add(cmStringNullGuard(cmDevCfgLocLabel(_dcH,i)),0,_s_ctl_cb,c); _restoreMenuValue(kLocMenuCId, val ); if((c = _idToCtl(kLocStoreBtnCId)) != NULL) c->u.btn->deactivate(); return true; } void Fl_DevCfgGroup::_recallLoc() { ctl_t* c; const char* s; if((s = _getMenuCtl(kLocMenuCId)) == NULL ) goto errLabel; if( cmDevCfgLocRecall(_dcH,s) != kOkDcRC ) goto errLabel; if((c = _idToCtl(kLocStringCId)) == NULL ) goto errLabel; c->u.inp->copy_label(s); errLabel: _syncLoc(); } void Fl_DevCfgGroup::_storeLoc() { ctl_t* c; const char* s; if((c = _idToCtl(kLocStringCId)) == NULL ) goto errLabel; if((s = c->u.inp->value()) == NULL ) goto errLabel; if( cmDevCfgLocStore(_dcH,s) != kOkDcRC ) goto errLabel; errLabel: _syncLoc(); } void Fl_DevCfgGroup::_deleteLoc() { const char* s; if((s = _getMenuCtl(kLocMenuCId)) == NULL ) goto errLabel; if( cmDevCfgLocDelete(_dcH,s) != kOkDcRC ) goto errLabel; errLabel: _syncLoc(); } // load MIDI device menu from the MIDI driver void Fl_DevCfgGroup::_loadMidiDevBtn() { unsigned j; ctl_t* c; if((c = _idToCtl(kMidiDevMenuCId)) == NULL ) return; int val = c->u.mbt->value(); c->u.mbt->clear(); for(j=0; ju.mbt->add(cmStringNullGuard(cmMpDeviceName(j)),0,_s_ctl_cb,c); } _restoreMenuValue(kMidiDevMenuCId, val ); } // Load the MIDI port menu from the MIDI driver accoring // to the MIDI device seleted in the MIDI device menu void Fl_DevCfgGroup::_loadMidiPortBtn() { ctl_t* c; if((c = _idToCtl(kMidiDevMenuCId)) == NULL ) return; int devIdx = c->u.mbt->value(); if((c = _idToCtl(kMidiInputCheckCId)) == NULL ) return; unsigned flags = c->u.chk->value() ? kInMpFl : kOutMpFl; unsigned n = devIdx<0 ? 0 : cmMpDevicePortCount(devIdx,flags); if((c = _idToCtl(kMidiPortMenuCId)) == NULL ) return; c->u.mbt->clear(); int val = c->u.mbt->value(); for(unsigned j=0; ju.mbt->add(cmStringNullGuard(cmMpDevicePortName(devIdx,flags,j)),0,_s_ctl_cb,c); _restoreMenuValue(kMidiPortMenuCId, val ); } // Load the audio device menu from the audio port driver. void Fl_DevCfgGroup::_loadAudioDevBtn( unsigned id, unsigned devIdx ) { ctl_t* c; unsigned i; if((c = _idToCtl(id)) == NULL ) return; unsigned n = cmApDeviceCount(); bool inputFl = id == kAudioInDevMenuCId; int val = c->u.mbt->value(); c->u.mbt->clear(); for(i=0; i 0 ) { const cmChar_t* str; if((str = cmApDeviceLabel(i)) != NULL ) { bool activeFl = cmDevCfgAudioIsDeviceActive(_dcH, str, inputFl ); if( devIdx == i ) activeFl = false; c->u.mbt->add(str,0,NULL,NULL, activeFl ? FL_MENU_INACTIVE : 0); } } c->u.mbt->add(DEVCFG_NONE_STR,0,_s_ctl_cb,c); _restoreMenuValue(id, val ); if( devIdx == cmInvalidIdx ) _setMenuBtnWithString(id,DEVCFG_NONE_STR); } // Load the sample rate menu with constant values. void Fl_DevCfgGroup::_loadAudioSrateBtn() { ctl_t* c; if((c = _idToCtl(kAudioSrateMenuCId)) == NULL ) return; int val = c->u.mbt->value(); char* p = 0; c->u.mbt->add("96000",0,NULL,p+96000); c->u.mbt->add("48000",0,NULL,p+48000); c->u.mbt->add("44100",0,NULL,p+44100); c->u.mbt->add("22050",0,NULL,p+22050); if( val < 0 || val >= c->u.mbt->size() ) _setSrate(kAsDfltSrate); else if( c->u.mbt->size() > 0 ) { c->u.mbt->value(val); c->u.mbt->copy_label( c->u.mbt->mvalue()->label() ); } } // Load a cfg menu with the labels of the cfg records from cmDevCfg. // (but don't update the label yet). void Fl_DevCfgGroup::_loadCfgMenu(cmTypeDcmId_t typeId, unsigned menuCtlId, unsigned deleteCtlId ) { ctl_t* c; if((c = _idToCtl(menuCtlId)) == NULL ) return; // get the current value of the menu int val = c->u.mbt->value(); // empty the menu c->u.mbt->clear(); // get the count of cfg recds unsigned n = cmDevCfgCount(_dcH,typeId); const cmChar_t* label; // reload the menu from cmDevCfg for(unsigned i=0; iu.mbt->add(label,0,_s_ctl_cb,c); // get the count of menu items int sz = c->u.mbt->size(); // if the original value is no longer valid then set the value to // the most likely valid value - zero. if( val < 0 || val >= sz ) val = 0; // if the menu is not empty then set the value if( sz > 0 ) c->u.mbt->value(val); // update the 'delete' btn if((c = _idToCtl(deleteCtlId)) != NULL ) { // if the menu is empty deactivate the delete btn if( sz > 0 ) c->u.btn->activate(); else c->u.btn->deactivate(); } } // Load the cfg label edit string, description and type // specific fields from the cmDevCfg based on the currently // selected cfg menu item. void Fl_DevCfgGroup::_recallCfg(cmTypeDcmId_t typeId, unsigned menuCtlId, unsigned strCtlId, unsigned descCtlId, unsigned storeCtlId ) { const Fl_Menu_Item* mip; ctl_t* c; // get the cfg menu if((c = _idToCtl(menuCtlId)) == NULL ) return; // get the current value of the cfg menu int menuIdx = c->u.mbt->value(); if( menuIdx == -1 ) return; // get the current menu item from the cfg menu if((mip = c->u.mbt->mvalue()) == NULL) return; // update the cfg menu label c->u.mbt->copy_label( mip->label() ); // set the cfg string text if((c = _idToCtl(strCtlId)) != NULL ) c->u.inp->value( mip->label() ); // set the desc string if((c = _idToCtl(descCtlId)) != NULL ) { const cmChar_t* s = cmDevCfgDesc(_dcH, typeId, menuIdx ); c->u.box->copy_label( s==NULL ? "" : s ); } // disable to store btn if((c = _idToCtl(storeCtlId)) != NULL ) c->u.btn->deactivate(); switch( typeId ) { case kMidiDcmTId: { const cmDcmMidi_t* r = cmDevCfgMidiCfg(_dcH,menuIdx); // set the midi device from the cfg recd _setMenuBtnWithString(kMidiDevMenuCId,r==NULL ? "" : r->devLabelStr); _setCheckCtl( kMidiInputCheckCId, r==NULL ? 0 : r->inputFl ); // sync the midi port menu to the device _loadMidiPortBtn(); } break; case kAudioDcmTId: { const cmDcmAudio_t* r = cmDevCfgAudioCfg(_dcH,menuIdx); _setMenuBtnWithString(kAudioInDevMenuCId, r==NULL ? "" : (r->inDevLabelStr==NULL ? DEVCFG_NONE_STR : r->inDevLabelStr)); _setMenuBtnWithString(kAudioOutDevMenuCId,r==NULL ? "" : (r->outDevLabelStr==NULL ? DEVCFG_NONE_STR : r->outDevLabelStr)); _setValueCtl(kAudioMsgQueSizeValCId, r==NULL ? 0 : r->rtSysArgs.msgQueueByteCnt); _setValueCtl(kAudioDevFpCValCId, r==NULL ? 0 : r->rtSysArgs.devFramesPerCycle); _setValueCtl(kAudioDspFpCValCId, r==NULL ? 0 : r->rtSysArgs.dspFramesPerCycle); _setValueCtl(kAudioBufCntValCId, r==NULL ? 0 : r->rtSysArgs.audioBufCnt); _setCheckCtl(kAudioSyncInCheckCId, r==NULL ? 0 : r->rtSysArgs.syncInputFl); _setInputCtl(kAudioNetNodeStringCId, r==NULL ? "" : r->netNodeLabel); _setInputCtl(kAudioBcastAddrStringCId, r==NULL ? "" : r->bcastAddr); _setInputCtl(kAudioIpAddrStringCId, r==NULL ? "" : r->ipAddr); _setValueCtl(kAudioIpPortValCId, r==NULL ? 0 : r->ipPort); _setCheckCtl(kAudioActiveCheckCId, r==NULL ? 0 : r->activeFl); _setSrate( r==NULL ? kAsDfltSrate : r->rtSysArgs.srate); //cmDevCfgAudioSetDefaultCfgIndex(_dcH,menuIdx); _loadAudioDevBtn(kAudioInDevMenuCId, r->rtSysArgs.inDevIdx ); _loadAudioDevBtn(kAudioOutDevMenuCId, r->rtSysArgs.outDevIdx ); } break; /* case kNetDcmTId: { const cmDcmNet_t* r = cmDevCfgNetCfg(_dcH,menuIdx); _setInputCtl(kNetSockAddrStringCId, r==NULL ? "" : r->sockAddr); _setValueCtl(kNetPortNumbValCId, r==NULL ? 0 : r->portNumber); _setCheckCtl(kNetActiveCheckCId, r==NULL ? 0 : r->activeFl); } break; */ default: assert(0); break; } } void Fl_DevCfgGroup::_syncLoc() { ctl_t* c; unsigned idx; _loadLocBtn(); if((idx = cmDevCfgLocCurIndex(_dcH)) == cmInvalidIdx ) return; if((c = _idToCtl(kLocMenuCId)) == NULL ) return; assert((int)idx < c->u.mbt->size() ); if( (int)idx >= c->u.mbt->size() ) return; c->u.mbt->value(idx); _setMenuBtnLabel(kLocMenuCId,kLocStringCId); // Load the menu's based on the currently // available hardware. _loadMidiDevBtn(); _loadMidiPortBtn(); _loadAudioDevBtn(kAudioInDevMenuCId,cmInvalidId); _loadAudioDevBtn(kAudioOutDevMenuCId,cmInvalidId); _loadAudioSrateBtn(); // Set the default values for some fields. These values will only be // used if there is no availabe cmDevCfg data. _idToCtl(kAudioMsgQueSizeValCId)->u.val->value(kAsDfltMsgQueueByteCnt); _idToCtl(kAudioDevFpCValCId)->u.val->value(kAsDfltDevFramesPerCycle); _idToCtl(kAudioDspFpCValCId)->u.val->value(kAsDfltDspFramesPerCycle); _idToCtl(kAudioBufCntValCId)->u.val->value(kAsDfltBufCnt); _idToCtl(kAudioSyncInCheckCId)->u.chk->value(kAsDfltSyncToInputFl); // set the bounds for the IP port value _idToCtl(kAudioIpPortValCId)->u.val->bounds(0,65535); _idToCtl(kAudioIpPortValCId)->u.val->step(1); // Load the MIDI cfg information from cmDevCfg. _loadCfgMenu(kMidiDcmTId, kMidiCfgMenuCId, kMidiDeleteBtnCId ); _recallCfg(kMidiDcmTId, kMidiCfgMenuCId, kMidiCfgStringCId, kMidiCfgDescCId, kMidiApplyBtnCId ); // Load the Audio cfg information from cmDevCfg. _loadCfgMenu(kAudioDcmTId, kAudioCfgMenuCId, kAudioDeleteBtnCId ); // Display the default audio configuration // if((c = _idToCtl(kAudioCfgMenuCId)) != NULL ) // if((idx = cmDevCfgAudioGetDefaultCfgIndex(_dcH)) != cmInvalidIdx ) // if( c->u.mbt->size() < (int)idx ) // c->u.mbt->value(idx); _recallCfg(kAudioDcmTId, kAudioCfgMenuCId, kAudioCfgStringCId, kAudioCfgDescCId, kAudioApplyBtnCId ); // Load the network cfg information from cmDevCfg. //_loadCfgMenu(kNetDcmTId, kNetCfgMenuCId, kNetDeleteBtnCId ); //_recallCfg(kNetDcmTId, kNetCfgMenuCId, kNetCfgStringCId, kNetCfgDescCId, kNetApplyBtnCId ); } // Called when the MIDI 'Store' cfg button is pressed. // Creates or edits a MIDI cfg recd in cmDevCfg. void Fl_DevCfgGroup::_createMidiCfg() { const cmChar_t* cfgStr = _getInputCtl(kMidiCfgStringCId); const cmChar_t* devStr = _getMenuCtl(kMidiDevMenuCId); const cmChar_t* portStr = _getMenuCtl(kMidiPortMenuCId); bool inputFl = _getCheckCtl(kMidiInputCheckCId); // create or edit a MIDI cfg recd if( cmDevCfgNameMidiPort(_dcH,cfgStr,devStr,portStr,inputFl) == kOkDcRC ) { // a MIDI cfg recd may have been created so reload the MIDI cfg menu btn _loadCfgMenu(kMidiDcmTId,kMidiCfgMenuCId,kMidiDeleteBtnCId); // set the MIDI cfg menu btn to display the label of the cfg just edited or creaed _setMenuBtnWithString(kMidiCfgMenuCId,cfgStr); // update the other MIDI fields based on the current cfg menu value _recallCfg(kMidiDcmTId, kMidiCfgMenuCId, kMidiCfgStringCId, kMidiCfgDescCId, kMidiApplyBtnCId ); } } // Called when the Audio 'Store' button is pressed. // Creates or edits an audio cfg recd in the cmDevCfg. void Fl_DevCfgGroup::_createAudioCfg() { const cmChar_t* cfgStr = _getInputCtl(kAudioCfgStringCId); const cmChar_t* inDevStr = _getMenuCtl(kAudioInDevMenuCId); const cmChar_t* outDevStr = _getMenuCtl(kAudioOutDevMenuCId); bool syncInFl = _getCheckCtl(kAudioSyncInCheckCId); unsigned msgQueCnt = _getValueCtl(kAudioMsgQueSizeValCId); unsigned devFpC = _getValueCtl(kAudioDevFpCValCId); unsigned dspFpC = _getValueCtl(kAudioDspFpCValCId); unsigned bufCnt = _getValueCtl(kAudioBufCntValCId); const cmChar_t* nodeStr = _getInputCtl(kAudioNetNodeStringCId); const cmChar_t* bcastAddr = _getInputCtl(kAudioBcastAddrStringCId); const cmChar_t* ipAddr = _getInputCtl(kAudioIpAddrStringCId); cmUdpPort_t ipPort = _getValueCtl(kAudioIpPortValCId); bool activeFl = _getCheckCtl(kAudioActiveCheckCId); double srate = _getSrate(); if( strcmp(inDevStr,DEVCFG_NONE_STR)==0 ) inDevStr = NULL; if( strcmp(outDevStr,DEVCFG_NONE_STR)==0 ) outDevStr = NULL; // create or edit a audio cfg recd if( cmDevCfgNameAudioPort(_dcH,cfgStr,inDevStr,outDevStr,syncInFl,msgQueCnt,devFpC,dspFpC,bufCnt,srate,nodeStr,bcastAddr,ipAddr,ipPort,activeFl) == kOkDcRC ) { // a new cfg recd may have been created so reload audio cfg menu _loadCfgMenu(kAudioDcmTId,kAudioCfgMenuCId,kAudioDeleteBtnCId); // set the cfg menu to display the label of the cfg just edited or created _setMenuBtnWithString(kAudioCfgMenuCId,cfgStr); // update the other audio fields based on the current cfg menu value _recallCfg(kAudioDcmTId, kAudioCfgMenuCId, kAudioCfgStringCId, kAudioCfgDescCId, kAudioApplyBtnCId ); } } /* // Called when the Net 'Store' button is pressed. // Creates or edits a net cfg recd in the cmDevCfg. void Fl_DevCfgGroup::_createNetCfg() { const cmChar_t* cfgStr = _idToCtl(kNetCfgStringCId)->u.inp->value(); const cmChar_t* addrStr = _idToCtl(kNetSockAddrStringCId)->u.inp->value(); unsigned portNum = _idToCtl(kNetPortNumbValCId)->u.val->value(); bool activeFl= _idToCtl(kNetActiveCheckCId)->u.chk->value(); // create or edit a NET cfg recd if( cmDevCfgNameNetPort(_dcH,cfgStr,addrStr,portNum,activeFl) == kOkDcRC ) { // a NET cfg recd may have been created so reload the NET cfg menu btn _loadCfgMenu(kNetDcmTId,kNetCfgMenuCId,kNetDeleteBtnCId); // set the NET cfg menu btn to display the label of the cfg just edited or creaed _setMenuBtnWithString(kNetCfgMenuCId,cfgStr); // update the other net fields based on the current cfg menu value _recallCfg(kNetDcmTId, kNetCfgMenuCId, kNetCfgStringCId, kNetCfgDescCId, kNetApplyBtnCId ); } } */ void Fl_DevCfgGroup::_deleteCfg( cmTypeDcmId_t typeId, unsigned menuCtlId, unsigned inpCtlId, unsigned descCtlId, unsigned storeCtlId, unsigned deleteCtlId ) { ctl_t* c; const cmChar_t* s; int idx; if((s = _getMenuCtl(menuCtlId)) == NULL ) goto errLabel; if(cmDevCfgDeleteCfg(_dcH, typeId, s ) != kOkDcRC ) goto errLabel; if(( c = _idToCtl(menuCtlId)) == NULL ) goto errLabel; if((idx = c->u.mbt->find_index(s)) < 0 ) goto errLabel; c->u.mbt->remove(idx); if( c->u.mbt->size() > 0 ) c->u.mbt->value(0); _loadCfgMenu(typeId,menuCtlId,deleteCtlId); _recallCfg(typeId,menuCtlId,inpCtlId,descCtlId,storeCtlId); errLabel: return; } void Fl_DevCfgGroup::_restoreMenuValue( unsigned menuCtlId, int val, int dfltVal ) { ctl_t* c; if((c = _idToCtl(menuCtlId)) == NULL ) return; if( val < 0 || val >= c->u.mbt->size() ) val = dfltVal; if( c->u.mbt->size() > 0 ) c->u.mbt->value(val); else c->u.mbt->value(-1); _setMenuBtnLabel(menuCtlId); } void Fl_DevCfgGroup::_setMenuBtnLabel( unsigned menuCtlId, unsigned inpCtlId ) { ctl_t* c; const Fl_Menu_Item* mip; const char* s; if((c = _idToCtl(menuCtlId)) == NULL ) goto errLabel; int v; if((v = c->u.mbt->value()) == -1 ) goto errLabel; if((mip = c->u.mbt->mvalue()) == NULL ) goto errLabel; if((s = mip->label()) == NULL || strlen(s)==0) s = ""; // the menu is empty or the label is invalid c->u.mbt->copy_label(s); if( inpCtlId != cmInvalidId ) { if((c = _idToCtl(inpCtlId)) == NULL ) goto errLabel; c->u.inp->copy_label(s); } errLabel: return; } void Fl_DevCfgGroup::_setMenuBtnWithString( unsigned menuCtlId, const char* string ) { ctl_t* c; int idx; if((c = _idToCtl(menuCtlId)) == NULL ) goto errLabel; if((idx = c->u.mbt->find_index(string)) < 0 ) goto errLabel; c->u.mbt->value(idx); c->u.mbt->copy_label(string); errLabel: return; } void Fl_DevCfgGroup::_setCheckCtl( unsigned ctlId, int val ) { ctl_t* c; if((c = _idToCtl(ctlId)) == NULL ) return; c->u.chk->value(val); } void Fl_DevCfgGroup::_setValueCtl( unsigned ctlId, double val ) { ctl_t* c; if((c = _idToCtl(ctlId)) == NULL ) return; c->u.val->value(val); } void Fl_DevCfgGroup::_setInputCtl( unsigned ctlId, const cmChar_t* val ) { ctl_t* c; if((c = _idToCtl(ctlId)) == NULL ) return; c->u.inp->value(val); } const cmChar_t* Fl_DevCfgGroup::_getMenuCtl( unsigned ctlId ) { ctl_t* c; const Fl_Menu_Item* mip; if((c = _idToCtl(ctlId)) == NULL) goto errLabel; if( c->u.mbt->value() == -1 ) goto errLabel; if((mip = c->u.mbt->mvalue()) == NULL) goto errLabel; if( mip->label() == NULL ) goto errLabel; return mip->label(); errLabel: return ""; } const cmChar_t* Fl_DevCfgGroup::_getInputCtl( unsigned ctlId ) { ctl_t* c; if((c = _idToCtl(ctlId)) == NULL) goto errLabel; if( c->u.inp->value() == NULL ) goto errLabel; return c->u.inp->value(); errLabel: return ""; } double Fl_DevCfgGroup::_getValueCtl( unsigned ctlId ) { ctl_t* c; if((c = _idToCtl(ctlId)) == NULL) return 0; return c->u.val->value(); } bool Fl_DevCfgGroup::_getCheckCtl( unsigned ctlId ) { ctl_t* c; if((c = _idToCtl(ctlId)) == NULL) return 0; return c->u.chk->value(); } double Fl_DevCfgGroup::_getSrate() { ctl_t* c; const Fl_Menu_Item* mip; if((c = _idToCtl(kAudioSrateMenuCId)) == NULL ) return kAsDfltSrate; assert( c->u.mbt->value() != -1); if((mip = c->u.mbt->mvalue()) == NULL ) return kAsDfltSrate; return (char*)mip->user_data() - (char*)NULL; } void Fl_DevCfgGroup::_setSrate( double srate ) { ctl_t* c; if((c = _idToCtl(kAudioSrateMenuCId)) == NULL ) return; int i; for(i=0; iu.mbt->size(); ++i) { const Fl_Menu_Item* mip = &c->u.mbt->menu()[i]; if( mip != NULL && ((char*)mip->user_data() - (char*)NULL) == srate) { c->u.mbt->value(i); c->u.mbt->copy_label( mip->label() ); return; } } } void Fl_DevCfgGroup::_enableStoreBtn( unsigned ctlId ) { ctl_t* c; if((c = _idToCtl(ctlId)) == NULL ) return; c->u.btn->activate(); } Fl_DevCfgGroup::ctl_t* Fl_DevCfgGroup::_idToCtl( unsigned id ) { unsigned i = 0; for(i=0; i<_ctlV.size(); ++i) if( _ctlV[i]->id == id ) return _ctlV[i]; assert(0); return NULL; } void Fl_DevCfgGroup::_s_ctl_cb( Fl_Widget* w, void* arg ) { ctl_t* c = (ctl_t*)arg; switch( c->id ) { // ------------------------------------------------------------ // Location case kLocLabelCId: break; case kLocMenuCId: c->p->_recallLoc(); break; case kLocStoreBtnCId: c->p->_storeLoc(); break; case kLocStringCId: c->p->_enableStoreBtn(kLocStoreBtnCId); break; case kLocDeleteBtnCId: c->p->_deleteLoc(); break; // ------------------------------------------------------------ // MIDI case kMidiCfgMenuCId: c->p->_recallCfg(kMidiDcmTId, kMidiCfgMenuCId, kMidiCfgStringCId, kMidiCfgDescCId, kMidiApplyBtnCId ); break; case kMidiDeleteBtnCId: c->p->_deleteCfg(kMidiDcmTId,kMidiCfgMenuCId,kMidiCfgStringCId,kMidiCfgDescCId,kMidiApplyBtnCId,kMidiDeleteBtnCId); break; case kMidiCfgStringCId: c->p->_enableStoreBtn(kMidiApplyBtnCId); break; case kMidiApplyBtnCId: c->p->_createMidiCfg(); c->p->_recallCfg(kMidiDcmTId, kMidiCfgMenuCId, kMidiCfgStringCId, kMidiCfgDescCId, kMidiApplyBtnCId ); break; case kMidiDevMenuCId: c->p->_setMenuBtnLabel(c->id); c->p->_loadMidiPortBtn(); c->p->_enableStoreBtn(kMidiApplyBtnCId); break; case kMidiPortMenuCId: c->p->_setMenuBtnLabel(c->id); c->p->_enableStoreBtn(kMidiApplyBtnCId); break; case kMidiInputCheckCId: c->p->_enableStoreBtn(kMidiApplyBtnCId); break; // ------------------------------------------------------------ // Audio case kAudioLabelCId: break; case kAudioCfgMenuCId: c->p->_recallCfg(kAudioDcmTId, kAudioCfgMenuCId, kAudioCfgStringCId, kAudioCfgDescCId, kAudioApplyBtnCId ); break; case kAudioDeleteBtnCId: c->p->_deleteCfg(kAudioDcmTId,kAudioCfgMenuCId,kAudioCfgStringCId,kAudioCfgDescCId, kAudioApplyBtnCId, kAudioDeleteBtnCId); break; case kAudioCfgStringCId: c->p->_enableStoreBtn(kAudioApplyBtnCId); break; case kAudioApplyBtnCId: c->p->_createAudioCfg(); c->p->_recallCfg(kAudioDcmTId, kAudioCfgMenuCId, kAudioCfgStringCId, kAudioCfgDescCId, kAudioApplyBtnCId ); break; case kAudioInDevMenuCId: c->p->_setMenuBtnLabel(c->id); c->p->_enableStoreBtn(kAudioApplyBtnCId); break; case kAudioOutDevMenuCId: c->p->_setMenuBtnLabel(c->id); c->p->_enableStoreBtn(kAudioApplyBtnCId); break; case kAudioSrateMenuCId: c->p->_setMenuBtnLabel(c->id); c->p->_enableStoreBtn(kAudioApplyBtnCId); break; case kAudioActiveCheckCId: case kAudioMsgQueSizeValCId: case kAudioDevFpCValCId: case kAudioDspFpCValCId: case kAudioBufCntValCId: case kAudioSyncInCheckCId: case kAudioNetNodeStringCId: case kAudioBcastAddrStringCId: case kAudioIpAddrStringCId: case kAudioIpPortValCId: c->p->_enableStoreBtn(kAudioApplyBtnCId); break; // ------------------------------------------------------------ // Network /* case kNetLabelCId: break; case kNetCfgMenuCId: c->p->_recallCfg(kNetDcmTId, kNetCfgMenuCId, kNetCfgStringCId, kNetCfgDescCId, kNetApplyBtnCId ); break; case kNetDeleteBtnCId: c->p->_deleteCfg(kNetDcmTId,kNetCfgMenuCId,kNetCfgStringCId,kNetCfgDescCId, kNetApplyBtnCId, kNetDeleteBtnCId); break; case kNetCfgStringCId: c->p->_enableStoreBtn(kNetApplyBtnCId); break; case kNetApplyBtnCId: c->p->_createNetCfg(); c->p->_recallCfg(kNetDcmTId, kNetCfgMenuCId, kNetCfgStringCId, kNetCfgDescCId, kNetApplyBtnCId ); c->p->_enableStoreBtn(kNetApplyBtnCId); break; case kNetSockAddrStringCId: case kNetPortNumbValCId: case kNetActiveCheckCId: c->p->_enableStoreBtn(kNetApplyBtnCId); break; */ default: break; } }