Browse Source

Delete old juce files

tags/2018-04-16
falkTX 7 years ago
parent
commit
b0d40d73b2
22 changed files with 0 additions and 7503 deletions
  1. +0
    -18
      libs/juce/source/README.txt
  2. +0
    -14
      libs/juce/source/doxygen/footer.html
  3. +0
    -311
      libs/juce/source/modules/juce_audio_basics/effects/juce_FFT.cpp
  4. +0
    -101
      libs/juce/source/modules/juce_audio_basics/effects/juce_FFT.h
  5. +0
    -387
      libs/juce/source/modules/juce_audio_formats/codecs/juce_QuickTimeAudioFormat.cpp
  6. +0
    -69
      libs/juce/source/modules/juce_audio_formats/codecs/juce_QuickTimeAudioFormat.h
  7. +0
    -144
      libs/juce/source/modules/juce_audio_processors/processors/juce_AudioPlayHead.h
  8. +0
    -56
      libs/juce/source/modules/juce_events/native/juce_ScopedXLock.h
  9. +0
    -153
      libs/juce/source/modules/juce_events/native/juce_linux-embed_Messaging.cpp
  10. +0
    -271
      libs/juce/source/modules/juce_gui_basics/native/juce_linux_Clipboard.cpp
  11. +0
    -4241
      libs/juce/source/modules/juce_gui_basics/native/juce_linux_Windowing.cpp
  12. +0
    -142
      libs/juce/source/modules/juce_gui_extra/native/juce_linux_SystemTrayIcon.cpp
  13. +0
    -122
      libs/juce/source/modules/juce_gui_extra/native/juce_linux_WebBrowserComponent.cpp
  14. +0
    -49
      libs/juce/source/modules/juce_tracktion_marketplace/juce_tracktion_marketplace.cpp
  15. +0
    -88
      libs/juce/source/modules/juce_tracktion_marketplace/juce_tracktion_marketplace.h
  16. +0
    -107
      libs/juce/source/modules/juce_tracktion_marketplace/marketplace/juce_KeyFileGeneration.h
  17. +0
    -283
      libs/juce/source/modules/juce_tracktion_marketplace/marketplace/juce_OnlineUnlockForm.cpp
  18. +0
    -88
      libs/juce/source/modules/juce_tracktion_marketplace/marketplace/juce_OnlineUnlockForm.h
  19. +0
    -496
      libs/juce/source/modules/juce_tracktion_marketplace/marketplace/juce_OnlineUnlockStatus.cpp
  20. +0
    -258
      libs/juce/source/modules/juce_tracktion_marketplace/marketplace/juce_OnlineUnlockStatus.h
  21. +0
    -54
      libs/juce/source/modules/juce_tracktion_marketplace/marketplace/juce_TracktionMarketplaceStatus.cpp
  22. +0
    -51
      libs/juce/source/modules/juce_tracktion_marketplace/marketplace/juce_TracktionMarketplaceStatus.h

+ 0
- 18
libs/juce/source/README.txt View File

@@ -1,18 +0,0 @@
# The JUCE Library
JUCE (Jules' Utility Class Extensions) is an all-encompassing
C++ framework for developing cross-platform software.
It contains pretty much everything you're likely to need to create
most applications, and is particularly well-suited for building
highly-customised GUIs, and for handling graphics and sound.
Most JUCE modules are shared under the GNU Public Licence
(GPLv2, v3, and the AGPLv3). This means that the code can
be freely copied and distributed, and costs nothing to use
in other GPL applications. The juce_audio_basics,
juce_audio_devices, juce_blocks_basics, juce_core and
juce_events modules are permissively licensed under the ISC.
For more information, visit the website:
http://www.juce.com

+ 0
- 14
libs/juce/source/doxygen/footer.html View File

@@ -1,14 +0,0 @@
<hr class="footer"/>
<address class="footer"><small>All content &copy ROLI Ltd.</small></address><br/>
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-19759318-1']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>
</body>
</html>

+ 0
- 311
libs/juce/source/modules/juce_audio_basics/effects/juce_FFT.cpp View File

@@ -1,311 +0,0 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2016 - ROLI Ltd.
Permission is granted to use this software under the terms of the ISC license
http://www.isc.org/downloads/software-support-policy/isc-license/
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH REGARD
TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT,
OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
OF THIS SOFTWARE.
-----------------------------------------------------------------------------
To release a closed-source product which uses other parts of JUCE not
licensed under the ISC terms, commercial licenses are available: visit
www.juce.com for more information.
==============================================================================
*/
// (For the moment, we'll implement a few local operators for this complex class - one
// day we'll probably either have a juce complex class, or use the C++11 one)
static FFT::Complex operator+ (FFT::Complex a, FFT::Complex b) noexcept { FFT::Complex c = { a.r + b.r, a.i + b.i }; return c; }
static FFT::Complex operator- (FFT::Complex a, FFT::Complex b) noexcept { FFT::Complex c = { a.r - b.r, a.i - b.i }; return c; }
static FFT::Complex operator* (FFT::Complex a, FFT::Complex b) noexcept { FFT::Complex c = { a.r * b.r - a.i * b.i, a.r * b.i + a.i * b.r }; return c; }
static FFT::Complex& operator+= (FFT::Complex& a, FFT::Complex b) noexcept { a.r += b.r; a.i += b.i; return a; }
//==============================================================================
struct FFT::FFTConfig
{
FFTConfig (int sizeOfFFT, bool isInverse)
: fftSize (sizeOfFFT), inverse (isInverse), twiddleTable ((size_t) sizeOfFFT)
{
for (int i = 0; i < fftSize; ++i)
{
const double phase = (isInverse ? 2.0 : -2.0) * double_Pi * i / fftSize;
twiddleTable[i].r = (float) cos (phase);
twiddleTable[i].i = (float) sin (phase);
}
const int root = (int) std::sqrt ((double) fftSize);
int divisor = 4, n = fftSize;
for (int i = 0; i < numElementsInArray (factors); ++i)
{
while ((n % divisor) != 0)
{
if (divisor == 2) divisor = 3;
else if (divisor == 4) divisor = 2;
else divisor += 2;
if (divisor > root)
divisor = n;
}
n /= divisor;
jassert (divisor == 1 || divisor == 2 || divisor == 4);
factors[i].radix = divisor;
factors[i].length = n;
}
}
void perform (const Complex* input, Complex* output) const noexcept
{
perform (input, output, 1, 1, factors);
}
const int fftSize;
const bool inverse;
struct Factor { int radix, length; };
Factor factors[32];
HeapBlock<Complex> twiddleTable;
void perform (const Complex* input, Complex* output, const int stride, const int strideIn, const Factor* facs) const noexcept
{
const Factor factor (*facs++);
Complex* const originalOutput = output;
const Complex* const outputEnd = output + factor.radix * factor.length;
if (stride == 1 && factor.radix <= 5)
{
for (int i = 0; i < factor.radix; ++i)
perform (input + stride * strideIn * i, output + i * factor.length, stride * factor.radix, strideIn, facs);
butterfly (factor, output, stride);
return;
}
if (factor.length == 1)
{
do
{
*output++ = *input;
input += stride * strideIn;
}
while (output < outputEnd);
}
else
{
do
{
perform (input, output, stride * factor.radix, strideIn, facs);
input += stride * strideIn;
output += factor.length;
}
while (output < outputEnd);
}
butterfly (factor, originalOutput, stride);
}
void butterfly (const Factor factor, Complex* data, const int stride) const noexcept
{
switch (factor.radix)
{
case 1: break;
case 2: butterfly2 (data, stride, factor.length); return;
case 4: butterfly4 (data, stride, factor.length); return;
default: jassertfalse; break;
}
Complex* scratch = static_cast<Complex*> (alloca (sizeof (Complex) * (size_t) factor.radix));
for (int i = 0; i < factor.length; ++i)
{
for (int k = i, q1 = 0; q1 < factor.radix; ++q1)
{
scratch[q1] = data[k];
k += factor.length;
}
for (int k = i, q1 = 0; q1 < factor.radix; ++q1)
{
int twiddleIndex = 0;
data[k] = scratch[0];
for (int q = 1; q < factor.radix; ++q)
{
twiddleIndex += stride * k;
if (twiddleIndex >= fftSize)
twiddleIndex -= fftSize;
data[k] += scratch[q] * twiddleTable[twiddleIndex];
}
k += factor.length;
}
}
}
void butterfly2 (Complex* data, const int stride, const int length) const noexcept
{
Complex* dataEnd = data + length;
const Complex* tw = twiddleTable;
for (int i = length; --i >= 0;)
{
const Complex s (*dataEnd * *tw);
tw += stride;
*dataEnd++ = *data - s;
*data++ += s;
}
}
void butterfly4 (Complex* data, const int stride, const int length) const noexcept
{
const int lengthX2 = length * 2;
const int lengthX3 = length * 3;
const Complex* twiddle1 = twiddleTable;
const Complex* twiddle2 = twiddle1;
const Complex* twiddle3 = twiddle1;
for (int i = length; --i >= 0;)
{
const Complex s0 = data[length] * *twiddle1;
const Complex s1 = data[lengthX2] * *twiddle2;
const Complex s2 = data[lengthX3] * *twiddle3;
const Complex s3 = s0 + s2;
const Complex s4 = s0 - s2;
const Complex s5 = *data - s1;
*data += s1;
data[lengthX2] = *data - s3;
twiddle1 += stride;
twiddle2 += stride * 2;
twiddle3 += stride * 3;
*data += s3;
if (inverse)
{
data[length].r = s5.r - s4.i;
data[length].i = s5.i + s4.r;
data[lengthX3].r = s5.r + s4.i;
data[lengthX3].i = s5.i - s4.r;
}
else
{
data[length].r = s5.r + s4.i;
data[length].i = s5.i - s4.r;
data[lengthX3].r = s5.r - s4.i;
data[lengthX3].i = s5.i + s4.r;
}
++data;
}
}
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FFTConfig)
};
//==============================================================================
FFT::FFT (int order, bool inverse) : config (new FFTConfig (1 << order, inverse)), size (1 << order) {}
FFT::~FFT() {}
void FFT::perform (const Complex* const input, Complex* const output) const noexcept
{
config->perform (input, output);
}
const size_t maxFFTScratchSpaceToAlloca = 256 * 1024;
void FFT::performRealOnlyForwardTransform (float* d) const noexcept
{
const size_t scratchSize = 16 + sizeof (FFT::Complex) * (size_t) size;
if (scratchSize < maxFFTScratchSpaceToAlloca)
{
performRealOnlyForwardTransform (static_cast<Complex*> (alloca (scratchSize)), d);
}
else
{
HeapBlock<char> heapSpace (scratchSize);
performRealOnlyForwardTransform (reinterpret_cast<Complex*> (heapSpace.getData()), d);
}
}
void FFT::performRealOnlyInverseTransform (float* d) const noexcept
{
const size_t scratchSize = 16 + sizeof (FFT::Complex) * (size_t) size;
if (scratchSize < maxFFTScratchSpaceToAlloca)
{
performRealOnlyInverseTransform (static_cast<Complex*> (alloca (scratchSize)), d);
}
else
{
HeapBlock<char> heapSpace (scratchSize);
performRealOnlyInverseTransform (reinterpret_cast<Complex*> (heapSpace.getData()), d);
}
}
void FFT::performRealOnlyForwardTransform (Complex* scratch, float* d) const noexcept
{
// This can only be called on an FFT object that was created to do forward transforms.
jassert (! config->inverse);
for (int i = 0; i < size; ++i)
{
scratch[i].r = d[i];
scratch[i].i = 0;
}
perform (scratch, reinterpret_cast<Complex*> (d));
}
void FFT::performRealOnlyInverseTransform (Complex* scratch, float* d) const noexcept
{
// This can only be called on an FFT object that was created to do inverse transforms.
jassert (config->inverse);
perform (reinterpret_cast<const Complex*> (d), scratch);
const float scaleFactor = 1.0f / size;
for (int i = 0; i < size; ++i)
{
d[i] = scratch[i].r * scaleFactor;
d[i + size] = scratch[i].i * scaleFactor;
}
}
void FFT::performFrequencyOnlyForwardTransform (float* d) const noexcept
{
performRealOnlyForwardTransform (d);
const int twiceSize = size * 2;
for (int i = 0; i < twiceSize; i += 2)
{
d[i / 2] = juce_hypot (d[i], d[i + 1]);
if (i >= size)
{
d[i] = 0;
d[i + 1] = 0;
}
}
}

