@@ -2,8 +2,8 @@ | |||
set -e | |||
JUCE_MODULES_DIR="/home/falktx/FOSS/GIT-mine/DISTRHO/libs/juce/source/modules/" | |||
CARLA_MODULES_DIR="/home/falktx/FOSS/GIT-mine/Carla/source/modules/" | |||
JUCE_MODULES_DIR="/home/falktx/Personal/FOSS/GIT/distrho/DISTRHO/libs/juce/source/modules/" | |||
CARLA_MODULES_DIR="/home/falktx/Personal/FOSS/GIT/falktx/Carla/source/modules/" | |||
MODULES=("juce_audio_basics juce_audio_devices juce_audio_formats juce_audio_processors juce_core juce_data_structures juce_events juce_graphics juce_gui_basics juce_gui_extra") | |||
@@ -1728,7 +1728,7 @@ bool CarlaEngine::loadProject(const char* const filename) | |||
if (pData->options.processMode != ENGINE_PROCESS_MODE_PATCHBAY) | |||
{ | |||
if (std::getenv("LADISH_APP_NAME") != nullptr || std::getenv("NSM_URL") != nullptr) | |||
return; | |||
return true; | |||
} | |||
// now connections | |||
@@ -1818,7 +1818,7 @@ bool CarlaEngine::saveProject(const char* const filename) | |||
if (pData->options.processMode != ENGINE_PROCESS_MODE_PATCHBAY) | |||
{ | |||
if (std::getenv("LADISH_APP_NAME") != nullptr || std::getenv("NSM_URL") != nullptr) | |||
return; | |||
return true; | |||
} | |||
if (const char* const* patchbayConns = getPatchbayConnections()) | |||
@@ -24,10 +24,8 @@ | |||
#ifdef WANT_LV2 | |||
// need this first for juce headers | |||
#include "CarlaMathUtils.hpp" | |||
#include "CarlaLv2Utils.hpp" | |||
#include "CarlaMathUtils.hpp" | |||
#include "CarlaPluginUi.hpp" | |||
#include "Lv2AtomQueue.hpp" | |||
@@ -21,7 +21,6 @@ | |||
#ifdef WANT_NATIVE | |||
#include "CarlaMathUtils.hpp" | |||
#include "CarlaNative.h" | |||
#include <QtCore/QStringList> | |||
@@ -200,6 +200,12 @@ static CarlaBackendStandalone gStandalone; | |||
#define NSM_API_VERSION_MAJOR 1 | |||
#define NSM_API_VERSION_MINOR 2 | |||
#ifdef HAVE_X11 | |||
# define NSM_CLIENT_FEATURES ":switch:optional-gui:" | |||
#else | |||
# define NSM_CLIENT_FEATURES ":switch:" | |||
#endif | |||
class CarlaNSM | |||
{ | |||
public: | |||
@@ -241,14 +247,14 @@ public: | |||
lo_server_add_method(fOscServer, "/reply", "ssss", _reply_handler, this); | |||
lo_server_add_method(fOscServer, "/nsm/client/open", "sss", _open_handler, this); | |||
lo_server_add_method(fOscServer, "/nsm/client/save", "", _save_handler, this); | |||
lo_server_add_method(fOscServer, "/nsm/client/show_optional_gui", "", _show_gui_handler, this); | |||
lo_server_add_method(fOscServer, "/nsm/client/hide_optional_gui", "", _hide_gui_handler, this); | |||
// /nsm/client/session_is_loaded | |||
// /nsm/client/show_optional_gui | |||
// /nsm/client/hide_optional_gui | |||
} | |||
#ifndef BUILD_ANSI_TEST | |||
lo_send_from(addr, fOscServer, LO_TT_IMMEDIATE, "/nsm/server/announce", "sssiii", | |||
"Carla", ":switch:", initName, NSM_API_VERSION_MAJOR, NSM_API_VERSION_MINOR, pid); // optional-gui: | |||
"Carla", NSM_CLIENT_FEATURES, initName, NSM_API_VERSION_MAJOR, NSM_API_VERSION_MINOR, pid); | |||
#endif | |||
lo_address_free(addr); | |||
@@ -356,6 +362,23 @@ protected: | |||
#endif | |||
} | |||
int handleShowHideGui(const bool show) | |||
{ | |||
CARLA_SAFE_ASSERT_RETURN(fOscServer != nullptr, 0); | |||
CARLA_SAFE_ASSERT_RETURN(gStandalone.engine != nullptr, 0); | |||
//CARLA_SAFE_ASSERT_RETURN(gStandalone.frontendWinId != 0, 0); | |||
carla_debug("CarlaNSM::handleShowHideGui(%s)", bool2str(show)); | |||
#ifdef HAVE_X11 | |||
#endif | |||
#ifndef BUILD_ANSI_TEST | |||
lo_send_from(lo_message_get_source(msg), fOscServer, LO_TT_IMMEDIATE, show ? "/nsm/client/gui_is_shown" : "/nsm/client/gui_is_hidden", ""); | |||
#endif | |||
return 0; | |||
} | |||
private: | |||
lo_server fOscServer; | |||
CarlaString fProjectPath; | |||
@@ -382,6 +405,16 @@ private: | |||
return handlePtr->handleSave(path, types, argv, argc, msg); | |||
} | |||
static int _show_gui_handler(const char*, const char*, lo_arg**, int, lo_message, void* data) | |||
{ | |||
return handlePtr->handleShowHideGui(true); | |||
} | |||
static int _hide_gui_handler(const char*, const char*, lo_arg**, int, lo_message, void* data) | |||
{ | |||
return handlePtr->handleShowHideGui(false); | |||
} | |||
#undef handlePtr | |||
CARLA_PREVENT_HEAP_ALLOCATION | |||
@@ -22,13 +22,20 @@ | |||
============================================================================== | |||
*/ | |||
AudioSampleBuffer::AudioSampleBuffer() noexcept | |||
: numChannels (0), size (0), allocatedBytes (0), | |||
channels (static_cast<float**> (preallocatedChannelSpace)), | |||
isClear (false) | |||
{ | |||
} | |||
AudioSampleBuffer::AudioSampleBuffer (const int numChans, | |||
const int numSamples) noexcept | |||
: numChannels (numChans), | |||
size (numSamples) | |||
{ | |||
jassert (numSamples >= 0); | |||
jassert (numChans > 0); | |||
jassert (numChans >= 0); | |||
allocateData(); | |||
} | |||
@@ -63,7 +70,7 @@ void AudioSampleBuffer::allocateData() | |||
const size_t channelListSize = sizeof (float*) * (size_t) (numChannels + 1); | |||
allocatedBytes = (size_t) numChannels * (size_t) size * sizeof (float) + channelListSize + 32; | |||
allocatedData.malloc (allocatedBytes); | |||
channels = reinterpret_cast <float**> (allocatedData.getData()); | |||
channels = reinterpret_cast<float**> (allocatedData.getData()); | |||
float* chan = (float*) (allocatedData + channelListSize); | |||
for (int i = 0; i < numChannels; ++i) | |||
@@ -83,7 +90,8 @@ AudioSampleBuffer::AudioSampleBuffer (float* const* dataToReferTo, | |||
size (numSamples), | |||
allocatedBytes (0) | |||
{ | |||
jassert (numChans > 0); | |||
jassert (dataToReferTo != nullptr); | |||
jassert (numChans >= 0); | |||
allocateChannels (dataToReferTo, 0); | |||
} | |||
@@ -96,7 +104,8 @@ AudioSampleBuffer::AudioSampleBuffer (float* const* dataToReferTo, | |||
allocatedBytes (0), | |||
isClear (false) | |||
{ | |||
jassert (numChans > 0); | |||
jassert (dataToReferTo != nullptr); | |||
jassert (numChans >= 0); | |||
allocateChannels (dataToReferTo, startSample); | |||
} | |||
@@ -104,7 +113,8 @@ void AudioSampleBuffer::setDataToReferTo (float** dataToReferTo, | |||
const int newNumChannels, | |||
const int newNumSamples) noexcept | |||
{ | |||
jassert (newNumChannels > 0); | |||
jassert (dataToReferTo != nullptr); | |||
jassert (newNumChannels >= 0); | |||
allocatedBytes = 0; | |||
allocatedData.free(); | |||
@@ -121,12 +131,12 @@ void AudioSampleBuffer::allocateChannels (float* const* const dataToReferTo, int | |||
// (try to avoid doing a malloc here, as that'll blow up things like Pro-Tools) | |||
if (numChannels < (int) numElementsInArray (preallocatedChannelSpace)) | |||
{ | |||
channels = static_cast <float**> (preallocatedChannelSpace); | |||
channels = static_cast<float**> (preallocatedChannelSpace); | |||
} | |||
else | |||
{ | |||
allocatedData.malloc ((size_t) numChannels + 1, sizeof (float*)); | |||
channels = reinterpret_cast <float**> (allocatedData.getData()); | |||
channels = reinterpret_cast<float**> (allocatedData.getData()); | |||
} | |||
for (int i = 0; i < numChannels; ++i) | |||
@@ -171,7 +181,7 @@ void AudioSampleBuffer::setSize (const int newNumChannels, | |||
const bool clearExtraSpace, | |||
const bool avoidReallocating) noexcept | |||
{ | |||
jassert (newNumChannels > 0); | |||
jassert (newNumChannels >= 0); | |||
jassert (newNumSamples >= 0); | |||
if (newNumSamples != size || newNumChannels != numChannels) | |||
@@ -34,6 +34,10 @@ | |||
class JUCE_API AudioSampleBuffer | |||
{ | |||
public: | |||
//============================================================================== | |||
/** Creates an empty buffer with 0 channels and 0 length. */ | |||
AudioSampleBuffer() noexcept; | |||
//============================================================================== | |||
/** Creates a buffer with a specified number of channels and samples. | |||
@@ -93,12 +97,12 @@ public: | |||
using an external data buffer, in which case boths buffers will just point to the same | |||
shared block of data. | |||
*/ | |||
AudioSampleBuffer (const AudioSampleBuffer& other) noexcept; | |||
AudioSampleBuffer (const AudioSampleBuffer&) noexcept; | |||
/** Copies another buffer onto this one. | |||
This buffer's size will be changed to that of the other buffer. | |||
*/ | |||
AudioSampleBuffer& operator= (const AudioSampleBuffer& other) noexcept; | |||
AudioSampleBuffer& operator= (const AudioSampleBuffer&) noexcept; | |||
/** Destructor. | |||
This will free any memory allocated by the buffer. | |||
@@ -493,14 +497,14 @@ public: | |||
//============================================================================== | |||
#ifndef DOXYGEN | |||
// Note that these methods have now been replaced by getReadPointer() and getWritePointer() | |||
JUCE_DEPRECATED (const float* getSampleData (int channel) const) { return getReadPointer (channel); } | |||
JUCE_DEPRECATED (const float* getSampleData (int channel, int index) const) { return getReadPointer (channel, index); } | |||
JUCE_DEPRECATED (float* getSampleData (int channel)) { return getWritePointer (channel); } | |||
JUCE_DEPRECATED (float* getSampleData (int channel, int index)) { return getWritePointer (channel, index); } | |||
JUCE_DEPRECATED_WITH_BODY (const float* getSampleData (int channel) const, { return getReadPointer (channel); }) | |||
JUCE_DEPRECATED_WITH_BODY (const float* getSampleData (int channel, int index) const, { return getReadPointer (channel, index); }) | |||
JUCE_DEPRECATED_WITH_BODY (float* getSampleData (int channel), { return getWritePointer (channel); }) | |||
JUCE_DEPRECATED_WITH_BODY (float* getSampleData (int channel, int index), { return getWritePointer (channel, index); }) | |||
// These have been replaced by getArrayOfReadPointers() and getArrayOfWritePointers() | |||
JUCE_DEPRECATED (const float** getArrayOfChannels() const) { return getArrayOfReadPointers(); } | |||
JUCE_DEPRECATED (float** getArrayOfChannels()) { return getArrayOfWritePointers(); } | |||
JUCE_DEPRECATED_WITH_BODY (const float** getArrayOfChannels() const, { return getArrayOfReadPointers(); }) | |||
JUCE_DEPRECATED_WITH_BODY (float** getArrayOfChannels(), { return getArrayOfWritePointers(); }) | |||
#endif | |||
private: | |||
@@ -513,7 +517,7 @@ private: | |||
bool isClear; | |||
void allocateData(); | |||
void allocateChannels (float* const* dataToReferTo, int offset); | |||
void allocateChannels (float* const*, int offset); | |||
JUCE_LEAK_DETECTOR (AudioSampleBuffer) | |||
}; | |||
@@ -53,8 +53,8 @@ namespace FloatVectorHelpers | |||
static forcedinline ParallelType load1 (Type v) noexcept { return _mm_load1_ps (&v); } | |||
static forcedinline ParallelType loadA (const Type* v) noexcept { return _mm_load_ps (v); } | |||
static forcedinline ParallelType loadU (const Type* v) noexcept { return _mm_loadu_ps (v); } | |||
static forcedinline void storeA (Type* dest, ParallelType a) noexcept { return _mm_store_ps (dest, a); } | |||
static forcedinline void storeU (Type* dest, ParallelType a) noexcept { return _mm_storeu_ps (dest, a); } | |||
static forcedinline void storeA (Type* dest, ParallelType a) noexcept { _mm_store_ps (dest, a); } | |||
static forcedinline void storeU (Type* dest, ParallelType a) noexcept { _mm_storeu_ps (dest, a); } | |||
static forcedinline ParallelType add (ParallelType a, ParallelType b) noexcept { return _mm_add_ps (a, b); } | |||
static forcedinline ParallelType sub (ParallelType a, ParallelType b) noexcept { return _mm_sub_ps (a, b); } | |||
@@ -75,8 +75,8 @@ namespace FloatVectorHelpers | |||
static forcedinline ParallelType load1 (Type v) noexcept { return _mm_load1_pd (&v); } | |||
static forcedinline ParallelType loadA (const Type* v) noexcept { return _mm_load_pd (v); } | |||
static forcedinline ParallelType loadU (const Type* v) noexcept { return _mm_loadu_pd (v); } | |||
static forcedinline void storeA (Type* dest, ParallelType a) noexcept { return _mm_store_pd (dest, a); } | |||
static forcedinline void storeU (Type* dest, ParallelType a) noexcept { return _mm_storeu_pd (dest, a); } | |||
static forcedinline void storeA (Type* dest, ParallelType a) noexcept { _mm_store_pd (dest, a); } | |||
static forcedinline void storeU (Type* dest, ParallelType a) noexcept { _mm_storeu_pd (dest, a); } | |||
static forcedinline ParallelType add (ParallelType a, ParallelType b) noexcept { return _mm_add_pd (a, b); } | |||
static forcedinline ParallelType sub (ParallelType a, ParallelType b) noexcept { return _mm_sub_pd (a, b); } | |||
@@ -134,8 +134,8 @@ namespace FloatVectorHelpers | |||
static forcedinline ParallelType load1 (Type v) noexcept { return vld1q_dup_f32 (&v); } | |||
static forcedinline ParallelType loadA (const Type* v) noexcept { return vld1q_f32 (v); } | |||
static forcedinline ParallelType loadU (const Type* v) noexcept { return vld1q_f32 (v); } | |||
static forcedinline void storeA (Type* dest, ParallelType a) noexcept { return vst1q_f32 (dest, a); } | |||
static forcedinline void storeU (Type* dest, ParallelType a) noexcept { return vst1q_f32 (dest, a); } | |||
static forcedinline void storeA (Type* dest, ParallelType a) noexcept { vst1q_f32 (dest, a); } | |||
static forcedinline void storeU (Type* dest, ParallelType a) noexcept { vst1q_f32 (dest, a); } | |||
static forcedinline ParallelType add (ParallelType a, ParallelType b) noexcept { return vaddq_f32 (a, b); } | |||
static forcedinline ParallelType sub (ParallelType a, ParallelType b) noexcept { return vsubq_f32 (a, b); } | |||
@@ -156,8 +156,8 @@ namespace FloatVectorHelpers | |||
static forcedinline ParallelType load1 (Type v) noexcept { return v; } | |||
static forcedinline ParallelType loadA (const Type* v) noexcept { return *v; } | |||
static forcedinline ParallelType loadU (const Type* v) noexcept { return *v; } | |||
static forcedinline void storeA (Type* dest, ParallelType a) noexcept { return *dest = a; } | |||
static forcedinline void storeU (Type* dest, ParallelType a) noexcept { return *dest = a; } | |||
static forcedinline void storeA (Type* dest, ParallelType a) noexcept { *dest = a; } | |||
static forcedinline void storeU (Type* dest, ParallelType a) noexcept { *dest = a; } | |||
static forcedinline ParallelType add (ParallelType a, ParallelType b) noexcept { return a + b; } | |||
static forcedinline ParallelType sub (ParallelType a, ParallelType b) noexcept { return a - b; } | |||
@@ -549,9 +549,9 @@ void FloatVectorOperations::negate (double* dest, const double* src, int num) no | |||
void JUCE_CALLTYPE FloatVectorOperations::convertFixedToFloat (float* dest, const int* src, float multiplier, int num) noexcept | |||
{ | |||
#if JUCE_USE_ARM_NEON | |||
JUCE_PERFORM_NEON_OP_SRC_DEST (dest[i] = src[i] * multiplier, | |||
vmulq_n_f32 (vcvtq_f32_s32 (vld1q_s32 (src)), multiplier), | |||
JUCE_LOAD_NONE) | |||
JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] = src[i] * multiplier, | |||
vmulq_n_f32 (vcvtq_f32_s32 (vld1q_s32 (src)), multiplier), | |||
JUCE_LOAD_NONE, JUCE_INCREMENT_SRC_DEST, ) | |||
#else | |||
JUCE_PERFORM_VEC_OP_SRC_DEST (dest[i] = src[i] * multiplier, | |||
Mode::mul (mult, _mm_cvtepi32_ps (_mm_loadu_si128 ((const __m128i*) src))), | |||
@@ -31,7 +31,6 @@ BufferingAudioSource::BufferingAudioSource (PositionableAudioSource* s, | |||
backgroundThread (thread), | |||
numberOfSamplesToBuffer (jmax (1024, bufferSizeSamples)), | |||
numberOfChannels (numChannels), | |||
buffer (numChannels, 0), | |||
bufferValidStart (0), | |||
bufferValidEnd (0), | |||
nextPlayPos (0), | |||
@@ -25,8 +25,7 @@ | |||
ChannelRemappingAudioSource::ChannelRemappingAudioSource (AudioSource* const source_, | |||
const bool deleteSourceWhenDeleted) | |||
: source (source_, deleteSourceWhenDeleted), | |||
requiredNumberOfChannels (2), | |||
buffer (2, 16) | |||
requiredNumberOfChannels (2) | |||
{ | |||
remappedInfo.buffer = &buffer; | |||
remappedInfo.startSample = 0; | |||
@@ -23,9 +23,7 @@ | |||
*/ | |||
MixerAudioSource::MixerAudioSource() | |||
: tempBuffer (2, 0), | |||
currentSampleRate (0.0), | |||
bufferSizeExpected (0) | |||
: currentSampleRate (0.0), bufferSizeExpected (0) | |||
{ | |||
} | |||
@@ -28,14 +28,12 @@ ResamplingAudioSource::ResamplingAudioSource (AudioSource* const inputSource, | |||
: input (inputSource, deleteInputWhenDeleted), | |||
ratio (1.0), | |||
lastRatio (1.0), | |||
buffer (numChannels_, 0), | |||
bufferPos (0), | |||
sampsInBuffer (0), | |||
subSampleOffset (0), | |||
numChannels (numChannels_) | |||
{ | |||
jassert (input != nullptr); | |||
zeromem (coefficients, sizeof (coefficients)); | |||
} | |||
@@ -90,10 +90,10 @@ void Synthesiser::clearVoices() | |||
voices.clear(); | |||
} | |||
void Synthesiser::addVoice (SynthesiserVoice* const newVoice) | |||
SynthesiserVoice* Synthesiser::addVoice (SynthesiserVoice* const newVoice) | |||
{ | |||
const ScopedLock sl (lock); | |||
voices.add (newVoice); | |||
return voices.add (newVoice); | |||
} | |||
void Synthesiser::removeVoice (const int index) | |||
@@ -108,10 +108,10 @@ void Synthesiser::clearSounds() | |||
sounds.clear(); | |||
} | |||
void Synthesiser::addSound (const SynthesiserSound::Ptr& newSound) | |||
SynthesiserSound* Synthesiser::addSound (const SynthesiserSound::Ptr& newSound) | |||
{ | |||
const ScopedLock sl (lock); | |||
sounds.add (newSound); | |||
return sounds.add (newSound); | |||
} | |||
void Synthesiser::removeSound (const int index) | |||
@@ -294,7 +294,7 @@ public: | |||
it later on when no longer needed. The caller should not retain a pointer to the | |||
voice. | |||
*/ | |||
void addVoice (SynthesiserVoice* newVoice); | |||
SynthesiserVoice* addVoice (SynthesiserVoice* newVoice); | |||
/** Deletes one of the voices. */ | |||
void removeVoice (int index); | |||
@@ -311,10 +311,10 @@ public: | |||
/** Adds a new sound to the synthesiser. | |||
The object passed in is reference counted, so will be deleted when it is removed | |||
from the synthesiser, and when no voices are still using it. | |||
The object passed in is reference counted, so will be deleted when the | |||
synthesiser and all voices are no longer using it. | |||
*/ | |||
void addSound (const SynthesiserSound::Ptr& newSound); | |||
SynthesiserSound* addSound (const SynthesiserSound::Ptr& newSound); | |||
/** Removes and deletes one of the sounds. */ | |||
void removeSound (int index); | |||
@@ -95,7 +95,6 @@ AudioDeviceManager::AudioDeviceManager() | |||
useInputNames (false), | |||
inputLevel (0), | |||
testSoundPosition (0), | |||
tempBuffer (2, 2), | |||
cpuUsageMs (0), | |||
timeToCpuScale (0) | |||
{ | |||
@@ -1026,8 +1026,7 @@ public: | |||
AudioIODeviceCombiner (const String& deviceName) | |||
: AudioIODevice (deviceName, "CoreAudio"), | |||
Thread (deviceName), callback (nullptr), | |||
currentSampleRate (0), currentBufferSize (0), active (false), | |||
fifos (1, 1) | |||
currentSampleRate (0), currentBufferSize (0), active (false) | |||
{ | |||
} | |||
@@ -731,8 +731,6 @@ public: | |||
isStarted (false), | |||
bufferSizeSamples (0), | |||
sampleRate (0.0), | |||
inputBuffers (1, 1), | |||
outputBuffers (1, 1), | |||
callback (nullptr) | |||
{ | |||
if (outputDeviceIndex_ >= 0) | |||
@@ -871,8 +869,8 @@ private: | |||
bool isStarted; | |||
String lastError; | |||
OwnedArray <DSoundInternalInChannel> inChans; | |||
OwnedArray <DSoundInternalOutChannel> outChans; | |||
OwnedArray<DSoundInternalInChannel> inChans; | |||
OwnedArray<DSoundInternalOutChannel> outChans; | |||
WaitableEvent startEvent; | |||
int bufferSizeSamples; | |||
@@ -316,7 +316,7 @@ String getDeviceID (IMMDevice* const device) | |||
EDataFlow getDataFlow (const ComSmartPtr<IMMDevice>& device) | |||
{ | |||
EDataFlow flow = eRender; | |||
ComSmartPtr <IMMEndpoint> endPoint; | |||
ComSmartPtr<IMMEndpoint> endPoint; | |||
if (check (device.QueryInterface (endPoint))) | |||
(void) check (endPoint->GetDataFlow (&flow)); | |||
@@ -338,7 +338,7 @@ void copyWavFormat (WAVEFORMATEXTENSIBLE& dest, const WAVEFORMATEX* const src) n | |||
class WASAPIDeviceBase | |||
{ | |||
public: | |||
WASAPIDeviceBase (const ComSmartPtr <IMMDevice>& d, const bool exclusiveMode) | |||
WASAPIDeviceBase (const ComSmartPtr<IMMDevice>& d, const bool exclusiveMode) | |||
: device (d), | |||
sampleRate (0), | |||
defaultSampleRate (0), | |||
@@ -352,7 +352,7 @@ public: | |||
{ | |||
clientEvent = CreateEvent (0, false, false, _T("JuceWASAPI")); | |||
ComSmartPtr <IAudioClient> tempClient (createClient()); | |||
ComSmartPtr<IAudioClient> tempClient (createClient()); | |||
if (tempClient == nullptr) | |||
return; | |||
@@ -453,17 +453,17 @@ public: | |||
} | |||
//============================================================================== | |||
ComSmartPtr <IMMDevice> device; | |||
ComSmartPtr <IAudioClient> client; | |||
ComSmartPtr<IMMDevice> device; | |||
ComSmartPtr<IAudioClient> client; | |||
double sampleRate, defaultSampleRate; | |||
int numChannels, actualNumChannels; | |||
int minBufferSize, defaultBufferSize, latencySamples; | |||
DWORD mixFormatChannelMask; | |||
const bool useExclusiveMode; | |||
Array <double> rates; | |||
Array<double> rates; | |||
HANDLE clientEvent; | |||
BigInteger channels; | |||
Array <int> channelMaps; | |||
Array<int> channelMaps; | |||
UINT32 actualBufferSize; | |||
int bytesPerSample; | |||
bool sampleRateHasChanged; | |||
@@ -472,7 +472,7 @@ public: | |||
private: | |||
//============================================================================== | |||
class SessionEventCallback : public ComBaseClassHelper <IAudioSessionEvents> | |||
class SessionEventCallback : public ComBaseClassHelper<IAudioSessionEvents> | |||
{ | |||
public: | |||
SessionEventCallback (WASAPIDeviceBase& d) : owner (d) {} | |||
@@ -498,8 +498,8 @@ private: | |||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (SessionEventCallback) | |||
}; | |||
ComSmartPtr <IAudioSessionControl> audioSessionControl; | |||
ComSmartPtr <SessionEventCallback> sessionEventCallback; | |||
ComSmartPtr<IAudioSessionControl> audioSessionControl; | |||
ComSmartPtr<SessionEventCallback> sessionEventCallback; | |||
void createSessionEventCallback() | |||
{ | |||
@@ -525,16 +525,13 @@ private: | |||
} | |||
//============================================================================== | |||
const ComSmartPtr <IAudioClient> createClient() | |||
ComSmartPtr<IAudioClient> createClient() | |||
{ | |||
ComSmartPtr <IAudioClient> client; | |||
ComSmartPtr<IAudioClient> client; | |||
if (device != nullptr) | |||
{ | |||
HRESULT hr = device->Activate (__uuidof (IAudioClient), CLSCTX_INPROC_SERVER, | |||
nullptr, (void**) client.resetAndGetPointerAddress()); | |||
logFailure (hr); | |||
} | |||
logFailure (device->Activate (__uuidof (IAudioClient), CLSCTX_INPROC_SERVER, | |||
nullptr, (void**) client.resetAndGetPointerAddress())); | |||
return client; | |||
} | |||
@@ -607,7 +604,7 @@ private: | |||
class WASAPIInputDevice : public WASAPIDeviceBase | |||
{ | |||
public: | |||
WASAPIInputDevice (const ComSmartPtr <IMMDevice>& d, const bool exclusiveMode) | |||
WASAPIInputDevice (const ComSmartPtr<IMMDevice>& d, const bool exclusiveMode) | |||
: WASAPIDeviceBase (d, exclusiveMode), | |||
reservoir (1, 1) | |||
{ | |||
@@ -635,11 +632,11 @@ public: | |||
reservoir.reset(); | |||
} | |||
template <class SourceType> | |||
template<class SourceType> | |||
void updateFormatWithType (SourceType*) | |||
{ | |||
typedef AudioData::Pointer <AudioData::Float32, AudioData::NativeEndian, AudioData::NonInterleaved, AudioData::NonConst> NativeType; | |||
converter = new AudioData::ConverterInstance <AudioData::Pointer <SourceType, AudioData::LittleEndian, AudioData::Interleaved, AudioData::Const>, NativeType> (actualNumChannels, 1); | |||
typedef AudioData::Pointer<AudioData::Float32, AudioData::NativeEndian, AudioData::NonInterleaved, AudioData::NonConst> NativeType; | |||
converter = new AudioData::ConverterInstance<AudioData::Pointer<SourceType, AudioData::LittleEndian, AudioData::Interleaved, AudioData::Const>, NativeType> (actualNumChannels, 1); | |||
} | |||
void updateFormat (bool isFloat) | |||
@@ -712,10 +709,10 @@ public: | |||
} | |||
} | |||
ComSmartPtr <IAudioCaptureClient> captureClient; | |||
ComSmartPtr<IAudioCaptureClient> captureClient; | |||
MemoryBlock reservoir; | |||
int reservoirSize, reservoirCapacity; | |||
ScopedPointer <AudioData::Converter> converter; | |||
ScopedPointer<AudioData::Converter> converter; | |||
private: | |||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (WASAPIInputDevice) | |||
@@ -725,7 +722,7 @@ private: | |||
class WASAPIOutputDevice : public WASAPIDeviceBase | |||
{ | |||
public: | |||
WASAPIOutputDevice (const ComSmartPtr <IMMDevice>& d, const bool exclusiveMode) | |||
WASAPIOutputDevice (const ComSmartPtr<IMMDevice>& d, const bool exclusiveMode) | |||
: WASAPIDeviceBase (d, exclusiveMode) | |||
{ | |||
} | |||
@@ -747,11 +744,11 @@ public: | |||
renderClient = nullptr; | |||
} | |||
template <class DestType> | |||
template<class DestType> | |||
void updateFormatWithType (DestType*) | |||
{ | |||
typedef AudioData::Pointer <AudioData::Float32, AudioData::NativeEndian, AudioData::NonInterleaved, AudioData::Const> NativeType; | |||
converter = new AudioData::ConverterInstance <NativeType, AudioData::Pointer <DestType, AudioData::LittleEndian, AudioData::Interleaved, AudioData::NonConst> > (1, actualNumChannels); | |||
typedef AudioData::Pointer<AudioData::Float32, AudioData::NativeEndian, AudioData::NonInterleaved, AudioData::Const> NativeType; | |||
converter = new AudioData::ConverterInstance<NativeType, AudioData::Pointer<DestType, AudioData::LittleEndian, AudioData::Interleaved, AudioData::NonConst> > (1, actualNumChannels); | |||
} | |||
void updateFormat (bool isFloat) | |||
@@ -801,8 +798,8 @@ public: | |||
} | |||
} | |||
ComSmartPtr <IAudioRenderClient> renderClient; | |||
ScopedPointer <AudioData::Converter> converter; | |||
ComSmartPtr<IAudioRenderClient> renderClient; | |||
ScopedPointer<AudioData::Converter> converter; | |||
private: | |||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (WASAPIOutputDevice) | |||
@@ -839,7 +836,7 @@ public: | |||
bool initialise() | |||
{ | |||
latencyIn = latencyOut = 0; | |||
Array <double> ratesIn, ratesOut; | |||
Array<double> ratesIn, ratesOut; | |||
if (createDevices()) | |||
{ | |||
@@ -1087,7 +1084,7 @@ public: | |||
const ScopedLock sl (startStopLock); | |||
if (isStarted) | |||
callback->audioDeviceIOCallback (const_cast <const float**> (inputBuffers), numInputBuffers, | |||
callback->audioDeviceIOCallback (const_cast<const float**> (inputBuffers), numInputBuffers, | |||
outputBuffers, numOutputBuffers, bufferSize); | |||
else | |||
outs.clear(); | |||
@@ -1095,7 +1092,7 @@ public: | |||
if (outputDevice != nullptr) | |||
{ | |||
outputDevice->copyBuffers (const_cast <const float**> (outputBuffers), numOutputBuffers, bufferSize, *this); | |||
outputDevice->copyBuffers (const_cast<const float**> (outputBuffers), numOutputBuffers, bufferSize, *this); | |||
if (outputDevice->sampleRateHasChanged) | |||
{ | |||
@@ -1124,8 +1121,8 @@ private: | |||
double defaultSampleRate; | |||
int minBufferSize, defaultBufferSize; | |||
int latencyIn, latencyOut; | |||
Array <double> sampleRates; | |||
Array <int> bufferSizes; | |||
Array<double> sampleRates; | |||
Array<int> bufferSizes; | |||
// Active state... | |||
bool isOpen_, isStarted; | |||
@@ -1141,11 +1138,11 @@ private: | |||
//============================================================================== | |||
bool createDevices() | |||
{ | |||
ComSmartPtr <IMMDeviceEnumerator> enumerator; | |||
ComSmartPtr<IMMDeviceEnumerator> enumerator; | |||
if (! check (enumerator.CoCreateInstance (__uuidof (MMDeviceEnumerator)))) | |||
return false; | |||
ComSmartPtr <IMMDeviceCollection> deviceCollection; | |||
ComSmartPtr<IMMDeviceCollection> deviceCollection; | |||
if (! check (enumerator->EnumAudioEndpoints (eAll, DEVICE_STATE_ACTIVE, deviceCollection.resetAndGetPointerAddress()))) | |||
return false; | |||
@@ -1155,7 +1152,7 @@ private: | |||
for (UINT32 i = 0; i < numDevices; ++i) | |||
{ | |||
ComSmartPtr <IMMDevice> device; | |||
ComSmartPtr<IMMDevice> device; | |||
if (! check (deviceCollection->Item (i, device.resetAndGetPointerAddress()))) | |||
continue; | |||
@@ -1255,9 +1252,12 @@ public: | |||
int getIndexOfDevice (AudioIODevice* device, bool asInput) const | |||
{ | |||
jassert (hasScanned); // need to call scanForDevices() before doing this | |||
WASAPIAudioIODevice* const d = dynamic_cast <WASAPIAudioIODevice*> (device); | |||
return d == nullptr ? -1 : (asInput ? inputDeviceIds.indexOf (d->inputDeviceId) | |||
: outputDeviceIds.indexOf (d->outputDeviceId)); | |||
if (WASAPIAudioIODevice* const d = dynamic_cast<WASAPIAudioIODevice*> (device)) | |||
return asInput ? inputDeviceIds.indexOf (d->inputDeviceId) | |||
: outputDeviceIds.indexOf (d->outputDeviceId); | |||
return -1; | |||
} | |||
bool hasSeparateInputsAndOutputs() const { return true; } | |||
@@ -1301,7 +1301,7 @@ private: | |||
{ | |||
public: | |||
ChangeNotificationClient (WASAPIAudioIODeviceType& d) | |||
: ComBaseClassHelper <IMMNotificationClient> (0), device (d) {} | |||
: ComBaseClassHelper<IMMNotificationClient> (0), device (d) {} | |||
HRESULT STDMETHODCALLTYPE OnDeviceAdded (LPCWSTR) { return notify(); } | |||
HRESULT STDMETHODCALLTYPE OnDeviceRemoved (LPCWSTR) { return notify(); } | |||
@@ -1360,7 +1360,7 @@ private: | |||
const String defaultRenderer (getDefaultEndpoint (enumerator, false)); | |||
const String defaultCapture (getDefaultEndpoint (enumerator, true)); | |||
ComSmartPtr <IMMDeviceCollection> deviceCollection; | |||
ComSmartPtr<IMMDeviceCollection> deviceCollection; | |||
UINT32 numDevices = 0; | |||
if (! (check (enumerator->EnumAudioEndpoints (eAll, DEVICE_STATE_ACTIVE, deviceCollection.resetAndGetPointerAddress())) | |||
@@ -1369,7 +1369,7 @@ private: | |||
for (UINT32 i = 0; i < numDevices; ++i) | |||
{ | |||
ComSmartPtr <IMMDevice> device; | |||
ComSmartPtr<IMMDevice> device; | |||
if (! check (deviceCollection->Item (i, device.resetAndGetPointerAddress()))) | |||
continue; | |||
@@ -1381,7 +1381,7 @@ private: | |||
String name; | |||
{ | |||
ComSmartPtr <IPropertyStore> properties; | |||
ComSmartPtr<IPropertyStore> properties; | |||
if (! check (device->OpenPropertyStore (STGM_READ, properties.resetAndGetPointerAddress()))) | |||
continue; | |||
@@ -26,7 +26,6 @@ AudioSourcePlayer::AudioSourcePlayer() | |||
: source (nullptr), | |||
sampleRate (0), | |||
bufferSize (0), | |||
tempBuffer (2, 8), | |||
lastGain (1.0f), | |||
gain (1.0f) | |||
{ | |||
@@ -49,6 +49,7 @@ namespace FlacNamespace | |||
#pragma clang diagnostic push | |||
#pragma clang diagnostic ignored "-Wconversion" | |||
#pragma clang diagnostic ignored "-Wshadow" | |||
#pragma clang diagnostic ignored "-Wdeprecated-register" | |||
#endif | |||
#if JUCE_INTEL | |||
@@ -104,7 +105,6 @@ class FlacReader : public AudioFormatReader | |||
public: | |||
FlacReader (InputStream* const in) | |||
: AudioFormatReader (in, flacFormatName), | |||
reservoir (2, 0), | |||
reservoirStart (0), | |||
samplesInReservoir (0), | |||
scanningForLength (false) | |||
@@ -40,6 +40,7 @@ namespace OggVorbisNamespace | |||
#pragma clang diagnostic push | |||
#pragma clang diagnostic ignored "-Wconversion" | |||
#pragma clang diagnostic ignored "-Wshadow" | |||
#pragma clang diagnostic ignored "-Wdeprecated-register" | |||
#endif | |||
#include "oggvorbis/vorbisenc.h" | |||
@@ -106,7 +107,6 @@ class OggReader : public AudioFormatReader | |||
public: | |||
OggReader (InputStream* const inp) | |||
: AudioFormatReader (inp, oggFormatName), | |||
reservoir (2, 4096), | |||
reservoirStart (0), | |||
samplesInReservoir (0) | |||
{ | |||
@@ -140,8 +140,7 @@ public: | |||
bitsPerSample = 16; | |||
sampleRate = info->rate; | |||
reservoir.setSize ((int) numChannels, | |||
(int) jmin (lengthInSamples, (int64) reservoir.getNumSamples())); | |||
reservoir.setSize ((int) numChannels, (int) jmin (lengthInSamples, (int64) 4096)); | |||
} | |||
} | |||
@@ -523,14 +523,16 @@ public: | |||
for (int i = 0; i < numOutputBusses; ++i) | |||
{ | |||
AudioBufferList* const abl = getAudioBufferListForBus(i); | |||
abl->mNumberBuffers = numOutputBusChannels; | |||
for (int j = 0; j < numOutputBusChannels; ++j) | |||
if (AudioBufferList* const abl = getAudioBufferListForBus(i)) | |||
{ | |||
abl->mBuffers[j].mNumberChannels = 1; | |||
abl->mBuffers[j].mDataByteSize = sizeof (float) * numSamples; | |||
abl->mBuffers[j].mData = buffer.getWritePointer (i * numOutputBusChannels + j); | |||
abl->mNumberBuffers = numOutputBusChannels; | |||
for (int j = 0; j < numOutputBusChannels; ++j) | |||
{ | |||
abl->mBuffers[j].mNumberChannels = 1; | |||
abl->mBuffers[j].mDataByteSize = sizeof (float) * numSamples; | |||
abl->mBuffers[j].mData = buffer.getWritePointer (i * numOutputBusChannels + j); | |||
} | |||
} | |||
} | |||
@@ -43,16 +43,16 @@ static bool doUIDsMatch (const Steinberg::TUID a, const Steinberg::TUID b) noexc | |||
return std::memcmp (a, b, sizeof (Steinberg::TUID)) == 0; | |||
} | |||
#define TEST_FOR_AND_RETURN_IF_VALID(ClassType) \ | |||
if (doUIDsMatch (iid, ClassType::iid)) \ | |||
#define TEST_FOR_AND_RETURN_IF_VALID(iidToTest, ClassType) \ | |||
if (doUIDsMatch (iidToTest, ClassType::iid)) \ | |||
{ \ | |||
addRef(); \ | |||
*obj = dynamic_cast<ClassType*> (this); \ | |||
return Steinberg::kResultOk; \ | |||
} | |||
#define TEST_FOR_COMMON_BASE_AND_RETURN_IF_VALID(CommonClassType, SourceClassType) \ | |||
if (doUIDsMatch (iid, CommonClassType::iid)) \ | |||
#define TEST_FOR_COMMON_BASE_AND_RETURN_IF_VALID(iidToTest, CommonClassType, SourceClassType) \ | |||
if (doUIDsMatch (iidToTest, CommonClassType::iid)) \ | |||
{ \ | |||
addRef(); \ | |||
*obj = (CommonClassType*) static_cast<SourceClassType*> (this); \ | |||
@@ -43,6 +43,7 @@ | |||
#pragma clang diagnostic ignored "-Wconversion" | |||
#pragma clang diagnostic ignored "-Woverloaded-virtual" | |||
#pragma clang diagnostic ignored "-Wshadow" | |||
#pragma clang diagnostic ignored "-Wdeprecated-register" | |||
#endif | |||
/* These files come with the Steinberg VST3 SDK - to get them, you'll need to | |||
@@ -534,14 +534,14 @@ public: | |||
return kResultOk; | |||
} | |||
TEST_FOR_AND_RETURN_IF_VALID (Vst::IComponentHandler) | |||
TEST_FOR_AND_RETURN_IF_VALID (Vst::IComponentHandler2) | |||
TEST_FOR_AND_RETURN_IF_VALID (Vst::IComponentHandler3) | |||
TEST_FOR_AND_RETURN_IF_VALID (Vst::IContextMenuTarget) | |||
TEST_FOR_AND_RETURN_IF_VALID (Vst::IHostApplication) | |||
TEST_FOR_AND_RETURN_IF_VALID (Vst::IParamValueQueue) | |||
TEST_FOR_AND_RETURN_IF_VALID (Vst::IUnitHandler) | |||
TEST_FOR_COMMON_BASE_AND_RETURN_IF_VALID (FUnknown, Vst::IComponentHandler) | |||
TEST_FOR_AND_RETURN_IF_VALID (iid, Vst::IComponentHandler) | |||
TEST_FOR_AND_RETURN_IF_VALID (iid, Vst::IComponentHandler2) | |||
TEST_FOR_AND_RETURN_IF_VALID (iid, Vst::IComponentHandler3) | |||
TEST_FOR_AND_RETURN_IF_VALID (iid, Vst::IContextMenuTarget) | |||
TEST_FOR_AND_RETURN_IF_VALID (iid, Vst::IHostApplication) | |||
TEST_FOR_AND_RETURN_IF_VALID (iid, Vst::IParamValueQueue) | |||
TEST_FOR_AND_RETURN_IF_VALID (iid, Vst::IUnitHandler) | |||
TEST_FOR_COMMON_BASE_AND_RETURN_IF_VALID (iid, FUnknown, Vst::IComponentHandler) | |||
*obj = nullptr; | |||
return kNotImplemented; | |||
@@ -33,6 +33,10 @@ | |||
This derives from the AudioProcessor class, and adds some extra functionality | |||
that helps when wrapping dynamically loaded plugins. | |||
This class is not needed when writing plugins, and you should never need to derive | |||
your own sub-classes from it. The plugin hosting classes use it internally and will | |||
return AudioPluginInstance objects which wrap external plugins. | |||
@see AudioProcessor, AudioPluginFormat | |||
*/ | |||
class JUCE_API AudioPluginInstance : public AudioProcessor | |||
@@ -923,9 +923,7 @@ void AudioProcessorGraph::Node::setParentGraph (AudioProcessorGraph* const graph | |||
//============================================================================== | |||
AudioProcessorGraph::AudioProcessorGraph() | |||
: lastNodeId (0), | |||
renderingBuffers (1, 1), | |||
currentAudioInputBuffer (nullptr), | |||
currentAudioOutputBuffer (1, 1), | |||
currentMidiInputBuffer (nullptr) | |||
{ | |||
} | |||
@@ -117,7 +117,7 @@ public: | |||
HashFunctionType hashFunction = HashFunctionType()) | |||
: hashFunctionToUse (hashFunction), totalNumItems (0) | |||
{ | |||
slots.insertMultiple (0, nullptr, numberOfSlots); | |||
hashSlots.insertMultiple (0, nullptr, numberOfSlots); | |||
} | |||
/** Destructor. */ | |||
@@ -135,9 +135,9 @@ public: | |||
{ | |||
const ScopedLockType sl (getLock()); | |||
for (int i = slots.size(); --i >= 0;) | |||
for (int i = hashSlots.size(); --i >= 0;) | |||
{ | |||
HashEntry* h = slots.getUnchecked(i); | |||
HashEntry* h = hashSlots.getUnchecked(i); | |||
while (h != nullptr) | |||
{ | |||
@@ -145,7 +145,7 @@ public: | |||
h = h->nextEntry; | |||
} | |||
slots.set (i, nullptr); | |||
hashSlots.set (i, nullptr); | |||
} | |||
totalNumItems = 0; | |||
@@ -166,7 +166,7 @@ public: | |||
{ | |||
const ScopedLockType sl (getLock()); | |||
for (const HashEntry* entry = slots.getUnchecked (generateHashFor (keyToLookFor)); entry != nullptr; entry = entry->nextEntry) | |||
for (const HashEntry* entry = hashSlots.getUnchecked (generateHashFor (keyToLookFor)); entry != nullptr; entry = entry->nextEntry) | |||
if (entry->key == keyToLookFor) | |||
return entry->value; | |||
@@ -179,7 +179,7 @@ public: | |||
{ | |||
const ScopedLockType sl (getLock()); | |||
for (const HashEntry* entry = slots.getUnchecked (generateHashFor (keyToLookFor)); entry != nullptr; entry = entry->nextEntry) | |||
for (const HashEntry* entry = hashSlots.getUnchecked (generateHashFor (keyToLookFor)); entry != nullptr; entry = entry->nextEntry) | |||
if (entry->key == keyToLookFor) | |||
return true; | |||
@@ -192,7 +192,7 @@ public: | |||
const ScopedLockType sl (getLock()); | |||
for (int i = getNumSlots(); --i >= 0;) | |||
for (const HashEntry* entry = slots.getUnchecked(i); entry != nullptr; entry = entry->nextEntry) | |||
for (const HashEntry* entry = hashSlots.getUnchecked(i); entry != nullptr; entry = entry->nextEntry) | |||
if (entry->value == valueToLookFor) | |||
return true; | |||
@@ -209,7 +209,7 @@ public: | |||
const ScopedLockType sl (getLock()); | |||
const int hashIndex = generateHashFor (newKey); | |||
HashEntry* const firstEntry = slots.getUnchecked (hashIndex); | |||
HashEntry* const firstEntry = hashSlots.getUnchecked (hashIndex); | |||
for (HashEntry* entry = firstEntry; entry != nullptr; entry = entry->nextEntry) | |||
{ | |||
@@ -220,7 +220,7 @@ public: | |||
} | |||
} | |||
slots.set (hashIndex, new HashEntry (newKey, newValue, firstEntry)); | |||
hashSlots.set (hashIndex, new HashEntry (newKey, newValue, firstEntry)); | |||
++totalNumItems; | |||
if (totalNumItems > (getNumSlots() * 3) / 2) | |||
@@ -232,7 +232,7 @@ public: | |||
{ | |||
const ScopedLockType sl (getLock()); | |||
const int hashIndex = generateHashFor (keyToRemove); | |||
HashEntry* entry = slots.getUnchecked (hashIndex); | |||
HashEntry* entry = hashSlots.getUnchecked (hashIndex); | |||
HashEntry* previous = nullptr; | |||
while (entry != nullptr) | |||
@@ -246,7 +246,7 @@ public: | |||
if (previous != nullptr) | |||
previous->nextEntry = entry; | |||
else | |||
slots.set (hashIndex, entry); | |||
hashSlots.set (hashIndex, entry); | |||
--totalNumItems; | |||
} | |||
@@ -265,7 +265,7 @@ public: | |||
for (int i = getNumSlots(); --i >= 0;) | |||
{ | |||
HashEntry* entry = slots.getUnchecked(i); | |||
HashEntry* entry = hashSlots.getUnchecked(i); | |||
HashEntry* previous = nullptr; | |||
while (entry != nullptr) | |||
@@ -279,7 +279,7 @@ public: | |||
if (previous != nullptr) | |||
previous->nextEntry = entry; | |||
else | |||
slots.set (i, entry); | |||
hashSlots.set (i, entry); | |||
--totalNumItems; | |||
} | |||
@@ -301,7 +301,7 @@ public: | |||
HashMap newTable (newNumberOfSlots); | |||
for (int i = getNumSlots(); --i >= 0;) | |||
for (const HashEntry* entry = slots.getUnchecked(i); entry != nullptr; entry = entry->nextEntry) | |||
for (const HashEntry* entry = hashSlots.getUnchecked(i); entry != nullptr; entry = entry->nextEntry) | |||
newTable.set (entry->key, entry->value); | |||
swapWith (newTable); | |||
@@ -313,7 +313,7 @@ public: | |||
*/ | |||
inline int getNumSlots() const noexcept | |||
{ | |||
return slots.size(); | |||
return hashSlots.size(); | |||
} | |||
//============================================================================== | |||
@@ -324,7 +324,7 @@ public: | |||
const ScopedLockType lock1 (getLock()); | |||
const typename OtherHashMapType::ScopedLockType lock2 (otherHashMap.getLock()); | |||
slots.swapWith (otherHashMap.slots); | |||
hashSlots.swapWith (otherHashMap.hashSlots); | |||
std::swap (totalNumItems, otherHashMap.totalNumItems); | |||
} | |||
@@ -400,7 +400,7 @@ public: | |||
if (index >= hashMap.getNumSlots()) | |||
return false; | |||
entry = hashMap.slots.getUnchecked (index++); | |||
entry = hashMap.hashSlots.getUnchecked (index++); | |||
} | |||
return true; | |||
@@ -437,7 +437,7 @@ private: | |||
friend class Iterator; | |||
HashFunctionType hashFunctionToUse; | |||
Array <HashEntry*> slots; | |||
Array<HashEntry*> hashSlots; | |||
int totalNumItems; | |||
TypeOfCriticalSectionToUse lock; | |||
@@ -355,7 +355,7 @@ File File::getChildFile (StringRef relativePath) const | |||
if (isAbsolutePath (relativePath)) | |||
return File (String (relativePath.text)); | |||
if (relativePath.text[0] != '.') | |||
if (relativePath[0] != '.') | |||
return File (addTrailingSeparator (fullPath) + relativePath); | |||
String path (fullPath); | |||
@@ -368,11 +368,11 @@ File File::getChildFile (StringRef relativePath) const | |||
while (relativePath[0] == '.') | |||
{ | |||
const juce_wchar secondChar = relativePath.text[1]; | |||
const juce_wchar secondChar = relativePath[1]; | |||
if (secondChar == '.') | |||
{ | |||
const juce_wchar thirdChar = relativePath.text[2]; | |||
const juce_wchar thirdChar = relativePath[2]; | |||
if (thirdChar == 0 || thirdChar == separator) | |||
{ | |||
@@ -35,7 +35,7 @@ | |||
Contains some static helper functions for manipulating the MS Windows registry | |||
(Only available on Windows, of course!) | |||
*/ | |||
class WindowsRegistry | |||
class JUCE_API WindowsRegistry | |||
{ | |||
public: | |||
/** These values can be used to specify whether the 32- or 64-bit registry should be used. | |||
@@ -59,48 +59,48 @@ public: | |||
The path is a string for the entire path of a value in the registry, | |||
e.g. "HKEY_CURRENT_USER\Software\foo\bar" | |||
*/ | |||
static String getValue (const String& regValuePath, | |||
const String& defaultValue = String::empty, | |||
WoW64Mode mode = WoW64_Default); | |||
static String JUCE_CALLTYPE getValue (const String& regValuePath, | |||
const String& defaultValue = String::empty, | |||
WoW64Mode mode = WoW64_Default); | |||
/** Reads a binary block from the registry. | |||
The path is a string for the entire path of a value in the registry, | |||
e.g. "HKEY_CURRENT_USER\Software\foo\bar" | |||
@returns a DWORD indicating the type of the key. | |||
*/ | |||
static uint32 getBinaryValue (const String& regValuePath, MemoryBlock& resultData, WoW64Mode mode = WoW64_Default); | |||
static uint32 JUCE_CALLTYPE getBinaryValue (const String& regValuePath, MemoryBlock& resultData, WoW64Mode mode = WoW64_Default); | |||
/** Sets a registry value as a string. | |||
This will take care of creating any groups needed to get to the given registry value. | |||
*/ | |||
static bool setValue (const String& regValuePath, const String& value, WoW64Mode mode = WoW64_Default); | |||
static bool JUCE_CALLTYPE setValue (const String& regValuePath, const String& value, WoW64Mode mode = WoW64_Default); | |||
/** Sets a registry value as a DWORD. | |||
This will take care of creating any groups needed to get to the given registry value. | |||
*/ | |||
static bool setValue (const String& regValuePath, uint32 value, WoW64Mode mode = WoW64_Default); | |||
static bool JUCE_CALLTYPE setValue (const String& regValuePath, uint32 value, WoW64Mode mode = WoW64_Default); | |||
/** Sets a registry value as a QWORD. | |||
This will take care of creating any groups needed to get to the given registry value. | |||
*/ | |||
static bool setValue (const String& regValuePath, uint64 value, WoW64Mode mode = WoW64_Default); | |||
static bool JUCE_CALLTYPE setValue (const String& regValuePath, uint64 value, WoW64Mode mode = WoW64_Default); | |||
/** Sets a registry value as a binary block. | |||
This will take care of creating any groups needed to get to the given registry value. | |||
*/ | |||
static bool setValue (const String& regValuePath, const MemoryBlock& value, WoW64Mode mode = WoW64_Default); | |||
static bool JUCE_CALLTYPE setValue (const String& regValuePath, const MemoryBlock& value, WoW64Mode mode = WoW64_Default); | |||
/** Returns true if the given value exists in the registry. */ | |||
static bool valueExists (const String& regValuePath, WoW64Mode mode = WoW64_Default); | |||
static bool JUCE_CALLTYPE valueExists (const String& regValuePath, WoW64Mode mode = WoW64_Default); | |||
/** Returns true if the given key exists in the registry. */ | |||
static bool keyExists (const String& regValuePath, WoW64Mode mode = WoW64_Default); | |||
static bool JUCE_CALLTYPE keyExists (const String& regValuePath, WoW64Mode mode = WoW64_Default); | |||
/** Deletes a registry value. */ | |||
static void deleteValue (const String& regValuePath, WoW64Mode mode = WoW64_Default); | |||
static void JUCE_CALLTYPE deleteValue (const String& regValuePath, WoW64Mode mode = WoW64_Default); | |||
/** Deletes a registry key (which is registry-talk for 'folder'). */ | |||
static void deleteKey (const String& regKeyPath, WoW64Mode mode = WoW64_Default); | |||
static void JUCE_CALLTYPE deleteKey (const String& regKeyPath, WoW64Mode mode = WoW64_Default); | |||
/** Creates a file association in the registry. | |||
@@ -119,13 +119,13 @@ public: | |||
association in HKEY_CURRENT_USER. | |||
@param mode the WoW64 mode to use for choosing the database | |||
*/ | |||
static bool registerFileAssociation (const String& fileExtension, | |||
const String& symbolicDescription, | |||
const String& fullDescription, | |||
const File& targetExecutable, | |||
int iconResourceNumber, | |||
bool registerForCurrentUserOnly, | |||
WoW64Mode mode = WoW64_Default); | |||
static bool JUCE_CALLTYPE registerFileAssociation (const String& fileExtension, | |||
const String& symbolicDescription, | |||
const String& fullDescription, | |||
const File& targetExecutable, | |||
int iconResourceNumber, | |||
bool registerForCurrentUserOnly, | |||
WoW64Mode mode = WoW64_Default); | |||
// DEPRECATED: use the other methods with a WoW64Mode parameter of WoW64_64bit instead. | |||
JUCE_DEPRECATED (static String getValueWow64 (const String&, const String& defaultValue = String::empty)); | |||
@@ -42,11 +42,6 @@ String SystemStats::getOperatingSystemName() | |||
return "Linux"; | |||
} | |||
String SystemStats::getDeviceDescription() | |||
{ | |||
return String(); | |||
} | |||
bool SystemStats::isOperatingSystem64Bit() | |||
{ | |||
#if JUCE_64BIT | |||
@@ -66,16 +61,26 @@ namespace LinuxStatsHelpers | |||
File ("/proc/cpuinfo").readLines (lines); | |||
for (int i = lines.size(); --i >= 0;) // (NB - it's important that this runs in reverse order) | |||
if (lines[i].startsWithIgnoreCase (key)) | |||
if (lines[i].upToFirstOccurrenceOf (":", false, false).trim().equalsIgnoreCase (key)) | |||
return lines[i].fromFirstOccurrenceOf (":", false, false).trim(); | |||
return String(); | |||
} | |||
} | |||
String SystemStats::getDeviceDescription() | |||
{ | |||
return LinuxStatsHelpers::getCpuInfo ("Hardware"); | |||
} | |||
String SystemStats::getCpuVendor() | |||
{ | |||
return LinuxStatsHelpers::getCpuInfo ("vendor_id"); | |||
String v (LinuxStatsHelpers::getCpuInfo ("vendor_id")); | |||
if (v.isEmpty()) | |||
v = LinuxStatsHelpers::getCpuInfo ("model name"); | |||
return v; | |||
} | |||
int SystemStats::getCpuSpeedInMegaherz() | |||
@@ -270,7 +270,7 @@ private: | |||
addMethod (@selector (connection:didReceiveResponse:), didReceiveResponse, "v@:@@"); | |||
addMethod (@selector (connection:didFailWithError:), didFailWithError, "v@:@@"); | |||
addMethod (@selector (connection:didReceiveData:), didReceiveData, "v@:@@"); | |||
addMethod (@selector (connection:didSendBodyData:totalBytesWritten:totalBytesExpectedToWrite:totalBytesExpectedToWrite:), | |||
addMethod (@selector (connection:didSendBodyData:totalBytesWritten:totalBytesExpectedToWrite:), | |||
connectionDidSendBodyData, "v@:@iii"); | |||
addMethod (@selector (connectionDidFinishLoading:), connectionDidFinishLoading, "v@:@"); | |||
addMethod (@selector (connection:willSendRequest:redirectResponse:), willSendRequest, "@@:@@"); | |||
@@ -31,13 +31,17 @@ | |||
live in juce_posix_SharedCode.h! | |||
*/ | |||
#if JUCE_IOS | |||
bool isIOSAppActive = true; | |||
#endif | |||
//============================================================================== | |||
JUCE_API bool JUCE_CALLTYPE Process::isForegroundProcess() | |||
{ | |||
#if JUCE_MAC | |||
return [NSApp isActive]; | |||
#else | |||
return true; // xxx change this if more than one app is ever possible on iOS! | |||
return isIOSAppActive; | |||
#endif | |||
} | |||
@@ -144,48 +144,48 @@ struct RegistryKeyWrapper | |||
JUCE_DECLARE_NON_COPYABLE (RegistryKeyWrapper) | |||
}; | |||
uint32 WindowsRegistry::getBinaryValue (const String& regValuePath, MemoryBlock& result, WoW64Mode mode) | |||
uint32 JUCE_CALLTYPE WindowsRegistry::getBinaryValue (const String& regValuePath, MemoryBlock& result, WoW64Mode mode) | |||
{ | |||
return RegistryKeyWrapper::getBinaryValue (regValuePath, result, (DWORD) mode); | |||
} | |||
String WindowsRegistry::getValue (const String& regValuePath, const String& defaultValue, WoW64Mode mode) | |||
String JUCE_CALLTYPE WindowsRegistry::getValue (const String& regValuePath, const String& defaultValue, WoW64Mode mode) | |||
{ | |||
return RegistryKeyWrapper::getValue (regValuePath, defaultValue, (DWORD) mode); | |||
} | |||
bool WindowsRegistry::setValue (const String& regValuePath, const String& value, WoW64Mode mode) | |||
bool JUCE_CALLTYPE WindowsRegistry::setValue (const String& regValuePath, const String& value, WoW64Mode mode) | |||
{ | |||
return RegistryKeyWrapper::setValue (regValuePath, REG_SZ, value.toWideCharPointer(), | |||
CharPointer_UTF16::getBytesRequiredFor (value.getCharPointer()), mode); | |||
} | |||
bool WindowsRegistry::setValue (const String& regValuePath, const uint32 value, WoW64Mode mode) | |||
bool JUCE_CALLTYPE WindowsRegistry::setValue (const String& regValuePath, const uint32 value, WoW64Mode mode) | |||
{ | |||
return RegistryKeyWrapper::setValue (regValuePath, REG_DWORD, &value, sizeof (value), (DWORD) mode); | |||
} | |||
bool WindowsRegistry::setValue (const String& regValuePath, const uint64 value, WoW64Mode mode) | |||
bool JUCE_CALLTYPE WindowsRegistry::setValue (const String& regValuePath, const uint64 value, WoW64Mode mode) | |||
{ | |||
return RegistryKeyWrapper::setValue (regValuePath, REG_QWORD, &value, sizeof (value), (DWORD) mode); | |||
} | |||
bool WindowsRegistry::setValue (const String& regValuePath, const MemoryBlock& value, WoW64Mode mode) | |||
bool JUCE_CALLTYPE WindowsRegistry::setValue (const String& regValuePath, const MemoryBlock& value, WoW64Mode mode) | |||
{ | |||
return RegistryKeyWrapper::setValue (regValuePath, REG_BINARY, value.getData(), value.getSize(), (DWORD) mode); | |||
} | |||
bool WindowsRegistry::valueExists (const String& regValuePath, WoW64Mode mode) | |||
bool JUCE_CALLTYPE WindowsRegistry::valueExists (const String& regValuePath, WoW64Mode mode) | |||
{ | |||
return RegistryKeyWrapper::valueExists (regValuePath, (DWORD) mode); | |||
} | |||
bool WindowsRegistry::keyExists (const String& regValuePath, WoW64Mode mode) | |||
bool JUCE_CALLTYPE WindowsRegistry::keyExists (const String& regValuePath, WoW64Mode mode) | |||
{ | |||
return RegistryKeyWrapper::keyExists (regValuePath, (DWORD) mode); | |||
} | |||
void WindowsRegistry::deleteValue (const String& regValuePath, WoW64Mode mode) | |||
void JUCE_CALLTYPE WindowsRegistry::deleteValue (const String& regValuePath, WoW64Mode mode) | |||
{ | |||
const RegistryKeyWrapper key (regValuePath, true, (DWORD) mode); | |||
@@ -193,7 +193,7 @@ void WindowsRegistry::deleteValue (const String& regValuePath, WoW64Mode mode) | |||
RegDeleteValue (key.key, key.wideCharValueName); | |||
} | |||
void WindowsRegistry::deleteKey (const String& regKeyPath, WoW64Mode mode) | |||
void JUCE_CALLTYPE WindowsRegistry::deleteKey (const String& regKeyPath, WoW64Mode mode) | |||
{ | |||
const RegistryKeyWrapper key (regKeyPath, true, (DWORD) mode); | |||
@@ -201,13 +201,13 @@ void WindowsRegistry::deleteKey (const String& regKeyPath, WoW64Mode mode) | |||
RegDeleteKey (key.key, key.wideCharValueName); | |||
} | |||
bool WindowsRegistry::registerFileAssociation (const String& fileExtension, | |||
const String& symbolicDescription, | |||
const String& fullDescription, | |||
const File& targetExecutable, | |||
const int iconResourceNumber, | |||
const bool registerForCurrentUserOnly, | |||
WoW64Mode mode) | |||
bool JUCE_CALLTYPE WindowsRegistry::registerFileAssociation (const String& fileExtension, | |||
const String& symbolicDescription, | |||
const String& fullDescription, | |||
const File& targetExecutable, | |||
const int iconResourceNumber, | |||
const bool registerForCurrentUserOnly, | |||
WoW64Mode mode) | |||
{ | |||
const char* const root = registerForCurrentUserOnly ? "HKEY_CURRENT_USER\\Software\\Classes\\" | |||
: "HKEY_CLASSES_ROOT\\"; | |||
@@ -555,7 +555,13 @@ bool ChildProcess::start (const String& command, int streamFlags) | |||
bool ChildProcess::start (const StringArray& args, int streamFlags) | |||
{ | |||
return start (args.joinIntoString (" "), streamFlags); | |||
String escaped; | |||
for (int i = 0; i < args.size(); ++i) | |||
escaped << args[i].replace ("\"", "\\\"") | |||
.replace (" ", "\\ ") << ' '; | |||
return start (escaped.trim(), streamFlags); | |||
} | |||
//============================================================================== | |||
@@ -360,6 +360,7 @@ private: | |||
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Upload) | |||
}; | |||
friend struct ContainerDeletePolicy<Upload>; | |||
ReferenceCountedArray<Upload> filesToUpload; | |||
URL (const String&, int); | |||
@@ -36,7 +36,7 @@ | |||
*/ | |||
#define JUCE_MAJOR_VERSION 3 | |||
#define JUCE_MINOR_VERSION 0 | |||
#define JUCE_BUILDNUMBER 4 | |||
#define JUCE_BUILDNUMBER 5 | |||
/** Current Juce version number. | |||
@@ -101,6 +101,9 @@ public: | |||
/** Returns the number of characters in the string. */ | |||
int length() const noexcept { return (int) text.length(); } | |||
/** Retrieves a character by index. */ | |||
juce_wchar operator[] (int index) const noexcept { return text[index]; } | |||
/** Compares this StringRef with a String. */ | |||
bool operator== (const String& s) const noexcept { return text.compare (s.getCharPointer()) == 0; } | |||
/** Compares this StringRef with a String. */ | |||
@@ -38,6 +38,7 @@ namespace zlibNamespace | |||
#pragma clang diagnostic push | |||
#pragma clang diagnostic ignored "-Wconversion" | |||
#pragma clang diagnostic ignored "-Wshadow" | |||
#pragma clang diagnostic ignored "-Wdeprecated-register" | |||
#endif | |||
#undef OS_CODE | |||
@@ -452,7 +452,7 @@ public: | |||
bool writeData (OutputStream& target, const int64 overallStartPosition) | |||
{ | |||
MemoryOutputStream compressedData; | |||
MemoryOutputStream compressedData ((size_t) file.getSize()); | |||
if (compressionLevel > 0) | |||
{ | |||
@@ -317,29 +317,37 @@ void Font::checkTypefaceSuitability() | |||
} | |||
//============================================================================== | |||
const String& Font::getDefaultSansSerifFontName() | |||
struct FontPlaceholderNames | |||
{ | |||
static const String name ("<Sans-Serif>"); | |||
return name; | |||
} | |||
FontPlaceholderNames() | |||
: sans ("<Sans-Serif>"), | |||
serif ("<Serif>"), | |||
mono ("<Monospaced>"), | |||
regular ("<Regular>") | |||
{ | |||
} | |||
const String& Font::getDefaultSerifFontName() | |||
{ | |||
static const String name ("<Serif>"); | |||
return name; | |||
} | |||
String sans, serif, mono, regular; | |||
}; | |||
const String& Font::getDefaultMonospacedFontName() | |||
const FontPlaceholderNames& getFontPlaceholderNames() | |||
{ | |||
static const String name ("<Monospaced>"); | |||
return name; | |||
static FontPlaceholderNames names; | |||
return names; | |||
} | |||
const String& Font::getDefaultStyle() | |||
{ | |||
static const String style ("<Regular>"); | |||
return style; | |||
} | |||
#if JUCE_MSVC | |||
// This is a workaround for the lack of thread-safety in MSVC's handling of function-local | |||
// statics - if multiple threads all try to create the first Font object at the same time, | |||
// it can cause a race-condition in creating these placeholder strings. | |||
struct FontNamePreloader { FontNamePreloader() { getFontPlaceholderNames(); } }; | |||
static FontNamePreloader fnp; | |||
#endif | |||
const String& Font::getDefaultSansSerifFontName() { return getFontPlaceholderNames().sans; } | |||
const String& Font::getDefaultSerifFontName() { return getFontPlaceholderNames().serif; } | |||
const String& Font::getDefaultMonospacedFontName() { return getFontPlaceholderNames().mono; } | |||
const String& Font::getDefaultStyle() { return getFontPlaceholderNames().regular; } | |||
const String& Font::getTypefaceName() const noexcept { return font->typefaceName; } | |||
const String& Font::getTypefaceStyle() const noexcept { return font->typefaceStyle; } | |||
@@ -37,9 +37,9 @@ namespace jpeglibNamespace | |||
#if JUCE_CLANG | |||
#pragma clang diagnostic push | |||
#pragma clang diagnostic ignored "-Wconversion" | |||
#pragma clang diagnostic ignored "-Wdeprecated-register" | |||
#endif | |||
#define JPEG_INTERNALS | |||
#undef FAR | |||
#include "jpglib/jpeglib.h" | |||
@@ -225,10 +225,13 @@ private: | |||
hits.set (0); | |||
misses.set (0); | |||
return glyphs.getLast(); | |||
} | |||
return findLeastRecentlyUsedGlyph(); | |||
if (CachedGlyphType* g = findLeastRecentlyUsedGlyph()) | |||
return g; | |||
addNewGlyphSlots (32); | |||
return glyphs.getLast(); | |||
} | |||
void addNewGlyphSlots (int num) | |||
@@ -241,8 +244,8 @@ private: | |||
CachedGlyphType* findLeastRecentlyUsedGlyph() const noexcept | |||
{ | |||
CachedGlyphType* oldest = glyphs.getLast(); | |||
int oldestCounter = oldest->lastAccessCount; | |||
CachedGlyphType* oldest = nullptr; | |||
int oldestCounter = std::numeric_limits<int>::max(); | |||
for (int i = glyphs.size() - 1; --i >= 0;) | |||
{ | |||
@@ -26,6 +26,7 @@ Desktop::Desktop() | |||
: mouseSources (new MouseInputSource::SourceList()), | |||
mouseClickCounter (0), mouseWheelCounter (0), | |||
kioskModeComponent (nullptr), | |||
kioskModeReentrant (false), | |||
allowedOrientations (allOrientations), | |||
masterScaleFactor ((float) getDefaultMasterScale()) | |||
{ | |||
@@ -340,15 +341,21 @@ void Desktop::Displays::refresh() | |||
//============================================================================== | |||
void Desktop::setKioskModeComponent (Component* componentToUse, const bool allowMenusAndBars) | |||
{ | |||
if (kioskModeReentrant) | |||
return; | |||
const ScopedValueSetter<bool> setter (kioskModeReentrant, true, false); | |||
if (kioskModeComponent != componentToUse) | |||
{ | |||
// agh! Don't delete or remove a component from the desktop while it's still the kiosk component! | |||
jassert (kioskModeComponent == nullptr || ComponentPeer::getPeerFor (kioskModeComponent) != nullptr); | |||
if (kioskModeComponent != nullptr) | |||
if (Component* const oldKioskComp = kioskModeComponent) | |||
{ | |||
setKioskComponent (kioskModeComponent, false, allowMenusAndBars); | |||
kioskModeComponent->setBounds (kioskComponentOriginalBounds); | |||
kioskModeComponent = nullptr; // (to make sure that isKioskMode() returns false when resizing the old one) | |||
setKioskComponent (oldKioskComp, false, allowMenusAndBars); | |||
oldKioskComp->setBounds (kioskComponentOriginalBounds); | |||
} | |||
kioskModeComponent = componentToUse; | |||
@@ -426,6 +426,7 @@ private: | |||
Component* kioskModeComponent; | |||
Rectangle<int> kioskComponentOriginalBounds; | |||
bool kioskModeReentrant; | |||
int allowedOrientations; | |||
float masterScaleFactor; | |||
@@ -22,6 +22,8 @@ | |||
============================================================================== | |||
*/ | |||
extern bool isIOSAppActive; | |||
} // (juce namespace) | |||
@interface JuceAppStartupDelegate : NSObject <UIApplicationDelegate> | |||
@@ -32,6 +34,8 @@ | |||
- (void) applicationWillTerminate: (UIApplication*) application; | |||
- (void) applicationDidEnterBackground: (UIApplication*) application; | |||
- (void) applicationWillEnterForeground: (UIApplication*) application; | |||
- (void) applicationDidBecomeActive: (UIApplication*) application; | |||
- (void) applicationWillResignActive: (UIApplication*) application; | |||
@end | |||
@@ -68,6 +72,18 @@ | |||
app->resumed(); | |||
} | |||
- (void) applicationDidBecomeActive: (UIApplication*) application | |||
{ | |||
(void) application; | |||
isIOSAppActive = true; | |||
} | |||
- (void) applicationWillResignActive: (UIApplication*) application | |||
{ | |||
(void) application; | |||
isIOSAppActive = false; | |||
} | |||
@end | |||
namespace juce | |||
@@ -34,8 +34,12 @@ static bool exeIsAvailable (const char* const executable) | |||
bool FileChooser::isPlatformDialogAvailable() | |||
{ | |||
#if JUCE_DISABLE_NATIVE_FILECHOOSERS | |||
return false; | |||
#else | |||
static bool canUseNativeBox = exeIsAvailable ("zenity") || exeIsAvailable ("kdialog"); | |||
return canUseNativeBox; | |||
#endif | |||
} | |||
void FileChooser::showPlatformDialog (Array<File>& results, | |||
@@ -98,6 +102,7 @@ void FileChooser::showPlatformDialog (Array<File>& results, | |||
args.add (startPath); | |||
args.add (filters.replaceCharacter (';', ' ')); | |||
args.add ("2>/dev/null"); | |||
} | |||
else | |||
{ | |||
@@ -131,8 +136,6 @@ void FileChooser::showPlatformDialog (Array<File>& results, | |||
args.add ("--filename=" + file.getFileName()); | |||
} | |||
args.add ("2>/dev/null"); | |||
ChildProcess child; | |||
if (child.start (args, ChildProcess::wantStdOut)) | |||
@@ -198,7 +198,11 @@ void FileChooser::showPlatformDialog (Array<File>& results, | |||
bool FileChooser::isPlatformDialogAvailable() | |||
{ | |||
#if JUCE_DISABLE_NATIVE_FILECHOOSERS | |||
return false; | |||
#else | |||
return true; | |||
#endif | |||
} | |||
#else | |||
@@ -476,7 +476,7 @@ public: | |||
void toBehind (ComponentPeer* other) override | |||
{ | |||
NSViewComponentPeer* const otherPeer = dynamic_cast <NSViewComponentPeer*> (other); | |||
NSViewComponentPeer* const otherPeer = dynamic_cast<NSViewComponentPeer*> (other); | |||
jassert (otherPeer != nullptr); // wrong type of window? | |||
if (otherPeer != nullptr) | |||
@@ -487,7 +487,7 @@ public: | |||
positioned: NSWindowBelow | |||
relativeTo: otherPeer->view]; | |||
} | |||
else | |||
else if (component.isVisible()) | |||
{ | |||
[window orderWindow: NSWindowBelow | |||
relativeTo: [otherPeer->window windowNumber]]; | |||
@@ -898,11 +898,7 @@ public: | |||
NSRect constrainRect (NSRect r) | |||
{ | |||
if (constrainer != nullptr | |||
#if defined (MAC_OS_X_VERSION_10_7) && (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7) | |||
&& ([window styleMask] & NSFullScreenWindowMask) == 0 | |||
#endif | |||
) | |||
if (constrainer != nullptr && ! isKioskMode()) | |||
{ | |||
Rectangle<int> pos (convertToRectInt (flippedScreenRect (r))); | |||
Rectangle<int> original (convertToRectInt (flippedScreenRect ([window frame]))); | |||
@@ -1600,7 +1596,7 @@ private: | |||
static NSRect firstRectForCharacterRange (id self, SEL, NSRange) | |||
{ | |||
if (NSViewComponentPeer* const owner = getOwner (self)) | |||
if (Component* const comp = dynamic_cast <Component*> (owner->findCurrentTextInputTarget())) | |||
if (Component* const comp = dynamic_cast<Component*> (owner->findCurrentTextInputTarget())) | |||
return flippedScreenRect (makeNSRect (comp->getScreenBounds())); | |||
return NSZeroRect; | |||
@@ -120,7 +120,11 @@ namespace FileChooserHelpers | |||
//============================================================================== | |||
bool FileChooser::isPlatformDialogAvailable() | |||
{ | |||
#if JUCE_DISABLE_NATIVE_FILECHOOSERS | |||
return false; | |||
#else | |||
return true; | |||
#endif | |||
} | |||
void FileChooser::showPlatformDialog (Array<File>& results, const String& title_, const File& currentFileOrDirectory, | |||
@@ -2135,7 +2135,8 @@ private: | |||
bool isConstrainedNativeWindow() const | |||
{ | |||
return constrainer != nullptr | |||
&& (styleFlags & (windowHasTitleBar | windowIsResizable)) == (windowHasTitleBar | windowIsResizable); | |||
&& (styleFlags & (windowHasTitleBar | windowIsResizable)) == (windowHasTitleBar | windowIsResizable) | |||
&& ! isKioskMode(); | |||
} | |||
Rectangle<int> getCurrentScaledBounds (float scale) const | |||
@@ -44,6 +44,8 @@ ComboBox::ComboBox (const String& name) | |||
isButtonDown (false), | |||
separatorPending (false), | |||
menuActive (false), | |||
scrollWheelEnabled (false), | |||
mouseWheelAccumulator (0), | |||
noChoicesMessage (TRANS("(no choices)")) | |||
{ | |||
setRepaintsOnMouseActivity (true); | |||
@@ -579,14 +581,24 @@ void ComboBox::mouseUp (const MouseEvent& e2) | |||
void ComboBox::mouseWheelMove (const MouseEvent& e, const MouseWheelDetails& wheel) | |||
{ | |||
#if 0 | |||
// NB: this is far too irritating if enabled, because on scrollable pages containing | |||
// comboboxes (e.g. introjucer settings pages), you can easily nudge them when trying to scroll | |||
if (! menuActive && wheel.deltaY != 0) | |||
nudgeSelectedItem (wheel.deltaY > 0 ? -1 : 1); | |||
if (! menuActive && scrollWheelEnabled && e.eventComponent == this && wheel.deltaY != 0) | |||
{ | |||
const int oldPos = (int) mouseWheelAccumulator; | |||
mouseWheelAccumulator += wheel.deltaY * 5.0f; | |||
const int delta = oldPos - (int) mouseWheelAccumulator; | |||
if (delta != 0) | |||
nudgeSelectedItem (delta); | |||
} | |||
else | |||
#endif | |||
{ | |||
Component::mouseWheelMove (e, wheel); | |||
} | |||
} | |||
void ComboBox::setScrollWheelEnabled (bool enabled) noexcept | |||
{ | |||
scrollWheelEnabled = enabled; | |||
} | |||
//============================================================================== | |||
@@ -313,6 +313,12 @@ public: | |||
/** Gives the ComboBox a tooltip. */ | |||
void setTooltip (const String& newTooltip) override; | |||
/** This can be used to allow the scroll-wheel to nudge the chosen item. | |||
By default it's disabled, and I'd recommend leaving it disabled if there's any | |||
chance that the control might be inside a scrollable list or viewport. | |||
*/ | |||
void setScrollWheelEnabled (bool enabled) noexcept; | |||
//============================================================================== | |||
/** A set of colour IDs to use to change the colour of various aspects of the combo box. | |||
@@ -410,7 +416,8 @@ private: | |||
OwnedArray <ItemInfo> items; | |||
Value currentId; | |||
int lastCurrentId; | |||
bool isButtonDown, separatorPending, menuActive; | |||
bool isButtonDown, separatorPending, menuActive, scrollWheelEnabled; | |||
float mouseWheelAccumulator; | |||
ListenerList <Listener> listeners; | |||
ScopedPointer<Label> label; | |||
String textWhenNothingSelected, noChoicesMessage; | |||
@@ -620,7 +620,6 @@ public: | |||
void setPopupMenuEnabled (bool menuEnabled); | |||
/** This can be used to stop the mouse scroll-wheel from moving the slider. | |||
By default it's enabled. | |||
*/ | |||
void setScrollWheelEnabled (bool enabled); | |||
@@ -134,9 +134,9 @@ public: | |||
bool deleteBackwards (bool moveInWholeWordSteps); | |||
bool deleteForwards (bool moveInWholeWordSteps); | |||
bool deleteWhitespaceBackwardsToTabStop(); | |||
bool copyToClipboard(); | |||
bool cutToClipboard(); | |||
bool pasteFromClipboard(); | |||
virtual bool copyToClipboard(); | |||
virtual bool cutToClipboard(); | |||
virtual bool pasteFromClipboard(); | |||
bool undo(); | |||
bool redo(); | |||
@@ -30,7 +30,10 @@ | |||
//============================================================================== | |||
/** | |||
On Windows and Linux only, this component sits in the taskbar tray as a small icon. | |||
This component sits in the taskbar tray as a small icon. | |||
(NB: The exact behaviour of this class will differ between OSes, and it | |||
isn't fully implemented for all OSes) | |||
To use it, just create one of these components, but don't attempt to make it | |||
visible, add it to a parent, or put it on the desktop. | |||
@@ -34,6 +34,7 @@ struct DownloadClickDetectorClass : public ObjCClass <NSObject> | |||
decidePolicyForNavigationAction, "v@:@@@@@"); | |||
addMethod (@selector (webView:didFinishLoadForFrame:), didFinishLoadForFrame, "v@:@@"); | |||
addMethod (@selector (webView:willCloseFrame:), willCloseFrame, "v@:@@"); | |||
addMethod (@selector (webView:runOpenPanelForFileButtonWithResultListener:allowMultipleFiles:), runOpenPanel, "v@:@@", @encode (BOOL)); | |||
registerClass(); | |||
} | |||
@@ -66,6 +67,21 @@ private: | |||
{ | |||
getOwner (self)->windowCloseRequest(); | |||
} | |||
static void runOpenPanel (id, SEL, WebView*, id<WebOpenPanelResultListener> resultListener, BOOL allowMultipleFiles) | |||
{ | |||
FileChooser chooser (TRANS("Select the file you want to upload..."), | |||
File::getSpecialLocation (File::userHomeDirectory), "*"); | |||
if (allowMultipleFiles ? chooser.browseForMultipleFilesToOpen() | |||
: chooser.browseForFileToOpen()) | |||
{ | |||
const Array<File>& files = chooser.getResults(); | |||
for (int i = 0; i < files.size(); ++i) | |||
[resultListener chooseFilename: juceStringToNS (files.getReference(i).getFullPathName())]; | |||
} | |||
} | |||
}; | |||
#else | |||
@@ -146,6 +162,7 @@ public: | |||
DownloadClickDetectorClass::setOwner (clickListener, owner); | |||
[webView setPolicyDelegate: clickListener]; | |||
[webView setFrameLoadDelegate: clickListener]; | |||
[webView setUIDelegate: clickListener]; | |||
#else | |||
webView = [[UIWebView alloc] initWithFrame: CGRectMake (0, 0, 1.0f, 1.0f)]; | |||
setView (webView); | |||
@@ -162,6 +179,7 @@ public: | |||
#if JUCE_MAC | |||
[webView setPolicyDelegate: nil]; | |||
[webView setFrameLoadDelegate: nil]; | |||
[webView setUIDelegate: nil]; | |||
[clickListener release]; | |||
#else | |||
webView.delegate = nil; | |||
@@ -558,6 +558,18 @@ public: | |||
return fBuffer; | |||
} | |||
char operator[](const size_t pos) const noexcept | |||
{ | |||
if (pos < fBufferLen) | |||
return fBuffer[pos]; | |||
carla_safe_assert("pos < fBufferLen", __FILE__, __LINE__); | |||
static char fallback; | |||
fallback = '\0'; | |||
return fallback; | |||
} | |||
char& operator[](const size_t pos) noexcept | |||
{ | |||
if (pos < fBufferLen) | |||