//----------------------------------------------------------------------------- // VST Plug-Ins SDK // VSTGUI: Graphical User Interface Framework for VST plugins // // Version 3.0 Date : 30/06/04 // //----------------------------------------------------------------------------- // //----------------------------------------------------------------------------- // VSTGUI LICENSE // © 2004, Steinberg Media Technologies, All Rights Reserved //----------------------------------------------------------------------------- // Redistribution and use in source and binary forms, with or without modification, // are permitted provided that the following conditions are met: // // * Redistributions of source code must retain the above copyright notice, // this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution. // * Neither the name of the Steinberg Media Technologies nor the names of its // contributors may be used to endorse or promote products derived from this // software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. // IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE // OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED // OF THE POSSIBILITY OF SUCH DAMAGE. //----------------------------------------------------------------------------- #ifndef __aeffguieditor__ #include "aeffguieditor.h" #endif //----------------------------------------------------------------------------- #define kIdleRate 100 // host idle rate in ms #define kIdleRate2 50 #define kIdleRateMin 4 // minimum time between 2 idles in ms #if MOTIF static unsigned int _getTicks (); #endif //----------------------------------------------------------------------------- VstInt32 AEffGUIEditor::knobMode = kCircularMode; //----------------------------------------------------------------------------- // AEffGUIEditor Implementation //----------------------------------------------------------------------------- AEffGUIEditor::AEffGUIEditor (AudioEffect* effect) : AEffEditor (effect), lLastTicks (0), inIdleStuff (false), frame (0) { rect.left = rect.top = rect.right = rect.bottom = 0; lLastTicks = getTicks (); effect->setEditor (this); #if WINDOWS OleInitialize (0); #endif #if MACX void InitMachOLibrary (); InitMachOLibrary (); #endif } //----------------------------------------------------------------------------- AEffGUIEditor::~AEffGUIEditor () { #if WINDOWS OleUninitialize (); #endif #if MACX void ExitMachOLibrary (); ExitMachOLibrary (); #endif } //----------------------------------------------------------------------------- void AEffGUIEditor::setParameter (VstInt32 index, float value) {} //----------------------------------------------------------------------------- void AEffGUIEditor::beginEdit (VstInt32 index) { ((AudioEffectX*)effect)->beginEdit (index); } //----------------------------------------------------------------------------- void AEffGUIEditor::endEdit (VstInt32 index) { ((AudioEffectX*)effect)->endEdit (index); } //----------------------------------------------------------------------------- #if VST_2_1_EXTENSIONS bool AEffGUIEditor::onKeyDown (VstKeyCode& keyCode) { return frame && frame->onKeyDown (keyCode) == 1 ? true : false; } //----------------------------------------------------------------------------- bool AEffGUIEditor::onKeyUp (VstKeyCode& keyCode) { return frame && frame->onKeyUp (keyCode) == 1 ? true : false; } //----------------------------------------------------------------------------- bool AEffGUIEditor::setKnobMode (VstInt32 val) { knobMode = val; return true; } //----------------------------------------------------------------------------- bool AEffGUIEditor::onWheel (float distance) { if (frame) { CDrawContext context (frame, NULL, systemWindow); CPoint where; context.getMouseLocation (where); return frame->onWheel (&context, where, distance); } return false; } #endif //----------------------------------------------------------------------------- #if MAC void AEffGUIEditor::DECLARE_VST_DEPRECATED (draw) (ERect* rect) { if (frame) { if (rect) { CRect r (rect->left, rect->top, rect->right, rect->bottom); CDrawContext context (frame, NULL, systemWindow); frame->drawRect (&context, r); } else frame->draw (); } } //----------------------------------------------------------------------------- VstInt32 AEffGUIEditor::DECLARE_VST_DEPRECATED (mouse) (VstInt32 x, VstInt32 y) { CDrawContext context (frame, NULL, systemWindow); CPoint where (x, y); if (frame) frame->mouse (&context, where); return 1; } #endif //----------------------------------------------------------------------------- bool AEffGUIEditor::getRect (ERect **ppErect) { *ppErect = ▭ return true; } //----------------------------------------------------------------------------- void AEffGUIEditor::idle () { #if MAC && !QUARTZ GrafPtr savePort; GetPort (&savePort); SetPort ((GrafPtr)GetWindowPort ((WindowRef)systemWindow)); AEffEditor::idle (); if (frame) frame->idle (); SetPort (savePort); #else #if BEOS PlugView *plugView = 0; if (frame) { plugView = (PlugView *) frame->getSystemWindow (); if (plugView->LockLooperWithTimeout (0) != B_OK) return; } #else if (inIdleStuff) return; #endif AEffEditor::idle (); if (frame) frame->idle (); #if BEOS if (frame) plugView->UnlockLooper (); #endif #endif } //----------------------------------------------------------------------------- void AEffGUIEditor::wait (unsigned int ms) { #if MAC unsigned long ticks; Delay (ms * 60 / 1000, &ticks); #elif WINDOWS Sleep (ms); #elif SGI struct timespec sleeptime = {0, ms * 1000000}; nanosleep (&sleeptime, NULL); #elif BEOS snooze (ms * 1000); #endif } //----------------------------------------------------------------------------- unsigned int AEffGUIEditor::getTicks () { #if MAC return (TickCount () * 1000) / 60; #elif WINDOWS return (unsigned int)GetTickCount (); #elif MOTIF return _getTicks (); #elif BEOS return (system_time () / 1000); #endif return 0; } //----------------------------------------------------------------------------- void AEffGUIEditor::doIdleStuff () { #if !(MAC && !TARGET_API_MAC_CARBON) // get the current time unsigned int currentTicks = getTicks (); // YG TEST idle (); if (currentTicks < lLastTicks) { #if (MAC && TARGET_API_MAC_CARBON) RunCurrentEventLoop (kEventDurationMillisecond * kIdleRateMin); #else wait (kIdleRateMin); #endif currentTicks += kIdleRateMin; if (currentTicks < lLastTicks - kIdleRate2) return; } idle (); #if WINDOWS MSG windowsMessage; if (PeekMessage (&windowsMessage, NULL, WM_PAINT, WM_PAINT, PM_REMOVE)) DispatchMessage (&windowsMessage); #elif MACX EventRef event; EventTypeSpec eventTypes[] = { {kEventClassWindow, kEventWindowUpdate}, {kEventClassWindow, kEventWindowDrawContent} }; if (ReceiveNextEvent (GetEventTypeCount (eventTypes), eventTypes, kEventDurationNoWait, true, &event) == noErr) { SendEventToEventTarget (event, GetEventDispatcherTarget ()); ReleaseEvent (event); } #endif // save the next time lLastTicks = currentTicks + kIdleRate; #endif inIdleStuff = true; #if !BEOS if (effect) effect->masterIdle (); #endif inIdleStuff = false; } #if MOTIF //----------------------------------------------------------------------------- unsigned int _getTicks () { #if SGI long long time; syssgi (SGI_GET_UST, &time, 0); return time / 1000000; #elif SUN hrtime_t nanosecs = gethrtime (); return (unsigned long long)nanosecs / 1000000UL; #elif LINUX // gettimeofday is not what we need here, checkout API for hw time struct timeval tv; struct timezone tz; gettimeofday (&tv, &tz); return tv.tv_sec * 1000 + tv.tv_usec / 1000; #endif } #endif #if MACX // ----------------------------------------------------------------------------- // ----------------------------------------------------------------------------- extern "C" { #include #include } #include BEGIN_NAMESPACE_VSTGUI void* gBundleRef = 0; END_NAMESPACE_VSTGUI #if USE_NAMESPACE #define VSTGUI_BUNDLEREF VSTGUI::gBundleRef #else #define VSTGUI_BUNDLEREF gBundleRef #endif // ----------------------------------------------------------------------------- static CFBundleRef _CFXBundleCreateFromImageName (CFAllocatorRef allocator, const char* image_name); static CFBundleRef _CFXBundleCreateFromImageName (CFAllocatorRef allocator, const char* image_name) { CFURLRef myBundleExecutableURL = CFURLCreateFromFileSystemRepresentation (allocator, (const unsigned char*)image_name, strlen (image_name), false); if (myBundleExecutableURL == 0) return 0; CFURLRef myBundleContentsMacOSURL = CFURLCreateCopyDeletingLastPathComponent (allocator, myBundleExecutableURL); // Delete Versions/Current/Executable CFRelease (myBundleExecutableURL); if (myBundleContentsMacOSURL == 0) return 0; CFURLRef myBundleContentsURL = CFURLCreateCopyDeletingLastPathComponent (allocator, myBundleContentsMacOSURL); // Delete Current CFRelease (myBundleContentsMacOSURL); if (myBundleContentsURL == 0) return 0; CFURLRef theBundleURL = CFURLCreateCopyDeletingLastPathComponent (allocator, myBundleContentsURL); // Delete Versions CFRelease (myBundleContentsURL); if (theBundleURL == 0) return 0; CFBundleRef result = CFBundleCreate (allocator, theBundleURL); CFRelease (theBundleURL); return result; } // ----------------------------------------------------------------------------- void InitMachOLibrary (); void InitMachOLibrary () { const mach_header* header = &_mh_bundle_header; const char* imagename = 0; /* determine the image name, TODO: ther have to be a better way */ int cnt = _dyld_image_count(); for (int idx1 = 1; idx1 < cnt; idx1++) { if (_dyld_get_image_header(idx1) == header) { imagename = _dyld_get_image_name(idx1); break; } } if (imagename == 0) return; /* get the bundle of a header, TODO: ther have to be a better way */ VSTGUI_BUNDLEREF = (void*)_CFXBundleCreateFromImageName (NULL, imagename); } // ----------------------------------------------------------------------------- void ExitMachOLibrary (); void ExitMachOLibrary () { if (VSTGUI_BUNDLEREF) CFRelease (VSTGUI_BUNDLEREF); } #endif