mirror of
				https://github.com/godotengine/godot.git
				synced 2025-10-31 21:51:22 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			541 lines
		
	
	
	
		
			16 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			541 lines
		
	
	
	
		
			16 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /*************************************************************************/
 | |
| /*  pepper_main.cpp                                                      */
 | |
| /*************************************************************************/
 | |
| /*                       This file is part of:                           */
 | |
| /*                           GODOT ENGINE                                */
 | |
| /*                    http://www.godotengine.org                         */
 | |
| /*************************************************************************/
 | |
| /* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur.                 */
 | |
| /*                                                                       */
 | |
| /* Permission is hereby granted, free of charge, to any person obtaining */
 | |
| /* a copy of this software and associated documentation files (the       */
 | |
| /* "Software"), to deal in the Software without restriction, including   */
 | |
| /* without limitation the rights to use, copy, modify, merge, publish,   */
 | |
| /* distribute, sublicense, and/or sell copies of the Software, and to    */
 | |
| /* permit persons to whom the Software is furnished to do so, subject to */
 | |
| /* the following conditions:                                             */
 | |
| /*                                                                       */
 | |
| /* The above copyright notice and this permission notice shall be        */
 | |
| /* included in all copies or substantial portions of the Software.       */
 | |
| /*                                                                       */
 | |
| /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
 | |
| /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
 | |
| /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
 | |
| /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
 | |
| /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
 | |
| /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
 | |
| /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
 | |
| /*************************************************************************/
 | |
|  IMPORTANT:  This Apple software is supplied to you by Apple Computer, Inc.
 | |
|  ("Apple") in consideration of your agreement to the following terms, and
 | |
|  your use, installation, modification or redistribution of this Apple software
 | |
|  constitutes acceptance of these terms.  If you do not agree with these terms,
 | |
|  please do not use, install, modify or redistribute this Apple software.
 | |
| 
 | |
|  In consideration of your agreement to abide by the following terms, and
 | |
|  subject to these terms, Apple grants you a personal, non-exclusive license,
 | |
|  under Apple's copyrights in this original Apple software
 | |
|  (the "Apple Software"), to use, reproduce, modify and redistribute the Apple
 | |
|  Software, with or without modifications, in source and/or binary forms;
 | |
|  provided that if you redistribute the Apple Software in its entirety and
 | |
|  without modifications, you must retain this notice and the following text and
 | |
|  disclaimers in all such redistributions of the Apple Software.  Neither the
 | |
|  name, trademarks, service marks or logos of Apple Computer, Inc. may be used
 | |
|  to endorse or promote products derived from the Apple Software without
 | |
|  specific prior written permission from Apple. Except as expressly stated in
 | |
|  this notice, no other rights or licenses, express or implied, are granted by
 | |
|  Apple herein, including but not limited to any patent rights that may be
 | |
|  infringed by your derivative works or by other works in which the Apple
 | |
|  Software may be incorporated.
 | |
| 
 | |
|  The Apple Software is provided by Apple on an "AS IS" basis.  APPLE MAKES NO
 | |
|  WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
 | |
|  WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 | |
|  PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
 | |
|  COMBINATION WITH YOUR PRODUCTS.
 | |
| 
 | |
|  IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
 | |
|  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 | |
|  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 | |
|  INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION
 | |
|  AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER
 | |
|  THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR
 | |
|  OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 | |
|  */
 | |
| 
 | |
| #include <stdlib.h>
 | |
| 
 | |
| #include "os_nacl.h"
 | |
| #include <GLES2/gl2.h>
 | |
| 
 | |
| #include <nacl/npupp.h>
 | |
| #include <pgl/pgl.h>
 | |
| #include <string.h>
 | |
| #include <stdint.h>
 | |
| 
 | |
| static NPNetscapeFuncs kBrowserFuncs = { 0 };
 | |
| static NPNetscapeFuncs* browser = &kBrowserFuncs;
 | |
| 
 | |
| static NPDevice* device3d_ = NULL;
 | |
| static PGLContext pgl_context_;
 | |
