dom/plugins/ipc/PluginMessageUtils.h

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
michael@0 2 * vim: sw=4 ts=4 et :
michael@0 3 * This Source Code Form is subject to the terms of the Mozilla Public
michael@0 4 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 6
michael@0 7 #ifndef DOM_PLUGINS_PLUGINMESSAGEUTILS_H
michael@0 8 #define DOM_PLUGINS_PLUGINMESSAGEUTILS_H
michael@0 9
michael@0 10 #include "ipc/IPCMessageUtils.h"
michael@0 11 #include "base/message_loop.h"
michael@0 12
michael@0 13 #include "mozilla/ipc/MessageChannel.h"
michael@0 14 #include "mozilla/ipc/CrossProcessMutex.h"
michael@0 15 #include "gfxipc/ShadowLayerUtils.h"
michael@0 16
michael@0 17 #include "npapi.h"
michael@0 18 #include "npruntime.h"
michael@0 19 #include "npfunctions.h"
michael@0 20 #include "nsAutoPtr.h"
michael@0 21 #include "nsString.h"
michael@0 22 #include "nsTArray.h"
michael@0 23 #include "prlog.h"
michael@0 24 #include "nsHashKeys.h"
michael@0 25 #ifdef MOZ_CRASHREPORTER
michael@0 26 # include "nsExceptionHandler.h"
michael@0 27 #endif
michael@0 28 #ifdef XP_MACOSX
michael@0 29 #include "PluginInterposeOSX.h"
michael@0 30 #else
michael@0 31 namespace mac_plugin_interposing { class NSCursorInfo { }; }
michael@0 32 #endif
michael@0 33 using mac_plugin_interposing::NSCursorInfo;
michael@0 34
michael@0 35 namespace mozilla {
michael@0 36 namespace plugins {
michael@0 37
michael@0 38 using layers::SurfaceDescriptorX11;
michael@0 39
michael@0 40 enum ScriptableObjectType
michael@0 41 {
michael@0 42 LocalObject,
michael@0 43 Proxy
michael@0 44 };
michael@0 45
michael@0 46 mozilla::ipc::RacyInterruptPolicy
michael@0 47 MediateRace(const mozilla::ipc::MessageChannel::Message& parent,
michael@0 48 const mozilla::ipc::MessageChannel::Message& child);
michael@0 49
michael@0 50 std::string
michael@0 51 MungePluginDsoPath(const std::string& path);
michael@0 52 std::string
michael@0 53 UnmungePluginDsoPath(const std::string& munged);
michael@0 54
michael@0 55 extern PRLogModuleInfo* GetPluginLog();
michael@0 56
michael@0 57 const uint32_t kAllowAsyncDrawing = 0x1;
michael@0 58
michael@0 59 inline bool IsDrawingModelAsync(int16_t aModel) {
michael@0 60 return aModel == NPDrawingModelAsyncBitmapSurface
michael@0 61 #ifdef XP_WIN
michael@0 62 || aModel == NPDrawingModelAsyncWindowsDXGISurface
michael@0 63 #endif
michael@0 64 ;
michael@0 65 }
michael@0 66
michael@0 67 #if defined(_MSC_VER)
michael@0 68 #define FULLFUNCTION __FUNCSIG__
michael@0 69 #elif defined(__GNUC__)
michael@0 70 #define FULLFUNCTION __PRETTY_FUNCTION__
michael@0 71 #else
michael@0 72 #define FULLFUNCTION __FUNCTION__
michael@0 73 #endif
michael@0 74
michael@0 75 #define PLUGIN_LOG_DEBUG(args) PR_LOG(GetPluginLog(), PR_LOG_DEBUG, args)
michael@0 76 #define PLUGIN_LOG_DEBUG_FUNCTION PR_LOG(GetPluginLog(), PR_LOG_DEBUG, ("%s", FULLFUNCTION))
michael@0 77 #define PLUGIN_LOG_DEBUG_METHOD PR_LOG(GetPluginLog(), PR_LOG_DEBUG, ("%s [%p]", FULLFUNCTION, (void*) this))
michael@0 78
michael@0 79 /**
michael@0 80 * This is NPByteRange without the linked list.
michael@0 81 */
michael@0 82 struct IPCByteRange
michael@0 83 {
michael@0 84 int32_t offset;
michael@0 85 uint32_t length;
michael@0 86 };
michael@0 87
michael@0 88 typedef std::vector<IPCByteRange> IPCByteRanges;
michael@0 89
michael@0 90 typedef nsCString Buffer;
michael@0 91
michael@0 92 struct NPRemoteWindow
michael@0 93 {
michael@0 94 NPRemoteWindow();
michael@0 95 uint64_t window;
michael@0 96 int32_t x;
michael@0 97 int32_t y;
michael@0 98 uint32_t width;
michael@0 99 uint32_t height;
michael@0 100 NPRect clipRect;
michael@0 101 NPWindowType type;
michael@0 102 #if defined(MOZ_X11) && defined(XP_UNIX) && !defined(XP_MACOSX)
michael@0 103 VisualID visualID;
michael@0 104 Colormap colormap;
michael@0 105 #endif /* XP_UNIX */
michael@0 106 #if defined(XP_WIN)
michael@0 107 base::SharedMemoryHandle surfaceHandle;
michael@0 108 #endif
michael@0 109 #if defined(XP_MACOSX)
michael@0 110 double contentsScaleFactor;
michael@0 111 #endif
michael@0 112 };
michael@0 113
michael@0 114 #ifdef XP_WIN
michael@0 115 typedef HWND NativeWindowHandle;
michael@0 116 #elif defined(MOZ_X11)
michael@0 117 typedef XID NativeWindowHandle;
michael@0 118 #elif defined(XP_MACOSX) || defined(ANDROID) || defined(MOZ_WIDGET_QT)
michael@0 119 typedef intptr_t NativeWindowHandle; // never actually used, will always be 0
michael@0 120 #else
michael@0 121 #error Need NativeWindowHandle for this platform
michael@0 122 #endif
michael@0 123
michael@0 124 #ifdef XP_WIN
michael@0 125 typedef base::SharedMemoryHandle WindowsSharedMemoryHandle;
michael@0 126 typedef HANDLE DXGISharedSurfaceHandle;
michael@0 127 #else
michael@0 128 typedef mozilla::null_t WindowsSharedMemoryHandle;
michael@0 129 typedef mozilla::null_t DXGISharedSurfaceHandle;
michael@0 130 #endif
michael@0 131
michael@0 132 // XXX maybe not the best place for these. better one?
michael@0 133
michael@0 134 #define VARSTR(v_) case v_: return #v_
michael@0 135 inline const char* const
michael@0 136 NPPVariableToString(NPPVariable aVar)
michael@0 137 {
michael@0 138 switch (aVar) {
michael@0 139 VARSTR(NPPVpluginNameString);
michael@0 140 VARSTR(NPPVpluginDescriptionString);
michael@0 141 VARSTR(NPPVpluginWindowBool);
michael@0 142 VARSTR(NPPVpluginTransparentBool);
michael@0 143 VARSTR(NPPVjavaClass);
michael@0 144 VARSTR(NPPVpluginWindowSize);
michael@0 145 VARSTR(NPPVpluginTimerInterval);
michael@0 146
michael@0 147 VARSTR(NPPVpluginScriptableInstance);
michael@0 148 VARSTR(NPPVpluginScriptableIID);
michael@0 149
michael@0 150 VARSTR(NPPVjavascriptPushCallerBool);
michael@0 151
michael@0 152 VARSTR(NPPVpluginKeepLibraryInMemory);
michael@0 153 VARSTR(NPPVpluginNeedsXEmbed);
michael@0 154
michael@0 155 VARSTR(NPPVpluginScriptableNPObject);
michael@0 156
michael@0 157 VARSTR(NPPVformValue);
michael@0 158
michael@0 159 VARSTR(NPPVpluginUrlRequestsDisplayedBool);
michael@0 160
michael@0 161 VARSTR(NPPVpluginWantsAllNetworkStreams);
michael@0 162
michael@0 163 #ifdef XP_MACOSX
michael@0 164 VARSTR(NPPVpluginDrawingModel);
michael@0 165 VARSTR(NPPVpluginEventModel);
michael@0 166 #endif
michael@0 167
michael@0 168 default: return "???";
michael@0 169 }
michael@0 170 }
michael@0 171
michael@0 172 inline const char*
michael@0 173 NPNVariableToString(NPNVariable aVar)
michael@0 174 {
michael@0 175 switch(aVar) {
michael@0 176 VARSTR(NPNVxDisplay);
michael@0 177 VARSTR(NPNVxtAppContext);
michael@0 178 VARSTR(NPNVnetscapeWindow);
michael@0 179 VARSTR(NPNVjavascriptEnabledBool);
michael@0 180 VARSTR(NPNVasdEnabledBool);
michael@0 181 VARSTR(NPNVisOfflineBool);
michael@0 182
michael@0 183 VARSTR(NPNVserviceManager);
michael@0 184 VARSTR(NPNVDOMElement);
michael@0 185 VARSTR(NPNVDOMWindow);
michael@0 186 VARSTR(NPNVToolkit);
michael@0 187 VARSTR(NPNVSupportsXEmbedBool);
michael@0 188
michael@0 189 VARSTR(NPNVWindowNPObject);
michael@0 190
michael@0 191 VARSTR(NPNVPluginElementNPObject);
michael@0 192
michael@0 193 VARSTR(NPNVSupportsWindowless);
michael@0 194
michael@0 195 VARSTR(NPNVprivateModeBool);
michael@0 196 VARSTR(NPNVdocumentOrigin);
michael@0 197
michael@0 198 default: return "???";
michael@0 199 }
michael@0 200 }
michael@0 201 #undef VARSTR
michael@0 202
michael@0 203 inline bool IsPluginThread()
michael@0 204 {
michael@0 205 MessageLoop* loop = MessageLoop::current();
michael@0 206 if (!loop)
michael@0 207 return false;
michael@0 208 return (loop->type() == MessageLoop::TYPE_UI);
michael@0 209 }
michael@0 210
michael@0 211 inline void AssertPluginThread()
michael@0 212 {
michael@0 213 NS_ASSERTION(IsPluginThread(), "Should be on the plugin's main thread!");
michael@0 214 }
michael@0 215
michael@0 216 #define ENSURE_PLUGIN_THREAD(retval) \
michael@0 217 PR_BEGIN_MACRO \
michael@0 218 if (!IsPluginThread()) { \
michael@0 219 NS_WARNING("Not running on the plugin's main thread!"); \
michael@0 220 return (retval); \
michael@0 221 } \
michael@0 222 PR_END_MACRO
michael@0 223
michael@0 224 #define ENSURE_PLUGIN_THREAD_VOID() \
michael@0 225 PR_BEGIN_MACRO \
michael@0 226 if (!IsPluginThread()) { \
michael@0 227 NS_WARNING("Not running on the plugin's main thread!"); \
michael@0 228 return; \
michael@0 229 } \
michael@0 230 PR_END_MACRO
michael@0 231
michael@0 232 void DeferNPObjectLastRelease(const NPNetscapeFuncs* f, NPObject* o);
michael@0 233 void DeferNPVariantLastRelease(const NPNetscapeFuncs* f, NPVariant* v);
michael@0 234
michael@0 235 // in NPAPI, char* == nullptr is sometimes meaningful. the following is
michael@0 236 // helper code for dealing with nullable nsCString's
michael@0 237 inline nsCString
michael@0 238 NullableString(const char* aString)
michael@0 239 {
michael@0 240 if (!aString) {
michael@0 241 nsCString str;
michael@0 242 str.SetIsVoid(true);
michael@0 243 return str;
michael@0 244 }
michael@0 245 return nsCString(aString);
michael@0 246 }
michael@0 247
michael@0 248 inline const char*
michael@0 249 NullableStringGet(const nsCString& str)
michael@0 250 {
michael@0 251 if (str.IsVoid())
michael@0 252 return nullptr;
michael@0 253
michael@0 254 return str.get();
michael@0 255 }
michael@0 256
michael@0 257 struct DeletingObjectEntry : public nsPtrHashKey<NPObject>
michael@0 258 {
michael@0 259 DeletingObjectEntry(const NPObject* key)
michael@0 260 : nsPtrHashKey<NPObject>(key)
michael@0 261 , mDeleted(false)
michael@0 262 { }
michael@0 263
michael@0 264 bool mDeleted;
michael@0 265 };
michael@0 266
michael@0 267 #ifdef XP_WIN
michael@0 268 // The private event used for double-pass widgetless plugin rendering.
michael@0 269 UINT DoublePassRenderingEvent();
michael@0 270 #endif
michael@0 271
michael@0 272 } /* namespace plugins */
michael@0 273
michael@0 274 } /* namespace mozilla */
michael@0 275
michael@0 276 namespace IPC {
michael@0 277
michael@0 278 template <>
michael@0 279 struct ParamTraits<NPRect>
michael@0 280 {
michael@0 281 typedef NPRect paramType;
michael@0 282
michael@0 283 static void Write(Message* aMsg, const paramType& aParam)
michael@0 284 {
michael@0 285 WriteParam(aMsg, aParam.top);
michael@0 286 WriteParam(aMsg, aParam.left);
michael@0 287 WriteParam(aMsg, aParam.bottom);
michael@0 288 WriteParam(aMsg, aParam.right);
michael@0 289 }
michael@0 290
michael@0 291 static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
michael@0 292 {
michael@0 293 uint16_t top, left, bottom, right;
michael@0 294 if (ReadParam(aMsg, aIter, &top) &&
michael@0 295 ReadParam(aMsg, aIter, &left) &&
michael@0 296 ReadParam(aMsg, aIter, &bottom) &&
michael@0 297 ReadParam(aMsg, aIter, &right)) {
michael@0 298 aResult->top = top;
michael@0 299 aResult->left = left;
michael@0 300 aResult->bottom = bottom;
michael@0 301 aResult->right = right;
michael@0 302 return true;
michael@0 303 }
michael@0 304 return false;
michael@0 305 }
michael@0 306
michael@0 307 static void Log(const paramType& aParam, std::wstring* aLog)
michael@0 308 {
michael@0 309 aLog->append(StringPrintf(L"[%u, %u, %u, %u]", aParam.top, aParam.left,
michael@0 310 aParam.bottom, aParam.right));
michael@0 311 }
michael@0 312 };
michael@0 313
michael@0 314 template <>
michael@0 315 struct ParamTraits<NPWindowType>
michael@0 316 {
michael@0 317 typedef NPWindowType paramType;
michael@0 318
michael@0 319 static void Write(Message* aMsg, const paramType& aParam)
michael@0 320 {
michael@0 321 aMsg->WriteInt16(int16_t(aParam));
michael@0 322 }
michael@0 323
michael@0 324 static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
michael@0 325 {
michael@0 326 int16_t result;
michael@0 327 if (aMsg->ReadInt16(aIter, &result)) {
michael@0 328 *aResult = paramType(result);
michael@0 329 return true;
michael@0 330 }
michael@0 331 return false;
michael@0 332 }
michael@0 333
michael@0 334 static void Log(const paramType& aParam, std::wstring* aLog)
michael@0 335 {
michael@0 336 aLog->append(StringPrintf(L"%d", int16_t(aParam)));
michael@0 337 }
michael@0 338 };
michael@0 339
michael@0 340 template <>
michael@0 341 struct ParamTraits<NPImageFormat>
michael@0 342 {
michael@0 343 typedef NPImageFormat paramType;
michael@0 344
michael@0 345 static void Write(Message* aMsg, const paramType& aParam)
michael@0 346 {
michael@0 347 aMsg->WriteInt16(int16_t(aParam));
michael@0 348 }
michael@0 349
michael@0 350 static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
michael@0 351 {
michael@0 352 int16_t result;
michael@0 353 if (aMsg->ReadInt16(aIter, &result)) {
michael@0 354 *aResult = paramType(result);
michael@0 355 return true;
michael@0 356 }
michael@0 357 return false;
michael@0 358 }
michael@0 359
michael@0 360 static void Log(const paramType& aParam, std::wstring* aLog)
michael@0 361 {
michael@0 362 aLog->append(StringPrintf(L"%d", int16_t(aParam)));
michael@0 363 }
michael@0 364 };
michael@0 365
michael@0 366 template <>
michael@0 367 struct ParamTraits<mozilla::plugins::NPRemoteWindow>
michael@0 368 {
michael@0 369 typedef mozilla::plugins::NPRemoteWindow paramType;
michael@0 370
michael@0 371 static void Write(Message* aMsg, const paramType& aParam)
michael@0 372 {
michael@0 373 aMsg->WriteUInt64(aParam.window);
michael@0 374 WriteParam(aMsg, aParam.x);
michael@0 375 WriteParam(aMsg, aParam.y);
michael@0 376 WriteParam(aMsg, aParam.width);
michael@0 377 WriteParam(aMsg, aParam.height);
michael@0 378 WriteParam(aMsg, aParam.clipRect);
michael@0 379 WriteParam(aMsg, aParam.type);
michael@0 380 #if defined(MOZ_X11) && defined(XP_UNIX) && !defined(XP_MACOSX)
michael@0 381 aMsg->WriteULong(aParam.visualID);
michael@0 382 aMsg->WriteULong(aParam.colormap);
michael@0 383 #endif
michael@0 384 #if defined(XP_WIN)
michael@0 385 WriteParam(aMsg, aParam.surfaceHandle);
michael@0 386 #endif
michael@0 387 #if defined(XP_MACOSX)
michael@0 388 aMsg->WriteDouble(aParam.contentsScaleFactor);
michael@0 389 #endif
michael@0 390 }
michael@0 391
michael@0 392 static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
michael@0 393 {
michael@0 394 uint64_t window;
michael@0 395 int32_t x, y;
michael@0 396 uint32_t width, height;
michael@0 397 NPRect clipRect;
michael@0 398 NPWindowType type;
michael@0 399 if (!(aMsg->ReadUInt64(aIter, &window) &&
michael@0 400 ReadParam(aMsg, aIter, &x) &&
michael@0 401 ReadParam(aMsg, aIter, &y) &&
michael@0 402 ReadParam(aMsg, aIter, &width) &&
michael@0 403 ReadParam(aMsg, aIter, &height) &&
michael@0 404 ReadParam(aMsg, aIter, &clipRect) &&
michael@0 405 ReadParam(aMsg, aIter, &type)))
michael@0 406 return false;
michael@0 407
michael@0 408 #if defined(MOZ_X11) && defined(XP_UNIX) && !defined(XP_MACOSX)
michael@0 409 unsigned long visualID;
michael@0 410 unsigned long colormap;
michael@0 411 if (!(aMsg->ReadULong(aIter, &visualID) &&
michael@0 412 aMsg->ReadULong(aIter, &colormap)))
michael@0 413 return false;
michael@0 414 #endif
michael@0 415
michael@0 416 #if defined(XP_WIN)
michael@0 417 base::SharedMemoryHandle surfaceHandle;
michael@0 418 if (!ReadParam(aMsg, aIter, &surfaceHandle))
michael@0 419 return false;
michael@0 420 #endif
michael@0 421
michael@0 422 #if defined(XP_MACOSX)
michael@0 423 double contentsScaleFactor;
michael@0 424 if (!aMsg->ReadDouble(aIter, &contentsScaleFactor))
michael@0 425 return false;
michael@0 426 #endif
michael@0 427
michael@0 428 aResult->window = window;
michael@0 429 aResult->x = x;
michael@0 430 aResult->y = y;
michael@0 431 aResult->width = width;
michael@0 432 aResult->height = height;
michael@0 433 aResult->clipRect = clipRect;
michael@0 434 aResult->type = type;
michael@0 435 #if defined(MOZ_X11) && defined(XP_UNIX) && !defined(XP_MACOSX)
michael@0 436 aResult->visualID = visualID;
michael@0 437 aResult->colormap = colormap;
michael@0 438 #endif
michael@0 439 #if defined(XP_WIN)
michael@0 440 aResult->surfaceHandle = surfaceHandle;
michael@0 441 #endif
michael@0 442 #if defined(XP_MACOSX)
michael@0 443 aResult->contentsScaleFactor = contentsScaleFactor;
michael@0 444 #endif
michael@0 445 return true;
michael@0 446 }
michael@0 447
michael@0 448 static void Log(const paramType& aParam, std::wstring* aLog)
michael@0 449 {
michael@0 450 aLog->append(StringPrintf(L"[%u, %d, %d, %u, %u, %d",
michael@0 451 (unsigned long)aParam.window,
michael@0 452 aParam.x, aParam.y, aParam.width,
michael@0 453 aParam.height, (long)aParam.type));
michael@0 454 }
michael@0 455 };
michael@0 456
michael@0 457 template <>
michael@0 458 struct ParamTraits<NPString>
michael@0 459 {
michael@0 460 typedef NPString paramType;
michael@0 461
michael@0 462 static void Write(Message* aMsg, const paramType& aParam)
michael@0 463 {
michael@0 464 WriteParam(aMsg, aParam.UTF8Length);
michael@0 465 aMsg->WriteBytes(aParam.UTF8Characters,
michael@0 466 aParam.UTF8Length * sizeof(NPUTF8));
michael@0 467 }
michael@0 468
michael@0 469 static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
michael@0 470 {
michael@0 471 if (ReadParam(aMsg, aIter, &aResult->UTF8Length)) {
michael@0 472 int byteCount = aResult->UTF8Length * sizeof(NPUTF8);
michael@0 473 if (!byteCount) {
michael@0 474 aResult->UTF8Characters = "\0";
michael@0 475 return true;
michael@0 476 }
michael@0 477
michael@0 478 const char* messageBuffer = nullptr;
michael@0 479 nsAutoArrayPtr<char> newBuffer(new char[byteCount]);
michael@0 480 if (newBuffer && aMsg->ReadBytes(aIter, &messageBuffer, byteCount )) {
michael@0 481 memcpy((void*)messageBuffer, newBuffer.get(), byteCount);
michael@0 482 aResult->UTF8Characters = newBuffer.forget();
michael@0 483 return true;
michael@0 484 }
michael@0 485 }
michael@0 486 return false;
michael@0 487 }
michael@0 488
michael@0 489 static void Log(const paramType& aParam, std::wstring* aLog)
michael@0 490 {
michael@0 491 aLog->append(StringPrintf(L"%s", aParam.UTF8Characters));
michael@0 492 }
michael@0 493 };
michael@0 494
michael@0 495 #ifdef XP_MACOSX
michael@0 496 template <>
michael@0 497 struct ParamTraits<NPNSString*>
michael@0 498 {
michael@0 499 typedef NPNSString* paramType;
michael@0 500
michael@0 501 // Empty string writes a length of 0 and no buffer.
michael@0 502 // We don't write a nullptr terminating character in buffers.
michael@0 503 static void Write(Message* aMsg, const paramType& aParam)
michael@0 504 {
michael@0 505 CFStringRef cfString = (CFStringRef)aParam;
michael@0 506
michael@0 507 // Write true if we have a string, false represents nullptr.
michael@0 508 aMsg->WriteBool(!!cfString);
michael@0 509 if (!cfString) {
michael@0 510 return;
michael@0 511 }
michael@0 512
michael@0 513 long length = ::CFStringGetLength(cfString);
michael@0 514 WriteParam(aMsg, length);
michael@0 515 if (length == 0) {
michael@0 516 return;
michael@0 517 }
michael@0 518
michael@0 519 // Attempt to get characters without any allocation/conversion.
michael@0 520 if (::CFStringGetCharactersPtr(cfString)) {
michael@0 521 aMsg->WriteBytes(::CFStringGetCharactersPtr(cfString), length * sizeof(UniChar));
michael@0 522 } else {
michael@0 523 UniChar *buffer = (UniChar*)moz_xmalloc(length * sizeof(UniChar));
michael@0 524 ::CFStringGetCharacters(cfString, ::CFRangeMake(0, length), buffer);
michael@0 525 aMsg->WriteBytes(buffer, length * sizeof(UniChar));
michael@0 526 free(buffer);
michael@0 527 }
michael@0 528 }
michael@0 529
michael@0 530 static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
michael@0 531 {
michael@0 532 bool haveString = false;
michael@0 533 if (!aMsg->ReadBool(aIter, &haveString)) {
michael@0 534 return false;
michael@0 535 }
michael@0 536 if (!haveString) {
michael@0 537 *aResult = nullptr;
michael@0 538 return true;
michael@0 539 }
michael@0 540
michael@0 541 long length;
michael@0 542 if (!ReadParam(aMsg, aIter, &length)) {
michael@0 543 return false;
michael@0 544 }
michael@0 545
michael@0 546 UniChar* buffer = nullptr;
michael@0 547 if (length != 0) {
michael@0 548 if (!aMsg->ReadBytes(aIter, (const char**)&buffer, length * sizeof(UniChar)) ||
michael@0 549 !buffer) {
michael@0 550 return false;
michael@0 551 }
michael@0 552 }
michael@0 553
michael@0 554 *aResult = (NPNSString*)::CFStringCreateWithBytes(kCFAllocatorDefault, (UInt8*)buffer,
michael@0 555 length * sizeof(UniChar),
michael@0 556 kCFStringEncodingUTF16, false);
michael@0 557 if (!*aResult) {
michael@0 558 return false;
michael@0 559 }
michael@0 560
michael@0 561 return true;
michael@0 562 }
michael@0 563 };
michael@0 564 #endif
michael@0 565
michael@0 566 #ifdef XP_MACOSX
michael@0 567 template <>
michael@0 568 struct ParamTraits<NSCursorInfo>
michael@0 569 {
michael@0 570 typedef NSCursorInfo paramType;
michael@0 571
michael@0 572 static void Write(Message* aMsg, const paramType& aParam)
michael@0 573 {
michael@0 574 NSCursorInfo::Type type = aParam.GetType();
michael@0 575
michael@0 576 aMsg->WriteInt(type);
michael@0 577
michael@0 578 nsPoint hotSpot = aParam.GetHotSpot();
michael@0 579 WriteParam(aMsg, hotSpot.x);
michael@0 580 WriteParam(aMsg, hotSpot.y);
michael@0 581
michael@0 582 uint32_t dataLength = aParam.GetCustomImageDataLength();
michael@0 583 WriteParam(aMsg, dataLength);
michael@0 584 if (dataLength == 0) {
michael@0 585 return;
michael@0 586 }
michael@0 587
michael@0 588 uint8_t* buffer = (uint8_t*)moz_xmalloc(dataLength);
michael@0 589 memcpy(buffer, aParam.GetCustomImageData(), dataLength);
michael@0 590 aMsg->WriteBytes(buffer, dataLength);
michael@0 591 free(buffer);
michael@0 592 }
michael@0 593
michael@0 594 static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
michael@0 595 {
michael@0 596 NSCursorInfo::Type type;
michael@0 597 if (!aMsg->ReadInt(aIter, (int*)&type)) {
michael@0 598 return false;
michael@0 599 }
michael@0 600
michael@0 601 nscoord hotSpotX, hotSpotY;
michael@0 602 if (!ReadParam(aMsg, aIter, &hotSpotX) ||
michael@0 603 !ReadParam(aMsg, aIter, &hotSpotY)) {
michael@0 604 return false;
michael@0 605 }
michael@0 606
michael@0 607 uint32_t dataLength;
michael@0 608 if (!ReadParam(aMsg, aIter, &dataLength)) {
michael@0 609 return false;
michael@0 610 }
michael@0 611
michael@0 612 uint8_t* data = nullptr;
michael@0 613 if (dataLength != 0) {
michael@0 614 if (!aMsg->ReadBytes(aIter, (const char**)&data, dataLength) || !data) {
michael@0 615 return false;
michael@0 616 }
michael@0 617 }
michael@0 618
michael@0 619 aResult->SetType(type);
michael@0 620 aResult->SetHotSpot(nsPoint(hotSpotX, hotSpotY));
michael@0 621 aResult->SetCustomImageData(data, dataLength);
michael@0 622
michael@0 623 return true;
michael@0 624 }
michael@0 625
michael@0 626 static void Log(const paramType& aParam, std::wstring* aLog)
michael@0 627 {
michael@0 628 const char* typeName = aParam.GetTypeName();
michael@0 629 nsPoint hotSpot = aParam.GetHotSpot();
michael@0 630 int hotSpotX, hotSpotY;
michael@0 631 #ifdef NS_COORD_IS_FLOAT
michael@0 632 hotSpotX = rint(hotSpot.x);
michael@0 633 hotSpotY = rint(hotSpot.y);
michael@0 634 #else
michael@0 635 hotSpotX = hotSpot.x;
michael@0 636 hotSpotY = hotSpot.y;
michael@0 637 #endif
michael@0 638 uint32_t dataLength = aParam.GetCustomImageDataLength();
michael@0 639 uint8_t* data = aParam.GetCustomImageData();
michael@0 640
michael@0 641 aLog->append(StringPrintf(L"[%s, (%i %i), %u, %p]",
michael@0 642 typeName, hotSpotX, hotSpotY, dataLength, data));
michael@0 643 }
michael@0 644 };
michael@0 645 #else
michael@0 646 template<>
michael@0 647 struct ParamTraits<NSCursorInfo>
michael@0 648 {
michael@0 649 typedef NSCursorInfo paramType;
michael@0 650 static void Write(Message* aMsg, const paramType& aParam) {
michael@0 651 NS_RUNTIMEABORT("NSCursorInfo isn't meaningful on this platform");
michael@0 652 }
michael@0 653 static bool Read(const Message* aMsg, void** aIter, paramType* aResult) {
michael@0 654 NS_RUNTIMEABORT("NSCursorInfo isn't meaningful on this platform");
michael@0 655 return false;
michael@0 656 }
michael@0 657 };
michael@0 658 #endif // #ifdef XP_MACOSX
michael@0 659
michael@0 660 template <>
michael@0 661 struct ParamTraits<NPVariant>
michael@0 662 {
michael@0 663 typedef NPVariant paramType;
michael@0 664
michael@0 665 static void Write(Message* aMsg, const paramType& aParam)
michael@0 666 {
michael@0 667 if (NPVARIANT_IS_VOID(aParam)) {
michael@0 668 aMsg->WriteInt(0);
michael@0 669 return;
michael@0 670 }
michael@0 671
michael@0 672 if (NPVARIANT_IS_NULL(aParam)) {
michael@0 673 aMsg->WriteInt(1);
michael@0 674 return;
michael@0 675 }
michael@0 676
michael@0 677 if (NPVARIANT_IS_BOOLEAN(aParam)) {
michael@0 678 aMsg->WriteInt(2);
michael@0 679 WriteParam(aMsg, NPVARIANT_TO_BOOLEAN(aParam));
michael@0 680 return;
michael@0 681 }
michael@0 682
michael@0 683 if (NPVARIANT_IS_INT32(aParam)) {
michael@0 684 aMsg->WriteInt(3);
michael@0 685 WriteParam(aMsg, NPVARIANT_TO_INT32(aParam));
michael@0 686 return;
michael@0 687 }
michael@0 688
michael@0 689 if (NPVARIANT_IS_DOUBLE(aParam)) {
michael@0 690 aMsg->WriteInt(4);
michael@0 691 WriteParam(aMsg, NPVARIANT_TO_DOUBLE(aParam));
michael@0 692 return;
michael@0 693 }
michael@0 694
michael@0 695 if (NPVARIANT_IS_STRING(aParam)) {
michael@0 696 aMsg->WriteInt(5);
michael@0 697 WriteParam(aMsg, NPVARIANT_TO_STRING(aParam));
michael@0 698 return;
michael@0 699 }
michael@0 700
michael@0 701 NS_ERROR("Unsupported type!");
michael@0 702 }
michael@0 703
michael@0 704 static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
michael@0 705 {
michael@0 706 int type;
michael@0 707 if (!aMsg->ReadInt(aIter, &type)) {
michael@0 708 return false;
michael@0 709 }
michael@0 710
michael@0 711 switch (type) {
michael@0 712 case 0:
michael@0 713 VOID_TO_NPVARIANT(*aResult);
michael@0 714 return true;
michael@0 715
michael@0 716 case 1:
michael@0 717 NULL_TO_NPVARIANT(*aResult);
michael@0 718 return true;
michael@0 719
michael@0 720 case 2: {
michael@0 721 bool value;
michael@0 722 if (ReadParam(aMsg, aIter, &value)) {
michael@0 723 BOOLEAN_TO_NPVARIANT(value, *aResult);
michael@0 724 return true;
michael@0 725 }
michael@0 726 } break;
michael@0 727
michael@0 728 case 3: {
michael@0 729 int32_t value;
michael@0 730 if (ReadParam(aMsg, aIter, &value)) {
michael@0 731 INT32_TO_NPVARIANT(value, *aResult);
michael@0 732 return true;
michael@0 733 }
michael@0 734 } break;
michael@0 735
michael@0 736 case 4: {
michael@0 737 double value;
michael@0 738 if (ReadParam(aMsg, aIter, &value)) {
michael@0 739 DOUBLE_TO_NPVARIANT(value, *aResult);
michael@0 740 return true;
michael@0 741 }
michael@0 742 } break;
michael@0 743
michael@0 744 case 5: {
michael@0 745 NPString value;
michael@0 746 if (ReadParam(aMsg, aIter, &value)) {
michael@0 747 STRINGN_TO_NPVARIANT(value.UTF8Characters, value.UTF8Length,
michael@0 748 *aResult);
michael@0 749 return true;
michael@0 750 }
michael@0 751 } break;
michael@0 752
michael@0 753 default:
michael@0 754 NS_ERROR("Unsupported type!");
michael@0 755 }
michael@0 756
michael@0 757 return false;
michael@0 758 }
michael@0 759
michael@0 760 static void Log(const paramType& aParam, std::wstring* aLog)
michael@0 761 {
michael@0 762 if (NPVARIANT_IS_VOID(aParam)) {
michael@0 763 aLog->append(L"[void]");
michael@0 764 return;
michael@0 765 }
michael@0 766
michael@0 767 if (NPVARIANT_IS_NULL(aParam)) {
michael@0 768 aLog->append(L"[null]");
michael@0 769 return;
michael@0 770 }
michael@0 771
michael@0 772 if (NPVARIANT_IS_BOOLEAN(aParam)) {
michael@0 773 LogParam(NPVARIANT_TO_BOOLEAN(aParam), aLog);
michael@0 774 return;
michael@0 775 }
michael@0 776
michael@0 777 if (NPVARIANT_IS_INT32(aParam)) {
michael@0 778 LogParam(NPVARIANT_TO_INT32(aParam), aLog);
michael@0 779 return;
michael@0 780 }
michael@0 781
michael@0 782 if (NPVARIANT_IS_DOUBLE(aParam)) {
michael@0 783 LogParam(NPVARIANT_TO_DOUBLE(aParam), aLog);
michael@0 784 return;
michael@0 785 }
michael@0 786
michael@0 787 if (NPVARIANT_IS_STRING(aParam)) {
michael@0 788 LogParam(NPVARIANT_TO_STRING(aParam), aLog);
michael@0 789 return;
michael@0 790 }
michael@0 791
michael@0 792 NS_ERROR("Unsupported type!");
michael@0 793 }
michael@0 794 };
michael@0 795
michael@0 796 template <>
michael@0 797 struct ParamTraits<mozilla::plugins::IPCByteRange>
michael@0 798 {
michael@0 799 typedef mozilla::plugins::IPCByteRange paramType;
michael@0 800
michael@0 801 static void Write(Message* aMsg, const paramType& aParam)
michael@0 802 {
michael@0 803 WriteParam(aMsg, aParam.offset);
michael@0 804 WriteParam(aMsg, aParam.length);
michael@0 805 }
michael@0 806
michael@0 807 static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
michael@0 808 {
michael@0 809 paramType p;
michael@0 810 if (ReadParam(aMsg, aIter, &p.offset) &&
michael@0 811 ReadParam(aMsg, aIter, &p.length)) {
michael@0 812 *aResult = p;
michael@0 813 return true;
michael@0 814 }
michael@0 815 return false;
michael@0 816 }
michael@0 817 };
michael@0 818
michael@0 819 template <>
michael@0 820 struct ParamTraits<NPNVariable>
michael@0 821 {
michael@0 822 typedef NPNVariable paramType;
michael@0 823
michael@0 824 static void Write(Message* aMsg, const paramType& aParam)
michael@0 825 {
michael@0 826 WriteParam(aMsg, int(aParam));
michael@0 827 }
michael@0 828
michael@0 829 static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
michael@0 830 {
michael@0 831 int intval;
michael@0 832 if (ReadParam(aMsg, aIter, &intval)) {
michael@0 833 *aResult = paramType(intval);
michael@0 834 return true;
michael@0 835 }
michael@0 836 return false;
michael@0 837 }
michael@0 838 };
michael@0 839
michael@0 840 template<>
michael@0 841 struct ParamTraits<NPNURLVariable>
michael@0 842 {
michael@0 843 typedef NPNURLVariable paramType;
michael@0 844
michael@0 845 static void Write(Message* aMsg, const paramType& aParam)
michael@0 846 {
michael@0 847 WriteParam(aMsg, int(aParam));
michael@0 848 }
michael@0 849
michael@0 850 static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
michael@0 851 {
michael@0 852 int intval;
michael@0 853 if (ReadParam(aMsg, aIter, &intval)) {
michael@0 854 switch (intval) {
michael@0 855 case NPNURLVCookie:
michael@0 856 case NPNURLVProxy:
michael@0 857 *aResult = paramType(intval);
michael@0 858 return true;
michael@0 859 }
michael@0 860 }
michael@0 861 return false;
michael@0 862 }
michael@0 863 };
michael@0 864
michael@0 865
michael@0 866 template<>
michael@0 867 struct ParamTraits<NPCoordinateSpace>
michael@0 868 {
michael@0 869 typedef NPCoordinateSpace paramType;
michael@0 870
michael@0 871 static void Write(Message* aMsg, const paramType& aParam)
michael@0 872 {
michael@0 873 WriteParam(aMsg, int32_t(aParam));
michael@0 874 }
michael@0 875
michael@0 876 static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
michael@0 877 {
michael@0 878 int32_t intval;
michael@0 879 if (ReadParam(aMsg, aIter, &intval)) {
michael@0 880 switch (intval) {
michael@0 881 case NPCoordinateSpacePlugin:
michael@0 882 case NPCoordinateSpaceWindow:
michael@0 883 case NPCoordinateSpaceFlippedWindow:
michael@0 884 case NPCoordinateSpaceScreen:
michael@0 885 case NPCoordinateSpaceFlippedScreen:
michael@0 886 *aResult = paramType(intval);
michael@0 887 return true;
michael@0 888 }
michael@0 889 }
michael@0 890 return false;
michael@0 891 }
michael@0 892 };
michael@0 893
michael@0 894 } /* namespace IPC */
michael@0 895
michael@0 896
michael@0 897 // Serializing NPEvents is completely platform-specific and can be rather
michael@0 898 // intricate depending on the platform. So for readability we split it
michael@0 899 // into separate files and have the only macro crud live here.
michael@0 900 //
michael@0 901 // NB: these guards are based on those where struct NPEvent is defined
michael@0 902 // in npapi.h. They should be kept in sync.
michael@0 903 #if defined(XP_MACOSX)
michael@0 904 # include "mozilla/plugins/NPEventOSX.h"
michael@0 905 #elif defined(XP_WIN)
michael@0 906 # include "mozilla/plugins/NPEventWindows.h"
michael@0 907 #elif defined(ANDROID)
michael@0 908 # include "mozilla/plugins/NPEventAndroid.h"
michael@0 909 #elif defined(XP_UNIX)
michael@0 910 # include "mozilla/plugins/NPEventUnix.h"
michael@0 911 #else
michael@0 912 # error Unsupported platform
michael@0 913 #endif
michael@0 914
michael@0 915 #endif /* DOM_PLUGINS_PLUGINMESSAGEUTILS_H */

mercurial