pepper_main.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542
  1. /*************************************************************************/
  2. /* pepper_main.cpp */
  3. /*************************************************************************/
  4. /* This file is part of: */
  5. /* GODOT ENGINE */
  6. /* http://www.godotengine.org */
  7. /*************************************************************************/
  8. /* Copyright (c) 2007-2015 Juan Linietsky, Ariel Manzur. */
  9. /* */
  10. /* Permission is hereby granted, free of charge, to any person obtaining */
  11. /* a copy of this software and associated documentation files (the */
  12. /* "Software"), to deal in the Software without restriction, including */
  13. /* without limitation the rights to use, copy, modify, merge, publish, */
  14. /* distribute, sublicense, and/or sell copies of the Software, and to */
  15. /* permit persons to whom the Software is furnished to do so, subject to */
  16. /* the following conditions: */
  17. /* */
  18. /* The above copyright notice and this permission notice shall be */
  19. /* included in all copies or substantial portions of the Software. */
  20. /* */
  21. /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
  22. /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
  23. /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
  24. /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
  25. /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
  26. /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
  27. /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
  28. /*************************************************************************/
  29. IMPORTANT: This Apple software is supplied to you by Apple Computer, Inc.
  30. ("Apple") in consideration of your agreement to the following terms, and
  31. your use, installation, modification or redistribution of this Apple software
  32. constitutes acceptance of these terms. If you do not agree with these terms,
  33. please do not use, install, modify or redistribute this Apple software.
  34. In consideration of your agreement to abide by the following terms, and
  35. subject to these terms, Apple grants you a personal, non-exclusive license,
  36. under Apple's copyrights in this original Apple software
  37. (the "Apple Software"), to use, reproduce, modify and redistribute the Apple
  38. Software, with or without modifications, in source and/or binary forms;
  39. provided that if you redistribute the Apple Software in its entirety and
  40. without modifications, you must retain this notice and the following text and
  41. disclaimers in all such redistributions of the Apple Software. Neither the
  42. name, trademarks, service marks or logos of Apple Computer, Inc. may be used
  43. to endorse or promote products derived from the Apple Software without
  44. specific prior written permission from Apple. Except as expressly stated in
  45. this notice, no other rights or licenses, express or implied, are granted by
  46. Apple herein, including but not limited to any patent rights that may be
  47. infringed by your derivative works or by other works in which the Apple
  48. Software may be incorporated.
  49. The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES NO
  50. WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED
  51. WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  52. PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN
  53. COMBINATION WITH YOUR PRODUCTS.
  54. IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR
  55. CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  56. SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  57. INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION
  58. AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER
  59. THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR
  60. OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  61. */
  62. #include <stdlib.h>
  63. #include "os_nacl.h"
  64. #include <GLES2/gl2.h>
  65. #include <nacl/npupp.h>
  66. #include <pgl/pgl.h>
  67. #include <string.h>
  68. #include <stdint.h>
  69. static NPNetscapeFuncs kBrowserFuncs = { 0 };
  70. static NPNetscapeFuncs* browser = &kBrowserFuncs;
  71. static NPDevice* device3d_ = NULL;
  72. static PGLContext pgl_context_;
  73. static NPDeviceContext3D context3d_;
  74. static int width_;
  75. static int height_;
  76. extern int nacl_main(int argc, char** argn, char** argv);
  77. extern void nacl_cleanup();
  78. NPExtensions* extensions = NULL;
  79. static NPP npp_;
  80. const int32_t kCommandBufferSize = 1024 * 1024;
  81. // Plugin entry points
  82. extern "C" {
  83. // Plugin entry points
  84. // Entrypoints -----------------------------------------------------------------
  85. NPError NP_GetEntryPoints(NPPluginFuncs* plugin_funcs) {
  86. plugin_funcs->version = 11;
  87. plugin_funcs->size = sizeof(plugin_funcs);
  88. plugin_funcs->newp = NPP_New;
  89. plugin_funcs->destroy = NPP_Destroy;
  90. plugin_funcs->setwindow = NPP_SetWindow;
  91. plugin_funcs->newstream = NPP_NewStream;
  92. plugin_funcs->destroystream = NPP_DestroyStream;
  93. plugin_funcs->asfile = NPP_StreamAsFile;
  94. plugin_funcs->writeready = NPP_WriteReady;
  95. plugin_funcs->write = (NPP_WriteUPP)NPP_Write;
  96. plugin_funcs->print = NPP_Print;
  97. plugin_funcs->event = NPP_HandleEvent;
  98. plugin_funcs->urlnotify = NPP_URLNotify;
  99. plugin_funcs->getvalue = NPP_GetValue;
  100. plugin_funcs->setvalue = NPP_SetValue;
  101. return NPERR_NO_ERROR;
  102. }
  103. NPError NP_Shutdown() {
  104. pglTerminate();
  105. return NPERR_NO_ERROR;
  106. }
  107. NPError NP_GetValue(void* instance, NPPVariable variable, void* value);
  108. char* NP_GetMIMEDescription();
  109. NPError NP_Initialize(NPNetscapeFuncs* browser_funcs,
  110. NPPluginFuncs* plugin_funcs) {
  111. printf("NPP_Initialize\n");
  112. memcpy(&kBrowserFuncs, browser_funcs, sizeof(kBrowserFuncs));
  113. pglInitialize();
  114. return NP_GetEntryPoints(plugin_funcs);
  115. }
  116. } // extern "C"
  117. void Initialize3D() {
  118. // Initialize a 3D context.
  119. NPDeviceContext3DConfig config;
  120. config.commandBufferSize = kCommandBufferSize;
  121. NPError err = device3d_->initializeContext(npp_, &config, &context3d_);
  122. if (err != NPERR_NO_ERROR) {
  123. printf("Failed to initialize 3D context\n");
  124. exit(1);
  125. }
  126. // Create a PGL context.
  127. pgl_context_ = pglCreateContext(npp_, device3d_, &context3d_);
  128. // Initialize the demo GL state.
  129. //pglMakeCurrent(pgl_context_);
  130. //GLFromCPPInit();
  131. //pglMakeCurrent(NULL);
  132. }
  133. NPError NPP_New(NPMIMEType pluginType,
  134. NPP instance,
  135. uint16_t mode,
  136. int16_t argc, char* argn[], char* argv[],
  137. NPSavedData* saved) {
  138. printf("NPP_New\n");
  139. if (browser->version >= 14) {
  140. npp_ = instance;
  141. if (!extensions) {
  142. browser->getvalue(npp_, NPNVPepperExtensions,
  143. reinterpret_cast<void*>(&extensions));
  144. // CHECK(extensions);
  145. }
  146. printf("%s: %i\n", __FUNCTION__, __LINE__);
  147. device3d_ = extensions->acquireDevice(npp_, NPPepper3DDevice);
  148. if (device3d_ == NULL) {
  149. printf("Failed to acquire 3DDevice\n");
  150. exit(1);
  151. }
  152. printf("%s: %i\n", __FUNCTION__, __LINE__);
  153. /*
  154. deviceaudio_ = extensions->acquireDevice(npp_, NPPepperAudioDevice);
  155. if (deviceaudio_ == NULL) {
  156. printf("Failed to acquire AudioDevice\n");
  157. exit(1);
  158. }
  159. */
  160. Initialize3D();
  161. pglMakeCurrent(pgl_context_);
  162. nacl_main(argc, argn, argv);
  163. pglMakeCurrent(NULL);
  164. };
  165. return NPERR_NO_ERROR;
  166. }
  167. NPError NPP_Destroy(NPP instance, NPSavedData** save) {
  168. nacl_cleanup();
  169. return NPERR_NO_ERROR;
  170. }
  171. void Destroy3D() {
  172. printf("destroy 3d\n");
  173. // Destroy the PGL context.
  174. pglDestroyContext(pgl_context_);
  175. pgl_context_ = NULL;
  176. // Destroy the Device3D context.
  177. device3d_->destroyContext(npp_, &context3d_);
  178. }
  179. static void iteration(void* data) {
  180. (void)data;
  181. OSNacl* os = (OSNacl*)OS::get_singleton();
  182. if (!pglMakeCurrent(pgl_context_) && pglGetError() == PGL_CONTEXT_LOST) {
  183. printf("******* Lost context! :O\n");
  184. Destroy3D();
  185. Initialize3D();
  186. pglMakeCurrent(pgl_context_);
  187. }
  188. glViewport(0, 0, width_, height_);
  189. os->iterate();
  190. pglSwapBuffers();
  191. pglMakeCurrent(NULL);
  192. browser->pluginthreadasynccall(npp_, iteration, NULL);
  193. };
  194. NPError NPP_SetWindow(NPP instance, NPWindow* window) {
  195. width_ = window->width;
  196. height_ = window->height;
  197. if (!pgl_context_)
  198. Initialize3D();
  199. // Schedule the first call to Draw.
  200. OSNacl* os = (OSNacl*)OS::get_singleton();
  201. OS::VideoMode vm;
  202. vm.width = width_;
  203. vm.height = height_;
  204. vm.resizable = false;
  205. vm.fullscreen = false;
  206. os->set_video_mode(vm);
  207. browser->pluginthreadasynccall(npp_, iteration, NULL);
  208. return NPERR_NO_ERROR;
  209. }
  210. NPError NPP_NewStream(NPP instance,
  211. NPMIMEType type,
  212. NPStream* stream,
  213. NPBool seekable,
  214. uint16_t* stype) {
  215. *stype = NP_ASFILEONLY;
  216. return NPERR_NO_ERROR;
  217. }
  218. NPError NPP_DestroyStream(NPP instance, NPStream* stream, NPReason reason) {
  219. return NPERR_NO_ERROR;
  220. }
  221. void NPP_StreamAsFile(NPP instance, NPStream* stream, const char* fname) {
  222. }
  223. int32_t NPP_Write(NPP instance,
  224. NPStream* stream,
  225. int32_t offset,
  226. int32_t len,
  227. void* buffer) {
  228. return 0;
  229. }
  230. int32_t NPP_WriteReady(NPP instance, NPStream* stream) {
  231. return 0;
  232. }
  233. void NPP_Print(NPP instance, NPPrint* platformPrint) {
  234. }
  235. int16_t NPP_HandleEvent(NPP instance, void* event) {
  236. OSNacl* os = (OSNacl*)OS::get_singleton();
  237. os->handle_event(event);
  238. return 1;
  239. }
  240. void NPP_URLNotify(NPP instance,
  241. const char* url,
  242. NPReason reason,
  243. void* notify_data) {
  244. // PluginObject* obj = static_cast<PluginObject*>(instance->pdata);
  245. }
  246. static NPObject* Allocate(NPP npp, NPClass* npclass) {
  247. return new NPObject;
  248. }
  249. static void Deallocate(NPObject* object) {
  250. delete object;
  251. }
  252. // Return |true| if |method_name| is a recognized method.
  253. static bool HasMethod(NPObject* obj, NPIdentifier method_name) {
  254. char *name = NPN_UTF8FromIdentifier(method_name);
  255. bool is_method = false;
  256. if (strcmp((const char *)name, "start_package") == 0) {
  257. is_method = true;
  258. } else if (strcmp((const char*)name, "add_package_chunk") == 0) {
  259. is_method = true;
  260. } else if (strcmp((const char*)name, "end_package") == 0) {
  261. is_method = true;
  262. } else if (strcmp((const char*)name, "start_scene") == 0) {
  263. is_method = true;
  264. }
  265. NPN_MemFree(name);
  266. return is_method;
  267. }
  268. // I don't know what this is
  269. static bool InvokeDefault(NPObject *obj, const NPVariant *args,
  270. uint32_t argCount, NPVariant *result) {
  271. if (result) {
  272. NULL_TO_NPVARIANT(*result);
  273. }
  274. return true;
  275. }
  276. static uint8_t* mem = NULL;
  277. static int pkg_size = 0;
  278. static String pkgname;
  279. static bool variant_is_number(const NPVariant& v) {
  280. switch (v.type) {
  281. case NPVariantType_Int32:
  282. case NPVariantType_Double:
  283. return true;
  284. default:
  285. return false;
  286. }
  287. return false;
  288. };
  289. static double variant_as_number(const NPVariant& v) {
  290. switch (v.type) {
  291. case NPVariantType_Int32:
  292. return (double)v.value.intValue;
  293. case NPVariantType_Double:
  294. return (double)v.value.doubleValue;
  295. default:
  296. return 0;
  297. }
  298. return 0;
  299. };
  300. // Invoke() is called by the browser to invoke a function object whose name
  301. // is |method_name|.
  302. static bool Invoke(NPObject* obj,
  303. NPIdentifier method_name,
  304. const NPVariant *args,
  305. uint32_t arg_count,
  306. NPVariant *result) {
  307. NULL_TO_NPVARIANT(*result);
  308. char *name = NPN_UTF8FromIdentifier(method_name);
  309. if (name == NULL)
  310. return false;
  311. bool rval = false;
  312. OSNacl* os = (OSNacl*)OS::get_singleton();
  313. if (strcmp(name, "start_package") == 0) {
  314. printf("arg count is %i\n", arg_count);
  315. for (int i=0; i<arg_count; i++) {
  316. printf("type for %i is %i\n", i, args[i].type);
  317. }
  318. if (arg_count != 2) {
  319. return false; // assuming "false" means error
  320. };
  321. if (args[0].type != NPVariantType_String) {
  322. printf("arg 0 not string type %i\n", args[1].type);
  323. return false;
  324. };
  325. if (!variant_is_number(args[1])) {
  326. printf("arg 1 not number, type %i\n", args[1].type);
  327. return false;
  328. };
  329. pkgname = String::utf8(args[0].value.stringValue.UTF8Characters, args[0].value.stringValue.UTF8Length);
  330. pkg_size = (int)variant_as_number(args[1]);
  331. mem = (uint8_t*)malloc(pkg_size);
  332. printf("args %ls, %lf\n", pkgname.c_str(), variant_as_number(args[1]));
  333. return true;
  334. };
  335. if (strcmp(name, "add_package_chunk") == 0) {
  336. if (arg_count != 3) { // assuming arg_count starts from 1
  337. return false; // assuming "false" means error
  338. };
  339. if (!variant_is_number(args[0])) return false;
  340. if (args[1].type != NPVariantType_String) return false;
  341. if (!variant_is_number(args[2])) return false;
  342. if (!mem)
  343. return false;
  344. int ofs = variant_as_number(args[0]);
  345. int len = variant_as_number(args[2]);
  346. String s;
  347. if (s.parse_utf8(args[1].value.stringValue.UTF8Characters, args[1].value.stringValue.UTF8Length)) {
  348. printf("error parsing?\n");
  349. };
  350. uint8_t* dst = mem + ofs;
  351. for (int i=0; i<len; i++) {
  352. dst[i] = s[i];
  353. };
  354. //memcpy(mem + ofs, args[1].value.stringValue.UTF8Characters, len);
  355. return true;
  356. };
  357. if (strcmp(name, "end_package") == 0) {
  358. os->add_package(pkgname, mem, pkg_size);
  359. return true;
  360. };
  361. if (strcmp(name, "start_scene") == 0) {
  362. printf("start_scene!\n");
  363. if (arg_count != 1) {
  364. return false;
  365. };
  366. if (args[0].type != NPVariantType_String) return false;
  367. printf("calling with param %s\n", args[0].value.stringValue.UTF8Characters);
  368. printf("pepper iteration\n");
  369. if (!pglMakeCurrent(pgl_context_) && pglGetError() == PGL_CONTEXT_LOST) {
  370. printf("******* Lost context! :O\n");
  371. Destroy3D();
  372. Initialize3D();
  373. pglMakeCurrent(pgl_context_);
  374. }
  375. os->start_scene(String::utf8(args[0].value.stringValue.UTF8Characters));
  376. pglSwapBuffers();
  377. pglMakeCurrent(NULL);
  378. printf("returning true\n");
  379. return true;
  380. };
  381. NPN_MemFree(name);
  382. return rval;
  383. }
  384. static NPClass GodotClass = {
  385. NP_CLASS_STRUCT_VERSION,
  386. Allocate,
  387. Deallocate,
  388. NULL, // Invalidate is not implemented
  389. HasMethod,
  390. Invoke,
  391. InvokeDefault,
  392. NULL, // HasProperty is not implemented
  393. NULL, // GetProperty is not implemented
  394. NULL, // SetProperty is not implemented
  395. };
  396. static NPObject* npobject = NULL;
  397. NPError NPP_GetValue(NPP instance, NPPVariable variable, void* value) {
  398. NPError err = NPERR_NO_ERROR;
  399. switch (variable) {
  400. case NPPVpluginNameString:
  401. *(reinterpret_cast<const char**>(value)) = "Pepper Test PlugIn";
  402. break;
  403. case NPPVpluginDescriptionString:
  404. *(reinterpret_cast<const char**>(value)) =
  405. "Simple Pepper plug-in for manual testing.";
  406. break;
  407. case NPPVpluginNeedsXEmbed:
  408. *(reinterpret_cast<NPBool*>(value)) = 1;
  409. break;
  410. case NPPVpluginScriptableNPObject: {
  411. if (npobject == NULL) {
  412. npobject = NPN_CreateObject(instance, &GodotClass);
  413. } else {
  414. NPN_RetainObject(npobject);
  415. };
  416. void** v = reinterpret_cast<void**>(value);
  417. *v = npobject;
  418. } break;
  419. default:
  420. fprintf(stderr, "Unhandled variable to NPP_GetValue\n");
  421. err = NPERR_GENERIC_ERROR;
  422. break;
  423. }
  424. return err;
  425. }
  426. NPError NPP_SetValue(NPP instance, NPNVariable variable, void* value) {
  427. return NPERR_GENERIC_ERROR;
  428. }
  429. NPError NP_GetValue(void* instance, NPPVariable variable, void* value) {
  430. return NPP_GetValue(reinterpret_cast<NPP>(instance), variable, value);
  431. }
  432. char* NP_GetMIMEDescription() {
  433. return const_cast<char*>("pepper-application/x-pepper-test-plugin;");
  434. }