Selaa lähdekoodia

support builds with WebKit's NPAPI, as well as Mozilla's

David Rose 16 vuotta sitten
vanhempi
sitoutus
7ca831ae0b

+ 2 - 2
direct/src/plugin/p3dInstance.cxx

@@ -2533,14 +2533,14 @@ report_package_progress(P3DPackage *package, double progress) {
   time_t elapsed = time(NULL) - _download_begin;
   time_t elapsed = time(NULL) - _download_begin;
   _panda_script_object->set_int_property("downloadElapsedSeconds", elapsed);
   _panda_script_object->set_int_property("downloadElapsedSeconds", elapsed);
 
 
-  sprintf(buffer, "%d:%02d", elapsed / 60, elapsed % 60);
+  sprintf(buffer, "%d:%02d", (int)(elapsed / 60), (int)(elapsed % 60));
   _panda_script_object->set_string_property("downloadElapsedFormatted", buffer);
   _panda_script_object->set_string_property("downloadElapsedFormatted", buffer);
 
 
   if (progress > 0 && (elapsed > 5 || progress > 0.2)) {
   if (progress > 0 && (elapsed > 5 || progress > 0.2)) {
     time_t total = (time_t)((double)elapsed / progress);
     time_t total = (time_t)((double)elapsed / progress);
     time_t remaining = max(total, elapsed) - elapsed;
     time_t remaining = max(total, elapsed) - elapsed;
     _panda_script_object->set_int_property("downloadRemainingSeconds", remaining);
     _panda_script_object->set_int_property("downloadRemainingSeconds", remaining);
-    sprintf(buffer, "%d:%02d", remaining / 60, remaining % 60);
+    sprintf(buffer, "%d:%02d", (int)(remaining / 60), (int)(remaining % 60));
     _panda_script_object->set_string_property("downloadRemainingFormatted", buffer);
     _panda_script_object->set_string_property("downloadRemainingFormatted", buffer);
   }
   }
 }
 }

+ 17 - 1
direct/src/plugin_npapi/nppanda3d_common.h

@@ -66,10 +66,26 @@ extern string global_root_dir;
 #endif  // _WIN32, __APPLE__
 #endif  // _WIN32, __APPLE__
 
 
 #include "npapi.h"
 #include "npapi.h"
-#include "npupp.h"
+#if NP_VERSION_MAJOR == 0 && NP_VERSION_MINOR <= 19
+  #include "npupp.h"
+#else
+  // Somewhere between version 0.19 and 0.22, Mozilla renamed npupp.h to
+  // npfunctions.h.
+  #include "npfunctions.h"
+#endif
 
 
 #include "load_plugin.h"
 #include "load_plugin.h"
 
 
+// Mozilla's version of NPAPI has these names lowercase.  WebKit's
+// version has them uppercase.  What a mess.  We have to define a
+// duplicate of the structure to allow us to reference them
+// consistently.
+struct UC_NPString {
+  const NPUTF8 *UTF8Characters;
+  uint32_t UTF8Length;
+};
+
+
 // If we are building with a version of Gecko that supports the
 // If we are building with a version of Gecko that supports the
 // asynchronous callback function, we should use it--it's just so
 // asynchronous callback function, we should use it--it's just so
 // handy.
 // handy.

+ 1 - 3
direct/src/plugin_npapi/ppBrowserObject.cxx

@@ -230,9 +230,7 @@ call(const string &method_name, P3D_object *params[], int num_params) const {
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 P3D_object *PPBrowserObject::
 P3D_object *PPBrowserObject::
 eval(const string &expression) const {
 eval(const string &expression) const {
-  NPString npexpr;
-  npexpr.utf8characters = expression.c_str();
-  npexpr.utf8length = expression.length();
+  NPString npexpr = { expression.c_str(), expression.length() };
 
 
   NPVariant result;
   NPVariant result;
   if (!browser->evaluate(_instance->get_npp_instance(), _npobj, 
   if (!browser->evaluate(_instance->get_npp_instance(), _npobj, 

+ 22 - 4
direct/src/plugin_npapi/ppInstance.cxx

@@ -138,6 +138,8 @@ begin() {
     PPDownloadRequest *req = new PPDownloadRequest(PPDownloadRequest::RT_contents_file);
     PPDownloadRequest *req = new PPDownloadRequest(PPDownloadRequest::RT_contents_file);
     start_download(url, req);
     start_download(url, req);
   }
   }
+
+  handle_request_loop();
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -740,7 +742,8 @@ variant_to_p3dobj(const NPVariant *variant) {
     return P3D_new_float_object(NPVARIANT_TO_DOUBLE(*variant));
     return P3D_new_float_object(NPVARIANT_TO_DOUBLE(*variant));
   } else if (NPVARIANT_IS_STRING(*variant)) {
   } else if (NPVARIANT_IS_STRING(*variant)) {
     NPString str = NPVARIANT_TO_STRING(*variant);
     NPString str = NPVARIANT_TO_STRING(*variant);
-    return P3D_new_string_object(str.utf8characters, str.utf8length);
+    const UC_NPString &uc_str = *(UC_NPString *)(&str);
+    return P3D_new_string_object(uc_str.UTF8Characters, uc_str.UTF8Length);
   } else if (NPVARIANT_IS_OBJECT(*variant)) {
   } else if (NPVARIANT_IS_OBJECT(*variant)) {
     NPObject *object = NPVARIANT_TO_OBJECT(*variant);
     NPObject *object = NPVARIANT_TO_OBJECT(*variant);
     if (object->_class == &PPPandaObject::_object_class) {
     if (object->_class == &PPPandaObject::_object_class) {
@@ -890,7 +893,10 @@ request_ready(P3D_instance *instance) {
   // Since we are running at least Gecko 1.9, and we have this very
   // Since we are running at least Gecko 1.9, and we have this very
   // useful function, let's use it to ask the browser to call us back
   // useful function, let's use it to ask the browser to call us back
   // in the main thread.
   // in the main thread.
-  browser->pluginthreadasynccall(inst->_npp_instance, browser_sync_callback, NULL);
+  //  nout << "async: " << (void *)browser->pluginthreadasynccall << "\n";
+  if (browser->pluginthreadasynccall != 0) {
+    browser->pluginthreadasynccall(inst->_npp_instance, browser_sync_callback, NULL);
+  }
 #else  // HAS_PLUGIN_THREAD_ASYNC_CALL
 #else  // HAS_PLUGIN_THREAD_ASYNC_CALL
 
 
   // If we're using an older version of Gecko, we have to do this some
   // If we're using an older version of Gecko, we have to do this some
@@ -1245,7 +1251,8 @@ create_instance() {
                                0, NULL, this);
                                0, NULL, this);
 
 
   if (_p3d_inst != NULL) {
   if (_p3d_inst != NULL) {
-    // Now get the browser's window object, to pass to the plugin.
+    // Now get the browser's toplevel DOM object (called the "window"
+    // object in JavaScript), to pass to the plugin.
     NPObject *window_object = NULL;
     NPObject *window_object = NULL;
     if (browser->getvalue(_npp_instance, NPNVWindowNPObject,
     if (browser->getvalue(_npp_instance, NPNVWindowNPObject,
                           &window_object) == NPERR_NO_ERROR) {
                           &window_object) == NPERR_NO_ERROR) {
@@ -1298,6 +1305,11 @@ send_window() {
 #elif defined(__APPLE__)
 #elif defined(__APPLE__)
     NP_Port *port = (NP_Port *)_window.window;
     NP_Port *port = (NP_Port *)_window.window;
     parent_window._port = port->port;
     parent_window._port = port->port;
+    /*
+    NP_CGContext *context = (NP_CGContext *)_window.window;
+    parent_window._context = context->context;
+    parent_window._window = (WindowRef)context->window;
+    */
 
 
 #elif defined(HAVE_X11)
 #elif defined(HAVE_X11)
     // We make it an 'unsigned long' instead of 'Window'
     // We make it an 'unsigned long' instead of 'Window'
@@ -1321,6 +1333,11 @@ send_window() {
 #elif defined(__APPLE__)
 #elif defined(__APPLE__)
     NP_Port *port = (NP_Port *)_window.window;
     NP_Port *port = (NP_Port *)_window.window;
     parent_window._port = port->port;
     parent_window._port = port->port;
+    /*
+    NP_CGContext *context = (NP_CGContext *)_window.window;
+    parent_window._context = context->context;
+    parent_window._window = (WindowRef)context->window;
+    */
 
 
 #elif defined(HAVE_X11)
 #elif defined(HAVE_X11)
     parent_window._xwindow = 0;
     parent_window._xwindow = 0;
@@ -1428,7 +1445,8 @@ output_np_variant(ostream &out, const NPVariant &result) {
     out << "double " << NPVARIANT_TO_DOUBLE(result);
     out << "double " << NPVARIANT_TO_DOUBLE(result);
   } else if (NPVARIANT_IS_STRING(result)) {
   } else if (NPVARIANT_IS_STRING(result)) {
     NPString str = NPVARIANT_TO_STRING(result);
     NPString str = NPVARIANT_TO_STRING(result);
-    out << "string " << string(str.utf8characters, str.utf8length);
+    const UC_NPString &uc_str = *(UC_NPString *)(&str);
+    out << "string " << string(uc_str.UTF8Characters, uc_str.UTF8Length);
   } else if (NPVARIANT_IS_OBJECT(result)) {
   } else if (NPVARIANT_IS_OBJECT(result)) {
     NPObject *child = NPVARIANT_TO_OBJECT(result);
     NPObject *child = NPVARIANT_TO_OBJECT(result);
     out << "object " << child;
     out << "object " << child;

+ 57 - 8
direct/src/plugin_npapi/startup.cxx

@@ -118,9 +118,11 @@ NP_GetValue(void*, NPPVariable variable, void* value) {
     case NPPVpluginDescriptionString:
     case NPPVpluginDescriptionString:
       *(const char **)value = "Runs 3-D games and interactive applets";
       *(const char **)value = "Runs 3-D games and interactive applets";
       break;
       break;
+      /*
     case NPPVpluginNeedsXEmbed:
     case NPPVpluginNeedsXEmbed:
-      *((PRBool *)value) = PR_FALSE;
+      *((NPBool *)value) = false;
       break;
       break;
+      */
     default:
     default:
       nout << "Ignoring GetValue request " << variable << "\n";
       nout << "Ignoring GetValue request " << variable << "\n";
       return NPERR_INVALID_PARAM;
       return NPERR_INVALID_PARAM;
@@ -172,13 +174,16 @@ NP_Initialize(NPNetscapeFuncs *browserFuncs,
   int expected_major = NP_VERSION_MAJOR;
   int expected_major = NP_VERSION_MAJOR;
   int expected_minor = NP_VERSION_MINOR;
   int expected_minor = NP_VERSION_MINOR;
 
 
-  nout << "Expected version " << expected_major << "." << expected_minor
-       << "\n";
-  if (browser_major < expected_major ||
-      (browser_major == expected_major && browser_minor < expected_minor)) {
+  nout << "Plugin compiled with version "
+       << expected_major << "." << expected_minor << "\n";
+
+#ifdef HAS_PLUGIN_THREAD_ASYNC_CALL
+  // We expect to find at least version NPVERS_HAS_PLUGIN_THREAD_ASYNC_CALL.
+  if (browser_major == 0 && browser_minor < NPVERS_HAS_PLUGIN_THREAD_ASYNC_CALL) {
     nout << "Cannot run: unsupported version of NPAPI detected.\n";
     nout << "Cannot run: unsupported version of NPAPI detected.\n";
     return NPERR_GENERIC_ERROR;
     return NPERR_GENERIC_ERROR;
   }
   }
+#endif
 
 
   // Seed the lame random number generator in rand(); we use it to
   // Seed the lame random number generator in rand(); we use it to
   // select a mirror for downloading.
   // select a mirror for downloading.
@@ -200,8 +205,21 @@ NP_GetEntryPoints(NPPluginFuncs *pluginFuncs) {
   // open_logfile() also assigns global_root_dir.
   // open_logfile() also assigns global_root_dir.
   open_logfile();
   open_logfile();
   nout << "NP_GetEntryPoints, pluginFuncs = " << pluginFuncs << "\n";
   nout << "NP_GetEntryPoints, pluginFuncs = " << pluginFuncs << "\n";
-  pluginFuncs->version = 11;
-  pluginFuncs->size = sizeof(pluginFuncs);
+  if (pluginFuncs->size == 0) {
+    pluginFuncs->size = sizeof(*pluginFuncs);
+  }
+  if (pluginFuncs->size < sizeof(*pluginFuncs)) {
+    nout << "Invalid NPPPluginFuncs size\n";
+    return NPERR_INVALID_FUNCTABLE_ERROR;
+  }
+
+  // Not entirely sure what version number we should send back here.
+  // Sending the verion number of the NPAPI library we're compiled
+  // against doesn't seem 100% right, because there's no reason to
+  // think that *this* code knows about all of the functions provided
+  // by the particular library version it's compiled against.
+  pluginFuncs->version = (NP_VERSION_MAJOR << 8) | NP_VERSION_MINOR;
+
   pluginFuncs->newp = NPP_New;
   pluginFuncs->newp = NPP_New;
   pluginFuncs->destroy = NPP_Destroy;
   pluginFuncs->destroy = NPP_Destroy;
   pluginFuncs->setwindow = NPP_SetWindow;
   pluginFuncs->setwindow = NPP_SetWindow;
@@ -209,7 +227,16 @@ NP_GetEntryPoints(NPPluginFuncs *pluginFuncs) {
   pluginFuncs->destroystream = NPP_DestroyStream;
   pluginFuncs->destroystream = NPP_DestroyStream;
   pluginFuncs->asfile = NPP_StreamAsFile;
   pluginFuncs->asfile = NPP_StreamAsFile;
   pluginFuncs->writeready = NPP_WriteReady;
   pluginFuncs->writeready = NPP_WriteReady;
-  pluginFuncs->write = NPP_Write;
+
+  // WebKit's NPAPI defines the wrong prototype for this type, so we
+  // have to cast it.  But the casting typename isn't consistent
+  // between WebKit and Mozilla's NPAPI headers.
+#ifdef NewNPP_WriteProc
+  pluginFuncs->write = NewNPP_WriteProc(NPP_Write);
+#else
+  pluginFuncs->write = (NPP_WriteProcPtr)NPP_Write;
+#endif
+
   pluginFuncs->print = NPP_Print;
   pluginFuncs->print = NPP_Print;
   pluginFuncs->event = NPP_HandleEvent;
   pluginFuncs->event = NPP_HandleEvent;
   pluginFuncs->urlnotify = NPP_URLNotify;
   pluginFuncs->urlnotify = NPP_URLNotify;
@@ -246,6 +273,28 @@ NPP_New(NPMIMEType pluginType, NPP instance, uint16 mode,
         int16 argc, char *argn[], char *argv[], NPSavedData *saved) {
         int16 argc, char *argn[], char *argv[], NPSavedData *saved) {
   nout << "new instance " << instance << "\n";
   nout << "new instance " << instance << "\n";
 
 
+  /*
+#ifdef __APPLE__
+  // We have to request the "core graphics" drawing model to be
+  // compatible with Snow Leopard.
+  NPBool supportsCoreGraphics = false;
+  NPError err = browser->getvalue(instance,
+                                  NPNVsupportsCoreGraphicsBool,
+                                  &supportsCoreGraphics);
+  if (err != NPERR_NO_ERROR || !supportsCoreGraphics) {
+    return NPERR_INCOMPATIBLE_VERSION_ERROR;
+  }
+  
+  // Set the drawing model
+  err = browser->setvalue(instance,
+                          (NPPVariable)NPNVpluginDrawingModel,
+                          (void *)NPDrawingModelCoreGraphics);
+  if (err != NPERR_NO_ERROR) {
+    return NPERR_INCOMPATIBLE_VERSION_ERROR;
+  }
+#endif
+  */
+
   PPInstance *inst = new PPInstance(pluginType, instance, mode,
   PPInstance *inst = new PPInstance(pluginType, instance, mode,
                                     argc, argn, argv, saved);
                                     argc, argn, argv, saved);
   instance->pdata = inst;
   instance->pdata = inst;

+ 4 - 0
direct/src/plugin_npapi/startup.h

@@ -17,6 +17,10 @@
 
 
 #include "nppanda3d_common.h"
 #include "nppanda3d_common.h"
 
 
+#ifndef OSCALL
+#define OSCALL
+#endif
+
 extern "C" {
 extern "C" {
 #ifdef _WIN32
 #ifdef _WIN32
   NPError OSCALL NP_Initialize(NPNetscapeFuncs *browserFuncs);
   NPError OSCALL NP_Initialize(NPNetscapeFuncs *browserFuncs);