/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim:expandtab:shiftwidth=2:tabstop=2:
*/
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "CmdLineAndEnvUtils.h"
#include "nsWinRemoteServer.h"
#include "RemoteUtils.h"
#include "nsCOMPtr.h"
#include "nsXPCOM.h"
#include "nsPIDOMWindow.h"
#include "nsIWindowMediator.h"
#include "nsIBaseWindow.h"
#include "nsIWidget.h"
#include "nsICommandLineRunner.h"
#include "nsICommandLine.h"
#include "nsCommandLine.h"
#include "nsIDocShell.h"
#include "WinRemoteMessage.h"
HWND hwndForDOMWindow(mozIDOMWindowProxy* window) {
if (!window) {
return 0;
}
nsCOMPtr<nsPIDOMWindowOuter> pidomwindow = nsPIDOMWindowOuter::From(window);
nsCOMPtr<nsIBaseWindow> ppBaseWindow =
do_QueryInterface(pidomwindow->GetDocShell());
if (!ppBaseWindow) {
return 0;
}
nsCOMPtr<nsIWidget> ppWidget;
ppBaseWindow->GetMainWidget(getter_AddRefs(ppWidget));
return (HWND)(ppWidget->GetNativeData(NS_NATIVE_WIDGET));
}
static nsresult GetMostRecentWindow(mozIDOMWindowProxy** aWindow) {
nsresult rv;
nsCOMPtr<nsIWindowMediator> med(
do_GetService(NS_WINDOWMEDIATOR_CONTRACTID, &rv));
if (NS_FAILED(rv))
return rv;
if (med)
return med->GetMostRecentWindow(nullptr, aWindow);
return NS_ERROR_FAILURE;
}
LRESULT CALLBACK WindowProc(HWND msgWindow, UINT msg, WPARAM wp, LPARAM lp) {
if (msg == WM_COPYDATA) {
WinRemoteMessageReceiver receiver;
if (NS_SUCCEEDED(receiver.Parse(
reinterpret_cast<COPYDATASTRUCT*>(lp)))) {
receiver.CommandLineRunner()->Run();
}
else {
NS_ERROR(
"Error initializing command line.");
}
// Get current window and return its window handle.
nsCOMPtr<mozIDOMWindowProxy> win;
GetMostRecentWindow(getter_AddRefs(win));
return win ? (LRESULT)hwndForDOMWindow(win) : 0;
}
return DefWindowProcW(msgWindow, msg, wp, lp);
}
nsresult nsWinRemoteServer::Startup(
const char* aAppName,
const char* aProfileName) {
nsString className;
BuildClassName(aAppName, aProfileName, className);
WNDCLASSW classStruct = {0,
// style
&WindowProc,
// lpfnWndProc
0,
// cbClsExtra
0,
// cbWndExtra
0,
// hInstance
0,
// hIcon
0,
// hCursor
0,
// hbrBackground
0,
// lpszMenuName
className.get()};
// lpszClassName
// Register the window class.
NS_ENSURE_TRUE(::RegisterClassW(&classStruct), NS_ERROR_FAILURE);
// Create the window.
mHandle = ::CreateWindowW(className.get(),
0,
// title
WS_CAPTION,
// style
0, 0, 0, 0,
// x, y, cx, cy
0,
// parent
0,
// menu
0,
// instance
0);
// create struct
return mHandle ? NS_OK : NS_ERROR_FAILURE;
}
void nsWinRemoteServer::Shutdown() {
DestroyWindow(mHandle);
mHandle = nullptr;
}