| static NPDeviceContext3D context3d_;
 | |
| static int width_;
 | |
| static int height_;
 | |
| 
 | |
| extern int nacl_main(int argc, char** argn, char** argv);
 | |
| extern void nacl_cleanup();
 | |
| 
 | |
| NPExtensions* extensions = NULL;
 | |
| static NPP npp_;
 | |
| 
 | |
| const int32_t kCommandBufferSize = 1024 * 1024;
 | |
| 
 | |
| // Plugin entry points
 | |
| extern "C" {
 | |
| 
 | |
| // Plugin entry points
 | |
| 
 | |
| // Entrypoints -----------------------------------------------------------------
 | |
| 
 | |
| NPError NP_GetEntryPoints(NPPluginFuncs* plugin_funcs) {
 | |
|   plugin_funcs->version = 11;
 | |
|   plugin_funcs->size = sizeof(plugin_funcs);
 | |
|   plugin_funcs->newp = NPP_New;
 | |
|   plugin_funcs->destroy = NPP_Destroy;
 | |
|   plugin_funcs->setwindow = NPP_SetWindow;
 | |
|   plugin_funcs->newstream = NPP_NewStream;
 | |
|   plugin_funcs->destroystream = NPP_DestroyStream;
 | |
|   plugin_funcs->asfile = NPP_StreamAsFile;
 | |
|   plugin_funcs->writeready = NPP_WriteReady;
 | |
|   plugin_funcs->write = (NPP_WriteUPP)NPP_Write;
 | |
|   plugin_funcs->print = NPP_Print;
 | |
|   plugin_funcs->event = NPP_HandleEvent;
 | |
|   plugin_funcs->urlnotify = NPP_URLNotify;
 | |
|   plugin_funcs->getvalue = NPP_GetValue;
 | |
|   plugin_funcs->setvalue = NPP_SetValue;
 | |
| 
 | |
|   return NPERR_NO_ERROR;
 | |
| }
 | |
| 
 | |
| NPError NP_Shutdown() {
 | |
|   pglTerminate();
 | |
|   return NPERR_NO_ERROR;
 | |
| }
 | |
| 
 | |
| NPError NP_GetValue(void* instance, NPPVariable variable, void* value);
 | |
| char* NP_GetMIMEDescription();
 | |
| 
 | |
| NPError NP_Initialize(NPNetscapeFuncs* browser_funcs,
 | |
| 							NPPluginFuncs* plugin_funcs) {
 | |
| 	printf("NPP_Initialize\n");
 | |
|   memcpy(&kBrowserFuncs, browser_funcs, sizeof(kBrowserFuncs));
 | |
|   pglInitialize();
 | |
|   return NP_GetEntryPoints(plugin_funcs);
 | |
| }
 | |
| 
 | |
| 
 | |
| }  // extern "C"
 | |
| 
 | |
| void Initialize3D() {
 | |
| 	// Initialize a 3D context.
 | |
| 	NPDeviceContext3DConfig config;
 | |
| 	config.commandBufferSize = kCommandBufferSize;
 | |
| 	NPError err = device3d_->initializeContext(npp_, &config, &context3d_);
 | |
| 	if (err != NPERR_NO_ERROR) {
 | |
| 		printf("Failed to initialize 3D context\n");
 | |
| 		exit(1);
 | |
| 	}
 | |
| 
 | |
| 	// Create a PGL context.
 | |
| 	pgl_context_ = pglCreateContext(npp_, device3d_, &context3d_);
 | |
| 
 | |
| 	// Initialize the demo GL state.
 | |
| 	//pglMakeCurrent(pgl_context_);
 | |
| 	//GLFromCPPInit();
 | |
| 	//pglMakeCurrent(NULL);
 | |
| }
 | |
| 
 | |
