diff --git a/extras/browser plugins/How to build a browser plugin.txt b/extras/browser plugins/How to build a browser plugin.txt new file mode 100644 index 0000000000..b85216e4e1 --- /dev/null +++ b/extras/browser plugins/How to build a browser plugin.txt @@ -0,0 +1,54 @@ + + + Juce Browser Plugin Framework + ============================= + +These classes let you easily turn a normal Juce component into a Mac/Windows NPAPI plugin +for use in Firefox, Safari, Opera, etc. + +To create your plugin, your code just needs to implement the createBrowserPlugin() function +to return a subclass of BrowserPluginComponent, and this acts as the plugin window. + +To communicate with javascript running in the host webpage, the 'var' and 'DynamicObject' juce +classes emulate javascript objects, so you can create a javascript object that represents +your plugin, and the webpage can invoke methods and access properties on this object. To +get bi-directional communication between the plugin and webpage, your webpage can simply +pass its own object to your plugin, and the plugin can call methods on this object to invoke +javascript actions. + +In a similar style to audio plugins, your project has to contain a BrowserPluginCharacteristics.h +file that defines various properties of the plugin. + + +Building a Mac NPAPI Plugin with XCode +-------------------------------------- + +- Create a new "CFPlugin Bundle" project +- Add the juce wrapper source files to the project (have a look at the demo project to + find out which files this includes). +- Set up all the usual frameworks, etc, like you would for any other juce project. +- In the project or target settings, change the "Wrapper Extension" to "plugin" +- In your target, add a build phase "Build ResourceManager resources", and add the juce_NPAPI_MacResource.r file + to this step. +- Check that your info.plist contains the same items as the demo plugin, because these needs to be set for the + browser to recognise it as a plugin. In particular, the "Bundle OS Type Code" should be set to BRPL. +- The finished bundle needs to be copied into "/Library/Internet Plug-Ins", so you might want to set up a + post-build copy step to do this automatically + + +Building a Windows NPAPI plugin in Visual Studio +------------------------------------------------ + +- Install the NPAPI framework and make sure that your include path is set up to include its headers +- Create a new project to build a win32 DLL +- Add the juce wrapper source files to the project (have a look at the demo project to + find out which files this includes). +- Your compiled plugin DLL must begin with the letters 'np' (in lower case) for it to be recognised as + a plugin, so you should make sure your target settings reflect this. +- To include the BrowserPluginCharacteristics.h file, you may need to add an include path to wherever this + file lives in your project. Don't use a global include path for this - just add it to the project's + search paths (both the c++ include paths and the resource include paths) +- (Refer to the normal juce instructions for setting up other project settings such as which c++ libs to link to etc) +- The finished plugin needs to be copied into "C:\Program Files\Mozilla Firefox\plugins", so you might want + to add a post-build step to copy it +- \ No newline at end of file diff --git a/extras/browser plugins/demo/build/npapi_mac/English.lproj/InfoPlist.strings b/extras/browser plugins/demo/build/npapi_mac/English.lproj/InfoPlist.strings new file mode 100644 index 0000000000..5e45963c38 Binary files /dev/null and b/extras/browser plugins/demo/build/npapi_mac/English.lproj/InfoPlist.strings differ diff --git a/extras/browser plugins/demo/build/npapi_mac/Info.plist b/extras/browser plugins/demo/build/npapi_mac/Info.plist new file mode 100644 index 0000000000..a57e13bec5 --- /dev/null +++ b/extras/browser plugins/demo/build/npapi_mac/Info.plist @@ -0,0 +1,28 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleName + ${PRODUCT_NAME} + CFBundleIconFile + + CFBundleIdentifier + com.yourcompany.${PRODUCT_NAME:identifier} + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + BRPL + CFBundleSignature + ???? + CFBundleVersion + 1.0 + CFBundleDisplayName + JuceBrowserPlugin_Desc + CFBundleShortVersionString + JuceBrowserPlugin_Name + + diff --git a/extras/browser plugins/demo/build/npapi_mac/JuceBrowserPluginDemo.xcodeproj/TemplateIcon.tiff b/extras/browser plugins/demo/build/npapi_mac/JuceBrowserPluginDemo.xcodeproj/TemplateIcon.tiff new file mode 100644 index 0000000000..82326a6c87 Binary files /dev/null and b/extras/browser plugins/demo/build/npapi_mac/JuceBrowserPluginDemo.xcodeproj/TemplateIcon.tiff differ diff --git a/extras/browser plugins/demo/build/npapi_mac/JuceBrowserPluginDemo.xcodeproj/project.pbxproj b/extras/browser plugins/demo/build/npapi_mac/JuceBrowserPluginDemo.xcodeproj/project.pbxproj new file mode 100644 index 0000000000..25d5335740 --- /dev/null +++ b/extras/browser plugins/demo/build/npapi_mac/JuceBrowserPluginDemo.xcodeproj/project.pbxproj @@ -0,0 +1,343 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 45; + objects = { + +/* Begin PBXBuildFile section */ + 842CC42B0FA5BD3C008C7970 /* juce_NPAPI_GlueCode.mm in Sources */ = {isa = PBXBuildFile; fileRef = 842CC4290FA5BD3C008C7970 /* juce_NPAPI_GlueCode.mm */; }; + 842CC4320FA5BD57008C7970 /* JuceBrowserPluginDemo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 842CC42E0FA5BD57008C7970 /* JuceBrowserPluginDemo.cpp */; }; + 842CC4330FA5BD57008C7970 /* juce_LibrarySource.mm in Sources */ = {isa = PBXBuildFile; fileRef = 842CC42F0FA5BD57008C7970 /* juce_LibrarySource.mm */; }; + 842CC8E20FA5D26A008C7970 /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 842CC8D30FA5D26A008C7970 /* Carbon.framework */; }; + 842CC8E30FA5D26A008C7970 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 842CC8D40FA5D26A008C7970 /* CoreFoundation.framework */; }; + 842CC8E40FA5D26A008C7970 /* DiscRecording.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 842CC8D50FA5D26A008C7970 /* DiscRecording.framework */; }; + 842CC8E50FA5D26A008C7970 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 842CC8D60FA5D26A008C7970 /* Cocoa.framework */; }; + 842CC8E60FA5D26A008C7970 /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 842CC8D70FA5D26A008C7970 /* WebKit.framework */; }; + 842CC8E70FA5D26A008C7970 /* AGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 842CC8D80FA5D26A008C7970 /* AGL.framework */; }; + 842CC8E80FA5D26A008C7970 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 842CC8D90FA5D26A008C7970 /* CoreAudio.framework */; }; + 842CC8E90FA5D26A008C7970 /* CoreMIDI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 842CC8DA0FA5D26A008C7970 /* CoreMIDI.framework */; }; + 842CC8EA0FA5D26A008C7970 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 842CC8DB0FA5D26A008C7970 /* IOKit.framework */; }; + 842CC8EB0FA5D26A008C7970 /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 842CC8DC0FA5D26A008C7970 /* OpenGL.framework */; }; + 842CC8EC0FA5D26A008C7970 /* QuickTime.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 842CC8DD0FA5D26A008C7970 /* QuickTime.framework */; }; + 842CC8ED0FA5D26A008C7970 /* QTKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 842CC8DE0FA5D26A008C7970 /* QTKit.framework */; }; + 842CC8EE0FA5D26A008C7970 /* CoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 842CC8DF0FA5D26A008C7970 /* CoreServices.framework */; }; + 842CC8EF0FA5D26A008C7970 /* ApplicationServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 842CC8E00FA5D26A008C7970 /* ApplicationServices.framework */; }; + 842CC8F00FA5D26A008C7970 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 842CC8E10FA5D26A008C7970 /* CoreFoundation.framework */; }; + 842CC94A0FA5D934008C7970 /* juce_NPAPI_MacResource.r in Rez */ = {isa = PBXBuildFile; fileRef = 842CC42A0FA5BD3C008C7970 /* juce_NPAPI_MacResource.r */; }; + 842CCB300FA5F201008C7970 /* JuceBrowserPluginDemo.bundle in CopyFiles */ = {isa = PBXBuildFile; fileRef = 842CC9360FA5D51F008C7970 /* JuceBrowserPluginDemo.bundle */; }; + 8D5B49A804867FD3000E48DA /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 8D5B49A704867FD3000E48DA /* InfoPlist.strings */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 842CCB3F0FA5F204008C7970 /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = "/Library/Internet Plug-Ins"; + dstSubfolderSpec = 0; + files = ( + 842CCB300FA5F201008C7970 /* JuceBrowserPluginDemo.bundle in CopyFiles */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 089C167EFE841241C02AAC07 /* English */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = English; path = English.lproj/InfoPlist.strings; sourceTree = ""; }; + 842CC4250FA5BD2D008C7970 /* How to build a browser plugin.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = "How to build a browser plugin.txt"; path = "../../../How to build a browser plugin.txt"; sourceTree = SOURCE_ROOT; }; + 842CC4270FA5BD3C008C7970 /* juce_BrowserPluginComponent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = juce_BrowserPluginComponent.h; path = ../../../wrapper/juce_BrowserPluginComponent.h; sourceTree = SOURCE_ROOT; }; + 842CC4280FA5BD3C008C7970 /* juce_IncludeBrowserPluginInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = juce_IncludeBrowserPluginInfo.h; path = ../../../wrapper/juce_IncludeBrowserPluginInfo.h; sourceTree = SOURCE_ROOT; }; + 842CC4290FA5BD3C008C7970 /* juce_NPAPI_GlueCode.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = juce_NPAPI_GlueCode.mm; path = ../../../wrapper/juce_NPAPI_GlueCode.mm; sourceTree = SOURCE_ROOT; }; + 842CC42A0FA5BD3C008C7970 /* juce_NPAPI_MacResource.r */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.rez; name = juce_NPAPI_MacResource.r; path = ../../../wrapper/juce_NPAPI_MacResource.r; sourceTree = SOURCE_ROOT; }; + 842CC42E0FA5BD57008C7970 /* JuceBrowserPluginDemo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = JuceBrowserPluginDemo.cpp; path = ../../src/JuceBrowserPluginDemo.cpp; sourceTree = SOURCE_ROOT; }; + 842CC42F0FA5BD57008C7970 /* juce_LibrarySource.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = juce_LibrarySource.mm; path = ../../src/juce_LibrarySource.mm; sourceTree = SOURCE_ROOT; }; + 842CC4310FA5BD57008C7970 /* BrowserPluginCharacteristics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BrowserPluginCharacteristics.h; path = ../../src/BrowserPluginCharacteristics.h; sourceTree = SOURCE_ROOT; }; + 842CC8D30FA5D26A008C7970 /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = /System/Library/Frameworks/Carbon.framework; sourceTree = ""; }; + 842CC8D40FA5D26A008C7970 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = /System/Library/Frameworks/CoreFoundation.framework; sourceTree = ""; }; + 842CC8D50FA5D26A008C7970 /* DiscRecording.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = DiscRecording.framework; path = /System/Library/Frameworks/DiscRecording.framework; sourceTree = ""; }; + 842CC8D60FA5D26A008C7970 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = ""; }; + 842CC8D70FA5D26A008C7970 /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = /System/Library/Frameworks/WebKit.framework; sourceTree = ""; }; + 842CC8D80FA5D26A008C7970 /* AGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AGL.framework; path = /System/Library/Frameworks/AGL.framework; sourceTree = ""; }; + 842CC8D90FA5D26A008C7970 /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = /System/Library/Frameworks/CoreAudio.framework; sourceTree = ""; }; + 842CC8DA0FA5D26A008C7970 /* CoreMIDI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMIDI.framework; path = /System/Library/Frameworks/CoreMIDI.framework; sourceTree = ""; }; + 842CC8DB0FA5D26A008C7970 /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = /System/Library/Frameworks/IOKit.framework; sourceTree = ""; }; + 842CC8DC0FA5D26A008C7970 /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = /System/Library/Frameworks/OpenGL.framework; sourceTree = ""; }; + 842CC8DD0FA5D26A008C7970 /* QuickTime.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuickTime.framework; path = /System/Library/Frameworks/QuickTime.framework; sourceTree = ""; }; + 842CC8DE0FA5D26A008C7970 /* QTKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QTKit.framework; path = /System/Library/Frameworks/QTKit.framework; sourceTree = ""; }; + 842CC8DF0FA5D26A008C7970 /* CoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreServices.framework; path = /System/Library/Frameworks/CoreServices.framework; sourceTree = ""; }; + 842CC8E00FA5D26A008C7970 /* ApplicationServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ApplicationServices.framework; path = /System/Library/Frameworks/ApplicationServices.framework; sourceTree = ""; }; + 842CC8E10FA5D26A008C7970 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = /System/Library/Frameworks/CoreFoundation.framework; sourceTree = ""; }; + 842CC9360FA5D51F008C7970 /* JuceBrowserPluginDemo.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = JuceBrowserPluginDemo.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; + 842CC93B0FA5D5D1008C7970 /* test.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; name = test.html; path = ../../test.html; sourceTree = SOURCE_ROOT; }; + 8D576317048677EA00EA77CD /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 8D576313048677EA00EA77CD /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 842CC8E20FA5D26A008C7970 /* Carbon.framework in Frameworks */, + 842CC8E30FA5D26A008C7970 /* CoreFoundation.framework in Frameworks */, + 842CC8E40FA5D26A008C7970 /* DiscRecording.framework in Frameworks */, + 842CC8E50FA5D26A008C7970 /* Cocoa.framework in Frameworks */, + 842CC8E60FA5D26A008C7970 /* WebKit.framework in Frameworks */, + 842CC8E70FA5D26A008C7970 /* AGL.framework in Frameworks */, + 842CC8E80FA5D26A008C7970 /* CoreAudio.framework in Frameworks */, + 842CC8E90FA5D26A008C7970 /* CoreMIDI.framework in Frameworks */, + 842CC8EA0FA5D26A008C7970 /* IOKit.framework in Frameworks */, + 842CC8EB0FA5D26A008C7970 /* OpenGL.framework in Frameworks */, + 842CC8EC0FA5D26A008C7970 /* QuickTime.framework in Frameworks */, + 842CC8ED0FA5D26A008C7970 /* QTKit.framework in Frameworks */, + 842CC8EE0FA5D26A008C7970 /* CoreServices.framework in Frameworks */, + 842CC8EF0FA5D26A008C7970 /* ApplicationServices.framework in Frameworks */, + 842CC8F00FA5D26A008C7970 /* CoreFoundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 089C166AFE841209C02AAC07 /* JuceBrowserPluginDemo */ = { + isa = PBXGroup; + children = ( + 08FB77AFFE84173DC02AAC07 /* Source */, + 089C167CFE841241C02AAC07 /* Resources */, + 089C1671FE841209C02AAC07 /* External Frameworks and Libraries */, + 842CC9370FA5D51F008C7970 /* Products */, + ); + name = JuceBrowserPluginDemo; + sourceTree = ""; + }; + 089C1671FE841209C02AAC07 /* External Frameworks and Libraries */ = { + isa = PBXGroup; + children = ( + 842CC8D30FA5D26A008C7970 /* Carbon.framework */, + 842CC8D40FA5D26A008C7970 /* CoreFoundation.framework */, + 842CC8D50FA5D26A008C7970 /* DiscRecording.framework */, + 842CC8D60FA5D26A008C7970 /* Cocoa.framework */, + 842CC8D70FA5D26A008C7970 /* WebKit.framework */, + 842CC8D80FA5D26A008C7970 /* AGL.framework */, + 842CC8D90FA5D26A008C7970 /* CoreAudio.framework */, + 842CC8DA0FA5D26A008C7970 /* CoreMIDI.framework */, + 842CC8DB0FA5D26A008C7970 /* IOKit.framework */, + 842CC8DC0FA5D26A008C7970 /* OpenGL.framework */, + 842CC8DD0FA5D26A008C7970 /* QuickTime.framework */, + 842CC8DE0FA5D26A008C7970 /* QTKit.framework */, + 842CC8DF0FA5D26A008C7970 /* CoreServices.framework */, + 842CC8E00FA5D26A008C7970 /* ApplicationServices.framework */, + 842CC8E10FA5D26A008C7970 /* CoreFoundation.framework */, + ); + name = "External Frameworks and Libraries"; + sourceTree = ""; + }; + 089C167CFE841241C02AAC07 /* Resources */ = { + isa = PBXGroup; + children = ( + 8D576317048677EA00EA77CD /* Info.plist */, + 8D5B49A704867FD3000E48DA /* InfoPlist.strings */, + ); + name = Resources; + sourceTree = ""; + }; + 08FB77AFFE84173DC02AAC07 /* Source */ = { + isa = PBXGroup; + children = ( + 842CC4250FA5BD2D008C7970 /* How to build a browser plugin.txt */, + 842CC93B0FA5D5D1008C7970 /* test.html */, + 842CC4130FA5BB01008C7970 /* wrapper code */, + 842CC42E0FA5BD57008C7970 /* JuceBrowserPluginDemo.cpp */, + 842CC42F0FA5BD57008C7970 /* juce_LibrarySource.mm */, + 842CC4310FA5BD57008C7970 /* BrowserPluginCharacteristics.h */, + ); + name = Source; + sourceTree = ""; + }; + 842CC4130FA5BB01008C7970 /* wrapper code */ = { + isa = PBXGroup; + children = ( + 842CC4270FA5BD3C008C7970 /* juce_BrowserPluginComponent.h */, + 842CC4280FA5BD3C008C7970 /* juce_IncludeBrowserPluginInfo.h */, + 842CC4290FA5BD3C008C7970 /* juce_NPAPI_GlueCode.mm */, + 842CC42A0FA5BD3C008C7970 /* juce_NPAPI_MacResource.r */, + ); + name = "wrapper code"; + sourceTree = ""; + }; + 842CC9370FA5D51F008C7970 /* Products */ = { + isa = PBXGroup; + children = ( + 842CC9360FA5D51F008C7970 /* JuceBrowserPluginDemo.bundle */, + ); + name = Products; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 8D57630D048677EA00EA77CD /* JuceBrowserPluginDemo */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1DEB911A08733D790010E9CD /* Build configuration list for PBXNativeTarget "JuceBrowserPluginDemo" */; + buildPhases = ( + 842CC9580FA5D939008C7970 /* Rez */, + 8D57630F048677EA00EA77CD /* Resources */, + 8D576311048677EA00EA77CD /* Sources */, + 8D576313048677EA00EA77CD /* Frameworks */, + 842CCB3F0FA5F204008C7970 /* CopyFiles */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = JuceBrowserPluginDemo; + productInstallPath = "$(HOME)/Library/Bundles"; + productName = JuceBrowserPluginDemo; + productReference = 842CC9360FA5D51F008C7970 /* JuceBrowserPluginDemo.bundle */; + productType = "com.apple.product-type.bundle"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 089C1669FE841209C02AAC07 /* Project object */ = { + isa = PBXProject; + buildConfigurationList = 1DEB911E08733D790010E9CD /* Build configuration list for PBXProject "JuceBrowserPluginDemo" */; + compatibilityVersion = "Xcode 3.1"; + hasScannedForEncodings = 1; + mainGroup = 089C166AFE841209C02AAC07 /* JuceBrowserPluginDemo */; + productRefGroup = 842CC9370FA5D51F008C7970 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 8D57630D048677EA00EA77CD /* JuceBrowserPluginDemo */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 8D57630F048677EA00EA77CD /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 8D5B49A804867FD3000E48DA /* InfoPlist.strings in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXRezBuildPhase section */ + 842CC9580FA5D939008C7970 /* Rez */ = { + isa = PBXRezBuildPhase; + buildActionMask = 2147483647; + files = ( + 842CC94A0FA5D934008C7970 /* juce_NPAPI_MacResource.r in Rez */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXRezBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 8D576311048677EA00EA77CD /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 842CC42B0FA5BD3C008C7970 /* juce_NPAPI_GlueCode.mm in Sources */, + 842CC4320FA5BD57008C7970 /* JuceBrowserPluginDemo.cpp in Sources */, + 842CC4330FA5BD57008C7970 /* juce_LibrarySource.mm in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 8D5B49A704867FD3000E48DA /* InfoPlist.strings */ = { + isa = PBXVariantGroup; + children = ( + 089C167EFE841241C02AAC07 /* English */, + ); + name = InfoPlist.strings; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 1DEB911B08733D790010E9CD /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_MODEL_TUNING = G5; + GCC_OPTIMIZATION_LEVEL = 0; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(HOME)/Library/Bundles"; + PRODUCT_NAME = JuceBrowserPluginDemo; + WRAPPER_EXTENSION = plugin; + }; + name = Debug; + }; + 1DEB911C08733D790010E9CD /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_MODEL_TUNING = G5; + INFOPLIST_FILE = Info.plist; + INSTALL_PATH = "$(HOME)/Library/Bundles"; + PRODUCT_NAME = JuceBrowserPluginDemo; + WRAPPER_EXTENSION = bundle; + }; + name = Release; + }; + 1DEB911F08733D790010E9CD /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + ONLY_ACTIVE_ARCH = YES; + PREBINDING = NO; + SDKROOT = macosx10.5; + }; + name = Debug; + }; + 1DEB912008733D790010E9CD /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_BIT)"; + GCC_C_LANGUAGE_STANDARD = c99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + PREBINDING = NO; + SDKROOT = macosx10.5; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1DEB911A08733D790010E9CD /* Build configuration list for PBXNativeTarget "JuceBrowserPluginDemo" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1DEB911B08733D790010E9CD /* Debug */, + 1DEB911C08733D790010E9CD /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 1DEB911E08733D790010E9CD /* Build configuration list for PBXProject "JuceBrowserPluginDemo" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1DEB911F08733D790010E9CD /* Debug */, + 1DEB912008733D790010E9CD /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 089C1669FE841209C02AAC07 /* Project object */; +} diff --git a/extras/browser plugins/demo/build/npapi_win/JuceBrowserPluginDemo.sln b/extras/browser plugins/demo/build/npapi_win/JuceBrowserPluginDemo.sln new file mode 100644 index 0000000000..c05fe8a99e --- /dev/null +++ b/extras/browser plugins/demo/build/npapi_win/JuceBrowserPluginDemo.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual C++ Express 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "JuceBrowserPluginDemo", "JuceBrowserPluginDemo.vcproj", "{865C6463-5BC7-4F36-8667-FF9221C32797}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {865C6463-5BC7-4F36-8667-FF9221C32797}.Debug|Win32.ActiveCfg = Debug|Win32 + {865C6463-5BC7-4F36-8667-FF9221C32797}.Debug|Win32.Build.0 = Debug|Win32 + {865C6463-5BC7-4F36-8667-FF9221C32797}.Release|Win32.ActiveCfg = Release|Win32 + {865C6463-5BC7-4F36-8667-FF9221C32797}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/extras/browser plugins/demo/build/npapi_win/JuceBrowserPluginDemo.vcproj b/extras/browser plugins/demo/build/npapi_win/JuceBrowserPluginDemo.vcproj new file mode 100644 index 0000000000..80ab4ca13f --- /dev/null +++ b/extras/browser plugins/demo/build/npapi_win/JuceBrowserPluginDemo.vcproj @@ -0,0 +1,216 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/extras/browser plugins/demo/src/BrowserPluginCharacteristics.h b/extras/browser plugins/demo/src/BrowserPluginCharacteristics.h new file mode 100644 index 0000000000..1ef6f0399c --- /dev/null +++ b/extras/browser plugins/demo/src/BrowserPluginCharacteristics.h @@ -0,0 +1,37 @@ +/* + ============================================================================== + + This file contains values that describe your plugin's behaviour. + + ============================================================================== +*/ + + +//============================================================================== +#define JuceBrowserPlugin_Company "Raw Material Software Ltd" +#define JuceBrowserPlugin_Name "Juce Plugin Demo!" +#define JuceBrowserPlugin_Desc "Juce Browser Plugin Demo!" + +//============================================================================== +/** This should be the same version number, in different forms.. +*/ +#define JuceBrowserPlugin_Version "0.1" +#define JuceBrowserPlugin_WinVersion 0, 0, 1, 0 + +//============================================================================== +/** This is the mime-type of the plugin. + + In your HTML, this is the 'type' parameter of the embed tag, e.g. + + + + These two macros must be the same string, but the "raw" one shouldn't have quotes around it. +*/ +#define JuceBrowserPlugin_MimeType_Raw application/npjucedemo-plugin +#define JuceBrowserPlugin_MimeType "application/npjucedemo-plugin" + +//============================================================================== +/** Because plugins are associated with a file-type, this is the suffix of the file type the plugin + can open. If you don't need to use it, just use a made-up name here. +*/ +#define JuceBrowserPlugin_FileSuffix ".jucedemo" diff --git a/extras/browser plugins/demo/src/JuceBrowserPluginDemo.cpp b/extras/browser plugins/demo/src/JuceBrowserPluginDemo.cpp new file mode 100644 index 0000000000..8b128d97d3 --- /dev/null +++ b/extras/browser plugins/demo/src/JuceBrowserPluginDemo.cpp @@ -0,0 +1,152 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-7 by Raw Material Software ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the + GNU General Public License, as published by the Free Software Foundation; + either version 2 of the License, or (at your option) any later version. + + JUCE is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with JUCE; if not, visit www.gnu.org/licenses or write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA + + ------------------------------------------------------------------------------ + + If you'd like to release a closed-source product which uses JUCE, commercial + licenses are also available: visit www.rawmaterialsoftware.com/juce for + more information. + + ============================================================================== +*/ + +#include "../../wrapper/juce_BrowserPluginComponent.h" + + +//============================================================================== +/** + This is our top-level component for our plugin.. +*/ +class JuceDemoBrowserPlugin : public BrowserPluginComponent, + public ButtonListener +{ +public: + JuceDemoBrowserPlugin() + { + addAndMakeVisible (textBox = new TextEditor (String::empty)); + textBox->setMultiLine (true); + textBox->setBounds (8, 8, 300, 300); + + addAndMakeVisible (button = new TextButton ("Send a message to the webpage")); + button->setBounds (320, 8, 180, 22); + button->addButtonListener (this); + button->setEnabled (false); + + ourJavascriptObject = new DemoBrowserObject (this); + + textBox->setText ("Browser version info: " + getBrowserVersion()); + } + + ~JuceDemoBrowserPlugin() + { + deleteAllChildren(); + } + + const var getJavascriptObject() + { + // The browser calls this to get the javascript object that represents our plugin.. + return ourJavascriptObject; + } + + void paint (Graphics& g) + { + g.fillAll (Colours::lightblue); + } + + void setJavascriptObjectFromBrowser (var callbackObject) + { + javascriptObjectFromBrowser = callbackObject; + + button->setEnabled (javascriptObjectFromBrowser.isObject()); + } + + void buttonClicked (Button*) + { + javascriptObjectFromBrowser.call ("printmessage", "This is a message sent from the plugin..."); + } + + var ourJavascriptObject; + var javascriptObjectFromBrowser; + TextEditor* textBox; + TextButton* button; + + //============================================================================== + /** This is the javascript object that the browser uses when the webpage accesses + methods or properties on our plugin object. + */ + class DemoBrowserObject : public DynamicObject + { + public: + DemoBrowserObject (JuceDemoBrowserPlugin* owner_) + : owner (owner_) + { + // Add a couple of methods to our object.. + setMethod ("printText", (var::MethodFunction) &DemoBrowserObject::printText); + setMethod ("popUpMessageBox", (var::MethodFunction) &DemoBrowserObject::popUpMessageBox); + setMethod ("registerCallbackObject", (var::MethodFunction) &DemoBrowserObject::registerCallbackObject); + + // Add some value properties that the webpage can access + setProperty ("property1", "testing testing..."); + setProperty ("property2", 12345678.0); + } + + DemoBrowserObject() + { + } + + //============================================================================== + // These methods are called by javascript in the webpage... + const var printText (const var* params, int numParams) + { + if (numParams > 0) + owner->textBox->setText (owner->textBox->getText() + "\n" + params[0].toString()); + + return var(); + } + + const var popUpMessageBox (const var* params, int numParams) + { + if (numParams > 0) + AlertWindow::showMessageBox (AlertWindow::InfoIcon, + "A message from the webpage", + params[0].toString(), + String::empty, owner); + return var(); + } + + const var registerCallbackObject (const var* params, int numParams) + { + if (numParams > 0) + owner->setJavascriptObjectFromBrowser (params[0]); + + return var(); + } + + //============================================================================== + JuceDemoBrowserPlugin* owner; + }; +}; + +BrowserPluginComponent* JUCE_CALLTYPE createBrowserPlugin() +{ + return new JuceDemoBrowserPlugin(); +} diff --git a/extras/browser plugins/demo/src/juce_LibrarySource.cpp b/extras/browser plugins/demo/src/juce_LibrarySource.cpp new file mode 100644 index 0000000000..234af483cb --- /dev/null +++ b/extras/browser plugins/demo/src/juce_LibrarySource.cpp @@ -0,0 +1,11 @@ + +/* + This file includes the entire juce source tree via the amalgamated file. + + You could add the amalgamated file directly to your project, but doing it + like this allows you to put your app's config settings in the + juce_AppConfig.h file and have them applied to both the juce headers and + the source code. +*/ + +#include "../../../../juce_amalgamated.cpp" diff --git a/extras/browser plugins/demo/src/juce_LibrarySource.mm b/extras/browser plugins/demo/src/juce_LibrarySource.mm new file mode 100644 index 0000000000..e696df6c87 --- /dev/null +++ b/extras/browser plugins/demo/src/juce_LibrarySource.mm @@ -0,0 +1,11 @@ + +/* + This file includes the entire juce source tree via the amalgamated file. + + You could add the amalgamated file directly to your project, but doing it + like this allows you to put your app's config settings in the + juce_AppConfig.h file and have them applied to both the juce headers and + the source code. +*/ + +#include "../../../../juce_amalgamated.mm" diff --git a/extras/browser plugins/demo/test.html b/extras/browser plugins/demo/test.html new file mode 100644 index 0000000000..e652d7539a --- /dev/null +++ b/extras/browser plugins/demo/test.html @@ -0,0 +1,55 @@ +Juce Plugin Test + +
+ + + + + +
+
+ + + +
+ +
+ +
+ diff --git a/extras/browser plugins/wrapper/juce_BrowserPluginComponent.h b/extras/browser plugins/wrapper/juce_BrowserPluginComponent.h new file mode 100644 index 0000000000..ad6c238422 --- /dev/null +++ b/extras/browser plugins/wrapper/juce_BrowserPluginComponent.h @@ -0,0 +1,89 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-7 by Raw Material Software ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the + GNU General Public License, as published by the Free Software Foundation; + either version 2 of the License, or (at your option) any later version. + + JUCE is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with JUCE; if not, visit www.gnu.org/licenses or write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA + + ------------------------------------------------------------------------------ + + If you'd like to release a closed-source product which uses JUCE, commercial + licenses are also available: visit www.rawmaterialsoftware.com/juce for + more information. + + ============================================================================== +*/ + +#ifndef __JUCE_BROWSERPLUGINCOMP_H__ +#define __JUCE_BROWSERPLUGINCOMP_H__ + +#include "../../../../juce/juce_amalgamated.h" + + +//============================================================================== +/** + Base class for a browser plugin object. + + You need to implement a createBrowserPlugin() function that the host will call + when it needs a new instance of your BrowserPluginComponent subclass. The host will + delete the BrowserPluginComponent later when the user navigates away from the + page. +*/ +class BrowserPluginComponent : public Component +{ +public: + //============================================================================== + /** + Creates a browser plugin object. + @see createBrowserPlugin + */ + BrowserPluginComponent(); + + /** Destructor. */ + ~BrowserPluginComponent(); + + //============================================================================== + /** Returns a string describing the host browser version. + */ + const String getBrowserVersion() const; + + /** The plugin must implement this method to return a variant object whose + properties and methods can be accessed by javascript in the browser. + + If your plugin doesn't need to represent itself, you can just return + a void var() object here. + */ + virtual const var getJavascriptObject() = 0; + + //============================================================================== + juce_UseDebuggingNewOperator +}; + + +//============================================================================== +/** + This function must be implemented somewhere in your code to create the actual + plugin object that you want to use. + + Obviously multiple instances may be used simultaneously, so be VERY cautious + in your use of static variables! +*/ +BrowserPluginComponent* JUCE_CALLTYPE createBrowserPlugin(); + + +#endif diff --git a/extras/browser plugins/wrapper/juce_IncludeBrowserPluginInfo.h b/extras/browser plugins/wrapper/juce_IncludeBrowserPluginInfo.h new file mode 100644 index 0000000000..d5b89e9063 --- /dev/null +++ b/extras/browser plugins/wrapper/juce_IncludeBrowserPluginInfo.h @@ -0,0 +1,53 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-7 by Raw Material Software ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the + GNU General Public License, as published by the Free Software Foundation; + either version 2 of the License, or (at your option) any later version. + + JUCE is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with JUCE; if not, visit www.gnu.org/licenses or write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA + + ------------------------------------------------------------------------------ + + If you'd like to release a closed-source product which uses JUCE, commercial + licenses are also available: visit www.rawmaterialsoftware.com/juce for + more information. + + ============================================================================== +*/ + +#ifndef __JUCE_INCLUDE_BROWSER_PLUGIN_INFO_H__ +#define __JUCE_INCLUDE_BROWSER_PLUGIN_INFO_H__ + +#include "BrowserPluginCharacteristics.h" + + +//============================================================================== +// The following macros just cause a compile error if you've forgotten to +// define all your plugin settings properly. + +#if ! (defined (JuceBrowserPlugin_Name) \ + && defined (JuceBrowserPlugin_Desc) \ + && defined (JuceBrowserPlugin_Company) \ + && defined (JuceBrowserPlugin_MimeType) \ + && defined (JuceBrowserPlugin_MimeType_Raw) \ + && defined (JuceBrowserPlugin_FileSuffix) \ + && defined (JuceBrowserPlugin_Version) \ + && defined (JuceBrowserPlugin_WinVersion)) + #error "You haven't defined all the necessary JuceBrowserPlugin_xx values in your BrowserPluginCharacteristics.h file!" +#endif + +#endif diff --git a/extras/browser plugins/wrapper/juce_NPAPI_GlueCode.cpp b/extras/browser plugins/wrapper/juce_NPAPI_GlueCode.cpp new file mode 100644 index 0000000000..002fb3aea2 --- /dev/null +++ b/extras/browser plugins/wrapper/juce_NPAPI_GlueCode.cpp @@ -0,0 +1,1116 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-7 by Raw Material Software ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the + GNU General Public License, as published by the Free Software Foundation; + either version 2 of the License, or (at your option) any later version. + + JUCE is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with JUCE; if not, visit www.gnu.org/licenses or write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA + + ------------------------------------------------------------------------------ + + If you'd like to release a closed-source product which uses JUCE, commercial + licenses are also available: visit www.rawmaterialsoftware.com/juce for + more information. + + ============================================================================== +*/ + +//============================================================================== +/* + This file contains all the mess that creates an NPAPI interface, and connects + that interface to your BrowserPluginComponent object. + +*/ +//============================================================================== +#if defined (__APPLE__) && ! JUCE_NPAPI_WRAPPED_IN_MM + #error "On the Mac, you can't compile this .cpp file directly - use juce_NPAPI_GlueCode.mm instead" +#endif + +#define XPCOM_GLUE + +//============================================================================== +#if _MSC_VER + #define XP_WIN + #define _X86_ + #include + #include + #include "npapi.h" + #include "npupp.h" + #include "npruntime.h" + + // Cunning trick used to add functions to export list and avoid messing about with .def files. + // (can't add a declspec because the functions have already been pre-declared in the npapi headers). + #define EXPORTED_FUNCTION comment(linker, "/EXPORT:" __FUNCTION__ "=" __FUNCDNAME__) + +//============================================================================== +#elif defined (__APPLE__) + #define XP_MACOSX + #define OSCALL + #include + #include + #include + +//============================================================================== +#else + #define XP_UNIX + #include "npapi.h" + #include "npupp.h" + #include "npruntime.h" + +#endif + +//============================================================================== +#include "../../../juce_amalgamated.h" +#include "juce_BrowserPluginComponent.h" +#include "juce_IncludeBrowserPluginInfo.h" + +#if JUCE_MAC && JUCE_DEBUG && 0 +static void log (const String& s) +{ + FILE* f = fopen ("/Users/jules/Desktop/log.txt", "a+"); + fprintf (f, (const char*) s); + fprintf (f, "\n"); + fflush (f); + fclose (f); +} +#else +#define log(a) +#endif + +//============================================================================== +#if JUCE_MAC +static const String nsStringToJuce (NSString* s) { return String::fromUTF8 ((juce::uint8*) [s UTF8String]); } +static NSString* juceStringToNS (const String& s) { return [NSString stringWithUTF8String: (const char*) s.toUTF8()]; } + +#pragma export on +extern "C" +{ + NPError NP_Initialize (NPNetscapeFuncs*); + NPError NP_GetEntryPoints (NPPluginFuncs*); + NPError NP_Shutdown(); +} +#pragma export off +#endif + +//============================================================================== +static NPNetscapeFuncs browser; + +//============================================================================== +NPError NP_GetValue (void* future, NPPVariable variable, void* value) +{ + return NPP_GetValue ((NPP_t*) future, variable, value); +} + +#if JUCE_WIN32 || JUCE_MAC +NPError OSCALL NP_GetEntryPoints (NPPluginFuncs* funcs) +{ +#if JUCE_WIN32 + #pragma EXPORTED_FUNCTION +#endif + + log ("NP_GetEntryPoints"); + if (funcs == 0 || (funcs->size > 0 && funcs->size < sizeof (NPPluginFuncs))) + return NPERR_INVALID_FUNCTABLE_ERROR; + + funcs->size = sizeof (NPPluginFuncs); + funcs->version = (NP_VERSION_MAJOR << 8) | NP_VERSION_MINOR; + funcs->newp = NPP_New; + funcs->destroy = NPP_Destroy; + funcs->setwindow = NPP_SetWindow; + funcs->newstream = NPP_NewStream; + funcs->destroystream = NPP_DestroyStream; + funcs->asfile = NPP_StreamAsFile; + funcs->writeready = NPP_WriteReady; +#if JUCE_MAC + funcs->write = (NPP_WriteProcPtr) NPP_Write; +#else + funcs->write = NPP_Write; +#endif + funcs->print = NPP_Print; + funcs->event = NPP_HandleEvent; + funcs->urlnotify = NPP_URLNotify; + funcs->getvalue = NPP_GetValue; + funcs->setvalue = NPP_SetValue; + funcs->javaClass = 0; + + return NPERR_NO_ERROR; +} +#endif + +NPError OSCALL NP_Initialize (NPNetscapeFuncs* funcs + #ifdef XP_UNIX + , NPPluginFuncs* pluginFuncs + #endif + ) +{ +#if JUCE_WIN32 + #pragma EXPORTED_FUNCTION +#endif + + log ("NP_Initialize"); + if (funcs == 0) + return NPERR_INVALID_FUNCTABLE_ERROR; + + if (((funcs->version >> 8) & 0xff) > NP_VERSION_MAJOR) + return NPERR_INCOMPATIBLE_VERSION_ERROR; + + if (funcs->size < sizeof (NPNetscapeFuncs)) + return NPERR_INVALID_FUNCTABLE_ERROR; + + browser.size = funcs->size; + browser.version = funcs->version; + browser.geturlnotify = funcs->geturlnotify; + browser.geturl = funcs->geturl; + browser.posturlnotify = funcs->posturlnotify; + browser.posturl = funcs->posturl; + browser.requestread = funcs->requestread; + browser.newstream = funcs->newstream; + browser.write = funcs->write; + browser.destroystream = funcs->destroystream; + browser.status = funcs->status; + browser.uagent = funcs->uagent; + browser.memalloc = funcs->memalloc; + browser.memfree = funcs->memfree; + browser.memflush = funcs->memflush; + browser.reloadplugins = funcs->reloadplugins; + browser.getJavaEnv = funcs->getJavaEnv; + browser.getJavaPeer = funcs->getJavaPeer; + browser.getvalue = funcs->getvalue; + browser.setvalue = funcs->setvalue; + browser.invalidaterect = funcs->invalidaterect; + browser.invalidateregion = funcs->invalidateregion; + browser.forceredraw = funcs->forceredraw; + browser.getstringidentifier = funcs->getstringidentifier; + browser.getstringidentifiers = funcs->getstringidentifiers; + browser.getintidentifier = funcs->getintidentifier; + browser.identifierisstring = funcs->identifierisstring; + browser.utf8fromidentifier = funcs->utf8fromidentifier; + browser.intfromidentifier = funcs->intfromidentifier; + browser.createobject = funcs->createobject; + browser.retainobject = funcs->retainobject; + browser.releaseobject = funcs->releaseobject; + browser.invoke = funcs->invoke; + browser.invokeDefault = funcs->invokeDefault; + browser.evaluate = funcs->evaluate; + browser.getproperty = funcs->getproperty; + browser.setproperty = funcs->setproperty; + browser.removeproperty = funcs->removeproperty; + browser.hasproperty = funcs->hasproperty; + browser.hasmethod = funcs->hasmethod; + browser.releasevariantvalue = funcs->releasevariantvalue; + browser.setexception = funcs->setexception; + +#ifdef XP_UNIX + pluginFuncs->version = (NP_VERSION_MAJOR << 8) + NP_VERSION_MINOR; + pluginFuncs->size = sizeof (NPPluginFuncs); + pluginFuncs->newp = NewNPP_NewProc (NPP_New); + pluginFuncs->destroy = NewNPP_DestroyProc (NPP_Destroy); + pluginFuncs->setwindow = NewNPP_SetWindowProc (NPP_SetWindow); + pluginFuncs->newstream = NewNPP_NewStreamProc (NPP_NewStream); + pluginFuncs->destroystream = NewNPP_DestroyStreamProc (NPP_DestroyStream); + pluginFuncs->asfile = NewNPP_StreamAsFileProc (NPP_StreamAsFile); + pluginFuncs->writeready = NewNPP_WriteReadyProc (NPP_WriteReady); + pluginFuncs->write = NewNPP_WriteProc (NPP_Write); + pluginFuncs->print = NewNPP_PrintProc (NPP_Print); + pluginFuncs->urlnotify = NewNPP_URLNotifyProc (NPP_URLNotify); + pluginFuncs->event = 0; + pluginFuncs->getvalue = NewNPP_GetValueProc (NPP_GetValue); + #ifdef OJI + pluginFuncs->javaClass = NPP_GetJavaClass(); + #endif +#endif + + return NPERR_NO_ERROR; +} + +NPError OSCALL NP_Shutdown() +{ +#if JUCE_WIN32 + #pragma EXPORTED_FUNCTION +#endif + + log ("NP_Shutdown"); + return NPERR_NO_ERROR; +} + +char* NP_GetMIMEDescription() +{ + log ("NP_GetMIMEDescription"); + static String mimeDesc; + + mimeDesc = String (T(JuceBrowserPlugin_MimeType)) + + T(":") + String (T(JuceBrowserPlugin_FileSuffix)) + + T(":") + String (T(JuceBrowserPlugin_Name)); + + return (char*) (const char*) mimeDesc.toUTF8(); +} + +//============================================================================== +/* +NPError NPN_GetURLNotify (NPP instance, const char *url, const char *target, void* notifyData) +{ + return (browser.version & 0xFF) >= NPVERS_HAS_NOTIFICATION + ? browser.geturlnotify (instance, url, target, notifyData); + : NPERR_INCOMPATIBLE_VERSION_ERROR; +} + +NPError NPN_PostURLNotify (NPP instance, const char* url, const char* window, uint32 len, const char* buf, NPBool file, void* notifyData) +{ + return (browser.version & 0xFF) >= NPVERS_HAS_NOTIFICATION + ? browser.posturlnotify (instance, url, window, len, buf, file, notifyData) + : NPERR_INCOMPATIBLE_VERSION_ERROR; +} + +NPError NPN_NewStream (NPP instance, NPMIMEType type, const char* target, NPStream** stream) +{ + return (browser.version & 0xFF) >= NPVERS_HAS_STREAMOUTPUT + ? browser.newstream (instance, type, target, stream) + : NPERR_INCOMPATIBLE_VERSION_ERROR; +} + +int32 NPN_Write (NPP instance, NPStream *stream, int32 len, void *buffer) +{ + return (browser.version & 0xFF) >= NPVERS_HAS_STREAMOUTPUT + ? browser.write (instance, stream, len, buffer) + : -1; +} + +NPError NPN_DestroyStream (NPP instance, NPStream* stream, NPError reason) +{ + return (browser.version & 0xFF) >= NPVERS_HAS_STREAMOUTPUT + ? browser.destroystream (instance, stream, reason) + : NPERR_INCOMPATIBLE_VERSION_ERROR; +} +*/ + +//============================================================================== +class BrowserPluginHolderComponent : public Component +{ +public: + //============================================================================== + BrowserPluginHolderComponent (NPP npp_) + : npp (npp_), + child (0) + { + log ("BrowserPluginHolderComponent created"); +#if JUCE_WIN32 + parentHWND = 0; + oldWinProc = 0; +#else + currentParentView = 0; +#endif + setOpaque (true); + setWantsKeyboardFocus (false); + + addAndMakeVisible (child = createBrowserPlugin()); + jassert (child != 0); // You have to create one of these! + } + + ~BrowserPluginHolderComponent() + { + log ("BrowserPluginHolderComponent deleted"); + setWindow (0); + deleteAndZero (child); + } + + //============================================================================== + void paint (Graphics& g) + { + if (child == 0 || ! child->isOpaque()) + g.fillAll (Colours::white); + } + + void resized() + { + if (child != 0) + child->setBounds (0, 0, getWidth(), getHeight()); + } + + const var getObject() + { + return child->getJavascriptObject(); + } + + //============================================================================== + NPP npp; + BrowserPluginComponent* child; + +private: + + //============================================================================== +#if JUCE_WIN32 + HWND parentHWND; + WNDPROC oldWinProc; + + void resizeToParentWindow() + { + if (IsWindow (parentHWND)) + { + RECT r; + GetWindowRect (parentHWND, &r); + setBounds (0, 0, r.right - r.left, r.bottom - r.top); + } + } + + static LRESULT CALLBACK interceptingWinProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) + { + switch (msg) + { + case WM_PAINT: + { + PAINTSTRUCT ps; + HDC hdc = BeginPaint (hWnd, &ps); + EndPaint (hWnd, &ps); + } + return 0; + + case WM_ERASEBKGND: + return 1; + + case WM_WINDOWPOSCHANGING: + if ((((WINDOWPOS*) lParam)->flags & SWP_NOSIZE) == 0) + { + BrowserPluginHolderComponent* const comp = (BrowserPluginHolderComponent*) GetWindowLong (hWnd, GWL_USERDATA); + comp->resizeToParentWindow(); + } + break; + + default: + break; + } + + return DefWindowProc (hWnd, msg, wParam, lParam); + } + +public: + void setWindow (NPWindow* window) + { + HWND newHWND = (window != 0 ? ((HWND) window->window) : 0); + + if (parentHWND != newHWND) + { + removeFromDesktop(); + setVisible (false); + + if (IsWindow (parentHWND)) + { + SubclassWindow (parentHWND, oldWinProc); // restore the old winproc.. + oldWinProc = 0; + } + + parentHWND = newHWND; + + if (parentHWND != 0) + { + addToDesktop (0); + + HWND ourHWND = (HWND) getWindowHandle(); + SetParent (ourHWND, parentHWND); + + DWORD val = GetWindowLong (ourHWND, GWL_STYLE); + val = (val & ~WS_POPUP) | WS_CHILD; + SetWindowLong (ourHWND, GWL_STYLE, val); + + setVisible (true); + + oldWinProc = SubclassWindow (parentHWND, (WNDPROC) interceptingWinProc); + SetWindowLong (parentHWND, GWL_USERDATA, (LONG) this); + + resizeToParentWindow(); + } + } + } + + //============================================================================== +#else + NSView* currentParentView; + + NSView* findViewAt (NSView* parent, float x, float y) const + { + NSRect r = [parent frame]; + x -= r.origin.x; + y -= r.origin.y; + + if (x >= 0 && x < r.size.width && y >= 0 && y < r.size.height) + { + for (int i = [[parent subviews] count]; --i >= 0;) + { + NSView* v = (NSView*) [[parent subviews] objectAtIndex: i]; + + if (v != (NSView*) getWindowHandle()) + { + NSView* found = findViewAt (v, x, y); + + if (found != 0) + return found; + } + } + + return parent; + } + + return 0; + } + +public: + static bool isBrowserContentView (NSView* v) + { + return [[v className] isEqualToString: @"WebNetscapePluginDocumentView"] + || [[v className] isEqualToString: @"WebPluginDocumentView"] + || [[v className] isEqualToString: @"ChildView"]; + } + + void setWindow (NPWindow* window) + { + const ScopedAutoReleasePool pool; + + NSView* parentView = 0; + WindowRef windowRef = window != 0 ? ((NP_CGContext*) window->window)->window : 0; + + if (windowRef != 0) + { + NSWindow* win = [[[NSWindow alloc] initWithWindowRef: windowRef] autorelease]; + parentView = findViewAt ([win contentView], window->x + 0.5f, window->y + 0.5f); + + log (nsStringToJuce ([parentView description])); + + if (! isBrowserContentView (parentView)) + parentView = currentParentView; + } + + if (parentView != currentParentView) + { + //log ("new view: " + nsStringToJuce ([parentView description])); + + removeFromDesktop(); + setVisible (false); + + currentParentView = parentView; + + if (parentView != 0) + { + setSize (window->width, window->height); + addToDesktop (0, parentView); + setVisible (true); + } + } + + if (window != 0) + setSize (window->width, window->height); + } +#endif +}; + +//============================================================================== +static NPIdentifier getIdentifierFromString (const var::identifier& s) throw() +{ + return browser.getstringidentifier (s.name.toUTF8()); +} + +static const var createValueFromNPVariant (NPP npp, const NPVariant& v); +static void createNPVariantFromValue (NPP npp, NPVariant& out, const var& v); + +#if JUCE_DEBUG + static int numDOWNP = 0, numJuceSO = 0; +#endif + +//============================================================================== +class DynamicObjectWrappingNPObject : public DynamicObject +{ + NPP npp; + NPObject* const source; + +public: + DynamicObjectWrappingNPObject (NPP npp_, NPObject* const source_) + : npp (npp_), + source (browser.retainobject (source_)) + { + DBG ("num NP wrapper objs: " + String (++numDOWNP)); + } + + ~DynamicObjectWrappingNPObject() + { + browser.releaseobject (source); + DBG ("num NP wrapper objs: " + String (--numDOWNP)); + } + + const var getProperty (const var::identifier& propertyName) const + { + NPVariant result; + VOID_TO_NPVARIANT (result); + browser.getproperty (npp, source, getIdentifierFromString (propertyName), &result); + const var v (createValueFromNPVariant (npp, result)); + browser.releasevariantvalue (&result); + return v; + } + + bool hasProperty (const var::identifier& propertyName) const + { + NPVariant result; + VOID_TO_NPVARIANT (result); + const bool hasProp = browser.getproperty (npp, source, getIdentifierFromString (propertyName), &result); + browser.releasevariantvalue (&result); + return hasProp; + } + + void setProperty (const var::identifier& propertyName, const var& newValue) + { + NPVariant value; + createNPVariantFromValue (npp, value, newValue); + + browser.setproperty (npp, source, getIdentifierFromString (propertyName), &value); + browser.releasevariantvalue (&value); + } + + void removeProperty (const var::identifier& propertyName) + { + browser.removeproperty (npp, source, getIdentifierFromString (propertyName)); + } + + bool hasMethod (const var::identifier& methodName) const + { + return browser.hasmethod (npp, source, getIdentifierFromString (methodName)); + } + + const var invokeMethod (const var::identifier& methodName, + const var* parameters, + int numParameters) + { + var returnVal; + + NPVariant result; + VOID_TO_NPVARIANT (result); + + if (numParameters > 0) + { + NPVariant* params = (NPVariant*) juce_malloc (sizeof (NPVariant*) * numParameters); + + int i; + for (i = 0; i < numParameters; ++i) + createNPVariantFromValue (npp, params[i], parameters[i]); + + if (browser.invoke (npp, source, getIdentifierFromString (methodName), + params, numParameters, &result)) + { + returnVal = createValueFromNPVariant (npp, result); + browser.releasevariantvalue (&result); + } + + for (i = 0; i < numParameters; ++i) + browser.releasevariantvalue (¶ms[i]); + + juce_free (params); + } + else + { + if (browser.invoke (npp, source, getIdentifierFromString (methodName), 0, 0, &result)) + { + returnVal = createValueFromNPVariant (npp, result); + browser.releasevariantvalue (&result); + } + } + + return returnVal; + } +}; + +//============================================================================== +class NPObjectWrappingDynamicObject : public NPObject +{ +public: + static NPObject* create (NPP npp, const var& objectToWrap); + + virtual ~NPObjectWrappingDynamicObject() + { + DBG ("num Juce wrapper objs: " + String (--numJuceSO)); + } + +private: + NPObjectWrappingDynamicObject (NPP npp_) + : npp (npp_) + { + DBG ("num Juce wrapper objs: " + String (++numJuceSO)); + } + + //============================================================================== + bool construct (const NPVariant *args, uint32_t argCount, NPVariant *result); + void invalidate() {} + + bool hasMethod (NPIdentifier name) + { + DynamicObject* const o = object.getObject(); + return o != 0 && o->hasMethod (identifierToString (name)); + } + + bool invoke (NPIdentifier name, const NPVariant* args, uint32_t argCount, NPVariant* out) + { + DynamicObject* const o = object.getObject(); + const var::identifier methodName (identifierToString (name)); + + if (o == 0 || ! o->hasMethod (methodName)) + return false; + + var* params = (var*) juce_calloc (sizeof (var) * argCount); + for (uint32_t i = 0; i < argCount; ++i) + params[i] = createValueFromNPVariant (npp, args[i]); + + const var result (o->invokeMethod (methodName, params, argCount)); + + for (int i = argCount; --i >= 0;) + params[i] = var(); + + juce_free (params); + + if (out != 0) + createNPVariantFromValue (npp, *out, result); + + return true; + } + + bool invokeDefault (const NPVariant* args, uint32_t argCount, NPVariant* result) + { + return false; + } + + bool hasProperty (NPIdentifier name) + { + DynamicObject* const o = object.getObject(); + return o != 0 && o->hasProperty (identifierToString (name)); + } + + bool getProperty (NPIdentifier name, NPVariant* out) + { + DynamicObject* const o = object.getObject(); + const var::identifier propName (identifierToString (name)); + + if (o == 0 || ! o->hasProperty (propName)) + return false; + + const var result (o->getProperty (propName)); + + if (out != 0) + createNPVariantFromValue (npp, *out, result); + + return true; + } + + bool setProperty (NPIdentifier name, const NPVariant* value) + { + DynamicObject* const o = object.getObject(); + + if (value == 0 || o == 0) + return false; + + o->setProperty (identifierToString (name), createValueFromNPVariant (npp, *value)); + return true; + } + + bool removeProperty (NPIdentifier name) + { + DynamicObject* const o = object.getObject(); + const var::identifier propName (identifierToString (name)); + + if (o == 0 || ! o->hasProperty (propName)) + return false; + + o->removeProperty (propName); + return true; + } + + bool enumerate (NPIdentifier** identifier, uint32_t* count) + { + return false; + } + + //============================================================================== + NPP npp; + var object; + + static const var::identifier identifierToString (NPIdentifier id) + { + NPUTF8* const name = browser.utf8fromidentifier (id); + const var::identifier result ((const char*) name); + browser.memfree (name); + return result; + } + +public: + //============================================================================== + static NPObject* createInstance (NPP npp, NPClass* aClass) { return new NPObjectWrappingDynamicObject (npp); } + static void class_deallocate (NPObject* npobj) { delete (NPObjectWrappingDynamicObject*) npobj; } + static void class_invalidate (NPObject* npobj) { ((NPObjectWrappingDynamicObject*) npobj)->invalidate(); } + static bool class_hasMethod (NPObject* npobj, NPIdentifier name) { return ((NPObjectWrappingDynamicObject*) npobj)->hasMethod (name); } + static bool class_invoke (NPObject* npobj, NPIdentifier name, const NPVariant* args, uint32_t argCount, NPVariant* result) { return ((NPObjectWrappingDynamicObject*) npobj)->invoke (name, args, argCount, result); } + static bool class_invokeDefault (NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result) { return ((NPObjectWrappingDynamicObject*) npobj)->invokeDefault (args, argCount, result); } + static bool class_hasProperty (NPObject* npobj, NPIdentifier name) { return ((NPObjectWrappingDynamicObject*) npobj)->hasProperty (name); } + static bool class_getProperty (NPObject* npobj, NPIdentifier name, NPVariant* result) { return ((NPObjectWrappingDynamicObject*) npobj)->getProperty (name, result); } + static bool class_setProperty (NPObject* npobj, NPIdentifier name, const NPVariant* value) { return ((NPObjectWrappingDynamicObject*) npobj)->setProperty (name, value); } + static bool class_removeProperty (NPObject* npobj, NPIdentifier name) { return ((NPObjectWrappingDynamicObject*) npobj)->removeProperty (name); } + static bool class_enumerate (NPObject* npobj, NPIdentifier** identifier, uint32_t* count) { return ((NPObjectWrappingDynamicObject*) npobj)->enumerate (identifier, count); } + static bool class_construct (NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result) { return ((NPObjectWrappingDynamicObject*) npobj)->construct (args, argCount, result); } +}; + +static NPClass sNPObjectWrappingDynamicObject_NPClass = +{ + NP_CLASS_STRUCT_VERSION_ENUM, NPObjectWrappingDynamicObject::createInstance, + NPObjectWrappingDynamicObject::class_deallocate, NPObjectWrappingDynamicObject::class_invalidate, + NPObjectWrappingDynamicObject::class_hasMethod, NPObjectWrappingDynamicObject::class_invoke, + NPObjectWrappingDynamicObject::class_invokeDefault, NPObjectWrappingDynamicObject::class_hasProperty, + NPObjectWrappingDynamicObject::class_getProperty, NPObjectWrappingDynamicObject::class_setProperty, + NPObjectWrappingDynamicObject::class_removeProperty, NPObjectWrappingDynamicObject::class_enumerate +}; + +bool NPObjectWrappingDynamicObject::construct (const NPVariant* args, uint32_t argCount, NPVariant* result) +{ + NPObject* const newObj = browser.createobject (npp, &sNPObjectWrappingDynamicObject_NPClass); + + if (newObj == 0) + return false; + + OBJECT_TO_NPVARIANT (newObj, *result); + return true; +} + +NPObject* NPObjectWrappingDynamicObject::create (NPP npp, const var& objectToWrap) +{ + jassert (objectToWrap.getObject() != 0); + + NPObject* const nppObject = browser.createobject (npp, &sNPObjectWrappingDynamicObject_NPClass); + + if (nppObject != 0) + ((NPObjectWrappingDynamicObject*) nppObject)->object = objectToWrap; + + return nppObject; +} + + +//============================================================================== +static const var createValueFromNPVariant (NPP npp, const NPVariant& v) +{ + if (NPVARIANT_IS_BOOLEAN (v)) + return var (NPVARIANT_TO_BOOLEAN (v)); + else if (NPVARIANT_IS_INT32 (v)) + return var (NPVARIANT_TO_INT32 (v)); + else if (NPVARIANT_IS_DOUBLE (v)) + return var (NPVARIANT_TO_DOUBLE (v)); + else if (NPVARIANT_IS_STRING (v)) +#if JUCE_MAC + return var (String::fromUTF8 ((const juce::uint8*) (NPVARIANT_TO_STRING (v).UTF8Characters), + (int) NPVARIANT_TO_STRING (v).UTF8Length)); +#else + return var (String::fromUTF8 ((const juce::uint8*) (NPVARIANT_TO_STRING (v).utf8characters), + (int) NPVARIANT_TO_STRING (v).utf8length)); +#endif + else if (NPVARIANT_IS_OBJECT (v)) + return var (new DynamicObjectWrappingNPObject (npp, NPVARIANT_TO_OBJECT (v))); + + return var(); +} + +static void createNPVariantFromValue (NPP npp, NPVariant& out, const var& v) +{ + if (v.isInt()) + INT32_TO_NPVARIANT ((int) v, out); + else if (v.isBool()) + BOOLEAN_TO_NPVARIANT ((bool) v, out); + else if (v.isDouble()) + DOUBLE_TO_NPVARIANT ((double) v, out); + else if (v.isString()) +#if JUCE_MAC + STRINGZ_TO_NPVARIANT (strdup (v.toString().toUTF8()), out); +#else + STRINGZ_TO_NPVARIANT (_strdup (v.toString().toUTF8()), out); +#endif + else if (v.isObject()) + OBJECT_TO_NPVARIANT (NPObjectWrappingDynamicObject::create (npp, v), out); + else + VOID_TO_NPVARIANT (out); +} + +//============================================================================== +class JucePluginInstance +{ +public: + //============================================================================== + JucePluginInstance (NPP npp_) + : npp (npp_), + holderComp (0), + scriptObject (0) + { + } + + ~JucePluginInstance() + { + setWindow (0); + } + + bool setWindow (NPWindow* window) + { + if (window != 0) + { + if (holderComp == 0) + holderComp = new BrowserPluginHolderComponent (npp); + + holderComp->setWindow (window); + } + else + { + deleteAndZero (holderComp); + scriptObject = 0; + } + + return true; + } + + NPObject* getScriptableObject() + { + if (scriptObject == 0) + scriptObject = NPObjectWrappingDynamicObject::create (npp, holderComp->getObject()); + + if (scriptObject != 0 && shouldRetainBrowserObject()) + browser.retainobject (scriptObject); + + return scriptObject; + } + + //============================================================================== + NPP npp; + BrowserPluginHolderComponent* holderComp; + NPObject* scriptObject; + +private: + bool shouldRetainBrowserObject() const + { +#if JUCE_MAC + const String version (browser.uagent (npp)); + + if (! version.containsIgnoreCase (T(" AppleWebKit/"))) + return true; + + int versionNum = version.fromFirstOccurrenceOf (T(" AppleWebKit/"), false, true).getIntValue(); + + return versionNum == 0 || versionNum >= 420; +#else + return true; +#endif + } +}; + +//============================================================================== +static NPP currentlyInitialisingNPP = 0; +static int numPluginInstances = 0; + +NPError NPP_New (NPMIMEType pluginType, NPP npp, ::uint16 mode, ::int16 argc, char* argn[], char* argv[], NPSavedData* saved) +{ + log ("NPP_New"); + if (npp == 0) + return NPERR_INVALID_INSTANCE_ERROR; + +#if JUCE_MAC + browser.setvalue (npp, (NPPVariable) NPNVpluginDrawingModel, (void*) NPDrawingModelCoreGraphics); +#endif + + if (numPluginInstances++ == 0) + { + initialiseJuce_GUI(); + log ("initialiseJuce_GUI()"); + } + + currentlyInitialisingNPP = npp; + JucePluginInstance* p = new JucePluginInstance (npp); + currentlyInitialisingNPP = 0; + + npp->pdata = (void*) p; + return NPERR_NO_ERROR; +} + +NPError NPP_Destroy (NPP npp, NPSavedData** save) +{ + log ("NPP_Destroy"); + if (npp == 0) + return NPERR_INVALID_INSTANCE_ERROR; + + JucePluginInstance* const p = (JucePluginInstance*) npp->pdata; + + if (p != 0) + { + delete p; + + if (--numPluginInstances == 0) + { + shutdownJuce_GUI(); + log ("shutdownJuce_GUI()"); + } + } + + return NPERR_NO_ERROR; +} + +NPError NPP_SetWindow (NPP npp, NPWindow* pNPWindow) +{ + if (npp == 0) + return NPERR_INVALID_INSTANCE_ERROR; + + if (pNPWindow == 0) + return NPERR_GENERIC_ERROR; + + JucePluginInstance* const p = (JucePluginInstance*) npp->pdata; + + if (p == 0) + return NPERR_GENERIC_ERROR; + + currentlyInitialisingNPP = npp; + NPError result = p->setWindow (pNPWindow) ? NPERR_NO_ERROR + : NPERR_MODULE_LOAD_FAILED_ERROR; + currentlyInitialisingNPP = 0; + return result; +} + +//============================================================================== +NPError NPP_GetValue (NPP npp, NPPVariable variable, void* value) +{ + if (npp == 0) + return NPERR_INVALID_INSTANCE_ERROR; + + JucePluginInstance* const p = (JucePluginInstance*) npp->pdata; + + if (p == 0) + return NPERR_GENERIC_ERROR; + + switch (variable) + { + case NPPVpluginNameString: + *((char**) value) = JuceBrowserPlugin_Name; + break; + case NPPVpluginDescriptionString: + *((char**) value) = JuceBrowserPlugin_Desc; + break; + case NPPVpluginScriptableNPObject: + *((NPObject**) value) = p->getScriptableObject(); + break; + + default: + return NPERR_GENERIC_ERROR; + } + + return NPERR_NO_ERROR; +} + +NPError NPP_NewStream (NPP npp, + NPMIMEType type, + NPStream* stream, + NPBool seekable, + ::uint16* stype) +{ + if (npp == 0) + return NPERR_INVALID_INSTANCE_ERROR; + + return NPERR_NO_ERROR; +} + +::int32 NPP_WriteReady (NPP npp, NPStream *stream) +{ + if (npp == 0) + return NPERR_INVALID_INSTANCE_ERROR; + + return 0x0fffffff; +} + +::int32 NPP_Write (NPP npp, NPStream *stream, ::int32 offset, ::int32 len, void *buffer) +{ + if (npp == 0) + return NPERR_INVALID_INSTANCE_ERROR; + + return len; +} + +NPError NPP_DestroyStream (NPP npp, NPStream *stream, NPError reason) +{ + if (npp == 0) + return NPERR_INVALID_INSTANCE_ERROR; + + return NPERR_NO_ERROR; +} + +void NPP_StreamAsFile (NPP npp, NPStream* stream, const char* fname) +{ + if (npp == 0) + return; +} + +void NPP_Print (NPP npp, NPPrint* printInfo) +{ + if (npp == 0) + return; +} + +void NPP_URLNotify (NPP npp, const char* url, NPReason reason, void* notifyData) +{ + if (npp == 0) + return; +} + +NPError NPP_SetValue (NPP npp, NPNVariable variable, void* value) +{ + if (npp == 0) + return NPERR_INVALID_INSTANCE_ERROR; + + return NPERR_NO_ERROR; +} + +::int16 NPP_HandleEvent (NPP npp, void* ev) +{ + if (npp != 0) + { + //JucePluginInstance* const p = (JucePluginInstance*) npp->pdata; + } + + return 0; +} + + +//============================================================================== +static NPP getInstance (const BrowserPluginComponent* bpc) +{ + BrowserPluginHolderComponent* holder = dynamic_cast (bpc->getParentComponent()); + + if (holder != 0) + return holder->npp; + + return currentlyInitialisingNPP; +} + +//============================================================================== +BrowserPluginComponent::BrowserPluginComponent() +{ +} + +BrowserPluginComponent::~BrowserPluginComponent() +{ +} +const String BrowserPluginComponent::getBrowserVersion() const +{ + String s; + + if (getInstance (this) != 0) + s << browser.uagent (getInstance (this)); + else + s << "Netscape Plugin V" << (int) ((browser.version >> 8) & 0xff) + << "." << (int) (browser.version & 0xff); + + return s; +} diff --git a/extras/browser plugins/wrapper/juce_NPAPI_GlueCode.mm b/extras/browser plugins/wrapper/juce_NPAPI_GlueCode.mm new file mode 100644 index 0000000000..d46000cbd6 --- /dev/null +++ b/extras/browser plugins/wrapper/juce_NPAPI_GlueCode.mm @@ -0,0 +1,38 @@ +/* + ============================================================================== + + This file is part of the JUCE library - "Jules' Utility Class Extensions" + Copyright 2004-7 by Raw Material Software ltd. + + ------------------------------------------------------------------------------ + + JUCE can be redistributed and/or modified under the terms of the + GNU General Public License, as published by the Free Software Foundation; + either version 2 of the License, or (at your option) any later version. + + JUCE is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with JUCE; if not, visit www.gnu.org/licenses or write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA + + ------------------------------------------------------------------------------ + + If you'd like to release a closed-source product which uses JUCE, commercial + licenses are also available: visit www.rawmaterialsoftware.com/juce for + more information. + + ============================================================================== +*/ + +//============================================================================== +/** The only reason this file exists is to wrap the .cpp file inside a .mm file to + make the compiler treat it as obj-C. +*/ +#include +#define JUCE_NPAPI_WRAPPED_IN_MM 1 +#include "juce_NPAPI_GlueCode.cpp" diff --git a/extras/browser plugins/wrapper/juce_NPAPI_MacResource.r b/extras/browser plugins/wrapper/juce_NPAPI_MacResource.r new file mode 100644 index 0000000000..7f82fb53de --- /dev/null +++ b/extras/browser plugins/wrapper/juce_NPAPI_MacResource.r @@ -0,0 +1,16 @@ +#include +#include "BrowserPluginCharacteristics.h" + +resource 'STR#' (126) { { + JuceBrowserPlugin_Desc, + JuceBrowserPlugin_Name +} }; + +resource 'STR#' (127) { { + JuceBrowserPlugin_FileSuffix +} }; + +resource 'STR#' (128) { { + JuceBrowserPlugin_MimeType, + JuceBrowserPlugin_FileSuffix +} }; diff --git a/extras/browser plugins/wrapper/juce_NPAPI_WinResource.rc b/extras/browser plugins/wrapper/juce_NPAPI_WinResource.rc new file mode 100644 index 0000000000..8a6c65f422 --- /dev/null +++ b/extras/browser plugins/wrapper/juce_NPAPI_WinResource.rc @@ -0,0 +1,93 @@ + +#include "juce_IncludeBrowserPluginInfo.h" + +#define APSTUDIO_READONLY_SYMBOLS +#include "windows.h" +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +#ifndef _MAC +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION JuceBrowserPlugin_WinVersion + PRODUCTVERSION JuceBrowserPlugin_WinVersion + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904e4" + BEGIN + VALUE "Comments", "\0" + VALUE "CompanyName", JuceBrowserPlugin_Company "\0" + VALUE "FileDescription", JuceBrowserPlugin_Desc "\0" + VALUE "FileVersion", JuceBrowserPlugin_Version "\0" + VALUE "MIMEType", JuceBrowserPlugin_MimeType "\0" + VALUE "ProductName", JuceBrowserPlugin_Name "\0" + VALUE "ProductVersion", JuceBrowserPlugin_Version "\0" + VALUE "SpecialBuild", "\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1252 + END +END + +#endif // !_MAC + + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE DISCARDABLE +BEGIN + "#include ""windows.h""\r\n" + "\0" +END + +2 TEXTINCLUDE DISCARDABLE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED +