1a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch/*
2a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * Copyright (C) 2010 Apple Inc. All rights reserved.
3a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch *
4a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * Redistribution and use in source and binary forms, with or without
5a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * modification, are permitted provided that the following conditions
6a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * are met:
7a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * 1. Redistributions of source code must retain the above copyright
8a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch *    notice, this list of conditions and the following disclaimer.
9a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * 2. Redistributions in binary form must reproduce the above copyright
10a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch *    notice, this list of conditions and the following disclaimer in the
11a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch *    documentation and/or other materials provided with the distribution.
12a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch *
13a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch * THE POSSIBILITY OF SUCH DAMAGE.
24a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch */
25a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
26a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#include "PlatformWebView.h"
27a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
28a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch#include "WindowMessageObserver.h"
29a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
30a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochnamespace TestWebKitAPI {
31a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
32a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochstatic const wchar_t* hostWindowClassName = L"org.WebKit.TestWebKitAPI.PlatformWebViewHostWindow";
33a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochstatic const wchar_t* webViewPointerProperty = L"org.WebKit.TestWebKitAPI.PlatformWebView.InstancePointer";
34a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
35a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch// These offsets come from rom <http://msdn.microsoft.com/en-us/library/ms646280(VS.85).aspx>.
36a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochstatic const size_t repeatCountBitOffset = 0;
37a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochstatic const size_t scanCodeBitOffset = 16;
38a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochstatic const size_t contextCodeBitOffset = 29;
39a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochstatic const size_t previousStateBitOffset = 30;
40a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochstatic const size_t transitionStateBitOffset = 31;
41a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
42a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochvoid PlatformWebView::registerWindowClass()
43a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
44a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    static bool initialized;
45a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (initialized)
46a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        return;
47a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    initialized = true;
48a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
49a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    WNDCLASSEXW wndClass = {0};
50a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    wndClass.cbSize = sizeof(wndClass);
51a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    wndClass.style = CS_HREDRAW | CS_VREDRAW;
52a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    wndClass.lpfnWndProc = wndProc;
53a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    wndClass.hCursor = LoadCursor(0, IDC_ARROW);
54a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    wndClass.lpszClassName = hostWindowClassName;
55a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
56a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    ::RegisterClassExW(&wndClass);
57a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
58a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
59f05b935882198ccf7d81675736e3aeb089c5113aBen MurdochPlatformWebView::PlatformWebView(WKContextRef contextRef, WKPageGroupRef pageGroupRef)
60a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    : m_parentWindowMessageObserver(0)
61a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
62a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    registerWindowClass();
63a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
64a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    RECT viewRect = {0, 0, 800, 600};
65a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    m_window = CreateWindowExW(0, hostWindowClassName, L"TestWebKitAPI", WS_OVERLAPPEDWINDOW, viewRect.left, viewRect.top, viewRect.right, viewRect.bottom, 0, 0, 0, this);
66f05b935882198ccf7d81675736e3aeb089c5113aBen Murdoch    m_view = WKViewCreate(viewRect, contextRef, pageGroupRef, m_window);
67a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
68a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
69a94275402997c11dd2e778633dacf4b7e630a35dBen MurdochPlatformWebView::~PlatformWebView()
70a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
71a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    ::DestroyWindow(m_window);
72a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    WKRelease(m_view);
73a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
74a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
752fc2651226baac27029e38c9d6ef883fa32084dbSteve BlockWKPageRef PlatformWebView::page() const
76a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
77a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    return WKViewGetPage(m_view);
78a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
79a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
802fc2651226baac27029e38c9d6ef883fa32084dbSteve Blockvoid PlatformWebView::resizeTo(unsigned width, unsigned height)
812fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{
822fc2651226baac27029e38c9d6ef883fa32084dbSteve Block    ::SetWindowPos(WKViewGetWindow(m_view), 0, 0, 0, width, height, SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOCOPYBITS);
832fc2651226baac27029e38c9d6ef883fa32084dbSteve Block}
842fc2651226baac27029e38c9d6ef883fa32084dbSteve Block
85a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochvoid PlatformWebView::simulateSpacebarKeyPress()
86a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
87a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    HWND window = WKViewGetWindow(m_view);
88a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
89a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // These values match what happens when you press the spacebar in Notepad, as observed by Spy++.
90a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    ::SendMessageW(window, WM_KEYDOWN, VK_SPACE, (1 << repeatCountBitOffset) | (39 << scanCodeBitOffset));
91a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    ::SendMessageW(window, WM_CHAR, ' ', (1 << repeatCountBitOffset) | (39 << scanCodeBitOffset));
92a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    ::SendMessageW(window, WM_KEYUP, VK_SPACE, (1 << repeatCountBitOffset) | (39 << scanCodeBitOffset) | (1 << previousStateBitOffset) | (1 << transitionStateBitOffset));
93a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
94a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
952daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochvoid PlatformWebView::simulateAKeyDown()
962daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch{
972daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    HWND window = WKViewGetWindow(m_view);
982daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
992daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    // These values match what happens when you press the 'A' key in Notepad, as observed by Spy++.
1002daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    ::SendMessageW(window, WM_KEYDOWN, 'A', (1 << repeatCountBitOffset) | (30 << scanCodeBitOffset));
1012daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch}
1022daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
103a94275402997c11dd2e778633dacf4b7e630a35dBen Murdochvoid PlatformWebView::simulateAltKeyPress()
104a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
105a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    HWND window = WKViewGetWindow(m_view);
106a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
107a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    // These values match what happens when you press the Alt key in Notepad, as observed by Spy++.
108a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    ::SendMessageW(window, WM_SYSKEYDOWN, VK_MENU, (1 << repeatCountBitOffset) | (38 << scanCodeBitOffset) | (1 << contextCodeBitOffset));
109a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    ::SendMessageW(window, WM_SYSKEYUP, VK_MENU, (1 << repeatCountBitOffset) | (38 << scanCodeBitOffset) | (1 << previousStateBitOffset) | (1 << transitionStateBitOffset));
110a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
111a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
11281bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdochvoid PlatformWebView::simulateRightClick(unsigned x, unsigned y)
11381bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch{
11481bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    HWND window = WKViewGetWindow(m_view);
11581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
11681bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    ::SendMessageW(window, WM_RBUTTONDOWN, 0, MAKELPARAM(x, y));
11781bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    ::SendMessageW(window, WM_RBUTTONUP, 0, MAKELPARAM(x, y));
11881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch}
11981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch
120a94275402997c11dd2e778633dacf4b7e630a35dBen MurdochLRESULT PlatformWebView::wndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
121a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch{
122a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    PlatformWebView* webView;
123a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (message == WM_CREATE) {
124a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        CREATESTRUCT* createStruct = reinterpret_cast<CREATESTRUCT*>(lParam);
125a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        webView = static_cast<PlatformWebView*>(createStruct->lpCreateParams);
126a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        ::SetPropW(hWnd, webViewPointerProperty, webView);
127a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    } else
128a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        webView = reinterpret_cast<PlatformWebView*>(::GetPropW(hWnd, webViewPointerProperty));
129a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
130a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (webView && webView->m_parentWindowMessageObserver)
131a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        webView->m_parentWindowMessageObserver->windowReceivedMessage(hWnd, message, wParam, lParam);
132a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
133a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    if (message == WM_NCDESTROY)
134a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch        ::RemovePropW(hWnd, webViewPointerProperty);
135a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
136a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch    return ::DefWindowProcW(hWnd, message, wParam, lParam);
137a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch}
138a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch
139a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch} // namespace TestWebKitAPI
140