| NPError NPP_New(NPMIMEType pluginType,
 | |
|                 NPP instance,
 | |
| 				uint16_t mode,
 | |
| 				int16_t argc, char* argn[], char* argv[],
 | |
|                 NPSavedData* saved) {
 | |
| 	printf("NPP_New\n");
 | |
| 	if (browser->version >= 14) {
 | |
| 
 | |
| 		npp_ = instance;
 | |
| 		if (!extensions) {
 | |
| 			browser->getvalue(npp_, NPNVPepperExtensions,
 | |
| 			reinterpret_cast<void*>(&extensions));
 | |
| 			// CHECK(extensions);
 | |
| 		}
 | |
| 
 | |
| 		printf("%s: %i\n", __FUNCTION__, __LINE__);
 | |
| 
 | |
| 		device3d_ = extensions->acquireDevice(npp_, NPPepper3DDevice);
 | |
| 		if (device3d_ == NULL) {
 | |
| 			printf("Failed to acquire 3DDevice\n");
 | |
| 			exit(1);
 | |
| 		}
 | |
| 		printf("%s: %i\n", __FUNCTION__, __LINE__);
 | |
| 
 | |
| 		/*
 | |
| 		deviceaudio_ = extensions->acquireDevice(npp_, NPPepperAudioDevice);
 | |
| 		if (deviceaudio_ == NULL) {
 | |
| 			printf("Failed to acquire AudioDevice\n");
 | |
| 			exit(1);
 | |
| 		}
 | |
| 		*/
 | |
| 		Initialize3D();
 | |
| 		pglMakeCurrent(pgl_context_);
 | |
| 		nacl_main(argc, argn, argv);
 | |
| 		pglMakeCurrent(NULL);
 | |
| 	};
 | |
| 
 | |
|   return NPERR_NO_ERROR;
 | |
| }
 | |
| 
 | |
| NPError NPP_Destroy(NPP instance, NPSavedData** save) {
 | |
| 
 | |
| 	nacl_cleanup();
 | |
| 	
 | |
| 	return NPERR_NO_ERROR;
 | |
| }
 | |
| 
 | |
| void Destroy3D() {
 | |
| 	printf("destroy 3d\n");
 | |
| 	// Destroy the PGL context.
 | |
| 	pglDestroyContext(pgl_context_);
 | |
| 	pgl_context_ = NULL;
 | |
| 
 | |
| 	// Destroy the Device3D context.
 | |
| 	device3d_->destroyContext(npp_, &context3d_);
 | |
| }
 | |
| 
 | |
| static void iteration(void* data) {
 | |
| 
 | |
| 	(void)data;
 | |
| 	OSNacl* os = (OSNacl*)OS::get_singleton();
 | |
| 
 | |
| 	if (!pglMakeCurrent(pgl_context_) && pglGetError() == PGL_CONTEXT_LOST) {
 | |
| 		printf("******* Lost context! :O\n");
 | |
| 		Destroy3D();
 | |
| 		Initialize3D();
 | |
| 		pglMakeCurrent(pgl_context_);
 | |
| 	}
 | |
| 
 | |
| 	glViewport(0, 0, width_, height_);
 | |
| 
 | |
| 	os->iterate();
 | |
| 
 | |
| 	pglSwapBuffers();
 | |
| 	pglMakeCurrent(NULL);
 | |
| 
 | |
| 	browser->pluginthreadasynccall(npp_, iteration, NULL);
 | |
| };
 | |
| 
 | |
| NPError NPP_SetWindow(NPP instance, NPWindow* window) {
 | |
| 
 | |
| 	width_ = window->width;
 | |
| 	height_ = window->height;
 | |
| 
 | |
| 	if (!pgl_context_)
 | |
| 		Initialize3D();
 | |
| 
 | |
| 	// Schedule the first call to Draw.
 | |
| 	OSNacl* os = (OSNacl*)OS::get_singleton();
 | |
| 	OS::VideoMode vm;
 | |
| 	vm.width = width_;
 | |
| 	vm.height = height_;
 | |
| 	vm.resizable = false;
 | |
| 	vm.fullscreen = false;
 | |
| 	os->set_video_mode(vm);
 | |
| 
 | |
| 	browser->pluginthreadasynccall(npp_, iteration, NULL);
 | |
| 
 | |
| 	return NPERR_NO_ERROR;
 | |
| }
 | |
| 
 | |
