# Copyright (C) 2010 Apple Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1.  Redistributions of source code must retain the above copyright
#     notice, this list of conditions and the following disclaimer.
# 2.  Redistributions in binary form must reproduce the above copyright
#     notice, this list of conditions and the following disclaimer in the
#     documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#if ENABLE(NETSCAPE_PLUGIN_API)

messages -> PluginControllerProxy LegacyReceiver NotRefCounted {
    # Sent when the plug-in geometry changes.
    GeometryDidChange(WebCore::IntSize pluginSize, WebCore::IntRect clipRect, WebCore::AffineTransform pluginToRootViewTransform, float scaleFactor, WebKit::ShareableBitmap::Handle backingStoreHandle)

    # Sent when the plug-in visibility changes.
    VisibilityDidChange(bool isVisible)

    # Sent when a frame has finished loading.
    FrameDidFinishLoading(uint64_t requestID)

    # Sent when a frame dfailed to load.
    FrameDidFail(uint64_t requestID, bool wasCancelled)

    # Sent when JavaScript that the plug-in asked to be evaluated has been evaluated.
    DidEvaluateJavaScript(uint64_t requestID, String result)

    # Sent when the plug-in receives will send a request for a stream.
    StreamWillSendRequest(uint64_t streamID, String requestURLString, String redirectResponseURLString, uint32_t redirectResponseStatusCode)

    # Sent when the plug-in receives a response for a stream.
    StreamDidReceiveResponse(uint64_t streamID, String responseURLString, uint32_t streamLength, uint32_t lastModifiedTime, String mimeType, String headers)

    # Sent when the plug-in receives data for a stream.
    StreamDidReceiveData(uint64_t streamID, IPC::DataReference data)

    # Sent when a plug-in stream has finishes loading.
    StreamDidFinishLoading(uint64_t streamID)

    # Sent when a plug-in stream has failed to load.
    StreamDidFail(uint64_t streamID, bool wasCancelled)

    # Sent when the plug-in receives a response for the manual stream.
    ManualStreamDidReceiveResponse(String responseURLString, uint32_t streamLength, uint32_t lastModifiedTime, String mimeType, String headers)

    # Sent when the plug-in receives data for the manual stream.
    ManualStreamDidReceiveData(IPC::DataReference data)

    # Sent when the plug-in manual stream has finishes loading.
    ManualStreamDidFinishLoading()

    # Sent when the plug-in manual stream has failed to load.
    ManualStreamDidFail(bool wasCancelled)

    # Sent when a mouse event (that isn't a mouse enter/leave event or a wheel event) should be processed.
    HandleMouseEvent(WebKit::WebMouseEvent mouseEvent)
    
    # Sent when a mouse wheel event should be processed.
    HandleWheelEvent(WebKit::WebWheelEvent wheelEvent) -> (bool handled) Synchronous

    # Sent when a mouse enter event should be processed.
    HandleMouseEnterEvent(WebKit::WebMouseEvent mouseEvent) -> (bool handled) Synchronous
    
    # Sent when a mouse leave event should be processed.
    HandleMouseLeaveEvent(WebKit::WebMouseEvent mouseEvent) -> (bool handled) Synchronous

    # Sent when a keyboard should be processed.
    HandleKeyboardEvent(WebKit::WebKeyboardEvent keyboardEvent) -> (bool handled) Synchronous
    
    # Sent when an editing command should be processed.
    HandleEditingCommand(String commandName, String argument) -> (bool handled) Synchronous
    
    # Return whether or not a plugin wants to enable the given editing command.
    IsEditingCommandEnabled(String commandName) -> (bool enabled) Synchronous
    
    # Return whether or not a plugin wants to handle page scale factor itself.
    HandlesPageScaleFactor() -> (bool enabled) Synchronous

    # Return whether or not a plugin wants page scale, page zoom, and text zoom all to affect page scale.
    RequiresUnifiedScaleFactor() -> (bool required) Synchronous

    # Sent when the plug-in focus changes.
    SetFocus(bool isFocused)

    # Sent when the update requested by Update has been painted.
    DidUpdate()

    # Paint the entire plug-in.
    PaintEntirePlugin() -> () Synchronous

    # Get a reference to the plug-in's scriptable NPObject.
    GetPluginScriptableNPObject() -> (uint64_t pluginScriptableNPObjectID) Synchronous

    # Sent when the containing NSWindow's focus changes
    WindowFocusChanged(bool hasFocus)

    # Sent when the containing NSWindow's visibility changes
    WindowVisibilityChanged(bool isVisible)

#if PLATFORM(COCOA)
    # Send the complex text input to the plug-in.
    SendComplexTextInput(String textInput)

    # Sent when the containing NSWindow or NSView frame changes
    WindowAndViewFramesChanged(WebCore::IntRect windowFrameInScreenCoordinates, WebCore::IntRect viewFrameInWindowCoordinates)

    # Sent when the containing window's layer hosting mode changes
    SetLayerHostingMode(uint32_t layerHostingMode)
#endif

    # Does the plugin support snapshotting?
    SupportsSnapshotting() -> (bool isSupported) Synchronous

    # Return a snapshot of the plugin.
    Snapshot() -> (WebKit::ShareableBitmap::Handle backingStoreHandle) Synchronous

    # Sent when storage blocking policy changes
    StorageBlockingStateChanged(bool storageBlockingEnabled)

    # Sent when private browsing is enabled or disabled
    PrivateBrowsingStateChanged(bool isPrivateBrowsingEnabled)

    # Gets the string representating the form value of the plug-in
    GetFormValue() -> (bool returnValue, String formValue) Synchronous

    # Sent when the browser wants to mute or unmute the plugin.
    MutedStateChanged(bool muted)
}

#endif
