diff options
| author | Allan Sandfeld Jensen <allan.jensen@digia.com> | 2013-09-13 12:51:20 +0200 |
|---|---|---|
| committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-09-19 20:50:05 +0200 |
| commit | d441d6f39bb846989d95bcf5caf387b42414718d (patch) | |
| tree | e367e64a75991c554930278175d403c072de6bb8 /Source/WebKit2/UIProcess/win/WebView.cpp | |
| parent | 0060b2994c07842f4c59de64b5e3e430525c4b90 (diff) | |
| download | qtwebkit-d441d6f39bb846989d95bcf5caf387b42414718d.tar.gz | |
Import Qt5x2 branch of QtWebkit for Qt 5.2
Importing a new snapshot of webkit.
Change-Id: I2d01ad12cdc8af8cb015387641120a9d7ea5f10c
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@digia.com>
Diffstat (limited to 'Source/WebKit2/UIProcess/win/WebView.cpp')
| -rw-r--r-- | Source/WebKit2/UIProcess/win/WebView.cpp | 1810 |
1 files changed, 0 insertions, 1810 deletions
diff --git a/Source/WebKit2/UIProcess/win/WebView.cpp b/Source/WebKit2/UIProcess/win/WebView.cpp deleted file mode 100644 index 70b875bb6..000000000 --- a/Source/WebKit2/UIProcess/win/WebView.cpp +++ /dev/null @@ -1,1810 +0,0 @@ -/* - * Copyright (C) 2010 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "WebView.h" - -#include "DrawingAreaProxyImpl.h" -#include "FindIndicator.h" -#include "Logging.h" -#include "NativeWebKeyboardEvent.h" -#include "NativeWebMouseEvent.h" -#include "NativeWebWheelEvent.h" -#include "WKAPICast.h" -#include "WebContext.h" -#include "WebContextMenuProxyWin.h" -#include "WebEditCommandProxy.h" -#include "WebEventFactory.h" -#include "WebPageProxy.h" -#include "WebPopupMenuProxyWin.h" -#include <Commctrl.h> -#include <WebCore/BitmapInfo.h> -#include <WebCore/Cursor.h> -#include <WebCore/DragSession.h> -#include <WebCore/Editor.h> -#include <WebCore/FileSystem.h> -#include <WebCore/FloatRect.h> -#include <WebCore/HWndDC.h> -#include <WebCore/IntRect.h> -#include <WebCore/NotImplemented.h> -#include <WebCore/Region.h> -#include <WebCore/RunLoop.h> -#include <WebCore/SoftLinking.h> -#include <WebCore/WebCoreInstanceHandle.h> -#include <WebCore/WindowMessageBroadcaster.h> -#include <WebCore/WindowsTouch.h> -#include <wtf/text/StringBuilder.h> -#include <wtf/text/WTFString.h> - -#if USE(CG) -#include "WKCACFViewWindow.h" -#include <WebCore/GraphicsContextCG.h> -#endif - -#if ENABLE(FULLSCREEN_API) -#include "WebFullScreenManagerProxy.h" -#include <WebCore/FullScreenController.h> -#endif - -namespace Ime { -// We need these functions in a separate namespace, because in the global namespace they conflict -// with the definitions in imm.h only by the type modifier (the macro defines them as static) and -// imm.h is included by windows.h -SOFT_LINK_LIBRARY(IMM32) -SOFT_LINK(IMM32, ImmGetContext, HIMC, WINAPI, (HWND hwnd), (hwnd)) -SOFT_LINK(IMM32, ImmReleaseContext, BOOL, WINAPI, (HWND hWnd, HIMC hIMC), (hWnd, hIMC)) -SOFT_LINK(IMM32, ImmGetCompositionStringW, LONG, WINAPI, (HIMC hIMC, DWORD dwIndex, LPVOID lpBuf, DWORD dwBufLen), (hIMC, dwIndex, lpBuf, dwBufLen)) -SOFT_LINK(IMM32, ImmSetCandidateWindow, BOOL, WINAPI, (HIMC hIMC, LPCANDIDATEFORM lpCandidate), (hIMC, lpCandidate)) -SOFT_LINK(IMM32, ImmSetOpenStatus, BOOL, WINAPI, (HIMC hIMC, BOOL fOpen), (hIMC, fOpen)) -SOFT_LINK(IMM32, ImmNotifyIME, BOOL, WINAPI, (HIMC hIMC, DWORD dwAction, DWORD dwIndex, DWORD dwValue), (hIMC, dwAction, dwIndex, dwValue)) -SOFT_LINK(IMM32, ImmAssociateContextEx, BOOL, WINAPI, (HWND hWnd, HIMC hIMC, DWORD dwFlags), (hWnd, hIMC, dwFlags)) -}; - -// Soft link functions for gestures and panning. -SOFT_LINK_LIBRARY(USER32); -SOFT_LINK_OPTIONAL(USER32, GetGestureInfo, BOOL, WINAPI, (HGESTUREINFO, PGESTUREINFO)); -SOFT_LINK_OPTIONAL(USER32, SetGestureConfig, BOOL, WINAPI, (HWND, DWORD, UINT, PGESTURECONFIG, UINT)); -SOFT_LINK_OPTIONAL(USER32, CloseGestureInfoHandle, BOOL, WINAPI, (HGESTUREINFO)); - -SOFT_LINK_LIBRARY(Uxtheme); -SOFT_LINK_OPTIONAL(Uxtheme, BeginPanningFeedback, BOOL, WINAPI, (HWND)); -SOFT_LINK_OPTIONAL(Uxtheme, EndPanningFeedback, BOOL, WINAPI, (HWND, BOOL)); -SOFT_LINK_OPTIONAL(Uxtheme, UpdatePanningFeedback, BOOL, WINAPI, (HWND, LONG, LONG, BOOL)); - -using namespace WebCore; - -namespace WebKit { - -static const LPCWSTR kWebKit2WebViewWindowClassName = L"WebKit2WebViewWindowClass"; - -// Constants not available on all platforms. -const int WM_XP_THEMECHANGED = 0x031A; -const int WM_VISTA_MOUSEHWHEEL = 0x020E; - -static const int kMaxToolTipWidth = 250; - -enum { - UpdateActiveStateTimer = 1, -}; - -LRESULT CALLBACK WebView::WebViewWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - LONG_PTR longPtr = ::GetWindowLongPtr(hWnd, 0); - - if (WebView* webView = reinterpret_cast<WebView*>(longPtr)) - return webView->wndProc(hWnd, message, wParam, lParam); - - if (message == WM_CREATE) { - LPCREATESTRUCT createStruct = reinterpret_cast<LPCREATESTRUCT>(lParam); - - // Associate the WebView with the window. - ::SetWindowLongPtr(hWnd, 0, (LONG_PTR)createStruct->lpCreateParams); - return 0; - } - - return ::DefWindowProc(hWnd, message, wParam, lParam); -} - -LRESULT WebView::wndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - LRESULT lResult = 0; - bool handled = true; - - switch (message) { - case WM_CLOSE: - m_page->tryClose(); - break; - case WM_DESTROY: - m_isBeingDestroyed = true; - close(); - break; - case WM_ERASEBKGND: - lResult = 1; - break; - case WM_PAINT: - lResult = onPaintEvent(hWnd, message, wParam, lParam, handled); - break; - case WM_PRINTCLIENT: - lResult = onPrintClientEvent(hWnd, message, wParam, lParam, handled); - break; - case WM_MOUSEACTIVATE: - setWasActivatedByMouseEvent(true); - handled = false; - break; - case WM_MOUSEMOVE: - case WM_LBUTTONDOWN: - case WM_MBUTTONDOWN: - case WM_RBUTTONDOWN: - case WM_LBUTTONDBLCLK: - case WM_MBUTTONDBLCLK: - case WM_RBUTTONDBLCLK: - case WM_LBUTTONUP: - case WM_MBUTTONUP: - case WM_RBUTTONUP: - case WM_MOUSELEAVE: - lResult = onMouseEvent(hWnd, message, wParam, lParam, handled); - break; - case WM_MOUSEWHEEL: - case WM_VISTA_MOUSEHWHEEL: - lResult = onWheelEvent(hWnd, message, wParam, lParam, handled); - break; - case WM_HSCROLL: - lResult = onHorizontalScroll(hWnd, message, wParam, lParam, handled); - break; - case WM_VSCROLL: - lResult = onVerticalScroll(hWnd, message, wParam, lParam, handled); - break; - case WM_GESTURENOTIFY: - lResult = onGestureNotify(hWnd, message, wParam, lParam, handled); - break; - case WM_GESTURE: - lResult = onGesture(hWnd, message, wParam, lParam, handled); - break; - case WM_SYSKEYDOWN: - case WM_KEYDOWN: - case WM_SYSCHAR: - case WM_CHAR: - case WM_SYSKEYUP: - case WM_KEYUP: - lResult = onKeyEvent(hWnd, message, wParam, lParam, handled); - break; - case WM_SIZE: - lResult = onSizeEvent(hWnd, message, wParam, lParam, handled); - break; - case WM_WINDOWPOSCHANGED: - lResult = onWindowPositionChangedEvent(hWnd, message, wParam, lParam, handled); - break; - case WM_SETFOCUS: - lResult = onSetFocusEvent(hWnd, message, wParam, lParam, handled); - break; - case WM_KILLFOCUS: - lResult = onKillFocusEvent(hWnd, message, wParam, lParam, handled); - break; - case WM_TIMER: - lResult = onTimerEvent(hWnd, message, wParam, lParam, handled); - break; - case WM_SHOWWINDOW: - lResult = onShowWindowEvent(hWnd, message, wParam, lParam, handled); - break; - case WM_SETCURSOR: - lResult = onSetCursor(hWnd, message, wParam, lParam, handled); - break; - case WM_IME_STARTCOMPOSITION: - handled = onIMEStartComposition(); - break; - case WM_IME_REQUEST: - lResult = onIMERequest(wParam, lParam); - break; - case WM_IME_COMPOSITION: - handled = onIMEComposition(lParam); - break; - case WM_IME_ENDCOMPOSITION: - handled = onIMEEndComposition(); - break; - case WM_IME_SELECT: - handled = onIMESelect(wParam, lParam); - break; - case WM_IME_SETCONTEXT: - handled = onIMESetContext(wParam, lParam); - break; - default: - handled = false; - break; - } - - if (!handled) - lResult = ::DefWindowProc(hWnd, message, wParam, lParam); - - return lResult; -} - -bool WebView::registerWebViewWindowClass() -{ - static bool haveRegisteredWindowClass = false; - if (haveRegisteredWindowClass) - return true; - haveRegisteredWindowClass = true; - - WNDCLASSEX wcex; - - wcex.cbSize = sizeof(WNDCLASSEX); - wcex.style = CS_DBLCLKS; - wcex.lpfnWndProc = WebView::WebViewWndProc; - wcex.cbClsExtra = 0; - wcex.cbWndExtra = sizeof(WebView*); - wcex.hInstance = instanceHandle(); - wcex.hIcon = 0; - wcex.hCursor = ::LoadCursor(0, IDC_ARROW); - wcex.hbrBackground = 0; - wcex.lpszMenuName = 0; - wcex.lpszClassName = kWebKit2WebViewWindowClassName; - wcex.hIconSm = 0; - - return !!::RegisterClassEx(&wcex); -} - -WebView::WebView(RECT rect, WebContext* context, WebPageGroup* pageGroup, HWND parentWindow) - : m_topLevelParentWindow(0) - , m_toolTipWindow(0) - , m_lastCursorSet(0) - , m_webCoreCursor(0) - , m_overrideCursor(0) - , m_trackingMouseLeave(false) - , m_isInWindow(false) - , m_isVisible(false) - , m_wasActivatedByMouseEvent(false) - , m_isBeingDestroyed(false) - , m_inIMEComposition(0) - , m_findIndicatorCallback(0) - , m_findIndicatorCallbackContext(0) - , m_pageOverlayInstalled(false) - , m_lastPanX(0) - , m_lastPanY(0) - , m_overPanY(0) - , m_gestureReachedScrollingLimit(false) -#if USE(ACCELERATED_COMPOSITING) - , m_layerHostWindow(0) -#endif -{ - registerWebViewWindowClass(); - - m_window = ::CreateWindowExW(0, kWebKit2WebViewWindowClassName, 0, WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN | WS_VISIBLE, - rect.top, rect.left, rect.right - rect.left, rect.bottom - rect.top, parentWindow ? parentWindow : HWND_MESSAGE, 0, instanceHandle(), this); - ASSERT(::IsWindow(m_window)); - // We only check our window style, and not ::IsWindowVisible, because m_isVisible only tracks - // this window's visibility status, while ::IsWindowVisible takes our ancestors' visibility - // status into account. <http://webkit.org/b/54104> - ASSERT(m_isVisible == static_cast<bool>(::GetWindowLong(m_window, GWL_STYLE) & WS_VISIBLE)); - - m_page = context->createWebPage(this, pageGroup); - m_page->initializeWebPage(); - - CoCreateInstance(CLSID_DragDropHelper, 0, CLSCTX_INPROC_SERVER, IID_IDropTargetHelper, (void**)&m_dropTargetHelper); - - // FIXME: Initializing the tooltip window here matches WebKit win, but seems like something - // we could do on demand to save resources. - initializeToolTipWindow(); - - // Initialize the top level parent window and register it with the WindowMessageBroadcaster. - windowAncestryDidChange(); - -#if ENABLE(FULLSCREEN_API) - m_page->fullScreenManager()->setWebView(this); -#endif -} - -WebView::~WebView() -{ - // Tooltip window needs to be explicitly destroyed since it isn't a WS_CHILD. - if (::IsWindow(m_toolTipWindow)) - ::DestroyWindow(m_toolTipWindow); -} - -void WebView::initialize() -{ - ::RegisterDragDrop(m_window, this); - - if (shouldInitializeTrackPointHack()) { - // If we detected a registry key belonging to a TrackPoint driver, then create fake - // scrollbars, so the WebView will receive WM_VSCROLL and WM_HSCROLL messages. - // We create an invisible vertical scrollbar and an invisible horizontal scrollbar to allow - // for receiving both types of messages. - ::CreateWindow(TEXT("SCROLLBAR"), TEXT("FAKETRACKPOINTHSCROLLBAR"), WS_CHILD | WS_VISIBLE | SBS_HORZ, 0, 0, 0, 0, m_window, 0, instanceHandle(), 0); - ::CreateWindow(TEXT("SCROLLBAR"), TEXT("FAKETRACKPOINTVSCROLLBAR"), WS_CHILD | WS_VISIBLE | SBS_VERT, 0, 0, 0, 0, m_window, 0, instanceHandle(), 0); - } -} - -void WebView::initializeUndoClient(const WKViewUndoClient* client) -{ - m_undoClient.initialize(client); -} - -void WebView::setParentWindow(HWND parentWindow) -{ - if (m_window) { - // If the host window hasn't changed, bail. - if (::GetParent(m_window) == parentWindow) - return; - if (parentWindow) - ::SetParent(m_window, parentWindow); - else if (!m_isBeingDestroyed) { - // Turn the WebView into a message-only window so it will no longer be a child of the - // old parent window and will be hidden from screen. We only do this when - // isBeingDestroyed() is false because doing this while handling WM_DESTROY can leave - // m_window in a weird state (see <http://webkit.org/b/29337>). - ::SetParent(m_window, HWND_MESSAGE); - } - } - - windowAncestryDidChange(); -} - -static HWND findTopLevelParentWindow(HWND window) -{ - if (!window) - return 0; - - HWND current = window; - for (HWND parent = GetParent(current); current; current = parent, parent = GetParent(parent)) { - if (!parent || !(GetWindowLongPtr(current, GWL_STYLE) & (WS_POPUP | WS_CHILD))) - return current; - } - ASSERT_NOT_REACHED(); - return 0; -} - -void WebView::windowAncestryDidChange() -{ - HWND newTopLevelParentWindow; - if (m_window) - newTopLevelParentWindow = findTopLevelParentWindow(m_window); - else { - // There's no point in tracking active state changes of our parent window if we don't have - // a window ourselves. - newTopLevelParentWindow = 0; - } - - if (newTopLevelParentWindow == m_topLevelParentWindow) - return; - - if (m_topLevelParentWindow) - WindowMessageBroadcaster::removeListener(m_topLevelParentWindow, this); - - m_topLevelParentWindow = newTopLevelParentWindow; - - if (m_topLevelParentWindow) - WindowMessageBroadcaster::addListener(m_topLevelParentWindow, this); - - updateActiveState(); -} - -LRESULT WebView::onMouseEvent(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, bool& handled) -{ - NativeWebMouseEvent mouseEvent = NativeWebMouseEvent(hWnd, message, wParam, lParam, m_wasActivatedByMouseEvent); - setWasActivatedByMouseEvent(false); - - switch (message) { - case WM_LBUTTONDOWN: - case WM_MBUTTONDOWN: - case WM_RBUTTONDOWN: - ::SetFocus(m_window); - ::SetCapture(m_window); - break; - case WM_LBUTTONUP: - case WM_MBUTTONUP: - case WM_RBUTTONUP: - ::ReleaseCapture(); - break; - case WM_MOUSEMOVE: - startTrackingMouseLeave(); - break; - case WM_MOUSELEAVE: - stopTrackingMouseLeave(); - break; - case WM_LBUTTONDBLCLK: - case WM_MBUTTONDBLCLK: - case WM_RBUTTONDBLCLK: - break; - default: - ASSERT_NOT_REACHED(); - } - - m_page->handleMouseEvent(mouseEvent); - - handled = true; - return 0; -} - -LRESULT WebView::onWheelEvent(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, bool& handled) -{ - NativeWebWheelEvent wheelEvent(hWnd, message, wParam, lParam); - if (wheelEvent.controlKey()) { - // We do not want WebKit to handle Control + Wheel, this should be handled by the client application - // to zoom the page. - handled = false; - return 0; - } - - m_page->handleWheelEvent(wheelEvent); - - handled = true; - return 0; -} - -LRESULT WebView::onHorizontalScroll(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, bool& handled) -{ - ScrollDirection direction; - ScrollGranularity granularity; - switch (LOWORD(wParam)) { - case SB_LINELEFT: - granularity = ScrollByLine; - direction = ScrollLeft; - break; - case SB_LINERIGHT: - granularity = ScrollByLine; - direction = ScrollRight; - break; - case SB_PAGELEFT: - granularity = ScrollByDocument; - direction = ScrollLeft; - break; - case SB_PAGERIGHT: - granularity = ScrollByDocument; - direction = ScrollRight; - break; - default: - handled = false; - return 0; - } - - m_page->scrollBy(direction, granularity); - - handled = true; - return 0; -} - -LRESULT WebView::onVerticalScroll(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, bool& handled) -{ - ScrollDirection direction; - ScrollGranularity granularity; - switch (LOWORD(wParam)) { - case SB_LINEDOWN: - granularity = ScrollByLine; - direction = ScrollDown; - break; - case SB_LINEUP: - granularity = ScrollByLine; - direction = ScrollUp; - break; - case SB_PAGEDOWN: - granularity = ScrollByDocument; - direction = ScrollDown; - break; - case SB_PAGEUP: - granularity = ScrollByDocument; - direction = ScrollUp; - break; - default: - handled = false; - return 0; - } - - m_page->scrollBy(direction, granularity); - - handled = true; - return 0; -} - -LRESULT WebView::onGestureNotify(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, bool& handled) -{ - // We shouldn't be getting any gesture messages without SetGestureConfig soft-linking correctly. - ASSERT(SetGestureConfigPtr()); - - GESTURENOTIFYSTRUCT* gn = reinterpret_cast<GESTURENOTIFYSTRUCT*>(lParam); - - POINT localPoint = { gn->ptsLocation.x, gn->ptsLocation.y }; - ::ScreenToClient(m_window, &localPoint); - - bool canPan = m_page->gestureWillBegin(localPoint); - - DWORD dwPanWant = GC_PAN | GC_PAN_WITH_INERTIA | GC_PAN_WITH_GUTTER; - DWORD dwPanBlock = GC_PAN_WITH_SINGLE_FINGER_HORIZONTALLY; - if (canPan) - dwPanWant |= GC_PAN_WITH_SINGLE_FINGER_VERTICALLY; - else - dwPanBlock |= GC_PAN_WITH_SINGLE_FINGER_VERTICALLY; - - GESTURECONFIG gc = { GID_PAN, dwPanWant, dwPanBlock }; - return SetGestureConfigPtr()(m_window, 0, 1, &gc, sizeof(gc)); -} - -LRESULT WebView::onGesture(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, bool& handled) -{ - ASSERT(GetGestureInfoPtr()); - ASSERT(CloseGestureInfoHandlePtr()); - ASSERT(UpdatePanningFeedbackPtr()); - ASSERT(BeginPanningFeedbackPtr()); - ASSERT(EndPanningFeedbackPtr()); - - if (!GetGestureInfoPtr() || !CloseGestureInfoHandlePtr() || !UpdatePanningFeedbackPtr() || !BeginPanningFeedbackPtr() || !EndPanningFeedbackPtr()) { - handled = false; - return 0; - } - - HGESTUREINFO gestureHandle = reinterpret_cast<HGESTUREINFO>(lParam); - GESTUREINFO gi = {0}; - gi.cbSize = sizeof(GESTUREINFO); - - if (!GetGestureInfoPtr()(gestureHandle, &gi)) { - handled = false; - return 0; - } - - switch (gi.dwID) { - case GID_BEGIN: - m_lastPanX = gi.ptsLocation.x; - m_lastPanY = gi.ptsLocation.y; - break; - case GID_END: - m_page->gestureDidEnd(); - break; - case GID_PAN: { - int currentX = gi.ptsLocation.x; - int currentY = gi.ptsLocation.y; - - // Reverse the calculations because moving your fingers up should move the screen down, and - // vice-versa. - int deltaX = m_lastPanX - currentX; - int deltaY = m_lastPanY - currentY; - - m_lastPanX = currentX; - m_lastPanY = currentY; - - // Calculate the overpan for window bounce. - m_overPanY -= deltaY; - - if (deltaX || deltaY) - m_page->gestureDidScroll(IntSize(deltaX, deltaY)); - - if (gi.dwFlags & GF_BEGIN) { - BeginPanningFeedbackPtr()(m_window); - m_gestureReachedScrollingLimit = false; - m_overPanY = 0; - } else if (gi.dwFlags & GF_END) { - EndPanningFeedbackPtr()(m_window, true); - m_overPanY = 0; - } - - // FIXME: Support horizontal window bounce - <http://webkit.org/b/58068>. - // FIXME: Window Bounce doesn't undo until user releases their finger - <http://webkit.org/b/58069>. - - if (m_gestureReachedScrollingLimit) - UpdatePanningFeedbackPtr()(m_window, 0, m_overPanY, gi.dwFlags & GF_INERTIA); - - CloseGestureInfoHandlePtr()(gestureHandle); - - handled = true; - return 0; - } - default: - break; - } - - // If we get to this point, the gesture has not been handled. We forward - // the call to DefWindowProc by returning false, and we don't need to - // to call CloseGestureInfoHandle. - // http://msdn.microsoft.com/en-us/library/dd353228(VS.85).aspx - handled = false; - return 0; -} - -LRESULT WebView::onKeyEvent(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, bool& handled) -{ -#if ENABLE(FULLSCREEN_API) - // Trap the ESC key when in full screen mode. - if (message == WM_KEYDOWN && wParam == VK_ESCAPE && m_fullScreenController && m_fullScreenController->isFullScreen()) { - m_fullScreenController->exitFullScreen(); - return false; - } -#endif - - m_page->handleKeyboardEvent(NativeWebKeyboardEvent(hWnd, message, wParam, lParam)); - - // We claim here to always have handled the event. If the event is not in fact handled, we will - // find out later in didNotHandleKeyEvent. - handled = true; - return 0; -} - -static void drawPageBackground(HDC dc, const WebPageProxy* page, const RECT& rect) -{ - if (!page->drawsBackground() || page->drawsTransparentBackground()) - return; - - ::FillRect(dc, &rect, reinterpret_cast<HBRUSH>(COLOR_WINDOW + 1)); -} - -void WebView::paint(HDC hdc, const IntRect& dirtyRect) -{ - m_page->endPrinting(); - if (DrawingAreaProxyImpl* drawingArea = static_cast<DrawingAreaProxyImpl*>(m_page->drawingArea())) { - // FIXME: We should port WebKit1's rect coalescing logic here. - Region unpaintedRegion; - drawingArea->paint(hdc, dirtyRect, unpaintedRegion); - - Vector<IntRect> unpaintedRects = unpaintedRegion.rects(); - for (size_t i = 0; i < unpaintedRects.size(); ++i) { - RECT winRect = unpaintedRects[i]; - drawPageBackground(hdc, m_page.get(), unpaintedRects[i]); - } - } else - drawPageBackground(hdc, m_page.get(), dirtyRect); - - m_page->didDraw(); -} - -static void flashRects(HDC dc, const IntRect rects[], size_t rectCount, HBRUSH brush) -{ - for (size_t i = 0; i < rectCount; ++i) { - RECT winRect = rects[i]; - ::FillRect(dc, &winRect, brush); - } - - ::GdiFlush(); - ::Sleep(50); -} - -static OwnPtr<HBRUSH> createBrush(const Color& color) -{ - return adoptPtr(::CreateSolidBrush(RGB(color.red(), color.green(), color.blue()))); -} - -LRESULT WebView::onPaintEvent(HWND hWnd, UINT message, WPARAM, LPARAM, bool& handled) -{ - // Update child windows now so that any areas of our window they reveal will be included in the - // invalid region that ::BeginPaint sees. - updateChildWindowGeometries(); - - PAINTSTRUCT paintStruct; - HDC hdc = ::BeginPaint(m_window, &paintStruct); - - if (WebPageProxy::debugPaintFlags() & kWKDebugFlashViewUpdates) { - static HBRUSH brush = createBrush(WebPageProxy::viewUpdatesFlashColor().rgb()).leakPtr(); - IntRect rect = paintStruct.rcPaint; - flashRects(hdc, &rect, 1, brush); - } - - paint(hdc, paintStruct.rcPaint); - - ::EndPaint(m_window, &paintStruct); - - handled = true; - return 0; -} - -LRESULT WebView::onPrintClientEvent(HWND hWnd, UINT, WPARAM wParam, LPARAM, bool& handled) -{ - HDC hdc = reinterpret_cast<HDC>(wParam); - RECT winRect; - ::GetClientRect(hWnd, &winRect); - - // Twidding the visibility flags tells the DrawingArea to resume painting. Right now, the - // the visible state of the view only affects whether or not painting happens, but in the - // future it could affect more, which we wouldn't want to touch here. - - // FIXME: We should have a better way of telling the WebProcess to draw even if we're - // invisible than twiddling the visibility flag. - - bool wasVisible = isViewVisible(); - if (!wasVisible) - setIsVisible(true); - - paint(hdc, winRect); - - if (!wasVisible) - setIsVisible(false); - - handled = true; - return 0; -} - -LRESULT WebView::onSizeEvent(HWND, UINT, WPARAM, LPARAM lParam, bool& handled) -{ - int width = LOWORD(lParam); - int height = HIWORD(lParam); - - if (m_page && m_page->drawingArea()) { - m_page->drawingArea()->setSize(IntSize(width, height), m_nextResizeScrollOffset); - m_nextResizeScrollOffset = IntSize(); - } - -#if USE(ACCELERATED_COMPOSITING) - if (m_layerHostWindow) - ::MoveWindow(m_layerHostWindow, 0, 0, width, height, FALSE); -#endif - - handled = true; - return 0; -} - -LRESULT WebView::onWindowPositionChangedEvent(HWND, UINT, WPARAM, LPARAM lParam, bool& handled) -{ - if (reinterpret_cast<WINDOWPOS*>(lParam)->flags & SWP_SHOWWINDOW) - updateActiveStateSoon(); - - handled = false; - return 0; -} - -LRESULT WebView::onSetFocusEvent(HWND, UINT, WPARAM, LPARAM lParam, bool& handled) -{ - m_page->viewStateDidChange(WebPageProxy::ViewIsFocused); - handled = true; - return 0; -} - -LRESULT WebView::onKillFocusEvent(HWND, UINT, WPARAM, LPARAM lParam, bool& handled) -{ - m_page->viewStateDidChange(WebPageProxy::ViewIsFocused); - handled = true; - return 0; -} - -LRESULT WebView::onTimerEvent(HWND hWnd, UINT, WPARAM wParam, LPARAM, bool& handled) -{ - switch (wParam) { - case UpdateActiveStateTimer: - ::KillTimer(hWnd, UpdateActiveStateTimer); - updateActiveState(); - break; - } - - handled = true; - return 0; -} - -LRESULT WebView::onShowWindowEvent(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, bool& handled) -{ - // lParam is 0 when the message is sent because of a ShowWindow call. - // FIXME: Since we don't get notified when an ancestor window is hidden or shown, we will keep - // painting even when we have a hidden ancestor. <http://webkit.org/b/54104> - if (!lParam) - setIsVisible(wParam); - - handled = false; - return 0; -} - -LRESULT WebView::onSetCursor(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam, bool& handled) -{ - if (!m_lastCursorSet) { - handled = false; - return 0; - } - - ::SetCursor(m_lastCursorSet); - return 0; -} - -void WebView::updateActiveState() -{ - m_page->viewStateDidChange(WebPageProxy::ViewWindowIsActive); -} - -void WebView::updateActiveStateSoon() -{ - // This function is called while processing the WM_NCACTIVATE message. - // While processing WM_NCACTIVATE when we are being deactivated, GetActiveWindow() will - // still return our window. If we were to call updateActiveState() in that case, we would - // wrongly think that we are still the active window. To work around this, we update our - // active state after a 0-delay timer fires, at which point GetActiveWindow() will return - // the newly-activated window. - - ::SetTimer(m_window, UpdateActiveStateTimer, 0, 0); -} - -static bool initCommonControls() -{ - static bool haveInitialized = false; - if (haveInitialized) - return true; - - INITCOMMONCONTROLSEX init; - init.dwSize = sizeof(init); - init.dwICC = ICC_TREEVIEW_CLASSES; - haveInitialized = !!::InitCommonControlsEx(&init); - return haveInitialized; -} - -void WebView::initializeToolTipWindow() -{ - if (!initCommonControls()) - return; - - m_toolTipWindow = ::CreateWindowEx(WS_EX_TRANSPARENT, TOOLTIPS_CLASS, 0, WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP, - CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, - m_window, 0, 0, 0); - if (!m_toolTipWindow) - return; - - TOOLINFO info = {0}; - info.cbSize = sizeof(info); - info.uFlags = TTF_IDISHWND | TTF_SUBCLASS; - info.uId = reinterpret_cast<UINT_PTR>(m_window); - - ::SendMessage(m_toolTipWindow, TTM_ADDTOOL, 0, reinterpret_cast<LPARAM>(&info)); - ::SendMessage(m_toolTipWindow, TTM_SETMAXTIPWIDTH, 0, kMaxToolTipWidth); - ::SetWindowPos(m_toolTipWindow, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); -} - -void WebView::startTrackingMouseLeave() -{ - if (m_trackingMouseLeave) - return; - m_trackingMouseLeave = true; - - TRACKMOUSEEVENT trackMouseEvent; - trackMouseEvent.cbSize = sizeof(TRACKMOUSEEVENT); - trackMouseEvent.dwFlags = TME_LEAVE; - trackMouseEvent.hwndTrack = m_window; - - ::TrackMouseEvent(&trackMouseEvent); -} - -void WebView::stopTrackingMouseLeave() -{ - if (!m_trackingMouseLeave) - return; - m_trackingMouseLeave = false; - - TRACKMOUSEEVENT trackMouseEvent; - trackMouseEvent.cbSize = sizeof(TRACKMOUSEEVENT); - trackMouseEvent.dwFlags = TME_LEAVE | TME_CANCEL; - trackMouseEvent.hwndTrack = m_window; - - ::TrackMouseEvent(&trackMouseEvent); -} - -bool WebView::shouldInitializeTrackPointHack() -{ - static bool shouldCreateScrollbars; - static bool hasRunTrackPointCheck; - - if (hasRunTrackPointCheck) - return shouldCreateScrollbars; - - hasRunTrackPointCheck = true; - const wchar_t* trackPointKeys[] = { - L"Software\\Lenovo\\TrackPoint", - L"Software\\Lenovo\\UltraNav", - L"Software\\Alps\\Apoint\\TrackPoint", - L"Software\\Synaptics\\SynTPEnh\\UltraNavUSB", - L"Software\\Synaptics\\SynTPEnh\\UltraNavPS2" - }; - - for (size_t i = 0; i < WTF_ARRAY_LENGTH(trackPointKeys); ++i) { - HKEY trackPointKey; - int readKeyResult = ::RegOpenKeyExW(HKEY_CURRENT_USER, trackPointKeys[i], 0, KEY_READ, &trackPointKey); - ::RegCloseKey(trackPointKey); - if (readKeyResult == ERROR_SUCCESS) { - shouldCreateScrollbars = true; - return shouldCreateScrollbars; - } - } - - return shouldCreateScrollbars; -} - -void WebView::close() -{ - m_undoClient.initialize(0); - ::RevokeDragDrop(m_window); - if (m_window) { - // We can't check IsWindow(m_window) here, because that will return true even while - // we're already handling WM_DESTROY. So we check !m_isBeingDestroyed instead. - if (!m_isBeingDestroyed) - DestroyWindow(m_window); - // Either we just destroyed m_window, or it's in the process of being destroyed. Either - // way, we clear it out to make sure we don't try to use it later. - m_window = 0; - } - setParentWindow(0); - m_page->close(); -} - -// PageClient - -PassOwnPtr<DrawingAreaProxy> WebView::createDrawingAreaProxy() -{ - return DrawingAreaProxyImpl::create(m_page.get()); -} - -void WebView::setViewNeedsDisplay(const WebCore::IntRect& rect) -{ - RECT r = rect; - ::InvalidateRect(m_window, &r, false); -} - -void WebView::displayView() -{ - ::UpdateWindow(m_window); -} - -void WebView::scrollView(const IntRect& scrollRect, const IntSize& scrollOffset) -{ - // FIXME: Actually scroll the view contents. - setViewNeedsDisplay(scrollRect); -} - -void WebView::flashBackingStoreUpdates(const Vector<IntRect>& updateRects) -{ - static HBRUSH brush = createBrush(WebPageProxy::backingStoreUpdatesFlashColor().rgb()).leakPtr(); - HWndDC dc(m_window); - flashRects(dc, updateRects.data(), updateRects.size(), brush); -} - -WebCore::IntSize WebView::viewSize() -{ - RECT clientRect; - GetClientRect(m_window, &clientRect); - - return IntRect(clientRect).size(); -} - -bool WebView::isViewWindowActive() -{ - HWND activeWindow = ::GetActiveWindow(); - return (activeWindow && m_topLevelParentWindow == findTopLevelParentWindow(activeWindow)); -} - -bool WebView::isViewFocused() -{ - return ::GetFocus() == m_window; -} - -bool WebView::isViewVisible() -{ - return m_isVisible; -} - -bool WebView::isViewInWindow() -{ - return m_isInWindow; -} - -void WebView::pageClosed() -{ -} - -void WebView::processDidCrash() -{ - updateNativeCursor(); - ::InvalidateRect(m_window, 0, TRUE); -} - -void WebView::didRelaunchProcess() -{ - updateNativeCursor(); - ::InvalidateRect(m_window, 0, TRUE); -} - -void WebView::toolTipChanged(const String&, const String& newToolTip) -{ - if (!m_toolTipWindow) - return; - - if (!newToolTip.isEmpty()) { - // This is necessary because String::charactersWithNullTermination() is not const. - String toolTip = newToolTip; - - TOOLINFO info = {0}; - info.cbSize = sizeof(info); - info.uFlags = TTF_IDISHWND; - info.uId = reinterpret_cast<UINT_PTR>(m_window); - info.lpszText = const_cast<UChar*>(toolTip.charactersWithNullTermination()); - ::SendMessage(m_toolTipWindow, TTM_UPDATETIPTEXT, 0, reinterpret_cast<LPARAM>(&info)); - } - - ::SendMessage(m_toolTipWindow, TTM_ACTIVATE, !newToolTip.isEmpty(), 0); -} - -HCURSOR WebView::cursorToShow() const -{ - if (!m_page->isValid()) - return 0; - - // We only show the override cursor if the default (arrow) cursor is showing. - static HCURSOR arrowCursor = ::LoadCursor(0, IDC_ARROW); - if (m_overrideCursor && m_webCoreCursor == arrowCursor) - return m_overrideCursor; - - return m_webCoreCursor; -} - -void WebView::updateNativeCursor() -{ - m_lastCursorSet = cursorToShow(); - if (!m_lastCursorSet) - return; - ::SetCursor(m_lastCursorSet); -} - -void WebView::setCursor(const WebCore::Cursor& cursor) -{ - if (!cursor.platformCursor()->nativeCursor()) - return; - m_webCoreCursor = cursor.platformCursor()->nativeCursor(); - updateNativeCursor(); -} - -void WebView::setCursorHiddenUntilMouseMoves(bool) -{ - notImplemented(); -} - -void WebView::setOverrideCursor(HCURSOR overrideCursor) -{ - m_overrideCursor = overrideCursor; - updateNativeCursor(); -} - -void WebView::setInitialFocus(bool forward, bool isKeyboardEventValid, const WebKeyboardEvent& event) -{ - m_page->setInitialFocus(forward, isKeyboardEventValid, event); -} - -void WebView::setScrollOffsetOnNextResize(const IntSize& scrollOffset) -{ - // The next time we get a WM_SIZE message, scroll by the specified amount in onSizeEvent(). - m_nextResizeScrollOffset = scrollOffset; -} - -void WebView::didChangeViewportProperties(const WebCore::ViewportAttributes&) -{ -} - -void WebView::registerEditCommand(PassRefPtr<WebEditCommandProxy> prpCommand, WebPageProxy::UndoOrRedo undoOrRedo) -{ - RefPtr<WebEditCommandProxy> command = prpCommand; - m_undoClient.registerEditCommand(this, command, undoOrRedo); -} - -void WebView::clearAllEditCommands() -{ - m_undoClient.clearAllEditCommands(this); -} - -bool WebView::canUndoRedo(WebPageProxy::UndoOrRedo undoOrRedo) -{ - return m_undoClient.canUndoRedo(this, undoOrRedo); -} - -void WebView::executeUndoRedo(WebPageProxy::UndoOrRedo undoOrRedo) -{ - m_undoClient.executeUndoRedo(this, undoOrRedo); -} - -void WebView::reapplyEditCommand(WebEditCommandProxy* command) -{ - if (!m_page->isValid() || !m_page->isValidEditCommand(command)) - return; - - command->reapply(); -} - -void WebView::unapplyEditCommand(WebEditCommandProxy* command) -{ - if (!m_page->isValid() || !m_page->isValidEditCommand(command)) - return; - - command->unapply(); -} - -void WebView::setCustomDropTarget(IDropTarget* dropTarget) -{ - if (!m_page->isValid() || !m_window) - return; - - ::RevokeDragDrop(m_window); - - if (dropTarget) - ::RegisterDragDrop(m_window, dropTarget); - else - ::RegisterDragDrop(m_window, this); -} - -FloatRect WebView::convertToDeviceSpace(const FloatRect& rect) -{ - return rect; -} - -IntPoint WebView::screenToWindow(const IntPoint& point) -{ - return point; -} - -IntRect WebView::windowToScreen(const IntRect& rect) -{ - return rect; -} - -FloatRect WebView::convertToUserSpace(const FloatRect& rect) -{ - return rect; -} - -HIMC WebView::getIMMContext() -{ - return Ime::ImmGetContext(m_window); -} - -void WebView::prepareCandidateWindow(HIMC hInputContext) -{ - IntRect caret = m_page->firstRectForCharacterInSelectedRange(0); - CANDIDATEFORM form; - form.dwIndex = 0; - form.dwStyle = CFS_EXCLUDE; - form.ptCurrentPos.x = caret.x(); - form.ptCurrentPos.y = caret.maxY(); - form.rcArea.top = caret.y(); - form.rcArea.bottom = caret.maxY(); - form.rcArea.left = caret.x(); - form.rcArea.right = caret.maxX(); - Ime::ImmSetCandidateWindow(hInputContext, &form); -} - -void WebView::resetIME() -{ - HIMC hInputContext = getIMMContext(); - if (!hInputContext) - return; - Ime::ImmNotifyIME(hInputContext, NI_COMPOSITIONSTR, CPS_CANCEL, 0); - Ime::ImmReleaseContext(m_window, hInputContext); -} - -void WebView::setInputMethodState(bool enabled) -{ - Ime::ImmAssociateContextEx(m_window, 0, enabled ? IACE_DEFAULT : 0); -} - -void WebView::compositionSelectionChanged(bool hasChanged) -{ - if (m_page->editorState().hasComposition && !hasChanged) - resetIME(); -} - -bool WebView::onIMEStartComposition() -{ - LOG(TextInput, "onIMEStartComposition"); - m_inIMEComposition++; - - HIMC hInputContext = getIMMContext(); - if (!hInputContext) - return false; - prepareCandidateWindow(hInputContext); - Ime::ImmReleaseContext(m_window, hInputContext); - return true; -} - -static bool getCompositionString(HIMC hInputContext, DWORD type, String& result) -{ - LONG compositionLength = Ime::ImmGetCompositionStringW(hInputContext, type, 0, 0); - if (compositionLength <= 0) - return false; - Vector<UChar> compositionBuffer(compositionLength / 2); - compositionLength = Ime::ImmGetCompositionStringW(hInputContext, type, compositionBuffer.data(), compositionLength); - result = String::adopt(compositionBuffer); - return true; -} - -static void compositionToUnderlines(const Vector<DWORD>& clauses, const Vector<BYTE>& attributes, Vector<CompositionUnderline>& underlines) -{ - if (clauses.isEmpty()) { - underlines.clear(); - return; - } - - size_t numBoundaries = clauses.size() - 1; - underlines.resize(numBoundaries); - for (unsigned i = 0; i < numBoundaries; ++i) { - underlines[i].startOffset = clauses[i]; - underlines[i].endOffset = clauses[i + 1]; - BYTE attribute = attributes[clauses[i]]; - underlines[i].thick = attribute == ATTR_TARGET_CONVERTED || attribute == ATTR_TARGET_NOTCONVERTED; - underlines[i].color = Color::black; - } -} - -#if !LOG_DISABLED -#define APPEND_ARGUMENT_NAME(name) \ - if (lparam & name) { \ - if (needsComma) \ - result.appendLiteral(", "); \ - result.appendLiteral(#name); \ - needsComma = true; \ - } - -static String imeCompositionArgumentNames(LPARAM lparam) -{ - StringBuilder result; - bool needsComma = false; - - APPEND_ARGUMENT_NAME(GCS_COMPATTR); - APPEND_ARGUMENT_NAME(GCS_COMPCLAUSE); - APPEND_ARGUMENT_NAME(GCS_COMPREADSTR); - APPEND_ARGUMENT_NAME(GCS_COMPREADATTR); - APPEND_ARGUMENT_NAME(GCS_COMPREADCLAUSE); - APPEND_ARGUMENT_NAME(GCS_COMPSTR); - APPEND_ARGUMENT_NAME(GCS_CURSORPOS); - APPEND_ARGUMENT_NAME(GCS_DELTASTART); - APPEND_ARGUMENT_NAME(GCS_RESULTCLAUSE); - APPEND_ARGUMENT_NAME(GCS_RESULTREADCLAUSE); - APPEND_ARGUMENT_NAME(GCS_RESULTREADSTR); - APPEND_ARGUMENT_NAME(GCS_RESULTSTR); - APPEND_ARGUMENT_NAME(CS_INSERTCHAR); - APPEND_ARGUMENT_NAME(CS_NOMOVECARET); - - return result.toString(); -} - -static String imeRequestName(WPARAM wparam) -{ - switch (wparam) { - case IMR_CANDIDATEWINDOW: - return "IMR_CANDIDATEWINDOW"; - case IMR_COMPOSITIONFONT: - return "IMR_COMPOSITIONFONT"; - case IMR_COMPOSITIONWINDOW: - return "IMR_COMPOSITIONWINDOW"; - case IMR_CONFIRMRECONVERTSTRING: - return "IMR_CONFIRMRECONVERTSTRING"; - case IMR_DOCUMENTFEED: - return "IMR_DOCUMENTFEED"; - case IMR_QUERYCHARPOSITION: - return "IMR_QUERYCHARPOSITION"; - case IMR_RECONVERTSTRING: - return "IMR_RECONVERTSTRING"; - default: - return "Unknown (" + String::number(wparam) + ")"; - } -} -#endif - -bool WebView::onIMEComposition(LPARAM lparam) -{ - LOG(TextInput, "onIMEComposition %s", imeCompositionArgumentNames(lparam).latin1().data()); - HIMC hInputContext = getIMMContext(); - if (!hInputContext) - return true; - - if (!m_page->editorState().isContentEditable) - return true; - - prepareCandidateWindow(hInputContext); - - if (lparam & GCS_RESULTSTR || !lparam) { - String compositionString; - if (!getCompositionString(hInputContext, GCS_RESULTSTR, compositionString) && lparam) - return true; - - m_page->confirmComposition(compositionString); - return true; - } - - String compositionString; - if (!getCompositionString(hInputContext, GCS_COMPSTR, compositionString)) - return true; - - // Composition string attributes - int numAttributes = Ime::ImmGetCompositionStringW(hInputContext, GCS_COMPATTR, 0, 0); - Vector<BYTE> attributes(numAttributes); - Ime::ImmGetCompositionStringW(hInputContext, GCS_COMPATTR, attributes.data(), numAttributes); - - // Get clauses - int numBytes = Ime::ImmGetCompositionStringW(hInputContext, GCS_COMPCLAUSE, 0, 0); - Vector<DWORD> clauses(numBytes / sizeof(DWORD)); - Ime::ImmGetCompositionStringW(hInputContext, GCS_COMPCLAUSE, clauses.data(), numBytes); - - Vector<CompositionUnderline> underlines; - compositionToUnderlines(clauses, attributes, underlines); - - int cursorPosition = LOWORD(Ime::ImmGetCompositionStringW(hInputContext, GCS_CURSORPOS, 0, 0)); - - m_page->setComposition(compositionString, underlines, cursorPosition); - - return true; -} - -bool WebView::onIMEEndComposition() -{ - LOG(TextInput, "onIMEEndComposition"); - // If the composition hasn't been confirmed yet, it needs to be cancelled. - // This happens after deleting the last character from inline input hole. - if (m_page->editorState().hasComposition) - m_page->confirmComposition(String()); - - if (m_inIMEComposition) - m_inIMEComposition--; - - return true; -} - -LRESULT WebView::onIMERequestCharPosition(IMECHARPOSITION* charPos) -{ - if (charPos->dwCharPos && !m_page->editorState().hasComposition) - return 0; - IntRect caret = m_page->firstRectForCharacterInSelectedRange(charPos->dwCharPos); - charPos->pt.x = caret.x(); - charPos->pt.y = caret.y(); - ::ClientToScreen(m_window, &charPos->pt); - charPos->cLineHeight = caret.height(); - ::GetWindowRect(m_window, &charPos->rcDocument); - return true; -} - -LRESULT WebView::onIMERequestReconvertString(RECONVERTSTRING* reconvertString) -{ - String text = m_page->getSelectedText(); - unsigned totalSize = sizeof(RECONVERTSTRING) + text.length() * sizeof(UChar); - - if (!reconvertString) - return totalSize; - - if (totalSize > reconvertString->dwSize) - return 0; - reconvertString->dwCompStrLen = text.length(); - reconvertString->dwStrLen = text.length(); - reconvertString->dwTargetStrLen = text.length(); - reconvertString->dwStrOffset = sizeof(RECONVERTSTRING); - memcpy(reconvertString + 1, text.characters(), text.length() * sizeof(UChar)); - return totalSize; -} - -LRESULT WebView::onIMERequest(WPARAM request, LPARAM data) -{ - LOG(TextInput, "onIMERequest %s", imeRequestName(request).latin1().data()); - if (!m_page->editorState().isContentEditable) - return 0; - - switch (request) { - case IMR_RECONVERTSTRING: - return onIMERequestReconvertString(reinterpret_cast<RECONVERTSTRING*>(data)); - - case IMR_QUERYCHARPOSITION: - return onIMERequestCharPosition(reinterpret_cast<IMECHARPOSITION*>(data)); - } - return 0; -} - -bool WebView::onIMESelect(WPARAM wparam, LPARAM lparam) -{ - UNUSED_PARAM(wparam); - UNUSED_PARAM(lparam); - LOG(TextInput, "onIMESelect locale %ld %s", lparam, wparam ? "select" : "deselect"); - return false; -} - -bool WebView::onIMESetContext(WPARAM wparam, LPARAM) -{ - LOG(TextInput, "onIMESetContext %s", wparam ? "active" : "inactive"); - return false; -} - -void WebView::doneWithKeyEvent(const NativeWebKeyboardEvent& event, bool wasEventHandled) -{ - // Calling ::DefWindowProcW will ensure that pressing the Alt key will generate a WM_SYSCOMMAND - // event, e.g. See <http://webkit.org/b/47671>. - if (!wasEventHandled) - ::DefWindowProcW(event.nativeEvent()->hwnd, event.nativeEvent()->message, event.nativeEvent()->wParam, event.nativeEvent()->lParam); -} - -PassRefPtr<WebPopupMenuProxy> WebView::createPopupMenuProxy(WebPageProxy* page) -{ - return WebPopupMenuProxyWin::create(this, page); -} - -PassRefPtr<WebContextMenuProxy> WebView::createContextMenuProxy(WebPageProxy* page) -{ - return WebContextMenuProxyWin::create(m_window, page); -} - -#if ENABLE(INPUT_TYPE_COLOR) -PassRefPtr<WebColorChooserProxy> WebView::createColorChooserProxy(WebPageProxy*, const WebCore::Color&, const WebCore::IntRect&) -{ - notImplemented(); - return 0; -} -#endif - -void WebView::setFindIndicator(PassRefPtr<FindIndicator> prpFindIndicator, bool fadeOut, bool animate) -{ - UNUSED_PARAM(animate); - - if (!m_findIndicatorCallback) - return; - - HBITMAP hbmp = 0; - IntRect selectionRect; - - if (RefPtr<FindIndicator> findIndicator = prpFindIndicator) { - if (ShareableBitmap* contentImage = findIndicator->contentImage()) { - // Render the contentImage to an HBITMAP. - void* bits; - HDC hdc = ::CreateCompatibleDC(0); - int width = contentImage->bounds().width(); - int height = contentImage->bounds().height(); - BitmapInfo bitmapInfo = BitmapInfo::create(contentImage->size()); - - hbmp = CreateDIBSection(0, &bitmapInfo, DIB_RGB_COLORS, static_cast<void**>(&bits), 0, 0); - HBITMAP hbmpOld = static_cast<HBITMAP>(SelectObject(hdc, hbmp)); -#if USE(CG) - RetainPtr<CGContextRef> context(AdoptCF, CGBitmapContextCreate(bits, width, height, - 8, width * sizeof(RGBQUAD), deviceRGBColorSpaceRef(), kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst)); - - GraphicsContext graphicsContext(context.get()); - contentImage->paint(graphicsContext, IntPoint(), contentImage->bounds()); -#else - // FIXME: Implement! -#endif - - ::SelectObject(hdc, hbmpOld); - ::DeleteDC(hdc); - } - - selectionRect = IntRect(findIndicator->selectionRectInWindowCoordinates()); - } - - // The callback is responsible for calling ::DeleteObject(hbmp). - (*m_findIndicatorCallback)(toAPI(this), hbmp, selectionRect, fadeOut, m_findIndicatorCallbackContext); -} - -void WebView::setFindIndicatorCallback(WKViewFindIndicatorCallback callback, void* context) -{ - m_findIndicatorCallback = callback; - m_findIndicatorCallbackContext = context; -} - -WKViewFindIndicatorCallback WebView::getFindIndicatorCallback(void** context) -{ - if (context) - *context = m_findIndicatorCallbackContext; - - return m_findIndicatorCallback; -} - -void WebView::didInstallOrUninstallPageOverlay(bool didInstall) -{ - m_pageOverlayInstalled = didInstall; -} - -void WebView::didCommitLoadForMainFrame(bool useCustomRepresentation) -{ -} - -void WebView::didFinishLoadingDataForCustomRepresentation(const String& suggestedFilename, const CoreIPC::DataReference&) -{ -} - -double WebView::customRepresentationZoomFactor() -{ - return 1; -} - -void WebView::setCustomRepresentationZoomFactor(double) -{ -} - -void WebView::didChangeScrollbarsForMainFrame() const -{ -} - -void WebView::findStringInCustomRepresentation(const String&, FindOptions, unsigned) -{ -} - -void WebView::countStringMatchesInCustomRepresentation(const String&, FindOptions, unsigned) -{ -} - -void WebView::setIsInWindow(bool isInWindow) -{ - m_isInWindow = isInWindow; - m_page->viewStateDidChange(WebPageProxy::ViewIsInWindow); -} - -void WebView::setIsVisible(bool isVisible) -{ - m_isVisible = isVisible; - - if (m_page) - m_page->viewStateDidChange(WebPageProxy::ViewIsVisible); -} - -#if USE(ACCELERATED_COMPOSITING) - -void WebView::enterAcceleratedCompositingMode(const LayerTreeContext& context) -{ -#if HAVE(WKQCA) - ASSERT(!context.isEmpty()); - - m_layerHostWindow = context.window; - - IntSize size = viewSize(); - // Ensure the layer host window is behind all other child windows (since otherwise it would obscure them). - ::SetWindowPos(m_layerHostWindow, HWND_BOTTOM, 0, 0, size.width(), size.height(), SWP_SHOWWINDOW | SWP_NOACTIVATE); -#else - ASSERT_NOT_REACHED(); -#endif -} - -void WebView::exitAcceleratedCompositingMode() -{ -#if HAVE(WKQCA) - ASSERT(m_layerHostWindow); - - // Tell the WKCACFViewWindow to destroy itself. We can't call ::DestroyWindow directly because - // the window is owned by another thread. - ::PostMessageW(m_layerHostWindow, WKCACFViewWindow::customDestroyMessage, 0, 0); - m_layerHostWindow = 0; -#else - ASSERT_NOT_REACHED(); -#endif -} - -void WebView::updateAcceleratedCompositingMode(const LayerTreeContext&) -{ -} -#endif // USE(ACCELERATED_COMPOSITING) - -HWND WebView::nativeWindow() -{ - return m_window; -} - -void WebView::scheduleChildWindowGeometryUpdate(const WindowGeometry& geometry) -{ - m_geometriesUpdater.addPendingUpdate(geometry); -} - -void WebView::updateChildWindowGeometries() -{ - m_geometriesUpdater.updateGeometries(DoNotBringToTop); -} - -// WebCore::WindowMessageListener - -void WebView::windowReceivedMessage(HWND, UINT message, WPARAM wParam, LPARAM) -{ - switch (message) { - case WM_NCACTIVATE: - updateActiveStateSoon(); - break; - case WM_SETTINGCHANGE: - // systemParameterChanged(wParam); - break; - } -} - -HRESULT STDMETHODCALLTYPE WebView::QueryInterface(REFIID riid, void** ppvObject) -{ - *ppvObject = 0; - if (IsEqualGUID(riid, IID_IUnknown)) - *ppvObject = static_cast<IUnknown*>(this); - else if (IsEqualGUID(riid, IID_IDropTarget)) - *ppvObject = static_cast<IDropTarget*>(this); - else - return E_NOINTERFACE; - - AddRef(); - return S_OK; -} - -ULONG STDMETHODCALLTYPE WebView::AddRef(void) -{ - ref(); - return refCount(); -} - -ULONG STDMETHODCALLTYPE WebView::Release(void) -{ - deref(); - return refCount(); -} - -static DWORD dragOperationToDragCursor(DragOperation op) -{ - DWORD res = DROPEFFECT_NONE; - if (op & DragOperationCopy) - res = DROPEFFECT_COPY; - else if (op & DragOperationLink) - res = DROPEFFECT_LINK; - else if (op & DragOperationMove) - res = DROPEFFECT_MOVE; - else if (op & DragOperationGeneric) - res = DROPEFFECT_MOVE; // This appears to be the Firefox behaviour - return res; -} - -WebCore::DragOperation WebView::keyStateToDragOperation(DWORD grfKeyState) const -{ - if (!m_page) - return DragOperationNone; - - // Conforms to Microsoft's key combinations as documented for - // IDropTarget::DragOver. Note, grfKeyState is the current - // state of the keyboard modifier keys on the keyboard. See: - // <http://msdn.microsoft.com/en-us/library/ms680129(VS.85).aspx>. - DragOperation operation = m_page->dragSession().operation; - - if ((grfKeyState & (MK_CONTROL | MK_SHIFT)) == (MK_CONTROL | MK_SHIFT)) - operation = DragOperationLink; - else if ((grfKeyState & MK_CONTROL) == MK_CONTROL) - operation = DragOperationCopy; - else if ((grfKeyState & MK_SHIFT) == MK_SHIFT) - operation = DragOperationGeneric; - - return operation; -} - -HRESULT STDMETHODCALLTYPE WebView::DragEnter(IDataObject* pDataObject, DWORD grfKeyState, POINTL pt, DWORD* pdwEffect) -{ - m_dragData = 0; - m_page->resetDragOperation(); - - if (m_dropTargetHelper) - m_dropTargetHelper->DragEnter(m_window, pDataObject, (POINT*)&pt, *pdwEffect); - - POINTL localpt = pt; - ::ScreenToClient(m_window, (LPPOINT)&localpt); - DragData data(pDataObject, IntPoint(localpt.x, localpt.y), IntPoint(pt.x, pt.y), keyStateToDragOperation(grfKeyState)); - m_page->dragEntered(&data); - *pdwEffect = dragOperationToDragCursor(m_page->dragSession().operation); - - m_lastDropEffect = *pdwEffect; - m_dragData = pDataObject; - - return S_OK; -} - -HRESULT STDMETHODCALLTYPE WebView::DragOver(DWORD grfKeyState, POINTL pt, DWORD* pdwEffect) -{ - if (m_dropTargetHelper) - m_dropTargetHelper->DragOver((POINT*)&pt, *pdwEffect); - - if (m_dragData) { - POINTL localpt = pt; - ::ScreenToClient(m_window, (LPPOINT)&localpt); - DragData data(m_dragData.get(), IntPoint(localpt.x, localpt.y), IntPoint(pt.x, pt.y), keyStateToDragOperation(grfKeyState)); - m_page->dragUpdated(&data); - *pdwEffect = dragOperationToDragCursor(m_page->dragSession().operation); - } else - *pdwEffect = DROPEFFECT_NONE; - - m_lastDropEffect = *pdwEffect; - return S_OK; -} - -HRESULT STDMETHODCALLTYPE WebView::DragLeave() -{ - if (m_dropTargetHelper) - m_dropTargetHelper->DragLeave(); - - if (m_dragData) { - DragData data(m_dragData.get(), IntPoint(), IntPoint(), DragOperationNone); - m_page->dragExited(&data); - m_dragData = 0; - m_page->resetDragOperation(); - } - return S_OK; -} - -static bool maybeCreateSandboxExtensionFromDragData(const DragData& dragData, SandboxExtension::Handle& sandboxExtensionHandle) -{ - if (!dragData.containsFiles()) - return false; - - // Unlike on Mac, we allow multiple files and directories, since on Windows - // we have actions for those (open the first file, open a Windows Explorer window). - - SandboxExtension::createHandle("\\", SandboxExtension::ReadOnly, sandboxExtensionHandle); - return true; -} - -HRESULT STDMETHODCALLTYPE WebView::Drop(IDataObject* pDataObject, DWORD grfKeyState, POINTL pt, DWORD* pdwEffect) -{ - if (m_dropTargetHelper) - m_dropTargetHelper->Drop(pDataObject, (POINT*)&pt, *pdwEffect); - - m_dragData = 0; - *pdwEffect = m_lastDropEffect; - POINTL localpt = pt; - ::ScreenToClient(m_window, (LPPOINT)&localpt); - DragData data(pDataObject, IntPoint(localpt.x, localpt.y), IntPoint(pt.x, pt.y), keyStateToDragOperation(grfKeyState)); - - SandboxExtension::Handle sandboxExtensionHandle; - bool createdExtension = maybeCreateSandboxExtensionFromDragData(data, sandboxExtensionHandle); - if (createdExtension) - m_page->process()->willAcquireUniversalFileReadSandboxExtension(); - SandboxExtension::HandleArray sandboxExtensionForUpload; - m_page->performDrag(&data, String(), sandboxExtensionHandle, sandboxExtensionForUpload); - return S_OK; -} - -#if ENABLE(FULLSCREEN_API) -FullScreenController* WebView::fullScreenController() -{ - if (!m_fullScreenController) - m_fullScreenController = adoptPtr(new FullScreenController(this)); - return m_fullScreenController.get(); -} - -HWND WebView::fullScreenClientWindow() const -{ - return m_window; -} - -HWND WebView::fullScreenClientParentWindow() const -{ - return ::GetParent(m_window); -} - -void WebView::fullScreenClientSetParentWindow(HWND hostWindow) -{ - setParentWindow(hostWindow); -} - -void WebView::fullScreenClientWillEnterFullScreen() -{ - page()->fullScreenManager()->willEnterFullScreen(); -} - -void WebView::fullScreenClientDidEnterFullScreen() -{ - page()->fullScreenManager()->didEnterFullScreen(); -} - -void WebView::fullScreenClientWillExitFullScreen() -{ - page()->fullScreenManager()->willExitFullScreen(); -} - -void WebView::fullScreenClientDidExitFullScreen() -{ - page()->fullScreenManager()->didExitFullScreen(); -} - -static void fullScreenClientForceRepaintCompleted(WKErrorRef, void* context) -{ - ASSERT(context); - static_cast<WebView*>(context)->fullScreenController()->repaintCompleted(); -} - -void WebView::fullScreenClientForceRepaint() -{ - page()->forceRepaint(VoidCallback::create(this, &fullScreenClientForceRepaintCompleted)); -} - -#endif -} // namespace WebKit |
