1/*
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.
7
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.
20
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.
25
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.
32 */
33
34#import <WebKit/npapi.h>
35#import <WebKit/npfunctions.h>
36#import <WebKit/npruntime.h>
37
38NPNetscapeFuncs *browser;
39
40NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16_t mode, int16_t argc, char* argn[], char* argv[], NPSavedData* saved);
41NPError NPP_Destroy(NPP instance, NPSavedData** save);
42NPError NPP_SetWindow(NPP instance, NPWindow* window);
43NPError NPP_NewStream(NPP instance, NPMIMEType type, NPStream* stream, NPBool seekable, uint16_t* stype);
44NPError NPP_DestroyStream(NPP instance, NPStream* stream, NPReason reason);
45int32_t NPP_WriteReady(NPP instance, NPStream* stream);
46int32_t NPP_Write(NPP instance, NPStream* stream, int32_t offset, int32_t len, void* buffer);
47void NPP_StreamAsFile(NPP instance, NPStream* stream, const char* fname);
48void NPP_Print(NPP instance, NPPrint* platformPrint);
49int16_t NPP_HandleEvent(NPP instance, void* event);
50void NPP_URLNotify(NPP instance, const char* URL, NPReason reason, void* notifyData);
51NPError NPP_GetValue(NPP instance, NPPVariable variable, void *value);
52NPError NPP_SetValue(NPP instance, NPNVariable variable, void *value);
53
54#pragma export on
55// Mach-o entry points
56NPError NP_Initialize(NPNetscapeFuncs *browserFuncs);
57NPError NP_GetEntryPoints(NPPluginFuncs *pluginFuncs);
58void NP_Shutdown(void);
59// For compatibility with CFM browsers.
60int main(NPNetscapeFuncs *browserFuncs, NPPluginFuncs *pluginFuncs, NPP_ShutdownProcPtr *shutdown);
61#pragma export off
62
63
64typedef void (* FunctionPointer) (void);
65typedef void (* TransitionVector) (void);
66static FunctionPointer functionPointerForTVector(TransitionVector);
67static TransitionVector tVectorForFunctionPointer(FunctionPointer);
68
69// Mach-o entry points
70NPError NP_Initialize(NPNetscapeFuncs* browserFuncs)
71{
72    browser = browserFuncs;
73    return NPERR_NO_ERROR;
74}
75
76NPError NP_GetEntryPoints(NPPluginFuncs* pluginFuncs)
77{
78    pluginFuncs->version = 11;
79    pluginFuncs->size = sizeof(pluginFuncs);
80    pluginFuncs->newp = NPP_New;
81    pluginFuncs->destroy = NPP_Destroy;
82    pluginFuncs->setwindow = NPP_SetWindow;
83    pluginFuncs->newstream = NPP_NewStream;
84    pluginFuncs->destroystream = NPP_DestroyStream;
85    pluginFuncs->asfile = NPP_StreamAsFile;
86    pluginFuncs->writeready = NPP_WriteReady;
87    pluginFuncs->write = (NPP_WriteProcPtr)NPP_Write;
88    pluginFuncs->print = NPP_Print;
89    pluginFuncs->event = NPP_HandleEvent;
90    pluginFuncs->urlnotify = NPP_URLNotify;
91    pluginFuncs->getvalue = NPP_GetValue;
92    pluginFuncs->setvalue = NPP_SetValue;
93
94    return NPERR_NO_ERROR;
95}
96
97void NP_Shutdown(void)
98{
99
100}
101
102// For compatibility with CFM browsers.
103int main(NPNetscapeFuncs *browserFuncs, NPPluginFuncs *pluginFuncs, NPP_ShutdownProcPtr *shutdown)
104{
105    browser = malloc(sizeof(NPNetscapeFuncs));
106    bzero(browser, sizeof(NPNetscapeFuncs));
107
108    browser->size = browserFuncs->size;
109    browser->version = browserFuncs->version;
110
111    // Since this is a mach-o plug-in and the browser is CFM because it is calling main, translate
112    // our function points into TVectors so the browser can call them.
113    browser->geturl = (NPN_GetURLProcPtr)functionPointerForTVector((TransitionVector)browserFuncs->geturl);
114    browser->posturl = (NPN_PostURLProcPtr)functionPointerForTVector((TransitionVector)browserFuncs->posturl);
115    browser->requestread = (NPN_RequestReadProcPtr)functionPointerForTVector((TransitionVector)browserFuncs->requestread);
116    browser->newstream = (NPN_NewStreamProcPtr)functionPointerForTVector((TransitionVector)browserFuncs->newstream);
117    browser->write = (NPN_WriteProcPtr)functionPointerForTVector((TransitionVector)browserFuncs->write);
118    browser->destroystream = (NPN_DestroyStreamProcPtr)functionPointerForTVector((TransitionVector)browserFuncs->destroystream);
119    browser->status = (NPN_StatusProcPtr)functionPointerForTVector((TransitionVector)browserFuncs->status);
120    browser->uagent = (NPN_UserAgentProcPtr)functionPointerForTVector((TransitionVector)browserFuncs->uagent);
121    browser->memalloc = (NPN_MemAllocProcPtr)functionPointerForTVector((TransitionVector)browserFuncs->memalloc);
122    browser->memfree = (NPN_MemFreeProcPtr)functionPointerForTVector((TransitionVector)browserFuncs->memfree);
123    browser->memflush = (NPN_MemFlushProcPtr)functionPointerForTVector((TransitionVector)browserFuncs->memflush);
124    browser->reloadplugins = (NPN_ReloadPluginsProcPtr)functionPointerForTVector((TransitionVector)browserFuncs->reloadplugins);
125    browser->geturlnotify = (NPN_GetURLNotifyProcPtr)functionPointerForTVector((TransitionVector)browserFuncs->geturlnotify);
126    browser->posturlnotify = (NPN_PostURLNotifyProcPtr)functionPointerForTVector((TransitionVector)browserFuncs->posturlnotify);
127    browser->getvalue = (NPN_GetValueProcPtr)functionPointerForTVector((TransitionVector)browserFuncs->getvalue);
128    browser->setvalue = (NPN_SetValueProcPtr)functionPointerForTVector((TransitionVector)browserFuncs->setvalue);
129    browser->invalidaterect = (NPN_InvalidateRectProcPtr)functionPointerForTVector((TransitionVector)browserFuncs->invalidaterect);
130    browser->invalidateregion = (NPN_InvalidateRegionProcPtr)functionPointerForTVector((TransitionVector)browserFuncs->invalidateregion);
131    browser->forceredraw = (NPN_ForceRedrawProcPtr)functionPointerForTVector((TransitionVector)browserFuncs->forceredraw);
132    browser->getJavaEnv = (NPN_GetJavaEnvProcPtr)functionPointerForTVector((TransitionVector)browserFuncs->getJavaEnv);
133    browser->getJavaPeer = (NPN_GetJavaPeerProcPtr)functionPointerForTVector((TransitionVector)browserFuncs->getJavaPeer);
134
135    pluginFuncs->version = 11;
136    pluginFuncs->size = sizeof(pluginFuncs);
137    pluginFuncs->newp = (NPP_NewProcPtr)tVectorForFunctionPointer((FunctionPointer)NPP_New);
138    pluginFuncs->destroy = (NPP_DestroyProcPtr)tVectorForFunctionPointer((FunctionPointer)NPP_Destroy);
139    pluginFuncs->setwindow = (NPP_SetWindowProcPtr)tVectorForFunctionPointer((FunctionPointer)NPP_SetWindow);
140    pluginFuncs->newstream = (NPP_NewStreamProcPtr)tVectorForFunctionPointer((FunctionPointer)NPP_NewStream);
141    pluginFuncs->destroystream = (NPP_DestroyStreamProcPtr)tVectorForFunctionPointer((FunctionPointer)NPP_DestroyStream);
142    pluginFuncs->asfile = (NPP_StreamAsFileProcPtr)tVectorForFunctionPointer((FunctionPointer)NPP_StreamAsFile);
143    pluginFuncs->writeready = (NPP_WriteReadyProcPtr)tVectorForFunctionPointer((FunctionPointer)NPP_WriteReady);
144    pluginFuncs->write = (NPP_WriteProcPtr)tVectorForFunctionPointer((FunctionPointer)NPP_Write);
145    pluginFuncs->print = (NPP_PrintProcPtr)tVectorForFunctionPointer((FunctionPointer)NPP_Print);
146    pluginFuncs->event = (NPP_HandleEventProcPtr)tVectorForFunctionPointer((FunctionPointer)NPP_HandleEvent);
147    pluginFuncs->urlnotify = (NPP_URLNotifyProcPtr)tVectorForFunctionPointer((FunctionPointer)NPP_URLNotify);
148    pluginFuncs->getvalue = (NPP_GetValueProcPtr)tVectorForFunctionPointer((FunctionPointer)NPP_GetValue);
149    pluginFuncs->setvalue = (NPP_SetValueProcPtr)tVectorForFunctionPointer((FunctionPointer)NPP_SetValue);
150
151    *shutdown = (NPP_ShutdownProcPtr)tVectorForFunctionPointer((FunctionPointer)NP_Shutdown);
152
153    return NPERR_NO_ERROR;
154}
155
156NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16_t mode, int16_t argc, char* argn[], char* argv[], NPSavedData* saved)
157{
158    // Call window.alert("Success!")
159    NPError error;
160    NPObject *windowObject = NULL;
161    error = browser->getvalue(instance, NPNVWindowNPObject, &windowObject);
162    if (error == NPERR_NO_ERROR) {
163        NPVariant alertMessage;
164        STRINGZ_TO_NPVARIANT("Success!", alertMessage);
165        NPVariant result;
166        browser->invoke(instance, windowObject, browser->getstringidentifier("alert"), &alertMessage, 1, &result);
167        browser->releaseobject(windowObject);
168    }
169
170    return NPERR_NO_ERROR;
171}
172
173NPError NPP_Destroy(NPP instance, NPSavedData** save)
174{
175    return NPERR_NO_ERROR;
176}
177
178NPError NPP_SetWindow(NPP instance, NPWindow* window)
179{
180    return NPERR_NO_ERROR;
181}
182
183NPError NPP_NewStream(NPP instance, NPMIMEType type, NPStream* stream, NPBool seekable, uint16_t* stype)
184{
185    *stype = NP_ASFILEONLY;
186    return NPERR_NO_ERROR;
187}
188
189NPError NPP_DestroyStream(NPP instance, NPStream* stream, NPReason reason)
190{
191    return NPERR_NO_ERROR;
192}
193
194int32_t NPP_WriteReady(NPP instance, NPStream* stream)
195{
196    return 0;
197}
198
199int32_t NPP_Write(NPP instance, NPStream* stream, int32_t offset, int32_t len, void* buffer)
200{
201    return 0;
202}
203
204void NPP_StreamAsFile(NPP instance, NPStream* stream, const char* fname)
205{
206}
207
208void NPP_Print(NPP instance, NPPrint* platformPrint)
209{
210
211}
212
213int16_t NPP_HandleEvent(NPP instance, void* event)
214{
215    return 1;
216}
217
218void NPP_URLNotify(NPP instance, const char* url, NPReason reason, void* notifyData)
219{
220
221}
222
223NPError NPP_GetValue(NPP instance, NPPVariable variable, void *value)
224{
225    return NPERR_GENERIC_ERROR;
226}
227
228NPError NPP_SetValue(NPP instance, NPNVariable variable, void *value)
229{
230    return NPERR_GENERIC_ERROR;
231}
232
233// function pointer converters
234
235FunctionPointer functionPointerForTVector(TransitionVector tvp)
236{
237    const uint32_t temp[6] = {0x3D800000, 0x618C0000, 0x800C0000, 0x804C0004, 0x7C0903A6, 0x4E800420};
238    uint32_t *newGlue = NULL;
239
240    if (tvp != NULL) {
241        newGlue = (uint32_t *)malloc(sizeof(temp));
242        if (newGlue != NULL) {
243            unsigned i;
244            for (i = 0; i < 6; i++) newGlue[i] = temp[i];
245            newGlue[0] |= ((UInt32)tvp >> 16);
246            newGlue[1] |= ((UInt32)tvp & 0xFFFF);
247            MakeDataExecutable(newGlue, sizeof(temp));
248        }
249    }
250
251    return (FunctionPointer)newGlue;
252}
253
254TransitionVector tVectorForFunctionPointer(FunctionPointer fp)
255{
256    FunctionPointer *newGlue = NULL;
257    if (fp != NULL) {
258        newGlue = (FunctionPointer *)malloc(2 * sizeof(FunctionPointer));
259        if (newGlue != NULL) {
260            newGlue[0] = fp;
261            newGlue[1] = NULL;
262        }
263    }
264    return (TransitionVector)newGlue;
265}
266