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 (
425 : #if defined(XP_WIN)
426 : drawingModel == NPDrawingModelSyncWin
427 : #elif defined(XP_MACOSX)
428 : #ifndef NP_NO_QUICKDRAW
429 : drawingModel == NPDrawingModelQuickDraw ||
430 : #endif
431 : drawingModel == NPDrawingModelOpenGL ||
432 : drawingModel == NPDrawingModelCoreGraphics
433 : #elif defined(MOZ_X11)
434 : drawingModel == NPDrawingModelSyncX
435 : #else
436 : false
437 : #endif
438 : ) {
439 0 : *shmem = null_t();
440 :
441 0 : ImageContainer *container = GetImageContainer();
442 0 : if (!container) {
443 0 : *result = NPERR_GENERIC_ERROR;
444 0 : return true;
445 : }
446 :
447 0 : mDrawingModel = drawingModel;
448 : *result = mNPNIface->setvalue(mNPP, NPPVpluginDrawingModel,
449 0 : (void*)drawingModel);
450 :
451 0 : if (mRemoteImageDataShmem.IsWritable()) {
452 0 : container->SetRemoteImageData(nsnull, nsnull);
453 0 : container->SetCompositionNotifySink(nsnull);
454 0 : DeallocShmem(mRemoteImageDataShmem);
455 0 : mRemoteImageDataMutex = NULL;
456 : }
457 : } else {
458 0 : *result = NPERR_GENERIC_ERROR;
459 : }
460 0 : return true;
461 : }
462 :
463 : bool
464 0 : PluginInstanceParent::AnswerNPN_SetValue_NPPVpluginEventModel(
465 : const int& eventModel, NPError* result)
466 : {
467 : #ifdef XP_MACOSX
468 : *result = mNPNIface->setvalue(mNPP, NPPVpluginEventModel,
469 : (void*)eventModel);
470 : return true;
471 : #else
472 0 : *result = NPERR_GENERIC_ERROR;
473 0 : return true;
474 : #endif
475 : }
476 :
477 : bool
478 0 : PluginInstanceParent::AnswerNPN_GetURL(const nsCString& url,
479 : const nsCString& target,
480 : NPError* result)
481 : {
482 : *result = mNPNIface->geturl(mNPP,
483 : NullableStringGet(url),
484 0 : NullableStringGet(target));
485 0 : return true;
486 : }
487 :
488 : bool
489 0 : PluginInstanceParent::AnswerNPN_PostURL(const nsCString& url,
490 : const nsCString& target,
491 : const nsCString& buffer,
492 : const bool& file,
493 : NPError* result)
494 : {
495 : *result = mNPNIface->posturl(mNPP, url.get(), NullableStringGet(target),
496 0 : buffer.Length(), buffer.get(), file);
497 0 : return true;
498 : }
499 :
500 : PStreamNotifyParent*
501 0 : PluginInstanceParent::AllocPStreamNotify(const nsCString& url,
502 : const nsCString& target,
503 : const bool& post,
504 : const nsCString& buffer,
505 : const bool& file,
506 : NPError* result)
507 : {
508 0 : return new StreamNotifyParent();
509 : }
510 :
511 : bool
512 0 : PluginInstanceParent::AnswerPStreamNotifyConstructor(PStreamNotifyParent* actor,
513 : const nsCString& url,
514 : const nsCString& target,
515 : const bool& post,
516 : const nsCString& buffer,
517 : const bool& file,
518 : NPError* result)
519 : {
520 0 : bool streamDestroyed = false;
521 : static_cast<StreamNotifyParent*>(actor)->
522 0 : SetDestructionFlag(&streamDestroyed);
523 :
524 0 : if (!post) {
525 : *result = mNPNIface->geturlnotify(mNPP,
526 : NullableStringGet(url),
527 : NullableStringGet(target),
528 0 : actor);
529 : }
530 : else {
531 : *result = mNPNIface->posturlnotify(mNPP,
532 : NullableStringGet(url),
533 : NullableStringGet(target),
534 : buffer.Length(),
535 : NullableStringGet(buffer),
536 0 : file, actor);
537 : }
538 :
539 0 : if (streamDestroyed) {
540 : // If the stream was destroyed, we must return an error code in the
541 : // constructor.
542 0 : *result = NPERR_GENERIC_ERROR;
543 : }
544 : else {
545 0 : static_cast<StreamNotifyParent*>(actor)->ClearDestructionFlag();
546 0 : if (*result != NPERR_NO_ERROR)
547 : return PStreamNotifyParent::Send__delete__(actor,
548 0 : NPERR_GENERIC_ERROR);
549 : }
550 :
551 0 : return true;
552 : }
553 :
554 : bool
555 0 : PluginInstanceParent::DeallocPStreamNotify(PStreamNotifyParent* notifyData)
556 : {
557 0 : delete notifyData;
558 0 : return true;
559 : }
560 :
561 : bool
562 0 : PluginInstanceParent::RecvNPN_InvalidateRect(const NPRect& rect)
563 : {
564 0 : mNPNIface->invalidaterect(mNPP, const_cast<NPRect*>(&rect));
565 0 : return true;
566 : }
567 :
568 : bool
569 0 : PluginInstanceParent::RecvShow(const NPRect& updatedRect,
570 : const SurfaceDescriptor& newSurface,
571 : SurfaceDescriptor* prevSurface)
572 : {
573 0 : PLUGIN_LOG_DEBUG(
574 : ("[InstanceParent][%p] RecvShow for <x=%d,y=%d, w=%d,h=%d>",
575 : this, updatedRect.left, updatedRect.top,
576 : updatedRect.right - updatedRect.left,
577 : updatedRect.bottom - updatedRect.top));
578 :
579 0 : nsRefPtr<gfxASurface> surface;
580 0 : if (newSurface.type() == SurfaceDescriptor::TShmem) {
581 0 : if (!newSurface.get_Shmem().IsReadable()) {
582 0 : NS_WARNING("back surface not readable");
583 0 : return false;
584 : }
585 0 : surface = gfxSharedImageSurface::Open(newSurface.get_Shmem());
586 : }
587 : #ifdef XP_MACOSX
588 : else if (newSurface.type() == SurfaceDescriptor::TIOSurfaceDescriptor) {
589 : IOSurfaceDescriptor iodesc = newSurface.get_IOSurfaceDescriptor();
590 :
591 : nsRefPtr<nsIOSurface> newIOSurface = nsIOSurface::LookupSurface(iodesc.surfaceId());
592 :
593 : if (!newIOSurface) {
594 : NS_WARNING("Got bad IOSurfaceDescriptor in RecvShow");
595 : return false;
596 : }
597 :
598 : if (mFrontIOSurface)
599 : *prevSurface = IOSurfaceDescriptor(mFrontIOSurface->GetIOSurfaceID());
600 : else
601 : *prevSurface = null_t();
602 :
603 : mFrontIOSurface = newIOSurface;
604 :
605 : RecvNPN_InvalidateRect(updatedRect);
606 :
607 : PLUGIN_LOG_DEBUG((" (RecvShow invalidated for surface %p)",
608 : mFrontSurface.get()));
609 :
610 : return true;
611 : }
612 : #endif
613 : #ifdef MOZ_X11
614 0 : else if (newSurface.type() == SurfaceDescriptor::TSurfaceDescriptorX11) {
615 0 : surface = newSurface.get_SurfaceDescriptorX11().OpenForeign();
616 : }
617 : #endif
618 : #ifdef XP_WIN
619 : else if (newSurface.type() == SurfaceDescriptor::TPPluginSurfaceParent) {
620 : PluginSurfaceParent* s =
621 : static_cast<PluginSurfaceParent*>(newSurface.get_PPluginSurfaceParent());
622 : surface = s->Surface();
623 : }
624 : #endif
625 :
626 : #ifdef MOZ_X11
627 0 : if (mFrontSurface &&
628 0 : mFrontSurface->GetType() == gfxASurface::SurfaceTypeXlib)
629 : // This is the "old front buffer" we're about to hand back to
630 : // the plugin. We might still have drawing operations
631 : // referencing it, so we XSync here to let them finish before
632 : // the plugin starts scribbling on it again, or worse,
633 : // destroys it.
634 0 : XSync(DefaultXDisplay(), False);
635 : #endif
636 :
637 0 : if (mFrontSurface && gfxSharedImageSurface::IsSharedImage(mFrontSurface))
638 0 : *prevSurface = static_cast<gfxSharedImageSurface*>(mFrontSurface.get())->GetShmem();
639 : else
640 0 : *prevSurface = null_t();
641 :
642 0 : if (surface) {
643 : // Notify the cairo backend that this surface has changed behind
644 : // its back.
645 : gfxRect ur(updatedRect.left, updatedRect.top,
646 : updatedRect.right - updatedRect.left,
647 0 : updatedRect.bottom - updatedRect.top);
648 0 : surface->MarkDirty(ur);
649 0 : surface->Flush();
650 : }
651 :
652 0 : mFrontSurface = surface;
653 0 : RecvNPN_InvalidateRect(updatedRect);
654 :
655 0 : PLUGIN_LOG_DEBUG((" (RecvShow invalidated for surface %p)",
656 : mFrontSurface.get()));
657 :
658 0 : return true;
659 : }
660 :
661 : nsresult
662 0 : PluginInstanceParent::AsyncSetWindow(NPWindow* aWindow)
663 : {
664 0 : NPRemoteWindow window;
665 0 : mWindowType = aWindow->type;
666 0 : window.window = reinterpret_cast<uint64_t>(aWindow->window);
667 0 : window.x = aWindow->x;
668 0 : window.y = aWindow->y;
669 0 : window.width = aWindow->width;
670 0 : window.height = aWindow->height;
671 0 : window.clipRect = aWindow->clipRect;
672 0 : window.type = aWindow->type;
673 0 : if (!SendAsyncSetWindow(gfxPlatform::GetPlatform()->ScreenReferenceSurface()->GetType(),
674 0 : window))
675 0 : return NS_ERROR_FAILURE;
676 :
677 0 : return NS_OK;
678 : }
679 :
680 : #if defined(MOZ_WIDGET_QT) && (MOZ_PLATFORM_MAEMO == 6)
681 : nsresult
682 : PluginInstanceParent::HandleGUIEvent(const nsGUIEvent& anEvent, bool* handled)
683 : {
684 : switch (anEvent.eventStructType) {
685 : case NS_KEY_EVENT:
686 : if (!CallHandleKeyEvent(static_cast<const nsKeyEvent&>(anEvent),
687 : handled)) {
688 : return NS_ERROR_FAILURE;
689 : }
690 : break;
691 : case NS_TEXT_EVENT:
692 : if (!CallHandleTextEvent(static_cast<const nsTextEvent&>(anEvent),
693 : handled)) {
694 : return NS_ERROR_FAILURE;
695 : }
696 : break;
697 : default:
698 : NS_ERROR("Not implemented for this event type");
699 : return NS_ERROR_FAILURE;
700 : }
701 : return NS_OK;
702 : }
703 : #endif
704 :
705 : nsresult
706 0 : PluginInstanceParent::GetImageContainer(ImageContainer** aContainer)
707 : {
708 : #ifdef XP_MACOSX
709 : nsIOSurface* ioSurface = NULL;
710 :
711 : if (mFrontIOSurface) {
712 : ioSurface = mFrontIOSurface;
713 : } else if (mIOSurface) {
714 : ioSurface = mIOSurface;
715 : }
716 :
717 : if (!mFrontSurface && !ioSurface)
718 : #else
719 0 : if (!mFrontSurface)
720 : #endif
721 0 : return NS_ERROR_NOT_AVAILABLE;
722 :
723 0 : Image::Format format = Image::CAIRO_SURFACE;
724 : #ifdef XP_MACOSX
725 : if (ioSurface) {
726 : format = Image::MAC_IO_SURFACE;
727 : }
728 : #endif
729 :
730 0 : ImageContainer *container = GetImageContainer();
731 :
732 0 : if (!container) {
733 0 : return NS_ERROR_FAILURE;
734 : }
735 :
736 0 : if (IsAsyncDrawing()) {
737 0 : NS_IF_ADDREF(container);
738 0 : *aContainer = container;
739 0 : return NS_OK;
740 : }
741 :
742 0 : nsRefPtr<Image> image;
743 0 : image = container->CreateImage(&format, 1);
744 0 : if (!image) {
745 0 : return NS_ERROR_FAILURE;
746 : }
747 :
748 : #ifdef XP_MACOSX
749 : if (ioSurface) {
750 : NS_ASSERTION(image->GetFormat() == Image::MAC_IO_SURFACE, "Wrong format?");
751 : MacIOSurfaceImage* ioImage = static_cast<MacIOSurfaceImage*>(image.get());
752 : MacIOSurfaceImage::Data ioData;
753 : ioData.mIOSurface = ioSurface;
754 : ioImage->SetData(ioData);
755 : container->SetCurrentImage(ioImage);
756 :
757 : NS_IF_ADDREF(container);
758 : *aContainer = container;
759 : return NS_OK;
760 : }
761 : #endif
762 :
763 0 : NS_ASSERTION(image->GetFormat() == Image::CAIRO_SURFACE, "Wrong format?");
764 0 : CairoImage* pluginImage = static_cast<CairoImage*>(image.get());
765 0 : CairoImage::Data cairoData;
766 0 : cairoData.mSurface = mFrontSurface;
767 0 : cairoData.mSize = mFrontSurface->GetSize();
768 0 : pluginImage->SetData(cairoData);
769 :
770 0 : container->SetCurrentImage(pluginImage);
771 :
772 0 : NS_IF_ADDREF(container);
773 0 : *aContainer = container;
774 0 : return NS_OK;
775 : }
776 :
777 : nsresult
778 0 : PluginInstanceParent::GetImageSize(nsIntSize* aSize)
779 : {
780 0 : if (mFrontSurface) {
781 0 : gfxIntSize size = mFrontSurface->GetSize();
782 0 : *aSize = nsIntSize(size.width, size.height);
783 0 : return NS_OK;
784 : }
785 :
786 : #ifdef XP_MACOSX
787 : if (mFrontIOSurface) {
788 : *aSize = nsIntSize(mFrontIOSurface->GetWidth(), mFrontIOSurface->GetHeight());
789 : return NS_OK;
790 : } else if (mIOSurface) {
791 : *aSize = nsIntSize(mIOSurface->GetWidth(), mIOSurface->GetHeight());
792 : return NS_OK;
793 : }
794 : #endif
795 :
796 0 : return NS_ERROR_NOT_AVAILABLE;
797 : }
798 :
799 : #ifdef XP_MACOSX
800 : nsresult
801 : PluginInstanceParent::IsRemoteDrawingCoreAnimation(bool *aDrawing)
802 : {
803 : *aDrawing = (NPDrawingModelCoreAnimation == (NPDrawingModel)mDrawingModel ||
804 : NPDrawingModelInvalidatingCoreAnimation == (NPDrawingModel)mDrawingModel);
805 : return NS_OK;
806 : }
807 : #endif
808 :
809 : nsresult
810 0 : PluginInstanceParent::SetBackgroundUnknown()
811 : {
812 0 : PLUGIN_LOG_DEBUG(("[InstanceParent][%p] SetBackgroundUnknown", this));
813 :
814 0 : if (mBackground) {
815 0 : DestroyBackground();
816 0 : NS_ABORT_IF_FALSE(!mBackground, "Background not destroyed");
817 : }
818 :
819 0 : return NS_OK;
820 : }
821 :
822 : nsresult
823 0 : PluginInstanceParent::BeginUpdateBackground(const nsIntRect& aRect,
824 : gfxContext** aCtx)
825 : {
826 0 : PLUGIN_LOG_DEBUG(
827 : ("[InstanceParent][%p] BeginUpdateBackground for <x=%d,y=%d, w=%d,h=%d>",
828 : this, aRect.x, aRect.y, aRect.width, aRect.height));
829 :
830 0 : if (!mBackground) {
831 : // XXX if we failed to create a background surface on one
832 : // update, there's no guarantee that later updates will be for
833 : // the entire background area until successful. We might want
834 : // to fix that eventually.
835 0 : NS_ABORT_IF_FALSE(aRect.TopLeft() == nsIntPoint(0, 0),
836 : "Expecting rect for whole frame");
837 0 : if (!CreateBackground(aRect.Size())) {
838 0 : *aCtx = nsnull;
839 0 : return NS_OK;
840 : }
841 : }
842 :
843 : #ifdef DEBUG
844 0 : gfxIntSize sz = mBackground->GetSize();
845 0 : NS_ABORT_IF_FALSE(nsIntRect(0, 0, sz.width, sz.height).Contains(aRect),
846 : "Update outside of background area");
847 : #endif
848 :
849 0 : nsRefPtr<gfxContext> ctx = new gfxContext(mBackground);
850 0 : *aCtx = ctx.forget().get();
851 :
852 0 : return NS_OK;
853 : }
854 :
855 : nsresult
856 0 : PluginInstanceParent::EndUpdateBackground(gfxContext* aCtx,
857 : const nsIntRect& aRect)
858 : {
859 0 : PLUGIN_LOG_DEBUG(
860 : ("[InstanceParent][%p] EndUpdateBackground for <x=%d,y=%d, w=%d,h=%d>",
861 : this, aRect.x, aRect.y, aRect.width, aRect.height));
862 :
863 : #ifdef MOZ_X11
864 : // Have to XSync here to avoid the plugin trying to draw with this
865 : // surface racing with its creation in the X server. We also want
866 : // to avoid the plugin drawing onto stale pixels, then handing us
867 : // back a front surface from those pixels that we might
868 : // recomposite for "a while" until the next update. This XSync
869 : // still doesn't guarantee that the plugin draws onto a consistent
870 : // view of its background, but it does mean that the plugin is
871 : // drawing onto pixels no older than those in the latest
872 : // EndUpdateBackground().
873 0 : XSync(DefaultXDisplay(), False);
874 : #endif
875 :
876 0 : unused << SendUpdateBackground(BackgroundDescriptor(), aRect);
877 :
878 0 : return NS_OK;
879 : }
880 :
881 : bool
882 0 : PluginInstanceParent::CreateBackground(const nsIntSize& aSize)
883 : {
884 0 : NS_ABORT_IF_FALSE(!mBackground, "Already have a background");
885 :
886 : // XXX refactor me
887 :
888 : #if defined(MOZ_X11)
889 0 : Screen* screen = DefaultScreenOfDisplay(DefaultXDisplay());
890 0 : Visual* visual = DefaultVisualOfScreen(screen);
891 : mBackground = gfxXlibSurface::Create(screen, visual,
892 0 : gfxIntSize(aSize.width, aSize.height));
893 0 : return !!mBackground;
894 :
895 : #elif defined(XP_WIN)
896 : // We have chosen to create an unsafe surface in which the plugin
897 : // can read from the region while we're writing to it.
898 : mBackground =
899 : gfxSharedImageSurface::CreateUnsafe(
900 : this,
901 : gfxIntSize(aSize.width, aSize.height),
902 : gfxASurface::ImageFormatRGB24);
903 : return !!mBackground;
904 : #else
905 : return nsnull;
906 : #endif
907 : }
908 :
909 : void
910 0 : PluginInstanceParent::DestroyBackground()
911 : {
912 0 : if (!mBackground) {
913 0 : return;
914 : }
915 :
916 : // Relinquish ownership of |mBackground| to its destroyer
917 : PPluginBackgroundDestroyerParent* pbd =
918 0 : new PluginBackgroundDestroyerParent(mBackground);
919 0 : mBackground = nsnull;
920 :
921 : // If this fails, there's no problem: |bd| will be destroyed along
922 : // with the old background surface.
923 0 : unused << SendPPluginBackgroundDestroyerConstructor(pbd);
924 : }
925 :
926 : SurfaceDescriptor
927 0 : PluginInstanceParent::BackgroundDescriptor()
928 : {
929 0 : NS_ABORT_IF_FALSE(mBackground, "Need a background here");
930 :
931 : // XXX refactor me
932 :
933 : #ifdef MOZ_X11
934 0 : gfxXlibSurface* xsurf = static_cast<gfxXlibSurface*>(mBackground.get());
935 0 : return SurfaceDescriptorX11(xsurf);
936 : #endif
937 :
938 : #ifdef XP_WIN
939 : NS_ABORT_IF_FALSE(gfxSharedImageSurface::IsSharedImage(mBackground),
940 : "Expected shared image surface");
941 : gfxSharedImageSurface* shmem =
942 : static_cast<gfxSharedImageSurface*>(mBackground.get());
943 : return shmem->GetShmem();
944 : #endif
945 :
946 : // If this is ever used, which it shouldn't be, it will trigger a
947 : // hard assertion in IPDL-generated code.
948 : return SurfaceDescriptor();
949 : }
950 :
951 : ImageContainer*
952 0 : PluginInstanceParent::GetImageContainer()
953 : {
954 0 : if (mImageContainer) {
955 0 : return mImageContainer;
956 : }
957 :
958 0 : mImageContainer = LayerManager::CreateImageContainer();
959 0 : return mImageContainer;
960 : }
961 :
962 : PPluginBackgroundDestroyerParent*
963 0 : PluginInstanceParent::AllocPPluginBackgroundDestroyer()
964 : {
965 0 : NS_RUNTIMEABORT("'Power-user' ctor is used exclusively");
966 0 : return nsnull;
967 : }
968 :
969 : bool
970 0 : PluginInstanceParent::DeallocPPluginBackgroundDestroyer(
971 : PPluginBackgroundDestroyerParent* aActor)
972 : {
973 0 : delete aActor;
974 0 : return true;
975 : }
976 :
977 : NPError
978 0 : PluginInstanceParent::NPP_SetWindow(const NPWindow* aWindow)
979 : {
980 0 : PLUGIN_LOG_DEBUG(("%s (aWindow=%p)", FULLFUNCTION, (void*) aWindow));
981 :
982 0 : NS_ENSURE_TRUE(aWindow, NPERR_GENERIC_ERROR);
983 :
984 0 : NPRemoteWindow window;
985 0 : mWindowType = aWindow->type;
986 :
987 : #if defined(OS_WIN)
988 : // On windowless controls, reset the shared memory surface as needed.
989 : if (mWindowType == NPWindowTypeDrawable) {
990 : // SharedSurfaceSetWindow will take care of NPRemoteWindow.
991 : if (!SharedSurfaceSetWindow(aWindow, window)) {
992 : return NPERR_OUT_OF_MEMORY_ERROR;
993 : }
994 : }
995 : else {
996 : SubclassPluginWindow(reinterpret_cast<HWND>(aWindow->window));
997 :
998 : window.window = reinterpret_cast<uint64_t>(aWindow->window);
999 : window.x = aWindow->x;
1000 : window.y = aWindow->y;
1001 : window.width = aWindow->width;
1002 : window.height = aWindow->height;
1003 : window.type = aWindow->type;
1004 : }
1005 : #else
1006 0 : window.window = reinterpret_cast<uint64_t>(aWindow->window);
1007 0 : window.x = aWindow->x;
1008 0 : window.y = aWindow->y;
1009 0 : window.width = aWindow->width;
1010 0 : window.height = aWindow->height;
1011 0 : window.clipRect = aWindow->clipRect; // MacOS specific
1012 0 : window.type = aWindow->type;
1013 : #endif
1014 :
1015 : #if defined(XP_MACOSX)
1016 : if (mShWidth != window.width || mShHeight != window.height) {
1017 : if (mDrawingModel == NPDrawingModelCoreAnimation ||
1018 : mDrawingModel == NPDrawingModelInvalidatingCoreAnimation) {
1019 : mIOSurface = nsIOSurface::CreateIOSurface(window.width, window.height);
1020 : } else if (mShWidth * mShHeight != window.width * window.height) {
1021 : if (mShWidth != 0 && mShHeight != 0) {
1022 : DeallocShmem(mShSurface);
1023 : mShWidth = 0;
1024 : mShHeight = 0;
1025 : }
1026 :
1027 : if (window.width != 0 && window.height != 0) {
1028 : if (!AllocShmem(window.width * window.height*4,
1029 : SharedMemory::TYPE_BASIC, &mShSurface)) {
1030 : PLUGIN_LOG_DEBUG(("Shared memory could not be allocated."));
1031 : return NPERR_GENERIC_ERROR;
1032 : }
1033 : }
1034 : }
1035 : mShWidth = window.width;
1036 : mShHeight = window.height;
1037 : }
1038 : #endif
1039 :
1040 : #if defined(MOZ_X11) && defined(XP_UNIX) && !defined(XP_MACOSX)
1041 : const NPSetWindowCallbackStruct* ws_info =
1042 0 : static_cast<NPSetWindowCallbackStruct*>(aWindow->ws_info);
1043 0 : window.visualID = ws_info->visual ? ws_info->visual->visualid : None;
1044 0 : window.colormap = ws_info->colormap;
1045 : #endif
1046 :
1047 0 : if (!CallNPP_SetWindow(window))
1048 0 : return NPERR_GENERIC_ERROR;
1049 :
1050 0 : return NPERR_NO_ERROR;
1051 : }
1052 :
1053 : NPError
1054 0 : PluginInstanceParent::NPP_GetValue(NPPVariable aVariable,
1055 : void* _retval)
1056 : {
1057 0 : switch (aVariable) {
1058 :
1059 : case NPPVpluginWantsAllNetworkStreams: {
1060 : bool wantsAllStreams;
1061 : NPError rv;
1062 :
1063 0 : if (!CallNPP_GetValue_NPPVpluginWantsAllNetworkStreams(&wantsAllStreams, &rv)) {
1064 0 : return NPERR_GENERIC_ERROR;
1065 : }
1066 :
1067 0 : if (NPERR_NO_ERROR != rv) {
1068 0 : return rv;
1069 : }
1070 :
1071 0 : (*(NPBool*)_retval) = wantsAllStreams;
1072 0 : return NPERR_NO_ERROR;
1073 : }
1074 :
1075 : #ifdef MOZ_X11
1076 : case NPPVpluginNeedsXEmbed: {
1077 : bool needsXEmbed;
1078 : NPError rv;
1079 :
1080 0 : if (!CallNPP_GetValue_NPPVpluginNeedsXEmbed(&needsXEmbed, &rv)) {
1081 0 : return NPERR_GENERIC_ERROR;
1082 : }
1083 :
1084 0 : if (NPERR_NO_ERROR != rv) {
1085 0 : return rv;
1086 : }
1087 :
1088 0 : (*(NPBool*)_retval) = needsXEmbed;
1089 0 : return NPERR_NO_ERROR;
1090 : }
1091 : #endif
1092 :
1093 : case NPPVpluginScriptableNPObject: {
1094 : PPluginScriptableObjectParent* actor;
1095 : NPError rv;
1096 0 : if (!CallNPP_GetValue_NPPVpluginScriptableNPObject(&actor, &rv)) {
1097 0 : return NPERR_GENERIC_ERROR;
1098 : }
1099 :
1100 0 : if (NPERR_NO_ERROR != rv) {
1101 0 : return rv;
1102 : }
1103 :
1104 0 : if (!actor) {
1105 0 : NS_ERROR("NPPVpluginScriptableNPObject succeeded but null.");
1106 0 : return NPERR_GENERIC_ERROR;
1107 : }
1108 :
1109 0 : const NPNetscapeFuncs* npn = mParent->GetNetscapeFuncs();
1110 0 : if (!npn) {
1111 0 : NS_WARNING("No netscape functions?!");
1112 0 : return NPERR_GENERIC_ERROR;
1113 : }
1114 :
1115 : NPObject* object =
1116 0 : static_cast<PluginScriptableObjectParent*>(actor)->GetObject(true);
1117 0 : NS_ASSERTION(object, "This shouldn't ever be null!");
1118 :
1119 0 : (*(NPObject**)_retval) = npn->retainobject(object);
1120 0 : return NPERR_NO_ERROR;
1121 : }
1122 :
1123 : #ifdef MOZ_ACCESSIBILITY_ATK
1124 : case NPPVpluginNativeAccessibleAtkPlugId: {
1125 0 : nsCString plugId;
1126 : NPError rv;
1127 0 : if (!CallNPP_GetValue_NPPVpluginNativeAccessibleAtkPlugId(&plugId, &rv)) {
1128 0 : return NPERR_GENERIC_ERROR;
1129 : }
1130 :
1131 0 : if (NPERR_NO_ERROR != rv) {
1132 0 : return rv;
1133 : }
1134 :
1135 0 : (*(nsCString*)_retval) = plugId;
1136 0 : return NPERR_NO_ERROR;
1137 : }
1138 : #endif
1139 :
1140 : default:
1141 0 : PR_LOG(gPluginLog, PR_LOG_WARNING,
1142 : ("In PluginInstanceParent::NPP_GetValue: Unhandled NPPVariable %i (%s)",
1143 : (int) aVariable, NPPVariableToString(aVariable)));
1144 0 : return NPERR_GENERIC_ERROR;
1145 : }
1146 : }
1147 :
1148 : NPError
1149 0 : PluginInstanceParent::NPP_SetValue(NPNVariable variable, void* value)
1150 : {
1151 0 : switch (variable) {
1152 : case NPNVprivateModeBool:
1153 : NPError result;
1154 0 : if (!CallNPP_SetValue_NPNVprivateModeBool(*static_cast<NPBool*>(value),
1155 0 : &result))
1156 0 : return NPERR_GENERIC_ERROR;
1157 :
1158 0 : return result;
1159 :
1160 : default:
1161 0 : NS_ERROR("Unhandled NPNVariable in NPP_SetValue");
1162 0 : PR_LOG(gPluginLog, PR_LOG_WARNING,
1163 : ("In PluginInstanceParent::NPP_SetValue: Unhandled NPNVariable %i (%s)",
1164 : (int) variable, NPNVariableToString(variable)));
1165 0 : return NPERR_GENERIC_ERROR;
1166 : }
1167 : }
1168 :
1169 : void
1170 0 : PluginInstanceParent::NPP_URLRedirectNotify(const char* url, int32_t status,
1171 : void* notifyData)
1172 : {
1173 0 : if (!notifyData)
1174 0 : return;
1175 :
1176 0 : PStreamNotifyParent* streamNotify = static_cast<PStreamNotifyParent*>(notifyData);
1177 0 : unused << streamNotify->SendRedirectNotify(NullableString(url), status);
1178 : }
1179 :
1180 : int16_t
1181 0 : PluginInstanceParent::NPP_HandleEvent(void* event)
1182 : {
1183 0 : PLUGIN_LOG_DEBUG_FUNCTION;
1184 :
1185 : #if defined(XP_MACOSX)
1186 : NPCocoaEvent* npevent = reinterpret_cast<NPCocoaEvent*>(event);
1187 : #else
1188 0 : NPEvent* npevent = reinterpret_cast<NPEvent*>(event);
1189 : #endif
1190 : NPRemoteEvent npremoteevent;
1191 0 : npremoteevent.event = *npevent;
1192 0 : int16_t handled = 0;
1193 :
1194 : #if defined(OS_WIN)
1195 : if (mWindowType == NPWindowTypeDrawable) {
1196 : if (IsAsyncDrawing()) {
1197 : if (npevent->event == WM_PAINT || npevent->event == DoublePassRenderingEvent()) {
1198 : // This plugin maintains its own async drawing.
1199 : return handled;
1200 : }
1201 : }
1202 : if (DoublePassRenderingEvent() == npevent->event) {
1203 : CallPaint(npremoteevent, &handled);
1204 : return handled;
1205 : }
1206 :
1207 : switch (npevent->event) {
1208 : case WM_PAINT:
1209 : {
1210 : RECT rect;
1211 : SharedSurfaceBeforePaint(rect, npremoteevent);
1212 : CallPaint(npremoteevent, &handled);
1213 : SharedSurfaceAfterPaint(npevent);
1214 : return handled;
1215 : }
1216 : break;
1217 :
1218 : case WM_KILLFOCUS:
1219 : {
1220 : // When the user selects fullscreen mode in Flash video players,
1221 : // WM_KILLFOCUS will be delayed by deferred event processing:
1222 : // WM_LBUTTONUP results in a call to CreateWindow within Flash,
1223 : // which fires WM_KILLFOCUS. Delayed delivery causes Flash to
1224 : // misinterpret the event, dropping back out of fullscreen. Trap
1225 : // this event and drop it.
1226 : PRUnichar szClass[26];
1227 : HWND hwnd = GetForegroundWindow();
1228 : if (hwnd && hwnd != mPluginHWND &&
1229 : GetClassNameW(hwnd, szClass,
1230 : sizeof(szClass)/sizeof(PRUnichar)) &&
1231 : !wcscmp(szClass, kFlashFullscreenClass)) {
1232 : return 0;
1233 : }
1234 : }
1235 : break;
1236 :
1237 : case WM_WINDOWPOSCHANGED:
1238 : {
1239 : // We send this in nsObjectFrame just before painting
1240 : SendWindowPosChanged(npremoteevent);
1241 : // nsObjectFrame doesn't care whether we handle this
1242 : // or not, just returning 1 for good hygiene
1243 : return 1;
1244 : }
1245 : break;
1246 : }
1247 : }
1248 : #endif
1249 :
1250 : #if defined(MOZ_X11)
1251 0 : switch (npevent->type) {
1252 : case GraphicsExpose:
1253 0 : PLUGIN_LOG_DEBUG((" schlepping drawable 0x%lx across the pipe\n",
1254 : npevent->xgraphicsexpose.drawable));
1255 : // Make sure the X server has created the Drawable and completes any
1256 : // drawing before the plugin draws on top.
1257 : //
1258 : // XSync() waits for the X server to complete. Really this parent
1259 : // process does not need to wait; the child is the process that needs
1260 : // to wait. A possibly-slightly-better alternative would be to send
1261 : // an X event to the child that the child would wait for.
1262 0 : XSync(DefaultXDisplay(), False);
1263 :
1264 0 : return CallPaint(npremoteevent, &handled) ? handled : 0;
1265 :
1266 : case ButtonPress:
1267 : // Release any active pointer grab so that the plugin X client can
1268 : // grab the pointer if it wishes.
1269 0 : Display *dpy = DefaultXDisplay();
1270 : # ifdef MOZ_WIDGET_GTK2
1271 : // GDK attempts to (asynchronously) track whether there is an active
1272 : // grab so ungrab through GDK.
1273 0 : gdk_pointer_ungrab(npevent->xbutton.time);
1274 : # else
1275 : XUngrabPointer(dpy, npevent->xbutton.time);
1276 : # endif
1277 : // Wait for the ungrab to complete.
1278 0 : XSync(dpy, False);
1279 0 : break;
1280 : }
1281 : #endif
1282 :
1283 : #ifdef XP_MACOSX
1284 : if (npevent->type == NPCocoaEventDrawRect) {
1285 : if (mDrawingModel == NPDrawingModelCoreAnimation ||
1286 : mDrawingModel == NPDrawingModelInvalidatingCoreAnimation) {
1287 : if (!mIOSurface) {
1288 : NS_ERROR("No IOSurface allocated.");
1289 : return false;
1290 : }
1291 : if (!CallNPP_HandleEvent_IOSurface(npremoteevent,
1292 : mIOSurface->GetIOSurfaceID(),
1293 : &handled))
1294 : return false; // no good way to handle errors here...
1295 :
1296 : CGContextRef cgContext = npevent->data.draw.context;
1297 : if (!mShColorSpace) {
1298 : mShColorSpace = CreateSystemColorSpace();
1299 : }
1300 : if (!mShColorSpace) {
1301 : PLUGIN_LOG_DEBUG(("Could not allocate ColorSpace."));
1302 : return false;
1303 : }
1304 : if (cgContext) {
1305 : nsCARenderer::DrawSurfaceToCGContext(cgContext, mIOSurface,
1306 : mShColorSpace,
1307 : npevent->data.draw.x,
1308 : npevent->data.draw.y,
1309 : npevent->data.draw.width,
1310 : npevent->data.draw.height);
1311 : }
1312 : return true;
1313 : } else if (mFrontIOSurface) {
1314 : CGContextRef cgContext = npevent->data.draw.context;
1315 : if (!mShColorSpace) {
1316 : mShColorSpace = CreateSystemColorSpace();
1317 : }
1318 : if (!mShColorSpace) {
1319 : PLUGIN_LOG_DEBUG(("Could not allocate ColorSpace."));
1320 : return false;
1321 : }
1322 : if (cgContext) {
1323 : nsCARenderer::DrawSurfaceToCGContext(cgContext, mFrontIOSurface,
1324 : mShColorSpace,
1325 : npevent->data.draw.x,
1326 : npevent->data.draw.y,
1327 : npevent->data.draw.width,
1328 : npevent->data.draw.height);
1329 : }
1330 : return true;
1331 : } else {
1332 : if (mShWidth == 0 && mShHeight == 0) {
1333 : PLUGIN_LOG_DEBUG(("NPCocoaEventDrawRect on window of size 0."));
1334 : return false;
1335 : }
1336 : if (!mShSurface.IsReadable()) {
1337 : PLUGIN_LOG_DEBUG(("Shmem is not readable."));
1338 : return false;
1339 : }
1340 :
1341 : if (!CallNPP_HandleEvent_Shmem(npremoteevent, mShSurface,
1342 : &handled, &mShSurface))
1343 : return false; // no good way to handle errors here...
1344 :
1345 : if (!mShSurface.IsReadable()) {
1346 : PLUGIN_LOG_DEBUG(("Shmem not returned. Either the plugin crashed "
1347 : "or we have a bug."));
1348 : return false;
1349 : }
1350 :
1351 : char* shContextByte = mShSurface.get<char>();
1352 :
1353 : if (!mShColorSpace) {
1354 : mShColorSpace = CreateSystemColorSpace();
1355 : }
1356 : if (!mShColorSpace) {
1357 : PLUGIN_LOG_DEBUG(("Could not allocate ColorSpace."));
1358 : return false;
1359 : }
1360 : CGContextRef shContext = ::CGBitmapContextCreate(shContextByte,
1361 : mShWidth, mShHeight, 8,
1362 : mShWidth*4, mShColorSpace,
1363 : kCGImageAlphaPremultipliedFirst |
1364 : kCGBitmapByteOrder32Host);
1365 : if (!shContext) {
1366 : PLUGIN_LOG_DEBUG(("Could not allocate CGBitmapContext."));
1367 : return false;
1368 : }
1369 :
1370 : CGImageRef shImage = ::CGBitmapContextCreateImage(shContext);
1371 : if (shImage) {
1372 : CGContextRef cgContext = npevent->data.draw.context;
1373 :
1374 : ::CGContextDrawImage(cgContext,
1375 : CGRectMake(0,0,mShWidth,mShHeight),
1376 : shImage);
1377 : ::CGImageRelease(shImage);
1378 : } else {
1379 : ::CGContextRelease(shContext);
1380 : return false;
1381 : }
1382 : ::CGContextRelease(shContext);
1383 : return true;
1384 : }
1385 : }
1386 : #endif
1387 :
1388 0 : if (!CallNPP_HandleEvent(npremoteevent, &handled))
1389 0 : return 0; // no good way to handle errors here...
1390 :
1391 0 : return handled;
1392 : }
1393 :
1394 : NPError
1395 0 : PluginInstanceParent::NPP_NewStream(NPMIMEType type, NPStream* stream,
1396 : NPBool seekable, uint16_t* stype)
1397 : {
1398 0 : PLUGIN_LOG_DEBUG(("%s (type=%s, stream=%p, seekable=%i)",
1399 : FULLFUNCTION, (char*) type, (void*) stream, (int) seekable));
1400 :
1401 0 : BrowserStreamParent* bs = new BrowserStreamParent(this, stream);
1402 :
1403 : NPError err;
1404 0 : if (!CallPBrowserStreamConstructor(bs,
1405 0 : NullableString(stream->url),
1406 : stream->end,
1407 : stream->lastmodified,
1408 : static_cast<PStreamNotifyParent*>(stream->notifyData),
1409 0 : NullableString(stream->headers),
1410 0 : NullableString(type), seekable,
1411 0 : &err, stype))
1412 0 : return NPERR_GENERIC_ERROR;
1413 :
1414 0 : if (NPERR_NO_ERROR != err)
1415 0 : unused << PBrowserStreamParent::Send__delete__(bs);
1416 :
1417 0 : return err;
1418 : }
1419 :
1420 : NPError
1421 0 : PluginInstanceParent::NPP_DestroyStream(NPStream* stream, NPReason reason)
1422 : {
1423 0 : PLUGIN_LOG_DEBUG(("%s (stream=%p, reason=%i)",
1424 : FULLFUNCTION, (void*) stream, (int) reason));
1425 :
1426 0 : AStream* s = static_cast<AStream*>(stream->pdata);
1427 0 : if (s->IsBrowserStream()) {
1428 : BrowserStreamParent* sp =
1429 0 : static_cast<BrowserStreamParent*>(s);
1430 0 : if (sp->mNPP != this)
1431 0 : NS_RUNTIMEABORT("Mismatched plugin data");
1432 :
1433 0 : sp->NPP_DestroyStream(reason);
1434 0 : return NPERR_NO_ERROR;
1435 : }
1436 : else {
1437 : PluginStreamParent* sp =
1438 0 : static_cast<PluginStreamParent*>(s);
1439 0 : if (sp->mInstance != this)
1440 0 : NS_RUNTIMEABORT("Mismatched plugin data");
1441 :
1442 0 : return PPluginStreamParent::Call__delete__(sp, reason, false) ?
1443 0 : NPERR_NO_ERROR : NPERR_GENERIC_ERROR;
1444 : }
1445 : }
1446 :
1447 : void
1448 0 : PluginInstanceParent::NPP_Print(NPPrint* platformPrint)
1449 : {
1450 : // TODO: implement me
1451 0 : NS_ERROR("Not implemented");
1452 0 : }
1453 :
1454 : PPluginScriptableObjectParent*
1455 0 : PluginInstanceParent::AllocPPluginScriptableObject()
1456 : {
1457 0 : return new PluginScriptableObjectParent(Proxy);
1458 : }
1459 :
1460 : #ifdef DEBUG
1461 : namespace {
1462 :
1463 : struct ActorSearchData
1464 : {
1465 : PluginScriptableObjectParent* actor;
1466 : bool found;
1467 : };
1468 :
1469 : PLDHashOperator
1470 0 : ActorSearch(const void* aKey,
1471 : PluginScriptableObjectParent* aData,
1472 : void* aUserData)
1473 : {
1474 0 : ActorSearchData* asd = reinterpret_cast<ActorSearchData*>(aUserData);
1475 0 : if (asd->actor == aData) {
1476 0 : asd->found = true;
1477 0 : return PL_DHASH_STOP;
1478 : }
1479 0 : return PL_DHASH_NEXT;
1480 : }
1481 :
1482 : } // anonymous namespace
1483 : #endif // DEBUG
1484 :
1485 : bool
1486 0 : PluginInstanceParent::DeallocPPluginScriptableObject(
1487 : PPluginScriptableObjectParent* aObject)
1488 : {
1489 : PluginScriptableObjectParent* actor =
1490 0 : static_cast<PluginScriptableObjectParent*>(aObject);
1491 :
1492 0 : NPObject* object = actor->GetObject(false);
1493 0 : if (object) {
1494 0 : NS_ASSERTION(mScriptableObjects.Get(object, nsnull),
1495 : "NPObject not in the hash!");
1496 0 : mScriptableObjects.Remove(object);
1497 : }
1498 : #ifdef DEBUG
1499 : else {
1500 0 : ActorSearchData asd = { actor, false };
1501 0 : mScriptableObjects.EnumerateRead(ActorSearch, &asd);
1502 0 : NS_ASSERTION(!asd.found, "Actor in the hash with a null NPObject!");
1503 : }
1504 : #endif
1505 :
1506 0 : delete actor;
1507 0 : return true;
1508 : }
1509 :
1510 : bool
1511 0 : PluginInstanceParent::RecvPPluginScriptableObjectConstructor(
1512 : PPluginScriptableObjectParent* aActor)
1513 : {
1514 : // This is only called in response to the child process requesting the
1515 : // creation of an actor. This actor will represent an NPObject that is
1516 : // created by the plugin and returned to the browser.
1517 : PluginScriptableObjectParent* actor =
1518 0 : static_cast<PluginScriptableObjectParent*>(aActor);
1519 0 : NS_ASSERTION(!actor->GetObject(false), "Actor already has an object?!");
1520 :
1521 0 : actor->InitializeProxy();
1522 0 : NS_ASSERTION(actor->GetObject(false), "Actor should have an object!");
1523 :
1524 0 : return true;
1525 : }
1526 :
1527 : void
1528 0 : PluginInstanceParent::NPP_URLNotify(const char* url, NPReason reason,
1529 : void* notifyData)
1530 : {
1531 0 : PLUGIN_LOG_DEBUG(("%s (%s, %i, %p)",
1532 : FULLFUNCTION, url, (int) reason, notifyData));
1533 :
1534 : PStreamNotifyParent* streamNotify =
1535 0 : static_cast<PStreamNotifyParent*>(notifyData);
1536 0 : unused << PStreamNotifyParent::Send__delete__(streamNotify, reason);
1537 0 : }
1538 :
1539 : bool
1540 0 : PluginInstanceParent::RegisterNPObjectForActor(
1541 : NPObject* aObject,
1542 : PluginScriptableObjectParent* aActor)
1543 : {
1544 0 : NS_ASSERTION(aObject && aActor, "Null pointers!");
1545 0 : NS_ASSERTION(mScriptableObjects.IsInitialized(), "Hash not initialized!");
1546 0 : NS_ASSERTION(!mScriptableObjects.Get(aObject, nsnull), "Duplicate entry!");
1547 0 : return !!mScriptableObjects.Put(aObject, aActor);
1548 : }
1549 :
1550 : void
1551 0 : PluginInstanceParent::UnregisterNPObject(NPObject* aObject)
1552 : {
1553 0 : NS_ASSERTION(aObject, "Null pointer!");
1554 0 : NS_ASSERTION(mScriptableObjects.IsInitialized(), "Hash not initialized!");
1555 0 : NS_ASSERTION(mScriptableObjects.Get(aObject, nsnull), "Unknown entry!");
1556 0 : mScriptableObjects.Remove(aObject);
1557 0 : }
1558 :
1559 : PluginScriptableObjectParent*
1560 0 : PluginInstanceParent::GetActorForNPObject(NPObject* aObject)
1561 : {
1562 0 : NS_ASSERTION(aObject, "Null pointer!");
1563 :
1564 0 : if (aObject->_class == PluginScriptableObjectParent::GetClass()) {
1565 : // One of ours!
1566 0 : ParentNPObject* object = static_cast<ParentNPObject*>(aObject);
1567 0 : NS_ASSERTION(object->parent, "Null actor!");
1568 0 : return object->parent;
1569 : }
1570 :
1571 : PluginScriptableObjectParent* actor;
1572 0 : if (mScriptableObjects.Get(aObject, &actor)) {
1573 0 : return actor;
1574 : }
1575 :
1576 0 : actor = new PluginScriptableObjectParent(LocalObject);
1577 0 : if (!actor) {
1578 0 : NS_ERROR("Out of memory!");
1579 0 : return nsnull;
1580 : }
1581 :
1582 0 : if (!SendPPluginScriptableObjectConstructor(actor)) {
1583 0 : NS_WARNING("Failed to send constructor message!");
1584 0 : return nsnull;
1585 : }
1586 :
1587 0 : actor->InitializeLocal(aObject);
1588 0 : return actor;
1589 : }
1590 :
1591 : PPluginSurfaceParent*
1592 0 : PluginInstanceParent::AllocPPluginSurface(const WindowsSharedMemoryHandle& handle,
1593 : const gfxIntSize& size,
1594 : const bool& transparent)
1595 : {
1596 : #ifdef XP_WIN
1597 : return new PluginSurfaceParent(handle, size, transparent);
1598 : #else
1599 0 : NS_ERROR("This shouldn't be called!");
1600 0 : return NULL;
1601 : #endif
1602 : }
1603 :
1604 : bool
1605 0 : PluginInstanceParent::DeallocPPluginSurface(PPluginSurfaceParent* s)
1606 : {
1607 : #ifdef XP_WIN
1608 : delete s;
1609 : return true;
1610 : #else
1611 0 : return false;
1612 : #endif
1613 : }
1614 :
1615 : bool
1616 0 : PluginInstanceParent::AnswerNPN_PushPopupsEnabledState(const bool& aState)
1617 : {
1618 0 : mNPNIface->pushpopupsenabledstate(mNPP, aState ? 1 : 0);
1619 0 : return true;
1620 : }
1621 :
1622 : bool
1623 0 : PluginInstanceParent::AnswerNPN_PopPopupsEnabledState()
1624 : {
1625 0 : mNPNIface->poppopupsenabledstate(mNPP);
1626 0 : return true;
1627 : }
1628 :
1629 : bool
1630 0 : PluginInstanceParent::AnswerNPN_GetValueForURL(const NPNURLVariable& variable,
1631 : const nsCString& url,
1632 : nsCString* value,
1633 : NPError* result)
1634 : {
1635 : char* v;
1636 : uint32_t len;
1637 :
1638 : *result = mNPNIface->getvalueforurl(mNPP, (NPNURLVariable) variable,
1639 0 : url.get(), &v, &len);
1640 0 : if (NPERR_NO_ERROR == *result)
1641 0 : value->Adopt(v, len);
1642 :
1643 0 : return true;
1644 : }
1645 :
1646 : bool
1647 0 : PluginInstanceParent::AnswerNPN_SetValueForURL(const NPNURLVariable& variable,
1648 : const nsCString& url,
1649 : const nsCString& value,
1650 : NPError* result)
1651 : {
1652 : *result = mNPNIface->setvalueforurl(mNPP, (NPNURLVariable) variable,
1653 : url.get(), value.get(),
1654 0 : value.Length());
1655 0 : return true;
1656 : }
1657 :
1658 : bool
1659 0 : PluginInstanceParent::AnswerNPN_GetAuthenticationInfo(const nsCString& protocol,
1660 : const nsCString& host,
1661 : const int32_t& port,
1662 : const nsCString& scheme,
1663 : const nsCString& realm,
1664 : nsCString* username,
1665 : nsCString* password,
1666 : NPError* result)
1667 : {
1668 : char* u;
1669 : uint32_t ulen;
1670 : char* p;
1671 : uint32_t plen;
1672 :
1673 : *result = mNPNIface->getauthenticationinfo(mNPP, protocol.get(),
1674 : host.get(), port,
1675 : scheme.get(), realm.get(),
1676 0 : &u, &ulen, &p, &plen);
1677 0 : if (NPERR_NO_ERROR == *result) {
1678 0 : username->Adopt(u, ulen);
1679 0 : password->Adopt(p, plen);
1680 : }
1681 0 : return true;
1682 : }
1683 :
1684 : bool
1685 0 : PluginInstanceParent::AnswerNPN_ConvertPoint(const double& sourceX,
1686 : const bool& ignoreDestX,
1687 : const double& sourceY,
1688 : const bool& ignoreDestY,
1689 : const NPCoordinateSpace& sourceSpace,
1690 : const NPCoordinateSpace& destSpace,
1691 : double *destX,
1692 : double *destY,
1693 : bool *result)
1694 : {
1695 : *result = mNPNIface->convertpoint(mNPP, sourceX, sourceY, sourceSpace,
1696 : ignoreDestX ? nsnull : destX,
1697 : ignoreDestY ? nsnull : destY,
1698 0 : destSpace);
1699 :
1700 0 : return true;
1701 : }
1702 :
1703 : bool
1704 0 : PluginInstanceParent::AnswerNPN_InitAsyncSurface(const gfxIntSize& size,
1705 : const NPImageFormat& format,
1706 : NPRemoteAsyncSurface* surfData,
1707 : bool* result)
1708 : {
1709 0 : if (!IsAsyncDrawing()) {
1710 0 : *result = false;
1711 0 : return true;
1712 : }
1713 :
1714 0 : switch (mDrawingModel) {
1715 : case NPDrawingModelAsyncBitmapSurface: {
1716 0 : Shmem sharedMem;
1717 0 : if (!AllocUnsafeShmem(size.width * size.height * 4, SharedMemory::TYPE_BASIC, &sharedMem)) {
1718 0 : *result = false;
1719 0 : return true;
1720 : }
1721 :
1722 0 : surfData->size() = size;
1723 0 : surfData->hostPtr() = (uintptr_t)sharedMem.get<unsigned char>();
1724 0 : surfData->stride() = size.width * 4;
1725 0 : surfData->format() = format;
1726 0 : surfData->data() = sharedMem;
1727 0 : *result = true;
1728 : }
1729 : }
1730 :
1731 0 : return true;
1732 : }
1733 :
1734 : bool
1735 0 : PluginInstanceParent::RecvRedrawPlugin()
1736 : {
1737 0 : nsNPAPIPluginInstance *inst = static_cast<nsNPAPIPluginInstance*>(mNPP->ndata);
1738 0 : if (!inst) {
1739 0 : return false;
1740 : }
1741 :
1742 0 : inst->RedrawPlugin();
1743 0 : return true;
1744 : }
1745 :
1746 : bool
1747 0 : PluginInstanceParent::RecvNegotiatedCarbon()
1748 : {
1749 0 : nsNPAPIPluginInstance *inst = static_cast<nsNPAPIPluginInstance*>(mNPP->ndata);
1750 0 : if (!inst) {
1751 0 : return false;
1752 : }
1753 0 : inst->CarbonNPAPIFailure();
1754 0 : return true;
1755 : }
1756 :
1757 : #if defined(OS_WIN)
1758 :
1759 : /*
1760 : plugin focus changes between processes
1761 :
1762 : focus from dom -> child:
1763 : Focus manager calls on widget to set the focus on the window.
1764 : We pick up the resulting wm_setfocus event here, and forward
1765 : that over ipc to the child which calls set focus on itself.
1766 :
1767 : focus from child -> focus manager:
1768 : Child picks up the local wm_setfocus and sends it via ipc over
1769 : here. We then post a custom event to widget/windows/nswindow
1770 : which fires off a gui event letting the browser know.
1771 : */
1772 :
1773 : static const PRUnichar kPluginInstanceParentProperty[] =
1774 : L"PluginInstanceParentProperty";
1775 :
1776 : // static
1777 : LRESULT CALLBACK
1778 : PluginInstanceParent::PluginWindowHookProc(HWND hWnd,
1779 : UINT message,
1780 : WPARAM wParam,
1781 : LPARAM lParam)
1782 : {
1783 : PluginInstanceParent* self = reinterpret_cast<PluginInstanceParent*>(
1784 : ::GetPropW(hWnd, kPluginInstanceParentProperty));
1785 : if (!self) {
1786 : NS_NOTREACHED("PluginInstanceParent::PluginWindowHookProc null this ptr!");
1787 : return DefWindowProc(hWnd, message, wParam, lParam);
1788 : }
1789 :
1790 : NS_ASSERTION(self->mPluginHWND == hWnd, "Wrong window!");
1791 :
1792 : switch (message) {
1793 : case WM_SETFOCUS:
1794 : // Let the child plugin window know it should take focus.
1795 : self->CallSetPluginFocus();
1796 : break;
1797 :
1798 : case WM_CLOSE:
1799 : self->UnsubclassPluginWindow();
1800 : break;
1801 : }
1802 :
1803 : if (self->mPluginWndProc == PluginWindowHookProc) {
1804 : NS_NOTREACHED(
1805 : "PluginWindowHookProc invoking mPluginWndProc w/"
1806 : "mPluginWndProc == PluginWindowHookProc????");
1807 : return DefWindowProc(hWnd, message, wParam, lParam);
1808 : }
1809 : return ::CallWindowProc(self->mPluginWndProc, hWnd, message, wParam,
1810 : lParam);
1811 : }
1812 :
1813 : void
1814 : PluginInstanceParent::SubclassPluginWindow(HWND aWnd)
1815 : {
1816 : NS_ASSERTION(!(mPluginHWND && aWnd != mPluginHWND),
1817 : "PluginInstanceParent::SubclassPluginWindow hwnd is not our window!");
1818 :
1819 : if (!mPluginHWND) {
1820 : mPluginHWND = aWnd;
1821 : mPluginWndProc =
1822 : (WNDPROC)::SetWindowLongPtrA(mPluginHWND, GWLP_WNDPROC,
1823 : reinterpret_cast<LONG_PTR>(PluginWindowHookProc));
1824 : bool bRes = ::SetPropW(mPluginHWND, kPluginInstanceParentProperty, this);
1825 : NS_ASSERTION(mPluginWndProc,
1826 : "PluginInstanceParent::SubclassPluginWindow failed to set subclass!");
1827 : NS_ASSERTION(bRes,
1828 : "PluginInstanceParent::SubclassPluginWindow failed to set prop!");
1829 : }
1830 : }
1831 :
1832 : void
1833 : PluginInstanceParent::UnsubclassPluginWindow()
1834 : {
1835 : if (mPluginHWND && mPluginWndProc) {
1836 : ::SetWindowLongPtrA(mPluginHWND, GWLP_WNDPROC,
1837 : reinterpret_cast<LONG_PTR>(mPluginWndProc));
1838 :
1839 : ::RemovePropW(mPluginHWND, kPluginInstanceParentProperty);
1840 :
1841 : mPluginWndProc = NULL;
1842 : mPluginHWND = NULL;
1843 : }
1844 : }
1845 :
1846 : /* windowless drawing helpers */
1847 :
1848 : /*
1849 : * Origin info:
1850 : *
1851 : * windowless, offscreen:
1852 : *
1853 : * WM_WINDOWPOSCHANGED: origin is relative to container
1854 : * setwindow: origin is 0,0
1855 : * WM_PAINT: origin is 0,0
1856 : *
1857 : * windowless, native:
1858 : *
1859 : * WM_WINDOWPOSCHANGED: origin is relative to container
1860 : * setwindow: origin is relative to container
1861 : * WM_PAINT: origin is relative to container
1862 : *
1863 : * PluginInstanceParent:
1864 : *
1865 : * painting: mPluginPort (nsIntRect, saved in SetWindow)
1866 : */
1867 :
1868 : void
1869 : PluginInstanceParent::SharedSurfaceRelease()
1870 : {
1871 : mSharedSurfaceDib.Close();
1872 : }
1873 :
1874 : bool
1875 : PluginInstanceParent::SharedSurfaceSetWindow(const NPWindow* aWindow,
1876 : NPRemoteWindow& aRemoteWindow)
1877 : {
1878 : aRemoteWindow.window = nsnull;
1879 : aRemoteWindow.x = aWindow->x;
1880 : aRemoteWindow.y = aWindow->y;
1881 : aRemoteWindow.width = aWindow->width;
1882 : aRemoteWindow.height = aWindow->height;
1883 : aRemoteWindow.type = aWindow->type;
1884 :
1885 : nsIntRect newPort(aWindow->x, aWindow->y, aWindow->width, aWindow->height);
1886 :
1887 : // save the the rect location within the browser window.
1888 : mPluginPort = newPort;
1889 :
1890 : // move the port to our shared surface origin
1891 : newPort.MoveTo(0,0);
1892 :
1893 : // check to see if we have the room in shared surface
1894 : if (mSharedSurfaceDib.IsValid() && mSharedSize.Contains(newPort)) {
1895 : // ok to paint
1896 : aRemoteWindow.surfaceHandle = 0;
1897 : return true;
1898 : }
1899 :
1900 : // allocate a new shared surface
1901 : SharedSurfaceRelease();
1902 : if (NS_FAILED(mSharedSurfaceDib.Create(reinterpret_cast<HDC>(aWindow->window),
1903 : newPort.width, newPort.height, false)))
1904 : return false;
1905 :
1906 : // save the new shared surface size we just allocated
1907 : mSharedSize = newPort;
1908 :
1909 : base::SharedMemoryHandle handle;
1910 : if (NS_FAILED(mSharedSurfaceDib.ShareToProcess(mParent->ChildProcessHandle(), &handle)))
1911 : return false;
1912 :
1913 : aRemoteWindow.surfaceHandle = handle;
1914 :
1915 : return true;
1916 : }
1917 :
1918 : void
1919 : PluginInstanceParent::SharedSurfaceBeforePaint(RECT& rect,
1920 : NPRemoteEvent& npremoteevent)
1921 : {
1922 : RECT* dr = (RECT*)npremoteevent.event.lParam;
1923 : HDC parentHdc = (HDC)npremoteevent.event.wParam;
1924 :
1925 : nsIntRect dirtyRect(dr->left, dr->top, dr->right-dr->left, dr->bottom-dr->top);
1926 : dirtyRect.MoveBy(-mPluginPort.x, -mPluginPort.y); // should always be smaller than dirtyRect
1927 :
1928 : ::BitBlt(mSharedSurfaceDib.GetHDC(),
1929 : dirtyRect.x,
1930 : dirtyRect.y,
1931 : dirtyRect.width,
1932 : dirtyRect.height,
1933 : parentHdc,
1934 : dr->left,
1935 : dr->top,
1936 : SRCCOPY);
1937 :
1938 : // setup the translated dirty rect we'll send to the child
1939 : rect.left = dirtyRect.x;
1940 : rect.top = dirtyRect.y;
1941 : rect.right = dirtyRect.x + dirtyRect.width;
1942 : rect.bottom = dirtyRect.y + dirtyRect.height;
1943 :
1944 : npremoteevent.event.wParam = WPARAM(0);
1945 : npremoteevent.event.lParam = LPARAM(&rect);
1946 : }
1947 :
1948 : void
1949 : PluginInstanceParent::SharedSurfaceAfterPaint(NPEvent* npevent)
1950 : {
1951 : RECT* dr = (RECT*)npevent->lParam;
1952 : HDC parentHdc = (HDC)npevent->wParam;
1953 :
1954 : nsIntRect dirtyRect(dr->left, dr->top, dr->right-dr->left, dr->bottom-dr->top);
1955 : dirtyRect.MoveBy(-mPluginPort.x, -mPluginPort.y);
1956 :
1957 : // src copy the shared dib into the parent surface we are handed.
1958 : ::BitBlt(parentHdc,
1959 : dr->left,
1960 : dr->top,
1961 : dirtyRect.width,
1962 : dirtyRect.height,
1963 : mSharedSurfaceDib.GetHDC(),
1964 : dirtyRect.x,
1965 : dirtyRect.y,
1966 : SRCCOPY);
1967 : }
1968 :
1969 : #endif // defined(OS_WIN)
1970 :
1971 : bool
1972 0 : PluginInstanceParent::AnswerPluginFocusChange(const bool& gotFocus)
1973 : {
1974 0 : PLUGIN_LOG_DEBUG(("%s", FULLFUNCTION));
1975 :
1976 : // Currently only in use on windows - an rpc event we receive from the
1977 : // child when it's plugin window (or one of it's children) receives keyboard
1978 : // focus. We forward the event down to widget so the dom/focus manager can
1979 : // be updated.
1980 : #if defined(OS_WIN)
1981 : ::SendMessage(mPluginHWND, gOOPPPluginFocusEvent, gotFocus ? 1 : 0, 0);
1982 : return true;
1983 : #else
1984 0 : NS_NOTREACHED("PluginInstanceParent::AnswerPluginFocusChange not implemented!");
1985 0 : return false;
1986 : #endif
1987 : }
|