WebKit:
authorandersca@apple.com <andersca@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 12 May 2008 17:41:37 +0000 (17:41 +0000)
committerandersca@apple.com <andersca@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 12 May 2008 17:41:37 +0000 (17:41 +0000)
2008-05-09  Anders Carlsson  <andersca@apple.com>

        Reviewed by Oliver.

        <rdar://problem/5774495> Make Unicode text input possible in Netscape-style plug-ins

        Add nptextinput.h as a public header.

        * WebKit.xcodeproj/project.pbxproj:

WebKit/mac:

2008-05-12  Anders Carlsson  <andersca@apple.com>

        Reviewed by Oliver.

        <rdar://problem/5774495> Make Unicode text input possible in Netscape-style plug-ins

        * Plugins/WebBaseNetscapePluginView.h:
        * Plugins/WebBaseNetscapePluginView.mm:
        (-[WebBaseNetscapePluginView start]):
        Get the plug-in text input vtable pointer.

        (-[WebBaseNetscapePluginView stop]):
        Set the plug-in text input vtable pointer to 0.

        (-[WebBaseNetscapePluginView inputContext]):
        Return 0 for Carbon plug-ins since we don't want Cocoa to handle text input for them.

        (-[WebBaseNetscapePluginView hasMarkedText]):
        (-[WebBaseNetscapePluginView insertText:]):
        (-[WebBaseNetscapePluginView markedRange]):
        (-[WebBaseNetscapePluginView selectedRange]):
        (-[WebBaseNetscapePluginView setMarkedText:selectedRange:]):
        (-[WebBaseNetscapePluginView unmarkText]):
        (-[WebBaseNetscapePluginView validAttributesForMarkedText]):
        (-[WebBaseNetscapePluginView attributedSubstringFromRange:]):
        (-[WebBaseNetscapePluginView characterIndexForPoint:]):
        (-[WebBaseNetscapePluginView doCommandBySelector:]):
        (-[WebBaseNetscapePluginView firstRectForCharacterRange:]):
        (-[WebBaseNetscapePluginView conversationIdentifier]):
        Implement NSTextInput and call into the plug-in text input vtable.

        (browserTextInputFuncs):
        New method which returns the browser input vtable.

        (-[WebBaseNetscapePluginView getVariable:value:]):
        Support getting the browser input vtable pointer.

        * Plugins/WebNetscapePluginEventHandlerCocoa.h:
        * Plugins/WebNetscapePluginEventHandlerCocoa.mm:
        (WebNetscapePluginEventHandlerCocoa::keyDown):
        (WebNetscapePluginEventHandlerCocoa::sendKeyEvent):
        If the plug-in returns 0 when a NPCocoaEventKeyDown is passed to NPP_HandleEvent,
        it means that the event should be passed on to the input manager.

        * Plugins/npapi.mm:
        (NPN_MarkedTextAbandoned):
        (NPN_MarkedTextSelectionChanged):
        Add implementations of browser input method methods.

        * Plugins/nptextinput.h: Added.
        Add file with new text input API.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@33049 268f45cc-cd09-0410-ab3c-d52691b4dbfc

WebKit/ChangeLog
WebKit/WebKit.xcodeproj/project.pbxproj
WebKit/mac/ChangeLog
WebKit/mac/Plugins/WebBaseNetscapePluginView.h
WebKit/mac/Plugins/WebBaseNetscapePluginView.mm
WebKit/mac/Plugins/WebNetscapePluginEventHandlerCocoa.h
WebKit/mac/Plugins/WebNetscapePluginEventHandlerCocoa.mm
WebKit/mac/Plugins/npapi.mm
WebKit/mac/Plugins/nptextinput.h [new file with mode: 0644]