+ 0
- 101
libs/juce/source/modules/juce_audio_basics/effects/juce_FFT.h View File

@@ -1,101 +0,0 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2016 - ROLI Ltd.
Permission is granted to use this software under the terms of the ISC license
http://www.isc.org/downloads/software-support-policy/isc-license/
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH REGARD
TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT,
OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
OF THIS SOFTWARE.
-----------------------------------------------------------------------------
To release a closed-source product which uses other parts of JUCE not
licensed under the ISC terms, commercial licenses are available: visit
www.juce.com for more information.
==============================================================================
*/
/**
A very minimal FFT class.
This is only a simple low-footprint implementation and isn't tuned for speed - it may
be useful for simple applications where one of the more complex FFT libraries would be
overkill. (But in the future it may end up becoming optimised of course...)
The FFT class itself contains lookup tables, so there's some overhead in creating
one, you should create and cache an FFT object for each size/direction of transform
that you need, and re-use them to perform the actual operation.
*/
class JUCE_API FFT
{
public:
/** Initialises an object for performing either a forward or inverse FFT with the given size.
The the number of points the FFT will operate on will be 2 ^ order.
*/
FFT (int order, bool isInverse);
/** Destructor. */
~FFT();
/** A complex number, for the purposes of the FFT class. */
struct Complex
{
float r; /**< Real part. */
float i; /**< Imaginary part. */
};
/** Performs an out-of-place FFT, either forward or inverse depending on the mode
that was passed to this object's constructor.
The arrays must contain at least getSize() elements.
*/
void perform (const Complex* input, Complex* output) const noexcept;
/** Performs an in-place forward transform on a block of real data.
The size of the array passed in must be 2 * getSize(), and the first half
should contain your raw input sample data. On return, the array will contain
complex frequency + phase data, and can be passed to performRealOnlyInverseTransform()
in order to convert it back to reals.
*/
void performRealOnlyForwardTransform (float* inputOutputData) const noexcept;
/** Performs a reverse operation to data created in performRealOnlyForwardTransform().
The size of the array passed in must be 2 * getSize(), containing complex
frequency and phase data. On return, the first half of the array will contain
the reconstituted samples.
*/
void performRealOnlyInverseTransform (float* inputOutputData) const noexcept;
/** Takes an array and simply transforms it to the frequency spectrum.
This may be handy for things like frequency displays or analysis.
*/
void performFrequencyOnlyForwardTransform (float* inputOutputData) const noexcept;
/** Returns the number of data points that this FFT was created to work with. */
int getSize() const noexcept { return size; }
private:
JUCE_PUBLIC_IN_DLL_BUILD (struct FFTConfig)
ScopedPointer<FFTConfig> config;
const int size;
void performRealOnlyForwardTransform (Complex*, float*) const noexcept;
void performRealOnlyInverseTransform (Complex*, float*) const noexcept;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (FFT)
};

+ 0
- 387
libs/juce/source/modules/juce_audio_formats/codecs/juce_QuickTimeAudioFormat.cpp View File

@@ -1,387 +0,0 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2015 - ROLI Ltd.
Permission is granted to use this software under the terms of either:
a) the GPL v2 (or any later version)
b) the Affero GPL v3
Details of these licenses can be found at: www.gnu.org/licenses
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
------------------------------------------------------------------------------
To release a closed-source product which uses JUCE, commercial licenses are
available: visit www.juce.com for more information.
==============================================================================
*/
#if JUCE_QUICKTIME && ! (JUCE_64BIT || JUCE_IOS)
} // (juce namespace)
#if ! JUCE_WINDOWS
#include <QuickTime/Movies.h>
#include <QuickTime/QTML.h>
#include <QuickTime/QuickTimeComponents.h>
#include <QuickTime/MediaHandlers.h>
#include <QuickTime/ImageCodec.h>
#else
#if JUCE_MSVC
#pragma warning (push)
#pragma warning (disable : 4100)
#endif
/* If you've got an include error here, you probably need to install the QuickTime SDK and
add its header directory to your include path.
Alternatively, if you don't need any QuickTime services, just set the JUCE_QUICKTIME flag to 0.
*/
#undef SIZE_MAX
#include <Movies.h>
#include <QTML.h>
#include <QuickTimeComponents.h>
#include <MediaHandlers.h>
#include <ImageCodec.h>
#undef SIZE_MAX
#if JUCE_MSVC
#pragma warning (pop)
#endif
#endif
namespace juce
{
bool juce_OpenQuickTimeMovieFromStream (InputStream* input, Movie& movie, Handle& dataHandle);
static const char* const quickTimeFormatName = "QuickTime file";
//==============================================================================
class QTAudioReader : public AudioFormatReader
{
public:
QTAudioReader (InputStream* const input_, const int trackNum_)
: AudioFormatReader (input_, quickTimeFormatName),
ok (false),
movie (0),
trackNum (trackNum_),
lastSampleRead (0),
lastThreadId (0),
extractor (0),
dataHandle (0)
{
JUCE_AUTORELEASEPOOL
{
bufferList.calloc (256, 1);
#if JUCE_WINDOWS
if (InitializeQTML (0) != noErr)
return;
#endif
if (EnterMovies() != noErr)
return;
bool opened = juce_OpenQuickTimeMovieFromStream (input_, movie, dataHandle);
if (! opened)
return;
{
const int numTracks = GetMovieTrackCount (movie);
int trackCount = 0;
for (int i = 1; i <= numTracks; ++i)
{
track = GetMovieIndTrack (movie, i);
media = GetTrackMedia (track);
OSType mediaType;
GetMediaHandlerDescription (media, &mediaType, 0, 0);
if (mediaType == SoundMediaType
&& trackCount++ == trackNum_)
{
ok = true;
break;
}
}
}
if (! ok)
return;
ok = false;
lengthInSamples = GetMediaDecodeDuration (media);
usesFloatingPointData = false;
samplesPerFrame = (int) (GetMediaDecodeDuration (media) / GetMediaSampleCount (media));
trackUnitsPerFrame = GetMovieTimeScale (movie) * samplesPerFrame
/ GetMediaTimeScale (media);
MovieAudioExtractionBegin (movie, 0, &extractor);
unsigned long output_layout_size;
OSStatus err = MovieAudioExtractionGetPropertyInfo (extractor,
kQTPropertyClass_MovieAudioExtraction_Audio,
kQTMovieAudioExtractionAudioPropertyID_AudioChannelLayout,
0, &output_layout_size, 0);
if (err != noErr)
return;
HeapBlock<AudioChannelLayout> qt_audio_channel_layout;
qt_audio_channel_layout.calloc (output_layout_size, 1);
MovieAudioExtractionGetProperty (extractor,
kQTPropertyClass_MovieAudioExtraction_Audio,
kQTMovieAudioExtractionAudioPropertyID_AudioChannelLayout,
output_layout_size, qt_audio_channel_layout, 0);
qt_audio_channel_layout[0].mChannelLayoutTag = kAudioChannelLayoutTag_Stereo;
MovieAudioExtractionSetProperty (extractor,
kQTPropertyClass_MovieAudioExtraction_Audio,
kQTMovieAudioExtractionAudioPropertyID_AudioChannelLayout,
output_layout_size,
qt_audio_channel_layout);
err = MovieAudioExtractionGetProperty (extractor,
kQTPropertyClass_MovieAudioExtraction_Audio,
kQTMovieAudioExtractionAudioPropertyID_AudioStreamBasicDescription,
sizeof (inputStreamDesc),
&inputStreamDesc, 0);
if (err != noErr)
return;
inputStreamDesc.mFormatFlags = kAudioFormatFlagIsSignedInteger
| kAudioFormatFlagIsPacked
| kAudioFormatFlagsNativeEndian;
inputStreamDesc.mBitsPerChannel = sizeof (SInt16) * 8;
inputStreamDesc.mChannelsPerFrame = jmin ((UInt32) 2, inputStreamDesc.mChannelsPerFrame);
inputStreamDesc.mBytesPerFrame = sizeof (SInt16) * inputStreamDesc.mChannelsPerFrame;
inputStreamDesc.mBytesPerPacket = inputStreamDesc.mBytesPerFrame;
err = MovieAudioExtractionSetProperty (extractor,
kQTPropertyClass_MovieAudioExtraction_Audio,
kQTMovieAudioExtractionAudioPropertyID_AudioStreamBasicDescription,
sizeof (inputStreamDesc),
&inputStreamDesc);
if (err != noErr)
return;
Boolean allChannelsDiscrete = false;
err = MovieAudioExtractionSetProperty (extractor,
kQTPropertyClass_MovieAudioExtraction_Movie,
kQTMovieAudioExtractionMoviePropertyID_AllChannelsDiscrete,
sizeof (allChannelsDiscrete),
&allChannelsDiscrete);
if (err != noErr)
return;
bufferList->mNumberBuffers = 1;
bufferList->mBuffers[0].mNumberChannels = inputStreamDesc.mChannelsPerFrame;
bufferList->mBuffers[0].mDataByteSize = jmax ((UInt32) 4096, (UInt32) (samplesPerFrame * (int) inputStreamDesc.mBytesPerFrame) + 16);
dataBuffer.malloc (bufferList->mBuffers[0].mDataByteSize);
bufferList->mBuffers[0].mData = dataBuffer;
sampleRate = inputStreamDesc.mSampleRate;
bitsPerSample = 16;
numChannels = inputStreamDesc.mChannelsPerFrame;
detachThread();
ok = true;
}
}
~QTAudioReader()
{
JUCE_AUTORELEASEPOOL
{
checkThreadIsAttached();
if (dataHandle != nullptr)
DisposeHandle (dataHandle);
if (extractor != nullptr)
{
MovieAudioExtractionEnd (extractor);
extractor = nullptr;
}
DisposeMovie (movie);
#if JUCE_MAC
ExitMoviesOnThread();
#endif
}
}
bool readSamples (int** destSamples, int numDestChannels, int startOffsetInDestBuffer,
int64 startSampleInFile, int numSamples)
{
JUCE_AUTORELEASEPOOL
{
checkThreadIsAttached();
bool readOk = true;
while (numSamples > 0)
{
if (lastSampleRead != startSampleInFile)
{
TimeRecord time;
time.scale = (TimeScale) inputStreamDesc.mSampleRate;
time.base = 0;
time.value.hi = 0;
time.value.lo = (UInt32) startSampleInFile;
OSStatus err = MovieAudioExtractionSetProperty (extractor,
kQTPropertyClass_MovieAudioExtraction_Movie,
kQTMovieAudioExtractionMoviePropertyID_CurrentTime,
sizeof (time), &time);
if (err != noErr)
{
readOk = false;
break;
}
}
int framesToDo = jmin (numSamples, (int) (bufferList->mBuffers[0].mDataByteSize / inputStreamDesc.mBytesPerFrame));
bufferList->mBuffers[0].mDataByteSize = inputStreamDesc.mBytesPerFrame * (UInt32) framesToDo;
UInt32 outFlags = 0;
UInt32 actualNumFrames = (UInt32) framesToDo;
OSStatus err = MovieAudioExtractionFillBuffer (extractor, &actualNumFrames, bufferList, &outFlags);
if (err != noErr)
{
readOk = false;
break;
}
lastSampleRead = startSampleInFile + actualNumFrames;
const int samplesReceived = (int) actualNumFrames;
for (int j = numDestChannels; --j >= 0;)
{
if (destSamples[j] != nullptr)
{
const short* src = ((const short*) bufferList->mBuffers[0].mData) + j;
for (int i = 0; i < samplesReceived; ++i)
{
destSamples[j][startOffsetInDestBuffer + i] = (*src << 16);
src += numChannels;
}
}
}
startOffsetInDestBuffer += samplesReceived;
startSampleInFile += samplesReceived;
numSamples -= samplesReceived;
if (((outFlags & kQTMovieAudioExtractionComplete) != 0 || samplesReceived == 0) && numSamples > 0)
{
for (int j = numDestChannels; --j >= 0;)
if (destSamples[j] != nullptr)
zeromem (destSamples[j] + startOffsetInDestBuffer, sizeof (int) * (size_t) numSamples);
break;
}
}
detachThread();
return readOk;
}
}
bool ok;
private:
Movie movie;
Media media;
Track track;
const int trackNum;
double trackUnitsPerFrame;
int samplesPerFrame;
int64 lastSampleRead;
Thread::ThreadID lastThreadId;
MovieAudioExtractionRef extractor;
AudioStreamBasicDescription inputStreamDesc;
HeapBlock<AudioBufferList> bufferList;
HeapBlock<char> dataBuffer;
Handle dataHandle;
//==============================================================================
void checkThreadIsAttached()
{
#if JUCE_MAC
if (Thread::getCurrentThreadId() != lastThreadId)
EnterMoviesOnThread (0);
AttachMovieToCurrentThread (movie);
#endif
}
void detachThread()
{
#if JUCE_MAC
DetachMovieFromCurrentThread (movie);
#endif
}
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (QTAudioReader)
};
//==============================================================================
QuickTimeAudioFormat::QuickTimeAudioFormat() : AudioFormat (quickTimeFormatName, ".mov .mp3 .mp4 .m4a")
{
}
QuickTimeAudioFormat::~QuickTimeAudioFormat()
{
}
Array<int> QuickTimeAudioFormat::getPossibleSampleRates() { return Array<int>(); }
Array<int> QuickTimeAudioFormat::getPossibleBitDepths() { return Array<int>(); }
bool QuickTimeAudioFormat::canDoStereo() { return true; }
bool QuickTimeAudioFormat::canDoMono() { return true; }
//==============================================================================
AudioFormatReader* QuickTimeAudioFormat::createReaderFor (InputStream* sourceStream,
const bool deleteStreamIfOpeningFails)
{
ScopedPointer<QTAudioReader> r (new QTAudioReader (sourceStream, 0));
if (r->ok)
return r.release();
if (! deleteStreamIfOpeningFails)
r->input = 0;
return nullptr;
}
AudioFormatWriter* QuickTimeAudioFormat::createWriterFor (OutputStream* /*streamToWriteTo*/,
double /*sampleRateToUse*/,
unsigned int /*numberOfChannels*/,
int /*bitsPerSample*/,
const StringPairArray& /*metadataValues*/,
int /*qualityOptionIndex*/)
{
jassertfalse; // not yet implemented!
return nullptr;
}
#endif

+ 0
- 69
libs/juce/source/modules/juce_audio_formats/codecs/juce_QuickTimeAudioFormat.h View File

@@ -1,69 +0,0 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2015 - ROLI Ltd.
Permission is granted to use this software under the terms of either:
a) the GPL v2 (or any later version)
b) the Affero GPL v3
Details of these licenses can be found at: www.gnu.org/licenses
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
------------------------------------------------------------------------------
To release a closed-source product which uses JUCE, commercial licenses are
available: visit www.juce.com for more information.
==============================================================================
*/
#if JUCE_QUICKTIME
//==============================================================================
/**
Uses QuickTime to read the audio track a movie or media file.
As well as QuickTime movies, this should also manage to open other audio
files that quicktime can understand, like mp3, m4a, etc.
@see AudioFormat
*/
class JUCE_API QuickTimeAudioFormat : public AudioFormat
{
public:
//==============================================================================
/** Creates a format object. */
QuickTimeAudioFormat();
/** Destructor. */
~QuickTimeAudioFormat();
//==============================================================================
Array<int> getPossibleSampleRates();
Array<int> getPossibleBitDepths();
bool canDoStereo();
bool canDoMono();
//==============================================================================
AudioFormatReader* createReaderFor (InputStream* sourceStream,
bool deleteStreamIfOpeningFails);
AudioFormatWriter* createWriterFor (OutputStream* streamToWriteTo,
double sampleRateToUse,
unsigned int numberOfChannels,
int bitsPerSample,
const StringPairArray& metadataValues,
int qualityOptionIndex);
private:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (QuickTimeAudioFormat)
};
#endif

+ 0
- 144
libs/juce/source/modules/juce_audio_processors/processors/juce_AudioPlayHead.h View File

@@ -1,144 +0,0 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2015 - ROLI Ltd.
Permission is granted to use this software under the terms of either:
a) the GPL v2 (or any later version)
b) the Affero GPL v3
Details of these licenses can be found at: www.gnu.org/licenses
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
------------------------------------------------------------------------------
To release a closed-source product which uses JUCE, commercial licenses are
available: visit www.juce.com for more information.
==============================================================================
*/
#ifndef JUCE_AUDIOPLAYHEAD_H_INCLUDED
#define JUCE_AUDIOPLAYHEAD_H_INCLUDED
//==============================================================================
/**
A subclass of AudioPlayHead can supply information about the position and
status of a moving play head during audio playback.
One of these can be supplied to an AudioProcessor object so that it can find
out about the position of the audio that it is rendering.
@see AudioProcessor::setPlayHead, AudioProcessor::getPlayHead
*/
class JUCE_API AudioPlayHead
{
protected:
//==============================================================================
AudioPlayHead() {}
public:
virtual ~AudioPlayHead() {}
//==============================================================================
/** Frame rate types. */
enum FrameRateType
{
fps24 = 0,
fps25 = 1,
fps2997 = 2,
fps30 = 3,
fps2997drop = 4,
fps30drop = 5,
fpsUnknown = 99
};
//==============================================================================
/** This structure is filled-in by the AudioPlayHead::getCurrentPosition() method.
*/
struct JUCE_API CurrentPositionInfo
{
/** The tempo in BPM */
double bpm;
/** Time signature numerator, e.g. the 3 of a 3/4 time sig */
int timeSigNumerator;
/** Time signature denominator, e.g. the 4 of a 3/4 time sig */
int timeSigDenominator;
/** The current play position, in samples from the start of the edit. */
int64 timeInSamples;
/** The current play position, in seconds from the start of the edit. */
double timeInSeconds;
/** For timecode, the position of the start of the edit, in seconds from 00:00:00:00. */
double editOriginTime;
/** The current play position, in pulses-per-quarter-note. */
double ppqPosition;
/** The position of the start of the last bar, in pulses-per-quarter-note.
This is the time from the start of the edit to the start of the current
bar, in ppq units.
Note - this value may be unavailable on some hosts, e.g. Pro-Tools. If
it's not available, the value will be 0.
*/
double ppqPositionOfLastBarStart;
/** The video frame rate, if applicable. */
FrameRateType frameRate;
/** True if the transport is currently playing. */
bool isPlaying;
/** True if the transport is currently recording.
(When isRecording is true, then isPlaying will also be true).
*/
bool isRecording;
/** The current cycle start position in pulses-per-quarter-note.
Note that not all hosts or plugin formats may provide this value.
@see isLooping
*/
double ppqLoopStart;
/** The current cycle end position in pulses-per-quarter-note.
Note that not all hosts or plugin formats may provide this value.
@see isLooping
*/
double ppqLoopEnd;
/** True if the transport is currently looping. */
bool isLooping;
//==============================================================================
bool operator== (const CurrentPositionInfo& other) const noexcept;
bool operator!= (const CurrentPositionInfo& other) const noexcept;
void resetToDefault();
};
//==============================================================================
/** Fills-in the given structure with details about the transport's
position at the start of the current processing block. If this method returns
false then the current play head position is not available and the given
structure will be undefined.
You can ONLY call this from your processBlock() method! Calling it at other
times will produce undefined behaviour, as the host may not have any context
in which a time would make sense, and some hosts will almost certainly have
multithreading issues if it's not called on the audio thread.
*/
virtual bool getCurrentPosition (CurrentPositionInfo& result) = 0;
};
#endif // JUCE_AUDIOPLAYHEAD_H_INCLUDED

+ 0
- 56
libs/juce/source/modules/juce_events/native/juce_ScopedXLock.h View File

@@ -1,56 +0,0 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2016 - ROLI Ltd.
Permission is granted to use this software under the terms of the ISC license
http://www.isc.org/downloads/software-support-policy/isc-license/
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH REGARD
TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT,
OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
OF THIS SOFTWARE.
-----------------------------------------------------------------------------
To release a closed-source product which uses other parts of JUCE not
licensed under the ISC terms, commercial licenses are available: visit
www.juce.com for more information.
==============================================================================
*/
#ifndef JUCE_SCOPEDXLOCK_H_INCLUDED
#define JUCE_SCOPEDXLOCK_H_INCLUDED
//==============================================================================
#if JUCE_LINUX || DOXYGEN
/** A handy class that uses XLockDisplay and XUnlockDisplay to lock the X server
using RAII (Only available in Linux!).
*/
class ScopedXLock
{
public:
/** Creating a ScopedXLock object locks the X display.
This uses XLockDisplay() to grab the display that Juce is using.
*/
ScopedXLock();
/** Deleting a ScopedXLock object unlocks the X display.
This calls XUnlockDisplay() to release the lock.
*/
~ScopedXLock();
};
#endif
#endif // JUCE_SCOPEDXLOCK_H_INCLUDED

+ 0
- 153
libs/juce/source/modules/juce_events/native/juce_linux-embed_Messaging.cpp View File

@@ -1,153 +0,0 @@
/*
==============================================================================

This file is part of the JUCE library.
Copyright (c) 2016 - ROLI Ltd.

Permission is granted to use this software under the terms of the ISC license
http://www.isc.org/downloads/software-support-policy/isc-license/

Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.

THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH REGARD
TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT,
OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
OF THIS SOFTWARE.

-----------------------------------------------------------------------------

To release a closed-source product which uses other parts of JUCE not
licensed under the ISC terms, commercial licenses are available: visit
www.juce.com for more information.

==============================================================================
*/

//==============================================================================
class EventsThread : public Thread
{
public:
EventsThread()
: Thread("EventsThread"),
initializing(false) {}

~EventsThread()
{
signalThreadShouldExit();
stopThread(2000);

const ScopedLock sl(queueLock);
jassert(queue.size() == 0);
queue.clear();
}

bool postMessage(MessageManager::MessageBase* const msg)
{
const ScopedLock sl(queueLock);
queue.add(msg);
return true;
}

bool isInitializing() const noexcept
{
return initializing;
}

protected:
void run() override
{
/*
* We need to know when we're initializing because MessageManager::setCurrentThreadAsMessageThread()
* calls doPlatformSpecificInitialisation/Shutdown, in which we started this thread previously.
* To avoid a deadlock we do not call start/stopThread if still initializing.
*/
initializing = true;

if (MessageManager* const msgMgr = MessageManager::getInstance())
msgMgr->setCurrentThreadAsMessageThread();

initializing = false;

for (; ! threadShouldExit();)
{
// dispatch messages until no more present, then sleep
for (; dispatchNextInternalMessage();) {}

sleep(25);
}
}

private:
volatile bool initializing;
ReferenceCountedArray<MessageManager::MessageBase> queue;
CriticalSection queueLock;

MessageManager::MessageBase::Ptr popNextMessage()
{
const ScopedLock sl(queueLock);
return queue.removeAndReturn(0);
}

bool dispatchNextInternalMessage()
{
if (const MessageManager::MessageBase::Ptr msg = popNextMessage())
{
JUCE_TRY
{
msg->messageCallback();
return true;
}
JUCE_CATCH_EXCEPTION
}

return false;
}

JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(EventsThread)
};

