Sat, 03 Jan 2015 20:18:00 +0100
Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.
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 | ¶m, 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 | } |