mirror of
https://github.com/juce-framework/JUCE.git
synced 2026-02-03 03:30:06 +00:00
This commit is contained in:
parent
c919933277
commit
47cf2369e5
136 changed files with 48629 additions and 38971 deletions
|
|
@ -367,7 +367,7 @@ private:
|
|||
class ALSAThread : public Thread
|
||||
{
|
||||
public:
|
||||
ALSAThread (const String& inputId_,
|
||||
ALSAThread (const String& inputId_,
|
||||
const String& outputId_)
|
||||
: Thread ("Juce ALSA"),
|
||||
sampleRate (0),
|
||||
|
|
@ -446,7 +446,7 @@ public:
|
|||
return;
|
||||
}
|
||||
|
||||
if (! outputDevice->setParameters ((unsigned int) sampleRate,
|
||||
if (! outputDevice->setParameters ((unsigned int) sampleRate,
|
||||
currentOutputChans.getHighestBit() + 1,
|
||||
bufferSize))
|
||||
{
|
||||
|
|
@ -467,7 +467,7 @@ public:
|
|||
return;
|
||||
}
|
||||
|
||||
if (! inputDevice->setParameters ((unsigned int) sampleRate,
|
||||
if (! inputDevice->setParameters ((unsigned int) sampleRate,
|
||||
currentInputChans.getHighestBit() + 1,
|
||||
bufferSize))
|
||||
{
|
||||
|
|
@ -673,7 +673,7 @@ class ALSAAudioIODevice : public AudioIODevice
|
|||
{
|
||||
public:
|
||||
ALSAAudioIODevice (const String& deviceName,
|
||||
const String& inputId_,
|
||||
const String& inputId_,
|
||||
const String& outputId_)
|
||||
: AudioIODevice (deviceName, T("ALSA")),
|
||||
inputId (inputId_),
|
||||
|
|
@ -980,8 +980,8 @@ public:
|
|||
deviceName = inputDeviceName;
|
||||
|
||||
if (index >= 0)
|
||||
return new ALSAAudioIODevice (deviceName,
|
||||
inputIds [inputIndex],
|
||||
return new ALSAAudioIODevice (deviceName,
|
||||
inputIds [inputIndex],
|
||||
outputIds [outputIndex]);
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -157,7 +157,7 @@ static void sig_handler (int sig)
|
|||
void MessageManager::doPlatformSpecificInitialisation()
|
||||
{
|
||||
// Initialise xlib for multiple thread support
|
||||
static bool initThreadCalled = false;
|
||||
static bool initThreadCalled = false;
|
||||
|
||||
if (! initThreadCalled)
|
||||
{
|
||||
|
|
@ -168,10 +168,10 @@ void MessageManager::doPlatformSpecificInitialisation()
|
|||
|
||||
if (juce_isRunningAsApplication())
|
||||
Process::terminate();
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
initThreadCalled = true;
|
||||
}
|
||||
|
||||
|
|
@ -212,7 +212,7 @@ void MessageManager::doPlatformSpecificInitialisation()
|
|||
|
||||
if (juce_isRunningAsApplication())
|
||||
Process::terminate();
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -247,11 +247,11 @@ void MessageManager::doPlatformSpecificShutdown()
|
|||
{
|
||||
XDestroyWindow (display, juce_messageWindowHandle);
|
||||
XCloseDisplay (display);
|
||||
|
||||
|
||||
// reset pointers
|
||||
juce_messageWindowHandle = 0;
|
||||
display = 0;
|
||||
|
||||
|
||||
// Restore original error handlers
|
||||
XSetIOErrorHandler (oldIOErrorHandler);
|
||||
oldIOErrorHandler = 0;
|
||||
|
|
@ -350,7 +350,7 @@ bool juce_dispatchNextMessageOnSystemQueue (bool returnIfNoPendingMessages)
|
|||
|
||||
if (juce_isRunningAsApplication())
|
||||
Process::terminate();
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -49,9 +49,6 @@ BEGIN_JUCE_NAMESPACE
|
|||
#include "../../../src/juce_core/misc/juce_PlatformUtilities.h"
|
||||
#include "../../../src/juce_core/io/network/juce_URL.h"
|
||||
|
||||
// we'll borrow the mac's socket-based http streaming code..
|
||||
#include "../../macosx/platform_specific_code/juce_mac_HTTPStream.h"
|
||||
|
||||
|
||||
//==============================================================================
|
||||
int SystemStats::getMACAddresses (int64* addresses, int maxNum, const bool littleEndian) throw()
|
||||
|
|
@ -103,5 +100,392 @@ bool PlatformUtilities::launchEmailWithAttachments (const String& targetEmailAdd
|
|||
return false;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
/** A HTTP input stream that uses sockets.
|
||||
*/
|
||||
class JUCE_HTTPSocketStream
|
||||
{
|
||||
public:
|
||||
//==============================================================================
|
||||
JUCE_HTTPSocketStream()
|
||||
: readPosition (0),
|
||||
socketHandle (-1),
|
||||
levelsOfRedirection (0),
|
||||
timeoutSeconds (15)
|
||||
{
|
||||
}
|
||||
|
||||
~JUCE_HTTPSocketStream()
|
||||
{
|
||||
closeSocket();
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
bool open (const String& url,
|
||||
const String& headers,
|
||||
const MemoryBlock& postData,
|
||||
const bool isPost,
|
||||
URL::OpenStreamProgressCallback* callback,
|
||||
void* callbackContext,
|
||||
int timeOutMs)
|
||||
{
|
||||
closeSocket();
|
||||
|
||||
uint32 timeOutTime = Time::getMillisecondCounter();
|
||||
|
||||
if (timeOutMs == 0)
|
||||
timeOutTime += 60000;
|
||||
else if (timeOutMs < 0)
|
||||
timeOutTime = 0xffffffff;
|
||||
else
|
||||
timeOutTime += timeOutMs;
|
||||
|
||||
String hostName, hostPath;
|
||||
int hostPort;
|
||||
|
||||
if (! decomposeURL (url, hostName, hostPath, hostPort))
|
||||
return false;
|
||||
|
||||
const struct hostent* host = 0;
|
||||
int port = 0;
|
||||
|
||||
String proxyName, proxyPath;
|
||||
int proxyPort = 0;
|
||||
|
||||
String proxyURL (getenv ("http_proxy"));
|
||||
if (proxyURL.startsWithIgnoreCase (T("http://")))
|
||||
{
|
||||
if (! decomposeURL (proxyURL, proxyName, proxyPath, proxyPort))
|
||||
return false;
|
||||
|
||||
host = gethostbyname ((const char*) proxyName.toUTF8());
|
||||
port = proxyPort;
|
||||
}
|
||||
else
|
||||
{
|
||||
host = gethostbyname ((const char*) hostName.toUTF8());
|
||||
port = hostPort;
|
||||
}
|
||||
|
||||
if (host == 0)
|
||||
return false;
|
||||
|
||||
struct sockaddr_in address;
|
||||
zerostruct (address);
|
||||
memcpy ((void*) &address.sin_addr, (const void*) host->h_addr, host->h_length);
|
||||
address.sin_family = host->h_addrtype;
|
||||
address.sin_port = htons (port);
|
||||
|
||||
socketHandle = socket (host->h_addrtype, SOCK_STREAM, 0);
|
||||
|
||||
if (socketHandle == -1)
|
||||
return false;
|
||||
|
||||
int receiveBufferSize = 16384;
|
||||
setsockopt (socketHandle, SOL_SOCKET, SO_RCVBUF, (char*) &receiveBufferSize, sizeof (receiveBufferSize));
|
||||
setsockopt (socketHandle, SOL_SOCKET, SO_KEEPALIVE, 0, 0);
|
||||
|
||||
#if JUCE_MAC
|
||||
setsockopt (socketHandle, SOL_SOCKET, SO_NOSIGPIPE, 0, 0);
|
||||
#endif
|
||||
|
||||
if (connect (socketHandle, (struct sockaddr*) &address, sizeof (address)) == -1)
|
||||
{
|
||||
closeSocket();
|
||||
return false;
|
||||
}
|
||||
|
||||
const MemoryBlock requestHeader (createRequestHeader (hostName, hostPort,
|
||||
proxyName, proxyPort,
|
||||
hostPath, url,
|
||||
headers, postData,
|
||||
isPost));
|
||||
int totalHeaderSent = 0;
|
||||
|
||||
while (totalHeaderSent < requestHeader.getSize())
|
||||
{
|
||||
if (Time::getMillisecondCounter() > timeOutTime)
|
||||
{
|
||||
closeSocket();
|
||||
return false;
|
||||
}
|
||||
|
||||
const int numToSend = jmin (1024, requestHeader.getSize() - totalHeaderSent);
|
||||
|
||||
if (send (socketHandle,
|
||||
((const char*) requestHeader.getData()) + totalHeaderSent,
|
||||
numToSend, 0)
|
||||
!= numToSend)
|
||||
{
|
||||
closeSocket();
|
||||
return false;
|
||||
}
|
||||
|
||||
totalHeaderSent += numToSend;
|
||||
|
||||
if (callback != 0 && ! callback (callbackContext, totalHeaderSent, requestHeader.getSize()))
|
||||
{
|
||||
closeSocket();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
const String responseHeader (readResponse (timeOutTime));
|
||||
|
||||
if (responseHeader.isNotEmpty())
|
||||
{
|
||||
//DBG (responseHeader);
|
||||
|
||||
StringArray lines;
|
||||
lines.addLines (responseHeader);
|
||||
|
||||
// NB - using charToString() here instead of just T(" "), because that was
|
||||
// causing a mysterious gcc internal compiler error...
|
||||
const int statusCode = responseHeader.fromFirstOccurrenceOf (String::charToString (T(' ')), false, false)
|
||||
.substring (0, 3)
|
||||
.getIntValue();
|
||||
|
||||
//int contentLength = findHeaderItem (lines, T("Content-Length:")).getIntValue();
|
||||
//bool isChunked = findHeaderItem (lines, T("Transfer-Encoding:")).equalsIgnoreCase ("chunked");
|
||||
|
||||
String location (findHeaderItem (lines, T("Location:")));
|
||||
|
||||
if (statusCode >= 300 && statusCode < 400
|
||||
&& location.isNotEmpty())
|
||||
{
|
||||
if (! location.startsWithIgnoreCase (T("http://")))
|
||||
location = T("http://") + location;
|
||||
|
||||
if (levelsOfRedirection++ < 3)
|
||||
return open (location, headers, postData, isPost, callback, callbackContext, timeOutMs);
|
||||
}
|
||||
else
|
||||
{
|
||||
levelsOfRedirection = 0;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
closeSocket();
|
||||
return false;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
int read (void* buffer, int bytesToRead)
|
||||
{
|
||||
fd_set readbits;
|
||||
FD_ZERO (&readbits);
|
||||
FD_SET (socketHandle, &readbits);
|
||||
|
||||
struct timeval tv;
|
||||
tv.tv_sec = timeoutSeconds;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
if (select (socketHandle + 1, &readbits, 0, 0, &tv) <= 0)
|
||||
return 0; // (timeout)
|
||||
|
||||
const int bytesRead = jmax (0, recv (socketHandle, buffer, bytesToRead, MSG_WAITALL));
|
||||
readPosition += bytesRead;
|
||||
return bytesRead;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
int readPosition;
|
||||
|
||||
//==============================================================================
|
||||
juce_UseDebuggingNewOperator
|
||||
|
||||
private:
|
||||
int socketHandle, levelsOfRedirection;
|
||||
const int timeoutSeconds;
|
||||
|
||||
//==============================================================================
|
||||
void closeSocket()
|
||||
{
|
||||
if (socketHandle >= 0)
|
||||
close (socketHandle);
|
||||
|
||||
socketHandle = -1;
|
||||
}
|
||||
|
||||
const MemoryBlock createRequestHeader (const String& hostName,
|
||||
const int hostPort,
|
||||
const String& proxyName,
|
||||
const int proxyPort,
|
||||
const String& hostPath,
|
||||
const String& originalURL,
|
||||
const String& headers,
|
||||
const MemoryBlock& postData,
|
||||
const bool isPost)
|
||||
{
|
||||
String header (isPost ? "POST " : "GET ");
|
||||
|
||||
if (proxyName.isEmpty())
|
||||
{
|
||||
header << hostPath << " HTTP/1.0\r\nHost: "
|
||||
<< hostName << ':' << hostPort;
|
||||
}
|
||||
else
|
||||
{
|
||||
header << originalURL << " HTTP/1.0\r\nHost: "
|
||||
<< proxyName << ':' << proxyPort;
|
||||
}
|
||||
|
||||
header << "\r\nUser-Agent: JUCE/"
|
||||
<< JUCE_MAJOR_VERSION << '.' << JUCE_MINOR_VERSION
|
||||
<< "\r\nConnection: Close\r\nContent-Length: "
|
||||
<< postData.getSize() << "\r\n"
|
||||
<< headers << "\r\n";
|
||||
|
||||
MemoryBlock mb;
|
||||
mb.append (header.toUTF8(), (int) strlen (header.toUTF8()));
|
||||
mb.append (postData.getData(), postData.getSize());
|
||||
|
||||
return mb;
|
||||
}
|
||||
|
||||
const String readResponse (const uint32 timeOutTime)
|
||||
{
|
||||
int bytesRead = 0, numConsecutiveLFs = 0;
|
||||
MemoryBlock buffer (1024, true);
|
||||
|
||||
while (numConsecutiveLFs < 2 && bytesRead < 32768
|
||||
&& Time::getMillisecondCounter() <= timeOutTime)
|
||||
{
|
||||
fd_set readbits;
|
||||
FD_ZERO (&readbits);
|
||||
FD_SET (socketHandle, &readbits);
|
||||
|
||||
struct timeval tv;
|
||||
tv.tv_sec = timeoutSeconds;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
if (select (socketHandle + 1, &readbits, 0, 0, &tv) <= 0)
|
||||
return String::empty; // (timeout)
|
||||
|
||||
buffer.ensureSize (bytesRead + 8, true);
|
||||
char* const dest = (char*) buffer.getData() + bytesRead;
|
||||
|
||||
if (recv (socketHandle, dest, 1, 0) == -1)
|
||||
return String::empty;
|
||||
|
||||
const char lastByte = *dest;
|
||||
++bytesRead;
|
||||
|
||||
if (lastByte == '\n')
|
||||
++numConsecutiveLFs;
|
||||
else if (lastByte != '\r')
|
||||
numConsecutiveLFs = 0;
|
||||
}
|
||||
|
||||
const String header (String::fromUTF8 ((const uint8*) buffer.getData()));
|
||||
|
||||
if (header.startsWithIgnoreCase (T("HTTP/")))
|
||||
return header.trimEnd();
|
||||
|
||||
return String::empty;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
static bool decomposeURL (const String& url,
|
||||
String& host, String& path, int& port)
|
||||
{
|
||||
if (! url.startsWithIgnoreCase (T("http://")))
|
||||
return false;
|
||||
|
||||
const int nextSlash = url.indexOfChar (7, '/');
|
||||
int nextColon = url.indexOfChar (7, ':');
|
||||
if (nextColon > nextSlash && nextSlash > 0)
|
||||
nextColon = -1;
|
||||
|
||||
if (nextColon >= 0)
|
||||
{
|
||||
host = url.substring (7, nextColon);
|
||||
|
||||
if (nextSlash >= 0)
|
||||
port = url.substring (nextColon + 1, nextSlash).getIntValue();
|
||||
else
|
||||
port = url.substring (nextColon + 1).getIntValue();
|
||||
}
|
||||
else
|
||||
{
|
||||
port = 80;
|
||||
|
||||
if (nextSlash >= 0)
|
||||
host = url.substring (7, nextSlash);
|
||||
else
|
||||
host = url.substring (7);
|
||||
}
|
||||
|
||||
if (nextSlash >= 0)
|
||||
path = url.substring (nextSlash);
|
||||
else
|
||||
path = T("/");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
static const String findHeaderItem (const StringArray& lines, const String& itemName)
|
||||
{
|
||||
for (int i = 0; i < lines.size(); ++i)
|
||||
if (lines[i].startsWithIgnoreCase (itemName))
|
||||
return lines[i].substring (itemName.length()).trim();
|
||||
|
||||
return String::empty;
|
||||
}
|
||||
};
|
||||
|
||||
//==============================================================================
|
||||
bool juce_isOnLine()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void* juce_openInternetFile (const String& url,
|
||||
const String& headers,
|
||||
const MemoryBlock& postData,
|
||||
const bool isPost,
|
||||
URL::OpenStreamProgressCallback* callback,
|
||||
void* callbackContext,
|
||||
int timeOutMs)
|
||||
{
|
||||
JUCE_HTTPSocketStream* const s = new JUCE_HTTPSocketStream();
|
||||
|
||||
if (s->open (url, headers, postData, isPost,
|
||||
callback, callbackContext, timeOutMs))
|
||||
return s;
|
||||
|
||||
delete s;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void juce_closeInternetFile (void* handle)
|
||||
{
|
||||
JUCE_HTTPSocketStream* const s = (JUCE_HTTPSocketStream*) handle;
|
||||
|
||||
if (s != 0)
|
||||
delete s;
|
||||
}
|
||||
|
||||
int juce_readFromInternetFile (void* handle, void* buffer, int bytesToRead)
|
||||
{
|
||||
JUCE_HTTPSocketStream* const s = (JUCE_HTTPSocketStream*) handle;
|
||||
|
||||
if (s != 0)
|
||||
return s->read (buffer, bytesToRead);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int juce_seekInInternetFile (void* handle, int newPosition)
|
||||
{
|
||||
JUCE_HTTPSocketStream* const s = (JUCE_HTTPSocketStream*) handle;
|
||||
|
||||
if (s != 0)
|
||||
return s->readPosition;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
END_JUCE_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ BEGIN_JUCE_NAMESPACE
|
|||
#include "../../../src/juce_core/threads/juce_Process.h"
|
||||
#include "../../../src/juce_core/io/files/juce_File.h"
|
||||
#include "../../../src/juce_core/basics/juce_SystemStats.h"
|
||||
#include "../../../src/juce_core/misc/juce_PlatformUtilities.h"
|
||||
|
||||
//==============================================================================
|
||||
/*
|
||||
|
|
@ -90,9 +91,9 @@ void juce_setCurrentThreadName (const String& /*name*/) throw()
|
|||
{
|
||||
}
|
||||
|
||||
int Thread::getCurrentThreadId() throw()
|
||||
int64 Thread::getCurrentThreadId() throw()
|
||||
{
|
||||
return (int) pthread_self();
|
||||
return pthread_self();
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -255,17 +256,17 @@ void Process::lowerPrivilege()
|
|||
}
|
||||
|
||||
#if JUCE_BUILD_GUI_CLASSES
|
||||
void* Process::loadDynamicLibrary (const String& name)
|
||||
void* PlatformUtilities::loadDynamicLibrary (const String& name)
|
||||
{
|
||||
return dlopen ((const char*) name.toUTF8(), RTLD_LOCAL | RTLD_NOW);
|
||||
}
|
||||
|
||||
void Process::freeDynamicLibrary (void* handle)
|
||||
void PlatformUtilities::freeDynamicLibrary (void* handle)
|
||||
{
|
||||
dlclose(handle);
|
||||
}
|
||||
|
||||
void* Process::getProcedureEntryPoint (void* libraryHandle, const String& procedureName)
|
||||
void* PlatformUtilities::getProcedureEntryPoint (void* libraryHandle, const String& procedureName)
|
||||
{
|
||||
return dlsym (libraryHandle, (const char*) procedureName);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ BEGIN_JUCE_NAMESPACE
|
|||
|
||||
#include "../../../src/juce_appframework/gui/components/special/juce_WebBrowserComponent.h"
|
||||
|
||||
#if JUCE_WEB_BROWSER
|
||||
|
||||
/*
|
||||
Sorry.. This class isn't implemented on Linux!
|
||||
|
|
@ -113,10 +114,6 @@ void WebBrowserComponent::parentHierarchyChanged()
|
|||
checkWindowAssociation();
|
||||
}
|
||||
|
||||
void WebBrowserComponent::moved()
|
||||
{
|
||||
}
|
||||
|
||||
void WebBrowserComponent::resized()
|
||||
{
|
||||
}
|
||||
|
|
@ -131,5 +128,5 @@ bool WebBrowserComponent::pageAboutToLoad (const String& url)
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
END_JUCE_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -467,7 +467,7 @@ static Pixmap juce_createColourPixmapFromImage (Display* display, const Image& i
|
|||
XImage* ximage = XCreateImage (display, CopyFromParent, 24, ZPixmap,
|
||||
0, (char*) colour, width, height, 32, 0);
|
||||
|
||||
Pixmap pixmap = XCreatePixmap (display, DefaultRootWindow (display),
|
||||
Pixmap pixmap = XCreatePixmap (display, DefaultRootWindow (display),
|
||||
width, height, 24);
|
||||
|
||||
GC gc = XCreateGC (display, pixmap, 0, 0);
|
||||
|
|
@ -1184,7 +1184,7 @@ public:
|
|||
wmHints->icon_mask = juce_createMaskPixmapFromImage (display, newIcon);
|
||||
|
||||
XSetWMHints (display, windowH, wmHints);
|
||||
XFree (wmHints);
|
||||
XFree (wmHints);
|
||||
|
||||
XSync (display, False);
|
||||
}
|
||||
|
|
@ -1754,7 +1754,7 @@ public:
|
|||
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
|
||||
// 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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue