dom/plugins/test/testplugin/nptest.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* ***** BEGIN LICENSE BLOCK *****
michael@0 2 *
michael@0 3 * Copyright (c) 2008, Mozilla Corporation
michael@0 4 * All rights reserved.
michael@0 5 *
michael@0 6 * Redistribution and use in source and binary forms, with or without
michael@0 7 * modification, are permitted provided that the following conditions are met:
michael@0 8 *
michael@0 9 * * Redistributions of source code must retain the above copyright notice, this
michael@0 10 * list of conditions and the following disclaimer.
michael@0 11 * * Redistributions in binary form must reproduce the above copyright notice,
michael@0 12 * this list of conditions and the following disclaimer in the documentation
michael@0 13 * and/or other materials provided with the distribution.
michael@0 14 * * Neither the name of the Mozilla Corporation nor the names of its
michael@0 15 * contributors may be used to endorse or promote products derived from this
michael@0 16 * software without specific prior written permission.
michael@0 17 *
michael@0 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
michael@0 19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
michael@0 20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
michael@0 21 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
michael@0 22 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
michael@0 23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
michael@0 24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
michael@0 25 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
michael@0 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
michael@0 27 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
michael@0 28 *
michael@0 29 * Contributor(s):
michael@0 30 * Dave Townsend <dtownsend@oxymoronical.com>
michael@0 31 * Josh Aas <josh@mozilla.com>
michael@0 32 *
michael@0 33 * ***** END LICENSE BLOCK ***** */
michael@0 34
michael@0 35 #include "nptest.h"
michael@0 36 #include "nptest_utils.h"
michael@0 37 #include "nptest_platform.h"
michael@0 38
michael@0 39 #include "mozilla/IntentionalCrash.h"
michael@0 40
michael@0 41 #include <stdlib.h>
michael@0 42 #include <string.h>
michael@0 43 #include <stdio.h>
michael@0 44 #include <iostream>
michael@0 45 #include <string>
michael@0 46 #include <sstream>
michael@0 47 #include <list>
michael@0 48 #include <ctime>
michael@0 49
michael@0 50 #ifdef XP_WIN
michael@0 51 #include <process.h>
michael@0 52 #include <float.h>
michael@0 53 #include <windows.h>
michael@0 54 #define getpid _getpid
michael@0 55 #define strcasecmp _stricmp
michael@0 56 #else
michael@0 57 #include <unistd.h>
michael@0 58 #include <pthread.h>
michael@0 59 #endif
michael@0 60
michael@0 61 #include "mozilla/NullPtr.h"
michael@0 62
michael@0 63 using namespace std;
michael@0 64
michael@0 65 #define PLUGIN_VERSION "1.0.0.0"
michael@0 66 #define ARRAY_LENGTH(a) (sizeof(a)/sizeof(a[0]))
michael@0 67 #define STATIC_ASSERT(condition) \
michael@0 68 extern void np_static_assert(int arg[(condition) ? 1 : -1])
michael@0 69
michael@0 70 extern const char *sPluginName;
michael@0 71 extern const char *sPluginDescription;
michael@0 72 static char sPluginVersion[] = PLUGIN_VERSION;
michael@0 73
michael@0 74 //
michael@0 75 // Intentional crash
michael@0 76 //
michael@0 77
michael@0 78 int gCrashCount = 0;
michael@0 79
michael@0 80 static void Crash()
michael@0 81 {
michael@0 82 int *pi = nullptr;
michael@0 83 *pi = 55; // Crash dereferencing null pointer
michael@0 84 ++gCrashCount;
michael@0 85 }
michael@0 86
michael@0 87 static void
michael@0 88 IntentionalCrash()
michael@0 89 {
michael@0 90 mozilla::NoteIntentionalCrash("plugin");
michael@0 91 Crash();
michael@0 92 }
michael@0 93
michael@0 94 //
michael@0 95 // static data
michael@0 96 //
michael@0 97
michael@0 98 static NPNetscapeFuncs* sBrowserFuncs = nullptr;
michael@0 99 static NPClass sNPClass;
michael@0 100
michael@0 101 void
michael@0 102 asyncCallback(void* cookie);
michael@0 103
michael@0 104 //
michael@0 105 // identifiers
michael@0 106 //
michael@0 107
michael@0 108 typedef bool (* ScriptableFunction)
michael@0 109 (NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
michael@0 110
michael@0 111 static bool npnEvaluateTest(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
michael@0 112 static bool npnInvokeTest(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
michael@0 113 static bool npnInvokeDefaultTest(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
michael@0 114 static bool setUndefinedValueTest(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
michael@0 115 static bool identifierToStringTest(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
michael@0 116 static bool timerTest(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
michael@0 117 static bool queryPrivateModeState(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
michael@0 118 static bool lastReportedPrivateModeState(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
michael@0 119 static bool hasWidget(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
michael@0 120 static bool getEdge(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
michael@0 121 static bool getClipRegionRectCount(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
michael@0 122 static bool getClipRegionRectEdge(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
michael@0 123 static bool startWatchingInstanceCount(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
michael@0 124 static bool getInstanceCount(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
michael@0 125 static bool stopWatchingInstanceCount(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
michael@0 126 static bool getLastMouseX(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
michael@0 127 static bool getLastMouseY(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
michael@0 128 static bool getPaintCount(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
michael@0 129 static bool getWidthAtLastPaint(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
michael@0 130 static bool setInvalidateDuringPaint(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
michael@0 131 static bool setSlowPaint(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
michael@0 132 static bool getError(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
michael@0 133 static bool doInternalConsistencyCheck(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
michael@0 134 static bool setColor(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
michael@0 135 static bool throwExceptionNextInvoke(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
michael@0 136 static bool convertPointX(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
michael@0 137 static bool convertPointY(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
michael@0 138 static bool streamTest(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
michael@0 139 static bool setPluginWantsAllStreams(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
michael@0 140 static bool crashPlugin(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
michael@0 141 static bool crashOnDestroy(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
michael@0 142 static bool getObjectValue(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
michael@0 143 static bool getJavaCodebase(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
michael@0 144 static bool checkObjectValue(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
michael@0 145 static bool enableFPExceptions(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
michael@0 146 static bool setCookie(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
michael@0 147 static bool getCookie(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
michael@0 148 static bool getAuthInfo(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
michael@0 149 static bool asyncCallbackTest(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
michael@0 150 static bool checkGCRace(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
michael@0 151 static bool hangPlugin(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
michael@0 152 static bool stallPlugin(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
michael@0 153 static bool getClipboardText(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
michael@0 154 static bool callOnDestroy(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
michael@0 155 static bool reinitWidget(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
michael@0 156 static bool crashPluginInNestedLoop(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
michael@0 157 static bool destroySharedGfxStuff(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
michael@0 158 static bool propertyAndMethod(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
michael@0 159 static bool getTopLevelWindowActivationState(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
michael@0 160 static bool getTopLevelWindowActivationEventCount(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
michael@0 161 static bool getFocusState(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
michael@0 162 static bool getFocusEventCount(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
michael@0 163 static bool getEventModel(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
michael@0 164 static bool getReflector(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
michael@0 165 static bool isVisible(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
michael@0 166 static bool getWindowPosition(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
michael@0 167 static bool constructObject(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
michael@0 168 static bool setSitesWithData(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
michael@0 169 static bool setSitesWithDataCapabilities(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
michael@0 170 static bool getLastKeyText(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
michael@0 171 static bool getNPNVdocumentOrigin(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
michael@0 172 static bool getMouseUpEventCount(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
michael@0 173 static bool queryContentsScaleFactor(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
michael@0 174
michael@0 175 static const NPUTF8* sPluginMethodIdentifierNames[] = {
michael@0 176 "npnEvaluateTest",
michael@0 177 "npnInvokeTest",
michael@0 178 "npnInvokeDefaultTest",
michael@0 179 "setUndefinedValueTest",
michael@0 180 "identifierToStringTest",
michael@0 181 "timerTest",
michael@0 182 "queryPrivateModeState",
michael@0 183 "lastReportedPrivateModeState",
michael@0 184 "hasWidget",
michael@0 185 "getEdge",
michael@0 186 "getClipRegionRectCount",
michael@0 187 "getClipRegionRectEdge",
michael@0 188 "startWatchingInstanceCount",
michael@0 189 "getInstanceCount",
michael@0 190 "stopWatchingInstanceCount",
michael@0 191 "getLastMouseX",
michael@0 192 "getLastMouseY",
michael@0 193 "getPaintCount",
michael@0 194 "getWidthAtLastPaint",
michael@0 195 "setInvalidateDuringPaint",
michael@0 196 "setSlowPaint",
michael@0 197 "getError",
michael@0 198 "doInternalConsistencyCheck",
michael@0 199 "setColor",
michael@0 200 "throwExceptionNextInvoke",
michael@0 201 "convertPointX",
michael@0 202 "convertPointY",
michael@0 203 "streamTest",
michael@0 204 "setPluginWantsAllStreams",
michael@0 205 "crash",
michael@0 206 "crashOnDestroy",
michael@0 207 "getObjectValue",
michael@0 208 "getJavaCodebase",
michael@0 209 "checkObjectValue",
michael@0 210 "enableFPExceptions",
michael@0 211 "setCookie",
michael@0 212 "getCookie",
michael@0 213 "getAuthInfo",
michael@0 214 "asyncCallbackTest",
michael@0 215 "checkGCRace",
michael@0 216 "hang",
michael@0 217 "stall",
michael@0 218 "getClipboardText",
michael@0 219 "callOnDestroy",
michael@0 220 "reinitWidget",
michael@0 221 "crashInNestedLoop",
michael@0 222 "destroySharedGfxStuff",
michael@0 223 "propertyAndMethod",
michael@0 224 "getTopLevelWindowActivationState",
michael@0 225 "getTopLevelWindowActivationEventCount",
michael@0 226 "getFocusState",
michael@0 227 "getFocusEventCount",
michael@0 228 "getEventModel",
michael@0 229 "getReflector",
michael@0 230 "isVisible",
michael@0 231 "getWindowPosition",
michael@0 232 "constructObject",
michael@0 233 "setSitesWithData",
michael@0 234 "setSitesWithDataCapabilities",
michael@0 235 "getLastKeyText",
michael@0 236 "getNPNVdocumentOrigin",
michael@0 237 "getMouseUpEventCount",
michael@0 238 "queryContentsScaleFactor"
michael@0 239 };
michael@0 240 static NPIdentifier sPluginMethodIdentifiers[ARRAY_LENGTH(sPluginMethodIdentifierNames)];
michael@0 241 static const ScriptableFunction sPluginMethodFunctions[] = {
michael@0 242 npnEvaluateTest,
michael@0 243 npnInvokeTest,
michael@0 244 npnInvokeDefaultTest,
michael@0 245 setUndefinedValueTest,
michael@0 246 identifierToStringTest,
michael@0 247 timerTest,
michael@0 248 queryPrivateModeState,
michael@0 249 lastReportedPrivateModeState,
michael@0 250 hasWidget,
michael@0 251 getEdge,
michael@0 252 getClipRegionRectCount,
michael@0 253 getClipRegionRectEdge,
michael@0 254 startWatchingInstanceCount,
michael@0 255 getInstanceCount,
michael@0 256 stopWatchingInstanceCount,
michael@0 257 getLastMouseX,
michael@0 258 getLastMouseY,
michael@0 259 getPaintCount,
michael@0 260 getWidthAtLastPaint,
michael@0 261 setInvalidateDuringPaint,
michael@0 262 setSlowPaint,
michael@0 263 getError,
michael@0 264 doInternalConsistencyCheck,
michael@0 265 setColor,
michael@0 266 throwExceptionNextInvoke,
michael@0 267 convertPointX,
michael@0 268 convertPointY,
michael@0 269 streamTest,
michael@0 270 setPluginWantsAllStreams,
michael@0 271 crashPlugin,
michael@0 272 crashOnDestroy,
michael@0 273 getObjectValue,
michael@0 274 getJavaCodebase,
michael@0 275 checkObjectValue,
michael@0 276 enableFPExceptions,
michael@0 277 setCookie,
michael@0 278 getCookie,
michael@0 279 getAuthInfo,
michael@0 280 asyncCallbackTest,
michael@0 281 checkGCRace,
michael@0 282 hangPlugin,
michael@0 283 stallPlugin,
michael@0 284 getClipboardText,
michael@0 285 callOnDestroy,
michael@0 286 reinitWidget,
michael@0 287 crashPluginInNestedLoop,
michael@0 288 destroySharedGfxStuff,
michael@0 289 propertyAndMethod,
michael@0 290 getTopLevelWindowActivationState,
michael@0 291 getTopLevelWindowActivationEventCount,
michael@0 292 getFocusState,
michael@0 293 getFocusEventCount,
michael@0 294 getEventModel,
michael@0 295 getReflector,
michael@0 296 isVisible,
michael@0 297 getWindowPosition,
michael@0 298 constructObject,
michael@0 299 setSitesWithData,
michael@0 300 setSitesWithDataCapabilities,
michael@0 301 getLastKeyText,
michael@0 302 getNPNVdocumentOrigin,
michael@0 303 getMouseUpEventCount,
michael@0 304 queryContentsScaleFactor
michael@0 305 };
michael@0 306
michael@0 307 STATIC_ASSERT(ARRAY_LENGTH(sPluginMethodIdentifierNames) ==
michael@0 308 ARRAY_LENGTH(sPluginMethodFunctions));
michael@0 309
michael@0 310 static const NPUTF8* sPluginPropertyIdentifierNames[] = {
michael@0 311 "propertyAndMethod"
michael@0 312 };
michael@0 313 static NPIdentifier sPluginPropertyIdentifiers[ARRAY_LENGTH(sPluginPropertyIdentifierNames)];
michael@0 314 static NPVariant sPluginPropertyValues[ARRAY_LENGTH(sPluginPropertyIdentifierNames)];
michael@0 315
michael@0 316 struct URLNotifyData
michael@0 317 {
michael@0 318 const char* cookie;
michael@0 319 NPObject* writeCallback;
michael@0 320 NPObject* notifyCallback;
michael@0 321 NPObject* redirectCallback;
michael@0 322 bool allowRedirects;
michael@0 323 uint32_t size;
michael@0 324 char* data;
michael@0 325 };
michael@0 326
michael@0 327 static URLNotifyData kNotifyData = {
michael@0 328 "static-cookie",
michael@0 329 nullptr,
michael@0 330 nullptr,
michael@0 331 nullptr,
michael@0 332 false,
michael@0 333 0,
michael@0 334 nullptr
michael@0 335 };
michael@0 336
michael@0 337 static const char* SUCCESS_STRING = "pass";
michael@0 338
michael@0 339 static bool sIdentifiersInitialized = false;
michael@0 340
michael@0 341 struct timerEvent {
michael@0 342 int32_t timerIdReceive;
michael@0 343 int32_t timerIdSchedule;
michael@0 344 uint32_t timerInterval;
michael@0 345 bool timerRepeat;
michael@0 346 int32_t timerIdUnschedule;
michael@0 347 };
michael@0 348 static timerEvent timerEvents[] = {
michael@0 349 {-1, 0, 200, false, -1},
michael@0 350 {0, 0, 400, false, -1},
michael@0 351 {0, 0, 200, true, -1},
michael@0 352 {0, 1, 400, true, -1},
michael@0 353 {0, -1, 0, false, 0},
michael@0 354 {1, -1, 0, false, -1},
michael@0 355 {1, -1, 0, false, 1},
michael@0 356 };
michael@0 357 static uint32_t currentTimerEventCount = 0;
michael@0 358 static uint32_t totalTimerEvents = sizeof(timerEvents) / sizeof(timerEvent);
michael@0 359
michael@0 360 /**
michael@0 361 * Incremented for every startWatchingInstanceCount.
michael@0 362 */
michael@0 363 static int32_t sCurrentInstanceCountWatchGeneration = 0;
michael@0 364 /**
michael@0 365 * Tracks the number of instances created or destroyed since the last
michael@0 366 * startWatchingInstanceCount.
michael@0 367 */
michael@0 368 static int32_t sInstanceCount = 0;
michael@0 369 /**
michael@0 370 * True when we've had a startWatchingInstanceCount with no corresponding
michael@0 371 * stopWatchingInstanceCount.
michael@0 372 */
michael@0 373 static bool sWatchingInstanceCount = false;
michael@0 374
michael@0 375 /**
michael@0 376 * A list representing sites for which the plugin has stored data. See
michael@0 377 * NPP_ClearSiteData and NPP_GetSitesWithData.
michael@0 378 */
michael@0 379 struct siteData {
michael@0 380 string site;
michael@0 381 uint64_t flags;
michael@0 382 uint64_t age;
michael@0 383 };
michael@0 384 static list<siteData>* sSitesWithData;
michael@0 385 static bool sClearByAgeSupported;
michael@0 386
michael@0 387 static void initializeIdentifiers()
michael@0 388 {
michael@0 389 if (!sIdentifiersInitialized) {
michael@0 390 NPN_GetStringIdentifiers(sPluginMethodIdentifierNames,
michael@0 391 ARRAY_LENGTH(sPluginMethodIdentifierNames), sPluginMethodIdentifiers);
michael@0 392 NPN_GetStringIdentifiers(sPluginPropertyIdentifierNames,
michael@0 393 ARRAY_LENGTH(sPluginPropertyIdentifierNames), sPluginPropertyIdentifiers);
michael@0 394
michael@0 395 sIdentifiersInitialized = true;
michael@0 396
michael@0 397 // Check whether nullptr is handled in NPN_GetStringIdentifiers
michael@0 398 NPIdentifier IDList[2];
michael@0 399 static char const *const kIDNames[2] = { nullptr, "setCookie" };
michael@0 400 NPN_GetStringIdentifiers(const_cast<const NPUTF8**>(kIDNames), 2, IDList);
michael@0 401 }
michael@0 402 }
michael@0 403
michael@0 404 static void clearIdentifiers()
michael@0 405 {
michael@0 406 memset(sPluginMethodIdentifiers, 0,
michael@0 407 ARRAY_LENGTH(sPluginMethodIdentifiers) * sizeof(NPIdentifier));
michael@0 408 memset(sPluginPropertyIdentifiers, 0,
michael@0 409 ARRAY_LENGTH(sPluginPropertyIdentifiers) * sizeof(NPIdentifier));
michael@0 410
michael@0 411 sIdentifiersInitialized = false;
michael@0 412 }
michael@0 413
michael@0 414 static void addRange(InstanceData* instanceData, const char* range)
michael@0 415 {
michael@0 416 char rangestr[16];
michael@0 417 strncpy(rangestr, range, sizeof(rangestr));
michael@0 418 const char* str1 = strtok(rangestr, ",");
michael@0 419 const char* str2 = str1 ? strtok(nullptr, ",") : nullptr;
michael@0 420 if (str1 && str2) {
michael@0 421 TestRange* byterange = new TestRange;
michael@0 422 byterange->offset = atoi(str1);
michael@0 423 byterange->length = atoi(str2);
michael@0 424 byterange->waiting = true;
michael@0 425 byterange->next = instanceData->testrange;
michael@0 426 instanceData->testrange = byterange;
michael@0 427 }
michael@0 428 }
michael@0 429
michael@0 430 static void sendBufferToFrame(NPP instance)
michael@0 431 {
michael@0 432 InstanceData* instanceData = (InstanceData*)(instance->pdata);
michael@0 433 string outbuf;
michael@0 434 if (!instanceData->npnNewStream) outbuf = "data:text/html,";
michael@0 435 const char* buf = reinterpret_cast<char *>(instanceData->streamBuf);
michael@0 436 int32_t bufsize = instanceData->streamBufSize;
michael@0 437 if (instanceData->streamMode == NP_ASFILE ||
michael@0 438 instanceData->streamMode == NP_ASFILEONLY) {
michael@0 439 buf = reinterpret_cast<char *>(instanceData->fileBuf);
michael@0 440 bufsize = instanceData->fileBufSize;
michael@0 441 }
michael@0 442 if (instanceData->err.str().length() > 0) {
michael@0 443 outbuf.append(instanceData->err.str());
michael@0 444 }
michael@0 445 else if (bufsize > 0) {
michael@0 446 outbuf.append(buf);
michael@0 447 }
michael@0 448 else {
michael@0 449 outbuf.append("Error: no data in buffer");
michael@0 450 }
michael@0 451
michael@0 452 if (instanceData->npnNewStream &&
michael@0 453 instanceData->err.str().length() == 0) {
michael@0 454 char typeHTML[] = "text/html";
michael@0 455 NPStream* stream;
michael@0 456 printf("calling NPN_NewStream...");
michael@0 457 NPError err = NPN_NewStream(instance, typeHTML,
michael@0 458 instanceData->frame.c_str(), &stream);
michael@0 459 printf("return value %d\n", err);
michael@0 460 if (err != NPERR_NO_ERROR) {
michael@0 461 instanceData->err << "NPN_NewStream returned " << err;
michael@0 462 return;
michael@0 463 }
michael@0 464
michael@0 465 int32_t bytesToWrite = outbuf.length();
michael@0 466 int32_t bytesWritten = 0;
michael@0 467 while ((bytesToWrite - bytesWritten) > 0) {
michael@0 468 int32_t numBytes = (bytesToWrite - bytesWritten) <
michael@0 469 instanceData->streamChunkSize ?
michael@0 470 bytesToWrite - bytesWritten : instanceData->streamChunkSize;
michael@0 471 int32_t written = NPN_Write(instance, stream,
michael@0 472 numBytes, (void*)(outbuf.c_str() + bytesWritten));
michael@0 473 if (written <= 0) {
michael@0 474 instanceData->err << "NPN_Write returned " << written;
michael@0 475 break;
michael@0 476 }
michael@0 477 bytesWritten += numBytes;
michael@0 478 printf("%d bytes written, total %d\n", written, bytesWritten);
michael@0 479 }
michael@0 480 err = NPN_DestroyStream(instance, stream, NPRES_DONE);
michael@0 481 if (err != NPERR_NO_ERROR) {
michael@0 482 instanceData->err << "NPN_DestroyStream returned " << err;
michael@0 483 }
michael@0 484 }
michael@0 485 else {
michael@0 486 // Convert CRLF to LF, and escape most other non-alphanumeric chars.
michael@0 487 for (size_t i = 0; i < outbuf.length(); i++) {
michael@0 488 if (outbuf[i] == '\n') {
michael@0 489 outbuf.replace(i, 1, "%0a");
michael@0 490 i += 2;
michael@0 491 }
michael@0 492 else if (outbuf[i] == '\r') {
michael@0 493 outbuf.replace(i, 1, "");
michael@0 494 i -= 1;
michael@0 495 }
michael@0 496 else {
michael@0 497 int ascii = outbuf[i];
michael@0 498 if (!((ascii >= ',' && ascii <= ';') ||
michael@0 499 (ascii >= 'A' && ascii <= 'Z') ||
michael@0 500 (ascii >= 'a' && ascii <= 'z'))) {
michael@0 501 char hex[8];
michael@0 502 sprintf(hex, "%%%x", ascii);
michael@0 503 outbuf.replace(i, 1, hex);
michael@0 504 i += 2;
michael@0 505 }
michael@0 506 }
michael@0 507 }
michael@0 508
michael@0 509 NPError err = NPN_GetURL(instance, outbuf.c_str(),
michael@0 510 instanceData->frame.c_str());
michael@0 511 if (err != NPERR_NO_ERROR) {
michael@0 512 instanceData->err << "NPN_GetURL returned " << err;
michael@0 513 }
michael@0 514 }
michael@0 515 }
michael@0 516
michael@0 517 static void XPSleep(unsigned int seconds)
michael@0 518 {
michael@0 519 #ifdef XP_WIN
michael@0 520 Sleep(1000 * seconds);
michael@0 521 #else
michael@0 522 sleep(seconds);
michael@0 523 #endif
michael@0 524 }
michael@0 525
michael@0 526 TestFunction
michael@0 527 getFuncFromString(const char* funcname)
michael@0 528 {
michael@0 529 FunctionTable funcTable[] =
michael@0 530 {
michael@0 531 { FUNCTION_NPP_NEWSTREAM, "npp_newstream" },
michael@0 532 { FUNCTION_NPP_WRITEREADY, "npp_writeready" },
michael@0 533 { FUNCTION_NPP_WRITE, "npp_write" },
michael@0 534 { FUNCTION_NPP_DESTROYSTREAM, "npp_destroystream" },
michael@0 535 { FUNCTION_NPP_WRITE_RPC, "npp_write_rpc" },
michael@0 536 { FUNCTION_NONE, nullptr }
michael@0 537 };
michael@0 538 int32_t i = 0;
michael@0 539 while(funcTable[i].funcName) {
michael@0 540 if (!strcmp(funcname, funcTable[i].funcName)) return funcTable[i].funcId;
michael@0 541 i++;
michael@0 542 }
michael@0 543 return FUNCTION_NONE;
michael@0 544 }
michael@0 545
michael@0 546 static void
michael@0 547 DuplicateNPVariant(NPVariant& aDest, const NPVariant& aSrc)
michael@0 548 {
michael@0 549 if (NPVARIANT_IS_STRING(aSrc)) {
michael@0 550 NPString src = NPVARIANT_TO_STRING(aSrc);
michael@0 551 char* buf = new char[src.UTF8Length];
michael@0 552 strncpy(buf, src.UTF8Characters, src.UTF8Length);
michael@0 553 STRINGN_TO_NPVARIANT(buf, src.UTF8Length, aDest);
michael@0 554 }
michael@0 555 else if (NPVARIANT_IS_OBJECT(aSrc)) {
michael@0 556 NPObject* obj =
michael@0 557 NPN_RetainObject(NPVARIANT_TO_OBJECT(aSrc));
michael@0 558 OBJECT_TO_NPVARIANT(obj, aDest);
michael@0 559 }
michael@0 560 else {
michael@0 561 aDest = aSrc;
michael@0 562 }
michael@0 563 }
michael@0 564
michael@0 565 void
michael@0 566 drawAsyncBitmapColor(InstanceData* instanceData)
michael@0 567 {
michael@0 568 NPP npp = instanceData->npp;
michael@0 569
michael@0 570 uint32_t *pixelData = (uint32_t*)instanceData->backBuffer->bitmap.data;
michael@0 571
michael@0 572 uint32_t rgba = instanceData->scriptableObject->drawColor;
michael@0 573
michael@0 574 unsigned char subpixels[4];
michael@0 575 subpixels[0] = rgba & 0xFF;
michael@0 576 subpixels[1] = (rgba & 0xFF00) >> 8;
michael@0 577 subpixels[2] = (rgba & 0xFF0000) >> 16;
michael@0 578 subpixels[3] = (rgba & 0xFF000000) >> 24;
michael@0 579
michael@0 580 subpixels[0] = uint8_t(float(subpixels[3] * subpixels[0]) / 0xFF);
michael@0 581 subpixels[1] = uint8_t(float(subpixels[3] * subpixels[1]) / 0xFF);
michael@0 582 subpixels[2] = uint8_t(float(subpixels[3] * subpixels[2]) / 0xFF);
michael@0 583 uint32_t premultiplied;
michael@0 584 memcpy(&premultiplied, subpixels, sizeof(premultiplied));
michael@0 585
michael@0 586 for (uint32_t* lastPixel = pixelData + instanceData->backBuffer->size.width * instanceData->backBuffer->size.height;
michael@0 587 pixelData < lastPixel;
michael@0 588 ++pixelData) {
michael@0 589 *pixelData = premultiplied;
michael@0 590 }
michael@0 591
michael@0 592 NPN_SetCurrentAsyncSurface(npp, instanceData->backBuffer, nullptr);
michael@0 593 NPAsyncSurface *oldFront = instanceData->frontBuffer;
michael@0 594 instanceData->frontBuffer = instanceData->backBuffer;
michael@0 595 instanceData->backBuffer = oldFront;
michael@0 596 }
michael@0 597
michael@0 598 static bool bug813906(NPP npp, const char* const function, const char* const url, const char* const frame)
michael@0 599 {
michael@0 600 NPObject *windowObj = nullptr;
michael@0 601 NPError err = NPN_GetValue(npp, NPNVWindowNPObject, &windowObj);
michael@0 602 if (err != NPERR_NO_ERROR) {
michael@0 603 return false;
michael@0 604 }
michael@0 605
michael@0 606 NPVariant result;
michael@0 607 bool res = NPN_Invoke(npp, windowObj, NPN_GetStringIdentifier(function), nullptr, 0, &result);
michael@0 608 NPN_ReleaseObject(windowObj);
michael@0 609 if (!res) {
michael@0 610 return false;
michael@0 611 }
michael@0 612
michael@0 613 NPN_ReleaseVariantValue(&result);
michael@0 614
michael@0 615 err = NPN_GetURL(npp, url, frame);
michael@0 616 if (err != NPERR_NO_ERROR) {
michael@0 617 err = NPN_GetURL(npp, "about:blank", frame);
michael@0 618 return false;
michael@0 619 }
michael@0 620
michael@0 621 return true;
michael@0 622 }
michael@0 623
michael@0 624 //
michael@0 625 // function signatures
michael@0 626 //
michael@0 627
michael@0 628 NPObject* scriptableAllocate(NPP npp, NPClass* aClass);
michael@0 629 void scriptableDeallocate(NPObject* npobj);
michael@0 630 void scriptableInvalidate(NPObject* npobj);
michael@0 631 bool scriptableHasMethod(NPObject* npobj, NPIdentifier name);
michael@0 632 bool scriptableInvoke(NPObject* npobj, NPIdentifier name, const NPVariant* args, uint32_t argCount, NPVariant* result);
michael@0 633 bool scriptableInvokeDefault(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
michael@0 634 bool scriptableHasProperty(NPObject* npobj, NPIdentifier name);
michael@0 635 bool scriptableGetProperty(NPObject* npobj, NPIdentifier name, NPVariant* result);
michael@0 636 bool scriptableSetProperty(NPObject* npobj, NPIdentifier name, const NPVariant* value);
michael@0 637 bool scriptableRemoveProperty(NPObject* npobj, NPIdentifier name);
michael@0 638 bool scriptableEnumerate(NPObject* npobj, NPIdentifier** identifier, uint32_t* count);
michael@0 639 bool scriptableConstruct(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result);
michael@0 640
michael@0 641 //
michael@0 642 // npapi plugin functions
michael@0 643 //
michael@0 644
michael@0 645 #ifdef XP_UNIX
michael@0 646 NP_EXPORT(char*)
michael@0 647 NP_GetPluginVersion()
michael@0 648 {
michael@0 649 return sPluginVersion;
michael@0 650 }
michael@0 651 #endif
michael@0 652
michael@0 653 extern const char *sMimeDescription;
michael@0 654
michael@0 655 #if defined(XP_UNIX)
michael@0 656 NP_EXPORT(const char*) NP_GetMIMEDescription()
michael@0 657 #elif defined(XP_WIN)
michael@0 658 const char* NP_GetMIMEDescription()
michael@0 659 #endif
michael@0 660 {
michael@0 661 return sMimeDescription;
michael@0 662 }
michael@0 663
michael@0 664 #ifdef XP_UNIX
michael@0 665 NP_EXPORT(NPError)
michael@0 666 NP_GetValue(void* future, NPPVariable aVariable, void* aValue) {
michael@0 667 switch (aVariable) {
michael@0 668 case NPPVpluginNameString:
michael@0 669 *((const char**)aValue) = sPluginName;
michael@0 670 break;
michael@0 671 case NPPVpluginDescriptionString:
michael@0 672 *((const char**)aValue) = sPluginDescription;
michael@0 673 break;
michael@0 674 default:
michael@0 675 return NPERR_INVALID_PARAM;
michael@0 676 break;
michael@0 677 }
michael@0 678 return NPERR_NO_ERROR;
michael@0 679 }
michael@0 680 #endif
michael@0 681
michael@0 682 static bool fillPluginFunctionTable(NPPluginFuncs* pFuncs)
michael@0 683 {
michael@0 684 // Check the size of the provided structure based on the offset of the
michael@0 685 // last member we need.
michael@0 686 if (pFuncs->size < (offsetof(NPPluginFuncs, getsiteswithdata) + sizeof(void*)))
michael@0 687 return false;
michael@0 688
michael@0 689 pFuncs->newp = NPP_New;
michael@0 690 pFuncs->destroy = NPP_Destroy;
michael@0 691 pFuncs->setwindow = NPP_SetWindow;
michael@0 692 pFuncs->newstream = NPP_NewStream;
michael@0 693 pFuncs->destroystream = NPP_DestroyStream;
michael@0 694 pFuncs->asfile = NPP_StreamAsFile;
michael@0 695 pFuncs->writeready = NPP_WriteReady;
michael@0 696 pFuncs->write = NPP_Write;
michael@0 697 pFuncs->print = NPP_Print;
michael@0 698 pFuncs->event = NPP_HandleEvent;
michael@0 699 pFuncs->urlnotify = NPP_URLNotify;
michael@0 700 pFuncs->getvalue = NPP_GetValue;
michael@0 701 pFuncs->setvalue = NPP_SetValue;
michael@0 702 pFuncs->urlredirectnotify = NPP_URLRedirectNotify;
michael@0 703 pFuncs->clearsitedata = NPP_ClearSiteData;
michael@0 704 pFuncs->getsiteswithdata = NPP_GetSitesWithData;
michael@0 705
michael@0 706 return true;
michael@0 707 }
michael@0 708
michael@0 709 #if defined(XP_MACOSX)
michael@0 710 NP_EXPORT(NPError) NP_Initialize(NPNetscapeFuncs* bFuncs)
michael@0 711 #elif defined(XP_WIN)
michael@0 712 NPError OSCALL NP_Initialize(NPNetscapeFuncs* bFuncs)
michael@0 713 #elif defined(XP_UNIX)
michael@0 714 NP_EXPORT(NPError) NP_Initialize(NPNetscapeFuncs* bFuncs, NPPluginFuncs* pFuncs)
michael@0 715 #endif
michael@0 716 {
michael@0 717 sBrowserFuncs = bFuncs;
michael@0 718
michael@0 719 initializeIdentifiers();
michael@0 720
michael@0 721 for (unsigned int i = 0; i < ARRAY_LENGTH(sPluginPropertyValues); i++) {
michael@0 722 VOID_TO_NPVARIANT(sPluginPropertyValues[i]);
michael@0 723 }
michael@0 724
michael@0 725 memset(&sNPClass, 0, sizeof(NPClass));
michael@0 726 sNPClass.structVersion = NP_CLASS_STRUCT_VERSION;
michael@0 727 sNPClass.allocate = (NPAllocateFunctionPtr)scriptableAllocate;
michael@0 728 sNPClass.deallocate = (NPDeallocateFunctionPtr)scriptableDeallocate;
michael@0 729 sNPClass.invalidate = (NPInvalidateFunctionPtr)scriptableInvalidate;
michael@0 730 sNPClass.hasMethod = (NPHasMethodFunctionPtr)scriptableHasMethod;
michael@0 731 sNPClass.invoke = (NPInvokeFunctionPtr)scriptableInvoke;
michael@0 732 sNPClass.invokeDefault = (NPInvokeDefaultFunctionPtr)scriptableInvokeDefault;
michael@0 733 sNPClass.hasProperty = (NPHasPropertyFunctionPtr)scriptableHasProperty;
michael@0 734 sNPClass.getProperty = (NPGetPropertyFunctionPtr)scriptableGetProperty;
michael@0 735 sNPClass.setProperty = (NPSetPropertyFunctionPtr)scriptableSetProperty;
michael@0 736 sNPClass.removeProperty = (NPRemovePropertyFunctionPtr)scriptableRemoveProperty;
michael@0 737 sNPClass.enumerate = (NPEnumerationFunctionPtr)scriptableEnumerate;
michael@0 738 sNPClass.construct = (NPConstructFunctionPtr)scriptableConstruct;
michael@0 739
michael@0 740 #if defined(XP_UNIX) && !defined(XP_MACOSX)
michael@0 741 if (!fillPluginFunctionTable(pFuncs)) {
michael@0 742 return NPERR_INVALID_FUNCTABLE_ERROR;
michael@0 743 }
michael@0 744 #endif
michael@0 745
michael@0 746 return NPERR_NO_ERROR;
michael@0 747 }
michael@0 748
michael@0 749 #if defined(XP_MACOSX)
michael@0 750 NP_EXPORT(NPError) NP_GetEntryPoints(NPPluginFuncs* pFuncs)
michael@0 751 #elif defined(XP_WIN)
michael@0 752 NPError OSCALL NP_GetEntryPoints(NPPluginFuncs* pFuncs)
michael@0 753 #endif
michael@0 754 #if defined(XP_MACOSX) || defined(XP_WIN)
michael@0 755 {
michael@0 756 if (!fillPluginFunctionTable(pFuncs)) {
michael@0 757 return NPERR_INVALID_FUNCTABLE_ERROR;
michael@0 758 }
michael@0 759
michael@0 760 return NPERR_NO_ERROR;
michael@0 761 }
michael@0 762 #endif
michael@0 763
michael@0 764 #if defined(XP_UNIX)
michael@0 765 NP_EXPORT(NPError) NP_Shutdown()
michael@0 766 #elif defined(XP_WIN)
michael@0 767 NPError OSCALL NP_Shutdown()
michael@0 768 #endif
michael@0 769 {
michael@0 770 clearIdentifiers();
michael@0 771
michael@0 772 for (unsigned int i = 0; i < ARRAY_LENGTH(sPluginPropertyValues); i++) {
michael@0 773 NPN_ReleaseVariantValue(&sPluginPropertyValues[i]);
michael@0 774 }
michael@0 775
michael@0 776 return NPERR_NO_ERROR;
michael@0 777 }
michael@0 778
michael@0 779 NPError
michael@0 780 NPP_New(NPMIMEType pluginType, NPP instance, uint16_t mode, int16_t argc, char* argn[], char* argv[], NPSavedData* saved)
michael@0 781 {
michael@0 782 // Make sure our pdata field is nullptr at this point. If it isn't, that
michael@0 783 // probably means the browser gave us uninitialized memory.
michael@0 784 if (instance->pdata) {
michael@0 785 printf("NPP_New called with non-NULL NPP->pdata pointer!\n");
michael@0 786 return NPERR_GENERIC_ERROR;
michael@0 787 }
michael@0 788
michael@0 789 // Make sure we can render this plugin
michael@0 790 NPBool browserSupportsWindowless = false;
michael@0 791 NPN_GetValue(instance, NPNVSupportsWindowless, &browserSupportsWindowless);
michael@0 792 if (!browserSupportsWindowless && !pluginSupportsWindowMode()) {
michael@0 793 printf("Windowless mode not supported by the browser, windowed mode not supported by the plugin!\n");
michael@0 794 return NPERR_GENERIC_ERROR;
michael@0 795 }
michael@0 796
michael@0 797 // set up our our instance data
michael@0 798 InstanceData* instanceData = new InstanceData;
michael@0 799 if (!instanceData)
michael@0 800 return NPERR_OUT_OF_MEMORY_ERROR;
michael@0 801 instanceData->npp = instance;
michael@0 802 instanceData->streamMode = NP_ASFILEONLY;
michael@0 803 instanceData->testFunction = FUNCTION_NONE;
michael@0 804 instanceData->functionToFail = FUNCTION_NONE;
michael@0 805 instanceData->failureCode = 0;
michael@0 806 instanceData->callOnDestroy = nullptr;
michael@0 807 instanceData->streamChunkSize = 1024;
michael@0 808 instanceData->streamBuf = nullptr;
michael@0 809 instanceData->streamBufSize = 0;
michael@0 810 instanceData->fileBuf = nullptr;
michael@0 811 instanceData->fileBufSize = 0;
michael@0 812 instanceData->throwOnNextInvoke = false;
michael@0 813 instanceData->runScriptOnPaint = false;
michael@0 814 instanceData->dontTouchElement = false;
michael@0 815 instanceData->testrange = nullptr;
michael@0 816 instanceData->hasWidget = false;
michael@0 817 instanceData->npnNewStream = false;
michael@0 818 instanceData->invalidateDuringPaint = false;
michael@0 819 instanceData->slowPaint = false;
michael@0 820 instanceData->writeCount = 0;
michael@0 821 instanceData->writeReadyCount = 0;
michael@0 822 memset(&instanceData->window, 0, sizeof(instanceData->window));
michael@0 823 instanceData->crashOnDestroy = false;
michael@0 824 instanceData->cleanupWidget = true; // only used by nptest_gtk
michael@0 825 instanceData->topLevelWindowActivationState = ACTIVATION_STATE_UNKNOWN;
michael@0 826 instanceData->topLevelWindowActivationEventCount = 0;
michael@0 827 instanceData->focusState = ACTIVATION_STATE_UNKNOWN;
michael@0 828 instanceData->focusEventCount = 0;
michael@0 829 instanceData->eventModel = 0;
michael@0 830 instanceData->closeStream = false;
michael@0 831 instanceData->wantsAllStreams = false;
michael@0 832 instanceData->asyncDrawing = AD_NONE;
michael@0 833 instanceData->frontBuffer = nullptr;
michael@0 834 instanceData->backBuffer = nullptr;
michael@0 835 instanceData->mouseUpEventCount = 0;
michael@0 836 instanceData->bugMode = -1;
michael@0 837 instance->pdata = instanceData;
michael@0 838
michael@0 839 TestNPObject* scriptableObject = (TestNPObject*)NPN_CreateObject(instance, &sNPClass);
michael@0 840 if (!scriptableObject) {
michael@0 841 printf("NPN_CreateObject failed to create an object, can't create a plugin instance\n");
michael@0 842 free(instanceData);
michael@0 843 return NPERR_GENERIC_ERROR;
michael@0 844 }
michael@0 845 scriptableObject->npp = instance;
michael@0 846 scriptableObject->drawMode = DM_DEFAULT;
michael@0 847 scriptableObject->drawColor = 0;
michael@0 848 instanceData->scriptableObject = scriptableObject;
michael@0 849
michael@0 850 instanceData->instanceCountWatchGeneration = sCurrentInstanceCountWatchGeneration;
michael@0 851
michael@0 852 if (NP_FULL == mode) {
michael@0 853 instanceData->streamMode = NP_SEEK;
michael@0 854 instanceData->frame = "testframe";
michael@0 855 addRange(instanceData, "100,100");
michael@0 856 }
michael@0 857
michael@0 858 bool requestWindow = false;
michael@0 859 // handle extra params
michael@0 860 for (int i = 0; i < argc; i++) {
michael@0 861 if (strcmp(argn[i], "drawmode") == 0) {
michael@0 862 if (strcmp(argv[i], "solid") == 0)
michael@0 863 scriptableObject->drawMode = DM_SOLID_COLOR;
michael@0 864 }
michael@0 865 else if (strcmp(argn[i], "color") == 0) {
michael@0 866 scriptableObject->drawColor = parseHexColor(argv[i], strlen(argv[i]));
michael@0 867 }
michael@0 868 else if (strcmp(argn[i], "wmode") == 0) {
michael@0 869 if (strcmp(argv[i], "window") == 0) {
michael@0 870 requestWindow = true;
michael@0 871 }
michael@0 872 }
michael@0 873 else if (strcmp(argn[i], "asyncmodel") == 0) {
michael@0 874 if (strcmp(argv[i], "bitmap") == 0) {
michael@0 875 if (pluginSupportsAsyncBitmapDrawing()) {
michael@0 876 instanceData->asyncDrawing = AD_BITMAP;
michael@0 877 }
michael@0 878 }
michael@0 879 if (strcmp(argv[i], "dxgi") == 0) {
michael@0 880 if (pluginSupportsAsyncDXGIDrawing()) {
michael@0 881 instanceData->asyncDrawing = AD_DXGI;
michael@0 882 }
michael@0 883 }
michael@0 884 }
michael@0 885 if (strcmp(argn[i], "streammode") == 0) {
michael@0 886 if (strcmp(argv[i], "normal") == 0) {
michael@0 887 instanceData->streamMode = NP_NORMAL;
michael@0 888 }
michael@0 889 else if ((strcmp(argv[i], "asfile") == 0) &&
michael@0 890 strlen(argv[i]) == strlen("asfile")) {
michael@0 891 instanceData->streamMode = NP_ASFILE;
michael@0 892 }
michael@0 893 else if (strcmp(argv[i], "asfileonly") == 0) {
michael@0 894 instanceData->streamMode = NP_ASFILEONLY;
michael@0 895 }
michael@0 896 else if (strcmp(argv[i], "seek") == 0) {
michael@0 897 instanceData->streamMode = NP_SEEK;
michael@0 898 }
michael@0 899 }
michael@0 900 if (strcmp(argn[i], "streamchunksize") == 0) {
michael@0 901 instanceData->streamChunkSize = atoi(argv[i]);
michael@0 902 }
michael@0 903 if (strcmp(argn[i], "failurecode") == 0) {
michael@0 904 instanceData->failureCode = atoi(argv[i]);
michael@0 905 }
michael@0 906 if (strcmp(argn[i], "functiontofail") == 0) {
michael@0 907 instanceData->functionToFail = getFuncFromString(argv[i]);
michael@0 908 }
michael@0 909 if (strcmp(argn[i], "geturl") == 0) {
michael@0 910 instanceData->testUrl = argv[i];
michael@0 911 instanceData->testFunction = FUNCTION_NPP_GETURL;
michael@0 912 }
michael@0 913 if (strcmp(argn[i], "posturl") == 0) {
michael@0 914 instanceData->testUrl = argv[i];
michael@0 915 instanceData->testFunction = FUNCTION_NPP_POSTURL;
michael@0 916 }
michael@0 917 if (strcmp(argn[i], "geturlnotify") == 0) {
michael@0 918 instanceData->testUrl = argv[i];
michael@0 919 instanceData->testFunction = FUNCTION_NPP_GETURLNOTIFY;
michael@0 920 }
michael@0 921 if (strcmp(argn[i], "postmode") == 0) {
michael@0 922 if (strcmp(argv[i], "frame") == 0) {
michael@0 923 instanceData->postMode = POSTMODE_FRAME;
michael@0 924 }
michael@0 925 else if (strcmp(argv[i], "stream") == 0) {
michael@0 926 instanceData->postMode = POSTMODE_STREAM;
michael@0 927 }
michael@0 928 }
michael@0 929 if (strcmp(argn[i], "frame") == 0) {
michael@0 930 instanceData->frame = argv[i];
michael@0 931 }
michael@0 932 if (strcmp(argn[i], "range") == 0) {
michael@0 933 string range = argv[i];
michael@0 934 size_t semicolon = range.find(';');
michael@0 935 while (semicolon != string::npos) {
michael@0 936 addRange(instanceData, range.substr(0, semicolon).c_str());
michael@0 937 if (semicolon == range.length()) {
michael@0 938 range = "";
michael@0 939 break;
michael@0 940 }
michael@0 941 range = range.substr(semicolon + 1);
michael@0 942 semicolon = range.find(';');
michael@0 943 }
michael@0 944 if (range.length()) addRange(instanceData, range.c_str());
michael@0 945 }
michael@0 946 if (strcmp(argn[i], "newstream") == 0 &&
michael@0 947 strcmp(argv[i], "true") == 0) {
michael@0 948 instanceData->npnNewStream = true;
michael@0 949 }
michael@0 950 if (strcmp(argn[i], "newcrash") == 0) {
michael@0 951 IntentionalCrash();
michael@0 952 }
michael@0 953 if (strcmp(argn[i], "paintscript") == 0) {
michael@0 954 instanceData->runScriptOnPaint = true;
michael@0 955 }
michael@0 956
michael@0 957 if (strcmp(argn[i], "donttouchelement") == 0) {
michael@0 958 instanceData->dontTouchElement = true;
michael@0 959 }
michael@0 960 // "cleanupwidget" is only used with nptest_gtk, defaulting to true. It
michael@0 961 // indicates whether the plugin should destroy its window in response to
michael@0 962 // NPP_Destroy (or let the platform destroy the widget when the parent
michael@0 963 // window gets destroyed).
michael@0 964 if (strcmp(argn[i], "cleanupwidget") == 0 &&
michael@0 965 strcmp(argv[i], "false") == 0) {
michael@0 966 instanceData->cleanupWidget = false;
michael@0 967 }
michael@0 968 if (!strcmp(argn[i], "closestream")) {
michael@0 969 instanceData->closeStream = true;
michael@0 970 }
michael@0 971 if (strcmp(argn[i], "bugmode") == 0) {
michael@0 972 instanceData->bugMode = atoi(argv[i]);
michael@0 973 }
michael@0 974 // Try to emulate java's codebase handling: Use the last seen codebase
michael@0 975 // value, regardless of whether it is in attributes or params.
michael@0 976 if (strcasecmp(argn[i], "codebase") == 0) {
michael@0 977 instanceData->javaCodebase = argv[i];
michael@0 978 }
michael@0 979 }
michael@0 980
michael@0 981 if (!browserSupportsWindowless || !pluginSupportsWindowlessMode()) {
michael@0 982 requestWindow = true;
michael@0 983 } else if (!pluginSupportsWindowMode()) {
michael@0 984 requestWindow = false;
michael@0 985 }
michael@0 986 if (requestWindow) {
michael@0 987 instanceData->hasWidget = true;
michael@0 988 } else {
michael@0 989 // NPPVpluginWindowBool should default to true, so we may as well
michael@0 990 // test that by not setting it in the window case
michael@0 991 NPN_SetValue(instance, NPPVpluginWindowBool, (void*)false);
michael@0 992 }
michael@0 993
michael@0 994 if (scriptableObject->drawMode == DM_SOLID_COLOR &&
michael@0 995 (scriptableObject->drawColor & 0xFF000000) != 0xFF000000) {
michael@0 996 NPN_SetValue(instance, NPPVpluginTransparentBool, (void*)true);
michael@0 997 }
michael@0 998
michael@0 999 if (instanceData->asyncDrawing == AD_BITMAP) {
michael@0 1000 NPBool supportsAsyncBitmap = false;
michael@0 1001 if ((NPN_GetValue(instance, NPNVsupportsAsyncBitmapSurfaceBool, &supportsAsyncBitmap) == NPERR_NO_ERROR) &&
michael@0 1002 supportsAsyncBitmap) {
michael@0 1003 NPN_SetValue(instance, NPPVpluginDrawingModel, (void*)NPDrawingModelAsyncBitmapSurface);
michael@0 1004 } else {
michael@0 1005 instanceData->asyncDrawing = AD_NONE;
michael@0 1006 }
michael@0 1007 }
michael@0 1008 #ifdef XP_WIN
michael@0 1009 else if (instanceData->asyncDrawing == AD_DXGI) {
michael@0 1010 NPBool supportsAsyncDXGI = false;
michael@0 1011 if ((NPN_GetValue(instance, NPNVsupportsAsyncWindowsDXGISurfaceBool, &supportsAsyncDXGI) == NPERR_NO_ERROR) &&
michael@0 1012 supportsAsyncDXGI) {
michael@0 1013 NPN_SetValue(instance, NPPVpluginDrawingModel, (void*)NPDrawingModelAsyncWindowsDXGISurface);
michael@0 1014 } else {
michael@0 1015 instanceData->asyncDrawing = AD_NONE;
michael@0 1016 }
michael@0 1017 }
michael@0 1018 #endif
michael@0 1019
michael@0 1020 instanceData->lastReportedPrivateModeState = false;
michael@0 1021 instanceData->lastMouseX = instanceData->lastMouseY = -1;
michael@0 1022 instanceData->widthAtLastPaint = -1;
michael@0 1023 instanceData->paintCount = 0;
michael@0 1024
michael@0 1025 // do platform-specific initialization
michael@0 1026 NPError err = pluginInstanceInit(instanceData);
michael@0 1027 if (err != NPERR_NO_ERROR) {
michael@0 1028 NPN_ReleaseObject(scriptableObject);
michael@0 1029 free(instanceData);
michael@0 1030 return err;
michael@0 1031 }
michael@0 1032
michael@0 1033 NPVariant variantTrue;
michael@0 1034 BOOLEAN_TO_NPVARIANT(true, variantTrue);
michael@0 1035 NPObject* o = nullptr;
michael@0 1036
michael@0 1037 // Set a property on NPNVPluginElementNPObject, unless the consumer explicitly
michael@0 1038 // opted out of this behavior.
michael@0 1039 if (!instanceData->dontTouchElement) {
michael@0 1040 err = NPN_GetValue(instance, NPNVPluginElementNPObject, &o);
michael@0 1041 if (err == NPERR_NO_ERROR) {
michael@0 1042 NPN_SetProperty(instance, o,
michael@0 1043 NPN_GetStringIdentifier("pluginFoundElement"), &variantTrue);
michael@0 1044 NPN_ReleaseObject(o);
michael@0 1045 o = nullptr;
michael@0 1046 }
michael@0 1047 }
michael@0 1048
michael@0 1049 // Set a property on NPNVWindowNPObject
michael@0 1050 err = NPN_GetValue(instance, NPNVWindowNPObject, &o);
michael@0 1051 if (err == NPERR_NO_ERROR) {
michael@0 1052 NPN_SetProperty(instance, o,
michael@0 1053 NPN_GetStringIdentifier("pluginFoundWindow"), &variantTrue);
michael@0 1054 NPN_ReleaseObject(o);
michael@0 1055 o = nullptr;
michael@0 1056 }
michael@0 1057
michael@0 1058 ++sInstanceCount;
michael@0 1059
michael@0 1060 if (instanceData->testFunction == FUNCTION_NPP_GETURL) {
michael@0 1061 NPError err = NPN_GetURL(instance, instanceData->testUrl.c_str(), nullptr);
michael@0 1062 if (err != NPERR_NO_ERROR) {
michael@0 1063 instanceData->err << "NPN_GetURL returned " << err;
michael@0 1064 }
michael@0 1065 }
michael@0 1066 else if (instanceData->testFunction == FUNCTION_NPP_GETURLNOTIFY) {
michael@0 1067 NPError err = NPN_GetURLNotify(instance, instanceData->testUrl.c_str(),
michael@0 1068 nullptr, static_cast<void*>(&kNotifyData));
michael@0 1069 if (err != NPERR_NO_ERROR) {
michael@0 1070 instanceData->err << "NPN_GetURLNotify returned " << err;
michael@0 1071 }
michael@0 1072 }
michael@0 1073
michael@0 1074 if ((instanceData->bugMode == 813906) && instanceData->frame.length()) {
michael@0 1075 bug813906(instance, "f", "browser.xul", instanceData->frame.c_str());
michael@0 1076 }
michael@0 1077
michael@0 1078 return NPERR_NO_ERROR;
michael@0 1079 }
michael@0 1080
michael@0 1081 NPError
michael@0 1082 NPP_Destroy(NPP instance, NPSavedData** save)
michael@0 1083 {
michael@0 1084 printf("NPP_Destroy\n");
michael@0 1085 InstanceData* instanceData = (InstanceData*)(instance->pdata);
michael@0 1086
michael@0 1087 if (instanceData->crashOnDestroy)
michael@0 1088 IntentionalCrash();
michael@0 1089
michael@0 1090 if (instanceData->callOnDestroy) {
michael@0 1091 NPVariant result;
michael@0 1092 NPN_InvokeDefault(instance, instanceData->callOnDestroy, nullptr, 0, &result);
michael@0 1093 NPN_ReleaseVariantValue(&result);
michael@0 1094 NPN_ReleaseObject(instanceData->callOnDestroy);
michael@0 1095 }
michael@0 1096
michael@0 1097 if (instanceData->streamBuf) {
michael@0 1098 free(instanceData->streamBuf);
michael@0 1099 }
michael@0 1100 if (instanceData->fileBuf) {
michael@0 1101 free(instanceData->fileBuf);
michael@0 1102 }
michael@0 1103
michael@0 1104 TestRange* currentrange = instanceData->testrange;
michael@0 1105 TestRange* nextrange;
michael@0 1106 while (currentrange != nullptr) {
michael@0 1107 nextrange = reinterpret_cast<TestRange*>(currentrange->next);
michael@0 1108 delete currentrange;
michael@0 1109 currentrange = nextrange;
michael@0 1110 }
michael@0 1111
michael@0 1112 if (instanceData->frontBuffer) {
michael@0 1113 NPN_SetCurrentAsyncSurface(instance, nullptr, nullptr);
michael@0 1114 NPN_FinalizeAsyncSurface(instance, instanceData->frontBuffer);
michael@0 1115 NPN_MemFree(instanceData->frontBuffer);
michael@0 1116 }
michael@0 1117 if (instanceData->backBuffer) {
michael@0 1118 NPN_FinalizeAsyncSurface(instance, instanceData->backBuffer);
michael@0 1119 NPN_MemFree(instanceData->backBuffer);
michael@0 1120 }
michael@0 1121
michael@0 1122 pluginInstanceShutdown(instanceData);
michael@0 1123 NPN_ReleaseObject(instanceData->scriptableObject);
michael@0 1124
michael@0 1125 if (sCurrentInstanceCountWatchGeneration == instanceData->instanceCountWatchGeneration) {
michael@0 1126 --sInstanceCount;
michael@0 1127 }
michael@0 1128 delete instanceData;
michael@0 1129
michael@0 1130 return NPERR_NO_ERROR;
michael@0 1131 }
michael@0 1132
michael@0 1133 NPError
michael@0 1134 NPP_SetWindow(NPP instance, NPWindow* window)
michael@0 1135 {
michael@0 1136 InstanceData* instanceData = (InstanceData*)(instance->pdata);
michael@0 1137
michael@0 1138 if (instanceData->scriptableObject->drawMode == DM_DEFAULT &&
michael@0 1139 (instanceData->window.width != window->width ||
michael@0 1140 instanceData->window.height != window->height)) {
michael@0 1141 NPRect r;
michael@0 1142 r.left = r.top = 0;
michael@0 1143 r.right = window->width;
michael@0 1144 r.bottom = window->height;
michael@0 1145 NPN_InvalidateRect(instance, &r);
michael@0 1146 }
michael@0 1147
michael@0 1148 void* oldWindow = instanceData->window.window;
michael@0 1149 pluginDoSetWindow(instanceData, window);
michael@0 1150 if (instanceData->hasWidget && oldWindow != instanceData->window.window) {
michael@0 1151 pluginWidgetInit(instanceData, oldWindow);
michael@0 1152 }
michael@0 1153
michael@0 1154 if (instanceData->asyncDrawing == AD_BITMAP) {
michael@0 1155 if (instanceData->frontBuffer &&
michael@0 1156 instanceData->frontBuffer->size.width >= 0 &&
michael@0 1157 (uint32_t)instanceData->frontBuffer->size.width == window->width &&
michael@0 1158 instanceData ->frontBuffer->size.height >= 0 &&
michael@0 1159 (uint32_t)instanceData->frontBuffer->size.height == window->height) {
michael@0 1160 return NPERR_NO_ERROR;
michael@0 1161 }
michael@0 1162 if (instanceData->frontBuffer) {
michael@0 1163 NPN_FinalizeAsyncSurface(instance, instanceData->frontBuffer);
michael@0 1164 NPN_MemFree(instanceData->frontBuffer);
michael@0 1165 }
michael@0 1166 if (instanceData->backBuffer) {
michael@0 1167 NPN_FinalizeAsyncSurface(instance, instanceData->backBuffer);
michael@0 1168 NPN_MemFree(instanceData->backBuffer);
michael@0 1169 }
michael@0 1170 instanceData->frontBuffer = (NPAsyncSurface*)NPN_MemAlloc(sizeof(NPAsyncSurface));
michael@0 1171 instanceData->backBuffer = (NPAsyncSurface*)NPN_MemAlloc(sizeof(NPAsyncSurface));
michael@0 1172
michael@0 1173 NPSize size;
michael@0 1174 size.width = window->width;
michael@0 1175 size.height = window->height;
michael@0 1176
michael@0 1177 memcpy(instanceData->backBuffer, instanceData->frontBuffer, sizeof(NPAsyncSurface));
michael@0 1178
michael@0 1179 NPN_InitAsyncSurface(instance, &size, NPImageFormatBGRA32, nullptr, instanceData->frontBuffer);
michael@0 1180 NPN_InitAsyncSurface(instance, &size, NPImageFormatBGRA32, nullptr, instanceData->backBuffer);
michael@0 1181
michael@0 1182 drawAsyncBitmapColor(instanceData);
michael@0 1183 }
michael@0 1184 return NPERR_NO_ERROR;
michael@0 1185 }
michael@0 1186
michael@0 1187 NPError
michael@0 1188 NPP_NewStream(NPP instance, NPMIMEType type, NPStream* stream, NPBool seekable, uint16_t* stype)
michael@0 1189 {
michael@0 1190 printf("NPP_NewStream\n");
michael@0 1191 InstanceData* instanceData = (InstanceData*)(instance->pdata);
michael@0 1192
michael@0 1193 if (instanceData->functionToFail == FUNCTION_NPP_NEWSTREAM &&
michael@0 1194 instanceData->failureCode) {
michael@0 1195 instanceData->err << SUCCESS_STRING;
michael@0 1196 if (instanceData->frame.length() > 0) {
michael@0 1197 sendBufferToFrame(instance);
michael@0 1198 }
michael@0 1199 return instanceData->failureCode;
michael@0 1200 }
michael@0 1201
michael@0 1202 if (stream->notifyData &&
michael@0 1203 static_cast<URLNotifyData*>(stream->notifyData) != &kNotifyData) {
michael@0 1204 // stream from streamTest
michael@0 1205 *stype = NP_NORMAL;
michael@0 1206 }
michael@0 1207 else {
michael@0 1208 *stype = instanceData->streamMode;
michael@0 1209
michael@0 1210 if (instanceData->streamBufSize) {
michael@0 1211 free(instanceData->streamBuf);
michael@0 1212 instanceData->streamBufSize = 0;
michael@0 1213 if (instanceData->testFunction == FUNCTION_NPP_POSTURL &&
michael@0 1214 instanceData->postMode == POSTMODE_STREAM) {
michael@0 1215 instanceData->testFunction = FUNCTION_NPP_GETURL;
michael@0 1216 }
michael@0 1217 else {
michael@0 1218 // We already got a stream and didn't ask for another one.
michael@0 1219 instanceData->err << "Received unexpected multiple NPP_NewStream";
michael@0 1220 }
michael@0 1221 }
michael@0 1222 }
michael@0 1223 return NPERR_NO_ERROR;
michael@0 1224 }
michael@0 1225
michael@0 1226 NPError
michael@0 1227 NPP_DestroyStream(NPP instance, NPStream* stream, NPReason reason)
michael@0 1228 {
michael@0 1229 printf("NPP_DestroyStream\n");
michael@0 1230 InstanceData* instanceData = (InstanceData*)(instance->pdata);
michael@0 1231
michael@0 1232 if (instanceData->functionToFail == FUNCTION_NPP_NEWSTREAM) {
michael@0 1233 instanceData->err << "NPP_DestroyStream called";
michael@0 1234 }
michael@0 1235
michael@0 1236 if (instanceData->functionToFail == FUNCTION_NPP_WRITE) {
michael@0 1237 if (instanceData->writeCount == 1)
michael@0 1238 instanceData->err << SUCCESS_STRING;
michael@0 1239 else
michael@0 1240 instanceData->err << "NPP_Write called after returning -1";
michael@0 1241 }
michael@0 1242
michael@0 1243 if (instanceData->functionToFail == FUNCTION_NPP_DESTROYSTREAM &&
michael@0 1244 instanceData->failureCode) {
michael@0 1245 instanceData->err << SUCCESS_STRING;
michael@0 1246 if (instanceData->frame.length() > 0) {
michael@0 1247 sendBufferToFrame(instance);
michael@0 1248 }
michael@0 1249 return instanceData->failureCode;
michael@0 1250 }
michael@0 1251
michael@0 1252 URLNotifyData* nd = static_cast<URLNotifyData*>(stream->notifyData);
michael@0 1253 if (nd && nd != &kNotifyData) {
michael@0 1254 return NPERR_NO_ERROR;
michael@0 1255 }
michael@0 1256
michael@0 1257 if (instanceData->streamMode == NP_ASFILE &&
michael@0 1258 instanceData->functionToFail == FUNCTION_NONE) {
michael@0 1259 if (!instanceData->streamBuf) {
michael@0 1260 instanceData->err <<
michael@0 1261 "Error: no data written with NPP_Write";
michael@0 1262 return NPERR_GENERIC_ERROR;
michael@0 1263 }
michael@0 1264
michael@0 1265 if (!instanceData->fileBuf) {
michael@0 1266 instanceData->err <<
michael@0 1267 "Error: no data written with NPP_StreamAsFile";
michael@0 1268 return NPERR_GENERIC_ERROR;
michael@0 1269 }
michael@0 1270
michael@0 1271 if (strcmp(reinterpret_cast<char *>(instanceData->fileBuf),
michael@0 1272 reinterpret_cast<char *>(instanceData->streamBuf))) {
michael@0 1273 instanceData->err <<
michael@0 1274 "Error: data passed to NPP_Write and NPP_StreamAsFile differed";
michael@0 1275 }
michael@0 1276 }
michael@0 1277 if (instanceData->frame.length() > 0 &&
michael@0 1278 instanceData->testFunction != FUNCTION_NPP_GETURLNOTIFY &&
michael@0 1279 instanceData->testFunction != FUNCTION_NPP_POSTURL) {
michael@0 1280 sendBufferToFrame(instance);
michael@0 1281 }
michael@0 1282 if (instanceData->testFunction == FUNCTION_NPP_POSTURL) {
michael@0 1283 NPError err = NPN_PostURL(instance, instanceData->testUrl.c_str(),
michael@0 1284 instanceData->postMode == POSTMODE_FRAME ? instanceData->frame.c_str() : nullptr,
michael@0 1285 instanceData->streamBufSize,
michael@0 1286 reinterpret_cast<char *>(instanceData->streamBuf), false);
michael@0 1287 if (err != NPERR_NO_ERROR)
michael@0 1288 instanceData->err << "Error: NPN_PostURL returned error value " << err;
michael@0 1289 }
michael@0 1290 return NPERR_NO_ERROR;
michael@0 1291 }
michael@0 1292
michael@0 1293 int32_t
michael@0 1294 NPP_WriteReady(NPP instance, NPStream* stream)
michael@0 1295 {
michael@0 1296 printf("NPP_WriteReady\n");
michael@0 1297 InstanceData* instanceData = (InstanceData*)(instance->pdata);
michael@0 1298 instanceData->writeReadyCount++;
michael@0 1299 if (instanceData->functionToFail == FUNCTION_NPP_NEWSTREAM) {
michael@0 1300 instanceData->err << "NPP_WriteReady called";
michael@0 1301 }
michael@0 1302
michael@0 1303 // temporarily disabled per bug 519870
michael@0 1304 //if (instanceData->writeReadyCount == 1) {
michael@0 1305 // return 0;
michael@0 1306 //}
michael@0 1307
michael@0 1308 return instanceData->streamChunkSize;
michael@0 1309 }
michael@0 1310
michael@0 1311 int32_t
michael@0 1312 NPP_Write(NPP instance, NPStream* stream, int32_t offset, int32_t len, void* buffer)
michael@0 1313 {
michael@0 1314 InstanceData* instanceData = (InstanceData*)(instance->pdata);
michael@0 1315 instanceData->writeCount++;
michael@0 1316
michael@0 1317 // temporarily disabled per bug 519870
michael@0 1318 //if (instanceData->writeReadyCount == 1) {
michael@0 1319 // instanceData->err << "NPP_Write called even though NPP_WriteReady " <<
michael@0 1320 // "returned 0";
michael@0 1321 //}
michael@0 1322
michael@0 1323 if (instanceData->functionToFail == FUNCTION_NPP_WRITE_RPC) {
michael@0 1324 // Make an RPC call and pretend to consume the data
michael@0 1325 NPObject* windowObject = nullptr;
michael@0 1326 NPN_GetValue(instance, NPNVWindowNPObject, &windowObject);
michael@0 1327 if (windowObject)
michael@0 1328 NPN_ReleaseObject(windowObject);
michael@0 1329
michael@0 1330 return len;
michael@0 1331 }
michael@0 1332
michael@0 1333 if (instanceData->functionToFail == FUNCTION_NPP_NEWSTREAM) {
michael@0 1334 instanceData->err << "NPP_Write called";
michael@0 1335 }
michael@0 1336
michael@0 1337 if (instanceData->functionToFail == FUNCTION_NPP_WRITE) {
michael@0 1338 return -1;
michael@0 1339 }
michael@0 1340
michael@0 1341 URLNotifyData* nd = static_cast<URLNotifyData*>(stream->notifyData);
michael@0 1342
michael@0 1343 if (nd && nd->writeCallback) {
michael@0 1344 NPVariant args[1];
michael@0 1345 STRINGN_TO_NPVARIANT(stream->url, strlen(stream->url), args[0]);
michael@0 1346
michael@0 1347 NPVariant result;
michael@0 1348 NPN_InvokeDefault(instance, nd->writeCallback, args, 1, &result);
michael@0 1349 NPN_ReleaseVariantValue(&result);
michael@0 1350 }
michael@0 1351
michael@0 1352 if (nd && nd != &kNotifyData) {
michael@0 1353 uint32_t newsize = nd->size + len;
michael@0 1354 nd->data = (char*) realloc(nd->data, newsize);
michael@0 1355 memcpy(nd->data + nd->size, buffer, len);
michael@0 1356 nd->size = newsize;
michael@0 1357 return len;
michael@0 1358 }
michael@0 1359
michael@0 1360 if (instanceData->closeStream) {
michael@0 1361 instanceData->closeStream = false;
michael@0 1362 if (instanceData->testrange != nullptr) {
michael@0 1363 NPN_RequestRead(stream, instanceData->testrange);
michael@0 1364 }
michael@0 1365 NPN_DestroyStream(instance, stream, NPRES_USER_BREAK);
michael@0 1366 }
michael@0 1367 else if (instanceData->streamMode == NP_SEEK &&
michael@0 1368 stream->end != 0 &&
michael@0 1369 stream->end == ((uint32_t)instanceData->streamBufSize + len)) {
michael@0 1370 // If the complete stream has been written, and we're doing a seek test,
michael@0 1371 // then call NPN_RequestRead.
michael@0 1372 // prevent recursion
michael@0 1373 instanceData->streamMode = NP_NORMAL;
michael@0 1374
michael@0 1375 if (instanceData->testrange != nullptr) {
michael@0 1376 NPError err = NPN_RequestRead(stream, instanceData->testrange);
michael@0 1377 if (err != NPERR_NO_ERROR) {
michael@0 1378 instanceData->err << "NPN_RequestRead returned error %d" << err;
michael@0 1379 }
michael@0 1380 printf("called NPN_RequestRead, return %d\n", err);
michael@0 1381 }
michael@0 1382 }
michael@0 1383
michael@0 1384 char* streamBuf = reinterpret_cast<char *>(instanceData->streamBuf);
michael@0 1385 if (offset + len <= instanceData->streamBufSize) {
michael@0 1386 if (memcmp(buffer, streamBuf + offset, len)) {
michael@0 1387 instanceData->err <<
michael@0 1388 "Error: data written from NPN_RequestRead doesn't match";
michael@0 1389 }
michael@0 1390 else {
michael@0 1391 printf("data matches!\n");
michael@0 1392 }
michael@0 1393 TestRange* range = instanceData->testrange;
michael@0 1394 bool stillwaiting = false;
michael@0 1395 while(range != nullptr) {
michael@0 1396 if (offset == range->offset &&
michael@0 1397 (uint32_t)len == range->length) {
michael@0 1398 range->waiting = false;
michael@0 1399 }
michael@0 1400 if (range->waiting) stillwaiting = true;
michael@0 1401 range = reinterpret_cast<TestRange*>(range->next);
michael@0 1402 }
michael@0 1403 if (!stillwaiting) {
michael@0 1404 NPError err = NPN_DestroyStream(instance, stream, NPRES_DONE);
michael@0 1405 if (err != NPERR_NO_ERROR) {
michael@0 1406 instanceData->err << "Error: NPN_DestroyStream returned " << err;
michael@0 1407 }
michael@0 1408 }
michael@0 1409 }
michael@0 1410 else {
michael@0 1411 if (instanceData->streamBufSize == 0) {
michael@0 1412 instanceData->streamBuf = malloc(len + 1);
michael@0 1413 streamBuf = reinterpret_cast<char *>(instanceData->streamBuf);
michael@0 1414 }
michael@0 1415 else {
michael@0 1416 instanceData->streamBuf =
michael@0 1417 realloc(reinterpret_cast<char *>(instanceData->streamBuf),
michael@0 1418 instanceData->streamBufSize + len + 1);
michael@0 1419 streamBuf = reinterpret_cast<char *>(instanceData->streamBuf);
michael@0 1420 }
michael@0 1421 memcpy(streamBuf + instanceData->streamBufSize, buffer, len);
michael@0 1422 instanceData->streamBufSize = instanceData->streamBufSize + len;
michael@0 1423 streamBuf[instanceData->streamBufSize] = '\0';
michael@0 1424 }
michael@0 1425 return len;
michael@0 1426 }
michael@0 1427
michael@0 1428 void
michael@0 1429 NPP_StreamAsFile(NPP instance, NPStream* stream, const char* fname)
michael@0 1430 {
michael@0 1431 printf("NPP_StreamAsFile, file=%s\n", fname);
michael@0 1432 size_t size;
michael@0 1433
michael@0 1434 InstanceData* instanceData = (InstanceData*)(instance->pdata);
michael@0 1435
michael@0 1436 if (instanceData->functionToFail == FUNCTION_NPP_NEWSTREAM ||
michael@0 1437 instanceData->functionToFail == FUNCTION_NPP_WRITE) {
michael@0 1438 instanceData->err << "NPP_StreamAsFile called";
michael@0 1439 }
michael@0 1440
michael@0 1441 if (!fname)
michael@0 1442 return;
michael@0 1443
michael@0 1444 FILE *file = fopen(fname, "rb");
michael@0 1445 if (file) {
michael@0 1446 fseek(file, 0, SEEK_END);
michael@0 1447 size = ftell(file);
michael@0 1448 instanceData->fileBuf = malloc((int32_t)size + 1);
michael@0 1449 char* buf = reinterpret_cast<char *>(instanceData->fileBuf);
michael@0 1450 fseek(file, 0, SEEK_SET);
michael@0 1451 size_t sizeRead = fread(instanceData->fileBuf, 1, size, file);
michael@0 1452 if (sizeRead != size) {
michael@0 1453 printf("Unable to read data from file\n");
michael@0 1454 instanceData->err << "Unable to read data from file " << fname;
michael@0 1455 }
michael@0 1456 fclose(file);
michael@0 1457 buf[size] = '\0';
michael@0 1458 instanceData->fileBufSize = (int32_t)size;
michael@0 1459 }
michael@0 1460 else {
michael@0 1461 printf("Unable to open file\n");
michael@0 1462 instanceData->err << "Unable to open file " << fname;
michael@0 1463 }
michael@0 1464 }
michael@0 1465
michael@0 1466 void
michael@0 1467 NPP_Print(NPP instance, NPPrint* platformPrint)
michael@0 1468 {
michael@0 1469 }
michael@0 1470
michael@0 1471 int16_t
michael@0 1472 NPP_HandleEvent(NPP instance, void* event)
michael@0 1473 {
michael@0 1474 InstanceData* instanceData = (InstanceData*)(instance->pdata);
michael@0 1475 return pluginHandleEvent(instanceData, event);
michael@0 1476 }
michael@0 1477
michael@0 1478 void
michael@0 1479 NPP_URLNotify(NPP instance, const char* url, NPReason reason, void* notifyData)
michael@0 1480 {
michael@0 1481 InstanceData* instanceData = (InstanceData*)(instance->pdata);
michael@0 1482 URLNotifyData* ndata = static_cast<URLNotifyData*>(notifyData);
michael@0 1483
michael@0 1484 printf("NPP_URLNotify called\n");
michael@0 1485 if (&kNotifyData == ndata) {
michael@0 1486 if (instanceData->frame.length() > 0) {
michael@0 1487 sendBufferToFrame(instance);
michael@0 1488 }
michael@0 1489 }
michael@0 1490 else if (!strcmp(ndata->cookie, "dynamic-cookie")) {
michael@0 1491 if (ndata->notifyCallback) {
michael@0 1492 NPVariant args[2];
michael@0 1493 INT32_TO_NPVARIANT(reason, args[0]);
michael@0 1494 if (ndata->data) {
michael@0 1495 STRINGN_TO_NPVARIANT(ndata->data, ndata->size, args[1]);
michael@0 1496 }
michael@0 1497 else {
michael@0 1498 STRINGN_TO_NPVARIANT("", 0, args[1]);
michael@0 1499 }
michael@0 1500
michael@0 1501 NPVariant result;
michael@0 1502 NPN_InvokeDefault(instance, ndata->notifyCallback, args, 2, &result);
michael@0 1503 NPN_ReleaseVariantValue(&result);
michael@0 1504 }
michael@0 1505
michael@0 1506 // clean up the URLNotifyData
michael@0 1507 if (ndata->writeCallback) {
michael@0 1508 NPN_ReleaseObject(ndata->writeCallback);
michael@0 1509 }
michael@0 1510 if (ndata->notifyCallback) {
michael@0 1511 NPN_ReleaseObject(ndata->notifyCallback);
michael@0 1512 }
michael@0 1513 if (ndata->redirectCallback) {
michael@0 1514 NPN_ReleaseObject(ndata->redirectCallback);
michael@0 1515 }
michael@0 1516 free(ndata->data);
michael@0 1517 delete ndata;
michael@0 1518 }
michael@0 1519 else {
michael@0 1520 printf("ERROR! NPP_URLNotify called with wrong cookie\n");
michael@0 1521 instanceData->err << "Error: NPP_URLNotify called with wrong cookie";
michael@0 1522 }
michael@0 1523 }
michael@0 1524
michael@0 1525 NPError
michael@0 1526 NPP_GetValue(NPP instance, NPPVariable variable, void* value)
michael@0 1527 {
michael@0 1528 InstanceData* instanceData = (InstanceData*)instance->pdata;
michael@0 1529 if (variable == NPPVpluginScriptableNPObject) {
michael@0 1530 NPObject* object = instanceData->scriptableObject;
michael@0 1531 NPN_RetainObject(object);
michael@0 1532 *((NPObject**)value) = object;
michael@0 1533 return NPERR_NO_ERROR;
michael@0 1534 }
michael@0 1535 if (variable == NPPVpluginNeedsXEmbed) {
michael@0 1536 // Only relevant for X plugins
michael@0 1537 // use 4-byte writes like some plugins may do
michael@0 1538 *(uint32_t*)value = instanceData->hasWidget;
michael@0 1539 return NPERR_NO_ERROR;
michael@0 1540 }
michael@0 1541 if (variable == NPPVpluginWantsAllNetworkStreams) {
michael@0 1542 // use 4-byte writes like some plugins may do
michael@0 1543 *(uint32_t*)value = instanceData->wantsAllStreams;
michael@0 1544 return NPERR_NO_ERROR;
michael@0 1545 }
michael@0 1546
michael@0 1547 return NPERR_GENERIC_ERROR;
michael@0 1548 }
michael@0 1549
michael@0 1550 NPError
michael@0 1551 NPP_SetValue(NPP instance, NPNVariable variable, void* value)
michael@0 1552 {
michael@0 1553 if (variable == NPNVprivateModeBool) {
michael@0 1554 InstanceData* instanceData = (InstanceData*)(instance->pdata);
michael@0 1555 instanceData->lastReportedPrivateModeState = bool(*static_cast<NPBool*>(value));
michael@0 1556 return NPERR_NO_ERROR;
michael@0 1557 }
michael@0 1558 return NPERR_GENERIC_ERROR;
michael@0 1559 }
michael@0 1560
michael@0 1561 void
michael@0 1562 NPP_URLRedirectNotify(NPP instance, const char* url, int32_t status, void* notifyData)
michael@0 1563 {
michael@0 1564 if (notifyData) {
michael@0 1565 URLNotifyData* nd = static_cast<URLNotifyData*>(notifyData);
michael@0 1566 if (nd->redirectCallback) {
michael@0 1567 NPVariant args[2];
michael@0 1568 STRINGN_TO_NPVARIANT(url, strlen(url), args[0]);
michael@0 1569 INT32_TO_NPVARIANT(status, args[1]);
michael@0 1570
michael@0 1571 NPVariant result;
michael@0 1572 NPN_InvokeDefault(instance, nd->redirectCallback, args, 2, &result);
michael@0 1573 NPN_ReleaseVariantValue(&result);
michael@0 1574 }
michael@0 1575 NPN_URLRedirectResponse(instance, notifyData, nd->allowRedirects);
michael@0 1576 return;
michael@0 1577 }
michael@0 1578 NPN_URLRedirectResponse(instance, notifyData, true);
michael@0 1579 }
michael@0 1580
michael@0 1581 NPError
michael@0 1582 NPP_ClearSiteData(const char* site, uint64_t flags, uint64_t maxAge)
michael@0 1583 {
michael@0 1584 if (!sSitesWithData)
michael@0 1585 return NPERR_NO_ERROR;
michael@0 1586
michael@0 1587 // Error condition: no support for clear-by-age
michael@0 1588 if (!sClearByAgeSupported && maxAge != uint64_t(int64_t(-1)))
michael@0 1589 return NPERR_TIME_RANGE_NOT_SUPPORTED;
michael@0 1590
michael@0 1591 // Iterate over list and remove matches
michael@0 1592 list<siteData>::iterator iter = sSitesWithData->begin();
michael@0 1593 list<siteData>::iterator end = sSitesWithData->end();
michael@0 1594 while (iter != end) {
michael@0 1595 const siteData& data = *iter;
michael@0 1596 list<siteData>::iterator next = iter;
michael@0 1597 ++next;
michael@0 1598 if ((!site || data.site.compare(site) == 0) &&
michael@0 1599 (flags == NP_CLEAR_ALL || data.flags & flags) &&
michael@0 1600 data.age <= maxAge) {
michael@0 1601 sSitesWithData->erase(iter);
michael@0 1602 }
michael@0 1603 iter = next;
michael@0 1604 }
michael@0 1605
michael@0 1606 return NPERR_NO_ERROR;
michael@0 1607 }
michael@0 1608
michael@0 1609 char**
michael@0 1610 NPP_GetSitesWithData()
michael@0 1611 {
michael@0 1612 int length = 0;
michael@0 1613 char** result;
michael@0 1614
michael@0 1615 if (sSitesWithData)
michael@0 1616 length = sSitesWithData->size();
michael@0 1617
michael@0 1618 // Allocate the maximum possible size the list could be.
michael@0 1619 result = static_cast<char**>(NPN_MemAlloc((length + 1) * sizeof(char*)));
michael@0 1620 result[length] = nullptr;
michael@0 1621
michael@0 1622 if (length == 0) {
michael@0 1623 // Represent the no site data case as an array of length 1 with a nullptr
michael@0 1624 // entry.
michael@0 1625 return result;
michael@0 1626 }
michael@0 1627
michael@0 1628 // Iterate the list of stored data, and build a list of strings.
michael@0 1629 list<string> sites;
michael@0 1630 {
michael@0 1631 list<siteData>::iterator iter = sSitesWithData->begin();
michael@0 1632 list<siteData>::iterator end = sSitesWithData->end();
michael@0 1633 for (; iter != end; ++iter) {
michael@0 1634 const siteData& data = *iter;
michael@0 1635 sites.push_back(data.site);
michael@0 1636 }
michael@0 1637 }
michael@0 1638
michael@0 1639 // Remove duplicate strings.
michael@0 1640 sites.sort();
michael@0 1641 sites.unique();
michael@0 1642
michael@0 1643 // Add strings to the result array, and null terminate.
michael@0 1644 {
michael@0 1645 int i = 0;
michael@0 1646 list<string>::iterator iter = sites.begin();
michael@0 1647 list<string>::iterator end = sites.end();
michael@0 1648 for (; iter != end; ++iter, ++i) {
michael@0 1649 const string& site = *iter;
michael@0 1650 result[i] = static_cast<char*>(NPN_MemAlloc(site.length() + 1));
michael@0 1651 memcpy(result[i], site.c_str(), site.length() + 1);
michael@0 1652 }
michael@0 1653 }
michael@0 1654 result[sites.size()] = nullptr;
michael@0 1655
michael@0 1656 return result;
michael@0 1657 }
michael@0 1658
michael@0 1659 //
michael@0 1660 // npapi browser functions
michael@0 1661 //
michael@0 1662
michael@0 1663 bool
michael@0 1664 NPN_SetProperty(NPP instance, NPObject* obj, NPIdentifier propertyName, const NPVariant* value)
michael@0 1665 {
michael@0 1666 return sBrowserFuncs->setproperty(instance, obj, propertyName, value);
michael@0 1667 }
michael@0 1668
michael@0 1669 NPIdentifier
michael@0 1670 NPN_GetIntIdentifier(int32_t intid)
michael@0 1671 {
michael@0 1672 return sBrowserFuncs->getintidentifier(intid);
michael@0 1673 }
michael@0 1674
michael@0 1675 NPIdentifier
michael@0 1676 NPN_GetStringIdentifier(const NPUTF8* name)
michael@0 1677 {
michael@0 1678 return sBrowserFuncs->getstringidentifier(name);
michael@0 1679 }
michael@0 1680
michael@0 1681 void
michael@0 1682 NPN_GetStringIdentifiers(const NPUTF8 **names, int32_t nameCount, NPIdentifier *identifiers)
michael@0 1683 {
michael@0 1684 return sBrowserFuncs->getstringidentifiers(names, nameCount, identifiers);
michael@0 1685 }
michael@0 1686
michael@0 1687 bool
michael@0 1688 NPN_IdentifierIsString(NPIdentifier identifier)
michael@0 1689 {
michael@0 1690 return sBrowserFuncs->identifierisstring(identifier);
michael@0 1691 }
michael@0 1692
michael@0 1693 NPUTF8*
michael@0 1694 NPN_UTF8FromIdentifier(NPIdentifier identifier)
michael@0 1695 {
michael@0 1696 return sBrowserFuncs->utf8fromidentifier(identifier);
michael@0 1697 }
michael@0 1698
michael@0 1699 int32_t
michael@0 1700 NPN_IntFromIdentifier(NPIdentifier identifier)
michael@0 1701 {
michael@0 1702 return sBrowserFuncs->intfromidentifier(identifier);
michael@0 1703 }
michael@0 1704
michael@0 1705 NPError
michael@0 1706 NPN_GetValue(NPP instance, NPNVariable variable, void* value)
michael@0 1707 {
michael@0 1708 return sBrowserFuncs->getvalue(instance, variable, value);
michael@0 1709 }
michael@0 1710
michael@0 1711 NPError
michael@0 1712 NPN_SetValue(NPP instance, NPPVariable variable, void* value)
michael@0 1713 {
michael@0 1714 return sBrowserFuncs->setvalue(instance, variable, value);
michael@0 1715 }
michael@0 1716
michael@0 1717 void
michael@0 1718 NPN_InvalidateRect(NPP instance, NPRect* rect)
michael@0 1719 {
michael@0 1720 sBrowserFuncs->invalidaterect(instance, rect);
michael@0 1721 }
michael@0 1722
michael@0 1723 bool
michael@0 1724 NPN_HasProperty(NPP instance, NPObject* obj, NPIdentifier propertyName)
michael@0 1725 {
michael@0 1726 return sBrowserFuncs->hasproperty(instance, obj, propertyName);
michael@0 1727 }
michael@0 1728
michael@0 1729 NPObject*
michael@0 1730 NPN_CreateObject(NPP instance, NPClass* aClass)
michael@0 1731 {
michael@0 1732 return sBrowserFuncs->createobject(instance, aClass);
michael@0 1733 }
michael@0 1734
michael@0 1735 bool
michael@0 1736 NPN_Invoke(NPP npp, NPObject* obj, NPIdentifier methodName, const NPVariant *args, uint32_t argCount, NPVariant *result)
michael@0 1737 {
michael@0 1738 return sBrowserFuncs->invoke(npp, obj, methodName, args, argCount, result);
michael@0 1739 }
michael@0 1740
michael@0 1741 bool
michael@0 1742 NPN_InvokeDefault(NPP npp, NPObject* obj, const NPVariant *args, uint32_t argCount, NPVariant *result)
michael@0 1743 {
michael@0 1744 return sBrowserFuncs->invokeDefault(npp, obj, args, argCount, result);
michael@0 1745 }
michael@0 1746
michael@0 1747 bool
michael@0 1748 NPN_Construct(NPP npp, NPObject* npobj, const NPVariant* args,
michael@0 1749 uint32_t argCount, NPVariant* result)
michael@0 1750 {
michael@0 1751 return sBrowserFuncs->construct(npp, npobj, args, argCount, result);
michael@0 1752 }
michael@0 1753
michael@0 1754 const char*
michael@0 1755 NPN_UserAgent(NPP instance)
michael@0 1756 {
michael@0 1757 return sBrowserFuncs->uagent(instance);
michael@0 1758 }
michael@0 1759
michael@0 1760 NPObject*
michael@0 1761 NPN_RetainObject(NPObject* obj)
michael@0 1762 {
michael@0 1763 return sBrowserFuncs->retainobject(obj);
michael@0 1764 }
michael@0 1765
michael@0 1766 void
michael@0 1767 NPN_ReleaseObject(NPObject* obj)
michael@0 1768 {
michael@0 1769 return sBrowserFuncs->releaseobject(obj);
michael@0 1770 }
michael@0 1771
michael@0 1772 void*
michael@0 1773 NPN_MemAlloc(uint32_t size)
michael@0 1774 {
michael@0 1775 return sBrowserFuncs->memalloc(size);
michael@0 1776 }
michael@0 1777
michael@0 1778 char*
michael@0 1779 NPN_StrDup(const char* str)
michael@0 1780 {
michael@0 1781 return strcpy((char*)sBrowserFuncs->memalloc(strlen(str) + 1), str);
michael@0 1782 }
michael@0 1783
michael@0 1784 void
michael@0 1785 NPN_MemFree(void* ptr)
michael@0 1786 {
michael@0 1787 return sBrowserFuncs->memfree(ptr);
michael@0 1788 }
michael@0 1789
michael@0 1790 uint32_t
michael@0 1791 NPN_ScheduleTimer(NPP instance, uint32_t interval, NPBool repeat, void (*timerFunc)(NPP npp, uint32_t timerID))
michael@0 1792 {
michael@0 1793 return sBrowserFuncs->scheduletimer(instance, interval, repeat, timerFunc);
michael@0 1794 }
michael@0 1795
michael@0 1796 void
michael@0 1797 NPN_UnscheduleTimer(NPP instance, uint32_t timerID)
michael@0 1798 {
michael@0 1799 return sBrowserFuncs->unscheduletimer(instance, timerID);
michael@0 1800 }
michael@0 1801
michael@0 1802 void
michael@0 1803 NPN_ReleaseVariantValue(NPVariant *variant)
michael@0 1804 {
michael@0 1805 return sBrowserFuncs->releasevariantvalue(variant);
michael@0 1806 }
michael@0 1807
michael@0 1808 NPError
michael@0 1809 NPN_GetURLNotify(NPP instance, const char* url, const char* target, void* notifyData)
michael@0 1810 {
michael@0 1811 return sBrowserFuncs->geturlnotify(instance, url, target, notifyData);
michael@0 1812 }
michael@0 1813
michael@0 1814 NPError
michael@0 1815 NPN_GetURL(NPP instance, const char* url, const char* target)
michael@0 1816 {
michael@0 1817 return sBrowserFuncs->geturl(instance, url, target);
michael@0 1818 }
michael@0 1819
michael@0 1820 NPError
michael@0 1821 NPN_RequestRead(NPStream* stream, NPByteRange* rangeList)
michael@0 1822 {
michael@0 1823 return sBrowserFuncs->requestread(stream, rangeList);
michael@0 1824 }
michael@0 1825
michael@0 1826 NPError
michael@0 1827 NPN_PostURLNotify(NPP instance, const char* url,
michael@0 1828 const char* target, uint32_t len,
michael@0 1829 const char* buf, NPBool file, void* notifyData)
michael@0 1830 {
michael@0 1831 return sBrowserFuncs->posturlnotify(instance, url, target, len, buf, file, notifyData);
michael@0 1832 }
michael@0 1833
michael@0 1834 NPError
michael@0 1835 NPN_PostURL(NPP instance, const char *url,
michael@0 1836 const char *target, uint32_t len,
michael@0 1837 const char *buf, NPBool file)
michael@0 1838 {
michael@0 1839 return sBrowserFuncs->posturl(instance, url, target, len, buf, file);
michael@0 1840 }
michael@0 1841
michael@0 1842 NPError
michael@0 1843 NPN_DestroyStream(NPP instance, NPStream* stream, NPError reason)
michael@0 1844 {
michael@0 1845 return sBrowserFuncs->destroystream(instance, stream, reason);
michael@0 1846 }
michael@0 1847
michael@0 1848 NPError
michael@0 1849 NPN_NewStream(NPP instance,
michael@0 1850 NPMIMEType type,
michael@0 1851 const char* target,
michael@0 1852 NPStream** stream)
michael@0 1853 {
michael@0 1854 return sBrowserFuncs->newstream(instance, type, target, stream);
michael@0 1855 }
michael@0 1856
michael@0 1857 int32_t
michael@0 1858 NPN_Write(NPP instance,
michael@0 1859 NPStream* stream,
michael@0 1860 int32_t len,
michael@0 1861 void* buf)
michael@0 1862 {
michael@0 1863 return sBrowserFuncs->write(instance, stream, len, buf);
michael@0 1864 }
michael@0 1865
michael@0 1866 bool
michael@0 1867 NPN_Enumerate(NPP instance,
michael@0 1868 NPObject *npobj,
michael@0 1869 NPIdentifier **identifiers,
michael@0 1870 uint32_t *identifierCount)
michael@0 1871 {
michael@0 1872 return sBrowserFuncs->enumerate(instance, npobj, identifiers,
michael@0 1873 identifierCount);
michael@0 1874 }
michael@0 1875
michael@0 1876 bool
michael@0 1877 NPN_GetProperty(NPP instance,
michael@0 1878 NPObject *npobj,
michael@0 1879 NPIdentifier propertyName,
michael@0 1880 NPVariant *result)
michael@0 1881 {
michael@0 1882 return sBrowserFuncs->getproperty(instance, npobj, propertyName, result);
michael@0 1883 }
michael@0 1884
michael@0 1885 bool
michael@0 1886 NPN_Evaluate(NPP instance, NPObject *npobj, NPString *script, NPVariant *result)
michael@0 1887 {
michael@0 1888 return sBrowserFuncs->evaluate(instance, npobj, script, result);
michael@0 1889 }
michael@0 1890
michael@0 1891 void
michael@0 1892 NPN_SetException(NPObject *npobj, const NPUTF8 *message)
michael@0 1893 {
michael@0 1894 return sBrowserFuncs->setexception(npobj, message);
michael@0 1895 }
michael@0 1896
michael@0 1897 NPBool
michael@0 1898 NPN_ConvertPoint(NPP instance, double sourceX, double sourceY, NPCoordinateSpace sourceSpace, double *destX, double *destY, NPCoordinateSpace destSpace)
michael@0 1899 {
michael@0 1900 return sBrowserFuncs->convertpoint(instance, sourceX, sourceY, sourceSpace, destX, destY, destSpace);
michael@0 1901 }
michael@0 1902
michael@0 1903 NPError
michael@0 1904 NPN_SetValueForURL(NPP instance, NPNURLVariable variable, const char *url, const char *value, uint32_t len)
michael@0 1905 {
michael@0 1906 return sBrowserFuncs->setvalueforurl(instance, variable, url, value, len);
michael@0 1907 }
michael@0 1908
michael@0 1909 NPError
michael@0 1910 NPN_GetValueForURL(NPP instance, NPNURLVariable variable, const char *url, char **value, uint32_t *len)
michael@0 1911 {
michael@0 1912 return sBrowserFuncs->getvalueforurl(instance, variable, url, value, len);
michael@0 1913 }
michael@0 1914
michael@0 1915 NPError
michael@0 1916 NPN_GetAuthenticationInfo(NPP instance,
michael@0 1917 const char *protocol,
michael@0 1918 const char *host, int32_t port,
michael@0 1919 const char *scheme,
michael@0 1920 const char *realm,
michael@0 1921 char **username, uint32_t *ulen,
michael@0 1922 char **password,
michael@0 1923 uint32_t *plen)
michael@0 1924 {
michael@0 1925 return sBrowserFuncs->getauthenticationinfo(instance, protocol, host, port, scheme, realm,
michael@0 1926 username, ulen, password, plen);
michael@0 1927 }
michael@0 1928
michael@0 1929 void
michael@0 1930 NPN_PluginThreadAsyncCall(NPP plugin, void (*func)(void*), void* userdata)
michael@0 1931 {
michael@0 1932 return sBrowserFuncs->pluginthreadasynccall(plugin, func, userdata);
michael@0 1933 }
michael@0 1934
michael@0 1935 void
michael@0 1936 NPN_URLRedirectResponse(NPP instance, void* notifyData, NPBool allow)
michael@0 1937 {
michael@0 1938 return sBrowserFuncs->urlredirectresponse(instance, notifyData, allow);
michael@0 1939 }
michael@0 1940
michael@0 1941 NPError
michael@0 1942 NPN_InitAsyncSurface(NPP instance, NPSize *size, NPImageFormat format,
michael@0 1943 void *initData, NPAsyncSurface *surface)
michael@0 1944 {
michael@0 1945 return sBrowserFuncs->initasyncsurface(instance, size, format, initData, surface);
michael@0 1946 }
michael@0 1947
michael@0 1948 NPError
michael@0 1949 NPN_FinalizeAsyncSurface(NPP instance, NPAsyncSurface *surface)
michael@0 1950 {
michael@0 1951 return sBrowserFuncs->finalizeasyncsurface(instance, surface);
michael@0 1952 }
michael@0 1953
michael@0 1954 void
michael@0 1955 NPN_SetCurrentAsyncSurface(NPP instance, NPAsyncSurface *surface, NPRect *changed)
michael@0 1956 {
michael@0 1957 sBrowserFuncs->setcurrentasyncsurface(instance, surface, changed);
michael@0 1958 }
michael@0 1959
michael@0 1960 //
michael@0 1961 // npruntime object functions
michael@0 1962 //
michael@0 1963
michael@0 1964 NPObject*
michael@0 1965 scriptableAllocate(NPP npp, NPClass* aClass)
michael@0 1966 {
michael@0 1967 TestNPObject* object = (TestNPObject*)NPN_MemAlloc(sizeof(TestNPObject));
michael@0 1968 if (!object)
michael@0 1969 return nullptr;
michael@0 1970 memset(object, 0, sizeof(TestNPObject));
michael@0 1971 return object;
michael@0 1972 }
michael@0 1973
michael@0 1974 void
michael@0 1975 scriptableDeallocate(NPObject* npobj)
michael@0 1976 {
michael@0 1977 NPN_MemFree(npobj);
michael@0 1978 }
michael@0 1979
michael@0 1980 void
michael@0 1981 scriptableInvalidate(NPObject* npobj)
michael@0 1982 {
michael@0 1983 }
michael@0 1984
michael@0 1985 bool
michael@0 1986 scriptableHasMethod(NPObject* npobj, NPIdentifier name)
michael@0 1987 {
michael@0 1988 for (int i = 0; i < int(ARRAY_LENGTH(sPluginMethodIdentifiers)); i++) {
michael@0 1989 if (name == sPluginMethodIdentifiers[i])
michael@0 1990 return true;
michael@0 1991 }
michael@0 1992 return false;
michael@0 1993 }
michael@0 1994
michael@0 1995 bool
michael@0 1996 scriptableInvoke(NPObject* npobj, NPIdentifier name, const NPVariant* args, uint32_t argCount, NPVariant* result)
michael@0 1997 {
michael@0 1998 NPP npp = static_cast<TestNPObject*>(npobj)->npp;
michael@0 1999 InstanceData* id = static_cast<InstanceData*>(npp->pdata);
michael@0 2000 if (id->throwOnNextInvoke) {
michael@0 2001 id->throwOnNextInvoke = false;
michael@0 2002 if (argCount == 0) {
michael@0 2003 NPN_SetException(npobj, nullptr);
michael@0 2004 }
michael@0 2005 else {
michael@0 2006 for (uint32_t i = 0; i < argCount; i++) {
michael@0 2007 const NPString* argstr = &NPVARIANT_TO_STRING(args[i]);
michael@0 2008 NPN_SetException(npobj, argstr->UTF8Characters);
michael@0 2009 }
michael@0 2010 }
michael@0 2011 return false;
michael@0 2012 }
michael@0 2013
michael@0 2014 for (int i = 0; i < int(ARRAY_LENGTH(sPluginMethodIdentifiers)); i++) {
michael@0 2015 if (name == sPluginMethodIdentifiers[i])
michael@0 2016 return sPluginMethodFunctions[i](npobj, args, argCount, result);
michael@0 2017 }
michael@0 2018 return false;
michael@0 2019 }
michael@0 2020
michael@0 2021 bool
michael@0 2022 scriptableInvokeDefault(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
michael@0 2023 {
michael@0 2024 NPP npp = static_cast<TestNPObject*>(npobj)->npp;
michael@0 2025 InstanceData* id = static_cast<InstanceData*>(npp->pdata);
michael@0 2026 if (id->throwOnNextInvoke) {
michael@0 2027 id->throwOnNextInvoke = false;
michael@0 2028 if (argCount == 0) {
michael@0 2029 NPN_SetException(npobj, nullptr);
michael@0 2030 }
michael@0 2031 else {
michael@0 2032 for (uint32_t i = 0; i < argCount; i++) {
michael@0 2033 const NPString* argstr = &NPVARIANT_TO_STRING(args[i]);
michael@0 2034 NPN_SetException(npobj, argstr->UTF8Characters);
michael@0 2035 }
michael@0 2036 }
michael@0 2037 return false;
michael@0 2038 }
michael@0 2039
michael@0 2040 ostringstream value;
michael@0 2041 value << sPluginName;
michael@0 2042 for (uint32_t i = 0; i < argCount; i++) {
michael@0 2043 switch(args[i].type) {
michael@0 2044 case NPVariantType_Int32:
michael@0 2045 value << ";" << NPVARIANT_TO_INT32(args[i]);
michael@0 2046 break;
michael@0 2047 case NPVariantType_String: {
michael@0 2048 const NPString* argstr = &NPVARIANT_TO_STRING(args[i]);
michael@0 2049 value << ";" << argstr->UTF8Characters;
michael@0 2050 break;
michael@0 2051 }
michael@0 2052 case NPVariantType_Void:
michael@0 2053 value << ";undefined";
michael@0 2054 break;
michael@0 2055 case NPVariantType_Null:
michael@0 2056 value << ";null";
michael@0 2057 break;
michael@0 2058 default:
michael@0 2059 value << ";other";
michael@0 2060 }
michael@0 2061 }
michael@0 2062
michael@0 2063 char *outval = NPN_StrDup(value.str().c_str());
michael@0 2064 STRINGZ_TO_NPVARIANT(outval, *result);
michael@0 2065 return true;
michael@0 2066 }
michael@0 2067
michael@0 2068 bool
michael@0 2069 scriptableHasProperty(NPObject* npobj, NPIdentifier name)
michael@0 2070 {
michael@0 2071 if (NPN_IdentifierIsString(name)) {
michael@0 2072 NPUTF8 *asUTF8 = NPN_UTF8FromIdentifier(name);
michael@0 2073 if (NPN_GetStringIdentifier(asUTF8) != name) {
michael@0 2074 Crash();
michael@0 2075 }
michael@0 2076 NPN_MemFree(asUTF8);
michael@0 2077 }
michael@0 2078 else {
michael@0 2079 if (NPN_GetIntIdentifier(NPN_IntFromIdentifier(name)) != name) {
michael@0 2080 Crash();
michael@0 2081 }
michael@0 2082 }
michael@0 2083 for (int i = 0; i < int(ARRAY_LENGTH(sPluginPropertyIdentifiers)); i++) {
michael@0 2084 if (name == sPluginPropertyIdentifiers[i]) {
michael@0 2085 return true;
michael@0 2086 }
michael@0 2087 }
michael@0 2088 return false;
michael@0 2089 }
michael@0 2090
michael@0 2091 bool
michael@0 2092 scriptableGetProperty(NPObject* npobj, NPIdentifier name, NPVariant* result)
michael@0 2093 {
michael@0 2094 for (int i = 0; i < int(ARRAY_LENGTH(sPluginPropertyIdentifiers)); i++) {
michael@0 2095 if (name == sPluginPropertyIdentifiers[i]) {
michael@0 2096 DuplicateNPVariant(*result, sPluginPropertyValues[i]);
michael@0 2097 return true;
michael@0 2098 }
michael@0 2099 }
michael@0 2100 return false;
michael@0 2101 }
michael@0 2102
michael@0 2103 bool
michael@0 2104 scriptableSetProperty(NPObject* npobj, NPIdentifier name, const NPVariant* value)
michael@0 2105 {
michael@0 2106 for (int i = 0; i < int(ARRAY_LENGTH(sPluginPropertyIdentifiers)); i++) {
michael@0 2107 if (name == sPluginPropertyIdentifiers[i]) {
michael@0 2108 NPN_ReleaseVariantValue(&sPluginPropertyValues[i]);
michael@0 2109 DuplicateNPVariant(sPluginPropertyValues[i], *value);
michael@0 2110 return true;
michael@0 2111 }
michael@0 2112 }
michael@0 2113 return false;
michael@0 2114 }
michael@0 2115
michael@0 2116 bool
michael@0 2117 scriptableRemoveProperty(NPObject* npobj, NPIdentifier name)
michael@0 2118 {
michael@0 2119 for (int i = 0; i < int(ARRAY_LENGTH(sPluginPropertyIdentifiers)); i++) {
michael@0 2120 if (name == sPluginPropertyIdentifiers[i]) {
michael@0 2121 NPN_ReleaseVariantValue(&sPluginPropertyValues[i]);
michael@0 2122 return true;
michael@0 2123 }
michael@0 2124 }
michael@0 2125 return false;
michael@0 2126 }
michael@0 2127
michael@0 2128 bool
michael@0 2129 scriptableEnumerate(NPObject* npobj, NPIdentifier** identifier, uint32_t* count)
michael@0 2130 {
michael@0 2131 const int bufsize = sizeof(NPIdentifier) * ARRAY_LENGTH(sPluginMethodIdentifierNames);
michael@0 2132 NPIdentifier* ids = (NPIdentifier*) NPN_MemAlloc(bufsize);
michael@0 2133 if (!ids)
michael@0 2134 return false;
michael@0 2135
michael@0 2136 memcpy(ids, sPluginMethodIdentifiers, bufsize);
michael@0 2137 *identifier = ids;
michael@0 2138 *count = ARRAY_LENGTH(sPluginMethodIdentifierNames);
michael@0 2139 return true;
michael@0 2140 }
michael@0 2141
michael@0 2142 bool
michael@0 2143 scriptableConstruct(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
michael@0 2144 {
michael@0 2145 return false;
michael@0 2146 }
michael@0 2147
michael@0 2148 //
michael@0 2149 // test functions
michael@0 2150 //
michael@0 2151
michael@0 2152 static bool
michael@0 2153 compareVariants(NPP instance, const NPVariant* var1, const NPVariant* var2)
michael@0 2154 {
michael@0 2155 bool success = true;
michael@0 2156 InstanceData* id = static_cast<InstanceData*>(instance->pdata);
michael@0 2157 if (var1->type != var2->type) {
michael@0 2158 id->err << "Variant types don't match; got " << var1->type <<
michael@0 2159 " expected " << var2->type;
michael@0 2160 return false;
michael@0 2161 }
michael@0 2162
michael@0 2163 switch (var1->type) {
michael@0 2164 case NPVariantType_Int32: {
michael@0 2165 int32_t result = NPVARIANT_TO_INT32(*var1);
michael@0 2166 int32_t expected = NPVARIANT_TO_INT32(*var2);
michael@0 2167 if (result != expected) {
michael@0 2168 id->err << "Variant values don't match; got " << result <<
michael@0 2169 " expected " << expected;
michael@0 2170 success = false;
michael@0 2171 }
michael@0 2172 break;
michael@0 2173 }
michael@0 2174 case NPVariantType_Double: {
michael@0 2175 double result = NPVARIANT_TO_DOUBLE(*var1);
michael@0 2176 double expected = NPVARIANT_TO_DOUBLE(*var2);
michael@0 2177 if (result != expected) {
michael@0 2178 id->err << "Variant values don't match (double)";
michael@0 2179 success = false;
michael@0 2180 }
michael@0 2181 break;
michael@0 2182 }
michael@0 2183 case NPVariantType_Void: {
michael@0 2184 // void values are always equivalent
michael@0 2185 break;
michael@0 2186 }
michael@0 2187 case NPVariantType_Null: {
michael@0 2188 // null values are always equivalent
michael@0 2189 break;
michael@0 2190 }
michael@0 2191 case NPVariantType_Bool: {
michael@0 2192 bool result = NPVARIANT_TO_BOOLEAN(*var1);
michael@0 2193 bool expected = NPVARIANT_TO_BOOLEAN(*var2);
michael@0 2194 if (result != expected) {
michael@0 2195 id->err << "Variant values don't match (bool)";
michael@0 2196 success = false;
michael@0 2197 }
michael@0 2198 break;
michael@0 2199 }
michael@0 2200 case NPVariantType_String: {
michael@0 2201 const NPString* result = &NPVARIANT_TO_STRING(*var1);
michael@0 2202 const NPString* expected = &NPVARIANT_TO_STRING(*var2);
michael@0 2203 if (strcmp(result->UTF8Characters, expected->UTF8Characters) ||
michael@0 2204 strlen(result->UTF8Characters) != strlen(expected->UTF8Characters)) {
michael@0 2205 id->err << "Variant values don't match; got " <<
michael@0 2206 result->UTF8Characters << " expected " <<
michael@0 2207 expected->UTF8Characters;
michael@0 2208 success = false;
michael@0 2209 }
michael@0 2210 break;
michael@0 2211 }
michael@0 2212 case NPVariantType_Object: {
michael@0 2213 uint32_t i, identifierCount = 0;
michael@0 2214 NPIdentifier* identifiers;
michael@0 2215 NPObject* result = NPVARIANT_TO_OBJECT(*var1);
michael@0 2216 NPObject* expected = NPVARIANT_TO_OBJECT(*var2);
michael@0 2217 bool enumerate_result = NPN_Enumerate(instance, expected,
michael@0 2218 &identifiers, &identifierCount);
michael@0 2219 if (!enumerate_result) {
michael@0 2220 id->err << "NPN_Enumerate failed";
michael@0 2221 success = false;
michael@0 2222 }
michael@0 2223 for (i = 0; i < identifierCount; i++) {
michael@0 2224 NPVariant resultVariant, expectedVariant;
michael@0 2225 if (!NPN_GetProperty(instance, expected, identifiers[i],
michael@0 2226 &expectedVariant)) {
michael@0 2227 id->err << "NPN_GetProperty returned false";
michael@0 2228 success = false;
michael@0 2229 }
michael@0 2230 else {
michael@0 2231 if (!NPN_HasProperty(instance, result, identifiers[i])) {
michael@0 2232 id->err << "NPN_HasProperty returned false";
michael@0 2233 success = false;
michael@0 2234 }
michael@0 2235 else {
michael@0 2236 if (!NPN_GetProperty(instance, result, identifiers[i],
michael@0 2237 &resultVariant)) {
michael@0 2238 id->err << "NPN_GetProperty 2 returned false";
michael@0 2239 success = false;
michael@0 2240 }
michael@0 2241 else {
michael@0 2242 success = compareVariants(instance, &resultVariant,
michael@0 2243 &expectedVariant);
michael@0 2244 NPN_ReleaseVariantValue(&expectedVariant);
michael@0 2245 }
michael@0 2246 }
michael@0 2247 NPN_ReleaseVariantValue(&resultVariant);
michael@0 2248 }
michael@0 2249 }
michael@0 2250 break;
michael@0 2251 }
michael@0 2252 default:
michael@0 2253 id->err << "Unknown variant type";
michael@0 2254 success = false;
michael@0 2255 }
michael@0 2256
michael@0 2257 return success;
michael@0 2258 }
michael@0 2259
michael@0 2260 static bool
michael@0 2261 throwExceptionNextInvoke(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
michael@0 2262 {
michael@0 2263 NPP npp = static_cast<TestNPObject*>(npobj)->npp;
michael@0 2264 InstanceData* id = static_cast<InstanceData*>(npp->pdata);
michael@0 2265 id->throwOnNextInvoke = true;
michael@0 2266 BOOLEAN_TO_NPVARIANT(true, *result);
michael@0 2267 return true;
michael@0 2268 }
michael@0 2269
michael@0 2270 static bool
michael@0 2271 npnInvokeDefaultTest(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
michael@0 2272 {
michael@0 2273 bool success = false;
michael@0 2274 NPP npp = static_cast<TestNPObject*>(npobj)->npp;
michael@0 2275
michael@0 2276 NPObject* windowObject;
michael@0 2277 NPN_GetValue(npp, NPNVWindowNPObject, &windowObject);
michael@0 2278 if (!windowObject)
michael@0 2279 return false;
michael@0 2280
michael@0 2281 NPIdentifier objectIdentifier = variantToIdentifier(args[0]);
michael@0 2282 if (!objectIdentifier)
michael@0 2283 return false;
michael@0 2284
michael@0 2285 NPVariant objectVariant;
michael@0 2286 if (NPN_GetProperty(npp, windowObject, objectIdentifier,
michael@0 2287 &objectVariant)) {
michael@0 2288 if (NPVARIANT_IS_OBJECT(objectVariant)) {
michael@0 2289 NPObject* selfObject = NPVARIANT_TO_OBJECT(objectVariant);
michael@0 2290 if (selfObject != nullptr) {
michael@0 2291 NPVariant resultVariant;
michael@0 2292 if (NPN_InvokeDefault(npp, selfObject, argCount > 1 ? &args[1] : nullptr,
michael@0 2293 argCount - 1, &resultVariant)) {
michael@0 2294 *result = resultVariant;
michael@0 2295 success = true;
michael@0 2296 }
michael@0 2297 }
michael@0 2298 }
michael@0 2299 NPN_ReleaseVariantValue(&objectVariant);
michael@0 2300 }
michael@0 2301
michael@0 2302 NPN_ReleaseObject(windowObject);
michael@0 2303 return success;
michael@0 2304 }
michael@0 2305
michael@0 2306 static bool
michael@0 2307 npnInvokeTest(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
michael@0 2308 {
michael@0 2309 NPP npp = static_cast<TestNPObject*>(npobj)->npp;
michael@0 2310 InstanceData* id = static_cast<InstanceData*>(npp->pdata);
michael@0 2311 id->err.str("");
michael@0 2312 if (argCount < 2)
michael@0 2313 return false;
michael@0 2314
michael@0 2315 NPIdentifier function = variantToIdentifier(args[0]);
michael@0 2316 if (!function)
michael@0 2317 return false;
michael@0 2318
michael@0 2319 NPObject* windowObject;
michael@0 2320 NPN_GetValue(npp, NPNVWindowNPObject, &windowObject);
michael@0 2321 if (!windowObject)
michael@0 2322 return false;
michael@0 2323
michael@0 2324 NPVariant invokeResult;
michael@0 2325 bool invokeReturn = NPN_Invoke(npp, windowObject, function,
michael@0 2326 argCount > 2 ? &args[2] : nullptr, argCount - 2, &invokeResult);
michael@0 2327
michael@0 2328 bool compareResult = compareVariants(npp, &invokeResult, &args[1]);
michael@0 2329
michael@0 2330 NPN_ReleaseObject(windowObject);
michael@0 2331 NPN_ReleaseVariantValue(&invokeResult);
michael@0 2332 BOOLEAN_TO_NPVARIANT(invokeReturn && compareResult, *result);
michael@0 2333 return true;
michael@0 2334 }
michael@0 2335
michael@0 2336 static bool
michael@0 2337 npnEvaluateTest(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
michael@0 2338 {
michael@0 2339 bool success = false;
michael@0 2340 NPP npp = static_cast<TestNPObject*>(npobj)->npp;
michael@0 2341
michael@0 2342 if (argCount != 1)
michael@0 2343 return false;
michael@0 2344
michael@0 2345 if (!NPVARIANT_IS_STRING(args[0]))
michael@0 2346 return false;
michael@0 2347
michael@0 2348 NPObject* windowObject;
michael@0 2349 NPN_GetValue(npp, NPNVWindowNPObject, &windowObject);
michael@0 2350 if (!windowObject)
michael@0 2351 return false;
michael@0 2352
michael@0 2353 success = NPN_Evaluate(npp, windowObject, (NPString*)&NPVARIANT_TO_STRING(args[0]), result);
michael@0 2354
michael@0 2355 NPN_ReleaseObject(windowObject);
michael@0 2356 return success;
michael@0 2357 }
michael@0 2358
michael@0 2359 static bool
michael@0 2360 setUndefinedValueTest(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
michael@0 2361 {
michael@0 2362 NPP npp = static_cast<TestNPObject*>(npobj)->npp;
michael@0 2363 NPError err = NPN_SetValue(npp, (NPPVariable)0x0, 0x0);
michael@0 2364 BOOLEAN_TO_NPVARIANT((err == NPERR_NO_ERROR), *result);
michael@0 2365 return true;
michael@0 2366 }
michael@0 2367
michael@0 2368 static bool
michael@0 2369 identifierToStringTest(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
michael@0 2370 {
michael@0 2371 if (argCount != 1)
michael@0 2372 return false;
michael@0 2373 NPIdentifier identifier = variantToIdentifier(args[0]);
michael@0 2374 if (!identifier)
michael@0 2375 return false;
michael@0 2376
michael@0 2377 NPUTF8* utf8String = NPN_UTF8FromIdentifier(identifier);
michael@0 2378 if (!utf8String)
michael@0 2379 return false;
michael@0 2380 STRINGZ_TO_NPVARIANT(utf8String, *result);
michael@0 2381 return true;
michael@0 2382 }
michael@0 2383
michael@0 2384 static bool
michael@0 2385 queryPrivateModeState(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
michael@0 2386 {
michael@0 2387 if (argCount != 0)
michael@0 2388 return false;
michael@0 2389
michael@0 2390 NPBool pms = false;
michael@0 2391 NPN_GetValue(static_cast<TestNPObject*>(npobj)->npp, NPNVprivateModeBool, &pms);
michael@0 2392 BOOLEAN_TO_NPVARIANT(pms, *result);
michael@0 2393 return true;
michael@0 2394 }
michael@0 2395
michael@0 2396 static bool
michael@0 2397 lastReportedPrivateModeState(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
michael@0 2398 {
michael@0 2399 if (argCount != 0)
michael@0 2400 return false;
michael@0 2401
michael@0 2402 InstanceData* id = static_cast<InstanceData*>(static_cast<TestNPObject*>(npobj)->npp->pdata);
michael@0 2403 BOOLEAN_TO_NPVARIANT(id->lastReportedPrivateModeState, *result);
michael@0 2404 return true;
michael@0 2405 }
michael@0 2406
michael@0 2407 static bool
michael@0 2408 hasWidget(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
michael@0 2409 {
michael@0 2410 if (argCount != 0)
michael@0 2411 return false;
michael@0 2412
michael@0 2413 InstanceData* id = static_cast<InstanceData*>(static_cast<TestNPObject*>(npobj)->npp->pdata);
michael@0 2414 BOOLEAN_TO_NPVARIANT(id->hasWidget, *result);
michael@0 2415 return true;
michael@0 2416 }
michael@0 2417
michael@0 2418 static bool
michael@0 2419 getEdge(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
michael@0 2420 {
michael@0 2421 if (argCount != 1)
michael@0 2422 return false;
michael@0 2423 if (!NPVARIANT_IS_INT32(args[0]))
michael@0 2424 return false;
michael@0 2425 int32_t edge = NPVARIANT_TO_INT32(args[0]);
michael@0 2426 if (edge < EDGE_LEFT || edge > EDGE_BOTTOM)
michael@0 2427 return false;
michael@0 2428
michael@0 2429 InstanceData* id = static_cast<InstanceData*>(static_cast<TestNPObject*>(npobj)->npp->pdata);
michael@0 2430 int32_t r = pluginGetEdge(id, RectEdge(edge));
michael@0 2431 if (r == NPTEST_INT32_ERROR)
michael@0 2432 return false;
michael@0 2433 INT32_TO_NPVARIANT(r, *result);
michael@0 2434 return true;
michael@0 2435 }
michael@0 2436
michael@0 2437 static bool
michael@0 2438 getClipRegionRectCount(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
michael@0 2439 {
michael@0 2440 if (argCount != 0)
michael@0 2441 return false;
michael@0 2442
michael@0 2443 InstanceData* id = static_cast<InstanceData*>(static_cast<TestNPObject*>(npobj)->npp->pdata);
michael@0 2444 int32_t r = pluginGetClipRegionRectCount(id);
michael@0 2445 if (r == NPTEST_INT32_ERROR)
michael@0 2446 return false;
michael@0 2447 INT32_TO_NPVARIANT(r, *result);
michael@0 2448 return true;
michael@0 2449 }
michael@0 2450
michael@0 2451 static bool
michael@0 2452 getClipRegionRectEdge(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
michael@0 2453 {
michael@0 2454 if (argCount != 2)
michael@0 2455 return false;
michael@0 2456 if (!NPVARIANT_IS_INT32(args[0]))
michael@0 2457 return false;
michael@0 2458 int32_t rectIndex = NPVARIANT_TO_INT32(args[0]);
michael@0 2459 if (rectIndex < 0)
michael@0 2460 return false;
michael@0 2461 if (!NPVARIANT_IS_INT32(args[1]))
michael@0 2462 return false;
michael@0 2463 int32_t edge = NPVARIANT_TO_INT32(args[1]);
michael@0 2464 if (edge < EDGE_LEFT || edge > EDGE_BOTTOM)
michael@0 2465 return false;
michael@0 2466
michael@0 2467 InstanceData* id = static_cast<InstanceData*>(static_cast<TestNPObject*>(npobj)->npp->pdata);
michael@0 2468 int32_t r = pluginGetClipRegionRectEdge(id, rectIndex, RectEdge(edge));
michael@0 2469 if (r == NPTEST_INT32_ERROR)
michael@0 2470 return false;
michael@0 2471 INT32_TO_NPVARIANT(r, *result);
michael@0 2472 return true;
michael@0 2473 }
michael@0 2474
michael@0 2475 static bool
michael@0 2476 startWatchingInstanceCount(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
michael@0 2477 {
michael@0 2478 if (argCount != 0)
michael@0 2479 return false;
michael@0 2480 if (sWatchingInstanceCount)
michael@0 2481 return false;
michael@0 2482
michael@0 2483 sWatchingInstanceCount = true;
michael@0 2484 sInstanceCount = 0;
michael@0 2485 ++sCurrentInstanceCountWatchGeneration;
michael@0 2486 return true;
michael@0 2487 }
michael@0 2488
michael@0 2489 static bool
michael@0 2490 getInstanceCount(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
michael@0 2491 {
michael@0 2492 if (argCount != 0)
michael@0 2493 return false;
michael@0 2494 if (!sWatchingInstanceCount)
michael@0 2495 return false;
michael@0 2496
michael@0 2497 INT32_TO_NPVARIANT(sInstanceCount, *result);
michael@0 2498 return true;
michael@0 2499 }
michael@0 2500
michael@0 2501 static bool
michael@0 2502 stopWatchingInstanceCount(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
michael@0 2503 {
michael@0 2504 if (argCount != 0)
michael@0 2505 return false;
michael@0 2506 if (!sWatchingInstanceCount)
michael@0 2507 return false;
michael@0 2508
michael@0 2509 sWatchingInstanceCount = false;
michael@0 2510 return true;
michael@0 2511 }
michael@0 2512
michael@0 2513 static bool
michael@0 2514 getLastMouseX(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
michael@0 2515 {
michael@0 2516 if (argCount != 0)
michael@0 2517 return false;
michael@0 2518
michael@0 2519 NPP npp = static_cast<TestNPObject*>(npobj)->npp;
michael@0 2520 InstanceData* id = static_cast<InstanceData*>(npp->pdata);
michael@0 2521 INT32_TO_NPVARIANT(id->lastMouseX, *result);
michael@0 2522 return true;
michael@0 2523 }
michael@0 2524
michael@0 2525 static bool
michael@0 2526 getLastMouseY(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
michael@0 2527 {
michael@0 2528 if (argCount != 0)
michael@0 2529 return false;
michael@0 2530
michael@0 2531 NPP npp = static_cast<TestNPObject*>(npobj)->npp;
michael@0 2532 InstanceData* id = static_cast<InstanceData*>(npp->pdata);
michael@0 2533 INT32_TO_NPVARIANT(id->lastMouseY, *result);
michael@0 2534 return true;
michael@0 2535 }
michael@0 2536
michael@0 2537 static bool
michael@0 2538 getPaintCount(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
michael@0 2539 {
michael@0 2540 if (argCount != 0)
michael@0 2541 return false;
michael@0 2542
michael@0 2543 NPP npp = static_cast<TestNPObject*>(npobj)->npp;
michael@0 2544 InstanceData* id = static_cast<InstanceData*>(npp->pdata);
michael@0 2545 INT32_TO_NPVARIANT(id->paintCount, *result);
michael@0 2546 return true;
michael@0 2547 }
michael@0 2548
michael@0 2549 static bool
michael@0 2550 getWidthAtLastPaint(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
michael@0 2551 {
michael@0 2552 if (argCount != 0)
michael@0 2553 return false;
michael@0 2554
michael@0 2555 NPP npp = static_cast<TestNPObject*>(npobj)->npp;
michael@0 2556 InstanceData* id = static_cast<InstanceData*>(npp->pdata);
michael@0 2557 INT32_TO_NPVARIANT(id->widthAtLastPaint, *result);
michael@0 2558 return true;
michael@0 2559 }
michael@0 2560
michael@0 2561 static bool
michael@0 2562 setInvalidateDuringPaint(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
michael@0 2563 {
michael@0 2564 if (argCount != 1)
michael@0 2565 return false;
michael@0 2566
michael@0 2567 if (!NPVARIANT_IS_BOOLEAN(args[0]))
michael@0 2568 return false;
michael@0 2569 bool doInvalidate = NPVARIANT_TO_BOOLEAN(args[0]);
michael@0 2570
michael@0 2571 NPP npp = static_cast<TestNPObject*>(npobj)->npp;
michael@0 2572 InstanceData* id = static_cast<InstanceData*>(npp->pdata);
michael@0 2573 id->invalidateDuringPaint = doInvalidate;
michael@0 2574 return true;
michael@0 2575 }
michael@0 2576
michael@0 2577 static bool
michael@0 2578 setSlowPaint(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
michael@0 2579 {
michael@0 2580 if (argCount != 1)
michael@0 2581 return false;
michael@0 2582
michael@0 2583 if (!NPVARIANT_IS_BOOLEAN(args[0]))
michael@0 2584 return false;
michael@0 2585 bool slow = NPVARIANT_TO_BOOLEAN(args[0]);
michael@0 2586
michael@0 2587 NPP npp = static_cast<TestNPObject*>(npobj)->npp;
michael@0 2588 InstanceData* id = static_cast<InstanceData*>(npp->pdata);
michael@0 2589 id->slowPaint = slow;
michael@0 2590 return true;
michael@0 2591 }
michael@0 2592
michael@0 2593 static bool
michael@0 2594 getError(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
michael@0 2595 {
michael@0 2596 if (argCount != 0)
michael@0 2597 return false;
michael@0 2598
michael@0 2599 NPP npp = static_cast<TestNPObject*>(npobj)->npp;
michael@0 2600 InstanceData* id = static_cast<InstanceData*>(npp->pdata);
michael@0 2601 if (id->err.str().length() == 0) {
michael@0 2602 char *outval = NPN_StrDup(SUCCESS_STRING);
michael@0 2603 STRINGZ_TO_NPVARIANT(outval, *result);
michael@0 2604 } else {
michael@0 2605 char *outval = NPN_StrDup(id->err.str().c_str());
michael@0 2606 STRINGZ_TO_NPVARIANT(outval, *result);
michael@0 2607 }
michael@0 2608 return true;
michael@0 2609 }
michael@0 2610
michael@0 2611 static bool
michael@0 2612 doInternalConsistencyCheck(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
michael@0 2613 {
michael@0 2614 if (argCount != 0)
michael@0 2615 return false;
michael@0 2616
michael@0 2617 NPP npp = static_cast<TestNPObject*>(npobj)->npp;
michael@0 2618 InstanceData* id = static_cast<InstanceData*>(npp->pdata);
michael@0 2619 string error;
michael@0 2620 pluginDoInternalConsistencyCheck(id, error);
michael@0 2621 NPUTF8* utf8String = (NPUTF8*)NPN_MemAlloc(error.length() + 1);
michael@0 2622 if (!utf8String) {
michael@0 2623 return false;
michael@0 2624 }
michael@0 2625 memcpy(utf8String, error.c_str(), error.length() + 1);
michael@0 2626 STRINGZ_TO_NPVARIANT(utf8String, *result);
michael@0 2627 return true;
michael@0 2628 }
michael@0 2629
michael@0 2630 static bool
michael@0 2631 convertPointX(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
michael@0 2632 {
michael@0 2633 if (argCount != 4)
michael@0 2634 return false;
michael@0 2635
michael@0 2636 NPP npp = static_cast<TestNPObject*>(npobj)->npp;
michael@0 2637
michael@0 2638 if (!NPVARIANT_IS_INT32(args[0]))
michael@0 2639 return false;
michael@0 2640 int32_t sourceSpace = NPVARIANT_TO_INT32(args[0]);
michael@0 2641
michael@0 2642 if (!NPVARIANT_IS_INT32(args[1]))
michael@0 2643 return false;
michael@0 2644 double sourceX = static_cast<double>(NPVARIANT_TO_INT32(args[1]));
michael@0 2645
michael@0 2646 if (!NPVARIANT_IS_INT32(args[2]))
michael@0 2647 return false;
michael@0 2648 double sourceY = static_cast<double>(NPVARIANT_TO_INT32(args[2]));
michael@0 2649
michael@0 2650 if (!NPVARIANT_IS_INT32(args[3]))
michael@0 2651 return false;
michael@0 2652 int32_t destSpace = NPVARIANT_TO_INT32(args[3]);
michael@0 2653
michael@0 2654 double resultX, resultY;
michael@0 2655 NPN_ConvertPoint(npp, sourceX, sourceY, (NPCoordinateSpace)sourceSpace, &resultX, &resultY, (NPCoordinateSpace)destSpace);
michael@0 2656
michael@0 2657 DOUBLE_TO_NPVARIANT(resultX, *result);
michael@0 2658 return true;
michael@0 2659 }
michael@0 2660
michael@0 2661 static bool
michael@0 2662 convertPointY(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
michael@0 2663 {
michael@0 2664 if (argCount != 4)
michael@0 2665 return false;
michael@0 2666
michael@0 2667 NPP npp = static_cast<TestNPObject*>(npobj)->npp;
michael@0 2668
michael@0 2669 if (!NPVARIANT_IS_INT32(args[0]))
michael@0 2670 return false;
michael@0 2671 int32_t sourceSpace = NPVARIANT_TO_INT32(args[0]);
michael@0 2672
michael@0 2673 if (!NPVARIANT_IS_INT32(args[1]))
michael@0 2674 return false;
michael@0 2675 double sourceX = static_cast<double>(NPVARIANT_TO_INT32(args[1]));
michael@0 2676
michael@0 2677 if (!NPVARIANT_IS_INT32(args[2]))
michael@0 2678 return false;
michael@0 2679 double sourceY = static_cast<double>(NPVARIANT_TO_INT32(args[2]));
michael@0 2680
michael@0 2681 if (!NPVARIANT_IS_INT32(args[3]))
michael@0 2682 return false;
michael@0 2683 int32_t destSpace = NPVARIANT_TO_INT32(args[3]);
michael@0 2684
michael@0 2685 double resultX, resultY;
michael@0 2686 NPN_ConvertPoint(npp, sourceX, sourceY, (NPCoordinateSpace)sourceSpace, &resultX, &resultY, (NPCoordinateSpace)destSpace);
michael@0 2687
michael@0 2688 DOUBLE_TO_NPVARIANT(resultY, *result);
michael@0 2689 return true;
michael@0 2690 }
michael@0 2691
michael@0 2692 static bool
michael@0 2693 streamTest(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
michael@0 2694 {
michael@0 2695 // .streamTest(url, doPost, doNull, writeCallback, notifyCallback, redirectCallback, allowRedirects)
michael@0 2696 if (7 != argCount)
michael@0 2697 return false;
michael@0 2698
michael@0 2699 NPP npp = static_cast<TestNPObject*>(npobj)->npp;
michael@0 2700
michael@0 2701 if (!NPVARIANT_IS_STRING(args[0]))
michael@0 2702 return false;
michael@0 2703 NPString url = NPVARIANT_TO_STRING(args[0]);
michael@0 2704
michael@0 2705 if (!NPVARIANT_IS_BOOLEAN(args[1]))
michael@0 2706 return false;
michael@0 2707 bool doPost = NPVARIANT_TO_BOOLEAN(args[1]);
michael@0 2708
michael@0 2709 NPString postData = { nullptr, 0 };
michael@0 2710 if (NPVARIANT_IS_STRING(args[2])) {
michael@0 2711 postData = NPVARIANT_TO_STRING(args[2]);
michael@0 2712 }
michael@0 2713 else {
michael@0 2714 if (!NPVARIANT_IS_NULL(args[2])) {
michael@0 2715 return false;
michael@0 2716 }
michael@0 2717 }
michael@0 2718
michael@0 2719 NPObject* writeCallback = nullptr;
michael@0 2720 if (NPVARIANT_IS_OBJECT(args[3])) {
michael@0 2721 writeCallback = NPVARIANT_TO_OBJECT(args[3]);
michael@0 2722 }
michael@0 2723 else {
michael@0 2724 if (!NPVARIANT_IS_NULL(args[3])) {
michael@0 2725 return false;
michael@0 2726 }
michael@0 2727 }
michael@0 2728
michael@0 2729 NPObject* notifyCallback = nullptr;
michael@0 2730 if (NPVARIANT_IS_OBJECT(args[4])) {
michael@0 2731 notifyCallback = NPVARIANT_TO_OBJECT(args[4]);
michael@0 2732 }
michael@0 2733 else {
michael@0 2734 if (!NPVARIANT_IS_NULL(args[4])) {
michael@0 2735 return false;
michael@0 2736 }
michael@0 2737 }
michael@0 2738
michael@0 2739 NPObject* redirectCallback = nullptr;
michael@0 2740 if (NPVARIANT_IS_OBJECT(args[5])) {
michael@0 2741 redirectCallback = NPVARIANT_TO_OBJECT(args[5]);
michael@0 2742 }
michael@0 2743 else {
michael@0 2744 if (!NPVARIANT_IS_NULL(args[5])) {
michael@0 2745 return false;
michael@0 2746 }
michael@0 2747 }
michael@0 2748
michael@0 2749 if (!NPVARIANT_IS_BOOLEAN(args[6]))
michael@0 2750 return false;
michael@0 2751 bool allowRedirects = NPVARIANT_TO_BOOLEAN(args[6]);
michael@0 2752
michael@0 2753 URLNotifyData* ndata = new URLNotifyData;
michael@0 2754 ndata->cookie = "dynamic-cookie";
michael@0 2755 ndata->writeCallback = writeCallback;
michael@0 2756 ndata->notifyCallback = notifyCallback;
michael@0 2757 ndata->redirectCallback = redirectCallback;
michael@0 2758 ndata->size = 0;
michael@0 2759 ndata->data = nullptr;
michael@0 2760 ndata->allowRedirects = allowRedirects;
michael@0 2761
michael@0 2762 /* null-terminate "url" */
michael@0 2763 char* urlstr = (char*) malloc(url.UTF8Length + 1);
michael@0 2764 strncpy(urlstr, url.UTF8Characters, url.UTF8Length);
michael@0 2765 urlstr[url.UTF8Length] = '\0';
michael@0 2766
michael@0 2767 NPError err;
michael@0 2768 if (doPost) {
michael@0 2769 err = NPN_PostURLNotify(npp, urlstr, nullptr,
michael@0 2770 postData.UTF8Length, postData.UTF8Characters,
michael@0 2771 false, ndata);
michael@0 2772 }
michael@0 2773 else {
michael@0 2774 err = NPN_GetURLNotify(npp, urlstr, nullptr, ndata);
michael@0 2775 }
michael@0 2776
michael@0 2777 free(urlstr);
michael@0 2778
michael@0 2779 if (NPERR_NO_ERROR == err) {
michael@0 2780 if (ndata->writeCallback) {
michael@0 2781 NPN_RetainObject(ndata->writeCallback);
michael@0 2782 }
michael@0 2783 if (ndata->notifyCallback) {
michael@0 2784 NPN_RetainObject(ndata->notifyCallback);
michael@0 2785 }
michael@0 2786 if (ndata->redirectCallback) {
michael@0 2787 NPN_RetainObject(ndata->redirectCallback);
michael@0 2788 }
michael@0 2789 BOOLEAN_TO_NPVARIANT(true, *result);
michael@0 2790 }
michael@0 2791 else {
michael@0 2792 delete ndata;
michael@0 2793 BOOLEAN_TO_NPVARIANT(false, *result);
michael@0 2794 }
michael@0 2795
michael@0 2796 return true;
michael@0 2797 }
michael@0 2798
michael@0 2799 static bool
michael@0 2800 setPluginWantsAllStreams(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
michael@0 2801 {
michael@0 2802 if (1 != argCount)
michael@0 2803 return false;
michael@0 2804
michael@0 2805 if (!NPVARIANT_IS_BOOLEAN(args[0]))
michael@0 2806 return false;
michael@0 2807 bool wantsAllStreams = NPVARIANT_TO_BOOLEAN(args[0]);
michael@0 2808
michael@0 2809 NPP npp = static_cast<TestNPObject*>(npobj)->npp;
michael@0 2810 InstanceData* id = static_cast<InstanceData*>(npp->pdata);
michael@0 2811
michael@0 2812 id->wantsAllStreams = wantsAllStreams;
michael@0 2813
michael@0 2814 return true;
michael@0 2815 }
michael@0 2816
michael@0 2817 static bool
michael@0 2818 crashPlugin(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
michael@0 2819 {
michael@0 2820 IntentionalCrash();
michael@0 2821 VOID_TO_NPVARIANT(*result);
michael@0 2822 return true;
michael@0 2823 }
michael@0 2824
michael@0 2825 static bool
michael@0 2826 crashOnDestroy(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
michael@0 2827 {
michael@0 2828 NPP npp = static_cast<TestNPObject*>(npobj)->npp;
michael@0 2829 InstanceData* id = static_cast<InstanceData*>(npp->pdata);
michael@0 2830
michael@0 2831 id->crashOnDestroy = true;
michael@0 2832 VOID_TO_NPVARIANT(*result);
michael@0 2833 return true;
michael@0 2834 }
michael@0 2835
michael@0 2836 static bool
michael@0 2837 setColor(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
michael@0 2838 {
michael@0 2839 if (argCount != 1)
michael@0 2840 return false;
michael@0 2841 if (!NPVARIANT_IS_STRING(args[0]))
michael@0 2842 return false;
michael@0 2843 const NPString* str = &NPVARIANT_TO_STRING(args[0]);
michael@0 2844
michael@0 2845 NPP npp = static_cast<TestNPObject*>(npobj)->npp;
michael@0 2846 InstanceData* id = static_cast<InstanceData*>(npp->pdata);
michael@0 2847
michael@0 2848 id->scriptableObject->drawColor =
michael@0 2849 parseHexColor(str->UTF8Characters, str->UTF8Length);
michael@0 2850
michael@0 2851 NPRect r;
michael@0 2852 r.left = 0;
michael@0 2853 r.top = 0;
michael@0 2854 r.right = id->window.width;
michael@0 2855 r.bottom = id->window.height;
michael@0 2856 if (id->asyncDrawing == AD_NONE) {
michael@0 2857 NPN_InvalidateRect(npp, &r);
michael@0 2858 } else if (id->asyncDrawing == AD_BITMAP) {
michael@0 2859 drawAsyncBitmapColor(id);
michael@0 2860 }
michael@0 2861 #ifdef XP_WIN
michael@0 2862 else if (id->asyncDrawing == AD_DXGI) {
michael@0 2863 pluginDrawAsyncDxgiColor(id);
michael@0 2864 }
michael@0 2865 #endif
michael@0 2866
michael@0 2867 VOID_TO_NPVARIANT(*result);
michael@0 2868 return true;
michael@0 2869 }
michael@0 2870
michael@0 2871 void notifyDidPaint(InstanceData* instanceData)
michael@0 2872 {
michael@0 2873 ++instanceData->paintCount;
michael@0 2874 instanceData->widthAtLastPaint = instanceData->window.width;
michael@0 2875
michael@0 2876 if (instanceData->invalidateDuringPaint) {
michael@0 2877 NPRect r;
michael@0 2878 r.left = 0;
michael@0 2879 r.top = 0;
michael@0 2880 r.right = instanceData->window.width;
michael@0 2881 r.bottom = instanceData->window.height;
michael@0 2882 NPN_InvalidateRect(instanceData->npp, &r);
michael@0 2883 }
michael@0 2884
michael@0 2885 if (instanceData->slowPaint) {
michael@0 2886 XPSleep(1);
michael@0 2887 }
michael@0 2888
michael@0 2889 if (instanceData->runScriptOnPaint) {
michael@0 2890 NPObject* o = nullptr;
michael@0 2891 NPN_GetValue(instanceData->npp, NPNVPluginElementNPObject, &o);
michael@0 2892 if (o) {
michael@0 2893 NPVariant param;
michael@0 2894 STRINGZ_TO_NPVARIANT("paintscript", param);
michael@0 2895 NPVariant result;
michael@0 2896 NPN_Invoke(instanceData->npp, o, NPN_GetStringIdentifier("getAttribute"),
michael@0 2897 &param, 1, &result);
michael@0 2898
michael@0 2899 if (NPVARIANT_IS_STRING(result)) {
michael@0 2900 NPObject* windowObject;
michael@0 2901 NPN_GetValue(instanceData->npp, NPNVWindowNPObject, &windowObject);
michael@0 2902 if (windowObject) {
michael@0 2903 NPVariant evalResult;
michael@0 2904 NPN_Evaluate(instanceData->npp, windowObject,
michael@0 2905 (NPString*)&NPVARIANT_TO_STRING(result), &evalResult);
michael@0 2906 NPN_ReleaseVariantValue(&evalResult);
michael@0 2907 NPN_ReleaseObject(windowObject);
michael@0 2908 }
michael@0 2909 }
michael@0 2910
michael@0 2911 NPN_ReleaseVariantValue(&result);
michael@0 2912 NPN_ReleaseObject(o);
michael@0 2913 }
michael@0 2914 }
michael@0 2915 }
michael@0 2916
michael@0 2917 static const NPClass kTestSharedNPClass = {
michael@0 2918 NP_CLASS_STRUCT_VERSION,
michael@0 2919 // Everything else is nullptr
michael@0 2920 };
michael@0 2921
michael@0 2922 static bool getJavaCodebase(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
michael@0 2923 {
michael@0 2924 if (argCount != 0) {
michael@0 2925 return false;
michael@0 2926 }
michael@0 2927
michael@0 2928 NPP npp = static_cast<TestNPObject*>(npobj)->npp;
michael@0 2929 InstanceData* id = static_cast<InstanceData*>(npp->pdata);
michael@0 2930
michael@0 2931 char *outval = NPN_StrDup(id->javaCodebase.c_str());
michael@0 2932 STRINGZ_TO_NPVARIANT(outval, *result);
michael@0 2933 return true;
michael@0 2934 }
michael@0 2935
michael@0 2936 static bool getObjectValue(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
michael@0 2937 {
michael@0 2938 NPP npp = static_cast<TestNPObject*>(npobj)->npp;
michael@0 2939
michael@0 2940 NPObject* o = NPN_CreateObject(npp,
michael@0 2941 const_cast<NPClass*>(&kTestSharedNPClass));
michael@0 2942 if (!o)
michael@0 2943 return false;
michael@0 2944
michael@0 2945 OBJECT_TO_NPVARIANT(o, *result);
michael@0 2946 return true;
michael@0 2947 }
michael@0 2948
michael@0 2949 static bool checkObjectValue(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
michael@0 2950 {
michael@0 2951 VOID_TO_NPVARIANT(*result);
michael@0 2952
michael@0 2953 if (1 != argCount)
michael@0 2954 return false;
michael@0 2955
michael@0 2956 if (!NPVARIANT_IS_OBJECT(args[0]))
michael@0 2957 return false;
michael@0 2958
michael@0 2959 NPObject* o = NPVARIANT_TO_OBJECT(args[0]);
michael@0 2960
michael@0 2961 BOOLEAN_TO_NPVARIANT(o->_class == &kTestSharedNPClass, *result);
michael@0 2962 return true;
michael@0 2963 }
michael@0 2964
michael@0 2965 static bool enableFPExceptions(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
michael@0 2966 {
michael@0 2967 VOID_TO_NPVARIANT(*result);
michael@0 2968
michael@0 2969 #if defined(XP_WIN) && defined(_M_IX86)
michael@0 2970 _control87(0, _MCW_EM);
michael@0 2971 return true;
michael@0 2972 #else
michael@0 2973 return false;
michael@0 2974 #endif
michael@0 2975 }
michael@0 2976
michael@0 2977 // caller is responsible for freeing return buffer
michael@0 2978 static char* URLForInstanceWindow(NPP instance) {
michael@0 2979 char *outString = nullptr;
michael@0 2980
michael@0 2981 NPObject* windowObject = nullptr;
michael@0 2982 NPError err = NPN_GetValue(instance, NPNVWindowNPObject, &windowObject);
michael@0 2983 if (err != NPERR_NO_ERROR || !windowObject)
michael@0 2984 return nullptr;
michael@0 2985
michael@0 2986 NPIdentifier locationIdentifier = NPN_GetStringIdentifier("location");
michael@0 2987 NPVariant locationVariant;
michael@0 2988 if (NPN_GetProperty(instance, windowObject, locationIdentifier, &locationVariant)) {
michael@0 2989 NPObject *locationObject = locationVariant.value.objectValue;
michael@0 2990 if (locationObject) {
michael@0 2991 NPIdentifier hrefIdentifier = NPN_GetStringIdentifier("href");
michael@0 2992 NPVariant hrefVariant;
michael@0 2993 if (NPN_GetProperty(instance, locationObject, hrefIdentifier, &hrefVariant)) {
michael@0 2994 const NPString* hrefString = &NPVARIANT_TO_STRING(hrefVariant);
michael@0 2995 if (hrefString) {
michael@0 2996 outString = (char *)malloc(hrefString->UTF8Length + 1);
michael@0 2997 if (outString) {
michael@0 2998 strcpy(outString, hrefString->UTF8Characters);
michael@0 2999 outString[hrefString->UTF8Length] = '\0';
michael@0 3000 }
michael@0 3001 }
michael@0 3002 NPN_ReleaseVariantValue(&hrefVariant);
michael@0 3003 }
michael@0 3004 }
michael@0 3005 NPN_ReleaseVariantValue(&locationVariant);
michael@0 3006 }
michael@0 3007
michael@0 3008 NPN_ReleaseObject(windowObject);
michael@0 3009
michael@0 3010 return outString;
michael@0 3011 }
michael@0 3012
michael@0 3013 static bool
michael@0 3014 setCookie(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
michael@0 3015 {
michael@0 3016 if (argCount != 1)
michael@0 3017 return false;
michael@0 3018 if (!NPVARIANT_IS_STRING(args[0]))
michael@0 3019 return false;
michael@0 3020 const NPString* cookie = &NPVARIANT_TO_STRING(args[0]);
michael@0 3021
michael@0 3022 NPP npp = static_cast<TestNPObject*>(npobj)->npp;
michael@0 3023
michael@0 3024 char* url = URLForInstanceWindow(npp);
michael@0 3025 if (!url)
michael@0 3026 return false;
michael@0 3027 NPError err = NPN_SetValueForURL(npp, NPNURLVCookie, url, cookie->UTF8Characters, cookie->UTF8Length);
michael@0 3028 free(url);
michael@0 3029
michael@0 3030 return (err == NPERR_NO_ERROR);
michael@0 3031 }
michael@0 3032
michael@0 3033 static bool
michael@0 3034 getCookie(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
michael@0 3035 {
michael@0 3036 if (argCount != 0)
michael@0 3037 return false;
michael@0 3038
michael@0 3039 NPP npp = static_cast<TestNPObject*>(npobj)->npp;
michael@0 3040
michael@0 3041 char* url = URLForInstanceWindow(npp);
michael@0 3042 if (!url)
michael@0 3043 return false;
michael@0 3044 char* cookie = nullptr;
michael@0 3045 unsigned int length = 0;
michael@0 3046 NPError err = NPN_GetValueForURL(npp, NPNURLVCookie, url, &cookie, &length);
michael@0 3047 free(url);
michael@0 3048 if (err != NPERR_NO_ERROR || !cookie)
michael@0 3049 return false;
michael@0 3050
michael@0 3051 STRINGZ_TO_NPVARIANT(cookie, *result);
michael@0 3052 return true;
michael@0 3053 }
michael@0 3054
michael@0 3055 static bool
michael@0 3056 getAuthInfo(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
michael@0 3057 {
michael@0 3058 if (argCount != 5)
michael@0 3059 return false;
michael@0 3060
michael@0 3061 NPP npp = static_cast<TestNPObject*>(npobj)->npp;
michael@0 3062
michael@0 3063 if (!NPVARIANT_IS_STRING(args[0]) || !NPVARIANT_IS_STRING(args[1]) ||
michael@0 3064 !NPVARIANT_IS_INT32(args[2]) || !NPVARIANT_IS_STRING(args[3]) ||
michael@0 3065 !NPVARIANT_IS_STRING(args[4]))
michael@0 3066 return false;
michael@0 3067
michael@0 3068 const NPString* protocol = &NPVARIANT_TO_STRING(args[0]);
michael@0 3069 const NPString* host = &NPVARIANT_TO_STRING(args[1]);
michael@0 3070 uint32_t port = NPVARIANT_TO_INT32(args[2]);
michael@0 3071 const NPString* scheme = &NPVARIANT_TO_STRING(args[3]);
michael@0 3072 const NPString* realm = &NPVARIANT_TO_STRING(args[4]);
michael@0 3073
michael@0 3074 char* username = nullptr;
michael@0 3075 char* password = nullptr;
michael@0 3076 uint32_t ulen = 0, plen = 0;
michael@0 3077
michael@0 3078 NPError err = NPN_GetAuthenticationInfo(npp,
michael@0 3079 protocol->UTF8Characters,
michael@0 3080 host->UTF8Characters,
michael@0 3081 port,
michael@0 3082 scheme->UTF8Characters,
michael@0 3083 realm->UTF8Characters,
michael@0 3084 &username,
michael@0 3085 &ulen,
michael@0 3086 &password,
michael@0 3087 &plen);
michael@0 3088
michael@0 3089 if (err != NPERR_NO_ERROR) {
michael@0 3090 return false;
michael@0 3091 }
michael@0 3092
michael@0 3093 char* outstring = (char*)NPN_MemAlloc(ulen + plen + 2);
michael@0 3094 memset(outstring, 0, ulen + plen + 2);
michael@0 3095 strncpy(outstring, username, ulen);
michael@0 3096 strcat(outstring, "|");
michael@0 3097 strncat(outstring, password, plen);
michael@0 3098
michael@0 3099 STRINGZ_TO_NPVARIANT(outstring, *result);
michael@0 3100
michael@0 3101 NPN_MemFree(username);
michael@0 3102 NPN_MemFree(password);
michael@0 3103
michael@0 3104 return true;
michael@0 3105 }
michael@0 3106
michael@0 3107 static void timerCallback(NPP npp, uint32_t timerID)
michael@0 3108 {
michael@0 3109 InstanceData* id = static_cast<InstanceData*>(npp->pdata);
michael@0 3110 currentTimerEventCount++;
michael@0 3111 timerEvent event = timerEvents[currentTimerEventCount];
michael@0 3112
michael@0 3113 NPObject* windowObject;
michael@0 3114 NPN_GetValue(npp, NPNVWindowNPObject, &windowObject);
michael@0 3115 if (!windowObject)
michael@0 3116 return;
michael@0 3117
michael@0 3118 NPVariant rval;
michael@0 3119 if (timerID != id->timerID[event.timerIdReceive]) {
michael@0 3120 id->timerTestResult = false;
michael@0 3121 }
michael@0 3122
michael@0 3123 if (currentTimerEventCount == totalTimerEvents - 1) {
michael@0 3124 NPVariant arg;
michael@0 3125 BOOLEAN_TO_NPVARIANT(id->timerTestResult, arg);
michael@0 3126 NPN_Invoke(npp, windowObject, NPN_GetStringIdentifier(id->timerTestScriptCallback.c_str()), &arg, 1, &rval);
michael@0 3127 NPN_ReleaseVariantValue(&arg);
michael@0 3128 }
michael@0 3129
michael@0 3130 NPN_ReleaseObject(windowObject);
michael@0 3131
michael@0 3132 if (event.timerIdSchedule > -1) {
michael@0 3133 id->timerID[event.timerIdSchedule] = NPN_ScheduleTimer(npp, event.timerInterval, event.timerRepeat, timerCallback);
michael@0 3134 }
michael@0 3135 if (event.timerIdUnschedule > -1) {
michael@0 3136 NPN_UnscheduleTimer(npp, id->timerID[event.timerIdUnschedule]);
michael@0 3137 }
michael@0 3138 }
michael@0 3139
michael@0 3140 static bool
michael@0 3141 timerTest(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
michael@0 3142 {
michael@0 3143 NPP npp = static_cast<TestNPObject*>(npobj)->npp;
michael@0 3144 InstanceData* id = static_cast<InstanceData*>(npp->pdata);
michael@0 3145 currentTimerEventCount = 0;
michael@0 3146
michael@0 3147 if (argCount < 1 || !NPVARIANT_IS_STRING(args[0]))
michael@0 3148 return false;
michael@0 3149 const NPString* argstr = &NPVARIANT_TO_STRING(args[0]);
michael@0 3150 id->timerTestScriptCallback = argstr->UTF8Characters;
michael@0 3151
michael@0 3152 id->timerTestResult = true;
michael@0 3153 timerEvent event = timerEvents[currentTimerEventCount];
michael@0 3154
michael@0 3155 id->timerID[event.timerIdSchedule] = NPN_ScheduleTimer(npp, event.timerInterval, event.timerRepeat, timerCallback);
michael@0 3156
michael@0 3157 return id->timerID[event.timerIdSchedule] != 0;
michael@0 3158 }
michael@0 3159
michael@0 3160 #ifdef XP_WIN
michael@0 3161 void
michael@0 3162 ThreadProc(void* cookie)
michael@0 3163 #else
michael@0 3164 void*
michael@0 3165 ThreadProc(void* cookie)
michael@0 3166 #endif
michael@0 3167 {
michael@0 3168 NPObject* npobj = (NPObject*)cookie;
michael@0 3169 NPP npp = static_cast<TestNPObject*>(npobj)->npp;
michael@0 3170 InstanceData* id = static_cast<InstanceData*>(npp->pdata);
michael@0 3171 id->asyncTestPhase = 1;
michael@0 3172 NPN_PluginThreadAsyncCall(npp, asyncCallback, (void*)npobj);
michael@0 3173 #ifndef XP_WIN
michael@0 3174 return nullptr;
michael@0 3175 #endif
michael@0 3176 }
michael@0 3177
michael@0 3178 void
michael@0 3179 asyncCallback(void* cookie)
michael@0 3180 {
michael@0 3181 NPObject* npobj = (NPObject*)cookie;
michael@0 3182 NPP npp = static_cast<TestNPObject*>(npobj)->npp;
michael@0 3183 InstanceData* id = static_cast<InstanceData*>(npp->pdata);
michael@0 3184
michael@0 3185 switch (id->asyncTestPhase) {
michael@0 3186 // async callback triggered from same thread
michael@0 3187 case 0:
michael@0 3188 #ifdef XP_WIN
michael@0 3189 if (_beginthread(ThreadProc, 0, (void*)npobj) == -1)
michael@0 3190 id->asyncCallbackResult = false;
michael@0 3191 #else
michael@0 3192 pthread_t tid;
michael@0 3193 if (pthread_create(&tid, 0, ThreadProc, (void*)npobj))
michael@0 3194 id->asyncCallbackResult = false;
michael@0 3195 #endif
michael@0 3196 break;
michael@0 3197
michael@0 3198 // async callback triggered from different thread
michael@0 3199 default:
michael@0 3200 NPObject* windowObject;
michael@0 3201 NPN_GetValue(npp, NPNVWindowNPObject, &windowObject);
michael@0 3202 if (!windowObject)
michael@0 3203 return;
michael@0 3204 NPVariant arg, rval;
michael@0 3205 BOOLEAN_TO_NPVARIANT(id->asyncCallbackResult, arg);
michael@0 3206 NPN_Invoke(npp, windowObject, NPN_GetStringIdentifier(id->asyncTestScriptCallback.c_str()), &arg, 1, &rval);
michael@0 3207 NPN_ReleaseVariantValue(&arg);
michael@0 3208 NPN_ReleaseObject(windowObject);
michael@0 3209 break;
michael@0 3210 }
michael@0 3211 }
michael@0 3212
michael@0 3213 static bool
michael@0 3214 asyncCallbackTest(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
michael@0 3215 {
michael@0 3216 NPP npp = static_cast<TestNPObject*>(npobj)->npp;
michael@0 3217 InstanceData* id = static_cast<InstanceData*>(npp->pdata);
michael@0 3218
michael@0 3219 if (argCount < 1 || !NPVARIANT_IS_STRING(args[0]))
michael@0 3220 return false;
michael@0 3221 const NPString* argstr = &NPVARIANT_TO_STRING(args[0]);
michael@0 3222 id->asyncTestScriptCallback = argstr->UTF8Characters;
michael@0 3223
michael@0 3224 id->asyncTestPhase = 0;
michael@0 3225 id->asyncCallbackResult = true;
michael@0 3226 NPN_PluginThreadAsyncCall(npp, asyncCallback, (void*)npobj);
michael@0 3227
michael@0 3228 return true;
michael@0 3229 }
michael@0 3230
michael@0 3231 static bool
michael@0 3232 GCRaceInvoke(NPObject*, NPIdentifier, const NPVariant*, uint32_t, NPVariant*)
michael@0 3233 {
michael@0 3234 return false;
michael@0 3235 }
michael@0 3236
michael@0 3237 static bool
michael@0 3238 GCRaceInvokeDefault(NPObject* o, const NPVariant* args, uint32_t argCount,
michael@0 3239 NPVariant* result)
michael@0 3240 {
michael@0 3241 if (1 != argCount || !NPVARIANT_IS_INT32(args[0]) ||
michael@0 3242 35 != NPVARIANT_TO_INT32(args[0]))
michael@0 3243 return false;
michael@0 3244
michael@0 3245 return true;
michael@0 3246 }
michael@0 3247
michael@0 3248 static const NPClass kGCRaceClass = {
michael@0 3249 NP_CLASS_STRUCT_VERSION,
michael@0 3250 nullptr,
michael@0 3251 nullptr,
michael@0 3252 nullptr,
michael@0 3253 nullptr,
michael@0 3254 GCRaceInvoke,
michael@0 3255 GCRaceInvokeDefault,
michael@0 3256 nullptr,
michael@0 3257 nullptr,
michael@0 3258 nullptr,
michael@0 3259 nullptr,
michael@0 3260 nullptr,
michael@0 3261 nullptr
michael@0 3262 };
michael@0 3263
michael@0 3264 struct GCRaceData
michael@0 3265 {
michael@0 3266 GCRaceData(NPP npp, NPObject* callback, NPObject* localFunc)
michael@0 3267 : npp_(npp)
michael@0 3268 , callback_(callback)
michael@0 3269 , localFunc_(localFunc)
michael@0 3270 {
michael@0 3271 NPN_RetainObject(callback_);
michael@0 3272 NPN_RetainObject(localFunc_);
michael@0 3273 }
michael@0 3274
michael@0 3275 ~GCRaceData()
michael@0 3276 {
michael@0 3277 NPN_ReleaseObject(callback_);
michael@0 3278 NPN_ReleaseObject(localFunc_);
michael@0 3279 }
michael@0 3280
michael@0 3281 NPP npp_;
michael@0 3282 NPObject* callback_;
michael@0 3283 NPObject* localFunc_;
michael@0 3284 };
michael@0 3285
michael@0 3286 static void
michael@0 3287 FinishGCRace(void* closure)
michael@0 3288 {
michael@0 3289 GCRaceData* rd = static_cast<GCRaceData*>(closure);
michael@0 3290
michael@0 3291 XPSleep(5);
michael@0 3292
michael@0 3293 NPVariant arg;
michael@0 3294 OBJECT_TO_NPVARIANT(rd->localFunc_, arg);
michael@0 3295
michael@0 3296 NPVariant result;
michael@0 3297 bool ok = NPN_InvokeDefault(rd->npp_, rd->callback_, &arg, 1, &result);
michael@0 3298 if (!ok)
michael@0 3299 return;
michael@0 3300
michael@0 3301 NPN_ReleaseVariantValue(&result);
michael@0 3302 delete rd;
michael@0 3303 }
michael@0 3304
michael@0 3305 bool
michael@0 3306 checkGCRace(NPObject* npobj, const NPVariant* args, uint32_t argCount,
michael@0 3307 NPVariant* result)
michael@0 3308 {
michael@0 3309 if (1 != argCount || !NPVARIANT_IS_OBJECT(args[0]))
michael@0 3310 return false;
michael@0 3311
michael@0 3312 NPP npp = static_cast<TestNPObject*>(npobj)->npp;
michael@0 3313
michael@0 3314 NPObject* localFunc =
michael@0 3315 NPN_CreateObject(npp, const_cast<NPClass*>(&kGCRaceClass));
michael@0 3316
michael@0 3317 GCRaceData* rd =
michael@0 3318 new GCRaceData(npp, NPVARIANT_TO_OBJECT(args[0]), localFunc);
michael@0 3319 NPN_PluginThreadAsyncCall(npp, FinishGCRace, rd);
michael@0 3320
michael@0 3321 OBJECT_TO_NPVARIANT(localFunc, *result);
michael@0 3322 return true;
michael@0 3323 }
michael@0 3324
michael@0 3325 bool
michael@0 3326 hangPlugin(NPObject* npobj, const NPVariant* args, uint32_t argCount,
michael@0 3327 NPVariant* result)
michael@0 3328 {
michael@0 3329 mozilla::NoteIntentionalCrash("plugin");
michael@0 3330
michael@0 3331 bool busyHang = false;
michael@0 3332 if ((argCount == 1) && NPVARIANT_IS_BOOLEAN(args[0])) {
michael@0 3333 busyHang = NPVARIANT_TO_BOOLEAN(args[0]);
michael@0 3334 }
michael@0 3335
michael@0 3336 if (busyHang) {
michael@0 3337 const time_t start = std::time(nullptr);
michael@0 3338 while ((std::time(nullptr) - start) < 100000) {
michael@0 3339 volatile int dummy = 0;
michael@0 3340 for (int i=0; i<1000; ++i) {
michael@0 3341 dummy++;
michael@0 3342 }
michael@0 3343 }
michael@0 3344 } else {
michael@0 3345 #ifdef XP_WIN
michael@0 3346 Sleep(100000000);
michael@0 3347 Sleep(100000000);
michael@0 3348 #else
michael@0 3349 pause();
michael@0 3350 pause();
michael@0 3351 #endif
michael@0 3352 }
michael@0 3353
michael@0 3354 // NB: returning true here means that we weren't terminated, and
michael@0 3355 // thus the hang detection/handling didn't work correctly. The
michael@0 3356 // test harness will succeed in calling this function, and the
michael@0 3357 // test will fail.
michael@0 3358 return true;
michael@0 3359 }
michael@0 3360
michael@0 3361 bool
michael@0 3362 stallPlugin(NPObject* npobj, const NPVariant* args, uint32_t argCount,
michael@0 3363 NPVariant* result)
michael@0 3364 {
michael@0 3365 uint32_t stallTimeSeconds = 0;
michael@0 3366 if ((argCount == 1) && NPVARIANT_IS_INT32(args[0])) {
michael@0 3367 stallTimeSeconds = (uint32_t) NPVARIANT_TO_INT32(args[0]);
michael@0 3368 }
michael@0 3369
michael@0 3370 #ifdef XP_WIN
michael@0 3371 Sleep(stallTimeSeconds * 1000U);
michael@0 3372 #else
michael@0 3373 sleep(stallTimeSeconds);
michael@0 3374 #endif
michael@0 3375
michael@0 3376 return true;
michael@0 3377 }
michael@0 3378
michael@0 3379 #if defined(MOZ_WIDGET_GTK)
michael@0 3380 bool
michael@0 3381 getClipboardText(NPObject* npobj, const NPVariant* args, uint32_t argCount,
michael@0 3382 NPVariant* result)
michael@0 3383 {
michael@0 3384 NPP npp = static_cast<TestNPObject*>(npobj)->npp;
michael@0 3385 InstanceData* id = static_cast<InstanceData*>(npp->pdata);
michael@0 3386 string sel = pluginGetClipboardText(id);
michael@0 3387
michael@0 3388 uint32_t len = sel.size();
michael@0 3389 char* selCopy = static_cast<char*>(NPN_MemAlloc(1 + len));
michael@0 3390 if (!selCopy)
michael@0 3391 return false;
michael@0 3392
michael@0 3393 memcpy(selCopy, sel.c_str(), len);
michael@0 3394 selCopy[len] = '\0';
michael@0 3395
michael@0 3396 STRINGN_TO_NPVARIANT(selCopy, len, *result);
michael@0 3397 // *result owns str now
michael@0 3398
michael@0 3399 return true;
michael@0 3400 }
michael@0 3401
michael@0 3402 bool
michael@0 3403 crashPluginInNestedLoop(NPObject* npobj, const NPVariant* args,
michael@0 3404 uint32_t argCount, NPVariant* result)
michael@0 3405 {
michael@0 3406 NPP npp = static_cast<TestNPObject*>(npobj)->npp;
michael@0 3407 InstanceData* id = static_cast<InstanceData*>(npp->pdata);
michael@0 3408 return pluginCrashInNestedLoop(id);
michael@0 3409 }
michael@0 3410
michael@0 3411 bool
michael@0 3412 destroySharedGfxStuff(NPObject* npobj, const NPVariant* args,
michael@0 3413 uint32_t argCount, NPVariant* result)
michael@0 3414 {
michael@0 3415 NPP npp = static_cast<TestNPObject*>(npobj)->npp;
michael@0 3416 InstanceData* id = static_cast<InstanceData*>(npp->pdata);
michael@0 3417 return pluginDestroySharedGfxStuff(id);
michael@0 3418 }
michael@0 3419
michael@0 3420 #else
michael@0 3421 bool
michael@0 3422 getClipboardText(NPObject* npobj, const NPVariant* args, uint32_t argCount,
michael@0 3423 NPVariant* result)
michael@0 3424 {
michael@0 3425 // XXX Not implemented!
michael@0 3426 return false;
michael@0 3427 }
michael@0 3428
michael@0 3429 bool
michael@0 3430 crashPluginInNestedLoop(NPObject* npobj, const NPVariant* args,
michael@0 3431 uint32_t argCount, NPVariant* result)
michael@0 3432 {
michael@0 3433 // XXX Not implemented!
michael@0 3434 return false;
michael@0 3435 }
michael@0 3436
michael@0 3437 bool
michael@0 3438 destroySharedGfxStuff(NPObject* npobj, const NPVariant* args,
michael@0 3439 uint32_t argCount, NPVariant* result)
michael@0 3440 {
michael@0 3441 // XXX Not implemented!
michael@0 3442 return false;
michael@0 3443 }
michael@0 3444 #endif
michael@0 3445
michael@0 3446 bool
michael@0 3447 callOnDestroy(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
michael@0 3448 {
michael@0 3449 NPP npp = static_cast<TestNPObject*>(npobj)->npp;
michael@0 3450 InstanceData* id = static_cast<InstanceData*>(npp->pdata);
michael@0 3451
michael@0 3452 if (id->callOnDestroy)
michael@0 3453 return false;
michael@0 3454
michael@0 3455 if (1 != argCount || !NPVARIANT_IS_OBJECT(args[0]))
michael@0 3456 return false;
michael@0 3457
michael@0 3458 id->callOnDestroy = NPVARIANT_TO_OBJECT(args[0]);
michael@0 3459 NPN_RetainObject(id->callOnDestroy);
michael@0 3460
michael@0 3461 return true;
michael@0 3462 }
michael@0 3463
michael@0 3464 // On Linux at least, a windowed plugin resize causes Flash Player to
michael@0 3465 // reconnect to the browser window. This method simulates that.
michael@0 3466 bool
michael@0 3467 reinitWidget(NPObject* npobj, const NPVariant* args, uint32_t argCount,
michael@0 3468 NPVariant* result)
michael@0 3469 {
michael@0 3470 if (argCount != 0)
michael@0 3471 return false;
michael@0 3472
michael@0 3473 NPP npp = static_cast<TestNPObject*>(npobj)->npp;
michael@0 3474 InstanceData* id = static_cast<InstanceData*>(npp->pdata);
michael@0 3475
michael@0 3476 if (!id->hasWidget)
michael@0 3477 return false;
michael@0 3478
michael@0 3479 pluginWidgetInit(id, id->window.window);
michael@0 3480 return true;
michael@0 3481 }
michael@0 3482
michael@0 3483 bool
michael@0 3484 propertyAndMethod(NPObject* npobj, const NPVariant* args, uint32_t argCount,
michael@0 3485 NPVariant* result)
michael@0 3486 {
michael@0 3487 INT32_TO_NPVARIANT(5, *result);
michael@0 3488 return true;
michael@0 3489 }
michael@0 3490
michael@0 3491 // Returns top-level window activation state as indicated by Cocoa NPAPI's
michael@0 3492 // NPCocoaEventWindowFocusChanged events - 'true' if active, 'false' if not.
michael@0 3493 // Throws an exception if no events have been received and thus this state
michael@0 3494 // is unknown.
michael@0 3495 bool
michael@0 3496 getTopLevelWindowActivationState(NPObject* npobj, const NPVariant* args, uint32_t argCount,
michael@0 3497 NPVariant* result)
michael@0 3498 {
michael@0 3499 if (argCount != 0)
michael@0 3500 return false;
michael@0 3501
michael@0 3502 NPP npp = static_cast<TestNPObject*>(npobj)->npp;
michael@0 3503 InstanceData* id = static_cast<InstanceData*>(npp->pdata);
michael@0 3504
michael@0 3505 // Throw an exception for unknown state.
michael@0 3506 if (id->topLevelWindowActivationState == ACTIVATION_STATE_UNKNOWN) {
michael@0 3507 return false;
michael@0 3508 }
michael@0 3509
michael@0 3510 if (id->topLevelWindowActivationState == ACTIVATION_STATE_ACTIVATED) {
michael@0 3511 BOOLEAN_TO_NPVARIANT(true, *result);
michael@0 3512 } else if (id->topLevelWindowActivationState == ACTIVATION_STATE_DEACTIVATED) {
michael@0 3513 BOOLEAN_TO_NPVARIANT(false, *result);
michael@0 3514 }
michael@0 3515
michael@0 3516 return true;
michael@0 3517 }
michael@0 3518
michael@0 3519 bool
michael@0 3520 getTopLevelWindowActivationEventCount(NPObject* npobj, const NPVariant* args, uint32_t argCount,
michael@0 3521 NPVariant* result)
michael@0 3522 {
michael@0 3523 if (argCount != 0)
michael@0 3524 return false;
michael@0 3525
michael@0 3526 NPP npp = static_cast<TestNPObject*>(npobj)->npp;
michael@0 3527 InstanceData* id = static_cast<InstanceData*>(npp->pdata);
michael@0 3528
michael@0 3529 INT32_TO_NPVARIANT(id->topLevelWindowActivationEventCount, *result);
michael@0 3530
michael@0 3531 return true;
michael@0 3532 }
michael@0 3533
michael@0 3534 // Returns top-level window activation state as indicated by Cocoa NPAPI's
michael@0 3535 // NPCocoaEventWindowFocusChanged events - 'true' if active, 'false' if not.
michael@0 3536 // Throws an exception if no events have been received and thus this state
michael@0 3537 // is unknown.
michael@0 3538 bool
michael@0 3539 getFocusState(NPObject* npobj, const NPVariant* args, uint32_t argCount,
michael@0 3540 NPVariant* result)
michael@0 3541 {
michael@0 3542 if (argCount != 0)
michael@0 3543 return false;
michael@0 3544
michael@0 3545 NPP npp = static_cast<TestNPObject*>(npobj)->npp;
michael@0 3546 InstanceData* id = static_cast<InstanceData*>(npp->pdata);
michael@0 3547
michael@0 3548 // Throw an exception for unknown state.
michael@0 3549 if (id->focusState == ACTIVATION_STATE_UNKNOWN) {
michael@0 3550 return false;
michael@0 3551 }
michael@0 3552
michael@0 3553 if (id->focusState == ACTIVATION_STATE_ACTIVATED) {
michael@0 3554 BOOLEAN_TO_NPVARIANT(true, *result);
michael@0 3555 } else if (id->focusState == ACTIVATION_STATE_DEACTIVATED) {
michael@0 3556 BOOLEAN_TO_NPVARIANT(false, *result);
michael@0 3557 }
michael@0 3558
michael@0 3559 return true;
michael@0 3560 }
michael@0 3561
michael@0 3562 bool
michael@0 3563 getFocusEventCount(NPObject* npobj, const NPVariant* args, uint32_t argCount,
michael@0 3564 NPVariant* result)
michael@0 3565 {
michael@0 3566 if (argCount != 0)
michael@0 3567 return false;
michael@0 3568
michael@0 3569 NPP npp = static_cast<TestNPObject*>(npobj)->npp;
michael@0 3570 InstanceData* id = static_cast<InstanceData*>(npp->pdata);
michael@0 3571
michael@0 3572 INT32_TO_NPVARIANT(id->focusEventCount, *result);
michael@0 3573
michael@0 3574 return true;
michael@0 3575 }
michael@0 3576
michael@0 3577 bool
michael@0 3578 getEventModel(NPObject* npobj, const NPVariant* args, uint32_t argCount,
michael@0 3579 NPVariant* result)
michael@0 3580 {
michael@0 3581 if (argCount != 0)
michael@0 3582 return false;
michael@0 3583
michael@0 3584 NPP npp = static_cast<TestNPObject*>(npobj)->npp;
michael@0 3585 InstanceData* id = static_cast<InstanceData*>(npp->pdata);
michael@0 3586
michael@0 3587 INT32_TO_NPVARIANT(id->eventModel, *result);
michael@0 3588
michael@0 3589 return true;
michael@0 3590 }
michael@0 3591
michael@0 3592 static bool
michael@0 3593 ReflectorHasMethod(NPObject* npobj, NPIdentifier name)
michael@0 3594 {
michael@0 3595 return false;
michael@0 3596 }
michael@0 3597
michael@0 3598 static bool
michael@0 3599 ReflectorHasProperty(NPObject* npobj, NPIdentifier name)
michael@0 3600 {
michael@0 3601 return true;
michael@0 3602 }
michael@0 3603
michael@0 3604 static bool
michael@0 3605 ReflectorGetProperty(NPObject* npobj, NPIdentifier name, NPVariant* result)
michael@0 3606 {
michael@0 3607 if (NPN_IdentifierIsString(name)) {
michael@0 3608 char* s = NPN_UTF8FromIdentifier(name);
michael@0 3609 STRINGZ_TO_NPVARIANT(s, *result);
michael@0 3610 return true;
michael@0 3611 }
michael@0 3612
michael@0 3613 INT32_TO_NPVARIANT(NPN_IntFromIdentifier(name), *result);
michael@0 3614 return true;
michael@0 3615 }
michael@0 3616
michael@0 3617 static const NPClass kReflectorNPClass = {
michael@0 3618 NP_CLASS_STRUCT_VERSION,
michael@0 3619 nullptr,
michael@0 3620 nullptr,
michael@0 3621 nullptr,
michael@0 3622 ReflectorHasMethod,
michael@0 3623 nullptr,
michael@0 3624 nullptr,
michael@0 3625 ReflectorHasProperty,
michael@0 3626 ReflectorGetProperty,
michael@0 3627 nullptr,
michael@0 3628 nullptr,
michael@0 3629 nullptr,
michael@0 3630 nullptr
michael@0 3631 };
michael@0 3632
michael@0 3633 bool
michael@0 3634 getReflector(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
michael@0 3635 {
michael@0 3636 if (0 != argCount)
michael@0 3637 return false;
michael@0 3638
michael@0 3639 NPP npp = static_cast<TestNPObject*>(npobj)->npp;
michael@0 3640
michael@0 3641 NPObject* reflector =
michael@0 3642 NPN_CreateObject(npp,
michael@0 3643 const_cast<NPClass*>(&kReflectorNPClass)); // retains
michael@0 3644 OBJECT_TO_NPVARIANT(reflector, *result);
michael@0 3645 return true;
michael@0 3646 }
michael@0 3647
michael@0 3648 bool isVisible(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
michael@0 3649 {
michael@0 3650 NPP npp = static_cast<TestNPObject*>(npobj)->npp;
michael@0 3651 InstanceData* id = static_cast<InstanceData*>(npp->pdata);
michael@0 3652
michael@0 3653 BOOLEAN_TO_NPVARIANT(id->window.clipRect.top != 0 ||
michael@0 3654 id->window.clipRect.left != 0 ||
michael@0 3655 id->window.clipRect.bottom != 0 ||
michael@0 3656 id->window.clipRect.right != 0, *result);
michael@0 3657 return true;
michael@0 3658 }
michael@0 3659
michael@0 3660 bool getWindowPosition(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
michael@0 3661 {
michael@0 3662 NPP npp = static_cast<TestNPObject*>(npobj)->npp;
michael@0 3663 InstanceData* id = static_cast<InstanceData*>(npp->pdata);
michael@0 3664
michael@0 3665 NPObject* window = nullptr;
michael@0 3666 NPError err = NPN_GetValue(npp, NPNVWindowNPObject, &window);
michael@0 3667 if (NPERR_NO_ERROR != err || !window)
michael@0 3668 return false;
michael@0 3669
michael@0 3670 NPIdentifier arrayID = NPN_GetStringIdentifier("Array");
michael@0 3671 NPVariant arrayFunctionV;
michael@0 3672 bool ok = NPN_GetProperty(npp, window, arrayID, &arrayFunctionV);
michael@0 3673
michael@0 3674 NPN_ReleaseObject(window);
michael@0 3675
michael@0 3676 if (!ok)
michael@0 3677 return false;
michael@0 3678
michael@0 3679 if (!NPVARIANT_IS_OBJECT(arrayFunctionV)) {
michael@0 3680 NPN_ReleaseVariantValue(&arrayFunctionV);
michael@0 3681 return false;
michael@0 3682 }
michael@0 3683 NPObject* arrayFunction = NPVARIANT_TO_OBJECT(arrayFunctionV);
michael@0 3684
michael@0 3685 NPVariant elements[4];
michael@0 3686 INT32_TO_NPVARIANT(id->window.x, elements[0]);
michael@0 3687 INT32_TO_NPVARIANT(id->window.y, elements[1]);
michael@0 3688 INT32_TO_NPVARIANT(id->window.width, elements[2]);
michael@0 3689 INT32_TO_NPVARIANT(id->window.height, elements[3]);
michael@0 3690
michael@0 3691 ok = NPN_InvokeDefault(npp, arrayFunction, elements, 4, result);
michael@0 3692
michael@0 3693 NPN_ReleaseObject(arrayFunction);
michael@0 3694
michael@0 3695 return ok;
michael@0 3696 }
michael@0 3697
michael@0 3698 bool constructObject(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
michael@0 3699 {
michael@0 3700 if (argCount == 0 || !NPVARIANT_IS_OBJECT(args[0]))
michael@0 3701 return false;
michael@0 3702
michael@0 3703 NPObject* ctor = NPVARIANT_TO_OBJECT(args[0]);
michael@0 3704
michael@0 3705 NPP npp = static_cast<TestNPObject*>(npobj)->npp;
michael@0 3706
michael@0 3707 return NPN_Construct(npp, ctor, args + 1, argCount - 1, result);
michael@0 3708 }
michael@0 3709
michael@0 3710 bool setSitesWithData(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
michael@0 3711 {
michael@0 3712 if (argCount != 1 || !NPVARIANT_IS_STRING(args[0]))
michael@0 3713 return false;
michael@0 3714
michael@0 3715 // Clear existing data.
michael@0 3716 delete sSitesWithData;
michael@0 3717
michael@0 3718 const NPString* str = &NPVARIANT_TO_STRING(args[0]);
michael@0 3719 if (str->UTF8Length == 0)
michael@0 3720 return true;
michael@0 3721
michael@0 3722 // Parse the comma-delimited string into a vector.
michael@0 3723 sSitesWithData = new list<siteData>;
michael@0 3724 const char* iterator = str->UTF8Characters;
michael@0 3725 const char* end = iterator + str->UTF8Length;
michael@0 3726 while (1) {
michael@0 3727 const char* next = strchr(iterator, ',');
michael@0 3728 if (!next)
michael@0 3729 next = end;
michael@0 3730
michael@0 3731 // Parse out the three tokens into a siteData struct.
michael@0 3732 const char* siteEnd = strchr(iterator, ':');
michael@0 3733 *((char*) siteEnd) = '\0';
michael@0 3734 const char* flagsEnd = strchr(siteEnd + 1, ':');
michael@0 3735 *((char*) flagsEnd) = '\0';
michael@0 3736 *((char*) next) = '\0';
michael@0 3737
michael@0 3738 siteData data;
michael@0 3739 data.site = string(iterator);
michael@0 3740 data.flags = atoi(siteEnd + 1);
michael@0 3741 data.age = atoi(flagsEnd + 1);
michael@0 3742
michael@0 3743 sSitesWithData->push_back(data);
michael@0 3744
michael@0 3745 if (next == end)
michael@0 3746 break;
michael@0 3747
michael@0 3748 iterator = next + 1;
michael@0 3749 }
michael@0 3750
michael@0 3751 return true;
michael@0 3752 }
michael@0 3753
michael@0 3754 bool setSitesWithDataCapabilities(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
michael@0 3755 {
michael@0 3756 if (argCount != 1 || !NPVARIANT_IS_BOOLEAN(args[0]))
michael@0 3757 return false;
michael@0 3758
michael@0 3759 sClearByAgeSupported = NPVARIANT_TO_BOOLEAN(args[0]);
michael@0 3760 return true;
michael@0 3761 }
michael@0 3762
michael@0 3763 bool getLastKeyText(NPObject* npobj, const NPVariant* args, uint32_t argCount,
michael@0 3764 NPVariant* result)
michael@0 3765 {
michael@0 3766 if (argCount != 0) {
michael@0 3767 return false;
michael@0 3768 }
michael@0 3769
michael@0 3770 NPP npp = static_cast<TestNPObject*>(npobj)->npp;
michael@0 3771 InstanceData* id = static_cast<InstanceData*>(npp->pdata);
michael@0 3772
michael@0 3773 char *outval = NPN_StrDup(id->lastKeyText.c_str());
michael@0 3774 STRINGZ_TO_NPVARIANT(outval, *result);
michael@0 3775 return true;
michael@0 3776 }
michael@0 3777
michael@0 3778 bool getNPNVdocumentOrigin(NPObject* npobj, const NPVariant* args, uint32_t argCount,
michael@0 3779 NPVariant* result)
michael@0 3780 {
michael@0 3781 if (argCount != 0) {
michael@0 3782 return false;
michael@0 3783 }
michael@0 3784
michael@0 3785 NPP npp = static_cast<TestNPObject*>(npobj)->npp;
michael@0 3786
michael@0 3787 char *origin = nullptr;
michael@0 3788 NPError err = NPN_GetValue(npp, NPNVdocumentOrigin, &origin);
michael@0 3789 if (err != NPERR_NO_ERROR) {
michael@0 3790 return false;
michael@0 3791 }
michael@0 3792
michael@0 3793 STRINGZ_TO_NPVARIANT(origin, *result);
michael@0 3794 return true;
michael@0 3795 }
michael@0 3796
michael@0 3797 bool getMouseUpEventCount(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
michael@0 3798 {
michael@0 3799 if (argCount != 0) {
michael@0 3800 return false;
michael@0 3801 }
michael@0 3802
michael@0 3803 NPP npp = static_cast<TestNPObject*>(npobj)->npp;
michael@0 3804 InstanceData* id = static_cast<InstanceData*>(npp->pdata);
michael@0 3805 INT32_TO_NPVARIANT(id->mouseUpEventCount, *result);
michael@0 3806 return true;
michael@0 3807 }
michael@0 3808
michael@0 3809 bool queryContentsScaleFactor(NPObject* npobj, const NPVariant* args, uint32_t argCount, NPVariant* result)
michael@0 3810 {
michael@0 3811 if (argCount != 0)
michael@0 3812 return false;
michael@0 3813
michael@0 3814 double scaleFactor = 1.0;
michael@0 3815 #if defined(XP_MACOSX)
michael@0 3816 NPError err = NPN_GetValue(static_cast<TestNPObject*>(npobj)->npp,
michael@0 3817 NPNVcontentsScaleFactor, &scaleFactor);
michael@0 3818 if (err != NPERR_NO_ERROR) {
michael@0 3819 return false;
michael@0 3820 }
michael@0 3821 #endif
michael@0 3822 DOUBLE_TO_NPVARIANT(scaleFactor, *result);
michael@0 3823 return true;
michael@0 3824 }

mercurial