2 WebNetscapePluginPackage.m
3 Copyright (c) 2002, Apple, Inc. All rights reserved.
6 #import <WebKit/WebNetscapePluginPackage.h>
8 #import <WebKit/WebKitLogging.h>
9 #import <WebKit/WebKitNSStringExtras.h>
10 #import <WebKit/WebNSObjectExtras.h>
12 #import <JavaScriptCore/npruntime_impl.h>
14 #import <Foundation/NSPrivateDecls.h>
16 typedef void (* FunctionPointer) (void);
17 typedef void (* TransitionVector) (void);
18 static FunctionPointer functionPointerForTVector(TransitionVector);
19 static TransitionVector tVectorForFunctionPointer(FunctionPointer);
21 #define PluginNameOrDescriptionStringNumber 126
22 #define MIMEDescriptionStringNumber 127
23 #define MIMEListStringStringNumber 128
25 #define RealPlayerAppIndentifier @"com.RealNetworks.RealOne Player"
26 #define RealPlayerPluginFilename @"RealPlayer Plugin"
28 @implementation WebNetscapePluginPackage
32 // The Shockwave plugin requires a valid file in CurApRefNum.
33 // But it doesn't seem to matter what file it is.
34 // If we're called inside a Cocoa application which won't have a
35 // CurApRefNum, we set it to point to the system resource file.
36 if (LMGetCurApRefNum() == -1) {
37 // To get the refNum for the system resource file, we have to do
38 // UseResFile(kSystemResFile) and then look at CurResFile().
39 short savedCurResFile = CurResFile();
40 UseResFile(kSystemResFile);
41 LMSetCurApRefNum(CurResFile());
42 UseResFile(savedCurResFile);
46 - (SInt16)openResourceFile
52 return CFBundleOpenBundleResourceMap([bundle _cfBundle]);
54 err = FSPathMakeRef((const UInt8 *)[path fileSystemRepresentation], &fref, NULL);
59 return FSOpenResFile(&fref, fsRdPerm);
63 - (void)closeResourceFile:(SInt16)resRef
66 CFBundleCloseBundleResourceMap([bundle _cfBundle], resRef);
72 - (NSString *)stringForStringListID:(SInt16)stringListID andIndex:(SInt16)index
74 // Get resource, and dereference the handle.
75 Handle stringHandle = Get1Resource('STR#', stringListID);
76 if (stringHandle == NULL) {
79 unsigned char *p = (unsigned char *)*stringHandle;
84 // Check the index against the length of the string list, then skip the length.
85 if (index < 1 || index > *(SInt16 *)p) {
90 // Skip any strings that come before the one we are looking for.
94 // Convert the one we found into an NSString.
95 return [[[NSString alloc] initWithBytes:(p + 1) length:*p encoding:[NSString _web_encodingForResource:stringHandle]] autorelease];
98 - (BOOL)getPluginInfoFromResources
100 SInt16 resRef = [self openResourceFile];
106 if (ResError() != noErr) {
110 NSString *MIME, *extensionsList, *description;
115 NSMutableDictionary *MIMEToExtensionsDictionary = [NSMutableDictionary dictionary];
116 NSMutableDictionary *MIMEToDescriptionDictionary = [NSMutableDictionary dictionary];
119 MIME = [[self stringForStringListID:MIMEListStringStringNumber
120 andIndex:i] lowercaseString];
125 // FIXME: Avoid mime types with semi-colons because KJS can't properly parse them using KWQKConfigBase
126 r = [MIME rangeOfString:@";"];
131 extensionsList = [[self stringForStringListID:MIMEListStringStringNumber
132 andIndex:i+1] lowercaseString];
133 if (extensionsList) {
134 extensions = [extensionsList componentsSeparatedByString:@","];
135 [MIMEToExtensionsDictionary setObject:extensions forKey:MIME];
137 // DRM and WMP claim MIMEs without extensions. Use a @"" extension in this case.
138 [MIMEToExtensionsDictionary setObject:[NSArray arrayWithObject:@""] forKey:MIME];
141 description = [self stringForStringListID:MIMEDescriptionStringNumber
142 andIndex:[MIMEToExtensionsDictionary count]];
144 [MIMEToDescriptionDictionary setObject:description forKey:MIME];
146 [MIMEToDescriptionDictionary setObject:@"" forKey:MIME];
150 [self setMIMEToDescriptionDictionary:MIMEToDescriptionDictionary];
151 [self setMIMEToExtensionsDictionary:MIMEToExtensionsDictionary];
153 NSString *filename = [self filename];
155 description = [self stringForStringListID:PluginNameOrDescriptionStringNumber andIndex:1];
157 description = filename;
159 [self setPluginDescription:description];
162 NSString *theName = [self stringForStringListID:PluginNameOrDescriptionStringNumber andIndex:2];
166 [self setName:theName];
168 [self closeResourceFile:resRef];
173 - initWithPath:(NSString *)pluginPath
175 [super initWithPath:pluginPath];
184 CFBundleGetPackageInfo([bundle _cfBundle], &type, NULL);
187 // Single-file plug-in with resource fork
189 type = [[[NSFileManager defaultManager] fileAttributesAtPath:path traverseLink:YES] fileHFSTypeCode];
195 if (type != FOUR_CHAR_CODE('BRPL')) {
200 // Check if the executable is Mach-O or CFM.
202 NSFileHandle *executableFile = [NSFileHandle fileHandleForReadingAtPath:[bundle executablePath]];
203 NSData *data = [executableFile readDataOfLength:8];
204 [executableFile closeFile];
205 // Check the length of the data before calling memcmp. We think this fixes 3782543.
206 if (data == nil || [data length] < 8) {
210 isCFM = memcmp([data bytes], "Joy!peff", 8) == 0;
220 if (![self getPluginInfoFromPLists] && ![self getPluginInfoFromResources]) {
228 - (WebExecutableType)executableType
231 return WebCFMExecutableType;
233 return WebMachOExecutableType;
242 - (void)unloadWithoutShutdown
248 if (resourceRef != -1) {
249 [self closeResourceFile:resourceRef];
253 CFBundleUnloadExecutable([bundle _cfBundle]);
255 CloseConnection(&connID);
258 LOG(Plugins, "Plugin Unloaded");
263 - (void)launchRealPlayer
265 CFURLRef appURL = NULL;
266 OSStatus error = LSFindApplicationForInfo(kLSUnknownCreator, (CFStringRef)RealPlayerAppIndentifier, NULL, NULL, &appURL);
268 LSLaunchURLSpec URLSpec;
269 bzero(&URLSpec, sizeof(URLSpec));
270 URLSpec.launchFlags = kLSLaunchDefaults | kLSLaunchDontSwitch;
271 URLSpec.appURL = appURL;
272 LSOpenFromURLSpec(&URLSpec, NULL);
279 NP_GetEntryPointsFuncPtr NP_GetEntryPoints = NULL;
280 NP_InitializeFuncPtr NP_Initialize = NULL;
281 MainFuncPtr pluginMainFunc;
286 CFAbsoluteTime start = CFAbsoluteTimeGetCurrent();
288 LOG(Plugins, "%f Load timing started for: %@", start, [self name]);
295 CFBundleRef cfBundle = [bundle _cfBundle];
296 if (!CFBundleLoadExecutable(cfBundle)) {
300 CFAbsoluteTime currentTime = CFAbsoluteTimeGetCurrent();
301 CFAbsoluteTime duration = currentTime - start;
303 LOG(Plugins, "%f CFBundleLoadExecutable took %f seconds", currentTime, duration);
307 pluginMainFunc = (MainFuncPtr)CFBundleGetFunctionPointerForName(cfBundle, CFSTR("main") );
308 if (!pluginMainFunc) {
312 NP_Initialize = (NP_InitializeFuncPtr)CFBundleGetFunctionPointerForName(cfBundle, CFSTR("NP_Initialize"));
313 NP_GetEntryPoints = (NP_GetEntryPointsFuncPtr)CFBundleGetFunctionPointerForName(cfBundle, CFSTR("NP_GetEntryPoints"));
314 NPP_Shutdown = (NPP_ShutdownProcPtr)CFBundleGetFunctionPointerForName(cfBundle, CFSTR("NP_Shutdown"));
315 if (!NP_Initialize || !NP_GetEntryPoints || !NPP_Shutdown) {
324 err = FSPathMakeRef((UInt8 *)[path fileSystemRepresentation], &fref, NULL);
326 ERROR("FSPathMakeRef failed. Error=%d", err);
329 err = FSGetCatalogInfo(&fref, kFSCatInfoNone, NULL, NULL, &spec, NULL);
331 ERROR("FSGetCatalogInfo failed. Error=%d", err);
334 err = GetDiskFragment(&spec, 0, kCFragGoesToEOF, nil, kPrivateCFragCopy, &connID, (Ptr *)&pluginMainFunc, nil);
336 ERROR("GetDiskFragment failed. Error=%d", err);
340 CFAbsoluteTime currentTime = CFAbsoluteTimeGetCurrent();
341 CFAbsoluteTime duration = currentTime - start;
343 LOG(Plugins, "%f GetDiskFragment took %f seconds", currentTime, duration);
346 pluginMainFunc = (MainFuncPtr)functionPointerForTVector((TransitionVector)pluginMainFunc);
347 if (!pluginMainFunc) {
351 // NOTE: pluginMainFunc is freed after it is called. Be sure not to return before that.
356 // Plugins (at least QT) require that you call UseResFile on the resource file before loading it.
357 resourceRef = [self openResourceFile];
358 if (resourceRef != -1) {
359 UseResFile(resourceRef);
362 // swap function tables
364 browserFuncs.version = NP_VERSION_MINOR;
365 browserFuncs.size = sizeof(NPNetscapeFuncs);
366 browserFuncs.geturl = (NPN_GetURLProcPtr)tVectorForFunctionPointer((FunctionPointer)NPN_GetURL);
367 browserFuncs.posturl = (NPN_PostURLProcPtr)tVectorForFunctionPointer((FunctionPointer)NPN_PostURL);
368 browserFuncs.requestread = (NPN_RequestReadProcPtr)tVectorForFunctionPointer((FunctionPointer)NPN_RequestRead);
369 browserFuncs.newstream = (NPN_NewStreamProcPtr)tVectorForFunctionPointer((FunctionPointer)NPN_NewStream);
370 browserFuncs.write = (NPN_WriteProcPtr)tVectorForFunctionPointer((FunctionPointer)NPN_Write);
371 browserFuncs.destroystream = (NPN_DestroyStreamProcPtr)tVectorForFunctionPointer((FunctionPointer)NPN_DestroyStream);
372 browserFuncs.status = (NPN_StatusProcPtr)tVectorForFunctionPointer((FunctionPointer)NPN_Status);
373 browserFuncs.uagent = (NPN_UserAgentProcPtr)tVectorForFunctionPointer((FunctionPointer)NPN_UserAgent);
374 browserFuncs.memalloc = (NPN_MemAllocProcPtr)tVectorForFunctionPointer((FunctionPointer)NPN_MemAlloc);
375 browserFuncs.memfree = (NPN_MemFreeProcPtr)tVectorForFunctionPointer((FunctionPointer)NPN_MemFree);
376 browserFuncs.memflush = (NPN_MemFlushProcPtr)tVectorForFunctionPointer((FunctionPointer)NPN_MemFlush);
377 browserFuncs.reloadplugins = (NPN_ReloadPluginsProcPtr)tVectorForFunctionPointer((FunctionPointer)NPN_ReloadPlugins);
378 browserFuncs.geturlnotify = (NPN_GetURLNotifyProcPtr)tVectorForFunctionPointer((FunctionPointer)NPN_GetURLNotify);
379 browserFuncs.posturlnotify = (NPN_PostURLNotifyProcPtr)tVectorForFunctionPointer((FunctionPointer)NPN_PostURLNotify);
380 browserFuncs.getvalue = (NPN_GetValueProcPtr)tVectorForFunctionPointer((FunctionPointer)NPN_GetValue);
381 browserFuncs.setvalue = (NPN_SetValueProcPtr)tVectorForFunctionPointer((FunctionPointer)NPN_SetValue);
382 browserFuncs.invalidaterect = (NPN_InvalidateRectProcPtr)tVectorForFunctionPointer((FunctionPointer)NPN_InvalidateRect);
383 browserFuncs.invalidateregion = (NPN_InvalidateRegionProcPtr)tVectorForFunctionPointer((FunctionPointer)NPN_InvalidateRegion);
384 browserFuncs.forceredraw = (NPN_ForceRedrawProcPtr)tVectorForFunctionPointer((FunctionPointer)NPN_ForceRedraw);
385 browserFuncs.getJavaEnv = (NPN_GetJavaEnvProcPtr)tVectorForFunctionPointer((FunctionPointer)NPN_GetJavaEnv);
386 browserFuncs.getJavaPeer = (NPN_GetJavaPeerProcPtr)tVectorForFunctionPointer((FunctionPointer)NPN_GetJavaPeer);
388 browserFuncs.releasevariantvalue = (NPN_ReleaseVariantValueProcPtr)tVectorForFunctionPointer((FunctionPointer)_NPN_ReleaseVariantValue);
389 browserFuncs.getstringidentifier = (NPN_GetStringIdentifierProcPtr)tVectorForFunctionPointer((FunctionPointer)_NPN_GetStringIdentifier);
390 browserFuncs.getstringidentifiers = (NPN_GetStringIdentifiersProcPtr)tVectorForFunctionPointer((FunctionPointer)_NPN_GetStringIdentifiers);
391 browserFuncs.getintidentifier = (NPN_GetIntIdentifierProcPtr)tVectorForFunctionPointer((FunctionPointer)_NPN_GetIntIdentifier);
392 browserFuncs.identifierisstring = (NPN_IdentifierIsStringProcPtr)tVectorForFunctionPointer((FunctionPointer)_NPN_IdentifierIsString);
393 browserFuncs.utf8fromidentifier = (NPN_UTF8FromIdentifierProcPtr)tVectorForFunctionPointer((FunctionPointer)_NPN_UTF8FromIdentifier);
394 browserFuncs.createobject = (NPN_CreateObjectProcPtr)tVectorForFunctionPointer((FunctionPointer)_NPN_CreateObject);
395 browserFuncs.retainobject = (NPN_RetainObjectProcPtr)tVectorForFunctionPointer((FunctionPointer)_NPN_RetainObject);
396 browserFuncs.releaseobject = (NPN_ReleaseObjectProcPtr)tVectorForFunctionPointer((FunctionPointer)_NPN_ReleaseObject);
397 browserFuncs.invoke = (NPN_InvokeProcPtr)tVectorForFunctionPointer((FunctionPointer)_NPN_Invoke);
398 browserFuncs.invokeDefault = (NPN_InvokeDefaultProcPtr)tVectorForFunctionPointer((FunctionPointer)_NPN_InvokeDefault);
399 browserFuncs.evaluate = (NPN_EvaluateProcPtr)tVectorForFunctionPointer((FunctionPointer)_NPN_Evaluate);
400 browserFuncs.getproperty = (NPN_GetPropertyProcPtr)tVectorForFunctionPointer((FunctionPointer)_NPN_GetProperty);
401 browserFuncs.setproperty = (NPN_SetPropertyProcPtr)tVectorForFunctionPointer((FunctionPointer)_NPN_SetProperty);
402 browserFuncs.removeproperty = (NPN_RemovePropertyProcPtr)tVectorForFunctionPointer((FunctionPointer)_NPN_RemoveProperty);
403 browserFuncs.setexception = (NPN_SetExceptionProcPtr)tVectorForFunctionPointer((FunctionPointer)_NPN_SetException);
406 CFAbsoluteTime mainStart = CFAbsoluteTimeGetCurrent();
408 LOG(Plugins, "%f main timing started", mainStart);
409 NPP_ShutdownProcPtr shutdownFunction;
410 npErr = pluginMainFunc(&browserFuncs, &pluginFuncs, &shutdownFunction);
411 NPP_Shutdown = (NPP_ShutdownProcPtr)functionPointerForTVector((TransitionVector)shutdownFunction);
413 // Don't free pluginMainFunc if we got it from a bundle because it is owned by CFBundle in that case.
414 free(pluginMainFunc);
417 // Workaround for 3270576. The RealPlayer plug-in fails to load if its preference file is out of date.
418 // Launch the RealPlayer application to refresh the file.
419 if (npErr != NPERR_NO_ERROR) {
420 if (npErr == NPERR_MODULE_LOAD_FAILED_ERROR && [[self filename] isEqualToString:RealPlayerPluginFilename]) {
421 [self launchRealPlayer];
426 CFAbsoluteTime currentTime = CFAbsoluteTimeGetCurrent();
427 CFAbsoluteTime duration = currentTime - mainStart;
429 LOG(Plugins, "%f main took %f seconds", currentTime, duration);
431 pluginSize = pluginFuncs.size;
432 pluginVersion = pluginFuncs.version;
433 LOG(Plugins, "pluginMainFunc: %d, size=%d, version=%d", npErr, pluginSize, pluginVersion);
435 NPP_New = (NPP_NewProcPtr)functionPointerForTVector((TransitionVector)pluginFuncs.newp);
436 NPP_Destroy = (NPP_DestroyProcPtr)functionPointerForTVector((TransitionVector)pluginFuncs.destroy);
437 NPP_SetWindow = (NPP_SetWindowProcPtr)functionPointerForTVector((TransitionVector)pluginFuncs.setwindow);
438 NPP_NewStream = (NPP_NewStreamProcPtr)functionPointerForTVector((TransitionVector)pluginFuncs.newstream);
439 NPP_DestroyStream = (NPP_DestroyStreamProcPtr)functionPointerForTVector((TransitionVector)pluginFuncs.destroystream);
440 NPP_StreamAsFile = (NPP_StreamAsFileProcPtr)functionPointerForTVector((TransitionVector)pluginFuncs.asfile);
441 NPP_WriteReady = (NPP_WriteReadyProcPtr)functionPointerForTVector((TransitionVector)pluginFuncs.writeready);
442 NPP_Write = (NPP_WriteProcPtr)functionPointerForTVector((TransitionVector)pluginFuncs.write);
443 NPP_Print = (NPP_PrintProcPtr)functionPointerForTVector((TransitionVector)pluginFuncs.print);
444 NPP_HandleEvent = (NPP_HandleEventProcPtr)functionPointerForTVector((TransitionVector)pluginFuncs.event);
445 NPP_URLNotify = (NPP_URLNotifyProcPtr)functionPointerForTVector((TransitionVector)pluginFuncs.urlnotify);
446 NPP_GetValue = (NPP_GetValueProcPtr)functionPointerForTVector((TransitionVector)pluginFuncs.getvalue);
447 NPP_SetValue = (NPP_SetValueProcPtr)functionPointerForTVector((TransitionVector)pluginFuncs.setvalue);
449 // LiveConnect support
450 NPP_GetJavaClass = (NPP_GetJavaClassProcPtr)functionPointerForTVector((TransitionVector)pluginFuncs.javaClass);
451 if (NPP_GetJavaClass){
452 LOG(LiveConnect, "%@: CFM entry point for NPP_GetJavaClass = %p", [self name], NPP_GetJavaClass);
454 LOG(LiveConnect, "%@: no entry point for NPP_GetJavaClass", [self name]);
458 // no function pointer conversion necessary for mach-o
459 browserFuncs.version = NP_VERSION_MINOR;
460 browserFuncs.size = sizeof(NPNetscapeFuncs);
461 browserFuncs.geturl = NPN_GetURL;
462 browserFuncs.posturl = NPN_PostURL;
463 browserFuncs.requestread = NPN_RequestRead;
464 browserFuncs.newstream = NPN_NewStream;
465 browserFuncs.write = NPN_Write;
466 browserFuncs.destroystream = NPN_DestroyStream;
467 browserFuncs.status = NPN_Status;
468 browserFuncs.uagent = NPN_UserAgent;
469 browserFuncs.memalloc = NPN_MemAlloc;
470 browserFuncs.memfree = NPN_MemFree;
471 browserFuncs.memflush = NPN_MemFlush;
472 browserFuncs.reloadplugins = NPN_ReloadPlugins;
473 browserFuncs.geturlnotify = NPN_GetURLNotify;
474 browserFuncs.posturlnotify = NPN_PostURLNotify;
475 browserFuncs.getvalue = NPN_GetValue;
476 browserFuncs.setvalue = NPN_SetValue;
477 browserFuncs.invalidaterect = NPN_InvalidateRect;
478 browserFuncs.invalidateregion = NPN_InvalidateRegion;
479 browserFuncs.forceredraw = NPN_ForceRedraw;
480 browserFuncs.getJavaEnv = NPN_GetJavaEnv;
481 browserFuncs.getJavaPeer = NPN_GetJavaPeer;
483 browserFuncs.releasevariantvalue = _NPN_ReleaseVariantValue;
484 browserFuncs.getstringidentifier = _NPN_GetStringIdentifier;
485 browserFuncs.getstringidentifiers = _NPN_GetStringIdentifiers;
486 browserFuncs.getintidentifier = _NPN_GetIntIdentifier;
487 browserFuncs.identifierisstring = _NPN_IdentifierIsString;
488 browserFuncs.utf8fromidentifier = _NPN_UTF8FromIdentifier;
489 browserFuncs.createobject = _NPN_CreateObject;
490 browserFuncs.retainobject = _NPN_RetainObject;
491 browserFuncs.releaseobject = _NPN_ReleaseObject;
492 browserFuncs.invoke = _NPN_Invoke;
493 browserFuncs.invokeDefault = _NPN_InvokeDefault;
494 browserFuncs.evaluate = _NPN_Evaluate;
495 browserFuncs.getproperty = _NPN_GetProperty;
496 browserFuncs.setproperty = _NPN_SetProperty;
497 browserFuncs.removeproperty = _NPN_RemoveProperty;
498 browserFuncs.setexception = _NPN_SetException;
501 CFAbsoluteTime initializeStart = CFAbsoluteTimeGetCurrent();
503 LOG(Plugins, "%f NP_Initialize timing started", initializeStart);
504 npErr = NP_Initialize(&browserFuncs);
505 if (npErr != NPERR_NO_ERROR) {
509 CFAbsoluteTime currentTime = CFAbsoluteTimeGetCurrent();
510 CFAbsoluteTime duration = currentTime - initializeStart;
512 LOG(Plugins, "%f NP_Initialize took %f seconds", currentTime, duration);
514 npErr = NP_GetEntryPoints(&pluginFuncs);
515 if (npErr != NPERR_NO_ERROR) {
519 pluginSize = pluginFuncs.size;
520 pluginVersion = pluginFuncs.version;
522 NPP_New = pluginFuncs.newp;
523 NPP_Destroy = pluginFuncs.destroy;
524 NPP_SetWindow = pluginFuncs.setwindow;
525 NPP_NewStream = pluginFuncs.newstream;
526 NPP_DestroyStream = pluginFuncs.destroystream;
527 NPP_StreamAsFile = pluginFuncs.asfile;
528 NPP_WriteReady = pluginFuncs.writeready;
529 NPP_Write = pluginFuncs.write;
530 NPP_Print = pluginFuncs.print;
531 NPP_HandleEvent = pluginFuncs.event;
532 NPP_URLNotify = pluginFuncs.urlnotify;
533 NPP_GetValue = pluginFuncs.getvalue;
534 NPP_SetValue = pluginFuncs.setvalue;
536 // LiveConnect support
537 NPP_GetJavaClass = pluginFuncs.javaClass;
538 if (NPP_GetJavaClass){
539 LOG(LiveConnect, "%@: mach-o entry point for NPP_GetJavaClass = %p", [self name], NPP_GetJavaClass);
541 LOG(LiveConnect, "%@: no entry point for NPP_GetJavaClass", [self name]);
546 CFAbsoluteTime currentTime = CFAbsoluteTimeGetCurrent();
547 CFAbsoluteTime duration = currentTime - start;
549 LOG(Plugins, "%f Total load time: %f seconds", currentTime, duration);
554 [self unloadWithoutShutdown];
564 LOG(Plugins, "Unloading %@...", name);
568 [self unloadWithoutShutdown];
571 - (NPP_SetWindowProcPtr)NPP_SetWindow
573 return NPP_SetWindow;
576 - (NPP_NewProcPtr)NPP_New
581 - (NPP_DestroyProcPtr)NPP_Destroy
586 - (NPP_NewStreamProcPtr)NPP_NewStream
588 return NPP_NewStream;
591 - (NPP_StreamAsFileProcPtr)NPP_StreamAsFile
593 return NPP_StreamAsFile;
595 - (NPP_DestroyStreamProcPtr)NPP_DestroyStream
597 return NPP_DestroyStream;
600 - (NPP_WriteReadyProcPtr)NPP_WriteReady
602 return NPP_WriteReady;
604 - (NPP_WriteProcPtr)NPP_Write
609 - (NPP_HandleEventProcPtr)NPP_HandleEvent
611 return NPP_HandleEvent;
614 -(NPP_URLNotifyProcPtr)NPP_URLNotify
616 return NPP_URLNotify;
619 -(NPP_GetValueProcPtr)NPP_GetValue
624 -(NPP_SetValueProcPtr)NPP_SetValue
629 -(NPP_PrintProcPtr)NPP_Print
637 // function pointer converters
639 FunctionPointer functionPointerForTVector(TransitionVector tvp)
641 const uint32 temp[6] = {0x3D800000, 0x618C0000, 0x800C0000, 0x804C0004, 0x7C0903A6, 0x4E800420};
642 uint32 *newGlue = NULL;
645 newGlue = (uint32 *)malloc(sizeof(temp));
646 if (newGlue != NULL) {
648 for (i = 0; i < 6; i++) newGlue[i] = temp[i];
649 newGlue[0] |= ((UInt32)tvp >> 16);
650 newGlue[1] |= ((UInt32)tvp & 0xFFFF);
651 MakeDataExecutable(newGlue, sizeof(temp));
655 return (FunctionPointer)newGlue;
658 TransitionVector tVectorForFunctionPointer(FunctionPointer fp)
660 FunctionPointer *newGlue = NULL;
662 newGlue = (FunctionPointer *)malloc(2 * sizeof(FunctionPointer));
663 if (newGlue != NULL) {
668 return (TransitionVector)newGlue;