~ubuntu-branches/ubuntu/raring/qtwebkit-source/raring-proposed

« back to all changes in this revision

Viewing changes to Source/WebKit2/UIProcess/win/WebView.cpp

  • Committer: Package Import Robot
  • Author(s): Jonathan Riddell
  • Date: 2013-02-18 14:24:18 UTC
  • Revision ID: package-import@ubuntu.com-20130218142418-eon0jmjg3nj438uy
Tags: upstream-2.3
ImportĀ upstreamĀ versionĀ 2.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2010 Apple Inc. All rights reserved.
 
3
 *
 
4
 * Redistribution and use in source and binary forms, with or without
 
5
 * modification, are permitted provided that the following conditions
 
6
 * are met:
 
7
 * 1. Redistributions of source code must retain the above copyright
 
8
 *    notice, this list of conditions and the following disclaimer.
 
9
 * 2. Redistributions in binary form must reproduce the above copyright
 
10
 *    notice, this list of conditions and the following disclaimer in the
 
11
 *    documentation and/or other materials provided with the distribution.
 
12
 *
 
13
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 
14
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 
15
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 
16
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 
17
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 
18
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 
19
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 
20
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 
21
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 
22
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 
23
 * THE POSSIBILITY OF SUCH DAMAGE.
 
24
 */
 
25
 
 
26
#include "config.h"
 
27
#include "WebView.h"
 
28
 
 
29
#include "DrawingAreaProxyImpl.h"
 
30
#include "FindIndicator.h"
 
31
#include "Logging.h"
 
32
#include "NativeWebKeyboardEvent.h"
 
33
#include "NativeWebMouseEvent.h"
 
34
#include "NativeWebWheelEvent.h"
 
35
#include "WKAPICast.h"
 
36
#include "WebContext.h"
 
37
#include "WebContextMenuProxyWin.h"
 
38
#include "WebEditCommandProxy.h"
 
39
#include "WebEventFactory.h"
 
40
#include "WebPageProxy.h"
 
41
#include "WebPopupMenuProxyWin.h"
 
42
#include <Commctrl.h>
 
43
#include <WebCore/BitmapInfo.h>
 
44
#include <WebCore/Cursor.h>
 
45
#include <WebCore/DragSession.h>
 
46
#include <WebCore/Editor.h>
 
47
#include <WebCore/FileSystem.h>
 
48
#include <WebCore/FloatRect.h>
 
49
#include <WebCore/HWndDC.h>
 
50
#include <WebCore/IntRect.h>
 
51
#include <WebCore/NotImplemented.h>
 
52
#include <WebCore/Region.h>
 
53
#include <WebCore/RunLoop.h>
 
54
#include <WebCore/SoftLinking.h>
 
55
#include <WebCore/WebCoreInstanceHandle.h>
 
56
#include <WebCore/WindowMessageBroadcaster.h>
 
57
#include <WebCore/WindowsTouch.h>
 
58
#include <wtf/text/StringBuilder.h>
 
59
#include <wtf/text/WTFString.h>
 
60
 
 
61
#if USE(CG)
 
62
#include "WKCACFViewWindow.h"
 
63
#include <WebCore/GraphicsContextCG.h>
 
64
#endif
 
65
 
 
66
#if ENABLE(FULLSCREEN_API)
 
67
#include "WebFullScreenManagerProxy.h"
 
68
#include <WebCore/FullScreenController.h>
 
69
#endif
 
70
 
 
71
namespace Ime {
 
72
// We need these functions in a separate namespace, because in the global namespace they conflict
 
73
// with the definitions in imm.h only by the type modifier (the macro defines them as static) and
 
74
// imm.h is included by windows.h
 
75
SOFT_LINK_LIBRARY(IMM32)
 
76
SOFT_LINK(IMM32, ImmGetContext, HIMC, WINAPI, (HWND hwnd), (hwnd))
 
77
SOFT_LINK(IMM32, ImmReleaseContext, BOOL, WINAPI, (HWND hWnd, HIMC hIMC), (hWnd, hIMC))
 
78
SOFT_LINK(IMM32, ImmGetCompositionStringW, LONG, WINAPI, (HIMC hIMC, DWORD dwIndex, LPVOID lpBuf, DWORD dwBufLen), (hIMC, dwIndex, lpBuf, dwBufLen))
 
79
SOFT_LINK(IMM32, ImmSetCandidateWindow, BOOL, WINAPI, (HIMC hIMC, LPCANDIDATEFORM lpCandidate), (hIMC, lpCandidate))
 
80
SOFT_LINK(IMM32, ImmSetOpenStatus, BOOL, WINAPI, (HIMC hIMC, BOOL fOpen), (hIMC, fOpen))
 
81
SOFT_LINK(IMM32, ImmNotifyIME, BOOL, WINAPI, (HIMC hIMC, DWORD dwAction, DWORD dwIndex, DWORD dwValue), (hIMC, dwAction, dwIndex, dwValue))
 
82
SOFT_LINK(IMM32, ImmAssociateContextEx, BOOL, WINAPI, (HWND hWnd, HIMC hIMC, DWORD dwFlags), (hWnd, hIMC, dwFlags))
 
83
};
 
84
 
 
85
// Soft link functions for gestures and panning.
 
86
SOFT_LINK_LIBRARY(USER32);
 
87
SOFT_LINK_OPTIONAL(USER32, GetGestureInfo, BOOL, WINAPI, (HGESTUREINFO, PGESTUREINFO));
 
88
SOFT_LINK_OPTIONAL(USER32, SetGestureConfig, BOOL, WINAPI, (HWND, DWORD, UINT, PGESTURECONFIG, UINT));
 
89
SOFT_LINK_OPTIONAL(USER32, CloseGestureInfoHandle, BOOL, WINAPI, (HGESTUREINFO));
 
90
 
 
91
SOFT_LINK_LIBRARY(Uxtheme);
 
92
SOFT_LINK_OPTIONAL(Uxtheme, BeginPanningFeedback, BOOL, WINAPI, (HWND));
 
93
SOFT_LINK_OPTIONAL(Uxtheme, EndPanningFeedback, BOOL, WINAPI, (HWND, BOOL));
 
94
SOFT_LINK_OPTIONAL(Uxtheme, UpdatePanningFeedback, BOOL, WINAPI, (HWND, LONG, LONG, BOOL));
 
95
 
 
96
using namespace WebCore;
 
