jat@google.com | 134be54 | 2009-08-03 15:30:11 +0000 | [diff] [blame] | 1 | /* ***** BEGIN LICENSE BLOCK ***** |
| 2 | * Version: NPL 1.1/GPL 2.0/LGPL 2.1 |
| 3 | * |
| 4 | * The contents of this file are subject to the Netscape Public License |
| 5 | * Version 1.1 (the "License"); you may not use this file except in |
| 6 | * compliance with the License. You may obtain a copy of the License at |
| 7 | * http://www.mozilla.org/NPL/ |
| 8 | * |
| 9 | * Software distributed under the License is distributed on an "AS IS" basis, |
| 10 | * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License |
| 11 | * for the specific language governing rights and limitations under the |
| 12 | * License. |
| 13 | * |
| 14 | * The Original Code is mozilla.org code. |
| 15 | * |
| 16 | * The Initial Developer of the Original Code is |
| 17 | * Netscape Communications Corporation. |
| 18 | * Portions created by the Initial Developer are Copyright (C) 1998 |
| 19 | * the Initial Developer. All Rights Reserved. |
| 20 | * |
| 21 | * Contributor(s): |
| 22 | * |
| 23 | * Alternatively, the contents of this file may be used under the terms of |
| 24 | * either the GNU General Public License Version 2 or later (the "GPL"), or |
| 25 | * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), |
| 26 | * in which case the provisions of the GPL or the LGPL are applicable instead |
| 27 | * of those above. If you wish to allow use of your version of this file only |
| 28 | * under the terms of either the GPL or the LGPL, and not to allow others to |
| 29 | * use your version of this file under the terms of the NPL, indicate your |
| 30 | * decision by deleting the provisions above and replace them with the notice |
| 31 | * and other provisions required by the GPL or the LGPL. If you do not delete |
| 32 | * the provisions above, a recipient may use your version of this file under |
| 33 | * the terms of any one of the NPL, the GPL or the LGPL. |
| 34 | * |
| 35 | * ***** END LICENSE BLOCK ***** */ |
| 36 | |
| 37 | //////////////////////////////////////////////////////////// |
| 38 | // |
| 39 | // Implementation of Netscape entry points (NPN_*), which are the functions |
| 40 | // the plugin calls to talk to the browser. |
| 41 | // |
| 42 | |
| 43 | #include "Debug.h" |
| 44 | |
| 45 | // Sun's cstring doesn't declare memcpy |
| 46 | #include <string.h> |
| 47 | //#include <cstring> |
| 48 | |
| 49 | #include "mozincludes.h" |
| 50 | //#include "gears/base/common/base_class.h" |
| 51 | //#include "gears/base/common/thread_locals.h" |
| 52 | //#include "gears/base/npapi/module.h" |
| 53 | |
| 54 | #ifndef HIBYTE |
| 55 | #define HIBYTE(x) ((((uint32)(x)) & 0xff00) >> 8) |
| 56 | #endif |
| 57 | |
| 58 | #ifndef LOBYTE |
| 59 | #define LOBYTE(W) ((W) & 0xFF) |
| 60 | #endif |
| 61 | |
| 62 | static NPNetscapeFuncs npn_funcs; |
| 63 | |
| 64 | void SetNPNFuncs(NPNetscapeFuncs* npnFuncs) { |
| 65 | // Since we can't rely on the pointer remaining valid, we need to |
| 66 | // copy the function pointers. |
| 67 | int size = sizeof(NPNetscapeFuncs); |
| 68 | if (size > npnFuncs->size) { |
| 69 | Debug::log(Debug::Warning) << "*** Warning: NPNetscapeFuncs supplied by " |
| 70 | "browser is smaller than expected: " << npnFuncs->size << " vs " << size |
| 71 | << Debug::flush; |
| 72 | size = npnFuncs->size; |
| 73 | } |
| 74 | memcpy(&npn_funcs, npnFuncs, size); |
| 75 | } |
| 76 | |
| 77 | const NPNetscapeFuncs &GetNPNFuncs() { |
| 78 | return npn_funcs; |
| 79 | } |
| 80 | |
| 81 | void NPN_Version(int* plugin_major, int* plugin_minor, |
| 82 | int* netscape_major, int* netscape_minor) |
| 83 | { |
| 84 | const NPNetscapeFuncs &funcs = GetNPNFuncs(); |
| 85 | *plugin_major = NP_VERSION_MAJOR; |
| 86 | *plugin_minor = NP_VERSION_MINOR; |
| 87 | *netscape_major = HIBYTE(funcs.version); |
| 88 | *netscape_minor = LOBYTE(funcs.version); |
| 89 | } |
| 90 | |
| 91 | NPError NPN_GetURLNotify(NPP instance, const char *url, const char *target, |
| 92 | void* notifyData) |
| 93 | { |
| 94 | const NPNetscapeFuncs &funcs = GetNPNFuncs(); |
| 95 | int navMinorVers = funcs.version & 0xFF; |
| 96 | NPError rv = NPERR_NO_ERROR; |
| 97 | |
| 98 | if (navMinorVers >= NPVERS_HAS_NOTIFICATION) |
| 99 | rv = funcs.geturlnotify(instance, url, target, notifyData); |
| 100 | else |
| 101 | rv = NPERR_INCOMPATIBLE_VERSION_ERROR; |
| 102 | |
| 103 | return rv; |
| 104 | } |
| 105 | |
| 106 | NPError NPN_GetURL(NPP instance, const char *url, const char *target) |
| 107 | { |
| 108 | NPError rv = GetNPNFuncs().geturl(instance, url, target); |
| 109 | return rv; |
| 110 | } |
| 111 | |
| 112 | NPError NPN_PostURLNotify(NPP instance, const char* url, const char* window, |
| 113 | uint32 len, const char* buf, NPBool file, |
| 114 | void* notifyData) |
| 115 | { |
| 116 | const NPNetscapeFuncs &funcs = GetNPNFuncs(); |
| 117 | int navMinorVers = funcs.version & 0xFF; |
| 118 | NPError rv = NPERR_NO_ERROR; |
| 119 | |
| 120 | if (navMinorVers >= NPVERS_HAS_NOTIFICATION) { |
| 121 | rv = funcs.posturlnotify(instance, url, window, len, buf, file, notifyData); |
| 122 | } else { |
| 123 | rv = NPERR_INCOMPATIBLE_VERSION_ERROR; |
| 124 | } |
| 125 | |
| 126 | return rv; |
| 127 | } |
| 128 | |
| 129 | NPError NPN_PostURL(NPP instance, const char* url, const char* window, |
| 130 | uint32 len, const char* buf, NPBool file) |
| 131 | { |
| 132 | NPError rv = GetNPNFuncs().posturl(instance, url, window, len, buf, file); |
| 133 | return rv; |
| 134 | } |
| 135 | |
| 136 | NPError NPN_RequestRead(NPStream* stream, NPByteRange* rangeList) |
| 137 | { |
| 138 | NPError rv = GetNPNFuncs().requestread(stream, rangeList); |
| 139 | return rv; |
| 140 | } |
| 141 | |
| 142 | NPError NPN_NewStream(NPP instance, NPMIMEType type, const char* target, |
| 143 | NPStream** stream) |
| 144 | { |
| 145 | const NPNetscapeFuncs &funcs = GetNPNFuncs(); |
| 146 | int navMinorVersion = funcs.version & 0xFF; |
| 147 | |
| 148 | NPError rv = NPERR_NO_ERROR; |
| 149 | |
| 150 | if ( navMinorVersion >= NPVERS_HAS_STREAMOUTPUT ) |
| 151 | rv = funcs.newstream(instance, type, target, stream); |
| 152 | else |
| 153 | rv = NPERR_INCOMPATIBLE_VERSION_ERROR; |
| 154 | |
| 155 | return rv; |
| 156 | } |
| 157 | |
| 158 | int32 NPN_Write(NPP instance, NPStream *stream, int32 len, void *buffer) |
| 159 | { |
| 160 | const NPNetscapeFuncs &funcs = GetNPNFuncs(); |
| 161 | int navMinorVersion = funcs.version & 0xFF; |
| 162 | int32 rv = 0; |
| 163 | |
| 164 | if ( navMinorVersion >= NPVERS_HAS_STREAMOUTPUT ) |
| 165 | rv = funcs.write(instance, stream, len, buffer); |
| 166 | else |
| 167 | rv = -1; |
| 168 | |
| 169 | return rv; |
| 170 | } |
| 171 | |
| 172 | NPError NPN_DestroyStream(NPP instance, NPStream* stream, NPError reason) |
| 173 | { |
| 174 | const NPNetscapeFuncs &funcs = GetNPNFuncs(); |
| 175 | int navMinorVersion = funcs.version & 0xFF; |
| 176 | NPError rv = NPERR_NO_ERROR; |
| 177 | |
| 178 | if ( navMinorVersion >= NPVERS_HAS_STREAMOUTPUT ) |
| 179 | rv = funcs.destroystream(instance, stream, reason); |
| 180 | else |
| 181 | rv = NPERR_INCOMPATIBLE_VERSION_ERROR; |
| 182 | |
| 183 | return rv; |
| 184 | } |
| 185 | |
| 186 | void NPN_Status(NPP instance, const char *message) |
| 187 | { |
| 188 | GetNPNFuncs().status(instance, message); |
| 189 | } |
| 190 | |
| 191 | const char* NPN_UserAgent(NPP instance) |
| 192 | { |
| 193 | const char * rv = NULL; |
| 194 | rv = GetNPNFuncs().uagent(instance); |
| 195 | return rv; |
| 196 | } |
| 197 | |
| 198 | void* NPN_MemAlloc(uint32 size) |
| 199 | { |
| 200 | void * rv = NULL; |
| 201 | rv = GetNPNFuncs().memalloc(size); |
| 202 | return rv; |
| 203 | } |
| 204 | |
| 205 | void NPN_MemFree(void* ptr) |
| 206 | { |
| 207 | GetNPNFuncs().memfree(ptr); |
| 208 | } |
| 209 | |
| 210 | uint32 NPN_MemFlush(uint32 size) |
| 211 | { |
| 212 | uint32 rv = GetNPNFuncs().memflush(size); |
| 213 | return rv; |
| 214 | } |
| 215 | |
| 216 | void NPN_ReloadPlugins(NPBool reloadPages) |
| 217 | { |
| 218 | GetNPNFuncs().reloadplugins(reloadPages); |
| 219 | } |
| 220 | |
| 221 | NPError NPN_GetValue(NPP instance, NPNVariable variable, void *value) |
| 222 | { |
| 223 | NPError rv = GetNPNFuncs().getvalue(instance, variable, value); |
| 224 | return rv; |
| 225 | } |
| 226 | |
| 227 | NPError NPN_SetValue(NPP instance, NPPVariable variable, void *value) |
| 228 | { |
| 229 | NPError rv = GetNPNFuncs().setvalue(instance, variable, value); |
| 230 | return rv; |
| 231 | } |
| 232 | |
| 233 | void NPN_InvalidateRect(NPP instance, NPRect *invalidRect) |
| 234 | { |
| 235 | GetNPNFuncs().invalidaterect(instance, invalidRect); |
| 236 | } |
| 237 | |
| 238 | void NPN_InvalidateRegion(NPP instance, NPRegion invalidRegion) |
| 239 | { |
| 240 | GetNPNFuncs().invalidateregion(instance, invalidRegion); |
| 241 | } |
| 242 | |
| 243 | void NPN_ForceRedraw(NPP instance) |
| 244 | { |
| 245 | GetNPNFuncs().forceredraw(instance); |
| 246 | } |
| 247 | |
| 248 | NPIdentifier NPN_GetStringIdentifier(const NPUTF8 *name) |
| 249 | { |
| 250 | return GetNPNFuncs().getstringidentifier(name); |
| 251 | } |
| 252 | |
| 253 | void NPN_GetStringIdentifiers(const NPUTF8 **names, int32_t nameCount, |
| 254 | NPIdentifier *identifiers) |
| 255 | { |
| 256 | return GetNPNFuncs().getstringidentifiers(names, nameCount, identifiers); |
| 257 | } |
| 258 | |
| 259 | NPIdentifier NPN_GetIntIdentifier(int32_t intid) |
| 260 | { |
| 261 | return GetNPNFuncs().getintidentifier(intid); |
| 262 | } |
| 263 | |
| 264 | bool NPN_IdentifierIsString(NPIdentifier identifier) |
| 265 | { |
| 266 | return GetNPNFuncs().identifierisstring(identifier); |
| 267 | } |
| 268 | |
| 269 | NPUTF8 *NPN_UTF8FromIdentifier(NPIdentifier identifier) |
| 270 | { |
| 271 | return GetNPNFuncs().utf8fromidentifier(identifier); |
| 272 | } |
| 273 | |
| 274 | // On WebKit under OSX, the intfromidentifier field of the structure isn't |
| 275 | // filled in (see WebNetscapePluginPackage.m#526 in WebKit source tree). |
| 276 | // At this time this function isn't called from our code, so for now comment it |
| 277 | // out. |
| 278 | // |
| 279 | int32_t NPN_IntFromIdentifier(NPIdentifier identifier) |
| 280 | { |
| 281 | return GetNPNFuncs().intfromidentifier(identifier); |
| 282 | } |
| 283 | |
| 284 | NPObject *NPN_CreateObject(NPP npp, NPClass *aClass) |
| 285 | { |
| 286 | return GetNPNFuncs().createobject(npp, aClass); |
| 287 | } |
| 288 | |
| 289 | NPObject *NPN_RetainObject(NPObject *obj) |
| 290 | { |
| 291 | return GetNPNFuncs().retainobject(obj); |
| 292 | } |
| 293 | |
| 294 | void NPN_ReleaseObject(NPObject *obj) |
| 295 | { |
| 296 | return GetNPNFuncs().releaseobject(obj); |
| 297 | } |
| 298 | |
| 299 | bool NPN_Invoke(NPP npp, NPObject* obj, NPIdentifier methodName, |
| 300 | const NPVariant *args, uint32_t argCount, NPVariant *result) |
| 301 | { |
| 302 | return GetNPNFuncs().invoke(npp, obj, methodName, args, argCount, result); |
| 303 | } |
| 304 | |
| 305 | bool NPN_InvokeDefault(NPP npp, NPObject* obj, const NPVariant *args, |
| 306 | uint32_t argCount, NPVariant *result) |
| 307 | { |
| 308 | return GetNPNFuncs().invokeDefault(npp, obj, args, argCount, result); |
| 309 | } |
| 310 | |
| 311 | bool NPN_Evaluate(NPP npp, NPObject* obj, NPString *script, |
| 312 | NPVariant *result) |
| 313 | { |
| 314 | return GetNPNFuncs().evaluate(npp, obj, script, result); |
| 315 | } |
| 316 | |
| 317 | bool NPN_GetProperty(NPP npp, NPObject* obj, NPIdentifier propertyName, |
| 318 | NPVariant *result) |
| 319 | { |
| 320 | // Workaround for bug in WebKit: GetProperty() fails when attempting to |
| 321 | // read a null value from an array, however it fills in the variant structure |
| 322 | // correctly. |
| 323 | // The workaround is to chek if GetProprety() touches the variant structure, |
| 324 | // if so, we assume it succeeded. |
| 325 | #ifdef BROWSER_WEBKIT |
| 326 | result->type = static_cast<NPVariantType>(-1); |
| 327 | |
| 328 | bool ret = GetNPNFuncs().getproperty(npp, obj, propertyName, result); |
| 329 | |
| 330 | if (result->type != -1 && !ret) { |
| 331 | ret = true; |
| 332 | } |
| 333 | return ret; |
| 334 | #else |
| 335 | return GetNPNFuncs().getproperty(npp, obj, propertyName, result); |
| 336 | #endif |
| 337 | } |
| 338 | |
| 339 | bool NPN_SetProperty(NPP npp, NPObject* obj, NPIdentifier propertyName, |
| 340 | const NPVariant *value) |
| 341 | { |
| 342 | return GetNPNFuncs().setproperty(npp, obj, propertyName, value); |
| 343 | } |
| 344 | |
| 345 | bool NPN_RemoveProperty(NPP npp, NPObject* obj, NPIdentifier propertyName) |
| 346 | { |
| 347 | return GetNPNFuncs().removeproperty(npp, obj, propertyName); |
| 348 | } |
| 349 | |
| 350 | #ifdef BROWSER_WEBKIT |
| 351 | // This field of NPN functions isn't filled in by WebKit on OSX. |
| 352 | #else |
| 353 | bool NPN_HasProperty(NPP npp, NPObject* obj, NPIdentifier propertyName) |
| 354 | { |
| 355 | return GetNPNFuncs().hasproperty(npp, obj, propertyName); |
| 356 | } |
| 357 | #endif |
| 358 | |
| 359 | #ifdef BROWSER_WEBKIT |
| 360 | // This field of NPN functions isn't filled in by WebKit on OSX. |
| 361 | #else |
| 362 | bool NPN_HasMethod(NPP npp, NPObject* obj, NPIdentifier methodName) |
| 363 | { |
| 364 | return GetNPNFuncs().hasmethod(npp, obj, methodName); |
| 365 | } |
| 366 | #endif |
| 367 | |
| 368 | void NPN_ReleaseVariantValue(NPVariant *variant) |
| 369 | { |
| 370 | GetNPNFuncs().releasevariantvalue(variant); |
| 371 | } |
| 372 | |
| 373 | #ifdef BROWSER_WEBKIT |
| 374 | // This function is buggy in WebKit, see |
| 375 | // http://bugs.webkit.org/show_bug.cgi?id=16829 |
| 376 | #else |
| 377 | void NPN_SetException(NPObject* obj, const NPUTF8 *message) |
| 378 | { |
| 379 | GetNPNFuncs().setexception(obj, message); |
| 380 | } |
| 381 | #endif |