| NPError NPP_NewStream(NPP instance,
 | |
|                       NPMIMEType type,
 | |
|                       NPStream* stream,
 | |
|                       NPBool seekable,
 | |
| 					  uint16_t* stype) {
 | |
|   *stype = NP_ASFILEONLY;
 | |
|   return NPERR_NO_ERROR;
 | |
| }
 | |
| 
 | |
| NPError NPP_DestroyStream(NPP instance, NPStream* stream, NPReason reason) {
 | |
|   return NPERR_NO_ERROR;
 | |
| }
 | |
| 
 | |
| void NPP_StreamAsFile(NPP instance, NPStream* stream, const char* fname) {
 | |
| }
 | |
| 
 | |
| int32_t NPP_Write(NPP instance,
 | |
|                 NPStream* stream,
 | |
| 				int32_t offset,
 | |
| 				int32_t len,
 | |
|                 void* buffer) {
 | |
|   return 0;
 | |
| }
 | |
| 
 | |
| int32_t NPP_WriteReady(NPP instance, NPStream* stream) {
 | |
|   return 0;
 | |
| }
 | |
| 
 | |
| void NPP_Print(NPP instance, NPPrint* platformPrint) {
 | |
| }
 | |
| 
 | |
| int16_t NPP_HandleEvent(NPP instance, void* event) {
 | |
| 
 | |
| 	OSNacl* os = (OSNacl*)OS::get_singleton();
 | |
| 	os->handle_event(event);
 | |
| 	return 1;
 | |
| }
 | |
| 
 | |
| void NPP_URLNotify(NPP instance,
 | |
|                    const char* url,
 | |
|                    NPReason reason,
 | |
|                    void* notify_data) {
 | |
|   // PluginObject* obj = static_cast<PluginObject*>(instance->pdata);
 | |
| }
 | |
| 
 | |
| static NPObject* Allocate(NPP npp, NPClass* npclass) {
 | |
|   return new NPObject;
 | |
| }
 | |
| 
 | |
| static void Deallocate(NPObject* object) {
 | |
|   delete object;
 | |
| }
 | |
| 
 | |
| // Return |true| if |method_name| is a recognized method.
 | |
| static bool HasMethod(NPObject* obj, NPIdentifier method_name) {
 | |
| 
 | |
|   char *name = NPN_UTF8FromIdentifier(method_name);
 | |
|   bool is_method = false;
 | |
|   if (strcmp((const char *)name, "start_package") == 0) {
 | |
| 	is_method = true;
 | |
|   } else if (strcmp((const char*)name, "add_package_chunk") == 0) {
 | |
| 	is_method = true;
 | |
|   } else if (strcmp((const char*)name, "end_package") == 0) {
 | |
| 	is_method = true;
 | |
|   } else if (strcmp((const char*)name, "start_scene") == 0) {
 | |
| 	is_method = true;
 | |
|   }
 | |
|   NPN_MemFree(name);
 | |
|   return is_method;
 | |
| }
 | |
| 
 | |
| // I don't know what this is
 | |
| static bool InvokeDefault(NPObject *obj, const NPVariant *args,
 | |
| 						  uint32_t argCount, NPVariant *result) {
 | |
|   if (result) {
 | |
| 	NULL_TO_NPVARIANT(*result);
 | |
|   }
 | |
|   return true;
 | |
| }
 | |
| 
 | |
| static uint8_t* mem = NULL;
 | |
| static int pkg_size = 0;
 | |
| static String pkgname;
 | |
| 
 | |
| static bool variant_is_number(const NPVariant& v) {
 | |
| 
 | |
| 	switch (v.type) {
 | |
| 
 | |
| 	case NPVariantType_Int32:
 | |
| 	case NPVariantType_Double:
 | |
| 		return true;
 | |
| 
 | |
| 	default:
 | |
| 		return false;
 | |
| 	}
 | |
| 	return false;
 | |
| };
 | |
| 
 | |
