1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 : * vim: sw=4 ts=4 et :
3 : * ***** BEGIN LICENSE BLOCK *****
4 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 : *
6 : * The contents of this file are subject to the Mozilla Public License Version
7 : * 1.1 (the "License"); you may not use this file except in compliance with
8 : * the License. You may obtain a copy of the License at
9 : * http://www.mozilla.org/MPL/
10 : *
11 : * Software distributed under the License is distributed on an "AS IS" basis,
12 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 : * for the specific language governing rights and limitations under the
14 : * License.
15 : *
16 : * The Original Code is Mozilla Plugin App.
17 : *
18 : * The Initial Developer of the Original Code is
19 : * Chris Jones <jones.chris.g@gmail.com>
20 : * Portions created by the Initial Developer are Copyright (C) 2009
21 : * the Initial Developer. All Rights Reserved.
22 : *
23 : * Contributor(s):
24 : * Jim Mathies <jmathies@mozilla.com>
25 : *
26 : * Alternatively, the contents of this file may be used under the terms of
27 : * either the GNU General Public License Version 2 or later (the "GPL"), or
28 : * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 : * in which case the provisions of the GPL or the LGPL are applicable instead
30 : * of those above. If you wish to allow use of your version of this file only
31 : * under the terms of either the GPL or the LGPL, and not to allow others to
32 : * use your version of this file under the terms of the MPL, indicate your
33 : * decision by deleting the provisions above and replace them with the notice
34 : * and other provisions required by the GPL or the LGPL. If you do not delete
35 : * the provisions above, a recipient may use your version of this file under
36 : * the terms of any one of the MPL, the GPL or the LGPL.
37 : *
38 : * ***** END LICENSE BLOCK ***** */
39 :
40 : #include "PluginInstanceParent.h"
41 : #include "BrowserStreamParent.h"
42 : #include "PluginBackgroundDestroyer.h"
43 : #include "PluginModuleParent.h"
44 : #include "PluginStreamParent.h"
45 : #include "StreamNotifyParent.h"
46 : #include "npfunctions.h"
47 : #include "nsAutoPtr.h"
48 : #include "mozilla/unused.h"
49 : #include "gfxASurface.h"
50 : #include "gfxContext.h"
51 : #include "gfxPlatform.h"
52 : #include "gfxSharedImageSurface.h"
53 : #include "nsNPAPIPluginInstance.h"
54 : #ifdef MOZ_X11
55 : #include "gfxXlibSurface.h"
56 : #endif
57 : #include "gfxContext.h"
58 : #include "gfxColor.h"
59 : #include "gfxUtils.h"
60 : #include "nsNPAPIPluginInstance.h"
61 :
62 : #if defined(OS_WIN)
63 : #include <windowsx.h>
64 : #include "mozilla/plugins/PluginSurfaceParent.h"
65 :
66 : // Plugin focus event for widget.
67 : extern const PRUnichar* kOOPPPluginFocusEventId;
68 : UINT gOOPPPluginFocusEvent =
69 : RegisterWindowMessage(kOOPPPluginFocusEventId);
70 : extern const PRUnichar* kFlashFullscreenClass;
71 : #elif defined(MOZ_WIDGET_GTK2)
72 : #include <gdk/gdk.h>
73 : #elif defined(XP_MACOSX)
74 : #include <ApplicationServices/ApplicationServices.h>
75 : #endif // defined(XP_MACOSX)
76 :
77 : using namespace mozilla::plugins;
78 :
79 : bool
80 0 : StreamNotifyParent::RecvRedirectNotifyResponse(const bool& allow)
81 : {
82 0 : PluginInstanceParent* instance = static_cast<PluginInstanceParent*>(Manager());
83 0 : instance->mNPNIface->urlredirectresponse(instance->mNPP, this, static_cast<NPBool>(allow));
84 0 : return true;
85 : }
86 :
87 0 : PluginInstanceParent::PluginInstanceParent(PluginModuleParent* parent,
88 : NPP npp,
89 : const nsCString& aMimeType,
90 : const NPNetscapeFuncs* npniface)
91 : : mParent(parent)
92 : , mNPP(npp)
93 : , mNPNIface(npniface)
94 : , mWindowType(NPWindowTypeWindow)
95 0 : , mDrawingModel(kDefaultDrawingModel)
96 : #if defined(OS_WIN)
97 : , mPluginHWND(NULL)
98 : , mPluginWndProc(NULL)
99 : , mNestedEventState(false)
100 : #endif // defined(XP_WIN)
101 : #if defined(XP_MACOSX)
102 : , mShWidth(0)
103 : , mShHeight(0)
104 : , mShColorSpace(nsnull)
105 : #endif
106 : {
107 0 : }
108 :
109 0 : PluginInstanceParent::~PluginInstanceParent()
110 : {
111 0 : if (mNPP)
112 0 : mNPP->pdata = NULL;
113 :
114 : #if defined(OS_WIN)
115 : NS_ASSERTION(!(mPluginHWND || mPluginWndProc),
116 : "Subclass was not reset correctly before the dtor was reached!");
117 : #endif
118 : #if defined(MOZ_WIDGET_COCOA)
119 : if (mShWidth != 0 && mShHeight != 0) {
120 : DeallocShmem(mShSurface);
121 : }
122 : if (mShColorSpace)
123 : ::CGColorSpaceRelease(mShColorSpace);
124 : #endif
125 0 : if (mRemoteImageDataShmem.IsWritable()) {
126 : ImageContainer *container =
127 0 : GetImageContainer();
128 :
129 0 : if (container) {
130 0 : container->SetRemoteImageData(nsnull, nsnull);
131 0 : container->SetCompositionNotifySink(nsnull);
132 0 : DeallocShmem(mRemoteImageDataShmem);
133 : }
134 : }
135 0 : }
136 :
137 : bool
138 0 : PluginInstanceParent::Init()
139 : {
140 0 : return !!mScriptableObjects.Init();
141 : }
142 :
143 : void
144 0 : PluginInstanceParent::ActorDestroy(ActorDestroyReason why)
145 : {
146 : #if defined(OS_WIN)
147 : if (why == AbnormalShutdown) {
148 : // If the plugin process crashes, this is the only
149 : // chance we get to destroy resources.
150 : SharedSurfaceRelease();
151 : UnsubclassPluginWindow();
152 : }
153 : #endif
154 : // After this method, the data backing the remote surface may no
155 : // longer be calid. The X surface may be destroyed, or the shared
156 : // memory backing this surface may no longer be valid. The right
157 : // way to inform the nsObjectFrame that the surface is no longer
158 : // valid is with an invalidate call.
159 0 : if (mFrontSurface) {
160 0 : mFrontSurface = NULL;
161 0 : const NPRect rect = {0, 0, 0, 0};
162 0 : RecvNPN_InvalidateRect(rect);
163 : #ifdef MOZ_X11
164 0 : XSync(DefaultXDisplay(), False);
165 : #endif
166 : }
167 0 : }
168 :
169 : NPError
170 0 : PluginInstanceParent::Destroy()
171 : {
172 : NPError retval;
173 0 : if (!CallNPP_Destroy(&retval))
174 0 : retval = NPERR_GENERIC_ERROR;
175 :
176 : #if defined(OS_WIN)
177 : SharedSurfaceRelease();
178 : UnsubclassPluginWindow();
179 : #endif
180 :
181 0 : return retval;
182 : }
183 :
184 : PBrowserStreamParent*
185 0 : PluginInstanceParent::AllocPBrowserStream(const nsCString& url,
186 : const uint32_t& length,
187 : const uint32_t& lastmodified,
188 : PStreamNotifyParent* notifyData,
189 : const nsCString& headers,
190 : const nsCString& mimeType,
191 : const bool& seekable,
192 : NPError* rv,
193 : uint16_t *stype)
194 : {
195 0 : NS_RUNTIMEABORT("Not reachable");
196 0 : return NULL;
197 : }
198 :
199 : bool
200 0 : PluginInstanceParent::DeallocPBrowserStream(PBrowserStreamParent* stream)
201 : {
202 0 : delete stream;
203 0 : return true;
204 : }
205 :
206 : PPluginStreamParent*
207 0 : PluginInstanceParent::AllocPPluginStream(const nsCString& mimeType,
208 : const nsCString& target,
209 : NPError* result)
210 : {
211 0 : return new PluginStreamParent(this, mimeType, target, result);
212 : }
213 :
214 : bool
215 0 : PluginInstanceParent::DeallocPPluginStream(PPluginStreamParent* stream)
216 : {
217 0 : delete stream;
218 0 : return true;
219 : }
220 :
221 : bool
222 0 : PluginInstanceParent::AnswerNPN_GetValue_NPNVjavascriptEnabledBool(
223 : bool* value,
224 : NPError* result)
225 : {
226 : NPBool v;
227 0 : *result = mNPNIface->getvalue(mNPP, NPNVjavascriptEnabledBool, &v);
228 0 : *value = v;
229 0 : return true;
230 : }
231 :
232 : bool
233 0 : PluginInstanceParent::AnswerNPN_GetValue_NPNVisOfflineBool(bool* value,
234 : NPError* result)
235 : {
236 : NPBool v;
237 0 : *result = mNPNIface->getvalue(mNPP, NPNVisOfflineBool, &v);
238 0 : *value = v;
239 0 : return true;
240 : }
241 :
242 : bool
243 0 : PluginInstanceParent::AnswerNPN_GetValue_NPNVnetscapeWindow(NativeWindowHandle* value,
244 : NPError* result)
245 : {
246 : #ifdef XP_WIN
247 : HWND id;
248 : #elif defined(MOZ_X11)
249 : XID id;
250 : #elif defined(XP_MACOSX)
251 : intptr_t id;
252 : #elif defined(ANDROID)
253 : #warning Need Android impl
254 : int id;
255 : #elif defined(MOZ_WIDGET_QT)
256 : # warning Need Qt non X impl
257 : int id;
258 : #else
259 : #warning Implement me
260 : #endif
261 :
262 0 : *result = mNPNIface->getvalue(mNPP, NPNVnetscapeWindow, &id);
263 0 : *value = id;
264 0 : return true;
265 : }
266 :
267 : bool
268 0 : PluginInstanceParent::InternalGetValueForNPObject(
269 : NPNVariable aVariable,
270 : PPluginScriptableObjectParent** aValue,
271 : NPError* aResult)
272 : {
273 : NPObject* npobject;
274 0 : NPError result = mNPNIface->getvalue(mNPP, aVariable, (void*)&npobject);
275 0 : if (result == NPERR_NO_ERROR) {
276 0 : NS_ASSERTION(npobject, "Shouldn't return null and NPERR_NO_ERROR!");
277 :
278 0 : PluginScriptableObjectParent* actor = GetActorForNPObject(npobject);
279 0 : mNPNIface->releaseobject(npobject);
280 0 : if (actor) {
281 0 : *aValue = actor;
282 0 : *aResult = NPERR_NO_ERROR;
283 0 : return true;
284 : }
285 :
286 0 : NS_ERROR("Failed to get actor!");
287 0 : result = NPERR_GENERIC_ERROR;
288 : }
289 :
290 0 : *aValue = nsnull;
291 0 : *aResult = result;
292 0 : return true;
293 : }
294 :
295 : bool
296 0 : PluginInstanceParent::IsAsyncDrawing()
297 : {
298 0 : return IsDrawingModelAsync(mDrawingModel);
299 : }
300 :
301 : bool
302 0 : PluginInstanceParent::AnswerNPN_GetValue_NPNVWindowNPObject(
303 : PPluginScriptableObjectParent** aValue,
304 : NPError* aResult)
305 : {
306 0 : return InternalGetValueForNPObject(NPNVWindowNPObject, aValue, aResult);
307 : }
308 :
309 : bool
310 0 : PluginInstanceParent::AnswerNPN_GetValue_NPNVPluginElementNPObject(
311 : PPluginScriptableObjectParent** aValue,
312 : NPError* aResult)
313 : {
314 : return InternalGetValueForNPObject(NPNVPluginElementNPObject, aValue,
315 0 : aResult);
316 : }
317 :
318 : bool
319 0 : PluginInstanceParent::AnswerNPN_GetValue_NPNVprivateModeBool(bool* value,
320 : NPError* result)
321 : {
322 : NPBool v;
323 0 : *result = mNPNIface->getvalue(mNPP, NPNVprivateModeBool, &v);
324 0 : *value = v;
325 0 : return true;
326 : }
327 :
328 : bool
329 0 : PluginInstanceParent::AnswerNPN_GetValue_NPNVdocumentOrigin(nsCString* value,
330 : NPError* result)
331 : {
332 0 : void *v = nsnull;
333 0 : *result = mNPNIface->getvalue(mNPP, NPNVdocumentOrigin, &v);
334 0 : if (*result == NPERR_NO_ERROR && v) {
335 0 : value->Adopt(static_cast<char*>(v));
336 : }
337 0 : return true;
338 : }
339 :
340 : bool
341 0 : PluginInstanceParent::AnswerNPN_SetValue_NPPVpluginWindow(
342 : const bool& windowed, NPError* result)
343 : {
344 0 : NPBool isWindowed = windowed;
345 : *result = mNPNIface->setvalue(mNPP, NPPVpluginWindowBool,
346 0 : (void*)isWindowed);
347 0 : return true;
348 : }
349 :
350 : bool
351 0 : PluginInstanceParent::AnswerNPN_SetValue_NPPVpluginTransparent(
352 : const bool& transparent, NPError* result)
353 : {
354 0 : NPBool isTransparent = transparent;
355 : *result = mNPNIface->setvalue(mNPP, NPPVpluginTransparentBool,
356 0 : (void*)isTransparent);
357 0 : return true;
358 : }
359 :
360 : bool
361 0 : PluginInstanceParent::AnswerNPN_SetValue_NPPVpluginUsesDOMForCursor(
362 : const bool& useDOMForCursor, NPError* result)
363 : {
364 : *result = mNPNIface->setvalue(mNPP, NPPVpluginUsesDOMForCursorBool,
365 0 : (void*)(NPBool)useDOMForCursor);
366 0 : return true;
367 : }
368 :
369 : class NotificationSink : public CompositionNotifySink
370 : {
371 : public:
372 0 : NotificationSink(PluginInstanceParent *aInstance) : mInstance(aInstance)
373 0 : { }
374 :
375 0 : virtual void DidComposite() { mInstance->DidComposite(); }
376 : private:
377 : PluginInstanceParent *mInstance;
378 : };
379 :
380 : bool
381 0 : PluginInstanceParent::AnswerNPN_SetValue_NPPVpluginDrawingModel(
382 : const int& drawingModel, OptionalShmem *shmem, CrossProcessMutexHandle *mutex, NPError* result)
383 : {
384 : #ifdef XP_MACOSX
385 : if (drawingModel == NPDrawingModelCoreAnimation ||
386 : drawingModel == NPDrawingModelInvalidatingCoreAnimation) {
387 : // We need to request CoreGraphics otherwise
388 : // the nsObjectFrame will try to draw a CALayer
389 : // that can not be shared across process.
390 : mDrawingModel = drawingModel;
391 : *result = mNPNIface->setvalue(mNPP, NPPVpluginDrawingModel,
392 : (void*)NPDrawingModelCoreGraphics);
393 : *shmem = null_t();
394 : } else
395 : #endif
396 0 : if (drawingModel == NPDrawingModelAsyncBitmapSurface) {
397 0 : ImageContainer *container = GetImageContainer();
398 0 : if (!container) {
399 0 : *result = NPERR_GENERIC_ERROR;
400 0 : return true;
401 : }
402 :
403 0 : mDrawingModel = drawingModel;
404 : *result = mNPNIface->setvalue(mNPP, NPPVpluginDrawingModel,
405 0 : (void*)drawingModel);
406 :
407 :
408 0 : if (*result != NPERR_NO_ERROR) {
409 0 : return true;
410 : }
411 :
412 0 : AllocUnsafeShmem(sizeof(RemoteImageData), SharedMemory::TYPE_BASIC, &mRemoteImageDataShmem);
413 :
414 0 : *shmem = mRemoteImageDataShmem;
415 :
416 0 : mRemoteImageDataMutex = new CrossProcessMutex("PluginInstanceParent.mRemoteImageDataMutex");
417 :
418 0 : *mutex = mRemoteImageDataMutex->ShareToProcess(OtherProcess());
419 0 : container->SetRemoteImageData(mRemoteImageDataShmem.get<RemoteImageData>(), mRemoteImageDataMutex);
420 :
421 0 : mNotifySink = new NotificationSink(this);
422 :
423 0 : container->SetCompositionNotifySink(mNotifySink);
424 0 : } else if (drawingModel == NPDrawingModelSyncWin ||
425 : #ifdef XP_MACOSX
426 : #ifndef NP_NO_QUICKDRAW
427 : drawingModel == NPDrawingModelQuickDraw ||
428 : #endif
429 : drawingModel == NPDrawingModelOpenGL ||
430 : drawingModel == NPDrawingModelCoreGraphics ||
431 : #endif
432 : drawingModel == NPDrawingModelSyncX) {
433 0 : *shmem = null_t();
434 :
435 0 : ImageContainer *container = GetImageContainer();
436 0 : if (!container) {
437 0 : *result = NPERR_GENERIC_ERROR;
438 0 : return true;
439 : }
440 :
441 0 : mDrawingModel = drawingModel;
442 : *result = mNPNIface->setvalue(mNPP, NPPVpluginDrawingModel,
443 0 : (void*)drawingModel);
444 :
445 0 : if (mRemoteImageDataShmem.IsWritable()) {
446 0 : container->SetRemoteImageData(nsnull, nsnull);
447 0 : container->SetCompositionNotifySink(nsnull);
448 0 : DeallocShmem(mRemoteImageDataShmem);
449 0 : mRemoteImageDataMutex = NULL;
450 0 : }
451 : } else {
452 0 : *result = NPERR_GENERIC_ERROR;
453 : }
454 0 : return true;
455 : }
456 :
457 : bool
458 0 : PluginInstanceParent::AnswerNPN_SetValue_NPPVpluginEventModel(
459 : const int& eventModel, NPError* result)
460 : {
461 : #ifdef XP_MACOSX
462 : *result = mNPNIface->setvalue(mNPP, NPPVpluginEventModel,
463 : (void*)eventModel);
464 : return true;
465 : #else
466 0 : *result = NPERR_GENERIC_ERROR;
467 0 : return true;
468 : #endif
469 : }
470 :
471 : bool
472 0 : PluginInstanceParent::AnswerNPN_GetURL(const nsCString& url,
473 : const nsCString& target,
474 : NPError* result)
475 : {
476 : *result = mNPNIface->geturl(mNPP,
477 : NullableStringGet(url),
478 0 : NullableStringGet(target));
479 0 : return true;
480 : }
481 :
482 : bool
483 0 : PluginInstanceParent::AnswerNPN_PostURL(const nsCString& url,
484 : const nsCString& target,
485 : const nsCString& buffer,
486 : const bool& file,
487 : NPError* result)
488 : {
489 : *result = mNPNIface->posturl(mNPP, url.get(), NullableStringGet(target),
490 0 : buffer.Length(), buffer.get(), file);
491 0 : return true;
492 : }
493 :
494 : PStreamNotifyParent*
495 0 : PluginInstanceParent::AllocPStreamNotify(const nsCString& url,
496 : const nsCString& target,
497 : const bool& post,
498 : const nsCString& buffer,
499 : const bool& file,
500 : NPError* result)
501 : {
502 0 : return new StreamNotifyParent();
503 : }
504 :
505 : bool
506 0 : PluginInstanceParent::AnswerPStreamNotifyConstructor(PStreamNotifyParent* actor,
507 : const nsCString& url,
508 : const nsCString& target,
509 : const bool& post,
510 : const nsCString& buffer,
511 : const bool& file,
512 : NPError* result)
513 : {
514 0 : bool streamDestroyed = false;
515 : static_cast<StreamNotifyParent*>(actor)->
516 0 : SetDestructionFlag(&streamDestroyed);
517 :
518 0 : if (!post) {
519 : *result = mNPNIface->geturlnotify(mNPP,
520 : NullableStringGet(url),
521 : NullableStringGet(target),
522 0 : actor);
523 : }
524 : else {
525 : *result = mNPNIface->posturlnotify(mNPP,
526 : NullableStringGet(url),
527 : NullableStringGet(target),
528 : buffer.Length(),
529 : NullableStringGet(buffer),
530 0 : file, actor);
531 : }
532 :
533 0 : if (streamDestroyed) {
534 : // If the stream was destroyed, we must return an error code in the
535 : // constructor.
536 0 : *result = NPERR_GENERIC_ERROR;
537 : }
538 : else {
539 0 : static_cast<StreamNotifyParent*>(actor)->ClearDestructionFlag();
540 0 : if (*result != NPERR_NO_ERROR)
541 : return PStreamNotifyParent::Send__delete__(actor,
542 0 : NPERR_GENERIC_ERROR);
543 : }
544 :
545 0 : return true;
546 : }
547 :
548 : bool
549 0 : PluginInstanceParent::DeallocPStreamNotify(PStreamNotifyParent* notifyData)
550 : {
551 0 : delete notifyData;
552 0 : return true;
553 : }
554 :
555 : bool
556 0 : PluginInstanceParent::RecvNPN_InvalidateRect(const NPRect& rect)
557 : {
558 0 : mNPNIface->invalidaterect(mNPP, const_cast<NPRect*>(&rect));
559 0 : return true;
560 : }
561 :
562 : bool
563 0 : PluginInstanceParent::RecvShow(const NPRect& updatedRect,
564 : const SurfaceDescriptor& newSurface,
565 : SurfaceDescriptor* prevSurface)
566 : {
567 0 : PLUGIN_LOG_DEBUG(
568 : ("[InstanceParent][%p] RecvShow for <x=%d,y=%d, w=%d,h=%d>",
569 : this, updatedRect.left, updatedRect.top,
570 : updatedRect.right - updatedRect.left,
571 : updatedRect.bottom - updatedRect.top));
572 :
573 0 : nsRefPtr<gfxASurface> surface;
574 0 : if (newSurface.type() == SurfaceDescriptor::TShmem) {
575 0 : if (!newSurface.get_Shmem().IsReadable()) {
576 0 : NS_WARNING("back surface not readable");
577 0 : return false;
578 : }
579 0 : surface = gfxSharedImageSurface::Open(newSurface.get_Shmem());
580 : }
581 : #ifdef XP_MACOSX
582 : else if (newSurface.type() == SurfaceDescriptor::TIOSurfaceDescriptor) {
583 : IOSurfaceDescriptor iodesc = newSurface.get_IOSurfaceDescriptor();
584 :
585 : nsRefPtr<nsIOSurface> newIOSurface = nsIOSurface::LookupSurface(iodesc.surfaceId());
586 :
587 : if (!newIOSurface) {
588 : NS_WARNING("Got bad IOSurfaceDescriptor in RecvShow");
589 : return false;
590 : }
591 :
592 : if (mFrontIOSurface)
593 : *prevSurface = IOSurfaceDescriptor(mFrontIOSurface->GetIOSurfaceID());
594 : else
595 : *prevSurface = null_t();
596 :
597 : mFrontIOSurface = newIOSurface;
598 :
599 : RecvNPN_InvalidateRect(updatedRect);
600 :
601 : PLUGIN_LOG_DEBUG((" (RecvShow invalidated for surface %p)",
602 : mFrontSurface.get()));
603 :
604 : return true;
605 : }
606 : #endif
607 : #ifdef MOZ_X11
608 0 : else if (newSurface.type() == SurfaceDescriptor::TSurfaceDescriptorX11) {
609 0 : surface = newSurface.get_SurfaceDescriptorX11().OpenForeign();
610 : }
611 : #endif
612 : #ifdef XP_WIN
613 : else if (newSurface.type() == SurfaceDescriptor::TPPluginSurfaceParent) {
614 : PluginSurfaceParent* s =
615 : static_cast<PluginSurfaceParent*>(newSurface.get_PPluginSurfaceParent());
616 : surface = s->Surface();
617 : }
618 : #endif
619 :
620 : #ifdef MOZ_X11
621 0 : if (mFrontSurface &&
622 0 : mFrontSurface->GetType() == gfxASurface::SurfaceTypeXlib)
623 : // This is the "old front buffer" we're about to hand back to
624 : // the plugin. We might still have drawing operations
625 : // referencing it, so we XSync here to let them finish before
626 : // the plugin starts scribbling on it again, or worse,
627 : // destroys it.
628 0 : XSync(DefaultXDisplay(), False);
629 : #endif
630 :
631 0 : if (mFrontSurface && gfxSharedImageSurface::IsSharedImage(mFrontSurface))
632 0 : *prevSurface = static_cast<gfxSharedImageSurface*>(mFrontSurface.get())->GetShmem();
633 : else
634 0 : *prevSurface = null_t();
635 :
636 0 : if (surface) {
637 : // Notify the cairo backend that this surface has changed behind
638 : // its back.
639 : gfxRect ur(updatedRect.left, updatedRect.top,
640 : updatedRect.right - updatedRect.left,
641 0 : updatedRect.bottom - updatedRect.top);
642 0 : surface->MarkDirty(ur);
643 0 : surface->Flush();
644 : }
645 :
646 0 : mFrontSurface = surface;
647 0 : RecvNPN_InvalidateRect(updatedRect);
648 :
649 0 : PLUGIN_LOG_DEBUG((" (RecvShow invalidated for surface %p)",
650 : mFrontSurface.get()));
651 :
652 0 : return true;
653 : }
654 :
655 : nsresult
656 0 : PluginInstanceParent::AsyncSetWindow(NPWindow* aWindow)
657 : {
658 0 : NPRemoteWindow window;
659 0 : mWindowType = aWindow->type;
660 0 : window.window = reinterpret_cast<uint64_t>(aWindow->window);
661 0 : window.x = aWindow->x;
662 0 : window.y = aWindow->y;
663 0 : window.width = aWindow->width;
664 0 : window.height = aWindow->height;
665 0 : window.clipRect = aWindow->clipRect;
666 0 : window.type = aWindow->type;
667 0 : if (!SendAsyncSetWindow(gfxPlatform::GetPlatform()->ScreenReferenceSurface()->GetType(),
668 0 : window))
669 0 : return NS_ERROR_FAILURE;
670 :
671 0 : return NS_OK;
672 : }
673 :
674 : #if defined(MOZ_WIDGET_QT) && (MOZ_PLATFORM_MAEMO == 6)
675 : nsresult
676 : PluginInstanceParent::HandleGUIEvent(const nsGUIEvent& anEvent, bool* handled)
677 : {
678 : switch (anEvent.eventStructType) {
679 : case NS_KEY_EVENT:
680 : if (!CallHandleKeyEvent(static_cast<const nsKeyEvent&>(anEvent),
681 : handled)) {
682 : return NS_ERROR_FAILURE;
683 : }
684 : break;
685 : case NS_TEXT_EVENT:
686 : if (!CallHandleTextEvent(static_cast<const nsTextEvent&>(anEvent),
687 : handled)) {
688 : return NS_ERROR_FAILURE;
689 : }
690 : break;
691 : default:
692 : NS_ERROR("Not implemented for this event type");
693 : return NS_ERROR_FAILURE;
694 : }
695 : return NS_OK;
696 : }
697 : #endif
698 :
699 : nsresult
700 0 : PluginInstanceParent::GetImageContainer(ImageContainer** aContainer)
701 : {
702 : #ifdef XP_MACOSX
703 : nsIOSurface* ioSurface = NULL;
704 :
705 : if (mFrontIOSurface) {
706 : ioSurface = mFrontIOSurface;
707 : } else if (mIOSurface) {
708 : ioSurface = mIOSurface;
709 : }
710 :
711 : if (!mFrontSurface && !ioSurface)
712 : #else
713 0 : if (!mFrontSurface)
714 : #endif
715 0 : return NS_ERROR_NOT_AVAILABLE;
716 :
717 0 : Image::Format format = Image::CAIRO_SURFACE;
718 : #ifdef XP_MACOSX
719 : if (ioSurface) {
720 : format = Image::MAC_IO_SURFACE;
721 : }
722 : #endif
723 :
724 0 : ImageContainer *container = GetImageContainer();
725 :
726 0 : if (!container) {
727 0 : return NS_ERROR_FAILURE;
728 : }
729 :
730 0 : if (IsAsyncDrawing()) {
731 0 : NS_IF_ADDREF(container);
732 0 : *aContainer = container;
733 0 : return NS_OK;
734 : }
735 :
736 0 : nsRefPtr<Image> image;
737 0 : image = container->CreateImage(&format, 1);
738 0 : if (!image) {
739 0 : return NS_ERROR_FAILURE;
740 : }
741 :
742 : #ifdef XP_MACOSX
743 : if (ioSurface) {
744 : NS_ASSERTION(image->GetFormat() == Image::MAC_IO_SURFACE, "Wrong format?");
745 : MacIOSurfaceImage* ioImage = static_cast<MacIOSurfaceImage*>(image.get());
746 : MacIOSurfaceImage::Data ioData;
747 : ioData.mIOSurface = ioSurface;
748 : ioImage->SetData(ioData);
749 : container->SetCurrentImage(ioImage);
750 :
751 : NS_IF_ADDREF(container);
752 : *aContainer = container;
753 : return NS_OK;
754 : }
755 : #endif
756 :
757 0 : NS_ASSERTION(image->GetFormat() == Image::CAIRO_SURFACE, "Wrong format?");
758 0 : CairoImage* pluginImage = static_cast<CairoImage*>(image.get());
759 0 : CairoImage::Data cairoData;
760 0 : cairoData.mSurface = mFrontSurface;
761 0 : cairoData.mSize = mFrontSurface->GetSize();
762 0 : pluginImage->SetData(cairoData);
763 :
764 0 : container->SetCurrentImage(pluginImage);
765 :
766 0 : NS_IF_ADDREF(container);
767 0 : *aContainer = container;
768 0 : return NS_OK;
769 : }
770 :
771 : nsresult
772 0 : PluginInstanceParent::GetImageSize(nsIntSize* aSize)
773 : {
774 0 : if (mFrontSurface) {
775 0 : gfxIntSize size = mFrontSurface->GetSize();
776 0 : *aSize = nsIntSize(size.width, size.height);
777 0 : return NS_OK;
778 : }
779 :
780 : #ifdef XP_MACOSX
781 : if (mFrontIOSurface) {
782 : *aSize = nsIntSize(mFrontIOSurface->GetWidth(), mFrontIOSurface->GetHeight());
783 : return NS_OK;
784 : } else if (mIOSurface) {
785 : *aSize = nsIntSize(mIOSurface->GetWidth(), mIOSurface->GetHeight());
786 : return NS_OK;
787 : }
788 : #endif
789 :
790 0 : return NS_ERROR_NOT_AVAILABLE;
791 : }
792 :
793 : #ifdef XP_MACOSX
794 : nsresult
795 : PluginInstanceParent::IsRemoteDrawingCoreAnimation(bool *aDrawing)
796 : {
797 : *aDrawing = (NPDrawingModelCoreAnimation == (NPDrawingModel)mDrawingModel ||
798 : NPDrawingModelInvalidatingCoreAnimation == (NPDrawingModel)mDrawingModel);
799 : return NS_OK;
800 : }
801 : #endif
802 :
803 : nsresult
804 0 : PluginInstanceParent::SetBackgroundUnknown()
805 : {
806 0 : PLUGIN_LOG_DEBUG(("[InstanceParent][%p] SetBackgroundUnknown", this));
807 :
808 0 : if (mBackground) {
809 0 : DestroyBackground();
810 0 : NS_ABORT_IF_FALSE(!mBackground, "Background not destroyed");
811 : }
812 :
813 0 : return NS_OK;
814 : }
815 :
816 : nsresult
817 0 : PluginInstanceParent::BeginUpdateBackground(const nsIntRect& aRect,
818 : gfxContext** aCtx)
819 : {
820 0 : PLUGIN_LOG_DEBUG(
821 : ("[InstanceParent][%p] BeginUpdateBackground for <x=%d,y=%d, w=%d,h=%d>",
822 : this, aRect.x, aRect.y, aRect.width, aRect.height));
823 :
824 0 : if (!mBackground) {
825 : // XXX if we failed to create a background surface on one
826 : // update, there's no guarantee that later updates will be for
827 : // the entire background area until successful. We might want
828 : // to fix that eventually.
829 0 : NS_ABORT_IF_FALSE(aRect.TopLeft() == nsIntPoint(0, 0),
830 : "Expecting rect for whole frame");
831 0 : if (!CreateBackground(aRect.Size())) {
832 0 : *aCtx = nsnull;
833 0 : return NS_OK;
834 : }
835 : }
836 :
837 : #ifdef DEBUG
838 0 : gfxIntSize sz = mBackground->GetSize();
839 0 : NS_ABORT_IF_FALSE(nsIntRect(0, 0, sz.width, sz.height).Contains(aRect),
840 : "Update outside of background area");
841 : #endif
842 :
843 0 : nsRefPtr<gfxContext> ctx = new gfxContext(mBackground);
844 0 : *aCtx = ctx.forget().get();
845 :
846 0 : return NS_OK;
847 : }
848 :
849 : nsresult
850 0 : PluginInstanceParent::EndUpdateBackground(gfxContext* aCtx,
851 : const nsIntRect& aRect)
852 : {
853 0 : PLUGIN_LOG_DEBUG(
854 : ("[InstanceParent][%p] EndUpdateBackground for <x=%d,y=%d, w=%d,h=%d>",
855 : this, aRect.x, aRect.y, aRect.width, aRect.height));
856 :
857 : #ifdef MOZ_X11
858 : // Have to XSync here to avoid the plugin trying to draw with this
859 : // surface racing with its creation in the X server. We also want
860 : // to avoid the plugin drawing onto stale pixels, then handing us
861 : // back a front surface from those pixels that we might
862 : // recomposite for "a while" until the next update. This XSync
863 : // still doesn't guarantee that the plugin draws onto a consistent
864 : // view of its background, but it does mean that the plugin is
865 : // drawing onto pixels no older than those in the latest
866 : // EndUpdateBackground().
867 0 : XSync(DefaultXDisplay(), False);
868 : #endif
869 :
870 0 : unused << SendUpdateBackground(BackgroundDescriptor(), aRect);
871 :
872 0 : return NS_OK;
873 : }
874 :
875 : bool
876 0 : PluginInstanceParent::CreateBackground(const nsIntSize& aSize)
877 : {
878 0 : NS_ABORT_IF_FALSE(!mBackground, "Already have a background");
879 :
880 : // XXX refactor me
881 :
882 : #if defined(MOZ_X11)
883 0 : Screen* screen = DefaultScreenOfDisplay(DefaultXDisplay());
884 0 : Visual* visual = DefaultVisualOfScreen(screen);
885 : mBackground = gfxXlibSurface::Create(screen, visual,
886 0 : gfxIntSize(aSize.width, aSize.height));
887 0 : return !!mBackground;
888 :
889 : #elif defined(XP_WIN)
890 : // We have chosen to create an unsafe surface in which the plugin
891 : // can read from the region while we're writing to it.
892 : mBackground =
893 : gfxSharedImageSurface::CreateUnsafe(
894 : this,
895 : gfxIntSize(aSize.width, aSize.height),
896 : gfxASurface::ImageFormatRGB24);
897 : return !!mBackground;
898 : #else
899 : return nsnull;
900 : #endif
901 : }
902 :
903 : void
904 0 : PluginInstanceParent::DestroyBackground()
905 : {
906 0 : if (!mBackground) {
907 0 : return;
908 : }
909 :
910 : // Relinquish ownership of |mBackground| to its destroyer
911 : PPluginBackgroundDestroyerParent* pbd =
912 0 : new PluginBackgroundDestroyerParent(mBackground);
913 0 : mBackground = nsnull;
914 :
915 : // If this fails, there's no problem: |bd| will be destroyed along
916 : // with the old background surface.
917 0 : unused << SendPPluginBackgroundDestroyerConstructor(pbd);
918 : }
919 :
920 : SurfaceDescriptor
921 0 : PluginInstanceParent::BackgroundDescriptor()
922 : {
923 0 : NS_ABORT_IF_FALSE(mBackground, "Need a background here");
924 :
925 : // XXX refactor me
926 :
927 : #ifdef MOZ_X11
928 0 : gfxXlibSurface* xsurf = static_cast<gfxXlibSurface*>(mBackground.get());
929 0 : return SurfaceDescriptorX11(xsurf);
930 : #endif
931 :
932 : #ifdef XP_WIN
933 : NS_ABORT_IF_FALSE(gfxSharedImageSurface::IsSharedImage(mBackground),
934 : "Expected shared image surface");
935 : gfxSharedImageSurface* shmem =
936 : static_cast<gfxSharedImageSurface*>(mBackground.get());
937 : return shmem->GetShmem();
938 : #endif
939 :
940 : // If this is ever used, which it shouldn't be, it will trigger a
941 : // hard assertion in IPDL-generated code.
942 : return SurfaceDescriptor();
943 : }
944 :
945 : ImageContainer*
946 0 : PluginInstanceParent::GetImageContainer()
947 : {
948 0 : if (mImageContainer) {
949 0 : return mImageContainer;
950 : }
951 :
952 0 : mImageContainer = LayerManager::CreateImageContainer();
953 0 : return mImageContainer;
954 : }
955 :
956 : PPluginBackgroundDestroyerParent*
957 0 : PluginInstanceParent::AllocPPluginBackgroundDestroyer()
958 : {
959 0 : NS_RUNTIMEABORT("'Power-user' ctor is used exclusively");
960 0 : return nsnull;
961 : }
962 :
963 : bool
964 0 : PluginInstanceParent::DeallocPPluginBackgroundDestroyer(
965 : PPluginBackgroundDestroyerParent* aActor)
966 : {
967 0 : delete aActor;
968 0 : return true;
969 : }
970 :
971 : NPError
972 0 : PluginInstanceParent::NPP_SetWindow(const NPWindow* aWindow)
973 : {
974 0 : PLUGIN_LOG_DEBUG(("%s (aWindow=%p)", FULLFUNCTION, (void*) aWindow));
975 :
976 0 : NS_ENSURE_TRUE(aWindow, NPERR_GENERIC_ERROR);
977 :
978 0 : NPRemoteWindow window;
979 0 : mWindowType = aWindow->type;
980 :
981 : #if defined(OS_WIN)
982 : // On windowless controls, reset the shared memory surface as needed.
983 : if (mWindowType == NPWindowTypeDrawable) {
984 : // SharedSurfaceSetWindow will take care of NPRemoteWindow.
985 : if (!SharedSurfaceSetWindow(aWindow, window)) {
986 : return NPERR_OUT_OF_MEMORY_ERROR;
987 : }
988 : }
989 : else {
990 : SubclassPluginWindow(reinterpret_cast<HWND>(aWindow->window));
991 :
992 : window.window = reinterpret_cast<uint64_t>(aWindow->window);
993 : window.x = aWindow->x;
994 : window.y = aWindow->y;
995 : window.width = aWindow->width;
996 : window.height = aWindow->height;
997 : window.type = aWindow->type;
998 : }
999 : #else
1000 0 : window.window = reinterpret_cast<uint64_t>(aWindow->window);
1001 0 : window.x = aWindow->x;
1002 0 : window.y = aWindow->y;
1003 0 : window.width = aWindow->width;
1004 0 : window.height = aWindow->height;
1005 0 : window.clipRect = aWindow->clipRect; // MacOS specific
1006 0 : window.type = aWindow->type;
1007 : #endif
1008 :
1009 : #if defined(XP_MACOSX)
1010 : if (mShWidth != window.width || mShHeight != window.height) {
1011 : if (mDrawingModel == NPDrawingModelCoreAnimation ||
1012 : mDrawingModel == NPDrawingModelInvalidatingCoreAnimation) {
1013 : mIOSurface = nsIOSurface::CreateIOSurface(window.width, window.height);
1014 : } else if (mShWidth * mShHeight != window.width * window.height) {
1015 : if (mShWidth != 0 && mShHeight != 0) {
1016 : DeallocShmem(mShSurface);
1017 : mShWidth = 0;
1018 : mShHeight = 0;
1019 : }
1020 :
1021 : if (window.width != 0 && window.height != 0) {
1022 : if (!AllocShmem(window.width * window.height*4,
1023 : SharedMemory::TYPE_BASIC, &mShSurface)) {
1024 : PLUGIN_LOG_DEBUG(("Shared memory could not be allocated."));
1025 : return NPERR_GENERIC_ERROR;
1026 : }
1027 : }
1028 : }
1029 : mShWidth = window.width;
1030 : mShHeight = window.height;
1031 : }
1032 : #endif
1033 :
1034 : #if defined(MOZ_X11) && defined(XP_UNIX) && !defined(XP_MACOSX)
1035 : const NPSetWindowCallbackStruct* ws_info =
1036 0 : static_cast<NPSetWindowCallbackStruct*>(aWindow->ws_info);
1037 0 : window.visualID = ws_info->visual ? ws_info->visual->visualid : None;
1038 0 : window.colormap = ws_info->colormap;
1039 : #endif
1040 :
1041 0 : if (!CallNPP_SetWindow(window))
1042 0 : return NPERR_GENERIC_ERROR;
1043 :
1044 0 : return NPERR_NO_ERROR;
1045 : }
1046 :
1047 : NPError
1048 0 : PluginInstanceParent::NPP_GetValue(NPPVariable aVariable,
1049 : void* _retval)
1050 : {
1051 0 : switch (aVariable) {
1052 :
1053 : case NPPVpluginWantsAllNetworkStreams: {
1054 : bool wantsAllStreams;
1055 : NPError rv;
1056 :
1057 0 : if (!CallNPP_GetValue_NPPVpluginWantsAllNetworkStreams(&wantsAllStreams, &rv)) {
1058 0 : return NPERR_GENERIC_ERROR;
1059 : }
1060 :
1061 0 : if (NPERR_NO_ERROR != rv) {
1062 0 : return rv;
1063 : }
1064 :
1065 0 : (*(NPBool*)_retval) = wantsAllStreams;
1066 0 : return NPERR_NO_ERROR;
1067 : }
1068 :
1069 : #ifdef MOZ_X11
1070 : case NPPVpluginNeedsXEmbed: {
1071 : bool needsXEmbed;
1072 : NPError rv;
1073 :
1074 0 : if (!CallNPP_GetValue_NPPVpluginNeedsXEmbed(&needsXEmbed, &rv)) {
1075 0 : return NPERR_GENERIC_ERROR;
1076 : }
1077 :
1078 0 : if (NPERR_NO_ERROR != rv) {
1079 0 : return rv;
1080 : }
1081 :
1082 0 : (*(NPBool*)_retval) = needsXEmbed;
1083 0 : return NPERR_NO_ERROR;
1084 : }
1085 : #endif
1086 :
1087 : case NPPVpluginScriptableNPObject: {
1088 : PPluginScriptableObjectParent* actor;
1089 : NPError rv;
1090 0 : if (!CallNPP_GetValue_NPPVpluginScriptableNPObject(&actor, &rv)) {
1091 0 : return NPERR_GENERIC_ERROR;
1092 : }
1093 :
1094 0 : if (NPERR_NO_ERROR != rv) {
1095 0 : return rv;
1096 : }
1097 :
1098 0 : if (!actor) {
1099 0 : NS_ERROR("NPPVpluginScriptableNPObject succeeded but null.");
1100 0 : return NPERR_GENERIC_ERROR;
1101 : }
1102 :
1103 0 : const NPNetscapeFuncs* npn = mParent->GetNetscapeFuncs();
1104 0 : if (!npn) {
1105 0 : NS_WARNING("No netscape functions?!");
1106 0 : return NPERR_GENERIC_ERROR;
1107 : }
1108 :
1109 : NPObject* object =
1110 0 : static_cast<PluginScriptableObjectParent*>(actor)->GetObject(true);
1111 0 : NS_ASSERTION(object, "This shouldn't ever be null!");
1112 :
1113 0 : (*(NPObject**)_retval) = npn->retainobject(object);
1114 0 : return NPERR_NO_ERROR;
1115 : }
1116 :
1117 : #ifdef MOZ_ACCESSIBILITY_ATK
1118 : case NPPVpluginNativeAccessibleAtkPlugId: {
1119 0 : nsCString plugId;
1120 : NPError rv;
1121 0 : if (!CallNPP_GetValue_NPPVpluginNativeAccessibleAtkPlugId(&plugId, &rv)) {
1122 0 : return NPERR_GENERIC_ERROR;
1123 : }
1124 :
1125 0 : if (NPERR_NO_ERROR != rv) {
1126 0 : return rv;
1127 : }
1128 :
1129 0 : (*(nsCString*)_retval) = plugId;
1130 0 : return NPERR_NO_ERROR;
1131 : }
1132 : #endif
1133 :
1134 : default:
1135 0 : PR_LOG(gPluginLog, PR_LOG_WARNING,
1136 : ("In PluginInstanceParent::NPP_GetValue: Unhandled NPPVariable %i (%s)",
1137 : (int) aVariable, NPPVariableToString(aVariable)));
1138 0 : return NPERR_GENERIC_ERROR;
1139 : }
1140 : }
1141 :
1142 : NPError
1143 0 : PluginInstanceParent::NPP_SetValue(NPNVariable variable, void* value)
1144 : {
1145 0 : switch (variable) {
1146 : case NPNVprivateModeBool:
1147 : NPError result;
1148 0 : if (!CallNPP_SetValue_NPNVprivateModeBool(*static_cast<NPBool*>(value),
1149 0 : &result))
1150 0 : return NPERR_GENERIC_ERROR;
1151 :
1152 0 : return result;
1153 :
1154 : default:
1155 0 : NS_ERROR("Unhandled NPNVariable in NPP_SetValue");
1156 0 : PR_LOG(gPluginLog, PR_LOG_WARNING,
1157 : ("In PluginInstanceParent::NPP_SetValue: Unhandled NPNVariable %i (%s)",
1158 : (int) variable, NPNVariableToString(variable)));
1159 0 : return NPERR_GENERIC_ERROR;
1160 : }
1161 : }
1162 :
1163 : void
1164 0 : PluginInstanceParent::NPP_URLRedirectNotify(const char* url, int32_t status,
1165 : void* notifyData)
1166 : {
1167 0 : if (!notifyData)
1168 0 : return;
1169 :
1170 0 : PStreamNotifyParent* streamNotify = static_cast<PStreamNotifyParent*>(notifyData);
1171 0 : unused << streamNotify->SendRedirectNotify(NullableString(url), status);
1172 : }
1173 :
1174 : int16_t
1175 0 : PluginInstanceParent::NPP_HandleEvent(void* event)
1176 : {
1177 0 : PLUGIN_LOG_DEBUG_FUNCTION;
1178 :
1179 : #if defined(XP_MACOSX)
1180 : NPCocoaEvent* npevent = reinterpret_cast<NPCocoaEvent*>(event);
1181 : #else
1182 0 : NPEvent* npevent = reinterpret_cast<NPEvent*>(event);
1183 : #endif
1184 : NPRemoteEvent npremoteevent;
1185 0 : npremoteevent.event = *npevent;
1186 0 : int16_t handled = 0;
1187 :
1188 : #if defined(OS_WIN)
1189 : if (mWindowType == NPWindowTypeDrawable) {
1190 : if (IsAsyncDrawing()) {
1191 : if (npevent->event == WM_PAINT || npevent->event == DoublePassRenderingEvent()) {
1192 : // This plugin maintains its own async drawing.
1193 : return handled;
1194 : }
1195 : }
1196 : if (DoublePassRenderingEvent() == npevent->event) {
1197 : CallPaint(npremoteevent, &handled);
1198 : return handled;
1199 : }
1200 :
1201 : switch (npevent->event) {
1202 : case WM_PAINT:
1203 : {
1204 : RECT rect;
1205 : SharedSurfaceBeforePaint(rect, npremoteevent);
1206 : CallPaint(npremoteevent, &handled);
1207 : SharedSurfaceAfterPaint(npevent);
1208 : return handled;
1209 : }
1210 : break;
1211 :
1212 : case WM_KILLFOCUS:
1213 : {
1214 : // When the user selects fullscreen mode in Flash video players,
1215 : // WM_KILLFOCUS will be delayed by deferred event processing:
1216 : // WM_LBUTTONUP results in a call to CreateWindow within Flash,
1217 : // which fires WM_KILLFOCUS. Delayed delivery causes Flash to
1218 : // misinterpret the event, dropping back out of fullscreen. Trap
1219 : // this event and drop it.
1220 : PRUnichar szClass[26];
1221 : HWND hwnd = GetForegroundWindow();
1222 : if (hwnd && hwnd != mPluginHWND &&
1223 : GetClassNameW(hwnd, szClass,
1224 : sizeof(szClass)/sizeof(PRUnichar)) &&
1225 : !wcscmp(szClass, kFlashFullscreenClass)) {
1226 : return 0;
1227 : }
1228 : }
1229 : break;
1230 :
1231 : case WM_WINDOWPOSCHANGED:
1232 : {
1233 : // We send this in nsObjectFrame just before painting
1234 : SendWindowPosChanged(npremoteevent);
1235 : // nsObjectFrame doesn't care whether we handle this
1236 : // or not, just returning 1 for good hygiene
1237 : return 1;
1238 : }
1239 : break;
1240 : }
1241 : }
1242 : #endif
1243 :
1244 : #if defined(MOZ_X11)
1245 0 : switch (npevent->type) {
1246 : case GraphicsExpose:
1247 0 : PLUGIN_LOG_DEBUG((" schlepping drawable 0x%lx across the pipe\n",
1248 : npevent->xgraphicsexpose.drawable));
1249 : // Make sure the X server has created the Drawable and completes any
1250 : // drawing before the plugin draws on top.
1251 : //
1252 : // XSync() waits for the X server to complete. Really this parent
1253 : // process does not need to wait; the child is the process that needs
1254 : // to wait. A possibly-slightly-better alternative would be to send
1255 : // an X event to the child that the child would wait for.
1256 0 : XSync(DefaultXDisplay(), False);
1257 :
1258 0 : return CallPaint(npremoteevent, &handled) ? handled : 0;
1259 :
1260 : case ButtonPress:
1261 : // Release any active pointer grab so that the plugin X client can
1262 : // grab the pointer if it wishes.
1263 0 : Display *dpy = DefaultXDisplay();
1264 : # ifdef MOZ_WIDGET_GTK2
1265 : // GDK attempts to (asynchronously) track whether there is an active
1266 : // grab so ungrab through GDK.
1267 0 : gdk_pointer_ungrab(npevent->xbutton.time);
1268 : # else
1269 : XUngrabPointer(dpy, npevent->xbutton.time);
1270 : # endif
1271 : // Wait for the ungrab to complete.
1272 0 : XSync(dpy, False);
1273 0 : break;
1274 : }
1275 : #endif
1276 :
1277 : #ifdef XP_MACOSX
1278 : if (npevent->type == NPCocoaEventDrawRect) {
1279 : if (mDrawingModel == NPDrawingModelCoreAnimation ||
1280 : mDrawingModel == NPDrawingModelInvalidatingCoreAnimation) {
1281 : if (!mIOSurface) {
1282 : NS_ERROR("No IOSurface allocated.");
1283 : return false;
1284 : }
1285 : if (!CallNPP_HandleEvent_IOSurface(npremoteevent,
1286 : mIOSurface->GetIOSurfaceID(),
1287 : &handled))
1288 : return false; // no good way to handle errors here...
1289 :
1290 : CGContextRef cgContext = npevent->data.draw.context;
1291 : if (!mShColorSpace) {
1292 : mShColorSpace = CreateSystemColorSpace();
1293 : }
1294 : if (!mShColorSpace) {
1295 : PLUGIN_LOG_DEBUG(("Could not allocate ColorSpace."));
1296 : return false;
1297 : }
1298 : if (cgContext) {
1299 : nsCARenderer::DrawSurfaceToCGContext(cgContext, mIOSurface,
1300 : mShColorSpace,
1301 : npevent->data.draw.x,
1302 : npevent->data.draw.y,
1303 : npevent->data.draw.width,
1304 : npevent->data.draw.height);
1305 : }
1306 : return true;
1307 : } else if (mFrontIOSurface) {
1308 : CGContextRef cgContext = npevent->data.draw.context;
1309 : if (!mShColorSpace) {
1310 : mShColorSpace = CreateSystemColorSpace();
1311 : }
1312 : if (!mShColorSpace) {
1313 : PLUGIN_LOG_DEBUG(("Could not allocate ColorSpace."));
1314 : return false;
1315 : }
1316 : if (cgContext) {
1317 : nsCARenderer::DrawSurfaceToCGContext(cgContext, mFrontIOSurface,
1318 : mShColorSpace,
1319 : npevent->data.draw.x,
1320 : npevent->data.draw.y,
1321 : npevent->data.draw.width,
1322 : npevent->data.draw.height);
1323 : }
1324 : return true;
1325 : } else {
1326 : if (mShWidth == 0 && mShHeight == 0) {
1327 : PLUGIN_LOG_DEBUG(("NPCocoaEventDrawRect on window of size 0."));
1328 : return false;
1329 : }
1330 : if (!mShSurface.IsReadable()) {
1331 : PLUGIN_LOG_DEBUG(("Shmem is not readable."));
1332 : return false;
1333 : }
1334 :
1335 : if (!CallNPP_HandleEvent_Shmem(npremoteevent, mShSurface,
1336 : &handled, &mShSurface))
1337 : return false; // no good way to handle errors here...
1338 :
1339 : if (!mShSurface.IsReadable()) {
1340 : PLUGIN_LOG_DEBUG(("Shmem not returned. Either the plugin crashed "
1341 : "or we have a bug."));
1342 : return false;
1343 : }
1344 :
1345 : char* shContextByte = mShSurface.get<char>();
1346 :
1347 : if (!mShColorSpace) {
1348 : mShColorSpace = CreateSystemColorSpace();
1349 : }
1350 : if (!mShColorSpace) {
1351 : PLUGIN_LOG_DEBUG(("Could not allocate ColorSpace."));
1352 : return false;
1353 : }
1354 : CGContextRef shContext = ::CGBitmapContextCreate(shContextByte,
1355 : mShWidth, mShHeight, 8,
1356 : mShWidth*4, mShColorSpace,
1357 : kCGImageAlphaPremultipliedFirst |
1358 : kCGBitmapByteOrder32Host);
1359 : if (!shContext) {
1360 : PLUGIN_LOG_DEBUG(("Could not allocate CGBitmapContext."));
1361 : return false;
1362 : }
1363 :
1364 : CGImageRef shImage = ::CGBitmapContextCreateImage(shContext);
1365 : if (shImage) {
1366 : CGContextRef cgContext = npevent->data.draw.context;
1367 :
1368 : ::CGContextDrawImage(cgContext,
1369 : CGRectMake(0,0,mShWidth,mShHeight),
1370 : shImage);
1371 : ::CGImageRelease(shImage);
1372 : } else {
1373 : ::CGContextRelease(shContext);
1374 : return false;
1375 : }
1376 : ::CGContextRelease(shContext);
1377 : return true;
1378 : }
1379 : }
1380 : #endif
1381 :
1382 0 : if (!CallNPP_HandleEvent(npremoteevent, &handled))
1383 0 : return 0; // no good way to handle errors here...
1384 :
1385 0 : return handled;
1386 : }
1387 :
1388 : NPError
1389 0 : PluginInstanceParent::NPP_NewStream(NPMIMEType type, NPStream* stream,
1390 : NPBool seekable, uint16_t* stype)
1391 : {
1392 0 : PLUGIN_LOG_DEBUG(("%s (type=%s, stream=%p, seekable=%i)",
1393 : FULLFUNCTION, (char*) type, (void*) stream, (int) seekable));
1394 :
1395 0 : BrowserStreamParent* bs = new BrowserStreamParent(this, stream);
1396 :
1397 : NPError err;
1398 0 : if (!CallPBrowserStreamConstructor(bs,
1399 0 : NullableString(stream->url),
1400 : stream->end,
1401 : stream->lastmodified,
1402 : static_cast<PStreamNotifyParent*>(stream->notifyData),
1403 0 : NullableString(stream->headers),
1404 0 : NullableString(type), seekable,
1405 0 : &err, stype))
1406 0 : return NPERR_GENERIC_ERROR;
1407 :
1408 0 : if (NPERR_NO_ERROR != err)
1409 0 : unused << PBrowserStreamParent::Send__delete__(bs);
1410 :
1411 0 : return err;
1412 : }
1413 :
1414 : NPError
1415 0 : PluginInstanceParent::NPP_DestroyStream(NPStream* stream, NPReason reason)
1416 : {
1417 0 : PLUGIN_LOG_DEBUG(("%s (stream=%p, reason=%i)",
1418 : FULLFUNCTION, (void*) stream, (int) reason));
1419 :
1420 0 : AStream* s = static_cast<AStream*>(stream->pdata);
1421 0 : if (s->IsBrowserStream()) {
1422 : BrowserStreamParent* sp =
1423 0 : static_cast<BrowserStreamParent*>(s);
1424 0 : if (sp->mNPP != this)
1425 0 : NS_RUNTIMEABORT("Mismatched plugin data");
1426 :
1427 0 : sp->NPP_DestroyStream(reason);
1428 0 : return NPERR_NO_ERROR;
1429 : }
1430 : else {
1431 : PluginStreamParent* sp =
1432 0 : static_cast<PluginStreamParent*>(s);
1433 0 : if (sp->mInstance != this)
1434 0 : NS_RUNTIMEABORT("Mismatched plugin data");
1435 :
1436 0 : return PPluginStreamParent::Call__delete__(sp, reason, false) ?
1437 0 : NPERR_NO_ERROR : NPERR_GENERIC_ERROR;
1438 : }
1439 : }
1440 :
1441 : void
1442 0 : PluginInstanceParent::NPP_Print(NPPrint* platformPrint)
1443 : {
1444 : // TODO: implement me
1445 0 : NS_ERROR("Not implemented");
1446 0 : }
1447 :
1448 : PPluginScriptableObjectParent*
1449 0 : PluginInstanceParent::AllocPPluginScriptableObject()
1450 : {
1451 0 : return new PluginScriptableObjectParent(Proxy);
1452 : }
1453 :
1454 : #ifdef DEBUG
1455 : namespace {
1456 :
1457 : struct ActorSearchData
1458 : {
1459 : PluginScriptableObjectParent* actor;
1460 : bool found;
1461 : };
1462 :
1463 : PLDHashOperator
1464 0 : ActorSearch(const void* aKey,
1465 : PluginScriptableObjectParent* aData,
1466 : void* aUserData)
1467 : {
1468 0 : ActorSearchData* asd = reinterpret_cast<ActorSearchData*>(aUserData);
1469 0 : if (asd->actor == aData) {
1470 0 : asd->found = true;
1471 0 : return PL_DHASH_STOP;
1472 : }
1473 0 : return PL_DHASH_NEXT;
1474 : }
1475 :
1476 : } // anonymous namespace
1477 : #endif // DEBUG
1478 :
1479 : bool
1480 0 : PluginInstanceParent::DeallocPPluginScriptableObject(
1481 : PPluginScriptableObjectParent* aObject)
1482 : {
1483 : PluginScriptableObjectParent* actor =
1484 0 : static_cast<PluginScriptableObjectParent*>(aObject);
1485 :
1486 0 : NPObject* object = actor->GetObject(false);
1487 0 : if (object) {
1488 0 : NS_ASSERTION(mScriptableObjects.Get(object, nsnull),
1489 : "NPObject not in the hash!");
1490 0 : mScriptableObjects.Remove(object);
1491 : }
1492 : #ifdef DEBUG
1493 : else {
1494 0 : ActorSearchData asd = { actor, false };
1495 0 : mScriptableObjects.EnumerateRead(ActorSearch, &asd);
1496 0 : NS_ASSERTION(!asd.found, "Actor in the hash with a null NPObject!");
1497 : }
1498 : #endif
1499 :
1500 0 : delete actor;
1501 0 : return true;
1502 : }
1503 :
1504 : bool
1505 0 : PluginInstanceParent::RecvPPluginScriptableObjectConstructor(
1506 : PPluginScriptableObjectParent* aActor)
1507 : {
1508 : // This is only called in response to the child process requesting the
1509 : // creation of an actor. This actor will represent an NPObject that is
1510 : // created by the plugin and returned to the browser.
1511 : PluginScriptableObjectParent* actor =
1512 0 : static_cast<PluginScriptableObjectParent*>(aActor);
1513 0 : NS_ASSERTION(!actor->GetObject(false), "Actor already has an object?!");
1514 :
1515 0 : actor->InitializeProxy();
1516 0 : NS_ASSERTION(actor->GetObject(false), "Actor should have an object!");
1517 :
1518 0 : return true;
1519 : }
1520 :
1521 : void
1522 0 : PluginInstanceParent::NPP_URLNotify(const char* url, NPReason reason,
1523 : void* notifyData)
1524 : {
1525 0 : PLUGIN_LOG_DEBUG(("%s (%s, %i, %p)",
1526 : FULLFUNCTION, url, (int) reason, notifyData));
1527 :
1528 : PStreamNotifyParent* streamNotify =
1529 0 : static_cast<PStreamNotifyParent*>(notifyData);
1530 0 : unused << PStreamNotifyParent::Send__delete__(streamNotify, reason);
1531 0 : }
1532 :
1533 : bool
1534 0 : PluginInstanceParent::RegisterNPObjectForActor(
1535 : NPObject* aObject,
1536 : PluginScriptableObjectParent* aActor)
1537 : {
1538 0 : NS_ASSERTION(aObject && aActor, "Null pointers!");
1539 0 : NS_ASSERTION(mScriptableObjects.IsInitialized(), "Hash not initialized!");
1540 0 : NS_ASSERTION(!mScriptableObjects.Get(aObject, nsnull), "Duplicate entry!");
1541 0 : return !!mScriptableObjects.Put(aObject, aActor);
1542 : }
1543 :
1544 : void
1545 0 : PluginInstanceParent::UnregisterNPObject(NPObject* aObject)
1546 : {
1547 0 : NS_ASSERTION(aObject, "Null pointer!");
1548 0 : NS_ASSERTION(mScriptableObjects.IsInitialized(), "Hash not initialized!");
1549 0 : NS_ASSERTION(mScriptableObjects.Get(aObject, nsnull), "Unknown entry!");
1550 0 : mScriptableObjects.Remove(aObject);
1551 0 : }
1552 :
1553 : PluginScriptableObjectParent*
1554 0 : PluginInstanceParent::GetActorForNPObject(NPObject* aObject)
1555 : {
1556 0 : NS_ASSERTION(aObject, "Null pointer!");
1557 :
1558 0 : if (aObject->_class == PluginScriptableObjectParent::GetClass()) {
1559 : // One of ours!
1560 0 : ParentNPObject* object = static_cast<ParentNPObject*>(aObject);
1561 0 : NS_ASSERTION(object->parent, "Null actor!");
1562 0 : return object->parent;
1563 : }
1564 :
1565 : PluginScriptableObjectParent* actor;
1566 0 : if (mScriptableObjects.Get(aObject, &actor)) {
1567 0 : return actor;
1568 : }
1569 :
1570 0 : actor = new PluginScriptableObjectParent(LocalObject);
1571 0 : if (!actor) {
1572 0 : NS_ERROR("Out of memory!");
1573 0 : return nsnull;
1574 : }
1575 :
1576 0 : if (!SendPPluginScriptableObjectConstructor(actor)) {
1577 0 : NS_WARNING("Failed to send constructor message!");
1578 0 : return nsnull;
1579 : }
1580 :
1581 0 : actor->InitializeLocal(aObject);
1582 0 : return actor;
1583 : }
1584 :
1585 : PPluginSurfaceParent*
1586 0 : PluginInstanceParent::AllocPPluginSurface(const WindowsSharedMemoryHandle& handle,
1587 : const gfxIntSize& size,
1588 : const bool& transparent)
1589 : {
1590 : #ifdef XP_WIN
1591 : return new PluginSurfaceParent(handle, size, transparent);
1592 : #else
1593 0 : NS_ERROR("This shouldn't be called!");
1594 0 : return NULL;
1595 : #endif
1596 : }
1597 :
1598 : bool
1599 0 : PluginInstanceParent::DeallocPPluginSurface(PPluginSurfaceParent* s)
1600 : {
1601 : #ifdef XP_WIN
1602 : delete s;
1603 : return true;
1604 : #else
1605 0 : return false;
1606 : #endif
1607 : }
1608 :
1609 : bool
1610 0 : PluginInstanceParent::AnswerNPN_PushPopupsEnabledState(const bool& aState)
1611 : {
1612 0 : mNPNIface->pushpopupsenabledstate(mNPP, aState ? 1 : 0);
1613 0 : return true;
1614 : }
1615 :
1616 : bool
1617 0 : PluginInstanceParent::AnswerNPN_PopPopupsEnabledState()
1618 : {
1619 0 : mNPNIface->poppopupsenabledstate(mNPP);
1620 0 : return true;
1621 : }
1622 :
1623 : bool
1624 0 : PluginInstanceParent::AnswerNPN_GetValueForURL(const NPNURLVariable& variable,
1625 : const nsCString& url,
1626 : nsCString* value,
1627 : NPError* result)
1628 : {
1629 : char* v;
1630 : uint32_t len;
1631 :
1632 : *result = mNPNIface->getvalueforurl(mNPP, (NPNURLVariable) variable,
1633 0 : url.get(), &v, &len);
1634 0 : if (NPERR_NO_ERROR == *result)
1635 0 : value->Adopt(v, len);
1636 :
1637 0 : return true;
1638 : }
1639 :
1640 : bool
1641 0 : PluginInstanceParent::AnswerNPN_SetValueForURL(const NPNURLVariable& variable,
1642 : const nsCString& url,
1643 : const nsCString& value,
1644 : NPError* result)
1645 : {
1646 : *result = mNPNIface->setvalueforurl(mNPP, (NPNURLVariable) variable,
1647 : url.get(), value.get(),
1648 0 : value.Length());
1649 0 : return true;
1650 : }
1651 :
1652 : bool
1653 0 : PluginInstanceParent::AnswerNPN_GetAuthenticationInfo(const nsCString& protocol,
1654 : const nsCString& host,
1655 : const int32_t& port,
1656 : const nsCString& scheme,
1657 : const nsCString& realm,
1658 : nsCString* username,
1659 : nsCString* password,
1660 : NPError* result)
1661 : {
1662 : char* u;
1663 : uint32_t ulen;
1664 : char* p;
1665 : uint32_t plen;
1666 :
1667 : *result = mNPNIface->getauthenticationinfo(mNPP, protocol.get(),
1668 : host.get(), port,
1669 : scheme.get(), realm.get(),
1670 0 : &u, &ulen, &p, &plen);
1671 0 : if (NPERR_NO_ERROR == *result) {
1672 0 : username->Adopt(u, ulen);
1673 0 : password->Adopt(p, plen);
1674 : }
1675 0 : return true;
1676 : }
1677 :
1678 : bool
1679 0 : PluginInstanceParent::AnswerNPN_ConvertPoint(const double& sourceX,
1680 : const bool& ignoreDestX,
1681 : const double& sourceY,
1682 : const bool& ignoreDestY,
1683 : const NPCoordinateSpace& sourceSpace,
1684 : const NPCoordinateSpace& destSpace,
1685 : double *destX,
1686 : double *destY,
1687 : bool *result)
1688 : {
1689 : *result = mNPNIface->convertpoint(mNPP, sourceX, sourceY, sourceSpace,
1690 : ignoreDestX ? nsnull : destX,
1691 : ignoreDestY ? nsnull : destY,
1692 0 : destSpace);
1693 :
1694 0 : return true;
1695 : }
1696 :
1697 : bool
1698 0 : PluginInstanceParent::AnswerNPN_InitAsyncSurface(const gfxIntSize& size,
1699 : const NPImageFormat& format,
1700 : NPRemoteAsyncSurface* surfData,
1701 : bool* result)
1702 : {
1703 0 : if (!IsAsyncDrawing()) {
1704 0 : *result = false;
1705 0 : return true;
1706 : }
1707 :
1708 0 : switch (mDrawingModel) {
1709 : case NPDrawingModelAsyncBitmapSurface: {
1710 0 : Shmem sharedMem;
1711 0 : if (!AllocUnsafeShmem(size.width * size.height * 4, SharedMemory::TYPE_BASIC, &sharedMem)) {
1712 0 : *result = false;
1713 0 : return true;
1714 : }
1715 :
1716 0 : surfData->size() = size;
1717 0 : surfData->hostPtr() = (uintptr_t)sharedMem.get<unsigned char>();
1718 0 : surfData->stride() = size.width * 4;
1719 0 : surfData->format() = format;
1720 0 : surfData->data() = sharedMem;
1721 0 : *result = true;
1722 : }
1723 : }
1724 :
1725 0 : return true;
1726 : }
1727 :
1728 : bool
1729 0 : PluginInstanceParent::RecvRedrawPlugin()
1730 : {
1731 0 : nsNPAPIPluginInstance *inst = static_cast<nsNPAPIPluginInstance*>(mNPP->ndata);
1732 0 : if (!inst) {
1733 0 : return false;
1734 : }
1735 :
1736 0 : inst->RedrawPlugin();
1737 0 : return true;
1738 : }
1739 :
1740 : bool
1741 0 : PluginInstanceParent::RecvNegotiatedCarbon()
1742 : {
1743 0 : nsNPAPIPluginInstance *inst = static_cast<nsNPAPIPluginInstance*>(mNPP->ndata);
1744 0 : if (!inst) {
1745 0 : return false;
1746 : }
1747 0 : inst->CarbonNPAPIFailure();
1748 0 : return true;
1749 : }
1750 :
1751 : #if defined(OS_WIN)
1752 :
1753 : /*
1754 : plugin focus changes between processes
1755 :
1756 : focus from dom -> child:
1757 : Focus manager calls on widget to set the focus on the window.
1758 : We pick up the resulting wm_setfocus event here, and forward
1759 : that over ipc to the child which calls set focus on itself.
1760 :
1761 : focus from child -> focus manager:
1762 : Child picks up the local wm_setfocus and sends it via ipc over
1763 : here. We then post a custom event to widget/windows/nswindow
1764 : which fires off a gui event letting the browser know.
1765 : */
1766 :
1767 : static const PRUnichar kPluginInstanceParentProperty[] =
1768 : L"PluginInstanceParentProperty";
1769 :
1770 : // static
1771 : LRESULT CALLBACK
1772 : PluginInstanceParent::PluginWindowHookProc(HWND hWnd,
1773 : UINT message,
1774 : WPARAM wParam,
1775 : LPARAM lParam)
1776 : {
1777 : PluginInstanceParent* self = reinterpret_cast<PluginInstanceParent*>(
1778 : ::GetPropW(hWnd, kPluginInstanceParentProperty));
1779 : if (!self) {
1780 : NS_NOTREACHED("PluginInstanceParent::PluginWindowHookProc null this ptr!");
1781 : return DefWindowProc(hWnd, message, wParam, lParam);
1782 : }
1783 :
1784 : NS_ASSERTION(self->mPluginHWND == hWnd, "Wrong window!");
1785 :
1786 : switch (message) {
1787 : case WM_SETFOCUS:
1788 : // Let the child plugin window know it should take focus.
1789 : self->CallSetPluginFocus();
1790 : break;
1791 :
1792 : case WM_CLOSE:
1793 : self->UnsubclassPluginWindow();
1794 : break;
1795 : }
1796 :
1797 : if (self->mPluginWndProc == PluginWindowHookProc) {
1798 : NS_NOTREACHED(
1799 : "PluginWindowHookProc invoking mPluginWndProc w/"
1800 : "mPluginWndProc == PluginWindowHookProc????");
1801 : return DefWindowProc(hWnd, message, wParam, lParam);
1802 : }
1803 : return ::CallWindowProc(self->mPluginWndProc, hWnd, message, wParam,
1804 : lParam);
1805 : }
1806 :
1807 : void
1808 : PluginInstanceParent::SubclassPluginWindow(HWND aWnd)
1809 : {
1810 : NS_ASSERTION(!(mPluginHWND && aWnd != mPluginHWND),
1811 : "PluginInstanceParent::SubclassPluginWindow hwnd is not our window!");
1812 :
1813 : if (!mPluginHWND) {
1814 : mPluginHWND = aWnd;
1815 : mPluginWndProc =
1816 : (WNDPROC)::SetWindowLongPtrA(mPluginHWND, GWLP_WNDPROC,
1817 : reinterpret_cast<LONG_PTR>(PluginWindowHookProc));
1818 : bool bRes = ::SetPropW(mPluginHWND, kPluginInstanceParentProperty, this);
1819 : NS_ASSERTION(mPluginWndProc,
1820 : "PluginInstanceParent::SubclassPluginWindow failed to set subclass!");
1821 : NS_ASSERTION(bRes,
1822 : "PluginInstanceParent::SubclassPluginWindow failed to set prop!");
1823 : }
1824 : }
1825 :
1826 : void
1827 : PluginInstanceParent::UnsubclassPluginWindow()
1828 : {
1829 : if (mPluginHWND && mPluginWndProc) {
1830 : ::SetWindowLongPtrA(mPluginHWND, GWLP_WNDPROC,
1831 : reinterpret_cast<LONG_PTR>(mPluginWndProc));
1832 :
1833 : ::RemovePropW(mPluginHWND, kPluginInstanceParentProperty);
1834 :
1835 : mPluginWndProc = NULL;
1836 : mPluginHWND = NULL;
1837 : }
1838 : }
1839 :
1840 : /* windowless drawing helpers */
1841 :
1842 : /*
1843 : * Origin info:
1844 : *
1845 : * windowless, offscreen:
1846 : *
1847 : * WM_WINDOWPOSCHANGED: origin is relative to container
1848 : * setwindow: origin is 0,0
1849 : * WM_PAINT: origin is 0,0
1850 : *
1851 : * windowless, native:
1852 : *
1853 : * WM_WINDOWPOSCHANGED: origin is relative to container
1854 : * setwindow: origin is relative to container
1855 : * WM_PAINT: origin is relative to container
1856 : *
1857 : * PluginInstanceParent:
1858 : *
1859 : * painting: mPluginPort (nsIntRect, saved in SetWindow)
1860 : */
1861 :
1862 : void
1863 : PluginInstanceParent::SharedSurfaceRelease()
1864 : {
1865 : mSharedSurfaceDib.Close();
1866 : }
1867 :
1868 : bool
1869 : PluginInstanceParent::SharedSurfaceSetWindow(const NPWindow* aWindow,
1870 : NPRemoteWindow& aRemoteWindow)
1871 : {
1872 : aRemoteWindow.window = nsnull;
1873 : aRemoteWindow.x = aWindow->x;
1874 : aRemoteWindow.y = aWindow->y;
1875 : aRemoteWindow.width = aWindow->width;
1876 : aRemoteWindow.height = aWindow->height;
1877 : aRemoteWindow.type = aWindow->type;
1878 :
1879 : nsIntRect newPort(aWindow->x, aWindow->y, aWindow->width, aWindow->height);
1880 :
1881 : // save the the rect location within the browser window.
1882 : mPluginPort = newPort;
1883 :
1884 : // move the port to our shared surface origin
1885 : newPort.MoveTo(0,0);
1886 :
1887 : // check to see if we have the room in shared surface
1888 : if (mSharedSurfaceDib.IsValid() && mSharedSize.Contains(newPort)) {
1889 : // ok to paint
1890 : aRemoteWindow.surfaceHandle = 0;
1891 : return true;
1892 : }
1893 :
1894 : // allocate a new shared surface
1895 : SharedSurfaceRelease();
1896 : if (NS_FAILED(mSharedSurfaceDib.Create(reinterpret_cast<HDC>(aWindow->window),
1897 : newPort.width, newPort.height, false)))
1898 : return false;
1899 :
1900 : // save the new shared surface size we just allocated
1901 : mSharedSize = newPort;
1902 :
1903 : base::SharedMemoryHandle handle;
1904 : if (NS_FAILED(mSharedSurfaceDib.ShareToProcess(mParent->ChildProcessHandle(), &handle)))
1905 : return false;
1906 :
1907 : aRemoteWindow.surfaceHandle = handle;
1908 :
1909 : return true;
1910 : }
1911 :
1912 : void
1913 : PluginInstanceParent::SharedSurfaceBeforePaint(RECT& rect,
1914 : NPRemoteEvent& npremoteevent)
1915 : {
1916 : RECT* dr = (RECT*)npremoteevent.event.lParam;
1917 : HDC parentHdc = (HDC)npremoteevent.event.wParam;
1918 :
1919 : nsIntRect dirtyRect(dr->left, dr->top, dr->right-dr->left, dr->bottom-dr->top);
1920 : dirtyRect.MoveBy(-mPluginPort.x, -mPluginPort.y); // should always be smaller than dirtyRect
1921 :
1922 : ::BitBlt(mSharedSurfaceDib.GetHDC(),
1923 : dirtyRect.x,
1924 : dirtyRect.y,
1925 : dirtyRect.width,
1926 : dirtyRect.height,
1927 : parentHdc,
1928 : dr->left,
1929 : dr->top,
1930 : SRCCOPY);
1931 :
1932 : // setup the translated dirty rect we'll send to the child
1933 : rect.left = dirtyRect.x;
1934 : rect.top = dirtyRect.y;
1935 : rect.right = dirtyRect.x + dirtyRect.width;
1936 : rect.bottom = dirtyRect.y + dirtyRect.height;
1937 :
1938 : npremoteevent.event.wParam = WPARAM(0);
1939 : npremoteevent.event.lParam = LPARAM(&rect);
1940 : }
1941 :
1942 : void
1943 : PluginInstanceParent::SharedSurfaceAfterPaint(NPEvent* npevent)
1944 : {
1945 : RECT* dr = (RECT*)npevent->lParam;
1946 : HDC parentHdc = (HDC)npevent->wParam;
1947 :
1948 : nsIntRect dirtyRect(dr->left, dr->top, dr->right-dr->left, dr->bottom-dr->top);
1949 : dirtyRect.MoveBy(-mPluginPort.x, -mPluginPort.y);
1950 :
1951 : // src copy the shared dib into the parent surface we are handed.
1952 : ::BitBlt(parentHdc,
1953 : dr->left,
1954 : dr->top,
1955 : dirtyRect.width,
1956 : dirtyRect.height,
1957 : mSharedSurfaceDib.GetHDC(),
1958 : dirtyRect.x,
1959 : dirtyRect.y,
1960 : SRCCOPY);
1961 : }
1962 :
1963 : #endif // defined(OS_WIN)
1964 :
1965 : bool
1966 0 : PluginInstanceParent::AnswerPluginFocusChange(const bool& gotFocus)
1967 : {
1968 0 : PLUGIN_LOG_DEBUG(("%s", FULLFUNCTION));
1969 :
1970 : // Currently only in use on windows - an rpc event we receive from the
1971 : // child when it's plugin window (or one of it's children) receives keyboard
1972 : // focus. We forward the event down to widget so the dom/focus manager can
1973 : // be updated.
1974 : #if defined(OS_WIN)
1975 : ::SendMessage(mPluginHWND, gOOPPPluginFocusEvent, gotFocus ? 1 : 0, 0);
1976 : return true;
1977 : #else
1978 0 : NS_NOTREACHED("PluginInstanceParent::AnswerPluginFocusChange not implemented!");
1979 0 : return false;
1980 : #endif
1981 : }
|