Rename pageCache() to PageCache::shared() and return a reference
[WebKit-https.git] / Source / WebKit / win / WebView.cpp
1 /*
2  * Copyright (C) 2006-2014 Apple, Inc.  All rights reserved.
3  * Copyright (C) 2009, 2010, 2011 Appcelerator, Inc. All rights reserved.
4  * Copyright (C) 2011 Brent Fulgham. All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
16  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
19  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
23  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
26  */
27
28 #include "WebView.h"
29
30 #include "BackForwardController.h"
31 #include "COMVariantSetter.h"
32 #include "DOMCoreClasses.h"
33 #include "FullscreenVideoController.h"
34 #include "MarshallingHelpers.h"
35 #include "PluginDatabase.h"
36 #include "PluginView.h"
37 #include "ResourceLoadScheduler.h"
38 #include "SoftLinking.h"
39 #include "SubframeLoader.h"
40 #include "TextIterator.h"
41 #include "WebBackForwardList.h"
42 #include "WebChromeClient.h"
43 #include "WebContextMenuClient.h"
44 #include "WebCoreTextRenderer.h"
45 #include "WebDatabaseManager.h"
46 #include "WebDatabaseProvider.h"
47 #include "WebDocumentLoader.h"
48 #include "WebDownload.h"
49 #include "WebDragClient.h"
50 #include "WebEditorClient.h"
51 #include "WebElementPropertyBag.h"
52 #include "WebFrame.h"
53 #include "WebFrameLoaderClient.h"
54 #include "WebFrameNetworkingContext.h"
55 #include "WebGeolocationClient.h"
56 #include "WebGeolocationPosition.h"
57 #include "WebIconDatabase.h"
58 #include "WebInspector.h"
59 #include "WebInspectorClient.h"
60 #include "WebKit.h"
61 #include "WebKitDLL.h"
62 #include "WebKitLogging.h"
63 #include "WebKitStatisticsPrivate.h"
64 #include "WebKitSystemBits.h"
65 #include "WebKitVersion.h"
66 #include "WebMutableURLRequest.h"
67 #include "WebNotificationCenter.h"
68 #include "WebPlatformStrategies.h"
69 #include "WebPreferences.h"
70 #include "WebScriptWorld.h"
71 #include "WebStorageNamespaceProvider.h"
72 #include "WebVisitedLinkStore.h"
73 #include "resource.h"
74 #include <JavaScriptCore/APICast.h>
75 #include <JavaScriptCore/InitializeThreading.h>
76 #include <JavaScriptCore/JSCJSValue.h>
77 #include <JavaScriptCore/JSLock.h>
78 #include <WebCore/AXObjectCache.h>
79 #include <WebCore/ApplicationCacheStorage.h>
80 #include <WebCore/BString.h>
81 #include <WebCore/BackForwardController.h>
82 #include <WebCore/BackForwardList.h>
83 #include <WebCore/BitmapInfo.h>
84 #include <WebCore/Chrome.h>
85 #include <WebCore/ContextMenu.h>
86 #include <WebCore/ContextMenuController.h>
87 #include <WebCore/Cursor.h>
88 #include <WebCore/DatabaseManager.h>
89 #include <WebCore/Document.h>
90 #include <WebCore/DocumentMarkerController.h>
91 #include <WebCore/DragController.h>
92 #include <WebCore/DragData.h>
93 #include <WebCore/Editor.h>
94 #include <WebCore/EventHandler.h>
95 #include <WebCore/EventNames.h>
96 #include <WebCore/FileSystem.h>
97 #include <WebCore/FloatQuad.h>
98 #include <WebCore/FocusController.h>
99 #include <WebCore/Font.h>
100 #include <WebCore/FrameLoader.h>
101 #include <WebCore/FrameSelection.h>
102 #include <WebCore/FrameTree.h>
103 #include <WebCore/FrameView.h>
104 #include <WebCore/FrameWin.h>
105 #include <WebCore/FullScreenController.h>
106 #include <WebCore/GDIObjectCounter.h>
107 #include <WebCore/GeolocationController.h>
108 #include <WebCore/GeolocationError.h>
109 #include <WebCore/GraphicsContext.h>
110 #include <WebCore/HTMLNames.h>
111 #include <WebCore/HTMLVideoElement.h>
112 #include <WebCore/HWndDC.h>
113 #include <WebCore/HistoryController.h>
114 #include <WebCore/HistoryItem.h>
115 #include <WebCore/HitTestRequest.h>
116 #include <WebCore/HitTestResult.h>
117 #include <WebCore/IntRect.h>
118 #include <WebCore/JSElement.h>
119 #include <WebCore/KeyboardEvent.h>
120 #include <WebCore/Logging.h>
121 #include <WebCore/MIMETypeRegistry.h>
122 #include <WebCore/MainFrame.h>
123 #include <WebCore/MemoryCache.h>
124 #include <WebCore/NotImplemented.h>
125 #include <WebCore/Page.h>
126 #include <WebCore/PageCache.h>
127 #include <WebCore/PageConfiguration.h>
128 #include <WebCore/PageGroup.h>
129 #include <WebCore/PlatformKeyboardEvent.h>
130 #include <WebCore/PlatformMouseEvent.h>
131 #include <WebCore/PlatformWheelEvent.h>
132 #include <WebCore/PluginData.h>
133 #include <WebCore/PopupMenu.h>
134 #include <WebCore/PopupMenuWin.h>
135 #include <WebCore/ProgressTracker.h>
136 #include <WebCore/RenderLayer.h>
137 #include <WebCore/RenderTheme.h>
138 #include <WebCore/RenderTreeAsText.h>
139 #include <WebCore/RenderView.h>
140 #include <WebCore/RenderWidget.h>
141 #include <WebCore/ResourceHandle.h>
142 #include <WebCore/ResourceHandleClient.h>
143 #include <WebCore/ResourceRequest.h>
144 #include <WebCore/RuntimeEnabledFeatures.h>
145 #include <WebCore/SchemeRegistry.h>
146 #include <WebCore/ScriptController.h>
147 #include <WebCore/Scrollbar.h>
148 #include <WebCore/ScrollbarTheme.h>
149 #include <WebCore/SecurityOrigin.h>
150 #include <WebCore/SecurityPolicy.h>
151 #include <WebCore/Settings.h>
152 #include <WebCore/SystemInfo.h>
153 #include <WebCore/WindowMessageBroadcaster.h>
154 #include <WebCore/WindowsTouch.h>
155 #include <bindings/ScriptValue.h>
156 #include <wtf/MainThread.h>
157
158 #if USE(CG)
159 #include <CoreGraphics/CGContext.h>
160 #endif
161
162 #if USE(CF)
163 #include <CoreFoundation/CoreFoundation.h>
164 #endif
165
166 #if USE(CFNETWORK)
167 #include <CFNetwork/CFURLCachePriv.h>
168 #include <CFNetwork/CFURLProtocolPriv.h>
169 #include <WebKitSystemInterface/WebKitSystemInterface.h>
170 #elif USE(CURL)
171 #include <WebCore/CurlCacheManager.h>
172 #endif
173
174 #if USE(CA)
175 #include <WebCore/CACFLayerTreeHost.h>
176 #include <WebCore/PlatformCALayer.h>
177 #elif USE(TEXTURE_MAPPER_GL)
178 #include "AcceleratedCompositingContext.h"
179 #endif
180
181 #if ENABLE(FULLSCREEN_API)
182 #include <WebCore/FullScreenController.h>
183 #endif
184
185 #include <ShlObj.h>
186 #include <comutil.h>
187 #include <dimm.h>
188 #include <oleacc.h>
189 #include <wchar.h>
190 #include <windowsx.h>
191 #include <wtf/HashSet.h>
192 #include <wtf/text/CString.h>
193 #include <wtf/text/StringConcatenate.h>
194 #include <wtf/win/GDIObject.h>
195
196 // Soft link functions for gestures and panning feedback
197 SOFT_LINK_LIBRARY(USER32);
198 SOFT_LINK_OPTIONAL(USER32, GetGestureInfo, BOOL, WINAPI, (HGESTUREINFO, PGESTUREINFO));
199 SOFT_LINK_OPTIONAL(USER32, SetGestureConfig, BOOL, WINAPI, (HWND, DWORD, UINT, PGESTURECONFIG, UINT));
200 SOFT_LINK_OPTIONAL(USER32, CloseGestureInfoHandle, BOOL, WINAPI, (HGESTUREINFO));
201 SOFT_LINK_LIBRARY(Uxtheme);
202 SOFT_LINK_OPTIONAL(Uxtheme, BeginPanningFeedback, BOOL, WINAPI, (HWND));
203 SOFT_LINK_OPTIONAL(Uxtheme, EndPanningFeedback, BOOL, WINAPI, (HWND, BOOL));
204 SOFT_LINK_OPTIONAL(Uxtheme, UpdatePanningFeedback, BOOL, WINAPI, (HWND, LONG, LONG, BOOL));
205
206 using namespace WebCore;
207 using namespace std;
208 using JSC::JSLock;
209
210 static HMODULE accessibilityLib;
211 static HashSet<WebView*>& pendingDeleteBackingStoreSet()
212 {
213     static NeverDestroyed<HashSet<WebView*>> pendingDeleteBackingStoreSet;
214     return pendingDeleteBackingStoreSet;
215 }
216
217 static CFStringRef WebKitLocalCacheDefaultsKey = CFSTR("WebKitLocalCache");
218
219 static String webKitVersionString();
220
221 WebView* kit(Page* page)
222 {
223     if (!page)
224         return 0;
225     
226     if (page->chrome().client().isEmptyChromeClient())
227         return 0;
228     
229     return static_cast<WebChromeClient&>(page->chrome().client()).webView();
230 }
231
232 static inline AtomicString toAtomicString(BSTR bstr)
233 {
234     return AtomicString(bstr, SysStringLen(bstr));
235 }
236
237 static inline String toString(BSTR bstr)
238 {
239     return String(bstr, SysStringLen(bstr));
240 }
241
242 static inline String toString(BString &bstr)
243 {
244     return String(bstr, SysStringLen(bstr));
245 }
246
247 static inline URL toURL(BSTR bstr)
248 {
249     return URL(URL(), toString(bstr));
250 }
251
252 class PreferencesChangedOrRemovedObserver : public IWebNotificationObserver {
253 public:
254     static PreferencesChangedOrRemovedObserver* sharedInstance();
255
256 private:
257     PreferencesChangedOrRemovedObserver() {}
258     ~PreferencesChangedOrRemovedObserver() {}
259
260     virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID, void**) { return E_FAIL; }
261     virtual ULONG STDMETHODCALLTYPE AddRef(void) { return 0; }
262     virtual ULONG STDMETHODCALLTYPE Release(void) { return 0; }
263
264 public:
265     // IWebNotificationObserver
266     virtual HRESULT STDMETHODCALLTYPE onNotify( 
267         /* [in] */ IWebNotification* notification);
268
269 private:
270     HRESULT notifyPreferencesChanged(WebCacheModel);
271     HRESULT notifyPreferencesRemoved(WebCacheModel);
272 };
273
274 PreferencesChangedOrRemovedObserver* PreferencesChangedOrRemovedObserver::sharedInstance()
275 {
276     static PreferencesChangedOrRemovedObserver* shared = new PreferencesChangedOrRemovedObserver;
277     return shared;
278 }
279
280 HRESULT PreferencesChangedOrRemovedObserver::onNotify(IWebNotification* notification)
281 {
282     HRESULT hr = S_OK;
283
284     COMPtr<IUnknown> unkPrefs;
285     hr = notification->getObject(&unkPrefs);
286     if (FAILED(hr))
287         return hr;
288
289     COMPtr<IWebPreferences> preferences(Query, unkPrefs);
290     if (!preferences)
291         return E_NOINTERFACE;
292
293     WebCacheModel cacheModel;
294     hr = preferences->cacheModel(&cacheModel);
295     if (FAILED(hr))
296         return hr;
297
298     BString name;
299     hr = notification->name(&name);
300     if (FAILED(hr))
301         return hr;
302
303     if (wcscmp(name, WebPreferences::webPreferencesChangedNotification()) == 0)
304         return notifyPreferencesChanged(cacheModel);
305
306     if (wcscmp(name, WebPreferences::webPreferencesRemovedNotification()) == 0)
307         return notifyPreferencesRemoved(cacheModel);
308
309     ASSERT_NOT_REACHED();
310     return E_FAIL;
311 }
312
313 HRESULT PreferencesChangedOrRemovedObserver::notifyPreferencesChanged(WebCacheModel cacheModel)
314 {
315     HRESULT hr = S_OK;
316
317     if (!WebView::didSetCacheModel() || cacheModel > WebView::cacheModel())
318         WebView::setCacheModel(cacheModel);
319     else if (cacheModel < WebView::cacheModel()) {
320         WebCacheModel sharedPreferencesCacheModel;
321         hr = WebPreferences::sharedStandardPreferences()->cacheModel(&sharedPreferencesCacheModel);
322         if (FAILED(hr))
323             return hr;
324         WebView::setCacheModel(max(sharedPreferencesCacheModel, WebView::maxCacheModelInAnyInstance()));
325     }
326
327     return hr;
328 }
329
330 HRESULT PreferencesChangedOrRemovedObserver::notifyPreferencesRemoved(WebCacheModel cacheModel)
331 {
332     HRESULT hr = S_OK;
333
334     if (cacheModel == WebView::cacheModel()) {
335         WebCacheModel sharedPreferencesCacheModel;
336         hr = WebPreferences::sharedStandardPreferences()->cacheModel(&sharedPreferencesCacheModel);
337         if (FAILED(hr))
338             return hr;
339         WebView::setCacheModel(max(sharedPreferencesCacheModel, WebView::maxCacheModelInAnyInstance()));
340     }
341
342     return hr;
343 }
344
345
346 const LPCWSTR kWebViewWindowClassName = L"WebViewWindowClass";
347
348 const int WM_XP_THEMECHANGED = 0x031A;
349 const int WM_VISTA_MOUSEHWHEEL = 0x020E;
350
351 static const int maxToolTipWidth = 250;
352
353 static const int delayBeforeDeletingBackingStoreMsec = 5000;
354
355 static ATOM registerWebView();
356
357 static void initializeStaticObservers();
358
359 static HRESULT updateSharedSettingsFromPreferencesIfNeeded(IWebPreferences*);
360
361 HRESULT createMatchEnumerator(Vector<IntRect>* rects, IEnumTextMatches** matches);
362
363 static bool continuousSpellCheckingEnabled;
364 static bool grammarCheckingEnabled;
365
366 static bool s_didSetCacheModel;
367 static WebCacheModel s_cacheModel = WebCacheModelDocumentViewer;
368
369 enum {
370     UpdateActiveStateTimer = 1,
371     DeleteBackingStoreTimer = 2,
372 };
373
374 // WebView ----------------------------------------------------------------
375
376 bool WebView::s_allowSiteSpecificHacks = false;
377
378 WebView::WebView()
379     : m_refCount(0)
380     , m_shouldInvertColors(false)
381 #if !ASSERT_DISABLED
382     , m_deletionHasBegun(false)
383 #endif
384     , m_hostWindow(0)
385     , m_viewWindow(0)
386     , m_mainFrame(0)
387     , m_page(0)
388     , m_inspectorClient(0)
389     , m_hasCustomDropTarget(false)
390     , m_useBackForwardList(true)
391     , m_userAgentOverridden(false)
392     , m_zoomMultiplier(1.0f)
393     , m_zoomsTextOnly(false)
394     , m_mouseActivated(false)
395     , m_dragData(0)
396     , m_currentCharacterCode(0)
397     , m_isBeingDestroyed(false)
398     , m_paintCount(0)
399     , m_hasSpellCheckerDocumentTag(false)
400     , m_didClose(false)
401     , m_inIMEComposition(0)
402     , m_toolTipHwnd(0)
403     , m_closeWindowTimer(0)
404     , m_topLevelParent(0)
405     , m_deleteBackingStoreTimerActive(false)
406     , m_transparent(false)
407     , m_lastPanX(0)
408     , m_lastPanY(0)
409     , m_xOverpan(0)
410     , m_yOverpan(0)
411     , m_isAcceleratedCompositing(false)
412     , m_nextDisplayIsSynchronous(false)
413     , m_lastSetCursor(0)
414     , m_usesLayeredWindow(false)
415     , m_needsDisplay(false)
416 #if USE(TEXTURE_MAPPER_GL)
417     , m_acceleratedCompositingContext(nullptr)
418 #endif
419 {
420     JSC::initializeThreading();
421     WTF::initializeMainThread();
422
423     m_backingStoreSize.cx = m_backingStoreSize.cy = 0;
424
425     CoCreateInstance(CLSID_DragDropHelper, 0, CLSCTX_INPROC_SERVER, IID_IDropTargetHelper,(void**)&m_dropTargetHelper);
426
427     initializeStaticObservers();
428
429     WebPreferences* sharedPreferences = WebPreferences::sharedStandardPreferences();
430     BOOL enabled;
431     if (SUCCEEDED(sharedPreferences->continuousSpellCheckingEnabled(&enabled)))
432         continuousSpellCheckingEnabled = !!enabled;
433     if (SUCCEEDED(sharedPreferences->grammarCheckingEnabled(&enabled)))
434         grammarCheckingEnabled = !!enabled;
435
436     WebViewCount++;
437     gClassCount++;
438     gClassNameCount().add("WebView");
439 }
440
441 WebView::~WebView()
442 {
443     deleteBackingStore();
444
445     // the tooltip window needs to be explicitly destroyed since it isn't a WS_CHILD
446     if (::IsWindow(m_toolTipHwnd))
447         ::DestroyWindow(m_toolTipHwnd);
448
449     ASSERT(!m_page);
450     ASSERT(!m_preferences);
451     ASSERT(!m_viewWindow);
452
453 #if USE(CA)
454     ASSERT(!m_layerTreeHost);
455 #endif
456
457     WebViewCount--;
458     gClassCount--;
459     gClassNameCount().remove("WebView");
460 }
461
462 WebView* WebView::createInstance()
463 {
464     WebView* instance = new WebView();
465     instance->AddRef();
466     return instance;
467 }
468
469 void initializeStaticObservers()
470 {
471     static bool initialized;
472     if (initialized)
473         return;
474     initialized = true;
475
476     IWebNotificationCenter* notifyCenter = WebNotificationCenter::defaultCenterInternal();
477     notifyCenter->addObserver(PreferencesChangedOrRemovedObserver::sharedInstance(), WebPreferences::webPreferencesChangedNotification(), 0);
478     notifyCenter->addObserver(PreferencesChangedOrRemovedObserver::sharedInstance(), WebPreferences::webPreferencesRemovedNotification(), 0);
479 }
480
481 static HashSet<WebView*>& allWebViewsSet()
482 {
483     static HashSet<WebView*> allWebViewsSet;
484     return allWebViewsSet;
485 }
486
487 void WebView::addToAllWebViewsSet()
488 {
489     allWebViewsSet().add(this);
490 }
491
492 void WebView::removeFromAllWebViewsSet()
493 {
494     allWebViewsSet().remove(this);
495 }
496
497 void WebView::setCacheModel(WebCacheModel cacheModel)
498 {
499     if (s_didSetCacheModel && cacheModel == s_cacheModel)
500         return;
501
502     String cacheDirectory;
503
504 #if USE(CFNETWORK)
505     RetainPtr<CFURLCacheRef> cfurlCache = adoptCF(CFURLCacheCopySharedURLCache());
506     RetainPtr<CFStringRef> cfurlCacheDirectory = adoptCF(wkCopyFoundationCacheDirectory(0));
507     if (!cfurlCacheDirectory) {
508         RetainPtr<CFPropertyListRef> preference = adoptCF(CFPreferencesCopyAppValue(WebKitLocalCacheDefaultsKey, kCFPreferencesCurrentApplication));
509         if (preference && (CFStringGetTypeID() == CFGetTypeID(preference.get())))
510             cfurlCacheDirectory = adoptCF(static_cast<CFStringRef>(preference.leakRef()));
511         else
512             cfurlCacheDirectory = WebCore::localUserSpecificStorageDirectory().createCFString();
513     }
514     cacheDirectory = String(cfurlCacheDirectory);
515     CFIndex cacheMemoryCapacity = 0;
516     CFIndex cacheDiskCapacity = 0;
517 #elif USE(CURL)
518     cacheDirectory = CurlCacheManager::getInstance().cacheDirectory();
519     long cacheMemoryCapacity = 0;
520     long cacheDiskCapacity = 0;
521 #endif
522
523     // As a fudge factor, use 1000 instead of 1024, in case the reported byte 
524     // count doesn't align exactly to a megabyte boundary.
525     unsigned long long memSize = WebMemorySize() / 1024 / 1000;
526     unsigned long long diskFreeSize = WebVolumeFreeSize(cacheDirectory) / 1024 / 1000;
527
528     unsigned cacheTotalCapacity = 0;
529     unsigned cacheMinDeadCapacity = 0;
530     unsigned cacheMaxDeadCapacity = 0;
531     auto deadDecodedDataDeletionInterval = std::chrono::seconds { 0 };
532
533     unsigned pageCacheCapacity = 0;
534
535
536     switch (cacheModel) {
537     case WebCacheModelDocumentViewer: {
538         // Page cache capacity (in pages)
539         pageCacheCapacity = 0;
540
541         // Object cache capacities (in bytes)
542         if (memSize >= 2048)
543             cacheTotalCapacity = 96 * 1024 * 1024;
544         else if (memSize >= 1536)
545             cacheTotalCapacity = 64 * 1024 * 1024;
546         else if (memSize >= 1024)
547             cacheTotalCapacity = 32 * 1024 * 1024;
548         else if (memSize >= 512)
549             cacheTotalCapacity = 16 * 1024 * 1024; 
550
551         cacheMinDeadCapacity = 0;
552         cacheMaxDeadCapacity = 0;
553
554         // Memory cache capacity (in bytes)
555         cacheMemoryCapacity = 0;
556
557 #if USE(CFNETWORK)
558         // Foundation disk cache capacity (in bytes)
559         cacheDiskCapacity = CFURLCacheDiskCapacity(cfurlCache.get());
560 #endif
561         break;
562     }
563     case WebCacheModelDocumentBrowser: {
564         // Page cache capacity (in pages)
565         if (memSize >= 1024)
566             pageCacheCapacity = 3;
567         else if (memSize >= 512)
568             pageCacheCapacity = 2;
569         else if (memSize >= 256)
570             pageCacheCapacity = 1;
571         else
572             pageCacheCapacity = 0;
573
574         // Object cache capacities (in bytes)
575         if (memSize >= 2048)
576             cacheTotalCapacity = 96 * 1024 * 1024;
577         else if (memSize >= 1536)
578             cacheTotalCapacity = 64 * 1024 * 1024;
579         else if (memSize >= 1024)
580             cacheTotalCapacity = 32 * 1024 * 1024;
581         else if (memSize >= 512)
582             cacheTotalCapacity = 16 * 1024 * 1024; 
583
584         cacheMinDeadCapacity = cacheTotalCapacity / 8;
585         cacheMaxDeadCapacity = cacheTotalCapacity / 4;
586
587         // Memory cache capacity (in bytes)
588         if (memSize >= 2048)
589             cacheMemoryCapacity = 4 * 1024 * 1024;
590         else if (memSize >= 1024)
591             cacheMemoryCapacity = 2 * 1024 * 1024;
592         else if (memSize >= 512)
593             cacheMemoryCapacity = 1 * 1024 * 1024;
594         else
595             cacheMemoryCapacity =      512 * 1024; 
596
597         // Disk cache capacity (in bytes)
598         if (diskFreeSize >= 16384)
599             cacheDiskCapacity = 50 * 1024 * 1024;
600         else if (diskFreeSize >= 8192)
601             cacheDiskCapacity = 40 * 1024 * 1024;
602         else if (diskFreeSize >= 4096)
603             cacheDiskCapacity = 30 * 1024 * 1024;
604         else
605             cacheDiskCapacity = 20 * 1024 * 1024;
606
607         break;
608     }
609     case WebCacheModelPrimaryWebBrowser: {
610         // Page cache capacity (in pages)
611         // (Research indicates that value / page drops substantially after 3 pages.)
612         if (memSize >= 2048)
613             pageCacheCapacity = 5;
614         else if (memSize >= 1024)
615             pageCacheCapacity = 4;
616         else if (memSize >= 512)
617             pageCacheCapacity = 3;
618         else if (memSize >= 256)
619             pageCacheCapacity = 2;
620         else
621             pageCacheCapacity = 1;
622
623         // Object cache capacities (in bytes)
624         // (Testing indicates that value / MB depends heavily on content and
625         // browsing pattern. Even growth above 128MB can have substantial 
626         // value / MB for some content / browsing patterns.)
627         if (memSize >= 2048)
628             cacheTotalCapacity = 128 * 1024 * 1024;
629         else if (memSize >= 1536)
630             cacheTotalCapacity = 96 * 1024 * 1024;
631         else if (memSize >= 1024)
632             cacheTotalCapacity = 64 * 1024 * 1024;
633         else if (memSize >= 512)
634             cacheTotalCapacity = 32 * 1024 * 1024; 
635
636         cacheMinDeadCapacity = cacheTotalCapacity / 4;
637         cacheMaxDeadCapacity = cacheTotalCapacity / 2;
638
639         // This code is here to avoid a PLT regression. We can remove it if we
640         // can prove that the overall system gain would justify the regression.
641         cacheMaxDeadCapacity = max(24u, cacheMaxDeadCapacity);
642
643         deadDecodedDataDeletionInterval = std::chrono::seconds { 60 };
644
645         // Memory cache capacity (in bytes)
646         // (These values are small because WebCore does most caching itself.)
647         if (memSize >= 1024)
648             cacheMemoryCapacity = 4 * 1024 * 1024;
649         else if (memSize >= 512)
650             cacheMemoryCapacity = 2 * 1024 * 1024;
651         else if (memSize >= 256)
652             cacheMemoryCapacity = 1 * 1024 * 1024;
653         else
654             cacheMemoryCapacity =      512 * 1024; 
655
656         // Disk cache capacity (in bytes)
657         if (diskFreeSize >= 16384)
658             cacheDiskCapacity = 175 * 1024 * 1024;
659         else if (diskFreeSize >= 8192)
660             cacheDiskCapacity = 150 * 1024 * 1024;
661         else if (diskFreeSize >= 4096)
662             cacheDiskCapacity = 125 * 1024 * 1024;
663         else if (diskFreeSize >= 2048)
664             cacheDiskCapacity = 100 * 1024 * 1024;
665         else if (diskFreeSize >= 1024)
666             cacheDiskCapacity = 75 * 1024 * 1024;
667         else
668             cacheDiskCapacity = 50 * 1024 * 1024;
669
670         break;
671     }
672     default:
673         ASSERT_NOT_REACHED();
674     }
675
676     memoryCache().setCapacities(cacheMinDeadCapacity, cacheMaxDeadCapacity, cacheTotalCapacity);
677     memoryCache().setDeadDecodedDataDeletionInterval(deadDecodedDataDeletionInterval);
678     PageCache::shared().setCapacity(pageCacheCapacity);
679
680 #if USE(CFNETWORK)
681     // Don't shrink a big disk cache, since that would cause churn.
682     cacheDiskCapacity = max(cacheDiskCapacity, CFURLCacheDiskCapacity(cfurlCache.get()));
683
684     CFURLCacheSetMemoryCapacity(cfurlCache.get(), cacheMemoryCapacity);
685     CFURLCacheSetDiskCapacity(cfurlCache.get(), cacheDiskCapacity);
686 #elif USE(CURL)
687     CurlCacheManager::getInstance().setStorageSizeLimit(cacheDiskCapacity);
688 #endif
689
690     s_didSetCacheModel = true;
691     s_cacheModel = cacheModel;
692     return;
693 }
694
695 WebCacheModel WebView::cacheModel()
696 {
697     return s_cacheModel;
698 }
699
700 bool WebView::didSetCacheModel()
701 {
702     return s_didSetCacheModel;
703 }
704
705 WebCacheModel WebView::maxCacheModelInAnyInstance()
706 {
707     WebCacheModel cacheModel = WebCacheModelDocumentViewer;
708
709     HashSet<WebView*>::iterator end = allWebViewsSet().end();
710     for (HashSet<WebView*>::iterator it = allWebViewsSet().begin(); it != end; ++it) {
711         COMPtr<IWebPreferences> pref;
712         if (FAILED((*it)->preferences(&pref)))
713             continue;
714         WebCacheModel prefCacheModel = WebCacheModelDocumentViewer;
715         if (FAILED(pref->cacheModel(&prefCacheModel)))
716             continue;
717
718         cacheModel = max(cacheModel, prefCacheModel);
719     }
720
721     return cacheModel;
722 }
723
724 HRESULT STDMETHODCALLTYPE WebView::close()
725 {
726     if (m_didClose)
727         return S_OK;
728
729     m_didClose = true;
730
731     setAcceleratedCompositing(false);
732
733     WebNotificationCenter::defaultCenterInternal()->postNotificationName(_bstr_t(WebViewWillCloseNotification).GetBSTR(), static_cast<IWebView*>(this), 0);
734
735     if (m_uiDelegatePrivate)
736         m_uiDelegatePrivate->webViewClosing(this);
737
738     removeFromAllWebViewsSet();
739
740     if (m_page)
741         m_page->mainFrame().loader().detachFromParent();
742
743     if (m_mouseOutTracker) {
744         m_mouseOutTracker->dwFlags = TME_CANCEL;
745         ::TrackMouseEvent(m_mouseOutTracker.get());
746         m_mouseOutTracker.reset();
747     }
748     
749     revokeDragDrop();
750
751     if (m_viewWindow) {
752         // We can't check IsWindow(m_viewWindow) here, because that will return true even while
753         // we're already handling WM_DESTROY. So we check !isBeingDestroyed() instead.
754         if (!isBeingDestroyed())
755             DestroyWindow(m_viewWindow);
756         // Either we just destroyed m_viewWindow, or it's in the process of being destroyed. Either
757         // way, we clear it out to make sure we don't try to use it later.
758         m_viewWindow = 0;
759     }
760
761     setHostWindow(0);
762
763     setAccessibilityDelegate(0);
764     setDownloadDelegate(0);
765     setEditingDelegate(0);
766     setFrameLoadDelegate(0);
767     setFrameLoadDelegatePrivate(0);
768     setHistoryDelegate(0);
769     setPolicyDelegate(0);
770     setResourceLoadDelegate(0);
771     setUIDelegate(0);
772     setFormDelegate(0);
773
774     m_inspectorClient = 0;
775     if (m_webInspector)
776         m_webInspector->webViewClosed();
777
778     delete m_page;
779     m_page = 0;
780
781     registerForIconNotification(false);
782     IWebNotificationCenter* notifyCenter = WebNotificationCenter::defaultCenterInternal();
783     notifyCenter->removeObserver(this, WebPreferences::webPreferencesChangedNotification(), static_cast<IWebPreferences*>(m_preferences.get()));
784
785     if (COMPtr<WebPreferences> preferences = m_preferences) {
786         BString identifier;
787         preferences->identifier(&identifier);
788
789         m_preferences = 0;
790         preferences->didRemoveFromWebView();
791         // Make sure we release the reference, since WebPreferences::removeReferenceForIdentifier will check for last reference to WebPreferences
792         preferences = 0;
793         if (identifier)
794             WebPreferences::removeReferenceForIdentifier(identifier);
795     }
796
797     deleteBackingStore();
798     return S_OK;
799 }
800
801 void WebView::repaint(const WebCore::IntRect& windowRect, bool contentChanged, bool immediate, bool repaintContentOnly)
802 {
803     if (isAcceleratedCompositing()) {
804         // The contentChanged, immediate, and repaintContentOnly parameters are all based on a non-
805         // compositing painting/scrolling model.
806         addToDirtyRegion(windowRect);
807         return;
808     }
809
810     if (!repaintContentOnly) {
811         RECT rect = windowRect;
812         ::InvalidateRect(m_viewWindow, &rect, false);
813     }
814     if (contentChanged)
815         addToDirtyRegion(windowRect);
816     if (immediate) {
817         if (repaintContentOnly)
818             updateBackingStore(core(topLevelFrame())->view());
819         else
820             ::UpdateWindow(m_viewWindow);
821     }
822     m_needsDisplay = true;
823 }
824
825 void WebView::deleteBackingStore()
826 {
827     pendingDeleteBackingStoreSet().remove(this);
828
829     if (m_deleteBackingStoreTimerActive) {
830         KillTimer(m_viewWindow, DeleteBackingStoreTimer);
831         m_deleteBackingStoreTimerActive = false;
832     }
833     m_backingStoreBitmap.clear();
834     m_backingStoreDirtyRegion.clear();
835     m_backingStoreSize.cx = m_backingStoreSize.cy = 0;
836 }
837
838 bool WebView::ensureBackingStore()
839 {
840     RECT windowRect;
841     ::GetClientRect(m_viewWindow, &windowRect);
842     LONG width = windowRect.right - windowRect.left;
843     LONG height = windowRect.bottom - windowRect.top;
844     if (width > 0 && height > 0 && (width != m_backingStoreSize.cx || height != m_backingStoreSize.cy)) {
845         deleteBackingStore();
846
847         m_backingStoreSize.cx = width;
848         m_backingStoreSize.cy = height;
849         BitmapInfo bitmapInfo = BitmapInfo::createBottomUp(IntSize(m_backingStoreSize));
850
851         void* pixels = NULL;
852         m_backingStoreBitmap = SharedGDIObject<HBITMAP>::create(adoptGDIObject(::CreateDIBSection(0, &bitmapInfo, DIB_RGB_COLORS, &pixels, 0, 0)));
853         return true;
854     }
855
856     return false;
857 }
858
859 void WebView::addToDirtyRegion(const IntRect& dirtyRect)
860 {
861     m_needsDisplay = true;
862
863     // FIXME: We want an assert here saying that the dirtyRect is inside the clienRect,
864     // but it was being hit during our layout tests, and is being investigated in
865     // http://webkit.org/b/29350.
866
867     if (isAcceleratedCompositing()) {
868 #if USE(CA)
869         m_backingLayer->setNeedsDisplayInRect(dirtyRect);
870 #elif USE(TEXTURE_MAPPER_GL)
871         m_acceleratedCompositingContext->setNonCompositedContentsNeedDisplay(dirtyRect);
872 #endif
873         return;
874     }
875
876     auto newRegion = adoptGDIObject(::CreateRectRgn(dirtyRect.x(), dirtyRect.y(),
877         dirtyRect.maxX(), dirtyRect.maxY()));
878     addToDirtyRegion(WTF::move(newRegion));
879 }
880
881 void WebView::addToDirtyRegion(GDIObject<HRGN> newRegion)
882 {
883     m_needsDisplay = true;
884
885     ASSERT(!isAcceleratedCompositing());
886
887     LOCAL_GDI_COUNTER(0, __FUNCTION__);
888
889     if (m_backingStoreDirtyRegion) {
890         auto combinedRegion = adoptGDIObject(::CreateRectRgn(0, 0, 0, 0));
891         ::CombineRgn(combinedRegion.get(), m_backingStoreDirtyRegion->get(), newRegion.get(), RGN_OR);
892         m_backingStoreDirtyRegion = SharedGDIObject<HRGN>::create(WTF::move(combinedRegion));
893     } else
894         m_backingStoreDirtyRegion = SharedGDIObject<HRGN>::create(WTF::move(newRegion));
895
896     if (m_uiDelegatePrivate)
897         m_uiDelegatePrivate->webViewDidInvalidate(this);
898 }
899
900 void WebView::scrollBackingStore(FrameView* frameView, int dx, int dy, const IntRect& scrollViewRect, const IntRect& clipRect)
901 {
902     m_needsDisplay = true;
903
904     if (isAcceleratedCompositing()) {
905         // FIXME: We should be doing something smarter here, like moving tiles around and painting
906         // any newly-exposed tiles. <http://webkit.org/b/52714>
907 #if USE(CA)
908         m_backingLayer->setNeedsDisplayInRect(scrollViewRect);
909 #elif USE(TEXTURE_MAPPER_GL)
910         m_acceleratedCompositingContext->scrollNonCompositedContents(scrollViewRect, IntSize(dx, dy));
911 #endif
912         return;
913     }
914
915     LOCAL_GDI_COUNTER(0, __FUNCTION__);
916
917     // If there's no backing store we don't need to update it
918     if (!m_backingStoreBitmap) {
919         if (m_uiDelegatePrivate)
920             m_uiDelegatePrivate->webViewScrolled(this);
921
922         return;
923     }
924
925     // Make a region to hold the invalidated scroll area.
926     auto updateRegion = adoptGDIObject(::CreateRectRgn(0, 0, 0, 0));
927
928     // Collect our device context info and select the bitmap to scroll.
929     HWndDC windowDC(m_viewWindow);
930     auto bitmapDC = adoptGDIObject(::CreateCompatibleDC(windowDC));
931     HGDIOBJ oldBitmap = ::SelectObject(bitmapDC.get(), m_backingStoreBitmap->get());
932     
933     // Scroll the bitmap.
934     RECT scrollRectWin(scrollViewRect);
935     RECT clipRectWin(clipRect);
936     ::ScrollDC(bitmapDC.get(), dx, dy, &scrollRectWin, &clipRectWin, updateRegion.get(), 0);
937     RECT regionBox;
938     ::GetRgnBox(updateRegion.get(), &regionBox);
939
940     // Flush.
941     GdiFlush();
942
943     // Add the dirty region to the backing store's dirty region.
944     addToDirtyRegion(WTF::move(updateRegion));
945
946     if (m_uiDelegatePrivate)
947         m_uiDelegatePrivate->webViewScrolled(this);
948
949     // Update the backing store.
950     updateBackingStore(frameView, bitmapDC.get(), false);
951
952     // Clean up.
953     ::SelectObject(bitmapDC.get(), oldBitmap);
954 }
955
956 void WebView::sizeChanged(const IntSize& newSize)
957 {
958     m_needsDisplay = true;
959
960     deleteBackingStore();
961
962     if (Frame* coreFrame = core(topLevelFrame()))
963         coreFrame->view()->resize(newSize);
964
965 #if USE(CA)
966     if (m_layerTreeHost)
967         m_layerTreeHost->resize();
968
969     if (m_backingLayer) {
970         m_backingLayer->setSize(newSize);
971         m_backingLayer->setNeedsDisplay();
972     }
973 #elif USE(TEXTURE_MAPPER_GL)
974     if (m_acceleratedCompositingContext)
975         m_acceleratedCompositingContext->resizeRootLayer(newSize);
976 #endif
977 }
978
979 // This emulates the Mac smarts for painting rects intelligently.  This is very
980 // important for us, since we double buffer based off dirty rects.
981 static void getUpdateRects(HRGN region, const IntRect& dirtyRect, Vector<IntRect>& rects)
982 {
983     ASSERT_ARG(region, region);
984
985     const int cRectThreshold = 10;
986     const float cWastedSpaceThreshold = 0.75f;
987
988     rects.clear();
989
990     DWORD regionDataSize = GetRegionData(region, sizeof(RGNDATA), NULL);
991     if (!regionDataSize) {
992         rects.append(dirtyRect);
993         return;
994     }
995
996     Vector<unsigned char> buffer(regionDataSize);
997     RGNDATA* regionData = reinterpret_cast<RGNDATA*>(buffer.data());
998     GetRegionData(region, regionDataSize, regionData);
999     if (regionData->rdh.nCount > cRectThreshold) {
1000         rects.append(dirtyRect);
1001         return;
1002     }
1003
1004     double singlePixels = 0.0;
1005     unsigned i;
1006     RECT* rect;
1007     for (i = 0, rect = reinterpret_cast<RECT*>(regionData->Buffer); i < regionData->rdh.nCount; i++, rect++)
1008         singlePixels += (rect->right - rect->left) * (rect->bottom - rect->top);
1009
1010     double unionPixels = dirtyRect.width() * dirtyRect.height();
1011     double wastedSpace = 1.0 - (singlePixels / unionPixels);
1012     if (wastedSpace <= cWastedSpaceThreshold) {
1013         rects.append(dirtyRect);
1014         return;
1015     }
1016
1017     for (i = 0, rect = reinterpret_cast<RECT*>(regionData->Buffer); i < regionData->rdh.nCount; i++, rect++)
1018         rects.append(*rect);
1019 }
1020
1021 void WebView::updateBackingStore(FrameView* frameView, HDC dc, bool backingStoreCompletelyDirty, WindowsToPaint windowsToPaint)
1022 {
1023     ASSERT(!isAcceleratedCompositing());
1024
1025     LOCAL_GDI_COUNTER(0, __FUNCTION__);
1026
1027     GDIObject<HDC> bitmapDCObject;
1028
1029     HDC bitmapDC = dc;
1030     HGDIOBJ oldBitmap = 0;
1031     if (!dc) {
1032         HWndDC windowDC(m_viewWindow);
1033         bitmapDCObject = adoptGDIObject(::CreateCompatibleDC(windowDC));
1034         bitmapDC = bitmapDCObject.get();
1035         oldBitmap = ::SelectObject(bitmapDC, m_backingStoreBitmap->get());
1036     }
1037
1038     if (m_backingStoreBitmap && (m_backingStoreDirtyRegion || backingStoreCompletelyDirty)) {
1039         // Do a layout first so that everything we render to the backing store is always current.
1040         if (Frame* coreFrame = core(m_mainFrame))
1041             if (FrameView* view = coreFrame->view())
1042                 view->updateLayoutAndStyleIfNeededRecursive();
1043
1044         Vector<IntRect> paintRects;
1045         if (!backingStoreCompletelyDirty && m_backingStoreDirtyRegion) {
1046             RECT regionBox;
1047             ::GetRgnBox(m_backingStoreDirtyRegion->get(), &regionBox);
1048             getUpdateRects(m_backingStoreDirtyRegion->get(), regionBox, paintRects);
1049         } else {
1050             RECT clientRect;
1051             ::GetClientRect(m_viewWindow, &clientRect);
1052             paintRects.append(clientRect);
1053         }
1054
1055         for (unsigned i = 0; i < paintRects.size(); ++i)
1056             paintIntoBackingStore(frameView, bitmapDC, paintRects[i], windowsToPaint);
1057
1058         if (m_uiDelegatePrivate)
1059             m_uiDelegatePrivate->webViewPainted(this);
1060
1061         m_backingStoreDirtyRegion.clear();
1062     }
1063
1064     if (!dc)
1065         ::SelectObject(bitmapDC, oldBitmap);
1066
1067     GdiFlush();
1068
1069     m_needsDisplay = true;
1070 }
1071
1072 void WebView::performLayeredWindowUpdate()
1073 {
1074     // The backing store may have been destroyed if the window rect was set to zero height or zero width.
1075     if (!m_backingStoreBitmap)
1076         return;
1077
1078     HWndDC hdcScreen(m_viewWindow);
1079     auto hdcMem = adoptGDIObject(::CreateCompatibleDC(hdcScreen));
1080     HBITMAP hbmOld = static_cast<HBITMAP>(::SelectObject(hdcMem.get(), m_backingStoreBitmap->get()));
1081
1082     BITMAP bmpInfo;
1083     ::GetObject(m_backingStoreBitmap->get(), sizeof(bmpInfo), &bmpInfo);
1084     SIZE windowSize = { bmpInfo.bmWidth, bmpInfo.bmHeight };
1085
1086     BLENDFUNCTION blendFunction;
1087     blendFunction.BlendOp = AC_SRC_OVER;
1088     blendFunction.BlendFlags = 0;
1089     blendFunction.SourceConstantAlpha = 0xFF;
1090     blendFunction.AlphaFormat = AC_SRC_ALPHA;
1091
1092     POINT layerPos = { 0, 0 };
1093     ::UpdateLayeredWindow(m_viewWindow, hdcScreen, 0, &windowSize, hdcMem.get(), &layerPos, 0, &blendFunction, ULW_ALPHA);
1094
1095     ::SelectObject(hdcMem.get(), hbmOld);
1096
1097     m_needsDisplay = false;
1098 }
1099
1100 void WebView::paint(HDC dc, LPARAM options)
1101 {
1102     LOCAL_GDI_COUNTER(0, __FUNCTION__);
1103
1104     if (isAcceleratedCompositing() && !usesLayeredWindow()) {
1105 #if USE(CA)
1106         m_layerTreeHost->flushPendingLayerChangesNow();
1107 #elif USE(TEXTURE_MAPPER_GL)
1108         m_acceleratedCompositingContext->flushAndRenderLayers();
1109 #endif
1110         // Flushing might have taken us out of compositing mode.
1111         if (isAcceleratedCompositing()) {
1112 #if USE(CA)
1113             // FIXME: We need to paint into dc (if provided). <http://webkit.org/b/52578>
1114             m_layerTreeHost->paint();
1115 #endif
1116             ::ValidateRect(m_viewWindow, 0);
1117             return;
1118         }
1119     }
1120
1121     Frame* coreFrame = core(m_mainFrame);
1122     if (!coreFrame)
1123         return;
1124     FrameView* frameView = coreFrame->view();
1125
1126     RECT rcPaint;
1127     HDC hdc;
1128     GDIObject<HRGN> region;
1129     int regionType = NULLREGION;
1130     PAINTSTRUCT ps;
1131     WindowsToPaint windowsToPaint;
1132     if (!dc) {
1133         region = adoptGDIObject(::CreateRectRgn(0, 0, 0, 0));
1134         regionType = GetUpdateRgn(m_viewWindow, region.get(), false);
1135         hdc = BeginPaint(m_viewWindow, &ps);
1136         rcPaint = ps.rcPaint;
1137         // We're painting to the screen, and our child windows can handle
1138         // painting themselves to the screen.
1139         windowsToPaint = PaintWebViewOnly;
1140     } else {
1141         hdc = dc;
1142         ::GetClientRect(m_viewWindow, &rcPaint);
1143         if (options & PRF_ERASEBKGND)
1144             ::FillRect(hdc, &rcPaint, (HBRUSH)GetStockObject(WHITE_BRUSH));
1145         // Since we aren't painting to the screen, we want to paint all our
1146         // children into the HDC.
1147         windowsToPaint = PaintWebViewAndChildren;
1148     }
1149
1150     bool backingStoreCompletelyDirty = ensureBackingStore();
1151     if (!m_backingStoreBitmap) {
1152         if (!dc)
1153             EndPaint(m_viewWindow, &ps);
1154         return;
1155     }
1156
1157     m_paintCount++;
1158
1159     auto bitmapDC = adoptGDIObject(::CreateCompatibleDC(hdc));
1160     HGDIOBJ oldBitmap = ::SelectObject(bitmapDC.get(), m_backingStoreBitmap->get());
1161
1162     // Update our backing store if needed.
1163     updateBackingStore(frameView, bitmapDC.get(), backingStoreCompletelyDirty, windowsToPaint);
1164
1165     // Now we blit the updated backing store
1166     IntRect windowDirtyRect = rcPaint;
1167     
1168     // Apply the same heuristic for this update region too.
1169     Vector<IntRect> blitRects;
1170     if (region && regionType == COMPLEXREGION)
1171         getUpdateRects(region.get(), windowDirtyRect, blitRects);
1172     else
1173         blitRects.append(windowDirtyRect);
1174
1175     for (unsigned i = 0; i < blitRects.size(); ++i)
1176         paintIntoWindow(bitmapDC.get(), hdc, blitRects[i]);
1177
1178     ::SelectObject(bitmapDC.get(), oldBitmap);
1179
1180     if (!dc)
1181         EndPaint(m_viewWindow, &ps);
1182
1183     m_paintCount--;
1184
1185     if (active())
1186         cancelDeleteBackingStoreSoon();
1187     else
1188         deleteBackingStoreSoon();
1189 }
1190
1191 void WebView::paintIntoBackingStore(FrameView* frameView, HDC bitmapDC, const IntRect& dirtyRect, WindowsToPaint windowsToPaint)
1192 {
1193     // FIXME: This function should never be called in accelerated compositing mode, and we should
1194     // assert as such. But currently it *is* sometimes called, so we can't assert yet. See
1195     // <http://webkit.org/b/58539>.
1196
1197     LOCAL_GDI_COUNTER(0, __FUNCTION__);
1198
1199     // FIXME: We want an assert here saying that the dirtyRect is inside the clienRect,
1200     // but it was being hit during our layout tests, and is being investigated in
1201     // http://webkit.org/b/29350.
1202
1203     RECT rect = dirtyRect;
1204
1205 #if FLASH_BACKING_STORE_REDRAW
1206     {
1207         HWndDC dc(m_viewWindow);
1208         auto yellowBrush = adoptGDIObject(::CreateSolidBrush(RGB(255, 255, 0)));
1209         FillRect(dc, &rect, yellowBrush.get());
1210         GdiFlush();
1211         Sleep(50);
1212         paintIntoWindow(bitmapDC, dc, dirtyRect);
1213     }
1214 #endif
1215
1216     GraphicsContext gc(bitmapDC, m_transparent);
1217     gc.setShouldIncludeChildWindows(windowsToPaint == PaintWebViewAndChildren);
1218     gc.save();
1219     if (m_transparent)
1220         gc.clearRect(dirtyRect);
1221     else
1222         FillRect(bitmapDC, &rect, (HBRUSH)GetStockObject(WHITE_BRUSH));
1223
1224     COMPtr<IWebUIDelegatePrivate2> uiPrivate(Query, m_uiDelegate);
1225     if (uiPrivate)
1226         uiPrivate->drawBackground(this, bitmapDC, &rect);
1227
1228     if (frameView && frameView->frame().contentRenderer()) {
1229         gc.clip(dirtyRect);
1230         frameView->paint(&gc, dirtyRect);
1231         if (m_shouldInvertColors)
1232             gc.fillRect(dirtyRect, Color::white, ColorSpaceDeviceRGB, CompositeDifference);
1233     }
1234     gc.restore();
1235 }
1236
1237 void WebView::paintIntoWindow(HDC bitmapDC, HDC windowDC, const IntRect& dirtyRect)
1238 {
1239     // FIXME: This function should never be called in accelerated compositing mode, and we should
1240     // assert as such. But currently it *is* sometimes called, so we can't assert yet. See
1241     // <http://webkit.org/b/58539>.
1242
1243     LOCAL_GDI_COUNTER(0, __FUNCTION__);
1244 #if FLASH_WINDOW_REDRAW
1245     auto greenBrush = adoptGDIObject(::CreateSolidBrush(RGB(0, 255, 0)));
1246     RECT rect = dirtyRect;
1247     FillRect(windowDC, &rect, greenBrush.get());
1248     GdiFlush();
1249     Sleep(50);
1250 #endif
1251
1252     // Blit the dirty rect from the backing store into the same position
1253     // in the destination DC.
1254     BitBlt(windowDC, dirtyRect.x(), dirtyRect.y(), dirtyRect.width(), dirtyRect.height(), bitmapDC,
1255            dirtyRect.x(), dirtyRect.y(), SRCCOPY);
1256
1257     m_needsDisplay = false;
1258 }
1259
1260 void WebView::frameRect(RECT* rect)
1261 {
1262     ::GetWindowRect(m_viewWindow, rect);
1263 }
1264
1265 class WindowCloseTimer : public WebCore::SuspendableTimer {
1266 public:
1267     static WindowCloseTimer* create(WebView*);
1268
1269 private:
1270     WindowCloseTimer(ScriptExecutionContext&, WebView*);
1271     virtual void contextDestroyed();
1272     virtual void fired();
1273
1274     WebView* m_webView;
1275 };
1276
1277 WindowCloseTimer* WindowCloseTimer::create(WebView* webView)
1278 {
1279     ASSERT_ARG(webView, webView);
1280     Frame* frame = core(webView->topLevelFrame());
1281     ASSERT(frame);
1282     if (!frame)
1283         return nullptr;
1284
1285     Document* document = frame->document();
1286     ASSERT(document);
1287     if (!document)
1288         return nullptr;
1289
1290     auto closeTimer = new WindowCloseTimer(*document, webView);
1291     closeTimer->suspendIfNeeded();
1292     return closeTimer;
1293 }
1294
1295 WindowCloseTimer::WindowCloseTimer(ScriptExecutionContext& context, WebView* webView)
1296     : SuspendableTimer(context)
1297     , m_webView(webView)
1298 {
1299     ASSERT_ARG(webView, webView);
1300 }
1301
1302 void WindowCloseTimer::contextDestroyed()
1303 {
1304     SuspendableTimer::contextDestroyed();
1305     delete this;
1306 }
1307
1308 void WindowCloseTimer::fired()
1309 {
1310     m_webView->closeWindowTimerFired();
1311 }
1312
1313 void WebView::closeWindowSoon()
1314 {
1315     if (m_closeWindowTimer)
1316         return;
1317
1318     m_closeWindowTimer = WindowCloseTimer::create(this);
1319     if (!m_closeWindowTimer)
1320         return;
1321     m_closeWindowTimer->startOneShot(0);
1322
1323     AddRef();
1324 }
1325
1326 void WebView::closeWindowTimerFired()
1327 {
1328     closeWindow();
1329     Release();
1330 }
1331
1332 void WebView::closeWindow()
1333 {
1334     if (m_hasSpellCheckerDocumentTag) {
1335         if (m_editingDelegate)
1336             m_editingDelegate->closeSpellDocument(this);
1337         m_hasSpellCheckerDocumentTag = false;
1338     }
1339
1340     COMPtr<IWebUIDelegate> ui;
1341     if (SUCCEEDED(uiDelegate(&ui)))
1342         ui->webViewClose(this);
1343 }
1344
1345 bool WebView::canHandleRequest(const WebCore::ResourceRequest& request)
1346 {
1347     // On the mac there's an about url protocol implementation but CFNetwork doesn't have that.
1348     if (equalIgnoringCase(String(request.url().protocol()), "about"))
1349         return true;
1350
1351 #if USE(CFNETWORK)
1352     if (CFURLProtocolCanHandleRequest(request.cfURLRequest(UpdateHTTPBody)))
1353         return true;
1354
1355     // FIXME: Mac WebKit calls _representationExistsForURLScheme here
1356     return false;
1357 #else
1358     return true;
1359 #endif
1360 }
1361
1362 String WebView::standardUserAgentWithApplicationName(const String& applicationName)
1363 {
1364     DEPRECATED_DEFINE_STATIC_LOCAL(String, osVersion, (windowsVersionForUAString()));
1365     DEPRECATED_DEFINE_STATIC_LOCAL(String, webKitVersion, (webKitVersionString()));
1366
1367     return makeString("Mozilla/5.0 (", osVersion, ") AppleWebKit/", webKitVersion, " (KHTML, like Gecko)", applicationName.isEmpty() ? "" : " ", applicationName);
1368 }
1369
1370 Page* WebView::page()
1371 {
1372     return m_page;
1373 }
1374
1375 bool WebView::handleContextMenuEvent(WPARAM wParam, LPARAM lParam)
1376 {
1377     // Translate the screen coordinates into window coordinates
1378     POINT coords = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
1379     if (coords.x == -1 || coords.y == -1) {
1380         // The contextMenuController() holds onto the last context menu that was popped up on the
1381         // page until a new one is created. We need to clear this menu before propagating the event
1382         // through the DOM so that we can detect if we create a new menu for this event, since we
1383         // won't create a new menu if the DOM swallows the event and the defaultEventHandler does
1384         // not run.
1385         m_page->contextMenuController().clearContextMenu();
1386
1387         Frame& focusedFrame = m_page->focusController().focusedOrMainFrame();
1388         return focusedFrame.eventHandler().sendContextMenuEventForKey();
1389
1390     } else {
1391         if (!::ScreenToClient(m_viewWindow, &coords))
1392             return false;
1393     }
1394
1395     lParam = MAKELPARAM(coords.x, coords.y);
1396
1397     m_page->contextMenuController().clearContextMenu();
1398
1399     IntPoint documentPoint(m_page->mainFrame().view()->windowToContents(coords));
1400     HitTestResult result = m_page->mainFrame().eventHandler().hitTestResultAtPoint(documentPoint);
1401     Frame* targetFrame = result.innerNonSharedNode() ? result.innerNonSharedNode()->document().frame() : &m_page->focusController().focusedOrMainFrame();
1402
1403     targetFrame->view()->setCursor(pointerCursor());
1404     PlatformMouseEvent mouseEvent(m_viewWindow, WM_RBUTTONUP, wParam, lParam);
1405     bool handledEvent = targetFrame->eventHandler().sendContextMenuEvent(mouseEvent);
1406     if (!handledEvent)
1407         return false;
1408
1409     ContextMenuController& contextMenuController = m_page->contextMenuController();
1410
1411     // Show the menu
1412     ContextMenu* coreMenu = contextMenuController.contextMenu();
1413     if (!coreMenu)
1414         return false;
1415
1416     Frame* frame = contextMenuController.hitTestResult().innerNodeFrame();
1417     if (!frame)
1418         return false;
1419
1420     FrameView* view = frame->view();
1421     if (!view)
1422         return false;
1423
1424     POINT point(view->contentsToWindow(contextMenuController.hitTestResult().roundedPointInInnerNodeFrame()));
1425
1426     // Translate the point to screen coordinates
1427     if (!::ClientToScreen(m_viewWindow, &point))
1428         return false;
1429
1430     BOOL hasCustomMenus = false;
1431     if (m_uiDelegate)
1432         m_uiDelegate->hasCustomMenuImplementation(&hasCustomMenus);
1433
1434     if (hasCustomMenus)
1435         m_uiDelegate->trackCustomPopupMenu((IWebView*)this, coreMenu->platformContextMenu(), &point);
1436     else {
1437         // Surprisingly, TPM_RIGHTBUTTON means that items are selectable with either the right OR left mouse button
1438         UINT flags = TPM_RIGHTBUTTON | TPM_TOPALIGN | TPM_VERPOSANIMATION | TPM_HORIZONTAL
1439             | TPM_LEFTALIGN | TPM_HORPOSANIMATION;
1440         ::TrackPopupMenuEx(coreMenu->platformContextMenu(), flags, point.x, point.y, m_viewWindow, 0);
1441     }
1442
1443     return true;
1444 }
1445
1446 bool WebView::onMeasureItem(WPARAM /*wParam*/, LPARAM lParam)
1447 {
1448     if (!m_uiDelegate)
1449         return false;
1450
1451     BOOL hasCustomMenus = false;
1452     m_uiDelegate->hasCustomMenuImplementation(&hasCustomMenus);
1453     if (!hasCustomMenus)
1454         return false;
1455
1456     m_uiDelegate->measureCustomMenuItem((IWebView*)this, (void*)lParam);
1457     return true;
1458 }
1459
1460 bool WebView::onDrawItem(WPARAM /*wParam*/, LPARAM lParam)
1461 {
1462     if (!m_uiDelegate)
1463         return false;
1464
1465     BOOL hasCustomMenus = false;
1466     m_uiDelegate->hasCustomMenuImplementation(&hasCustomMenus);
1467     if (!hasCustomMenus)
1468         return false;
1469
1470     m_uiDelegate->drawCustomMenuItem((IWebView*)this, (void*)lParam);
1471     return true;
1472 }
1473
1474 bool WebView::onInitMenuPopup(WPARAM wParam, LPARAM /*lParam*/)
1475 {
1476     if (!m_uiDelegate)
1477         return false;
1478
1479     HMENU menu = (HMENU)wParam;
1480     if (!menu)
1481         return false;
1482
1483     BOOL hasCustomMenus = false;
1484     m_uiDelegate->hasCustomMenuImplementation(&hasCustomMenus);
1485     if (!hasCustomMenus)
1486         return false;
1487
1488     m_uiDelegate->addCustomMenuDrawingData((IWebView*)this, menu);
1489     return true;
1490 }
1491
1492 bool WebView::onUninitMenuPopup(WPARAM wParam, LPARAM /*lParam*/)
1493 {
1494     if (!m_uiDelegate)
1495         return false;
1496
1497     HMENU menu = (HMENU)wParam;
1498     if (!menu)
1499         return false;
1500
1501     BOOL hasCustomMenus = false;
1502     m_uiDelegate->hasCustomMenuImplementation(&hasCustomMenus);
1503     if (!hasCustomMenus)
1504         return false;
1505
1506     m_uiDelegate->cleanUpCustomMenuDrawingData((IWebView*)this, menu);
1507     return true;
1508 }
1509
1510 void WebView::performContextMenuAction(WPARAM wParam, LPARAM lParam, bool byPosition)
1511 {
1512     ContextMenu* menu = m_page->contextMenuController().contextMenu();
1513     ASSERT(menu);
1514
1515     ContextMenuItem* item = byPosition ? menu->itemAtIndex((unsigned)wParam) : menu->itemWithAction((ContextMenuAction)wParam);
1516     if (!item)
1517         return;
1518     m_page->contextMenuController().contextMenuItemSelected(item);
1519 }
1520
1521 bool WebView::handleMouseEvent(UINT message, WPARAM wParam, LPARAM lParam)
1522 {
1523     static LONG globalClickCount;
1524     static IntPoint globalPrevPoint;
1525     static MouseButton globalPrevButton;
1526     static LONG globalPrevMouseDownTime;
1527
1528     if (message == WM_CANCELMODE) {
1529         m_page->mainFrame().eventHandler().lostMouseCapture();
1530         return true;
1531     }
1532
1533     // Create our event.
1534     // On WM_MOUSELEAVE we need to create a mouseout event, so we force the position
1535     // of the event to be at (MINSHORT, MINSHORT).
1536     LPARAM position = (message == WM_MOUSELEAVE) ? ((MINSHORT << 16) | MINSHORT) : lParam;
1537     PlatformMouseEvent mouseEvent(m_viewWindow, message, wParam, position, m_mouseActivated);
1538
1539     setMouseActivated(false);
1540
1541     bool insideThreshold = abs(globalPrevPoint.x() - mouseEvent.position().x()) < ::GetSystemMetrics(SM_CXDOUBLECLK) &&
1542                            abs(globalPrevPoint.y() - mouseEvent.position().y()) < ::GetSystemMetrics(SM_CYDOUBLECLK);
1543     LONG messageTime = ::GetMessageTime();
1544
1545     bool handled = false;
1546
1547     if (message == WM_LBUTTONDOWN || message == WM_MBUTTONDOWN || message == WM_RBUTTONDOWN) {
1548         // FIXME: I'm not sure if this is the "right" way to do this
1549         // but without this call, we never become focused since we don't allow
1550         // the default handling of mouse events.
1551         SetFocus(m_viewWindow);
1552
1553         // Always start capturing events when the mouse goes down in our HWND.
1554         ::SetCapture(m_viewWindow);
1555
1556         if (((messageTime - globalPrevMouseDownTime) < (LONG)::GetDoubleClickTime()) && 
1557             insideThreshold &&
1558             mouseEvent.button() == globalPrevButton)
1559             globalClickCount++;
1560         else
1561             // Reset the click count.
1562             globalClickCount = 1;
1563         globalPrevMouseDownTime = messageTime;
1564         globalPrevButton = mouseEvent.button();
1565         globalPrevPoint = mouseEvent.position();
1566         
1567         mouseEvent.setClickCount(globalClickCount);
1568         handled = m_page->mainFrame().eventHandler().handleMousePressEvent(mouseEvent);
1569     } else if (message == WM_LBUTTONDBLCLK || message == WM_MBUTTONDBLCLK || message == WM_RBUTTONDBLCLK) {
1570         globalClickCount++;
1571         mouseEvent.setClickCount(globalClickCount);
1572         handled = m_page->mainFrame().eventHandler().handleMousePressEvent(mouseEvent);
1573     } else if (message == WM_LBUTTONUP || message == WM_MBUTTONUP || message == WM_RBUTTONUP) {
1574         // Record the global position and the button of the up.
1575         globalPrevButton = mouseEvent.button();
1576         globalPrevPoint = mouseEvent.position();
1577         mouseEvent.setClickCount(globalClickCount);
1578         m_page->mainFrame().eventHandler().handleMouseReleaseEvent(mouseEvent);
1579         ::ReleaseCapture();
1580     } else if (message == WM_MOUSELEAVE && m_mouseOutTracker) {
1581         // Once WM_MOUSELEAVE is fired windows clears this tracker
1582         // so there is no need to disable it ourselves.
1583         m_mouseOutTracker.reset();
1584         m_page->mainFrame().eventHandler().mouseMoved(mouseEvent);
1585         handled = true;
1586     } else if (message == WM_MOUSEMOVE) {
1587         if (!insideThreshold)
1588             globalClickCount = 0;
1589         mouseEvent.setClickCount(globalClickCount);
1590         handled = m_page->mainFrame().eventHandler().mouseMoved(mouseEvent);
1591         if (!m_mouseOutTracker) {
1592             m_mouseOutTracker = std::make_unique<TRACKMOUSEEVENT>();
1593             m_mouseOutTracker->cbSize = sizeof(TRACKMOUSEEVENT);
1594             m_mouseOutTracker->dwFlags = TME_LEAVE;
1595             m_mouseOutTracker->hwndTrack = m_viewWindow;
1596             ::TrackMouseEvent(m_mouseOutTracker.get());
1597         }
1598     }
1599     return handled;
1600 }
1601
1602 bool WebView::gestureNotify(WPARAM wParam, LPARAM lParam)
1603 {
1604     GESTURENOTIFYSTRUCT* gn = reinterpret_cast<GESTURENOTIFYSTRUCT*>(lParam);
1605
1606     Frame* coreFrame = core(m_mainFrame);
1607     if (!coreFrame)
1608         return false;
1609
1610     ScrollView* view = coreFrame->view();
1611     if (!view)
1612         return false;
1613
1614     // If we don't have this function, we shouldn't be receiving this message
1615     ASSERT(SetGestureConfigPtr());
1616
1617     bool hitScrollbar = false;
1618     POINT gestureBeginPoint = {gn->ptsLocation.x, gn->ptsLocation.y};
1619     HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::DisallowShadowContent);
1620     for (Frame* childFrame = &m_page->mainFrame(); childFrame; childFrame = EventHandler::subframeForTargetNode(m_gestureTargetNode.get())) {
1621         FrameView* frameView = childFrame->view();
1622         if (!frameView)
1623             break;
1624         RenderView* renderView = childFrame->document()->renderView();
1625         if (!renderView)
1626             break;
1627         RenderLayer* layer = renderView->layer();
1628         if (!layer)
1629             break;
1630
1631         HitTestResult result(frameView->screenToContents(gestureBeginPoint));
1632         layer->hitTest(request, result);
1633         m_gestureTargetNode = result.innerNode();
1634
1635         if (!hitScrollbar)
1636             hitScrollbar = result.scrollbar();
1637     }
1638
1639     if (!hitScrollbar) {
1640         // The hit testing above won't detect if we've hit the main frame's vertical scrollbar. Check that manually now.
1641         RECT webViewRect;
1642         GetWindowRect(m_viewWindow, &webViewRect);
1643         hitScrollbar = (view->verticalScrollbar() && (gestureBeginPoint.x > (webViewRect.right - view->verticalScrollbar()->theme()->scrollbarThickness()))) 
1644             || (view->horizontalScrollbar() && (gestureBeginPoint.y > (webViewRect.bottom - view->horizontalScrollbar()->theme()->scrollbarThickness())));  
1645     }
1646
1647     bool canBeScrolled = false;
1648     if (m_gestureTargetNode) {
1649         for (RenderObject* renderer = m_gestureTargetNode->renderer(); renderer; renderer = renderer->parent()) {
1650             if (is<RenderBox>(*renderer) && downcast<RenderBox>(*renderer).canBeScrolledAndHasScrollableArea()) {
1651                 canBeScrolled = true;
1652                 break;
1653             }
1654         }
1655     } else {
1656         // We've hit the main document but not any of the document's content
1657         if (core(m_mainFrame)->view()->isScrollable())
1658             canBeScrolled = true;
1659     }
1660
1661     // We always allow two-fingered panning with inertia and a gutter (which limits movement to one
1662     // direction in most cases).
1663     DWORD dwPanWant = GC_PAN | GC_PAN_WITH_INERTIA | GC_PAN_WITH_GUTTER;
1664     DWORD dwPanBlock = 0;
1665
1666     if (hitScrollbar || !canBeScrolled) {
1667         // The part of the page under the gesture can't be scrolled, or the gesture is on a scrollbar.
1668         // Disallow single-fingered panning in this case so we'll fall back to the default
1669         // behavior (which allows the scrollbar thumb to be dragged, text selections to be made, etc.).
1670         dwPanBlock = GC_PAN_WITH_SINGLE_FINGER_VERTICALLY | GC_PAN_WITH_SINGLE_FINGER_HORIZONTALLY;
1671     } else {
1672         // The part of the page the gesture is under can be scrolled, and we're not under a scrollbar.
1673         // Allow single-fingered vertical panning in this case, so the user will be able to pan the page
1674         // with one or two fingers.
1675         dwPanWant |= GC_PAN_WITH_SINGLE_FINGER_VERTICALLY;
1676
1677         // Disable single-fingered horizontal panning only if the target node is text.
1678         if (m_gestureTargetNode && m_gestureTargetNode->isTextNode())
1679             dwPanBlock = GC_PAN_WITH_SINGLE_FINGER_HORIZONTALLY;
1680         else
1681             dwPanWant |= GC_PAN_WITH_SINGLE_FINGER_HORIZONTALLY;
1682     }
1683
1684     GESTURECONFIG gc = { GID_PAN, dwPanWant, dwPanBlock };
1685     return SetGestureConfigPtr()(m_viewWindow, 0, 1, &gc, sizeof(GESTURECONFIG));
1686 }
1687
1688 bool WebView::gesture(WPARAM wParam, LPARAM lParam) 
1689 {
1690     // We want to bail out if we don't have either of these functions
1691     if (!GetGestureInfoPtr() || !CloseGestureInfoHandlePtr())
1692         return false;
1693
1694     HGESTUREINFO gestureHandle = reinterpret_cast<HGESTUREINFO>(lParam);
1695     
1696     GESTUREINFO gi = {0};
1697     gi.cbSize = sizeof(GESTUREINFO);
1698
1699     if (!GetGestureInfoPtr()(gestureHandle, reinterpret_cast<PGESTUREINFO>(&gi)))
1700         return false;
1701
1702     switch (gi.dwID) {
1703     case GID_BEGIN:
1704         m_lastPanX = gi.ptsLocation.x;
1705         m_lastPanY = gi.ptsLocation.y;
1706
1707         break;
1708     case GID_END:
1709         m_gestureTargetNode = 0;
1710         break;
1711     case GID_PAN: {
1712         if (gi.dwFlags & GF_BEGIN) {
1713             m_lastPanX = gi.ptsLocation.x;
1714             m_lastPanY = gi.ptsLocation.y;
1715         }
1716         // Where are the fingers currently?
1717         long currentX = gi.ptsLocation.x;
1718         long currentY = gi.ptsLocation.y;
1719         // How far did we pan in each direction?
1720         long deltaX = currentX - m_lastPanX;
1721         long deltaY = currentY - m_lastPanY;
1722         // Calculate the overpan for window bounce
1723         m_yOverpan -= m_lastPanY - currentY;
1724         m_xOverpan -= m_lastPanX - currentX;
1725         // Update our class variables with updated values
1726         m_lastPanX = currentX;
1727         m_lastPanY = currentY;
1728
1729         Frame* coreFrame = core(m_mainFrame);
1730         if (!coreFrame) {
1731             CloseGestureInfoHandlePtr()(gestureHandle);
1732             return false;
1733         }
1734
1735         ScrollableArea* scrolledArea = 0;
1736
1737         if (!m_gestureTargetNode || !m_gestureTargetNode->renderer()) {
1738             // We might directly hit the document without hitting any nodes
1739             coreFrame->view()->scrollBy(IntSize(-deltaX, -deltaY));
1740             scrolledArea = coreFrame->view();
1741         } else
1742             m_gestureTargetNode->renderer()->enclosingLayer()->enclosingScrollableLayer()->scrollByRecursively(IntSize(-deltaX, -deltaY), WebCore::RenderLayer::ScrollOffsetClamped, &scrolledArea);
1743
1744         if (!(UpdatePanningFeedbackPtr() && BeginPanningFeedbackPtr() && EndPanningFeedbackPtr())) {
1745             CloseGestureInfoHandlePtr()(gestureHandle);
1746             return true;
1747         }
1748
1749         // Handle overpanning
1750         if (gi.dwFlags & GF_BEGIN) {
1751             BeginPanningFeedbackPtr()(m_viewWindow);
1752             m_yOverpan = 0;
1753             m_xOverpan = 0;
1754         } else if (gi.dwFlags & GF_END) {
1755             EndPanningFeedbackPtr()(m_viewWindow, true);
1756             m_yOverpan = 0;
1757             m_xOverpan = 0;
1758         }
1759
1760         if (!scrolledArea) {
1761             CloseGestureInfoHandlePtr()(gestureHandle);
1762             return true;
1763         }
1764
1765         Scrollbar* vertScrollbar = scrolledArea->verticalScrollbar();
1766
1767         int ypan = 0;
1768         int xpan = 0;
1769
1770         if (vertScrollbar && (!vertScrollbar->currentPos() || vertScrollbar->currentPos() >= vertScrollbar->maximum()))
1771             ypan = m_yOverpan;
1772
1773         Scrollbar* horiScrollbar = scrolledArea->horizontalScrollbar();
1774
1775         if (horiScrollbar && (!horiScrollbar->currentPos() || horiScrollbar->currentPos() >= horiScrollbar->maximum()))
1776             xpan = m_xOverpan;
1777
1778         UpdatePanningFeedbackPtr()(m_viewWindow, xpan, ypan, gi.dwFlags & GF_INERTIA);
1779
1780         CloseGestureInfoHandlePtr()(gestureHandle);
1781         return true;
1782     }
1783     default:
1784         break;
1785     }
1786
1787     // If we get to this point, the gesture has not been handled. We forward
1788     // the call to DefWindowProc by returning false, and we don't need to 
1789     // to call CloseGestureInfoHandle. 
1790     // http://msdn.microsoft.com/en-us/library/dd353228(VS.85).aspx
1791     return false;
1792 }
1793
1794 bool WebView::mouseWheel(WPARAM wParam, LPARAM lParam, bool isMouseHWheel)
1795 {
1796     // Ctrl+Mouse wheel doesn't ever go into WebCore.  It is used to
1797     // zoom instead (Mac zooms the whole Desktop, but Windows browsers trigger their
1798     // own local zoom modes for Ctrl+wheel).
1799     if (wParam & MK_CONTROL) {
1800         short delta = short(HIWORD(wParam));
1801         if (delta < 0)
1802             makeTextSmaller(0);
1803         else
1804             makeTextLarger(0);
1805         return true;
1806     }
1807     
1808     // FIXME: This doesn't fix https://bugs.webkit.org/show_bug.cgi?id=28217. This only fixes https://bugs.webkit.org/show_bug.cgi?id=28203.
1809     HWND focusedWindow = GetFocus();
1810     if (focusedWindow && focusedWindow != m_viewWindow) {
1811         // Our focus is on a different hwnd, see if it's a PopupMenu and if so, set the focus back on us (which will hide the popup).
1812         WCHAR className[256];
1813
1814         // Make sure truncation won't affect the comparison.
1815         ASSERT(WTF_ARRAY_LENGTH(className) > wcslen(PopupMenuWin::popupClassName()));
1816
1817         if (GetClassNameW(focusedWindow, className, WTF_ARRAY_LENGTH(className)) && !wcscmp(className, PopupMenuWin::popupClassName())) {
1818             // We don't let the WebView scroll here for two reasons - 1) To match Firefox behavior, 2) If we do scroll, we lose the
1819             // focus ring around the select menu.
1820             SetFocus(m_viewWindow);
1821             return true;
1822         }
1823     }
1824
1825     PlatformWheelEvent wheelEvent(m_viewWindow, wParam, lParam, isMouseHWheel);
1826     Frame* coreFrame = core(m_mainFrame);
1827     if (!coreFrame)
1828         return false;
1829
1830     return coreFrame->eventHandler().handleWheelEvent(wheelEvent);
1831 }
1832
1833 bool WebView::verticalScroll(WPARAM wParam, LPARAM /*lParam*/)
1834 {
1835     ScrollDirection direction;
1836     ScrollGranularity granularity;
1837     switch (LOWORD(wParam)) {
1838     case SB_LINEDOWN:
1839         granularity = ScrollByLine;
1840         direction = ScrollDown;
1841         break;
1842     case SB_LINEUP:
1843         granularity = ScrollByLine;
1844         direction = ScrollUp;
1845         break;
1846     case SB_PAGEDOWN:
1847         granularity = ScrollByDocument;
1848         direction = ScrollDown;
1849         break;
1850     case SB_PAGEUP:
1851         granularity = ScrollByDocument;
1852         direction = ScrollUp;
1853         break;
1854     default:
1855         return false;
1856         break;
1857     }
1858     
1859     Frame& frame = m_page->focusController().focusedOrMainFrame();
1860     return frame.eventHandler().scrollRecursively(direction, granularity);
1861 }
1862
1863 bool WebView::horizontalScroll(WPARAM wParam, LPARAM /*lParam*/)
1864 {
1865     ScrollDirection direction;
1866     ScrollGranularity granularity;
1867     switch (LOWORD(wParam)) {
1868     case SB_LINELEFT:
1869         granularity = ScrollByLine;
1870         direction = ScrollLeft;
1871         break;
1872     case SB_LINERIGHT:
1873         granularity = ScrollByLine;
1874         direction = ScrollRight;
1875         break;
1876     case SB_PAGELEFT:
1877         granularity = ScrollByDocument;
1878         direction = ScrollLeft;
1879         break;
1880     case SB_PAGERIGHT:
1881         granularity = ScrollByDocument;
1882         direction = ScrollRight;
1883         break;
1884     default:
1885         return false;
1886     }
1887
1888     Frame& frame = m_page->focusController().focusedOrMainFrame();
1889     return frame.eventHandler().scrollRecursively(direction, granularity);
1890 }
1891
1892
1893 bool WebView::execCommand(WPARAM wParam, LPARAM /*lParam*/)
1894 {
1895     Frame& frame = m_page->focusController().focusedOrMainFrame();
1896     switch (LOWORD(wParam)) {
1897         case SelectAll:
1898             return frame.editor().command("SelectAll").execute();
1899         case Undo:
1900             return frame.editor().command("Undo").execute();
1901         case Redo:
1902             return frame.editor().command("Redo").execute();
1903     }
1904     return false;
1905 }
1906
1907 bool WebView::keyUp(WPARAM virtualKeyCode, LPARAM keyData, bool systemKeyDown)
1908 {
1909     PlatformKeyboardEvent keyEvent(m_viewWindow, virtualKeyCode, keyData, PlatformEvent::KeyUp, systemKeyDown);
1910
1911     Frame& frame = m_page->focusController().focusedOrMainFrame();
1912     m_currentCharacterCode = 0;
1913
1914     return frame.eventHandler().keyEvent(keyEvent);
1915 }
1916
1917 static const unsigned CtrlKey = 1 << 0;
1918 static const unsigned AltKey = 1 << 1;
1919 static const unsigned ShiftKey = 1 << 2;
1920
1921
1922 struct KeyDownEntry {
1923     unsigned virtualKey;
1924     unsigned modifiers;
1925     const char* name;
1926 };
1927
1928 struct KeyPressEntry {
1929     unsigned charCode;
1930     unsigned modifiers;
1931     const char* name;
1932 };
1933
1934 static const KeyDownEntry keyDownEntries[] = {
1935     { VK_LEFT,   0,                  "MoveLeft"                                    },
1936     { VK_LEFT,   ShiftKey,           "MoveLeftAndModifySelection"                  },
1937     { VK_LEFT,   CtrlKey,            "MoveWordLeft"                                },
1938     { VK_LEFT,   CtrlKey | ShiftKey, "MoveWordLeftAndModifySelection"              },
1939     { VK_RIGHT,  0,                  "MoveRight"                                   },
1940     { VK_RIGHT,  ShiftKey,           "MoveRightAndModifySelection"                 },
1941     { VK_RIGHT,  CtrlKey,            "MoveWordRight"                               },
1942     { VK_RIGHT,  CtrlKey | ShiftKey, "MoveWordRightAndModifySelection"             },
1943     { VK_UP,     0,                  "MoveUp"                                      },
1944     { VK_UP,     ShiftKey,           "MoveUpAndModifySelection"                    },
1945     { VK_PRIOR,  ShiftKey,           "MovePageUpAndModifySelection"                },
1946     { VK_DOWN,   0,                  "MoveDown"                                    },
1947     { VK_DOWN,   ShiftKey,           "MoveDownAndModifySelection"                  },
1948     { VK_NEXT,   ShiftKey,           "MovePageDownAndModifySelection"              },
1949     { VK_PRIOR,  0,                  "MovePageUp"                                  },
1950     { VK_NEXT,   0,                  "MovePageDown"                                },
1951     { VK_HOME,   0,                  "MoveToBeginningOfLine"                       },
1952     { VK_HOME,   ShiftKey,           "MoveToBeginningOfLineAndModifySelection"     },
1953     { VK_HOME,   CtrlKey,            "MoveToBeginningOfDocument"                   },
1954     { VK_HOME,   CtrlKey | ShiftKey, "MoveToBeginningOfDocumentAndModifySelection" },
1955
1956     { VK_END,    0,                  "MoveToEndOfLine"                             },
1957     { VK_END,    ShiftKey,           "MoveToEndOfLineAndModifySelection"           },
1958     { VK_END,    CtrlKey,            "MoveToEndOfDocument"                         },
1959     { VK_END,    CtrlKey | ShiftKey, "MoveToEndOfDocumentAndModifySelection"       },
1960
1961     { VK_BACK,   0,                  "DeleteBackward"                              },
1962     { VK_BACK,   ShiftKey,           "DeleteBackward"                              },
1963     { VK_DELETE, 0,                  "DeleteForward"                               },
1964     { VK_BACK,   CtrlKey,            "DeleteWordBackward"                          },
1965     { VK_DELETE, CtrlKey,            "DeleteWordForward"                           },
1966     
1967     { 'B',       CtrlKey,            "ToggleBold"                                  },
1968     { 'I',       CtrlKey,            "ToggleItalic"                                },
1969
1970     { VK_ESCAPE, 0,                  "Cancel"                                      },
1971     { VK_OEM_PERIOD, CtrlKey,        "Cancel"                                      },
1972     { VK_TAB,    0,                  "InsertTab"                                   },
1973     { VK_TAB,    ShiftKey,           "InsertBacktab"                               },
1974     { VK_RETURN, 0,                  "InsertNewline"                               },
1975     { VK_RETURN, CtrlKey,            "InsertNewline"                               },
1976     { VK_RETURN, AltKey,             "InsertNewline"                               },
1977     { VK_RETURN, ShiftKey,           "InsertNewline"                               },
1978     { VK_RETURN, AltKey | ShiftKey,  "InsertNewline"                               },
1979
1980     // It's not quite clear whether clipboard shortcuts and Undo/Redo should be handled
1981     // in the application or in WebKit. We chose WebKit.
1982     { 'C',       CtrlKey,            "Copy"                                        },
1983     { 'V',       CtrlKey,            "Paste"                                       },
1984     { 'X',       CtrlKey,            "Cut"                                         },
1985     { 'A',       CtrlKey,            "SelectAll"                                   },
1986     { VK_INSERT, CtrlKey,            "Copy"                                        },
1987     { VK_DELETE, ShiftKey,           "Cut"                                         },
1988     { VK_INSERT, ShiftKey,           "Paste"                                       },
1989     { 'Z',       CtrlKey,            "Undo"                                        },
1990     { 'Z',       CtrlKey | ShiftKey, "Redo"                                        },
1991 };
1992
1993 static const KeyPressEntry keyPressEntries[] = {
1994     { '\t',   0,                  "InsertTab"                                   },
1995     { '\t',   ShiftKey,           "InsertBacktab"                               },
1996     { '\r',   0,                  "InsertNewline"                               },
1997     { '\r',   CtrlKey,            "InsertNewline"                               },
1998     { '\r',   AltKey,             "InsertNewline"                               },
1999     { '\r',   ShiftKey,           "InsertNewline"                               },
2000     { '\r',   AltKey | ShiftKey,  "InsertNewline"                               },
2001 };
2002
2003 const char* WebView::interpretKeyEvent(const KeyboardEvent* evt)
2004 {
2005     ASSERT(evt->type() == eventNames().keydownEvent || evt->type() == eventNames().keypressEvent);
2006
2007     static HashMap<int, const char*>* keyDownCommandsMap = 0;
2008     static HashMap<int, const char*>* keyPressCommandsMap = 0;
2009
2010     if (!keyDownCommandsMap) {
2011         keyDownCommandsMap = new HashMap<int, const char*>;
2012         keyPressCommandsMap = new HashMap<int, const char*>;
2013
2014         for (size_t i = 0; i < WTF_ARRAY_LENGTH(keyDownEntries); ++i)
2015             keyDownCommandsMap->set(keyDownEntries[i].modifiers << 16 | keyDownEntries[i].virtualKey, keyDownEntries[i].name);
2016
2017         for (size_t i = 0; i < WTF_ARRAY_LENGTH(keyPressEntries); ++i)
2018             keyPressCommandsMap->set(keyPressEntries[i].modifiers << 16 | keyPressEntries[i].charCode, keyPressEntries[i].name);
2019     }
2020
2021     unsigned modifiers = 0;
2022     if (evt->shiftKey())
2023         modifiers |= ShiftKey;
2024     if (evt->altKey())
2025         modifiers |= AltKey;
2026     if (evt->ctrlKey())
2027         modifiers |= CtrlKey;
2028
2029     if (evt->type() == eventNames().keydownEvent) {
2030         int mapKey = modifiers << 16 | evt->keyCode();
2031         return mapKey ? keyDownCommandsMap->get(mapKey) : 0;
2032     }
2033
2034     int mapKey = modifiers << 16 | evt->charCode();
2035     return mapKey ? keyPressCommandsMap->get(mapKey) : 0;
2036 }
2037
2038 bool WebView::handleEditingKeyboardEvent(KeyboardEvent* evt)
2039 {
2040     Node* node = evt->target()->toNode();
2041     ASSERT(node);
2042     Frame* frame = node->document().frame();
2043     ASSERT(frame);
2044
2045     const PlatformKeyboardEvent* keyEvent = evt->keyEvent();
2046     if (!keyEvent || keyEvent->isSystemKey())  // do not treat this as text input if it's a system key event
2047         return false;
2048
2049     Editor::Command command = frame->editor().command(interpretKeyEvent(evt));
2050
2051     if (keyEvent->type() == PlatformEvent::RawKeyDown) {
2052         // WebKit doesn't have enough information about mode to decide how commands that just insert text if executed via Editor should be treated,
2053         // so we leave it upon WebCore to either handle them immediately (e.g. Tab that changes focus) or let a keypress event be generated
2054         // (e.g. Tab that inserts a Tab character, or Enter).
2055         return !command.isTextInsertion() && command.execute(evt);
2056     }
2057
2058      if (command.execute(evt))
2059         return true;
2060
2061     // Don't insert null or control characters as they can result in unexpected behaviour
2062     if (evt->charCode() < ' ')
2063         return false;
2064
2065     return frame->editor().insertText(evt->keyEvent()->text(), evt);
2066 }
2067
2068 bool WebView::keyDown(WPARAM virtualKeyCode, LPARAM keyData, bool systemKeyDown)
2069 {
2070 #if ENABLE(FULLSCREEN_API)
2071     // Trap the ESC key when in full screen mode.
2072     if (virtualKeyCode == VK_ESCAPE && isFullScreen()) {
2073         m_fullscreenController->exitFullScreen();
2074         return false;
2075     }
2076 #endif
2077     Frame& frame = m_page->focusController().focusedOrMainFrame();
2078
2079     PlatformKeyboardEvent keyEvent(m_viewWindow, virtualKeyCode, keyData, PlatformEvent::RawKeyDown, systemKeyDown);
2080     bool handled = frame.eventHandler().keyEvent(keyEvent);
2081
2082     // These events cannot be canceled, and we have no default handling for them.
2083     // FIXME: match IE list more closely, see <http://msdn2.microsoft.com/en-us/library/ms536938.aspx>.
2084     if (systemKeyDown && virtualKeyCode != VK_RETURN)
2085         return false;
2086
2087     if (handled) {
2088         // FIXME: remove WM_UNICHAR, too
2089         MSG msg;
2090         // WM_SYSCHAR events should not be removed, because access keys are implemented in WebCore in WM_SYSCHAR handler.
2091         if (!systemKeyDown)
2092             ::PeekMessage(&msg, m_viewWindow, WM_CHAR, WM_CHAR, PM_REMOVE);
2093         return true;
2094     }
2095
2096     // We need to handle back/forward using either Ctrl+Left/Right Arrow keys.
2097     // FIXME: This logic should probably be in EventHandler::defaultArrowEventHandler().
2098     // FIXME: Should check that other modifiers aren't pressed.
2099     if (virtualKeyCode == VK_RIGHT && keyEvent.ctrlKey())
2100         return m_page->backForward().goForward();
2101     if (virtualKeyCode == VK_LEFT && keyEvent.ctrlKey())
2102         return m_page->backForward().goBack();
2103
2104     // Need to scroll the page if the arrow keys, pgup/dn, or home/end are hit.
2105     ScrollDirection direction;
2106     ScrollGranularity granularity;
2107     switch (virtualKeyCode) {
2108         case VK_LEFT:
2109             granularity = ScrollByLine;
2110             direction = ScrollLeft;
2111             break;
2112         case VK_RIGHT:
2113             granularity = ScrollByLine;
2114             direction = ScrollRight;
2115             break;
2116         case VK_UP:
2117             granularity = ScrollByLine;
2118             direction = ScrollUp;
2119             break;
2120         case VK_DOWN:
2121             granularity = ScrollByLine;
2122             direction = ScrollDown;
2123             break;
2124         case VK_HOME:
2125             granularity = ScrollByDocument;
2126             direction = ScrollUp;
2127             break;
2128         case VK_END:
2129             granularity = ScrollByDocument;
2130             direction = ScrollDown;
2131             break;
2132         case VK_PRIOR:
2133             granularity = ScrollByPage;
2134             direction = ScrollUp;
2135             break;
2136         case VK_NEXT:
2137             granularity = ScrollByPage;
2138             direction = ScrollDown;
2139             break;
2140         default:
2141             return false;
2142     }
2143
2144     return frame.eventHandler().scrollRecursively(direction, granularity);
2145 }
2146
2147 bool WebView::keyPress(WPARAM charCode, LPARAM keyData, bool systemKeyDown)
2148 {
2149     Frame& frame = m_page->focusController().focusedOrMainFrame();
2150
2151     PlatformKeyboardEvent keyEvent(m_viewWindow, charCode, keyData, PlatformEvent::Char, systemKeyDown);
2152     // IE does not dispatch keypress event for WM_SYSCHAR.
2153     if (systemKeyDown)
2154         return frame.eventHandler().handleAccessKey(keyEvent);
2155     return frame.eventHandler().keyEvent(keyEvent);
2156 }
2157
2158 void WebView::setIsBeingDestroyed()
2159 {
2160     m_isBeingDestroyed = true;
2161
2162     // Remove our this pointer from the window so we won't try to handle any more window messages.
2163     // See <http://webkit.org/b/55054>.
2164     ::SetWindowLongPtrW(m_viewWindow, 0, 0);
2165 }
2166
2167 void WebView::setShouldInvertColors(bool shouldInvertColors)
2168 {
2169     if (m_shouldInvertColors == shouldInvertColors)
2170         return;
2171
2172     m_shouldInvertColors = shouldInvertColors;
2173
2174 #if USE(CA)
2175     if (m_layerTreeHost)
2176         m_layerTreeHost->setShouldInvertColors(shouldInvertColors);
2177 #endif
2178
2179     RECT windowRect = {0};
2180     frameRect(&windowRect);
2181     repaint(windowRect, true, true);
2182 }
2183
2184 bool WebView::registerWebViewWindowClass()
2185 {
2186     static bool haveRegisteredWindowClass = false;
2187     if (haveRegisteredWindowClass)
2188         return true;
2189
2190     haveRegisteredWindowClass = true;
2191
2192     WNDCLASSEX wcex;
2193
2194     wcex.cbSize = sizeof(WNDCLASSEX);
2195
2196     wcex.style          = CS_DBLCLKS;
2197     wcex.lpfnWndProc    = WebViewWndProc;
2198     wcex.cbClsExtra     = 0;
2199     wcex.cbWndExtra     = sizeof(WebView*);
2200     wcex.hInstance      = gInstance;
2201     wcex.hIcon          = 0;
2202     wcex.hCursor        = ::LoadCursor(0, IDC_ARROW);
2203     wcex.hbrBackground  = 0;
2204     wcex.lpszMenuName   = 0;
2205     wcex.lpszClassName  = kWebViewWindowClassName;
2206     wcex.hIconSm        = 0;
2207
2208     return !!RegisterClassEx(&wcex);
2209 }
2210
2211 static HWND findTopLevelParent(HWND window)
2212 {
2213     if (!window)
2214         return 0;
2215
2216     HWND current = window;
2217     for (HWND parent = GetParent(current); current; current = parent, parent = GetParent(parent))
2218         if (!parent || !(GetWindowLongPtr(current, GWL_STYLE) & (WS_POPUP | WS_CHILD)))
2219             return current;
2220     ASSERT_NOT_REACHED();
2221     return 0;
2222 }
2223
2224 LRESULT CALLBACK WebView::WebViewWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
2225 {
2226     LRESULT lResult = 0;
2227     LONG_PTR longPtr = GetWindowLongPtr(hWnd, 0);
2228     WebView* webView = reinterpret_cast<WebView*>(longPtr);
2229     WebFrame* mainFrameImpl = webView ? webView->topLevelFrame() : 0;
2230     if (!mainFrameImpl)
2231         return DefWindowProc(hWnd, message, wParam, lParam);
2232
2233     // We shouldn't be trying to handle any window messages after WM_DESTROY.
2234     // See <http://webkit.org/b/55054>.
2235     ASSERT(!webView->isBeingDestroyed());
2236
2237     // hold a ref, since the WebView could go away in an event handler.
2238     COMPtr<WebView> protector(webView);
2239     ASSERT(webView);
2240
2241     // Windows Media Player has a modal message loop that will deliver messages
2242     // to us at inappropriate times and we will crash if we handle them when
2243     // they are delivered. We repost paint messages so that we eventually get
2244     // a chance to paint once the modal loop has exited, but other messages
2245     // aren't safe to repost, so we just drop them.
2246     if (PluginView::isCallingPlugin()) {
2247         if (message == WM_PAINT)
2248             PostMessage(hWnd, message, wParam, lParam);
2249         return 0;
2250     }
2251
2252     bool handled = true;
2253
2254     switch (message) {
2255         case WM_PAINT: {
2256             webView->paint(0, 0);
2257             if (webView->usesLayeredWindow())
2258                 webView->performLayeredWindowUpdate();
2259             break;
2260         }
2261         case WM_ERASEBKGND:
2262             // Don't perform a background erase.
2263             handled = true;
2264             lResult = 1;
2265             break;
2266         case WM_PRINTCLIENT:
2267             webView->paint((HDC)wParam, lParam);
2268             break;
2269         case WM_DESTROY:
2270             webView->setIsBeingDestroyed();
2271             webView->close();
2272             break;
2273         case WM_GESTURENOTIFY:
2274             handled = webView->gestureNotify(wParam, lParam);
2275             break;
2276         case WM_GESTURE:
2277             handled = webView->gesture(wParam, lParam);
2278             break;
2279         case WM_MOUSEMOVE:
2280         case WM_LBUTTONDOWN:
2281         case WM_MBUTTONDOWN:
2282         case WM_RBUTTONDOWN:
2283         case WM_LBUTTONDBLCLK:
2284         case WM_MBUTTONDBLCLK:
2285         case WM_RBUTTONDBLCLK:
2286         case WM_LBUTTONUP:
2287         case WM_MBUTTONUP:
2288         case WM_RBUTTONUP:
2289         case WM_MOUSELEAVE:
2290         case WM_CANCELMODE:
2291             if (Frame* coreFrame = core(mainFrameImpl))
2292                 if (coreFrame->view()->didFirstLayout())
2293                     handled = webView->handleMouseEvent(message, wParam, lParam);
2294             break;
2295         case WM_MOUSEWHEEL:
2296         case WM_VISTA_MOUSEHWHEEL:
2297             if (Frame* coreFrame = core(mainFrameImpl))
2298                 if (coreFrame->view()->didFirstLayout())
2299                     handled = webView->mouseWheel(wParam, lParam, message == WM_VISTA_MOUSEHWHEEL);
2300             break;
2301         case WM_SYSKEYDOWN:
2302             handled = webView->keyDown(wParam, lParam, true);
2303             break;
2304         case WM_KEYDOWN:
2305             handled = webView->keyDown(wParam, lParam);
2306             break;
2307         case WM_SYSKEYUP:
2308             handled = webView->keyUp(wParam, lParam, true);
2309             break;
2310         case WM_KEYUP:
2311             handled = webView->keyUp(wParam, lParam);
2312             break;
2313         case WM_SYSCHAR:
2314             handled = webView->keyPress(wParam, lParam, true);
2315             break;
2316         case WM_CHAR:
2317             handled = webView->keyPress(wParam, lParam);
2318             break;
2319         // FIXME: We need to check WM_UNICHAR to support supplementary characters (that don't fit in 16 bits).
2320         case WM_SIZE:
2321             if (lParam != 0)
2322                 webView->sizeChanged(IntSize(LOWORD(lParam), HIWORD(lParam)));
2323             break;
2324         case WM_SHOWWINDOW:
2325             lResult = DefWindowProc(hWnd, message, wParam, lParam);
2326             if (wParam == 0) {
2327                 // The window is being hidden (e.g., because we switched tabs).
2328                 // Null out our backing store.
2329                 webView->deleteBackingStore();
2330             }
2331             break;
2332         case WM_SETFOCUS: {
2333             COMPtr<IWebUIDelegate> uiDelegate;
2334             COMPtr<IWebUIDelegatePrivate> uiDelegatePrivate;
2335             if (SUCCEEDED(webView->uiDelegate(&uiDelegate)) && uiDelegate
2336                 && SUCCEEDED(uiDelegate->QueryInterface(IID_IWebUIDelegatePrivate, (void**) &uiDelegatePrivate)) && uiDelegatePrivate)
2337                 uiDelegatePrivate->webViewReceivedFocus(webView);
2338
2339             FocusController& focusController = webView->page()->focusController();
2340             if (Frame* frame = focusController.focusedFrame()) {
2341                 // Send focus events unless the previously focused window is a
2342                 // child of ours (for example a plugin).
2343                 if (!IsChild(hWnd, reinterpret_cast<HWND>(wParam)))
2344                     focusController.setFocused(true);
2345             } else
2346                 focusController.setFocused(true);
2347             break;
2348         }
2349         case WM_KILLFOCUS: {
2350             COMPtr<IWebUIDelegate> uiDelegate;
2351             COMPtr<IWebUIDelegatePrivate> uiDelegatePrivate;
2352             HWND newFocusWnd = reinterpret_cast<HWND>(wParam);
2353             if (SUCCEEDED(webView->uiDelegate(&uiDelegate)) && uiDelegate
2354                 && SUCCEEDED(uiDelegate->QueryInterface(IID_IWebUIDelegatePrivate, (void**) &uiDelegatePrivate)) && uiDelegatePrivate)
2355                 uiDelegatePrivate->webViewLostFocus(webView, newFocusWnd);
2356
2357             FocusController& focusController = webView->page()->focusController();
2358             Frame& frame = focusController.focusedOrMainFrame();
2359             webView->resetIME(&frame);
2360             // Send blur events unless we're losing focus to a child of ours.
2361             if (!IsChild(hWnd, newFocusWnd))
2362                 focusController.setFocused(false);
2363
2364             // If we are pan-scrolling when we lose focus, stop the pan scrolling.
2365             frame.eventHandler().stopAutoscrollTimer();
2366
2367             break;
2368         }
2369         case WM_WINDOWPOSCHANGED:
2370             if (reinterpret_cast<WINDOWPOS*>(lParam)->flags & SWP_SHOWWINDOW)
2371                 webView->updateActiveStateSoon();
2372             handled = false;
2373             break;
2374         case WM_CUT:
2375             webView->cut(0);
2376             break;
2377         case WM_COPY:
2378             webView->copy(0);
2379             break;
2380         case WM_PASTE:
2381             webView->paste(0);
2382             break;
2383         case WM_CLEAR:
2384             webView->delete_(0);
2385             break;
2386         case WM_COMMAND:
2387             if (HIWORD(wParam))
2388                 handled = webView->execCommand(wParam, lParam);
2389             else // If the high word of wParam is 0, the message is from a menu
2390                 webView->performContextMenuAction(wParam, lParam, false);
2391             break;
2392         case WM_MENUCOMMAND:
2393             webView->performContextMenuAction(wParam, lParam, true);
2394             break;
2395         case WM_CONTEXTMENU:
2396             handled = webView->handleContextMenuEvent(wParam, lParam);
2397             break;
2398         case WM_INITMENUPOPUP:
2399             handled = webView->onInitMenuPopup(wParam, lParam);
2400             break;
2401         case WM_MEASUREITEM:
2402             handled = webView->onMeasureItem(wParam, lParam);
2403             break;
2404         case WM_DRAWITEM:
2405             handled = webView->onDrawItem(wParam, lParam);
2406             break;
2407         case WM_UNINITMENUPOPUP:
2408             handled = webView->onUninitMenuPopup(wParam, lParam);
2409             break;
2410         case WM_XP_THEMECHANGED:
2411             if (Frame* coreFrame = core(mainFrameImpl)) {
2412                 webView->deleteBackingStore();
2413                 coreFrame->page()->theme().themeChanged();
2414                 ScrollbarTheme::theme()->themeChanged();
2415                 RECT windowRect;
2416                 ::GetClientRect(hWnd, &windowRect);
2417                 ::InvalidateRect(hWnd, &windowRect, false);
2418 #if USE(CA)
2419                 if (webView->isAcceleratedCompositing())
2420                     webView->m_backingLayer->setNeedsDisplay();
2421 #endif
2422            }
2423             break;
2424         case WM_MOUSEACTIVATE:
2425             webView->setMouseActivated(true);
2426             handled = false;
2427             break;
2428         case WM_GETDLGCODE: {
2429             COMPtr<IWebUIDelegate> uiDelegate;
2430             COMPtr<IWebUIDelegatePrivate> uiDelegatePrivate;
2431             LONG_PTR dlgCode = 0;
2432             UINT keyCode = 0;
2433             if (lParam) {
2434                 LPMSG lpMsg = (LPMSG)lParam;
2435                 if (lpMsg->message == WM_KEYDOWN)
2436                     keyCode = (UINT) lpMsg->wParam;
2437             }
2438             if (SUCCEEDED(webView->uiDelegate(&uiDelegate)) && uiDelegate
2439                 && SUCCEEDED(uiDelegate->QueryInterface(IID_IWebUIDelegatePrivate, (void**) &uiDelegatePrivate)) && uiDelegatePrivate
2440                 && SUCCEEDED(uiDelegatePrivate->webViewGetDlgCode(webView, keyCode, &dlgCode)))
2441                 return dlgCode;
2442             handled = false;
2443             break;
2444         }
2445         case WM_GETOBJECT:
2446             handled = webView->onGetObject(wParam, lParam, lResult);
2447             break;
2448         case WM_IME_STARTCOMPOSITION:
2449             handled = webView->onIMEStartComposition();
2450             break;
2451         case WM_IME_REQUEST:
2452             lResult = webView->onIMERequest(wParam, lParam);
2453             break;
2454         case WM_IME_COMPOSITION:
2455             handled = webView->onIMEComposition(lParam);
2456             break;
2457         case WM_IME_ENDCOMPOSITION:
2458             handled = webView->onIMEEndComposition();
2459             break;
2460         case WM_IME_CHAR:
2461             handled = webView->onIMEChar(wParam, lParam);
2462             break;
2463         case WM_IME_NOTIFY:
2464             handled = webView->onIMENotify(wParam, lParam, &lResult);
2465             break;
2466         case WM_IME_SELECT:
2467             handled = webView->onIMESelect(wParam, lParam);
2468             break;
2469         case WM_IME_SETCONTEXT:
2470             handled = webView->onIMESetContext(wParam, lParam);
2471             break;
2472         case WM_TIMER:
2473             switch (wParam) {
2474                 case UpdateActiveStateTimer:
2475                     KillTimer(hWnd, UpdateActiveStateTimer);
2476                     webView->updateActiveState();
2477                     break;
2478                 case DeleteBackingStoreTimer:
2479                     webView->deleteBackingStore();
2480                     break;
2481             }
2482             break;
2483         case WM_SETCURSOR:
2484             handled = ::SetCursor(webView->m_lastSetCursor);
2485             break;
2486         case WM_VSCROLL:
2487             handled = webView->verticalScroll(wParam, lParam);
2488             break;
2489         case WM_HSCROLL:
2490             handled = webView->horizontalScroll(wParam, lParam);
2491             break;
2492         default:
2493             handled = false;
2494             break;
2495     }
2496
2497     if (webView->needsDisplay() && message != WM_PAINT)
2498         ::UpdateWindow(hWnd);
2499
2500     if (!handled)
2501         lResult = DefWindowProc(hWnd, message, wParam, lParam);
2502     
2503     // Let the client know whether we consider this message handled.
2504     return (message == WM_KEYDOWN || message == WM_SYSKEYDOWN || message == WM_KEYUP || message == WM_SYSKEYUP) ? !handled : lResult;
2505 }
2506
2507 bool WebView::developerExtrasEnabled() const
2508 {
2509     if (m_preferences->developerExtrasDisabledByOverride())
2510         return false;
2511
2512 #ifdef NDEBUG
2513     BOOL enabled;
2514     return SUCCEEDED(m_preferences->developerExtrasEnabled(&enabled)) && enabled;
2515 #else
2516     return true;
2517 #endif
2518 }
2519
2520 static String webKitVersionString()
2521 {
2522 #if !USE(CAIRO)
2523     LPWSTR buildNumberStringPtr;
2524     if (::LoadStringW(gInstance, BUILD_NUMBER, reinterpret_cast<LPWSTR>(&buildNumberStringPtr), 0) && buildNumberStringPtr)
2525         return buildNumberStringPtr;
2526 #endif
2527     return String::format("%d.%d", WEBKIT_MAJOR_VERSION, WEBKIT_MINOR_VERSION);
2528 }
2529
2530 const String& WebView::userAgentForKURL(const URL&)
2531 {
2532     if (m_userAgentOverridden)
2533         return m_userAgentCustom;
2534
2535     if (!m_userAgentStandard.length())
2536         m_userAgentStandard = WebView::standardUserAgentWithApplicationName(m_applicationName);
2537     return m_userAgentStandard;
2538 }
2539
2540 // IUnknown -------------------------------------------------------------------
2541
2542 HRESULT STDMETHODCALLTYPE WebView::QueryInterface(REFIID riid, void** ppvObject)
2543 {
2544     *ppvObject = 0;
2545     if (IsEqualGUID(riid, CLSID_WebView))
2546         *ppvObject = this;
2547     else if (IsEqualGUID(riid, IID_IUnknown))
2548         *ppvObject = static_cast<IWebView*>(this);
2549     else if (IsEqualGUID(riid, IID_IWebView))
2550         *ppvObject = static_cast<IWebView*>(this);
2551     else if (IsEqualGUID(riid, IID_IWebViewPrivate))
2552         *ppvObject = static_cast<IWebViewPrivate*>(this);
2553     else if (IsEqualGUID(riid, IID_IWebIBActions))
2554         *ppvObject = static_cast<IWebIBActions*>(this);
2555     else if (IsEqualGUID(riid, IID_IWebViewCSS))
2556         *ppvObject = static_cast<IWebViewCSS*>(this);
2557     else if (IsEqualGUID(riid, IID_IWebViewEditing))
2558         *ppvObject = static_cast<IWebViewEditing*>(this);
2559     else if (IsEqualGUID(riid, IID_IWebViewUndoableEditing))
2560         *ppvObject = static_cast<IWebViewUndoableEditing*>(this);
2561     else if (IsEqualGUID(riid, IID_IWebViewEditingActions))
2562         *ppvObject = static_cast<IWebViewEditingActions*>(this);
2563     else if (IsEqualGUID(riid, IID_IWebNotificationObserver))
2564         *ppvObject = static_cast<IWebNotificationObserver*>(this);
2565     else if (IsEqualGUID(riid, IID_IDropTarget))
2566         *ppvObject = static_cast<IDropTarget*>(this);
2567     else
2568         return E_NOINTERFACE;
2569
2570     AddRef();
2571     return S_OK;
2572 }
2573
2574 ULONG STDMETHODCALLTYPE WebView::AddRef(void)
2575 {
2576     ASSERT(!m_deletionHasBegun);
2577     return ++m_refCount;
2578 }
2579
2580 ULONG STDMETHODCALLTYPE WebView::Release(void)
2581 {
2582     ASSERT(!m_deletionHasBegun);
2583
2584     if (m_refCount == 1) {
2585         // Call close() now so that clients don't have to. (It's harmless to call close() multiple
2586         // times.) We do this here instead of in our destructor because close() can cause AddRef()
2587         // and Release() to be called, and if that happened in our destructor we would be destroyed
2588         // more than once.
2589         close();
2590     }
2591
2592     ULONG newRef = --m_refCount;
2593     if (!newRef) {
2594 #if !ASSERT_DISABLED
2595         m_deletionHasBegun = true;
2596 #endif
2597         delete(this);
2598     }
2599
2600     return newRef;
2601 }
2602
2603 // IWebView --------------------------------------------------------------------
2604
2605 HRESULT WebView::canShowMIMEType(/* [in] */ BSTR mimeType, /* [retval][out] */ BOOL* canShow)
2606 {
2607     if (!canShow)
2608         return E_POINTER;
2609
2610     *canShow = canShowMIMEType(toString(mimeType));
2611
2612     return S_OK;
2613 }
2614
2615 bool WebView::canShowMIMEType(const String& mimeType)
2616 {
2617     Frame* coreFrame = core(m_mainFrame);
2618     bool allowPlugins = coreFrame && coreFrame->loader().subframeLoader().allowPlugins(NotAboutToInstantiatePlugin);
2619
2620     bool canShow = MIMETypeRegistry::isSupportedImageMIMEType(mimeType)
2621         || MIMETypeRegistry::isSupportedNonImageMIMEType(mimeType)
2622         || MIMETypeRegistry::isSupportedMediaMIMEType(mimeType);
2623
2624     if (!canShow && m_page) {
2625         canShow = (m_page->pluginData().supportsMimeType(mimeType, PluginData::AllPlugins) && allowPlugins)
2626             || m_page->pluginData().supportsMimeType(mimeType, PluginData::OnlyApplicationPlugins);
2627     }
2628
2629     if (!canShow)
2630         canShow = shouldUseEmbeddedView(mimeType);
2631
2632     return canShow;
2633 }
2634
2635 HRESULT WebView::canShowMIMETypeAsHTML(/* [in] */ BSTR mimeType, /* [retval][out] */ BOOL* canShow)
2636 {
2637     if (!canShow)
2638         return E_POINTER;
2639
2640     *canShow = canShowMIMETypeAsHTML(toString(mimeType));
2641
2642     return S_OK;
2643 }
2644
2645 bool WebView::canShowMIMETypeAsHTML(const String& /*mimeType*/)
2646 {
2647     // FIXME
2648     notImplemented();
2649     return true;
2650 }
2651
2652 HRESULT STDMETHODCALLTYPE WebView::MIMETypesShownAsHTML( 
2653     /* [retval][out] */ IEnumVARIANT** /*enumVariant*/)
2654 {
2655     ASSERT_NOT_REACHED();
2656     return E_NOTIMPL;
2657 }
2658
2659 HRESULT STDMETHODCALLTYPE WebView::setMIMETypesShownAsHTML( 
2660         /* [size_is][in] */ BSTR* /*mimeTypes*/,
2661         /* [in] */ int /*cMimeTypes*/)
2662 {
2663     ASSERT_NOT_REACHED();
2664     return E_NOTIMPL;
2665 }
2666
2667 HRESULT STDMETHODCALLTYPE WebView::URLFromPasteboard( 
2668     /* [in] */ IDataObject* /*pasteboard*/,
2669     /* [retval][out] */ BSTR* /*url*/)
2670 {
2671     ASSERT_NOT_REACHED();
2672     return E_NOTIMPL;
2673 }
2674
2675 HRESULT STDMETHODCALLTYPE WebView::URLTitleFromPasteboard( 
2676     /* [in] */ IDataObject* /*pasteboard*/,
2677     /* [retval][out] */ BSTR* /*urlTitle*/)
2678 {
2679     ASSERT_NOT_REACHED();
2680     return E_NOTIMPL;
2681 }
2682
2683 static void WebKitSetApplicationCachePathIfNecessary()
2684 {
2685     static bool initialized = false;
2686     if (initialized)
2687         return;
2688
2689     String path = localUserSpecificStorageDirectory();
2690
2691 #if USE(CF)
2692     RetainPtr<CFPropertyListRef> cacheDirectoryPreference = adoptCF(CFPreferencesCopyAppValue(WebKitLocalCacheDefaultsKey, kCFPreferencesCurrentApplication));
2693     if (cacheDirectoryPreference && (CFStringGetTypeID() == CFGetTypeID(cacheDirectoryPreference.get())))
2694         path = static_cast<CFStringRef>(cacheDirectoryPreference.get());
2695 #endif
2696
2697     if (!path.isNull())
2698         cacheStorage().setCacheDirectory(path);
2699
2700     initialized = true;
2701 }
2702
2703 bool WebView::shouldInitializeTrackPointHack()
2704 {
2705     static bool shouldCreateScrollbars;
2706     static bool hasRunTrackPointCheck;
2707
2708     if (hasRunTrackPointCheck)
2709         return shouldCreateScrollbars;
2710
2711     hasRunTrackPointCheck = true;
2712     const WCHAR trackPointKeys[][50] = { L"Software\\Lenovo\\TrackPoint",
2713         L"Software\\Lenovo\\UltraNav",
2714         L"Software\\Alps\\Apoint\\TrackPoint",
2715         L"Software\\Synaptics\\SynTPEnh\\UltraNavUSB",
2716         L"Software\\Synaptics\\SynTPEnh\\UltraNavPS2" };
2717
2718     for (int i = 0; i < 5; ++i) {
2719         HKEY trackPointKey = nullptr;
2720         LSTATUS readKeyResult = ::RegOpenKeyExW(HKEY_CURRENT_USER, trackPointKeys[i], 0, KEY_READ, &trackPointKey);
2721         ::RegCloseKey(trackPointKey);
2722         if (readKeyResult == ERROR_SUCCESS) {
2723             shouldCreateScrollbars = true;
2724             return shouldCreateScrollbars;
2725         }
2726     }
2727
2728     return shouldCreateScrollbars;
2729 }
2730
2731 static String localStorageDatabasePath(WebPreferences* preferences)
2732 {
2733     BString localStorageDatabasePath;
2734     if (FAILED(preferences->localStorageDatabasePath(&localStorageDatabasePath)))
2735         return String();
2736
2737     return toString(localStorageDatabasePath);
2738 }
2739
2740 HRESULT STDMETHODCALLTYPE WebView::initWithFrame( 
2741     /* [in] */ RECT frame,
2742     /* [in] */ BSTR frameName,
2743     /* [in] */ BSTR groupName)
2744 {
2745     HRESULT hr = S_OK;
2746
2747     if (m_viewWindow)
2748         return E_FAIL;
2749
2750     registerWebViewWindowClass();
2751
2752     m_viewWindow = CreateWindowEx(0, kWebViewWindowClassName, 0, WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
2753         frame.left, frame.top, frame.right - frame.left, frame.bottom - frame.top, m_hostWindow ? m_hostWindow : HWND_MESSAGE, 0, gInstance, 0);
2754     ASSERT(::IsWindow(m_viewWindow));
2755
2756     if (shouldInitializeTrackPointHack()) {
2757         // If we detected a registry key belonging to a TrackPoint driver, then create fake trackpoint
2758         // scrollbars, so the WebView will receive WM_VSCROLL and WM_HSCROLL messages. We create one
2759         // vertical scrollbar and one horizontal to allow for receiving both types of messages.
2760         ::CreateWindowW(L"SCROLLBAR", L"FAKETRACKPOINTHSCROLLBAR", WS_CHILD | WS_VISIBLE | SBS_HORZ, 0, 0, 0, 0, m_viewWindow, 0, gInstance, 0);
2761         ::CreateWindowW(L"SCROLLBAR", L"FAKETRACKPOINTVSCROLLBAR", WS_CHILD | WS_VISIBLE | SBS_VERT, 0, 0, 0, 0, m_viewWindow, 0, gInstance, 0);
2762     }
2763
2764     hr = registerDragDrop();
2765     if (FAILED(hr))
2766         return hr;
2767
2768     WebPreferences* sharedPreferences = WebPreferences::sharedStandardPreferences();
2769     sharedPreferences->willAddToWebView();
2770     m_preferences = sharedPreferences;
2771
2772     static bool didOneTimeInitialization;
2773     if (!didOneTimeInitialization) {
2774 #if !LOG_DISABLED
2775         initializeLoggingChannelsIfNecessary();
2776 #endif // !LOG_DISABLED
2777
2778         // Initialize our platform strategies first before invoking the rest
2779         // of the initialization code which may depend on the strategies.
2780         WebPlatformStrategies::initialize();
2781
2782         WebKitInitializeWebDatabasesIfNecessary();
2783         WebKitSetApplicationCachePathIfNecessary();
2784         Settings::setDefaultMinDOMTimerInterval(0.004);
2785
2786         didOneTimeInitialization = true;
2787      }
2788
2789 #if USE(SAFARI_THEME)
2790     BOOL shouldPaintNativeControls;
2791     if (SUCCEEDED(m_preferences->shouldPaintNativeControls(&shouldPaintNativeControls)))
2792         Settings::setShouldPaintNativeControls(shouldPaintNativeControls);
2793 #endif
2794
2795     BOOL useHighResolutionTimer;
2796     if (SUCCEEDED(m_preferences->shouldUseHighResolutionTimers(&useHighResolutionTimer)))
2797         Settings::setShouldUseHighResolutionTimers(useHighResolutionTimer);
2798
2799     m_inspectorClient = new WebInspectorClient(this);
2800
2801     PageConfiguration configuration;
2802     configuration.chromeClient = new WebChromeClient(this);
2803     configuration.contextMenuClient = new WebContextMenuClient(this);
2804     configuration.editorClient = new WebEditorClient(this);
2805     configuration.dragClient = new WebDragClient(this);
2806     configuration.inspectorClient = m_inspectorClient;
2807     configuration.loaderClientForMainFrame = new WebFrameLoaderClient;
2808     configuration.databaseProvider = &WebDatabaseProvider::shared();
2809     configuration.storageNamespaceProvider = WebStorageNamespaceProvider::create(localStorageDatabasePath(m_preferences.get()));
2810     configuration.progressTrackerClient = static_cast<WebFrameLoaderClient*>(configuration.loaderClientForMainFrame);
2811     configuration.visitedLinkStore = &WebVisitedLinkStore::shared();
2812
2813     m_page = new Page(configuration);
2814     provideGeolocationTo(m_page, new WebGeolocationClient(this));
2815
2816     unsigned layoutMilestones = DidFirstLayout | DidFirstVisuallyNonEmptyLayout;
2817     m_page->addLayoutMilestones(static_cast<LayoutMilestones>(layoutMilestones));
2818
2819
2820     if (m_uiDelegate) {
2821         BString path;
2822         if (SUCCEEDED(m_uiDelegate->ftpDirectoryTemplatePath(this, &path)))
2823             m_page->settings().setFTPDirectoryTemplatePath(toString(path));
2824     }
2825
2826     WebFrame* webFrame = WebFrame::createInstance();
2827     webFrame->initWithWebView(this, m_page);
2828     static_cast<WebFrameLoaderClient&>(m_page->mainFrame().loader().client()).setWebFrame(webFrame);
2829     m_mainFrame = webFrame;
2830     webFrame->Release(); // The WebFrame is owned by the Frame, so release our reference to it.
2831
2832     m_page->mainFrame().tree().setName(toString(frameName));
2833     m_page->mainFrame().init();
2834     setGroupName(groupName);
2835
2836     addToAllWebViewsSet();
2837
2838     #pragma warning(suppress: 4244)
2839     SetWindowLongPtr(m_viewWindow, 0, (LONG_PTR)this);
2840     ShowWindow(m_viewWindow, SW_SHOW);
2841
2842     initializeToolTipWindow();
2843     windowAncestryDidChange();
2844
2845     IWebNotificationCenter* notifyCenter = WebNotificationCenter::defaultCenterInternal();
2846     notifyCenter->addObserver(this, WebPreferences::webPreferencesChangedNotification(), static_cast<IWebPreferences*>(m_preferences.get()));
2847     m_preferences->postPreferencesChangesNotification();
2848
2849     setSmartInsertDeleteEnabled(TRUE);
2850     return hr;
2851 }
2852
2853 static bool initCommonControls()
2854 {
2855     static bool haveInitialized = false;
2856     if (haveInitialized)
2857         return true;
2858
2859     INITCOMMONCONTROLSEX init;
2860     init.dwSize = sizeof(init);
2861     init.dwICC = ICC_TREEVIEW_CLASSES;
2862     haveInitialized = !!::InitCommonControlsEx(&init);
2863     return haveInitialized;
2864 }
2865
2866 void WebView::initializeToolTipWindow()
2867 {
2868     if (!initCommonControls())
2869         return;
2870
2871     m_toolTipHwnd = CreateWindowEx(WS_EX_TRANSPARENT, TOOLTIPS_CLASS, 0, WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP,
2872                                    CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
2873                                    m_viewWindow, 0, 0, 0);
2874     if (!m_toolTipHwnd)
2875         return;
2876
2877     TOOLINFO info = {0};
2878     info.cbSize = sizeof(info);
2879     info.uFlags = TTF_IDISHWND | TTF_SUBCLASS ;
2880     info.uId = reinterpret_cast<UINT_PTR>(m_viewWindow);
2881
2882     ::SendMessage(m_toolTipHwnd, TTM_ADDTOOL, 0, reinterpret_cast<LPARAM>(&info));
2883     ::SendMessage(m_toolTipHwnd, TTM_SETMAXTIPWIDTH, 0, maxToolTipWidth);
2884
2885     ::SetWindowPos(m_toolTipHwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
2886 }
2887
2888 void WebView::setToolTip(const String& toolTip)
2889 {
2890     if (!m_toolTipHwnd)
2891         return;
2892
2893     if (toolTip == m_toolTip)
2894         return;
2895
2896     m_toolTip = toolTip;
2897
2898     if (!m_toolTip.isEmpty()) {
2899         TOOLINFO info = {0};
2900         info.cbSize = sizeof(info);
2901         info.uFlags = TTF_IDISHWND;
2902         info.uId = reinterpret_cast<UINT_PTR>(m_viewWindow);
2903         Vector<UChar> toolTipCharacters = m_toolTip.charactersWithNullTermination(); // Retain buffer long enough to make the SendMessage call
2904         info.lpszText = const_cast<UChar*>(toolTipCharacters.data());
2905         ::SendMessage(m_toolTipHwnd, TTM_UPDATETIPTEXT, 0, reinterpret_cast<LPARAM>(&info));
2906     }
2907
2908     ::SendMessage(m_toolTipHwnd, TTM_ACTIVATE, !m_toolTip.isEmpty(), 0);
2909 }
2910
2911 HRESULT WebView::notifyDidAddIcon(IWebNotification* notification)
2912 {
2913     COMPtr<IPropertyBag> propertyBag;
2914     HRESULT hr = notification->userInfo(&propertyBag);
2915     if (FAILED(hr))
2916         return hr;
2917     if (!propertyBag)
2918         return E_FAIL;
2919
2920     COMVariant iconUserInfoURL;
2921     hr = propertyBag->Read(WebIconDatabase::iconDatabaseNotificationUserInfoURLKey(), &iconUserInfoURL, nullptr);
2922     if (FAILED(hr))
2923         return hr;
2924
2925     if (iconUserInfoURL.variantType() != VT_BSTR)
2926         return E_FAIL;
2927
2928     String mainFrameURL;
2929     if (m_mainFrame)
2930         mainFrameURL = m_mainFrame->url().string();
2931
2932     if (!mainFrameURL.isEmpty() && mainFrameURL == toString(V_BSTR(&iconUserInfoURL)))
2933         dispatchDidReceiveIconFromWebFrame(m_mainFrame);
2934
2935     return hr;
2936 }
2937
2938 void WebView::registerForIconNotification(bool listen)
2939 {
2940     IWebNotificationCenter* nc = WebNotificationCenter::defaultCenterInternal();
2941     if (listen)
2942         nc->addObserver(this, WebIconDatabase::iconDatabaseDidAddIconNotification(), 0);
2943     else
2944         nc->removeObserver(this, WebIconDatabase::iconDatabaseDidAddIconNotification(), 0);
2945 }
2946
2947 void WebView::dispatchDidReceiveIconFromWebFrame(WebFrame* frame)
2948 {
2949     registerForIconNotification(false);
2950
2951     if (m_frameLoadDelegate) {
2952         String str = frame->url().string();
2953
2954         IntSize sz(16, 16);
2955
2956         BitmapInfo bmInfo = BitmapInfo::create(sz);
2957
2958         HBITMAP hBitmap = nullptr;
2959
2960         Image* icon = iconDatabase().synchronousIconForPageURL(str, sz);
2961
2962         if (icon && icon->width()) {
2963             HWndDC dc(0);
2964             hBitmap = CreateDIBSection(dc, &bmInfo, DIB_RGB_COLORS, 0, 0, 0);
2965             icon->getHBITMAPOfSize(hBitmap, &sz);
2966         }
2967
2968         HRESULT hr = m_frameLoadDelegate->didReceiveIcon(this, hBitmap, frame);
2969         if ((hr == E_NOTIMPL) && hBitmap)
2970             DeleteObject(hBitmap);
2971     }
2972 }
2973
2974 HRESULT WebView::setAccessibilityDelegate(
2975     /* [in] */ IAccessibilityDelegate* d)
2976 {
2977     m_accessibilityDelegate = d;
2978     return S_OK;
2979 }
2980
2981 HRESULT WebView::accessibilityDelegate(
2982     /* [out][retval] */ IAccessibilityDelegate** d)
2983 {
2984     if (!m_accessibilityDelegate)
2985         return E_POINTER;
2986
2987     return m_accessibilityDelegate.copyRefTo(d);
2988 }
2989
2990 HRESULT STDMETHODCALLTYPE WebView::setUIDelegate( 
2991     /* [in] */ IWebUIDelegate* d)
2992 {
2993     m_uiDelegate = d;
2994
2995     if (m_uiDelegatePrivate)
2996         m_uiDelegatePrivate = 0;
2997
2998     if (d) {
2999         if (FAILED(d->QueryInterface(IID_IWebUIDelegatePrivate, (void**)&m_uiDelegatePrivate)))
3000             m_uiDelegatePrivate = 0;
3001     }
3002
3003     return S_OK;
3004 }
3005
3006 HRESULT STDMETHODCALLTYPE WebView::uiDelegate( 
3007     /* [out][retval] */ IWebUIDelegate** d)
3008 {
3009     if (!m_uiDelegate)
3010         return E_FAIL;
3011
3012     return m_uiDelegate.copyRefTo(d);
3013 }
3014
3015 HRESULT STDMETHODCALLTYPE WebView::setResourceLoadDelegate( 
3016     /* [in] */ IWebResourceLoadDelegate* d)
3017 {
3018     m_resourceLoadDelegate = d;
3019     return S_OK;
3020 }
3021
3022 HRESULT STDMETHODCALLTYPE WebView::resourceLoadDelegate( 
3023     /* [out][retval] */ IWebResourceLoadDelegate** d)
3024 {
3025     if (!m_resourceLoadDelegate)
3026         return E_FAIL;
3027
3028     return m_resourceLoadDelegate.copyRefTo(d);
3029 }
3030
3031 HRESULT STDMETHODCALLTYPE WebView::setDownloadDelegate( 
3032     /* [in] */ IWebDownloadDelegate* d)
3033 {
3034     m_downloadDelegate = d;
3035     return S_OK;
3036 }
3037
3038 HRESULT STDMETHODCALLTYPE WebView::downloadDelegate( 
3039     /* [out][retval] */ IWebDownloadDelegate** d)
3040 {
3041     if (!m_downloadDelegate)
3042         return E_FAIL;
3043
3044     return m_downloadDelegate.copyRefTo(d);
3045 }
3046
3047 HRESULT STDMETHODCALLTYPE WebView::setFrameLoadDelegate( 
3048     /* [in] */ IWebFrameLoadDelegate* d)
3049 {
3050     m_frameLoadDelegate = d;
3051     return S_OK;
3052 }
3053
3054 HRESULT STDMETHODCALLTYPE WebView::frameLoadDelegate( 
3055     /* [out][retval] */ IWebFrameLoadDelegate** d)
3056 {
3057     if (!m_frameLoadDelegate)
3058         return E_FAIL;
3059
3060     return m_frameLoadDelegate.copyRefTo(d);
3061 }
3062
3063 HRESULT STDMETHODCALLTYPE WebView::setPolicyDelegate( 
3064     /* [in] */ IWebPolicyDelegate* d)
3065 {
3066     m_policyDelegate = d;
3067     return S_OK;
3068 }
3069
3070 HRESULT STDMETHODCALLTYPE WebView::policyDelegate( 
3071     /* [out][retval] */ IWebPolicyDelegate** d)
3072 {
3073     if (!m_policyDelegate)
3074         return E_FAIL;
3075     return m_policyDelegate.copyRefTo(d);
3076 }
3077
3078 HRESULT STDMETHODCALLTYPE WebView::mainFrame( 
3079     /* [out][retval] */ IWebFrame** frame)
3080 {
3081     if (!frame) {
3082         ASSERT_NOT_REACHED();
3083         return E_POINTER;
3084     }
3085
3086     *frame = m_mainFrame;
3087     if (!m_mainFrame)
3088         return E_FAIL;
3089
3090     m_mainFrame->AddRef();
3091     return S_OK;
3092 }
3093
3094 HRESULT STDMETHODCALLTYPE WebView::focusedFrame( 
3095     /* [out][retval] */ IWebFrame** frame)
3096 {
3097     if (!frame) {
3098         ASSERT_NOT_REACHED();
3099         return E_POINTER;
3100     }
3101
3102     *frame = 0;
3103     Frame* f = m_page->focusController().focusedFrame();
3104     if (!f)
3105         return E_FAIL;
3106
3107     WebFrame* webFrame = kit(f);
3108     if (!webFrame)
3109         return E_FAIL;
3110
3111     return webFrame->QueryInterface(IID_IWebFrame, (void**) frame);
3112 }
3113
3114 HRESULT STDMETHODCALLTYPE WebView::backForwardList( 
3115     /* [out][retval] */ IWebBackForwardList** list)
3116 {
3117     if (!m_useBackForwardList)
3118         return E_FAIL;
3119  
3120     *list = WebBackForwardList::createInstance(static_cast<WebCore::BackForwardList*>(m_page->backForward().client()));
3121
3122     return S_OK;
3123 }
3124
3125 HRESULT STDMETHODCALLTYPE WebView::setMaintainsBackForwardList( 
3126     /* [in] */ BOOL flag)
3127 {
3128     m_useBackForwardList = !!flag;
3129     return S_OK;
3130 }
3131
3132 HRESULT STDMETHODCALLTYPE WebView::goBack( 
3133     /* [retval][out] */ BOOL* succeeded)
3134 {
3135     *succeeded = m_page->backForward().goBack();
3136     return S_OK;
3137 }
3138
3139 HRESULT STDMETHODCALLTYPE WebView::goForward( 
3140     /* [retval][out] */ BOOL* succeeded)
3141 {
3142     *succeeded = m_page->backForward().goForward();
3143     return S_OK;
3144 }
3145
3146 HRESULT STDMETHODCALLTYPE WebView::goToBackForwardItem( 
3147     /* [in] */ IWebHistoryItem* item,
3148     /* [retval][out] */ BOOL* succeeded)
3149 {
3150     *succeeded = FALSE;
3151
3152     COMPtr<WebHistoryItem> webHistoryItem;
3153     HRESULT hr = item->QueryInterface(&webHistoryItem);
3154     if (FAILED(hr))
3155         return hr;
3156
3157     m_page->goToItem(webHistoryItem->historyItem(), FrameLoadType::IndexedBackForward);
3158     *succeeded = TRUE;
3159
3160     return S_OK;
3161 }
3162
3163 HRESULT STDMETHODCALLTYPE WebView::setTextSizeMultiplier( 
3164     /* [in] */ float multiplier)
3165 {
3166     if (!m_mainFrame)
3167         return E_FAIL;
3168     setZoomMultiplier(multiplier, true);
3169     return S_OK;
3170 }
3171
3172 HRESULT STDMETHODCALLTYPE WebView::setPageSizeMultiplier( 
3173     /* [in] */ float multiplier)
3174 {
3175     if (!m_mainFrame)
3176         return E_FAIL;
3177     setZoomMultiplier(multiplier, false);
3178     return S_OK;
3179 }
3180
3181 void WebView::setZoomMultiplier(float multiplier, bool isTextOnly)
3182 {
3183     m_zoomMultiplier = multiplier;
3184     m_zoomsTextOnly = isTextOnly;
3185
3186     if (Frame* coreFrame = core(m_mainFrame)) {
3187         if (m_zoomsTextOnly)
3188             coreFrame->setPageAndTextZoomFactors(1, multiplier);
3189         else
3190             coreFrame->setPageAndTextZoomFactors(multiplier, 1);
3191     }
3192 }
3193
3194 HRESULT STDMETHODCALLTYPE WebView::textSizeMultiplier( 
3195     /* [retval][out] */ float* multiplier)
3196 {
3197     *multiplier = zoomMultiplier(true);
3198     return S_OK;
3199 }
3200
3201 HRESULT STDMETHODCALLTYPE WebView::pageSizeMultiplier( 
3202     /* [retval][out] */ float* multiplier)
3203 {
3204     *multiplier = zoomMultiplier(false);
3205     return S_OK;
3206 }
3207
3208 float WebView::zoomMultiplier(bool isTextOnly)
3209 {
3210     if (isTextOnly != m_zoomsTextOnly)
3211         return 1.0f;
3212     return m_zoomMultiplier;
3213 }
3214
3215 HRESULT STDMETHODCALLTYPE WebView::setApplicationNameForUserAgent( 
3216     /* [in] */ BSTR applicationName)
3217 {
3218     m_applicationName = toString(applicationName);
3219     m_userAgentStandard = String();
3220     return S_OK;
3221 }
3222
3223 HRESULT STDMETHODCALLTYPE WebView::applicationNameForUserAgent( 
3224     /* [retval][out] */ BSTR* applicationName)
3225 {
3226     *applicationName = BString(m_applicationName).release();
3227     if (!*applicationName && m_applicationName.length())
3228         return E_OUTOFMEMORY;
3229     return S_OK;
3230 }
3231
3232 HRESULT STDMETHODCALLTYPE WebView::setCustomUserAgent( 
3233     /* [in] */ BSTR userAgentString)
3234 {
3235     m_userAgentOverridden = userAgentString;
3236     m_userAgentCustom = toString(userAgentString);
3237     return S_OK;
3238 }
3239
3240 HRESULT STDMETHODCALLTYPE WebView::customUserAgent( 
3241     /* [retval][out] */ BSTR* userAgentString)
3242 {
3243     *userAgentString = 0;
3244     if (!m_userAgentOverridden)
3245         return S_OK;
3246     *userAgentString = BString(m_userAgentCustom).release();
3247     if (!*userAgentString && m_userAgentCustom.length())
3248         return E_OUTOFMEMORY;
3249     return S_OK;
3250 }
3251
3252 HRESULT STDMETHODCALLTYPE WebView::userAgentForURL( 
3253     /* [in] */ BSTR url,
3254     /* [retval][out] */ BSTR* userAgent)
3255 {
3256     String userAgentString = userAgentForKURL(MarshallingHelpers::BSTRToKURL(url));
3257     *userAgent = BString(userAgentString).release();
3258     if (!*userAgent && userAgentString.length())
3259         return E_OUTOFMEMORY;
3260     return S_OK;
3261 }
3262
3263 HRESULT STDMETHODCALLTYPE WebView::supportsTextEncoding( 
3264     /* [retval][out] */ BOOL* supports)
3265 {
3266     *supports = TRUE;
3267     return S_OK;
3268 }
3269
3270 HRESULT STDMETHODCALLTYPE WebView::setCustomTextEncodingName( 
3271     /* [in] */ BSTR encodingName)
3272 {
3273     if (!m_mainFrame)
3274         return E_FAIL;
3275
3276     HRESULT hr;
3277     BString oldEncoding;
3278     hr = customTextEncodingName(&oldEncoding);
3279     if (FAILED(hr))
3280         return hr;
3281
3282     if (oldEncoding != encodingName && (!oldEncoding || !encodingName || wcscmp(oldEncoding, encodingName))) {
3283         if (Frame* coreFrame = core(m_mainFrame))
3284             coreFrame->loader().reloadWithOverrideEncoding(toString(encodingName));
3285     }
3286
3287     return S_OK;
3288 }
3289
3290 HRESULT STDMETHODCALLTYPE WebView::customTextEncodingName( 
3291     /* [retval][out] */ BSTR* encodingName)
3292 {
3293     HRESULT hr = S_OK;
3294     COMPtr<IWebDataSource> dataSource;
3295     COMPtr<WebDataSource> dataSourceImpl;
3296     *encodingName = 0;
3297
3298     if (!m_mainFrame)
3299         return E_FAIL;
3300
3301     if (FAILED(m_mainFrame->provisionalDataSource(&dataSource)) || !dataSource) {
3302         hr = m_mainFrame->dataSource(&dataSource);
3303         if (FAILED(hr) || !dataSource)
3304             return hr;
3305     }
3306
3307     hr = dataSource->QueryInterface(IID_WebDataSource, (void**)&dataSourceImpl);
3308     if (FAILED(hr))
3309         return hr;
3310
3311     BString str = dataSourceImpl->documentLoader()->overrideEncoding();
3312     if (FAILED(hr))
3313         return hr;
3314
3315     if (!*encodingName)
3316         *encodingName = BString(m_overrideEncoding).release();
3317
3318     if (!*encodingName && m_overrideEncoding.length())
3319         return E_OUTOFMEMORY;
3320
3321     return S_OK;
3322 }
3323
3324 HRESULT STDMETHODCALLTYPE WebView::setMediaStyle( 
3325     /* [in] */ BSTR /*media*/)
3326 {
3327     ASSERT_NOT_REACHED();
3328     return E_NOTIMPL;
3329 }
3330
3331 HRESULT STDMETHODCALLTYPE WebView::mediaStyle( 
3332     /* [retval][out] */ BSTR* /*media*/)
3333 {
3334     ASSERT_NOT_REACHED();
3335     return E_NOTIMPL;
3336 }
3337
3338 HRESULT STDMETHODCALLTYPE WebView::stringByEvaluatingJavaScriptFromString( 
3339     /* [in] */ BSTR script, // assumes input does not have "JavaScript" at the begining.
3340     /* [retval][out] */ BSTR* result)
3341 {
3342     if (!result) {
3343         ASSERT_NOT_REACHED();
3344         return E_POINTER;
3345     }
3346
3347     *result = 0;
3348
3349     Frame* coreFrame = core(m_mainFrame);
3350     if (!coreFrame)
3351         return E_FAIL;
3352
3353     JSC::JSValue scriptExecutionResult = coreFrame->script().executeScript(WTF::String(script), true).jsValue();
3354     if (!scriptExecutionResult)
3355         return E_FAIL;
3356     else if (scriptExecutionResult.isString()) {
3357         JSC::ExecState* exec = coreFrame->script().globalObject(mainThreadNormalWorld())->globalExec();
3358         JSC::JSLockHolder lock(exec);
3359         *result = BString(scriptExecutionResult.getString(exec));
3360     }
3361
3362     return S_OK;
3363 }
3364
3365 HRESULT STDMETHODCALLTYPE WebView::windowScriptObject( 
3366     /* [retval][out] */ IWebScriptObject** /*webScriptObject*/)
3367 {
3368     ASSERT_NOT_REACHED();
3369     return E_NOTIMPL;
3370 }
3371
3372 HRESULT STDMETHODCALLTYPE WebView::setPreferences( 
3373     /* [in] */ IWebPreferences* prefs)
3374 {
3375     if (!prefs)
3376         prefs = WebPreferences::sharedStandardPreferences();
3377
3378     if (m_preferences == prefs)
3379         return S_OK;
3380
3381     COMPtr<WebPreferences> webPrefs(Query, prefs);
3382     if (!webPrefs)
3383         return E_NOINTERFACE;
3384     webPrefs->willAddToWebView();
3385
3386     COMPtr<WebPreferences> oldPrefs = m_preferences;
3387
3388     IWebNotificationCenter* nc = WebNotificationCenter::defaultCenterInternal();
3389     nc->removeObserver(this, WebPreferences::webPreferencesChangedNotification(), static_cast<IWebPreferences*>(m_preferences.get()));
3390
3391     BString identifier;
3392     oldPrefs->identifier(&identifier);
3393     oldPrefs->didRemoveFromWebView();
3394     oldPrefs = 0; // Make sure we release the reference, since WebPreferences::removeReferenceForIdentifier will check for last reference to WebPreferences
3395
3396     m_preferences = webPrefs;
3397
3398     if (identifier)
3399         WebPreferences::removeReferenceForIdentifier(identifier);
3400
3401     nc->addObserver(this, WebPreferences::webPreferencesChangedNotification(), static_cast<IWebPreferences*>(m_preferences.get()));
3402
3403     m_preferences->postPreferencesChangesNotification();
3404
3405     return S_OK;
3406 }
3407
3408 HRESULT STDMETHODCALLTYPE WebView::preferences( 
3409     /* [retval][out] */ IWebPreferences** prefs)
3410 {
3411     if (!prefs)
3412         return E_POINTER;
3413     *prefs = m_preferences.get();
3414     if (m_preferences)
3415         m_preferences->AddRef();
3416     return S_OK;
3417 }
3418
3419 HRESULT STDMETHODCALLTYPE WebView::setPreferencesIdentifier( 
3420     /* [in] */ BSTR /*anIdentifier*/)
3421 {
3422     ASSERT_NOT_REACHED();
3423     return E_NOTIMPL;
3424 }
3425
3426 HRESULT STDMETHODCALLTYPE WebView::preferencesIdentifier( 
3427     /* [retval][out] */ BSTR* /*anIdentifier*/)
3428 {
3429     ASSERT_NOT_REACHED();
3430     return E_NOTIMPL;
3431 }
3432
3433 static void systemParameterChanged(WPARAM parameter)
3434 {
3435 #if USE(CG)
3436     if (parameter == SPI_SETFONTSMOOTHING || parameter == SPI_SETFONTSMOOTHINGTYPE || parameter == SPI_SETFONTSMOOTHINGCONTRAST || parameter == SPI_SETFONTSMOOTHINGORIENTATION)
3437         wkSystemFontSmoothingChanged();
3438 #endif
3439 }
3440
3441 void WebView::windowReceivedMessage(HWND, UINT message, WPARAM wParam, LPARAM)
3442 {
3443     switch (message) {
3444     case WM_NCACTIVATE:
3445         updateActiveStateSoon();
3446         if (!wParam)
3447             deleteBackingStoreSoon();
3448         break;
3449     case WM_SETTINGCHANGE:
3450         systemParameterChanged(wParam);
3451         break;
3452     }
3453 }
3454
3455 void WebView::updateActiveStateSoon() const
3456 {
3457     // This function is called while processing the WM_NCACTIVATE message.
3458     // While processing WM_NCACTIVATE when we are being deactivated, GetActiveWindow() will
3459     // still return our window. If we were to call updateActiveState() in that case, we would
3460     // wrongly think that we are still the active window. To work around this, we update our
3461     // active state after a 0-delay timer fires, at which point GetActiveWindow() will return
3462     // the newly-activated window.
3463
3464     SetTimer(m_viewWindow, UpdateActiveStateTimer, 0, 0);
3465 }
3466
3467 void WebView::deleteBackingStoreSoon()
3468 {
3469     if (pendingDeleteBackingStoreSet().size() > 2) {
3470         Vector<WebView*> views;
3471         HashSet<WebView*>::iterator end = pendingDeleteBackingStoreSet().end();
3472         for (HashSet<WebView*>::iterator it = pendingDeleteBackingStoreSet().begin(); it != end; ++it)
3473             views.append(*it);
3474         for (int i = 0; i < views.size(); ++i)
3475             views[i]->deleteBackingStore();
3476         ASSERT(pendingDeleteBackingStoreSet().isEmpty());
3477     }
3478
3479     pendingDeleteBackingStoreSet().add(this);
3480     m_deleteBackingStoreTimerActive = true;
3481     SetTimer(m_viewWindow, DeleteBackingStoreTimer, delayBeforeDeletingBackingStoreMsec, 0);
3482 }
3483
3484 void WebView::cancelDeleteBackingStoreSoon()
3485 {
3486     if (!m_deleteBackingStoreTimerActive)
3487         return;
3488     pendingDeleteBackingStoreSet().remove(this);
3489     m_deleteBackingStoreTimerActive = false;
3490     KillTimer(m_viewWindow, DeleteBackingStoreTimer);
3491 }
3492
3493 HRESULT WebView::setHostWindow(/* [in] */ HWND window)
3494 {
3495     if (m_viewWindow) {
3496         if (window)
3497             SetParent(m_viewWindow, window);
3498         else if (!isBeingDestroyed()) {
3499             // Turn the WebView into a message-only window so it will no longer be a child of the
3500             // old host window and will be hidden from screen. We only do this when
3501             // isBeingDestroyed() is false because doing this while handling WM_DESTROY can leave
3502             // m_viewWindow in a weird state (see <http://webkit.org/b/29337>).
3503             SetParent(m_viewWindow, HWND_MESSAGE);
3504         }
3505     }
3506
3507     m_hostWindow = window;
3508
3509     windowAncestryDidChange();
3510
3511     return S_OK;
3512 }
3513
3514 HRESULT WebView::hostWindow(/* [retval][out] */ HWND* window)
3515 {
3516     *window = m_hostWindow;
3517     return S_OK;
3518 }
3519
3520
3521 static Frame *incrementFrame(Frame *curr, bool forward, bool wrapFlag)
3522 {
3523     return forward
3524         ? curr->tree().traverseNextWithWrap(wrapFlag)
3525         : curr->tree().traversePreviousWithWrap(wrapFlag);
3526 }
3527
3528 HRESULT STDMETHODCALLTYPE WebView::searchFor( 
3529     /* [in] */ BSTR str,
3530     /* [in] */ BOOL forward,
3531     /* [in] */ BOOL caseFlag,
3532     /* [in] */ BOOL wrapFlag,
3533     /* [retval][out] */ BOOL* found)
3534 {
3535     if (!found)
3536         return E_INVALIDARG;
3537     
3538     if (!m_page)
3539         return E_UNEXPECTED;
3540
3541     if (!str || !SysStringLen(str))
3542         return E_INVALIDARG;
3543
3544     FindOptions options = (caseFlag ? 0 : CaseInsensitive) | (forward ? 0 : Backwards) | (wrapFlag ? WrapAround : 0);
3545     *found = m_page->findString(toString(str), options);
3546     return S_OK;
3547 }
3548
3549 bool WebView::active()
3550 {
3551     HWND activeWindow = GetActiveWindow();
3552     if (usesLayeredWindow() && activeWindow == m_viewWindow)
3553         return true;
3554
3555     return (activeWindow && m_topLevelParent == findTopLevelParent(activeWindow));
3556 }
3557
3558 void WebView::updateActiveState()
3559 {
3560     m_page->focusController().setActive(active());
3561 }
3562
3563 HRESULT STDMETHODCALLTYPE WebView::updateFocusedAndActiveState()
3564 {
3565     updateActiveState();
3566
3567     bool active = m_page->focusController().isActive();
3568     Frame& mainFrame = m_page->mainFrame();
3569     Frame& focusedFrame = m_page->focusController().focusedOrMainFrame();
3570     mainFrame.selection().setFocused(active && &mainFrame == &focusedFrame);
3571
3572     return S_OK;
3573 }
3574
3575 HRESULT STDMETHODCALLTYPE WebView::executeCoreCommandByName(BSTR name, BSTR value)
3576 {
3577     m_page->focusController().focusedOrMainFrame().editor().command(toString(name)).execute(toString(value));
3578
3579     return S_OK;
3580 }
3581
3582 HRESULT STDMETHODCALLTYPE WebView::clearMainFrameName()
3583 {
3584     m_page->mainFrame().tree().clearName();
3585
3586     return S_OK;
3587 }
3588
3589 HRESULT STDMETHODCALLTYPE WebView::markAllMatchesForText(
3590     BSTR str, BOOL caseSensitive, BOOL highlight, UINT limit, UINT* matches)
3591 {
3592     if (!matches)
3593         return E_INVALIDARG;
3594
3595     if (!m_page)
3596         return E_UNEXPECTED;
3597
3598     if (!str || !SysStringLen(str))
3599         return E_INVALIDARG;
3600
3601     *matches = m_page->markAllMatchesForText(toString(str), caseSensitive ? TextCaseSensitive : TextCaseInsensitive, highlight, limit);
3602     return S_OK;
3603 }
3604
3605 HRESULT STDMETHODCALLTYPE WebView::unmarkAllTextMatches()
3606 {
3607     if (!m_page)
3608         return E_UNEXPECTED;
3609
3610     m_page->unmarkAllTextMatches();
3611     return S_OK;
3612 }
3613
3614 HRESULT STDMETHODCALLTYPE WebView::rectsForTextMatches(
3615     IEnumTextMatches** pmatches)
3616 {
3617     Vector<IntRect> allRects;
3618     WebCore::Frame* frame = &m_page->mainFrame();
<