Browse Source

Fixed multiple harmless warnings in Android builds

tags/2021-05-28
hogliux 8 years ago
parent
commit
6559b3e185
25 changed files with 152 additions and 135 deletions
  1. +2
    -0
      examples/Demo/Source/Demos/MDIDemo.cpp
  2. +5
    -5
      modules/juce_audio_devices/native/juce_android_Audio.cpp
  3. +5
    -5
      modules/juce_audio_devices/native/juce_android_Midi.cpp
  4. +29
    -29
      modules/juce_audio_devices/native/juce_android_OpenSL.cpp
  5. +3
    -3
      modules/juce_audio_formats/codecs/juce_AiffAudioFormat.cpp
  6. +5
    -6
      modules/juce_audio_utils/native/juce_android_BluetoothMidiDevicePairingDialogue.cpp
  7. +1
    -1
      modules/juce_core/javascript/juce_JSON.cpp
  8. +1
    -1
      modules/juce_core/javascript/juce_Javascript.cpp
  9. +1
    -1
      modules/juce_core/native/juce_android_Files.cpp
  10. +5
    -4
      modules/juce_core/native/juce_android_JNIHelpers.h
  11. +8
    -8
      modules/juce_core/native/juce_android_Network.cpp
  12. +1
    -1
      modules/juce_core/native/juce_android_SystemStats.cpp
  13. +1
    -1
      modules/juce_core/native/juce_android_Threads.cpp
  14. +12
    -6
      modules/juce_core/native/juce_posix_SharedCode.h
  15. +13
    -4
      modules/juce_core/network/juce_Socket.cpp
  16. +2
    -2
      modules/juce_core/text/juce_CharPointer_UTF16.h
  17. +1
    -1
      modules/juce_core/text/juce_CharPointer_UTF8.h
  18. +2
    -2
      modules/juce_core/text/juce_String.cpp
  19. +2
    -2
      modules/juce_events/native/juce_android_Messaging.cpp
  20. +1
    -1
      modules/juce_graphics/fonts/juce_CustomTypeface.cpp
  21. +4
    -4
      modules/juce_graphics/native/juce_android_Fonts.cpp
  22. +1
    -1
      modules/juce_gui_basics/keyboard/juce_KeyPress.cpp
  23. +10
    -10
      modules/juce_gui_basics/native/juce_android_FileChooser.cpp
  24. +36
    -36
      modules/juce_gui_basics/native/juce_android_Windowing.cpp
  25. +1
    -1
      modules/juce_opengl/native/juce_OpenGL_android.h

+ 2
- 0
examples/Demo/Source/Demos/MDIDemo.cpp View File

@@ -140,6 +140,8 @@ public:
#if JUCE_MODAL_LOOPS_PERMITTED
if (Note* note = dynamic_cast<Note*> (component))
return note->saveIfNeededAndUserAgrees() != FileBasedDocument::failedToWriteToFile;
#else
ignoreUnused (component);
#endif
return true;


+ 5
- 5
modules/juce_audio_devices/native/juce_android_Audio.cpp View File

