Back to index

lightning-sunbird  0.9+nobinonly
Classes | Defines | Enumerations | Functions | Variables
nsPluginNativeWindowWin.cpp File Reference
#include "windows.h"
#include "windowsx.h"
#include "nsDebug.h"
#include "plevent.h"
#include "nsIEventQueueService.h"
#include "nsIPluginInstancePeer.h"
#include "nsIPluginInstanceInternal.h"
#include "nsPluginSafety.h"
#include "nsPluginNativeWindow.h"

Go to the source code of this file.

Classes

class  PluginWindowEvent
 PLEvent handling code. More...
class  nsPluginNativeWindowWin

Defines

#define NS_PLUGIN_WINDOW_PROPERTY_ASSOCIATION   "MozillaPluginWindowPropertyAssociation"

Enumerations

enum  nsPluginType {
  nsPluginType_Unknown = 0, nsPluginType_Flash, nsPluginType_Java_vm, nsPluginType_Other,
  nsPluginType_Unknown = 0, nsPluginType_Flash, nsPluginType_Real, nsPluginType_Other
}
 nsPluginNativeWindow Windows specific class declaration More...

Functions

static NS_DEFINE_CID (kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID)
static NS_DEFINE_CID (kCPluginManagerCID, NS_PLUGINMANAGER_CID)
static PRBool ProcessFlashMessageDelayed (nsPluginNativeWindowWin *aWin, HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
 DelayedPopupsEnabledEvent_Handle (PLEvent *event)
 DelayedPopupsEnabledEvent_Destroy (PLEvent *event)
static LRESULT CALLBACK PluginWndProc (HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
 New plugin window procedure.
 PluginWindowEvent_Handle (PLEvent *self)
 PluginWindowEvent_Destroy (PLEvent *self)
nsresult PLUG_NewPluginNativeWindow (nsPluginNativeWindow **aPluginNativeWindow)
nsresult PLUG_DeletePluginNativeWindow (nsPluginNativeWindow *aPluginNativeWindow)

Variables

static PRBool sInMessageDispatch = PR_FALSE
static UINT sLastMsg = 0

Define Documentation

#define NS_PLUGIN_WINDOW_PROPERTY_ASSOCIATION   "MozillaPluginWindowPropertyAssociation"

Definition at line 64 of file nsPluginNativeWindowWin.cpp.


Enumeration Type Documentation

nsPluginNativeWindow Windows specific class declaration

Enumerator:
nsPluginType_Unknown 
nsPluginType_Flash 
nsPluginType_Java_vm 
nsPluginType_Other 
nsPluginType_Unknown 
nsPluginType_Flash 
nsPluginType_Real 
nsPluginType_Other 

Definition at line 117 of file nsPluginNativeWindowWin.cpp.


Function Documentation

Definition at line 192 of file nsPluginNativeWindowWin.cpp.

{
  nsIPluginInstanceInternal *instInternal =
    (nsIPluginInstanceInternal *)event->owner;

  NS_RELEASE(instInternal);

  delete event;
}

Here is the caller graph for this function:

Definition at line 181 of file nsPluginNativeWindowWin.cpp.

{
  nsIPluginInstanceInternal *instInternal =
    (nsIPluginInstanceInternal *)event->owner;

  instInternal->PushPopupsEnabledState(PR_FALSE);

  return nsnull;
}

Here is the caller graph for this function:

static NS_DEFINE_CID ( kCPluginManagerCID  ,
NS_PLUGINMANAGER_CID   
) [static]

Definition at line 556 of file nsPluginNativeWindowWin.cpp.

{
  NS_ENSURE_ARG_POINTER(aPluginNativeWindow);
  nsPluginNativeWindowWin *p = (nsPluginNativeWindowWin *)aPluginNativeWindow;
  delete p;
  return NS_OK;
}

Here is the caller graph for this function:

Definition at line 547 of file nsPluginNativeWindowWin.cpp.

{
  NS_ENSURE_ARG_POINTER(aPluginNativeWindow);

  *aPluginNativeWindow = new nsPluginNativeWindowWin();

  return *aPluginNativeWindow ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
}

Here is the caller graph for this function:

Definition at line 428 of file nsPluginNativeWindowWin.cpp.

{
  if (!self)
    return;

  PluginWindowEvent *event = NS_STATIC_CAST(PluginWindowEvent*, self);
  if (event->GetIsAlloced()) {
    delete event;
  }
  else
    event->Clear();
}

Definition at line 401 of file nsPluginNativeWindowWin.cpp.

{
  if (!self)
    return nsnull;

  PluginWindowEvent *event = NS_STATIC_CAST(PluginWindowEvent*, self);
  
  HWND hWnd = event->GetWnd();
  if (!hWnd)
    return nsnull;

  nsPluginNativeWindowWin * win = (nsPluginNativeWindowWin *)::GetProp(hWnd, NS_PLUGIN_WINDOW_PROPERTY_ASSOCIATION);
  if (win) {
    nsCOMPtr<nsIPluginInstance> inst;
    win->GetPluginInstance(inst);
    NS_TRY_SAFE_CALL_VOID(::CallWindowProc(win->GetWindowProc(), 
                          hWnd, 
                          event->GetMsg(), 
                          event->GetWParam(), 
                          event->GetLParam()),
                          nsnull, inst);
  }

  return nsnull;
}

Here is the call graph for this function:

static LRESULT CALLBACK PluginWndProc ( HWND  hWnd,
UINT  msg,
WPARAM  wParam,
LPARAM  lParam 
) [static]

New plugin window procedure.

Definition at line 205 of file nsPluginNativeWindowWin.cpp.

{
  nsPluginNativeWindowWin * win = (nsPluginNativeWindowWin *)::GetProp(hWnd, NS_PLUGIN_WINDOW_PROPERTY_ASSOCIATION);
  if (!win)
    return TRUE;

  // check plugin myme type and cache whether it is Flash or not
  // Flash will need special treatment later
  if (win->mPluginType == nsPluginType_Unknown) {
    nsCOMPtr<nsIPluginInstance> inst;
    win->GetPluginInstance(inst);
    if (inst) {
      nsCOMPtr<nsIPluginInstancePeer> pip;
      inst->GetPeer(getter_AddRefs(pip));
      if (pip) {
        nsMIMEType mimetype = nsnull;
        pip->GetMIMEType(&mimetype);
        if (mimetype) { 
          if (!strcmp(mimetype, "application/x-shockwave-flash"))
            win->mPluginType = nsPluginType_Flash;
          else if (!strcmp(mimetype, "audio/x-pn-realaudio-plugin"))
            win->mPluginType = nsPluginType_Real;
          else
            win->mPluginType = nsPluginType_Other;
        }
      }
    }
  }

  // Real may go into a state where it recursivly dispatches the same event
  // when subclassed. If this is Real, lets examine the event and drop it
  // on the floor if we get into this recursive situation. See bug 192914.
  if (win->mPluginType == nsPluginType_Real) {
    
    if (sInMessageDispatch && (msg == sLastMsg)) {
#ifdef DEBUG
      printf("Dropping event %d for Real on the floor\n", msg);
#endif
      return PR_TRUE;  // prevents event dispatch
    } else {
      sLastMsg = msg;  // no need to prevent dispatch
    }
  }

  PRBool enablePopups = PR_FALSE;

  // Activate/deactivate mouse capture on the plugin widget
  // here, before we pass the Windows event to the plugin
  // because its possible our widget won't get paired events
  // (see bug 131007) and we'll look frozen. Note that this
  // is also done in ChildWindow::DispatchMouseEvent.
  switch (msg) {
    case WM_LBUTTONDOWN:
    case WM_MBUTTONDOWN:
    case WM_RBUTTONDOWN: {
      nsCOMPtr<nsIWidget> widget;
      win->GetPluginWidget(getter_AddRefs(widget));
      if (widget)
        widget->CaptureMouse(PR_TRUE);
      break;
    }
    case WM_LBUTTONUP:
      enablePopups = PR_TRUE;

      // fall through
    case WM_MBUTTONUP:
    case WM_RBUTTONUP: {
      nsCOMPtr<nsIWidget> widget;
      win->GetPluginWidget(getter_AddRefs(widget));
      if (widget)
        widget->CaptureMouse(PR_FALSE);
      break;
    }
    case WM_KEYDOWN:
      // Ignore repeating keydown messages...
      if ((lParam & 0x40000000) != 0) {
        break;
      }

      // fall through
    case WM_KEYUP:
      enablePopups = PR_TRUE;

      break;
  }

  // Macromedia Flash plugin may flood the message queue with some special messages
  // (WM_USER+1) causing 100% CPU consumption and GUI freeze, see mozilla bug 132759;
  // we can prevent this from happening by delaying the processing such messages;
  if (win->mPluginType == nsPluginType_Flash) {
    if (ProcessFlashMessageDelayed(win, hWnd, msg, wParam, lParam))
      return TRUE;
  }

  LRESULT res = TRUE;

  nsCOMPtr<nsIPluginInstanceInternal> instInternal;
  nsCOMPtr<nsIPluginInstance> inst;
  win->GetPluginInstance(inst);

  if (enablePopups) {
    nsCOMPtr<nsIPluginInstanceInternal> tmp = do_QueryInterface(inst);

    if (tmp && !nsVersionOK(tmp->GetPluginAPIVersion(),
                            NP_POPUP_API_VERSION)) {
      tmp.swap(instInternal);

      instInternal->PushPopupsEnabledState(PR_TRUE);
    }
  }

  sInMessageDispatch = PR_TRUE;

  NS_TRY_SAFE_CALL_RETURN(res, 
                          ::CallWindowProc((WNDPROC)win->GetWindowProc(), hWnd, msg, wParam, lParam),
                          nsnull, inst);

  sInMessageDispatch = PR_FALSE;

  if (instInternal) {
    // Popups are enabled (were enabled before the call to
    // CallWindowProc()). Some plugins (at least the flash player)
    // post messages from their key handlers etc that delay the actual
    // processing, so we need to delay the disabling of popups so that
    // popups remain enabled when the flash player ends up processing
    // the actual key handlers. We do this by posting an event that
    // does the disabling, this way our disabling will happen after
    // the handlers in the plugin are done.

    // Note that it's not fatal if any of this fails (which won't
    // happen unless we're out of memory anyways) since the plugin
    // code will pop any popup state pushed by this plugin on
    // destruction.

    nsIEventQueueService *eventService = win->GetEventService();
    if (eventService) {
      nsCOMPtr<nsIEventQueue> eventQueue;  
      eventService->GetThreadEventQueue(PR_GetCurrentThread(),
                                        getter_AddRefs(eventQueue));
      if (eventQueue) {
        PLEvent *event = new PLEvent;

        if (event) {
          nsIPluginInstanceInternal *eventInst = instInternal;

          // Make the event own the plugin instance.
          NS_ADDREF(eventInst);

          PL_InitEvent(event, eventInst, DelayedPopupsEnabledEvent_Handle,
                       DelayedPopupsEnabledEvent_Destroy);

          eventQueue->PostEvent(event);
        }
      }
    }
  }

  return res;
}

Here is the call graph for this function:

static PRBool ProcessFlashMessageDelayed ( nsPluginNativeWindowWin aWin,
HWND  hWnd,
UINT  msg,
WPARAM  wParam,
LPARAM  lParam 
) [static]

Definition at line 155 of file nsPluginNativeWindowWin.cpp.

{
  NS_ENSURE_TRUE(aWin, NS_ERROR_NULL_POINTER);

  if (msg != WM_USER+1)
    return PR_FALSE; // no need to delay

  // do stuff
  nsIEventQueueService *eventService = aWin->GetEventService();
  if (eventService) {
    nsCOMPtr<nsIEventQueue> eventQueue;  
    eventService->GetThreadEventQueue(PR_GetCurrentThread(),
                                      getter_AddRefs(eventQueue));
    if (eventQueue) {
      PluginWindowEvent *pwe = aWin->GetPluginWindowEvent(hWnd, msg, wParam, lParam);
      if (pwe) {
        eventQueue->PostEvent(pwe);
        return PR_TRUE;  
      }
    }
  }
  return PR_FALSE;
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

Definition at line 152 of file nsPluginNativeWindowWin.cpp.

UINT sLastMsg = 0 [static]

Definition at line 153 of file nsPluginNativeWindowWin.cpp.