index 378c3a3..cbf4874 100644 (file)
@@ -1,3 +1,13 @@
+2008-05-09  Anders Carlsson  <andersca@apple.com>
+
+        Reviewed by Oliver.
+
+        <rdar://problem/5774495> Make Unicode text input possible in Netscape-style plug-ins
+        
+        Add nptextinput.h as a public header.
+        
+        * WebKit.xcodeproj/project.pbxproj:
+
 2008-05-06  Stephanie Lewis  <slewis@apple.com>
 
         Reviewed by Andersca.
index 5ecebc5..4f0bb98 100644 (file)
@@ -13,6 +13,7 @@
                06693DDD0BFBA85200216072 /* WebInspectorClient.mm in Sources */ = {isa = PBXBuildFile; fileRef = 06693DDB0BFBA85200216072 /* WebInspectorClient.mm */; };
                14D8252F0AF955090004F057 /* WebChromeClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 14D8252D0AF955090004F057 /* WebChromeClient.h */; };
                14D825300AF955090004F057 /* WebChromeClient.mm in Sources */ = {isa = PBXBuildFile; fileRef = 14D8252E0AF955090004F057 /* WebChromeClient.mm */; };
+               1A7F9C4C0DD3DDEA0028F8A5 /* nptextinput.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A7F9C4B0DD3DDEA0028F8A5 /* nptextinput.h */; settings = {ATTRIBUTES = (Public, ); }; };
                1AEA66D40DC6B1FF003D12BF /* WebNetscapePluginEventHandler.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AEA66D20DC6B1FF003D12BF /* WebNetscapePluginEventHandler.h */; };
                1AEA66D50DC6B1FF003D12BF /* WebNetscapePluginEventHandler.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1AEA66D30DC6B1FF003D12BF /* WebNetscapePluginEventHandler.mm */; };
                1AEA66D80DC6B209003D12BF /* WebNetscapePluginEventHandlerCarbon.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AEA66D60DC6B209003D12BF /* WebNetscapePluginEventHandlerCarbon.h */; };
                06693DDB0BFBA85200216072 /* WebInspectorClient.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebInspectorClient.mm; sourceTree = "<group>"; };
                14D8252D0AF955090004F057 /* WebChromeClient.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = WebChromeClient.h; sourceTree = "<group>"; };
                14D8252E0AF955090004F057 /* WebChromeClient.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; path = WebChromeClient.mm; sourceTree = "<group>"; };
+               1A7F9C4B0DD3DDEA0028F8A5 /* nptextinput.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = nptextinput.h; sourceTree = "<group>"; };
                1AEA66D20DC6B1FF003D12BF /* WebNetscapePluginEventHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebNetscapePluginEventHandler.h; sourceTree = "<group>"; };
                1AEA66D30DC6B1FF003D12BF /* WebNetscapePluginEventHandler.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebNetscapePluginEventHandler.mm; sourceTree = "<group>"; };
                1AEA66D60DC6B209003D12BF /* WebNetscapePluginEventHandlerCarbon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebNetscapePluginEventHandlerCarbon.h; sourceTree = "<group>"; };
                        isa = PBXGroup;
                        children = (
                                F5F717230288493C018635CA /* npapi.mm */,
+                               1A7F9C4B0DD3DDEA0028F8A5 /* nptextinput.h */,
                                F5A672B90263866E01000102 /* WebBaseNetscapePluginStream.h */,
                                F5A672BA0263866E01000102 /* WebBaseNetscapePluginStream.mm */,
                                F5EBC45502134BC301CA1520 /* WebBaseNetscapePluginView.h */,
                                1AEA66D40DC6B1FF003D12BF /* WebNetscapePluginEventHandler.h in Headers */,
                                1AEA66D80DC6B209003D12BF /* WebNetscapePluginEventHandlerCarbon.h in Headers */,
                                1AEA6A500DC8CE2F003D12BF /* WebNetscapePluginEventHandlerCocoa.h in Headers */,