@@ -199,7 +199,7 @@ public:
numDeviceOutputChannels = 2;
outputDevice = GlobalRef (env->NewObject (AudioTrack, AudioTrack.constructor,
STREAM_MUSIC, sampleRate, CHANNEL_OUT_STEREO, ENCODING_PCM_16BIT,
(jint) (minBufferSizeOut * numDeviceOutputChannels * sizeof (int16)), MODE_STREAM));
(jint) (minBufferSizeOut * numDeviceOutputChannels * static_cast<int> (sizeof (int16))), MODE_STREAM));
int outputDeviceState = env->CallIntMethod (outputDevice, AudioTrack.getState);
if (outputDeviceState > 0)
@@ -232,7 +232,7 @@ public:
0 /* (default audio source) */, sampleRate,
numDeviceInputChannelsAvailable > 1 ? CHANNEL_IN_STEREO : CHANNEL_IN_MONO,
ENCODING_PCM_16BIT,
(jint) (minBufferSizeIn * numDeviceInputChannels * sizeof (int16))));
(jint) (minBufferSizeIn * numDeviceInputChannels * static_cast<int> (sizeof (int16)))));
int inputDeviceState = env->CallIntMethod (inputDevice, AudioRecord.getState);
if (inputDeviceState > 0)
@@ -441,9 +441,9 @@ public:
//==============================================================================
void scanForDevices() {}
StringArray getDeviceNames (bool wantInputNames) const { return StringArray (javaAudioTypeName); }
int getDefaultDeviceIndex (bool forInput) const { return 0; }
int getIndexOfDevice (AudioIODevice* device, bool asInput) const { return device != nullptr ? 0 : -1; }
StringArray getDeviceNames (bool) const { return StringArray (javaAudioTypeName); }
int getDefaultDeviceIndex (bool) const { return 0; }
int getIndexOfDevice (AudioIODevice* device, bool) const { return device != nullptr ? 0 : -1; }
bool hasSeparateInputsAndOutputs() const { return false; }
AudioIODevice* createDevice (const String& outputDeviceName,


+ 5
- 5
modules/juce_audio_devices/native/juce_android_Midi.cpp View File

@@ -96,8 +96,8 @@ public:
jassert (byteArray != nullptr);
jbyte* data = getEnv()->GetByteArrayElements (byteArray, nullptr);
HeapBlock<uint8> buffer (len);
std::memcpy (buffer.getData(), data + offset, len);
HeapBlock<uint8> buffer (static_cast<size_t> (len));
std::memcpy (buffer.getData(), data + offset, static_cast<size_t> (len));
midiConcatenator.pushMidiData (buffer.getData(),
len, static_cast<double> (timestamp) * 1.0e-9,
@@ -109,8 +109,8 @@ public:
private:
MidiInput* juceMidiInput;
MidiInputCallback* callback;
GlobalRef javaMidiDevice;
MidiDataConcatenator midiConcatenator;
GlobalRef javaMidiDevice;
};
//==============================================================================
@@ -144,7 +144,7 @@ private:
};
JUCE_JNI_CALLBACK (JUCE_JOIN_MACRO (JUCE_ANDROID_ACTIVITY_CLASSNAME, _00024JuceMidiInputPort), handleReceive,
void, (JNIEnv* env, jobject device, jlong host, jbyteArray byteArray,
void, (JNIEnv* env, jobject, jlong host, jbyteArray byteArray,
jint offset, jint count, jlong timestamp))
{
// Java may create a Midi thread which JUCE doesn't know about and this callback may be
@@ -302,7 +302,7 @@ void MidiOutput::sendMessageNow (const MidiMessage& message)
jbyteArray content = messageContent.get();
jbyte* rawBytes = env->GetByteArrayElements (content, nullptr);
std::memcpy (rawBytes, message.getRawData(), messageSize);
std::memcpy (rawBytes, message.getRawData(), static_cast<size_t> (messageSize));
env->ReleaseByteArrayElements (content, rawBytes, 0);
androidMidi->send (content, (jint) 0, (jint) messageSize);


+ 29
- 29
modules/juce_audio_devices/native/juce_android_OpenSL.cpp View File

@@ -393,22 +393,22 @@ private:
if (engineObject != nullptr) (*engineObject)->Destroy (engineObject);
}
Player* createPlayer (const int numChannels, const int sampleRate, const int numBuffers, const int bufferSize)
Player* createPlayer (const int numChannels, const int sampleRateToUse, const int numBuffers, const int bufferSize)
{
if (numChannels <= 0)
return nullptr;
ScopedPointer<Player> player (new Player (numChannels, sampleRate, *this, numBuffers, bufferSize));
return player->openedOk() ? player.release() : nullptr;
ScopedPointer<Player> newPlayer (new Player (numChannels, sampleRateToUse, *this, numBuffers, bufferSize));
return newPlayer->openedOk() ? newPlayer.release() : nullptr;
}
Recorder* createRecorder (const int numChannels, const int sampleRate, const int numBuffers, const int bufferSize)
Recorder* createRecorder (const int numChannels, const int sampleRateToUse, const int numBuffers, const int bufferSize)
{
if (numChannels <= 0)
return nullptr;
ScopedPointer<Recorder> recorder (new Recorder (numChannels, sampleRate, *this, numBuffers, bufferSize));
return recorder->openedOk() ? recorder.release() : nullptr;
ScopedPointer<Recorder> newRecorder (new Recorder (numChannels, sampleRateToUse, *this, numBuffers, bufferSize));
return newRecorder->openedOk() ? newRecorder.release() : nullptr;
}
SLObjectItf engineObject;
@@ -431,7 +431,7 @@ private:
{
BufferList (const int numChannels_, const int numBuffers_, const int numSamples_)
: numChannels (numChannels_), numBuffers (numBuffers_), numSamples (numSamples_),
bufferSpace (numChannels_ * numSamples * numBuffers), nextBlock (0)
bufferSpace (static_cast<size_t> (numChannels_ * numSamples * numBuffers)), nextBlock (0)
{
}
@@ -459,7 +459,7 @@ private:
void bufferReturned() noexcept { --numBlocksOut; dataArrived.signal(); }
void bufferSent() noexcept { ++numBlocksOut; dataArrived.signal(); }
int getBufferSizeBytes() const noexcept { return numChannels * numSamples * sizeof (int16); }
int getBufferSizeBytes() const noexcept { return numChannels * numSamples * static_cast<int> (sizeof (int16)); }
const int numChannels, numBuffers, numSamples;
@@ -473,7 +473,7 @@ private:
//==============================================================================
struct Player
{
Player (int numChannels, int sampleRate, Engine& engine, int playerNumBuffers, int playerBufferSize)
Player (int numChannels, int playerSampleRate, Engine& slEngine, int playerNumBuffers, int playerBufferSize)
: playerObject (nullptr), playerPlay (nullptr), playerBufferQueue (nullptr),
bufferList (numChannels, playerNumBuffers, playerBufferSize)
{
@@ -481,7 +481,7 @@ private:
{
SL_DATAFORMAT_PCM,
(SLuint32) numChannels,
(SLuint32) (sampleRate * 1000),
(SLuint32) (playerSampleRate * 1000),
SL_PCMSAMPLEFORMAT_FIXED_16,
SL_PCMSAMPLEFORMAT_FIXED_16,
(numChannels == 1) ? SL_SPEAKER_FRONT_CENTER : (SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT),
@@ -492,19 +492,19 @@ private:
static_cast<SLuint32> (bufferList.numBuffers) };
SLDataSource audioSrc = { &bufferQueue, &pcmFormat };
SLDataLocator_OutputMix outputMix = { SL_DATALOCATOR_OUTPUTMIX, engine.outputMixObject };
SLDataLocator_OutputMix outputMix = { SL_DATALOCATOR_OUTPUTMIX, slEngine.outputMixObject };
SLDataSink audioSink = { &outputMix, nullptr };
// (SL_IID_BUFFERQUEUE is not guaranteed to remain future-proof, so use SL_IID_ANDROIDSIMPLEBUFFERQUEUE)
const SLInterfaceID interfaceIDs[] = { *engine.SL_IID_ANDROIDSIMPLEBUFFERQUEUE };
const SLInterfaceID interfaceIDs[] = { *slEngine.SL_IID_ANDROIDSIMPLEBUFFERQUEUE };
const SLboolean flags[] = { SL_BOOLEAN_TRUE };
check ((*engine.engineInterface)->CreateAudioPlayer (engine.engineInterface, &playerObject, &audioSrc, &audioSink,
1, interfaceIDs, flags));
check ((*slEngine.engineInterface)->CreateAudioPlayer (slEngine.engineInterface, &playerObject, &audioSrc, &audioSink,
1, interfaceIDs, flags));
check ((*playerObject)->Realize (playerObject, SL_BOOLEAN_FALSE));
check ((*playerObject)->GetInterface (playerObject, *engine.SL_IID_PLAY, &playerPlay));
check ((*playerObject)->GetInterface (playerObject, *engine.SL_IID_ANDROIDSIMPLEBUFFERQUEUE, &playerBufferQueue));
check ((*playerObject)->GetInterface (playerObject, *slEngine.SL_IID_PLAY, &playerPlay));
check ((*playerObject)->GetInterface (playerObject, *slEngine.SL_IID_ANDROIDSIMPLEBUFFERQUEUE, &playerBufferQueue));
check ((*playerBufferQueue)->RegisterCallback (playerBufferQueue, staticCallback, this));
}
@@ -572,7 +572,7 @@ private:
void enqueueBuffer (int16* buffer) noexcept
{
check ((*playerBufferQueue)->Enqueue (playerBufferQueue, buffer, bufferList.getBufferSizeBytes()));
check ((*playerBufferQueue)->Enqueue (playerBufferQueue, buffer, static_cast<SLuint32> (bufferList.getBufferSizeBytes())));
bufferList.bufferSent();
}
@@ -588,7 +588,7 @@ private:
//==============================================================================
struct Recorder
{
Recorder (int numChannels, int sampleRate, Engine& engine, const int numBuffers, const int numSamples)
Recorder (int numChannels, int recorderSampleRate, Engine& slEngine, const int numBuffers, const int numSamples)
: recorderObject (nullptr), recorderRecord (nullptr),
recorderBufferQueue (nullptr), configObject (nullptr),
bufferList (numChannels, numBuffers, numSamples)
@@ -597,7 +597,7 @@ private:
{
SL_DATAFORMAT_PCM,
(SLuint32) numChannels,
(SLuint32) (sampleRate * 1000), // (sample rate units are millihertz)
(SLuint32) (recorderSampleRate * 1000), // (sample rate units are millihertz)
SL_PCMSAMPLEFORMAT_FIXED_16,
SL_PCMSAMPLEFORMAT_FIXED_16,
(numChannels == 1) ? SL_SPEAKER_FRONT_CENTER : (SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT),
@@ -611,19 +611,19 @@ private:
static_cast<SLuint32> (bufferList.numBuffers) };
SLDataSink audioSink = { &bufferQueue, &pcmFormat };
const SLInterfaceID interfaceIDs[] = { *engine.SL_IID_ANDROIDSIMPLEBUFFERQUEUE };
const SLInterfaceID interfaceIDs[] = { *slEngine.SL_IID_ANDROIDSIMPLEBUFFERQUEUE };
const SLboolean flags[] = { SL_BOOLEAN_TRUE };
if (check ((*engine.engineInterface)->CreateAudioRecorder (engine.engineInterface, &recorderObject, &audioSrc,
&audioSink, 1, interfaceIDs, flags)))
if (check ((*slEngine.engineInterface)->CreateAudioRecorder (slEngine.engineInterface, &recorderObject, &audioSrc,
&audioSink, 1, interfaceIDs, flags)))
{
if (check ((*recorderObject)->Realize (recorderObject, SL_BOOLEAN_FALSE)))
{
check ((*recorderObject)->GetInterface (recorderObject, *engine.SL_IID_RECORD, &recorderRecord));
check ((*recorderObject)->GetInterface (recorderObject, *engine.SL_IID_ANDROIDSIMPLEBUFFERQUEUE, &recorderBufferQueue));
check ((*recorderObject)->GetInterface (recorderObject, *slEngine.SL_IID_RECORD, &recorderRecord));
check ((*recorderObject)->GetInterface (recorderObject, *slEngine.SL_IID_ANDROIDSIMPLEBUFFERQUEUE, &recorderBufferQueue));
// not all android versions seem to have a config object
SLresult result = (*recorderObject)->GetInterface (recorderObject,
*engine.SL_IID_ANDROIDCONFIGURATION, &configObject);
*slEngine.SL_IID_ANDROIDCONFIGURATION, &configObject);
if (result != SL_RESULT_SUCCESS)
configObject = nullptr;
@@ -707,7 +707,7 @@ private:
void enqueueBuffer (int16* buffer) noexcept
{
check ((*recorderBufferQueue)->Enqueue (recorderBufferQueue, buffer, bufferList.getBufferSizeBytes()));
check ((*recorderBufferQueue)->Enqueue (recorderBufferQueue, buffer, static_cast<SLuint32> (bufferList.getBufferSizeBytes())));
bufferList.bufferSent();
}
@@ -746,9 +746,9 @@ public:
//==============================================================================
void scanForDevices() override {}
StringArray getDeviceNames (bool wantInputNames) const override { return StringArray (openSLTypeName); }
int getDefaultDeviceIndex (bool forInput) const override { return 0; }
int getIndexOfDevice (AudioIODevice* device, bool asInput) const override { return device != nullptr ? 0 : -1; }
StringArray getDeviceNames (bool) const override { return StringArray (openSLTypeName); }
int getDefaultDeviceIndex (bool) const override { return 0; }
int getIndexOfDevice (AudioIODevice* device, bool) const override { return device != nullptr ? 0 : -1; }
bool hasSeparateInputsAndOutputs() const override { return false; }
AudioIODevice* createDevice (const String& outputDeviceName,


+ 3
- 3
modules/juce_audio_formats/codecs/juce_AiffAudioFormat.cpp View File

@@ -197,9 +197,9 @@ namespace AiffFileHelpers
{
static bool isValidTag (const char* d) noexcept
{
return CharacterFunctions::isLetterOrDigit (d[0]) && CharacterFunctions::isUpperCase (d[0])
&& CharacterFunctions::isLetterOrDigit (d[1]) && CharacterFunctions::isLowerCase (d[1])
&& CharacterFunctions::isLetterOrDigit (d[2]) && CharacterFunctions::isLowerCase (d[2]);
return CharacterFunctions::isLetterOrDigit (d[0]) && CharacterFunctions::isUpperCase (static_cast<juce_wchar> (d[0]))
&& CharacterFunctions::isLetterOrDigit (d[1]) && CharacterFunctions::isLowerCase (static_cast<juce_wchar> (d[1]))
&& CharacterFunctions::isLetterOrDigit (d[2]) && CharacterFunctions::isLowerCase (static_cast<juce_wchar> (d[2]));
}
static bool isAppleGenre (const String& tag) noexcept


+ 5
- 6
modules/juce_audio_utils/native/juce_android_BluetoothMidiDevicePairingDialogue.cpp View File

@@ -192,7 +192,7 @@ private:
}
void paintListBoxItem (int rowNumber, Graphics& g,
int width, int height, bool rowIsSelected) override
int width, int height, bool) override
{
if (isPositiveAndBelow (rowNumber, devices.size()))
{
@@ -210,14 +210,13 @@ private:
g.setColour (getDeviceNameFontColour (device.connectionStatus));
g.drawText (device.name,
xmargin, ymargin,
deviceNameWidth - (2.0f * xmargin), height - (2.0f * ymargin),
Rectangle<float> (xmargin, ymargin, deviceNameWidth - (2.0f * xmargin), height - (2.0f * ymargin)),
Justification::topLeft, true);
g.setColour (getDeviceStatusFontColour (device.connectionStatus));
g.drawText (statusString,
deviceNameWidth + xmargin, ymargin,
width - deviceNameWidth - (2.0f * xmargin), height - (2.0f * ymargin),
Rectangle<float> (deviceNameWidth + xmargin, ymargin,
width - deviceNameWidth - (2.0f * xmargin), height - (2.0f * ymargin)),
Justification::topRight, true);
g.setColour (Colours::grey);
@@ -439,7 +438,7 @@ bool BluetoothMidiDevicePairingDialogue::open (ModalComponentManager::Callback*
return false;
}
BluetoothMidiSelectorOverlay* overlay = new BluetoothMidiSelectorOverlay (exitCallback.release());
new BluetoothMidiSelectorOverlay (exitCallback.release());
return true;
}


+ 1
- 1
modules/juce_core/javascript/juce_JSON.cpp View File

@@ -84,7 +84,7 @@ public:
if (digitValue < 0)
return createFail ("Syntax error in unicode escape sequence");
c = (juce_wchar) ((c << 4) + digitValue);
c = (juce_wchar) ((c << 4) + static_cast<juce_wchar> (digitValue));
}
break;


+ 1
- 1
modules/juce_core/javascript/juce_Javascript.cpp View File

@@ -1636,7 +1636,7 @@ struct JavascriptEngine::RootObject : public DynamicObject
static Identifier getClassName() { static const Identifier i ("String"); return i; }
static var fromCharCode (Args a) { return String::charToString (getInt (a, 0)); }
static var fromCharCode (Args a) { return String::charToString (static_cast<juce_wchar> (getInt (a, 0))); }
static var substring (Args a) { return a.thisObject.toString().substring (getInt (a, 0), getInt (a, 1)); }
static var indexOf (Args a) { return a.thisObject.toString().indexOf (getString (a, 0)); }
static var charCodeAt (Args a) { return (int) a.thisObject.toString() [getInt (a, 0)]; }


+ 1
- 1
modules/juce_core/native/juce_android_Files.cpp View File

@@ -98,7 +98,7 @@ bool File::moveToTrash() const
return false;
}
JUCE_API bool JUCE_CALLTYPE Process::openDocument (const String& fileName, const String& parameters)
JUCE_API bool JUCE_CALLTYPE Process::openDocument (const String& fileName, const String&)
{
const LocalRef<jstring> t (javaString (fileName));
android.activity.callVoidMethod (JuceAppActivity.launchURL, t.get());


+ 5
- 4
modules/juce_core/native/juce_android_JNIHelpers.h View File

@@ -149,7 +149,7 @@ private:
//==============================================================================
namespace
{
String juceString (JNIEnv* env, jstring s)
inline String juceString (JNIEnv* env, jstring s)
{
const char* const utf8 = env->GetStringUTFChars (s, nullptr);
CharPointer_UTF8 utf8CP (utf8);
@@ -158,17 +158,17 @@ namespace
return result;
}
String juceString (jstring s)
inline String juceString (jstring s)
{
return juceString (getEnv(), s);
}
LocalRef<jstring> javaString (const String& s)
inline LocalRef<jstring> javaString (const String& s)
{
return LocalRef<jstring> (getEnv()->NewStringUTF (s.toUTF8()));
}
LocalRef<jstring> javaStringFromChar (const juce_wchar c)
inline LocalRef<jstring> javaStringFromChar (const juce_wchar c)
{
char utf8[8] = { 0 };
CharPointer_UTF8 (utf8).write (c);
@@ -223,6 +223,7 @@ private:
\
void initialiseFields (JNIEnv* env) \
{ \
ignoreUnused (env); \
JNI_CLASS_MEMBERS (CREATE_JNI_METHOD, CREATE_JNI_STATICMETHOD, CREATE_JNI_FIELD, CREATE_JNI_STATICFIELD); \
} \
\


+ 8
- 8
modules/juce_core/native/juce_android_Network.cpp View File

@@ -50,16 +50,16 @@ DECLARE_JNI_CLASS (HTTPStream, JUCE_ANDROID_ACTIVITY_CLASSPATH "$HTTPStream");
//==============================================================================
void MACAddress::findAllAddresses (Array<MACAddress>& result)
void MACAddress::findAllAddresses (Array<MACAddress>& /*result*/)
{
// TODO
}
JUCE_API bool JUCE_CALLTYPE Process::openEmailWithAttachments (const String& targetEmailAddress,
const String& emailSubject,
const String& bodyText,
const StringArray& filesToAttach)
JUCE_API bool JUCE_CALLTYPE Process::openEmailWithAttachments (const String& /*targetEmailAddress*/,
const String& /*emailSubject*/,
const String& /*bodyText*/,
const StringArray& /*filesToAttach*/)
{
// TODO
return false;
@@ -95,7 +95,7 @@ public:
}
}
bool connect (WebInputStream::Listener* listener)
bool connect (WebInputStream::Listener* /*listener*/)
{
String address = url.toString (! isPost);
@@ -112,8 +112,8 @@ public:
if (postData.getSize() > 0)
{
postDataArray = env->NewByteArray (postData.getSize());
env->SetByteArrayRegion (postDataArray, 0, postData.getSize(), (const jbyte*) postData.getData());
postDataArray = env->NewByteArray (static_cast<jsize> (postData.getSize()));
env->SetByteArrayRegion (postDataArray, 0, static_cast<jsize> (postData.getSize()), (const jbyte*) postData.getData());
}
LocalRef<jobject> responseHeaderBuffer (env->NewObject (StringBuffer, StringBuffer.constructor));


+ 1
- 1
modules/juce_core/native/juce_android_SystemStats.cpp View File

@@ -275,7 +275,7 @@ uint32 juce_millisecondsSinceStartup() noexcept
timespec t;
clock_gettime (CLOCK_MONOTONIC, &t);
return t.tv_sec * 1000 + t.tv_nsec / 1000000;
return static_cast<uint32> (t.tv_sec) * 1000U + static_cast<uint32> (t.tv_nsec) / 1000000U;
}
int64 Time::getHighResolutionTicks() noexcept


+ 1
- 1
modules/juce_core/native/juce_android_Threads.cpp View File

@@ -98,7 +98,7 @@ void* threadEntryProc (AndroidThreadData* priv)
}
JUCE_JNI_CALLBACK (JUCE_JOIN_MACRO (JUCE_ANDROID_ACTIVITY_CLASSNAME, _00024JuceThread), runThread,
void, (JNIEnv* env, jobject device, jlong host))
void, (JNIEnv* env, jobject /*device*/, jlong host))
{
// This thread does not have a JNIEnv assigned to it yet. So assign it now.
setEnv (env);


+ 12
- 6
modules/juce_core/native/juce_posix_SharedCode.h View File

@@ -219,6 +219,12 @@ bool File::setAsCurrentWorkingDirectory() const
return chdir (getFullPathName().toUTF8()) == 0;
}
#if JUCE_ANDROID
typedef unsigned long juce_sigactionflags_type;
#else
typedef int juce_sigactionflags_type;
#endif
//==============================================================================
// The unix siginterrupt function is deprecated - this does the same job.
int juce_siginterrupt (int sig, int flag)
@@ -227,9 +233,9 @@ int juce_siginterrupt (int sig, int flag)
(void) ::sigaction (sig, nullptr, &act);
if (flag != 0)
act.sa_flags &= ~SA_RESTART;
act.sa_flags &= static_cast<juce_sigactionflags_type> (~SA_RESTART);
else
act.sa_flags |= SA_RESTART;
act.sa_flags |= static_cast<juce_sigactionflags_type> (SA_RESTART);
return ::sigaction (sig, &act, nullptr);
}
@@ -369,7 +375,7 @@ static bool setFileModeFlags (const String& fullPath, mode_t flags, bool shouldS
else
info.st_mode &= ~flags;
return chmod (fullPath.toUTF8(), info.st_mode) == 0;
return chmod (fullPath.toUTF8(), (mode_t) info.st_mode) == 0;
}
bool File::setFileReadOnlyInternal (bool shouldBeReadOnly) const
@@ -406,8 +412,8 @@ bool File::setFileTimesInternal (int64 modificationTime, int64 accessTime, int64
if ((modificationTime != 0 || accessTime != 0) && juce_stat (fullPath, info))
{
struct utimbuf times;
times.actime = accessTime != 0 ? (time_t) (accessTime / 1000) : info.st_atime;
times.modtime = modificationTime != 0 ? (time_t) (modificationTime / 1000) : info.st_mtime;
times.actime = (time_t) (accessTime != 0 ? (accessTime / 1000) : info.st_atime);
times.modtime = (time_t) (modificationTime != 0 ? (modificationTime / 1000) : info.st_mtime);
return utime (fullPath.toUTF8(), &times) == 0;
}
@@ -455,7 +461,7 @@ Result File::createDirectoryInternal (const String& fileName) const
//==============================================================================
int64 juce_fileSetPosition (void* handle, int64 pos)
{
if (handle != 0 && lseek (getFD (handle), pos, SEEK_SET) == pos)
if (handle != 0 && lseek (getFD (handle), (off_t) pos, SEEK_SET) == pos)
return pos;
return -1;


+ 13
- 4
modules/juce_core/network/juce_Socket.cpp View File

@@ -39,10 +39,17 @@
#if JUCE_WINDOWS
typedef int juce_socklen_t;
typedef int juce_recvsend_size_t;
typedef SOCKET SocketHandle;
static const SocketHandle invalidSocket = INVALID_SOCKET;
#elif JUCE_ANDROID
typedef socklen_t juce_socklen_t;
typedef size_t juce_recvsend_size_t;
typedef int SocketHandle;
static const SocketHandle invalidSocket = -1;
#else
typedef socklen_t juce_socklen_t;
typedef socklen_t juce_recvsend_size_t;
typedef int SocketHandle;
static const SocketHandle invalidSocket = -1;
#endif
@@ -198,7 +205,7 @@ namespace SocketHelpers
{
long bytesThisTime = -1;
char* const buffer = static_cast<char*> (destBuffer) + bytesRead;
const juce_socklen_t numToRead = (juce_socklen_t) (maxBytesToRead - bytesRead);
const juce_recvsend_size_t numToRead = (juce_recvsend_size_t) (maxBytesToRead - bytesRead);
{
// avoid race-condition
@@ -467,7 +474,7 @@ int StreamingSocket::write (const void* sourceBuffer, const int numBytesToWrite)
if (isListener || ! connected)
return -1;
return (int) ::send (handle, (const char*) sourceBuffer, (juce_socklen_t) numBytesToWrite, 0);
return (int) ::send (handle, (const char*) sourceBuffer, (juce_recvsend_size_t) numBytesToWrite, 0);
}
//==============================================================================
@@ -730,7 +737,7 @@ int DatagramSocket::write (const String& remoteHostname, int remotePortNumber,
}
return (int) ::sendto (handle, (const char*) sourceBuffer,
(juce_socklen_t) numBytesToWrite, 0,
(juce_recvsend_size_t) numBytesToWrite, 0,
info->ai_addr, (socklen_t) info->ai_addrlen);
}
@@ -752,7 +759,9 @@ bool DatagramSocket::leaveMulticast (const String& multicastIPAddress)
bool DatagramSocket::setEnablePortReuse (bool enabled)
{
#if ! JUCE_ANDROID
#if JUCE_ANDROID
ignoreUnused (enabled);
#else
if (handle >= 0)
return SocketHelpers::setOption (handle,
#if JUCE_WINDOWS || JUCE_LINUX


+ 2
- 2
modules/juce_core/text/juce_CharPointer_UTF16.h View File

@@ -99,7 +99,7 @@ public:
/** Moves this pointer along to the next character in the string. */
CharPointer_UTF16 operator++() noexcept
{
const juce_wchar n = *data++;
const juce_wchar n = static_cast<juce_wchar> (*data++);
if (n >= 0xd800 && n <= 0xdfff && ((uint32) (uint16) *data) >= 0xdc00)
++data;
@@ -110,7 +110,7 @@ public:
/** Moves this pointer back to the previous character in the string. */
CharPointer_UTF16 operator--() noexcept
{
const juce_wchar n = *--data;
const juce_wchar n = static_cast<juce_wchar> (*--data);
if (n >= 0xdc00 && n <= 0xdfff)
--data;


+ 1
- 1
modules/juce_core/text/juce_CharPointer_UTF8.h View File

@@ -126,7 +126,7 @@ public:
{
juce_wchar bit = 0x40;
while ((n & bit) != 0 && bit > 0x8)
while ((static_cast<juce_wchar> (n) & bit) != 0 && bit > 0x8)
{
++data;
bit >>= 1;


+ 2
- 2
modules/juce_core/text/juce_String.cpp View File

@@ -1883,7 +1883,7 @@ String String::formatted (const String pf, ... )
#elif JUCE_ANDROID
HeapBlock<char> temp (bufferSize);
int num = (int) vsnprintf (temp.getData(), bufferSize - 1, pf.toUTF8(), args);
if (num >= bufferSize)
if (num >= static_cast<int> (bufferSize))
num = -1;
#else
HeapBlock<wchar_t> temp (bufferSize);
@@ -1926,7 +1926,7 @@ int String::getTrailingIntValue() const noexcept
break;
}
n += mult * (*t - '0');
n += static_cast<juce_wchar> (mult) * (*t - '0');
mult *= 10;
}


+ 2
- 2
modules/juce_events/native/juce_android_Messaging.cpp View File

@@ -32,7 +32,7 @@ void MessageManager::doPlatformSpecificInitialisation() {}
void MessageManager::doPlatformSpecificShutdown() {}
//==============================================================================
bool MessageManager::dispatchNextMessageOnSystemQueue (const bool returnIfNoPendingMessages)
bool MessageManager::dispatchNextMessageOnSystemQueue (const bool)
{
Logger::outputDebugString ("*** Modal loops are not possible in Android!! Exiting...");
exit (1);
@@ -48,7 +48,7 @@ bool MessageManager::postMessageToSystemQueue (MessageManager::MessageBase* cons
return true;
}
JUCE_JNI_CALLBACK (JUCE_ANDROID_ACTIVITY_CLASSNAME, deliverMessage, void, (JNIEnv* env, jobject activity, jlong value))
JUCE_JNI_CALLBACK (JUCE_ANDROID_ACTIVITY_CLASSNAME, deliverMessage, void, (JNIEnv* env, jobject, jlong value))
{
setEnv (env);


+ 1
- 1
modules/juce_graphics/fonts/juce_CustomTypeface.cpp View File

@@ -227,7 +227,7 @@ void CustomTypeface::addGlyphsFromOtherTypeface (Typeface& typefaceToCopy, juce_
for (int i = 0; i < numCharacters; ++i)
{
const juce_wchar c = (juce_wchar) (characterStartIndex + i);
const juce_wchar c = (juce_wchar) (characterStartIndex + static_cast<juce_wchar> (i));
Array <int> glyphIndexes;
Array <float> offsets;


+ 4
- 4
modules/juce_graphics/native/juce_android_Fonts.cpp View File

@@ -169,8 +169,8 @@ public:
{
JNIEnv* const env = getEnv();
LocalRef<jbyteArray> bytes (env->NewByteArray (size));
env->SetByteArrayRegion (bytes, 0, size, (const jbyte*) data);
LocalRef<jbyteArray> bytes (env->NewByteArray ((jsize) size));
env->SetByteArrayRegion (bytes, 0, (jsize) size, (const jbyte*) data);
typeface = GlobalRef (android.activity.callObjectMethod (JuceAppActivity.getTypeFaceFromByteArray, bytes.get()));
@@ -207,7 +207,7 @@ public:
const int numDone = paint.callIntMethod (Paint.getTextWidths, javaString (text).get(), widths);
HeapBlock<jfloat> localWidths (numDone);
HeapBlock<jfloat> localWidths (static_cast<size_t> (numDone));
env->GetFloatArrayRegion (widths, 0, numDone, localWidths);
env->DeleteLocalRef (widths);
@@ -226,7 +226,7 @@ public:
const int numDone = paint.callIntMethod (Paint.getTextWidths, javaString (text).get(), widths);
HeapBlock<jfloat> localWidths (numDone);
HeapBlock<jfloat> localWidths (static_cast<size_t> (numDone));
env->GetFloatArrayRegion (widths, 0, numDone, localWidths);
env->DeleteLocalRef (widths);


+ 1
- 1
modules/juce_gui_basics/keyboard/juce_KeyPress.cpp View File

@@ -150,7 +150,7 @@ namespace KeyPressHelpers
{
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
return (int) (KeyPress::numberPad0 + lastChar - '0');
return (int) (KeyPress::numberPad0 + (int) lastChar - '0');
case '+': return KeyPress::numberPadAdd;
case '-': return KeyPress::numberPadSubtract;


+ 10
- 10
modules/juce_gui_basics/native/juce_android_FileChooser.cpp View File

@@ -22,17 +22,17 @@
==============================================================================
*/
void FileChooser::showPlatformDialog (Array<File>& results,
const String& title,
const File& currentFileOrDirectory,
const String& filter,
bool selectsDirectory,
bool selectsFiles,
bool isSaveDialogue,
bool warnAboutOverwritingExistingFiles,
bool selectMultipleFiles,
void FileChooser::showPlatformDialog (Array<File>& /*results*/,
const String& /*title*/,
const File& /*currentFileOrDirectory*/,
const String& /*filter*/,
bool /*selectsDirectory*/,
bool /*selectsFiles*/,
bool /*isSaveDialogue*/,
bool /*warnAboutOverwritingExistingFiles*/,
bool /*selectMultipleFiles*/,
bool /*treatFilePackagesAsDirs*/,
FilePreviewComponent* extraInfoComponent)
FilePreviewComponent* /*extraInfoComponent*/)
{
// TODO


+ 36
- 36
modules/juce_gui_basics/native/juce_android_Windowing.cpp View File

@@ -56,7 +56,7 @@ JUCE_JNI_CALLBACK (JUCE_ANDROID_ACTIVITY_CLASSNAME, launchApp, void, (JNIEnv* en
jassert (MessageManager::getInstance()->isThisTheMessageThread());
}
JUCE_JNI_CALLBACK (JUCE_ANDROID_ACTIVITY_CLASSNAME, suspendApp, void, (JNIEnv* env, jobject activity))
JUCE_JNI_CALLBACK (JUCE_ANDROID_ACTIVITY_CLASSNAME, suspendApp, void, (JNIEnv* env, jobject))
{
setEnv (env);
@@ -64,7 +64,7 @@ JUCE_JNI_CALLBACK (JUCE_ANDROID_ACTIVITY_CLASSNAME, suspendApp, void, (JNIEnv* e
app->suspended();
}
JUCE_JNI_CALLBACK (JUCE_ANDROID_ACTIVITY_CLASSNAME, resumeApp, void, (JNIEnv* env, jobject activity))
JUCE_JNI_CALLBACK (JUCE_ANDROID_ACTIVITY_CLASSNAME, resumeApp, void, (JNIEnv* env, jobject))
{
setEnv (env);
@@ -72,7 +72,7 @@ JUCE_JNI_CALLBACK (JUCE_ANDROID_ACTIVITY_CLASSNAME, resumeApp, void, (JNIEnv* en
app->resumed();
}
JUCE_JNI_CALLBACK (JUCE_ANDROID_ACTIVITY_CLASSNAME, quitApp, void, (JNIEnv* env, jobject activity))
JUCE_JNI_CALLBACK (JUCE_ANDROID_ACTIVITY_CLASSNAME, quitApp, void, (JNIEnv* env, jobject))
{
setEnv (env);
@@ -213,7 +213,7 @@ public:
class ViewMover : public CallbackMessage
{
public:
ViewMover (const GlobalRef& v, const Rectangle<int>& r) : view (v), bounds (r) {}
ViewMover (const GlobalRef& v, const Rectangle<int>& boundsToUse) : view (v), bounds (boundsToUse) {}
void messageCallback() override
{
@@ -262,7 +262,7 @@ public:
return screenPosition - getScreenPosition().toFloat();
}
void setMinimised (bool shouldBeMinimised) override
void setMinimised (bool /*shouldBeMinimised*/) override
{
// n/a
}
@@ -337,7 +337,7 @@ public:
stopTimer();
}
void setIcon (const Image& newIcon) override
void setIcon (const Image& /*newIcon*/) override
{
// n/a
}
@@ -357,7 +357,7 @@ public:
return BorderSize<int>();
}
bool setAlwaysOnTop (bool alwaysOnTop) override
bool setAlwaysOnTop (bool /*alwaysOnTop*/) override
{
// TODO
return false;
@@ -419,10 +419,10 @@ public:
void handleKeyDownCallback (int k, int kc)
{
handleKeyPress (k, kc);
handleKeyPress (k, static_cast<juce_wchar> (kc));
}
void handleKeyUpCallback (int k, int kc)
void handleKeyUpCallback (int /*k*/, int /*kc*/)
{
}
@@ -549,7 +549,7 @@ public:
// TODO
}
void setAlpha (float newAlpha) override
void setAlpha (float /*newAlpha*/) override
{
// TODO
}
@@ -578,7 +578,7 @@ private:
: ImagePixelData (Image::ARGB, width_, height_), data (data_), hasAlpha (hasAlpha_)
{
if (hasAlpha_)
zeromem (data_, width * height * sizeof (jint));
zeromem (data_, static_cast<size_t> (width * height) * sizeof (jint));
}
~PreallocatedImage()
@@ -598,10 +598,10 @@ private:
ImageType* createType() const override { return new SoftwareImageType(); }
LowLevelGraphicsContext* createLowLevelContext() override { return new LowLevelGraphicsSoftwareRenderer (Image (this)); }
void initialiseBitmapData (Image::BitmapData& bm, int x, int y, Image::BitmapData::ReadWriteMode mode) override
void initialiseBitmapData (Image::BitmapData& bm, int x, int y, Image::BitmapData::ReadWriteMode /*mode*/) override
{
bm.lineStride = width * sizeof (jint);
bm.pixelStride = sizeof (jint);
bm.lineStride = width * static_cast<int> (sizeof (jint));
bm.pixelStride = static_cast<int> (sizeof (jint));
bm.pixelFormat = Image::ARGB;
bm.data = (uint8*) (data + x + y * width);
}
@@ -609,9 +609,9 @@ private:
ImagePixelData::Ptr clone() override
{
PreallocatedImage* s = new PreallocatedImage (width, height, 0, hasAlpha);
s->allocatedData.malloc (sizeof (jint) * width * height);
s->allocatedData.malloc (sizeof (jint) * static_cast<size_t> (width * height));
s->data = s->allocatedData;
memcpy (s->data, data, sizeof (jint) * width * height);
memcpy (s->data, data, sizeof (jint) * static_cast<size_t> (width * height));
return s;
}
@@ -639,14 +639,14 @@ int64 AndroidComponentPeer::touchesDown = 0;
peer->juceMethodInvocation; \
}
JUCE_VIEW_CALLBACK (void, handlePaint, (JNIEnv* env, jobject view, jlong host, jobject canvas, jobject paint), handlePaintCallback (env, canvas, paint))
JUCE_VIEW_CALLBACK (void, handleMouseDown, (JNIEnv* env, jobject view, jlong host, jint i, jfloat x, jfloat y, jlong time), handleMouseDownCallback (i, Point<float> ((float) x, (float) y), (int64) time))
JUCE_VIEW_CALLBACK (void, handleMouseDrag, (JNIEnv* env, jobject view, jlong host, jint i, jfloat x, jfloat y, jlong time), handleMouseDragCallback (i, Point<float> ((float) x, (float) y), (int64) time))
JUCE_VIEW_CALLBACK (void, handleMouseUp, (JNIEnv* env, jobject view, jlong host, jint i, jfloat x, jfloat y, jlong time), handleMouseUpCallback (i, Point<float> ((float) x, (float) y), (int64) time))
JUCE_VIEW_CALLBACK (void, viewSizeChanged, (JNIEnv* env, jobject view, jlong host), handleMovedOrResized())
JUCE_VIEW_CALLBACK (void, focusChanged, (JNIEnv* env, jobject view, jlong host, jboolean hasFocus), handleFocusChangeCallback (hasFocus))
JUCE_VIEW_CALLBACK (void, handleKeyDown, (JNIEnv* env, jobject view, jlong host, jint k, jint kc), handleKeyDownCallback ((int) k, (int) kc))
JUCE_VIEW_CALLBACK (void, handleKeyUp, (JNIEnv* env, jobject view, jlong host, jint k, jint kc), handleKeyUpCallback ((int) k, (int) kc))
JUCE_VIEW_CALLBACK (void, handlePaint, (JNIEnv* env, jobject /*view*/, jlong host, jobject canvas, jobject paint), handlePaintCallback (env, canvas, paint))
JUCE_VIEW_CALLBACK (void, handleMouseDown, (JNIEnv* env, jobject /*view*/, jlong host, jint i, jfloat x, jfloat y, jlong time), handleMouseDownCallback (i, Point<float> ((float) x, (float) y), (int64) time))
JUCE_VIEW_CALLBACK (void, handleMouseDrag, (JNIEnv* env, jobject /*view*/, jlong host, jint i, jfloat x, jfloat y, jlong time), handleMouseDragCallback (i, Point<float> ((float) x, (float) y), (int64) time))
JUCE_VIEW_CALLBACK (void, handleMouseUp, (JNIEnv* env, jobject /*view*/, jlong host, jint i, jfloat x, jfloat y, jlong time), handleMouseUpCallback (i, Point<float> ((float) x, (float) y), (int64) time))
JUCE_VIEW_CALLBACK (void, viewSizeChanged, (JNIEnv* env, jobject /*view*/, jlong host), handleMovedOrResized())
JUCE_VIEW_CALLBACK (void, focusChanged, (JNIEnv* env, jobject /*view*/, jlong host, jboolean hasFocus), handleFocusChangeCallback (hasFocus))
JUCE_VIEW_CALLBACK (void, handleKeyDown, (JNIEnv* env, jobject /*view*/, jlong host, jint k, jint kc), handleKeyDownCallback ((int) k, (int) kc))
JUCE_VIEW_CALLBACK (void, handleKeyUp, (JNIEnv* env, jobject /*view*/, jlong host, jint k, jint kc), handleKeyUpCallback ((int) k, (int) kc))
//==============================================================================
ComponentPeer* Component::createNewPeer (int styleFlags, void*)
@@ -688,7 +688,7 @@ void MouseInputSource::setRawMousePosition (Point<float>)
}
//==============================================================================
bool KeyPress::isKeyCurrentlyDown (const int keyCode)
bool KeyPress::isKeyCurrentlyDown (const int /*keyCode*/)
{
// TODO
return false;
@@ -711,18 +711,18 @@ JUCE_API void JUCE_CALLTYPE Process::makeForegroundProcess() {}
JUCE_API void JUCE_CALLTYPE Process::hide() {}
//==============================================================================
void JUCE_CALLTYPE NativeMessageBox::showMessageBoxAsync (AlertWindow::AlertIconType iconType,
void JUCE_CALLTYPE NativeMessageBox::showMessageBoxAsync (AlertWindow::AlertIconType /*iconType*/,
const String& title, const String& message,
Component* associatedComponent,
Component* /*associatedComponent*/,
ModalComponentManager::Callback* callback)
{
android.activity.callVoidMethod (JuceAppActivity.showMessageBox, javaString (title).get(),
javaString (message).get(), (jlong) (pointer_sized_int) callback);
}
bool JUCE_CALLTYPE NativeMessageBox::showOkCancelBox (AlertWindow::AlertIconType iconType,
bool JUCE_CALLTYPE NativeMessageBox::showOkCancelBox (AlertWindow::AlertIconType /*iconType*/,
const String& title, const String& message,
Component* associatedComponent,
Component* /*associatedComponent*/,
ModalComponentManager::Callback* callback)
{
jassert (callback != nullptr); // on android, all alerts must be non-modal!!
@@ -732,9 +732,9 @@ bool JUCE_CALLTYPE NativeMessageBox::showOkCancelBox (AlertWindow::AlertIconType
return false;
}
int JUCE_CALLTYPE NativeMessageBox::showYesNoCancelBox (AlertWindow::AlertIconType iconType,
int JUCE_CALLTYPE NativeMessageBox::showYesNoCancelBox (AlertWindow::AlertIconType /*iconType*/,
const String& title, const String& message,
Component* associatedComponent,
Component* /*associatedComponent*/,
ModalComponentManager::Callback* callback)
{
jassert (callback != nullptr); // on android, all alerts must be non-modal!!
@@ -744,7 +744,7 @@ int JUCE_CALLTYPE NativeMessageBox::showYesNoCancelBox (AlertWindow::AlertIconTy
return 0;
}
JUCE_JNI_CALLBACK (JUCE_ANDROID_ACTIVITY_CLASSNAME, alertDismissed, void, (JNIEnv* env, jobject activity,
JUCE_JNI_CALLBACK (JUCE_ANDROID_ACTIVITY_CLASSNAME, alertDismissed, void, (JNIEnv* env, jobject /*activity*/,
jlong callbackAsLong, jint result))
{
setEnv (env);
@@ -830,7 +830,7 @@ void Desktop::Displays::findDisplays (float masterScale)
displays.add (d);
}
JUCE_JNI_CALLBACK (JUCE_ANDROID_ACTIVITY_CLASSNAME, setScreenSize, void, (JNIEnv* env, jobject activity,
JUCE_JNI_CALLBACK (JUCE_ANDROID_ACTIVITY_CLASSNAME, setScreenSize, void, (JNIEnv* env, jobject /*activity*/,
jint screenWidth, jint screenHeight,
jint dpi))
{
@@ -844,7 +844,7 @@ JUCE_JNI_CALLBACK (JUCE_ANDROID_ACTIVITY_CLASSNAME, setScreenSize, void, (JNIEnv
}
//==============================================================================
Image juce_createIconForFile (const File& file)
Image juce_createIconForFile (const File& /*file*/)
{
return Image();
}
@@ -859,12 +859,12 @@ void MouseCursor::showInWindow (ComponentPeer*) const {}
void MouseCursor::showInAllWindows() const {}
//==============================================================================
bool DragAndDropContainer::performExternalDragDropOfFiles (const StringArray& files, const bool canMove)
bool DragAndDropContainer::performExternalDragDropOfFiles (const StringArray& /*files*/, const bool /*canMove*/)
{
return false;
}
bool DragAndDropContainer::performExternalDragDropOfText (const String& text)
bool DragAndDropContainer::performExternalDragDropOfText (const String& /*text*/)
{
return false;
}


+ 1
- 1
modules/juce_opengl/native/juce_OpenGL_android.h View File

@@ -43,7 +43,7 @@ class OpenGLContext::NativeContext
{
public:
NativeContext (Component& comp,
const OpenGLPixelFormat& pixelFormat,
const OpenGLPixelFormat& /*pixelFormat*/,
void* /*contextToShareWith*/,
bool /*useMultisampling*/,
OpenGLVersion)


Loading…
Cancel
Save