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