@@ -118,8 +118,8 @@ class LADSPAPluginInstance : public AudioPluginInstance | |||
{ | |||
public: | |||
LADSPAPluginInstance (const LADSPAModuleHandle::Ptr& m) | |||
: plugin (nullptr), handle (nullptr), initialised (false), | |||
tempBuffer (1, 1), module (m) | |||
: module (m), plugin (nullptr), handle (nullptr), | |||
initialised (false), tempBuffer (1, 1) | |||
{ | |||
++insideLADSPACallback; | |||
@@ -79,10 +79,11 @@ JUCE_API bool JUCE_CALLTYPE Process::isRunningUnderDebugger() | |||
return juce_isRunningUnderDebugger(); | |||
} | |||
static void swapUserAndEffectiveUser() | |||
static bool swapUserAndEffectiveUser() | |||
{ | |||
(void) setreuid (geteuid(), getuid()); | |||
(void) setregid (getegid(), getgid()); | |||
int result1 = setreuid (geteuid(), getuid()); | |||
int result2 = setregid (getegid(), getgid()); | |||
return result1 == 0 && result2 == 0; | |||
} | |||
JUCE_API void JUCE_CALLTYPE Process::raisePrivilege() { if (geteuid() != 0 && getuid() == 0) swapUserAndEffectiveUser(); } | |||
@@ -94,24 +94,20 @@ private: | |||
//============================================================================== | |||
Value::Value() | |||
: value (new SimpleValueSource()) | |||
Value::Value() : value (new SimpleValueSource()) | |||
{ | |||
} | |||
Value::Value (ValueSource* const v) | |||
: value (v) | |||
Value::Value (ValueSource* const v) : value (v) | |||
{ | |||
jassert (v != nullptr); | |||
} | |||
Value::Value (const var& initialValue) | |||
: value (new SimpleValueSource (initialValue)) | |||
Value::Value (const var& initialValue) : value (new SimpleValueSource (initialValue)) | |||
{ | |||
} | |||
Value::Value (const Value& other) | |||
: value (other.value) | |||
Value::Value (const Value& other) : value (other.value) | |||
{ | |||
} | |||
@@ -123,12 +119,22 @@ Value& Value::operator= (const Value& other) | |||
#if JUCE_COMPILER_SUPPORTS_MOVE_SEMANTICS | |||
Value::Value (Value&& other) noexcept | |||
: value (static_cast<ReferenceCountedObjectPtr<ValueSource>&&> (other.value)) | |||
{ | |||
// moving a Value with listeners will lose those listeners, which | |||
// probably isn't what you wanted to happen! | |||
jassert (other.listeners.size() == 0); | |||
other.removeFromListenerList(); | |||
value = static_cast<ReferenceCountedObjectPtr<ValueSource>&&> (other.value); | |||
} | |||
Value& Value::operator= (Value&& other) noexcept | |||
{ | |||
// moving a Value with listeners will lose those listeners, which | |||
// probably isn't what you wanted to happen! | |||
jassert (other.listeners.size() == 0); | |||
other.removeFromListenerList(); | |||
value = static_cast<ReferenceCountedObjectPtr<ValueSource>&&> (other.value); | |||
return *this; | |||
} | |||
@@ -136,7 +142,12 @@ Value& Value::operator= (Value&& other) noexcept | |||
Value::~Value() | |||
{ | |||
if (listeners.size() > 0) | |||
removeFromListenerList(); | |||
} | |||
void Value::removeFromListenerList() | |||
{ | |||
if (listeners.size() > 0 && value != nullptr) // may be nullptr after a move operation | |||
value->valuesWithListeners.removeValue (this); | |||
} | |||
@@ -217,6 +217,7 @@ private: | |||
ListenerList<Listener> listeners; | |||
void callListeners(); | |||
void removeFromListenerList(); | |||
// This is disallowed to avoid confusion about whether it should | |||
// do a by-value or by-reference copy. | |||
@@ -27,7 +27,7 @@ enum { magicMastSlaveConnectionHeader = 0x712baf04 }; | |||
static const char* startMessage = "__ipc_st"; | |||
static const char* killMessage = "__ipc_k_"; | |||
static const char* pingMessage = "__ipc_p_"; | |||
enum { specialMessageSize = 8 }; | |||
enum { specialMessageSize = 8, defaultTimeoutMs = 8000 }; | |||
static String getCommandLinePrefix (const String& commandLineUniqueID) | |||
{ | |||
@@ -40,7 +40,7 @@ static String getCommandLinePrefix (const String& commandLineUniqueID) | |||
struct ChildProcessPingThread : public Thread, | |||
private AsyncUpdater | |||
{ | |||
ChildProcessPingThread() : Thread ("IPC ping"), timeoutMs (8000) | |||
ChildProcessPingThread (int timeout) : Thread ("IPC ping"), timeoutMs (timeout) | |||
{ | |||
pingReceived(); | |||
} | |||
@@ -84,8 +84,10 @@ private: | |||
struct ChildProcessMaster::Connection : public InterprocessConnection, | |||
private ChildProcessPingThread | |||
{ | |||
Connection (ChildProcessMaster& m, const String& pipeName) | |||
: InterprocessConnection (false, magicMastSlaveConnectionHeader), owner (m) | |||
Connection (ChildProcessMaster& m, const String& pipeName, int timeout) | |||
: InterprocessConnection (false, magicMastSlaveConnectionHeader), | |||
ChildProcessPingThread (timeout), | |||
owner (m) | |||
{ | |||
if (createPipe (pipeName, timeoutMs)) | |||
startThread (4); | |||
@@ -140,7 +142,7 @@ bool ChildProcessMaster::sendMessageToSlave (const MemoryBlock& mb) | |||
return false; | |||
} | |||
bool ChildProcessMaster::launchSlaveProcess (const File& executable, const String& commandLineUniqueID) | |||
bool ChildProcessMaster::launchSlaveProcess (const File& executable, const String& commandLineUniqueID, int timeoutMs) | |||
{ | |||
connection = nullptr; | |||
jassert (childProcess.kill()); | |||
@@ -153,7 +155,7 @@ bool ChildProcessMaster::launchSlaveProcess (const File& executable, const Strin | |||
if (childProcess.start (args)) | |||
{ | |||
connection = new Connection (*this, pipeName); | |||
connection = new Connection (*this, pipeName, timeoutMs <= 0 ? defaultTimeoutMs : timeoutMs); | |||
if (connection->isConnected()) | |||
{ | |||
@@ -171,8 +173,10 @@ bool ChildProcessMaster::launchSlaveProcess (const File& executable, const Strin | |||
struct ChildProcessSlave::Connection : public InterprocessConnection, | |||
private ChildProcessPingThread | |||
{ | |||
Connection (ChildProcessSlave& p, const String& pipeName) | |||
: InterprocessConnection (false, magicMastSlaveConnectionHeader), owner (p) | |||
Connection (ChildProcessSlave& p, const String& pipeName, int timeout) | |||
: InterprocessConnection (false, magicMastSlaveConnectionHeader), | |||
ChildProcessPingThread (timeout), | |||
owner (p) | |||
{ | |||
connectToPipe (pipeName, timeoutMs); | |||
startThread (4); | |||
@@ -237,7 +241,8 @@ bool ChildProcessSlave::sendMessageToMaster (const MemoryBlock& mb) | |||
} | |||
bool ChildProcessSlave::initialiseFromCommandLine (const String& commandLine, | |||
const String& commandLineUniqueID) | |||
const String& commandLineUniqueID, | |||
int timeoutMs) | |||
{ | |||
String prefix (getCommandLinePrefix (commandLineUniqueID)); | |||
@@ -248,7 +253,7 @@ bool ChildProcessSlave::initialiseFromCommandLine (const String& commandLine, | |||
if (pipeName.isNotEmpty()) | |||
{ | |||
connection = new Connection (*this, pipeName); | |||
connection = new Connection (*this, pipeName, timeoutMs <= 0 ? defaultTimeoutMs : timeoutMs); | |||
if (! connection->isConnected()) | |||
connection = nullptr; | |||
@@ -64,10 +64,16 @@ public: | |||
The commandLineUniqueID should be a short alphanumeric identifier (no spaces!) | |||
that matches the string passed to ChildProcessMaster::launchSlaveProcess(). | |||
The timeoutMs parameter lets you specify how long the child process is allowed | |||
to run without receiving a ping from the master before the master is considered to | |||
have died, and handleConnectionLost() will be called. Passing <= 0 for this timeout | |||
makes it use a default value. | |||
Returns true if the command-line matches and the connection is made successfully. | |||
*/ | |||
bool initialiseFromCommandLine (const String& commandLine, | |||
const String& commandLineUniqueID); | |||
const String& commandLineUniqueID, | |||
int timeoutMs = 0); | |||
//============================================================================== | |||
/** This will be called to deliver messages from the master process. | |||
@@ -141,11 +147,17 @@ public: | |||
that gets launched must respond by calling ChildProcessSlave::initialiseFromCommandLine() | |||
in its startup code, and must use a matching ID to commandLineUniqueID. | |||
The timeoutMs parameter lets you specify how long the child process is allowed | |||
to go without sending a ping before it is considered to have died and | |||
handleConnectionLost() will be called. Passing <= 0 for this timeout makes | |||
it use a default value. | |||
If this all works, the method returns true, and you can begin sending and | |||
receiving messages with the slave process. | |||
*/ | |||
bool launchSlaveProcess (const File& executableToLaunch, | |||
const String& commandLineUniqueID); | |||
const String& commandLineUniqueID, | |||
int timeoutMs = 0); | |||
/** This will be called to deliver a message from the slave process. | |||
The call will probably be made on a background thread, so be careful with your thread-safety! | |||
@@ -589,6 +589,10 @@ namespace EdgeTableFillers | |||
filler[2].set (sourceColour); | |||
filler[3].set (sourceColour); | |||
} | |||
else | |||
{ | |||
areRGBComponentsEqual = false; | |||
} | |||
} | |||
forcedinline void setEdgeTableYPos (const int y) noexcept | |||
@@ -3049,7 +3049,7 @@ void Desktop::Displays::findDisplays (float masterScale) | |||
d.userArea = d.totalArea = Rectangle<int> (screens[j].x_org, | |||
screens[j].y_org, | |||
screens[j].width, | |||
screens[j].height) * masterScale; | |||
screens[j].height) / masterScale; | |||
d.isMain = (index == 0); | |||
d.scale = masterScale; | |||
d.dpi = getDisplayDPI (0); // (all screens share the same DPI) | |||
@@ -1931,7 +1931,7 @@ bool TextEditor::deleteBackwards (bool moveInWholeWordSteps) | |||
if (moveInWholeWordSteps) | |||
moveCaretTo (findWordBreakBefore (getCaretPosition()), true); | |||
else if (selection.isEmpty() && selection.getStart() > 0) | |||
selection.setStart (selection.getEnd() - 1); | |||
selection = Range<int> (selection.getEnd() - 1, selection.getEnd()); | |||
cut(); | |||
return true; | |||
@@ -1940,7 +1940,7 @@ bool TextEditor::deleteBackwards (bool moveInWholeWordSteps) | |||
bool TextEditor::deleteForwards (bool /*moveInWholeWordSteps*/) | |||
{ | |||
if (selection.isEmpty() && selection.getStart() < getTotalNumChars()) | |||
selection.setEnd (selection.getStart() + 1); | |||
selection = Range<int> (selection.getStart(), selection.getStart() + 1); | |||
cut(); | |||
return true; | |||