97
 
 
98
namespace WebKit {
 
99
 
 
100
static const LPCWSTR kWebKit2WebViewWindowClassName = L"WebKit2WebViewWindowClass";
 
101
 
 
102
// Constants not available on all platforms.
 
103
const int WM_XP_THEMECHANGED = 0x031A;
 
104
const int WM_VISTA_MOUSEHWHEEL = 0x020E;
 
105
 
 
106
static const int kMaxToolTipWidth = 250;
 
107
 
 
108
enum {
 
109
    UpdateActiveStateTimer = 1,
 
110
};
 
111
 
 
112
LRESULT CALLBACK WebView::WebViewWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
 
113
{
 
114
    LONG_PTR longPtr = ::GetWindowLongPtr(hWnd, 0);
 
115
    
 
116
    if (WebView* webView = reinterpret_cast<WebView*>(longPtr))
 
117
        return webView->wndProc(hWnd, message, wParam, lParam);
 
118
 
 
119
    if (message == WM_CREATE) {
 
120
        LPCREATESTRUCT createStruct = reinterpret_cast<LPCREATESTRUCT>(lParam);
 
121
 
 
122
        // Associate the WebView with the window.
 
123
        ::SetWindowLongPtr(hWnd, 0, (LONG_PTR)createStruct->lpCreateParams);
 
124
        return 0;
 
125
    }
 
126
 
 
127
    return ::DefWindowProc(hWnd, message, wParam, lParam);
 
128
}
 
129
 
 
130
LRESULT WebView::wndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
 
131
{
 
132
    LRESULT lResult = 0;
 
133
    bool handled = true;
 
134
 
 
135
    switch (message) {
 
136
    case WM_CLOSE:
 
137
        m_page->tryClose();
 
138
        break;
 
139
    case WM_DESTROY:
 
140
        m_isBeingDestroyed = true;
 
141
        close();
 
142
        break;
 
143
    case WM_ERASEBKGND:
 
144
        lResult = 1;
 
145
        break;
 
146
    case WM_PAINT:
 
147
        lResult = onPaintEvent(hWnd, message, wParam, lParam, handled);
 
148
        break;
 
149
    case WM_PRINTCLIENT:
 
150
        lResult = onPrintClientEvent(hWnd, message, wParam, lParam, handled);
 
151
        break;
 
152
    case WM_MOUSEACTIVATE:
 
153
        setWasActivatedByMouseEvent(true);
 
154
        handled = false;
 
155
        break;
 
156
    case WM_MOUSEMOVE:
 
157
    case WM_LBUTTONDOWN:
 
158
    case WM_MBUTTONDOWN:
 
159
    case WM_RBUTTONDOWN:
 
160
    case WM_LBUTTONDBLCLK:
 
161
    case WM_MBUTTONDBLCLK:
 
162
    case WM_RBUTTONDBLCLK:
 
163
    case WM_LBUTTONUP:
 
164
    case WM_MBUTTONUP:
 
165
    case WM_RBUTTONUP:
 
166
    case WM_MOUSELEAVE:
 
167
        lResult = onMouseEvent(hWnd, message, wParam, lParam, handled);
 
168
        break;
 
169
    case WM_MOUSEWHEEL:
 
170
    case WM_VISTA_MOUSEHWHEEL:
 
171
        lResult = onWheelEvent(hWnd, message, wParam, lParam, handled);
 
172
        break;
 
173
    case WM_HSCROLL:
 
174
        lResult = onHorizontalScroll(hWnd, message, wParam, lParam, handled);
 
175
        break;
 
176
    case WM_VSCROLL:
 
177
        lResult = onVerticalScroll(hWnd, message, wParam, lParam, handled);
 
178
        break;
 
179
    case WM_GESTURENOTIFY:
 
180
        lResult = onGestureNotify(hWnd, message, wParam, lParam, handled);
 
181
        break;
 
182
    case WM_GESTURE:
 
183
        lResult = onGesture(hWnd, message, wParam, lParam, handled);
 
184
        break;
 
185
    case WM_SYSKEYDOWN:
 
186
    case WM_KEYDOWN:
 
187
    case WM_SYSCHAR:
 
188
    case WM_CHAR:
 
189
    case WM_SYSKEYUP:
 
190
    case WM_KEYUP:
 
191
        lResult = onKeyEvent(hWnd, message, wParam, lParam, handled);
 
192
        break;
 
193
    case WM_SIZE:
 
194
        lResult = onSizeEvent(hWnd, message, wParam, lParam, handled);
 
195
        break;
 
196
    case WM_WINDOWPOSCHANGED:
 
197
        lResult = onWindowPositionChangedEvent(hWnd, message, wParam, lParam, handled);
 
198
        break;
 
199
    case WM_SETFOCUS:
 
200
        lResult = onSetFocusEvent(hWnd, message, wParam, lParam, handled);
 
201
        break;
 
202
    case WM_KILLFOCUS:
 
203
        lResult = onKillFocusEvent(hWnd, message, wParam, lParam, handled);
 
204
        break;
 
205
    case WM_TIMER:
 
206
        lResult = onTimerEvent(hWnd, message, wParam, lParam, handled);
 
207
        break;
 
208
    case WM_SHOWWINDOW:
 
209
        lResult = onShowWindowEvent(hWnd, message, wParam, lParam, handled);
 
210
        break;
 
211
    case WM_SETCURSOR:
 
212
        lResult = onSetCursor(hWnd, message, wParam, lParam, handled);
 
213
        break;
 
214
    case WM_IME_STARTCOMPOSITION:
 
215
        handled = onIMEStartComposition();
 
216
        break;
 
217
    case WM_IME_REQUEST:
 
218
        lResult = onIMERequest(wParam, lParam);
 
219
        break;
 
220
    case WM_IME_COMPOSITION:
 
221
        handled = onIMEComposition(lParam);
 
222
        break;
 
223
    case WM_IME_ENDCOMPOSITION:
 
224
        handled = onIMEEndComposition();
 
225
        break;
 
226
    case WM_IME_SELECT:
 
227
        handled = onIMESelect(wParam, lParam);
 
228
        break;
 
229
    case WM_IME_SETCONTEXT:
 
230
        handled = onIMESetContext(wParam, lParam);
 
231
        break;
 
232
    default:
 
233
        handled = false;
 
234
        break;
 
235
    }
 
236
 
 
237
    if (!handled)
 
238
        lResult = ::DefWindowProc(hWnd, message, wParam, lParam);
 
239
 
 
240
    return lResult;
 
241
}
 
242
 
 
243
bool WebView::registerWebViewWindowClass()
 
244
{
 
245
    static bool haveRegisteredWindowClass = false;
 
246
    if (haveRegisteredWindowClass)
 
247
        return true;
 
248
    haveRegisteredWindowClass = true;
 
249
 
 
250
    WNDCLASSEX wcex;
 
251
 
 
252
    wcex.cbSize = sizeof(WNDCLASSEX);
 
253
    wcex.style          = CS_DBLCLKS;
 
254
    wcex.lpfnWndProc    = WebView::WebViewWndProc;
 
255
    wcex.cbClsExtra     = 0;
 
256
    wcex.cbWndExtra     = sizeof(WebView*);
 
257
    wcex.hInstance      = instanceHandle();
 
258
    wcex.hIcon          = 0;
 
259
    wcex.hCursor        = ::LoadCursor(0, IDC_ARROW);
 
260
    wcex.hbrBackground  = 0;
 
261
    wcex.lpszMenuName   = 0;
 
262
    wcex.lpszClassName  = kWebKit2WebViewWindowClassName;
 
263
    wcex.hIconSm        = 0;
 
264
 
 
265
    return !!::RegisterClassEx(&wcex);
 
266
}
 
267
 
 
268
WebView::WebView(RECT rect, WebContext* context, WebPageGroup* pageGroup, HWND parentWindow)
 
269
    : m_topLevelParentWindow(0)
 
270
    , m_toolTipWindow(0)
 
271
    , m_lastCursorSet(0)
 
272
    , m_webCoreCursor(0)
 
273
    , m_overrideCursor(0)
 
274
    , m_trackingMouseLeave(false)
 
275
    , m_isInWindow(false)
 
276
    , m_isVisible(false)
 
277
    , m_wasActivatedByMouseEvent(false)
 
278
    , m_isBeingDestroyed(false)
 
279
    , m_inIMEComposition(0)
 
280
    , m_findIndicatorCallback(0)
 
281
    , m_findIndicatorCallbackContext(0)
 
282
    , m_pageOverlayInstalled(false)
 
283
    , m_lastPanX(0)
 
284
    , m_lastPanY(0)
 
285
    , m_overPanY(0)
 
286
    , m_gestureReachedScrollingLimit(false)
 
287
#if USE(ACCELERATED_COMPOSITING)
 
288
    , m_layerHostWindow(0)
 
289
#endif
 
290
{
 
291
    registerWebViewWindowClass();
 
292
 
 
293
    m_window = ::CreateWindowExW(0, kWebKit2WebViewWindowClassName, 0, WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_VISIBLE,
 
294
        rect.top, rect.left, rect.right - rect.left, rect.bottom - rect.top, parentWindow ? parentWindow : HWND_MESSAGE, 0, instanceHandle(), this);
 
295
    ASSERT(::IsWindow(m_window));
 
296
    // We only check our window style, and not ::IsWindowVisible, because m_isVisible only tracks
 
297
    // this window's visibility status, while ::IsWindowVisible takes our ancestors' visibility
 
298
    // status into account. <http://webkit.org/b/54104>
 
299
    ASSERT(m_isVisible == static_cast<bool>(::GetWindowLong(m_window, GWL_STYLE) & WS_VISIBLE));
 
300
 
 
301
    m_page = context->createWebPage(this, pageGroup);
 
302
    m_page->initializeWebPage();
 
303
 
 
304
    CoCreateInstance(CLSID_DragDropHelper, 0, CLSCTX_INPROC_SERVER, IID_IDropTargetHelper, (void**)&m_dropTargetHelper);
 
305
 
 
306
    // FIXME: Initializing the tooltip window here matches WebKit win, but seems like something
 
307
    // we could do on demand to save resources.
 
308
    initializeToolTipWindow();
 
309
 
 
310
    // Initialize the top level parent window and register it with the WindowMessageBroadcaster.
 
311
    windowAncestryDidChange();
 
312
 
 
313
#if ENABLE(FULLSCREEN_API)
 
314
    m_page->fullScreenManager()->setWebView(this);
 
315
#endif
 
316
}
 
317
 
 
318
WebView::~WebView()
 
319
{
 
320
    // Tooltip window needs to be explicitly destroyed since it isn't a WS_CHILD.
 
321
    if (::IsWindow(m_toolTipWindow))
 
322
        ::DestroyWindow(m_toolTipWindow);
 
323
}
 
324
 
 
325
void WebView::initialize()
 
326
{
 
327
    ::RegisterDragDrop(m_window, this);
 
328
 
 
329
    if (shouldInitializeTrackPointHack()) {
 
330
        // If we detected a registry key belonging to a TrackPoint driver, then create fake
 
331
        // scrollbars, so the WebView will receive WM_VSCROLL and WM_HSCROLL messages.
 
332
        // We create an invisible vertical scrollbar and an invisible horizontal scrollbar to allow
 
333
        // for receiving both types of messages.
 
334
        ::CreateWindow(TEXT("SCROLLBAR"), TEXT("FAKETRACKPOINTHSCROLLBAR"), WS_CHILD | WS_VISIBLE | SBS_HORZ, 0, 0, 0, 0, m_window, 0, instanceHandle(), 0);
 
335
        ::CreateWindow(TEXT("SCROLLBAR"), TEXT("FAKETRACKPOINTVSCROLLBAR"), WS_CHILD | WS_VISIBLE | SBS_VERT, 0, 0, 0, 0, m_window, 0, instanceHandle(), 0);
 
336
    }
 
337
}
 
338
 
 
339
void WebView::initializeUndoClient(const WKViewUndoClient* client)
 
340
{
 
341
    m_undoClient.initialize(client);
 
342
}
 
343
 
 
344
void WebView::setParentWindow(HWND parentWindow)
 
345
{
 
346
    if (m_window) {
 
347
        // If the host window hasn't changed, bail.
 
348
        if (::GetParent(m_window) == parentWindow)
 
349
            return;
 
350
        if (parentWindow)
 
351
            ::SetParent(m_window, parentWindow);
 
352
        else if (!m_isBeingDestroyed) {
 
353
            // Turn the WebView into a message-only window so it will no longer be a child of the
 
354
            // old parent window and will be hidden from screen. We only do this when
 
355
            // isBeingDestroyed() is false because doing this while handling WM_DESTROY can leave
 
356
            // m_window in a weird state (see <http://webkit.org/b/29337>).
 
357
            ::SetParent(m_window, HWND_MESSAGE);
 
358
        }
 
359
    }
 
360
 
 
361
    windowAncestryDidChange();
 
362
}
 
363
 
 
364
static HWND findTopLevelParentWindow(HWND window)
 
365
{
 
366
    if (!window)
 
367
        return 0;
 
368
 
 
369
    HWND current = window;
 
370
    for (HWND parent = GetParent(current); current; current = parent, parent = GetParent(parent)) {
 
371
        if (!parent || !(GetWindowLongPtr(current, GWL_STYLE) & (WS_POPUP | WS_CHILD)))
 
372
            return current;
 
373
    }
 
374
    ASSERT_NOT_REACHED();
 
375
    return 0;
 
376
}
 
377
 
 
378
void WebView::windowAncestryDidChange()
 
379
{
 
380
    HWND newTopLevelParentWindow;
 
381
    if (m_window)
 
382
        newTopLevelParentWindow = findTopLevelParentWindow(m_window);
 
383
    else {
 
384
        // There's no point in tracking active state changes of our parent window if we don't have
 
385
        // a window ourselves.
 
386
        newTopLevelParentWindow = 0;
 
387
    }
 
388
 
 
389
    if (newTopLevelParentWindow == m_topLevelParentWindow)
 
390
        return;
 
391
 
 
392
    if (m_topLevelParentWindow)
 
393
        WindowMessageBroadcaster::removeListener(m_topLevelParentWindow, this);
 
394
 
 
395
    m_topLevelParentWindow = newTopLevelParentWindow;
 
396
 
 
397
    if (m_topLevelParentWindow)
 
398
        WindowMessageBroadcaster::addListener(m_topLevelParentWindow, this);
 
399
 
 
400
    updateActiveState();
 
401
}
 
402
 
 
403
LRESULT WebView::onMouseEvent(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, bool& handled)
 
404
{
 
405
    NativeWebMouseEvent mouseEvent = NativeWebMouseEvent(hWnd, message, wParam, lParam, m_wasActivatedByMouseEvent);
 
406
    setWasActivatedByMouseEvent(false);
 
407
    
 
408
    switch (message) {
 
409
    case WM_LBUTTONDOWN:
 
410
    case WM_MBUTTONDOWN:
 
411
    case WM_RBUTTONDOWN:
 
412
        ::SetFocus(m_window);
 
413
        ::SetCapture(m_window);
 
414
        break; 
 
415
    case WM_LBUTTONUP:
 
416
    case WM_MBUTTONUP:
 
417
    case WM_RBUTTONUP:
 
418
        ::ReleaseCapture();
 
419
        break;
 
420
    case WM_MOUSEMOVE:
 
421
        startTrackingMouseLeave();
 
422
        break;
 
423
    case WM_MOUSELEAVE:
 
424
        stopTrackingMouseLeave();
 
425
        break;
 
426
    case WM_LBUTTONDBLCLK:
 
427
    case WM_MBUTTONDBLCLK:
 
428
    case WM_RBUTTONDBLCLK:
 
429
        break;
 
430
    default:
 
431
        ASSERT_NOT_REACHED();
 
432
    }
 
433
 
 
434
    m_page->handleMouseEvent(mouseEvent);
 
435
 
 
436
    handled = true;
 
437
    return 0;
 
438
}
 
439
 
 
440
LRESULT WebView::onWheelEvent(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, bool& handled)
 
441
{
 
442
    NativeWebWheelEvent wheelEvent(hWnd, message, wParam, lParam);
 
443
    if (wheelEvent.controlKey()) {
 
444
        // We do not want WebKit to handle Control + Wheel, this should be handled by the client application
 
445
        // to zoom the page.
 
446
        handled = false;
 
447
        return 0;
 
448
    }
 
449
 
 
450
    m_page->handleWheelEvent(wheelEvent);
 
451
 
 
452
    handled = true;
 
453
    return 0;
 
454
}
 
455
 
 
456
LRESULT WebView::onHorizontalScroll(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, bool& handled)
 
457
{
 
458
    ScrollDirection direction;
 
459
    ScrollGranularity granularity;
 
460
    switch (LOWORD(wParam)) {
 
461
    case SB_LINELEFT:
 
462
        granularity = ScrollByLine;
 
463
        direction = ScrollLeft;
 
464
        break;
 
465
    case SB_LINERIGHT:
 
466
        granularity = ScrollByLine;
 
467
        direction = ScrollRight;
 
468
        break;
 
469
    case SB_PAGELEFT:
 
470
        granularity = ScrollByDocument;
 
471
        direction = ScrollLeft;
 
472
        break;
 
473
    case SB_PAGERIGHT:
 
474
        granularity = ScrollByDocument;
 
475
        direction = ScrollRight;
 
476
        break;
 
477
    default:
 
478
        handled = false;
 
479
        return 0;
 
480
    }
 
481
 
 
482
    m_page->scrollBy(direction, granularity);
 
483
 
 
484
    handled = true;
 
485
    return 0;
 
486
}
 
487
 
 
488
LRESULT WebView::onVerticalScroll(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, bool& handled)
 
489
{
 
490
    ScrollDirection direction;
 
491
    ScrollGranularity granularity;
 
492
    switch (LOWORD(wParam)) {
 
493
    case SB_LINEDOWN:
 
494
        granularity = ScrollByLine;
 
495
        direction = ScrollDown;
 
496
        break;
 
497
    case SB_LINEUP:
 
498
        granularity = ScrollByLine;
 
499
        direction = ScrollUp;
 
500
        break;
 
501
    case SB_PAGEDOWN:
 
502
        granularity = ScrollByDocument;
 
503
        direction = ScrollDown;
 
504
        break;
 
505
    case SB_PAGEUP:
 
506
        granularity = ScrollByDocument;
 
507
        direction = ScrollUp;
 
508
        break;
 
509
    default:
 
510
        handled = false;
 
511
        return 0;
 
512
    }
 
513
 
 
514
    m_page->scrollBy(direction, granularity);
 
515
 
 
516
    handled = true;
 
517
    return 0;
 
518
}
 
519
 
 
520
LRESULT WebView::onGestureNotify(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, bool& handled)
 
521
{
 
522
    // We shouldn't be getting any gesture messages without SetGestureConfig soft-linking correctly.
 
523
    ASSERT(SetGestureConfigPtr());
 
524
 
 
525
    GESTURENOTIFYSTRUCT* gn = reinterpret_cast<GESTURENOTIFYSTRUCT*>(lParam);
 
526
 
 
527
    POINT localPoint = { gn->ptsLocation.x, gn->ptsLocation.y };
 
528
    ::ScreenToClient(m_window, &localPoint);
 
529
 
 
530
    bool canPan = m_page->gestureWillBegin(localPoint);
 
531
 
 
532
    DWORD dwPanWant = GC_PAN | GC_PAN_WITH_INERTIA | GC_PAN_WITH_GUTTER;
 
533
    DWORD dwPanBlock = GC_PAN_WITH_SINGLE_FINGER_HORIZONTALLY;
 
534
    if (canPan)
 
535
        dwPanWant |= GC_PAN_WITH_SINGLE_FINGER_VERTICALLY;
 
536
    else
 
537
        dwPanBlock |= GC_PAN_WITH_SINGLE_FINGER_VERTICALLY;
 
538
 
 
539
    GESTURECONFIG gc = { GID_PAN, dwPanWant, dwPanBlock };
 
540
    return SetGestureConfigPtr()(m_window, 0, 1, &gc, sizeof(gc));
 
541
}
 
542
 
 
543
LRESULT WebView::onGesture(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, bool& handled)
 
544
{
 
545
    ASSERT(GetGestureInfoPtr());
 
546
    ASSERT(CloseGestureInfoHandlePtr());
 
547
    ASSERT(UpdatePanningFeedbackPtr());
 
548
    ASSERT(BeginPanningFeedbackPtr());
 
549
    ASSERT(EndPanningFeedbackPtr());
 
550
 
 
551
    if (!GetGestureInfoPtr() || !CloseGestureInfoHandlePtr() || !UpdatePanningFeedbackPtr() || !BeginPanningFeedbackPtr() || !EndPanningFeedbackPtr()) {
 
552
        handled = false;
 
553
        return 0;
 
554
    }
 
555
 
 
556
    HGESTUREINFO gestureHandle = reinterpret_cast<HGESTUREINFO>(lParam);
 
557
    GESTUREINFO gi = {0};
 
558
    gi.cbSize = sizeof(GESTUREINFO);
 
559
 
 
560
    if (!GetGestureInfoPtr()(gestureHandle, &gi)) {
 
561
        handled = false;
 
562
        return 0;
 
563
    }
 
564
 
 
565
    switch (gi.dwID) {
 
566
    case GID_BEGIN:
 
567
        m_lastPanX = gi.ptsLocation.x;
 
568
        m_lastPanY = gi.ptsLocation.y;
 
569
        break;
 
570
    case GID_END:
 
571
        m_page->gestureDidEnd();
 
572
        break;
 
573
    case GID_PAN: {
 
574
        int currentX = gi.ptsLocation.x;
 
575
        int currentY = gi.ptsLocation.y;
 
576
 
 
577
        // Reverse the calculations because moving your fingers up should move the screen down, and
 
578
        // vice-versa.
 
579
        int deltaX = m_lastPanX - currentX;
 
580
        int deltaY = m_lastPanY - currentY;
 
581
 
 
582
        m_lastPanX = currentX;
 
583
        m_lastPanY = currentY;
 
584
 
 
585
        // Calculate the overpan for window bounce.
 
586
        m_overPanY -= deltaY;
 
587
 
 
588
        if (deltaX || deltaY)
 
589
            m_page->gestureDidScroll(IntSize(deltaX, deltaY));
 
590
 
 
591
        if (gi.dwFlags & GF_BEGIN) {
 
592
            BeginPanningFeedbackPtr()(m_window);
 
593
            m_gestureReachedScrollingLimit = false;
 
594
            m_overPanY = 0;
 
595
        } else if (gi.dwFlags & GF_END) {
 
596
            EndPanningFeedbackPtr()(m_window, true);
 
597
            m_overPanY = 0;
 
598
        }
 
599
 
 
600
        // FIXME: Support horizontal window bounce - <http://webkit.org/b/58068>.
 
601
        // FIXME: Window Bounce doesn't undo until user releases their finger - <http://webkit.org/b/58069>.
 
602
 
 
603
        if (m_gestureReachedScrollingLimit)
 
604
            UpdatePanningFeedbackPtr()(m_window, 0, m_overPanY, gi.dwFlags & GF_INERTIA);
 
605
 
 
606
        CloseGestureInfoHandlePtr()(gestureHandle);
 
607
 
 
608
        handled = true;
 
609
        return 0;
 
610
    }
 
611
    default:
 
612
        break;
 
613
    }
 
614
 
 
615
    // If we get to this point, the gesture has not been handled. We forward
 
616
    // the call to DefWindowProc by returning false, and we don't need to 
 
617
    // to call CloseGestureInfoHandle. 
 
618
    // http://msdn.microsoft.com/en-us/library/dd353228(VS.85).aspx
 
619
    handled = false;
 
620
    return 0;
 
621
}
 
622
 
 
623
LRESULT WebView::onKeyEvent(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, bool& handled)
 
624
{
 
625
#if ENABLE(FULLSCREEN_API)
 
626
    // Trap the ESC key when in full screen mode.
 
627
    if (message == WM_KEYDOWN && wParam == VK_ESCAPE && m_fullScreenController && m_fullScreenController->isFullScreen()) {
 
628
        m_fullScreenController->exitFullScreen();
 
629
        return false;
 
630
    }
 
631
#endif
 
632
 
 
633
    m_page->handleKeyboardEvent(NativeWebKeyboardEvent(hWnd, message, wParam, lParam));
 
634
 
 
635
    // We claim here to always have handled the event. If the event is not in fact handled, we will
 
636
    // find out later in didNotHandleKeyEvent.
 
637
    handled = true;
 
638
    return 0;
 
639
}
 
640
 
 
641
static void drawPageBackground(HDC dc, const WebPageProxy* page, const RECT& rect)
 
642
{
 
643
    if (!page->drawsBackground() || page->drawsTransparentBackground())
 
644
        return;
 
645
 
 
646
    ::FillRect(dc, &rect, reinterpret_cast<HBRUSH>(COLOR_WINDOW + 1));
 
647
}
 
648
 
 
649
void WebView::paint(HDC hdc, const IntRect& dirtyRect)
 
650
{
 
651
    m_page->endPrinting();
 
652
    if (DrawingAreaProxyImpl* drawingArea = static_cast<DrawingAreaProxyImpl*>(m_page->drawingArea())) {
 
653
        // FIXME: We should port WebKit1's rect coalescing logic here.
 
654
        Region unpaintedRegion;
 
655
        drawingArea->paint(hdc, dirtyRect, unpaintedRegion);
 
656
 
 
657
        Vector<IntRect> unpaintedRects = unpaintedRegion.rects();
 
658
        for (size_t i = 0; i < unpaintedRects.size(); ++i) {
 
659
            RECT winRect = unpaintedRects[i];
 
660
            drawPageBackground(hdc, m_page.get(), unpaintedRects[i]);
 
661
        }
 
662
    } else
 
663
        drawPageBackground(hdc, m_page.get(), dirtyRect);
 
664
 
 
665
    m_page->didDraw();
 
666
}
 
667
 
 
668
static void flashRects(HDC dc, const IntRect rects[], size_t rectCount, HBRUSH brush)
 
669
{
 
670
    for (size_t i = 0; i < rectCount; ++i) {
 
671
        RECT winRect = rects[i];
 
672
        ::FillRect(dc, &winRect, brush);
 
673
    }
 
674
 
 
675
    ::GdiFlush();
 
676
    ::Sleep(50);
 
677
}
 
678
 
 
679
static OwnPtr<HBRUSH> createBrush(const Color& color)
 
680
{
 
681
    return adoptPtr(::CreateSolidBrush(RGB(color.red(), color.green(), color.blue())));
 
682
}
 
683
 
 
684
LRESULT WebView::onPaintEvent(HWND hWnd, UINT message, WPARAM, LPARAM, bool& handled)
 
685
{
 
686
    // Update child windows now so that any areas of our window they reveal will be included in the
 
687
    // invalid region that ::BeginPaint sees.
 
688
    updateChildWindowGeometries();
 
689
 
 
690
    PAINTSTRUCT paintStruct;
 
691
    HDC hdc = ::BeginPaint(m_window, &paintStruct);
 
692
 
 
693
    if (WebPageProxy::debugPaintFlags() & kWKDebugFlashViewUpdates) {
 
694
        static HBRUSH brush = createBrush(WebPageProxy::viewUpdatesFlashColor().rgb()).leakPtr();
 
695
        IntRect rect = paintStruct.rcPaint;
 
696
        flashRects(hdc, &rect, 1, brush);
 
697
    }
 
698
 
 
699
    paint(hdc, paintStruct.rcPaint);
 
700
 
 
701
    ::EndPaint(m_window, &paintStruct);
 
702
 
 
703
    handled = true;
 
704
    return 0;
 
705
}
 
706
 
 
707
LRESULT WebView::onPrintClientEvent(HWND hWnd, UINT, WPARAM wParam, LPARAM, bool& handled)
 
708
{
 
709
    HDC hdc = reinterpret_cast<HDC>(wParam);
 
710
    RECT winRect;
 
711
    ::GetClientRect(hWnd, &winRect);
 
712
 
 
713
    // Twidding the visibility flags tells the DrawingArea to resume painting. Right now, the
 
714
    // the visible state of the view only affects whether or not painting happens, but in the
 
715
    // future it could affect more, which we wouldn't want to touch here.
 
716
 
 
717
    // FIXME: We should have a better way of telling the WebProcess to draw even if we're
 
718
    // invisible than twiddling the visibility flag.
 
719
 
 
720
    bool wasVisible = isViewVisible();
 
721
    if (!wasVisible)
 
722
        setIsVisible(true);
 
723
 
 
724
    paint(hdc, winRect);
 
725
 
 
726
    if (!wasVisible)
 
727
        setIsVisible(false);
 
728
 
 
729
    handled = true;
 
730
    return 0;
 
731
}
 
732
 
 
733
LRESULT WebView::onSizeEvent(HWND, UINT, WPARAM, LPARAM lParam, bool& handled)
 
734
{
 
735
    int width = LOWORD(lParam);
 
736
    int height = HIWORD(lParam);
 
737
 
 
738
    if (m_page && m_page->drawingArea()) {
 
739
        m_page->drawingArea()->setSize(IntSize(width, height), m_nextResizeScrollOffset);
 
740
        m_nextResizeScrollOffset = IntSize();
 
741
    }
 
742
 
 
743
#if USE(ACCELERATED_COMPOSITING)
 
744
    if (m_layerHostWindow)
 
745
        ::MoveWindow(m_layerHostWindow, 0, 0, width, height, FALSE);
 
746
#endif
 
747
 
 
748
    handled = true;
 
749
    return 0;
 
750
}
 
751
 
 
752
LRESULT WebView::onWindowPositionChangedEvent(HWND, UINT, WPARAM, LPARAM lParam, bool& handled)
 
753
{
 
754
    if (reinterpret_cast<WINDOWPOS*>(lParam)->flags & SWP_SHOWWINDOW)
 
755
        updateActiveStateSoon();
 
756
 
 
757
    handled = false;
 
758
    return 0;
 
759
}
 
760
 
 
761
LRESULT WebView::onSetFocusEvent(HWND, UINT, WPARAM, LPARAM lParam, bool& handled)
 
762
{
 
763
    m_page->viewStateDidChange(WebPageProxy::ViewIsFocused);
 
764
    handled = true;
 
765
    return 0;
 
766
}
 
767
 
 
768
LRESULT WebView::onKillFocusEvent(HWND, UINT, WPARAM, LPARAM lParam, bool& handled)
 
769
{
 
770
    m_page->viewStateDidChange(WebPageProxy::ViewIsFocused);
 
771
    handled = true;
 
772
    return 0;
 
773
}
 
774
 
 
775
LRESULT WebView::onTimerEvent(HWND hWnd, UINT, WPARAM wParam, LPARAM, bool& handled)
 
776
{
 
777
    switch (wParam) {
 
778
    case UpdateActiveStateTimer:
 
779
        ::KillTimer(hWnd, UpdateActiveStateTimer);
 
780
        updateActiveState();
 
781
        break;
 
782
    }
 
783
 
 
784
    handled = true;
 
785
    return 0;
 
786
}
 
787
 
 
788
LRESULT WebView::onShowWindowEvent(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, bool& handled)
 
789
{
 
790
    // lParam is 0 when the message is sent because of a ShowWindow call.
 
791
    // FIXME: Since we don't get notified when an ancestor window is hidden or shown, we will keep
 
792
    // painting even when we have a hidden ancestor. <http://webkit.org/b/54104>
 
793
    if (!lParam)
 
794
        setIsVisible(wParam);
 
795
 
 
796
    handled = false;
 
797
    return 0;
 
798
}
 
799
 
 
800
LRESULT WebView::onSetCursor(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, bool& handled)
 
801
{
 
802
    if (!m_lastCursorSet) {
 
803
        handled = false;
 
804
        return 0;
 
805
    }
 
806
 
 
807
    ::SetCursor(m_lastCursorSet);
 
808
    return 0;
 
809
}
 
810
 
 
811
void WebView::updateActiveState()
 
812
{
 
813
    m_page->viewStateDidChange(WebPageProxy::ViewWindowIsActive);
 
814
}
 
815
 
 
816
void WebView::updateActiveStateSoon()
 
817
{
 
818
    // This function is called while processing the WM_NCACTIVATE message.
 
819
    // While processing WM_NCACTIVATE when we are being deactivated, GetActiveWindow() will
 
820
    // still return our window. If we were to call updateActiveState() in that case, we would
 
821
    // wrongly think that we are still the active window. To work around this, we update our
 
822
    // active state after a 0-delay timer fires, at which point GetActiveWindow() will return
 
823
    // the newly-activated window.
 
824
 
 
825
    ::SetTimer(m_window, UpdateActiveStateTimer, 0, 0);
 
826
}
 
827
 
 
828
static bool initCommonControls()
 
829
{
 
830
    static bool haveInitialized = false;
 
831
    if (haveInitialized)
 
832
        return true;
 
833
 
 
834
    INITCOMMONCONTROLSEX init;
 
835
    init.dwSize = sizeof(init);
 
836
    init.dwICC = ICC_TREEVIEW_CLASSES;
 
837
    haveInitialized = !!::InitCommonControlsEx(&init);
 
838
    return haveInitialized;
 
839
}
 
840
 
 
841
void WebView::initializeToolTipWindow()
 
842
{
 
843
    if (!initCommonControls())
 
844
        return;
 
845
 
 
846
    m_toolTipWindow = ::CreateWindowEx(WS_EX_TRANSPARENT, TOOLTIPS_CLASS, 0, WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP,
 
847
                                       CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
 
848
                                       m_window, 0, 0, 0);
 
849
    if (!m_toolTipWindow)
 
850
        return;
 
851
 
 
852
    TOOLINFO info = {0};
 
853
    info.cbSize = sizeof(info);
 
854
    info.uFlags = TTF_IDISHWND | TTF_SUBCLASS;
 
855
    info.uId = reinterpret_cast<UINT_PTR>(m_window);
 
856
 
 
857
    ::SendMessage(m_toolTipWindow, TTM_ADDTOOL, 0, reinterpret_cast<LPARAM>(&info));
 
858
    ::SendMessage(m_toolTipWindow, TTM_SETMAXTIPWIDTH, 0, kMaxToolTipWidth);
 
859
    ::SetWindowPos(m_toolTipWindow, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
 
860
}
 
861
 
 
862
void WebView::startTrackingMouseLeave()
 
863
{
 
864
    if (m_trackingMouseLeave)
 
865
        return;
 
866
    m_trackingMouseLeave = true;
 
867
 
 
868
    TRACKMOUSEEVENT trackMouseEvent;
 
869
    trackMouseEvent.cbSize = sizeof(TRACKMOUSEEVENT);
 
870
    trackMouseEvent.dwFlags = TME_LEAVE;
 
871
    trackMouseEvent.hwndTrack = m_window;
 
872
 
 
873
    ::TrackMouseEvent(&trackMouseEvent);
 
874
}
 
875
 
 
876
void WebView::stopTrackingMouseLeave()
 
877
{
 
878
    if (!m_trackingMouseLeave)
 
879
        return;
 
880
    m_trackingMouseLeave = false;
 
881
 
 
882
    TRACKMOUSEEVENT trackMouseEvent;
 
883
    trackMouseEvent.cbSize = sizeof(TRACKMOUSEEVENT);
 
884
    trackMouseEvent.dwFlags = TME_LEAVE | TME_CANCEL;
 
885
    trackMouseEvent.hwndTrack = m_window;
 
886
 
 
887
    ::TrackMouseEvent(&trackMouseEvent);
 
888
}
 
889
 
 
890
bool WebView::shouldInitializeTrackPointHack()
 
891
{
 
892
    static bool shouldCreateScrollbars;
 
893
    static bool hasRunTrackPointCheck;
 
894
 
 
895
    if (hasRunTrackPointCheck)
 
896
        return shouldCreateScrollbars;
 
897
 
 
898
    hasRunTrackPointCheck = true;
 
899
    const wchar_t* trackPointKeys[] = { 
 
900
        L"Software\\Lenovo\\TrackPoint",
 
901
        L"Software\\Lenovo\\UltraNav",
 
902
        L"Software\\Alps\\Apoint\\TrackPoint",
 
903
        L"Software\\Synaptics\\SynTPEnh\\UltraNavUSB",
 
904
        L"Software\\Synaptics\\SynTPEnh\\UltraNavPS2"
 
905
    };
 
906
 
 
907
    for (size_t i = 0; i < WTF_ARRAY_LENGTH(trackPointKeys); ++i) {
 
908
        HKEY trackPointKey;
 
909
        int readKeyResult = ::RegOpenKeyExW(HKEY_CURRENT_USER, trackPointKeys[i], 0, KEY_READ, &trackPointKey);
 
910
        ::RegCloseKey(trackPointKey);
 
911
        if (readKeyResult == ERROR_SUCCESS) {
 
912
            shouldCreateScrollbars = true;
 
913
            return shouldCreateScrollbars;
 
914
        }
 
915
    }
 
916
 
 
917
    return shouldCreateScrollbars;
 
918
}
 
919
 
 
920
void WebView::close()
 
921
{
 
922
    m_undoClient.initialize(0);
 
923
    ::RevokeDragDrop(m_window);
 
924
    if (m_window) {
 
925
        // We can't check IsWindow(m_window) here, because that will return true even while
 
926
        // we're already handling WM_DESTROY. So we check !m_isBeingDestroyed instead.
 
927
        if (!m_isBeingDestroyed)
 
928
            DestroyWindow(m_window);
 
929
        // Either we just destroyed m_window, or it's in the process of being destroyed. Either
 
930
        // way, we clear it out to make sure we don't try to use it later.
 
931
        m_window = 0;
 
932
    }
 
933
    setParentWindow(0);
 
934
    m_page->close();
 
935
}
 
936
 
 
937
// PageClient
 
938
 
 
939
PassOwnPtr<DrawingAreaProxy> WebView::createDrawingAreaProxy()
 
940
{
 
941
    return DrawingAreaProxyImpl::create(m_page.get());
 
942
}
 
943
 
 
944
void WebView::setViewNeedsDisplay(const WebCore::IntRect& rect)
 
945
{
 
946
    RECT r = rect;
 
947
    ::InvalidateRect(m_window, &r, false);
 
948
}
 
949
 
 
950
void WebView::displayView()
 
951
{
 
952
    ::UpdateWindow(m_window);
 
953
}
 
954
 
 
955
void WebView::scrollView(const IntRect& scrollRect, const IntSize& scrollOffset)
 
956
{
 
957
    // FIXME: Actually scroll the view contents.
 
958
    setViewNeedsDisplay(scrollRect);
 
959
}
 
960
 
 
961
void WebView::flashBackingStoreUpdates(const Vector<IntRect>& updateRects)
 
962
{
 
963
    static HBRUSH brush = createBrush(WebPageProxy::backingStoreUpdatesFlashColor().rgb()).leakPtr();
 
964
    HWndDC dc(m_window);
 
965
    flashRects(dc, updateRects.data(), updateRects.size(), brush);
 
966
}
 
967
 
 
968
WebCore::IntSize WebView::viewSize()
 
969
{
 
970
    RECT clientRect;
 
971
    GetClientRect(m_window, &clientRect);
 
972
 
 
973
    return IntRect(clientRect).size();
 
974
}
 
975
 
 
976
bool WebView::isViewWindowActive()
 
977
{    
 
978
    HWND activeWindow = ::GetActiveWindow();
 
979
    return (activeWindow && m_topLevelParentWindow == findTopLevelParentWindow(activeWindow));
 
980
}
 
981
 
 
982
bool WebView::isViewFocused()
 
983
{
 
984
    return ::GetFocus() == m_window;
 
985
}
 
986
 
 
987
bool WebView::isViewVisible()
 
988
{
 
989
    return m_isVisible;
 
990
}
 
991
 
 
992
bool WebView::isViewInWindow()
 
993
{
 
994
    return m_isInWindow;
 
995
}
 
996
 
 
997
void WebView::pageClosed()
 
998
{
 
999
}
 
1000
 
 
1001
void WebView::processDidCrash()
 
1002
{
 
1003
    updateNativeCursor();
 
1004
    ::InvalidateRect(m_window, 0, TRUE);
 
1005
}
 
1006
 
 
1007
void WebView::didRelaunchProcess()
 
1008
{
 
1009
    updateNativeCursor();
 
1010
    ::InvalidateRect(m_window, 0, TRUE);
 
1011
}
 
1012
 
 
1013
void WebView::toolTipChanged(const String&, const String& newToolTip)
 
1014
{
 
1015
    if (!m_toolTipWindow)
 
1016
        return;
 
1017
 
 
1018
    if (!newToolTip.isEmpty()) {
 
1019
        // This is necessary because String::charactersWithNullTermination() is not const.
 
1020
        String toolTip = newToolTip;
 
1021
 
 
1022
        TOOLINFO info = {0};
 
1023
        info.cbSize = sizeof(info);
 
1024
        info.uFlags = TTF_IDISHWND;
 
1025
        info.uId = reinterpret_cast<UINT_PTR>(m_window);
 
1026
        info.lpszText = const_cast<UChar*>(toolTip.charactersWithNullTermination());
 
1027
        ::SendMessage(m_toolTipWindow, TTM_UPDATETIPTEXT, 0, reinterpret_cast<LPARAM>(&info));
 
1028
    }
 
1029
 
 
1030
    ::SendMessage(m_toolTipWindow, TTM_ACTIVATE, !newToolTip.isEmpty(), 0);
 
1031
}
 
1032
 
 
1033
HCURSOR WebView::cursorToShow() const
 
1034
{
 
1035
    if (!m_page->isValid())
 
1036
        return 0;
 
1037
 
 
1038
    // We only show the override cursor if the default (arrow) cursor is showing.
 
1039
    static HCURSOR arrowCursor = ::LoadCursor(0, IDC_ARROW);
 
1040
    if (m_overrideCursor && m_webCoreCursor == arrowCursor)
 
1041
        return m_overrideCursor;
 
1042
 
 
1043
    return m_webCoreCursor;
 
1044
}
 
1045
 
 
1046
void WebView::updateNativeCursor()
 
1047
{
 
1048
    m_lastCursorSet = cursorToShow();
 
1049
    if (!m_lastCursorSet)
 
1050
        return;
 
1051
    ::SetCursor(m_lastCursorSet);
 
1052
}
 
1053
 
 
1054
void WebView::setCursor(const WebCore::Cursor& cursor)
 
1055
{
 
1056
    if (!cursor.platformCursor()->nativeCursor())
 
1057
        return;
 
1058
    m_webCoreCursor = cursor.platformCursor()->nativeCursor();
 
1059
    updateNativeCursor();
 
1060
}
 
1061
 
 
1062
void WebView::setCursorHiddenUntilMouseMoves(bool)
 
1063
{
 
1064
    notImplemented();
 
1065
}
 
1066
 
 
1067
void WebView::setOverrideCursor(HCURSOR overrideCursor)
 
1068
{
 
1069
    m_overrideCursor = overrideCursor;
 
1070
    updateNativeCursor();
 
1071
}
 
1072
 
 
1073
void WebView::setInitialFocus(bool forward, bool isKeyboardEventValid, const WebKeyboardEvent& event)
 
1074
{
 
1075
    m_page->setInitialFocus(forward, isKeyboardEventValid, event);
 
1076
}
 
1077
 
 
1078
void WebView::setScrollOffsetOnNextResize(const IntSize& scrollOffset)
 
1079
{
 
1080
    // The next time we get a WM_SIZE message, scroll by the specified amount in onSizeEvent().
 
1081
    m_nextResizeScrollOffset = scrollOffset;
 
1082
}
 
1083
 
 
1084
void WebView::didChangeViewportProperties(const WebCore::ViewportAttributes&)
 
1085
{
 
1086
}
 
1087
 
 
1088
void WebView::registerEditCommand(PassRefPtr<WebEditCommandProxy> prpCommand, WebPageProxy::UndoOrRedo undoOrRedo)
 
1089
{
 
1090
    RefPtr<WebEditCommandProxy> command = prpCommand;
 
1091
    m_undoClient.registerEditCommand(this, command, undoOrRedo);
 
1092
}
 
1093
 
 
1094
void WebView::clearAllEditCommands()
 
1095
{
 
1096
    m_undoClient.clearAllEditCommands(this);
 
1097
}
 
1098
 
 
1099
bool WebView::canUndoRedo(WebPageProxy::UndoOrRedo undoOrRedo)
 
1100
{
 
1101
    return m_undoClient.canUndoRedo(this, undoOrRedo);
 
1102
}
 
1103
 
 
1104
void WebView::executeUndoRedo(WebPageProxy::UndoOrRedo undoOrRedo)
 
1105
{
 
1106
    m_undoClient.executeUndoRedo(this, undoOrRedo);
 
1107
}
 
1108
    
 
1109
void WebView::reapplyEditCommand(WebEditCommandProxy* command)
 
1110
{
 
1111
    if (!m_page->isValid() || !m_page->isValidEditCommand(command))
 
1112
        return;
 
1113
    
 
1114
    command->reapply();
 
1115
}
 
1116
 
 
1117
void WebView::unapplyEditCommand(WebEditCommandProxy* command)
 
1118
{
 
1119
    if (!m_page->isValid() || !m_page->isValidEditCommand(command))
 
1120
        return;
 
1121
    
 
1122
    command->unapply();
 
1123
}
 
1124
 
 
1125
void WebView::setCustomDropTarget(IDropTarget* dropTarget)
 
1126
{
 
1127
    if (!m_page->isValid() || !m_window)
 
1128
        return;
 
1129
 
 
1130
    ::RevokeDragDrop(m_window);
 
1131
 
 
1132
    if (dropTarget)
 
1133
        ::RegisterDragDrop(m_window, dropTarget);
 
1134
    else
 
1135
        ::RegisterDragDrop(m_window, this);
 
1136
}
 
1137
 
 
1138
FloatRect WebView::convertToDeviceSpace(const FloatRect& rect)
 
1139
{
 
1140
    return rect;
 
1141
}
 
1142
 
 
1143
IntPoint WebView::screenToWindow(const IntPoint& point)
 
1144
{
 
1145
    return point;
 
1146
}
 
1147
 
 
1148
IntRect WebView::windowToScreen(const IntRect& rect)
 
1149
{
 
1150
    return rect;
 
1151
}
 
1152
 
 
1153
FloatRect WebView::convertToUserSpace(const FloatRect& rect)
 
1154
{
 
1155
    return rect;
 
1156
}
 
1157
 
 
1158
HIMC WebView::getIMMContext() 
 
1159
{
 
1160
    return Ime::ImmGetContext(m_window);
 
1161
}
 
1162
 
 
1163
void WebView::prepareCandidateWindow(HIMC hInputContext) 
 
1164
{
 
1165
    IntRect caret = m_page->firstRectForCharacterInSelectedRange(0);
 
1166
    CANDIDATEFORM form;
 
1167
    form.dwIndex = 0;
 
1168
    form.dwStyle = CFS_EXCLUDE;
 
1169
    form.ptCurrentPos.x = caret.x();
 
1170
    form.ptCurrentPos.y = caret.maxY();
 
1171
    form.rcArea.top = caret.y();
 
1172
    form.rcArea.bottom = caret.maxY();
 
1173
    form.rcArea.left = caret.x();
 
1174
    form.rcArea.right = caret.maxX();
 
1175
    Ime::ImmSetCandidateWindow(hInputContext, &form);
 
1176
}
 
1177
 
 
1178
void WebView::resetIME()
 
1179
{
 
1180
    HIMC hInputContext = getIMMContext();
 
1181
    if (!hInputContext)
 
1182
        return;
 
1183
    Ime::ImmNotifyIME(hInputContext, NI_COMPOSITIONSTR, CPS_CANCEL, 0);
 
1184
    Ime::ImmReleaseContext(m_window, hInputContext);
 
1185
}
 
1186
 
 
1187
void WebView::setInputMethodState(bool enabled)
 
1188
{
 
1189
    Ime::ImmAssociateContextEx(m_window, 0, enabled ? IACE_DEFAULT : 0);
 
1190
}
 
1191
 
 
1192
void WebView::compositionSelectionChanged(bool hasChanged)
 
1193
{
 
1194
    if (m_page->editorState().hasComposition && !hasChanged)
 
1195
        resetIME();
 
1196
}
 
1197
 
 
1198
bool WebView::onIMEStartComposition()
 
1199
{
 
1200
    LOG(TextInput, "onIMEStartComposition");
 
1201
    m_inIMEComposition++;
 
1202
 
 
1203
    HIMC hInputContext = getIMMContext();
 
1204
    if (!hInputContext)
 
1205
        return false;
 
1206
    prepareCandidateWindow(hInputContext);
 
1207
    Ime::ImmReleaseContext(m_window, hInputContext);
 
1208
    return true;
 
1209
}
 
1210
 
 
1211
static bool getCompositionString(HIMC hInputContext, DWORD type, String& result)
 
1212
{
 
1213
    LONG compositionLength = Ime::ImmGetCompositionStringW(hInputContext, type, 0, 0);
 
1214
    if (compositionLength <= 0)
 
1215
        return false;
 
1216
    Vector<UChar> compositionBuffer(compositionLength / 2);
 
1217
    compositionLength = Ime::ImmGetCompositionStringW(hInputContext, type, compositionBuffer.data(), compositionLength);
 
1218
    result = String::adopt(compositionBuffer);
 
1219
    return true;
 
1220
}
 
1221
 
 
1222
static void compositionToUnderlines(const Vector<DWORD>& clauses, const Vector<BYTE>& attributes, Vector<CompositionUnderline>& underlines)
 
1223
{
 
1224
    if (clauses.isEmpty()) {
 
1225
        underlines.clear();
 
1226
        return;
 
1227
    }
 
1228
  
 
1229
    size_t numBoundaries = clauses.size() - 1;
 
1230
    underlines.resize(numBoundaries);
 
1231
    for (unsigned i = 0; i < numBoundaries; ++i) {
 
1232
        underlines[i].startOffset = clauses[i];
 
1233
        underlines[i].endOffset = clauses[i + 1];
 
1234
        BYTE attribute = attributes[clauses[i]];
 
1235
        underlines[i].thick = attribute == ATTR_TARGET_CONVERTED || attribute == ATTR_TARGET_NOTCONVERTED;
 
1236
        underlines[i].color = Color::black;
 
1237
    }
 
1238
}
 
1239
 
 
1240
#if !LOG_DISABLED
 
1241
#define APPEND_ARGUMENT_NAME(name) \
 
1242
    if (lparam & name) { \
 
1243
        if (needsComma) \
 
1244
            result.appendLiteral(", "); \
 
1245
        result.appendLiteral(#name); \
 
1246
        needsComma = true; \
 
1247
    }
 
1248
 
 
1249
static String imeCompositionArgumentNames(LPARAM lparam)
 
1250
{
 
1251
    StringBuilder result;
 
1252
    bool needsComma = false;
 
1253
 
 
1254
    APPEND_ARGUMENT_NAME(GCS_COMPATTR);
 
1255
    APPEND_ARGUMENT_NAME(GCS_COMPCLAUSE);
 
1256
    APPEND_ARGUMENT_NAME(GCS_COMPREADSTR);
 
1257
    APPEND_ARGUMENT_NAME(GCS_COMPREADATTR);
 
1258
    APPEND_ARGUMENT_NAME(GCS_COMPREADCLAUSE);
 
1259
    APPEND_ARGUMENT_NAME(GCS_COMPSTR);
 
1260
    APPEND_ARGUMENT_NAME(GCS_CURSORPOS);
 
1261
    APPEND_ARGUMENT_NAME(GCS_DELTASTART);
 
1262
    APPEND_ARGUMENT_NAME(GCS_RESULTCLAUSE);
 
1263
    APPEND_ARGUMENT_NAME(GCS_RESULTREADCLAUSE);
 
1264
    APPEND_ARGUMENT_NAME(GCS_RESULTREADSTR);
 
1265
    APPEND_ARGUMENT_NAME(GCS_RESULTSTR);
 
1266
    APPEND_ARGUMENT_NAME(CS_INSERTCHAR);
 
1267
    APPEND_ARGUMENT_NAME(CS_NOMOVECARET);
 
1268
 
 
1269
    return result.toString();
 
1270
}
 
1271
 
 
1272
static String imeRequestName(WPARAM wparam)
 
1273
{
 
1274
    switch (wparam) {
 
1275
    case IMR_CANDIDATEWINDOW:
 
1276
        return "IMR_CANDIDATEWINDOW";
 
1277
    case IMR_COMPOSITIONFONT:
 
1278
        return "IMR_COMPOSITIONFONT";
 
1279
    case IMR_COMPOSITIONWINDOW:
 
1280
        return "IMR_COMPOSITIONWINDOW";
 
1281
    case IMR_CONFIRMRECONVERTSTRING:
 
1282
        return "IMR_CONFIRMRECONVERTSTRING";
 
1283
    case IMR_DOCUMENTFEED:
 
1284
        return "IMR_DOCUMENTFEED";
 
1285
    case IMR_QUERYCHARPOSITION:
 
1286
        return "IMR_QUERYCHARPOSITION";
 
1287
    case IMR_RECONVERTSTRING:
 
1288
        return "IMR_RECONVERTSTRING";
 
1289
    default:
 
1290
        return "Unknown (" + String::number(wparam) + ")";
 
1291
    }
 
1292
}
 
1293
#endif
 
1294
 
 
1295
bool WebView::onIMEComposition(LPARAM lparam)
 
1296
{
 
1297
    LOG(TextInput, "onIMEComposition %s", imeCompositionArgumentNames(lparam).latin1().data());
 
1298
    HIMC hInputContext = getIMMContext();
 
1299
    if (!hInputContext)
 
1300
        return true;
 
1301
 
 
1302
    if (!m_page->editorState().isContentEditable)
 
1303
        return true;
 
1304
 
 
1305
    prepareCandidateWindow(hInputContext);
 
1306
 
 
1307
    if (lparam & GCS_RESULTSTR || !lparam) {
 
1308
        String compositionString;
 
1309
        if (!getCompositionString(hInputContext, GCS_RESULTSTR, compositionString) && lparam)
 
1310
            return true;
 
1311
        
 
1312
        m_page->confirmComposition(compositionString);
 
1313
        return true;
 
1314
    }
 
1315
 
 
1316
    String compositionString;
 
1317
    if (!getCompositionString(hInputContext, GCS_COMPSTR, compositionString))
 
1318
        return true;
 
1319
    
 
1320
    // Composition string attributes
 
1321
    int numAttributes = Ime::ImmGetCompositionStringW(hInputContext, GCS_COMPATTR, 0, 0);
 
1322
    Vector<BYTE> attributes(numAttributes);
 
1323
    Ime::ImmGetCompositionStringW(hInputContext, GCS_COMPATTR, attributes.data(), numAttributes);
 
1324
 
 
1325
    // Get clauses
 
1326
    int numBytes = Ime::ImmGetCompositionStringW(hInputContext, GCS_COMPCLAUSE, 0, 0);
 
1327
    Vector<DWORD> clauses(numBytes / sizeof(DWORD));
 
1328
    Ime::ImmGetCompositionStringW(hInputContext, GCS_COMPCLAUSE, clauses.data(), numBytes);
 
1329
 
 
1330
    Vector<CompositionUnderline> underlines;
 
1331
    compositionToUnderlines(clauses, attributes, underlines);
 
1332
 
 
1333
    int cursorPosition = LOWORD(Ime::ImmGetCompositionStringW(hInputContext, GCS_CURSORPOS, 0, 0));
 
1334
 
 
1335
    m_page->setComposition(compositionString, underlines, cursorPosition);
 
1336
 
 
1337
    return true;
 
1338
}
 
1339
 
 
1340
bool WebView::onIMEEndComposition()
 
1341
{
 
1342
    LOG(TextInput, "onIMEEndComposition");
 
1343
    // If the composition hasn't been confirmed yet, it needs to be cancelled.
 
1344
    // This happens after deleting the last character from inline input hole.
 
1345
    if (m_page->editorState().hasComposition)
 
1346
        m_page->confirmComposition(String());
 
1347
 
 
1348
    if (m_inIMEComposition)
 
1349
        m_inIMEComposition--;
 
1350
 
 
1351
    return true;
 
1352
}
 
1353
 
 
1354
LRESULT WebView::onIMERequestCharPosition(IMECHARPOSITION* charPos)
 
1355
{
 
1356
    if (charPos->dwCharPos && !m_page->editorState().hasComposition)
 
1357
        return 0;
 
1358
    IntRect caret = m_page->firstRectForCharacterInSelectedRange(charPos->dwCharPos);
 
1359
    charPos->pt.x = caret.x();
 
1360
    charPos->pt.y = caret.y();
 
1361
    ::ClientToScreen(m_window, &charPos->pt);
 
1362
    charPos->cLineHeight = caret.height();
 
1363
    ::GetWindowRect(m_window, &charPos->rcDocument);
 
1364
    return true;
 
1365
}
 
1366
 
 
1367
LRESULT WebView::onIMERequestReconvertString(RECONVERTSTRING* reconvertString)
 
1368
{
 
1369
    String text = m_page->getSelectedText();
 
1370
    unsigned totalSize = sizeof(RECONVERTSTRING) + text.length() * sizeof(UChar);
 
1371
    
 
1372
    if (!reconvertString)
 
1373
        return totalSize;
 
1374
 
 
1375
    if (totalSize > reconvertString->dwSize)
 
1376
        return 0;
 
1377
    reconvertString->dwCompStrLen = text.length();
 
1378
    reconvertString->dwStrLen = text.length();
 
1379
    reconvertString->dwTargetStrLen = text.length();
 
1380
    reconvertString->dwStrOffset = sizeof(RECONVERTSTRING);
 
1381
    memcpy(reconvertString + 1, text.characters(), text.length() * sizeof(UChar));
 
1382
    return totalSize;
 
1383
}
 
1384
 
 
1385
LRESULT WebView::onIMERequest(WPARAM request, LPARAM data)
 
1386
{
 
1387
    LOG(TextInput, "onIMERequest %s", imeRequestName(request).latin1().data());
 
1388
    if (!m_page->editorState().isContentEditable)
 
1389
        return 0;
 
1390
 
 
1391
    switch (request) {
 
1392
    case IMR_RECONVERTSTRING:
 
1393
        return onIMERequestReconvertString(reinterpret_cast<RECONVERTSTRING*>(data));
 
1394
 
 
1395
    case IMR_QUERYCHARPOSITION:
 
1396
        return onIMERequestCharPosition(reinterpret_cast<IMECHARPOSITION*>(data));
 
1397
    }
 
1398
    return 0;
 
1399
}
 
1400
 
 
1401
bool WebView::onIMESelect(WPARAM wparam, LPARAM lparam)
 
1402
{
 
1403
    UNUSED_PARAM(wparam);
 
1404
    UNUSED_PARAM(lparam);
 
1405
    LOG(TextInput, "onIMESelect locale %ld %s", lparam, wparam ? "select" : "deselect");
 
1406
    return false;
 
1407
}
 
1408
 
 
1409
bool WebView::onIMESetContext(WPARAM wparam, LPARAM)
 
1410
{
 
1411
    LOG(TextInput, "onIMESetContext %s", wparam ? "active" : "inactive");
 
1412
    return false;
 
1413
}
 
1414
 
 
1415
void WebView::doneWithKeyEvent(const NativeWebKeyboardEvent& event, bool wasEventHandled)
 
1416
{
 
1417
    // Calling ::DefWindowProcW will ensure that pressing the Alt key will generate a WM_SYSCOMMAND
 
1418
    // event, e.g. See <http://webkit.org/b/47671>.
 
1419
    if (!wasEventHandled)
 
1420
        ::DefWindowProcW(event.nativeEvent()->hwnd, event.nativeEvent()->message, event.nativeEvent()->wParam, event.nativeEvent()->lParam);
 
1421
}
 
1422
 
 
1423
PassRefPtr<WebPopupMenuProxy> WebView::createPopupMenuProxy(WebPageProxy* page)
 
1424
{
 
1425
    return WebPopupMenuProxyWin::create(this, page);
 
1426
}
 
1427
 
 
1428
PassRefPtr<WebContextMenuProxy> WebView::createContextMenuProxy(WebPageProxy* page)
 
1429
{
 
1430
    return WebContextMenuProxyWin::create(m_window, page);
 
1431
}
 
1432
 
 
1433
#if ENABLE(INPUT_TYPE_COLOR)
 
1434
PassRefPtr<WebColorChooserProxy> WebView::createColorChooserProxy(WebPageProxy*, const WebCore::Color&, const WebCore::IntRect&)
 
1435
{
 
1436
    notImplemented();
 
1437
    return 0;
 
1438
}
 
1439
#endif
 
1440
 
 
1441
void WebView::setFindIndicator(PassRefPtr<FindIndicator> prpFindIndicator, bool fadeOut, bool animate)
 
1442
{
 
1443
    UNUSED_PARAM(animate);
 
1444
 
 
1445
    if (!m_findIndicatorCallback)
 
1446
        return;
 
1447
 
 
1448
    HBITMAP hbmp = 0;
 
1449
    IntRect selectionRect;
 
1450
 
 
1451
    if (RefPtr<FindIndicator> findIndicator = prpFindIndicator) {
 
1452
        if (ShareableBitmap* contentImage = findIndicator->contentImage()) {
 
1453
            // Render the contentImage to an HBITMAP.
 
1454
            void* bits;
 
1455
            HDC hdc = ::CreateCompatibleDC(0);
 
1456
            int width = contentImage->bounds().width();
 
1457
            int height = contentImage->bounds().height();
 
1458
            BitmapInfo bitmapInfo = BitmapInfo::create(contentImage->size());
 
1459
 
 
1460
            hbmp = CreateDIBSection(0, &bitmapInfo, DIB_RGB_COLORS, static_cast<void**>(&bits), 0, 0);
 
1461
            HBITMAP hbmpOld = static_cast<HBITMAP>(SelectObject(hdc, hbmp));
 
1462
#if USE(CG)
 
1463
            RetainPtr<CGContextRef> context(AdoptCF, CGBitmapContextCreate(bits, width, height,
 
1464
                8, width * sizeof(RGBQUAD), deviceRGBColorSpaceRef(), kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst));
 
1465
 
 
1466
            GraphicsContext graphicsContext(context.get());
 
1467
            contentImage->paint(graphicsContext, IntPoint(), contentImage->bounds());
 
1468
#else
 
1469
            // FIXME: Implement!
 
1470
#endif
 
1471
 
 
1472
            ::SelectObject(hdc, hbmpOld);
 
1473
            ::DeleteDC(hdc);
 
1474
        }
 
1475
 
 
1476
        selectionRect = IntRect(findIndicator->selectionRectInWindowCoordinates());
 
1477
    }
 
1478
    
 
1479
    // The callback is responsible for calling ::DeleteObject(hbmp).
 
1480
    (*m_findIndicatorCallback)(toAPI(this), hbmp, selectionRect, fadeOut, m_findIndicatorCallbackContext);
 
1481
}
 
1482
 
 
1483
void WebView::setFindIndicatorCallback(WKViewFindIndicatorCallback callback, void* context)
 
1484
{
 
1485
    m_findIndicatorCallback = callback;
 
1486
    m_findIndicatorCallbackContext = context;
 
1487
}
 
1488
 
 
1489
WKViewFindIndicatorCallback WebView::getFindIndicatorCallback(void** context)
 
1490
{
 
1491
    if (context)
 
1492
        *context = m_findIndicatorCallbackContext;
 
1493
    
 
1494
    return m_findIndicatorCallback;
 
1495
}
 
1496
 
 
1497
void WebView::didInstallOrUninstallPageOverlay(bool didInstall)
 
1498
{
 
1499
    m_pageOverlayInstalled = didInstall;
 
1500
}
 
1501
 
 
1502
void WebView::didCommitLoadForMainFrame(bool useCustomRepresentation)
 
1503
{
 
1504
}
 
1505
 
 
1506
void WebView::didFinishLoadingDataForCustomRepresentation(const String& suggestedFilename, const CoreIPC::DataReference&)
 
1507
{
 
1508
}
 
1509
 
 
1510
double WebView::customRepresentationZoomFactor()
 
1511
{
 
1512
    return 1;
 
1513
}
 
1514
 
 
1515
void WebView::setCustomRepresentationZoomFactor(double)
 
1516
{
 
1517
}
 
1518
 
 
1519
void WebView::didChangeScrollbarsForMainFrame() const
 
1520
{
 
1521
}
 
1522
 
 
1523
void WebView::findStringInCustomRepresentation(const String&, FindOptions, unsigned)
 
1524
{
 
1525
}
 
1526
 
 
1527
void WebView::countStringMatchesInCustomRepresentation(const String&, FindOptions, unsigned)
 
1528
{
 
1529
}
 
1530
 
 
1531
void WebView::setIsInWindow(bool isInWindow)
 
1532
{
 
1533
    m_isInWindow = isInWindow;
 
1534
    m_page->viewStateDidChange(WebPageProxy::ViewIsInWindow);
 
1535
}
 
1536
 
 
1537
void WebView::setIsVisible(bool isVisible)
 
1538
{
 
1539
    m_isVisible = isVisible;
 
1540
 
 
1541
    if (m_page)
 
1542
        m_page->viewStateDidChange(WebPageProxy::ViewIsVisible);
 
1543
}
 
1544
 
 
1545
#if USE(ACCELERATED_COMPOSITING)
 
1546
 
 
1547
void WebView::enterAcceleratedCompositingMode(const LayerTreeContext& context)
 
1548
{
 
1549
#if HAVE(WKQCA)
 
1550
    ASSERT(!context.isEmpty());
 
1551
 
 
1552
    m_layerHostWindow = context.window;
 
1553
 
 
1554
    IntSize size = viewSize();
 
1555
    // Ensure the layer host window is behind all other child windows (since otherwise it would obscure them).
 
1556
    ::SetWindowPos(m_layerHostWindow, HWND_BOTTOM, 0, 0, size.width(), size.height(), SWP_SHOWWINDOW | SWP_NOACTIVATE);
 
1557
#else
 
1558
    ASSERT_NOT_REACHED();
 
1559
#endif
 
1560
}
 
1561
 
 
1562
void WebView::exitAcceleratedCompositingMode()
 
1563
{
 
1564
#if HAVE(WKQCA)
 
1565
    ASSERT(m_layerHostWindow);
 
1566
 
 
1567
    // Tell the WKCACFViewWindow to destroy itself. We can't call ::DestroyWindow directly because
 
1568
    // the window is owned by another thread.
 
1569
    ::PostMessageW(m_layerHostWindow, WKCACFViewWindow::customDestroyMessage, 0, 0);
 
1570
    m_layerHostWindow = 0;
 
1571
#else
 
1572
    ASSERT_NOT_REACHED();
 
1573
#endif
 
1574
}
 
1575
 
 
1576
void WebView::updateAcceleratedCompositingMode(const LayerTreeContext&)
 
1577
{
 
1578
}
 
1579
#endif // USE(ACCELERATED_COMPOSITING)
 
1580
 
 
1581
HWND WebView::nativeWindow()
 
1582
{
 
1583
    return m_window;
 
1584
}
 
1585
 
 
1586
void WebView::scheduleChildWindowGeometryUpdate(const WindowGeometry& geometry)
 
1587
{
 
1588
    m_geometriesUpdater.addPendingUpdate(geometry);
 
1589
}
 
1590
 
 
1591
void WebView::updateChildWindowGeometries()
 
1592
{
 
1593
    m_geometriesUpdater.updateGeometries(DoNotBringToTop);
 
1594
}
 
1595
 
 
1596
// WebCore::WindowMessageListener
 
1597
 
 
1598
void WebView::windowReceivedMessage(HWND, UINT message, WPARAM wParam, LPARAM)
 
1599
{
 
1600
    switch (message) {
 
1601
    case WM_NCACTIVATE:
 
1602
        updateActiveStateSoon();
 
1603
        break;
 
1604
    case WM_SETTINGCHANGE:
 
1605
        // systemParameterChanged(wParam);
 
1606
        break;
 
1607
    }
 
1608
}
 
1609
 
 
1610
HRESULT STDMETHODCALLTYPE WebView::QueryInterface(REFIID riid, void** ppvObject)
 
1611
{
 
1612
    *ppvObject = 0;
 
1613
    if (IsEqualGUID(riid, IID_IUnknown))
 
1614
        *ppvObject = static_cast<IUnknown*>(this);
 
1615
    else if (IsEqualGUID(riid, IID_IDropTarget))
 
1616
        *ppvObject = static_cast<IDropTarget*>(this);
 
1617
    else
 
1618
        return E_NOINTERFACE;
 
1619
 
 
1620
    AddRef();
 
1621
    return S_OK;
 
1622
}
 
1623
 
 
1624
ULONG STDMETHODCALLTYPE WebView::AddRef(void)
 
1625
{
 
1626
    ref();
 
1627
    return refCount();
 
1628
}
 
1629
 
 
1630
ULONG STDMETHODCALLTYPE WebView::Release(void)
 
1631
{
 
1632
    deref();
 
1633
    return refCount();
 
1634
}
 
1635
 
 
1636
static DWORD dragOperationToDragCursor(DragOperation op)
 
1637
{
 
1638
    DWORD res = DROPEFFECT_NONE;
 
1639
    if (op & DragOperationCopy) 
 
1640
        res = DROPEFFECT_COPY;
 
1641
    else if (op & DragOperationLink) 
 
1642
        res = DROPEFFECT_LINK;
 
1643
    else if (op & DragOperationMove) 
 
1644
        res = DROPEFFECT_MOVE;
 
1645
    else if (op & DragOperationGeneric) 
 
1646
        res = DROPEFFECT_MOVE; // This appears to be the Firefox behaviour
 
1647
    return res;
 
1648
}
 
1649
 
 
1650
WebCore::DragOperation WebView::keyStateToDragOperation(DWORD grfKeyState) const
 
1651
{
 
1652
    if (!m_page)
 
1653
        return DragOperationNone;
 
1654
 
 
1655
    // Conforms to Microsoft's key combinations as documented for 
 
1656
    // IDropTarget::DragOver. Note, grfKeyState is the current 
 
1657
    // state of the keyboard modifier keys on the keyboard. See:
 
1658
    // <http://msdn.microsoft.com/en-us/library/ms680129(VS.85).aspx>.
 
1659
    DragOperation operation = m_page->dragSession().operation;
 
1660
 
 
1661
    if ((grfKeyState & (MK_CONTROL | MK_SHIFT)) == (MK_CONTROL | MK_SHIFT))
 
1662
        operation = DragOperationLink;
 
1663
    else if ((grfKeyState & MK_CONTROL) == MK_CONTROL)
 
1664
        operation = DragOperationCopy;
 
1665
    else if ((grfKeyState & MK_SHIFT) == MK_SHIFT)
 
1666
        operation = DragOperationGeneric;
 
1667
 
 
1668
    return operation;
 
1669
}
 
1670
 
 
1671
HRESULT STDMETHODCALLTYPE WebView::DragEnter(IDataObject* pDataObject, DWORD grfKeyState, POINTL pt, DWORD* pdwEffect)
 
1672
{
 
1673
    m_dragData = 0;
 
1674
    m_page->resetDragOperation();
 
1675
 
 
1676
    if (m_dropTargetHelper)
 
1677
        m_dropTargetHelper->DragEnter(m_window, pDataObject, (POINT*)&pt, *pdwEffect);
 
1678
 
 
1679
    POINTL localpt = pt;
 
1680
    ::ScreenToClient(m_window, (LPPOINT)&localpt);
 
1681
    DragData data(pDataObject, IntPoint(localpt.x, localpt.y), IntPoint(pt.x, pt.y), keyStateToDragOperation(grfKeyState));
 
1682
    m_page->dragEntered(&data);
 
1683
    *pdwEffect = dragOperationToDragCursor(m_page->dragSession().operation);
 
1684
 
 
1685
    m_lastDropEffect = *pdwEffect;
 
1686
    m_dragData = pDataObject;
 
1687
 
 
1688
    return S_OK;
 
1689
}
 
1690
 
 
1691
HRESULT STDMETHODCALLTYPE WebView::DragOver(DWORD grfKeyState, POINTL pt, DWORD* pdwEffect)
 
1692
{
 
1693
    if (m_dropTargetHelper)
 
1694
        m_dropTargetHelper->DragOver((POINT*)&pt, *pdwEffect);
 
1695
 
 
1696
    if (m_dragData) {
 
1697
        POINTL localpt = pt;
 
1698
        ::ScreenToClient(m_window, (LPPOINT)&localpt);
 
1699
        DragData data(m_dragData.get(), IntPoint(localpt.x, localpt.y), IntPoint(pt.x, pt.y), keyStateToDragOperation(grfKeyState));
 
1700
        m_page->dragUpdated(&data);
 
1701
        *pdwEffect = dragOperationToDragCursor(m_page->dragSession().operation);
 
1702
    } else
 
1703
        *pdwEffect = DROPEFFECT_NONE;
 
1704
 
 
1705
    m_lastDropEffect = *pdwEffect;
 
1706
    return S_OK;
 
1707
}
 
1708
 
 
1709
HRESULT STDMETHODCALLTYPE WebView::DragLeave()
 
1710
{
 
1711
    if (m_dropTargetHelper)
 
1712
        m_dropTargetHelper->DragLeave();
 
1713
 
 
1714
    if (m_dragData) {
 
1715
        DragData data(m_dragData.get(), IntPoint(), IntPoint(), DragOperationNone);
 
1716
        m_page->dragExited(&data);
 
1717
        m_dragData = 0;
 
1718
        m_page->resetDragOperation();
 
1719
    }
 
1720
    return S_OK;
 
1721
}
 
1722
 
 
1723
static bool maybeCreateSandboxExtensionFromDragData(const DragData& dragData, SandboxExtension::Handle& sandboxExtensionHandle)
 
1724
{
 
1725
    if (!dragData.containsFiles())
 
1726
        return false;
 
1727
 
 
1728
    // Unlike on Mac, we allow multiple files and directories, since on Windows
 
1729
    // we have actions for those (open the first file, open a Windows Explorer window).
 
1730
 
 
1731
    SandboxExtension::createHandle("\\", SandboxExtension::ReadOnly, sandboxExtensionHandle);
 
1732
    return true;
 
1733
}
 
1734
 
 
1735
HRESULT STDMETHODCALLTYPE WebView::Drop(IDataObject* pDataObject, DWORD grfKeyState, POINTL pt, DWORD* pdwEffect)
 
1736
{
 
1737
    if (m_dropTargetHelper)
 
1738
        m_dropTargetHelper->Drop(pDataObject, (POINT*)&pt, *pdwEffect);
 
1739
 
 
1740
    m_dragData = 0;
 
1741
    *pdwEffect = m_lastDropEffect;
 
1742
    POINTL localpt = pt;
 
1743
    ::ScreenToClient(m_window, (LPPOINT)&localpt);
 
1744
    DragData data(pDataObject, IntPoint(localpt.x, localpt.y), IntPoint(pt.x, pt.y), keyStateToDragOperation(grfKeyState));
 
1745
 
 
1746
    SandboxExtension::Handle sandboxExtensionHandle;
 
1747
    bool createdExtension = maybeCreateSandboxExtensionFromDragData(data, sandboxExtensionHandle);
 
1748
    if (createdExtension)
 
1749
        m_page->process()->willAcquireUniversalFileReadSandboxExtension();
 
1750
    SandboxExtension::HandleArray sandboxExtensionForUpload;
 
1751
    m_page->performDrag(&data, String(), sandboxExtensionHandle, sandboxExtensionForUpload);
 
1752
    return S_OK;
 
1753
}
 
1754
 
 
1755
#if ENABLE(FULLSCREEN_API)
 
1756
FullScreenController* WebView::fullScreenController()
 
1757
{
 
1758
    if (!m_fullScreenController)
 
1759
        m_fullScreenController = adoptPtr(new FullScreenController(this));
 
1760
    return m_fullScreenController.get();
 
1761
}
 
1762
 
 
1763
HWND WebView::fullScreenClientWindow() const
 
1764
{
 
1765
    return m_window;
 
1766
}
 
1767
 
 
1768
HWND WebView::fullScreenClientParentWindow() const
 
1769
{
 
1770
    return ::GetParent(m_window);
 
1771
}
 
1772
 
 
1773
void WebView::fullScreenClientSetParentWindow(HWND hostWindow)
 
1774
{
 
1775
    setParentWindow(hostWindow);
 
1776
}
 
1777
 
 
1778
void WebView::fullScreenClientWillEnterFullScreen()
 
1779
{
 
1780
    page()->fullScreenManager()->willEnterFullScreen();
 
1781
}
 
1782
 
 
1783
void WebView::fullScreenClientDidEnterFullScreen()
 
1784
{
 
1785
    page()->fullScreenManager()->didEnterFullScreen();
 
1786
}
 
1787
 
 
1788
void WebView::fullScreenClientWillExitFullScreen()
 
1789
{
 
1790
    page()->fullScreenManager()->willExitFullScreen();
 
1791
}
 
1792
 
 
1793
void WebView::fullScreenClientDidExitFullScreen()
 
1794
{
 
1795
    page()->fullScreenManager()->didExitFullScreen();
 
1796
}
 
1797
 
 
1798
static void fullScreenClientForceRepaintCompleted(WKErrorRef, void* context)
 
1799
{
 
1800
    ASSERT(context);
 
1801
    static_cast<WebView*>(context)->fullScreenController()->repaintCompleted();
 
1802
}
 
1803
 
 
1804
void WebView::fullScreenClientForceRepaint()
 
1805
{
 
1806
    page()->forceRepaint(VoidCallback::create(this, &fullScreenClientForceRepaintCompleted));
 
1807
}
 
1808
 
 
1809
#endif
 
1810
} // namespace WebKit