| static double variant_as_number(const NPVariant& v) {
 | |
| 
 | |
| 	switch (v.type) {
 | |
| 
 | |
| 	case NPVariantType_Int32:
 | |
| 		return (double)v.value.intValue;
 | |
| 	case NPVariantType_Double:
 | |
| 		return (double)v.value.doubleValue;
 | |
| 	default:
 | |
| 		return 0;
 | |
| 	}
 | |
| 
 | |
| 	return 0;
 | |
| };
 | |
| 
 | |
| // Invoke() is called by the browser to invoke a function object whose name
 | |
| // is |method_name|.
 | |
| static bool Invoke(NPObject* obj,
 | |
| 				   NPIdentifier method_name,
 | |
| 				   const NPVariant *args,
 | |
| 				   uint32_t arg_count,
 | |
| 				   NPVariant *result) {
 | |
|   NULL_TO_NPVARIANT(*result);
 | |
|   char *name = NPN_UTF8FromIdentifier(method_name);
 | |
|   if (name == NULL)
 | |
| 	return false;
 | |
|   bool rval = false;
 | |
| 
 | |
|   OSNacl* os = (OSNacl*)OS::get_singleton();
 | |
| 
 | |
|   if (strcmp(name, "start_package") == 0) {
 | |
| 
 | |
| 	  printf("arg count is %i\n", arg_count);
 | |
| 	  for (int i=0; i<arg_count; i++) {
 | |
| 		  printf("type for %i is %i\n", i, args[i].type);
 | |
| 	  }
 | |
| 	  if (arg_count != 2) {
 | |
| 		  return false;	// assuming "false" means error
 | |
| 	  };
 | |
| 
 | |
| 	  if (args[0].type != NPVariantType_String) {
 | |
| 		  printf("arg 0 not string type %i\n", args[1].type);
 | |
| 		  return false;
 | |
| 	  };
 | |
| 
 | |
| 	  if (!variant_is_number(args[1])) {
 | |
| 
 | |
| 		  printf("arg 1 not number, type %i\n", args[1].type);
 | |
| 		  return false;
 | |
| 	  };
 | |
| 
 | |
| 	  pkgname = String::utf8(args[0].value.stringValue.UTF8Characters, args[0].value.stringValue.UTF8Length);
 | |
| 	  pkg_size = (int)variant_as_number(args[1]);
 | |
| 	  mem = (uint8_t*)malloc(pkg_size);
 | |
| 
 | |
| 	  printf("args %ls, %lf\n", pkgname.c_str(), variant_as_number(args[1]));
 | |
| 
 | |
| 	  return true;
 | |
|   };
 | |
| 
 | |
|   if (strcmp(name, "add_package_chunk") == 0) {
 | |
| 
 | |
| 	  if (arg_count != 3) { // assuming arg_count starts from 1
 | |
| 		  return false;	// assuming "false" means error
 | |
| 	  };
 | |
| 
 | |
| 	  if (!variant_is_number(args[0])) return false;
 | |
| 	  if (args[1].type != NPVariantType_String) return false;
 | |
| 	  if (!variant_is_number(args[2])) return false;
 | |
| 
 | |
| 	  if (!mem)
 | |
| 		  return false;
 | |
| 
 | |
| 	  int ofs = variant_as_number(args[0]);
 | |
| 	  int len = variant_as_number(args[2]);
 | |
| 
 | |
| 	  String s;
 | |
| 	  if (s.parse_utf8(args[1].value.stringValue.UTF8Characters, args[1].value.stringValue.UTF8Length)) {
 | |
| 		  printf("error parsing?\n");
 | |
| 	  };
 | |
| 	  uint8_t* dst = mem + ofs;
 | |
| 	  for (int i=0; i<len; i++) {
 | |
| 
 | |
| 		  dst[i] = s[i];
 | |
| 	  };
 | |
| 
 | |
| 	  //memcpy(mem + ofs, args[1].value.stringValue.UTF8Characters, len);
 | |
| 	  return true;
 | |
|   };
 | |
| 
 | |
|   if (strcmp(name, "end_package") == 0) {
 | |
| 
 | |
| 	  os->add_package(pkgname, mem, pkg_size);
 | |
| 	  return true;
 | |
|   };
 | |
| 
 | |
| 
 | |
|   if (strcmp(name, "start_scene") == 0) {
 | |
| printf("start_scene!\n");
 | |
| 	  if (arg_count != 1) {
 | |
| 		  return false;
 | |
| 	  };
 | |
| 
 | |
| 	  if (args[0].type != NPVariantType_String) return false;
 | |
| printf("calling with param %s\n", args[0].value.stringValue.UTF8Characters);
 | |
| 
 | |
| 	printf("pepper iteration\n");
 | |
| 	if (!pglMakeCurrent(pgl_context_) && pglGetError() == PGL_CONTEXT_LOST) {
 | |
| 		printf("******* Lost context! :O\n");
 | |
| 		Destroy3D();
 | |
| 		Initialize3D();
 | |
| 		pglMakeCurrent(pgl_context_);
 | |
| 	}
 | |
| 	os->start_scene(String::utf8(args[0].value.stringValue.UTF8Characters));
 | |
| 	pglSwapBuffers();
 | |
| 	pglMakeCurrent(NULL);
 | |
| 
 | |
| printf("returning true\n");
 | |
| 	  return true;
 | |
|   };
 | |
| 
 | |
|   NPN_MemFree(name);
 | |
| 
 | |
|   return rval;
 | |
| }
 | |
