From 571a2626daac546f9d64d19087e692986ab1c179 Mon Sep 17 00:00:00 2001 From: Julian Storer Date: Fri, 4 Feb 2011 12:20:04 +0000 Subject: [PATCH] Fixed an image anti-aliasing problem. Created some new methods in AudioIODeviceType to create device-specific types. Tidied up some win32 DLL build problems. Added support for drag-and-drop from iTunes on mac. --- juce.h | 4 +- juce_amalgamated.cpp | 696 +++++++++++++----- juce_amalgamated.h | 54 +- src/audio/devices/juce_AudioDeviceManager.cpp | 49 +- src/audio/devices/juce_AudioIODeviceType.cpp | 27 + src/audio/devices/juce_AudioIODeviceType.h | 16 + src/containers/juce_Variant.h | 2 +- src/core/juce_PlatformUtilities.h | 3 +- src/core/juce_StandardHeader.h | 2 +- src/core/juce_Time.h | 20 +- .../juce_LowLevelGraphicsSoftwareRenderer.cpp | 68 +- .../android/juce_android_GraphicsContext.cpp | 258 ++++++- src/native/android/juce_android_Messaging.cpp | 9 +- src/native/android/juce_android_Misc.cpp | 4 +- .../android/juce_android_NativeCode.cpp | 118 ++- src/native/android/juce_android_Windowing.cpp | 56 +- src/native/linux/juce_linux_Audio.cpp | 2 +- src/native/linux/juce_linux_JackAudio.cpp | 8 +- src/native/mac/juce_ios_Audio.cpp | 2 +- src/native/mac/juce_mac_CoreAudio.cpp | 2 +- .../mac/juce_mac_NSViewComponentPeer.mm | 83 ++- src/native/windows/juce_win32_ASIO.cpp | 2 +- src/native/windows/juce_win32_DirectSound.cpp | 2 +- src/native/windows/juce_win32_WASAPI.cpp | 7 +- src/text/juce_String.h | 2 +- src/threads/juce_CriticalSection.h | 4 +- src/threads/juce_ScopedLock.h | 2 +- 27 files changed, 1092 insertions(+), 410 deletions(-) diff --git a/juce.h b/juce.h index a41c379421..84ae097254 100644 --- a/juce.h +++ b/juce.h @@ -73,8 +73,8 @@ BEGIN_JUCE_NAMESPACE #pragma pack (pop) #endif -#ifdef JUCE_DLL - #undef JUCE_LEAK_DETECTOR(OwnerClass) +#if defined (JUCE_DLL) && ! (JUCE_AMALGAMATED_TEMPLATE || defined (JUCE_DLL_BUILD)) + #undef JUCE_LEAK_DETECTOR #define JUCE_LEAK_DETECTOR(OwnerClass) #endif diff --git a/juce_amalgamated.cpp b/juce_amalgamated.cpp index b13f4fb855..1e5ebb2cf8 100644 --- a/juce_amalgamated.cpp +++ b/juce_amalgamated.cpp @@ -25077,48 +25077,25 @@ const OwnedArray & AudioDeviceManager::getAvailableDeviceType return availableDeviceTypes; } -AudioIODeviceType* juce_createAudioIODeviceType_CoreAudio(); -AudioIODeviceType* juce_createAudioIODeviceType_iPhoneAudio(); -AudioIODeviceType* juce_createAudioIODeviceType_WASAPI(); -AudioIODeviceType* juce_createAudioIODeviceType_DirectSound(); -AudioIODeviceType* juce_createAudioIODeviceType_ASIO(); -AudioIODeviceType* juce_createAudioIODeviceType_ALSA(); AudioIODeviceType* juce_createAudioIODeviceType_JACK(); -void AudioDeviceManager::createAudioDeviceTypes (OwnedArray & list) +static void addIfNotNull (OwnedArray & list, AudioIODeviceType* const device) { - (void) list; // (to avoid 'unused param' warnings) - - #if JUCE_WINDOWS - #if JUCE_WASAPI - if (SystemStats::getOperatingSystemType() >= SystemStats::WinVista) - list.add (juce_createAudioIODeviceType_WASAPI()); - #endif - - #if JUCE_DIRECTSOUND - list.add (juce_createAudioIODeviceType_DirectSound()); - #endif - - #if JUCE_ASIO - list.add (juce_createAudioIODeviceType_ASIO()); - #endif - #endif - - #if JUCE_MAC - list.add (juce_createAudioIODeviceType_CoreAudio()); - #endif + if (device != 0) + list.add (device); +} - #if JUCE_IOS - list.add (juce_createAudioIODeviceType_iPhoneAudio()); - #endif +void AudioDeviceManager::createAudioDeviceTypes (OwnedArray & list) +{ + addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_WASAPI()); + addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_DirectSound()); + addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_ASIO()); - #if JUCE_LINUX && JUCE_ALSA - list.add (juce_createAudioIODeviceType_ALSA()); - #endif + addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_CoreAudio()); + addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_iOSAudio()); - #if JUCE_LINUX && JUCE_JACK - list.add (juce_createAudioIODeviceType_JACK()); - #endif + addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_ALSA()); + addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_JACK()); } const String AudioDeviceManager::initialise (const int numInputChannelsNeeded, @@ -25967,6 +25944,34 @@ AudioIODeviceType::~AudioIODeviceType() { } +#if ! JUCE_MAC +AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_CoreAudio() { return 0; } +#endif + +#if ! JUCE_IOS +AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_iOSAudio() { return 0; } +#endif + +#if ! (JUCE_WINDOWS && JUCE_WASAPI) +AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_WASAPI() { return 0; } +#endif + +#if ! (JUCE_WINDOWS && JUCE_DIRECTSOUND) +AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_DirectSound() { return 0; } +#endif + +#if ! (JUCE_WINDOWS && JUCE_ASIO) +AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_ASIO() { return 0; } +#endif + +#if ! (JUCE_LINUX && JUCE_ALSA) +AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_ALSA() { return 0; } +#endif + +#if ! (JUCE_LINUX && JUCE_JACK) +AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_JACK() { return 0; } +#endif + END_JUCE_NAMESPACE /*** End of inlined file: juce_AudioIODeviceType.cpp ***/ @@ -83944,9 +83949,9 @@ private: if (! repeatPattern) { if (loResY < 0) - render2PixelAverageX (dest, this->srcData.getPixelPointer (loResX, 0), hiResX & 255, hiResY & 255); + render2PixelAverageX (dest, this->srcData.getPixelPointer (loResX, 0), hiResX & 255); else - render2PixelAverageX (dest, this->srcData.getPixelPointer (loResX, maxY), hiResX & 255, 255 - (hiResY & 255)); + render2PixelAverageX (dest, this->srcData.getPixelPointer (loResX, maxY), hiResX & 255); ++dest; continue; @@ -83961,9 +83966,9 @@ private: if (! repeatPattern) { if (loResX < 0) - render2PixelAverageY (dest, this->srcData.getPixelPointer (0, loResY), hiResY & 255, hiResX & 255); + render2PixelAverageY (dest, this->srcData.getPixelPointer (0, loResY), hiResY & 255); else - render2PixelAverageY (dest, this->srcData.getPixelPointer (maxX, loResY), hiResY & 255, 255 - (hiResX & 255)); + render2PixelAverageY (dest, this->srcData.getPixelPointer (maxX, loResY), hiResY & 255); ++dest; continue; @@ -84022,33 +84027,33 @@ private: (uint8) (c[PixelARGB::indexB] >> 16)); } - void render2PixelAverageX (PixelARGB* const dest, const uint8* src, const int subPixelX, const int alpha) throw() + void render2PixelAverageX (PixelARGB* const dest, const uint8* src, const int subPixelX) throw() { - uint32 c[4] = { 256 * 128, 256 * 128, 256 * 128, 256 * 128 }; + uint32 c[4] = { 128, 128, 128, 128 }; - uint32 weight = (256 - subPixelX) * alpha; + uint32 weight = 256 - subPixelX; c[0] += weight * src[0]; c[1] += weight * src[1]; c[2] += weight * src[2]; c[3] += weight * src[3]; - weight = subPixelX * alpha; + weight = subPixelX; c[0] += weight * src[4]; c[1] += weight * src[5]; c[2] += weight * src[6]; c[3] += weight * src[7]; - dest->setARGB ((uint8) (c[PixelARGB::indexA] >> 16), - (uint8) (c[PixelARGB::indexR] >> 16), - (uint8) (c[PixelARGB::indexG] >> 16), - (uint8) (c[PixelARGB::indexB] >> 16)); + dest->setARGB ((uint8) (c[PixelARGB::indexA] >> 8), + (uint8) (c[PixelARGB::indexR] >> 8), + (uint8) (c[PixelARGB::indexG] >> 8), + (uint8) (c[PixelARGB::indexB] >> 8)); } - void render2PixelAverageY (PixelARGB* const dest, const uint8* src, const int subPixelY, const int alpha) throw() + void render2PixelAverageY (PixelARGB* const dest, const uint8* src, const int subPixelY) throw() { - uint32 c[4] = { 256 * 128, 256 * 128, 256 * 128, 256 * 128 }; + uint32 c[4] = { 128, 128, 128, 128 }; - uint32 weight = (256 - subPixelY) * alpha; + uint32 weight = 256 - subPixelY; c[0] += weight * src[0]; c[1] += weight * src[1]; c[2] += weight * src[2]; @@ -84056,16 +84061,16 @@ private: src += this->srcData.lineStride; - weight = subPixelY * alpha; + weight = subPixelY; c[0] += weight * src[0]; c[1] += weight * src[1]; c[2] += weight * src[2]; c[3] += weight * src[3]; - dest->setARGB ((uint8) (c[PixelARGB::indexA] >> 16), - (uint8) (c[PixelARGB::indexR] >> 16), - (uint8) (c[PixelARGB::indexG] >> 16), - (uint8) (c[PixelARGB::indexB] >> 16)); + dest->setARGB ((uint8) (c[PixelARGB::indexA] >> 8), + (uint8) (c[PixelARGB::indexR] >> 8), + (uint8) (c[PixelARGB::indexG] >> 8), + (uint8) (c[PixelARGB::indexB] >> 8)); } void render4PixelAverage (PixelRGB* const dest, const uint8* src, const int subPixelX, const int subPixelY) throw() @@ -84100,11 +84105,11 @@ private: (uint8) (c[PixelRGB::indexB] >> 16)); } - void render2PixelAverageX (PixelRGB* const dest, const uint8* src, const int subPixelX, const int /*alpha*/) throw() + void render2PixelAverageX (PixelRGB* const dest, const uint8* src, const int subPixelX) throw() { uint32 c[3] = { 128, 128, 128 }; - uint32 weight = (256 - subPixelX); + const uint32 weight = 256 - subPixelX; c[0] += weight * src[0]; c[1] += weight * src[1]; c[2] += weight * src[2]; @@ -84119,11 +84124,11 @@ private: (uint8) (c[PixelRGB::indexB] >> 8)); } - void render2PixelAverageY (PixelRGB* const dest, const uint8* src, const int subPixelY, const int /*alpha*/) throw() + void render2PixelAverageY (PixelRGB* const dest, const uint8* src, const int subPixelY) throw() { uint32 c[3] = { 128, 128, 128 }; - uint32 weight = (256 - subPixelY); + const uint32 weight = 256 - subPixelY; c[0] += weight * src[0]; c[1] += weight * src[1]; c[2] += weight * src[2]; @@ -84152,21 +84157,21 @@ private: *((uint8*) dest) = (uint8) (c >> 16); } - void render2PixelAverageX (PixelAlpha* const dest, const uint8* src, const int subPixelX, const int alpha) throw() + void render2PixelAverageX (PixelAlpha* const dest, const uint8* src, const int subPixelX) throw() { - uint32 c = 256 * 128; - c += src[0] * (256 - subPixelX) * alpha; - c += src[1] * subPixelX * alpha; - *((uint8*) dest) = (uint8) (c >> 16); + uint32 c = 128; + c += src[0] * (256 - subPixelX); + c += src[1] * subPixelX; + *((uint8*) dest) = (uint8) (c >> 8); } - void render2PixelAverageY (PixelAlpha* const dest, const uint8* src, const int subPixelY, const int alpha) throw() + void render2PixelAverageY (PixelAlpha* const dest, const uint8* src, const int subPixelY) throw() { - uint32 c = 256 * 128; - c += src[0] * (256 - subPixelY) * alpha; + uint32 c = 128; + c += src[0] * (256 - subPixelY); src += this->srcData.lineStride; - c += src[0] * subPixelY * alpha; - *((uint8*) dest) = (uint8) (c >> 16); + c += src[0] * subPixelY; + *((uint8*) dest) = (uint8) (c >> 8); } class TransformedImageSpanInterpolator @@ -249992,7 +249997,7 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ASIOAudioIODeviceType); }; -AudioIODeviceType* juce_createAudioIODeviceType_ASIO() +AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_ASIO() { return new ASIOAudioIODeviceType(); } @@ -251362,7 +251367,7 @@ const String DSoundAudioIODevice::openDevice (const BigInteger& inputChannels, return error; } -AudioIODeviceType* juce_createAudioIODeviceType_DirectSound() +AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_DirectSound() { return new DSoundAudioIODeviceType(); } @@ -252386,9 +252391,12 @@ private: } -AudioIODeviceType* juce_createAudioIODeviceType_WASAPI() +AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_WASAPI() { - return new WasapiClasses::WASAPIAudioIODeviceType(); + if (SystemStats::getOperatingSystemType() >= SystemStats::WinVista) + return new WasapiClasses::WASAPIAudioIODeviceType(); + + return 0; } #endif @@ -260817,7 +260825,7 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ALSAAudioIODeviceType); }; -AudioIODeviceType* juce_createAudioIODeviceType_ALSA() +AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_ALSA() { return new ALSAAudioIODeviceType(); } @@ -261385,15 +261393,11 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (JackAudioIODeviceType); }; -AudioIODeviceType* juce_createAudioIODeviceType_JACK() +AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_JACK() { return new JackAudioIODeviceType(); } -#else // if JACK is turned off.. - -AudioIODeviceType* juce_createAudioIODeviceType_JACK() { return 0; } - #endif #endif /*** End of inlined file: juce_linux_JackAudio.cpp ***/ @@ -269046,7 +269050,7 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (IPhoneAudioIODeviceType); }; -AudioIODeviceType* juce_createAudioIODeviceType_iPhoneAudio() +AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_iOSAudio() { return new IPhoneAudioIODeviceType(); } @@ -271569,7 +271573,7 @@ END_JUCE_NAMESPACE - (NSArray*) getSupportedDragTypes { - return [NSArray arrayWithObjects: NSFilenamesPboardType, /*NSFilesPromisePboardType, NSStringPboardType,*/ nil]; + return [NSArray arrayWithObjects: NSFilenamesPboardType, NSFilesPromisePboardType, /* NSStringPboardType,*/ nil]; } - (BOOL) sendDragCallback: (int) type sender: (id ) sender @@ -272003,9 +272007,26 @@ NSRect NSViewComponentPeer::constrainRect (NSRect r) void NSViewComponentPeer::setAlpha (float newAlpha) { if (! isSharedWindow) + { [window setAlphaValue: (CGFloat) newAlpha]; + } else + { + #if defined (MAC_OS_X_VERSION_10_5) && MAC_OS_X_VERSION_MIN_ALLOWED >= MAC_OS_X_VERSION_10_5 [view setAlphaValue: (CGFloat) newAlpha]; + #else + if ([view respondsToSelector: @selector (setAlphaValue:)]) + { + // PITA dynamic invocation for 10.4 builds.. + NSInvocation* inv = [NSInvocation invocationWithMethodSignature: [view methodSignatureForSelector: @selector (setAlphaValue:)]]; + [inv setSelector: @selector (setAlphaValue:)]; + [inv setTarget: view]; + CGFloat cgNewAlpha = (CGFloat) newAlpha; + [inv setArgument: &cgNewAlpha atIndex: 2]; + [inv invoke]; + } + #endif + } } void NSViewComponentPeer::setMinimised (bool shouldBeMinimised) @@ -272387,7 +272408,7 @@ void NSViewComponentPeer::showArrowCursorIfNeeded() } } -BOOL NSViewComponentPeer::sendDragCallback (int type, id sender) +BOOL NSViewComponentPeer::sendDragCallback (const int type, id sender) { NSString* bestType = [[sender draggingPasteboard] availableTypeFromArray: [view getSupportedDragTypes]]; @@ -272398,31 +272419,59 @@ BOOL NSViewComponentPeer::sendDragCallback (int type, id sender NSPoint p = [view convertPoint: [sender draggingLocation] fromView: nil]; const Point pos ((int) p.x, (int) ([view frame].size.height - p.y)); - id list = [[sender draggingPasteboard] propertyListForType: bestType]; - if (list == nil) - return false; - + NSPasteboard* pasteBoard = [sender draggingPasteboard]; StringArray files; - if ([list isKindOfClass: [NSArray class]]) + NSString* iTunesPasteboardType = @"CorePasteboardFlavorType 0x6974756E"; // 'itun' + + if (bestType == NSFilesPromisePboardType + && [[pasteBoard types] containsObject: iTunesPasteboardType]) { - NSArray* items = (NSArray*) list; + id list = [pasteBoard propertyListForType: iTunesPasteboardType]; + + if ([list isKindOfClass: [NSDictionary class]]) + { + NSDictionary* iTunesDictionary = (NSDictionary*) list; + NSArray* tracks = [iTunesDictionary valueForKey: @"Tracks"]; + NSEnumerator* enumerator = [tracks objectEnumerator]; + NSDictionary* track; + + while ((track = [enumerator nextObject]) != nil) + { + NSURL* url = [NSURL URLWithString: [track valueForKey: @"Location"]]; - for (unsigned int i = 0; i < [items count]; ++i) - files.add (nsStringToJuce ((NSString*) [items objectAtIndex: i])); + if ([url isFileURL]) + files.add (nsStringToJuce ([url path])); + } + } } + else + { + id list = [pasteBoard propertyListForType: NSFilenamesPboardType]; - if (files.size() == 0) - return false; + if ([list isKindOfClass: [NSArray class]]) + { + NSArray* items = (NSArray*) [pasteBoard propertyListForType: NSFilenamesPboardType]; + + for (unsigned int i = 0; i < [items count]; ++i) + files.add (nsStringToJuce ((NSString*) [items objectAtIndex: i])); + } + } - if (type == 0) - handleFileDragMove (files, pos); - else if (type == 1) - handleFileDragExit (files); - else if (type == 2) - handleFileDragDrop (files, pos); + if (files.size() > 0) + { + switch (type) + { + case 0: handleFileDragMove (files, pos); break; + case 1: handleFileDragExit (files); break; + case 2: handleFileDragDrop (files, pos); break; + default: jassertfalse; break; + } - return true; + return true; + } + + return false; } bool NSViewComponentPeer::isOpaque() @@ -277558,7 +277607,7 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (CoreAudioIODeviceType); }; -AudioIODeviceType* juce_createAudioIODeviceType_CoreAudio() +AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_CoreAudio() { return new CoreAudioIODeviceType(); } @@ -278560,21 +278609,81 @@ BEGIN_JUCE_NAMESPACE JAVACLASS (contextClass, "android/content/Context") \ JAVACLASS (canvasClass, "android/graphics/Canvas") \ JAVACLASS (paintClass, "android/graphics/Paint") \ - -#define JUCE_JNI_METHODS(METHOD, STATICMETHOD) \ + JAVACLASS (pathClass, "android/graphics/Path") \ + JAVACLASS (matrixClass, "android/graphics/Matrix") \ + JAVACLASS (rectClass, "android/graphics/Rect") \ + JAVACLASS (regionClass, "android/graphics/Region") \ + JAVACLASS (shaderClass, "android/graphics/Shader") \ + JAVACLASS (linearGradientClass, "android/graphics/LinearGradient") \ + JAVACLASS (radialGradientClass, "android/graphics/RadialGradient") \ + +#define JUCE_JNI_METHODS(METHOD, STATICMETHOD, FIELD) \ \ STATICMETHOD (activityClass, printToConsole, "printToConsole", "(Ljava/lang/String;)V") \ METHOD (activityClass, createNewView, "createNewView", "()Lcom/juce/ComponentPeerView;") \ METHOD (activityClass, deleteView, "deleteView", "(Lcom/juce/ComponentPeerView;)V") \ + METHOD (activityClass, postMessage, "postMessage", "(J)V") \ \ METHOD (fileClass, fileExists, "exists", "()Z") \ \ + METHOD (componentPeerViewClass, setViewName, "setViewName", "(Ljava/lang/String;)V") \ METHOD (componentPeerViewClass, layout, "layout", "(IIII)V") \ + METHOD (componentPeerViewClass, getLeft, "getLeft", "()I") \ + METHOD (componentPeerViewClass, getTop, "getTop", "()I") \ + METHOD (componentPeerViewClass, getWidth, "getWidth", "()I") \ + METHOD (componentPeerViewClass, getHeight, "getHeight", "()I") \ + METHOD (componentPeerViewClass, getLocationOnScreen, "getLocationOnScreen", "([I)V") \ + METHOD (componentPeerViewClass, bringToFront, "bringToFront", "()V") \ + METHOD (componentPeerViewClass, requestFocus, "requestFocus", "()Z") \ + METHOD (componentPeerViewClass, setVisible, "setVisible", "(Z)V") \ + METHOD (componentPeerViewClass, isVisible, "isVisible", "()Z") \ + METHOD (componentPeerViewClass, hasFocus, "hasFocus", "()Z") \ + METHOD (componentPeerViewClass, invalidate, "invalidate", "(IIII)V") \ \ METHOD (canvasClass, drawRect, "drawRect", "(FFFFLandroid/graphics/Paint;)V") \ + METHOD (canvasClass, translate, "translate", "(FF)V") \ + METHOD (canvasClass, clipPath, "clipPath", "(Landroid/graphics/Path;)Z") \ + METHOD (canvasClass, clipRect, "clipRect", "(FFFF)Z") \ + METHOD (canvasClass, clipRegion, "clipRegion", "(Landroid/graphics/Region;)Z") \ + METHOD (canvasClass, concat, "concat", "(Landroid/graphics/Matrix;)V") \ + METHOD (canvasClass, drawBitmap, "drawBitmap", "(Landroid/graphics/Bitmap;Landroid/graphics/Matrix;Landroid/graphics/Paint;)V") \ + METHOD (canvasClass, drawLine, "drawLine", "(FFFFLandroid/graphics/Paint;)V") \ + METHOD (canvasClass, drawPath, "drawPath", "(Landroid/graphics/Path;Landroid/graphics/Paint;)V") \ + METHOD (canvasClass, getClipBounds, "getClipBounds", "(Landroid/graphics/Rect;)Z") \ + METHOD (canvasClass, getClipBounds2, "getClipBounds", "()Landroid/graphics/Rect;") \ + METHOD (canvasClass, getMatrix, "getMatrix", "()Landroid/graphics/Matrix;") \ + METHOD (canvasClass, save, "save", "()I") \ + METHOD (canvasClass, restore, "restore", "()V") \ + METHOD (canvasClass, saveLayerAlpha, "saveLayerAlpha", "(FFFFII)I") \ \ METHOD (paintClass, paintClassConstructor, "", "()V") \ METHOD (paintClass, setColor, "setColor", "(I)V") \ + METHOD (paintClass, setShader, "setShader", "(Landroid/graphics/Shader;)Landroid/graphics/Shader;") \ +\ + METHOD (shaderClass, setLocalMatrix, "setLocalMatrix", "(Landroid/graphics/Matrix;)V") \ +\ + METHOD (pathClass, pathClassConstructor, "", "()V") \ + METHOD (pathClass, moveTo, "moveTo", "(FF)V") \ + METHOD (pathClass, lineTo, "lineTo", "(FF)V") \ + METHOD (pathClass, quadTo, "quadTo", "(FFFF)V") \ + METHOD (pathClass, cubicTo, "cubicTo", "(FFFFFF)V") \ + METHOD (pathClass, closePath, "close", "()V") \ +\ + METHOD (matrixClass, matrixClassConstructor, "", "()V") \ + METHOD (matrixClass, setValues, "setValues", "([F)V") \ +\ + METHOD (rectClass, rectConstructor, "", "(IIII)V") \ + FIELD (rectClass, rectLeft, "left", "I") \ + FIELD (rectClass, rectRight, "right", "I") \ + FIELD (rectClass, rectTop, "top", "I") \ + FIELD (rectClass, rectBottom, "bottom", "I") \ +\ + METHOD (linearGradientClass, linearGradientConstructor, "", "(FFFF[I[FLandroid/graphics/Shader$TileMode;)V") \ +\ + METHOD (radialGradientClass, radialGradientConstructor, "", "(FFF[I[FLandroid/graphics/Shader$TileMode;)V") \ +\ + METHOD (regionClass, regionConstructor, "", "()V"); \ + METHOD (regionClass, regionUnion, "union", "(Landroid/graphics/Rect;)Z"); \ class GlobalRef { @@ -278598,39 +278707,37 @@ public: ~GlobalRef() { - release(); + clear(); + } + + void clear() + { + if (env != 0) + { + env->DeleteGlobalRef (obj); + env = 0; + obj = 0; + } } GlobalRef& operator= (const GlobalRef& other) { - release(); + clear(); env = other.env; obj = retain (env, other.obj); return *this; } - GlobalRef& operator= (jobject newObj) - { - jassert (env != 0 || newObj == 0); - - if (newObj != obj && env != 0) - { - release(); - obj = retain (env, newObj); - } - } - inline operator jobject() const throw() { return obj; } inline jobject get() const throw() { return obj; } inline JNIEnv* getEnv() const throw() { return env; } #define DECLARE_CALL_TYPE_METHOD(returnType, typeName) \ - returnType call##typeName##Method (jmethodID methodID, ... ) \ + returnType call##typeName##Method (jmethodID methodID, ... ) const \ { \ - returnType result; \ va_list args; \ va_start (args, methodID); \ - result = env->Call##typeName##MethodV (obj, methodID, args); \ + returnType result = env->Call##typeName##MethodV (obj, methodID, args); \ va_end (args); \ return result; \ } @@ -278646,7 +278753,7 @@ public: DECLARE_CALL_TYPE_METHOD (jdouble, Double) #undef DECLARE_CALL_TYPE_METHOD - void callVoidMethod (jmethodID methodID, ... ) + void callVoidMethod (jmethodID methodID, ... ) const { va_list args; va_start (args, methodID); @@ -278659,12 +278766,6 @@ private: JNIEnv* env; jobject obj; - void release() - { - if (env != 0) - env->DeleteGlobalRef (obj); - } - static jobject retain (JNIEnv* const env, jobject obj_) { return env == 0 ? 0 : env->NewGlobalRef (obj_); @@ -278674,14 +278775,16 @@ private: class AndroidJavaCallbacks { public: - AndroidJavaCallbacks() : env (0) + AndroidJavaCallbacks() : env (0), screenWidth (0), screenHeight (0) { } - void initialise (JNIEnv* env_, jobject activity_) + void initialise (JNIEnv* env_, jobject activity_, int screenWidth_, int screenHeight_) { env = env_; activity = GlobalRef (env, activity_); + screenWidth = screenWidth_; + screenHeight = screenHeight_; #define CREATE_JNI_CLASS(className, path) \ className = (jclass) env->NewGlobalRef (env->FindClass (path)); \ @@ -278695,7 +278798,10 @@ public: #define CREATE_JNI_STATICMETHOD(ownerClass, methodID, stringName, params) \ methodID = env->GetStaticMethodID (ownerClass, stringName, params); \ jassert (methodID != 0); - JUCE_JNI_METHODS (CREATE_JNI_METHOD, CREATE_JNI_STATICMETHOD); + #define CREATE_JNI_FIELD(ownerClass, fieldID, stringName, signature) \ + fieldID = env->GetFieldID (ownerClass, stringName, signature); \ + jassert (fieldID != 0); + JUCE_JNI_METHODS (CREATE_JNI_METHOD, CREATE_JNI_STATICMETHOD, CREATE_JNI_FIELD); #undef CREATE_JNI_METHOD } @@ -278707,7 +278813,7 @@ public: JUCE_JNI_CLASSES (RELEASE_JNI_CLASS); #undef RELEASE_JNI_CLASS - activity = 0; + activity.clear(); env = 0; } } @@ -278729,13 +278835,15 @@ public: JNIEnv* env; GlobalRef activity; + int screenWidth, screenHeight; #define DECLARE_JNI_CLASS(className, path) jclass className; JUCE_JNI_CLASSES (DECLARE_JNI_CLASS); #undef DECLARE_JNI_CLASS #define DECLARE_JNI_METHOD(ownerClass, methodID, stringName, params) jmethodID methodID; - JUCE_JNI_METHODS (DECLARE_JNI_METHOD, DECLARE_JNI_METHOD); + #define DECLARE_JNI_FIELD(ownerClass, fieldID, stringName, signature) jfieldID fieldID; + JUCE_JNI_METHODS (DECLARE_JNI_METHOD, DECLARE_JNI_METHOD, DECLARE_JNI_FIELD); #undef DECLARE_JNI_METHOD }; @@ -278754,9 +278862,9 @@ END_JUCE_NAMESPACE extern JUCE_NAMESPACE::JUCEApplication* juce_CreateApplication(); // (from START_JUCE_APPLICATION) BEGIN_JUCE_NAMESPACE -JUCE_JNI_CALLBACK (JuceAppActivity, launchApp, void, (JNIEnv* env, jobject activity)) +JUCE_JNI_CALLBACK (JuceAppActivity, launchApp, void, (JNIEnv* env, jobject activity, int screenWidth, int screenHeight)) { - android.initialise (env, activity); + android.initialise (env, activity, screenWidth, screenHeight); JUCEApplication::createInstance = &juce_CreateApplication; @@ -280355,11 +280463,16 @@ bool juce_dispatchNextMessageOnSystemQueue (const bool returnIfNoPendingMessages bool juce_postMessageToSystemQueue (Message* message) { - // TODO - + android.activity.callVoidMethod (android.postMessage, (jlong) (pointer_sized_uint) message); return true; } +JUCE_JNI_CALLBACK (JuceAppActivity, deliverMessage, void, (jobject activity, jlong value)) +{ + Message* m = (Message*) (pointer_sized_uint) value; + MessageManager::getInstance()->deliverMessage ((Message*) (pointer_sized_uint) value); +} + class AsyncFunctionCaller : public AsyncUpdater { public: @@ -280488,8 +280601,11 @@ class AndroidLowLevelGraphicsContext : public LowLevelGraphicsContext { public: AndroidLowLevelGraphicsContext (const GlobalRef& canvas_) - : canvas (canvas_) + : canvas (canvas_), + currentState (new SavedState()), { + paintStack.add (new GlobalRef()); + setFill (Colours::black); } ~AndroidLowLevelGraphicsContext() @@ -280500,10 +280616,12 @@ public: void setOrigin (int x, int y) { + canvas.callVoidMethod (android.translate, (float) x, (float) y); } void addTransform (const AffineTransform& transform) { + canvas.callVoidMethod (android.concat, createMatrix (canvas.getEnv(), transform)); } float getScaleFactor() @@ -280513,12 +280631,12 @@ public: bool clipToRectangle (const Rectangle& r) { - return true; + return canvas.callBooleanMethod (android.clipRect, (float) r.getX(), (float) r.getY(), (float) r.getRight(), (float) r.getBottom()); } bool clipToRectangleList (const RectangleList& clipRegion) { - return true; + return canvas.callBooleanMethod (android.clipRegion, createRegion (canvas.getEnv(), clipRegion)); } void excludeClipRectangle (const Rectangle& r) @@ -280527,6 +280645,7 @@ public: void clipToPath (const Path& path, const AffineTransform& transform) { + (void) canvas.callBooleanMethod (android.clipPath, createPath (canvas.getEnv(), path, transform)); } void clipToImageAlpha (const Image& sourceImage, const AffineTransform& transform) @@ -280535,39 +280654,30 @@ public: bool clipRegionIntersects (const Rectangle& r) { - return true; + return getClipBounds().intersects (r); } const Rectangle getClipBounds() const { - return Rectangle (0, 0, 1000, 1000); - } - - bool isClipEmpty() const - { - return false; - } - - void saveState() - { - } + jobject rect = canvas.callObjectMethod (android.getClipBounds2); - void restoreState() - { - } + const int left = canvas.getEnv()->GetIntField (rect, android.rectLeft); + const int top = canvas.getEnv()->GetIntField (rect, android.rectTop); + const int right = canvas.getEnv()->GetIntField (rect, android.rectRight); + const int bottom = canvas.getEnv()->GetIntField (rect, android.rectBottom); - void beginTransparencyLayer (float opacity) - { + return Rectangle (left, top, right - left, bottom - top); } - void endTransparencyLayer() + bool isClipEmpty() const { + return ! canvas.callBooleanMethod (android.getClipBounds, + canvas.getEnv()->NewObject (android.rectClass, android.rectConstructor, 0, 0, 0, 0)); } void setFill (const FillType& fillType) { - currentPaint = android.env->NewObject (android.paintClass, android.paintClassConstructor); - currentPaint.callVoidMethod (android.setColor, fillType.colour.getARGB()); + currentState->setFillType (fillType); } void setOpacity (float newOpacity) @@ -280582,11 +280692,13 @@ public: { canvas.callVoidMethod (android.drawRect, (float) r.getX(), (float) r.getY(), (float) r.getRight(), (float) r.getBottom(), - currentPaint.get()); + getCurrentPaint().get()); } void fillPath (const Path& path, const AffineTransform& transform) { + canvas.callVoidMethod (android.drawPath, createPath (canvas.getEnv(), path, transform), + getCurrentPaint().get()); } void drawImage (const Image& sourceImage, const AffineTransform& transform, bool fillEntireClipAsTiles) @@ -280595,14 +280707,19 @@ public: void drawLine (const Line & line) { + canvas.callVoidMethod (android.drawLine, line.getStartX(), line.getStartY(), + line.getEndX(), line.getEndY(), + getCurrentPaint().get()); } void drawVerticalLine (int x, float top, float bottom) { + canvas.callVoidMethod (android.drawRect, (float) x, top, x + 1.0f, bottom, getCurrentPaint().get()); } void drawHorizontalLine (int y, float left, float right) { + canvas.callVoidMethod (android.drawRect, left, (float) y, right, y + 1.0f, getCurrentPaint().get()); } void setFont (const Font& newFont) @@ -280618,8 +280735,211 @@ public: { } + void saveState() + { + (void) canvas.callIntMethod (android.save); + stateStack.add (new SavedState (*currentState)); + + } + + void restoreState() + { + canvas.callVoidMethod (android.restore); + + SavedState* const top = stateStack.getLast(); + + if (top != 0) + { + currentState = top; + stateStack.removeLast (1, false); + } + else + { + jassertfalse; // trying to pop with an empty stack! + } + } + + void beginTransparencyLayer (float opacity) + { + } + + void endTransparencyLayer() + { + } + + class SavedState + { + public: + SavedState() + : font (1.0f), needsUpdate (true) + { + } + + SavedState (const SavedState& other) + : fillType (other.fillType), font (other.font), needsUpdate (true) + { + } + + void setFillType (const FillType& newType) + { + needsUpdate = true; + fillType = newType; + } + + jobject getPaint (JNIEnv* env) + { + if (needsUpdate) + { + if (paint.get() == 0) + paint = GlobalRef (env, env->NewObject (android.paintClass, android.paintClassConstructor)); + + if (fillType.isColour()) + { + paint.callVoidMethod (android.setShader, (jobject) 0); + paint.callVoidMethod (android.setColor, colourToInt (fillType.colour)); + } + else if (fillType.isGradient()) + { + const ColourGradient& g = fillType.gradient; + const Point p1 (g.point1); + const Point p2 (g.point2); + + const int numColours = g.getNumColours(); + jintArray coloursArray = env->NewIntArray (numColours); + jfloatArray positionsArray = env->NewFloatArray (numColours); + + { + HeapBlock colours (numColours); + HeapBlock positions (numColours); + + for (int i = 0; i < numColours; ++i) + { + colours[i] = g.getColour (i); + positions[i] = (float) g.getColourPosition(i); + } + + env->SetIntArrayRegion (coloursArray, 0, numColours, colours.getData()); + env->SetFloatArrayRegion (positionsArray, 0, numColours, positions.getData()); + } + + jobject tileMode = xxxx + + jobject shader; + if (fillType.gradient->isRadial) + { + shader = env->NewObject (android.radialGradientClass, + android.radialGradientConstructor, + p1.getX(), p1.getY(), + p1.getDistanceFrom (p2), + coloursArray, positionsArray, + tileMode)); + } + else + { + shader = env->NewObject (android.linearGradientClass, + android.linearGradientConstructor, + p1.getX(), p1.getY(), p2.getX(), p2.getY(), + coloursArray, positionsArray, + tileMode)); + } + + env->CallVoidMethod (shader, android.setLocalMatrix, createMatrix (fillType.transform)); + paint.callVoidMethod (android.setShader, shader); + } + else + {x + } + } + + return paint.get(); + } + + private: + FillType fillType; + Font font; + GlobalRef paint; + bool needsUpdate; + }; + private: - GlobalRef canvas, currentPaint; + GlobalRef canvas; + + ScopedPointer currentState; + OwnedArray stateStack; + + GlobalRef& getCurrentPaint() throw() { return *paintStack.getUnchecked (paintStack.size() - 1); } + + static jobject createPath (JNIEnv* env, const Path& path) + { + jobject p = env->NewObject (android.pathClass, android.pathClassConstructor); + + Path::Iterator i (path); + + while (i.next()) + { + switch (i.elementType) + { + case Path::Iterator::startNewSubPath: env->CallVoidMethod (p, android.moveTo, i.x1, i.y1); break; + case Path::Iterator::lineTo: env->CallVoidMethod (p, android.lineTo, i.x1, i.y1); break; + case Path::Iterator::quadraticTo: env->CallVoidMethod (p, android.quadTo, i.x1, i.y1, i.x2, i.y2); break; + case Path::Iterator::cubicTo: env->CallVoidMethod (p, android.cubicTo, i.x1, i.y1, i.x2, i.y2, i.x3, i.y3); break; + case Path::Iterator::closePath: env->CallVoidMethod (p, android.closePath); break; + default: jassertfalse; break; + } + } + + return p; + } + + static jobject createPath (JNIEnv* env, const Path& path, const AffineTransform& transform) + { + if (transform.isIdentity()) + return createPath (env, path); + + Path tempPath (path); + tempPath.applyTransform (transform); + return createPath (env, tempPath); + } + + static jobject createMatrix (JNIEnv* env, const AffineTransform& t) + { + jobject m = env->NewObject (android.matrixClass, android.matrixClassConstructor); + + jfloat values[9] = { t.mat00, t.mat01, t.mat02, + t.mat10, t.mat11, t.mat12, + 0.0f, 0.0f, 1.0f }; + + jfloatArray javaArray = env->NewFloatArray (9); + env->SetFloatArrayRegion (javaArray, 0, 9, values); + + env->CallVoidMethod (m, android.setValues, javaArray); + env->DeleteLocalRef (javaArray); + + return m; + } + + static jobject createRect (JNIEnv* env, const Rectangle& r) + { + return env->NewObject (android.rectClass, android.rectConstructor, + r.getX(), r.getY(), r.getRight(), r.getBottom()); + } + + static jobject createRegion (JNIEnv* env, const RectangleList& list) + { + jobject region = env->NewObject (android.regionClass, android.regionConstructor); + + const int numRects = list.getNumRectangles(); + + for (int i = 0; i < numRects; ++i) + env->CallVoidMethod (region, android.regionUnion, createRect (env, list.getRectangle(i))); + + return region; + } + + static int colourToInt (const Colour& col) throw() + { + return col.getARGB(); + } JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AndroidLowLevelGraphicsContext); }; @@ -280646,58 +280966,71 @@ public: ~AndroidComponentPeer() { android.activity.callVoidMethod (android.deleteView, view.get()); - view = 0; + view.clear(); } void* getNativeHandle() const { - return 0; // TODO + return (void*) view.get(); } void setVisible (bool shouldBeVisible) { + view.callVoidMethod (android.setVisible, shouldBeVisible); } void setTitle (const String& title) { + view.callVoidMethod (android.setViewName, android.javaString (title)); } void setPosition (int x, int y) { - // TODO + const Rectangle pos (getBounds()); + setBounds (x, y, pos.getWidth(), pos.getHeight(), false); } void setSize (int w, int h) { + const Rectangle pos (getBounds()); + setBounds (pos.getX(), pos.getY(), w, h, false); } void setBounds (int x, int y, int w, int h, bool isNowFullScreen) { - DBG ("Window size: " << x << " " << y << " " << w << " " << h); view.callVoidMethod (android.layout, x, y, x + w, y + h); } const Rectangle getBounds() const { - // TODO - return Rectangle(); + return Rectangle (view.callIntMethod (android.getLeft), + view.callIntMethod (android.getTop), + view.callIntMethod (android.getWidth), + view.callIntMethod (android.getHeight)); } const Point getScreenPosition() const { - // TODO - return Point(); + JNIEnv* const env = view.getEnv(); + + jintArray pos = env->NewIntArray (2); + view.callVoidMethod (android.getLocationOnScreen, pos); + + jint coords[2]; + jint i, sum = 0; + env->GetIntArrayRegion (pos, 0, 2, coords); + env->DeleteLocalRef (pos); + + return Point (coords[0], coords[1]); } const Point localToGlobal (const Point& relativePosition) { - // TODO return relativePosition + getScreenPosition(); } const Point globalToLocal (const Point& screenPosition) { - // TODO return screenPosition - getScreenPosition(); } @@ -280708,6 +281041,7 @@ public: bool isMinimised() const { + return false; } void setFullScreen (bool shouldBeFullScreen) @@ -280748,7 +281082,10 @@ public: void toFront (bool makeActive) { - // TODO + view.callVoidMethod (android.bringToFront); + + if (makeActive) + grabFocus(); } void toBehind (ComponentPeer* other) @@ -280758,13 +281095,12 @@ public: bool isFocused() const { - // TODO - return false; + return view.callBooleanMethod (android.hasFocus); } void grabFocus() { - // TODO + (void) view.callBooleanMethod (android.requestFocus); } void textInputRequired (const Point& position) @@ -280780,7 +281116,7 @@ public: void repaint (const Rectangle& area) { - // TODO + view.callVoidMethod (android.invalidate, area.getX(), area.getY(), area.getRight(), area.getBottom()); } void performAnyPendingRepaintsNow() @@ -280909,17 +281245,9 @@ void juce_setKioskComponent (Component* kioskModeComponent, bool enableOrDisable { } -static int screenWidth = 0, screenHeight = 0; - void juce_updateMultiMonitorInfo (Array >& monitorCoords, const bool clipToWorkArea) { - monitorCoords.add (Rectangle (0, 0, screenWidth, screenHeight)); -} - -JUCE_JNI_CALLBACK (JuceAppActivity, setScreenSize, void, (JNIEnv* env, jobject activity, int w, int h)) -{ - screenWidth = w; - screenHeight = h; + monitorCoords.add (Rectangle (0, 0, android.screenWidth, android.screenHeight)); } const Image juce_createIconForFile (const File& file) diff --git a/juce_amalgamated.h b/juce_amalgamated.h index eb63af9d46..7225233ecf 100644 --- a/juce_amalgamated.h +++ b/juce_amalgamated.h @@ -73,7 +73,7 @@ namespace JuceDummyNamespace {} */ #define JUCE_MAJOR_VERSION 1 #define JUCE_MINOR_VERSION 53 -#define JUCE_BUILDNUMBER 26 +#define JUCE_BUILDNUMBER 27 /** Current Juce version number. @@ -5320,7 +5320,7 @@ JUCE_API bool JUCE_CALLTYPE operator<= (const String& string1, const String& str This is very handy for writing strings to std::cout, std::cerr, etc. */ template -JUCE_API std::basic_ostream & JUCE_CALLTYPE operator<< (std::basic_ostream & stream, const String& stringToWrite) +std::basic_ostream & JUCE_CALLTYPE operator<< (std::basic_ostream & stream, const String& stringToWrite) { return stream << stringToWrite.toUTF8().getAddress(); } @@ -6286,8 +6286,8 @@ public: #define __JUCE_CRITICALSECTION_JUCEHEADER__ #ifndef DOXYGEN - class JUCE_API ScopedLock; - class JUCE_API ScopedUnlock; + class ScopedLock; + class ScopedUnlock; #endif /** @@ -8228,7 +8228,7 @@ OutputStream& JUCE_CALLTYPE operator<< (OutputStream& stream, const NewLine&); /*** End of inlined file: juce_OutputStream.h ***/ #ifndef DOXYGEN - class JUCE_API DynamicObject; + class DynamicObject; #endif /** @@ -10857,27 +10857,27 @@ private: }; /** Adds a RelativeTime to a Time. */ -const Time operator+ (const Time& time, const RelativeTime& delta); +JUCE_API const Time operator+ (const Time& time, const RelativeTime& delta); /** Adds a RelativeTime to a Time. */ -const Time operator+ (const RelativeTime& delta, const Time& time); +JUCE_API const Time operator+ (const RelativeTime& delta, const Time& time); /** Subtracts a RelativeTime from a Time. */ -const Time operator- (const Time& time, const RelativeTime& delta); +JUCE_API const Time operator- (const Time& time, const RelativeTime& delta); /** Returns the relative time difference between two times. */ -const RelativeTime operator- (const Time& time1, const Time& time2); +JUCE_API const RelativeTime operator- (const Time& time1, const Time& time2); /** Compares two Time objects. */ -bool operator== (const Time& time1, const Time& time2); +JUCE_API bool operator== (const Time& time1, const Time& time2); /** Compares two Time objects. */ -bool operator!= (const Time& time1, const Time& time2); +JUCE_API bool operator!= (const Time& time1, const Time& time2); /** Compares two Time objects. */ -bool operator< (const Time& time1, const Time& time2); +JUCE_API bool operator< (const Time& time1, const Time& time2); /** Compares two Time objects. */ -bool operator<= (const Time& time1, const Time& time2); +JUCE_API bool operator<= (const Time& time1, const Time& time2); /** Compares two Time objects. */ -bool operator> (const Time& time1, const Time& time2); +JUCE_API bool operator> (const Time& time1, const Time& time2); /** Compares two Time objects. */ -bool operator>= (const Time& time1, const Time& time2); +JUCE_API bool operator>= (const Time& time1, const Time& time2); #endif // __JUCE_TIME_JUCEHEADER__ /*** End of inlined file: juce_Time.h ***/ @@ -16729,8 +16729,7 @@ private: #if JUCE_MAC || JUCE_IOS -/** A handy C++ wrapper that creates and deletes an NSAutoreleasePool object - using RAII. +/** A handy C++ wrapper that creates and deletes an NSAutoreleasePool object using RAII. */ class ScopedAutoReleasePool { @@ -16896,7 +16895,7 @@ private: @see CriticalSection, ScopedUnlock */ -class JUCE_API ScopedLock +class ScopedLock { public: @@ -37748,6 +37747,21 @@ public: /** Destructor. */ virtual ~AudioIODeviceType(); + /** Creates a CoreAudio device type if it's available on this platform, or returns null. */ + static AudioIODeviceType* createAudioIODeviceType_CoreAudio(); + /** Creates an iOS device type if it's available on this platform, or returns null. */ + static AudioIODeviceType* createAudioIODeviceType_iOSAudio(); + /** Creates a WASAPI device type if it's available on this platform, or returns null. */ + static AudioIODeviceType* createAudioIODeviceType_WASAPI(); + /** Creates a DirectSound device type if it's available on this platform, or returns null. */ + static AudioIODeviceType* createAudioIODeviceType_DirectSound(); + /** Creates an ASIO device type if it's available on this platform, or returns null. */ + static AudioIODeviceType* createAudioIODeviceType_ASIO(); + /** Creates an ALSA device type if it's available on this platform, or returns null. */ + static AudioIODeviceType* createAudioIODeviceType_ALSA(); + /** Creates a JACK device type if it's available on this platform, or returns null. */ + static AudioIODeviceType* createAudioIODeviceType_JACK(); + protected: explicit AudioIODeviceType (const String& typeName); @@ -66198,8 +66212,8 @@ private: #pragma pack (pop) #endif -#ifdef JUCE_DLL - #undef JUCE_LEAK_DETECTOR(OwnerClass) +#if defined (JUCE_DLL) && ! (JUCE_AMALGAMATED_TEMPLATE || defined (JUCE_DLL_BUILD)) + #undef JUCE_LEAK_DETECTOR #define JUCE_LEAK_DETECTOR(OwnerClass) #endif diff --git a/src/audio/devices/juce_AudioDeviceManager.cpp b/src/audio/devices/juce_AudioDeviceManager.cpp index 99523b5f01..dfc8bf9af5 100644 --- a/src/audio/devices/juce_AudioDeviceManager.cpp +++ b/src/audio/devices/juce_AudioDeviceManager.cpp @@ -101,48 +101,25 @@ const OwnedArray & AudioDeviceManager::getAvailableDeviceType } //============================================================================== -AudioIODeviceType* juce_createAudioIODeviceType_CoreAudio(); -AudioIODeviceType* juce_createAudioIODeviceType_iPhoneAudio(); -AudioIODeviceType* juce_createAudioIODeviceType_WASAPI(); -AudioIODeviceType* juce_createAudioIODeviceType_DirectSound(); -AudioIODeviceType* juce_createAudioIODeviceType_ASIO(); -AudioIODeviceType* juce_createAudioIODeviceType_ALSA(); AudioIODeviceType* juce_createAudioIODeviceType_JACK(); -void AudioDeviceManager::createAudioDeviceTypes (OwnedArray & list) +static void addIfNotNull (OwnedArray & list, AudioIODeviceType* const device) { - (void) list; // (to avoid 'unused param' warnings) - - #if JUCE_WINDOWS - #if JUCE_WASAPI - if (SystemStats::getOperatingSystemType() >= SystemStats::WinVista) - list.add (juce_createAudioIODeviceType_WASAPI()); - #endif - - #if JUCE_DIRECTSOUND - list.add (juce_createAudioIODeviceType_DirectSound()); - #endif - - #if JUCE_ASIO - list.add (juce_createAudioIODeviceType_ASIO()); - #endif - #endif - - #if JUCE_MAC - list.add (juce_createAudioIODeviceType_CoreAudio()); - #endif + if (device != 0) + list.add (device); +} - #if JUCE_IOS - list.add (juce_createAudioIODeviceType_iPhoneAudio()); - #endif +void AudioDeviceManager::createAudioDeviceTypes (OwnedArray & list) +{ + addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_WASAPI()); + addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_DirectSound()); + addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_ASIO()); - #if JUCE_LINUX && JUCE_ALSA - list.add (juce_createAudioIODeviceType_ALSA()); - #endif + addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_CoreAudio()); + addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_iOSAudio()); - #if JUCE_LINUX && JUCE_JACK - list.add (juce_createAudioIODeviceType_JACK()); - #endif + addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_ALSA()); + addIfNotNull (list, AudioIODeviceType::createAudioIODeviceType_JACK()); } //============================================================================== diff --git a/src/audio/devices/juce_AudioIODeviceType.cpp b/src/audio/devices/juce_AudioIODeviceType.cpp index eeed74a86e..6c3b2fa56e 100644 --- a/src/audio/devices/juce_AudioIODeviceType.cpp +++ b/src/audio/devices/juce_AudioIODeviceType.cpp @@ -40,5 +40,32 @@ AudioIODeviceType::~AudioIODeviceType() { } +#if ! JUCE_MAC +AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_CoreAudio() { return 0; } +#endif + +#if ! JUCE_IOS +AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_iOSAudio() { return 0; } +#endif + +#if ! (JUCE_WINDOWS && JUCE_WASAPI) +AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_WASAPI() { return 0; } +#endif + +#if ! (JUCE_WINDOWS && JUCE_DIRECTSOUND) +AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_DirectSound() { return 0; } +#endif + +#if ! (JUCE_WINDOWS && JUCE_ASIO) +AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_ASIO() { return 0; } +#endif + +#if ! (JUCE_LINUX && JUCE_ALSA) +AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_ALSA() { return 0; } +#endif + +#if ! (JUCE_LINUX && JUCE_JACK) +AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_JACK() { return 0; } +#endif END_JUCE_NAMESPACE diff --git a/src/audio/devices/juce_AudioIODeviceType.h b/src/audio/devices/juce_AudioIODeviceType.h index 9f9756ced8..054036688e 100644 --- a/src/audio/devices/juce_AudioIODeviceType.h +++ b/src/audio/devices/juce_AudioIODeviceType.h @@ -131,6 +131,22 @@ public: /** Destructor. */ virtual ~AudioIODeviceType(); + //============================================================================== + /** Creates a CoreAudio device type if it's available on this platform, or returns null. */ + static AudioIODeviceType* createAudioIODeviceType_CoreAudio(); + /** Creates an iOS device type if it's available on this platform, or returns null. */ + static AudioIODeviceType* createAudioIODeviceType_iOSAudio(); + /** Creates a WASAPI device type if it's available on this platform, or returns null. */ + static AudioIODeviceType* createAudioIODeviceType_WASAPI(); + /** Creates a DirectSound device type if it's available on this platform, or returns null. */ + static AudioIODeviceType* createAudioIODeviceType_DirectSound(); + /** Creates an ASIO device type if it's available on this platform, or returns null. */ + static AudioIODeviceType* createAudioIODeviceType_ASIO(); + /** Creates an ALSA device type if it's available on this platform, or returns null. */ + static AudioIODeviceType* createAudioIODeviceType_ALSA(); + /** Creates a JACK device type if it's available on this platform, or returns null. */ + static AudioIODeviceType* createAudioIODeviceType_JACK(); + protected: explicit AudioIODeviceType (const String& typeName); diff --git a/src/containers/juce_Variant.h b/src/containers/juce_Variant.h index e8dec7b924..f9ac0c946e 100644 --- a/src/containers/juce_Variant.h +++ b/src/containers/juce_Variant.h @@ -31,7 +31,7 @@ #include "../io/streams/juce_InputStream.h" #ifndef DOXYGEN - class JUCE_API DynamicObject; + class DynamicObject; #endif //============================================================================== diff --git a/src/core/juce_PlatformUtilities.h b/src/core/juce_PlatformUtilities.h index b94b1adb1d..3a6ac4b7b4 100644 --- a/src/core/juce_PlatformUtilities.h +++ b/src/core/juce_PlatformUtilities.h @@ -205,8 +205,7 @@ private: //============================================================================== #if JUCE_MAC || JUCE_IOS -/** A handy C++ wrapper that creates and deletes an NSAutoreleasePool object - using RAII. +/** A handy C++ wrapper that creates and deletes an NSAutoreleasePool object using RAII. */ class ScopedAutoReleasePool { diff --git a/src/core/juce_StandardHeader.h b/src/core/juce_StandardHeader.h index 99a2f24be4..7dbbf28c0d 100644 --- a/src/core/juce_StandardHeader.h +++ b/src/core/juce_StandardHeader.h @@ -33,7 +33,7 @@ */ #define JUCE_MAJOR_VERSION 1 #define JUCE_MINOR_VERSION 53 -#define JUCE_BUILDNUMBER 26 +#define JUCE_BUILDNUMBER 27 /** Current Juce version number. diff --git a/src/core/juce_Time.h b/src/core/juce_Time.h index 3094c02f8d..4194c74746 100644 --- a/src/core/juce_Time.h +++ b/src/core/juce_Time.h @@ -370,27 +370,27 @@ private: //============================================================================== /** Adds a RelativeTime to a Time. */ -const Time operator+ (const Time& time, const RelativeTime& delta); +JUCE_API const Time operator+ (const Time& time, const RelativeTime& delta); /** Adds a RelativeTime to a Time. */ -const Time operator+ (const RelativeTime& delta, const Time& time); +JUCE_API const Time operator+ (const RelativeTime& delta, const Time& time); /** Subtracts a RelativeTime from a Time. */ -const Time operator- (const Time& time, const RelativeTime& delta); +JUCE_API const Time operator- (const Time& time, const RelativeTime& delta); /** Returns the relative time difference between two times. */ -const RelativeTime operator- (const Time& time1, const Time& time2); +JUCE_API const RelativeTime operator- (const Time& time1, const Time& time2); /** Compares two Time objects. */ -bool operator== (const Time& time1, const Time& time2); +JUCE_API bool operator== (const Time& time1, const Time& time2); /** Compares two Time objects. */ -bool operator!= (const Time& time1, const Time& time2); +JUCE_API bool operator!= (const Time& time1, const Time& time2); /** Compares two Time objects. */ -bool operator< (const Time& time1, const Time& time2); +JUCE_API bool operator< (const Time& time1, const Time& time2); /** Compares two Time objects. */ -bool operator<= (const Time& time1, const Time& time2); +JUCE_API bool operator<= (const Time& time1, const Time& time2); /** Compares two Time objects. */ -bool operator> (const Time& time1, const Time& time2); +JUCE_API bool operator> (const Time& time1, const Time& time2); /** Compares two Time objects. */ -bool operator>= (const Time& time1, const Time& time2); +JUCE_API bool operator>= (const Time& time1, const Time& time2); #endif // __JUCE_TIME_JUCEHEADER__ diff --git a/src/gui/graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp b/src/gui/graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp index 0e2ce33ae0..a8b6a1b25e 100644 --- a/src/gui/graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp +++ b/src/gui/graphics/contexts/juce_LowLevelGraphicsSoftwareRenderer.cpp @@ -692,9 +692,9 @@ private: if (! repeatPattern) { if (loResY < 0) - render2PixelAverageX (dest, this->srcData.getPixelPointer (loResX, 0), hiResX & 255, hiResY & 255); + render2PixelAverageX (dest, this->srcData.getPixelPointer (loResX, 0), hiResX & 255); else - render2PixelAverageX (dest, this->srcData.getPixelPointer (loResX, maxY), hiResX & 255, 255 - (hiResY & 255)); + render2PixelAverageX (dest, this->srcData.getPixelPointer (loResX, maxY), hiResX & 255); ++dest; continue; @@ -709,9 +709,9 @@ private: if (! repeatPattern) { if (loResX < 0) - render2PixelAverageY (dest, this->srcData.getPixelPointer (0, loResY), hiResY & 255, hiResX & 255); + render2PixelAverageY (dest, this->srcData.getPixelPointer (0, loResY), hiResY & 255); else - render2PixelAverageY (dest, this->srcData.getPixelPointer (maxX, loResY), hiResY & 255, 255 - (hiResX & 255)); + render2PixelAverageY (dest, this->srcData.getPixelPointer (maxX, loResY), hiResY & 255); ++dest; continue; @@ -771,33 +771,33 @@ private: (uint8) (c[PixelARGB::indexB] >> 16)); } - void render2PixelAverageX (PixelARGB* const dest, const uint8* src, const int subPixelX, const int alpha) throw() + void render2PixelAverageX (PixelARGB* const dest, const uint8* src, const int subPixelX) throw() { - uint32 c[4] = { 256 * 128, 256 * 128, 256 * 128, 256 * 128 }; + uint32 c[4] = { 128, 128, 128, 128 }; - uint32 weight = (256 - subPixelX) * alpha; + uint32 weight = 256 - subPixelX; c[0] += weight * src[0]; c[1] += weight * src[1]; c[2] += weight * src[2]; c[3] += weight * src[3]; - weight = subPixelX * alpha; + weight = subPixelX; c[0] += weight * src[4]; c[1] += weight * src[5]; c[2] += weight * src[6]; c[3] += weight * src[7]; - dest->setARGB ((uint8) (c[PixelARGB::indexA] >> 16), - (uint8) (c[PixelARGB::indexR] >> 16), - (uint8) (c[PixelARGB::indexG] >> 16), - (uint8) (c[PixelARGB::indexB] >> 16)); + dest->setARGB ((uint8) (c[PixelARGB::indexA] >> 8), + (uint8) (c[PixelARGB::indexR] >> 8), + (uint8) (c[PixelARGB::indexG] >> 8), + (uint8) (c[PixelARGB::indexB] >> 8)); } - void render2PixelAverageY (PixelARGB* const dest, const uint8* src, const int subPixelY, const int alpha) throw() + void render2PixelAverageY (PixelARGB* const dest, const uint8* src, const int subPixelY) throw() { - uint32 c[4] = { 256 * 128, 256 * 128, 256 * 128, 256 * 128 }; + uint32 c[4] = { 128, 128, 128, 128 }; - uint32 weight = (256 - subPixelY) * alpha; + uint32 weight = 256 - subPixelY; c[0] += weight * src[0]; c[1] += weight * src[1]; c[2] += weight * src[2]; @@ -805,16 +805,16 @@ private: src += this->srcData.lineStride; - weight = subPixelY * alpha; + weight = subPixelY; c[0] += weight * src[0]; c[1] += weight * src[1]; c[2] += weight * src[2]; c[3] += weight * src[3]; - dest->setARGB ((uint8) (c[PixelARGB::indexA] >> 16), - (uint8) (c[PixelARGB::indexR] >> 16), - (uint8) (c[PixelARGB::indexG] >> 16), - (uint8) (c[PixelARGB::indexB] >> 16)); + dest->setARGB ((uint8) (c[PixelARGB::indexA] >> 8), + (uint8) (c[PixelARGB::indexR] >> 8), + (uint8) (c[PixelARGB::indexG] >> 8), + (uint8) (c[PixelARGB::indexB] >> 8)); } //============================================================================== @@ -850,11 +850,11 @@ private: (uint8) (c[PixelRGB::indexB] >> 16)); } - void render2PixelAverageX (PixelRGB* const dest, const uint8* src, const int subPixelX, const int /*alpha*/) throw() + void render2PixelAverageX (PixelRGB* const dest, const uint8* src, const int subPixelX) throw() { uint32 c[3] = { 128, 128, 128 }; - uint32 weight = (256 - subPixelX); + const uint32 weight = 256 - subPixelX; c[0] += weight * src[0]; c[1] += weight * src[1]; c[2] += weight * src[2]; @@ -869,11 +869,11 @@ private: (uint8) (c[PixelRGB::indexB] >> 8)); } - void render2PixelAverageY (PixelRGB* const dest, const uint8* src, const int subPixelY, const int /*alpha*/) throw() + void render2PixelAverageY (PixelRGB* const dest, const uint8* src, const int subPixelY) throw() { uint32 c[3] = { 128, 128, 128 }; - uint32 weight = (256 - subPixelY); + const uint32 weight = 256 - subPixelY; c[0] += weight * src[0]; c[1] += weight * src[1]; c[2] += weight * src[2]; @@ -903,21 +903,21 @@ private: *((uint8*) dest) = (uint8) (c >> 16); } - void render2PixelAverageX (PixelAlpha* const dest, const uint8* src, const int subPixelX, const int alpha) throw() + void render2PixelAverageX (PixelAlpha* const dest, const uint8* src, const int subPixelX) throw() { - uint32 c = 256 * 128; - c += src[0] * (256 - subPixelX) * alpha; - c += src[1] * subPixelX * alpha; - *((uint8*) dest) = (uint8) (c >> 16); + uint32 c = 128; + c += src[0] * (256 - subPixelX); + c += src[1] * subPixelX; + *((uint8*) dest) = (uint8) (c >> 8); } - void render2PixelAverageY (PixelAlpha* const dest, const uint8* src, const int subPixelY, const int alpha) throw() + void render2PixelAverageY (PixelAlpha* const dest, const uint8* src, const int subPixelY) throw() { - uint32 c = 256 * 128; - c += src[0] * (256 - subPixelY) * alpha; + uint32 c = 128; + c += src[0] * (256 - subPixelY); src += this->srcData.lineStride; - c += src[0] * subPixelY * alpha; - *((uint8*) dest) = (uint8) (c >> 16); + c += src[0] * subPixelY; + *((uint8*) dest) = (uint8) (c >> 8); } //============================================================================== diff --git a/src/native/android/juce_android_GraphicsContext.cpp b/src/native/android/juce_android_GraphicsContext.cpp index bd17fae646..3660815012 100644 --- a/src/native/android/juce_android_GraphicsContext.cpp +++ b/src/native/android/juce_android_GraphicsContext.cpp @@ -34,8 +34,11 @@ class AndroidLowLevelGraphicsContext : public LowLevelGraphicsContext { public: AndroidLowLevelGraphicsContext (const GlobalRef& canvas_) - : canvas (canvas_) + : canvas (canvas_), + currentState (new SavedState()), { + paintStack.add (new GlobalRef()); + setFill (Colours::black); } ~AndroidLowLevelGraphicsContext() @@ -47,10 +50,12 @@ public: //============================================================================== void setOrigin (int x, int y) { + canvas.callVoidMethod (android.translate, (float) x, (float) y); } void addTransform (const AffineTransform& transform) { + canvas.callVoidMethod (android.concat, createMatrix (canvas.getEnv(), transform)); } float getScaleFactor() @@ -60,12 +65,12 @@ public: bool clipToRectangle (const Rectangle& r) { - return true; + return canvas.callBooleanMethod (android.clipRect, (float) r.getX(), (float) r.getY(), (float) r.getRight(), (float) r.getBottom()); } bool clipToRectangleList (const RectangleList& clipRegion) { - return true; + return canvas.callBooleanMethod (android.clipRegion, createRegion (canvas.getEnv(), clipRegion)); } void excludeClipRectangle (const Rectangle& r) @@ -74,6 +79,7 @@ public: void clipToPath (const Path& path, const AffineTransform& transform) { + (void) canvas.callBooleanMethod (android.clipPath, createPath (canvas.getEnv(), path, transform)); } void clipToImageAlpha (const Image& sourceImage, const AffineTransform& transform) @@ -82,40 +88,31 @@ public: bool clipRegionIntersects (const Rectangle& r) { - return true; + return getClipBounds().intersects (r); } const Rectangle getClipBounds() const { - return Rectangle (0, 0, 1000, 1000); - } - - bool isClipEmpty() const - { - return false; - } - - void saveState() - { - } + jobject rect = canvas.callObjectMethod (android.getClipBounds2); - void restoreState() - { - } + const int left = canvas.getEnv()->GetIntField (rect, android.rectLeft); + const int top = canvas.getEnv()->GetIntField (rect, android.rectTop); + const int right = canvas.getEnv()->GetIntField (rect, android.rectRight); + const int bottom = canvas.getEnv()->GetIntField (rect, android.rectBottom); - void beginTransparencyLayer (float opacity) - { + return Rectangle (left, top, right - left, bottom - top); } - void endTransparencyLayer() + bool isClipEmpty() const { + return ! canvas.callBooleanMethod (android.getClipBounds, + canvas.getEnv()->NewObject (android.rectClass, android.rectConstructor, 0, 0, 0, 0)); } //============================================================================== void setFill (const FillType& fillType) { - currentPaint = android.env->NewObject (android.paintClass, android.paintClassConstructor); - currentPaint.callVoidMethod (android.setColor, fillType.colour.getARGB()); + currentState->setFillType (fillType); } void setOpacity (float newOpacity) @@ -131,11 +128,13 @@ public: { canvas.callVoidMethod (android.drawRect, (float) r.getX(), (float) r.getY(), (float) r.getRight(), (float) r.getBottom(), - currentPaint.get()); + getCurrentPaint().get()); } void fillPath (const Path& path, const AffineTransform& transform) { + canvas.callVoidMethod (android.drawPath, createPath (canvas.getEnv(), path, transform), + getCurrentPaint().get()); } void drawImage (const Image& sourceImage, const AffineTransform& transform, bool fillEntireClipAsTiles) @@ -144,14 +143,19 @@ public: void drawLine (const Line & line) { + canvas.callVoidMethod (android.drawLine, line.getStartX(), line.getStartY(), + line.getEndX(), line.getEndY(), + getCurrentPaint().get()); } void drawVerticalLine (int x, float top, float bottom) { + canvas.callVoidMethod (android.drawRect, (float) x, top, x + 1.0f, bottom, getCurrentPaint().get()); } void drawHorizontalLine (int y, float left, float right) { + canvas.callVoidMethod (android.drawRect, left, (float) y, right, y + 1.0f, getCurrentPaint().get()); } void setFont (const Font& newFont) @@ -167,8 +171,212 @@ public: { } + //============================================================================== + void saveState() + { + (void) canvas.callIntMethod (android.save); + stateStack.add (new SavedState (*currentState)); + + } + + void restoreState() + { + canvas.callVoidMethod (android.restore); + + SavedState* const top = stateStack.getLast(); + + if (top != 0) + { + currentState = top; + stateStack.removeLast (1, false); + } + else + { + jassertfalse; // trying to pop with an empty stack! + } + } + + void beginTransparencyLayer (float opacity) + { + } + + void endTransparencyLayer() + { + } + + class SavedState + { + public: + SavedState() + : font (1.0f), needsUpdate (true) + { + } + + SavedState (const SavedState& other) + : fillType (other.fillType), font (other.font), needsUpdate (true) + { + } + + void setFillType (const FillType& newType) + { + needsUpdate = true; + fillType = newType; + } + + jobject getPaint (JNIEnv* env) + { + if (needsUpdate) + { + if (paint.get() == 0) + paint = GlobalRef (env, env->NewObject (android.paintClass, android.paintClassConstructor)); + + if (fillType.isColour()) + { + paint.callVoidMethod (android.setShader, (jobject) 0); + paint.callVoidMethod (android.setColor, colourToInt (fillType.colour)); + } + else if (fillType.isGradient()) + { + const ColourGradient& g = fillType.gradient; + const Point p1 (g.point1); + const Point p2 (g.point2); + + const int numColours = g.getNumColours(); + jintArray coloursArray = env->NewIntArray (numColours); + jfloatArray positionsArray = env->NewFloatArray (numColours); + + { + HeapBlock colours (numColours); + HeapBlock positions (numColours); + + for (int i = 0; i < numColours; ++i) + { + colours[i] = g.getColour (i); + positions[i] = (float) g.getColourPosition(i); + } + + env->SetIntArrayRegion (coloursArray, 0, numColours, colours.getData()); + env->SetFloatArrayRegion (positionsArray, 0, numColours, positions.getData()); + } + + jobject tileMode = xxxx + + jobject shader; + if (fillType.gradient->isRadial) + { + shader = env->NewObject (android.radialGradientClass, + android.radialGradientConstructor, + p1.getX(), p1.getY(), + p1.getDistanceFrom (p2), + coloursArray, positionsArray, + tileMode)); + } + else + { + shader = env->NewObject (android.linearGradientClass, + android.linearGradientConstructor, + p1.getX(), p1.getY(), p2.getX(), p2.getY(), + coloursArray, positionsArray, + tileMode)); + } + + env->CallVoidMethod (shader, android.setLocalMatrix, createMatrix (fillType.transform)); + paint.callVoidMethod (android.setShader, shader); + } + else + {x + } + } + + return paint.get(); + } + + private: + FillType fillType; + Font font; + GlobalRef paint; + bool needsUpdate; + }; + private: - GlobalRef canvas, currentPaint; + GlobalRef canvas; + + ScopedPointer currentState; + OwnedArray stateStack; + + GlobalRef& getCurrentPaint() throw() { return *paintStack.getUnchecked (paintStack.size() - 1); } + + static jobject createPath (JNIEnv* env, const Path& path) + { + jobject p = env->NewObject (android.pathClass, android.pathClassConstructor); + + Path::Iterator i (path); + + while (i.next()) + { + switch (i.elementType) + { + case Path::Iterator::startNewSubPath: env->CallVoidMethod (p, android.moveTo, i.x1, i.y1); break; + case Path::Iterator::lineTo: env->CallVoidMethod (p, android.lineTo, i.x1, i.y1); break; + case Path::Iterator::quadraticTo: env->CallVoidMethod (p, android.quadTo, i.x1, i.y1, i.x2, i.y2); break; + case Path::Iterator::cubicTo: env->CallVoidMethod (p, android.cubicTo, i.x1, i.y1, i.x2, i.y2, i.x3, i.y3); break; + case Path::Iterator::closePath: env->CallVoidMethod (p, android.closePath); break; + default: jassertfalse; break; + } + } + + return p; + } + + static jobject createPath (JNIEnv* env, const Path& path, const AffineTransform& transform) + { + if (transform.isIdentity()) + return createPath (env, path); + + Path tempPath (path); + tempPath.applyTransform (transform); + return createPath (env, tempPath); + } + + static jobject createMatrix (JNIEnv* env, const AffineTransform& t) + { + jobject m = env->NewObject (android.matrixClass, android.matrixClassConstructor); + + jfloat values[9] = { t.mat00, t.mat01, t.mat02, + t.mat10, t.mat11, t.mat12, + 0.0f, 0.0f, 1.0f }; + + jfloatArray javaArray = env->NewFloatArray (9); + env->SetFloatArrayRegion (javaArray, 0, 9, values); + + env->CallVoidMethod (m, android.setValues, javaArray); + env->DeleteLocalRef (javaArray); + + return m; + } + + static jobject createRect (JNIEnv* env, const Rectangle& r) + { + return env->NewObject (android.rectClass, android.rectConstructor, + r.getX(), r.getY(), r.getRight(), r.getBottom()); + } + + static jobject createRegion (JNIEnv* env, const RectangleList& list) + { + jobject region = env->NewObject (android.regionClass, android.regionConstructor); + + const int numRects = list.getNumRectangles(); + + for (int i = 0; i < numRects; ++i) + env->CallVoidMethod (region, android.regionUnion, createRect (env, list.getRectangle(i))); + + return region; + } + + static int colourToInt (const Colour& col) throw() + { + return col.getARGB(); + } JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (AndroidLowLevelGraphicsContext); }; diff --git a/src/native/android/juce_android_Messaging.cpp b/src/native/android/juce_android_Messaging.cpp index daf5d97905..82fbb53f8c 100644 --- a/src/native/android/juce_android_Messaging.cpp +++ b/src/native/android/juce_android_Messaging.cpp @@ -61,11 +61,16 @@ bool juce_dispatchNextMessageOnSystemQueue (const bool returnIfNoPendingMessages //============================================================================== bool juce_postMessageToSystemQueue (Message* message) { - // TODO - + android.activity.callVoidMethod (android.postMessage, (jlong) (pointer_sized_uint) message); return true; } +JUCE_JNI_CALLBACK (JuceAppActivity, deliverMessage, void, (jobject activity, jlong value)) +{ + Message* m = (Message*) (pointer_sized_uint) value; + MessageManager::getInstance()->deliverMessage ((Message*) (pointer_sized_uint) value); +} + //============================================================================== class AsyncFunctionCaller : public AsyncUpdater { diff --git a/src/native/android/juce_android_Misc.cpp b/src/native/android/juce_android_Misc.cpp index e17ea1111f..7fda1d2e1c 100644 --- a/src/native/android/juce_android_Misc.cpp +++ b/src/native/android/juce_android_Misc.cpp @@ -32,9 +32,9 @@ extern JUCE_NAMESPACE::JUCEApplication* juce_CreateApplication(); // (from START BEGIN_JUCE_NAMESPACE //============================================================================== -JUCE_JNI_CALLBACK (JuceAppActivity, launchApp, void, (JNIEnv* env, jobject activity)) +JUCE_JNI_CALLBACK (JuceAppActivity, launchApp, void, (JNIEnv* env, jobject activity, int screenWidth, int screenHeight)) { - android.initialise (env, activity); + android.initialise (env, activity, screenWidth, screenHeight); JUCEApplication::createInstance = &juce_CreateApplication; diff --git a/src/native/android/juce_android_NativeCode.cpp b/src/native/android/juce_android_NativeCode.cpp index 2274cf79b4..8ffab85bcd 100644 --- a/src/native/android/juce_android_NativeCode.cpp +++ b/src/native/android/juce_android_NativeCode.cpp @@ -102,23 +102,82 @@ BEGIN_JUCE_NAMESPACE JAVACLASS (contextClass, "android/content/Context") \ JAVACLASS (canvasClass, "android/graphics/Canvas") \ JAVACLASS (paintClass, "android/graphics/Paint") \ - + JAVACLASS (pathClass, "android/graphics/Path") \ + JAVACLASS (matrixClass, "android/graphics/Matrix") \ + JAVACLASS (rectClass, "android/graphics/Rect") \ + JAVACLASS (regionClass, "android/graphics/Region") \ + JAVACLASS (shaderClass, "android/graphics/Shader") \ + JAVACLASS (linearGradientClass, "android/graphics/LinearGradient") \ + JAVACLASS (radialGradientClass, "android/graphics/RadialGradient") \ //============================================================================== -#define JUCE_JNI_METHODS(METHOD, STATICMETHOD) \ +#define JUCE_JNI_METHODS(METHOD, STATICMETHOD, FIELD) \ \ STATICMETHOD (activityClass, printToConsole, "printToConsole", "(Ljava/lang/String;)V") \ METHOD (activityClass, createNewView, "createNewView", "()Lcom/juce/ComponentPeerView;") \ METHOD (activityClass, deleteView, "deleteView", "(Lcom/juce/ComponentPeerView;)V") \ + METHOD (activityClass, postMessage, "postMessage", "(J)V") \ \ METHOD (fileClass, fileExists, "exists", "()Z") \ \ + METHOD (componentPeerViewClass, setViewName, "setViewName", "(Ljava/lang/String;)V") \ METHOD (componentPeerViewClass, layout, "layout", "(IIII)V") \ + METHOD (componentPeerViewClass, getLeft, "getLeft", "()I") \ + METHOD (componentPeerViewClass, getTop, "getTop", "()I") \ + METHOD (componentPeerViewClass, getWidth, "getWidth", "()I") \ + METHOD (componentPeerViewClass, getHeight, "getHeight", "()I") \ + METHOD (componentPeerViewClass, getLocationOnScreen, "getLocationOnScreen", "([I)V") \ + METHOD (componentPeerViewClass, bringToFront, "bringToFront", "()V") \ + METHOD (componentPeerViewClass, requestFocus, "requestFocus", "()Z") \ + METHOD (componentPeerViewClass, setVisible, "setVisible", "(Z)V") \ + METHOD (componentPeerViewClass, isVisible, "isVisible", "()Z") \ + METHOD (componentPeerViewClass, hasFocus, "hasFocus", "()Z") \ + METHOD (componentPeerViewClass, invalidate, "invalidate", "(IIII)V") \ \ METHOD (canvasClass, drawRect, "drawRect", "(FFFFLandroid/graphics/Paint;)V") \ + METHOD (canvasClass, translate, "translate", "(FF)V") \ + METHOD (canvasClass, clipPath, "clipPath", "(Landroid/graphics/Path;)Z") \ + METHOD (canvasClass, clipRect, "clipRect", "(FFFF)Z") \ + METHOD (canvasClass, clipRegion, "clipRegion", "(Landroid/graphics/Region;)Z") \ + METHOD (canvasClass, concat, "concat", "(Landroid/graphics/Matrix;)V") \ + METHOD (canvasClass, drawBitmap, "drawBitmap", "(Landroid/graphics/Bitmap;Landroid/graphics/Matrix;Landroid/graphics/Paint;)V") \ + METHOD (canvasClass, drawLine, "drawLine", "(FFFFLandroid/graphics/Paint;)V") \ + METHOD (canvasClass, drawPath, "drawPath", "(Landroid/graphics/Path;Landroid/graphics/Paint;)V") \ + METHOD (canvasClass, getClipBounds, "getClipBounds", "(Landroid/graphics/Rect;)Z") \ + METHOD (canvasClass, getClipBounds2, "getClipBounds", "()Landroid/graphics/Rect;") \ + METHOD (canvasClass, getMatrix, "getMatrix", "()Landroid/graphics/Matrix;") \ + METHOD (canvasClass, save, "save", "()I") \ + METHOD (canvasClass, restore, "restore", "()V") \ + METHOD (canvasClass, saveLayerAlpha, "saveLayerAlpha", "(FFFFII)I") \ \ METHOD (paintClass, paintClassConstructor, "", "()V") \ METHOD (paintClass, setColor, "setColor", "(I)V") \ + METHOD (paintClass, setShader, "setShader", "(Landroid/graphics/Shader;)Landroid/graphics/Shader;") \ +\ + METHOD (shaderClass, setLocalMatrix, "setLocalMatrix", "(Landroid/graphics/Matrix;)V") \ +\ + METHOD (pathClass, pathClassConstructor, "", "()V") \ + METHOD (pathClass, moveTo, "moveTo", "(FF)V") \ + METHOD (pathClass, lineTo, "lineTo", "(FF)V") \ + METHOD (pathClass, quadTo, "quadTo", "(FFFF)V") \ + METHOD (pathClass, cubicTo, "cubicTo", "(FFFFFF)V") \ + METHOD (pathClass, closePath, "close", "()V") \ +\ + METHOD (matrixClass, matrixClassConstructor, "", "()V") \ + METHOD (matrixClass, setValues, "setValues", "([F)V") \ +\ + METHOD (rectClass, rectConstructor, "", "(IIII)V") \ + FIELD (rectClass, rectLeft, "left", "I") \ + FIELD (rectClass, rectRight, "right", "I") \ + FIELD (rectClass, rectTop, "top", "I") \ + FIELD (rectClass, rectBottom, "bottom", "I") \ +\ + METHOD (linearGradientClass, linearGradientConstructor, "", "(FFFF[I[FLandroid/graphics/Shader$TileMode;)V") \ +\ + METHOD (radialGradientClass, radialGradientConstructor, "", "(FFF[I[FLandroid/graphics/Shader$TileMode;)V") \ +\ + METHOD (regionClass, regionConstructor, "", "()V"); \ + METHOD (regionClass, regionUnion, "union", "(Landroid/graphics/Rect;)Z"); \ //============================================================================== @@ -144,28 +203,27 @@ public: ~GlobalRef() { - release(); + clear(); + } + + void clear() + { + if (env != 0) + { + env->DeleteGlobalRef (obj); + env = 0; + obj = 0; + } } GlobalRef& operator= (const GlobalRef& other) { - release(); + clear(); env = other.env; obj = retain (env, other.obj); return *this; } - GlobalRef& operator= (jobject newObj) - { - jassert (env != 0 || newObj == 0); - - if (newObj != obj && env != 0) - { - release(); - obj = retain (env, newObj); - } - } - //============================================================================== inline operator jobject() const throw() { return obj; } inline jobject get() const throw() { return obj; } @@ -173,12 +231,11 @@ public: //============================================================================== #define DECLARE_CALL_TYPE_METHOD(returnType, typeName) \ - returnType call##typeName##Method (jmethodID methodID, ... ) \ + returnType call##typeName##Method (jmethodID methodID, ... ) const \ { \ - returnType result; \ va_list args; \ va_start (args, methodID); \ - result = env->Call##typeName##MethodV (obj, methodID, args); \ + returnType result = env->Call##typeName##MethodV (obj, methodID, args); \ va_end (args); \ return result; \ } @@ -194,7 +251,7 @@ public: DECLARE_CALL_TYPE_METHOD (jdouble, Double) #undef DECLARE_CALL_TYPE_METHOD - void callVoidMethod (jmethodID methodID, ... ) + void callVoidMethod (jmethodID methodID, ... ) const { va_list args; va_start (args, methodID); @@ -207,12 +264,6 @@ private: JNIEnv* env; jobject obj; - void release() - { - if (env != 0) - env->DeleteGlobalRef (obj); - } - static jobject retain (JNIEnv* const env, jobject obj_) { return env == 0 ? 0 : env->NewGlobalRef (obj_); @@ -223,14 +274,16 @@ private: class AndroidJavaCallbacks { public: - AndroidJavaCallbacks() : env (0) + AndroidJavaCallbacks() : env (0), screenWidth (0), screenHeight (0) { } - void initialise (JNIEnv* env_, jobject activity_) + void initialise (JNIEnv* env_, jobject activity_, int screenWidth_, int screenHeight_) { env = env_; activity = GlobalRef (env, activity_); + screenWidth = screenWidth_; + screenHeight = screenHeight_; #define CREATE_JNI_CLASS(className, path) \ className = (jclass) env->NewGlobalRef (env->FindClass (path)); \ @@ -244,7 +297,10 @@ public: #define CREATE_JNI_STATICMETHOD(ownerClass, methodID, stringName, params) \ methodID = env->GetStaticMethodID (ownerClass, stringName, params); \ jassert (methodID != 0); - JUCE_JNI_METHODS (CREATE_JNI_METHOD, CREATE_JNI_STATICMETHOD); + #define CREATE_JNI_FIELD(ownerClass, fieldID, stringName, signature) \ + fieldID = env->GetFieldID (ownerClass, stringName, signature); \ + jassert (fieldID != 0); + JUCE_JNI_METHODS (CREATE_JNI_METHOD, CREATE_JNI_STATICMETHOD, CREATE_JNI_FIELD); #undef CREATE_JNI_METHOD } @@ -256,7 +312,7 @@ public: JUCE_JNI_CLASSES (RELEASE_JNI_CLASS); #undef RELEASE_JNI_CLASS - activity = 0; + activity.clear(); env = 0; } } @@ -280,6 +336,7 @@ public: //============================================================================== JNIEnv* env; GlobalRef activity; + int screenWidth, screenHeight; //============================================================================== #define DECLARE_JNI_CLASS(className, path) jclass className; @@ -287,7 +344,8 @@ public: #undef DECLARE_JNI_CLASS #define DECLARE_JNI_METHOD(ownerClass, methodID, stringName, params) jmethodID methodID; - JUCE_JNI_METHODS (DECLARE_JNI_METHOD, DECLARE_JNI_METHOD); + #define DECLARE_JNI_FIELD(ownerClass, fieldID, stringName, signature) jfieldID fieldID; + JUCE_JNI_METHODS (DECLARE_JNI_METHOD, DECLARE_JNI_METHOD, DECLARE_JNI_FIELD); #undef DECLARE_JNI_METHOD }; diff --git a/src/native/android/juce_android_Windowing.cpp b/src/native/android/juce_android_Windowing.cpp index 5dbda28c6a..b3f7e0c62e 100644 --- a/src/native/android/juce_android_Windowing.cpp +++ b/src/native/android/juce_android_Windowing.cpp @@ -42,58 +42,71 @@ public: ~AndroidComponentPeer() { android.activity.callVoidMethod (android.deleteView, view.get()); - view = 0; + view.clear(); } void* getNativeHandle() const { - return 0; // TODO + return (void*) view.get(); } void setVisible (bool shouldBeVisible) { + view.callVoidMethod (android.setVisible, shouldBeVisible); } void setTitle (const String& title) { + view.callVoidMethod (android.setViewName, android.javaString (title)); } void setPosition (int x, int y) { - // TODO + const Rectangle pos (getBounds()); + setBounds (x, y, pos.getWidth(), pos.getHeight(), false); } void setSize (int w, int h) { + const Rectangle pos (getBounds()); + setBounds (pos.getX(), pos.getY(), w, h, false); } void setBounds (int x, int y, int w, int h, bool isNowFullScreen) { - DBG ("Window size: " << x << " " << y << " " << w << " " << h); view.callVoidMethod (android.layout, x, y, x + w, y + h); } const Rectangle getBounds() const { - // TODO - return Rectangle(); + return Rectangle (view.callIntMethod (android.getLeft), + view.callIntMethod (android.getTop), + view.callIntMethod (android.getWidth), + view.callIntMethod (android.getHeight)); } const Point getScreenPosition() const { - // TODO - return Point(); + JNIEnv* const env = view.getEnv(); + + jintArray pos = env->NewIntArray (2); + view.callVoidMethod (android.getLocationOnScreen, pos); + + jint coords[2]; + jint i, sum = 0; + env->GetIntArrayRegion (pos, 0, 2, coords); + env->DeleteLocalRef (pos); + + return Point (coords[0], coords[1]); } const Point localToGlobal (const Point& relativePosition) { - // TODO return relativePosition + getScreenPosition(); } const Point globalToLocal (const Point& screenPosition) { - // TODO return screenPosition - getScreenPosition(); } @@ -104,6 +117,7 @@ public: bool isMinimised() const { + return false; } void setFullScreen (bool shouldBeFullScreen) @@ -144,7 +158,10 @@ public: void toFront (bool makeActive) { - // TODO + view.callVoidMethod (android.bringToFront); + + if (makeActive) + grabFocus(); } void toBehind (ComponentPeer* other) @@ -155,13 +172,12 @@ public: //============================================================================== bool isFocused() const { - // TODO - return false; + return view.callBooleanMethod (android.hasFocus); } void grabFocus() { - // TODO + (void) view.callBooleanMethod (android.requestFocus); } void textInputRequired (const Point& position) @@ -178,7 +194,7 @@ public: void repaint (const Rectangle& area) { - // TODO + view.callVoidMethod (android.invalidate, area.getX(), area.getY(), area.getRight(), area.getBottom()); } void performAnyPendingRepaintsNow() @@ -319,17 +335,9 @@ void juce_setKioskComponent (Component* kioskModeComponent, bool enableOrDisable } //============================================================================== -static int screenWidth = 0, screenHeight = 0; - void juce_updateMultiMonitorInfo (Array >& monitorCoords, const bool clipToWorkArea) { - monitorCoords.add (Rectangle (0, 0, screenWidth, screenHeight)); -} - -JUCE_JNI_CALLBACK (JuceAppActivity, setScreenSize, void, (JNIEnv* env, jobject activity, int w, int h)) -{ - screenWidth = w; - screenHeight = h; + monitorCoords.add (Rectangle (0, 0, android.screenWidth, android.screenHeight)); } //============================================================================== diff --git a/src/native/linux/juce_linux_Audio.cpp b/src/native/linux/juce_linux_Audio.cpp index 3bda233c4f..eb41de75b0 100644 --- a/src/native/linux/juce_linux_Audio.cpp +++ b/src/native/linux/juce_linux_Audio.cpp @@ -1011,7 +1011,7 @@ private: }; //============================================================================== -AudioIODeviceType* juce_createAudioIODeviceType_ALSA() +AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_ALSA() { return new ALSAAudioIODeviceType(); } diff --git a/src/native/linux/juce_linux_JackAudio.cpp b/src/native/linux/juce_linux_JackAudio.cpp index f7d1a36b80..9b6c65da8f 100644 --- a/src/native/linux/juce_linux_JackAudio.cpp +++ b/src/native/linux/juce_linux_JackAudio.cpp @@ -592,16 +592,10 @@ private: }; //============================================================================== -AudioIODeviceType* juce_createAudioIODeviceType_JACK() +AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_JACK() { return new JackAudioIODeviceType(); } - -//============================================================================== -#else // if JACK is turned off.. - -AudioIODeviceType* juce_createAudioIODeviceType_JACK() { return 0; } - #endif #endif diff --git a/src/native/mac/juce_ios_Audio.cpp b/src/native/mac/juce_ios_Audio.cpp index 50cf2ab99d..71dcd538af 100644 --- a/src/native/mac/juce_ios_Audio.cpp +++ b/src/native/mac/juce_ios_Audio.cpp @@ -574,7 +574,7 @@ private: }; //============================================================================== -AudioIODeviceType* juce_createAudioIODeviceType_iPhoneAudio() +AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_iOSAudio() { return new IPhoneAudioIODeviceType(); } diff --git a/src/native/mac/juce_mac_CoreAudio.cpp b/src/native/mac/juce_mac_CoreAudio.cpp index 2c186b49b6..b981a520dc 100644 --- a/src/native/mac/juce_mac_CoreAudio.cpp +++ b/src/native/mac/juce_mac_CoreAudio.cpp @@ -1292,7 +1292,7 @@ private: }; //============================================================================== -AudioIODeviceType* juce_createAudioIODeviceType_CoreAudio() +AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_CoreAudio() { return new CoreAudioIODeviceType(); } diff --git a/src/native/mac/juce_mac_NSViewComponentPeer.mm b/src/native/mac/juce_mac_NSViewComponentPeer.mm index c73b0ecbd9..525d3eda89 100644 --- a/src/native/mac/juce_mac_NSViewComponentPeer.mm +++ b/src/native/mac/juce_mac_NSViewComponentPeer.mm @@ -665,7 +665,7 @@ END_JUCE_NAMESPACE //============================================================================== - (NSArray*) getSupportedDragTypes { - return [NSArray arrayWithObjects: NSFilenamesPboardType, /*NSFilesPromisePboardType, NSStringPboardType,*/ nil]; + return [NSArray arrayWithObjects: NSFilenamesPboardType, NSFilesPromisePboardType, /* NSStringPboardType,*/ nil]; } - (BOOL) sendDragCallback: (int) type sender: (id ) sender @@ -1106,9 +1106,26 @@ NSRect NSViewComponentPeer::constrainRect (NSRect r) void NSViewComponentPeer::setAlpha (float newAlpha) { if (! isSharedWindow) + { [window setAlphaValue: (CGFloat) newAlpha]; + } else + { + #if defined (MAC_OS_X_VERSION_10_5) && MAC_OS_X_VERSION_MIN_ALLOWED >= MAC_OS_X_VERSION_10_5 [view setAlphaValue: (CGFloat) newAlpha]; + #else + if ([view respondsToSelector: @selector (setAlphaValue:)]) + { + // PITA dynamic invocation for 10.4 builds.. + NSInvocation* inv = [NSInvocation invocationWithMethodSignature: [view methodSignatureForSelector: @selector (setAlphaValue:)]]; + [inv setSelector: @selector (setAlphaValue:)]; + [inv setTarget: view]; + CGFloat cgNewAlpha = (CGFloat) newAlpha; + [inv setArgument: &cgNewAlpha atIndex: 2]; + [inv invoke]; + } + #endif + } } void NSViewComponentPeer::setMinimised (bool shouldBeMinimised) @@ -1493,7 +1510,7 @@ void NSViewComponentPeer::showArrowCursorIfNeeded() } //============================================================================== -BOOL NSViewComponentPeer::sendDragCallback (int type, id sender) +BOOL NSViewComponentPeer::sendDragCallback (const int type, id sender) { NSString* bestType = [[sender draggingPasteboard] availableTypeFromArray: [view getSupportedDragTypes]]; @@ -1504,31 +1521,59 @@ BOOL NSViewComponentPeer::sendDragCallback (int type, id sender NSPoint p = [view convertPoint: [sender draggingLocation] fromView: nil]; const Point pos ((int) p.x, (int) ([view frame].size.height - p.y)); - id list = [[sender draggingPasteboard] propertyListForType: bestType]; - if (list == nil) - return false; - + NSPasteboard* pasteBoard = [sender draggingPasteboard]; StringArray files; - if ([list isKindOfClass: [NSArray class]]) + NSString* iTunesPasteboardType = @"CorePasteboardFlavorType 0x6974756E"; // 'itun' + + if (bestType == NSFilesPromisePboardType + && [[pasteBoard types] containsObject: iTunesPasteboardType]) { - NSArray* items = (NSArray*) list; + id list = [pasteBoard propertyListForType: iTunesPasteboardType]; + + if ([list isKindOfClass: [NSDictionary class]]) + { + NSDictionary* iTunesDictionary = (NSDictionary*) list; + NSArray* tracks = [iTunesDictionary valueForKey: @"Tracks"]; + NSEnumerator* enumerator = [tracks objectEnumerator]; + NSDictionary* track; - for (unsigned int i = 0; i < [items count]; ++i) - files.add (nsStringToJuce ((NSString*) [items objectAtIndex: i])); + while ((track = [enumerator nextObject]) != nil) + { + NSURL* url = [NSURL URLWithString: [track valueForKey: @"Location"]]; + + if ([url isFileURL]) + files.add (nsStringToJuce ([url path])); + } + } } + else + { + id list = [pasteBoard propertyListForType: NSFilenamesPboardType]; - if (files.size() == 0) - return false; + if ([list isKindOfClass: [NSArray class]]) + { + NSArray* items = (NSArray*) [pasteBoard propertyListForType: NSFilenamesPboardType]; - if (type == 0) - handleFileDragMove (files, pos); - else if (type == 1) - handleFileDragExit (files); - else if (type == 2) - handleFileDragDrop (files, pos); + for (unsigned int i = 0; i < [items count]; ++i) + files.add (nsStringToJuce ((NSString*) [items objectAtIndex: i])); + } + } - return true; + if (files.size() > 0) + { + switch (type) + { + case 0: handleFileDragMove (files, pos); break; + case 1: handleFileDragExit (files); break; + case 2: handleFileDragDrop (files, pos); break; + default: jassertfalse; break; + } + + return true; + } + + return false; } bool NSViewComponentPeer::isOpaque() diff --git a/src/native/windows/juce_win32_ASIO.cpp b/src/native/windows/juce_win32_ASIO.cpp index fef7fcd62d..3018e697b9 100644 --- a/src/native/windows/juce_win32_ASIO.cpp +++ b/src/native/windows/juce_win32_ASIO.cpp @@ -1859,7 +1859,7 @@ private: JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (ASIOAudioIODeviceType); }; -AudioIODeviceType* juce_createAudioIODeviceType_ASIO() +AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_ASIO() { return new ASIOAudioIODeviceType(); } diff --git a/src/native/windows/juce_win32_DirectSound.cpp b/src/native/windows/juce_win32_DirectSound.cpp index 64e36e71b5..e9a948069d 100644 --- a/src/native/windows/juce_win32_DirectSound.cpp +++ b/src/native/windows/juce_win32_DirectSound.cpp @@ -1386,7 +1386,7 @@ const String DSoundAudioIODevice::openDevice (const BigInteger& inputChannels, } //============================================================================== -AudioIODeviceType* juce_createAudioIODeviceType_DirectSound() +AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_DirectSound() { return new DSoundAudioIODeviceType(); } diff --git a/src/native/windows/juce_win32_WASAPI.cpp b/src/native/windows/juce_win32_WASAPI.cpp index a20d04b605..fcb696483b 100644 --- a/src/native/windows/juce_win32_WASAPI.cpp +++ b/src/native/windows/juce_win32_WASAPI.cpp @@ -1052,9 +1052,12 @@ private: } //============================================================================== -AudioIODeviceType* juce_createAudioIODeviceType_WASAPI() +AudioIODeviceType* AudioIODeviceType::createAudioIODeviceType_WASAPI() { - return new WasapiClasses::WASAPIAudioIODeviceType(); + if (SystemStats::getOperatingSystemType() >= SystemStats::WinVista) + return new WasapiClasses::WASAPIAudioIODeviceType(); + + return 0; } #endif diff --git a/src/text/juce_String.h b/src/text/juce_String.h index 61d41fc989..ccb7c6489a 100644 --- a/src/text/juce_String.h +++ b/src/text/juce_String.h @@ -1290,7 +1290,7 @@ JUCE_API bool JUCE_CALLTYPE operator<= (const String& string1, const String& str This is very handy for writing strings to std::cout, std::cerr, etc. */ template -JUCE_API std::basic_ostream & JUCE_CALLTYPE operator<< (std::basic_ostream & stream, const String& stringToWrite) +std::basic_ostream & JUCE_CALLTYPE operator<< (std::basic_ostream & stream, const String& stringToWrite) { return stream << stringToWrite.toUTF8().getAddress(); } diff --git a/src/threads/juce_CriticalSection.h b/src/threads/juce_CriticalSection.h index 668c0b80e6..621a88aee3 100644 --- a/src/threads/juce_CriticalSection.h +++ b/src/threads/juce_CriticalSection.h @@ -27,8 +27,8 @@ #define __JUCE_CRITICALSECTION_JUCEHEADER__ #ifndef DOXYGEN - class JUCE_API ScopedLock; - class JUCE_API ScopedUnlock; + class ScopedLock; + class ScopedUnlock; #endif diff --git a/src/threads/juce_ScopedLock.h b/src/threads/juce_ScopedLock.h index f83fa9dab1..961be79d15 100644 --- a/src/threads/juce_ScopedLock.h +++ b/src/threads/juce_ScopedLock.h @@ -52,7 +52,7 @@ @see CriticalSection, ScopedUnlock */ -class JUCE_API ScopedLock +class ScopedLock { public: //==============================================================================