--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/webengine/osswebengine/WebKitTools/Drosera/win/Drosera.cpp Mon Mar 30 12:54:55 2009 +0300
@@ -0,0 +1,445 @@
+/*
+ * Copyright (C) 2007 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "Drosera.h"
+
+#include "DebuggerClient.h"
+#include "DebuggerDocument.h"
+#include "HelperFunctions.h"
+#include "resource.h"
+
+#include <JavaScriptCore/JSStringRef.h>
+#include <WebCore/IntRect.h>
+#include <WebKit/IWebMutableURLRequest.h>
+#include <WebKit/IWebView.h>
+#include <WebKit/WebKit.h>
+#include <windowsx.h>
+
+const unsigned MAX_LOADSTRING = 100;
+
+TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
+TCHAR szWindowClass[MAX_LOADSTRING]; // the main window class name
+
+static const LRESULT kNotHandledResult = -1;
+static LPCTSTR kDroseraPointerProp = TEXT("DroseraPointer");
+HINSTANCE Drosera::m_hInst(0);
+
+extern "C" BOOL InitializeCoreGraphics();
+
+ATOM registerDroseraClass(HINSTANCE hInstance);
+LRESULT CALLBACK droseraWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
+INT_PTR CALLBACK attachWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
+INT_PTR CALLBACK aboutWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
+
+int APIENTRY _tWinMain(HINSTANCE hInstance,
+ HINSTANCE hPrevInstance,
+ LPTSTR lpCmdLine,
+ int nCmdShow)
+{
+ UNREFERENCED_PARAMETER(hPrevInstance);
+ UNREFERENCED_PARAMETER(lpCmdLine);
+
+ MSG msg;
+
+ InitializeCoreGraphics();
+
+ Drosera drosera;
+
+ HRESULT ret = drosera.initUI(hInstance, nCmdShow);
+ if (FAILED(ret))
+ return ret;
+
+ HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_DROSERA));
+
+ // Main message loop:
+ while (GetMessage(&msg, 0, 0, 0)) {
+ if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) {
+ TranslateMessage(&msg);
+ DispatchMessage(&msg);
+ }
+ }
+
+ return static_cast<int>(msg.wParam);
+}
+
+////////////////// Setup Windows Specific Interface //////////////////
+
+ATOM registerDroseraClass(HINSTANCE hInstance)
+{
+ WNDCLASSEX wcex;
+
+ wcex.cbSize = sizeof(WNDCLASSEX);
+
+ wcex.style = CS_HREDRAW | CS_VREDRAW;
+ wcex.lpfnWndProc = ::droseraWndProc;
+ wcex.cbClsExtra = 0;
+ wcex.cbWndExtra = sizeof(Drosera*);
+ wcex.hInstance = hInstance;
+ wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_DROSERA));
+ wcex.hCursor = LoadCursor(0, IDC_ARROW);
+ wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
+ wcex.lpszMenuName = MAKEINTRESOURCE(IDC_DROSERA);
+ wcex.lpszClassName = szWindowClass;
+ wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
+
+ return RegisterClassEx(&wcex);
+}
+
+//Processes messages for the main window.
+LRESULT CALLBACK droseraWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ int wmId, wmEvent;
+ PAINTSTRUCT ps;
+ HDC hdc;
+
+ LONG_PTR longPtr = GetWindowLongPtr(hWnd, 0);
+ Drosera* drosera = reinterpret_cast<Drosera*>(longPtr);
+
+ switch (message) {
+ case WM_COMMAND:
+ wmId = LOWORD(wParam);
+ wmEvent = HIWORD(wParam);
+ switch (wmId) {
+ case ID_HELP_ABOUT:
+ DialogBox(Drosera::getInst(), MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, ::aboutWndProc);
+ break;
+ case ID_FILE_ATTACH:
+ DialogBox(Drosera::getInst(), MAKEINTRESOURCE(IDD_ATTACH), hWnd, ::attachWndProc);
+ break;
+ case ID_FILE_EXIT:
+ DestroyWindow(hWnd);
+ break;
+ default:
+ return DefWindowProc(hWnd, message, wParam, lParam);
+ }
+ break;
+ case WM_SIZE:
+ if (!drosera)
+ return 0;
+ return drosera->webViewLoaded() ? drosera->onSize(wParam, lParam) : 0;
+ case WM_PAINT:
+ hdc = BeginPaint(hWnd, &ps);
+ // TODO: Add any drawing code here...
+ EndPaint(hWnd, &ps);
+ break;
+ case WM_DESTROY:
+ PostQuitMessage(0);
+ break;
+ default:
+ return DefWindowProc(hWnd, message, wParam, lParam);
+ }
+ return 0;
+}
+
+// Message handler for about box.
+INT_PTR CALLBACK aboutWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ UNREFERENCED_PARAMETER(lParam);
+ switch (message) {
+ case WM_INITDIALOG:
+ return (INT_PTR)TRUE;
+
+ case WM_COMMAND:
+ if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) {
+ EndDialog(hDlg, LOWORD(wParam));
+ return (INT_PTR)TRUE;
+ }
+ break;
+ }
+ return (INT_PTR)FALSE;
+}
+
+// Message handler for Attach box.
+INT_PTR CALLBACK attachWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
+{
+ UNREFERENCED_PARAMETER(lParam);
+ switch (message) {
+ case WM_INITDIALOG:
+ return (INT_PTR)TRUE;
+
+ case WM_COMMAND:
+ if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) {
+ EndDialog(hDlg, LOWORD(wParam));
+ return (INT_PTR)TRUE;
+ }
+ break;
+ }
+ return (INT_PTR)FALSE;
+}
+
+////////////////// End Setup Windows Specific Interface //////////////////
+
+Drosera::Drosera()
+ : m_hWnd(0)
+ , m_webViewLoaded(false)
+ , m_debuggerDocument(new DebuggerClient())
+{
+}
+
+HRESULT Drosera::initUI(HINSTANCE hInstance, int nCmdShow)
+{
+ // Initialize global strings
+ LoadString(hInstance, IDS_APP_TITLE, szTitle, ARRAYSIZE(szTitle));
+ LoadString(hInstance, IDC_DROSERA, szWindowClass, ARRAYSIZE(szWindowClass));
+ registerDroseraClass(hInstance);
+
+ Drosera::setInst(hInstance); // Store instance handle in our local variable
+
+ m_hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
+ CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, 0, 0, hInstance, 0);
+
+ if (!m_hWnd)
+ return HRESULT_FROM_WIN32(GetLastError());
+
+ SetLastError(0);
+ SetWindowLongPtr(m_hWnd, 0, reinterpret_cast<LONG_PTR>(this));
+ HRESULT ret = HRESULT_FROM_WIN32(GetLastError());
+ if (FAILED(ret))
+ return ret;
+
+ ret = OleInitialize(0);
+ if (FAILED(ret))
+ return ret;
+
+ ret = CoCreateInstance(CLSID_WebView, 0, CLSCTX_ALL, IID_IWebView, (void**)&m_webView);
+ if (FAILED(ret))
+ return ret;
+
+ ret = m_webView->QueryInterface(IID_IWebViewPrivate, reinterpret_cast<void**>(&m_webViewPrivate));
+ if (FAILED(ret))
+ return ret;
+
+ ret = m_webView->setHostWindow(reinterpret_cast<OLE_HANDLE>(m_hWnd));
+ if (FAILED(ret))
+ return ret;
+
+ ret = m_webView->setFrameLoadDelegate(this);
+ if (FAILED(ret))
+ return ret;
+
+ ret = m_webView->setUIDelegate(this);
+ if (FAILED(ret))
+ return ret;
+
+ RECT rect = {0};
+ ret = m_webView->initWithFrame(rect, 0, 0);
+ if (FAILED(ret))
+ return ret;
+
+ HWND viewWindow;
+ ret = m_webViewPrivate->viewWindow(reinterpret_cast<OLE_HANDLE*>(&viewWindow));
+ if (FAILED(ret))
+ return ret;
+
+ ::SetProp(viewWindow, kDroseraPointerProp, (HANDLE)this);
+
+ COMPtr<IWebFrame> mainFrame;
+ ret = m_webView->mainFrame(&mainFrame);
+ if (FAILED(ret))
+ return ret;
+
+ COMPtr<IWebMutableURLRequest> request;
+ ret = CoCreateInstance(CLSID_WebMutableURLRequest, 0, CLSCTX_ALL, IID_IWebMutableURLRequest, (void**)&request);
+ if (FAILED(ret))
+ return ret;
+
+ RetainPtr<CFURLRef> htmlURLRef(AdoptCF, ::CFBundleCopyResourceURL(::CFBundleGetBundleWithIdentifier(CFSTR("org.webkit.drosera")), CFSTR("debugger"), CFSTR("html"), CFSTR("Drosera")));
+ if (!htmlURLRef)
+ return E_FAIL;
+
+ CFStringRef urlStringRef = ::CFURLGetString(htmlURLRef.get());
+ BSTR tempStr = cfStringToBSTR(urlStringRef); // Both initWithRUL and SysFreeString can handle 0.
+ ret = request->initWithURL(tempStr, WebURLRequestUseProtocolCachePolicy, 60);
+ SysFreeString(tempStr);
+ if (FAILED(ret))
+ return ret;
+
+ ret = mainFrame->loadRequest(request.get());
+ if (FAILED(ret))
+ return ret;
+
+ m_webViewLoaded = true;
+
+ // FIXME: Implement window size/position save/restore
+
+ RECT frame;
+ frame.left = 60;
+ frame.top = 200;
+ frame.right = 750;
+ frame.bottom = 550;
+ ::SetWindowPos(m_hWnd, HWND_TOPMOST, frame.left, frame.top, frame.right - frame.left, frame.bottom - frame.top, 0);
+ ShowWindow(m_hWnd, nCmdShow);
+ UpdateWindow(m_hWnd);
+
+ return 0;
+}
+
+// IUnknown ------------------------------
+HRESULT STDMETHODCALLTYPE Drosera::QueryInterface(REFIID riid, void** ppvObject) // how to cast between implemented interfaces
+{
+ *ppvObject = 0;
+ if (IsEqualGUID(riid, IID_IUnknown))
+ *ppvObject = this;
+ else if (IsEqualGUID(riid, IID_IWebFrameLoadDelegate))
+ *ppvObject = static_cast<IWebFrameLoadDelegate*>(this);
+ else if (IsEqualGUID(riid, IID_IWebUIDelegate))
+ *ppvObject = static_cast<IWebUIDelegate*>(this);
+ else
+ return E_NOINTERFACE;
+
+ AddRef();
+ return S_OK;
+}
+
+ULONG STDMETHODCALLTYPE Drosera::AddRef(void)
+{ // COM ref-counting isn't useful to us because we're in charge of the lifetime of the WebView.
+ // We use the number 2 because of some idiosycracy with COM that expects us to be referenced twice.
+ return 2;
+}
+
+ULONG STDMETHODCALLTYPE Drosera::Release(void)
+{ // COM ref-counting isn't useful to us because we're in charge of the lifetime of the WebView.
+ // We use the number 2 because of some idiosycracy with COM that expects us to be referenced twice.
+ return 2;
+}
+
+// IWebFrameLoadDelegate ------------------------------
+HRESULT STDMETHODCALLTYPE Drosera::didFinishLoadForFrame(
+ /* [in] */ IWebView* m_webView,
+ /* [in] */ IWebFrame* frame)
+{
+ // note: this is Drosera's own WebView, not the one in the app that we are attached to.
+ m_webViewLoaded = true;
+
+ COMPtr<IWebFrame> mainFrame;
+ HRESULT hr = m_webView->mainFrame(&mainFrame);
+ if (FAILED(hr))
+ return hr;
+
+ if (mainFrame != frame) // FIXME Replace below with X Drosera
+ return S_OK;
+
+ COMPtr<IDOMDocument> document;
+ hr = mainFrame->DOMDocument(&document);
+ if (FAILED(hr))
+ return hr;
+
+ COMPtr<IDOMHTMLDocument> htmlDocument;
+ hr = document->QueryInterface(IID_IDOMHTMLDocument, reinterpret_cast<void**>(&htmlDocument));
+ if (FAILED(hr))
+ return hr;
+
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE Drosera::windowScriptObjectAvailable(
+ /* [in] */ IWebView*,
+ /* [in] */ JSContextRef context,
+ /* [in] */ JSObjectRef windowObject)
+{
+
+ JSValueRef exception = 0;
+ m_debuggerDocument.windowScriptObjectAvailable(context, windowObject, &exception);
+ if (exception)
+ return S_FALSE;
+
+ return S_OK;
+}
+
+HRESULT STDMETHODCALLTYPE Drosera::runJavaScriptAlertPanelWithMessage( // For debugging purposes
+ /* [in] */ IWebView*,
+ /* [in] */ BSTR message)
+{
+#ifndef NDEBUG
+ fwprintf(stderr, L"%s\n", message ? message : L"");
+#else
+ (void)message;
+#endif
+ return S_OK;
+}
+
+LRESULT Drosera::onSize(WPARAM, LPARAM)
+{
+ if (!m_webViewPrivate)
+ return 0;
+
+ RECT clientRect = {0};
+ ::GetClientRect(m_hWnd, &clientRect);
+
+ HWND viewWindow;
+ if (FAILED(m_webViewPrivate->viewWindow(reinterpret_cast<OLE_HANDLE*>(&viewWindow))))
+ return 0;
+
+ // FIXME should this be the height-command bars height?
+ ::SetWindowPos(viewWindow, 0, clientRect.left, clientRect.top, clientRect.right - clientRect.left, clientRect.bottom - clientRect.top, SWP_NOZORDER);
+ return 0;
+}
+
+void Drosera::initWithServerName(std::wstring* /*serverName*/)
+{
+// m_debuggerDocument = new DebuggerDocument(m_debuggerClient);
+
+ //if ((self = [super init]))
+ // [self switchToServerNamed:serverName];
+ //return self;
+}
+
+void Drosera::switchToServerNamed(std::wstring* /*server*/)
+{
+ //if (server) {
+ // [[NSNotificationCenter defaultCenter] removeObserver:self name:NSConnectionDidDieNotification object:[(NSDistantObject *)server connectionForProxy]];
+ // if ([[(NSDistantObject *)server connectionForProxy] isValid]) {
+ // [server removeListener:self];
+ // [self resume];
+ // }
+ //}
+
+ //id old = server;
+ //server = ([name length] ? [[NSConnection rootProxyForConnectionWithRegisteredName:name host:nil] retain] : nil);
+ //[old release];
+
+ //old = currentServerName;
+ //currentServerName = [name copy];
+ //[old release];
+
+ //if (server) {
+ // @try {
+ // [(NSDistantObject *)server setProtocolForProxy:@protocol(WebScriptDebugServer)];
+ // [server addListener:self];
+ // } @catch (NSException *exception) {
+ // [currentServerName release];
+ // currentServerName = nil;
+ // [server release];
+ // server = nil;
+ // }
+
+ // if (server)
+ // [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(serverConnectionDidDie:) name:NSConnectionDidDieNotification object:[(NSDistantObject *)server connectionForProxy]];
+ //}
+}
\ No newline at end of file