| 
 | |
| 
 | |
| static NPClass GodotClass = {
 | |
|   NP_CLASS_STRUCT_VERSION,
 | |
|   Allocate,
 | |
|   Deallocate,
 | |
|   NULL,  // Invalidate is not implemented
 | |
|   HasMethod,
 | |
|   Invoke,
 | |
|   InvokeDefault,
 | |
|   NULL,  // HasProperty is not implemented
 | |
|   NULL,  // GetProperty is not implemented
 | |
|   NULL,  // SetProperty is not implemented
 | |
| };
 | |
| 
 | |
| static NPObject* npobject = NULL;
 | |
| 
 | |
| NPError NPP_GetValue(NPP instance, NPPVariable variable, void* value) {
 | |
|   NPError err = NPERR_NO_ERROR;
 | |
| 
 | |
|   switch (variable) {
 | |
|     case NPPVpluginNameString:
 | |
|       *(reinterpret_cast<const char**>(value)) = "Pepper Test PlugIn";
 | |
|       break;
 | |
|     case NPPVpluginDescriptionString:
 | |
|       *(reinterpret_cast<const char**>(value)) =
 | |
|           "Simple Pepper plug-in for manual testing.";
 | |
|       break;
 | |
|     case NPPVpluginNeedsXEmbed:
 | |
| 	  *(reinterpret_cast<NPBool*>(value)) = 1;
 | |
|       break;
 | |
| 	case NPPVpluginScriptableNPObject: {
 | |
| 	  if (npobject == NULL) {
 | |
| 		  npobject = NPN_CreateObject(instance, &GodotClass);
 | |
| 	  } else {
 | |
| 		  NPN_RetainObject(npobject);
 | |
| 	  };
 | |
| 	  void** v = reinterpret_cast<void**>(value);
 | |
| 	  *v = npobject;
 | |
| 	} break;
 | |
|     default:
 | |
|       fprintf(stderr, "Unhandled variable to NPP_GetValue\n");
 | |
|       err = NPERR_GENERIC_ERROR;
 | |
|       break;
 | |
|   }
 | |
| 
 | |
|   return err;
 | |
| }
 | |
| 
 | |
| NPError NPP_SetValue(NPP instance, NPNVariable variable, void* value) {
 | |
|   return NPERR_GENERIC_ERROR;
 | |
| }
 | |
| 
 | |
| NPError NP_GetValue(void* instance, NPPVariable variable, void* value) {
 | |
|   return NPP_GetValue(reinterpret_cast<NPP>(instance), variable, value);
 | |
| }
 | |
| 
 | |
| char* NP_GetMIMEDescription() {
 | |
|   return const_cast<char*>("pepper-application/x-pepper-test-plugin;");
 | |
| }
 | 
