Bug 536369 - OOPP: Add NPNVnetscapeWindow support for windows. r=bsmedberg.
[mozilla-central.git] / dom / plugins / PluginInstanceParent.cpp
blob2c7740eefd86c95e1c85bf6940afd87c0b2cf79a
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
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/
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.
16 * The Original Code is Mozilla Plugin App.
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.
23 * Contributor(s):
24 * Jim Mathies <jmathies@mozilla.com>
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.
38 * ***** END LICENSE BLOCK ***** */
40 #include "PluginInstanceParent.h"
42 #include "BrowserStreamParent.h"
43 #include "PluginModuleParent.h"
44 #include "PluginStreamParent.h"
45 #include "StreamNotifyParent.h"
47 #include "npfunctions.h"
48 #include "nsAutoPtr.h"
50 #if defined(OS_WIN)
51 #include <windowsx.h>
52 #endif
54 using namespace mozilla::plugins;
56 PluginInstanceParent::PluginInstanceParent(PluginModuleParent* parent,
57 NPP npp,
58 const NPNetscapeFuncs* npniface)
59 : mParent(parent),
60 mNPP(npp),
61 mNPNIface(npniface),
62 mWindowType(NPWindowTypeWindow)
66 PluginInstanceParent::~PluginInstanceParent()
68 if (mNPP)
69 mNPP->pdata = NULL;
72 void
73 PluginInstanceParent::Destroy()
75 // Copy the actors here so we don't enumerate a mutating array.
76 nsAutoTArray<PluginScriptableObjectParent*, 10> objects;
77 PRUint32 count = mScriptableObjects.Length();
78 for (PRUint32 index = 0; index < count; index++) {
79 objects.AppendElement(mScriptableObjects[index]);
82 count = objects.Length();
83 for (PRUint32 index = 0; index < count; index++) {
84 NPObject* object = objects[index]->GetObject();
85 if (object->_class == PluginScriptableObjectParent::GetClass()) {
86 PluginScriptableObjectParent::ScriptableInvalidate(object);
90 #if defined(OS_WIN)
91 SharedSurfaceRelease();
92 #endif
95 PBrowserStreamParent*
96 PluginInstanceParent::AllocPBrowserStream(const nsCString& url,
97 const uint32_t& length,
98 const uint32_t& lastmodified,
99 PStreamNotifyParent* notifyData,
100 const nsCString& headers,
101 const nsCString& mimeType,
102 const bool& seekable,
103 NPError* rv,
104 uint16_t *stype)
106 NS_RUNTIMEABORT("Not reachable");
107 return NULL;
110 bool
111 PluginInstanceParent::DeallocPBrowserStream(PBrowserStreamParent* stream)
113 delete stream;
114 return true;
117 PPluginStreamParent*
118 PluginInstanceParent::AllocPPluginStream(const nsCString& mimeType,
119 const nsCString& target,
120 NPError* result)
122 return new PluginStreamParent(this, mimeType, target, result);
125 bool
126 PluginInstanceParent::DeallocPPluginStream(PPluginStreamParent* stream)
128 delete stream;
129 return true;
132 bool
133 PluginInstanceParent::AnswerNPN_GetValue_NPNVjavascriptEnabledBool(
134 bool* value,
135 NPError* result)
137 NPBool v;
138 *result = mNPNIface->getvalue(mNPP, NPNVjavascriptEnabledBool, &v);
139 *value = v;
140 return true;
143 bool
144 PluginInstanceParent::AnswerNPN_GetValue_NPNVisOfflineBool(bool* value,
145 NPError* result)
147 NPBool v;
148 *result = mNPNIface->getvalue(mNPP, NPNVisOfflineBool, &v);
149 *value = v;
150 return true;
153 bool
154 PluginInstanceParent::AnswerNPN_GetValue_NPNVnetscapeWindow(intptr_t* value,
155 NPError* result)
157 #ifdef XP_WIN
158 HWND hwnd;
159 *result = mNPNIface->getvalue(mNPP, NPNVnetscapeWindow, &hwnd);
160 *value = (intptr_t)hwnd;
161 return true;
162 #endif
163 return false;
166 bool
167 PluginInstanceParent::InternalGetValueForNPObject(
168 NPNVariable aVariable,
169 PPluginScriptableObjectParent** aValue,
170 NPError* aResult)
172 NPObject* npobject;
173 NPError result = mNPNIface->getvalue(mNPP, aVariable, (void*)&npobject);
174 if (result == NPERR_NO_ERROR) {
175 NS_ASSERTION(npobject, "Shouldn't return null and NPERR_NO_ERROR!");
177 PluginScriptableObjectParent* actor = GetActorForNPObject(npobject);
178 mNPNIface->releaseobject(npobject);
179 if (actor) {
180 *aValue = actor;
181 *aResult = NPERR_NO_ERROR;
182 return true;
185 NS_ERROR("Failed to get actor!");
186 result = NPERR_GENERIC_ERROR;
189 *aValue = nsnull;
190 *aResult = result;
191 return true;
194 bool
195 PluginInstanceParent::AnswerNPN_GetValue_NPNVWindowNPObject(
196 PPluginScriptableObjectParent** aValue,
197 NPError* aResult)
199 return InternalGetValueForNPObject(NPNVWindowNPObject, aValue, aResult);
202 bool
203 PluginInstanceParent::AnswerNPN_GetValue_NPNVPluginElementNPObject(
204 PPluginScriptableObjectParent** aValue,
205 NPError* aResult)
207 return InternalGetValueForNPObject(NPNVPluginElementNPObject, aValue,
208 aResult);
211 bool
212 PluginInstanceParent::AnswerNPN_GetValue_NPNVprivateModeBool(bool* value,
213 NPError* result)
215 NPBool v;
216 *result = mNPNIface->getvalue(mNPP, NPNVprivateModeBool, &v);
217 *value = v;
218 return true;
222 bool
223 PluginInstanceParent::AnswerNPN_SetValue_NPPVpluginWindow(
224 const bool& windowed, NPError* result)
226 NPBool isWindowed = windowed;
227 *result = mNPNIface->setvalue(mNPP, NPPVpluginWindowBool,
228 (void*)isWindowed);
229 return true;
232 bool
233 PluginInstanceParent::AnswerNPN_SetValue_NPPVpluginTransparent(
234 const bool& transparent, NPError* result)
236 NPBool isTransparent = transparent;
237 *result = mNPNIface->setvalue(mNPP, NPPVpluginTransparentBool,
238 (void*)isTransparent);
239 return true;
243 bool
244 PluginInstanceParent::AnswerNPN_GetURL(const nsCString& url,
245 const nsCString& target,
246 NPError* result)
248 *result = mNPNIface->geturl(mNPP,
249 NullableStringGet(url),
250 NullableStringGet(target));
251 return true;
254 bool
255 PluginInstanceParent::AnswerNPN_PostURL(const nsCString& url,
256 const nsCString& target,
257 const nsCString& buffer,
258 const bool& file,
259 NPError* result)
261 *result = mNPNIface->posturl(mNPP, url.get(), NullableStringGet(target),
262 buffer.Length(), buffer.get(), file);
263 return true;
266 PStreamNotifyParent*
267 PluginInstanceParent::AllocPStreamNotify(const nsCString& url,
268 const nsCString& target,
269 const bool& post,
270 const nsCString& buffer,
271 const bool& file,
272 NPError* result)
274 return new StreamNotifyParent();
277 bool
278 PluginInstanceParent::AnswerPStreamNotifyConstructor(PStreamNotifyParent* actor,
279 const nsCString& url,
280 const nsCString& target,
281 const bool& post,
282 const nsCString& buffer,
283 const bool& file,
284 NPError* result)
286 bool streamDestroyed = false;
287 static_cast<StreamNotifyParent*>(actor)->
288 SetDestructionFlag(&streamDestroyed);
290 if (!post) {
291 *result = mNPNIface->geturlnotify(mNPP,
292 NullableStringGet(url),
293 NullableStringGet(target),
294 actor);
296 else {
297 *result = mNPNIface->posturlnotify(mNPP,
298 NullableStringGet(url),
299 NullableStringGet(target),
300 buffer.Length(),
301 NullableStringGet(buffer),
302 file, actor);
305 if (!streamDestroyed) {
306 static_cast<StreamNotifyParent*>(actor)->ClearDestructionFlag();
307 if (*result != NPERR_NO_ERROR)
308 PStreamNotifyParent::Call__delete__(actor, NPERR_GENERIC_ERROR);
311 return true;
314 bool
315 PluginInstanceParent::DeallocPStreamNotify(PStreamNotifyParent* notifyData)
317 delete notifyData;
318 return true;
321 bool
322 PluginInstanceParent::RecvNPN_InvalidateRect(const NPRect& rect)
324 mNPNIface->invalidaterect(mNPP, const_cast<NPRect*>(&rect));
325 return true;
328 NPError
329 PluginInstanceParent::NPP_SetWindow(const NPWindow* aWindow)
331 PLUGIN_LOG_DEBUG(("%s (aWindow=%p)", FULLFUNCTION, (void*) aWindow));
333 NS_ENSURE_TRUE(aWindow, NPERR_GENERIC_ERROR);
335 NPRemoteWindow window;
336 mWindowType = aWindow->type;
338 #if defined(OS_WIN)
339 // On windowless controls, reset the shared memory surface as needed.
340 if (mWindowType == NPWindowTypeDrawable) {
341 // SharedSurfaceSetWindow will take care of NPRemoteWindow.
342 if (!SharedSurfaceSetWindow(aWindow, window)) {
343 return NPERR_OUT_OF_MEMORY_ERROR;
346 else {
347 window.window = reinterpret_cast<unsigned long>(aWindow->window);
348 window.x = aWindow->x;
349 window.y = aWindow->y;
350 window.width = aWindow->width;
351 window.height = aWindow->height;
352 window.type = aWindow->type;
354 #else
355 window.window = reinterpret_cast<unsigned long>(aWindow->window);
356 window.x = aWindow->x;
357 window.y = aWindow->y;
358 window.width = aWindow->width;
359 window.height = aWindow->height;
360 window.clipRect = aWindow->clipRect; // MacOS specific
361 window.type = aWindow->type;
362 #endif
364 #if defined(MOZ_X11) && defined(XP_UNIX) && !defined(XP_MACOSX)
365 const NPSetWindowCallbackStruct* ws_info =
366 static_cast<NPSetWindowCallbackStruct*>(aWindow->ws_info);
367 window.visualID = ws_info->visual ? ws_info->visual->visualid : None;
368 window.colormap = ws_info->colormap;
369 #endif
371 NPError prv;
372 if (!CallNPP_SetWindow(window, &prv))
373 return NPERR_GENERIC_ERROR;
374 return prv;
377 NPError
378 PluginInstanceParent::NPP_GetValue(NPPVariable aVariable,
379 void* _retval)
381 switch (aVariable) {
383 case NPPVpluginWindowBool: {
384 bool windowed;
385 NPError rv;
387 if (!CallNPP_GetValue_NPPVpluginWindow(&windowed, &rv)) {
388 return NPERR_GENERIC_ERROR;
391 if (NPERR_NO_ERROR != rv) {
392 return rv;
395 (*(NPBool*)_retval) = windowed;
396 return NPERR_NO_ERROR;
399 case NPPVpluginTransparentBool: {
400 bool transparent;
401 NPError rv;
403 if (!CallNPP_GetValue_NPPVpluginTransparent(&transparent, &rv)) {
404 return NPERR_GENERIC_ERROR;
407 if (NPERR_NO_ERROR != rv) {
408 return rv;
411 (*(NPBool*)_retval) = transparent;
412 return NPERR_NO_ERROR;
415 #ifdef OS_LINUX
416 case NPPVpluginNeedsXEmbed: {
417 bool needsXEmbed;
418 NPError rv;
420 if (!CallNPP_GetValue_NPPVpluginNeedsXEmbed(&needsXEmbed, &rv)) {
421 return NPERR_GENERIC_ERROR;
424 if (NPERR_NO_ERROR != rv) {
425 return rv;
428 (*(NPBool*)_retval) = needsXEmbed;
429 return NPERR_NO_ERROR;
431 #endif
433 case NPPVpluginScriptableNPObject: {
434 PPluginScriptableObjectParent* actor;
435 NPError rv;
436 if (!CallNPP_GetValue_NPPVpluginScriptableNPObject(&actor, &rv)) {
437 return NPERR_GENERIC_ERROR;
440 if (NPERR_NO_ERROR != rv) {
441 return rv;
444 if (!actor) {
445 NS_ERROR("NPPVpluginScriptableNPObject succeeded but null.");
446 return NPERR_GENERIC_ERROR;
449 const NPNetscapeFuncs* npn = mParent->GetNetscapeFuncs();
450 if (!npn) {
451 NS_WARNING("No netscape functions?!");
452 return NPERR_GENERIC_ERROR;
455 NPObject* object =
456 static_cast<PluginScriptableObjectParent*>(actor)->GetObject();
457 NS_ASSERTION(object, "This shouldn't ever be null!");
459 (*(NPObject**)_retval) = npn->retainobject(object);
460 return NPERR_NO_ERROR;
463 default:
464 PR_LOG(gPluginLog, PR_LOG_WARNING,
465 ("In PluginInstanceParent::NPP_GetValue: Unhandled NPPVariable %i (%s)",
466 (int) aVariable, NPPVariableToString(aVariable)));
467 return NPERR_GENERIC_ERROR;
471 int16_t
472 PluginInstanceParent::NPP_HandleEvent(void* event)
474 PLUGIN_LOG_DEBUG_FUNCTION;
476 NPEvent* npevent = reinterpret_cast<NPEvent*>(event);
477 NPRemoteEvent npremoteevent;
478 npremoteevent.event = *npevent;
479 int16_t handled;
481 #if defined(OS_WIN)
482 if (mWindowType == NPWindowTypeDrawable) {
483 switch(npevent->event) {
484 case WM_PAINT:
486 RECT rect;
487 SharedSurfaceBeforePaint(rect, npremoteevent);
488 if (!CallNPP_HandleEvent(npremoteevent, &handled))
489 return 0;
490 if (handled)
491 SharedSurfaceAfterPaint(npevent);
493 break;
494 default:
495 if (!CallNPP_HandleEvent(npremoteevent, &handled))
496 return 0;
497 break;
500 else {
501 if (!CallNPP_HandleEvent(npremoteevent, &handled))
502 return 0;
504 #endif
506 #if defined(MOZ_X11)
507 if (GraphicsExpose == npevent->type) {
508 printf(" schlepping drawable 0x%lx across the pipe\n",
509 npevent->xgraphicsexpose.drawable);
510 // Make sure the X server has created the Drawable and completes any
511 // drawing before the plugin draws on top.
513 // XSync() waits for the X server to complete. Really this parent
514 // process does not need to wait; the child is the process that needs
515 // to wait. A possibly-slightly-better alternative would be to send
516 // an X event to the child that the child would wait for.
517 # ifdef MOZ_WIDGET_GTK2
518 XSync(GDK_DISPLAY(), False);
519 # endif
522 if (!CallNPP_HandleEvent(npremoteevent, &handled))
523 return 0; // no good way to handle errors here...
524 #endif
526 return handled;
529 NPError
530 PluginInstanceParent::NPP_NewStream(NPMIMEType type, NPStream* stream,
531 NPBool seekable, uint16_t* stype)
533 PLUGIN_LOG_DEBUG(("%s (type=%s, stream=%p, seekable=%i)",
534 FULLFUNCTION, (char*) type, (void*) stream, (int) seekable));
536 BrowserStreamParent* bs = new BrowserStreamParent(this, stream);
538 NPError err;
539 if (!CallPBrowserStreamConstructor(bs,
540 NullableString(stream->url),
541 stream->end,
542 stream->lastmodified,
543 static_cast<PStreamNotifyParent*>(stream->notifyData),
544 NullableString(stream->headers),
545 NullableString(type), seekable,
546 &err, stype))
547 return NPERR_GENERIC_ERROR;
549 if (NPERR_NO_ERROR != err)
550 PBrowserStreamParent::Call__delete__(bs, NPERR_GENERIC_ERROR, true);
552 return err;
555 NPError
556 PluginInstanceParent::NPP_DestroyStream(NPStream* stream, NPReason reason)
558 PLUGIN_LOG_DEBUG(("%s (stream=%p, reason=%i)",
559 FULLFUNCTION, (void*) stream, (int) reason));
561 AStream* s = static_cast<AStream*>(stream->pdata);
562 if (s->IsBrowserStream()) {
563 BrowserStreamParent* sp =
564 static_cast<BrowserStreamParent*>(s);
565 if (sp->mNPP != this)
566 NS_RUNTIMEABORT("Mismatched plugin data");
568 PBrowserStreamParent::Call__delete__(sp, reason, false);
569 return NPERR_NO_ERROR;
571 else {
572 PluginStreamParent* sp =
573 static_cast<PluginStreamParent*>(s);
574 if (sp->mInstance != this)
575 NS_RUNTIMEABORT("Mismatched plugin data");
577 PPluginStreamParent::Call__delete__(sp, reason, false);
578 return NPERR_NO_ERROR;
582 PPluginScriptableObjectParent*
583 PluginInstanceParent::AllocPPluginScriptableObject()
585 nsAutoPtr<PluginScriptableObjectParent>* object =
586 mScriptableObjects.AppendElement();
587 NS_ENSURE_TRUE(object, nsnull);
589 *object = new PluginScriptableObjectParent();
590 NS_ENSURE_TRUE(*object, nsnull);
592 return object->get();
595 bool
596 PluginInstanceParent::DeallocPPluginScriptableObject(
597 PPluginScriptableObjectParent* aObject)
599 PluginScriptableObjectParent* object =
600 reinterpret_cast<PluginScriptableObjectParent*>(aObject);
602 PRUint32 count = mScriptableObjects.Length();
603 for (PRUint32 index = 0; index < count; index++) {
604 if (mScriptableObjects[index] == object) {
605 mScriptableObjects.RemoveElementAt(index);
606 return true;
609 NS_NOTREACHED("An actor we don't know about?!");
610 return false;
613 bool
614 PluginInstanceParent::AnswerPPluginScriptableObjectConstructor(
615 PPluginScriptableObjectParent* aActor)
617 // This is only called in response to the child process requesting the
618 // creation of an actor. This actor will represent an NPObject that is
619 // created by the plugin and returned to the browser.
620 const NPNetscapeFuncs* npn = mParent->GetNetscapeFuncs();
621 if (!npn) {
622 NS_WARNING("No netscape function pointers?!");
623 return false;
626 NPClass* npclass =
627 const_cast<NPClass*>(PluginScriptableObjectParent::GetClass());
629 ParentNPObject* object = reinterpret_cast<ParentNPObject*>(
630 npn->createobject(mNPP, npclass));
631 if (!object) {
632 NS_WARNING("Failed to create NPObject!");
633 return false;
636 static_cast<PluginScriptableObjectParent*>(aActor)->Initialize(
637 const_cast<PluginInstanceParent*>(this), object);
638 return true;
641 void
642 PluginInstanceParent::NPP_URLNotify(const char* url, NPReason reason,
643 void* notifyData)
645 PLUGIN_LOG_DEBUG(("%s (%s, %i, %p)",
646 FULLFUNCTION, url, (int) reason, notifyData));
648 PStreamNotifyParent* streamNotify =
649 static_cast<PStreamNotifyParent*>(notifyData);
650 PStreamNotifyParent::Call__delete__(streamNotify, reason);
653 PluginScriptableObjectParent*
654 PluginInstanceParent::GetActorForNPObject(NPObject* aObject)
656 NS_ASSERTION(aObject, "Null pointer!");
658 if (aObject->_class == PluginScriptableObjectParent::GetClass()) {
659 // One of ours!
660 ParentNPObject* object = static_cast<ParentNPObject*>(aObject);
661 NS_ASSERTION(object->parent, "Null actor!");
662 return object->parent;
665 PRUint32 count = mScriptableObjects.Length();
666 for (PRUint32 index = 0; index < count; index++) {
667 nsAutoPtr<PluginScriptableObjectParent>& actor =
668 mScriptableObjects[index];
669 if (actor->GetObject() == aObject) {
670 return actor;
674 PluginScriptableObjectParent* actor =
675 static_cast<PluginScriptableObjectParent*>(
676 CallPPluginScriptableObjectConstructor());
677 NS_ENSURE_TRUE(actor, nsnull);
679 actor->Initialize(const_cast<PluginInstanceParent*>(this), aObject);
680 return actor;
683 bool
684 PluginInstanceParent::AnswerNPN_PushPopupsEnabledState(const bool& aState,
685 bool* aSuccess)
687 *aSuccess = mNPNIface->pushpopupsenabledstate(mNPP, aState ? 1 : 0);
688 return true;
691 bool
692 PluginInstanceParent::AnswerNPN_PopPopupsEnabledState(bool* aSuccess)
694 *aSuccess = mNPNIface->poppopupsenabledstate(mNPP);
695 return true;
698 #if defined(OS_WIN)
700 /* windowless drawing helpers */
703 * Origin info:
705 * windowless, offscreen:
707 * WM_WINDOWPOSCHANGED: origin is relative to container
708 * setwindow: origin is 0,0
709 * WM_PAINT: origin is 0,0
711 * windowless, native:
713 * WM_WINDOWPOSCHANGED: origin is relative to container
714 * setwindow: origin is relative to container
715 * WM_PAINT: origin is relative to container
717 * PluginInstanceParent:
719 * painting: mPluginPort (nsIntRect, saved in SetWindow)
722 void
723 PluginInstanceParent::SharedSurfaceRelease()
725 mSharedSurfaceDib.Close();
728 bool
729 PluginInstanceParent::SharedSurfaceSetWindow(const NPWindow* aWindow,
730 NPRemoteWindow& aRemoteWindow)
732 aRemoteWindow.window = nsnull;
733 aRemoteWindow.x = 0;
734 aRemoteWindow.y = 0;
735 aRemoteWindow.width = aWindow->width;
736 aRemoteWindow.height = aWindow->height;
737 aRemoteWindow.type = aWindow->type;
739 nsIntRect newPort(aWindow->x, aWindow->y, aWindow->width, aWindow->height);
741 // save the the rect location within the browser window.
742 mPluginPort = newPort;
744 // move the port to our shared surface origin
745 newPort.MoveTo(0,0);
747 // check to see if we have the room in shared surface
748 if (mSharedSurfaceDib.IsValid() && mSharedSize.Contains(newPort)) {
749 // ok to paint
750 aRemoteWindow.surfaceHandle = 0;
751 return true;
754 // allocate a new shared surface
755 SharedSurfaceRelease();
756 if (NS_FAILED(mSharedSurfaceDib.Create(reinterpret_cast<HDC>(aWindow->window),
757 newPort.width, newPort.height, 32)))
758 return false;
760 // save the new shared surface size we just allocated
761 mSharedSize = newPort;
763 base::SharedMemoryHandle handle;
764 if (NS_FAILED(mSharedSurfaceDib.ShareToProcess(mParent->ChildProcessHandle(), &handle)))
765 return false;
767 aRemoteWindow.surfaceHandle = handle;
769 return true;
772 void
773 PluginInstanceParent::SharedSurfaceBeforePaint(RECT& rect,
774 NPRemoteEvent& npremoteevent)
776 RECT* dr = (RECT*)npremoteevent.event.lParam;
777 HDC parentHdc = (HDC)npremoteevent.event.wParam;
779 nsIntRect dirtyRect(dr->left, dr->top, dr->right-dr->left, dr->bottom-dr->top);
780 dirtyRect.MoveBy(-mPluginPort.x, -mPluginPort.y); // should always be smaller than dirtyRect
782 ::BitBlt(mSharedSurfaceDib.GetHDC(),
783 dirtyRect.x,
784 dirtyRect.y,
785 dirtyRect.width,
786 dirtyRect.height,
787 parentHdc,
788 dr->left,
789 dr->top,
790 SRCCOPY);
792 // setup the translated dirty rect we'll send to the child
793 rect.left = dirtyRect.x;
794 rect.top = dirtyRect.y;
795 rect.right = dirtyRect.x + dirtyRect.width;
796 rect.bottom = dirtyRect.y + dirtyRect.height;
798 npremoteevent.event.wParam = WPARAM(0);
799 npremoteevent.event.lParam = LPARAM(&rect);
802 void
803 PluginInstanceParent::SharedSurfaceAfterPaint(NPEvent* npevent)
805 RECT* dr = (RECT*)npevent->lParam;
806 HDC parentHdc = (HDC)npevent->wParam;
808 nsIntRect dirtyRect(dr->left, dr->top, dr->right-dr->left, dr->bottom-dr->top);
809 dirtyRect.MoveBy(-mPluginPort.x, -mPluginPort.y);
811 // src copy the shared dib into the parent surface we are handed.
812 ::BitBlt(parentHdc,
813 dr->left,
814 dr->top,
815 dirtyRect.width,
816 dirtyRect.height,
817 mSharedSurfaceDib.GetHDC(),
818 dirtyRect.x,
819 dirtyRect.y,
820 SRCCOPY);
823 #endif // defined(OS_WIN)