+                               1A7F9C4C0DD3DDEA0028F8A5 /* nptextinput.h in Headers */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
index d2eb7f5..f6e08d7 100644 (file)
@@ -1,3 +1,55 @@
+2008-05-12  Anders Carlsson  <andersca@apple.com>
+
+        Reviewed by Oliver.
+
+        <rdar://problem/5774495> Make Unicode text input possible in Netscape-style plug-ins
+        
+        * Plugins/WebBaseNetscapePluginView.h:
+        * Plugins/WebBaseNetscapePluginView.mm:
+        (-[WebBaseNetscapePluginView start]):
+        Get the plug-in text input vtable pointer.
+        
+        (-[WebBaseNetscapePluginView stop]):
+        Set the plug-in text input vtable pointer to 0.
+        
+        (-[WebBaseNetscapePluginView inputContext]):
+        Return 0 for Carbon plug-ins since we don't want Cocoa to handle text input for them.
+        
+        (-[WebBaseNetscapePluginView hasMarkedText]):        
+        (-[WebBaseNetscapePluginView insertText:]):
+        (-[WebBaseNetscapePluginView markedRange]):
+        (-[WebBaseNetscapePluginView selectedRange]):
+        (-[WebBaseNetscapePluginView setMarkedText:selectedRange:]):
+        (-[WebBaseNetscapePluginView unmarkText]):
+        (-[WebBaseNetscapePluginView validAttributesForMarkedText]):
+        (-[WebBaseNetscapePluginView attributedSubstringFromRange:]):
+        (-[WebBaseNetscapePluginView characterIndexForPoint:]):
+        (-[WebBaseNetscapePluginView doCommandBySelector:]):
+        (-[WebBaseNetscapePluginView firstRectForCharacterRange:]):
+        (-[WebBaseNetscapePluginView conversationIdentifier]):
+        Implement NSTextInput and call into the plug-in text input vtable.
+        
+        (browserTextInputFuncs):
+        New method which returns the browser input vtable.
+        
+        (-[WebBaseNetscapePluginView getVariable:value:]):
+        Support getting the browser input vtable pointer.
+        
+        * Plugins/WebNetscapePluginEventHandlerCocoa.h:
+        * Plugins/WebNetscapePluginEventHandlerCocoa.mm:
+        (WebNetscapePluginEventHandlerCocoa::keyDown):
+        (WebNetscapePluginEventHandlerCocoa::sendKeyEvent):
+        If the plug-in returns 0 when a NPCocoaEventKeyDown is passed to NPP_HandleEvent,
+        it means that the event should be passed on to the input manager.
+         
+        * Plugins/npapi.mm:
+        (NPN_MarkedTextAbandoned):
+        (NPN_MarkedTextSelectionChanged):
+        Add implementations of browser input method methods.
+        
+        * Plugins/nptextinput.h: Added.
+        Add file with new text input API.
+
 2008-05-12  Alexey Proskuryakov  <ap@webkit.org>
 
         Roll out recent  threading changes (r32807, r32810, r32819, r32822) to simplify
index 8a7e83f..ae9279e 100644 (file)
@@ -55,7 +55,9 @@ typedef union PluginPort {
     NP_GLContext aglPort;
 } PluginPort;
 
-@interface WebBaseNetscapePluginView : NSView <WebPluginManualLoader>
+typedef struct _NPPluginTextInputFuncs NPPluginTextInputFuncs;
+
+@interface WebBaseNetscapePluginView : NSView <WebPluginManualLoader, NSTextInput>
 {
     WebNetscapePluginPackage *pluginPackage;
     
@@ -116,6 +118,8 @@ typedef union PluginPort {
     NSMutableArray *streams;
     NSMutableDictionary *pendingFrameLoads;
     
+    NPPluginTextInputFuncs *textInputFuncs;
+    
     NPP_NewProcPtr NPP_New;
     NPP_DestroyProcPtr NPP_Destroy;
     NPP_SetWindowProcPtr NPP_SetWindow;
index 7794b07..d63072a 100644 (file)
@@ -63,6 +63,7 @@
 #import <WebCore/Page.h> 
 #import <WebCore/SoftLinking.h> 
 #import <WebCore/WebCoreObjCExtras.h>
+#import <WebKit/nptextinput.h>
 #import <WebKit/DOMPrivate.h>
 #import <WebKit/WebUIDelegate.h>
 #import <objc/objc-runtime.h>
@@ -181,6 +182,11 @@ typedef struct {
     AGLContext oldContext;
 } PortState_GL;
 
+@class NSInputContext;
+@interface NSResponder (IMSecretsIKnowAbout)
+- (NSInputContext *)inputContext;
+@end
+
 @interface WebPluginRequest : NSObject
 {
     NSURLRequest *_request;
@@ -1233,6 +1239,18 @@ static inline void getNPRect(const NSRect& nr, NPRect& npr)
     // Create the event handler
     eventHandler = WebNetscapePluginEventHandler::create(self);
     
+    // Get the text input vtable
+    if (eventModel == NPEventModelCocoa) {
+        [self willCallPlugInFunction];
+        {
+            KJS::JSLock::DropAllLocks dropAllLocks;
+            NPPluginTextInputFuncs *value;
+            if (NPP_GetValue(plugin, NPPVpluginTextInputFuncs, &value) == NPERR_NO_ERROR && value)
+                textInputFuncs = value;
+        }
+        [self didCallPlugInFunction];
+    }
+    
     isStarted = YES;
         
     [self updateAndSetWindow];
@@ -1293,6 +1311,8 @@ static inline void getNPRect(const NSRect& nr, NPRect& npr)
     delete eventHandler;
     eventHandler = 0;
     
+    textInputFuncs = 0;
+    
     if (drawingModel == NPDrawingModelOpenGL)
         [self _destroyAGLContext];
 }
@@ -1850,6 +1870,160 @@ static inline void getNPRect(const NSRect& nr, NPRect& npr)
         [_manualStream finishedLoading];
 }
 
+#pragma mark NSTextInput implementation
+
+- (NSInputContext *)inputContext
+{
+#ifndef NP_NO_CARBON
+    if ([self isStarted] && eventModel == NPEventModelCarbon)
+        return nil;
+#endif
+        
+    return [super inputContext];
+}
+
+- (BOOL)hasMarkedText
+{
+    ASSERT(eventModel == NPEventModelCocoa);
+    ASSERT([self isStarted]);
+    
+    if (textInputFuncs && textInputFuncs->hasMarkedText)
+        return textInputFuncs->hasMarkedText(plugin);
+    
+    return NO;
+}
+
+- (void)insertText:(id)aString
+{
+    ASSERT(eventModel == NPEventModelCocoa);
+    ASSERT([self isStarted]);
+    
+    if (textInputFuncs && textInputFuncs->insertText)
+        textInputFuncs->insertText(plugin, aString);
+}
+
+- (NSRange)markedRange
+{
+    ASSERT(eventModel == NPEventModelCocoa);
+    ASSERT([self isStarted]);
+
+    if (textInputFuncs && textInputFuncs->markedRange)
+        return textInputFuncs->markedRange(plugin);
+    
+    return NSMakeRange(NSNotFound, 0);
+}
+
+- (NSRange)selectedRange
+{
+    ASSERT(eventModel == NPEventModelCocoa);
+    ASSERT([self isStarted]);
+
+    if (textInputFuncs && textInputFuncs->selectedRange)
+        return textInputFuncs->selectedRange(plugin);
+
+    return NSMakeRange(NSNotFound, 0);
+}    
+
+- (void)setMarkedText:(id)aString selectedRange:(NSRange)selRange
+{
+    ASSERT(eventModel == NPEventModelCocoa);
+    ASSERT([self isStarted]);
+
+    if (textInputFuncs && textInputFuncs->setMarkedText)
+        textInputFuncs->setMarkedText(plugin, aString, selRange);
+}
+
+- (void)unmarkText
+{
+    ASSERT(eventModel == NPEventModelCocoa);
+    ASSERT([self isStarted]);
+    
+    if (textInputFuncs && textInputFuncs->unmarkText)
+        textInputFuncs->unmarkText(plugin);
+}
+
+- (NSArray *)validAttributesForMarkedText
+{
+    ASSERT(eventModel == NPEventModelCocoa);
+    ASSERT([self isStarted]);
+        
+    if (textInputFuncs && textInputFuncs->validAttributesForMarkedText)
+        return textInputFuncs->validAttributesForMarkedText(plugin);
+    
+    return [NSArray array];
+}
+
+- (NSAttributedString *)attributedSubstringFromRange:(NSRange)theRange
+{
+    ASSERT(eventModel == NPEventModelCocoa);
+    ASSERT([self isStarted]);
+    
+    if (textInputFuncs && textInputFuncs->attributedSubstringFromRange)
+        return textInputFuncs->attributedSubstringFromRange(plugin, theRange);
+
+    return nil;
+}
+
+- (NSUInteger)characterIndexForPoint:(NSPoint)thePoint
+{
+    ASSERT(eventModel == NPEventModelCocoa);
+    ASSERT([self isStarted]);
+
+    if (textInputFuncs && textInputFuncs->characterIndexForPoint) {
+        // Convert the point to window coordinates
+        NSPoint point = [[self window] convertScreenToBase:thePoint];
+        
+        // And view coordinates
+        point = [self convertPoint:point fromView:nil];
+        
+        return textInputFuncs->characterIndexForPoint(plugin, point);
+    }        
+
+    return NSNotFound;
+}
+
+- (void)doCommandBySelector:(SEL)aSelector
+{
+    ASSERT(eventModel == NPEventModelCocoa);
+    ASSERT([self isStarted]);
+
+    if (textInputFuncs && textInputFuncs->doCommandBySelector)
+        textInputFuncs->doCommandBySelector(plugin, aSelector);
+}
+
+- (NSRect)firstRectForCharacterRange:(NSRange)theRange
+{
+    ASSERT(eventModel == NPEventModelCocoa);
+    ASSERT([self isStarted]);
+
+    if (textInputFuncs && textInputFuncs->firstRectForCharacterRange) {
+        NSRect rect = textInputFuncs->firstRectForCharacterRange(plugin, theRange);
+        
+        // Convert the rect to window coordinates
+        rect = [self convertRect:rect toView:nil];
+        
+        // Convert the rect location to screen coordinates
+        rect.origin = [[self window] convertBaseToScreen:rect.origin];
+        
+        return rect;
+    }
+
+    return NSZeroRect;
+}
+
+// test for 10.4 because of <rdar://problem/4243463>
+#ifdef BUILDING_ON_TIGER
+- (long)conversationIdentifier
+{
+    return (long)self;
+}
+#else
+- (NSInteger)conversationIdentifier
+{
+    return (NSInteger)self;
+}
+#endif
+
 @end
 
 @implementation WebBaseNetscapePluginView (WebNPPCallbacks)
@@ -2311,6 +2485,18 @@ static inline void getNPRect(const NSRect& nr, NPRect& npr)
     [[self window] displayIfNeeded];
 }
 
+static NPBrowserTextInputFuncs *browserTextInputFuncs()
+{
+    static NPBrowserTextInputFuncs inputFuncs = {
+        0,
+        sizeof(NPBrowserTextInputFuncs),
+        NPN_MarkedTextAbandoned,
+        NPN_MarkedTextSelectionChanged
+    };
+    
+    return &inputFuncs;
+}
+
 - (NPError)getVariable:(NPNVariable)variable value:(void *)value
 {
     switch (variable) {
@@ -2392,6 +2578,13 @@ static inline void getNPRect(const NSRect& nr, NPRect& npr)
             return NPERR_NO_ERROR;
         }
             
+        case NPNVbrowserTextInputFuncs:
+        {
+            if (eventModel == NPEventModelCocoa) {
+                *(NPBrowserTextInputFuncs **)value = browserTextInputFuncs();
+                return NPERR_NO_ERROR;
+            }
+        }
         default:
             break;
     }
index 43b0c5b..e22ff3d 100644 (file)
@@ -55,7 +55,7 @@ public:
     virtual void* platformWindow(NSWindow*);
 private:
     bool sendMouseEvent(NSEvent*, NPCocoaEventType);
-    void sendKeyEvent(NSEvent*, NPCocoaEventType);
+    bool sendKeyEvent(NSEvent*, NPCocoaEventType);
     bool sendEvent(NPCocoaEvent*);
 };
 
index 47c5b40..f952f6b 100644 (file)
@@ -109,7 +109,11 @@ bool WebNetscapePluginEventHandlerCocoa::sendMouseEvent(NSEvent *nsEvent, NPCoco
 
 void WebNetscapePluginEventHandlerCocoa::keyDown(NSEvent *event)
 {
-    sendKeyEvent(event, NPCocoaEventKeyDown);
+    bool retval = sendKeyEvent(event, NPCocoaEventKeyDown);
+    
+    // If the plug-in did not handle the event, pass it on to the Input Manager.
+    if (!retval)
+        [m_pluginView interpretKeyEvents:[NSArray arrayWithObject:event]];
 }
 
 void WebNetscapePluginEventHandlerCocoa::keyUp(NSEvent *event)
@@ -131,7 +135,7 @@ void WebNetscapePluginEventHandlerCocoa::flagsChanged(NSEvent *nsEvent)
     sendEvent(&event);
 }
 
-void WebNetscapePluginEventHandlerCocoa::sendKeyEvent(NSEvent* nsEvent, NPCocoaEventType type)
+bool WebNetscapePluginEventHandlerCocoa::sendKeyEvent(NSEvent* nsEvent, NPCocoaEventType type)
 {
     NPCocoaEvent event;
         
@@ -142,7 +146,7 @@ void WebNetscapePluginEventHandlerCocoa::sendKeyEvent(NSEvent* nsEvent, NPCocoaE
     event.event.key.characters = (NPNSString *)[nsEvent characters];
     event.event.key.charactersIgnoringModifiers = (NPNSString *)[nsEvent charactersIgnoringModifiers];
      
-    sendEvent(&event);
+    return sendEvent(&event);
 }
 
 void WebNetscapePluginEventHandlerCocoa::windowFocusChanged(bool hasFocus)
index 5751cef..5573698 100644 (file)
@@ -28,6 +28,7 @@
 
 #if ENABLE(NETSCAPE_PLUGIN_API)
 #import <WebKit/npapi.h>
+#import <WebKit/nptextinput.h>
 
 #import <WebKit/WebBaseNetscapePluginViewPrivate.h>
 #import <WebKit/WebKitLogging.h>
@@ -185,4 +186,18 @@ NPError NPN_PopUpContextMenu(NPP instance, NPMenu *menu)
     return [pluginViewForInstance(instance) popUpContextMenu:menu];
 }
 
+void NPN_MarkedTextAbandoned(NPP instance)
+{
+    WebBaseNetscapePluginView *pluginView = pluginViewForInstance(instance);
+    
+    [[NSInputManager currentInputManager] markedTextAbandoned:pluginView];
+}
+
+void NPN_MarkedTextSelectionChanged(NPP instance, NSRange newSel)
+{
+    WebBaseNetscapePluginView *pluginView = pluginViewForInstance(instance);
+    
+    [[NSInputManager currentInputManager] markedTextSelectionChanged:newSel client:pluginView];
+}
+
 #endif
