NS_IMETHODIMP
PartialSHistory::OnDeactive()
{
  MOZ_ASSERT(mGroupedSHistory);

  mActive = nsIPartialSHistory::STATE_INACTIVE;

  // In-process case.
  nsCOMPtr<nsISHistory> shistory(GetSessionHistory());
  if (shistory) {
    if (NS_FAILED(shistory->OnPartialSHistoryDeactive())) {
      return NS_ERROR_FAILURE;
    }
    return NS_OK;
  }

  // Cross-process case.
  RefPtr<TabParent> tabParent(GetTabParent());
  if (!tabParent) {
    // We have neither shistory nor tabParent?
    NS_WARNING("Unable to get shitory nor tabParent!");
    return NS_ERROR_UNEXPECTED;
  }
  Unused << tabParent->SendNotifyPartialSHistoryDeactive();
  return NS_OK;
}
NS_IMETHODIMP
PartialSHistory::OnActive(uint32_t aGlobalLength, uint32_t aTargetLocalIndex)
{
  MOZ_ASSERT(mGroupedSHistory);

  mActive = nsIPartialSHistory::STATE_ACTIVE;

  // In-process case.
  nsCOMPtr<nsISHistory> shistory(GetSessionHistory());
  if (shistory) {
    // nsISHistory uses int32_t
    if (aGlobalLength > INT32_MAX || aTargetLocalIndex > INT32_MAX) {
      return NS_ERROR_FAILURE;
    }
    return shistory->OnPartialSHistoryActive(aGlobalLength, aTargetLocalIndex);
  }

  // Cross-process case.
  RefPtr<TabParent> tabParent(GetTabParent());
  if (!tabParent) {
    // We have neither shistory nor tabParent?
    NS_WARNING("Unable to get shitory nor tabParent!");
    return NS_ERROR_UNEXPECTED;
  }
  Unused << tabParent->SendNotifyPartialSHistoryActive(aGlobalLength,
                                                       aTargetLocalIndex);

  return NS_OK;
}
bool
PluginWidgetParent::RecvCreate()
{
  PWLOG("PluginWidgetParent::RecvCreate()\n");

  nsresult rv;

  mWidget = do_CreateInstance(kWidgetCID, &rv);

#if defined(MOZ_WIDGET_GTK)
  // We need this currently just for GTK in setting up a socket widget
  // we can send over to content -> plugin.
  PLUG_NewPluginNativeWindow((nsPluginNativeWindow**)&mWrapper);
  if (!mWrapper) {
    return false;
  }
#endif

  // This returns the top level window widget
  nsCOMPtr<nsIWidget> parentWidget = GetTabParent()->GetWidget();

  nsWidgetInitData initData;
  initData.mWindowType = eWindowType_plugin_ipc_chrome;
  initData.mUnicode = false;
  initData.clipChildren = true;
  initData.clipSiblings = true;
  rv = mWidget->Create(parentWidget.get(), nullptr, nsIntRect(0,0,0,0),
                       nullptr, &initData);
  if (NS_FAILED(rv)) {
    mWidget->Destroy();
    mWidget = nullptr;
    return false;
  }

  mWidget->EnableDragDrop(true);
  mWidget->Show(false);
  mWidget->Enable(false);

  // Force the initial position down into content. If we miss an
  // initial position update this insures the widget doesn't overlap
  // chrome.
  RecvMove(0, 0);

#if defined(MOZ_WIDGET_GTK)
  // For setup, initially GTK code expects 'window' to hold the parent.
  mWrapper->window = mWidget->GetNativeData(NS_NATIVE_PLUGIN_PORT);
  mWrapper->CreateXEmbedWindow(false);
  mWrapper->SetAllocation();
  PWLOG("Plugin XID=%p\n", (void*)mWrapper->window);
#endif

  return true;
}
bool
PluginWidgetParent::RecvMove(const double& aX, const double& aY)
{
  ENSURE_CHANNEL;
  PWLOG("PluginWidgetParent::RecvMove(%f, %f)\n", aX, aY);


  // This returns the top level window
  nsCOMPtr<nsIWidget> widget = GetTabParent()->GetWidget();
  if (!widget) {
    // return true otherwise ipc will abort the content process, crashing
    // all tabs.
    return true;
  }

  // Passed in coords are at the tab origin, adjust to the main window.
  nsIntPoint offset = GetTabParent()->GetChildProcessOffset();
  offset.x = abs(offset.x);
  offset.y = abs(offset.y);
  offset += nsIntPoint(ceil(aX), ceil(aY));
  mWidget->Move(offset.x, offset.y);

  return true;
}
bool
PluginWidgetParent::RecvCreate(nsresult* aResult)
{
  PWLOG("PluginWidgetParent::RecvCreate()\n");

  mWidget = do_CreateInstance(kWidgetCID, aResult);
  NS_ASSERTION(NS_SUCCEEDED(*aResult), "widget create failure");

#if defined(MOZ_WIDGET_GTK)
  // We need this currently just for GTK in setting up a socket widget
  // we can send over to content -> plugin.
  PLUG_NewPluginNativeWindow((nsPluginNativeWindow**)&mWrapper);
  if (!mWrapper) {
    KillWidget();
    return false;
  }
  // Give a copy of this to the widget, which handles some update
  // work for us.
  mWidget->SetNativeData(NS_NATIVE_PLUGIN_OBJECT_PTR, (uintptr_t)mWrapper.get());
#endif

  // This returns the top level window widget
  nsCOMPtr<nsIWidget> parentWidget = GetTabParent()->GetWidget();
  // If this fails, bail.
  if (!parentWidget) {
    *aResult = NS_ERROR_NOT_AVAILABLE;
    KillWidget();
    return true;
  }

  nsWidgetInitData initData;
  initData.mWindowType = eWindowType_plugin_ipc_chrome;
  initData.mUnicode = false;
  initData.clipChildren = true;
  initData.clipSiblings = true;
  *aResult = mWidget->Create(parentWidget.get(), nullptr, nsIntRect(0,0,0,0),
                             &initData);
  if (NS_FAILED(*aResult)) {
    KillWidget();
    // This should never fail, abort.
    return false;
  }

  DebugOnly<nsresult> drv;
  drv = mWidget->EnableDragDrop(true);
  NS_ASSERTION(NS_SUCCEEDED(drv), "widget call failure");

#if defined(MOZ_WIDGET_GTK)
  // For setup, initially GTK code expects 'window' to hold the parent.
  mWrapper->window = mWidget->GetNativeData(NS_NATIVE_PLUGIN_PORT);
  drv = mWrapper->CreateXEmbedWindow(false);
  NS_ASSERTION(NS_SUCCEEDED(drv), "widget call failure");
  mWrapper->SetAllocation();
  PWLOG("Plugin XID=%p\n", (void*)mWrapper->window);
#elif defined(XP_WIN)
  DebugOnly<DWORD> winres =
    ::SetPropW((HWND)mWidget->GetNativeData(NS_NATIVE_WINDOW),
               mozilla::dom::kPluginWidgetContentParentProperty,
               GetTabParent()->Manager()->AsContentParent());
  NS_ASSERTION(winres, "SetPropW call failure");
#endif

  // This is a special call we make to nsBaseWidget to register this
  // window as a remote plugin window which is expected to receive
  // visibility updates from the compositor, which ships this data
  // over with corresponding layer updates.
  mWidget->RegisterPluginWindowForRemoteUpdates();

  return true;
}