WebView.cpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462
  1. /*
  2. * Copyright (C) 2006, 2007, 2008, 2009, 2010 Apple, Inc. All rights reserved.
  3. * Copyright (C) 2010 Patrick Gansterer <paroga@paroga.com>
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions
  7. * are met:
  8. * 1. Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * 2. Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in the
  12. * documentation and/or other materials provided with the distribution.
  13. *
  14. * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
  15. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  16. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  17. * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
  18. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  19. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  20. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  21. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  22. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  23. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  24. */
  25. #include "config.h"
  26. #include "WebView.h"
  27. #include "ChromeClientWinCE.h"
  28. #include "ContextMenuClientWinCE.h"
  29. #include "DragClientWinCE.h"
  30. #include "EditorClientWinCE.h"
  31. #include "EventHandler.h"
  32. #include "FocusController.h"
  33. #include "Frame.h"
  34. #include "FrameLoadRequest.h"
  35. #include "FrameLoader.h"
  36. #include "FrameLoaderClientWinCE.h"
  37. #include "FrameView.h"
  38. #include "GraphicsContext.h"
  39. #include "HTMLFormElement.h"
  40. #include "InitializeThreading.h"
  41. #include "InspectorClientWinCE.h"
  42. #include "IntSize.h"
  43. #include "NotImplemented.h"
  44. #include "Page.h"
  45. #include "PlatformKeyboardEvent.h"
  46. #include "PlatformMouseEvent.h"
  47. #include "PlatformStrategiesWinCE.h"
  48. #include "PlatformWheelEvent.h"
  49. #include "ResourceRequest.h"
  50. #include "Settings.h"
  51. #include "SharedBuffer.h"
  52. #include "WebCoreInstanceHandle.h"
  53. #include <wtf/MainThread.h>
  54. using namespace WebCore;
  55. const LPCWSTR kWebViewWindowClassName = L"WebViewWindowClass";
  56. LRESULT CALLBACK WebView::webViewWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  57. {
  58. if (WebView* webView = reinterpret_cast<WebView*>(GetWindowLong(hWnd, 0)))
  59. return webView->wndProc(hWnd, message, wParam, lParam);
  60. return DefWindowProc(hWnd, message, wParam, lParam);
  61. }
  62. PassRefPtr<SharedBuffer> loadResourceIntoBuffer(const char* name)
  63. {
  64. notImplemented();
  65. return 0;
  66. }
  67. WebView::WebView(HWND hwnd, unsigned features)
  68. : m_frame(0)
  69. , m_page(0)
  70. , m_parentWindowHandle(hwnd)
  71. , m_enableDoubleBuffer(features & EnableDoubleBuffering)
  72. {
  73. RECT rcClient;
  74. GetClientRect(hwnd, &rcClient);
  75. m_windowHandle = CreateWindow(kWebViewWindowClassName, 0, WS_CHILD,
  76. CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, hwnd, 0, WebCore::instanceHandle(), 0);
  77. SetWindowLong(m_windowHandle, 0, reinterpret_cast<LONG>(this));
  78. MoveWindow(m_windowHandle, 0, 0, rcClient.right, rcClient.bottom, TRUE);
  79. ShowWindow(m_windowHandle, SW_SHOW);
  80. Page::PageClients pageClients;
  81. pageClients.chromeClient = new WebKit::ChromeClientWinCE(this);
  82. pageClients.contextMenuClient = new WebKit::ContextMenuClientWinCE(this);
  83. pageClients.editorClient = new WebKit::EditorClientWinCE(this);
  84. pageClients.dragClient = new WebKit::DragClientWinCE();
  85. pageClients.inspectorClient = new WebKit::InspectorClientWinCE(this);
  86. m_page = new Page(pageClients);
  87. Settings* settings = m_page->settings();
  88. settings->setDefaultFixedFontSize(14);
  89. settings->setDefaultFontSize(14);
  90. settings->setMinimumFontSize(8);
  91. settings->setMinimumLogicalFontSize(8);
  92. settings->setScriptEnabled(true);
  93. settings->setLoadsImagesAutomatically(true);
  94. WebKit::FrameLoaderClientWinCE* loaderClient = new WebKit::FrameLoaderClientWinCE(this);
  95. RefPtr<Frame> frame = Frame::create(m_page, 0, loaderClient);
  96. m_frame = frame.get();
  97. loaderClient->setFrame(m_frame);
  98. m_page->mainFrame()->init();
  99. if (view()) {
  100. RECT windowRect;
  101. frameRect(&windowRect);
  102. view()->resize(IntRect(windowRect).size());
  103. }
  104. }
  105. WebView::~WebView()
  106. {
  107. delete m_page;
  108. DestroyWindow(m_windowHandle);
  109. }
  110. void WebView::initialize(HINSTANCE instanceHandle)
  111. {
  112. JSC::initializeThreading();
  113. WTF::initializeMainThread();
  114. PlatformStrategiesWinCE::initialize();
  115. WebCore::setInstanceHandle(instanceHandle);
  116. WNDCLASS wc;
  117. wc.style = CS_DBLCLKS;
  118. wc.lpfnWndProc = WebView::webViewWndProc;
  119. wc.cbClsExtra = 0;
  120. wc.cbWndExtra = sizeof(void *);
  121. wc.hInstance = instanceHandle;
  122. wc.hIcon = 0;
  123. wc.hCursor = LoadCursor(0, IDC_ARROW);
  124. wc.hbrBackground = 0;
  125. wc.lpszMenuName = 0;
  126. wc.lpszClassName = kWebViewWindowClassName;
  127. RegisterClass(&wc);
  128. }
  129. void WebView::cleanup()
  130. {
  131. UnregisterClass(kWebViewWindowClassName, WebCore::instanceHandle());
  132. }
  133. PassRefPtr<Frame> WebView::createFrame(const KURL& url, const String& name, HTMLFrameOwnerElement* ownerElement, const String& referrer,
  134. bool /*allowsScrolling*/, int /*marginWidth*/, int /*marginHeight*/)
  135. {
  136. Frame* coreFrame = m_frame;
  137. WebKit::FrameLoaderClientWinCE *loaderClient = new WebKit::FrameLoaderClientWinCE(this);
  138. RefPtr<Frame> childFrame = Frame::create(m_page, ownerElement, loaderClient);
  139. loaderClient->setFrame(childFrame.get());
  140. coreFrame->tree()->appendChild(childFrame);
  141. childFrame->tree()->setName(name);
  142. childFrame->init();
  143. // The creation of the frame may have run arbitrary JavaScript that removed it from the page already.
  144. if (!childFrame->page())
  145. return 0;
  146. coreFrame->loader()->loadURLIntoChildFrame(url, referrer, childFrame.get());
  147. // The frame's onload handler may have removed it from the document.
  148. if (!childFrame->tree()->parent())
  149. return 0;
  150. return childFrame.release();
  151. }
  152. void WebView::runJavaScriptAlert(const String& message)
  153. {
  154. notImplemented();
  155. }
  156. bool WebView::runJavaScriptConfirm(const String& message)
  157. {
  158. notImplemented();
  159. return false;
  160. }
  161. bool WebView::runJavaScriptPrompt(const String& message, const String& defaultValue, String& result)
  162. {
  163. notImplemented();
  164. return false;
  165. }
  166. void WebView::frameRect(RECT* rect) const
  167. {
  168. GetWindowRect(m_windowHandle, rect);
  169. }
  170. FrameView* WebView::view() const
  171. {
  172. return m_frame ? m_frame->view() : 0;
  173. }
  174. void WebView::load(LPCWSTR url)
  175. {
  176. load(String(url));
  177. }
  178. void WebView::load(const String &url)
  179. {
  180. load(WebCore::ResourceRequest(url));
  181. }
  182. void WebView::load(const WebCore::ResourceRequest &request)
  183. {
  184. frame()->loader()->load(FrameLoadRequest(frame(), request));
  185. }
  186. void WebView::reload()
  187. {
  188. frame()->loader()->reload();
  189. }
  190. void WebView::stop()
  191. {
  192. frame()->loader()->stopAllLoaders();
  193. }
  194. void WebView::paint(HDC hDC, const IntRect& clipRect)
  195. {
  196. FrameView* frameView = view();
  197. if (!frameView)
  198. return;
  199. OwnPtr<HRGN> clipRgn = adoptPtr(CreateRectRgn(clipRect.x(), clipRect.y(), clipRect.maxX(), clipRect.maxY()));
  200. SelectClipRgn(hDC, clipRgn.get());
  201. frameView->updateLayoutAndStyleIfNeededRecursive();
  202. GraphicsContext gc(hDC);
  203. frameView->paint(&gc, clipRect);
  204. }
  205. bool WebView::handlePaint(HWND hWnd)
  206. {
  207. RECT updateRect;
  208. if (!GetUpdateRect(hWnd, &updateRect, false))
  209. return false;
  210. PAINTSTRUCT ps;
  211. HDC hDC = BeginPaint(m_windowHandle, &ps);
  212. IntRect clipRect(updateRect);
  213. if (m_enableDoubleBuffer) {
  214. if (!m_doubleBufferDC) {
  215. RECT rcClient;
  216. GetClientRect(m_windowHandle, &rcClient);
  217. m_doubleBufferDC = adoptPtr(CreateCompatibleDC(hDC));
  218. m_doubleBufferBitmap = adoptPtr(CreateCompatibleBitmap(hDC, rcClient.right, rcClient.bottom));
  219. SelectObject(m_doubleBufferDC.get(), m_doubleBufferBitmap.get());
  220. }
  221. paint(m_doubleBufferDC.get(), clipRect);
  222. BitBlt(hDC, clipRect.x(), clipRect.y(), clipRect.width(), clipRect.height(), m_doubleBufferDC.get(), clipRect.x(), clipRect.y(), SRCCOPY);
  223. } else
  224. paint(hDC, clipRect);
  225. EndPaint(m_windowHandle, &ps);
  226. return true;
  227. }
  228. bool WebView::handleMouseEvent(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  229. {
  230. static LONG globalClickCount;
  231. static IntPoint globalPrevPoint;
  232. static MouseButton globalPrevButton;
  233. static LONG globalPrevMouseDownTime;
  234. // Create our event.
  235. // On WM_MOUSELEAVE we need to create a mouseout event, so we force the position
  236. // of the event to be at (MINSHORT, MINSHORT).
  237. PlatformMouseEvent mouseEvent(hWnd, message, wParam, lParam);
  238. bool insideThreshold = abs(globalPrevPoint.x() - mouseEvent.position().x()) < ::GetSystemMetrics(SM_CXDOUBLECLK)
  239. && abs(globalPrevPoint.y() - mouseEvent.position().y()) < ::GetSystemMetrics(SM_CYDOUBLECLK);
  240. LONG messageTime = 0;
  241. bool handled = false;
  242. if (message == WM_LBUTTONDOWN || message == WM_MBUTTONDOWN || message == WM_RBUTTONDOWN) {
  243. // FIXME: I'm not sure if this is the "right" way to do this
  244. // but without this call, we never become focused since we don't allow
  245. // the default handling of mouse events.
  246. SetFocus(m_windowHandle);
  247. PlatformMouseEvent moveEvent(hWnd, WM_MOUSEMOVE, 0, lParam, false);
  248. moveEvent.setClickCount(0);
  249. m_page->mainFrame()->eventHandler()->handleMouseMoveEvent(moveEvent);
  250. // Always start capturing events when the mouse goes down in our HWND.
  251. SetCapture(m_windowHandle);
  252. if (insideThreshold && mouseEvent.button() == globalPrevButton)
  253. globalClickCount++;
  254. else
  255. // Reset the click count.
  256. globalClickCount = 1;
  257. globalPrevMouseDownTime = messageTime;
  258. globalPrevButton = mouseEvent.button();
  259. globalPrevPoint = mouseEvent.position();
  260. mouseEvent.setClickCount(globalClickCount);
  261. handled = m_page->mainFrame()->eventHandler()->handleMousePressEvent(mouseEvent);
  262. } else if (message == WM_LBUTTONDBLCLK || message == WM_MBUTTONDBLCLK || message == WM_RBUTTONDBLCLK) {
  263. globalClickCount++;
  264. mouseEvent.setClickCount(globalClickCount);
  265. handled = m_page->mainFrame()->eventHandler()->handleMousePressEvent(mouseEvent);
  266. } else if (message == WM_LBUTTONUP || message == WM_MBUTTONUP || message == WM_RBUTTONUP) {
  267. // Record the global position and the button of the up.
  268. globalPrevButton = mouseEvent.button();
  269. globalPrevPoint = mouseEvent.position();
  270. mouseEvent.setClickCount(globalClickCount);
  271. m_page->mainFrame()->eventHandler()->handleMouseReleaseEvent(mouseEvent);
  272. ReleaseCapture();
  273. } else if (message == WM_MOUSEMOVE) {
  274. if (!insideThreshold)
  275. globalClickCount = 0;
  276. mouseEvent.setClickCount(globalClickCount);
  277. handled = m_page->mainFrame()->eventHandler()->mouseMoved(mouseEvent);
  278. }
  279. return handled;
  280. }
  281. bool WebView::handleMouseWheel(HWND hWnd, WPARAM wParam, LPARAM lParam, bool isHorizontal)
  282. {
  283. PlatformWheelEvent wheelEvent(hWnd, wParam, lParam, isHorizontal);
  284. return frame()->eventHandler()->handleWheelEvent(wheelEvent);
  285. }
  286. bool WebView::handleKeyDown(WPARAM virtualKeyCode, LPARAM keyData, bool systemKeyDown)
  287. {
  288. Frame* frame = m_page->focusController()->focusedOrMainFrame();
  289. PlatformKeyboardEvent keyEvent(m_windowHandle, virtualKeyCode, keyData, PlatformEvent::RawKeyDown, systemKeyDown);
  290. bool handled = frame->eventHandler()->keyEvent(keyEvent);
  291. // These events cannot be canceled, and we have no default handling for them.
  292. // FIXME: match IE list more closely, see <http://msdn2.microsoft.com/en-us/library/ms536938.aspx>.
  293. if (systemKeyDown && virtualKeyCode != VK_RETURN)
  294. return false;
  295. if (handled) {
  296. MSG msg;
  297. if (!systemKeyDown)
  298. ::PeekMessage(&msg, m_windowHandle, WM_CHAR, WM_CHAR, PM_REMOVE);
  299. return true;
  300. }
  301. return handled;
  302. }
  303. bool WebView::handleKeyPress(WPARAM charCode, LPARAM keyData, bool systemKeyDown)
  304. {
  305. Frame* frame = m_page->focusController()->focusedOrMainFrame();
  306. PlatformKeyboardEvent keyEvent(m_windowHandle, charCode, keyData, PlatformEvent::Char, systemKeyDown);
  307. // IE does not dispatch keypress event for WM_SYSCHAR.
  308. if (systemKeyDown)
  309. return frame->eventHandler()->handleAccessKey(keyEvent);
  310. if (frame->eventHandler()->keyEvent(keyEvent))
  311. return true;
  312. return false;
  313. }
  314. bool WebView::handleKeyUp(WPARAM virtualKeyCode, LPARAM keyData, bool systemKeyDown)
  315. {
  316. PlatformKeyboardEvent keyEvent(m_windowHandle, virtualKeyCode, keyData, PlatformEvent::KeyUp, systemKeyDown);
  317. Frame* frame = m_page->focusController()->focusedOrMainFrame();
  318. return frame->eventHandler()->keyEvent(keyEvent);
  319. }
  320. LRESULT WebView::wndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  321. {
  322. bool handled = false;
  323. if (view()) {
  324. switch (message) {
  325. case WM_PAINT:
  326. handled = handlePaint(hWnd);
  327. break;
  328. case WM_MOUSEMOVE:
  329. case WM_LBUTTONDOWN:
  330. case WM_MBUTTONDOWN:
  331. case WM_RBUTTONDOWN:
  332. case WM_LBUTTONDBLCLK:
  333. case WM_MBUTTONDBLCLK:
  334. case WM_RBUTTONDBLCLK:
  335. case WM_LBUTTONUP:
  336. case WM_MBUTTONUP:
  337. case WM_RBUTTONUP:
  338. if (frame()->eventHandler() && view()->didFirstLayout())
  339. handled = handleMouseEvent(hWnd, message, wParam, lParam);
  340. break;
  341. case WM_MOUSEWHEEL:
  342. if (frame()->eventHandler() && view()->didFirstLayout())
  343. handled = handleMouseWheel(hWnd, wParam, lParam, wParam & MK_SHIFT);
  344. break;
  345. case WM_SYSKEYDOWN:
  346. handled = handleKeyDown(wParam, lParam, true);
  347. break;
  348. case WM_KEYDOWN:
  349. handled = handleKeyDown(wParam, lParam, false);
  350. break;
  351. case WM_SYSKEYUP:
  352. handled = handleKeyUp(wParam, lParam, true);
  353. break;
  354. case WM_KEYUP:
  355. handled = handleKeyUp(wParam, lParam, false);
  356. break;
  357. case WM_SYSCHAR:
  358. handled = handleKeyPress(wParam, lParam, true);
  359. break;
  360. case WM_CHAR:
  361. handled = handleKeyPress(wParam, lParam, false);
  362. break;
  363. case WM_CLOSE:
  364. PostMessage(m_parentWindowHandle, WM_CLOSE, wParam, lParam);
  365. handled = true;
  366. break;
  367. default:
  368. break;
  369. }
  370. }
  371. if (handled)
  372. return 0;
  373. return DefWindowProc(hWnd, message, wParam, lParam);
  374. }