diff --git a/WebKit/mac/Plugins/nptextinput.h b/WebKit/mac/Plugins/nptextinput.h
new file mode 100644 (file)
index 0000000..f9bba4b
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2008, Apple Inc. and The Mozilla Foundation. 
+ * 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.
+ * 3. Neither the names of Apple Inc. ("Apple") or The Mozilla
+ * Foundation ("Mozilla") nor the names of their contributors may be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY APPLE, MOZILLA AND THEIR 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, MOZILLA OR
+ * THEIR 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.
+ *
+ */
+
+
+#ifndef __OBJC__
+#error "npinput.h can only be included from Objective-C code."
+#endif
+
+#ifndef _NP_TEXTINPUT_H_
+#define _NP_TEXTINPUT_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <WebKit/npapi.h>
+
+#import <Cocoa/Cocoa.h>
+
+typedef void (*NPP_InsertTextFunc)(NPP npp, id aString);
+typedef void (*NPP_DoCommandBySelectorFunc)(NPP npp, SEL aSelector);
+typedef void (*NPP_SetMarkedTextFunc)(NPP npp, id aString, NSRange selRange);
+typedef void (*NPP_UnmarkTextFunc)(NPP npp);
+typedef BOOL (*NPP_HasMarkedTextFunc)(NPP npp);
+typedef NSAttributedString * (*NPP_AttributedSubstringFromRangeFunc)(NPP npp, NSRange theRange);
+typedef NSRange (*NPP_MarkedRangeFunc)(NPP npp);
+typedef NSRange (*NPP_SelectedRangeFunc)(NPP npp);
+typedef NSRect (*NPP_FirstRectForCharacterRangeFunc)(NPP npp, NSRange theRange);
+typedef unsigned long long (*NPP_CharacterIndexForPointFunc)(NPP npp, NSPoint thePoint);
+typedef NSArray *(*NPP_ValidAttributesForMarkedTextFunc)(NPP npp);
+
+typedef struct _NPPluginTextInputFuncs {
+    uint16 size;
+    uint16 version;
+    
+    NPP_InsertTextFunc insertText;
+    NPP_DoCommandBySelectorFunc doCommandBySelector;
+    NPP_SetMarkedTextFunc setMarkedText;
+    NPP_UnmarkTextFunc unmarkText;
+    NPP_HasMarkedTextFunc hasMarkedText;
+    NPP_AttributedSubstringFromRangeFunc attributedSubstringFromRange;
+    NPP_MarkedRangeFunc markedRange;
+    NPP_SelectedRangeFunc selectedRange;
+    NPP_FirstRectForCharacterRangeFunc firstRectForCharacterRange;
+    NPP_CharacterIndexForPointFunc characterIndexForPoint;
+    NPP_ValidAttributesForMarkedTextFunc validAttributesForMarkedText;
+} NPPluginTextInputFuncs;
+
+void NPP_InsertText(NPP npp, id aString);
+void NPP_DoCommandBySelector(NPP npp, SEL aSelector);
+void NPP_SetMarkedText(NPP npp, id aString, NSRange selRange);
+void NPP_UnmarkText(NPP npp);
+BOOL NPP_HasMarkedText(NPP npp);
+NSAttributedString *NPP_AttributedSubstringFromRange(NPP npp, NSRange theRange);
+NSRange NPP_MarkedRange(NPP npp);
+NSRange NPP_SelectedRange(NPP npp);
+NSRect NPP_FirstRectForCharacterRange(NPP npp, NSRange theRange);
+unsigned long long NPP_CharacterIndexForPoint(NPP npp, NSPoint thePoint);
+NSArray NPP_ValidAttributesForMarkedText(NPP npp);
+
+typedef void (*NPN_MarkedTextAbandonedFunc)(NPP npp);
+typedef void (*NPN_MarkedTextSelectionChangedFunc)(NPP npp, NSRange newSel);
+
+typedef struct _NPBrowserTextInputFuncs {
+    uint16 size;
+    uint16 version;
+    
+    NPN_MarkedTextAbandonedFunc markedTextAbandoned;
+    NPN_MarkedTextSelectionChangedFunc markedTextSelectionChanged;
+} NPBrowserTextInputFuncs;
+
+void NPN_MarkedTextAbandoned(NPP npp);
+void NPN_MarkedTextSelectionChanged(NPP npp, NSRange newSel);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif