2 IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc. ("Apple") in
3 consideration of your agreement to the following terms, and your use, installation,
4 modification or redistribution of this Apple software constitutes acceptance of these
5 terms. If you do not agree with these terms, please do not use, install, modify or
6 redistribute this Apple software.
8 In consideration of your agreement to abide by the following terms, and subject to these
9 terms, Apple grants you a personal, non-exclusive license, under Appleās copyrights in
10 this original Apple software (the "Apple Software"), to use, reproduce, modify and
11 redistribute the Apple Software, with or without modifications, in source and/or binary
12 forms; provided that if you redistribute the Apple Software in its entirety and without
13 modifications, you must retain this notice and the following text and disclaimers in all
14 such redistributions of the Apple Software. Neither the name, trademarks, service marks
15 or logos of Apple Computer, Inc. may be used to endorse or promote products derived from
16 the Apple Software without specific prior written permission from Apple. Except as expressly
17 stated in this notice, no other rights or licenses, express or implied, are granted by Apple
18 herein, including but not limited to any patent rights that may be infringed by your
19 derivative works or by other works in which the Apple Software may be incorporated.
21 The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO WARRANTIES,
22 EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT,
23 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS
24 USE AND OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.
26 IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR CONSEQUENTIAL
27 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
28 OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE,
29 REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND
30 WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR
31 OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 #import <WebKit/npapi.h>
35 #import <WebKit/npfunctions.h>
36 #import <WebKit/npruntime.h>
38 #import <Cocoa/Cocoa.h>
40 // Browser function table
41 static NPNetscapeFuncs* browser;
43 // Structure for per-instance storage
44 typedef struct PluginObject
52 bool textFieldHasFocus;
55 NSRange selectedRange;
56 NSTextStorage *textStorage;
57 NSLayoutManager *layoutManager;
58 NSTextContainer *textContainer;
62 NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc, char* argn[], char* argv[], NPSavedData* saved);
63 NPError NPP_Destroy(NPP instance, NPSavedData** save);
64 NPError NPP_SetWindow(NPP instance, NPWindow* window);
65 NPError NPP_NewStream(NPP instance, NPMIMEType type, NPStream* stream, NPBool seekable, uint16* stype);
66 NPError NPP_DestroyStream(NPP instance, NPStream* stream, NPReason reason);
67 int32 NPP_WriteReady(NPP instance, NPStream* stream);
68 int32 NPP_Write(NPP instance, NPStream* stream, int32 offset, int32 len, void* buffer);
69 void NPP_StreamAsFile(NPP instance, NPStream* stream, const char* fname);
70 void NPP_Print(NPP instance, NPPrint* platformPrint);
71 int16 NPP_HandleEvent(NPP instance, void* event);
72 void NPP_URLNotify(NPP instance, const char* URL, NPReason reason, void* notifyData);
73 NPError NPP_GetValue(NPP instance, NPPVariable variable, void* value);
74 NPError NPP_SetValue(NPP instance, NPNVariable variable, void* value);
77 // Mach-o entry points
78 NPError NP_Initialize(NPNetscapeFuncs* browserFuncs);
79 NPError NP_GetEntryPoints(NPPluginFuncs* pluginFuncs);
80 void NP_Shutdown(void);
83 NPError NP_Initialize(NPNetscapeFuncs* browserFuncs)
85 browser = browserFuncs;
86 return NPERR_NO_ERROR;
89 NPError NP_GetEntryPoints(NPPluginFuncs* pluginFuncs)
91 pluginFuncs->version = 11;
92 pluginFuncs->size = sizeof(pluginFuncs);
93 pluginFuncs->newp = NPP_New;
94 pluginFuncs->destroy = NPP_Destroy;
95 pluginFuncs->setwindow = NPP_SetWindow;
96 pluginFuncs->newstream = NPP_NewStream;
97 pluginFuncs->destroystream = NPP_DestroyStream;
98 pluginFuncs->asfile = NPP_StreamAsFile;
99 pluginFuncs->writeready = NPP_WriteReady;
100 pluginFuncs->write = (NPP_WriteProcPtr)NPP_Write;
101 pluginFuncs->print = NPP_Print;
102 pluginFuncs->event = NPP_HandleEvent;
103 pluginFuncs->urlnotify = NPP_URLNotify;
104 pluginFuncs->getvalue = NPP_GetValue;
105 pluginFuncs->setvalue = NPP_SetValue;
107 return NPERR_NO_ERROR;
110 void NP_Shutdown(void)
114 NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc, char* argn[], char* argv[], NPSavedData* saved)
116 // Create per-instance storage
117 PluginObject* obj = (PluginObject*)malloc(sizeof(PluginObject));
118 bzero(obj, sizeof(PluginObject));
121 instance->pdata = obj;
123 // Ask the browser if it supports the CoreGraphics drawing model
124 NPBool supportsCoreGraphics;
125 if (browser->getvalue(instance, NPNVsupportsCoreGraphicsBool, &supportsCoreGraphics) != NPERR_NO_ERROR)
126 supportsCoreGraphics = FALSE;
128 if (!supportsCoreGraphics)
129 return NPERR_INCOMPATIBLE_VERSION_ERROR;
131 // If the browser supports the CoreGraphics drawing model, enable it.
132 browser->setvalue(instance, NPPVpluginDrawingModel, (void*)NPDrawingModelCoreGraphics);
134 // If the browser supports the Cocoa event model, enable it.
135 NPBool supportsCocoa;
136 if (browser->getvalue(instance, NPNVsupportsCocoaBool, &supportsCocoa) != NPERR_NO_ERROR)
137 supportsCocoa = FALSE;
140 return NPERR_INCOMPATIBLE_VERSION_ERROR;
142 browser->setvalue(instance, NPPVpluginEventModel, (void*)NPEventModelCocoa);
144 obj->textFieldRect = NSMakeRect(10, 10, 200, 100);
146 obj->textStorage = [[NSTextStorage alloc] initWithString:@""];
147 obj->layoutManager = [[NSLayoutManager alloc] init];
148 [obj->textStorage addLayoutManager:obj->layoutManager];
150 obj->textContainer = [[NSTextContainer alloc] initWithContainerSize:obj->textFieldRect.size];
151 [obj->layoutManager addTextContainer:obj->textContainer];
153 obj->selectedRange.location = [obj->textStorage length];
155 return NPERR_NO_ERROR;
158 NPError NPP_Destroy(NPP instance, NPSavedData** save)
160 // Free per-instance storage
161 PluginObject* obj = instance->pdata;
163 [obj->textStorage release];
164 [obj->layoutManager release];
168 return NPERR_NO_ERROR;
171 NPError NPP_SetWindow(NPP instance, NPWindow* window)
173 PluginObject* obj = instance->pdata;
174 obj->window = *window;
176 return NPERR_NO_ERROR;
180 NPError NPP_NewStream(NPP instance, NPMIMEType type, NPStream* stream, NPBool seekable, uint16* stype)
182 *stype = NP_ASFILEONLY;
183 return NPERR_NO_ERROR;
186 NPError NPP_DestroyStream(NPP instance, NPStream* stream, NPReason reason)
188 return NPERR_NO_ERROR;
191 int32 NPP_WriteReady(NPP instance, NPStream* stream)
196 int32 NPP_Write(NPP instance, NPStream* stream, int32 offset, int32 len, void* buffer)
201 void NPP_StreamAsFile(NPP instance, NPStream* stream, const char* fname)
205 void NPP_Print(NPP instance, NPPrint* platformPrint)
210 static void handleDraw(PluginObject* obj, NPCocoaEvent *event)
212 NSGraphicsContext *oldContext = [[NSGraphicsContext currentContext] retain];
214 NSGraphicsContext *context = [NSGraphicsContext graphicsContextWithGraphicsPort:event->data.draw.context
218 [NSGraphicsContext setCurrentContext:context];
220 NSRect rect = NSMakeRect(0, 0, obj->window.width, obj->window.height);
222 [[NSColor lightGrayColor] set];
223 [NSBezierPath fillRect:rect];
225 if (obj->pluginHasFocus) {
226 [[NSColor blackColor] set];
227 [NSBezierPath strokeRect:rect];
230 [[NSColor whiteColor] set];
231 [NSBezierPath fillRect:obj->textFieldRect];
234 NSRange glyphRange = [obj->layoutManager glyphRangeForTextContainer:obj->textContainer];
235 if (glyphRange.length > 0) {
236 [obj->layoutManager drawBackgroundForGlyphRange:glyphRange atPoint:obj->textFieldRect.origin];
237 [obj->layoutManager drawGlyphsForGlyphRange:glyphRange atPoint:obj->textFieldRect.origin];
240 NSBezierPath *textInputBorder = [NSBezierPath bezierPathWithRect:obj->textFieldRect];
241 [[NSColor blackColor] set];
243 if (obj->pluginHasFocus && obj->textFieldHasFocus)
244 [textInputBorder setLineWidth:2];
246 [textInputBorder setLineWidth:1];
248 [textInputBorder stroke];
250 if (obj->pluginHasFocus && obj->textFieldHasFocus) {
251 NSUInteger rectCount;
252 NSRect *rectArray = [obj->layoutManager rectArrayForCharacterRange:obj->selectedRange
253 withinSelectedCharacterRange:obj->selectedRange
254 inTextContainer:obj->textContainer
255 rectCount:&rectCount];
257 [[NSColor blackColor] set];
258 for (unsigned i = 0; i < rectCount; i++) {
259 NSRect rect = rectArray[i];
260 rect.origin.x += obj->textFieldRect.origin.x;
261 rect.origin.y += obj->textFieldRect.origin.y;
263 [NSBezierPath strokeRect:rect];
267 [NSGraphicsContext setCurrentContext:oldContext];
270 static void invalidatePlugin(PluginObject* obj)
275 rect.right = obj->window.width;
276 rect.bottom = obj->window.height;
278 browser->invalidaterect(obj->npp, &rect);
281 static void handleFocusChanged(NPCocoaEvent* cocoaEvent, PluginObject* obj)
283 obj->pluginHasFocus = cocoaEvent->data.focus.hasFocus;
285 invalidatePlugin(obj);
288 static void handleMouseMoved(NPCocoaEvent* cocoaEvent, PluginObject* obj)
290 NSPoint point = NSMakePoint(cocoaEvent->data.mouse.pluginX, cocoaEvent->data.mouse.pluginY);
292 if (NSPointInRect(point, obj->textFieldRect))
293 [[NSCursor IBeamCursor] set];
295 [[NSCursor arrowCursor] set];
298 static void handleMouseDown(NPCocoaEvent* cocoaEvent, PluginObject* obj)
300 NSPoint point = NSMakePoint(cocoaEvent->data.mouse.pluginX, cocoaEvent->data.mouse.pluginY);
302 obj->textFieldHasFocus = NSPointInRect(point, obj->textFieldRect);
304 invalidatePlugin(obj);
307 static int16_t handleTextFieldKeyDown(NPCocoaEvent* event, PluginObject* obj)
309 NSString *string = (NSString *)event->data.key.charactersIgnoringModifiers;
311 unichar c = [string length] > 0 ? [string characterAtIndex:0] : 0;
314 case NSLeftArrowFunctionKey:
315 if (obj->selectedRange.location > 0) {
316 obj->selectedRange.location--;
317 invalidatePlugin(obj);
321 case NSRightArrowFunctionKey:
322 if (obj->selectedRange.location < [obj->textStorage length]) {
323 obj->selectedRange.location++;
324 invalidatePlugin(obj);
330 // Return 0 and let the text input system handle it.
336 static int16_t handleTextInput(NPCocoaEvent* event, PluginObject* obj)
338 NSString *string = (NSString *)event->data.text.text;
339 NSRange range = obj->selectedRange;
341 [obj->textStorage replaceCharactersInRange:range withString:string];
343 obj->selectedRange.location = range.location + [string length];
344 obj->selectedRange.length = 0;
346 invalidatePlugin(obj);
351 int16 NPP_HandleEvent(NPP instance, void* event)
353 PluginObject* obj = instance->pdata;
355 NPCocoaEvent* cocoaEvent = event;
357 switch (cocoaEvent->type) {
358 case NPCocoaEventDrawRect:
359 handleDraw(obj, cocoaEvent);
361 case NPCocoaEventFocusChanged:
362 handleFocusChanged(cocoaEvent, obj);
364 case NPCocoaEventMouseMoved:
365 handleMouseMoved(cocoaEvent, obj);
367 case NPCocoaEventMouseDown:
368 handleMouseDown(cocoaEvent, obj);
370 case NPCocoaEventKeyDown:
371 // If the text field has focus we ignore the event, causing it
372 // to be sent to the input manager.
373 if (obj->textFieldHasFocus)
374 return handleTextFieldKeyDown(cocoaEvent, obj);
377 case NPCocoaEventTextInput:
378 return handleTextInput(cocoaEvent, obj);
386 void NPP_URLNotify(NPP instance, const char* url, NPReason reason, void* notifyData)
390 NPError NPP_GetValue(NPP instance, NPPVariable variable, void* value)
392 return NPERR_GENERIC_ERROR;
395 NPError NPP_SetValue(NPP instance, NPNVariable variable, void* value)
397 return NPERR_GENERIC_ERROR;