static EventsThread& getEventsThreadInstance()
{
static EventsThread eventsThread;
return eventsThread;
}

//==============================================================================
void MessageManager::doPlatformSpecificInitialisation()
{
EventsThread& eventsThread(getEventsThreadInstance());

if (! eventsThread.isInitializing())
eventsThread.startThread();
}

void MessageManager::doPlatformSpecificShutdown()
{
EventsThread& eventsThread(getEventsThreadInstance());

if (! eventsThread.isInitializing())
eventsThread.stopThread(-1);
}

bool MessageManager::postMessageToSystemQueue (MessageManager::MessageBase* const message)
{
EventsThread& eventsThread(getEventsThreadInstance());
return eventsThread.postMessage(message);
}

void MessageManager::broadcastMessage (const String& /* value */)
{
/* TODO */
}

// this function expects that it will NEVER be called simultaneously for two concurrent threads
bool MessageManager::dispatchNextMessageOnSystemQueue (bool returnIfNoPendingMessages)
{
DBG ("MessageManager::dispatchNextMessageOnSystemQueue() unsupported");
return false;
}

+ 0
- 271
libs/juce/source/modules/juce_gui_basics/native/juce_linux_Clipboard.cpp View File

@@ -1,271 +0,0 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2015 - ROLI Ltd.
Permission is granted to use this software under the terms of either:
a) the GPL v2 (or any later version)
b) the Affero GPL v3
Details of these licenses can be found at: www.gnu.org/licenses
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
------------------------------------------------------------------------------
To release a closed-source product which uses JUCE, commercial licenses are
available: visit www.juce.com for more information.
==============================================================================
*/
extern ::Display* display;
extern ::Window juce_messageWindowHandle;
namespace ClipboardHelpers
{
static String localClipboardContent;
static Atom atom_UTF8_STRING;
static Atom atom_CLIPBOARD;
static Atom atom_TARGETS;
//==============================================================================
static void initSelectionAtoms()
{
static bool isInitialised = false;
if (! isInitialised)
{
isInitialised = true;
atom_UTF8_STRING = XInternAtom (display, "UTF8_STRING", False);
atom_CLIPBOARD = XInternAtom (display, "CLIPBOARD", False);
atom_TARGETS = XInternAtom (display, "TARGETS", False);
}
}
//==============================================================================
// Read the content of a window property as either a locale-dependent string or an utf8 string
// works only for strings shorter than 1000000 bytes
static String readWindowProperty (Window window, Atom prop)
{
String returnData;
if (display != nullptr)
{
char* clipData;
Atom actualType;
int actualFormat;
unsigned long numItems, bytesLeft;
if (XGetWindowProperty (display, window, prop,
0L /* offset */, 1000000 /* length (max) */, False,
AnyPropertyType /* format */,
&actualType, &actualFormat, &numItems, &bytesLeft,
(unsigned char**) &clipData) == Success)
{
if (actualType == atom_UTF8_STRING && actualFormat == 8)
returnData = String::fromUTF8 (clipData, (int) numItems);
else if (actualType == XA_STRING && actualFormat == 8)
returnData = String (clipData, numItems);
if (clipData != nullptr)
XFree (clipData);
jassert (bytesLeft == 0 || numItems == 1000000);
}
XDeleteProperty (display, window, prop);
}
return returnData;
}
//==============================================================================
// Send a SelectionRequest to the window owning the selection and waits for its answer (with a timeout) */
static bool requestSelectionContent (String& selectionContent, Atom selection, Atom requestedFormat)
{
Atom property_name = XInternAtom (display, "JUCE_SEL", false);
// The selection owner will be asked to set the JUCE_SEL property on the
// juce_messageWindowHandle with the selection content
XConvertSelection (display, selection, requestedFormat, property_name,
juce_messageWindowHandle, CurrentTime);
int count = 50; // will wait at most for 200 ms
while (--count >= 0)
{
XEvent event;
if (XCheckTypedWindowEvent (display, juce_messageWindowHandle, SelectionNotify, &event))
{
if (event.xselection.property == property_name)
{
jassert (event.xselection.requestor == juce_messageWindowHandle);
selectionContent = readWindowProperty (event.xselection.requestor,
event.xselection.property);
return true;
}
return false; // the format we asked for was denied.. (event.xselection.property == None)
}
// not very elegant.. we could do a select() or something like that...
// however clipboard content requesting is inherently slow on x11, it
// often takes 50ms or more so...
Thread::sleep (4);
}
return false;
}
//==============================================================================
// Called from the event loop in juce_linux_Messaging in response to SelectionRequest events
static void handleSelection (XSelectionRequestEvent& evt)
{
if (display != nullptr)
{
ClipboardHelpers::initSelectionAtoms();
// the selection content is sent to the target window as a window property
XSelectionEvent reply;
reply.type = SelectionNotify;
reply.display = evt.display;
reply.requestor = evt.requestor;
reply.selection = evt.selection;
reply.target = evt.target;
reply.property = None; // == "fail"
reply.time = evt.time;
HeapBlock<char> data;
int propertyFormat = 0;
size_t numDataItems = 0;
if (evt.selection == XA_PRIMARY || evt.selection == ClipboardHelpers::atom_CLIPBOARD)
{
if (evt.target == XA_STRING || evt.target == ClipboardHelpers::atom_UTF8_STRING)
{
// translate to utf8
numDataItems = ClipboardHelpers::localClipboardContent.getNumBytesAsUTF8() + 1;
data.calloc (numDataItems + 1);
ClipboardHelpers::localClipboardContent.copyToUTF8 (data, numDataItems);
propertyFormat = 8; // bits/item
}
else if (evt.target == ClipboardHelpers::atom_TARGETS)
{
// another application wants to know what we are able to send
numDataItems = 2;
propertyFormat = 32; // atoms are 32-bit
data.calloc (numDataItems * 4);
Atom* atoms = reinterpret_cast<Atom*> (data.getData());
atoms[0] = ClipboardHelpers::atom_UTF8_STRING;
atoms[1] = XA_STRING;
evt.target = XA_ATOM;
}
}
else
{
DBG ("requested unsupported clipboard");
}
if (data != nullptr)
{
const size_t maxReasonableSelectionSize = 1000000;
// for very big chunks of data, we should use the "INCR" protocol , which is a pain in the *ss
if (evt.property != None && numDataItems < maxReasonableSelectionSize)
{
XChangeProperty (evt.display, evt.requestor,
evt.property, evt.target,
propertyFormat /* 8 or 32 */, PropModeReplace,
reinterpret_cast<const unsigned char*> (data.getData()), (int) numDataItems);
reply.property = evt.property; // " == success"
}
}
XSendEvent (evt.display, evt.requestor, 0, NoEventMask, (XEvent*) &reply);
}
}
}
//==============================================================================
typedef void (*SelectionRequestCallback) (XSelectionRequestEvent&);
extern SelectionRequestCallback handleSelectionRequest;
struct ClipboardCallbackInitialiser
{
ClipboardCallbackInitialiser()
{
handleSelectionRequest = ClipboardHelpers::handleSelection;
}
};
static ClipboardCallbackInitialiser clipboardInitialiser;
//==============================================================================
void SystemClipboard::copyTextToClipboard (const String& clipText)
{
if (display != nullptr)
{
ClipboardHelpers::initSelectionAtoms();
ClipboardHelpers::localClipboardContent = clipText;
XSetSelectionOwner (display, XA_PRIMARY, juce_messageWindowHandle, CurrentTime);
XSetSelectionOwner (display, ClipboardHelpers::atom_CLIPBOARD, juce_messageWindowHandle, CurrentTime);
}
}
String SystemClipboard::getTextFromClipboard()
{
String content;
if (display != nullptr)
{
ClipboardHelpers::initSelectionAtoms();
/* 1) try to read from the "CLIPBOARD" selection first (the "high
level" clipboard that is supposed to be filled by ctrl-C
etc). When a clipboard manager is running, the content of this
selection is preserved even when the original selection owner
exits.
2) and then try to read from "PRIMARY" selection (the "legacy" selection
filled by good old x11 apps such as xterm)
*/
Atom selection = XA_PRIMARY;
Window selectionOwner = None;
if ((selectionOwner = XGetSelectionOwner (display, selection)) == None)
{
selection = ClipboardHelpers::atom_CLIPBOARD;
selectionOwner = XGetSelectionOwner (display, selection);
}
if (selectionOwner != None)
{
if (selectionOwner == juce_messageWindowHandle)
{
content = ClipboardHelpers::localClipboardContent;
}
else
{
// first try: we want an utf8 string
bool ok = ClipboardHelpers::requestSelectionContent (content, selection, ClipboardHelpers::atom_UTF8_STRING);
if (! ok)
{
// second chance, ask for a good old locale-dependent string ..
ok = ClipboardHelpers::requestSelectionContent (content, selection, XA_STRING);
}
}
}
}
return content;
}

+ 0
- 4241
libs/juce/source/modules/juce_gui_basics/native/juce_linux_Windowing.cpp
File diff suppressed because it is too large
View File


+ 0
- 142
libs/juce/source/modules/juce_gui_extra/native/juce_linux_SystemTrayIcon.cpp View File

@@ -1,142 +0,0 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2015 - ROLI Ltd.
Permission is granted to use this software under the terms of either:
a) the GPL v2 (or any later version)
b) the Affero GPL v3
Details of these licenses can be found at: www.gnu.org/licenses
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
------------------------------------------------------------------------------
To release a closed-source product which uses JUCE, commercial licenses are
available: visit www.juce.com for more information.
==============================================================================
*/
extern ::Display* display;
//==============================================================================
class SystemTrayIconComponent::Pimpl
{
public:
Pimpl (const Image& im, Window windowH) : image (im)
{
ScopedXLock xlock;
Screen* const screen = XDefaultScreenOfDisplay (display);
const int screenNumber = XScreenNumberOfScreen (screen);
String screenAtom ("_NET_SYSTEM_TRAY_S");
screenAtom << screenNumber;
Atom selectionAtom = XInternAtom (display, screenAtom.toUTF8(), false);
XGrabServer (display);
Window managerWin = XGetSelectionOwner (display, selectionAtom);
if (managerWin != None)
XSelectInput (display, managerWin, StructureNotifyMask);
XUngrabServer (display);
XFlush (display);
if (managerWin != None)
{
XEvent ev = { 0 };
ev.xclient.type = ClientMessage;
ev.xclient.window = managerWin;
ev.xclient.message_type = XInternAtom (display, "_NET_SYSTEM_TRAY_OPCODE", False);
ev.xclient.format = 32;
ev.xclient.data.l[0] = CurrentTime;
ev.xclient.data.l[1] = 0 /*SYSTEM_TRAY_REQUEST_DOCK*/;
ev.xclient.data.l[2] = (long) windowH;
ev.xclient.data.l[3] = 0;
ev.xclient.data.l[4] = 0;
XSendEvent (display, managerWin, False, NoEventMask, &ev);
XSync (display, False);
}
// For older KDE's ...
long atomData = 1;
Atom trayAtom = XInternAtom (display, "KWM_DOCKWINDOW", false);
XChangeProperty (display, windowH, trayAtom, trayAtom, 32, PropModeReplace, (unsigned char*) &atomData, 1);
// For more recent KDE's...
trayAtom = XInternAtom (display, "_KDE_NET_WM_SYSTEM_TRAY_WINDOW_FOR", false);
XChangeProperty (display, windowH, trayAtom, XA_WINDOW, 32, PropModeReplace, (unsigned char*) &windowH, 1);
// A minimum size must be specified for GNOME and Xfce, otherwise the icon is displayed with a width of 1
XSizeHints* hints = XAllocSizeHints();
hints->flags = PMinSize;
hints->min_width = 22;
hints->min_height = 22;
XSetWMNormalHints (display, windowH, hints);
XFree (hints);
}
Image image;
private:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Pimpl)
};
//==============================================================================
void SystemTrayIconComponent::setIconImage (const Image& newImage)
{
pimpl = nullptr;
if (newImage.isValid())
{
if (! isOnDesktop())
addToDesktop (0);
pimpl = new Pimpl (newImage, (Window) getWindowHandle());
setVisible (true);
toFront (false);
}
repaint();
}
void SystemTrayIconComponent::paint (Graphics& g)
{
if (pimpl != nullptr)
g.drawImage (pimpl->image, getLocalBounds().toFloat(),
RectanglePlacement::xLeft | RectanglePlacement::yTop | RectanglePlacement::onlyReduceInSize);
}
void SystemTrayIconComponent::setIconTooltip (const String& /*tooltip*/)
{
// xxx Not implemented!
}
void SystemTrayIconComponent::setHighlighted (bool)
{
// xxx Not implemented!
}
void SystemTrayIconComponent::showInfoBubble (const String& /*title*/, const String& /*content*/)
{
// xxx Not implemented!
}
void SystemTrayIconComponent::hideInfoBubble()
{
// xxx Not implemented!
}
void* SystemTrayIconComponent::getNativeHandle() const
{
return getWindowHandle();
}

+ 0
- 122
libs/juce/source/modules/juce_gui_extra/native/juce_linux_WebBrowserComponent.cpp View File

@@ -1,122 +0,0 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2015 - ROLI Ltd.
Permission is granted to use this software under the terms of either:
a) the GPL v2 (or any later version)
b) the Affero GPL v3
Details of these licenses can be found at: www.gnu.org/licenses
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
------------------------------------------------------------------------------
To release a closed-source product which uses JUCE, commercial licenses are
available: visit www.juce.com for more information.
==============================================================================
*/
/*
Sorry.. This class isn't implemented on Linux!
*/
//==============================================================================
WebBrowserComponent::WebBrowserComponent (const bool unloadPageWhenBrowserIsHidden_)
: browser (0),
blankPageShown (false),
unloadPageWhenBrowserIsHidden (unloadPageWhenBrowserIsHidden_)
{
// Unfortunately, WebBrowserComponent is not implemented for Linux yet!
// This is just a stub implementation without any useful functionality.
jassertfalse;
setOpaque (true);
}
WebBrowserComponent::~WebBrowserComponent()
{
}
//==============================================================================
void WebBrowserComponent::goToURL (const String& url,
const StringArray* headers,
const MemoryBlock* postData)
{
lastURL = url;
if (headers != nullptr)
lastHeaders = *headers;
else
lastHeaders.clear();
if (postData != nullptr)
lastPostData = *postData;
else
lastPostData.reset();
blankPageShown = false;
}
void WebBrowserComponent::stop()
{
}
void WebBrowserComponent::goBack()
{
lastURL.clear();
blankPageShown = false;
}
void WebBrowserComponent::goForward()
{
lastURL.clear();
}
void WebBrowserComponent::refresh()
{
}
//==============================================================================
void WebBrowserComponent::paint (Graphics& g)
{
g.fillAll (Colours::white);
}
void WebBrowserComponent::checkWindowAssociation()
{
}
void WebBrowserComponent::reloadLastURL()
{
if (lastURL.isNotEmpty())
{
goToURL (lastURL, &lastHeaders, &lastPostData);
lastURL.clear();
}
}
void WebBrowserComponent::parentHierarchyChanged()
{
checkWindowAssociation();
}
void WebBrowserComponent::resized()
{
}
void WebBrowserComponent::visibilityChanged()
{
checkWindowAssociation();
}
void WebBrowserComponent::focusGained (FocusChangeType)
{
}

+ 0
- 49
libs/juce/source/modules/juce_tracktion_marketplace/juce_tracktion_marketplace.cpp View File

@@ -1,49 +0,0 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2015 - ROLI Ltd.
Permission is granted to use this software under the terms of either:
a) the GPL v2 (or any later version)
b) the Affero GPL v3
Details of these licenses can be found at: www.gnu.org/licenses
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
------------------------------------------------------------------------------
To release a closed-source product which uses JUCE, commercial licenses are
available: visit www.juce.com for more information.
==============================================================================
*/
#ifdef JUCE_TRACKTION_MARKETPLACE_H_INCLUDED
/* When you add this cpp file to your project, you mustn't include it in a file where you've
already included any other headers - just put it inside a file on its own, possibly with your config
flags preceding it, but don't include anything else. That also includes avoiding any automatic prefix
header files that the compiler may be using.
*/
#error "Incorrect use of JUCE cpp file"
#endif
#include "AppConfig.h"
#include "juce_tracktion_marketplace.h"
namespace juce
{
#include "marketplace/juce_OnlineUnlockStatus.cpp"
#if JUCE_MODULE_AVAILABLE_juce_data_structures
#include "marketplace/juce_TracktionMarketplaceStatus.cpp"
#endif
#if JUCE_MODULE_AVAILABLE_juce_gui_extra
#include "marketplace/juce_OnlineUnlockForm.cpp"
#endif
}

+ 0
- 88
libs/juce/source/modules/juce_tracktion_marketplace/juce_tracktion_marketplace.h View File

@@ -1,88 +0,0 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2015 - ROLI Ltd.
Permission is granted to use this software under the terms of either:
a) the GPL v2 (or any later version)
b) the Affero GPL v3
Details of these licenses can be found at: www.gnu.org/licenses
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
------------------------------------------------------------------------------
To release a closed-source product which uses JUCE, commercial licenses are
available: visit www.juce.com for more information.
==============================================================================
*/
/*******************************************************************************
The block below describes the properties of this module, and is read by
the Projucer to automatically generate project code that uses it.
For details about the syntax and how to create or use a module, see the
JUCE Module Format.txt file.
BEGIN_JUCE_MODULE_DECLARATION
ID: juce_tracktion_marketplace
vendor: juce
version: 4.3.1
name: JUCE Tracktion marketplace support
description: Classes for online product authentication via the Tracktion marketplace.
website: http://www.juce.com/juce
license: GPL/Commercial
dependencies: juce_cryptography
END_JUCE_MODULE_DECLARATION
*******************************************************************************/
#ifndef JUCE_TRACKTION_MARKETPLACE_H_INCLUDED
#define JUCE_TRACKTION_MARKETPLACE_H_INCLUDED
/**
The Tracktion Marketplace module is a simple user-registration system for
allowing you to build apps/plugins with features that are unlocked by a
user having a suitable account on a webserver.
Although originally designed for use with products that are sold on the
Tracktion Marketplace web-store, the module itself is fully open, and can
be used to connect to your own web-store instead, if you implement your
own compatible web-server back-end.
*/
//==============================================================================
#include <juce_cryptography/juce_cryptography.h>
#if JUCE_MODULE_AVAILABLE_juce_data_structures
#include <juce_data_structures/juce_data_structures.h>
#endif
#if JUCE_MODULE_AVAILABLE_juce_gui_extra
#include <juce_gui_extra/juce_gui_extra.h>
#endif
namespace juce
{
#if JUCE_MODULE_AVAILABLE_juce_data_structures
#include "marketplace/juce_OnlineUnlockStatus.h"
#include "marketplace/juce_TracktionMarketplaceStatus.h"
#endif
#include "marketplace/juce_KeyFileGeneration.h"
#if JUCE_MODULE_AVAILABLE_juce_gui_extra
#include "marketplace/juce_OnlineUnlockForm.h"
#endif
}
#endif // JUCE_TRACKTION_MARKETPLACE_H_INCLUDED

+ 0
- 107
libs/juce/source/modules/juce_tracktion_marketplace/marketplace/juce_KeyFileGeneration.h View File

@@ -1,107 +0,0 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2015 - ROLI Ltd.
Permission is granted to use this software under the terms of either:
a) the GPL v2 (or any later version)
b) the Affero GPL v3
Details of these licenses can be found at: www.gnu.org/licenses
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
------------------------------------------------------------------------------
To release a closed-source product which uses JUCE, commercial licenses are
available: visit www.juce.com for more information.
==============================================================================
*/
/**
Contains static utilities for generating key-files that can be unlocked by
the OnlineUnlockStatus class.
*/
class JUCE_API KeyGeneration
{
public:
/**
Generates the content of a key-file which can be sent to a user's machine to
unlock a product.
The returned value is a block of text containing an RSA-encoded block, followed
by some human-readable details. If you pass this block of text to
OnlineUnlockStatus::applyKeyFile(), it will decrypt it, and if the
key matches and the machine numbers match, it will unlock that machine.
Typically the way you'd use this on a server would be to build a small executable
that simply calls this method and prints the result, so that the webserver can
use this as a reply to the product's auto-registration mechanism. The
keyGenerationAppMain() function is an example of how to build such a function.
@see OnlineUnlockStatus
*/
static String JUCE_CALLTYPE generateKeyFile (const String& appName,
const String& userEmail,
const String& userName,
const String& machineNumbers,
const RSAKey& privateKey);
/** Similar to the above key file generation method but with an expiry time.
You must supply a Time after which this key file should no longer be considered as active.
N.B. when an app is unlocked with an expiring key file, OnlineUnlockStatus::isUnlocked will
still return false. You must then check OnlineUnlockStatus::getExpiryTime to see if this
expiring key file is still in date and act accordingly.
@see OnlineUnlockStatus
*/
static String JUCE_CALLTYPE generateExpiringKeyFile (const String& appName,
const String& userEmail,
const String& userName,
const String& machineNumbers,
const Time expiryTime,
const RSAKey& privateKey);
//==============================================================================
/** This is a simple implementation of a key-generator that you could easily wrap in
a command-line main() function for use on your server.
So for example you might use this in a command line app called "unlocker" and
then call it like this:
unlocker MyGreatApp Joe_Bloggs joebloggs@foobar.com 1234abcd,95432ff 22d9aec92d986dd1,923ad49e9e7ff294c
*/
static inline int keyGenerationAppMain (int argc, char* argv[])
{
StringArray args;
for (int i = 1; i < argc; ++i)
args.add (argv[i]);
if (args.size() != 5)
{
std::cout << "Requires 5 arguments: app-name user-email username machine-numbers private-key" << std::endl
<< " app-name: name of the product being unlocked" << std::endl
<< " user-email: user's email address" << std::endl
<< " username: name of the user. Careful not to allow any spaces!" << std::endl
<< " machine-numbers: a comma- or semicolon-separated list of all machine ID strings this user can run this product on (no whitespace between items!)" << std::endl
<< " private-key: the RSA private key corresponding to the public key you've used in the app" << std::endl
<< std::endl;
return 1;
}
if (! args[4].containsChar (','))
{
std::cout << "Not a valid RSA key!" << std::endl;
return 1;
}
std::cout << generateKeyFile (args[0], args[1], args[2], args[3], RSAKey (args[4])) << std::endl;
return 0;
}
};

+ 0
- 283
libs/juce/source/modules/juce_tracktion_marketplace/marketplace/juce_OnlineUnlockForm.cpp View File

@@ -1,283 +0,0 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2015 - ROLI Ltd.
Permission is granted to use this software under the terms of either:
a) the GPL v2 (or any later version)
b) the Affero GPL v3
Details of these licenses can be found at: www.gnu.org/licenses
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
------------------------------------------------------------------------------
To release a closed-source product which uses JUCE, commercial licenses are
available: visit www.juce.com for more information.
==============================================================================
*/
struct Spinner : public Component, private Timer
{
Spinner() { startTimer (1000 / 50); }
void timerCallback() override { repaint(); }
void paint (Graphics& g) override
{
getLookAndFeel().drawSpinningWaitAnimation (g, Colours::darkgrey, 0, 0, getWidth(), getHeight());
}
};
struct OnlineUnlockForm::OverlayComp : public Component,
private Thread,
private Timer
{
OverlayComp (OnlineUnlockForm& f) : Thread (String()), form (f)
{
result.succeeded = false;
email = form.emailBox.getText();
password = form.passwordBox.getText();
addAndMakeVisible (spinner);
startThread (4);
}
~OverlayComp()
{
stopThread (10000);
}
void paint (Graphics& g) override
{
g.fillAll (Colours::white.withAlpha (0.97f));
g.setColour (Colours::black);
g.setFont (15.0f);
g.drawFittedText (TRANS("Contacting XYZ...").replace ("XYZ", form.status.getWebsiteName()),
getLocalBounds().reduced (20, 0).removeFromTop (proportionOfHeight (0.6f)),
Justification::centred, 5);
}
void resized() override
{
const int spinnerSize = 40;
spinner.setBounds ((getWidth() - spinnerSize) / 2, proportionOfHeight (0.6f), spinnerSize, spinnerSize);
}
void run() override
{
result = form.status.attemptWebserverUnlock (email, password);
startTimer (100);
}
void timerCallback() override
{
spinner.setVisible (false);
stopTimer();
if (result.errorMessage.isNotEmpty())
{
AlertWindow::showMessageBoxAsync (AlertWindow::WarningIcon,
TRANS("Registration Failed"),
result.errorMessage);
}
else if (result.informativeMessage.isNotEmpty())
{
AlertWindow::showMessageBoxAsync (AlertWindow::InfoIcon,
TRANS("Registration Complete!"),
result.informativeMessage);
}
else if (result.urlToLaunch.isNotEmpty())
{
URL url (result.urlToLaunch);
url.launchInDefaultBrowser();
}
// (local copies because we're about to delete this)
const bool worked = result.succeeded;
OnlineUnlockForm& f = form;
delete this;
if (worked)
f.dismiss();
}
OnlineUnlockForm& form;
Spinner spinner;
OnlineUnlockStatus::UnlockResult result;
String email, password;
JUCE_LEAK_DETECTOR (OnlineUnlockForm::OverlayComp)
};
static juce_wchar getDefaultPasswordChar() noexcept
{
#if JUCE_LINUX
return 0x2022;
#else
return 0x25cf;
#endif
}
OnlineUnlockForm::OnlineUnlockForm (OnlineUnlockStatus& s,
const String& userInstructions,
bool hasCancelButton)
: message (String(), userInstructions),
passwordBox (String(), getDefaultPasswordChar()),
registerButton (TRANS("Register")),
cancelButton (TRANS ("Cancel")),
status (s)
{
// Please supply a message to tell your users what to do!
jassert (userInstructions.isNotEmpty());
setOpaque (true);
emailBox.setText (status.getUserEmail());
message.setJustificationType (Justification::centred);
addAndMakeVisible (message);
addAndMakeVisible (emailBox);
addAndMakeVisible (passwordBox);
addAndMakeVisible (registerButton);
if (hasCancelButton)
addAndMakeVisible (cancelButton);
emailBox.setEscapeAndReturnKeysConsumed (false);
passwordBox.setEscapeAndReturnKeysConsumed (false);
registerButton.addShortcut (KeyPress (KeyPress::returnKey));
registerButton.addListener (this);
cancelButton.addListener (this);
lookAndFeelChanged();
setSize (500, 250);
}
OnlineUnlockForm::~OnlineUnlockForm()
{
unlockingOverlay.deleteAndZero();
}
void OnlineUnlockForm::paint (Graphics& g)
{
g.fillAll (Colours::lightgrey);
}
void OnlineUnlockForm::resized()
{
/* If you're writing a plugin, then DO NOT USE A POP-UP A DIALOG WINDOW!
Plugins that create external windows are incredibly annoying for users, and
cause all sorts of headaches for hosts. Don't be the person who writes that
plugin that irritates everyone with a nagging dialog box every time they scan!
*/
jassert (JUCEApplicationBase::isStandaloneApp() || findParentComponentOfClass<DialogWindow>() == nullptr);
const int buttonHeight = 22;
Rectangle<int> r (getLocalBounds().reduced (10, 20));
Rectangle<int> buttonArea (r.removeFromBottom (buttonHeight));
registerButton.changeWidthToFitText (buttonHeight);
cancelButton.changeWidthToFitText (buttonHeight);
const int gap = 20;
buttonArea = buttonArea.withSizeKeepingCentre (registerButton.getWidth()
+ (cancelButton.isVisible() ? gap + cancelButton.getWidth() : 0),
buttonHeight);
registerButton.setBounds (buttonArea.removeFromLeft (registerButton.getWidth()));
buttonArea.removeFromLeft (gap);
cancelButton.setBounds (buttonArea);
r.removeFromBottom (20);
// (force use of a default system font to make sure it has the password blob character)
Font font (Font::getDefaultTypefaceForFont (Font (Font::getDefaultSansSerifFontName(),
Font::getDefaultStyle(),
5.0f)));
const int boxHeight = 24;
passwordBox.setBounds (r.removeFromBottom (boxHeight));
passwordBox.setInputRestrictions (64);
passwordBox.setFont (font);
r.removeFromBottom (20);
emailBox.setBounds (r.removeFromBottom (boxHeight));
emailBox.setInputRestrictions (512);
emailBox.setFont (font);
r.removeFromBottom (20);
message.setBounds (r);
if (unlockingOverlay != nullptr)
unlockingOverlay->setBounds (getLocalBounds());
}
void OnlineUnlockForm::lookAndFeelChanged()
{
Colour labelCol (findColour (TextEditor::backgroundColourId).contrasting (0.5f));
emailBox.setTextToShowWhenEmpty (TRANS("Email Address"), labelCol);
passwordBox.setTextToShowWhenEmpty (TRANS("Password"), labelCol);
}
void OnlineUnlockForm::showBubbleMessage (const String& text, Component& target)
{
bubble = new BubbleMessageComponent (500);
addChildComponent (bubble);
AttributedString attString;
attString.append (text, Font (16.0f));
bubble->showAt (getLocalArea (&target, target.getLocalBounds()),
attString, 500, // numMillisecondsBeforeRemoving
true, // removeWhenMouseClicked
false); // deleteSelfAfterUse
}
void OnlineUnlockForm::buttonClicked (Button* b)
{
if (b == &registerButton)
attemptRegistration();
else if (b == &cancelButton)
dismiss();
}
void OnlineUnlockForm::attemptRegistration()
{
if (unlockingOverlay == nullptr)
{
if (emailBox.getText().trim().length() < 3)
{
showBubbleMessage (TRANS ("Please enter a valid email address!"), emailBox);
return;
}
if (passwordBox.getText().trim().length() < 3)
{
showBubbleMessage (TRANS ("Please enter a valid password!"), passwordBox);
return;
}
status.setUserEmail (emailBox.getText());
addAndMakeVisible (unlockingOverlay = new OverlayComp (*this));
resized();
unlockingOverlay->enterModalState();
}
}
void OnlineUnlockForm::dismiss()
{
delete this;
}

+ 0
- 88
libs/juce/source/modules/juce_tracktion_marketplace/marketplace/juce_OnlineUnlockForm.h View File

@@ -1,88 +0,0 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2015 - ROLI Ltd.
Permission is granted to use this software under the terms of either:
a) the GPL v2 (or any later version)
b) the Affero GPL v3
Details of these licenses can be found at: www.gnu.org/licenses
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
------------------------------------------------------------------------------
To release a closed-source product which uses JUCE, commercial licenses are
available: visit www.juce.com for more information.
==============================================================================
*/
/** Acts as a GUI which asks the user for their details, and calls the approriate
methods on your OnlineUnlockStatus object to attempt to register the app.
You should create one of these components and add it to your parent window,
or use a DialogWindow to display it as a pop-up. But if you're writing a plugin,
then DO NOT USE A DIALOG WINDOW! Add it as a child component of your plugin's editor
component instead. Plugins that pop up external registration windows are incredibly
annoying, and cause all sorts of headaches for hosts. Don't be the person who
writes that plugin that irritates everyone with a dialog box every time they
try to scan for new plugins!
Note that after adding it, you should put the component into a modal state,
and it will automatically delete itself when it has completed.
Although it deletes itself, it's also OK to delete it manually yourself
if you need to get rid of it sooner.
@see OnlineUnlockStatus
*/
class JUCE_API OnlineUnlockForm : public Component,
private ButtonListener
{
public:
/** Creates an unlock form that will work with the given status object.
The userInstructions will be displayed above the email and password boxes.
*/
OnlineUnlockForm (OnlineUnlockStatus&,
const String& userInstructions,
bool hasCancelButton = true);
/** Destructor. */
~OnlineUnlockForm();
/** This is called when the form is dismissed (either cancelled or when registration
succeeds).
By default it will delete this, but you can override it to do other things.
*/
virtual void dismiss();
/** @internal */
void paint (Graphics&) override;
/** @internal */
void resized() override;
/** @internal */
void lookAndFeelChanged() override;
Label message;
TextEditor emailBox, passwordBox;
TextButton registerButton, cancelButton;
private:
OnlineUnlockStatus& status;
ScopedPointer<BubbleMessageComponent> bubble;
struct OverlayComp;
friend struct OverlayComp;
Component::SafePointer<Component> unlockingOverlay;
void buttonClicked (Button*) override;
void attemptRegistration();
void showBubbleMessage (const String&, Component&);
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (OnlineUnlockForm)
};

+ 0
- 496
libs/juce/source/modules/juce_tracktion_marketplace/marketplace/juce_OnlineUnlockStatus.cpp View File

@@ -1,496 +0,0 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2015 - ROLI Ltd.
Permission is granted to use this software under the terms of either:
a) the GPL v2 (or any later version)
b) the Affero GPL v3
Details of these licenses can be found at: www.gnu.org/licenses
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
------------------------------------------------------------------------------
To release a closed-source product which uses JUCE, commercial licenses are
available: visit www.juce.com for more information.
==============================================================================
*/
/* Note: there's a bit of light obfuscation in this code, just to make things
a bit more annoying for crackers who try to reverse-engineer your binaries, but
nothing particularly foolproof.
*/
struct KeyFileUtils
{
static XmlElement createKeyFileContent (const String& appName,
const String& userEmail,
const String& userName,
const String& machineNumbers,
const String& machineNumbersAttributeName)
{
XmlElement xml ("key");
xml.setAttribute ("user", userName);
xml.setAttribute ("email", userEmail);
xml.setAttribute (machineNumbersAttributeName, machineNumbers);
xml.setAttribute ("app", appName);
xml.setAttribute ("date", String::toHexString (Time::getCurrentTime().toMilliseconds()));
return xml;
}
static String createKeyFileComment (const String& appName,
const String& userEmail,
const String& userName,
const String& machineNumbers)
{
String comment;
comment << "Keyfile for " << appName << newLine;
if (userName.isNotEmpty())
comment << "User: " << userName << newLine;
comment << "Email: " << userEmail << newLine
<< "Machine numbers: " << machineNumbers << newLine
<< "Created: " << Time::getCurrentTime().toString (true, true);
return comment;
}
//==============================================================================
static String encryptXML (const XmlElement& xml, RSAKey privateKey)
{
MemoryOutputStream text;
text << xml.createDocument (StringRef(), true);
BigInteger val;
val.loadFromMemoryBlock (text.getMemoryBlock());
privateKey.applyToValue (val);
return val.toString (16);
}
static String createKeyFile (String comment,
const XmlElement& xml,
RSAKey rsaPrivateKey)
{
String asHex ("#" + encryptXML (xml, rsaPrivateKey));
StringArray lines;
lines.add (comment);
lines.add (String());
const int charsPerLine = 70;
while (asHex.length() > 0)
{
lines.add (asHex.substring (0, charsPerLine));
asHex = asHex.substring (charsPerLine);
}
lines.add (String());
return lines.joinIntoString ("\r\n");
}
//==============================================================================
static XmlElement decryptXML (String hexData, RSAKey rsaPublicKey)
{
BigInteger val;
val.parseString (hexData, 16);
RSAKey key (rsaPublicKey);
jassert (key.isValid());
ScopedPointer<XmlElement> xml;
if (! val.isZero())
{
key.applyToValue (val);
const MemoryBlock mb (val.toMemoryBlock());
if (CharPointer_UTF8::isValidString (static_cast<const char*> (mb.getData()), (int) mb.getSize()))
xml = XmlDocument::parse (mb.toString());
}
return xml != nullptr ? *xml : XmlElement("key");
}
static XmlElement getXmlFromKeyFile (String keyFileText, RSAKey rsaPublicKey)
{
return decryptXML (keyFileText.fromLastOccurrenceOf ("#", false, false).trim(), rsaPublicKey);
}
static StringArray getMachineNumbers (XmlElement xml, StringRef attributeName)
{
StringArray numbers;
numbers.addTokens (xml.getStringAttribute (attributeName), ",; ", StringRef());
numbers.trim();
numbers.removeEmptyStrings();
return numbers;
}
static String getLicensee (const XmlElement& xml) { return xml.getStringAttribute ("user"); }
static String getEmail (const XmlElement& xml) { return xml.getStringAttribute ("email"); }
static String getAppID (const XmlElement& xml) { return xml.getStringAttribute ("app"); }
struct KeyFileData
{
String licensee, email, appID;
StringArray machineNumbers;
bool keyFileExpires;
Time expiryTime;
};
static KeyFileData getDataFromKeyFile (XmlElement xml)
{
KeyFileData data;
data.licensee = getLicensee (xml);
data.email = getEmail (xml);
data.appID = getAppID (xml);
if (xml.hasAttribute ("expiryTime") && xml.hasAttribute ("expiring_mach"))
{
data.keyFileExpires = true;
data.machineNumbers.addArray (getMachineNumbers (xml, "expiring_mach"));
data.expiryTime = Time (xml.getStringAttribute ("expiryTime").getHexValue64());
}
else
{
data.keyFileExpires = false;
data.machineNumbers.addArray (getMachineNumbers (xml, "mach"));
}
return data;
}
};
//==============================================================================
#if JUCE_MODULE_AVAILABLE_juce_data_structures
const char* OnlineUnlockStatus::unlockedProp = "u";
const char* OnlineUnlockStatus::expiryTimeProp = "t";
static const char* stateTagName = "REG";
static const char* userNameProp = "user";
static const char* keyfileDataProp = "key";
static var machineNumberAllowed (StringArray numbersFromKeyFile,
StringArray localMachineNumbers)
{
var result;
for (int i = 0; i < localMachineNumbers.size(); ++i)
{
String localNumber (localMachineNumbers[i].trim());
if (localNumber.isNotEmpty())
{
for (int j = numbersFromKeyFile.size(); --j >= 0;)
{
var ok (localNumber.trim().equalsIgnoreCase (numbersFromKeyFile[j].trim()));
result.swapWith (ok);
if (result)
break;
}
}
}
return result;
}
//==============================================================================
OnlineUnlockStatus::OnlineUnlockStatus() : status (stateTagName)
{
}
OnlineUnlockStatus::~OnlineUnlockStatus()
{
}
void OnlineUnlockStatus::load()
{
MemoryBlock mb;
mb.fromBase64Encoding (getState());
if (mb.getSize() > 0)
status = ValueTree::readFromGZIPData (mb.getData(), mb.getSize());
else
status = ValueTree (stateTagName);
StringArray localMachineNums (getLocalMachineIDs());
if (machineNumberAllowed (StringArray ("1234"), localMachineNums))
status.removeProperty (unlockedProp, nullptr);
KeyFileUtils::KeyFileData data;
data = KeyFileUtils::getDataFromKeyFile (KeyFileUtils::getXmlFromKeyFile (status[keyfileDataProp], getPublicKey()));
if (data.keyFileExpires)
{
if (! doesProductIDMatch (data.appID))
status.removeProperty (expiryTimeProp, nullptr);
if (! machineNumberAllowed (data.machineNumbers, localMachineNums))
status.removeProperty (expiryTimeProp, nullptr);
}
else
{
if (! doesProductIDMatch (data.appID))
status.removeProperty (unlockedProp, nullptr);
if (! machineNumberAllowed (data.machineNumbers, localMachineNums))
status.removeProperty (unlockedProp, nullptr);
}
}
void OnlineUnlockStatus::save()
{
MemoryOutputStream mo;
{
GZIPCompressorOutputStream gzipStream (&mo, 9);
status.writeToStream (gzipStream);
}
saveState (mo.getMemoryBlock().toBase64Encoding());
}
char OnlineUnlockStatus::MachineIDUtilities::getPlatformPrefix()
{
#if JUCE_MAC
return 'M';
#elif JUCE_WINDOWS
return 'W';
#elif JUCE_LINUX
return 'L';
#elif JUCE_IOS
return 'I';
#elif JUCE_ANDROID
return 'A';
#endif
}
String OnlineUnlockStatus::MachineIDUtilities::getEncodedIDString (const String& input)
{
const String platform (String::charToString (getPlatformPrefix()));
return platform + MD5 ((input + "salt_1" + platform).toUTF8())
.toHexString().substring (0, 9).toUpperCase();
}
bool OnlineUnlockStatus::MachineIDUtilities::addFileIDToList (StringArray& ids, const File& f)
{
if (uint64 num = f.getFileIdentifier())
{
ids.add (getEncodedIDString (String::toHexString ((int64) num)));
return true;
}
return false;
}
void OnlineUnlockStatus::MachineIDUtilities::addMACAddressesToList (StringArray& ids)
{
Array<MACAddress> addresses;
MACAddress::findAllAddresses (addresses);
for (int i = 0; i < addresses.size(); ++i)
ids.add (getEncodedIDString (addresses.getReference(i).toString()));
}
StringArray OnlineUnlockStatus::MachineIDUtilities::getLocalMachineIDs()
{
StringArray ids;
// First choice for an ID number is a filesystem ID for the user's home
// folder or windows directory.
#if JUCE_WINDOWS
MachineIDUtilities::addFileIDToList (ids, File::getSpecialLocation (File::windowsSystemDirectory));
#else
MachineIDUtilities::addFileIDToList (ids, File ("~"));
#endif
// ..if that fails, use the MAC addresses..
if (ids.size() == 0)
MachineIDUtilities::addMACAddressesToList (ids);
jassert (ids.size() > 0); // failed to create any IDs!
return ids;
}
StringArray OnlineUnlockStatus::getLocalMachineIDs()
{
return MachineIDUtilities::getLocalMachineIDs();
}
void OnlineUnlockStatus::setUserEmail (const String& usernameOrEmail)
{
status.setProperty (userNameProp, usernameOrEmail, nullptr);
}
String OnlineUnlockStatus::getUserEmail() const
{
return status[userNameProp].toString();
}
bool OnlineUnlockStatus::applyKeyFile (String keyFileContent)
{
KeyFileUtils::KeyFileData data;
data = KeyFileUtils::getDataFromKeyFile (KeyFileUtils::getXmlFromKeyFile (keyFileContent, getPublicKey()));
if (data.licensee.isNotEmpty() && data.email.isNotEmpty() && doesProductIDMatch (data.appID))
{
setUserEmail (data.email);
status.setProperty (keyfileDataProp, keyFileContent, nullptr);
status.removeProperty (data.keyFileExpires ? expiryTimeProp : unlockedProp, nullptr);
var actualResult (0), dummyResult (1.0);
var v (machineNumberAllowed (data.machineNumbers, getLocalMachineIDs()));
actualResult.swapWith (v);
v = machineNumberAllowed (StringArray ("01"), getLocalMachineIDs());
dummyResult.swapWith (v);
jassert (! dummyResult);
if (data.keyFileExpires)
{
if ((! dummyResult) && actualResult)
status.setProperty (expiryTimeProp, data.expiryTime.toMilliseconds(), nullptr);
return getExpiryTime().toMilliseconds() > 0;
}
if ((! dummyResult) && actualResult)
status.setProperty (unlockedProp, actualResult, nullptr);
return isUnlocked();
}
return false;
}
static bool canConnectToWebsite (const URL& url)
{
ScopedPointer<InputStream> in (url.createInputStream (false, nullptr, nullptr, String(), 2000, nullptr));
return in != nullptr;
}
static bool areMajorWebsitesAvailable()
{
const char* urlsToTry[] = { "http://google.com", "http://bing.com", "http://amazon.com",
"https://google.com", "https://bing.com", "https://amazon.com", nullptr};
for (const char** url = urlsToTry; *url != nullptr; ++url)
if (canConnectToWebsite (URL (*url)))
return true;
return false;
}
OnlineUnlockStatus::UnlockResult OnlineUnlockStatus::handleXmlReply (XmlElement xml)
{
UnlockResult r;
if (const XmlElement* keyNode = xml.getChildByName ("KEY"))
{
const String keyText (keyNode->getAllSubText().trim());
r.succeeded = keyText.length() > 10 && applyKeyFile (keyText);
}
else
{
r.succeeded = false;
}
if (xml.hasTagName ("MESSAGE"))
r.informativeMessage = xml.getStringAttribute ("message").trim();
if (xml.hasTagName ("ERROR"))
r.errorMessage = xml.getStringAttribute ("error").trim();
if (xml.getStringAttribute ("url").isNotEmpty())
r.urlToLaunch = xml.getStringAttribute ("url").trim();
if (r.errorMessage.isEmpty() && r.informativeMessage.isEmpty() && r.urlToLaunch.isEmpty() && ! r.succeeded)
r.errorMessage = TRANS ("Unexpected or corrupted reply from XYZ").replace ("XYZ", getWebsiteName()) + "...\n\n"
+ TRANS("Please try again in a few minutes, and contact us for support if this message appears again.");
return r;
}
OnlineUnlockStatus::UnlockResult OnlineUnlockStatus::handleFailedConnection()
{
UnlockResult r;
r.succeeded = false;
r.errorMessage = TRANS("Couldn't connect to XYZ").replace ("XYZ", getWebsiteName()) + "...\n\n";
if (areMajorWebsitesAvailable())
r.errorMessage << TRANS("Your internet connection seems to be OK, but our webserver "
"didn't respond... This is most likely a temporary problem, so try "
"again in a few minutes, but if it persists, please contact us for support!");
else
r.errorMessage << TRANS("No internet sites seem to be accessible from your computer.. Before trying again, "
"please check that your network is working correctly, and make sure "
"that any firewall/security software installed on your machine isn't "
"blocking your web connection.");
return r;
}
OnlineUnlockStatus::UnlockResult OnlineUnlockStatus::attemptWebserverUnlock (const String& email,
const String& password)
{
// This method will block while it contacts the server, so you must run it on a background thread!
jassert (! MessageManager::getInstance()->isThisTheMessageThread());
String reply (readReplyFromWebserver (email, password));
DBG ("Reply from server: " << reply);
ScopedPointer<XmlElement> xml (XmlDocument::parse (reply));
if (xml != nullptr)
return handleXmlReply (*xml);
return handleFailedConnection();
}
#endif // JUCE_MODULE_AVAILABLE_juce_data_structures
//==============================================================================
String KeyGeneration::generateKeyFile (const String& appName,
const String& userEmail,
const String& userName,
const String& machineNumbers,
const RSAKey& privateKey)
{
XmlElement xml (KeyFileUtils::createKeyFileContent (appName, userEmail, userName, machineNumbers, "mach"));
const String comment (KeyFileUtils::createKeyFileComment (appName, userEmail, userName, machineNumbers));
return KeyFileUtils::createKeyFile (comment, xml, privateKey);
}
String KeyGeneration::generateExpiringKeyFile (const String& appName,
const String& userEmail,
const String& userName,
const String& machineNumbers,
const Time expiryTime,
const RSAKey& privateKey)
{
XmlElement xml (KeyFileUtils::createKeyFileContent (appName, userEmail, userName, machineNumbers, "expiring_mach"));
xml.setAttribute ("expiryTime", String::toHexString (expiryTime.toMilliseconds()));
String comment (KeyFileUtils::createKeyFileComment (appName, userEmail, userName, machineNumbers));
comment << newLine << "Expires: " << expiryTime.toString (true, true);
return KeyFileUtils::createKeyFile (comment, xml, privateKey);
}

+ 0
- 258
libs/juce/source/modules/juce_tracktion_marketplace/marketplace/juce_OnlineUnlockStatus.h View File

@@ -1,258 +0,0 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2015 - ROLI Ltd.
Permission is granted to use this software under the terms of either:
a) the GPL v2 (or any later version)
b) the Affero GPL v3
Details of these licenses can be found at: www.gnu.org/licenses
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
------------------------------------------------------------------------------
To release a closed-source product which uses JUCE, commercial licenses are
available: visit www.juce.com for more information.
==============================================================================
*/
/**
A base class for online unlocking systems.
This class stores information about whether your app has been unlocked for the
current machine, and handles communication with a web-store to perform the
unlock procedure.
You probably won't ever use this base class directly, but rather a store-specific
subclass such as TracktionMarketplaceStatus, which knows how to talk to the particular
online store that you're using.
To use it, you create a subclass which implements all the pure virtual methods
(see their comments to find out what you'll need to make them do).
Then you can create an instance of your subclass which will hold the registration
state. Typically, you'll want to just keep a single instance of the class around for
the duration of your app. You can then call its methods to handle the various
registration tasks.
Areas of your code that need to know whether the user is registered (e.g. to decide
whether a particular feature is available) should call isUnlocked() to find out.
If you want to create a GUI that allows your users to enter their details and
register, see the OnlineUnlockForm class.
@see OnlineUnlockForm, KeyGeneration
*/
class JUCE_API OnlineUnlockStatus
{
public:
OnlineUnlockStatus();
/** Destructor. */
virtual ~OnlineUnlockStatus();
//==============================================================================
/** This must return your product's ID, as allocated by the store. */
virtual String getProductID() = 0;
/** This must check whether a product ID string that the server returned is OK for
unlocking the current app.
*/
virtual bool doesProductIDMatch (const String& returnedIDFromServer) = 0;
/** This must return the RSA public key for authenticating responses from
the server for this app. You can get this key from your marketplace
account page.
*/
virtual RSAKey getPublicKey() = 0;
/** This method must store the given string somewhere in your app's
persistent properties, so it can be retrieved later by getState().
*/
virtual void saveState (const String&) = 0;
/** This method must retrieve the last state that was provided by the
saveState method.
On first-run, it should just return an empty string.
*/
virtual String getState() = 0;
/** Returns the name of the web-store website, not for communication, but for
presenting to the user.
*/
virtual String getWebsiteName() = 0;
/** Returns the URL of the authentication API. */
virtual URL getServerAuthenticationURL() = 0;
/** Subclasses that talk to a particular web-store will implement this method
to contact their webserver and attempt to unlock the current machine for
the given username and password. The return value is the XML text from the
server which contains error information and/or the encrypted keyfile.
*/
virtual String readReplyFromWebserver (const String& email, const String& password) = 0;
/** Returns a list of strings, any of which should be unique to this
physical computer.
When testing whether the user is allowed to use the product on this
machine, this list of tokens is compared to the ones that were stored
on the webserver.
The default implementation of this method will simply call
MachineIDUtilities::getLocalMachineIDs(), which provides a default
version of this functionality.
*/
virtual StringArray getLocalMachineIDs();
//==============================================================================
// The following methods can be called by your app:
/** Returns true if the product has been successfully authorised for this machine.
The reason it returns a variant rather than a bool is just to make it marginally
more tedious for crackers to work around. Hopefully if this method gets inlined
they'll need to hack all the places where you call it, rather than just the
function itself.
Bear in mind that each place where you check this return value will need to be
changed by a cracker in order to unlock your app, so the more places you call this
method, the more hassle it will be for them to find and crack them all.
*/
inline var isUnlocked() const { return status[unlockedProp]; }
/** Returns the Time when the keyfile expires.
If a the key file obtained has an expiry time, isUnlocked will return false and this
will return a non-zero time. The interpretation of this is up to your app but could
be used for subscription based models or trial periods.
*/
inline Time getExpiryTime() const { return Time (static_cast<int64> (status[expiryTimeProp])); }
/** Optionally allows the app to provide the user's email address if
it is known.
You don't need to call this, but if you do it may save the user
typing it in.
*/
void setUserEmail (const String& usernameOrEmail);
/** Returns the user's email address if known. */
String getUserEmail() const;
/** Attempts to perform an unlock using a block of key-file data provided.
You may wish to use this as a way of allowing a user to unlock your app
by drag-and-dropping a file containing the key data, or by letting them
select such a file. This is often needed for allowing registration on
machines without internet access.
*/
bool applyKeyFile (String keyFileContent);
/** This provides some details about the reply that the server gave in a call
to attemptWebserverUnlock().
*/
struct UnlockResult
{
/** If an unlock operation fails, this is the error message that the webserver
supplied (or a message saying that the server couldn't be contacted)
*/
String errorMessage;
/** This is a message that the webserver returned, and which the user should
be shown.
It's not necessarily an error message, e.g. it might say that there's a
new version of the app available or some other status update.
*/
String informativeMessage;
/** If the webserver wants the user to be directed to a web-page for further
information, this is the URL that it would like them to go to.
*/
String urlToLaunch;
/** If the unlock operation succeeded, this will be set to true. */
bool succeeded;
};
/** Contacts the webserver and attempts to perform a registration with the
given user details.
The return value will either be a success, or a failure with an error message
from the server, so you should show this message to your user.
Because this method blocks while it contacts the server, you must run it on
a background thread, not on the message thread. For an easier way to create
a GUI to do the unlocking, see OnlineUnlockForm.
*/
UnlockResult attemptWebserverUnlock (const String& email, const String& password);
/** Attempts to load the status from the state retrieved by getState().
Call this somewhere in your app's startup code.
*/
void load();
/** Triggers a call to saveState which you can use to store the current unlock status
in your app's settings.
*/
void save();
/** This class contains some utility functions that might help with machine ID generation. */
struct MachineIDUtilities
{
/** Returns a character that represents the current OS.
E.g. 'M' for Mac, 'W' for windows, etc
*/
static char getPlatformPrefix();
/** Returns an encoded hash string from the given input string, prefixing it with
a letter to represent the current OS type.
*/
static String getEncodedIDString (const String& inputString);
/** Utility function that you may want to use in your machine-ID generation code.
This adds an ID string to the given array which is a hash of the filesystem ID of the
given file.
*/
static bool addFileIDToList (StringArray& result, const File& file);
/** Utility function that you may want to use in your machine-ID generation code.
This adds some ID strings to the given array which represent each MAC address of the machine.
*/
static void addMACAddressesToList (StringArray& result);
/** This method calculates some machine IDs based on things like network
MAC addresses, hard-disk IDs, etc, but if you want, you can overload
it to generate your own list of IDs.
The IDs that are returned should be short alphanumeric strings
without any punctuation characters. Since users may need to type
them, case is ignored when comparing them.
Note that the first item in the list is considered to be the
"main" ID, and this will be the one that is displayed to the user
and registered with the marketplace webserver. Subsequent IDs are
just used as fallback to avoid false negatives when checking for
registration on machines which have had hardware added/removed
since the product was first registered.
*/
static StringArray getLocalMachineIDs();
};
private:
ValueTree status;
UnlockResult handleXmlReply (XmlElement);
UnlockResult handleFailedConnection();
static const char* unlockedProp;
static const char* expiryTimeProp;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (OnlineUnlockStatus)
};

+ 0
- 54
libs/juce/source/modules/juce_tracktion_marketplace/marketplace/juce_TracktionMarketplaceStatus.cpp View File

@@ -1,54 +0,0 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2015 - ROLI Ltd.
Permission is granted to use this software under the terms of either:
a) the GPL v2 (or any later version)
b) the Affero GPL v3
Details of these licenses can be found at: www.gnu.org/licenses
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
------------------------------------------------------------------------------
To release a closed-source product which uses JUCE, commercial licenses are
available: visit www.juce.com for more information.
==============================================================================
*/
TracktionMarketplaceStatus::TracktionMarketplaceStatus() {}
URL TracktionMarketplaceStatus::getServerAuthenticationURL()
{
return URL ("https://www.tracktion.com/marketplace/authenticate.php");
}
String TracktionMarketplaceStatus::getWebsiteName()
{
return "tracktion.com";
}
bool TracktionMarketplaceStatus::doesProductIDMatch (const String& returnedIDFromServer)
{
return getProductID() == returnedIDFromServer;
}
String TracktionMarketplaceStatus::readReplyFromWebserver (const String& email, const String& password)
{
URL url (getServerAuthenticationURL()
.withParameter ("product", getProductID())
.withParameter ("email", email)
.withParameter ("pw", password)
.withParameter ("os", SystemStats::getOperatingSystemName())
.withParameter ("mach", getLocalMachineIDs()[0]));
DBG ("Trying to unlock via URL: " << url.toString (true));
return url.readEntireTextStream();
}

+ 0
- 51
libs/juce/source/modules/juce_tracktion_marketplace/marketplace/juce_TracktionMarketplaceStatus.h View File

@@ -1,51 +0,0 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2015 - ROLI Ltd.
Permission is granted to use this software under the terms of either:
a) the GPL v2 (or any later version)
b) the Affero GPL v3
Details of these licenses can be found at: www.gnu.org/licenses
JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
------------------------------------------------------------------------------
To release a closed-source product which uses JUCE, commercial licenses are
available: visit www.juce.com for more information.
==============================================================================
*/
/**
An implementation of the OnlineUnlockStatus class which talks to the
Tracktion Marketplace server.
For details about how to use this class, see the docs for the base
class: OnlineUnlockStatus. Basically, you need to inherit from it, and
implement all the pure virtual methods to tell it about your product.
@see OnlineUnlockStatus, OnlineUnlockForm, KeyGeneration
*/
class JUCE_API TracktionMarketplaceStatus : public OnlineUnlockStatus
{
public:
TracktionMarketplaceStatus();
/** @internal */
bool doesProductIDMatch (const String& returnedIDFromServer) override;
/** @internal */
URL getServerAuthenticationURL() override;
/** @internal */
String getWebsiteName() override;
/** @internal */
String readReplyFromWebserver (const String& email, const String& password) override;
private:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (TracktionMarketplaceStatus)
};

Loading…
Cancel
Save