diff options
Diffstat (limited to 'WebKit/chromium/src')
116 files changed, 6387 insertions, 3141 deletions
diff --git a/WebKit/chromium/src/ApplicationCacheHostInternal.h b/WebKit/chromium/src/ApplicationCacheHostInternal.h index 3e52c1b..bf6c4ae 100644 --- a/WebKit/chromium/src/ApplicationCacheHostInternal.h +++ b/WebKit/chromium/src/ApplicationCacheHostInternal.h @@ -33,7 +33,10 @@ #if ENABLE(OFFLINE_WEB_APPLICATIONS) +#include "DocumentLoader.h" #include "WebApplicationCacheHostClient.h" +#include "WebFrameClient.h" +#include "WebFrameImpl.h" #include "WebKit.h" #include "WebKitClient.h" @@ -44,7 +47,9 @@ public: ApplicationCacheHostInternal(ApplicationCacheHost* host) : m_innerHost(host) { - m_outerHost.set(WebKit::webKitClient()->createApplicationCacheHost(this)); + WebKit::WebFrameImpl* webFrame = WebKit::WebFrameImpl::fromFrame(host->m_documentLoader->frame()); + ASSERT(webFrame); + m_outerHost.set(webFrame->client()->createApplicationCacheHost(webFrame, this)); } virtual void notifyEventListener(WebKit::WebApplicationCacheHost::EventID eventID) diff --git a/WebKit/chromium/src/AutoFillPopupMenuClient.cpp b/WebKit/chromium/src/AutoFillPopupMenuClient.cpp index 8e6cab4..4f8793a 100644 --- a/WebKit/chromium/src/AutoFillPopupMenuClient.cpp +++ b/WebKit/chromium/src/AutoFillPopupMenuClient.cpp @@ -32,8 +32,11 @@ #include "AutoFillPopupMenuClient.h" #include "HTMLInputElement.h" +#include "WebNode.h" #include "WebString.h" #include "WebVector.h" +#include "WebViewClient.h" +#include "WebViewImpl.h" using namespace WebCore; @@ -59,6 +62,19 @@ void AutoFillPopupMenuClient::removeSuggestionAtIndex(unsigned listIndex) m_labels.remove(listIndex); } +void AutoFillPopupMenuClient::valueChanged(unsigned listIndex, bool fireEvents) +{ + ASSERT(listIndex >= 0 && listIndex < m_names.size()); + + WebViewImpl* webView = getWebView(); + if (!webView) + return; + + webView->client()->didAcceptAutoFillSuggestion(WebNode(getTextField()), + m_names[listIndex], + m_labels[listIndex]); +} + void AutoFillPopupMenuClient::initialize( HTMLInputElement* textField, const WebVector<WebString>& names, diff --git a/WebKit/chromium/src/AutoFillPopupMenuClient.h b/WebKit/chromium/src/AutoFillPopupMenuClient.h index 1912fa3..568ce4d 100644 --- a/WebKit/chromium/src/AutoFillPopupMenuClient.h +++ b/WebKit/chromium/src/AutoFillPopupMenuClient.h @@ -50,6 +50,9 @@ public: virtual WebString getSuggestion(unsigned listIndex) const; virtual void removeSuggestionAtIndex(unsigned listIndex); + // WebCore::PopupMenuClient implementation: + virtual void valueChanged(unsigned listIndex, bool fireEvents = true); + void initialize(WebCore::HTMLInputElement*, const WebVector<WebString>& names, const WebVector<WebString>& labels, diff --git a/WebKit/chromium/src/ChromeClientImpl.cpp b/WebKit/chromium/src/ChromeClientImpl.cpp index 6e5bfc2..c7acab5 100644 --- a/WebKit/chromium/src/ChromeClientImpl.cpp +++ b/WebKit/chromium/src/ChromeClientImpl.cpp @@ -45,8 +45,9 @@ #include "FrameView.h" #include "Geolocation.h" #include "GeolocationService.h" -#include "GeolocationServiceBridgeChromium.h" +#include "WebGeolocationService.h" #include "GeolocationServiceChromium.h" +#include "GraphicsLayer.h" #include "HitTestResult.h" #include "IntRect.h" #include "Node.h" @@ -67,6 +68,7 @@ #include "WebKit.h" #include "WebPopupMenuImpl.h" #include "WebPopupMenuInfo.h" +#include "WebPopupType.h" #include "WebRect.h" #include "WebTextDirection.h" #include "WebURLRequest.h" @@ -79,6 +81,20 @@ using namespace WebCore; namespace WebKit { +// Converts a WebCore::PopupContainerType to a WebKit::WebPopupType. +static WebPopupType convertPopupType(PopupContainer::PopupType type) +{ + switch (type) { + case PopupContainer::Select: + return WebPopupTypeSelect; + case PopupContainer::Suggestion: + return WebPopupTypeSuggestion; + default: + ASSERT_NOT_REACHED(); + return WebPopupTypeNone; + } +} + ChromeClientImpl::ChromeClientImpl(WebViewImpl* webView) : m_webView(webView) , m_toolbarsVisible(true) @@ -86,7 +102,6 @@ ChromeClientImpl::ChromeClientImpl(WebViewImpl* webView) , m_scrollbarsVisible(true) , m_menubarVisible(true) , m_resizable(true) - , m_ignoreNextSetCursor(false) { } @@ -327,7 +342,7 @@ void ChromeClientImpl::setScrollbarsVisible(bool value) m_scrollbarsVisible = value; WebFrameImpl* web_frame = static_cast<WebFrameImpl*>(m_webView->mainFrame()); if (web_frame) - web_frame->setAllowsScrolling(value); + web_frame->setCanHaveScrollbars(value); } bool ChromeClientImpl::scrollbarsVisible() @@ -466,15 +481,22 @@ IntRect ChromeClientImpl::windowResizerRect() const return result; } -void ChromeClientImpl::repaint( - const IntRect& paintRect, bool contentChanged, bool immediate, - bool repaintContentOnly) +void ChromeClientImpl::invalidateWindow(const IntRect&, bool) +{ + notImplemented(); +} + +void ChromeClientImpl::invalidateContentsAndWindow(const IntRect& updateRect, bool /*immediate*/) { - // Ignore spurious calls. - if (!contentChanged || paintRect.isEmpty()) + if (updateRect.isEmpty()) return; if (m_webView->client()) - m_webView->client()->didInvalidateRect(paintRect); + m_webView->client()->didInvalidateRect(updateRect); +} + +void ChromeClientImpl::invalidateContentsForSlowScroll(const IntRect& updateRect, bool immediate) +{ + invalidateContentsAndWindow(updateRect, immediate); } void ChromeClientImpl::scroll( @@ -580,14 +602,13 @@ void ChromeClientImpl::runOpenPanel(Frame* frame, PassRefPtr<FileChooser> fileCh chooserCompletion->didChooseFile(WebVector<WebString>()); } -void ChromeClientImpl::iconForFiles(const Vector<WebCore::String>&, PassRefPtr<WebCore::FileChooser>) +void ChromeClientImpl::chooseIconForFiles(const Vector<WebCore::String>&, WebCore::FileChooser*) { notImplemented(); } void ChromeClientImpl::popupOpened(PopupContainer* popupContainer, const IntRect& bounds, - bool activatable, bool handleExternally) { if (!m_webView->client()) @@ -598,19 +619,28 @@ void ChromeClientImpl::popupOpened(PopupContainer* popupContainer, WebPopupMenuInfo popupInfo; getPopupMenuInfo(popupContainer, &popupInfo); webwidget = m_webView->client()->createPopupMenu(popupInfo); - } else - webwidget = m_webView->client()->createPopupMenu(activatable); - + } else { + webwidget = m_webView->client()->createPopupMenu( + convertPopupType(popupContainer->popupType())); + // Try the deprecated methods. + // FIXME: Remove the deprecated methods once the Chromium side use the + // new method. + if (!webwidget) + webwidget = m_webView->client()->createPopupMenu(); + if (!webwidget) + webwidget = m_webView->client()->createPopupMenu(false); + } + m_webView->popupOpened(popupContainer); static_cast<WebPopupMenuImpl*>(webwidget)->Init(popupContainer, bounds); } -void ChromeClientImpl::setCursor(const WebCursorInfo& cursor) +void ChromeClientImpl::popupClosed(WebCore::PopupContainer* popupContainer) { - if (m_ignoreNextSetCursor) { - m_ignoreNextSetCursor = false; - return; - } + m_webView->popupClosed(popupContainer); +} +void ChromeClientImpl::setCursor(const WebCursorInfo& cursor) +{ if (m_webView->client()) m_webView->client()->didChangeCursor(cursor); } @@ -618,11 +648,6 @@ void ChromeClientImpl::setCursor(const WebCursorInfo& cursor) void ChromeClientImpl::setCursorForPlugin(const WebCursorInfo& cursor) { setCursor(cursor); - - // Currently, Widget::setCursor is always called after this function in - // EventHandler.cpp and since we don't want that we set a flag indicating - // that the next SetCursor call is to be ignored. - m_ignoreNextSetCursor = true; } void ChromeClientImpl::formStateDidChange(const Node* node) @@ -664,6 +689,7 @@ void ChromeClientImpl::getPopupMenuInfo(PopupContainer* popupContainer, } info->itemHeight = popupContainer->menuItemHeight(); + info->itemFontSize = popupContainer->menuItemFontSize(); info->selectedIndex = popupContainer->selectedIndex(); info->items.swap(outputItems); } @@ -675,7 +701,6 @@ void ChromeClientImpl::didChangeAccessibilityObjectState(AccessibilityObject* ob m_webView->client()->didChangeAccessibilityObjectState(WebAccessibilityObject(obj)); } - #if ENABLE(NOTIFICATIONS) NotificationPresenter* ChromeClientImpl::notificationPresenter() const { @@ -685,8 +710,26 @@ NotificationPresenter* ChromeClientImpl::notificationPresenter() const void ChromeClientImpl::requestGeolocationPermissionForFrame(Frame* frame, Geolocation* geolocation) { - GeolocationServiceChromium* geolocationService = reinterpret_cast<GeolocationServiceChromium*>(geolocation->getGeolocationService()); - m_webView->client()->getGeolocationService()->requestPermissionForFrame(geolocationService->geolocationServiceBridge()->getBridgeId(), frame->document()->url()); + GeolocationServiceChromium* geolocationService = static_cast<GeolocationServiceChromium*>(geolocation->getGeolocationService()); + m_webView->client()->geolocationService()->requestPermissionForFrame(geolocationService->geolocationServiceBridge()->getBridgeId(), frame->document()->url()); +} + +void ChromeClientImpl::cancelGeolocationPermissionRequestForFrame(Frame* frame, Geolocation* geolocation) +{ + GeolocationServiceChromium* geolocationService = static_cast<GeolocationServiceChromium*>(geolocation->getGeolocationService()); + m_webView->client()->geolocationService()->cancelPermissionRequestForFrame(geolocationService->geolocationServiceBridge()->getBridgeId(), frame->document()->url()); +} + +#if USE(ACCELERATED_COMPOSITING) +void ChromeClientImpl::attachRootGraphicsLayer(Frame* frame, GraphicsLayer* graphicsLayer) +{ + m_webView->setRootGraphicsLayer(graphicsLayer ? graphicsLayer->platformLayer() : 0); } +void ChromeClientImpl::scheduleCompositingLayerSync() +{ + m_webView->setRootLayerNeedsDisplay(); +} +#endif + } // namespace WebKit diff --git a/WebKit/chromium/src/ChromeClientImpl.h b/WebKit/chromium/src/ChromeClientImpl.h index 3a4035b..3b5ebd5 100644 --- a/WebKit/chromium/src/ChromeClientImpl.h +++ b/WebKit/chromium/src/ChromeClientImpl.h @@ -35,6 +35,7 @@ namespace WebCore { class AccessibilityObject; +class FileChooser; class HTMLParserQuirks; class PopupContainer; class SecurityOrigin; @@ -96,9 +97,9 @@ public: virtual bool shouldInterruptJavaScript(); virtual bool tabsToLinks() const; virtual WebCore::IntRect windowResizerRect() const; - virtual void repaint( - const WebCore::IntRect&, bool contentChanged, bool immediate = false, - bool repaintContentOnly = false); + virtual void invalidateWindow(const WebCore::IntRect&, bool); + virtual void invalidateContentsAndWindow(const WebCore::IntRect&, bool); + virtual void invalidateContentsForSlowScroll(const WebCore::IntRect&, bool); virtual void scroll( const WebCore::IntSize& scrollDelta, const WebCore::IntRect& rectToScroll, const WebCore::IntRect& clipRect); @@ -122,17 +123,34 @@ public: virtual WebCore::NotificationPresenter* notificationPresenter() const; #endif virtual void requestGeolocationPermissionForFrame(WebCore::Frame*, WebCore::Geolocation*); + virtual void cancelGeolocationPermissionRequestForFrame(WebCore::Frame*, WebCore::Geolocation*); virtual void runOpenPanel(WebCore::Frame*, PassRefPtr<WebCore::FileChooser>); - virtual void iconForFiles(const Vector<WebCore::String>&, PassRefPtr<WebCore::FileChooser>); + virtual void chooseIconForFiles(const Vector<WebCore::String>&, WebCore::FileChooser*); virtual bool setCursor(WebCore::PlatformCursorHandle) { return false; } virtual void formStateDidChange(const WebCore::Node*); virtual PassOwnPtr<WebCore::HTMLParserQuirks> createHTMLParserQuirks() { return 0; } +#if ENABLE(TOUCH_EVENTS) + // FIXME: All touch events are forwarded regardless of whether or not they are needed. + virtual void needTouchEvents(bool needTouchEvents) { } +#endif + +#if USE(ACCELERATED_COMPOSITING) + // Pass 0 as the GraphicsLayer to detatch the root layer. + virtual void attachRootGraphicsLayer(WebCore::Frame*, WebCore::GraphicsLayer*); + // Sets a flag to specify that the next time content is drawn to the window, + // the changes appear on the screen in synchrony with updates to GraphicsLayers. + virtual void setNeedsOneShotDrawingSynchronization() { } + + // Sets a flag to specify that the view needs to be updated, so we need + // to do an eager layout before the drawing. + virtual void scheduleCompositingLayerSync(); +#endif // ChromeClientChromium methods: virtual void popupOpened(WebCore::PopupContainer* popupContainer, const WebCore::IntRect& bounds, - bool activatable, bool handleExternally); + virtual void popupClosed(WebCore::PopupContainer* popupContainer); virtual void didChangeAccessibilityObjectState(WebCore::AccessibilityObject*); // ChromeClientImpl: @@ -148,8 +166,6 @@ private: bool m_scrollbarsVisible; bool m_menubarVisible; bool m_resizable; - // Set to true if the next SetCursor is to be ignored. - bool m_ignoreNextSetCursor; }; } // namespace WebKit diff --git a/WebKit/chromium/src/ChromiumBridge.cpp b/WebKit/chromium/src/ChromiumBridge.cpp index e04226e..cffd166 100644 --- a/WebKit/chromium/src/ChromiumBridge.cpp +++ b/WebKit/chromium/src/ChromiumBridge.cpp @@ -65,6 +65,7 @@ #if OS(LINUX) #include "WebSandboxSupport.h" #include "WebFontInfo.h" +#include "WebFontRenderStyle.h" #endif #if WEBKIT_USING_SKIA @@ -74,12 +75,14 @@ #include "BitmapImage.h" #include "Cookie.h" #include "FrameView.h" -#include "GeolocationServiceBridgeChromium.h" #include "GraphicsContext.h" +#include "IndexedDatabaseProxy.h" #include "KURL.h" #include "NotImplemented.h" #include "PlatformContextSkia.h" #include "PluginData.h" +#include "SharedBuffer.h" +#include "WebGeolocationServiceBridgeImpl.h" #include "Worker.h" #include "WorkerContextProxy.h" #include <wtf/Assertions.h> @@ -91,6 +94,9 @@ namespace WebCore { static ChromeClientImpl* toChromeClientImpl(Widget* widget) { + if (!widget) + return 0; + FrameView* view; if (widget->isFrameView()) view = static_cast<FrameView*>(widget); @@ -192,8 +198,6 @@ void ChromiumBridge::setCookies(const Document* document, const KURL& url, WebCookieJar* cookieJar = getCookieJar(document); if (cookieJar) cookieJar->setCookie(url, document->firstPartyForCookies(), value); - else - webKitClient()->setCookies(url, document->firstPartyForCookies(), value); // DEPRECATED } String ChromiumBridge::cookies(const Document* document, const KURL& url) @@ -202,8 +206,6 @@ String ChromiumBridge::cookies(const Document* document, const KURL& url) WebCookieJar* cookieJar = getCookieJar(document); if (cookieJar) result = cookieJar->cookies(url, document->firstPartyForCookies()); - else - result = webKitClient()->cookies(url, document->firstPartyForCookies()); // DEPRECATED return result; } @@ -214,10 +216,6 @@ String ChromiumBridge::cookieRequestHeaderFieldValue(const Document* document, WebCookieJar* cookieJar = getCookieJar(document); if (cookieJar) result = cookieJar->cookieRequestHeaderFieldValue(url, document->firstPartyForCookies()); - else { - // FIXME: This does not return http-only cookies - result = webKitClient()->cookies(url, document->firstPartyForCookies()); // DEPRECATED - } return result; } @@ -229,8 +227,6 @@ bool ChromiumBridge::rawCookies(const Document* document, const KURL& url, Vecto WebCookieJar* cookieJar = getCookieJar(document); if (cookieJar) cookieJar->rawCookies(url, document->firstPartyForCookies(), webCookies); - else - webKitClient()->rawCookies(url, document->firstPartyForCookies(), &webCookies); // DEPRECATED for (unsigned i = 0; i < webCookies.size(); ++i) { const WebCookie& webCookie = webCookies[i]; @@ -252,18 +248,14 @@ void ChromiumBridge::deleteCookie(const Document* document, const KURL& url, con WebCookieJar* cookieJar = getCookieJar(document); if (cookieJar) cookieJar->deleteCookie(url, cookieName); - else - webKitClient()->deleteCookie(url, cookieName); // DEPRECATED } bool ChromiumBridge::cookiesEnabled(const Document* document) { - bool result; + bool result = false; WebCookieJar* cookieJar = getCookieJar(document); if (cookieJar) result = cookieJar->cookiesEnabled(document->cookieURL(), document->firstPartyForCookies()); - else - result = webKitClient()->cookiesEnabled(document->cookieURL(), document->firstPartyForCookies()); // DEPRECATED return result; } @@ -298,7 +290,11 @@ bool ChromiumBridge::getFileSize(const String& path, long long& result) bool ChromiumBridge::getFileModificationTime(const String& path, time_t& result) { - return webKitClient()->getFileModificationTime(path, result); + double modificationTime; + if (!webKitClient()->getFileModificationTime(path, modificationTime)) + return false; + result = static_cast<time_t>(modificationTime); + return true; } String ChromiumBridge::directoryName(const String& path) @@ -356,6 +352,18 @@ String ChromiumBridge::getFontFamilyForCharacters(const UChar* characters, size_ return WebString(); } + +void ChromiumBridge::getRenderStyleForStrike(const char* font, int sizeAndStyle, FontRenderStyle* result) +{ + WebFontRenderStyle style; + + if (webKitClient()->sandboxSupport()) + webKitClient()->sandboxSupport()->getRenderStyleForStrike(font, sizeAndStyle, &style); + else + WebFontInfo::renderStyleForStrike(font, sizeAndStyle, &style); + + style.toFontRenderStyle(result); +} #endif // Geolocation ---------------------------------------------------------------- @@ -389,6 +397,15 @@ long long ChromiumBridge::databaseGetFileSize(const String& vfsFileName) } #endif +// Indexed Database ----------------------------------------------------------- + +PassRefPtr<IndexedDatabase> ChromiumBridge::indexedDatabase() +{ + // There's no reason why we need to allocate a new proxy each time, but + // there's also no strong reason not to. + return IndexedDatabaseProxy::create(); +} + // Keygen --------------------------------------------------------------------- String ChromiumBridge::signedPublicKeyAndChallengeString( diff --git a/WebKit/chromium/src/ContextMenuClientImpl.cpp b/WebKit/chromium/src/ContextMenuClientImpl.cpp index 06a29ff..bee4310 100644 --- a/WebKit/chromium/src/ContextMenuClientImpl.cpp +++ b/WebKit/chromium/src/ContextMenuClientImpl.cpp @@ -181,6 +181,10 @@ PlatformMenuDescription ContextMenuClientImpl::getCustomMenuFromDefaultItems( data.mediaFlags |= WebContextMenuData::MediaCanSave; if (mediaElement->hasAudio()) data.mediaFlags |= WebContextMenuData::MediaHasAudio; + if (mediaElement->hasVideo()) + data.mediaFlags |= WebContextMenuData::MediaHasVideo; + if (mediaElement->controls()) + data.mediaFlags |= WebContextMenuData::MediaControls; } data.isImageBlocked = @@ -188,7 +192,7 @@ PlatformMenuDescription ContextMenuClientImpl::getCustomMenuFromDefaultItems( // If it's not a link, an image, a media element, or an image/media link, // show a selection menu or a more generic page menu. - data.frameEncoding = selectedFrame->loader()->encoding(); + data.frameEncoding = selectedFrame->loader()->writer()->encoding(); // Send the frame and page URLs in any case. data.pageURL = urlFromFrame(m_webView->mainFrameImpl()->frame()); diff --git a/WebKit/chromium/src/DatabaseObserver.cpp b/WebKit/chromium/src/DatabaseObserver.cpp index 54e93e1..6a2e2a7 100644 --- a/WebKit/chromium/src/DatabaseObserver.cpp +++ b/WebKit/chromium/src/DatabaseObserver.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009 Google Inc. All rights reserved. + * Copyright (C) 2010 Google Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -32,13 +32,35 @@ #include "DatabaseObserver.h" #include "Database.h" +#include "Document.h" +#include "ScriptExecutionContext.h" #include "WebDatabase.h" #include "WebDatabaseObserver.h" +#include "WebFrameClient.h" +#include "WebFrameImpl.h" +#include "WebSecurityOrigin.h" +#include "WebWorkerImpl.h" +#include "WorkerContext.h" +#include "WorkerThread.h" using namespace WebKit; namespace WebCore { +bool DatabaseObserver::canEstablishDatabase(ScriptExecutionContext* scriptExecutionContext, const String& name, const String& displayName, unsigned long estimatedSize) +{ + ASSERT(scriptExecutionContext->isContextThread()); + // FIXME: add support for the case scriptExecutionContext()->isWorker() once workers implement web databases. + ASSERT(scriptExecutionContext->isDocument()); + if (scriptExecutionContext->isDocument()) { + Document* document = static_cast<Document*>(scriptExecutionContext); + WebFrameImpl* webFrame = WebFrameImpl::fromFrame(document->frame()); + return webFrame->client()->allowDatabase(webFrame, name, displayName, estimatedSize); + } + + return true; +} + void DatabaseObserver::databaseOpened(Database* database) { ASSERT(isMainThread()); diff --git a/WebKit/chromium/src/DebuggerAgent.h b/WebKit/chromium/src/DebuggerAgent.h index 17cde11..7f3dbbb 100644 --- a/WebKit/chromium/src/DebuggerAgent.h +++ b/WebKit/chromium/src/DebuggerAgent.h @@ -40,7 +40,10 @@ namespace WebKit { METHOD0(getContextId) \ \ /* Request v8 to process all debug commands in the queue. */ \ - METHOD0(processDebugCommands) + METHOD0(processDebugCommands) \ + \ + /* Push DebuggerScript.js content to the agent. */ \ + METHOD1(setDebuggerScriptSource, String) DEFINE_RPC_CLASS(DebuggerAgent, DEBUGGER_AGENT_STRUCT) diff --git a/WebKit/chromium/src/DebuggerAgentImpl.cpp b/WebKit/chromium/src/DebuggerAgentImpl.cpp index d592710..673482a 100644 --- a/WebKit/chromium/src/DebuggerAgentImpl.cpp +++ b/WebKit/chromium/src/DebuggerAgentImpl.cpp @@ -35,10 +35,8 @@ #include "Document.h" #include "Frame.h" #include "Page.h" +#include "ScriptDebugServer.h" #include "V8Binding.h" -#include "V8DOMWindow.h" -#include "V8Index.h" -#include "V8Proxy.h" #include "WebDevToolsAgentImpl.h" #include "WebViewImpl.h" #include <wtf/HashSet.h> @@ -50,10 +48,6 @@ using WebCore::Document; using WebCore::Frame; using WebCore::Page; using WebCore::String; -using WebCore::V8ClassIndex; -using WebCore::V8DOMWindow; -using WebCore::V8DOMWrapper; -using WebCore::V8Proxy; namespace WebKit { @@ -85,62 +79,15 @@ void DebuggerAgentImpl::processDebugCommands() v8::Debug::ProcessDebugMessages(); } -void DebuggerAgentImpl::debuggerOutput(const String& command) +void DebuggerAgentImpl::setDebuggerScriptSource(const String& source) { - m_delegate->debuggerOutput(command); - m_webdevtoolsAgent->forceRepaint(); + WebCore::ScriptDebugServer::shared().setDebuggerScriptSource(source); } -// static -void DebuggerAgentImpl::createUtilityContext(Frame* frame, v8::Persistent<v8::Context>* context) +void DebuggerAgentImpl::debuggerOutput(const String& command) { - v8::HandleScope scope; - bool canExecuteScripts = frame->script()->canExecuteScripts(); - - // Set up the DOM window as the prototype of the new global object. - v8::Handle<v8::Context> windowContext = V8Proxy::context(frame); - v8::Handle<v8::Object> windowGlobal; - v8::Handle<v8::Object> windowWrapper; - if (canExecuteScripts) { - // FIXME: This check prevents renderer from crashing, while providing limited capabilities for - // DOM inspection, Resources tracking, no scripts support, some timeline profiling. Console will - // result in exceptions for each evaluation. There is still some work that needs to be done in - // order to polish the script-less experience. - windowGlobal = windowContext->Global(); - windowWrapper = V8DOMWrapper::lookupDOMWrapper(V8DOMWindow::GetTemplate(), windowGlobal); - ASSERT(V8DOMWindow::toNative(windowWrapper) == frame->domWindow()); - } - - v8::Handle<v8::ObjectTemplate> globalTemplate = v8::ObjectTemplate::New(); - - // TODO(yurys): provide a function in v8 bindings that would make the - // utility context more like main world context of the inspected frame, - // otherwise we need to manually make it satisfy various invariants - // that V8Proxy::getEntered and some other V8Proxy methods expect to find - // on v8 contexts on the contexts stack. - // See V8Proxy::createNewContext. - // - // Install a security handler with V8. - globalTemplate->SetAccessCheckCallbacks( - V8DOMWindow::namedSecurityCheck, - V8DOMWindow::indexedSecurityCheck, - v8::Integer::New(V8ClassIndex::DOMWINDOW)); - // We set number of internal fields to match that in V8DOMWindow wrapper. - // See http://crbug.com/28961 - globalTemplate->SetInternalFieldCount(V8DOMWindow::internalFieldCount); - - *context = v8::Context::New(0 /* no extensions */, globalTemplate, v8::Handle<v8::Object>()); - v8::Context::Scope contextScope(*context); - v8::Handle<v8::Object> global = (*context)->Global(); - - v8::Handle<v8::String> implicitProtoString = v8::String::New("__proto__"); - if (canExecuteScripts) - global->Set(implicitProtoString, windowWrapper); - - // Give the code running in the new context a way to get access to the - // original context. - if (canExecuteScripts) - global->Set(v8::String::New("contentWindow"), windowGlobal); + m_delegate->debuggerOutput(command); + m_webdevtoolsAgent->forceRepaint(); } String DebuggerAgentImpl::executeUtilityFunction( diff --git a/WebKit/chromium/src/DebuggerAgentImpl.h b/WebKit/chromium/src/DebuggerAgentImpl.h index 6eaf576..bd9ddf6 100644 --- a/WebKit/chromium/src/DebuggerAgentImpl.h +++ b/WebKit/chromium/src/DebuggerAgentImpl.h @@ -52,9 +52,6 @@ class WebViewImpl; class DebuggerAgentImpl : public DebuggerAgent { public: - // Creates utility context with injected js agent. - static void createUtilityContext(WebCore::Frame* frame, v8::Persistent<v8::Context>* context); - DebuggerAgentImpl(WebKit::WebViewImpl* webViewImpl, DebuggerAgentDelegate* delegate, WebDevToolsAgentImpl* webdevtoolsAgent); @@ -63,6 +60,7 @@ public: // DebuggerAgent implementation. virtual void getContextId(); virtual void processDebugCommands(); + virtual void setDebuggerScriptSource(const String&); void debuggerOutput(const WebCore::String& out); diff --git a/WebKit/chromium/src/DebuggerAgentManager.cpp b/WebKit/chromium/src/DebuggerAgentManager.cpp index faafaff..d3f7fea 100644 --- a/WebKit/chromium/src/DebuggerAgentManager.cpp +++ b/WebKit/chromium/src/DebuggerAgentManager.cpp @@ -34,6 +34,7 @@ #include "DebuggerAgentImpl.h" #include "Frame.h" #include "PageGroupLoadDeferrer.h" +#include "ScriptDebugServer.h" #include "V8Proxy.h" #include "WebDevToolsAgentImpl.h" #include "WebFrameImpl.h" @@ -72,6 +73,42 @@ private: } // namespace +void DebuggerAgentManager::hostDispatchHandler(const Vector<WebCore::Page*>& pages) +{ + if (!s_messageLoopDispatchHandler) + return; + + if (s_inHostDispatchHandler) + return; + + s_inHostDispatchHandler = true; + + Vector<WebViewImpl*> views; + // 1. Disable active objects and input events. + for (size_t i = 0; i < pages.size(); i++) { + WebCore::Page* page = pages[i]; + WebViewImpl* view = WebViewImpl::fromPage(page); + s_pageDeferrers.set(view , new WebCore::PageGroupLoadDeferrer(page, true)); + views.append(view); + view->setIgnoreInputEvents(true); + } + + // 2. Process messages. + s_messageLoopDispatchHandler(); + + // 3. Bring things back. + for (Vector<WebViewImpl*>::iterator it = views.begin(); it != views.end(); ++it) { + if (s_pageDeferrers.contains(*it)) { + // The view was not closed during the dispatch. + (*it)->setIgnoreInputEvents(false); + } + } + deleteAllValues(s_pageDeferrers); + s_pageDeferrers.clear(); + + s_inHostDispatchHandler = false; +} + void DebuggerAgentManager::debugHostDispatchHandler() { if (!s_messageLoopDispatchHandler || !s_attachedAgentsMap) @@ -116,6 +153,9 @@ DebuggerAgentManager::AttachedAgentsMap* DebuggerAgentManager::s_attachedAgentsM void DebuggerAgentManager::debugAttach(DebuggerAgentImpl* debuggerAgent) { +#if ENABLE(V8_SCRIPT_DEBUG_SERVER) + return; +#endif if (!s_attachedAgentsMap) { s_attachedAgentsMap = new AttachedAgentsMap(); v8::Debug::SetMessageHandler2(&DebuggerAgentManager::onV8DebugMessage); @@ -128,6 +168,9 @@ void DebuggerAgentManager::debugAttach(DebuggerAgentImpl* debuggerAgent) void DebuggerAgentManager::debugDetach(DebuggerAgentImpl* debuggerAgent) { +#if ENABLE(V8_SCRIPT_DEBUG_SERVER) + return; +#endif if (!s_attachedAgentsMap) { ASSERT_NOT_REACHED(); return; @@ -249,6 +292,7 @@ void DebuggerAgentManager::executeDebuggerCommand(const String& command, int cal void DebuggerAgentManager::setMessageLoopDispatchHandler(WebDevToolsAgent::MessageLoopDispatchHandler handler) { s_messageLoopDispatchHandler = handler; + WebCore::ScriptDebugServer::setMessageLoopDispatchHandler(DebuggerAgentManager::hostDispatchHandler); } void DebuggerAgentManager::setHostId(WebFrameImpl* webframe, int hostId) diff --git a/WebKit/chromium/src/DebuggerAgentManager.h b/WebKit/chromium/src/DebuggerAgentManager.h index a2e9030..a8bc7a3 100644 --- a/WebKit/chromium/src/DebuggerAgentManager.h +++ b/WebKit/chromium/src/DebuggerAgentManager.h @@ -31,12 +31,15 @@ #ifndef DebuggerAgentManager_h #define DebuggerAgentManager_h +#include "WebCString.h" #include "WebDevToolsAgent.h" #include <v8-debug.h> #include <wtf/HashMap.h> #include <wtf/Noncopyable.h> +#include <wtf/Vector.h> namespace WebCore { +class Page; class PageGroupLoadDeferrer; class String; } @@ -97,6 +100,7 @@ private: DebuggerAgentManager(); ~DebuggerAgentManager(); + static void hostDispatchHandler(const Vector<WebCore::Page*>&); static void debugHostDispatchHandler(); static void onV8DebugMessage(const v8::Debug::Message& message); static void sendCommandToV8(const WebCore::String& cmd, diff --git a/WebKit/chromium/src/DragClientImpl.cpp b/WebKit/chromium/src/DragClientImpl.cpp index 671e7ca..9874401 100644 --- a/WebKit/chromium/src/DragClientImpl.cpp +++ b/WebKit/chromium/src/DragClientImpl.cpp @@ -30,11 +30,14 @@ #include "config.h" #include "DragClientImpl.h" - +#include "DragImageRef.h" #include "ChromiumDataObject.h" #include "ClipboardChromium.h" #include "Frame.h" +#include "NativeImageSkia.h" +#include "WebCommon.h" #include "WebDragData.h" +#include "WebImage.h" #include "WebViewClient.h" #include "WebViewImpl.h" @@ -81,8 +84,16 @@ void DragClientImpl::startDrag(DragImageRef dragImage, DragOperation dragOperationMask = clipboard->sourceOperation(); + IntSize offsetSize(eventPos - dragImageOrigin); + WebPoint offsetPoint(offsetSize.width(), offsetSize.height()); m_webView->startDragging( - eventPos, dragData, static_cast<WebDragOperationsMask>(dragOperationMask)); + dragData, static_cast<WebDragOperationsMask>(dragOperationMask), +#if WEBKIT_USING_SKIA + dragImage ? WebImage(*dragImage) : WebImage(), +#else + dragImage ? WebImage(dragImage) : WebImage(), +#endif + offsetPoint); } DragImageRef DragClientImpl::createDragImageForLink(KURL&, const String& label, Frame*) diff --git a/WebKit/chromium/src/EditorClientImpl.cpp b/WebKit/chromium/src/EditorClientImpl.cpp index cfd8ec4..4ecdcf7 100644 --- a/WebKit/chromium/src/EditorClientImpl.cpp +++ b/WebKit/chromium/src/EditorClientImpl.cpp @@ -413,8 +413,10 @@ static const KeyDownEntry keyDownEntries[] = { { VKEY_DOWN, 0, "MoveDown" }, { VKEY_DOWN, ShiftKey, "MoveDownAndModifySelection" }, { VKEY_NEXT, ShiftKey, "MovePageDownAndModifySelection" }, +#if !OS(DARWIN) { VKEY_PRIOR, 0, "MovePageUp" }, { VKEY_NEXT, 0, "MovePageDown" }, +#endif { VKEY_HOME, 0, "MoveToBeginningOfLine" }, { VKEY_HOME, ShiftKey, "MoveToBeginningOfLineAndModifySelection" }, @@ -422,6 +424,8 @@ static const KeyDownEntry keyDownEntries[] = { { VKEY_LEFT, CommandKey, "MoveToBeginningOfLine" }, { VKEY_LEFT, CommandKey | ShiftKey, "MoveToBeginningOfLineAndModifySelection" }, + { VKEY_PRIOR, OptionKey, "MovePageUp" }, + { VKEY_NEXT, OptionKey, "MovePageDown" }, #endif #if OS(DARWIN) { VKEY_UP, CommandKey, "MoveToBeginningOfDocument" }, @@ -703,8 +707,9 @@ bool EditorClientImpl::autofill(HTMLInputElement* inputElement, // Let's try to trigger autofill for that field, if applicable. if (!inputElement->isEnabledFormControl() || !inputElement->isTextField() - || inputElement->isPasswordField() - || !inputElement->autoComplete()) + || inputElement->isPasswordField() || !inputElement->autoComplete() + || !inputElement->isEnabledFormControl() + || inputElement->isReadOnlyFormControl()) return false; WebString name = WebInputElement(inputElement).nameForAutofill(); diff --git a/WebKit/chromium/src/FrameLoaderClientImpl.cpp b/WebKit/chromium/src/FrameLoaderClientImpl.cpp index 8fb267d..135392b 100644 --- a/WebKit/chromium/src/FrameLoaderClientImpl.cpp +++ b/WebKit/chromium/src/FrameLoaderClientImpl.cpp @@ -32,12 +32,13 @@ #include "FrameLoaderClientImpl.h" #include "Chrome.h" -#include "CString.h" #include "Document.h" #include "DocumentLoader.h" #include "FormState.h" #include "FrameLoader.h" #include "FrameLoadRequest.h" +#include "HTTPParsers.h" +#include "HistoryItem.h" #include "HitTestResult.h" #include "HTMLAppletElement.h" #include "HTMLFormElement.h" // needed by FormState.h @@ -71,6 +72,7 @@ #include "WindowFeatures.h" #include "WrappedResourceRequest.h" #include "WrappedResourceResponse.h" +#include <wtf/text/CString.h> using namespace WebCore; @@ -180,6 +182,18 @@ bool FrameLoaderClientImpl::allowImages(bool enabledPerSettings) return enabledPerSettings; } +void FrameLoaderClientImpl::didNotAllowScript() +{ + if (m_webFrame->client()) + m_webFrame->client()->didNotAllowScript(m_webFrame); +} + +void FrameLoaderClientImpl::didNotAllowPlugins() +{ + if (m_webFrame->client()) + m_webFrame->client()->didNotAllowPlugins(m_webFrame); +} + bool FrameLoaderClientImpl::hasWebView() const { return m_webFrame->viewImpl(); @@ -392,12 +406,6 @@ bool FrameLoaderClientImpl::dispatchDidLoadResourceFromMemoryCache( return false; // Do not suppress remaining notifications } -void FrameLoaderClientImpl::dispatchDidLoadResourceByXMLHttpRequest( - unsigned long identifier, - const ScriptString& source) -{ -} - void FrameLoaderClientImpl::dispatchDidHandleOnloadEvents() { if (m_webFrame->client()) @@ -556,7 +564,7 @@ void FrameLoaderClientImpl::dispatchWillPerformClientRedirect( } } -void FrameLoaderClientImpl::dispatchDidChangeLocationWithinPage() +void FrameLoaderClientImpl::dispatchDidNavigateWithinPage() { // Anchor fragment navigations are not normal loads, so we need to synthesize // some events for our delegate. @@ -567,12 +575,17 @@ void FrameLoaderClientImpl::dispatchDidChangeLocationWithinPage() // them for fragment redirection that happens in window.onload handler. // See https://bugs.webkit.org/show_bug.cgi?id=31838 bool loaderCompleted = - !m_webFrame->frame()->page()->mainFrame()->loader()->isLoading(); + !webView->page()->mainFrame()->loader()->activeDocumentLoader()->isLoadingInAPISense(); // Generate didStartLoading if loader is completed. if (webView->client() && loaderCompleted) webView->client()->didStartLoading(); + // We need to classify some hash changes as client redirects. + // FIXME: It seems wrong that the currentItem can sometimes be null. + HistoryItem* currentItem = m_webFrame->frame()->loader()->history()->currentItem(); + bool isHashChange = !currentItem || !currentItem->stateObject(); + WebDataSourceImpl* ds = m_webFrame->dataSourceImpl(); ASSERT(ds); // Should not be null when navigating to a reference fragment! if (ds) { @@ -583,27 +596,29 @@ void FrameLoaderClientImpl::dispatchDidChangeLocationWithinPage() ds->clearRedirectChain(); } - // Figure out if this location change is because of a JS-initiated - // client redirect (e.g onload/setTimeout document.location.href=). - // FIXME: (bugs 1085325, 1046841) We don't get proper redirect - // performed/cancelled notifications across anchor navigations, so the - // other redirect-tracking code in this class (see - // dispatch*ClientRedirect() and dispatchDidStartProvisionalLoad) is - // insufficient to catch and properly flag these transitions. Once a - // proper fix for this bug is identified and applied the following - // block may no longer be required. - bool wasClientRedirect = - (url == m_expectedClientRedirectDest && chainEnd == m_expectedClientRedirectSrc) - || !m_webFrame->isProcessingUserGesture(); - - if (wasClientRedirect) { - if (m_webFrame->client()) - m_webFrame->client()->didCompleteClientRedirect(m_webFrame, chainEnd); - ds->appendRedirect(chainEnd); - // Make sure we clear the expected redirect since we just effectively - // completed it. - m_expectedClientRedirectSrc = KURL(); - m_expectedClientRedirectDest = KURL(); + if (isHashChange) { + // Figure out if this location change is because of a JS-initiated + // client redirect (e.g onload/setTimeout document.location.href=). + // FIXME: (b/1085325, b/1046841) We don't get proper redirect + // performed/cancelled notifications across anchor navigations, so the + // other redirect-tracking code in this class (see + // dispatch*ClientRedirect() and dispatchDidStartProvisionalLoad) is + // insufficient to catch and properly flag these transitions. Once a + // proper fix for this bug is identified and applied the following + // block may no longer be required. + bool wasClientRedirect = + (url == m_expectedClientRedirectDest && chainEnd == m_expectedClientRedirectSrc) + || !m_webFrame->isProcessingUserGesture(); + + if (wasClientRedirect) { + if (m_webFrame->client()) + m_webFrame->client()->didCompleteClientRedirect(m_webFrame, chainEnd); + ds->appendRedirect(chainEnd); + // Make sure we clear the expected redirect since we just effectively + // completed it. + m_expectedClientRedirectSrc = KURL(); + m_expectedClientRedirectDest = KURL(); + } } // Regardless of how we got here, we are navigating to a URL so we need to @@ -613,27 +628,38 @@ void FrameLoaderClientImpl::dispatchDidChangeLocationWithinPage() bool isNewNavigation; webView->didCommitLoad(&isNewNavigation); - if (m_webFrame->client()) - m_webFrame->client()->didChangeLocationWithinPage(m_webFrame, isNewNavigation); + if (m_webFrame->client()) { + m_webFrame->client()->didNavigateWithinPage(m_webFrame, isNewNavigation); + + // FIXME: Remove this notification once it is no longer consumed downstream. + if (isHashChange) + m_webFrame->client()->didChangeLocationWithinPage(m_webFrame, isNewNavigation); + } // Generate didStopLoading if loader is completed. if (webView->client() && loaderCompleted) webView->client()->didStopLoading(); } +void FrameLoaderClientImpl::dispatchDidChangeLocationWithinPage() +{ + if (m_webFrame) + m_webFrame->client()->didChangeLocationWithinPage(m_webFrame); +} + void FrameLoaderClientImpl::dispatchDidPushStateWithinPage() { - // FIXME + dispatchDidNavigateWithinPage(); } void FrameLoaderClientImpl::dispatchDidReplaceStateWithinPage() { - // FIXME + dispatchDidNavigateWithinPage(); } void FrameLoaderClientImpl::dispatchDidPopStateWithinPage() { - // FIXME + // Ignored since dispatchDidNavigateWithinPage was already called. } void FrameLoaderClientImpl::dispatchWillClose() @@ -797,38 +823,6 @@ void FrameLoaderClientImpl::dispatchShow() webView->client()->show(webView->initialNavigationPolicy()); } -static bool shouldTreatAsAttachment(const ResourceResponse& response) -{ - const String& contentDisposition = - response.httpHeaderField("Content-Disposition"); - if (contentDisposition.isEmpty()) - return false; - - // Some broken sites just send - // Content-Disposition: ; filename="file" - // screen those out here. - if (contentDisposition.startsWith(";")) - return false; - - if (contentDisposition.startsWith("inline", false)) - return false; - - // Some broken sites just send - // Content-Disposition: filename="file" - // without a disposition token... screen those out. - if (contentDisposition.startsWith("filename", false)) - return false; - - // Also in use is Content-Disposition: name="file" - if (contentDisposition.startsWith("name", false)) - return false; - - // We have a content-disposition of "attachment" or unknown. - // RFC 2183, section 2.8 says that an unknown disposition - // value should be treated as "attachment" - return true; -} - void FrameLoaderClientImpl::dispatchDecidePolicyForMIMEType( FramePolicyFunction function, const String& mimeType, @@ -843,7 +837,7 @@ void FrameLoaderClientImpl::dispatchDecidePolicyForMIMEType( if (statusCode == 204 || statusCode == 205) { // The server does not want us to replace the page contents. action = PolicyIgnore; - } else if (shouldTreatAsAttachment(response)) { + } else if (WebCore::contentDispositionType(response.httpHeaderField("Content-Disposition")) == WebCore::ContentDispositionAttachment) { // The server wants us to download instead of replacing the page contents. // Downloading is handled by the embedder, but we still get the initial // response so that we can ignore it and clean up properly. @@ -898,51 +892,48 @@ void FrameLoaderClientImpl::dispatchDecidePolicyForNavigationAction( // The null check here is to fix a crash that seems strange // (see - https://bugs.webkit.org/show_bug.cgi?id=23554). if (m_webFrame->client() && !request.url().isNull()) { - WebNavigationPolicy navigationPolicy = WebNavigationPolicyCurrentTab; - actionSpecifiesNavigationPolicy(action, &navigationPolicy); - - // Give the delegate a chance to change the navigation policy. - const WebDataSourceImpl* ds = m_webFrame->provisionalDataSourceImpl(); - if (ds) { - KURL url = ds->request().url(); - if (url.protocolIs(backForwardNavigationScheme)) { - handleBackForwardNavigation(url); - navigationPolicy = WebNavigationPolicyIgnore; - } else { - bool isRedirect = ds->hasRedirectChain(); - - WebNavigationType webnavType = - WebDataSourceImpl::toWebNavigationType(action.type()); - - RefPtr<Node> node; - for (const Event* event = action.event(); event; event = event->underlyingEvent()) { - if (event->isMouseEvent()) { - const MouseEvent* mouseEvent = - static_cast<const MouseEvent*>(event); - node = m_webFrame->frame()->eventHandler()->hitTestResultAtPoint( - mouseEvent->absoluteLocation(), false).innerNonSharedNode(); - break; - } - } - WebNode originatingNode(node); - - navigationPolicy = m_webFrame->client()->decidePolicyForNavigation( - m_webFrame, ds->request(), webnavType, originatingNode, - navigationPolicy, isRedirect); - } - } - - if (navigationPolicy == WebNavigationPolicyCurrentTab) - policyAction = PolicyUse; - else if (navigationPolicy == WebNavigationPolicyDownload) - policyAction = PolicyDownload; - else { - if (navigationPolicy != WebNavigationPolicyIgnore) { - WrappedResourceRequest webreq(request); - m_webFrame->client()->loadURLExternally(m_webFrame, webreq, navigationPolicy); - } - policyAction = PolicyIgnore; - } + WebNavigationPolicy navigationPolicy = WebNavigationPolicyCurrentTab; + actionSpecifiesNavigationPolicy(action, &navigationPolicy); + + // Give the delegate a chance to change the navigation policy. + const WebDataSourceImpl* ds = m_webFrame->provisionalDataSourceImpl(); + if (ds) { + KURL url = ds->request().url(); + ASSERT(!url.protocolIs(backForwardNavigationScheme)); + + bool isRedirect = ds->hasRedirectChain(); + + WebNavigationType webnavType = + WebDataSourceImpl::toWebNavigationType(action.type()); + + RefPtr<Node> node; + for (const Event* event = action.event(); event; event = event->underlyingEvent()) { + if (event->isMouseEvent()) { + const MouseEvent* mouseEvent = + static_cast<const MouseEvent*>(event); + node = m_webFrame->frame()->eventHandler()->hitTestResultAtPoint( + mouseEvent->absoluteLocation(), false).innerNonSharedNode(); + break; + } + } + WebNode originatingNode(node); + + navigationPolicy = m_webFrame->client()->decidePolicyForNavigation( + m_webFrame, ds->request(), webnavType, originatingNode, + navigationPolicy, isRedirect); + } + + if (navigationPolicy == WebNavigationPolicyCurrentTab) + policyAction = PolicyUse; + else if (navigationPolicy == WebNavigationPolicyDownload) + policyAction = PolicyDownload; + else { + if (navigationPolicy != WebNavigationPolicyIgnore) { + WrappedResourceRequest webreq(request); + m_webFrame->client()->loadURLExternally(m_webFrame, webreq, navigationPolicy); + } + policyAction = PolicyIgnore; + } } (m_webFrame->frame()->loader()->policyChecker()->*function)(policyAction); @@ -1075,7 +1066,7 @@ void FrameLoaderClientImpl::finishedLoading(DocumentLoader* dl) // However, we only want to do this if makeRepresentation has been called, to // match the behavior on the Mac. if (m_hasRepresentation) - dl->frameLoader()->setEncoding("", false); + dl->frameLoader()->writer()->setEncoding("", false); } } @@ -1087,10 +1078,28 @@ void FrameLoaderClientImpl::updateGlobalHistoryRedirectLinks() { } -bool FrameLoaderClientImpl::shouldGoToHistoryItem(HistoryItem*) const +bool FrameLoaderClientImpl::shouldGoToHistoryItem(HistoryItem* item) const { - // FIXME - return true; + const KURL& url = item->url(); + if (!url.protocolIs(backForwardNavigationScheme)) + return true; + + // Else, we'll punt this history navigation to the embedder. It is + // necessary that we intercept this here, well before the FrameLoader + // has made any state changes for this history traversal. + + bool ok; + int offset = url.lastPathComponent().toIntStrict(&ok); + if (!ok) { + ASSERT_NOT_REACHED(); + return false; + } + + WebViewImpl* webview = m_webFrame->viewImpl(); + if (webview->client()) + webview->client()->navigateBackForwardSoon(offset); + + return false; } void FrameLoaderClientImpl::dispatchDidAddBackForwardItem(HistoryItem*) const @@ -1465,29 +1474,24 @@ bool FrameLoaderClientImpl::actionSpecifiesNavigationPolicy( const NavigationAction& action, WebNavigationPolicy* policy) { - if ((action.type() != NavigationTypeLinkClicked) || !action.event()->isMouseEvent()) + const MouseEvent* event = 0; + if (action.type() == NavigationTypeLinkClicked + && action.event()->isMouseEvent()) + event = static_cast<const MouseEvent*>(action.event()); + else if (action.type() == NavigationTypeFormSubmitted + && action.event() + && action.event()->underlyingEvent() + && action.event()->underlyingEvent()->isMouseEvent()) + event = static_cast<const MouseEvent*>(action.event()->underlyingEvent()); + + if (!event) return false; - const MouseEvent* event = static_cast<const MouseEvent*>(action.event()); return WebViewImpl::navigationPolicyFromMouseEvent( event->button(), event->ctrlKey(), event->shiftKey(), event->altKey(), event->metaKey(), policy); } -void FrameLoaderClientImpl::handleBackForwardNavigation(const KURL& url) -{ - ASSERT(url.protocolIs(backForwardNavigationScheme)); - - bool ok; - int offset = url.lastPathComponent().toIntStrict(&ok); - if (!ok) - return; - - WebViewImpl* webview = m_webFrame->viewImpl(); - if (webview->client()) - webview->client()->navigateBackForwardSoon(offset); -} - PassOwnPtr<WebPluginLoadObserver> FrameLoaderClientImpl::pluginLoadObserver() { WebDataSourceImpl* ds = WebDataSourceImpl::fromDocumentLoader( diff --git a/WebKit/chromium/src/FrameLoaderClientImpl.h b/WebKit/chromium/src/FrameLoaderClientImpl.h index 8a39393..1cbc1de 100644 --- a/WebKit/chromium/src/FrameLoaderClientImpl.h +++ b/WebKit/chromium/src/FrameLoaderClientImpl.h @@ -89,11 +89,11 @@ public: virtual void dispatchDidFinishLoading(WebCore::DocumentLoader*, unsigned long identifier); virtual void dispatchDidFailLoading(WebCore::DocumentLoader*, unsigned long identifier, const WebCore::ResourceError&); virtual bool dispatchDidLoadResourceFromMemoryCache(WebCore::DocumentLoader*, const WebCore::ResourceRequest&, const WebCore::ResourceResponse&, int length); - virtual void dispatchDidLoadResourceByXMLHttpRequest(unsigned long identifier, const WebCore::ScriptString&); virtual void dispatchDidHandleOnloadEvents(); virtual void dispatchDidReceiveServerRedirectForProvisionalLoad(); virtual void dispatchDidCancelClientRedirect(); virtual void dispatchWillPerformClientRedirect(const WebCore::KURL&, double interval, double fireDate); + virtual void dispatchDidNavigateWithinPage(); virtual void dispatchDidChangeLocationWithinPage(); virtual void dispatchDidPushStateWithinPage(); virtual void dispatchDidReplaceStateWithinPage(); @@ -195,6 +195,8 @@ public: virtual bool allowJavaScript(bool enabledPerSettings); virtual bool allowPlugins(bool enabledPerSettings); virtual bool allowImages(bool enabledPerSettings); + virtual void didNotAllowScript(); + virtual void didNotAllowPlugins(); private: void makeDocumentView(); @@ -204,9 +206,6 @@ private: static bool actionSpecifiesNavigationPolicy( const WebCore::NavigationAction& action, WebNavigationPolicy* policy); - // Called when a dummy back-forward navigation is intercepted. - void handleBackForwardNavigation(const WebCore::KURL&); - PassOwnPtr<WebPluginLoadObserver> pluginLoadObserver(); // The WebFrame that owns this object and manages its lifetime. Therefore, diff --git a/WebKit/chromium/src/GLES2Context.cpp b/WebKit/chromium/src/GLES2Context.cpp new file mode 100644 index 0000000..9dd4eff --- /dev/null +++ b/WebKit/chromium/src/GLES2Context.cpp @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2010 Google 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: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER OR 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 "GLES2Context.h" +#include "WebGLES2Context.h" +#include "WebKit.h" +#include "WebKitClient.h" +#include "WebViewImpl.h" +#include <wtf/OwnPtr.h> + +// There are two levels of delegation in this file: +// +// 1. GLES2Context delegates to GLES2ContextInternal. This is done +// so that we have some place to store data members common among +// implementations. +// +// 2. GLES2ContextInternal delegates to an implementation of +// WebGLES2Context. This is done so we have a place to inject an +// implementation which creates the GL ES context. + +namespace WebCore { + +class GLES2ContextInternal { +public: + GLES2ContextInternal() {} + ~GLES2ContextInternal() {} + + bool initialize(Page*); + + WebKit::WebGLES2Context* getWebGLES2Context() { return m_impl.get(); } + +private: + OwnPtr<WebKit::WebGLES2Context> m_impl; +}; + +bool GLES2ContextInternal::initialize(Page* page) +{ + m_impl = WebKit::webKitClient()->createGLES2Context(); + if (!m_impl) + return false; + + WebKit::WebViewImpl* webView = WebKit::WebViewImpl::fromPage(page); + if (!m_impl->initialize(webView)) { + m_impl.clear(); + return false; + } + return true; +} + +PassOwnPtr<GLES2Context> GLES2Context::create(Page* page) +{ + GLES2ContextInternal* internal = new GLES2ContextInternal(); + if (!internal->initialize(page)) { + delete internal; + return 0; + } + PassOwnPtr<GLES2Context> result = new GLES2Context(); + result->m_internal.set(internal); + return result; +} + +GLES2Context::~GLES2Context() +{ +} + +bool GLES2Context::makeCurrent() +{ + WebKit::WebGLES2Context* webContext = m_internal->getWebGLES2Context(); + if (!webContext) + return false; + return webContext->makeCurrent(); +} + +bool GLES2Context::destroy() +{ + WebKit::WebGLES2Context* webContext = m_internal->getWebGLES2Context(); + if (!webContext) + return false; + return webContext->destroy(); +} + +bool GLES2Context::swapBuffers() +{ + WebKit::WebGLES2Context* webContext = m_internal->getWebGLES2Context(); + if (!webContext) + return false; + return webContext->swapBuffers(); +} + +} // namespace WebCore diff --git a/WebKit/chromium/src/GraphicsContext3D.cpp b/WebKit/chromium/src/GraphicsContext3D.cpp index 807a794..0f9c959 100644 --- a/WebKit/chromium/src/GraphicsContext3D.cpp +++ b/WebKit/chromium/src/GraphicsContext3D.cpp @@ -35,12 +35,10 @@ #include "GraphicsContext3D.h" #include "CachedImage.h" -#include "CString.h" #include "HTMLCanvasElement.h" #include "HTMLImageElement.h" #include "ImageBuffer.h" #include "ImageData.h" -#include "NotImplemented.h" #include "WebGLBuffer.h" #include "WebGLByteArray.h" #include "WebGLFloatArray.h" @@ -52,39 +50,42 @@ #include "WebGLShader.h" #include "WebGLTexture.h" #include "WebGLUnsignedByteArray.h" +#include "WebGraphicsContext3D.h" +#include "WebGraphicsContext3DDefaultImpl.h" +#include "WebKit.h" +#include "WebKitClient.h" #include <stdio.h> #include <wtf/FastMalloc.h> - -#if OS(WINDOWS) -#include <windows.h> -#endif - -#include "GL/glew.h" +#include <wtf/text/CString.h> #if PLATFORM(CG) #include "GraphicsContext.h" #include <CoreGraphics/CGContext.h> #include <CoreGraphics/CGImage.h> -#include <OpenGL/OpenGL.h> -#else -#define FLIP_FRAMEBUFFER_VERTICALLY -#endif - -#if OS(DARWIN) -#define USE_TEXTURE_RECTANGLE_FOR_FRAMEBUFFER -#endif - -#if OS(LINUX) -#include <dlfcn.h> -#include "GL/glxew.h" #endif -using namespace std; +// using namespace std; + +// There are two levels of delegation in this file: +// +// 1. GraphicsContext3D delegates to GraphicsContext3DInternal. This is done +// so that we have some place to store data members common among +// implementations; GraphicsContext3D only provides us the m_internal +// pointer. We always delegate to the GraphicsContext3DInternal. While we +// could sidestep it and go directly to the WebGraphicsContext3D in some +// cases, it is better for consistency to always delegate through it. +// +// 2. GraphicsContext3DInternal delegates to an implementation of +// WebGraphicsContext3D. This is done so we have a place to inject an +// implementation which remotes the OpenGL calls across processes. +// +// The legacy, in-process, implementation uses WebGraphicsContext3DDefaultImpl. namespace WebCore { -// GraphicsContext3DInternal ----------------------------------------------------- +//---------------------------------------------------------------------- +// GraphicsContext3DInternal // Uncomment this to render to a separate window for debugging // #define RENDER_TO_DEBUGGING_WINDOW @@ -93,744 +94,324 @@ namespace WebCore { class GraphicsContext3DInternal { public: - GraphicsContext3DInternal(GraphicsContext3D::Attributes attrs); + GraphicsContext3DInternal(); ~GraphicsContext3DInternal(); - bool makeContextCurrent(); + bool initialize(GraphicsContext3D::Attributes attrs); PlatformGraphicsContext3D platformGraphicsContext3D() const; Platform3DObject platformTexture() const; + bool makeContextCurrent(); + + int sizeInBytes(int type); + void reshape(int width, int height); void beginPaint(WebGLRenderingContext* context); + void endPaint(); - bool validateTextureTarget(int target); - bool validateTextureParameter(int param); - + //---------------------------------------------------------------------- + // Entry points for WebGL. + // void activeTexture(unsigned long texture); - void bindBuffer(unsigned long target, - WebGLBuffer* buffer); - void bindFramebuffer(unsigned long target, - WebGLFramebuffer* framebuffer); - void bindTexture(unsigned long target, - WebGLTexture* texture); - void bufferDataImpl(unsigned long target, int size, const void* data, unsigned long usage); + void attachShader(WebGLProgram* program, WebGLShader* shader); + void bindAttribLocation(WebGLProgram*, unsigned long index, const String& name); + void bindBuffer(unsigned long target, WebGLBuffer*); + void bindFramebuffer(unsigned long target, WebGLFramebuffer*); + void bindRenderbuffer(unsigned long target, WebGLRenderbuffer*); + void bindTexture(unsigned long target, WebGLTexture* texture); + void blendColor(double red, double green, double blue, double alpha); + void blendEquation(unsigned long mode); + void blendEquationSeparate(unsigned long modeRGB, unsigned long modeAlpha); + void blendFunc(unsigned long sfactor, unsigned long dfactor); + void blendFuncSeparate(unsigned long srcRGB, unsigned long dstRGB, unsigned long srcAlpha, unsigned long dstAlpha); + + void bufferData(unsigned long target, int size, unsigned long usage); + void bufferData(unsigned long target, WebGLArray* data, unsigned long usage); + void bufferSubData(unsigned long target, long offset, WebGLArray* data); + + unsigned long checkFramebufferStatus(unsigned long target); + void clear(unsigned long mask); + void clearColor(double red, double green, double blue, double alpha); + void clearDepth(double depth); + void clearStencil(long s); + void colorMask(bool red, bool green, bool blue, bool alpha); + void compileShader(WebGLShader*); + + void copyTexImage2D(unsigned long target, long level, unsigned long internalformat, long x, long y, unsigned long width, unsigned long height, long border); + void copyTexSubImage2D(unsigned long target, long level, long xoffset, long yoffset, long x, long y, unsigned long width, unsigned long height); + void cullFace(unsigned long mode); + void depthFunc(unsigned long func); + void depthMask(bool flag); + void depthRange(double zNear, double zFar); + void detachShader(WebGLProgram*, WebGLShader*); + void disable(unsigned long cap); void disableVertexAttribArray(unsigned long index); + void drawArrays(unsigned long mode, long first, long count); + void drawElements(unsigned long mode, unsigned long count, unsigned long type, long offset); + + void enable(unsigned long cap); void enableVertexAttribArray(unsigned long index); - unsigned long getError(); + void finish(); + void flush(); + void framebufferRenderbuffer(unsigned long target, unsigned long attachment, unsigned long renderbuffertarget, WebGLRenderbuffer*); + void framebufferTexture2D(unsigned long target, unsigned long attachment, unsigned long textarget, WebGLTexture*, long level); + void frontFace(unsigned long mode); + void generateMipmap(unsigned long target); + + bool getActiveAttrib(WebGLProgram* program, unsigned long index, ActiveInfo&); + bool getActiveUniform(WebGLProgram* program, unsigned long index, ActiveInfo&); + + int getAttribLocation(WebGLProgram*, const String& name); + + void getBooleanv(unsigned long pname, unsigned char* value); + + void getBufferParameteriv(unsigned long target, unsigned long pname, int* value); + GraphicsContext3D::Attributes getContextAttributes(); - void vertexAttribPointer(unsigned long indx, int size, int type, bool normalized, - unsigned long stride, unsigned long offset); - void viewportImpl(long x, long y, unsigned long width, unsigned long height); - void synthesizeGLError(unsigned long error); + unsigned long getError(); -private: - GraphicsContext3D::Attributes m_attrs; + void getFloatv(unsigned long pname, float* value); + + void getFramebufferAttachmentParameteriv(unsigned long target, unsigned long attachment, unsigned long pname, int* value); + + void getIntegerv(unsigned long pname, int* value); + + void getProgramiv(WebGLProgram* program, unsigned long pname, int* value); + + String getProgramInfoLog(WebGLProgram*); + + void getRenderbufferParameteriv(unsigned long target, unsigned long pname, int* value); + + void getShaderiv(WebGLShader*, unsigned long pname, int* value); + + String getShaderInfoLog(WebGLShader*); + + String getShaderSource(WebGLShader*); + String getString(unsigned long name); + + void getTexParameterfv(unsigned long target, unsigned long pname, float* value); + void getTexParameteriv(unsigned long target, unsigned long pname, int* value); + + void getUniformfv(WebGLProgram* program, long location, float* value); + void getUniformiv(WebGLProgram* program, long location, int* value); + + long getUniformLocation(WebGLProgram*, const String& name); + + void getVertexAttribfv(unsigned long index, unsigned long pname, float* value); + void getVertexAttribiv(unsigned long index, unsigned long pname, int* value); + + long getVertexAttribOffset(unsigned long index, unsigned long pname); + + void hint(unsigned long target, unsigned long mode); + bool isBuffer(WebGLBuffer*); + bool isEnabled(unsigned long cap); + bool isFramebuffer(WebGLFramebuffer*); + bool isProgram(WebGLProgram*); + bool isRenderbuffer(WebGLRenderbuffer*); + bool isShader(WebGLShader*); + bool isTexture(WebGLTexture*); + void lineWidth(double); + void linkProgram(WebGLProgram*); + void pixelStorei(unsigned long pname, long param); + void polygonOffset(double factor, double units); + + void readPixels(long x, long y, unsigned long width, unsigned long height, unsigned long format, unsigned long type, void* data); + + void releaseShaderCompiler(); + void renderbufferStorage(unsigned long target, unsigned long internalformat, unsigned long width, unsigned long height); + void sampleCoverage(double value, bool invert); + void scissor(long x, long y, unsigned long width, unsigned long height); + void shaderSource(WebGLShader*, const String& string); + void stencilFunc(unsigned long func, long ref, unsigned long mask); + void stencilFuncSeparate(unsigned long face, unsigned long func, long ref, unsigned long mask); + void stencilMask(unsigned long mask); + void stencilMaskSeparate(unsigned long face, unsigned long mask); + void stencilOp(unsigned long fail, unsigned long zfail, unsigned long zpass); + void stencilOpSeparate(unsigned long face, unsigned long fail, unsigned long zfail, unsigned long zpass); + + // These next several functions return an error code (0 if no errors) rather than using an ExceptionCode. + // Currently they return -1 on any error. + int texImage2D(unsigned target, unsigned level, unsigned internalformat, unsigned width, unsigned height, unsigned border, unsigned format, unsigned type, void* pixels); + + void texParameterf(unsigned target, unsigned pname, float param); + void texParameteri(unsigned target, unsigned pname, int param); + + int texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset, unsigned width, unsigned height, unsigned format, unsigned type, void* pixels); + + void uniform1f(long location, float x); + void uniform1fv(long location, float* v, int size); + void uniform1i(long location, int x); + void uniform1iv(long location, int* v, int size); + void uniform2f(long location, float x, float y); + void uniform2fv(long location, float* v, int size); + void uniform2i(long location, int x, int y); + void uniform2iv(long location, int* v, int size); + void uniform3f(long location, float x, float y, float z); + void uniform3fv(long location, float* v, int size); + void uniform3i(long location, int x, int y, int z); + void uniform3iv(long location, int* v, int size); + void uniform4f(long location, float x, float y, float z, float w); + void uniform4fv(long location, float* v, int size); + void uniform4i(long location, int x, int y, int z, int w); + void uniform4iv(long location, int* v, int size); + void uniformMatrix2fv(long location, bool transpose, float* value, int size); + void uniformMatrix3fv(long location, bool transpose, float* value, int size); + void uniformMatrix4fv(long location, bool transpose, float* value, int size); + + void useProgram(WebGLProgram*); + void validateProgram(WebGLProgram*); + + void vertexAttrib1f(unsigned long indx, float x); + void vertexAttrib1fv(unsigned long indx, float* values); + void vertexAttrib2f(unsigned long indx, float x, float y); + void vertexAttrib2fv(unsigned long indx, float* values); + void vertexAttrib3f(unsigned long indx, float x, float y, float z); + void vertexAttrib3fv(unsigned long indx, float* values); + void vertexAttrib4f(unsigned long indx, float x, float y, float z, float w); + void vertexAttrib4fv(unsigned long indx, float* values); + void vertexAttribPointer(unsigned long indx, int size, int type, bool normalized, + unsigned long stride, unsigned long offset); - unsigned int m_texture; - unsigned int m_fbo; - unsigned int m_depthBuffer; - unsigned int m_cachedWidth, m_cachedHeight; + void viewport(long x, long y, unsigned long width, unsigned long height); - // For tracking which FBO is bound - unsigned int m_boundFBO; + unsigned createBuffer(); + unsigned createFramebuffer(); + unsigned createProgram(); + unsigned createRenderbuffer(); + unsigned createShader(unsigned long); + unsigned createTexture(); -#ifdef FLIP_FRAMEBUFFER_VERTICALLY - unsigned char* m_scanline; - void flipVertically(unsigned char* framebuffer, - unsigned int width, - unsigned int height); -#endif + void deleteBuffer(unsigned); + void deleteFramebuffer(unsigned); + void deleteProgram(unsigned); + void deleteRenderbuffer(unsigned); + void deleteShader(unsigned); + void deleteTexture(unsigned); - // Note: we aren't currently using this information, but we will - // need to in order to verify that all enabled vertex arrays have - // a valid buffer bound -- to avoid crashes on certain cards. - unsigned int m_boundArrayBuffer; - class VertexAttribPointerState { - public: - VertexAttribPointerState(); - - bool enabled; - unsigned long buffer; - unsigned long indx; - int size; - int type; - bool normalized; - unsigned long stride; - unsigned long offset; - }; - - enum { - NumTrackedPointerStates = 2 - }; - VertexAttribPointerState m_vertexAttribPointerState[NumTrackedPointerStates]; - - // Errors raised by synthesizeGLError(). - ListHashSet<unsigned long> m_syntheticErrors; + void synthesizeGLError(unsigned long error); +private: + OwnPtr<WebKit::WebGraphicsContext3D> m_impl; #if PLATFORM(SKIA) // If the width and height of the Canvas's backing store don't // match those that we were given in the most recent call to // reshape(), then we need an intermediate bitmap to read back the // frame buffer into. This seems to happen when CSS styles are // used to resize the Canvas. - SkBitmap* m_resizingBitmap; + SkBitmap m_resizingBitmap; #endif - static bool s_initializedGLEW; -#if OS(WINDOWS) - HWND m_canvasWindow; - HDC m_canvasDC; - HGLRC m_contextObj; -#elif PLATFORM(CG) - CGLPBufferObj m_pbuffer; - CGLContextObj m_contextObj; +#if PLATFORM(CG) unsigned char* m_renderOutput; -#elif OS(LINUX) - GLXContext m_contextObj; - GLXPbuffer m_pbuffer; - - // In order to avoid problems caused by linking against libGL, we - // dynamically look up all the symbols we need. - // http://code.google.com/p/chromium/issues/detail?id=16800 - class GLConnection { - public: - ~GLConnection(); - - static GLConnection* create(); - - GLXFBConfig* chooseFBConfig(int screen, const int *attrib_list, int *nelements) - { - return m_glXChooseFBConfig(m_display, screen, attrib_list, nelements); - } - - GLXContext createNewContext(GLXFBConfig config, int renderType, GLXContext shareList, Bool direct) - { - return m_glXCreateNewContext(m_display, config, renderType, shareList, direct); - } - - GLXPbuffer createPbuffer(GLXFBConfig config, const int *attribList) - { - return m_glXCreatePbuffer(m_display, config, attribList); - } - - void destroyPbuffer(GLXPbuffer pbuf) - { - m_glXDestroyPbuffer(m_display, pbuf); - } - - Bool makeCurrent(GLXDrawable drawable, GLXContext ctx) - { - return m_glXMakeCurrent(m_display, drawable, ctx); - } - - void destroyContext(GLXContext ctx) - { - m_glXDestroyContext(m_display, ctx); - } - - GLXContext getCurrentContext() - { - return m_glXGetCurrentContext(); - } - - private: - Display* m_display; - void* m_libGL; - PFNGLXCHOOSEFBCONFIGPROC m_glXChooseFBConfig; - PFNGLXCREATENEWCONTEXTPROC m_glXCreateNewContext; - PFNGLXCREATEPBUFFERPROC m_glXCreatePbuffer; - PFNGLXDESTROYPBUFFERPROC m_glXDestroyPbuffer; - typedef Bool (* PFNGLXMAKECURRENTPROC)(Display* dpy, GLXDrawable drawable, GLXContext ctx); - PFNGLXMAKECURRENTPROC m_glXMakeCurrent; - typedef void (* PFNGLXDESTROYCONTEXTPROC)(Display* dpy, GLXContext ctx); - PFNGLXDESTROYCONTEXTPROC m_glXDestroyContext; - typedef GLXContext (* PFNGLXGETCURRENTCONTEXTPROC)(void); - PFNGLXGETCURRENTCONTEXTPROC m_glXGetCurrentContext; - - GLConnection(Display* display, - void* libGL, - PFNGLXCHOOSEFBCONFIGPROC chooseFBConfig, - PFNGLXCREATENEWCONTEXTPROC createNewContext, - PFNGLXCREATEPBUFFERPROC createPbuffer, - PFNGLXDESTROYPBUFFERPROC destroyPbuffer, - PFNGLXMAKECURRENTPROC makeCurrent, - PFNGLXDESTROYCONTEXTPROC destroyContext, - PFNGLXGETCURRENTCONTEXTPROC getCurrentContext) - : m_libGL(libGL) - , m_display(display) - , m_glXChooseFBConfig(chooseFBConfig) - , m_glXCreateNewContext(createNewContext) - , m_glXCreatePbuffer(createPbuffer) - , m_glXDestroyPbuffer(destroyPbuffer) - , m_glXMakeCurrent(makeCurrent) - , m_glXDestroyContext(destroyContext) - , m_glXGetCurrentContext(getCurrentContext) - { - } - }; - - static GLConnection* s_gl; -#else - #error Must port GraphicsContext3D to your platform #endif }; -bool GraphicsContext3DInternal::s_initializedGLEW = false; - -#if OS(LINUX) -GraphicsContext3DInternal::GLConnection* GraphicsContext3DInternal::s_gl = 0; - -GraphicsContext3DInternal::GLConnection* GraphicsContext3DInternal::GLConnection::create() -{ - Display* dpy = XOpenDisplay(0); - if (!dpy) { - printf("GraphicsContext3D: error opening X display\n"); - return 0; - } - - // We use RTLD_GLOBAL semantics so that GLEW initialization works; - // GLEW expects to be able to open the current process's handle - // and do dlsym's of GL entry points from there. - void* libGL = dlopen("libGL.so.1", RTLD_LAZY | RTLD_GLOBAL); - if (!libGL) { - XCloseDisplay(dpy); - printf("GraphicsContext3D: error opening libGL.so.1: %s\n", dlerror()); - return 0; - } - - PFNGLXCHOOSEFBCONFIGPROC chooseFBConfig = (PFNGLXCHOOSEFBCONFIGPROC) dlsym(libGL, "glXChooseFBConfig"); - PFNGLXCREATENEWCONTEXTPROC createNewContext = (PFNGLXCREATENEWCONTEXTPROC) dlsym(libGL, "glXCreateNewContext"); - PFNGLXCREATEPBUFFERPROC createPbuffer = (PFNGLXCREATEPBUFFERPROC) dlsym(libGL, "glXCreatePbuffer"); - PFNGLXDESTROYPBUFFERPROC destroyPbuffer = (PFNGLXDESTROYPBUFFERPROC) dlsym(libGL, "glXDestroyPbuffer"); - PFNGLXMAKECURRENTPROC makeCurrent = (PFNGLXMAKECURRENTPROC) dlsym(libGL, "glXMakeCurrent"); - PFNGLXDESTROYCONTEXTPROC destroyContext = (PFNGLXDESTROYCONTEXTPROC) dlsym(libGL, "glXDestroyContext"); - PFNGLXGETCURRENTCONTEXTPROC getCurrentContext = (PFNGLXGETCURRENTCONTEXTPROC) dlsym(libGL, "glXGetCurrentContext"); - if (!chooseFBConfig || !createNewContext || !createPbuffer - || !destroyPbuffer || !makeCurrent || !destroyContext - || !getCurrentContext) { - XCloseDisplay(dpy); - dlclose(libGL); - printf("GraphicsContext3D: error looking up bootstrapping entry points\n"); - return 0; - } - return new GLConnection(dpy, - libGL, - chooseFBConfig, - createNewContext, - createPbuffer, - destroyPbuffer, - makeCurrent, - destroyContext, - getCurrentContext); -} - -GraphicsContext3DInternal::GLConnection::~GLConnection() -{ - XCloseDisplay(m_display); - dlclose(m_libGL); -} - -#endif // OS(LINUX) - -GraphicsContext3DInternal::VertexAttribPointerState::VertexAttribPointerState() - : enabled(false) - , buffer(0) - , indx(0) - , size(0) - , type(0) - , normalized(false) - , stride(0) - , offset(0) -{ -} - -GraphicsContext3DInternal::GraphicsContext3DInternal(GraphicsContext3D::Attributes attrs) - : m_attrs(attrs) - , m_texture(0) - , m_fbo(0) - , m_depthBuffer(0) - , m_boundFBO(0) -#ifdef FLIP_FRAMEBUFFER_VERTICALLY - , m_scanline(0) -#endif - , m_boundArrayBuffer(0) +GraphicsContext3DInternal::GraphicsContext3DInternal() #if PLATFORM(SKIA) - , m_resizingBitmap(0) -#endif -#if OS(WINDOWS) - , m_canvasWindow(0) - , m_canvasDC(0) - , m_contextObj(0) #elif PLATFORM(CG) - , m_pbuffer(0) - , m_contextObj(0) - , m_renderOutput(0) -#elif OS(LINUX) - , m_contextObj(0) - , m_pbuffer(0) + : m_renderOutput(0) #else #error Must port to your platform #endif { - // FIXME: we need to take into account the user's requested - // context creation attributes, in particular stencil and - // antialias, and determine which could and could not be honored - // based on the capabilities of the OpenGL implementation. - m_attrs.alpha = true; - m_attrs.depth = true; - m_attrs.stencil = false; - m_attrs.antialias = false; - m_attrs.premultipliedAlpha = true; - -#if OS(WINDOWS) - WNDCLASS wc; - if (!GetClassInfo(GetModuleHandle(0), L"CANVASGL", &wc)) { - ZeroMemory(&wc, sizeof(WNDCLASS)); - wc.style = CS_OWNDC; - wc.hInstance = GetModuleHandle(0); - wc.lpfnWndProc = DefWindowProc; - wc.lpszClassName = L"CANVASGL"; - - if (!RegisterClass(&wc)) { - printf("GraphicsContext3D: RegisterClass failed\n"); - return; - } - } - - m_canvasWindow = CreateWindow(L"CANVASGL", L"CANVASGL", - WS_CAPTION, - CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, - CW_USEDEFAULT, 0, 0, GetModuleHandle(0), 0); - if (!m_canvasWindow) { - printf("GraphicsContext3DInternal: CreateWindow failed\n"); - return; - } - - // get the device context - m_canvasDC = GetDC(m_canvasWindow); - if (!m_canvasDC) { - printf("GraphicsContext3DInternal: GetDC failed\n"); - return; - } - - // find default pixel format - PIXELFORMATDESCRIPTOR pfd; - ZeroMemory(&pfd, sizeof(PIXELFORMATDESCRIPTOR)); - pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); - pfd.nVersion = 1; - pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL -#ifdef RENDER_TO_DEBUGGING_WINDOW - | PFD_DOUBLEBUFFER -#endif // RENDER_TO_DEBUGGING_WINDOW - ; - int pixelformat = ChoosePixelFormat(m_canvasDC, &pfd); - - // set the pixel format for the dc - if (!SetPixelFormat(m_canvasDC, pixelformat, &pfd)) { - printf("GraphicsContext3D: SetPixelFormat failed\n"); - return; - } - - // create rendering context - m_contextObj = wglCreateContext(m_canvasDC); - if (!m_contextObj) { - printf("GraphicsContext3D: wglCreateContext failed\n"); - return; - } - - if (!wglMakeCurrent(m_canvasDC, m_contextObj)) { - printf("GraphicsContext3D: wglMakeCurrent failed\n"); - return; - } - -#ifdef RENDER_TO_DEBUGGING_WINDOW - typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC) (int interval); - PFNWGLSWAPINTERVALEXTPROC setSwapInterval = 0; - setSwapInterval = (PFNWGLSWAPINTERVALEXTPROC) wglGetProcAddress("wglSwapIntervalEXT"); - if (setSwapInterval) - setSwapInterval(1); -#endif // RENDER_TO_DEBUGGING_WINDOW - -#elif PLATFORM(CG) - // Create a 1x1 pbuffer and associated context to bootstrap things - CGLPixelFormatAttribute attribs[] = { - (CGLPixelFormatAttribute) kCGLPFAPBuffer, - (CGLPixelFormatAttribute) 0 - }; - CGLPixelFormatObj pixelFormat; - GLint numPixelFormats; - if (CGLChoosePixelFormat(attribs, &pixelFormat, &numPixelFormats) != kCGLNoError) { - printf("GraphicsContext3D: error choosing pixel format\n"); - return; - } - if (!pixelFormat) { - printf("GraphicsContext3D: no pixel format selected\n"); - return; - } - CGLContextObj context; - CGLError res = CGLCreateContext(pixelFormat, 0, &context); - CGLDestroyPixelFormat(pixelFormat); - if (res != kCGLNoError) { - printf("GraphicsContext3D: error creating context\n"); - return; - } - CGLPBufferObj pbuffer; - if (CGLCreatePBuffer(1, 1, GL_TEXTURE_2D, GL_RGBA, 0, &pbuffer) != kCGLNoError) { - CGLDestroyContext(context); - printf("GraphicsContext3D: error creating pbuffer\n"); - return; - } - if (CGLSetPBuffer(context, pbuffer, 0, 0, 0) != kCGLNoError) { - CGLDestroyContext(context); - CGLDestroyPBuffer(pbuffer); - printf("GraphicsContext3D: error attaching pbuffer to context\n"); - return; - } - if (CGLSetCurrentContext(context) != kCGLNoError) { - CGLDestroyContext(context); - CGLDestroyPBuffer(pbuffer); - printf("GraphicsContext3D: error making context current\n"); - return; - } - m_pbuffer = pbuffer; - m_contextObj = context; -#elif OS(LINUX) - if (!s_gl) { - s_gl = GLConnection::create(); - if (!s_gl) - return; - } - - int configAttrs[] = { - GLX_DRAWABLE_TYPE, - GLX_PBUFFER_BIT, - GLX_RENDER_TYPE, - GLX_RGBA_BIT, - GLX_DOUBLEBUFFER, - 0, - 0 - }; - int nelements = 0; - GLXFBConfig* config = s_gl->chooseFBConfig(0, configAttrs, &nelements); - if (!config) { - printf("GraphicsContext3D: glXChooseFBConfig failed\n"); - return; - } - if (!nelements) { - printf("GraphicsContext3D: glXChooseFBConfig returned 0 elements\n"); - XFree(config); - return; - } - GLXContext context = s_gl->createNewContext(config[0], GLX_RGBA_TYPE, 0, True); - if (!context) { - printf("GraphicsContext3D: glXCreateNewContext failed\n"); - XFree(config); - return; - } - int pbufferAttrs[] = { - GLX_PBUFFER_WIDTH, - 1, - GLX_PBUFFER_HEIGHT, - 1, - 0 - }; - GLXPbuffer pbuffer = s_gl->createPbuffer(config[0], pbufferAttrs); - XFree(config); - if (!pbuffer) { - printf("GraphicsContext3D: glxCreatePbuffer failed\n"); - return; - } - if (!s_gl->makeCurrent(pbuffer, context)) { - printf("GraphicsContext3D: glXMakeCurrent failed\n"); - return; - } - m_contextObj = context; - m_pbuffer = pbuffer; -#else -#error Must port to your platform -#endif - - if (!s_initializedGLEW) { - // Initialize GLEW and check for GL 2.0 support by the drivers. - GLenum glewInitResult = glewInit(); - if (glewInitResult != GLEW_OK) { - printf("GraphicsContext3D: GLEW initialization failed\n"); - return; - } - if (!glewIsSupported("GL_VERSION_2_0")) { - printf("GraphicsContext3D: OpenGL 2.0 not supported\n"); - return; - } - s_initializedGLEW = true; - } } GraphicsContext3DInternal::~GraphicsContext3DInternal() { - makeContextCurrent(); -#ifndef RENDER_TO_DEBUGGING_WINDOW - glDeleteRenderbuffersEXT(1, &m_depthBuffer); - glDeleteTextures(1, &m_texture); -#ifdef FLIP_FRAMEBUFFER_VERTICALLY - if (m_scanline) - delete[] m_scanline; -#endif - glDeleteFramebuffersEXT(1, &m_fbo); -#endif // !RENDER_TO_DEBUGGING_WINDOW -#if PLATFORM(SKIA) - if (m_resizingBitmap) - delete m_resizingBitmap; -#endif -#if OS(WINDOWS) - wglMakeCurrent(0, 0); - wglDeleteContext(m_contextObj); - ReleaseDC(m_canvasWindow, m_canvasDC); - DestroyWindow(m_canvasWindow); -#elif PLATFORM(CG) - CGLSetCurrentContext(0); - CGLDestroyContext(m_contextObj); - CGLDestroyPBuffer(m_pbuffer); +#if PLATFORM(CG) if (m_renderOutput) delete[] m_renderOutput; -#elif OS(LINUX) - s_gl->makeCurrent(0, 0); - s_gl->destroyContext(m_contextObj); - s_gl->destroyPbuffer(m_pbuffer); -#else -#error Must port to your platform #endif - m_contextObj = 0; } -bool GraphicsContext3DInternal::makeContextCurrent() +bool GraphicsContext3DInternal::initialize(GraphicsContext3D::Attributes attrs) { -#if OS(WINDOWS) - if (wglGetCurrentContext() != m_contextObj) - if (wglMakeCurrent(m_canvasDC, m_contextObj)) - return true; -#elif PLATFORM(CG) - if (CGLGetCurrentContext() != m_contextObj) - if (CGLSetCurrentContext(m_contextObj) == kCGLNoError) - return true; -#elif OS(LINUX) - if (s_gl->getCurrentContext() != m_contextObj) - if (s_gl->makeCurrent(m_pbuffer, m_contextObj)) - return true; -#else -#error Must port to your platform -#endif - return false; + WebKit::WebGraphicsContext3D::Attributes webAttributes; + webAttributes.alpha = attrs.alpha; + webAttributes.depth = attrs.depth; + webAttributes.stencil = attrs.stencil; + webAttributes.antialias = attrs.antialias; + webAttributes.premultipliedAlpha = attrs.premultipliedAlpha; + WebKit::WebGraphicsContext3D* webContext = WebKit::webKitClient()->createGraphicsContext3D(); + if (!webContext) + return false; + if (!webContext->initialize(webAttributes)) { + delete webContext; + return false; + } + m_impl.set(webContext); + return true; } PlatformGraphicsContext3D GraphicsContext3DInternal::platformGraphicsContext3D() const { - return m_contextObj; + return 0; } Platform3DObject GraphicsContext3DInternal::platformTexture() const { - return m_texture; -} - -static int createTextureObject(GLenum target) -{ - GLuint texture = 0; - glGenTextures(1, &texture); - glBindTexture(target, texture); - glTexParameterf(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameterf(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - return texture; -} - -void GraphicsContext3DInternal::reshape(int width, int height) -{ -#ifdef RENDER_TO_DEBUGGING_WINDOW - SetWindowPos(m_canvasWindow, HWND_TOP, 0, 0, width, height, - SWP_NOMOVE); - ShowWindow(m_canvasWindow, SW_SHOW); -#endif - - m_cachedWidth = width; - m_cachedHeight = height; - makeContextCurrent(); - -#ifndef RENDER_TO_DEBUGGING_WINDOW -#ifdef USE_TEXTURE_RECTANGLE_FOR_FRAMEBUFFER - // GL_TEXTURE_RECTANGLE_ARB is the best supported render target on Mac OS X - GLenum target = GL_TEXTURE_RECTANGLE_ARB; -#else - GLenum target = GL_TEXTURE_2D; -#endif - if (!m_texture) { - // Generate the texture object - m_texture = createTextureObject(target); - // Generate the framebuffer object - glGenFramebuffersEXT(1, &m_fbo); - // Generate the depth buffer - glGenRenderbuffersEXT(1, &m_depthBuffer); - } - - // Reallocate the color and depth buffers - glBindTexture(target, m_texture); - glTexImage2D(target, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0); - glBindTexture(target, 0); - - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo); - m_boundFBO = m_fbo; - glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_depthBuffer); - glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT, width, height); - glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); - - glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, target, m_texture, 0); - glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depthBuffer); - GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); - if (status != GL_FRAMEBUFFER_COMPLETE_EXT) { - printf("GraphicsContext3D: framebuffer was incomplete\n"); - - // FIXME: cleanup. - notImplemented(); - } -#endif // RENDER_TO_DEBUGGING_WINDOW - -#ifdef FLIP_FRAMEBUFFER_VERTICALLY - if (m_scanline) { - delete[] m_scanline; - m_scanline = 0; - } - m_scanline = new unsigned char[width * 4]; -#endif // FLIP_FRAMEBUFFER_VERTICALLY - - glClear(GL_COLOR_BUFFER_BIT); - -#if PLATFORM(CG) - // Need to reallocate the client-side backing store. - // FIXME: make this more efficient. - if (m_renderOutput) { - delete[] m_renderOutput; - m_renderOutput = 0; - } - int rowBytes = width * 4; - m_renderOutput = new unsigned char[height * rowBytes]; -#endif // PLATFORM(CG) -} - -#ifdef FLIP_FRAMEBUFFER_VERTICALLY -void GraphicsContext3DInternal::flipVertically(unsigned char* framebuffer, - unsigned int width, - unsigned int height) -{ - unsigned char* scanline = m_scanline; - if (!scanline) - return; - unsigned int rowBytes = width * 4; - unsigned int count = height / 2; - for (unsigned int i = 0; i < count; i++) { - unsigned char* rowA = framebuffer + i * rowBytes; - unsigned char* rowB = framebuffer + (height - i - 1) * rowBytes; - // FIXME: this is where the multiplication of the alpha - // channel into the color buffer will need to occur if the - // user specifies the "premultiplyAlpha" flag in the context - // creation attributes. - memcpy(scanline, rowB, rowBytes); - memcpy(rowB, rowA, rowBytes); - memcpy(rowA, scanline, rowBytes); - } + return 0; } -#endif void GraphicsContext3DInternal::beginPaint(WebGLRenderingContext* context) { - makeContextCurrent(); - -#ifdef RENDER_TO_DEBUGGING_WINDOW - SwapBuffers(m_canvasDC); -#else - // Earlier versions of this code used the GPU to flip the - // framebuffer vertically before reading it back for compositing - // via software. This code was quite complicated, used a lot of - // GPU memory, and didn't provide an obvious speedup. Since this - // vertical flip is only a temporary solution anyway until Chrome - // is fully GPU composited, it wasn't worth the complexity. - HTMLCanvasElement* canvas = context->canvas(); ImageBuffer* imageBuffer = canvas->buffer(); unsigned char* pixels = 0; - bool mustRestoreFBO = (m_boundFBO != m_fbo); - if (mustRestoreFBO) - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo); #if PLATFORM(SKIA) const SkBitmap* canvasBitmap = imageBuffer->context()->platformContext()->bitmap(); const SkBitmap* readbackBitmap = 0; ASSERT(canvasBitmap->config() == SkBitmap::kARGB_8888_Config); - if (canvasBitmap->width() == m_cachedWidth && canvasBitmap->height() == m_cachedHeight) { + if (canvasBitmap->width() == m_impl->width() && canvasBitmap->height() == m_impl->height()) { // This is the fastest and most common case. We read back // directly into the canvas's backing store. readbackBitmap = canvasBitmap; - if (m_resizingBitmap) { - delete m_resizingBitmap; - m_resizingBitmap = 0; - } + m_resizingBitmap.reset(); } else { // We need to allocate a temporary bitmap for reading back the // pixel data. We will then use Skia to rescale this bitmap to // the size of the canvas's backing store. - if (m_resizingBitmap && (m_resizingBitmap->width() != m_cachedWidth || m_resizingBitmap->height() != m_cachedHeight)) { - delete m_resizingBitmap; - m_resizingBitmap = 0; - } - if (!m_resizingBitmap) { - m_resizingBitmap = new SkBitmap(); - m_resizingBitmap->setConfig(SkBitmap::kARGB_8888_Config, - m_cachedWidth, - m_cachedHeight); - if (!m_resizingBitmap->allocPixels()) { - delete m_resizingBitmap; - m_resizingBitmap = 0; + if (m_resizingBitmap.width() != m_impl->width() || m_resizingBitmap.height() != m_impl->height()) { + m_resizingBitmap.setConfig(SkBitmap::kARGB_8888_Config, + m_impl->width(), + m_impl->height()); + if (!m_resizingBitmap.allocPixels()) { return; } } - readbackBitmap = m_resizingBitmap; + readbackBitmap = &m_resizingBitmap; } // Read back the frame buffer. SkAutoLockPixels bitmapLock(*readbackBitmap); pixels = static_cast<unsigned char*>(readbackBitmap->getPixels()); - glReadPixels(0, 0, m_cachedWidth, m_cachedHeight, GL_BGRA, GL_UNSIGNED_BYTE, pixels); #elif PLATFORM(CG) - if (m_renderOutput) { + if (m_renderOutput) pixels = m_renderOutput; - glReadPixels(0, 0, m_cachedWidth, m_cachedHeight, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, pixels); - } #else #error Must port to your platform #endif - if (mustRestoreFBO) - glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_boundFBO); - -#ifdef FLIP_FRAMEBUFFER_VERTICALLY - if (pixels) - flipVertically(pixels, m_cachedWidth, m_cachedHeight); -#endif + m_impl->readBackFramebuffer(pixels, 4 * m_impl->width() * m_impl->height()); #if PLATFORM(SKIA) - if (m_resizingBitmap) { + if (m_resizingBitmap.readyToDraw()) { // We need to draw the resizing bitmap into the canvas's backing store. SkCanvas canvas(*canvasBitmap); SkRect dst; - dst.set(0, 0, canvasBitmap->width(), canvasBitmap->height()); - canvas.drawBitmapRect(*m_resizingBitmap, 0, dst); + dst.set(SkIntToScalar(0), SkIntToScalar(0), canvasBitmap->width(), canvasBitmap->height()); + canvas.drawBitmapRect(m_resizingBitmap, 0, dst); } #elif PLATFORM(CG) if (m_renderOutput) { - int rowBytes = m_cachedWidth * 4; - CGDataProviderRef dataProvider = CGDataProviderCreateWithData(0, m_renderOutput, rowBytes * m_cachedHeight, 0); + int rowBytes = m_impl->width() * 4; + CGDataProviderRef dataProvider = CGDataProviderCreateWithData(0, m_renderOutput, rowBytes * m_impl->height(), 0); CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); - CGImageRef cgImage = CGImageCreate(m_cachedWidth, - m_cachedHeight, + CGImageRef cgImage = CGImageCreate(m_impl->width(), + m_impl->height(), 8, 32, rowBytes, @@ -861,1017 +442,766 @@ void GraphicsContext3DInternal::beginPaint(WebGLRenderingContext* context) #else #error Must port to your platform #endif - -#endif // RENDER_TO_DEBUGGING_WINDOW } -void GraphicsContext3DInternal::activeTexture(unsigned long texture) +void GraphicsContext3DInternal::endPaint() { - // FIXME: query number of textures available. - if (texture < GL_TEXTURE0 || texture > GL_TEXTURE0+32) - // FIXME: raise exception. - return; - - makeContextCurrent(); - glActiveTexture(texture); } -void GraphicsContext3DInternal::bindBuffer(unsigned long target, - WebGLBuffer* buffer) -{ - makeContextCurrent(); - GLuint bufID = EXTRACT(buffer); - if (target == GL_ARRAY_BUFFER) - m_boundArrayBuffer = bufID; - glBindBuffer(target, bufID); -} - -void GraphicsContext3DInternal::bindFramebuffer(unsigned long target, - WebGLFramebuffer* framebuffer) -{ - makeContextCurrent(); - GLuint id = EXTRACT(framebuffer); - if (!id) - id = m_fbo; - glBindFramebufferEXT(target, id); - m_boundFBO = id; -} - -// If we didn't have to hack GL_TEXTURE_WRAP_R for cube maps, -// we could just use: -// GL_SAME_METHOD_2_X2(BindTexture, bindTexture, unsigned long, WebGLTexture*) -void GraphicsContext3DInternal::bindTexture(unsigned long target, - WebGLTexture* texture) +void GraphicsContext3DInternal::reshape(int width, int height) { - makeContextCurrent(); - unsigned int textureObject = EXTRACT(texture); + if (width == m_impl->width() && height == m_impl->height()) + return; - glBindTexture(target, textureObject); + m_impl->reshape(width, height); - // FIXME: GL_TEXTURE_WRAP_R isn't exposed in the OpenGL ES 2.0 - // API. On desktop OpenGL implementations it seems necessary to - // set this wrap mode to GL_CLAMP_TO_EDGE to get correct behavior - // of cube maps. - if (texture) { - if (target == GL_TEXTURE_CUBE_MAP) { - if (!texture->isCubeMapRWrapModeInitialized()) { - glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); - texture->setCubeMapRWrapModeInitialized(true); - } - } else - texture->setCubeMapRWrapModeInitialized(false); +#if PLATFORM(CG) + // Need to reallocate the client-side backing store. + // FIXME: make this more efficient. + if (m_renderOutput) { + delete[] m_renderOutput; + m_renderOutput = 0; } + int rowBytes = width * 4; + m_renderOutput = new unsigned char[height * rowBytes]; +#endif // PLATFORM(CG) } -void GraphicsContext3DInternal::bufferDataImpl(unsigned long target, int size, const void* data, unsigned long usage) -{ - makeContextCurrent(); - // FIXME: make this verification more efficient. - GLint binding = 0; - GLenum binding_target = GL_ARRAY_BUFFER_BINDING; - if (target == GL_ELEMENT_ARRAY_BUFFER) - binding_target = GL_ELEMENT_ARRAY_BUFFER_BINDING; - glGetIntegerv(binding_target, &binding); - if (binding <= 0) { - // FIXME: raise exception. - // LogMessagef(("bufferData: no buffer bound")); - return; - } +// Macros to assist in delegating from GraphicsContext3DInternal to +// WebGraphicsContext3D. - glBufferData(target, - size, - data, - usage); +#define DELEGATE_TO_IMPL(name) \ +void GraphicsContext3DInternal::name() \ +{ \ + m_impl->name(); \ } -void GraphicsContext3DInternal::disableVertexAttribArray(unsigned long index) -{ - makeContextCurrent(); - if (index < NumTrackedPointerStates) - m_vertexAttribPointerState[index].enabled = false; - glDisableVertexAttribArray(index); +#define DELEGATE_TO_IMPL_R(name, rt) \ +rt GraphicsContext3DInternal::name() \ +{ \ + return m_impl->name(); \ } -void GraphicsContext3DInternal::enableVertexAttribArray(unsigned long index) -{ - makeContextCurrent(); - if (index < NumTrackedPointerStates) - m_vertexAttribPointerState[index].enabled = true; - glEnableVertexAttribArray(index); +#define DELEGATE_TO_IMPL_1(name, t1) \ +void GraphicsContext3DInternal::name(t1 a1) \ +{ \ + m_impl->name(a1); \ } -unsigned long GraphicsContext3DInternal::getError() -{ - if (m_syntheticErrors.size() > 0) { - ListHashSet<unsigned long>::iterator iter = m_syntheticErrors.begin(); - unsigned long err = *iter; - m_syntheticErrors.remove(iter); - return err; - } - - makeContextCurrent(); - return glGetError(); +#define DELEGATE_TO_IMPL_1_X(name, t1) \ +void GraphicsContext3DInternal::name(t1 a1) \ +{ \ + m_impl->name(EXTRACT(a1)); \ } -GraphicsContext3D::Attributes GraphicsContext3DInternal::getContextAttributes() -{ - return m_attrs; +#define DELEGATE_TO_IMPL_1R(name, t1, rt) \ +rt GraphicsContext3DInternal::name(t1 a1) \ +{ \ + return m_impl->name(a1); \ } -void GraphicsContext3DInternal::vertexAttribPointer(unsigned long indx, int size, int type, bool normalized, - unsigned long stride, unsigned long offset) -{ - makeContextCurrent(); - - if (m_boundArrayBuffer <= 0) { - // FIXME: raise exception. - // LogMessagef(("bufferData: no buffer bound")); - return; - } - - if (indx < NumTrackedPointerStates) { - VertexAttribPointerState& state = m_vertexAttribPointerState[indx]; - state.buffer = m_boundArrayBuffer; - state.indx = indx; - state.size = size; - state.type = type; - state.normalized = normalized; - state.stride = stride; - state.offset = offset; - } - - glVertexAttribPointer(indx, size, type, normalized, stride, - reinterpret_cast<void*>(static_cast<intptr_t>(offset))); +#define DELEGATE_TO_IMPL_1R_X(name, t1, rt) \ +rt GraphicsContext3DInternal::name(t1 a1) \ +{ \ + return m_impl->name(EXTRACT(a1)); \ } -void GraphicsContext3DInternal::viewportImpl(long x, long y, unsigned long width, unsigned long height) -{ - glViewport(x, y, width, height); +#define DELEGATE_TO_IMPL_2(name, t1, t2) \ +void GraphicsContext3DInternal::name(t1 a1, t2 a2) \ +{ \ + m_impl->name(a1, a2); \ } -void GraphicsContext3DInternal::synthesizeGLError(unsigned long error) -{ - m_syntheticErrors.add(error); +#define DELEGATE_TO_IMPL_2_X12(name, t1, t2) \ +void GraphicsContext3DInternal::name(t1 a1, t2 a2) \ +{ \ + m_impl->name(EXTRACT(a1), EXTRACT(a2)); \ } -// GraphicsContext3D ----------------------------------------------------- - -/* Helper macros for when we're just wrapping a gl method, so that - * we can avoid having to type this 500 times. Note that these MUST - * NOT BE USED if we need to check any of the parameters. - */ - -#define GL_SAME_METHOD_0(glname, name) \ -void GraphicsContext3D::name() \ -{ \ - makeContextCurrent(); \ - gl##glname(); \ +#define DELEGATE_TO_IMPL_2_X2(name, t1, t2) \ +void GraphicsContext3DInternal::name(t1 a1, t2 a2) \ +{ \ + m_impl->name(a1, EXTRACT(a2)); \ } -#define GL_SAME_METHOD_1(glname, name, t1) \ -void GraphicsContext3D::name(t1 a1) \ -{ \ - makeContextCurrent(); \ - gl##glname(a1); \ +#define DELEGATE_TO_IMPL_2R(name, t1, t2, rt) \ +rt GraphicsContext3DInternal::name(t1 a1, t2 a2) \ +{ \ + return m_impl->name(a1, a2); \ } -#define GL_SAME_METHOD_1_X(glname, name, t1) \ -void GraphicsContext3D::name(t1 a1) \ -{ \ - makeContextCurrent(); \ - gl##glname(EXTRACT(a1)); \ +#define DELEGATE_TO_IMPL_3(name, t1, t2, t3) \ +void GraphicsContext3DInternal::name(t1 a1, t2 a2, t3 a3) \ +{ \ + m_impl->name(a1, a2, a3); \ } -#define GL_SAME_METHOD_2(glname, name, t1, t2) \ -void GraphicsContext3D::name(t1 a1, t2 a2) \ -{ \ - makeContextCurrent(); \ - gl##glname(a1, a2); \ +#define DELEGATE_TO_IMPL_3_X1(name, t1, t2, t3) \ +void GraphicsContext3DInternal::name(t1 a1, t2 a2, t3 a3) \ +{ \ + m_impl->name(EXTRACT(a1), a2, a3); \ } -#define GL_SAME_METHOD_2_X12(glname, name, t1, t2) \ -void GraphicsContext3D::name(t1 a1, t2 a2) \ -{ \ - makeContextCurrent(); \ - gl##glname(EXTRACT(a1), EXTRACT(a2)); \ +#define DELEGATE_TO_IMPL_3R(name, t1, t2, t3, rt) \ +rt GraphicsContext3DInternal::name(t1 a1, t2 a2, t3 a3) \ +{ \ + return m_impl->name(a1, a2, a3); \ } -#define GL_SAME_METHOD_2_X2(glname, name, t1, t2) \ -void GraphicsContext3D::name(t1 a1, t2 a2) \ -{ \ - makeContextCurrent(); \ - gl##glname(a1, EXTRACT(a2)); \ +#define DELEGATE_TO_IMPL_4(name, t1, t2, t3, t4) \ +void GraphicsContext3DInternal::name(t1 a1, t2 a2, t3 a3, t4 a4) \ +{ \ + m_impl->name(a1, a2, a3, a4); \ } -#define GL_SAME_METHOD_3(glname, name, t1, t2, t3) \ -void GraphicsContext3D::name(t1 a1, t2 a2, t3 a3) \ -{ \ - makeContextCurrent(); \ - gl##glname(a1, a2, a3); \ +#define DELEGATE_TO_IMPL_4_X4(name, t1, t2, t3, t4) \ +void GraphicsContext3DInternal::name(t1 a1, t2 a2, t3 a3, t4 a4) \ +{ \ + m_impl->name(a1, a2, a3, EXTRACT(a4)); \ } -#define GL_SAME_METHOD_3_X12(glname, name, t1, t2, t3) \ -void GraphicsContext3D::name(t1 a1, t2 a2, t3 a3) \ -{ \ - makeContextCurrent(); \ - gl##glname(EXTRACT(a1), EXTRACT(a2), a3); \ +#define DELEGATE_TO_IMPL_5(name, t1, t2, t3, t4, t5) \ +void GraphicsContext3DInternal::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5) \ +{ \ + m_impl->name(a1, a2, a3, a4, a5); \ } -#define GL_SAME_METHOD_3_X2(glname, name, t1, t2, t3) \ -void GraphicsContext3D::name(t1 a1, t2 a2, t3 a3) \ -{ \ - makeContextCurrent(); \ - gl##glname(a1, EXTRACT(a2), a3); \ +#define DELEGATE_TO_IMPL_5_X4(name, t1, t2, t3, t4, t5) \ +void GraphicsContext3DInternal::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5) \ +{ \ + m_impl->name(a1, a2, a3, EXTRACT(a4), a5); \ } -#define GL_SAME_METHOD_4(glname, name, t1, t2, t3, t4) \ -void GraphicsContext3D::name(t1 a1, t2 a2, t3 a3, t4 a4) \ -{ \ - makeContextCurrent(); \ - gl##glname(a1, a2, a3, a4); \ +#define DELEGATE_TO_IMPL_5R(name, t1, t2, t3, t4, t5, rt) \ +rt GraphicsContext3DInternal::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5) \ +{ \ + return m_impl->name(a1, a2, a3, a4, a5); \ } -#define GL_SAME_METHOD_4_X4(glname, name, t1, t2, t3, t4) \ -void GraphicsContext3D::name(t1 a1, t2 a2, t3 a3, t4 a4) \ -{ \ - makeContextCurrent(); \ - gl##glname(a1, a2, a3, EXTRACT(a4)); \ +#define DELEGATE_TO_IMPL_6(name, t1, t2, t3, t4, t5, t6) \ +void GraphicsContext3DInternal::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6) \ +{ \ + m_impl->name(a1, a2, a3, a4, a5, a6); \ } -#define GL_SAME_METHOD_5(glname, name, t1, t2, t3, t4, t5) \ -void GraphicsContext3D::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5) \ -{ \ - makeContextCurrent(); \ - gl##glname(a1, a2, a3, a4, a5); \ +#define DELEGATE_TO_IMPL_6R(name, t1, t2, t3, t4, t5, t6, rt) \ +rt GraphicsContext3DInternal::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6) \ +{ \ + return m_impl->name(a1, a2, a3, a4, a5, a6); \ } -#define GL_SAME_METHOD_5_X4(glname, name, t1, t2, t3, t4, t5) \ -void GraphicsContext3D::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5) \ -{ \ - makeContextCurrent(); \ - gl##glname(a1, a2, a3, EXTRACT(a4), a5); \ +#define DELEGATE_TO_IMPL_7(name, t1, t2, t3, t4, t5, t6, t7) \ +void GraphicsContext3DInternal::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7) \ +{ \ + m_impl->name(a1, a2, a3, a4, a5, a6, a7); \ } -#define GL_SAME_METHOD_6(glname, name, t1, t2, t3, t4, t5, t6) \ -void GraphicsContext3D::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6) \ -{ \ - makeContextCurrent(); \ - gl##glname(a1, a2, a3, a4, a5, a6); \ +#define DELEGATE_TO_IMPL_7R(name, t1, t2, t3, t4, t5, t6, t7, rt) \ +rt GraphicsContext3DInternal::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7) \ +{ \ + return m_impl->name(a1, a2, a3, a4, a5, a6, a7); \ } -#define GL_SAME_METHOD_8(glname, name, t1, t2, t3, t4, t5, t6, t7, t8) \ -void GraphicsContext3D::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7, t8 a8) \ -{ \ - makeContextCurrent(); \ - gl##glname(a1, a2, a3, a4, a5, a6, a7, a8); \ +#define DELEGATE_TO_IMPL_8(name, t1, t2, t3, t4, t5, t6, t7, t8) \ +void GraphicsContext3DInternal::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7, t8 a8) \ +{ \ + m_impl->name(a1, a2, a3, a4, a5, a6, a7, a8); \ } -PassOwnPtr<GraphicsContext3D> GraphicsContext3D::create(GraphicsContext3D::Attributes attrs) -{ - PassOwnPtr<GraphicsContext3D> context = new GraphicsContext3D(attrs); - // FIXME: add error checking - return context; +#define DELEGATE_TO_IMPL_9R(name, t1, t2, t3, t4, t5, t6, t7, t8, t9, rt) \ +rt GraphicsContext3DInternal::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7, t8 a8, t9 a9) \ +{ \ + return m_impl->name(a1, a2, a3, a4, a5, a6, a7, a8, a9); \ } -GraphicsContext3D::GraphicsContext3D(GraphicsContext3D::Attributes attrs) - : m_currentWidth(0) - , m_currentHeight(0) - , m_internal(new GraphicsContext3DInternal(attrs)) -{ -} +DELEGATE_TO_IMPL_R(makeContextCurrent, bool) +DELEGATE_TO_IMPL_1R(sizeInBytes, int, int) -GraphicsContext3D::~GraphicsContext3D() -{ -} +DELEGATE_TO_IMPL_1(activeTexture, unsigned long) +DELEGATE_TO_IMPL_2_X12(attachShader, WebGLProgram*, WebGLShader*) -PlatformGraphicsContext3D GraphicsContext3D::platformGraphicsContext3D() const +void GraphicsContext3DInternal::bindAttribLocation(WebGLProgram* program, unsigned long index, const String& name) { - return m_internal->platformGraphicsContext3D(); + m_impl->bindAttribLocation(EXTRACT(program), index, name.utf8().data()); } -Platform3DObject GraphicsContext3D::platformTexture() const -{ - return m_internal->platformTexture(); -} +DELEGATE_TO_IMPL_2_X2(bindBuffer, unsigned long, WebGLBuffer*) +DELEGATE_TO_IMPL_2_X2(bindFramebuffer, unsigned long, WebGLFramebuffer*) +DELEGATE_TO_IMPL_2_X2(bindRenderbuffer, unsigned long, WebGLRenderbuffer*) -void GraphicsContext3D::makeContextCurrent() -{ - m_internal->makeContextCurrent(); -} +static const int kTextureWrapR = 0x8072; -void GraphicsContext3D::reshape(int width, int height) +// If we didn't have to hack GL_TEXTURE_WRAP_R for cube maps, +// we could just use: +// DELEGATE_TO_IMPL_2_X2(bindTexture, unsigned long, WebGLTexture*) +void GraphicsContext3DInternal::bindTexture(unsigned long target, + WebGLTexture* texture) { - if (width == m_currentWidth && height == m_currentHeight) - return; + unsigned int textureObject = EXTRACT(texture); - m_currentWidth = width; - m_currentHeight = height; + m_impl->bindTexture(target, textureObject); - m_internal->reshape(width, height); + // FIXME: GL_TEXTURE_WRAP_R isn't exposed in the OpenGL ES 2.0 + // API. On desktop OpenGL implementations it seems necessary to + // set this wrap mode to GL_CLAMP_TO_EDGE to get correct behavior + // of cube maps. + if (texture) + if (target == GraphicsContext3D::TEXTURE_CUBE_MAP) { + if (!texture->isCubeMapRWrapModeInitialized()) { + m_impl->texParameteri(GraphicsContext3D::TEXTURE_CUBE_MAP, kTextureWrapR, GraphicsContext3D::CLAMP_TO_EDGE); + texture->setCubeMapRWrapModeInitialized(true); + } + } else + texture->setCubeMapRWrapModeInitialized(false); } -void GraphicsContext3D::beginPaint(WebGLRenderingContext* context) -{ - m_internal->beginPaint(context); -} +DELEGATE_TO_IMPL_4(blendColor, double, double, double, double) +DELEGATE_TO_IMPL_1(blendEquation, unsigned long) +DELEGATE_TO_IMPL_2(blendEquationSeparate, unsigned long, unsigned long) +DELEGATE_TO_IMPL_2(blendFunc, unsigned long, unsigned long) +DELEGATE_TO_IMPL_4(blendFuncSeparate, unsigned long, unsigned long, unsigned long, unsigned long) -void GraphicsContext3D::endPaint() +void GraphicsContext3DInternal::bufferData(unsigned long target, int size, unsigned long usage) { + m_impl->bufferData(target, size, 0, usage); } -int GraphicsContext3D::sizeInBytes(int type) +void GraphicsContext3DInternal::bufferData(unsigned long target, WebGLArray* array, unsigned long usage) { - switch (type) { - case GL_BYTE: - return sizeof(GLbyte); - case GL_UNSIGNED_BYTE: - return sizeof(GLubyte); - case GL_SHORT: - return sizeof(GLshort); - case GL_UNSIGNED_SHORT: - return sizeof(GLushort); - case GL_INT: - return sizeof(GLint); - case GL_UNSIGNED_INT: - return sizeof(GLuint); - case GL_FLOAT: - return sizeof(GLfloat); - default: // FIXME: default cases are discouraged in WebKit. - return 0; - } + m_impl->bufferData(target, array->byteLength(), array->baseAddress(), usage); } -unsigned GraphicsContext3D::createBuffer() +void GraphicsContext3DInternal::bufferSubData(unsigned long target, long offset, WebGLArray* array) { - makeContextCurrent(); - GLuint o; - glGenBuffers(1, &o); - return o; + m_impl->bufferSubData(target, offset, array->byteLength(), array->baseAddress()); } -unsigned GraphicsContext3D::createFramebuffer() -{ - makeContextCurrent(); - GLuint o = 0; - glGenFramebuffersEXT(1, &o); - return o; -} +DELEGATE_TO_IMPL_1R(checkFramebufferStatus, unsigned long, unsigned long) +DELEGATE_TO_IMPL_1(clear, unsigned long) +DELEGATE_TO_IMPL_4(clearColor, double, double, double, double) +DELEGATE_TO_IMPL_1(clearDepth, double) +DELEGATE_TO_IMPL_1(clearStencil, long) +DELEGATE_TO_IMPL_4(colorMask, bool, bool, bool, bool) +DELEGATE_TO_IMPL_1_X(compileShader, WebGLShader*) -unsigned GraphicsContext3D::createProgram() -{ - makeContextCurrent(); - return glCreateProgram(); -} +DELEGATE_TO_IMPL_8(copyTexImage2D, unsigned long, long, unsigned long, long, long, unsigned long, unsigned long, long) +DELEGATE_TO_IMPL_8(copyTexSubImage2D, unsigned long, long, long, long, long, long, unsigned long, unsigned long) +DELEGATE_TO_IMPL_1(cullFace, unsigned long) +DELEGATE_TO_IMPL_1(depthFunc, unsigned long) +DELEGATE_TO_IMPL_1(depthMask, bool) +DELEGATE_TO_IMPL_2(depthRange, double, double) +DELEGATE_TO_IMPL_2_X12(detachShader, WebGLProgram*, WebGLShader*) +DELEGATE_TO_IMPL_1(disable, unsigned long) +DELEGATE_TO_IMPL_1(disableVertexAttribArray, unsigned long) +DELEGATE_TO_IMPL_3(drawArrays, unsigned long, long, long) +DELEGATE_TO_IMPL_4(drawElements, unsigned long, unsigned long, unsigned long, long) -unsigned GraphicsContext3D::createRenderbuffer() -{ - makeContextCurrent(); - GLuint o; - glGenRenderbuffersEXT(1, &o); - return o; -} +DELEGATE_TO_IMPL_1(enable, unsigned long) +DELEGATE_TO_IMPL_1(enableVertexAttribArray, unsigned long) +DELEGATE_TO_IMPL(finish) +DELEGATE_TO_IMPL(flush) +DELEGATE_TO_IMPL_4_X4(framebufferRenderbuffer, unsigned long, unsigned long, unsigned long, WebGLRenderbuffer*) +DELEGATE_TO_IMPL_5_X4(framebufferTexture2D, unsigned long, unsigned long, unsigned long, WebGLTexture*, long) +DELEGATE_TO_IMPL_1(frontFace, unsigned long) +DELEGATE_TO_IMPL_1(generateMipmap, unsigned long) -unsigned GraphicsContext3D::createShader(unsigned long type) +bool GraphicsContext3DInternal::getActiveAttrib(WebGLProgram* program, unsigned long index, ActiveInfo& info) { - makeContextCurrent(); - return glCreateShader((type == FRAGMENT_SHADER) ? GL_FRAGMENT_SHADER : GL_VERTEX_SHADER); + WebKit::WebGraphicsContext3D::ActiveInfo webInfo; + if (!m_impl->getActiveAttrib(EXTRACT(program), index, webInfo)) + return false; + info.name = webInfo.name; + info.type = webInfo.type; + info.size = webInfo.size; + return true; } -unsigned GraphicsContext3D::createTexture() +bool GraphicsContext3DInternal::getActiveUniform(WebGLProgram* program, unsigned long index, ActiveInfo& info) { - makeContextCurrent(); - GLuint o; - glGenTextures(1, &o); - return o; + WebKit::WebGraphicsContext3D::ActiveInfo webInfo; + if (!m_impl->getActiveUniform(EXTRACT(program), index, webInfo)) + return false; + info.name = webInfo.name; + info.type = webInfo.type; + info.size = webInfo.size; + return true; } -void GraphicsContext3D::deleteBuffer(unsigned buffer) +int GraphicsContext3DInternal::getAttribLocation(WebGLProgram* program, const String& name) { - makeContextCurrent(); - glDeleteBuffers(1, &buffer); + return m_impl->getAttribLocation(EXTRACT(program), name.utf8().data()); } -void GraphicsContext3D::deleteFramebuffer(unsigned framebuffer) -{ - makeContextCurrent(); - glDeleteFramebuffersEXT(1, &framebuffer); -} +DELEGATE_TO_IMPL_2(getBooleanv, unsigned long, unsigned char*) -void GraphicsContext3D::deleteProgram(unsigned program) -{ - makeContextCurrent(); - glDeleteProgram(program); -} +DELEGATE_TO_IMPL_3(getBufferParameteriv, unsigned long, unsigned long, int*) -void GraphicsContext3D::deleteRenderbuffer(unsigned renderbuffer) +GraphicsContext3D::Attributes GraphicsContext3DInternal::getContextAttributes() { - makeContextCurrent(); - glDeleteRenderbuffersEXT(1, &renderbuffer); + WebKit::WebGraphicsContext3D::Attributes webAttributes = m_impl->getContextAttributes(); + GraphicsContext3D::Attributes attributes; + attributes.alpha = webAttributes.alpha; + attributes.depth = webAttributes.depth; + attributes.stencil = webAttributes.stencil; + attributes.antialias = webAttributes.antialias; + attributes.premultipliedAlpha = webAttributes.premultipliedAlpha; + return attributes; } -void GraphicsContext3D::deleteShader(unsigned shader) -{ - makeContextCurrent(); - glDeleteShader(shader); -} +DELEGATE_TO_IMPL_R(getError, unsigned long) -void GraphicsContext3D::deleteTexture(unsigned texture) -{ - makeContextCurrent(); - glDeleteTextures(1, &texture); -} +DELEGATE_TO_IMPL_2(getFloatv, unsigned long, float*) + +DELEGATE_TO_IMPL_4(getFramebufferAttachmentParameteriv, unsigned long, unsigned long, unsigned long, int*) -void GraphicsContext3D::activeTexture(unsigned long texture) +DELEGATE_TO_IMPL_2(getIntegerv, unsigned long, int*) + +DELEGATE_TO_IMPL_3_X1(getProgramiv, WebGLProgram*, unsigned long, int*) + +String GraphicsContext3DInternal::getProgramInfoLog(WebGLProgram* program) { - m_internal->activeTexture(texture); + return m_impl->getProgramInfoLog(EXTRACT(program)); } -GL_SAME_METHOD_2_X12(AttachShader, attachShader, WebGLProgram*, WebGLShader*) +DELEGATE_TO_IMPL_3(getRenderbufferParameteriv, unsigned long, unsigned long, int*) -void GraphicsContext3D::bindAttribLocation(WebGLProgram* program, - unsigned long index, - const String& name) +DELEGATE_TO_IMPL_3_X1(getShaderiv, WebGLShader*, unsigned long, int*) + +String GraphicsContext3DInternal::getShaderInfoLog(WebGLShader* shader) { - if (!program) - return; - makeContextCurrent(); - glBindAttribLocation(EXTRACT(program), index, name.utf8().data()); + return m_impl->getShaderInfoLog(EXTRACT(shader)); } -void GraphicsContext3D::bindBuffer(unsigned long target, - WebGLBuffer* buffer) +String GraphicsContext3DInternal::getShaderSource(WebGLShader* shader) { - m_internal->bindBuffer(target, buffer); + return m_impl->getShaderSource(EXTRACT(shader)); } -void GraphicsContext3D::bindFramebuffer(unsigned long target, WebGLFramebuffer* framebuffer) +String GraphicsContext3DInternal::getString(unsigned long name) { - m_internal->bindFramebuffer(target, framebuffer); + return m_impl->getString(name); } -GL_SAME_METHOD_2_X2(BindRenderbufferEXT, bindRenderbuffer, unsigned long, WebGLRenderbuffer*) +DELEGATE_TO_IMPL_3(getTexParameterfv, unsigned long, unsigned long, float*) +DELEGATE_TO_IMPL_3(getTexParameteriv, unsigned long, unsigned long, int*) -// If we didn't have to hack GL_TEXTURE_WRAP_R for cube maps, -// we could just use: -// GL_SAME_METHOD_2_X2(BindTexture, bindTexture, unsigned long, WebGLTexture*) -void GraphicsContext3D::bindTexture(unsigned long target, - WebGLTexture* texture) +DELEGATE_TO_IMPL_3_X1(getUniformfv, WebGLProgram*, long, float*) +DELEGATE_TO_IMPL_3_X1(getUniformiv, WebGLProgram*, long, int*) + +long GraphicsContext3DInternal::getUniformLocation(WebGLProgram* program, const String& name) { - m_internal->bindTexture(target, texture); + return m_impl->getUniformLocation(EXTRACT(program), name.utf8().data()); } -GL_SAME_METHOD_4(BlendColor, blendColor, double, double, double, double) - -GL_SAME_METHOD_1(BlendEquation, blendEquation, unsigned long) +DELEGATE_TO_IMPL_3(getVertexAttribfv, unsigned long, unsigned long, float*) +DELEGATE_TO_IMPL_3(getVertexAttribiv, unsigned long, unsigned long, int*) -GL_SAME_METHOD_2(BlendEquationSeparate, blendEquationSeparate, unsigned long, unsigned long) +DELEGATE_TO_IMPL_2R(getVertexAttribOffset, unsigned long, unsigned long, long) -GL_SAME_METHOD_2(BlendFunc, blendFunc, unsigned long, unsigned long) +DELEGATE_TO_IMPL_2(hint, unsigned long, unsigned long) +DELEGATE_TO_IMPL_1R_X(isBuffer, WebGLBuffer*, bool) +DELEGATE_TO_IMPL_1R(isEnabled, unsigned long, bool) +DELEGATE_TO_IMPL_1R_X(isFramebuffer, WebGLFramebuffer*, bool) +DELEGATE_TO_IMPL_1R_X(isProgram, WebGLProgram*, bool) +DELEGATE_TO_IMPL_1R_X(isRenderbuffer, WebGLRenderbuffer*, bool) +DELEGATE_TO_IMPL_1R_X(isShader, WebGLShader*, bool) +DELEGATE_TO_IMPL_1R_X(isTexture, WebGLTexture*, bool) +DELEGATE_TO_IMPL_1(lineWidth, double) +DELEGATE_TO_IMPL_1_X(linkProgram, WebGLProgram*) +DELEGATE_TO_IMPL_2(pixelStorei, unsigned long, long) +DELEGATE_TO_IMPL_2(polygonOffset, double, double) +DELEGATE_TO_IMPL_7(readPixels, long, long, unsigned long, unsigned long, unsigned long, unsigned long, void*) +DELEGATE_TO_IMPL(releaseShaderCompiler) +DELEGATE_TO_IMPL_4(renderbufferStorage, unsigned long, unsigned long, unsigned long, unsigned long) +DELEGATE_TO_IMPL_2(sampleCoverage, double, bool) +DELEGATE_TO_IMPL_4(scissor, long, long, unsigned long, unsigned long) -GL_SAME_METHOD_4(BlendFuncSeparate, blendFuncSeparate, unsigned long, unsigned long, unsigned long, unsigned long) - -void GraphicsContext3D::bufferData(unsigned long target, int size, unsigned long usage) +void GraphicsContext3DInternal::shaderSource(WebGLShader* shader, const String& string) { - m_internal->bufferDataImpl(target, size, 0, usage); + m_impl->shaderSource(EXTRACT(shader), string.utf8().data()); } -void GraphicsContext3D::bufferData(unsigned long target, WebGLArray* array, unsigned long usage) +DELEGATE_TO_IMPL_3(stencilFunc, unsigned long, long, unsigned long) +DELEGATE_TO_IMPL_4(stencilFuncSeparate, unsigned long, unsigned long, long, unsigned long) +DELEGATE_TO_IMPL_1(stencilMask, unsigned long) +DELEGATE_TO_IMPL_2(stencilMaskSeparate, unsigned long, unsigned long) +DELEGATE_TO_IMPL_3(stencilOp, unsigned long, unsigned long, unsigned long) +DELEGATE_TO_IMPL_4(stencilOpSeparate, unsigned long, unsigned long, unsigned long, unsigned long) + +int GraphicsContext3DInternal::texImage2D(unsigned target, unsigned level, unsigned internalformat, unsigned width, unsigned height, unsigned border, unsigned format, unsigned type, void* pixels) { - m_internal->bufferDataImpl(target, array->byteLength(), array->baseAddress(), usage); + m_impl->texImage2D(target, level, internalformat, width, height, border, format, type, pixels); + return 0; } -void GraphicsContext3D::bufferSubData(unsigned long target, long offset, WebGLArray* array) -{ - if (!array || !array->length()) - return; +DELEGATE_TO_IMPL_3(texParameterf, unsigned, unsigned, float) +DELEGATE_TO_IMPL_3(texParameteri, unsigned, unsigned, int) - makeContextCurrent(); - // FIXME: make this verification more efficient. - GLint binding = 0; - GLenum binding_target = GL_ARRAY_BUFFER_BINDING; - if (target == GL_ELEMENT_ARRAY_BUFFER) - binding_target = GL_ELEMENT_ARRAY_BUFFER_BINDING; - glGetIntegerv(binding_target, &binding); - if (binding <= 0) { - // FIXME: raise exception. - // LogMessagef(("bufferSubData: no buffer bound")); - return; - } - glBufferSubData(target, offset, array->byteLength(), array->baseAddress()); +int GraphicsContext3DInternal::texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset, unsigned width, unsigned height, unsigned format, unsigned type, void* pixels) +{ + m_impl->texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels); + return 0; } -unsigned long GraphicsContext3D::checkFramebufferStatus(unsigned long target) +DELEGATE_TO_IMPL_2(uniform1f, long, float) + +void GraphicsContext3DInternal::uniform1fv(long location, float* v, int size) { - makeContextCurrent(); - return glCheckFramebufferStatusEXT(target); + m_impl->uniform1fv(location, size, v); } -GL_SAME_METHOD_1(Clear, clear, unsigned long) - -GL_SAME_METHOD_4(ClearColor, clearColor, double, double, double, double) +DELEGATE_TO_IMPL_2(uniform1i, long, int) -GL_SAME_METHOD_1(ClearDepth, clearDepth, double) +void GraphicsContext3DInternal::uniform1iv(long location, int* v, int size) +{ + m_impl->uniform1iv(location, size, v); +} -GL_SAME_METHOD_1(ClearStencil, clearStencil, long) +DELEGATE_TO_IMPL_3(uniform2f, long, float, float) -GL_SAME_METHOD_4(ColorMask, colorMask, bool, bool, bool, bool) +void GraphicsContext3DInternal::uniform2fv(long location, float* v, int size) +{ + m_impl->uniform2fv(location, size, v); +} -GL_SAME_METHOD_1_X(CompileShader, compileShader, WebGLShader*) +DELEGATE_TO_IMPL_3(uniform2i, long, int, int) -GL_SAME_METHOD_8(CopyTexImage2D, copyTexImage2D, unsigned long, long, unsigned long, long, long, unsigned long, unsigned long, long) +void GraphicsContext3DInternal::uniform2iv(long location, int* v, int size) +{ + m_impl->uniform2iv(location, size, v); +} -GL_SAME_METHOD_8(CopyTexSubImage2D, copyTexSubImage2D, unsigned long, long, long, long, long, long, unsigned long, unsigned long) +DELEGATE_TO_IMPL_4(uniform3f, long, float, float, float) -GL_SAME_METHOD_1(CullFace, cullFace, unsigned long) +void GraphicsContext3DInternal::uniform3fv(long location, float* v, int size) +{ + m_impl->uniform3fv(location, size, v); +} -GL_SAME_METHOD_1(DepthFunc, depthFunc, unsigned long) +DELEGATE_TO_IMPL_4(uniform3i, long, int, int, int) -GL_SAME_METHOD_1(DepthMask, depthMask, bool) +void GraphicsContext3DInternal::uniform3iv(long location, int* v, int size) +{ + m_impl->uniform3iv(location, size, v); +} -GL_SAME_METHOD_2(DepthRange, depthRange, double, double) +DELEGATE_TO_IMPL_5(uniform4f, long, float, float, float, float) -void GraphicsContext3D::detachShader(WebGLProgram* program, WebGLShader* shader) +void GraphicsContext3DInternal::uniform4fv(long location, float* v, int size) { - if (!program || !shader) - return; - - makeContextCurrent(); - glDetachShader(EXTRACT(program), EXTRACT(shader)); + m_impl->uniform4fv(location, size, v); } -GL_SAME_METHOD_1(Disable, disable, unsigned long) +DELEGATE_TO_IMPL_5(uniform4i, long, int, int, int, int) -void GraphicsContext3D::disableVertexAttribArray(unsigned long index) +void GraphicsContext3DInternal::uniform4iv(long location, int* v, int size) { - m_internal->disableVertexAttribArray(index); + m_impl->uniform4iv(location, size, v); } -void GraphicsContext3D::drawArrays(unsigned long mode, long first, long count) +void GraphicsContext3DInternal::uniformMatrix2fv(long location, bool transpose, float* value, int size) { - switch (mode) { - case GL_TRIANGLES: - case GL_TRIANGLE_STRIP: - case GL_TRIANGLE_FAN: - case GL_POINTS: - case GL_LINE_STRIP: - case GL_LINE_LOOP: - case GL_LINES: - break; - default: // FIXME: default cases are discouraged in WebKit. - // FIXME: output log message, raise exception. - // LogMessage(NS_LITERAL_CSTRING("drawArrays: invalid mode")); - // return NS_ERROR_DOM_SYNTAX_ERR; - return; - } - - if (first+count < first || first+count < count) { - // FIXME: output log message, raise exception. - // LogMessage(NS_LITERAL_CSTRING("drawArrays: overflow in first+count")); - // return NS_ERROR_INVALID_ARG; - return; - } - - // FIXME: validate against currently bound buffer. - // if (!ValidateBuffers(first+count)) - // return NS_ERROR_INVALID_ARG; - - makeContextCurrent(); - glDrawArrays(mode, first, count); + m_impl->uniformMatrix2fv(location, size, transpose, value); } -void GraphicsContext3D::drawElements(unsigned long mode, unsigned long count, unsigned long type, long offset) +void GraphicsContext3DInternal::uniformMatrix3fv(long location, bool transpose, float* value, int size) { - makeContextCurrent(); - // FIXME: make this verification more efficient. - GLint binding = 0; - GLenum binding_target = GL_ELEMENT_ARRAY_BUFFER_BINDING; - glGetIntegerv(binding_target, &binding); - if (binding <= 0) { - // FIXME: raise exception. - // LogMessagef(("bufferData: no buffer bound")); - return; - } - glDrawElements(mode, count, type, - reinterpret_cast<void*>(static_cast<intptr_t>(offset))); + m_impl->uniformMatrix3fv(location, size, transpose, value); } -GL_SAME_METHOD_1(Enable, enable, unsigned long) - -void GraphicsContext3D::enableVertexAttribArray(unsigned long index) +void GraphicsContext3DInternal::uniformMatrix4fv(long location, bool transpose, float* value, int size) { - m_internal->enableVertexAttribArray(index); + m_impl->uniformMatrix4fv(location, size, transpose, value); } -GL_SAME_METHOD_0(Finish, finish) +DELEGATE_TO_IMPL_1_X(useProgram, WebGLProgram*) +DELEGATE_TO_IMPL_1_X(validateProgram, WebGLProgram*) -GL_SAME_METHOD_0(Flush, flush) +DELEGATE_TO_IMPL_2(vertexAttrib1f, unsigned long, float) +DELEGATE_TO_IMPL_2(vertexAttrib1fv, unsigned long, float*) +DELEGATE_TO_IMPL_3(vertexAttrib2f, unsigned long, float, float) +DELEGATE_TO_IMPL_2(vertexAttrib2fv, unsigned long, float*) +DELEGATE_TO_IMPL_4(vertexAttrib3f, unsigned long, float, float, float) +DELEGATE_TO_IMPL_2(vertexAttrib3fv, unsigned long, float*) +DELEGATE_TO_IMPL_5(vertexAttrib4f, unsigned long, float, float, float, float) +DELEGATE_TO_IMPL_2(vertexAttrib4fv, unsigned long, float*) +DELEGATE_TO_IMPL_6(vertexAttribPointer, unsigned long, int, int, bool, unsigned long, unsigned long) -GL_SAME_METHOD_4_X4(FramebufferRenderbufferEXT, framebufferRenderbuffer, unsigned long, unsigned long, unsigned long, WebGLRenderbuffer*) +DELEGATE_TO_IMPL_4(viewport, long, long, unsigned long, unsigned long) -GL_SAME_METHOD_5_X4(FramebufferTexture2DEXT, framebufferTexture2D, unsigned long, unsigned long, unsigned long, WebGLTexture*, long) +DELEGATE_TO_IMPL_R(createBuffer, unsigned) +DELEGATE_TO_IMPL_R(createFramebuffer, unsigned) +DELEGATE_TO_IMPL_R(createProgram, unsigned) +DELEGATE_TO_IMPL_R(createRenderbuffer, unsigned) +DELEGATE_TO_IMPL_1R(createShader, unsigned long, unsigned) +DELEGATE_TO_IMPL_R(createTexture, unsigned) -GL_SAME_METHOD_1(FrontFace, frontFace, unsigned long) +DELEGATE_TO_IMPL_1(deleteBuffer, unsigned) +DELEGATE_TO_IMPL_1(deleteFramebuffer, unsigned) +DELEGATE_TO_IMPL_1(deleteProgram, unsigned) +DELEGATE_TO_IMPL_1(deleteRenderbuffer, unsigned) +DELEGATE_TO_IMPL_1(deleteShader, unsigned) +DELEGATE_TO_IMPL_1(deleteTexture, unsigned) -void GraphicsContext3D::generateMipmap(unsigned long target) -{ - makeContextCurrent(); - if (glGenerateMipmapEXT) - glGenerateMipmapEXT(target); - // FIXME: provide alternative code path? This will be unpleasant - // to implement if glGenerateMipmapEXT is not available -- it will - // require a texture readback and re-upload. -} +DELEGATE_TO_IMPL_1(synthesizeGLError, unsigned long) -bool GraphicsContext3D::getActiveAttrib(WebGLProgram* program, unsigned long index, ActiveInfo& info) -{ - if (!program) { - synthesizeGLError(INVALID_VALUE); - return false; - } - GLint maxNameLength = -1; - glGetProgramiv(EXTRACT(program), GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &maxNameLength); - if (maxNameLength < 0) - return false; - GLchar* name = 0; - if (!tryFastMalloc(maxNameLength * sizeof(GLchar)).getValue(name)) { - synthesizeGLError(OUT_OF_MEMORY); - return false; - } - GLsizei length = 0; - GLint size = -1; - GLenum type = 0; - glGetActiveAttrib(EXTRACT(program), index, maxNameLength, - &length, &size, &type, name); - if (size < 0) { - fastFree(name); - return false; - } - info.name = String(name, length); - info.type = type; - info.size = size; - fastFree(name); - return true; -} +//---------------------------------------------------------------------- +// GraphicsContext3D +// -bool GraphicsContext3D::getActiveUniform(WebGLProgram* program, unsigned long index, ActiveInfo& info) -{ - if (!program) { - synthesizeGLError(INVALID_VALUE); - return false; - } - GLint maxNameLength = -1; - glGetProgramiv(EXTRACT(program), GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxNameLength); - if (maxNameLength < 0) - return false; - GLchar* name = 0; - if (!tryFastMalloc(maxNameLength * sizeof(GLchar)).getValue(name)) { - synthesizeGLError(OUT_OF_MEMORY); - return false; - } - GLsizei length = 0; - GLint size = -1; - GLenum type = 0; - glGetActiveUniform(EXTRACT(program), index, maxNameLength, - &length, &size, &type, name); - if (size < 0) { - fastFree(name); - return false; - } - info.name = String(name, length); - info.type = type; - info.size = size; - fastFree(name); - return true; -} +// Macros to assist in delegating from GraphicsContext3D to +// GraphicsContext3DInternal. -int GraphicsContext3D::getAttribLocation(WebGLProgram* program, const String& name) -{ - if (!program) - return -1; +#define DELEGATE_TO_INTERNAL(name) \ +void GraphicsContext3D::name() \ +{ \ + m_internal->name(); \ +} - makeContextCurrent(); - return glGetAttribLocation(EXTRACT(program), name.utf8().data()); +#define DELEGATE_TO_INTERNAL_R(name, rt) \ +rt GraphicsContext3D::name() \ +{ \ + return m_internal->name(); \ } -void GraphicsContext3D::getBooleanv(unsigned long pname, unsigned char* value) -{ - makeContextCurrent(); - glGetBooleanv(pname, value); +#define DELEGATE_TO_INTERNAL_1(name, t1) \ +void GraphicsContext3D::name(t1 a1) \ +{ \ + m_internal->name(a1); \ } -void GraphicsContext3D::getBufferParameteriv(unsigned long target, unsigned long pname, int* value) -{ - makeContextCurrent(); - glGetBufferParameteriv(target, pname, value); +#define DELEGATE_TO_INTERNAL_1R(name, t1, rt) \ +rt GraphicsContext3D::name(t1 a1) \ +{ \ + return m_internal->name(a1); \ } -GraphicsContext3D::Attributes GraphicsContext3D::getContextAttributes() -{ - return m_internal->getContextAttributes(); +#define DELEGATE_TO_INTERNAL_2(name, t1, t2) \ +void GraphicsContext3D::name(t1 a1, t2 a2) \ +{ \ + m_internal->name(a1, a2); \ } -unsigned long GraphicsContext3D::getError() -{ - return m_internal->getError(); +#define DELEGATE_TO_INTERNAL_2R(name, t1, t2, rt) \ +rt GraphicsContext3D::name(t1 a1, t2 a2) \ +{ \ + return m_internal->name(a1, a2); \ } -void GraphicsContext3D::getFloatv(unsigned long pname, float* value) -{ - makeContextCurrent(); - glGetFloatv(pname, value); +#define DELEGATE_TO_INTERNAL_3(name, t1, t2, t3) \ +void GraphicsContext3D::name(t1 a1, t2 a2, t3 a3) \ +{ \ + m_internal->name(a1, a2, a3); \ } -void GraphicsContext3D::getFramebufferAttachmentParameteriv(unsigned long target, - unsigned long attachment, - unsigned long pname, - int* value) -{ - makeContextCurrent(); - glGetFramebufferAttachmentParameterivEXT(target, attachment, pname, value); +#define DELEGATE_TO_INTERNAL_3R(name, t1, t2, t3, rt) \ +rt GraphicsContext3D::name(t1 a1, t2 a2, t3 a3) \ +{ \ + return m_internal->name(a1, a2, a3); \ } -void GraphicsContext3D::getIntegerv(unsigned long pname, int* value) -{ - makeContextCurrent(); - glGetIntegerv(pname, value); +#define DELEGATE_TO_INTERNAL_4(name, t1, t2, t3, t4) \ +void GraphicsContext3D::name(t1 a1, t2 a2, t3 a3, t4 a4) \ +{ \ + m_internal->name(a1, a2, a3, a4); \ } -void GraphicsContext3D::getProgramiv(WebGLProgram* program, - unsigned long pname, - int* value) -{ - makeContextCurrent(); - glGetProgramiv(EXTRACT(program), pname, value); +#define DELEGATE_TO_INTERNAL_5(name, t1, t2, t3, t4, t5) \ +void GraphicsContext3D::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5) \ +{ \ + m_internal->name(a1, a2, a3, a4, a5); \ } -String GraphicsContext3D::getProgramInfoLog(WebGLProgram* program) -{ - makeContextCurrent(); - GLuint programID = EXTRACT(program); - GLint logLength; - glGetProgramiv(programID, GL_INFO_LOG_LENGTH, &logLength); - if (!logLength) - return String(); - GLchar* log = 0; - if (!tryFastMalloc(logLength * sizeof(GLchar)).getValue(log)) - return String(); - GLsizei returnedLogLength; - glGetProgramInfoLog(programID, logLength, &returnedLogLength, log); - ASSERT(logLength == returnedLogLength + 1); - String res = String(log, returnedLogLength); - fastFree(log); - return res; -} - -void GraphicsContext3D::getRenderbufferParameteriv(unsigned long target, - unsigned long pname, - int* value) -{ - makeContextCurrent(); - glGetRenderbufferParameterivEXT(target, pname, value); +#define DELEGATE_TO_INTERNAL_6(name, t1, t2, t3, t4, t5, t6) \ +void GraphicsContext3D::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6) \ +{ \ + m_internal->name(a1, a2, a3, a4, a5, a6); \ } -void GraphicsContext3D::getShaderiv(WebGLShader* shader, - unsigned long pname, - int* value) -{ - makeContextCurrent(); - glGetShaderiv(EXTRACT(shader), pname, value); +#define DELEGATE_TO_INTERNAL_6R(name, t1, t2, t3, t4, t5, t6, rt) \ +rt GraphicsContext3D::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6) \ +{ \ + return m_internal->name(a1, a2, a3, a4, a5, a6); \ } -String GraphicsContext3D::getShaderInfoLog(WebGLShader* shader) -{ - makeContextCurrent(); - GLuint shaderID = EXTRACT(shader); - GLint logLength; - glGetShaderiv(shaderID, GL_INFO_LOG_LENGTH, &logLength); - if (!logLength) - return String(); - GLchar* log = 0; - if (!tryFastMalloc(logLength * sizeof(GLchar)).getValue(log)) - return String(); - GLsizei returnedLogLength; - glGetShaderInfoLog(shaderID, logLength, &returnedLogLength, log); - ASSERT(logLength == returnedLogLength + 1); - String res = String(log, returnedLogLength); - fastFree(log); - return res; -} - -String GraphicsContext3D::getShaderSource(WebGLShader* shader) -{ - makeContextCurrent(); - GLuint shaderID = EXTRACT(shader); - GLint logLength; - glGetShaderiv(shaderID, GL_SHADER_SOURCE_LENGTH, &logLength); - if (!logLength) - return String(); - GLchar* log = 0; - if (!tryFastMalloc(logLength * sizeof(GLchar)).getValue(log)) - return String(); - GLsizei returnedLogLength; - glGetShaderSource(shaderID, logLength, &returnedLogLength, log); - ASSERT(logLength == returnedLogLength + 1); - String res = String(log, returnedLogLength); - fastFree(log); - return res; -} - -String GraphicsContext3D::getString(unsigned long name) -{ - makeContextCurrent(); - return String(reinterpret_cast<const char*>(glGetString(name))); +#define DELEGATE_TO_INTERNAL_7(name, t1, t2, t3, t4, t5, t6, t7) \ +void GraphicsContext3D::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7) \ +{ \ + m_internal->name(a1, a2, a3, a4, a5, a6, a7); \ } -void GraphicsContext3D::getTexParameterfv(unsigned long target, unsigned long pname, float* value) -{ - makeContextCurrent(); - glGetTexParameterfv(target, pname, value); +#define DELEGATE_TO_INTERNAL_7R(name, t1, t2, t3, t4, t5, t6, t7, rt) \ +rt GraphicsContext3D::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7) \ +{ \ + return m_internal->name(a1, a2, a3, a4, a5, a6, a7); \ } -void GraphicsContext3D::getTexParameteriv(unsigned long target, unsigned long pname, int* value) -{ - makeContextCurrent(); - glGetTexParameteriv(target, pname, value); +#define DELEGATE_TO_INTERNAL_8(name, t1, t2, t3, t4, t5, t6, t7, t8) \ +void GraphicsContext3D::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7, t8 a8) \ +{ \ + m_internal->name(a1, a2, a3, a4, a5, a6, a7, a8); \ } -void GraphicsContext3D::getUniformfv(WebGLProgram* program, long location, float* value) -{ - makeContextCurrent(); - glGetUniformfv(EXTRACT(program), location, value); +#define DELEGATE_TO_INTERNAL_9R(name, t1, t2, t3, t4, t5, t6, t7, t8, t9, rt) \ +rt GraphicsContext3D::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7, t8 a8, t9 a9) \ +{ \ + return m_internal->name(a1, a2, a3, a4, a5, a6, a7, a8, a9); \ } -void GraphicsContext3D::getUniformiv(WebGLProgram* program, long location, int* value) +GraphicsContext3D::GraphicsContext3D(GraphicsContext3D::Attributes, HostWindow*) { - makeContextCurrent(); - glGetUniformiv(EXTRACT(program), location, value); } -long GraphicsContext3D::getUniformLocation(WebGLProgram* program, const String& name) +GraphicsContext3D::~GraphicsContext3D() { - if (!program) - return -1; - - makeContextCurrent(); - return glGetUniformLocation(EXTRACT(program), name.utf8().data()); } -void GraphicsContext3D::getVertexAttribfv(unsigned long index, - unsigned long pname, - float* value) +PassOwnPtr<GraphicsContext3D> GraphicsContext3D::create(GraphicsContext3D::Attributes attrs, HostWindow* hostWindow) { - makeContextCurrent(); - glGetVertexAttribfv(index, pname, value); + GraphicsContext3DInternal* internal = new GraphicsContext3DInternal(); + if (!internal->initialize(attrs)) { + delete internal; + return 0; + } + PassOwnPtr<GraphicsContext3D> result = new GraphicsContext3D(attrs, hostWindow); + result->m_internal.set(internal); + return result; } -void GraphicsContext3D::getVertexAttribiv(unsigned long index, - unsigned long pname, - int* value) +PlatformGraphicsContext3D GraphicsContext3D::platformGraphicsContext3D() const { - makeContextCurrent(); - glGetVertexAttribiv(index, pname, value); + return m_internal->platformGraphicsContext3D(); } -long GraphicsContext3D::getVertexAttribOffset(unsigned long index, unsigned long pname) +Platform3DObject GraphicsContext3D::platformTexture() const { - // FIXME: implement. - notImplemented(); - return 0; + return m_internal->platformTexture(); } -GL_SAME_METHOD_2(Hint, hint, unsigned long, unsigned long); +DELEGATE_TO_INTERNAL(makeContextCurrent) +DELEGATE_TO_INTERNAL_1R(sizeInBytes, int, int) +DELEGATE_TO_INTERNAL_2(reshape, int, int) -bool GraphicsContext3D::isBuffer(WebGLBuffer* buffer) -{ - makeContextCurrent(); - return glIsBuffer(EXTRACT(buffer)); -} +DELEGATE_TO_INTERNAL_1(activeTexture, unsigned long) +DELEGATE_TO_INTERNAL_2(attachShader, WebGLProgram*, WebGLShader*) +DELEGATE_TO_INTERNAL_3(bindAttribLocation, WebGLProgram*, unsigned long, const String&) -bool GraphicsContext3D::isEnabled(unsigned long cap) -{ - makeContextCurrent(); - return glIsEnabled(cap); -} +DELEGATE_TO_INTERNAL_2(bindBuffer, unsigned long, WebGLBuffer*) +DELEGATE_TO_INTERNAL_2(bindFramebuffer, unsigned long, WebGLFramebuffer*) +DELEGATE_TO_INTERNAL_2(bindRenderbuffer, unsigned long, WebGLRenderbuffer*) +DELEGATE_TO_INTERNAL_2(bindTexture, unsigned long, WebGLTexture*) +DELEGATE_TO_INTERNAL_4(blendColor, double, double, double, double) +DELEGATE_TO_INTERNAL_1(blendEquation, unsigned long) +DELEGATE_TO_INTERNAL_2(blendEquationSeparate, unsigned long, unsigned long) +DELEGATE_TO_INTERNAL_2(blendFunc, unsigned long, unsigned long) +DELEGATE_TO_INTERNAL_4(blendFuncSeparate, unsigned long, unsigned long, unsigned long, unsigned long) -bool GraphicsContext3D::isFramebuffer(WebGLFramebuffer* framebuffer) -{ - makeContextCurrent(); - return glIsFramebufferEXT(EXTRACT(framebuffer)); -} +DELEGATE_TO_INTERNAL_3(bufferData, unsigned long, int, unsigned long) +DELEGATE_TO_INTERNAL_3(bufferData, unsigned long, WebGLArray*, unsigned long) +DELEGATE_TO_INTERNAL_3(bufferSubData, unsigned long, long, WebGLArray*) -bool GraphicsContext3D::isProgram(WebGLProgram* program) -{ - makeContextCurrent(); - return glIsProgram(EXTRACT(program)); -} +DELEGATE_TO_INTERNAL_1R(checkFramebufferStatus, unsigned long, unsigned long) +DELEGATE_TO_INTERNAL_1(clear, unsigned long) +DELEGATE_TO_INTERNAL_4(clearColor, double, double, double, double) +DELEGATE_TO_INTERNAL_1(clearDepth, double) +DELEGATE_TO_INTERNAL_1(clearStencil, long) +DELEGATE_TO_INTERNAL_4(colorMask, bool, bool, bool, bool) +DELEGATE_TO_INTERNAL_1(compileShader, WebGLShader*) -bool GraphicsContext3D::isRenderbuffer(WebGLRenderbuffer* renderbuffer) -{ - makeContextCurrent(); - return glIsRenderbufferEXT(EXTRACT(renderbuffer)); -} +DELEGATE_TO_INTERNAL_8(copyTexImage2D, unsigned long, long, unsigned long, long, long, unsigned long, unsigned long, long) +DELEGATE_TO_INTERNAL_8(copyTexSubImage2D, unsigned long, long, long, long, long, long, unsigned long, unsigned long) +DELEGATE_TO_INTERNAL_1(cullFace, unsigned long) +DELEGATE_TO_INTERNAL_1(depthFunc, unsigned long) +DELEGATE_TO_INTERNAL_1(depthMask, bool) +DELEGATE_TO_INTERNAL_2(depthRange, double, double) +DELEGATE_TO_INTERNAL_2(detachShader, WebGLProgram*, WebGLShader*) +DELEGATE_TO_INTERNAL_1(disable, unsigned long) +DELEGATE_TO_INTERNAL_1(disableVertexAttribArray, unsigned long) +DELEGATE_TO_INTERNAL_3(drawArrays, unsigned long, long, long) +DELEGATE_TO_INTERNAL_4(drawElements, unsigned long, unsigned long, unsigned long, long) -bool GraphicsContext3D::isShader(WebGLShader* shader) -{ - makeContextCurrent(); - return glIsShader(EXTRACT(shader)); -} +DELEGATE_TO_INTERNAL_1(enable, unsigned long) +DELEGATE_TO_INTERNAL_1(enableVertexAttribArray, unsigned long) +DELEGATE_TO_INTERNAL(finish) +DELEGATE_TO_INTERNAL(flush) +DELEGATE_TO_INTERNAL_4(framebufferRenderbuffer, unsigned long, unsigned long, unsigned long, WebGLRenderbuffer*) +DELEGATE_TO_INTERNAL_5(framebufferTexture2D, unsigned long, unsigned long, unsigned long, WebGLTexture*, long) +DELEGATE_TO_INTERNAL_1(frontFace, unsigned long) +DELEGATE_TO_INTERNAL_1(generateMipmap, unsigned long) -bool GraphicsContext3D::isTexture(WebGLTexture* texture) -{ - makeContextCurrent(); - return glIsTexture(EXTRACT(texture)); -} +DELEGATE_TO_INTERNAL_3R(getActiveAttrib, WebGLProgram*, unsigned long, ActiveInfo&, bool) +DELEGATE_TO_INTERNAL_3R(getActiveUniform, WebGLProgram*, unsigned long, ActiveInfo&, bool) -GL_SAME_METHOD_1(LineWidth, lineWidth, double) +DELEGATE_TO_INTERNAL_2R(getAttribLocation, WebGLProgram*, const String&, int) -GL_SAME_METHOD_1_X(LinkProgram, linkProgram, WebGLProgram*) +DELEGATE_TO_INTERNAL_2(getBooleanv, unsigned long, unsigned char*) -void GraphicsContext3D::pixelStorei(unsigned long pname, long param) -{ - if (pname != GL_PACK_ALIGNMENT && pname != GL_UNPACK_ALIGNMENT) { - // FIXME: Create a fake GL error and throw an exception. - return; - } +DELEGATE_TO_INTERNAL_3(getBufferParameteriv, unsigned long, unsigned long, int*) - makeContextCurrent(); - glPixelStorei(pname, param); -} +DELEGATE_TO_INTERNAL_R(getContextAttributes, GraphicsContext3D::Attributes) -GL_SAME_METHOD_2(PolygonOffset, polygonOffset, double, double) +DELEGATE_TO_INTERNAL_R(getError, unsigned long) -PassRefPtr<WebGLArray> GraphicsContext3D::readPixels(long x, long y, - unsigned long width, unsigned long height, - unsigned long format, unsigned long type) { - // FIXME: support more pixel formats and types. - if (!((format == GL_RGBA) && (type == GL_UNSIGNED_BYTE))) - return 0; +DELEGATE_TO_INTERNAL_2(getFloatv, unsigned long, float*) - // FIXME: take into account pack alignment. - RefPtr<WebGLUnsignedByteArray> array = WebGLUnsignedByteArray::create(width * height * 4); - glReadPixels(x, y, width, height, format, type, array->baseAddress()); - return array; -} +DELEGATE_TO_INTERNAL_4(getFramebufferAttachmentParameteriv, unsigned long, unsigned long, unsigned long, int*) -void GraphicsContext3D::releaseShaderCompiler() -{ -} +DELEGATE_TO_INTERNAL_2(getIntegerv, unsigned long, int*) -GL_SAME_METHOD_4(RenderbufferStorageEXT, renderbufferStorage, unsigned long, unsigned long, unsigned long, unsigned long) +DELEGATE_TO_INTERNAL_3(getProgramiv, WebGLProgram*, unsigned long, int*) -GL_SAME_METHOD_2(SampleCoverage, sampleCoverage, double, bool) +DELEGATE_TO_INTERNAL_1R(getProgramInfoLog, WebGLProgram*, String) -GL_SAME_METHOD_4(Scissor, scissor, long, long, unsigned long, unsigned long) +DELEGATE_TO_INTERNAL_3(getRenderbufferParameteriv, unsigned long, unsigned long, int*) -void GraphicsContext3D::shaderSource(WebGLShader* shader, const String& source) -{ - makeContextCurrent(); - CString str = source.utf8(); - const char* data = str.data(); - GLint length = str.length(); - glShaderSource(EXTRACT(shader), 1, &data, &length); -} +DELEGATE_TO_INTERNAL_3(getShaderiv, WebGLShader*, unsigned long, int*) -GL_SAME_METHOD_3(StencilFunc, stencilFunc, unsigned long, long, unsigned long) +DELEGATE_TO_INTERNAL_1R(getShaderInfoLog, WebGLShader*, String) -GL_SAME_METHOD_4(StencilFuncSeparate, stencilFuncSeparate, unsigned long, unsigned long, long, unsigned long) +DELEGATE_TO_INTERNAL_1R(getShaderSource, WebGLShader*, String) +DELEGATE_TO_INTERNAL_1R(getString, unsigned long, String) -GL_SAME_METHOD_1(StencilMask, stencilMask, unsigned long) +DELEGATE_TO_INTERNAL_3(getTexParameterfv, unsigned long, unsigned long, float*) +DELEGATE_TO_INTERNAL_3(getTexParameteriv, unsigned long, unsigned long, int*) -GL_SAME_METHOD_2(StencilMaskSeparate, stencilMaskSeparate, unsigned long, unsigned long) +DELEGATE_TO_INTERNAL_3(getUniformfv, WebGLProgram*, long, float*) +DELEGATE_TO_INTERNAL_3(getUniformiv, WebGLProgram*, long, int*) -GL_SAME_METHOD_3(StencilOp, stencilOp, unsigned long, unsigned long, unsigned long) +DELEGATE_TO_INTERNAL_2R(getUniformLocation, WebGLProgram*, const String&, long) -GL_SAME_METHOD_4(StencilOpSeparate, stencilOpSeparate, unsigned long, unsigned long, unsigned long, unsigned long) +DELEGATE_TO_INTERNAL_3(getVertexAttribfv, unsigned long, unsigned long, float*) +DELEGATE_TO_INTERNAL_3(getVertexAttribiv, unsigned long, unsigned long, int*) -void GraphicsContext3D::synthesizeGLError(unsigned long error) -{ - m_internal->synthesizeGLError(error); -} - -int GraphicsContext3D::texImage2D(unsigned target, - unsigned level, - unsigned internalformat, - unsigned width, - unsigned height, - unsigned border, - unsigned format, - unsigned type, - void* pixels) -{ - // FIXME: must do validation similar to JOGL's to ensure that - // the incoming array is of the appropriate length. - glTexImage2D(target, - level, - internalformat, - width, - height, - border, - format, - type, - pixels); - return 0; -} +DELEGATE_TO_INTERNAL_2R(getVertexAttribOffset, unsigned long, unsigned long, long) + +DELEGATE_TO_INTERNAL_2(hint, unsigned long, unsigned long) +DELEGATE_TO_INTERNAL_1R(isBuffer, WebGLBuffer*, bool) +DELEGATE_TO_INTERNAL_1R(isEnabled, unsigned long, bool) +DELEGATE_TO_INTERNAL_1R(isFramebuffer, WebGLFramebuffer*, bool) +DELEGATE_TO_INTERNAL_1R(isProgram, WebGLProgram*, bool) +DELEGATE_TO_INTERNAL_1R(isRenderbuffer, WebGLRenderbuffer*, bool) +DELEGATE_TO_INTERNAL_1R(isShader, WebGLShader*, bool) +DELEGATE_TO_INTERNAL_1R(isTexture, WebGLTexture*, bool) +DELEGATE_TO_INTERNAL_1(lineWidth, double) +DELEGATE_TO_INTERNAL_1(linkProgram, WebGLProgram*) +DELEGATE_TO_INTERNAL_2(pixelStorei, unsigned long, long) +DELEGATE_TO_INTERNAL_2(polygonOffset, double, double) + +DELEGATE_TO_INTERNAL_7(readPixels, long, long, unsigned long, unsigned long, unsigned long, unsigned long, void*) + +DELEGATE_TO_INTERNAL(releaseShaderCompiler) +DELEGATE_TO_INTERNAL_4(renderbufferStorage, unsigned long, unsigned long, unsigned long, unsigned long) +DELEGATE_TO_INTERNAL_2(sampleCoverage, double, bool) +DELEGATE_TO_INTERNAL_4(scissor, long, long, unsigned long, unsigned long) +DELEGATE_TO_INTERNAL_2(shaderSource, WebGLShader*, const String&) +DELEGATE_TO_INTERNAL_3(stencilFunc, unsigned long, long, unsigned long) +DELEGATE_TO_INTERNAL_4(stencilFuncSeparate, unsigned long, unsigned long, long, unsigned long) +DELEGATE_TO_INTERNAL_1(stencilMask, unsigned long) +DELEGATE_TO_INTERNAL_2(stencilMaskSeparate, unsigned long, unsigned long) +DELEGATE_TO_INTERNAL_3(stencilOp, unsigned long, unsigned long, unsigned long) +DELEGATE_TO_INTERNAL_4(stencilOpSeparate, unsigned long, unsigned long, unsigned long, unsigned long) + +DELEGATE_TO_INTERNAL_9R(texImage2D, unsigned, unsigned, unsigned, unsigned, unsigned, unsigned, unsigned, unsigned, void*, int) int GraphicsContext3D::texImage2D(unsigned target, unsigned level, Image* image, bool flipY, bool premultiplyAlpha) @@ -1880,29 +1210,15 @@ int GraphicsContext3D::texImage2D(unsigned target, unsigned level, Image* image, unsigned int format, internalFormat; if (!extractImageData(image, flipY, premultiplyAlpha, imageData, &format, &internalFormat)) return -1; - glTexImage2D(target, level, internalFormat, - image->width(), image->height(), 0, - format, GL_UNSIGNED_BYTE, imageData.data()); - return 0; + return m_internal->texImage2D(target, level, internalFormat, + image->width(), image->height(), 0, + format, UNSIGNED_BYTE, imageData.data()); } -GL_SAME_METHOD_3(TexParameterf, texParameterf, unsigned, unsigned, float); +DELEGATE_TO_INTERNAL_3(texParameterf, unsigned, unsigned, float) +DELEGATE_TO_INTERNAL_3(texParameteri, unsigned, unsigned, int) -GL_SAME_METHOD_3(TexParameteri, texParameteri, unsigned, unsigned, int); - -int GraphicsContext3D::texSubImage2D(unsigned target, - unsigned level, - unsigned xoffset, - unsigned yoffset, - unsigned width, - unsigned height, - unsigned format, - unsigned type, - void* pixels) -{ - glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels); - return 0; -} +DELEGATE_TO_INTERNAL_9R(texSubImage2D, unsigned, unsigned, unsigned, unsigned, unsigned, unsigned, unsigned, unsigned, void*, int) int GraphicsContext3D::texSubImage2D(unsigned target, unsigned level, @@ -1916,142 +1232,65 @@ int GraphicsContext3D::texSubImage2D(unsigned target, unsigned int format, internalFormat; if (!extractImageData(image, flipY, premultiplyAlpha, imageData, &format, &internalFormat)) return -1; - glTexSubImage2D(target, level, xoffset, yoffset, - image->width(), image->height(), - format, GL_UNSIGNED_BYTE, imageData.data()); - return 0; -} - -GL_SAME_METHOD_2(Uniform1f, uniform1f, long, float) - -void GraphicsContext3D::uniform1fv(long location, float* v, int size) -{ - makeContextCurrent(); - glUniform1fv(location, size, v); -} - -GL_SAME_METHOD_2(Uniform1i, uniform1i, long, int) - -void GraphicsContext3D::uniform1iv(long location, int* v, int size) -{ - makeContextCurrent(); - glUniform1iv(location, size, v); -} - -GL_SAME_METHOD_3(Uniform2f, uniform2f, long, float, float) - -void GraphicsContext3D::uniform2fv(long location, float* v, int size) -{ - makeContextCurrent(); - glUniform2fv(location, size, v); -} - -GL_SAME_METHOD_3(Uniform2i, uniform2i, long, int, int) - -void GraphicsContext3D::uniform2iv(long location, int* v, int size) -{ - makeContextCurrent(); - glUniform2iv(location, size, v); -} - -GL_SAME_METHOD_4(Uniform3f, uniform3f, long, float, float, float) - -void GraphicsContext3D::uniform3fv(long location, float* v, int size) -{ - makeContextCurrent(); - glUniform3fv(location, size, v); -} - -GL_SAME_METHOD_4(Uniform3i, uniform3i, long, int, int, int) - -void GraphicsContext3D::uniform3iv(long location, int* v, int size) -{ - makeContextCurrent(); - glUniform3iv(location, size, v); -} - -GL_SAME_METHOD_5(Uniform4f, uniform4f, long, float, float, float, float) - -void GraphicsContext3D::uniform4fv(long location, float* v, int size) -{ - makeContextCurrent(); - glUniform4fv(location, size, v); -} - -GL_SAME_METHOD_5(Uniform4i, uniform4i, long, int, int, int, int) - -void GraphicsContext3D::uniform4iv(long location, int* v, int size) -{ - makeContextCurrent(); - glUniform4iv(location, size, v); -} - -void GraphicsContext3D::uniformMatrix2fv(long location, bool transpose, float* value, int size) -{ - makeContextCurrent(); - glUniformMatrix2fv(location, size, transpose, value); -} - -void GraphicsContext3D::uniformMatrix3fv(long location, bool transpose, float* value, int size) -{ - makeContextCurrent(); - glUniformMatrix3fv(location, size, transpose, value); -} - -void GraphicsContext3D::uniformMatrix4fv(long location, bool transpose, float* value, int size) -{ - makeContextCurrent(); - glUniformMatrix4fv(location, size, transpose, value); -} - -GL_SAME_METHOD_1_X(UseProgram, useProgram, WebGLProgram*) - -GL_SAME_METHOD_1_X(ValidateProgram, validateProgram, WebGLProgram*) - -GL_SAME_METHOD_2(VertexAttrib1f, vertexAttrib1f, unsigned long, float) - -void GraphicsContext3D::vertexAttrib1fv(unsigned long indx, float* values) -{ - makeContextCurrent(); - glVertexAttrib1fv(indx, values); -} - -GL_SAME_METHOD_3(VertexAttrib2f, vertexAttrib2f, unsigned long, float, float) - -void GraphicsContext3D::vertexAttrib2fv(unsigned long indx, float* values) -{ - makeContextCurrent(); - glVertexAttrib2fv(indx, values); -} - -GL_SAME_METHOD_4(VertexAttrib3f, vertexAttrib3f, unsigned long, float, float, float) - -void GraphicsContext3D::vertexAttrib3fv(unsigned long indx, float* values) -{ - makeContextCurrent(); - glVertexAttrib3fv(indx, values); -} - -GL_SAME_METHOD_5(VertexAttrib4f, vertexAttrib4f, unsigned long, float, float, float, float) - -void GraphicsContext3D::vertexAttrib4fv(unsigned long indx, float* values) -{ - makeContextCurrent(); - glVertexAttrib4fv(indx, values); -} - -void GraphicsContext3D::vertexAttribPointer(unsigned long indx, int size, int type, bool normalized, - unsigned long stride, unsigned long offset) -{ - m_internal->vertexAttribPointer(indx, size, type, normalized, stride, offset); -} - -void GraphicsContext3D::viewport(long x, long y, unsigned long width, unsigned long height) -{ - makeContextCurrent(); - m_internal->viewportImpl(x, y, width, height); -} - -} + return m_internal->texSubImage2D(target, level, xoffset, yoffset, + image->width(), image->height(), + format, UNSIGNED_BYTE, imageData.data()); +} + +DELEGATE_TO_INTERNAL_2(uniform1f, long, float) +DELEGATE_TO_INTERNAL_3(uniform1fv, long, float*, int) +DELEGATE_TO_INTERNAL_2(uniform1i, long, int) +DELEGATE_TO_INTERNAL_3(uniform1iv, long, int*, int) +DELEGATE_TO_INTERNAL_3(uniform2f, long, float, float) +DELEGATE_TO_INTERNAL_3(uniform2fv, long, float*, int) +DELEGATE_TO_INTERNAL_3(uniform2i, long, int, int) +DELEGATE_TO_INTERNAL_3(uniform2iv, long, int*, int) +DELEGATE_TO_INTERNAL_4(uniform3f, long, float, float, float) +DELEGATE_TO_INTERNAL_3(uniform3fv, long, float*, int) +DELEGATE_TO_INTERNAL_4(uniform3i, long, int, int, int) +DELEGATE_TO_INTERNAL_3(uniform3iv, long, int*, int) +DELEGATE_TO_INTERNAL_5(uniform4f, long, float, float, float, float) +DELEGATE_TO_INTERNAL_3(uniform4fv, long, float*, int) +DELEGATE_TO_INTERNAL_5(uniform4i, long, int, int, int, int) +DELEGATE_TO_INTERNAL_3(uniform4iv, long, int*, int) +DELEGATE_TO_INTERNAL_4(uniformMatrix2fv, long, bool, float*, int) +DELEGATE_TO_INTERNAL_4(uniformMatrix3fv, long, bool, float*, int) +DELEGATE_TO_INTERNAL_4(uniformMatrix4fv, long, bool, float*, int) + +DELEGATE_TO_INTERNAL_1(useProgram, WebGLProgram*) +DELEGATE_TO_INTERNAL_1(validateProgram, WebGLProgram*) + +DELEGATE_TO_INTERNAL_2(vertexAttrib1f, unsigned long, float) +DELEGATE_TO_INTERNAL_2(vertexAttrib1fv, unsigned long, float*) +DELEGATE_TO_INTERNAL_3(vertexAttrib2f, unsigned long, float, float) +DELEGATE_TO_INTERNAL_2(vertexAttrib2fv, unsigned long, float*) +DELEGATE_TO_INTERNAL_4(vertexAttrib3f, unsigned long, float, float, float) +DELEGATE_TO_INTERNAL_2(vertexAttrib3fv, unsigned long, float*) +DELEGATE_TO_INTERNAL_5(vertexAttrib4f, unsigned long, float, float, float, float) +DELEGATE_TO_INTERNAL_2(vertexAttrib4fv, unsigned long, float*) +DELEGATE_TO_INTERNAL_6(vertexAttribPointer, unsigned long, int, int, bool, unsigned long, unsigned long) + +DELEGATE_TO_INTERNAL_4(viewport, long, long, unsigned long, unsigned long) + +DELEGATE_TO_INTERNAL_1(beginPaint, WebGLRenderingContext*) +DELEGATE_TO_INTERNAL(endPaint) + +DELEGATE_TO_INTERNAL_R(createBuffer, unsigned) +DELEGATE_TO_INTERNAL_R(createFramebuffer, unsigned) +DELEGATE_TO_INTERNAL_R(createProgram, unsigned) +DELEGATE_TO_INTERNAL_R(createRenderbuffer, unsigned) +DELEGATE_TO_INTERNAL_1R(createShader, unsigned long, unsigned) +DELEGATE_TO_INTERNAL_R(createTexture, unsigned) + +DELEGATE_TO_INTERNAL_1(deleteBuffer, unsigned) +DELEGATE_TO_INTERNAL_1(deleteFramebuffer, unsigned) +DELEGATE_TO_INTERNAL_1(deleteProgram, unsigned) +DELEGATE_TO_INTERNAL_1(deleteRenderbuffer, unsigned) +DELEGATE_TO_INTERNAL_1(deleteShader, unsigned) +DELEGATE_TO_INTERNAL_1(deleteTexture, unsigned) + +DELEGATE_TO_INTERNAL_1(synthesizeGLError, unsigned long) + +} // namespace WebCore #endif // ENABLE(3D_CANVAS) diff --git a/WebKit/chromium/src/IDBCallbacksProxy.h b/WebKit/chromium/src/IDBCallbacksProxy.h new file mode 100644 index 0000000..e803c96 --- /dev/null +++ b/WebKit/chromium/src/IDBCallbacksProxy.h @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2010 Google 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. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE 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 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. + */ + +#ifndef IDBCallbacksProxy_h +#define IDBCallbacksProxy_h + +#include "IDBCallbacks.h" +#include "IDBDatabaseError.h" +#include "WebIDBCallbacks.h" +#include "WebIDBDatabaseError.h" +#include <wtf/PassRefPtr.h> +#include <wtf/RefPtr.h> + +#if ENABLE(INDEXED_DATABASE) + +namespace WebCore { + +template <typename WebKitClass, typename WebCoreClass, typename WebCoreProxy> +class IDBCallbacksProxy : public WebKit::WebIDBCallbacks<WebKitClass> { +public: + IDBCallbacksProxy(PassRefPtr<IDBCallbacks<WebCoreClass> > callbacks) + : m_callbacks(callbacks) { } + + virtual ~IDBCallbacksProxy() { } + + virtual void onSuccess(WebKitClass* webKitInstance) + { + RefPtr<WebCoreClass> proxy = WebCoreProxy::create(webKitInstance); + m_callbacks->onSuccess(proxy); + m_callbacks.clear(); + } + + virtual void onError(const WebKit::WebIDBDatabaseError& error) + { + m_callbacks->onError(error); + m_callbacks.clear(); + } + +private: + PassRefPtr<IDBCallbacks<WebCoreClass> > m_callbacks; +}; + + +} // namespace WebCore + +#endif + +#endif // IDBCallbacksProxy_h diff --git a/WebKit/chromium/src/IDBDatabaseProxy.cpp b/WebKit/chromium/src/IDBDatabaseProxy.cpp new file mode 100644 index 0000000..d12ec70 --- /dev/null +++ b/WebKit/chromium/src/IDBDatabaseProxy.cpp @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2010 Google 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. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE 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 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 "IDBDatabaseProxy.h" + +#include "IDBDatabaseError.h" +#include "WebIDBDatabase.h" +#include "WebIDBDatabaseError.h" + +#if ENABLE(INDEXED_DATABASE) + +namespace WebCore { + +PassRefPtr<IDBDatabase> IDBDatabaseProxy::create(PassOwnPtr<WebKit::WebIDBDatabase> database) +{ + return adoptRef(new IDBDatabaseProxy(database)); +} + +IDBDatabaseProxy::IDBDatabaseProxy(PassOwnPtr<WebKit::WebIDBDatabase> database) + : m_webIDBDatabase(database) +{ +} + +IDBDatabaseProxy::~IDBDatabaseProxy() +{ +} + +} // namespace WebCore + +#endif // ENABLE(INDEXED_DATABASE) + diff --git a/WebKit/chromium/src/IDBDatabaseProxy.h b/WebKit/chromium/src/IDBDatabaseProxy.h new file mode 100644 index 0000000..ac96a15 --- /dev/null +++ b/WebKit/chromium/src/IDBDatabaseProxy.h @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2010 Google 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. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE 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 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. + */ + +#ifndef IDBDatabaseProxy_h +#define IDBDatabaseProxy_h + +#include "IDBDatabase.h" +#include <wtf/OwnPtr.h> +#include <wtf/PassOwnPtr.h> +#include <wtf/PassRefPtr.h> + +#if ENABLE(INDEXED_DATABASE) + +namespace WebKit { class WebIDBDatabase; } + +namespace WebCore { + +class IDBDatabaseProxy : public IDBDatabase { +public: + static PassRefPtr<IDBDatabase> create(PassOwnPtr<WebKit::WebIDBDatabase>); + virtual ~IDBDatabaseProxy(); + + // FIXME: Add other methods. + +private: + IDBDatabaseProxy(PassOwnPtr<WebKit::WebIDBDatabase>); + + OwnPtr<WebKit::WebIDBDatabase> m_webIDBDatabase; +}; + +} // namespace WebCore + +#endif + +#endif // IDBDatabaseProxy_h + diff --git a/WebKit/chromium/src/IndexedDatabaseProxy.cpp b/WebKit/chromium/src/IndexedDatabaseProxy.cpp new file mode 100644 index 0000000..9069b46 --- /dev/null +++ b/WebKit/chromium/src/IndexedDatabaseProxy.cpp @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2010 Google 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. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE 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 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 "IndexedDatabaseProxy.h" + +#include "IDBCallbacksProxy.h" +#include "IDBDatabaseError.h" +#include "IDBDatabaseProxy.h" +#include "WebFrameImpl.h" +#include "WebIDBDatabase.h" +#include "WebIDBDatabaseError.h" +#include "WebIndexedDatabase.h" +#include "WebKit.h" +#include "WebKitClient.h" + +#if ENABLE(INDEXED_DATABASE) + +namespace WebCore { + +PassRefPtr<IndexedDatabase> IndexedDatabaseProxy::create() +{ + return adoptRef(new IndexedDatabaseProxy()); +} + +IndexedDatabaseProxy::IndexedDatabaseProxy() + : m_webIndexedDatabase(WebKit::webKitClient()->indexedDatabase()) +{ +} + +IndexedDatabaseProxy::~IndexedDatabaseProxy() +{ +} + +void IndexedDatabaseProxy::open(const String& name, const String& description, bool modifyDatabase, PassRefPtr<IDBDatabaseCallbacks> callbacks, Frame* frame, ExceptionCode& ec) +{ + WebKit::WebFrame* webFrame = WebKit::WebFrameImpl::fromFrame(frame); + typedef IDBCallbacksProxy<WebKit::WebIDBDatabase, IDBDatabase, IDBDatabaseProxy> CallbacksProxy; + m_webIndexedDatabase->open(name, description, modifyDatabase, new CallbacksProxy(callbacks), webFrame, ec); +} + +} // namespace WebCore + +#endif // ENABLE(INDEXED_DATABASE) + diff --git a/WebKit/chromium/src/IndexedDatabaseProxy.h b/WebKit/chromium/src/IndexedDatabaseProxy.h new file mode 100644 index 0000000..d0f55b6 --- /dev/null +++ b/WebKit/chromium/src/IndexedDatabaseProxy.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2010 Google 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. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE 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 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. + */ + +#ifndef IndexedDatabaseProxy_h +#define IndexedDatabaseProxy_h + +#include "IndexedDatabase.h" + +#if ENABLE(INDEXED_DATABASE) + +namespace WebKit { class WebIndexedDatabase; } + +namespace WebCore { + +class IndexedDatabaseProxy : public IndexedDatabase { +public: + static PassRefPtr<IndexedDatabase> create(); + virtual ~IndexedDatabaseProxy(); + + virtual void open(const String& name, const String& description, bool modifyDatabase, PassRefPtr<IDBDatabaseCallbacks>, Frame*, ExceptionCode&); + +private: + IndexedDatabaseProxy(); + + // We don't own this pointer (unlike all the other proxy classes which do). + WebKit::WebIndexedDatabase* m_webIndexedDatabase; +}; + +} // namespace WebCore + +#endif + +#endif // IndexedDatabaseProxy_h + diff --git a/WebKit/chromium/src/InspectorClientImpl.cpp b/WebKit/chromium/src/InspectorClientImpl.cpp index 54550d1..f69ef72 100644 --- a/WebKit/chromium/src/InspectorClientImpl.cpp +++ b/WebKit/chromium/src/InspectorClientImpl.cpp @@ -63,46 +63,8 @@ void InspectorClientImpl::inspectorDestroyed() // Our lifetime is bound to the WebViewImpl. } -Page* InspectorClientImpl::createPage() +void InspectorClientImpl::openInspectorFrontend(InspectorController*) { - // This method should never be called in Chrome as inspector front-end lives - // in a separate process. - ASSERT_NOT_REACHED(); - return 0; -} - -void InspectorClientImpl::showWindow() -{ - ASSERT(m_inspectedWebView->devToolsAgentPrivate()); - m_inspectedWebView->page()->inspectorController()->setWindowVisible(true); -} - -void InspectorClientImpl::closeWindow() -{ - if (m_inspectedWebView->page()) - m_inspectedWebView->page()->inspectorController()->setWindowVisible(false); -} - -bool InspectorClientImpl::windowVisible() -{ - ASSERT(m_inspectedWebView->devToolsAgentPrivate()); - return false; -} - -void InspectorClientImpl::attachWindow() -{ - // FIXME: Implement this -} - -void InspectorClientImpl::detachWindow() -{ - // FIXME: Implement this -} - -void InspectorClientImpl::setAttachedWindowHeight(unsigned int height) -{ - // FIXME: Implement this - notImplemented(); } static void invalidateNodeBoundingRect(WebViewImpl* webView) @@ -130,23 +92,6 @@ void InspectorClientImpl::hideHighlight() invalidateNodeBoundingRect(m_inspectedWebView); } -void InspectorClientImpl::inspectedURLChanged(const String& newURL) -{ - // FIXME: Implement this -} - -String InspectorClientImpl::localizedStringsURL() -{ - notImplemented(); - return String(); -} - -String InspectorClientImpl::hiddenPanels() -{ - notImplemented(); - return ""; -} - void InspectorClientImpl::populateSetting(const String& key, String* value) { loadSettings(); @@ -161,11 +106,6 @@ void InspectorClientImpl::storeSetting(const String& key, const String& value) saveSettings(); } -void InspectorClientImpl::inspectorWindowObjectCleared() -{ - notImplemented(); -} - void InspectorClientImpl::loadSettings() { if (m_settings) diff --git a/WebKit/chromium/src/InspectorClientImpl.h b/WebKit/chromium/src/InspectorClientImpl.h index 6f7f8b1..ccbcef7 100644 --- a/WebKit/chromium/src/InspectorClientImpl.h +++ b/WebKit/chromium/src/InspectorClientImpl.h @@ -45,25 +45,15 @@ public: // InspectorClient methods: virtual void inspectorDestroyed(); - virtual WebCore::Page* createPage(); - virtual WebCore::String localizedStringsURL(); - virtual WebCore::String hiddenPanels(); - virtual void showWindow(); - virtual void closeWindow(); - virtual bool windowVisible(); - virtual void attachWindow(); - virtual void detachWindow(); - virtual void setAttachedWindowHeight(unsigned height); + virtual void openInspectorFrontend(WebCore::InspectorController*); virtual void highlight(WebCore::Node*); virtual void hideHighlight(); - virtual void inspectedURLChanged(const WebCore::String& newURL); virtual void populateSetting( const WebCore::String& key, WebCore::String* value); virtual void storeSetting( const WebCore::String& key, const WebCore::String& value); - virtual void inspectorWindowObjectCleared(); private: void loadSettings(); diff --git a/WebKit/chromium/src/InspectorFrontendClientImpl.cpp b/WebKit/chromium/src/InspectorFrontendClientImpl.cpp new file mode 100644 index 0000000..9ff3938 --- /dev/null +++ b/WebKit/chromium/src/InspectorFrontendClientImpl.cpp @@ -0,0 +1,126 @@ +/* + * Copyright (C) 2010 Google 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: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER OR 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 "InspectorFrontendClientImpl.h" + +#include "InspectorFrontendHost.h" +#include "Page.h" +#include "PlatformString.h" +#include "V8InspectorFrontendHost.h" +#include "V8Proxy.h" +#include "WebDevToolsFrontendClient.h" +#include "WebDevToolsFrontendImpl.h" + +using namespace WebCore; + +namespace WebKit { + +InspectorFrontendClientImpl::InspectorFrontendClientImpl(Page* frontendPage, WebDevToolsFrontendClient* client, WebDevToolsFrontendImpl* frontend) + : m_frontendPage(frontendPage) + , m_client(client) + , m_frontend(frontend) +{ +} + +InspectorFrontendClientImpl::~InspectorFrontendClientImpl() +{ + if (m_frontendHost) + m_frontendHost->disconnectClient(); + m_client = 0; +} + +void InspectorFrontendClientImpl::windowObjectCleared() +{ + v8::HandleScope handleScope; + v8::Handle<v8::Context> frameContext = V8Proxy::context(m_frontendPage->mainFrame()); + v8::Context::Scope contextScope(frameContext); + + ASSERT(!m_frontendHost); + m_frontendHost = InspectorFrontendHost::create(this, m_frontendPage); + v8::Handle<v8::Value> frontendHostObj = toV8(m_frontendHost.get()); + v8::Handle<v8::Object> global = frameContext->Global(); + + global->Set(v8::String::New("InspectorFrontendHost"), frontendHostObj); +#if ENABLE(V8_SCRIPT_DEBUG_SERVER) + global->Set(v8::String::New("v8ScriptDebugServerEnabled"), v8::True()); +#endif +} + +void InspectorFrontendClientImpl::frontendLoaded() +{ + m_frontend->frontendLoaded(); +} + +void InspectorFrontendClientImpl::moveWindowBy(float x, float y) +{ +} + +String InspectorFrontendClientImpl::localizedStringsURL() +{ + return ""; +} + +String InspectorFrontendClientImpl::hiddenPanels() +{ + return ""; +} + +void InspectorFrontendClientImpl::bringToFront() +{ + m_client->activateWindow(); +} + +void InspectorFrontendClientImpl::closeWindow() +{ + m_client->closeWindow(); +} + +void InspectorFrontendClientImpl::requestAttachWindow() +{ + m_client->requestDockWindow(); +} + +void InspectorFrontendClientImpl::requestDetachWindow() +{ + m_client->requestUndockWindow(); +} + +void InspectorFrontendClientImpl::changeAttachedWindowHeight(unsigned) +{ + // Do nothing; +} + +void InspectorFrontendClientImpl::inspectedURLChanged(const String&) +{ + // Do nothing; +} + +} // namespace WebKit diff --git a/WebKit/chromium/src/InspectorFrontendClientImpl.h b/WebKit/chromium/src/InspectorFrontendClientImpl.h new file mode 100644 index 0000000..f869ac3 --- /dev/null +++ b/WebKit/chromium/src/InspectorFrontendClientImpl.h @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2010 Google 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: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER OR 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. + */ + +#ifndef InspectorFrontendClientImpl_h +#define InspectorFrontendClientImpl_h + +#include "InspectorFrontendClient.h" +#include <wtf/Noncopyable.h> + +namespace WebCore { +class InspectorFrontendHost; +class Page; +} + +namespace WebKit { + +class WebDevToolsFrontendClient; +class WebDevToolsFrontendImpl; + +class InspectorFrontendClientImpl : public WebCore::InspectorFrontendClient + , public Noncopyable { +public: + InspectorFrontendClientImpl(WebCore::Page*, WebDevToolsFrontendClient*, WebDevToolsFrontendImpl*); + virtual ~InspectorFrontendClientImpl(); + + // InspectorFrontendClient methods: + virtual void windowObjectCleared(); + virtual void frontendLoaded(); + + virtual void moveWindowBy(float x, float y); + + virtual WebCore::String localizedStringsURL(); + virtual WebCore::String hiddenPanels(); + + virtual void bringToFront(); + virtual void closeWindow(); + + virtual void requestAttachWindow(); + virtual void requestDetachWindow(); + virtual void changeAttachedWindowHeight(unsigned); + + virtual void inspectedURLChanged(const WebCore::String&); + +private: + WebCore::Page* m_frontendPage; + WebDevToolsFrontendClient* m_client; + WebDevToolsFrontendImpl* m_frontend; + RefPtr<WebCore::InspectorFrontendHost> m_frontendHost; +}; + +} // namespace WebKit + +#endif diff --git a/WebKit/chromium/src/LocalizedStrings.cpp b/WebKit/chromium/src/LocalizedStrings.cpp index 4e01848..74ff699 100644 --- a/WebKit/chromium/src/LocalizedStrings.cpp +++ b/WebKit/chromium/src/LocalizedStrings.cpp @@ -174,6 +174,18 @@ String AXMenuListActionVerb() { return String(); } + +String missingPluginText() +{ + notImplemented(); + return String("Missing Plug-in"); +} + +String crashedPluginText() +{ + notImplemented(); + return String("Plug-in Failure"); +} String multipleFileUploadText(unsigned numberOfFiles) { diff --git a/WebKit/chromium/src/NotificationPresenterImpl.cpp b/WebKit/chromium/src/NotificationPresenterImpl.cpp index a38b8b5..dca1856 100644 --- a/WebKit/chromium/src/NotificationPresenterImpl.cpp +++ b/WebKit/chromium/src/NotificationPresenterImpl.cpp @@ -33,11 +33,10 @@ #if ENABLE(NOTIFICATIONS) -#include "Document.h" +#include "KURL.h" #include "Notification.h" #include "SecurityOrigin.h" -#include "WebDocument.h" #include "WebNotification.h" #include "WebNotificationPermissionCallback.h" #include "WebNotificationPresenter.h" @@ -92,19 +91,15 @@ void NotificationPresenterImpl::notificationObjectDestroyed(Notification* notifi m_presenter->objectDestroyed(PassRefPtr<Notification>(notification)); } -NotificationPresenter::Permission NotificationPresenterImpl::checkPermission(const KURL& url, Document* document) +NotificationPresenter::Permission NotificationPresenterImpl::checkPermission(const KURL& sourceURL) { - WebDocument webDocument; - if (document) - webDocument = document; - - int result = m_presenter->checkPermission(url, document ? &webDocument : 0); + int result = m_presenter->checkPermission(sourceURL); return static_cast<NotificationPresenter::Permission>(result); } void NotificationPresenterImpl::requestPermission(SecurityOrigin* origin, PassRefPtr<VoidCallback> callback) { - m_presenter->requestPermission(origin->toString(), new VoidCallbackClient(callback)); + m_presenter->requestPermission(WebSecurityOrigin(origin), new VoidCallbackClient(callback)); } } // namespace WebKit diff --git a/WebKit/chromium/src/NotificationPresenterImpl.h b/WebKit/chromium/src/NotificationPresenterImpl.h index 8e3799c..479538f 100644 --- a/WebKit/chromium/src/NotificationPresenterImpl.h +++ b/WebKit/chromium/src/NotificationPresenterImpl.h @@ -54,7 +54,7 @@ public: virtual bool show(WebCore::Notification* object); virtual void cancel(WebCore::Notification* object); virtual void notificationObjectDestroyed(WebCore::Notification* object); - virtual WebCore::NotificationPresenter::Permission checkPermission(const WebCore::KURL& url, WebCore::Document* document); + virtual WebCore::NotificationPresenter::Permission checkPermission(const WebCore::KURL& sourceURL); virtual void requestPermission(WebCore::SecurityOrigin* origin, WTF::PassRefPtr<WebCore::VoidCallback> callback); private: diff --git a/WebKit/chromium/src/ResourceHandle.cpp b/WebKit/chromium/src/ResourceHandle.cpp index bf6910f..39270e7 100644 --- a/WebKit/chromium/src/ResourceHandle.cpp +++ b/WebKit/chromium/src/ResourceHandle.cpp @@ -33,6 +33,7 @@ #include "ResourceHandleClient.h" #include "ResourceRequest.h" +#include "SharedBuffer.h" #include "WebKit.h" #include "WebKitClient.h" @@ -56,6 +57,7 @@ public: : m_request(request) , m_owner(0) , m_client(client) + , m_state(ConnectionStateNew) { } @@ -73,14 +75,32 @@ public: virtual void didFinishLoading(WebURLLoader*); virtual void didFail(WebURLLoader*, const WebURLError&); + enum ConnectionState { + ConnectionStateNew, + ConnectionStateStarted, + ConnectionStateReceivedResponse, + ConnectionStateReceivingData, + ConnectionStateFinishedLoading, + ConnectionStateCanceled, + ConnectionStateFailed, + }; + ResourceRequest m_request; ResourceHandle* m_owner; ResourceHandleClient* m_client; OwnPtr<WebURLLoader> m_loader; + + // Used for sanity checking to make sure we don't experience illegal state + // transitions. + ConnectionState m_state; }; void ResourceHandleInternal::start() { + if (m_state != ConnectionStateNew) + CRASH(); + m_state = ConnectionStateStarted; + m_loader.set(webKitClient()->createURLLoader()); ASSERT(m_loader.get()); @@ -91,6 +111,7 @@ void ResourceHandleInternal::start() void ResourceHandleInternal::cancel() { + m_state = ConnectionStateCanceled; m_loader->cancel(); // Do not make any further calls to the client. @@ -127,6 +148,12 @@ void ResourceHandleInternal::didReceiveResponse(WebURLLoader*, const WebURLRespo { ASSERT(m_client); ASSERT(!response.isNull()); + bool isMultipart = response.isMultipartPayload(); + bool isValidStateTransition = (m_state == ConnectionStateStarted || m_state == ConnectionStateReceivedResponse); + // In the case of multipart loads, calls to didReceiveData & didReceiveResponse can be interleaved. + if (!isMultipart && !isValidStateTransition) + CRASH(); + m_state = ConnectionStateReceivedResponse; m_client->didReceiveResponse(m_owner, response.toResourceResponse()); } @@ -134,6 +161,9 @@ void ResourceHandleInternal::didReceiveData( WebURLLoader*, const char* data, int dataLength) { ASSERT(m_client); + if (m_state != ConnectionStateReceivedResponse && m_state != ConnectionStateReceivingData) + CRASH(); + m_state = ConnectionStateReceivingData; // FIXME(yurys): it looks like lengthReceived is always the same as // dataLength and that the latter parameter can be eliminated. @@ -144,12 +174,16 @@ void ResourceHandleInternal::didReceiveData( void ResourceHandleInternal::didFinishLoading(WebURLLoader*) { ASSERT(m_client); + if (m_state != ConnectionStateReceivedResponse && m_state != ConnectionStateReceivingData) + CRASH(); + m_state = ConnectionStateFinishedLoading; m_client->didFinishLoading(m_owner); } void ResourceHandleInternal::didFail(WebURLLoader*, const WebURLError& error) { ASSERT(m_client); + m_state = ConnectionStateFailed; m_client->didFail(m_owner, error); } @@ -158,8 +192,7 @@ void ResourceHandleInternal::didFail(WebURLLoader*, const WebURLError& error) ResourceHandle::ResourceHandle(const ResourceRequest& request, ResourceHandleClient* client, bool defersLoading, - bool shouldContentSniff, - bool mightDownloadFromHandle) + bool shouldContentSniff) : d(new ResourceHandleInternal(request, client)) { d->m_owner = this; @@ -171,11 +204,10 @@ PassRefPtr<ResourceHandle> ResourceHandle::create(const ResourceRequest& request ResourceHandleClient* client, Frame* deprecated, bool defersLoading, - bool shouldContentSniff, - bool mightDownloadFromHandle) + bool shouldContentSniff) { RefPtr<ResourceHandle> newHandle = adoptRef(new ResourceHandle( - request, client, defersLoading, shouldContentSniff, mightDownloadFromHandle)); + request, client, defersLoading, shouldContentSniff)); if (newHandle->start(deprecated)) return newHandle.release(); diff --git a/WebKit/chromium/src/SharedWorkerRepository.cpp b/WebKit/chromium/src/SharedWorkerRepository.cpp index c803aac..f0a8ec8 100644 --- a/WebKit/chromium/src/SharedWorkerRepository.cpp +++ b/WebKit/chromium/src/SharedWorkerRepository.cpp @@ -36,6 +36,7 @@ #include "Event.h" #include "EventNames.h" +#include "InspectorController.h" #include "MessagePortChannel.h" #include "PlatformMessagePortChannel.h" #include "ScriptExecutionContext.h" @@ -152,6 +153,10 @@ void SharedWorkerScriptLoader::notifyFinished() m_worker->dispatchEvent(Event::create(eventNames().errorEvent, false, true)); delete this; } else { +#if ENABLE(INSPECTOR) + if (InspectorController* inspector = m_worker->scriptExecutionContext()->inspectorController()) + inspector->scriptImported(m_scriptLoader.identifier(), m_scriptLoader.script()); +#endif // Pass the script off to the worker, then send a connect event. m_webWorker->startWorkerContext(m_url, m_name, m_worker->scriptExecutionContext()->userAgent(m_url), m_scriptLoader.script()); sendConnect(); diff --git a/WebKit/chromium/src/StorageAreaProxy.cpp b/WebKit/chromium/src/StorageAreaProxy.cpp index c9185fe..0e44250 100644 --- a/WebKit/chromium/src/StorageAreaProxy.cpp +++ b/WebKit/chromium/src/StorageAreaProxy.cpp @@ -40,6 +40,7 @@ #include "StorageAreaImpl.h" #include "StorageEvent.h" +#include "WebFrameImpl.h" #include "WebStorageArea.h" #include "WebString.h" #include "WebURL.h" @@ -73,12 +74,13 @@ String StorageAreaProxy::getItem(const String& key) const String StorageAreaProxy::setItem(const String& key, const String& value, ExceptionCode& ec, Frame* frame) { - bool quotaException = false; + WebKit::WebStorageArea::Result result = WebKit::WebStorageArea::ResultOK; WebKit::WebString oldValue; - m_storageArea->setItem(key, value, frame->document()->url(), quotaException, oldValue); - ec = quotaException ? QUOTA_EXCEEDED_ERR : 0; + WebKit::WebFrame* webFrame = WebKit::WebFrameImpl::fromFrame(frame); + m_storageArea->setItem(key, value, frame->document()->url(), result, oldValue, webFrame); + ec = (result == WebKit::WebStorageArea::ResultOK) ? 0 : QUOTA_EXCEEDED_ERR; String oldValueString = oldValue; - if (oldValueString != value) + if (oldValueString != value && result == WebKit::WebStorageArea::ResultOK) storageEvent(key, oldValue, value, m_storageType, frame->document()->securityOrigin(), frame); return oldValue; } @@ -124,7 +126,7 @@ void StorageAreaProxy::storageEvent(const String& key, const String& oldValue, c } for (unsigned i = 0; i < frames.size(); ++i) - frames[i]->document()->enqueueStorageEvent(StorageEvent::create(eventNames().storageEvent, key, oldValue, newValue, sourceFrame->document()->url(), frames[i]->domWindow()->sessionStorage())); + frames[i]->document()->enqueueEvent(StorageEvent::create(eventNames().storageEvent, key, oldValue, newValue, sourceFrame->document()->url(), frames[i]->domWindow()->sessionStorage())); } else { // Send events to every page. const HashSet<Page*>& pages = page->group().pages(); @@ -136,8 +138,12 @@ void StorageAreaProxy::storageEvent(const String& key, const String& oldValue, c } } - for (unsigned i = 0; i < frames.size(); ++i) - frames[i]->document()->enqueueStorageEvent(StorageEvent::create(eventNames().storageEvent, key, oldValue, newValue, sourceFrame->document()->url(), frames[i]->domWindow()->localStorage())); + for (unsigned i = 0; i < frames.size(); ++i) { + ExceptionCode ec = 0; + Storage* storage = frames[i]->domWindow()->localStorage(ec); + if (!ec) + frames[i]->document()->enqueueEvent(StorageEvent::create(eventNames().storageEvent, key, oldValue, newValue, sourceFrame->document()->url(), storage)); + } } } diff --git a/WebKit/chromium/src/StorageEventDispatcherImpl.cpp b/WebKit/chromium/src/StorageEventDispatcherImpl.cpp index 3518796..ae25d44 100644 --- a/WebKit/chromium/src/StorageEventDispatcherImpl.cpp +++ b/WebKit/chromium/src/StorageEventDispatcherImpl.cpp @@ -73,8 +73,11 @@ void StorageEventDispatcherImpl::dispatchStorageEvent(const String& key, const S // FIXME: Figure out how to pass in the document URI. for (unsigned i = 0; i < frames.size(); ++i) { - frames[i]->document()->dispatchWindowEvent(StorageEvent::create(eventNames().storageEvent, key, oldValue, newValue, - url, frames[i]->domWindow()->localStorage())); + ExceptionCode ec = 0; + Storage* storage = frames[i]->domWindow()->localStorage(ec); + if (!ec) + frames[i]->document()->dispatchWindowEvent(StorageEvent::create(eventNames().storageEvent, key, oldValue, newValue, + url, storage)); } } diff --git a/WebKit/chromium/src/StorageNamespaceProxy.cpp b/WebKit/chromium/src/StorageNamespaceProxy.cpp index 3c87554..252bc14 100644 --- a/WebKit/chromium/src/StorageNamespaceProxy.cpp +++ b/WebKit/chromium/src/StorageNamespaceProxy.cpp @@ -47,7 +47,7 @@ PassRefPtr<StorageNamespace> StorageNamespace::localStorageNamespace(const Strin return adoptRef(new StorageNamespaceProxy(WebKit::webKitClient()->createLocalStorageNamespace(path, quota), LocalStorage)); } -PassRefPtr<StorageNamespace> StorageNamespace::sessionStorageNamespace(Page* page) +PassRefPtr<StorageNamespace> StorageNamespace::sessionStorageNamespace(Page* page, unsigned quota) { WebKit::ChromeClientImpl* chromeClientImpl = static_cast<WebKit::ChromeClientImpl*>(page->chrome()->client()); WebKit::WebViewClient* webViewClient = chromeClientImpl->webView()->client(); diff --git a/WebKit/chromium/src/SuggestionsPopupMenuClient.h b/WebKit/chromium/src/SuggestionsPopupMenuClient.h index edc4c09..77b3890 100644 --- a/WebKit/chromium/src/SuggestionsPopupMenuClient.h +++ b/WebKit/chromium/src/SuggestionsPopupMenuClient.h @@ -63,6 +63,7 @@ public: virtual void valueChanged(unsigned listIndex, bool fireEvents = true); virtual WebCore::String itemText(unsigned listIndex) const; virtual WebCore::String itemToolTip(unsigned lastIndex) const { return WebCore::String(); } + virtual WebCore::String itemAccessibilityText(unsigned lastIndex) const { return WebCore::String(); } virtual bool itemIsEnabled(unsigned listIndex) const { return true; } virtual WebCore::PopupMenuStyle itemStyle(unsigned listIndex) const; virtual WebCore::PopupMenuStyle menuStyle() const; diff --git a/WebKit/chromium/src/WebBindings.cpp b/WebKit/chromium/src/WebBindings.cpp index 04f2f85..41619d6 100644 --- a/WebKit/chromium/src/WebBindings.cpp +++ b/WebKit/chromium/src/WebBindings.cpp @@ -284,7 +284,7 @@ static bool getRangeImpl(NPObject* npobj, WebRange* range) { V8NPObject* v8npobject = reinterpret_cast<V8NPObject*>(npobj); v8::Handle<v8::Object> v8object(v8npobject->v8Object); - if (V8ClassIndex::RANGE != V8DOMWrapper::domWrapperType(v8object)) + if (!V8Range::info.equals(V8DOMWrapper::domWrapperType(v8object))) return false; Range* native = V8Range::toNative(v8object); diff --git a/WebKit/chromium/src/WebCString.cpp b/WebKit/chromium/src/WebCString.cpp index 82fbac0..b484b19 100644 --- a/WebKit/chromium/src/WebCString.cpp +++ b/WebKit/chromium/src/WebCString.cpp @@ -31,14 +31,14 @@ #include "config.h" #include "WebCString.h" -#include "CString.h" #include "TextEncoding.h" +#include <wtf/text/CString.h> #include "WebString.h" namespace WebKit { -class WebCStringPrivate : public WebCore::CStringBuffer { +class WebCStringPrivate : public WTF::CStringBuffer { }; void WebCString::reset() @@ -57,8 +57,8 @@ void WebCString::assign(const WebCString& other) void WebCString::assign(const char* data, size_t length) { char* newData; - RefPtr<WebCore::CStringBuffer> buffer = - WebCore::CString::newUninitialized(length, newData).buffer(); + RefPtr<WTF::CStringBuffer> buffer = + WTF::CString::newUninitialized(length, newData).buffer(); memcpy(newData, data, length); assign(static_cast<WebCStringPrivate*>(buffer.get())); } @@ -97,20 +97,20 @@ WebCString WebCString::fromUTF16(const WebUChar* data) return fromUTF16(data, len); } -WebCString::WebCString(const WebCore::CString& s) +WebCString::WebCString(const WTF::CString& s) : m_private(static_cast<WebCStringPrivate*>(s.buffer())) { if (m_private) m_private->ref(); } -WebCString& WebCString::operator=(const WebCore::CString& s) +WebCString& WebCString::operator=(const WTF::CString& s) { assign(static_cast<WebCStringPrivate*>(s.buffer())); return *this; } -WebCString::operator WebCore::CString() const +WebCString::operator WTF::CString() const { return m_private; } diff --git a/WebKit/chromium/src/WebCommon.cpp b/WebKit/chromium/src/WebCommon.cpp new file mode 100644 index 0000000..f9457fb --- /dev/null +++ b/WebKit/chromium/src/WebCommon.cpp @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2010 Google 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: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER OR 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 "WebCommon.h" + +#include <wtf/Assertions.h> + +namespace WebKit { + +void failedAssertion(const char* file, int line, const char* function, const char* assertion) +{ + WTFReportAssertionFailure(file, line, function, assertion); + CRASH(); +} + +} // namespace WebKit diff --git a/WebKit/chromium/src/WebDatabase.cpp b/WebKit/chromium/src/WebDatabase.cpp index 50b9220..1479eb0 100644 --- a/WebKit/chromium/src/WebDatabase.cpp +++ b/WebKit/chromium/src/WebDatabase.cpp @@ -111,7 +111,7 @@ void WebDatabase::updateDatabaseSize( void WebDatabase::closeDatabaseImmediately(const WebString& originIdentifier, const WebString& databaseName) { HashSet<RefPtr<Database> > databaseHandles; - PassRefPtr<SecurityOrigin> originPrp(*WebSecurityOrigin::createFromDatabaseIdentifier(originIdentifier)); + PassRefPtr<SecurityOrigin> originPrp(WebSecurityOrigin::createFromDatabaseIdentifier(originIdentifier)); RefPtr<SecurityOrigin> origin = originPrp; DatabaseTracker::tracker().getOpenDatabases(origin.get(), databaseName, &databaseHandles); for (HashSet<RefPtr<Database> >::iterator it = databaseHandles.begin(); it != databaseHandles.end(); ++it) { @@ -119,7 +119,7 @@ void WebDatabase::closeDatabaseImmediately(const WebString& originIdentifier, co DatabaseThread* databaseThread = database->scriptExecutionContext()->databaseThread(); if (databaseThread && !databaseThread->terminationRequested()) { database->stop(); - databaseThread->scheduleTask(DatabaseCloseTask::create(database, 0)); + databaseThread->scheduleTask(DatabaseCloseTask::create(database, Database::RemoveDatabaseFromContext, 0)); } } } diff --git a/WebKit/chromium/src/WebDevToolsAgentImpl.cpp b/WebKit/chromium/src/WebDevToolsAgentImpl.cpp index 9ce35b4..0969d37 100644 --- a/WebKit/chromium/src/WebDevToolsAgentImpl.cpp +++ b/WebKit/chromium/src/WebDevToolsAgentImpl.cpp @@ -86,7 +86,6 @@ using WebCore::ScriptObject; using WebCore::ScriptState; using WebCore::ScriptValue; using WebCore::String; -using WebCore::V8ClassIndex; using WebCore::V8DOMWrapper; using WebCore::V8InspectorBackend; using WebCore::V8Proxy; @@ -161,15 +160,6 @@ void WebDevToolsAgentImpl::disposeUtilityContext() } } -void WebDevToolsAgentImpl::unhideResourcesPanelIfNecessary() -{ - InspectorController* ic = m_webViewImpl->page()->inspectorController(); - ic->ensureResourceTrackingSettingsLoaded(); - String command = String::format("[\"setResourcesPanelEnabled\", %s]", - ic->resourceTrackingEnabled() ? "true" : "false"); - m_toolsAgentDelegateStub->dispatchOnClient(command); -} - void WebDevToolsAgentImpl::attach() { if (m_attached) @@ -178,8 +168,8 @@ void WebDevToolsAgentImpl::attach() new DebuggerAgentImpl(m_webViewImpl, m_debuggerAgentDelegateStub.get(), this)); - resetInspectorFrontendProxy(); - unhideResourcesPanelIfNecessary(); + createInspectorFrontendProxy(); + // Allow controller to send messages to the frontend. InspectorController* ic = inspectorController(); @@ -194,7 +184,7 @@ void WebDevToolsAgentImpl::attach() } } - ic->setWindowVisible(true, false); + setInspectorFrontendProxyToInspectorController(); m_attached = true; } @@ -202,6 +192,7 @@ void WebDevToolsAgentImpl::detach() { // Prevent controller from sending messages to the frontend. InspectorController* ic = m_webViewImpl->page()->inspectorController(); + ic->disconnectFrontend(); ic->hideHighlight(); ic->close(); disposeUtilityContext(); @@ -225,10 +216,8 @@ void WebDevToolsAgentImpl::didCommitProvisionalLoad(WebFrameImpl* webframe, bool ds->unreachableURL() : request.url(); if (!webframe->parent()) { - resetInspectorFrontendProxy(); m_toolsAgentDelegateStub->frameNavigate(WebCore::KURL(url).string()); SetApuAgentEnabledInUtilityContext(m_utilityContext, m_apuAgentEnabled); - unhideResourcesPanelIfNecessary(); } } @@ -347,7 +336,6 @@ void WebDevToolsAgentImpl::initDevToolsAgentHost() v8::Local<v8::Object> WebDevToolsAgentImpl::createInspectorBackendV8Wrapper() { - V8ClassIndex::V8WrapperType descriptorType = V8ClassIndex::INSPECTORBACKEND; v8::Handle<v8::Function> function = V8InspectorBackend::GetTemplate()->GetFunction(); if (function.IsEmpty()) { // Return if allocation failed. @@ -359,7 +347,7 @@ v8::Local<v8::Object> WebDevToolsAgentImpl::createInspectorBackendV8Wrapper() return v8::Local<v8::Object>(); } InspectorBackend* backend = m_webViewImpl->page()->inspectorController()->inspectorBackend(); - V8DOMWrapper::setDOMWrapper(instance, V8ClassIndex::ToInt(descriptorType), backend); + V8DOMWrapper::setDOMWrapper(instance, &V8InspectorBackend::info, backend); // Create a weak reference to the v8 wrapper of InspectorBackend to deref // InspectorBackend when the wrapper is garbage collected. backend->ref(); @@ -368,19 +356,22 @@ v8::Local<v8::Object> WebDevToolsAgentImpl::createInspectorBackendV8Wrapper() return instance; } -void WebDevToolsAgentImpl::resetInspectorFrontendProxy() +void WebDevToolsAgentImpl::createInspectorFrontendProxy() { disposeUtilityContext(); - m_debuggerAgentImpl->createUtilityContext(m_webViewImpl->page()->mainFrame(), &m_utilityContext); + m_utilityContext = v8::Context::New(); compileUtilityScripts(); initDevToolsAgentHost(); +} +void WebDevToolsAgentImpl::setInspectorFrontendProxyToInspectorController() +{ v8::HandleScope scope; - v8::Context::Scope contextScope(m_utilityContext); ScriptState* state = ScriptState::forContext( v8::Local<v8::Context>::New(m_utilityContext)); InspectorController* ic = inspectorController(); - ic->setFrontendProxyObject(state, ScriptObject(state, m_utilityContext->Global())); + ic->setFrontend(new InspectorFrontend( + ScriptObject(state, m_utilityContext->Global()))); } void WebDevToolsAgentImpl::setApuAgentEnabled(bool enabled) diff --git a/WebKit/chromium/src/WebDevToolsAgentImpl.h b/WebKit/chromium/src/WebDevToolsAgentImpl.h index 1f81c6d..455dcef 100644 --- a/WebKit/chromium/src/WebDevToolsAgentImpl.h +++ b/WebKit/chromium/src/WebDevToolsAgentImpl.h @@ -106,11 +106,11 @@ private: static v8::Handle<v8::Value> jsOnRuntimeFeatureStateChanged(const v8::Arguments& args); void disposeUtilityContext(); - void unhideResourcesPanelIfNecessary(); void compileUtilityScripts(); void initDevToolsAgentHost(); - void resetInspectorFrontendProxy(); + void createInspectorFrontendProxy(); + void setInspectorFrontendProxyToInspectorController(); void setApuAgentEnabled(bool enabled); WebCore::InspectorController* inspectorController(); diff --git a/WebKit/chromium/src/WebDevToolsFrontendImpl.cpp b/WebKit/chromium/src/WebDevToolsFrontendImpl.cpp index 89fa6e7..0a6c8de 100644 --- a/WebKit/chromium/src/WebDevToolsFrontendImpl.cpp +++ b/WebKit/chromium/src/WebDevToolsFrontendImpl.cpp @@ -42,6 +42,7 @@ #include "Frame.h" #include "InspectorBackend.h" #include "InspectorController.h" +#include "InspectorFrontendClientImpl.h" #include "InspectorFrontendHost.h" #include "Node.h" #include "Page.h" @@ -54,6 +55,7 @@ #include "V8Binding.h" #include "V8DOMWrapper.h" #include "V8InspectorFrontendHost.h" +#include "V8MouseEvent.h" #include "V8Node.h" #include "V8Proxy.h" #include "V8Utilities.h" @@ -100,6 +102,9 @@ WebDevToolsFrontendImpl::WebDevToolsFrontendImpl( , m_applicationLocale(applicationLocale) , m_loaded(false) { + InspectorController* ic = m_webViewImpl->page()->inspectorController(); + ic->setInspectorFrontendClient(new InspectorFrontendClientImpl(m_webViewImpl->page(), m_client, this)); + WebFrameImpl* frame = m_webViewImpl->mainFrameImpl(); v8::HandleScope scope; v8::Handle<v8::Context> frameContext = V8Proxy::context(frame->frame()); @@ -117,57 +122,10 @@ WebDevToolsFrontendImpl::WebDevToolsFrontendImpl( "DebuggerPauseScript", WebDevToolsFrontendImpl::jsDebuggerPauseScript); debuggerCommandExecutorObj.build(); - - BoundObject devToolsHost(frameContext, this, "InspectorFrontendHost"); - devToolsHost.addProtoFunction( - "loaded", - WebDevToolsFrontendImpl::jsLoaded); - devToolsHost.addProtoFunction( - "platform", - WebDevToolsFrontendImpl::jsPlatform); - devToolsHost.addProtoFunction( - "port", - WebDevToolsFrontendImpl::jsPort); - devToolsHost.addProtoFunction( - "copyText", - WebDevToolsFrontendImpl::jsCopyText); - devToolsHost.addProtoFunction( - "activateWindow", - WebDevToolsFrontendImpl::jsActivateWindow); - devToolsHost.addProtoFunction( - "closeWindow", - WebDevToolsFrontendImpl::jsCloseWindow); - devToolsHost.addProtoFunction( - "attach", - WebDevToolsFrontendImpl::jsDockWindow); - devToolsHost.addProtoFunction( - "detach", - WebDevToolsFrontendImpl::jsUndockWindow); - devToolsHost.addProtoFunction( - "localizedStringsURL", - WebDevToolsFrontendImpl::jsLocalizedStringsURL); - devToolsHost.addProtoFunction( - "hiddenPanels", - WebDevToolsFrontendImpl::jsHiddenPanels); - devToolsHost.addProtoFunction( - "setting", - WebDevToolsFrontendImpl::jsSetting); - devToolsHost.addProtoFunction( - "setSetting", - WebDevToolsFrontendImpl::jsSetSetting); - devToolsHost.addProtoFunction( - "windowUnloading", - WebDevToolsFrontendImpl::jsWindowUnloading); - devToolsHost.addProtoFunction( - "showContextMenu", - WebDevToolsFrontendImpl::jsShowContextMenu); - devToolsHost.build(); } WebDevToolsFrontendImpl::~WebDevToolsFrontendImpl() { - if (m_menuProvider) - m_menuProvider->disconnect(); } void WebDevToolsFrontendImpl::dispatchMessageFromAgent(const WebDevToolsMessageData& data) @@ -184,6 +142,22 @@ void WebDevToolsFrontendImpl::dispatchMessageFromAgent(const WebDevToolsMessageD executeScript(v); } +void WebDevToolsFrontendImpl::frontendLoaded() +{ + m_loaded = true; + + // Grant the devtools page the ability to have source view iframes. + SecurityOrigin* origin = m_webViewImpl->page()->mainFrame()->domWindow()->securityOrigin(); + origin->grantUniversalAccess(); + + for (Vector<Vector<String> >::iterator it = m_pendingIncomingMessages.begin(); + it != m_pendingIncomingMessages.end(); + ++it) { + executeScript(*it); + } + m_pendingIncomingMessages.clear(); +} + void WebDevToolsFrontendImpl::executeScript(const Vector<String>& v) { WebFrameImpl* frame = m_webViewImpl->mainFrameImpl(); @@ -199,125 +173,11 @@ void WebDevToolsFrontendImpl::executeScript(const Vector<String>& v) function->Call(frameContext->Global(), args.size(), args.data()); } -void WebDevToolsFrontendImpl::dispatchOnWebInspector(const String& methodName, const String& param) -{ - WebFrameImpl* frame = m_webViewImpl->mainFrameImpl(); - v8::HandleScope scope; - v8::Handle<v8::Context> frameContext = V8Proxy::context(frame->frame()); - v8::Context::Scope contextScope(frameContext); - - v8::Handle<v8::Value> webInspector = frameContext->Global()->Get(v8::String::New("WebInspector")); - ASSERT(webInspector->IsObject()); - v8::Handle<v8::Object> webInspectorObj = v8::Handle<v8::Object>::Cast(webInspector); - - v8::Handle<v8::Value> method = webInspectorObj->Get(ToV8String(methodName)); - ASSERT(method->IsFunction()); - v8::Handle<v8::Function> methodFunc = v8::Handle<v8::Function>::Cast(method); - v8::Handle<v8::Value> args[] = { - ToV8String(param) - }; - methodFunc->Call(frameContext->Global(), 1, args); -} - void WebDevToolsFrontendImpl::sendRpcMessage(const WebDevToolsMessageData& data) { m_client->sendMessageToAgent(data); } -void WebDevToolsFrontendImpl::contextMenuItemSelected(ContextMenuItem* item) -{ - int itemNumber = item->action() - ContextMenuItemBaseCustomTag; - dispatchOnWebInspector("contextMenuItemSelected", String::number(itemNumber)); -} - -void WebDevToolsFrontendImpl::contextMenuCleared() -{ - dispatchOnWebInspector("contextMenuCleared", ""); -} - -v8::Handle<v8::Value> WebDevToolsFrontendImpl::jsLoaded(const v8::Arguments& args) -{ - WebDevToolsFrontendImpl* frontend = static_cast<WebDevToolsFrontendImpl*>(v8::External::Cast(*args.Data())->Value()); - frontend->m_loaded = true; - - // Grant the devtools page the ability to have source view iframes. - Page* page = V8Proxy::retrieveFrameForEnteredContext()->page(); - SecurityOrigin* origin = page->mainFrame()->domWindow()->securityOrigin(); - origin->grantUniversalAccess(); - - for (Vector<Vector<String> >::iterator it = frontend->m_pendingIncomingMessages.begin(); - it != frontend->m_pendingIncomingMessages.end(); - ++it) { - frontend->executeScript(*it); - } - frontend->m_pendingIncomingMessages.clear(); - return v8::Undefined(); -} - -// static -v8::Handle<v8::Value> WebDevToolsFrontendImpl::jsPlatform(const v8::Arguments& args) -{ -#if defined(OS_MACOSX) - return v8String("mac"); -#elif defined(OS_LINUX) - return v8String("linux"); -#elif defined(OS_WIN) - return v8String("windows"); -#else - return v8String("unknown"); -#endif -} - -v8::Handle<v8::Value> WebDevToolsFrontendImpl::jsPort(const v8::Arguments& args) -{ - return v8::Undefined(); -} - -v8::Handle<v8::Value> WebDevToolsFrontendImpl::jsCopyText(const v8::Arguments& args) -{ - String text = WebCore::toWebCoreStringWithNullCheck(args[0]); - Pasteboard::generalPasteboard()->writePlainText(text); - return v8::Undefined(); -} - -v8::Handle<v8::Value> WebDevToolsFrontendImpl::jsActivateWindow(const v8::Arguments& args) -{ - WebDevToolsFrontendImpl* frontend = static_cast<WebDevToolsFrontendImpl*>(v8::External::Cast(*args.Data())->Value()); - frontend->m_client->activateWindow(); - return v8::Undefined(); -} - -v8::Handle<v8::Value> WebDevToolsFrontendImpl::jsCloseWindow(const v8::Arguments& args) -{ - WebDevToolsFrontendImpl* frontend = static_cast<WebDevToolsFrontendImpl*>(v8::External::Cast(*args.Data())->Value()); - frontend->m_client->closeWindow(); - return v8::Undefined(); -} - -v8::Handle<v8::Value> WebDevToolsFrontendImpl::jsDockWindow(const v8::Arguments& args) -{ - WebDevToolsFrontendImpl* frontend = static_cast<WebDevToolsFrontendImpl*>(v8::External::Cast(*args.Data())->Value()); - frontend->m_client->dockWindow(); - return v8::Undefined(); -} - -v8::Handle<v8::Value> WebDevToolsFrontendImpl::jsUndockWindow(const v8::Arguments& args) -{ - WebDevToolsFrontendImpl* frontend = static_cast<WebDevToolsFrontendImpl*>(v8::External::Cast(*args.Data())->Value()); - frontend->m_client->undockWindow(); - return v8::Undefined(); -} - -v8::Handle<v8::Value> WebDevToolsFrontendImpl::jsLocalizedStringsURL(const v8::Arguments& args) -{ - return v8::Undefined(); -} - -v8::Handle<v8::Value> WebDevToolsFrontendImpl::jsHiddenPanels(const v8::Arguments& args) -{ - return v8String(""); -} - v8::Handle<v8::Value> WebDevToolsFrontendImpl::jsDebuggerCommand(const v8::Arguments& args) { WebDevToolsFrontendImpl* frontend = static_cast<WebDevToolsFrontendImpl*>(v8::External::Cast(*args.Data())->Value()); @@ -326,16 +186,6 @@ v8::Handle<v8::Value> WebDevToolsFrontendImpl::jsDebuggerCommand(const v8::Argum return v8::Undefined(); } -v8::Handle<v8::Value> WebDevToolsFrontendImpl::jsSetting(const v8::Arguments& args) -{ - return v8::Undefined(); -} - -v8::Handle<v8::Value> WebDevToolsFrontendImpl::jsSetSetting(const v8::Arguments& args) -{ - return v8::Undefined(); -} - v8::Handle<v8::Value> WebDevToolsFrontendImpl::jsDebuggerPauseScript(const v8::Arguments& args) { WebDevToolsFrontendImpl* frontend = static_cast<WebDevToolsFrontendImpl*>(v8::External::Cast(*args.Data())->Value()); @@ -343,53 +193,4 @@ v8::Handle<v8::Value> WebDevToolsFrontendImpl::jsDebuggerPauseScript(const v8::A return v8::Undefined(); } -v8::Handle<v8::Value> WebDevToolsFrontendImpl::jsWindowUnloading(const v8::Arguments& args) -{ - // TODO(pfeldman): Implement this. - return v8::Undefined(); -} - -v8::Handle<v8::Value> WebDevToolsFrontendImpl::jsShowContextMenu(const v8::Arguments& args) -{ - if (args.Length() < 2) - return v8::Undefined(); - - v8::Local<v8::Object> eventWrapper = v8::Local<v8::Object>::Cast(args[0]); - if (V8DOMWrapper::domWrapperType(eventWrapper) != V8ClassIndex::MOUSEEVENT) - return v8::Undefined(); - - Event* event = V8Event::toNative(eventWrapper); - if (!args[1]->IsArray()) - return v8::Undefined(); - - v8::Local<v8::Array> array = v8::Local<v8::Array>::Cast(args[1]); - Vector<ContextMenuItem*> items; - - for (size_t i = 0; i < array->Length(); ++i) { - v8::Local<v8::Object> item = v8::Local<v8::Object>::Cast(array->Get(v8::Integer::New(i))); - v8::Local<v8::Value> label = item->Get(v8::String::New("label")); - v8::Local<v8::Value> id = item->Get(v8::String::New("id")); - if (label->IsUndefined() || id->IsUndefined()) { - items.append(new ContextMenuItem(SeparatorType, - ContextMenuItemTagNoAction, - String())); - } else { - ContextMenuAction typedId = static_cast<ContextMenuAction>( - ContextMenuItemBaseCustomTag + id->ToInt32()->Value()); - items.append(new ContextMenuItem(ActionType, - typedId, - toWebCoreStringWithNullCheck(label))); - } - } - - WebDevToolsFrontendImpl* frontend = static_cast<WebDevToolsFrontendImpl*>(v8::External::Cast(*args.Data())->Value()); - - frontend->m_menuProvider = MenuProvider::create(frontend, items); - - ContextMenuController* menuController = frontend->m_webViewImpl->page()->contextMenuController(); - menuController->showContextMenu(event, frontend->m_menuProvider); - - return v8::Undefined(); -} - } // namespace WebKit diff --git a/WebKit/chromium/src/WebDevToolsFrontendImpl.h b/WebKit/chromium/src/WebDevToolsFrontendImpl.h index 62b34da..fa4707d 100644 --- a/WebKit/chromium/src/WebDevToolsFrontendImpl.h +++ b/WebKit/chromium/src/WebDevToolsFrontendImpl.h @@ -31,8 +31,6 @@ #ifndef WebDevToolsFrontendImpl_h #define WebDevToolsFrontendImpl_h -#include "ContextMenu.h" -#include "ContextMenuProvider.h" #include "DevToolsRPC.h" #include "WebDevToolsFrontend.h" #include <v8.h> @@ -74,76 +72,13 @@ public: // WebDevToolsFrontend implementation. virtual void dispatchMessageFromAgent(const WebKit::WebDevToolsMessageData& data); -private: - class MenuProvider : public WebCore::ContextMenuProvider { - public: - static PassRefPtr<MenuProvider> create(WebDevToolsFrontendImpl* frontendHost, const Vector<WebCore::ContextMenuItem*>& items) - { - return adoptRef(new MenuProvider(frontendHost, items)); - } - - virtual ~MenuProvider() - { - contextMenuCleared(); - } - - void disconnect() - { - m_frontendHost = 0; - } - - virtual void populateContextMenu(WebCore::ContextMenu* menu) - { - for (size_t i = 0; i < m_items.size(); ++i) - menu->appendItem(*m_items[i]); - } - - virtual void contextMenuItemSelected(WebCore::ContextMenuItem* item) - { - if (m_frontendHost) - m_frontendHost->contextMenuItemSelected(item); - } - - virtual void contextMenuCleared() - { - if (m_frontendHost) - m_frontendHost->contextMenuCleared(); - deleteAllValues(m_items); - m_items.clear(); - } - - private: - MenuProvider(WebDevToolsFrontendImpl* frontendHost, const Vector<WebCore::ContextMenuItem*>& items) - : m_frontendHost(frontendHost) - , m_items(items) { } - WebDevToolsFrontendImpl* m_frontendHost; - Vector<WebCore::ContextMenuItem*> m_items; - }; + void frontendLoaded(); +private: void executeScript(const Vector<String>& v); - void dispatchOnWebInspector(const String& method, const String& param); - - // friend class MenuSelectionHandler; - void contextMenuItemSelected(WebCore::ContextMenuItem* menuItem); - void contextMenuCleared(); - - static v8::Handle<v8::Value> jsLoaded(const v8::Arguments& args); - static v8::Handle<v8::Value> jsPlatform(const v8::Arguments& args); - static v8::Handle<v8::Value> jsPort(const v8::Arguments& args); - static v8::Handle<v8::Value> jsCopyText(const v8::Arguments& args); - static v8::Handle<v8::Value> jsActivateWindow(const v8::Arguments& args); - static v8::Handle<v8::Value> jsCloseWindow(const v8::Arguments& args); - static v8::Handle<v8::Value> jsDockWindow(const v8::Arguments& args); - static v8::Handle<v8::Value> jsUndockWindow(const v8::Arguments& args); - static v8::Handle<v8::Value> jsLocalizedStringsURL(const v8::Arguments& args); - static v8::Handle<v8::Value> jsHiddenPanels(const v8::Arguments& args); static v8::Handle<v8::Value> jsDebuggerCommand(const v8::Arguments& args); - static v8::Handle<v8::Value> jsSetting(const v8::Arguments& args); - static v8::Handle<v8::Value> jsSetSetting(const v8::Arguments& args); static v8::Handle<v8::Value> jsDebuggerPauseScript(const v8::Arguments& args); - static v8::Handle<v8::Value> jsWindowUnloading(const v8::Arguments& args); - static v8::Handle<v8::Value> jsShowContextMenu(const v8::Arguments& args); WebKit::WebViewImpl* m_webViewImpl; WebKit::WebDevToolsFrontendClient* m_client; @@ -153,7 +88,6 @@ private: OwnPtr<JSToolsAgentBoundObj> m_toolsAgentObj; bool m_loaded; Vector<Vector<String> > m_pendingIncomingMessages; - RefPtr<MenuProvider> m_menuProvider; }; } // namespace WebKit diff --git a/WebKit/chromium/src/WebDocument.cpp b/WebKit/chromium/src/WebDocument.cpp index 2a91e22..21e2bb8 100644 --- a/WebKit/chromium/src/WebDocument.cpp +++ b/WebKit/chromium/src/WebDocument.cpp @@ -32,7 +32,6 @@ #include "WebDocument.h" #include "Document.h" -#include "DocumentLoader.h" #include "Element.h" #include "HTMLAllCollection.h" #include "HTMLBodyElement.h" @@ -44,6 +43,7 @@ #include "WebElement.h" #include "WebFrameImpl.h" #include "WebNodeCollection.h" +#include "WebNodeList.h" #include "WebURL.h" #include <wtf/PassRefPtr.h> @@ -52,22 +52,6 @@ using namespace WebCore; namespace WebKit { -WebDocument::WebDocument(const PassRefPtr<Document>& elem) - : WebNode(elem) -{ -} - -WebDocument& WebDocument::operator=(const PassRefPtr<Document>& elem) -{ - WebNode::assign(elem.releaseRef()); - return *this; -} - -WebDocument::operator PassRefPtr<Document>() const -{ - return PassRefPtr<Document>(static_cast<Document*>(m_private)); -} - WebFrame* WebDocument::frame() const { return WebFrameImpl::fromFrame(constUnwrap<Document>()->frame()); @@ -78,11 +62,21 @@ bool WebDocument::isHTMLDocument() const return constUnwrap<Document>()->isHTMLDocument(); } +bool WebDocument::isPluginDocument() const +{ + return constUnwrap<Document>()->isPluginDocument(); +} + WebURL WebDocument::baseURL() const { return constUnwrap<Document>()->baseURL(); } +WebURL WebDocument::firstPartyForCookies() const +{ + return constUnwrap<Document>()->firstPartyForCookies(); +} + WebElement WebDocument::documentElement() const { return WebElement(constUnwrap<Document>()->documentElement()); @@ -118,38 +112,25 @@ WebElement WebDocument::getElementById(const WebString& id) const return WebElement(constUnwrap<Document>()->getElementById(id)); } -WebString WebDocument::applicationID() const +WebNode WebDocument::focusedNode() const +{ + return WebNode(constUnwrap<Document>()->focusedNode()); +} + +WebDocument::WebDocument(const PassRefPtr<Document>& elem) + : WebNode(elem) +{ +} + +WebDocument& WebDocument::operator=(const PassRefPtr<Document>& elem) +{ + m_private = elem; + return *this; +} + +WebDocument::operator PassRefPtr<Document>() const { - const char* kChromeApplicationHeader = "x-chrome-application"; - - // First check if the document's response included a header indicating the - // application it should go with. - const Document* document = constUnwrap<Document>(); - Frame* frame = document->frame(); - if (!frame) - return WebString(); - - DocumentLoader* loader = frame->loader()->documentLoader(); - if (!loader) - return WebString(); - - WebString headerValue = - loader->response().httpHeaderField(kChromeApplicationHeader); - if (!headerValue.isEmpty()) - return headerValue; - - // Otherwise, fall back to looking for the meta tag. - RefPtr<NodeList> metaTags = - const_cast<Document*>(document)->getElementsByTagName("meta"); - for (unsigned i = 0; i < metaTags->length(); ++i) { - Element* element = static_cast<Element*>(metaTags->item(i)); - if (element->getAttribute("http-equiv").lower() == - kChromeApplicationHeader) { - return element->getAttribute("value"); - } - } - - return WebString(); + return static_cast<Document*>(m_private.get()); } } // namespace WebKit diff --git a/WebKit/chromium/src/WebDragData.cpp b/WebKit/chromium/src/WebDragData.cpp index 2f476a7..643c35d 100644 --- a/WebKit/chromium/src/WebDragData.cpp +++ b/WebKit/chromium/src/WebDragData.cpp @@ -67,13 +67,13 @@ void WebDragData::assign(const WebDragData& other) WebURL WebDragData::url() const { ASSERT(!isNull()); - return m_private->url; + return m_private->getURL(); } void WebDragData::setURL(const WebURL& url) { ensureMutable(); - m_private->url = url; + m_private->setURL(url); } WebString WebDragData::urlTitle() const diff --git a/WebKit/chromium/src/WebElement.cpp b/WebKit/chromium/src/WebElement.cpp index 6501771..3ed16e6 100644 --- a/WebKit/chromium/src/WebElement.cpp +++ b/WebKit/chromium/src/WebElement.cpp @@ -38,20 +38,9 @@ using namespace WebCore; namespace WebKit { -WebElement::WebElement(const WTF::PassRefPtr<WebCore::Element>& elem) - : WebNode(elem) -{ -} - -WebElement& WebElement::operator=(const WTF::PassRefPtr<WebCore::Element>& elem) -{ - WebNode::assign(elem.releaseRef()); - return *this; -} - -WebElement::operator WTF::PassRefPtr<Element>() const +bool WebElement::isFormControlElement() const { - return PassRefPtr<Element>(static_cast<Element*>(m_private)); + return constUnwrap<Element>()->isFormControlElement(); } WebString WebElement::tagName() const @@ -62,7 +51,7 @@ WebString WebElement::tagName() const bool WebElement::hasTagName(const WebString& tagName) const { return equalIgnoringCase(constUnwrap<Element>()->tagName(), - tagName.operator WebCore::String()); + tagName.operator String()); } bool WebElement::hasAttribute(const WebString& attrName) const @@ -87,5 +76,20 @@ WebString WebElement::innerText() const return constUnwrap<Element>()->innerText(); } -} // namespace WebKit +WebElement::WebElement(const PassRefPtr<Element>& elem) + : WebNode(elem) +{ +} + +WebElement& WebElement::operator=(const PassRefPtr<Element>& elem) +{ + m_private = elem; + return *this; +} +WebElement::operator PassRefPtr<Element>() const +{ + return static_cast<Element*>(m_private.get()); +} + +} // namespace WebKit diff --git a/WebKit/chromium/src/WebFormControlElement.cpp b/WebKit/chromium/src/WebFormControlElement.cpp new file mode 100644 index 0000000..0530776 --- /dev/null +++ b/WebKit/chromium/src/WebFormControlElement.cpp @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2010 Google 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: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER OR 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 "WebFormControlElement.h" + +#include "HTMLFormControlElement.h" +#include <wtf/PassRefPtr.h> + +using namespace WebCore; + +namespace WebKit { + +bool WebFormControlElement::isEnabled() const +{ + return constUnwrap<HTMLFormControlElement>()->isEnabledFormControl(); +} + +WebString WebFormControlElement::formControlName() const +{ + return constUnwrap<HTMLFormControlElement>()->formControlName(); +} + +WebString WebFormControlElement::formControlType() const +{ + return constUnwrap<HTMLFormControlElement>()->formControlType(); +} + +WebString WebFormControlElement::nameForAutofill() const +{ + String name = constUnwrap<HTMLFormControlElement>()->name(); + String trimmedName = name.stripWhiteSpace(); + if (!trimmedName.isEmpty()) + return trimmedName; + name = constUnwrap<HTMLFormControlElement>()->getAttribute(HTMLNames::idAttr); + trimmedName = name.stripWhiteSpace(); + if (!trimmedName.isEmpty()) + return trimmedName; + return String(); +} + +WebFormControlElement::WebFormControlElement(const PassRefPtr<HTMLFormControlElement>& elem) + : WebElement(elem) +{ +} + +WebFormControlElement& WebFormControlElement::operator=(const PassRefPtr<HTMLFormControlElement>& elem) +{ + m_private = elem; + return *this; +} + +WebFormControlElement::operator PassRefPtr<HTMLFormControlElement>() const +{ + return static_cast<HTMLFormControlElement*>(m_private.get()); +} + +} // namespace WebKit diff --git a/WebKit/chromium/src/WebFormElement.cpp b/WebKit/chromium/src/WebFormElement.cpp index 0024892..610c36d 100644 --- a/WebKit/chromium/src/WebFormElement.cpp +++ b/WebKit/chromium/src/WebFormElement.cpp @@ -35,6 +35,8 @@ #include "HTMLFormElement.h" #include "HTMLInputElement.h" #include "HTMLNames.h" +#include "WebFormControlElement.h" +#include "WebInputElement.h" #include "WebString.h" #include "WebURL.h" #include <wtf/PassRefPtr.h> @@ -43,25 +45,6 @@ using namespace WebCore; namespace WebKit { -class WebFormPrivate : public HTMLFormElement { -}; - -WebFormElement::WebFormElement(const WTF::PassRefPtr<HTMLFormElement>& e) - : WebElement(e) -{ -} - -WebFormElement& WebFormElement::operator=(const WTF::PassRefPtr<HTMLFormElement>& e) -{ - WebNode::assign(e.releaseRef()); - return *this; -} - -WebFormElement::operator WTF::PassRefPtr<WebCore::HTMLFormElement>() const -{ - return PassRefPtr<HTMLFormElement>(static_cast<HTMLFormElement*>(m_private)); -} - bool WebFormElement::autoComplete() const { return constUnwrap<HTMLFormElement>()->autoComplete(); @@ -107,4 +90,32 @@ void WebFormElement::getInputElements(WebVector<WebInputElement>& result) const result.assign(tempVector); } +void WebFormElement::getFormControlElements(WebVector<WebFormControlElement>& result) const +{ + const HTMLFormElement* form = constUnwrap<HTMLFormElement>(); + Vector<RefPtr<HTMLFormControlElement> > tempVector; + for (size_t i = 0; i < form->formElements.size(); i++) { + if (form->formElements[i]->hasLocalName(HTMLNames::inputTag) + || form->formElements[i]->hasLocalName(HTMLNames::selectTag)) + tempVector.append(form->formElements[i]); + } + result.assign(tempVector); +} + +WebFormElement::WebFormElement(const PassRefPtr<HTMLFormElement>& e) + : WebElement(e) +{ +} + +WebFormElement& WebFormElement::operator=(const PassRefPtr<HTMLFormElement>& e) +{ + m_private = e; + return *this; +} + +WebFormElement::operator PassRefPtr<HTMLFormElement>() const +{ + return static_cast<HTMLFormElement*>(m_private.get()); +} + } // namespace WebKit diff --git a/WebKit/chromium/src/WebFrameImpl.cpp b/WebKit/chromium/src/WebFrameImpl.cpp index 665f6a3..7b6c8ce 100644 --- a/WebKit/chromium/src/WebFrameImpl.cpp +++ b/WebKit/chromium/src/WebFrameImpl.cpp @@ -101,6 +101,7 @@ #include "markup.h" #include "Page.h" #include "PlatformContextSkia.h" +#include "PluginDocument.h" #include "PrintContext.h" #include "RenderFrame.h" #include "RenderTreeAsText.h" @@ -130,6 +131,7 @@ #include "WebHistoryItem.h" #include "WebInputElement.h" #include "WebPasswordAutocompleteListener.h" +#include "WebPluginContainerImpl.h" #include "WebRange.h" #include "WebRect.h" #include "WebScriptSource.h" @@ -246,7 +248,20 @@ static void frameContentAsPlainText(size_t maxChars, Frame* frame, } } -// Simple class to override some of PrintContext behavior. +// If the frame hosts a PluginDocument, this method returns the WebPluginContainerImpl +// that hosts the plugin. +static WebPluginContainerImpl* pluginContainerFromFrame(Frame* frame) +{ + if (!frame) + return 0; + if (!frame->document() || !frame->document()->isPluginDocument()) + return 0; + PluginDocument* pluginDocument = static_cast<PluginDocument*>(frame->document()); + return static_cast<WebPluginContainerImpl *>(pluginDocument->pluginWidget()); +} + +// Simple class to override some of PrintContext behavior. Some of the methods +// made virtual so that they can be overriden by ChromePluginPrintContext. class ChromePrintContext : public PrintContext, public Noncopyable { public: ChromePrintContext(Frame* frame) @@ -255,28 +270,38 @@ public: { } - void begin(float width) + virtual void begin(float width) { ASSERT(!m_printedPageWidth); m_printedPageWidth = width; PrintContext::begin(m_printedPageWidth); } - float getPageShrink(int pageNumber) const + virtual void end() + { + PrintContext::end(); + } + + virtual float getPageShrink(int pageNumber) const { IntRect pageRect = m_pageRects[pageNumber]; return m_printedPageWidth / pageRect.width(); } - // Spools the printed page, a subrect of m_frame. Skip the scale step. + // Spools the printed page, a subrect of m_frame. Skip the scale step. // NativeTheme doesn't play well with scaling. Scaling is done browser side - // instead. Returns the scale to be applied. - float spoolPage(GraphicsContext& ctx, int pageNumber) + // instead. Returns the scale to be applied. + // On Linux, we don't have the problem with NativeTheme, hence we let WebKit + // do the scaling and ignore the return value. + virtual float spoolPage(GraphicsContext& ctx, int pageNumber) { IntRect pageRect = m_pageRects[pageNumber]; float scale = m_printedPageWidth / pageRect.width(); ctx.save(); +#if OS(LINUX) + ctx.scale(WebCore::FloatSize(scale, scale)); +#endif ctx.translate(static_cast<float>(-pageRect.x()), static_cast<float>(-pageRect.y())); ctx.clip(pageRect); @@ -285,11 +310,95 @@ public: return scale; } + virtual void computePageRects(const FloatRect& printRect, float headerHeight, float footerHeight, float userScaleFactor, float& outPageHeight) + { + return PrintContext::computePageRects(printRect, headerHeight, footerHeight, userScaleFactor, outPageHeight); + } + + virtual int pageCount() const + { + return PrintContext::pageCount(); + } + + virtual bool shouldUseBrowserOverlays() const + { + return true; + } + private: // Set when printing. float m_printedPageWidth; }; +// Simple class to override some of PrintContext behavior. This is used when +// the frame hosts a plugin that supports custom printing. In this case, we +// want to delegate all printing related calls to the plugin. +class ChromePluginPrintContext : public ChromePrintContext { +public: + ChromePluginPrintContext(Frame* frame, int printerDPI) + : ChromePrintContext(frame), m_pageCount(0), m_printerDPI(printerDPI) + { + // This HAS to be a frame hosting a full-mode plugin + ASSERT(frame->document()->isPluginDocument()); + } + + virtual void begin(float width) + { + } + + virtual void end() + { + WebPluginContainerImpl* pluginContainer = pluginContainerFromFrame(m_frame); + if (pluginContainer && pluginContainer->supportsPaginatedPrint()) + pluginContainer->printEnd(); + else + ASSERT_NOT_REACHED(); + } + + virtual float getPageShrink(int pageNumber) const + { + // We don't shrink the page (maybe we should ask the widget ??) + return 1.0; + } + + virtual void computePageRects(const FloatRect& printRect, float headerHeight, float footerHeight, float userScaleFactor, float& outPageHeight) + { + WebPluginContainerImpl* pluginContainer = pluginContainerFromFrame(m_frame); + if (pluginContainer && pluginContainer->supportsPaginatedPrint()) + m_pageCount = pluginContainer->printBegin(IntRect(printRect), m_printerDPI); + else + ASSERT_NOT_REACHED(); + } + + virtual int pageCount() const + { + return m_pageCount; + } + + // Spools the printed page, a subrect of m_frame. Skip the scale step. + // NativeTheme doesn't play well with scaling. Scaling is done browser side + // instead. Returns the scale to be applied. + virtual float spoolPage(GraphicsContext& ctx, int pageNumber) + { + WebPluginContainerImpl* pluginContainer = pluginContainerFromFrame(m_frame); + if (pluginContainer && pluginContainer->supportsPaginatedPrint()) + pluginContainer->printPage(pageNumber, &ctx); + else + ASSERT_NOT_REACHED(); + return 1.0; + } + + virtual bool shouldUseBrowserOverlays() const + { + return false; + } + +private: + // Set when printing. + int m_pageCount; + int m_printerDPI; +}; + static WebDataSource* DataSourceForDocLoader(DocumentLoader* loader) { return loader ? WebDataSourceImpl::fromDocumentLoader(loader) : 0; @@ -413,7 +522,7 @@ WebURL WebFrameImpl::openSearchDescriptionURL() const WebString WebFrameImpl::encoding() const { - return frame()->loader()->encoding(); + return frame()->loader()->writer()->encoding(); } WebSize WebFrameImpl::scrollOffset() const @@ -553,13 +662,18 @@ void WebFrameImpl::forms(WebVector<WebFormElement>& results) const return; RefPtr<HTMLCollection> forms = m_frame->document()->forms(); - size_t formCount = forms->length(); + size_t formCount = 0; + for (size_t i = 0; i < forms->length(); ++i) { + Node* node = forms->item(i); + if (node && node->isHTMLElement()) + ++formCount; + } WebVector<WebFormElement> temp(formCount); for (size_t i = 0; i < formCount; ++i) { Node* node = forms->item(i); // Strange but true, sometimes item can be 0. - if (node) + if (node && node->isHTMLElement()) temp[i] = static_cast<HTMLFormElement*>(node); } results.swap(temp); @@ -596,7 +710,7 @@ NPObject* WebFrameImpl::windowObject() const void WebFrameImpl::bindToWindowObject(const WebString& name, NPObject* object) { ASSERT(m_frame); - if (!m_frame || !m_frame->script()->canExecuteScripts()) + if (!m_frame || !m_frame->script()->canExecuteScripts(NotAboutToExecuteScript)) return; String key = name; @@ -670,6 +784,13 @@ void WebFrameImpl::collectGarbage() } #if USE(V8) +v8::Handle<v8::Value> WebFrameImpl::executeScriptAndReturnValue( + const WebScriptSource& source) +{ + return m_frame->script()->executeScript( + ScriptSourceCode(source.code, source.url, source.startLine)).v8Value(); +} + // Returns the V8 context for this frame, or an empty handle if there is none. v8::Local<v8::Context> WebFrameImpl::mainWorldScriptContext() const { @@ -716,9 +837,6 @@ bool WebFrameImpl::insertStyleText( void WebFrameImpl::reload(bool ignoreCache) { m_frame->loader()->history()->saveDocumentAndScrollState(); - - stopLoading(); // Make sure existing activity stops. - m_frame->loader()->reload(ignoreCache); } @@ -732,7 +850,6 @@ void WebFrameImpl::loadRequest(const WebURLRequest& request) return; } - stopLoading(); // Make sure existing activity stops. m_frame->loader()->load(resourceRequest, false); } @@ -741,8 +858,6 @@ void WebFrameImpl::loadHistoryItem(const WebHistoryItem& item) RefPtr<HistoryItem> historyItem = PassRefPtr<HistoryItem>(item); ASSERT(historyItem.get()); - stopLoading(); // Make sure existing activity stops. - // If there is no currentItem, which happens when we are navigating in // session history after a crash, we need to manufacture one otherwise WebKit // hoarks. This is probably the wrong thing to do, but it seems to work. @@ -779,8 +894,6 @@ void WebFrameImpl::loadData(const WebData& data, request = m_frame->loader()->originalRequest(); request.setURL(baseURL); - stopLoading(); // Make sure existing activity stops. - m_frame->loader()->load(request, substData, false); if (replace) { // Do this to force WebKit to treat the load as replacing the currently @@ -848,7 +961,12 @@ WebHistoryItem WebFrameImpl::previousHistoryItem() const WebHistoryItem WebFrameImpl::currentHistoryItem() const { - m_frame->loader()->history()->saveDocumentAndScrollState(); + // If we are still loading, then we don't want to clobber the current + // history item as this could cause us to lose the scroll position and + // document state. However, it is OK for new navigations. + if (m_frame->loader()->loadType() == FrameLoadTypeStandard + || !m_frame->loader()->activeDocumentLoader()->isLoadingInAPISense()) + m_frame->loader()->history()->saveDocumentAndScrollState(); return WebHistoryItem(m_frame->page()->backForwardList()->currentItem()); } @@ -898,7 +1016,7 @@ void WebFrameImpl::commitDocumentData(const char* data, size_t dataLen) userChosen = false; encoding = documentLoader->response().textEncodingName(); } - m_frame->loader()->setEncoding(encoding, userChosen); + m_frame->loader()->writer()->setEncoding(encoding, userChosen); // NOTE: mac only does this if there is a document m_frame->loader()->addData(data, dataLen); @@ -1083,11 +1201,10 @@ void WebFrameImpl::selectWordAroundPosition(Frame* frame, VisiblePosition pos) VisibleSelection selection(pos); selection.expandUsingGranularity(WordGranularity); - if (selection.isRange()) - frame->setSelectionGranularity(WordGranularity); - - if (frame->shouldChangeSelection(selection)) - frame->selection()->setSelection(selection); + if (frame->shouldChangeSelection(selection)) { + TextGranularity granularity = selection.isRange() ? WordGranularity : CharacterGranularity; + frame->selection()->setSelection(selection, granularity); + } } bool WebFrameImpl::selectWordAroundCaret() @@ -1100,11 +1217,17 @@ bool WebFrameImpl::selectWordAroundCaret() return true; } -int WebFrameImpl::printBegin(const WebSize& pageSize) +int WebFrameImpl::printBegin(const WebSize& pageSize, int printerDPI, bool *useBrowserOverlays) { ASSERT(!frame()->document()->isFrameSet()); + // If this is a plugin document, check if the plugin supports its own + // printing. If it does, we will delegate all printing to that. + WebPluginContainerImpl* pluginContainer = pluginContainerFromFrame(frame()); + if (pluginContainer && pluginContainer->supportsPaginatedPrint()) + m_printContext.set(new ChromePluginPrintContext(frame(), printerDPI)); + else + m_printContext.set(new ChromePrintContext(frame())); - m_printContext.set(new ChromePrintContext(frame())); FloatRect rect(0, 0, static_cast<float>(pageSize.width), static_cast<float>(pageSize.height)); m_printContext->begin(rect.width()); @@ -1112,6 +1235,9 @@ int WebFrameImpl::printBegin(const WebSize& pageSize) // We ignore the overlays calculation for now since they are generated in the // browser. pageHeight is actually an output parameter. m_printContext->computePageRects(rect, 0, 0, 1.0, pageHeight); + if (useBrowserOverlays) + *useBrowserOverlays = m_printContext->shouldUseBrowserOverlays(); + return m_printContext->pageCount(); } @@ -1134,7 +1260,7 @@ float WebFrameImpl::printPage(int page, WebCanvas* canvas) return 0; } -#if OS(WINDOWS) || OS(LINUX) || OS(FREEBSD) +#if OS(WINDOWS) || OS(LINUX) || OS(FREEBSD) || OS(SOLARIS) PlatformContextSkia context(canvas); GraphicsContext spool(&context); #elif OS(DARWIN) @@ -1209,6 +1335,9 @@ bool WebFrameImpl::find(int identifier, executeCommand(WebString::fromUTF8("Unselect")); } + // Make sure no node is focused. See http://crbug.com/38700. + frame()->document()->setFocusedNode(0); + if (!options.findNext || activeSelection) { // This is either a Find operation or a Find-next from a new start point // due to a selection, so we set the flag to ask the scoping effort @@ -1534,6 +1663,14 @@ int WebFrameImpl::pageNumberForElementById(const WebString& id, return PrintContext::pageNumberForElement(element, pageSize); } +WebRect WebFrameImpl::selectionBoundsRect() const +{ + if (hasSelection()) + return IntRect(frame()->selectionBounds(false)); + + return WebRect(); +} + // WebFrameImpl public --------------------------------------------------------- PassRefPtr<WebFrameImpl> WebFrameImpl::create(WebFrameClient* client) @@ -1635,11 +1772,23 @@ void WebFrameImpl::layout() view->layoutIfNeededRecursive(); } +void WebFrameImpl::paintWithContext(GraphicsContext& gc, const WebRect& rect) +{ + IntRect dirtyRect(rect); + gc.save(); + if (m_frame->document() && frameView()) { + gc.clip(dirtyRect); + frameView()->paint(&gc, dirtyRect); + m_frame->page()->inspectorController()->drawNodeHighlight(gc); + } else + gc.fillRect(dirtyRect, Color::white, DeviceColorSpace); + gc.restore(); +} + void WebFrameImpl::paint(WebCanvas* canvas, const WebRect& rect) { if (rect.isEmpty()) return; - IntRect dirtyRect(rect); #if WEBKIT_USING_CG GraphicsContext gc(canvas); LocalCurrentGraphicsContext localContext(&gc); @@ -1651,14 +1800,7 @@ void WebFrameImpl::paint(WebCanvas* canvas, const WebRect& rect) #else notImplemented(); #endif - gc.save(); - if (m_frame->document() && frameView()) { - gc.clip(dirtyRect); - frameView()->paint(&gc, dirtyRect); - m_frame->page()->inspectorController()->drawNodeHighlight(gc); - } else - gc.fillRect(dirtyRect, Color::white, DeviceColorSpace); - gc.restore(); + paintWithContext(gc, rect); } void WebFrameImpl::createFrameView() @@ -1720,7 +1862,7 @@ WebFrameImpl* WebFrameImpl::fromFrameOwnerElement(Element* element) static_cast<HTMLFrameOwnerElement*>(element); return fromFrame(frameElement->contentFrame()); } - + WebViewImpl* WebFrameImpl::viewImpl() const { if (!m_frame) @@ -1795,9 +1937,9 @@ void WebFrameImpl::didFail(const ResourceError& error, bool wasProvisional) client()->didFailLoad(this, webError); } -void WebFrameImpl::setAllowsScrolling(bool flag) +void WebFrameImpl::setCanHaveScrollbars(bool canHaveScrollbars) { - m_frame->view()->setCanHaveScrollbars(flag); + m_frame->view()->setCanHaveScrollbars(canHaveScrollbars); } void WebFrameImpl::registerPasswordListener( @@ -1833,6 +1975,8 @@ void WebFrameImpl::invalidateArea(AreaToInvalidate area) if ((area & InvalidateContentArea) == InvalidateContentArea) { IntRect contentArea( view->x(), view->y(), view->visibleWidth(), view->visibleHeight()); + IntRect frameRect = view->frameRect(); + contentArea.move(-frameRect.topLeft().x(), -frameRect.topLeft().y()); view->invalidateRect(contentArea); } @@ -1842,6 +1986,8 @@ void WebFrameImpl::invalidateArea(AreaToInvalidate area) view->x() + view->visibleWidth(), view->y(), ScrollbarTheme::nativeTheme()->scrollbarThickness(), view->visibleHeight()); + IntRect frameRect = view->frameRect(); + scrollBarVert.move(-frameRect.topLeft().x(), -frameRect.topLeft().y()); view->invalidateRect(scrollBarVert); } } @@ -1975,12 +2121,13 @@ void WebFrameImpl::clearPasswordListeners() void WebFrameImpl::loadJavaScriptURL(const KURL& url) { - // This is copied from FrameLoader::executeIfJavaScriptURL. Unfortunately, - // we cannot just use that method since it is private, and it also doesn't - // quite behave as we require it to for bookmarklets. The key difference is - // that we need to suppress loading the string result from evaluating the JS - // URL if executing the JS URL resulted in a location change. We also allow - // a JS URL to be loaded even if scripts on the page are otherwise disabled. + // This is copied from ScriptController::executeIfJavaScriptURL. + // Unfortunately, we cannot just use that method since it is private, and + // it also doesn't quite behave as we require it to for bookmarklets. The + // key difference is that we need to suppress loading the string result + // from evaluating the JS URL if executing the JS URL resulted in a + // location change. We also allow a JS URL to be loaded even if scripts on + // the page are otherwise disabled. if (!m_frame->document() || !m_frame->page()) return; @@ -1996,9 +2143,9 @@ void WebFrameImpl::loadJavaScriptURL(const KURL& url) if (!m_frame->redirectScheduler()->locationChangePending()) { m_frame->loader()->stopAllLoaders(); - m_frame->loader()->begin(m_frame->loader()->url(), true, securityOrigin); - m_frame->loader()->write(scriptResult); - m_frame->loader()->end(); + m_frame->loader()->writer()->begin(m_frame->loader()->url(), true, securityOrigin); + m_frame->loader()->writer()->addData(scriptResult); + m_frame->loader()->writer()->end(); } } diff --git a/WebKit/chromium/src/WebFrameImpl.h b/WebKit/chromium/src/WebFrameImpl.h index f23106c..08d3cc2 100644 --- a/WebKit/chromium/src/WebFrameImpl.h +++ b/WebKit/chromium/src/WebFrameImpl.h @@ -42,6 +42,7 @@ #include "WebAnimationControllerImpl.h" namespace WebCore { +class GraphicsContext; class HistoryItem; class KURL; class Node; @@ -88,7 +89,7 @@ public: virtual WebFrame* findChildByExpression(const WebString&) const; virtual WebDocument document() const; virtual void forms(WebVector<WebFormElement>&) const; - virtual WebAnimationController* animationController(); + virtual WebAnimationController* animationController(); virtual WebSecurityOrigin securityOrigin() const; virtual void grantUniversalAccess(); virtual NPObject* windowObject() const; @@ -100,6 +101,8 @@ public: virtual void addMessageToConsole(const WebConsoleMessage&); virtual void collectGarbage(); #if WEBKIT_USING_V8 + virtual v8::Handle<v8::Value> executeScriptAndReturnValue( + const WebScriptSource&); virtual v8::Local<v8::Context> mainWorldScriptContext() const; #endif virtual bool insertStyleText(const WebString& css, const WebString& id); @@ -142,7 +145,8 @@ public: virtual WebString selectionAsText() const; virtual WebString selectionAsMarkup() const; virtual bool selectWordAroundCaret(); - virtual int printBegin(const WebSize& pageSize); + virtual int printBegin(const WebSize& pageSize, int printerDPI, + bool* useBrowserOverlays); virtual float printPage(int pageToPrint, WebCanvas*); virtual float getPrintPageShrink(int page); virtual void printEnd(); @@ -167,6 +171,7 @@ public: virtual int pageNumberForElementById(const WebString& id, float pageWidthInPixels, float pageHeightInPixels) const; + virtual WebRect selectionBoundsRect() const; static PassRefPtr<WebFrameImpl> create(WebFrameClient* client); ~WebFrameImpl(); @@ -179,6 +184,7 @@ public: void layout(); void paint(WebCanvas*, const WebRect&); + void paintWithContext(WebCore::GraphicsContext&, const WebRect&); void createFrameView(); static WebFrameImpl* fromFrame(WebCore::Frame* frame); @@ -212,7 +218,7 @@ public: // Sets whether the WebFrameImpl allows its document to be scrolled. // If the parameter is true, allow the document to be scrolled. // Otherwise, disallow scrolling. - void setAllowsScrolling(bool); + void setCanHaveScrollbars(bool); // Returns the password autocomplete listener associated with the passed // user name input element, or 0 if none available. diff --git a/WebKit/chromium/src/GeolocationServiceBridgeChromium.cpp b/WebKit/chromium/src/WebGeolocationServiceBridgeImpl.cpp index abbb9c6..07f09da 100644 --- a/WebKit/chromium/src/GeolocationServiceBridgeChromium.cpp +++ b/WebKit/chromium/src/WebGeolocationServiceBridgeImpl.cpp @@ -29,8 +29,7 @@ */ #include "config.h" - -#include "GeolocationServiceBridgeChromium.h" +#include "WebGeolocationServiceBridgeImpl.h" #include "Chrome.h" #include "ChromeClientImpl.h" @@ -43,6 +42,8 @@ #include "PositionOptions.h" #include "WebFrame.h" #include "WebFrameImpl.h" +#include "WebGeolocationService.h" +#include "WebGeolocationServiceBridge.h" #include "WebViewClient.h" #include "WebViewImpl.h" @@ -61,10 +62,10 @@ using WebCore::String; namespace WebKit { -class GeolocationServiceBridgeImpl : public GeolocationServiceBridge, public WebGeolocationServiceBridge { +class WebGeolocationServiceBridgeImpl : public GeolocationServiceBridge, public WebGeolocationServiceBridge { public: - explicit GeolocationServiceBridgeImpl(GeolocationServiceChromium*); - virtual ~GeolocationServiceBridgeImpl(); + explicit WebGeolocationServiceBridgeImpl(GeolocationServiceChromium*); + virtual ~WebGeolocationServiceBridgeImpl(); // GeolocationServiceBridge virtual bool startUpdating(PositionOptions*); @@ -88,83 +89,82 @@ private: GeolocationServiceBridge* createGeolocationServiceBridgeImpl(GeolocationServiceChromium* geolocationServiceChromium) { - return new GeolocationServiceBridgeImpl(geolocationServiceChromium); + return new WebGeolocationServiceBridgeImpl(geolocationServiceChromium); } -GeolocationServiceBridgeImpl::GeolocationServiceBridgeImpl(GeolocationServiceChromium* geolocationServiceChromium) +WebGeolocationServiceBridgeImpl::WebGeolocationServiceBridgeImpl(GeolocationServiceChromium* geolocationServiceChromium) : m_GeolocationServiceChromium(geolocationServiceChromium) { // We need to attach ourselves here: Geolocation calls requestPermissionForFrame() // directly, and we need to be attached so that the embedder can call // our setIsAllowed(). - m_bridgeId = getWebViewClient()->getGeolocationService()->attachBridge(this); + m_bridgeId = getWebViewClient()->geolocationService()->attachBridge(this); ASSERT(m_bridgeId); } -GeolocationServiceBridgeImpl::~GeolocationServiceBridgeImpl() +WebGeolocationServiceBridgeImpl::~WebGeolocationServiceBridgeImpl() { WebKit::WebViewClient* webViewClient = getWebViewClient(); // Geolocation has an OwnPtr to us, and it's destroyed after the frame has // been potentially disconnected. In this case, it calls stopUpdating() - // has been called and we have already dettached ourselves. - if (!webViewClient) { + // has been called and we have already detached ourselves. + if (!webViewClient) ASSERT(!m_bridgeId); - } else if (m_bridgeId) - webViewClient->getGeolocationService()->dettachBridge(m_bridgeId); + else if (m_bridgeId) + webViewClient->geolocationService()->detachBridge(m_bridgeId); } -bool GeolocationServiceBridgeImpl::startUpdating(PositionOptions* positionOptions) +bool WebGeolocationServiceBridgeImpl::startUpdating(PositionOptions* positionOptions) { if (!m_bridgeId) - m_bridgeId = getWebViewClient()->getGeolocationService()->attachBridge(this); - getWebViewClient()->getGeolocationService()->startUpdating(m_bridgeId, positionOptions->enableHighAccuracy()); - //// FIXME: this will trigger a permission request regardless. - //// Is it correct? confirm with andreip. - // positionChanged(); + m_bridgeId = getWebViewClient()->geolocationService()->attachBridge(this); + getWebViewClient()->geolocationService()->startUpdating(m_bridgeId, m_GeolocationServiceChromium->frame()->document()->url(), positionOptions->enableHighAccuracy()); return true; } -void GeolocationServiceBridgeImpl::stopUpdating() +void WebGeolocationServiceBridgeImpl::stopUpdating() { - if (m_bridgeId) { - WebGeolocationServiceInterface* geolocationService = getWebViewClient()->getGeolocationService(); + WebViewClient* webViewClient = getWebViewClient(); + if (m_bridgeId && webViewClient) { + WebGeolocationService* geolocationService = webViewClient->geolocationService(); geolocationService->stopUpdating(m_bridgeId); - geolocationService->dettachBridge(m_bridgeId); - m_bridgeId = 0; + geolocationService->detachBridge(m_bridgeId); } + m_bridgeId = 0; } -void GeolocationServiceBridgeImpl::suspend() +void WebGeolocationServiceBridgeImpl::suspend() { - getWebViewClient()->getGeolocationService()->suspend(m_bridgeId); + getWebViewClient()->geolocationService()->suspend(m_bridgeId); } -void GeolocationServiceBridgeImpl::resume() +void WebGeolocationServiceBridgeImpl::resume() { - getWebViewClient()->getGeolocationService()->resume(m_bridgeId); + getWebViewClient()->geolocationService()->resume(m_bridgeId); } -int GeolocationServiceBridgeImpl::getBridgeId() const +int WebGeolocationServiceBridgeImpl::getBridgeId() const { return m_bridgeId; } -void GeolocationServiceBridgeImpl::setIsAllowed(bool allowed) +void WebGeolocationServiceBridgeImpl::setIsAllowed(bool allowed) { m_GeolocationServiceChromium->setIsAllowed(allowed); } -void GeolocationServiceBridgeImpl::setLastPosition(double latitude, double longitude, bool providesAltitude, double altitude, double accuracy, bool providesAltitudeAccuracy, double altitudeAccuracy, bool providesHeading, double heading, bool providesSpeed, double speed, long long timestamp) +void WebGeolocationServiceBridgeImpl::setLastPosition(double latitude, double longitude, bool providesAltitude, double altitude, double accuracy, bool providesAltitudeAccuracy, double altitudeAccuracy, bool providesHeading, double heading, bool providesSpeed, double speed, long long timestamp) { - m_GeolocationServiceChromium->setLastPosition(latitude, longitude, providesAltitude, altitude, accuracy, providesAltitudeAccuracy, altitudeAccuracy, providesHeading, heading, providesSpeed, speed, timestamp); + RefPtr<Geoposition> geoposition = Geoposition::create(Coordinates::create(latitude, longitude, providesAltitude, altitude, accuracy, providesAltitudeAccuracy, altitudeAccuracy, providesHeading, heading, providesSpeed, speed), timestamp); + m_GeolocationServiceChromium->setLastPosition(geoposition); } -void GeolocationServiceBridgeImpl::setLastError(int errorCode, const WebString& message) +void WebGeolocationServiceBridgeImpl::setLastError(int errorCode, const WebString& message) { m_GeolocationServiceChromium->setLastError(errorCode, message); } -WebViewClient* GeolocationServiceBridgeImpl::getWebViewClient() +WebViewClient* WebGeolocationServiceBridgeImpl::getWebViewClient() { Frame* frame = m_GeolocationServiceChromium->frame(); if (!frame || !frame->page()) diff --git a/WebKit/chromium/src/WebGeolocationServiceBridgeImpl.h b/WebKit/chromium/src/WebGeolocationServiceBridgeImpl.h new file mode 100644 index 0000000..2c37bcb --- /dev/null +++ b/WebKit/chromium/src/WebGeolocationServiceBridgeImpl.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2010, Google 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: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER OR 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. + */ + +#ifndef WebGeolocationServiceBridgeImpl_h +#define WebGeolocationServiceBridgeImpl_h + +namespace WebCore { +class GeolocationServiceBridge; +class GeolocationServiceChromium; +} + +namespace WebKit { +WebCore::GeolocationServiceBridge* createGeolocationServiceBridgeImpl(WebCore::GeolocationServiceChromium*); +} // namespace WebKit + +#endif // WebGeolocationServiceBridgeImpl_h diff --git a/WebKit/chromium/src/WebGraphicsContext3D.cpp b/WebKit/chromium/src/WebGraphicsContext3D.cpp new file mode 100644 index 0000000..bc23703 --- /dev/null +++ b/WebKit/chromium/src/WebGraphicsContext3D.cpp @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2010 Google 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: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER OR 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 "WebGraphicsContext3D.h" + +#if ENABLE(3D_CANVAS) + +#include "WebGraphicsContext3DDefaultImpl.h" + +namespace WebKit { + +WebGraphicsContext3D* WebGraphicsContext3D::createDefault() +{ +#if ENABLE(3D_CANVAS) + return new WebGraphicsContext3DDefaultImpl(); +#else + return 0; +#endif +} + +} // namespace WebKit + +#endif // ENABLE(3D_CANVAS) diff --git a/WebKit/chromium/src/WebGraphicsContext3DDefaultImpl.cpp b/WebKit/chromium/src/WebGraphicsContext3DDefaultImpl.cpp new file mode 100644 index 0000000..2ff1c11 --- /dev/null +++ b/WebKit/chromium/src/WebGraphicsContext3DDefaultImpl.cpp @@ -0,0 +1,1399 @@ +/* + * Copyright (C) 2010 Google 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: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER OR 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" + +#if ENABLE(3D_CANVAS) + +#include <stdio.h> +#include <string.h> + +#include "WebGraphicsContext3DDefaultImpl.h" + +#include "NotImplemented.h" + +#if OS(LINUX) +#include <dlfcn.h> +#endif + +namespace WebKit { + +// Uncomment this to render to a separate window for debugging +// #define RENDER_TO_DEBUGGING_WINDOW + +#if OS(DARWIN) +#define USE_TEXTURE_RECTANGLE_FOR_FRAMEBUFFER +#endif + +bool WebGraphicsContext3DDefaultImpl::s_initializedGLEW = false; + +#if OS(LINUX) +WebGraphicsContext3DDefaultImpl::GLConnection* WebGraphicsContext3DDefaultImpl::s_gl = 0; + +WebGraphicsContext3DDefaultImpl::GLConnection* WebGraphicsContext3DDefaultImpl::GLConnection::create() +{ + Display* dpy = XOpenDisplay(0); + if (!dpy) { + printf("GraphicsContext3D: error opening X display\n"); + return 0; + } + + // We use RTLD_GLOBAL semantics so that GLEW initialization works; + // GLEW expects to be able to open the current process's handle + // and do dlsym's of GL entry points from there. + void* libGL = dlopen("libGL.so.1", RTLD_LAZY | RTLD_GLOBAL); + if (!libGL) { + XCloseDisplay(dpy); + printf("GraphicsContext3D: error opening libGL.so.1: %s\n", dlerror()); + return 0; + } + + PFNGLXCHOOSEFBCONFIGPROC chooseFBConfig = (PFNGLXCHOOSEFBCONFIGPROC) dlsym(libGL, "glXChooseFBConfig"); + PFNGLXCREATENEWCONTEXTPROC createNewContext = (PFNGLXCREATENEWCONTEXTPROC) dlsym(libGL, "glXCreateNewContext"); + PFNGLXCREATEPBUFFERPROC createPbuffer = (PFNGLXCREATEPBUFFERPROC) dlsym(libGL, "glXCreatePbuffer"); + PFNGLXDESTROYPBUFFERPROC destroyPbuffer = (PFNGLXDESTROYPBUFFERPROC) dlsym(libGL, "glXDestroyPbuffer"); + PFNGLXMAKECURRENTPROC makeCurrent = (PFNGLXMAKECURRENTPROC) dlsym(libGL, "glXMakeCurrent"); + PFNGLXDESTROYCONTEXTPROC destroyContext = (PFNGLXDESTROYCONTEXTPROC) dlsym(libGL, "glXDestroyContext"); + PFNGLXGETCURRENTCONTEXTPROC getCurrentContext = (PFNGLXGETCURRENTCONTEXTPROC) dlsym(libGL, "glXGetCurrentContext"); + if (!chooseFBConfig || !createNewContext || !createPbuffer + || !destroyPbuffer || !makeCurrent || !destroyContext + || !getCurrentContext) { + XCloseDisplay(dpy); + dlclose(libGL); + printf("GraphicsContext3D: error looking up bootstrapping entry points\n"); + return 0; + } + return new GLConnection(dpy, + libGL, + chooseFBConfig, + createNewContext, + createPbuffer, + destroyPbuffer, + makeCurrent, + destroyContext, + getCurrentContext); +} + +WebGraphicsContext3DDefaultImpl::GLConnection::~GLConnection() +{ + XCloseDisplay(m_display); + dlclose(m_libGL); +} + +#endif // OS(LINUX) + +WebGraphicsContext3DDefaultImpl::VertexAttribPointerState::VertexAttribPointerState() + : enabled(false) + , buffer(0) + , indx(0) + , size(0) + , type(0) + , normalized(false) + , stride(0) + , offset(0) +{ +} + +WebGraphicsContext3DDefaultImpl::WebGraphicsContext3DDefaultImpl() + : m_initialized(false) + , m_texture(0) + , m_fbo(0) + , m_depthStencilBuffer(0) + , m_multisampleFBO(0) + , m_multisampleDepthStencilBuffer(0) + , m_multisampleColorBuffer(0) + , m_boundFBO(0) +#ifdef FLIP_FRAMEBUFFER_VERTICALLY + , m_scanline(0) +#endif + , m_boundArrayBuffer(0) +#if OS(WINDOWS) + , m_canvasWindow(0) + , m_canvasDC(0) + , m_contextObj(0) +#elif PLATFORM(CG) + , m_pbuffer(0) + , m_contextObj(0) + , m_renderOutput(0) +#elif OS(LINUX) + , m_contextObj(0) + , m_pbuffer(0) +#else +#error Must port to your platform +#endif +{ +} + +WebGraphicsContext3DDefaultImpl::~WebGraphicsContext3DDefaultImpl() +{ + if (m_initialized) { + makeContextCurrent(); +#ifndef RENDER_TO_DEBUGGING_WINDOW + if (m_attributes.antialias) { + glDeleteRenderbuffersEXT(1, &m_multisampleColorBuffer); + if (m_attributes.depth || m_attributes.stencil) + glDeleteRenderbuffersEXT(1, &m_multisampleDepthStencilBuffer); + glDeleteFramebuffersEXT(1, &m_multisampleFBO); + } else { + if (m_attributes.depth || m_attributes.stencil) + glDeleteRenderbuffersEXT(1, &m_depthStencilBuffer); + } + glDeleteTextures(1, &m_texture); +#ifdef FLIP_FRAMEBUFFER_VERTICALLY + if (m_scanline) + delete[] m_scanline; +#endif + glDeleteFramebuffersEXT(1, &m_fbo); +#endif // !RENDER_TO_DEBUGGING_WINDOW +#if OS(WINDOWS) + wglMakeCurrent(0, 0); + wglDeleteContext(m_contextObj); + ReleaseDC(m_canvasWindow, m_canvasDC); + DestroyWindow(m_canvasWindow); +#elif PLATFORM(CG) + CGLSetCurrentContext(0); + CGLDestroyContext(m_contextObj); + CGLDestroyPBuffer(m_pbuffer); + if (m_renderOutput) + delete[] m_renderOutput; +#elif OS(LINUX) + s_gl->makeCurrent(0, 0); + s_gl->destroyContext(m_contextObj); + s_gl->destroyPbuffer(m_pbuffer); +#else +#error Must port to your platform +#endif + m_contextObj = 0; + } +} + +bool WebGraphicsContext3DDefaultImpl::initialize(WebGraphicsContext3D::Attributes attributes) +{ +#if OS(WINDOWS) + WNDCLASS wc; + if (!GetClassInfo(GetModuleHandle(0), L"CANVASGL", &wc)) { + ZeroMemory(&wc, sizeof(WNDCLASS)); + wc.style = CS_OWNDC; + wc.hInstance = GetModuleHandle(0); + wc.lpfnWndProc = DefWindowProc; + wc.lpszClassName = L"CANVASGL"; + + if (!RegisterClass(&wc)) { + printf("WebGraphicsContext3DDefaultImpl: RegisterClass failed\n"); + return false; + } + } + + m_canvasWindow = CreateWindow(L"CANVASGL", L"CANVASGL", + WS_CAPTION, + CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, + CW_USEDEFAULT, 0, 0, GetModuleHandle(0), 0); + if (!m_canvasWindow) { + printf("WebGraphicsContext3DDefaultImpl: CreateWindow failed\n"); + return false; + } + + // get the device context + m_canvasDC = GetDC(m_canvasWindow); + if (!m_canvasDC) { + printf("WebGraphicsContext3DDefaultImpl: GetDC failed\n"); + return false; + } + + // find default pixel format + PIXELFORMATDESCRIPTOR pfd; + ZeroMemory(&pfd, sizeof(PIXELFORMATDESCRIPTOR)); + pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR); + pfd.nVersion = 1; +#ifdef RENDER_TO_DEBUGGING_WINDOW + pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; +#else + pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL; +#endif + int pixelformat = ChoosePixelFormat(m_canvasDC, &pfd); + + // set the pixel format for the dc + if (!SetPixelFormat(m_canvasDC, pixelformat, &pfd)) { + printf("WebGraphicsContext3DDefaultImpl: SetPixelFormat failed\n"); + return false; + } + + // create rendering context + m_contextObj = wglCreateContext(m_canvasDC); + if (!m_contextObj) { + printf("WebGraphicsContext3DDefaultImpl: wglCreateContext failed\n"); + return false; + } + + if (!wglMakeCurrent(m_canvasDC, m_contextObj)) { + printf("WebGraphicsContext3DDefaultImpl: wglMakeCurrent failed\n"); + return false; + } + +#ifdef RENDER_TO_DEBUGGING_WINDOW + typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC) (int interval); + PFNWGLSWAPINTERVALEXTPROC setSwapInterval = 0; + setSwapInterval = (PFNWGLSWAPINTERVALEXTPROC) wglGetProcAddress("wglSwapIntervalEXT"); + if (setSwapInterval) + setSwapInterval(1); +#endif // RENDER_TO_DEBUGGING_WINDOW + +#elif PLATFORM(CG) + // Create a 1x1 pbuffer and associated context to bootstrap things + CGLPixelFormatAttribute attribs[] = { + (CGLPixelFormatAttribute) kCGLPFAPBuffer, + (CGLPixelFormatAttribute) 0 + }; + CGLPixelFormatObj pixelFormat; + GLint numPixelFormats; + if (CGLChoosePixelFormat(attribs, &pixelFormat, &numPixelFormats) != kCGLNoError) { + printf("WebGraphicsContext3DDefaultImpl: error choosing pixel format\n"); + return false; + } + if (!pixelFormat) { + printf("WebGraphicsContext3DDefaultImpl: no pixel format selected\n"); + return false; + } + CGLContextObj context; + CGLError res = CGLCreateContext(pixelFormat, 0, &context); + CGLDestroyPixelFormat(pixelFormat); + if (res != kCGLNoError) { + printf("WebGraphicsContext3DDefaultImpl: error creating context\n"); + return false; + } + CGLPBufferObj pbuffer; + if (CGLCreatePBuffer(1, 1, GL_TEXTURE_2D, GL_RGBA, 0, &pbuffer) != kCGLNoError) { + CGLDestroyContext(context); + printf("WebGraphicsContext3DDefaultImpl: error creating pbuffer\n"); + return false; + } + if (CGLSetPBuffer(context, pbuffer, 0, 0, 0) != kCGLNoError) { + CGLDestroyContext(context); + CGLDestroyPBuffer(pbuffer); + printf("WebGraphicsContext3DDefaultImpl: error attaching pbuffer to context\n"); + return false; + } + if (CGLSetCurrentContext(context) != kCGLNoError) { + CGLDestroyContext(context); + CGLDestroyPBuffer(pbuffer); + printf("WebGraphicsContext3DDefaultImpl: error making context current\n"); + return false; + } + m_pbuffer = pbuffer; + m_contextObj = context; +#elif OS(LINUX) + if (!s_gl) { + s_gl = GLConnection::create(); + if (!s_gl) + return false; + } + + int configAttrs[] = { + GLX_DRAWABLE_TYPE, + GLX_PBUFFER_BIT, + GLX_RENDER_TYPE, + GLX_RGBA_BIT, + GLX_DOUBLEBUFFER, + 0, + 0 + }; + int nelements = 0; + GLXFBConfig* config = s_gl->chooseFBConfig(0, configAttrs, &nelements); + if (!config) { + printf("WebGraphicsContext3DDefaultImpl: glXChooseFBConfig failed\n"); + return false; + } + if (!nelements) { + printf("WebGraphicsContext3DDefaultImpl: glXChooseFBConfig returned 0 elements\n"); + XFree(config); + return false; + } + GLXContext context = s_gl->createNewContext(config[0], GLX_RGBA_TYPE, 0, True); + if (!context) { + printf("WebGraphicsContext3DDefaultImpl: glXCreateNewContext failed\n"); + XFree(config); + return false; + } + int pbufferAttrs[] = { + GLX_PBUFFER_WIDTH, + 1, + GLX_PBUFFER_HEIGHT, + 1, + 0 + }; + GLXPbuffer pbuffer = s_gl->createPbuffer(config[0], pbufferAttrs); + XFree(config); + if (!pbuffer) { + printf("WebGraphicsContext3DDefaultImpl: glxCreatePbuffer failed\n"); + return false; + } + if (!s_gl->makeCurrent(pbuffer, context)) { + printf("WebGraphicsContext3DDefaultImpl: glXMakeCurrent failed\n"); + return false; + } + m_contextObj = context; + m_pbuffer = pbuffer; +#else +#error Must port to your platform +#endif + + if (!s_initializedGLEW) { + // Initialize GLEW and check for GL 2.0 support by the drivers. + GLenum glewInitResult = glewInit(); + if (glewInitResult != GLEW_OK) { + printf("WebGraphicsContext3DDefaultImpl: GLEW initialization failed\n"); + return false; + } + if (!glewIsSupported("GL_VERSION_2_0")) { + printf("WebGraphicsContext3DDefaultImpl: OpenGL 2.0 not supported\n"); + return false; + } + s_initializedGLEW = true; + } + + m_attributes = attributes; + validateAttributes(); + + glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); + m_initialized = true; + return true; +} + +void WebGraphicsContext3DDefaultImpl::validateAttributes() +{ + const char* extensions = reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS)); + + if (m_attributes.stencil) { + if (strstr(extensions, "GL_EXT_packed_depth_stencil")) { + if (!m_attributes.depth) + m_attributes.depth = true; + } else + m_attributes.stencil = false; + } + if (m_attributes.antialias) { + bool isValidVendor = true; +#if PLATFORM(CG) + // Currently in Mac we only turn on antialias if vendor is NVIDIA. + const char* vendor = reinterpret_cast<const char*>(glGetString(GL_VENDOR)); + if (!strstr(vendor, "NVIDIA")) + isValidVendor = false; +#endif + if (!isValidVendor || !strstr(extensions, "GL_EXT_framebuffer_multisample")) + m_attributes.antialias = false; + } + // FIXME: instead of enforcing premultipliedAlpha = true, implement the + // correct behavior when premultipliedAlpha = false is requested. + m_attributes.premultipliedAlpha = true; +} + +bool WebGraphicsContext3DDefaultImpl::makeContextCurrent() +{ +#if OS(WINDOWS) + if (wglGetCurrentContext() != m_contextObj) + if (wglMakeCurrent(m_canvasDC, m_contextObj)) + return true; +#elif PLATFORM(CG) + if (CGLGetCurrentContext() != m_contextObj) + if (CGLSetCurrentContext(m_contextObj) == kCGLNoError) + return true; +#elif OS(LINUX) + if (s_gl->getCurrentContext() != m_contextObj) + if (s_gl->makeCurrent(m_pbuffer, m_contextObj)) + return true; +#else +#error Must port to your platform +#endif + return false; +} + +int WebGraphicsContext3DDefaultImpl::width() +{ + return m_cachedWidth; +} + +int WebGraphicsContext3DDefaultImpl::height() +{ + return m_cachedHeight; +} + +int WebGraphicsContext3DDefaultImpl::sizeInBytes(int type) +{ + switch (type) { + case GL_BYTE: + return sizeof(GLbyte); + case GL_UNSIGNED_BYTE: + return sizeof(GLubyte); + case GL_SHORT: + return sizeof(GLshort); + case GL_UNSIGNED_SHORT: + return sizeof(GLushort); + case GL_INT: + return sizeof(GLint); + case GL_UNSIGNED_INT: + return sizeof(GLuint); + case GL_FLOAT: + return sizeof(GLfloat); + } + return 0; +} + +static int createTextureObject(GLenum target) +{ + GLuint texture = 0; + glGenTextures(1, &texture); + glBindTexture(target, texture); + glTexParameterf(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameterf(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + return texture; +} + +void WebGraphicsContext3DDefaultImpl::reshape(int width, int height) +{ +#ifdef RENDER_TO_DEBUGGING_WINDOW + SetWindowPos(m_canvasWindow, HWND_TOP, 0, 0, width, height, + SWP_NOMOVE); + ShowWindow(m_canvasWindow, SW_SHOW); +#endif + + m_cachedWidth = width; + m_cachedHeight = height; + makeContextCurrent(); + +#ifndef RENDER_TO_DEBUGGING_WINDOW +#ifdef USE_TEXTURE_RECTANGLE_FOR_FRAMEBUFFER + // GL_TEXTURE_RECTANGLE_ARB is the best supported render target on Mac OS X + GLenum target = GL_TEXTURE_RECTANGLE_ARB; +#else + GLenum target = GL_TEXTURE_2D; +#endif + if (!m_texture) { + // Generate the texture object + m_texture = createTextureObject(target); + // Generate the framebuffer object + glGenFramebuffersEXT(1, &m_fbo); + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo); + m_boundFBO = m_fbo; + if (m_attributes.depth || m_attributes.stencil) + glGenRenderbuffersEXT(1, &m_depthStencilBuffer); + // Generate the multisample framebuffer object + if (m_attributes.antialias) { + glGenFramebuffersEXT(1, &m_multisampleFBO); + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_multisampleFBO); + m_boundFBO = m_multisampleFBO; + glGenRenderbuffersEXT(1, &m_multisampleColorBuffer); + if (m_attributes.depth || m_attributes.stencil) + glGenRenderbuffersEXT(1, &m_multisampleDepthStencilBuffer); + } + } + + GLint internalColorFormat, colorFormat, internalDepthStencilFormat = 0; + if (m_attributes.alpha) { + internalColorFormat = GL_RGBA8; + colorFormat = GL_RGBA; + } else { + internalColorFormat = GL_RGB8; + colorFormat = GL_RGB; + } + if (m_attributes.stencil || m_attributes.depth) { + // We don't allow the logic where stencil is required and depth is not. + // See GraphicsContext3DInternal constructor. + if (m_attributes.stencil && m_attributes.depth) + internalDepthStencilFormat = GL_DEPTH24_STENCIL8_EXT; + else + internalDepthStencilFormat = GL_DEPTH_COMPONENT; + } + + bool mustRestoreFBO = false; + + // Resize multisampling FBO + if (m_attributes.antialias) { + GLint maxSampleCount; + glGetIntegerv(GL_MAX_SAMPLES_EXT, &maxSampleCount); + GLint sampleCount = std::min(8, maxSampleCount); + if (m_boundFBO != m_multisampleFBO) { + mustRestoreFBO = true; + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_multisampleFBO); + } + glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_multisampleColorBuffer); + glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, sampleCount, internalColorFormat, width, height); + glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_EXT, m_multisampleColorBuffer); + if (m_attributes.stencil || m_attributes.depth) { + glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_multisampleDepthStencilBuffer); + glRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, sampleCount, internalDepthStencilFormat, width, height); + if (m_attributes.stencil) + glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_multisampleDepthStencilBuffer); + if (m_attributes.depth) + glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_multisampleDepthStencilBuffer); + } + glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); + GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); + if (status != GL_FRAMEBUFFER_COMPLETE_EXT) { + printf("GraphicsContext3D: multisampling framebuffer was incomplete\n"); + + // FIXME: cleanup. + notImplemented(); + } + } + + // Resize regular FBO + if (m_boundFBO != m_fbo) { + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo); + mustRestoreFBO = true; + } + glBindTexture(target, m_texture); + glTexImage2D(target, 0, internalColorFormat, width, height, 0, colorFormat, GL_UNSIGNED_BYTE, 0); + glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, target, m_texture, 0); + glBindTexture(target, 0); + if (!m_attributes.antialias && (m_attributes.stencil || m_attributes.depth)) { + glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, m_depthStencilBuffer); + glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, internalDepthStencilFormat, width, height); + if (m_attributes.stencil) + glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depthStencilBuffer); + if (m_attributes.depth) + glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, m_depthStencilBuffer); + glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); + } + GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); + if (status != GL_FRAMEBUFFER_COMPLETE_EXT) { + printf("WebGraphicsContext3DDefaultImpl: framebuffer was incomplete\n"); + + // FIXME: cleanup. + notImplemented(); + } + + if (mustRestoreFBO) + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_boundFBO); +#endif // RENDER_TO_DEBUGGING_WINDOW + +#ifdef FLIP_FRAMEBUFFER_VERTICALLY + if (m_scanline) { + delete[] m_scanline; + m_scanline = 0; + } + m_scanline = new unsigned char[width * 4]; +#endif // FLIP_FRAMEBUFFER_VERTICALLY + + GLbitfield clearMask = GL_COLOR_BUFFER_BIT; + if (m_attributes.stencil) + clearMask |= GL_STENCIL_BUFFER_BIT; + if (m_attributes.depth) + clearMask |= GL_DEPTH_BUFFER_BIT; + glClear(clearMask); +} + +#ifdef FLIP_FRAMEBUFFER_VERTICALLY +void WebGraphicsContext3DDefaultImpl::flipVertically(unsigned char* framebuffer, + unsigned int width, + unsigned int height) +{ + unsigned char* scanline = m_scanline; + if (!scanline) + return; + unsigned int rowBytes = width * 4; + unsigned int count = height / 2; + for (unsigned int i = 0; i < count; i++) { + unsigned char* rowA = framebuffer + i * rowBytes; + unsigned char* rowB = framebuffer + (height - i - 1) * rowBytes; + // FIXME: this is where the multiplication of the alpha + // channel into the color buffer will need to occur if the + // user specifies the "premultiplyAlpha" flag in the context + // creation attributes. + memcpy(scanline, rowB, rowBytes); + memcpy(rowB, rowA, rowBytes); + memcpy(rowA, scanline, rowBytes); + } +} +#endif + +bool WebGraphicsContext3DDefaultImpl::readBackFramebuffer(unsigned char* pixels, size_t bufferSize) +{ + if (bufferSize != static_cast<size_t>(4 * width() * height())) + return false; + + makeContextCurrent(); + +#ifdef RENDER_TO_DEBUGGING_WINDOW + SwapBuffers(m_canvasDC); +#else + // Earlier versions of this code used the GPU to flip the + // framebuffer vertically before reading it back for compositing + // via software. This code was quite complicated, used a lot of + // GPU memory, and didn't provide an obvious speedup. Since this + // vertical flip is only a temporary solution anyway until Chrome + // is fully GPU composited, it wasn't worth the complexity. + + bool mustRestoreFBO; + if (m_attributes.antialias) { + glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_multisampleFBO); + glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_fbo); + glBlitFramebufferEXT(0, 0, m_cachedWidth, m_cachedHeight, 0, 0, m_cachedWidth, m_cachedHeight, GL_COLOR_BUFFER_BIT, GL_LINEAR); + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo); + mustRestoreFBO = true; + } else { + if (m_boundFBO != m_fbo) { + mustRestoreFBO = true; + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo); + } + } + + GLint packAlignment = 4; + bool mustRestorePackAlignment = false; + glGetIntegerv(GL_PACK_ALIGNMENT, &packAlignment); + if (packAlignment > 4) { + glPixelStorei(GL_PACK_ALIGNMENT, 4); + mustRestorePackAlignment = true; + } + +#if PLATFORM(SKIA) + glReadPixels(0, 0, m_cachedWidth, m_cachedHeight, GL_BGRA, GL_UNSIGNED_BYTE, pixels); +#elif PLATFORM(CG) + glReadPixels(0, 0, m_cachedWidth, m_cachedHeight, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, pixels); +#else +#error Must port to your platform +#endif + + if (mustRestorePackAlignment) + glPixelStorei(GL_PACK_ALIGNMENT, packAlignment); + + if (mustRestoreFBO) + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_boundFBO); + +#ifdef FLIP_FRAMEBUFFER_VERTICALLY + if (pixels) + flipVertically(pixels, m_cachedWidth, m_cachedHeight); +#endif + +#endif // RENDER_TO_DEBUGGING_WINDOW + return true; +} + +void WebGraphicsContext3DDefaultImpl::synthesizeGLError(unsigned long error) +{ + m_syntheticErrors.add(error); +} + +// Helper macros to reduce the amount of code. + +#define DELEGATE_TO_GL(name, glname) \ +void WebGraphicsContext3DDefaultImpl::name() \ +{ \ + makeContextCurrent(); \ + gl##glname(); \ +} + +#define DELEGATE_TO_GL_1(name, glname, t1) \ +void WebGraphicsContext3DDefaultImpl::name(t1 a1) \ +{ \ + makeContextCurrent(); \ + gl##glname(a1); \ +} + +#define DELEGATE_TO_GL_1R(name, glname, t1, rt) \ +rt WebGraphicsContext3DDefaultImpl::name(t1 a1) \ +{ \ + makeContextCurrent(); \ + return gl##glname(a1); \ +} + +#define DELEGATE_TO_GL_2(name, glname, t1, t2) \ +void WebGraphicsContext3DDefaultImpl::name(t1 a1, t2 a2) \ +{ \ + makeContextCurrent(); \ + gl##glname(a1, a2); \ +} + +#define DELEGATE_TO_GL_2R(name, glname, t1, t2, rt) \ +rt WebGraphicsContext3DDefaultImpl::name(t1 a1, t2 a2) \ +{ \ + makeContextCurrent(); \ + return gl##glname(a1, a2); \ +} + +#define DELEGATE_TO_GL_3(name, glname, t1, t2, t3) \ +void WebGraphicsContext3DDefaultImpl::name(t1 a1, t2 a2, t3 a3) \ +{ \ + makeContextCurrent(); \ + gl##glname(a1, a2, a3); \ +} + +#define DELEGATE_TO_GL_4(name, glname, t1, t2, t3, t4) \ +void WebGraphicsContext3DDefaultImpl::name(t1 a1, t2 a2, t3 a3, t4 a4) \ +{ \ + makeContextCurrent(); \ + gl##glname(a1, a2, a3, a4); \ +} + +#define DELEGATE_TO_GL_5(name, glname, t1, t2, t3, t4, t5) \ +void WebGraphicsContext3DDefaultImpl::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5) \ +{ \ + makeContextCurrent(); \ + gl##glname(a1, a2, a3, a4, a5); \ +} + +#define DELEGATE_TO_GL_6(name, glname, t1, t2, t3, t4, t5, t6) \ +void WebGraphicsContext3DDefaultImpl::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6) \ +{ \ + makeContextCurrent(); \ + gl##glname(a1, a2, a3, a4, a5, a6); \ +} + +#define DELEGATE_TO_GL_7(name, glname, t1, t2, t3, t4, t5, t6, t7) \ +void WebGraphicsContext3DDefaultImpl::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7) \ +{ \ + makeContextCurrent(); \ + gl##glname(a1, a2, a3, a4, a5, a6, a7); \ +} + +#define DELEGATE_TO_GL_8(name, glname, t1, t2, t3, t4, t5, t6, t7, t8) \ +void WebGraphicsContext3DDefaultImpl::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7, t8 a8) \ +{ \ + makeContextCurrent(); \ + gl##glname(a1, a2, a3, a4, a5, a6, a7, a8); \ +} + +#define DELEGATE_TO_GL_9(name, glname, t1, t2, t3, t4, t5, t6, t7, t8, t9) \ +void WebGraphicsContext3DDefaultImpl::name(t1 a1, t2 a2, t3 a3, t4 a4, t5 a5, t6 a6, t7 a7, t8 a8, t9 a9) \ +{ \ + makeContextCurrent(); \ + gl##glname(a1, a2, a3, a4, a5, a6, a7, a8, a9); \ +} + +void WebGraphicsContext3DDefaultImpl::activeTexture(unsigned long texture) +{ + // FIXME: query number of textures available. + if (texture < GL_TEXTURE0 || texture > GL_TEXTURE0+32) + // FIXME: raise exception. + return; + + makeContextCurrent(); + glActiveTexture(texture); +} + +DELEGATE_TO_GL_2(attachShader, AttachShader, WebGLId, WebGLId) + +DELEGATE_TO_GL_3(bindAttribLocation, BindAttribLocation, WebGLId, unsigned long, const char*) + +void WebGraphicsContext3DDefaultImpl::bindBuffer(unsigned long target, WebGLId buffer) +{ + makeContextCurrent(); + if (target == GL_ARRAY_BUFFER) + m_boundArrayBuffer = buffer; + glBindBuffer(target, buffer); +} + +void WebGraphicsContext3DDefaultImpl::bindFramebuffer(unsigned long target, WebGLId framebuffer) +{ + makeContextCurrent(); + if (!framebuffer) + framebuffer = (m_attributes.antialias ? m_multisampleFBO : m_fbo); + if (framebuffer != m_boundFBO) { + glBindFramebufferEXT(target, framebuffer); + m_boundFBO = framebuffer; + } +} + +DELEGATE_TO_GL_2(bindRenderbuffer, BindRenderbufferEXT, unsigned long, WebGLId) + +DELEGATE_TO_GL_2(bindTexture, BindTexture, unsigned long, WebGLId) + +DELEGATE_TO_GL_4(blendColor, BlendColor, double, double, double, double) + +DELEGATE_TO_GL_1(blendEquation, BlendEquation, unsigned long) + +DELEGATE_TO_GL_2(blendEquationSeparate, BlendEquationSeparate, unsigned long, unsigned long) + +DELEGATE_TO_GL_2(blendFunc, BlendFunc, unsigned long, unsigned long) + +DELEGATE_TO_GL_4(blendFuncSeparate, BlendFuncSeparate, unsigned long, unsigned long, unsigned long, unsigned long) + +DELEGATE_TO_GL_4(bufferData, BufferData, unsigned long, int, const void*, unsigned long) + +DELEGATE_TO_GL_4(bufferSubData, BufferSubData, unsigned long, long, int, const void*) + +DELEGATE_TO_GL_1R(checkFramebufferStatus, CheckFramebufferStatusEXT, unsigned long, unsigned long) + +DELEGATE_TO_GL_1(clear, Clear, unsigned long) + +DELEGATE_TO_GL_4(clearColor, ClearColor, double, double, double, double) + +DELEGATE_TO_GL_1(clearDepth, ClearDepth, double) + +DELEGATE_TO_GL_1(clearStencil, ClearStencil, long) + +DELEGATE_TO_GL_4(colorMask, ColorMask, bool, bool, bool, bool) + +DELEGATE_TO_GL_1(compileShader, CompileShader, WebGLId) + +void WebGraphicsContext3DDefaultImpl::copyTexImage2D(unsigned long target, long level, unsigned long internalformat, + long x, long y, unsigned long width, unsigned long height, long border) +{ + makeContextCurrent(); +#ifndef RENDER_TO_DEBUGGING_WINDOW + if (m_attributes.antialias && m_boundFBO == m_multisampleFBO) { + glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_multisampleFBO); + glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_fbo); + glBlitFramebufferEXT(x, y, x + width, y + height, x, y, x + width, y + height, GL_COLOR_BUFFER_BIT, GL_LINEAR); + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo); + } +#endif + glCopyTexImage2D(target, level, internalformat, x, y, width, height, border); +#ifndef RENDER_TO_DEBUGGING_WINDOW + if (m_attributes.antialias && m_boundFBO == m_multisampleFBO) + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_boundFBO); +#endif +} + +void WebGraphicsContext3DDefaultImpl::copyTexSubImage2D(unsigned long target, long level, long xoffset, long yoffset, + long x, long y, unsigned long width, unsigned long height) +{ + makeContextCurrent(); +#ifndef RENDER_TO_DEBUGGING_WINDOW + if (m_attributes.antialias && m_boundFBO == m_multisampleFBO) { + glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_multisampleFBO); + glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_fbo); + glBlitFramebufferEXT(x, y, x + width, y + height, x, y, x + width, y + height, GL_COLOR_BUFFER_BIT, GL_LINEAR); + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo); + } +#endif + glCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height); +#ifndef RENDER_TO_DEBUGGING_WINDOW + if (m_attributes.antialias && m_boundFBO == m_multisampleFBO) + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_boundFBO); +#endif +} + +DELEGATE_TO_GL_1(cullFace, CullFace, unsigned long) + +DELEGATE_TO_GL_1(depthFunc, DepthFunc, unsigned long) + +DELEGATE_TO_GL_1(depthMask, DepthMask, bool) + +DELEGATE_TO_GL_2(depthRange, DepthRange, double, double) + +DELEGATE_TO_GL_2(detachShader, DetachShader, WebGLId, WebGLId) + +DELEGATE_TO_GL_1(disable, Disable, unsigned long) + +void WebGraphicsContext3DDefaultImpl::disableVertexAttribArray(unsigned long index) +{ + makeContextCurrent(); + if (index < NumTrackedPointerStates) + m_vertexAttribPointerState[index].enabled = false; + glDisableVertexAttribArray(index); +} + +DELEGATE_TO_GL_3(drawArrays, DrawArrays, unsigned long, long, long) + +void WebGraphicsContext3DDefaultImpl::drawElements(unsigned long mode, unsigned long count, unsigned long type, long offset) +{ + makeContextCurrent(); + glDrawElements(mode, count, type, + reinterpret_cast<void*>(static_cast<intptr_t>(offset))); +} + +DELEGATE_TO_GL_1(enable, Enable, unsigned long) + +void WebGraphicsContext3DDefaultImpl::enableVertexAttribArray(unsigned long index) +{ + makeContextCurrent(); + if (index < NumTrackedPointerStates) + m_vertexAttribPointerState[index].enabled = true; + glEnableVertexAttribArray(index); +} + +DELEGATE_TO_GL(finish, Finish) + +DELEGATE_TO_GL(flush, Flush) + +void WebGraphicsContext3DDefaultImpl::framebufferRenderbuffer(unsigned long target, unsigned long attachment, + unsigned long renderbuffertarget, WebGLId buffer) +{ + makeContextCurrent(); + if (attachment == GL_DEPTH_STENCIL_ATTACHMENT) { + glFramebufferRenderbufferEXT(target, GL_DEPTH_ATTACHMENT, renderbuffertarget, buffer); + glFramebufferRenderbufferEXT(target, GL_STENCIL_ATTACHMENT, renderbuffertarget, buffer); + } else + glFramebufferRenderbufferEXT(target, attachment, renderbuffertarget, buffer); +} + +DELEGATE_TO_GL_5(framebufferTexture2D, FramebufferTexture2DEXT, unsigned long, unsigned long, unsigned long, WebGLId, long) + +DELEGATE_TO_GL_1(frontFace, FrontFace, unsigned long) + +void WebGraphicsContext3DDefaultImpl::generateMipmap(unsigned long target) +{ + makeContextCurrent(); + if (glGenerateMipmapEXT) + glGenerateMipmapEXT(target); + // FIXME: provide alternative code path? This will be unpleasant + // to implement if glGenerateMipmapEXT is not available -- it will + // require a texture readback and re-upload. +} + +bool WebGraphicsContext3DDefaultImpl::getActiveAttrib(WebGLId program, unsigned long index, ActiveInfo& info) +{ + if (!program) { + synthesizeGLError(GL_INVALID_VALUE); + return false; + } + GLint maxNameLength = -1; + glGetProgramiv(program, GL_ACTIVE_ATTRIBUTE_MAX_LENGTH, &maxNameLength); + if (maxNameLength < 0) + return false; + GLchar* name = 0; + if (!tryFastMalloc(maxNameLength * sizeof(GLchar)).getValue(name)) { + synthesizeGLError(GL_OUT_OF_MEMORY); + return false; + } + GLsizei length = 0; + GLint size = -1; + GLenum type = 0; + glGetActiveAttrib(program, index, maxNameLength, + &length, &size, &type, name); + if (size < 0) { + fastFree(name); + return false; + } + info.name = WebString::fromUTF8(name, length); + info.type = type; + info.size = size; + fastFree(name); + return true; +} + +bool WebGraphicsContext3DDefaultImpl::getActiveUniform(WebGLId program, unsigned long index, ActiveInfo& info) +{ + GLint maxNameLength = -1; + glGetProgramiv(program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxNameLength); + if (maxNameLength < 0) + return false; + GLchar* name = 0; + if (!tryFastMalloc(maxNameLength * sizeof(GLchar)).getValue(name)) { + synthesizeGLError(GL_OUT_OF_MEMORY); + return false; + } + GLsizei length = 0; + GLint size = -1; + GLenum type = 0; + glGetActiveUniform(program, index, maxNameLength, + &length, &size, &type, name); + if (size < 0) { + fastFree(name); + return false; + } + info.name = WebString::fromUTF8(name, length); + info.type = type; + info.size = size; + fastFree(name); + return true; +} + +DELEGATE_TO_GL_2R(getAttribLocation, GetAttribLocation, WebGLId, const char*, int) + +DELEGATE_TO_GL_2(getBooleanv, GetBooleanv, unsigned long, unsigned char*) + +DELEGATE_TO_GL_3(getBufferParameteriv, GetBufferParameteriv, unsigned long, unsigned long, int*) + +WebGraphicsContext3D::Attributes WebGraphicsContext3DDefaultImpl::getContextAttributes() +{ + return m_attributes; +} + +unsigned long WebGraphicsContext3DDefaultImpl::getError() +{ + if (m_syntheticErrors.size() > 0) { + ListHashSet<unsigned long>::iterator iter = m_syntheticErrors.begin(); + unsigned long err = *iter; + m_syntheticErrors.remove(iter); + return err; + } + + makeContextCurrent(); + return glGetError(); +} + +DELEGATE_TO_GL_2(getFloatv, GetFloatv, unsigned long, float*) + +void WebGraphicsContext3DDefaultImpl::getFramebufferAttachmentParameteriv(unsigned long target, unsigned long attachment, + unsigned long pname, int* value) +{ + makeContextCurrent(); + if (attachment == GL_DEPTH_STENCIL_ATTACHMENT) + attachment = GL_DEPTH_ATTACHMENT; // Or GL_STENCIL_ATTACHMENT, either works. + glGetFramebufferAttachmentParameterivEXT(target, attachment, pname, value); +} + +DELEGATE_TO_GL_2(getIntegerv, GetIntegerv, unsigned long, int*) + +DELEGATE_TO_GL_3(getProgramiv, GetProgramiv, WebGLId, unsigned long, int*) + +WebString WebGraphicsContext3DDefaultImpl::getProgramInfoLog(WebGLId program) +{ + makeContextCurrent(); + GLint logLength; + glGetProgramiv(program, GL_INFO_LOG_LENGTH, &logLength); + if (!logLength) + return WebString(); + GLchar* log = 0; + if (!tryFastMalloc(logLength * sizeof(GLchar)).getValue(log)) + return WebString(); + GLsizei returnedLogLength; + glGetProgramInfoLog(program, logLength, &returnedLogLength, log); + ASSERT(logLength == returnedLogLength + 1); + WebString res = WebString::fromUTF8(log, returnedLogLength); + fastFree(log); + return res; +} + +DELEGATE_TO_GL_3(getRenderbufferParameteriv, GetRenderbufferParameterivEXT, unsigned long, unsigned long, int*) + +DELEGATE_TO_GL_3(getShaderiv, GetShaderiv, WebGLId, unsigned long, int*) + +WebString WebGraphicsContext3DDefaultImpl::getShaderInfoLog(WebGLId shader) +{ + makeContextCurrent(); + GLint logLength; + glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &logLength); + if (!logLength) + return WebString(); + GLchar* log = 0; + if (!tryFastMalloc(logLength * sizeof(GLchar)).getValue(log)) + return WebString(); + GLsizei returnedLogLength; + glGetShaderInfoLog(shader, logLength, &returnedLogLength, log); + ASSERT(logLength == returnedLogLength + 1); + WebString res = WebString::fromUTF8(log, returnedLogLength); + fastFree(log); + return res; +} + +WebString WebGraphicsContext3DDefaultImpl::getShaderSource(WebGLId shader) +{ + makeContextCurrent(); + GLint logLength; + glGetShaderiv(shader, GL_SHADER_SOURCE_LENGTH, &logLength); + if (!logLength) + return WebString(); + GLchar* log = 0; + if (!tryFastMalloc(logLength * sizeof(GLchar)).getValue(log)) + return WebString(); + GLsizei returnedLogLength; + glGetShaderSource(shader, logLength, &returnedLogLength, log); + ASSERT(logLength == returnedLogLength + 1); + WebString res = WebString::fromUTF8(log, returnedLogLength); + fastFree(log); + return res; +} + +WebString WebGraphicsContext3DDefaultImpl::getString(unsigned long name) +{ + makeContextCurrent(); + return WebString::fromUTF8(reinterpret_cast<const char*>(glGetString(name))); +} + +DELEGATE_TO_GL_3(getTexParameterfv, GetTexParameterfv, unsigned long, unsigned long, float*) + +DELEGATE_TO_GL_3(getTexParameteriv, GetTexParameteriv, unsigned long, unsigned long, int*) + +DELEGATE_TO_GL_3(getUniformfv, GetUniformfv, WebGLId, long, float*) + +DELEGATE_TO_GL_3(getUniformiv, GetUniformiv, WebGLId, long, int*) + +DELEGATE_TO_GL_2R(getUniformLocation, GetUniformLocation, WebGLId, const char*, long) + +DELEGATE_TO_GL_3(getVertexAttribfv, GetVertexAttribfv, unsigned long, unsigned long, float*) + +DELEGATE_TO_GL_3(getVertexAttribiv, GetVertexAttribiv, unsigned long, unsigned long, int*) + +long WebGraphicsContext3DDefaultImpl::getVertexAttribOffset(unsigned long index, unsigned long pname) +{ + // FIXME: implement. + notImplemented(); + return 0; +} + +DELEGATE_TO_GL_2(hint, Hint, unsigned long, unsigned long) + +DELEGATE_TO_GL_1R(isBuffer, IsBuffer, WebGLId, bool) + +DELEGATE_TO_GL_1R(isEnabled, IsEnabled, unsigned long, bool) + +DELEGATE_TO_GL_1R(isFramebuffer, IsFramebuffer, WebGLId, bool) + +DELEGATE_TO_GL_1R(isProgram, IsProgram, WebGLId, bool) + +DELEGATE_TO_GL_1R(isRenderbuffer, IsRenderbuffer, WebGLId, bool) + +DELEGATE_TO_GL_1R(isShader, IsShader, WebGLId, bool) + +DELEGATE_TO_GL_1R(isTexture, IsTexture, WebGLId, bool) + +DELEGATE_TO_GL_1(lineWidth, LineWidth, double) + +DELEGATE_TO_GL_1(linkProgram, LinkProgram, WebGLId) + +DELEGATE_TO_GL_2(pixelStorei, PixelStorei, unsigned long, long) + +DELEGATE_TO_GL_2(polygonOffset, PolygonOffset, double, double) + +void WebGraphicsContext3DDefaultImpl::readPixels(long x, long y, unsigned long width, unsigned long height, unsigned long format, unsigned long type, void* pixels) +{ + // FIXME: remove the two glFlush calls when the driver bug is fixed, i.e., + // all previous rendering calls should be done before reading pixels. + glFlush(); +#ifndef RENDER_TO_DEBUGGING_WINDOW + if (m_attributes.antialias && m_boundFBO == m_multisampleFBO) { + glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, m_multisampleFBO); + glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, m_fbo); + glBlitFramebufferEXT(x, y, x + width, y + height, x, y, x + width, y + height, GL_COLOR_BUFFER_BIT, GL_LINEAR); + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_fbo); + glFlush(); + } +#endif + glReadPixels(x, y, width, height, format, type, pixels); +#ifndef RENDER_TO_DEBUGGING_WINDOW + if (m_attributes.antialias && m_boundFBO == m_multisampleFBO) + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, m_boundFBO); +#endif +} + +void WebGraphicsContext3DDefaultImpl::releaseShaderCompiler() +{ +} + +void WebGraphicsContext3DDefaultImpl::renderbufferStorage(unsigned long target, + unsigned long internalformat, + unsigned long width, + unsigned long height) +{ + makeContextCurrent(); + if (internalformat == GL_DEPTH_STENCIL) + internalformat = GL_DEPTH24_STENCIL8_EXT; + else if (internalformat == GL_DEPTH_COMPONENT16) + internalformat = GL_DEPTH_COMPONENT; + glRenderbufferStorageEXT(target, internalformat, width, height); +} + +DELEGATE_TO_GL_2(sampleCoverage, SampleCoverage, double, bool) + +DELEGATE_TO_GL_4(scissor, Scissor, long, long, unsigned long, unsigned long) + +void WebGraphicsContext3DDefaultImpl::shaderSource(WebGLId shader, const char* string) +{ + makeContextCurrent(); + GLint length = strlen(string); + glShaderSource(shader, 1, &string, &length); +} + +DELEGATE_TO_GL_3(stencilFunc, StencilFunc, unsigned long, long, unsigned long) + +DELEGATE_TO_GL_4(stencilFuncSeparate, StencilFuncSeparate, unsigned long, unsigned long, long, unsigned long) + +DELEGATE_TO_GL_1(stencilMask, StencilMask, unsigned long) + +DELEGATE_TO_GL_2(stencilMaskSeparate, StencilMaskSeparate, unsigned long, unsigned long) + +DELEGATE_TO_GL_3(stencilOp, StencilOp, unsigned long, unsigned long, unsigned long) + +DELEGATE_TO_GL_4(stencilOpSeparate, StencilOpSeparate, unsigned long, unsigned long, unsigned long, unsigned long) + +DELEGATE_TO_GL_9(texImage2D, TexImage2D, unsigned, unsigned, unsigned, unsigned, unsigned, unsigned, unsigned, unsigned, const void*) + +DELEGATE_TO_GL_3(texParameterf, TexParameterf, unsigned, unsigned, float); + +DELEGATE_TO_GL_3(texParameteri, TexParameteri, unsigned, unsigned, int); + +DELEGATE_TO_GL_9(texSubImage2D, TexSubImage2D, unsigned, unsigned, unsigned, unsigned, unsigned, unsigned, unsigned, unsigned, const void*) + +DELEGATE_TO_GL_2(uniform1f, Uniform1f, long, float) + +DELEGATE_TO_GL_3(uniform1fv, Uniform1fv, long, int, float*) + +DELEGATE_TO_GL_2(uniform1i, Uniform1i, long, int) + +DELEGATE_TO_GL_3(uniform1iv, Uniform1iv, long, int, int*) + +DELEGATE_TO_GL_3(uniform2f, Uniform2f, long, float, float) + +DELEGATE_TO_GL_3(uniform2fv, Uniform2fv, long, int, float*) + +DELEGATE_TO_GL_3(uniform2i, Uniform2i, long, int, int) + +DELEGATE_TO_GL_3(uniform2iv, Uniform2iv, long, int, int*) + +DELEGATE_TO_GL_4(uniform3f, Uniform3f, long, float, float, float) + +DELEGATE_TO_GL_3(uniform3fv, Uniform3fv, long, int, float*) + +DELEGATE_TO_GL_4(uniform3i, Uniform3i, long, int, int, int) + +DELEGATE_TO_GL_3(uniform3iv, Uniform3iv, long, int, int*) + +DELEGATE_TO_GL_5(uniform4f, Uniform4f, long, float, float, float, float) + +DELEGATE_TO_GL_3(uniform4fv, Uniform4fv, long, int, float*) + +DELEGATE_TO_GL_5(uniform4i, Uniform4i, long, int, int, int, int) + +DELEGATE_TO_GL_3(uniform4iv, Uniform4iv, long, int, int*) + +DELEGATE_TO_GL_4(uniformMatrix2fv, UniformMatrix2fv, long, int, bool, const float*) + +DELEGATE_TO_GL_4(uniformMatrix3fv, UniformMatrix3fv, long, int, bool, const float*) + +DELEGATE_TO_GL_4(uniformMatrix4fv, UniformMatrix4fv, long, int, bool, const float*) + +DELEGATE_TO_GL_1(useProgram, UseProgram, WebGLId) + +DELEGATE_TO_GL_1(validateProgram, ValidateProgram, WebGLId) + +DELEGATE_TO_GL_2(vertexAttrib1f, VertexAttrib1f, unsigned long, float) + +DELEGATE_TO_GL_2(vertexAttrib1fv, VertexAttrib1fv, unsigned long, const float*) + +DELEGATE_TO_GL_3(vertexAttrib2f, VertexAttrib2f, unsigned long, float, float) + +DELEGATE_TO_GL_2(vertexAttrib2fv, VertexAttrib2fv, unsigned long, const float*) + +DELEGATE_TO_GL_4(vertexAttrib3f, VertexAttrib3f, unsigned long, float, float, float) + +DELEGATE_TO_GL_2(vertexAttrib3fv, VertexAttrib3fv, unsigned long, const float*) + +DELEGATE_TO_GL_5(vertexAttrib4f, VertexAttrib4f, unsigned long, float, float, float, float) + +DELEGATE_TO_GL_2(vertexAttrib4fv, VertexAttrib4fv, unsigned long, const float*) + +void WebGraphicsContext3DDefaultImpl::vertexAttribPointer(unsigned long indx, int size, int type, bool normalized, + unsigned long stride, unsigned long offset) +{ + makeContextCurrent(); + + if (m_boundArrayBuffer <= 0) { + // FIXME: raise exception. + // LogMessagef(("bufferData: no buffer bound")); + return; + } + + if (indx < NumTrackedPointerStates) { + VertexAttribPointerState& state = m_vertexAttribPointerState[indx]; + state.buffer = m_boundArrayBuffer; + state.indx = indx; + state.size = size; + state.type = type; + state.normalized = normalized; + state.stride = stride; + state.offset = offset; + } + + glVertexAttribPointer(indx, size, type, normalized, stride, + reinterpret_cast<void*>(static_cast<intptr_t>(offset))); +} + +DELEGATE_TO_GL_4(viewport, Viewport, long, long, unsigned long, unsigned long) + +unsigned WebGraphicsContext3DDefaultImpl::createBuffer() +{ + makeContextCurrent(); + GLuint o; + glGenBuffers(1, &o); + return o; +} + +unsigned WebGraphicsContext3DDefaultImpl::createFramebuffer() +{ + makeContextCurrent(); + GLuint o = 0; + glGenFramebuffersEXT(1, &o); + return o; +} + +unsigned WebGraphicsContext3DDefaultImpl::createProgram() +{ + makeContextCurrent(); + return glCreateProgram(); +} + +unsigned WebGraphicsContext3DDefaultImpl::createRenderbuffer() +{ + makeContextCurrent(); + GLuint o; + glGenRenderbuffersEXT(1, &o); + return o; +} + +DELEGATE_TO_GL_1R(createShader, CreateShader, unsigned long, unsigned); + +unsigned WebGraphicsContext3DDefaultImpl::createTexture() +{ + makeContextCurrent(); + GLuint o; + glGenTextures(1, &o); + return o; +} + +void WebGraphicsContext3DDefaultImpl::deleteBuffer(unsigned buffer) +{ + makeContextCurrent(); + glDeleteBuffers(1, &buffer); +} + +void WebGraphicsContext3DDefaultImpl::deleteFramebuffer(unsigned framebuffer) +{ + makeContextCurrent(); + glDeleteFramebuffersEXT(1, &framebuffer); +} + +void WebGraphicsContext3DDefaultImpl::deleteProgram(unsigned program) +{ + makeContextCurrent(); + glDeleteProgram(program); +} + +void WebGraphicsContext3DDefaultImpl::deleteRenderbuffer(unsigned renderbuffer) +{ + makeContextCurrent(); + glDeleteRenderbuffersEXT(1, &renderbuffer); +} + +void WebGraphicsContext3DDefaultImpl::deleteShader(unsigned shader) +{ + makeContextCurrent(); + glDeleteShader(shader); +} + +void WebGraphicsContext3DDefaultImpl::deleteTexture(unsigned texture) +{ + makeContextCurrent(); + glDeleteTextures(1, &texture); +} + +} // namespace WebKit + +#endif // ENABLE(3D_CANVAS) diff --git a/WebKit/chromium/src/WebGraphicsContext3DDefaultImpl.h b/WebKit/chromium/src/WebGraphicsContext3DDefaultImpl.h new file mode 100644 index 0000000..cc283e3 --- /dev/null +++ b/WebKit/chromium/src/WebGraphicsContext3DDefaultImpl.h @@ -0,0 +1,419 @@ +/* + * Copyright (C) 2010 Google 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: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER OR 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. + */ + +#ifndef WebGraphicsContext3DDefaultImpl_h +#define WebGraphicsContext3DDefaultImpl_h + +#if ENABLE(3D_CANVAS) + +#include "WebGraphicsContext3D.h" + +#include <wtf/ListHashSet.h> + +#if OS(WINDOWS) +#include <windows.h> +#endif + +#include "GL/glew.h" + +#if PLATFORM(CG) +#include <OpenGL/OpenGL.h> +#else +#define FLIP_FRAMEBUFFER_VERTICALLY +#endif + +#if OS(LINUX) +#include "GL/glxew.h" +#endif + +namespace WebKit { + +// The default implementation of WebGL. In Chromium, using this class +// requires the sandbox to be disabled, which is strongly discouraged. +// It is provided for support of test_shell and any Chromium ports +// where an in-renderer WebGL implementation would be helpful. + +class WebGraphicsContext3DDefaultImpl : public WebGraphicsContext3D { +public: + WebGraphicsContext3DDefaultImpl(); + virtual ~WebGraphicsContext3DDefaultImpl(); + + //---------------------------------------------------------------------- + // WebGraphicsContext3D methods + virtual bool initialize(WebGraphicsContext3D::Attributes attributes); + virtual bool makeContextCurrent(); + + virtual int width(); + virtual int height(); + + virtual int sizeInBytes(int type); + + virtual void reshape(int width, int height); + + virtual bool readBackFramebuffer(unsigned char* pixels, size_t bufferSize); + + virtual void synthesizeGLError(unsigned long error); + + virtual void activeTexture(unsigned long texture); + virtual void attachShader(WebGLId program, WebGLId shader); + virtual void bindAttribLocation(WebGLId program, unsigned long index, const char* name); + virtual void bindBuffer(unsigned long target, WebGLId buffer); + virtual void bindFramebuffer(unsigned long target, WebGLId framebuffer); + virtual void bindRenderbuffer(unsigned long target, WebGLId renderbuffer); + virtual void bindTexture(unsigned long target, WebGLId texture); + virtual void blendColor(double red, double green, double blue, double alpha); + virtual void blendEquation(unsigned long mode); + virtual void blendEquationSeparate(unsigned long modeRGB, unsigned long modeAlpha); + virtual void blendFunc(unsigned long sfactor, unsigned long dfactor); + virtual void blendFuncSeparate(unsigned long srcRGB, unsigned long dstRGB, unsigned long srcAlpha, unsigned long dstAlpha); + + virtual void bufferData(unsigned long target, int size, const void* data, unsigned long usage); + virtual void bufferSubData(unsigned long target, long offset, int size, const void* data); + + virtual unsigned long checkFramebufferStatus(unsigned long target); + virtual void clear(unsigned long mask); + virtual void clearColor(double red, double green, double blue, double alpha); + virtual void clearDepth(double depth); + virtual void clearStencil(long s); + virtual void colorMask(bool red, bool green, bool blue, bool alpha); + virtual void compileShader(WebGLId shader); + + virtual void copyTexImage2D(unsigned long target, long level, unsigned long internalformat, long x, long y, unsigned long width, unsigned long height, long border); + virtual void copyTexSubImage2D(unsigned long target, long level, long xoffset, long yoffset, long x, long y, unsigned long width, unsigned long height); + virtual void cullFace(unsigned long mode); + virtual void depthFunc(unsigned long func); + virtual void depthMask(bool flag); + virtual void depthRange(double zNear, double zFar); + virtual void detachShader(WebGLId program, WebGLId shader); + virtual void disable(unsigned long cap); + virtual void disableVertexAttribArray(unsigned long index); + virtual void drawArrays(unsigned long mode, long first, long count); + virtual void drawElements(unsigned long mode, unsigned long count, unsigned long type, long offset); + + virtual void enable(unsigned long cap); + virtual void enableVertexAttribArray(unsigned long index); + virtual void finish(); + virtual void flush(); + virtual void framebufferRenderbuffer(unsigned long target, unsigned long attachment, unsigned long renderbuffertarget, WebGLId renderbuffer); + virtual void framebufferTexture2D(unsigned long target, unsigned long attachment, unsigned long textarget, WebGLId texture, long level); + virtual void frontFace(unsigned long mode); + virtual void generateMipmap(unsigned long target); + + virtual bool getActiveAttrib(WebGLId program, unsigned long index, ActiveInfo&); + virtual bool getActiveUniform(WebGLId program, unsigned long index, ActiveInfo&); + + virtual int getAttribLocation(WebGLId program, const char* name); + + virtual void getBooleanv(unsigned long pname, unsigned char* value); + + virtual void getBufferParameteriv(unsigned long target, unsigned long pname, int* value); + + virtual Attributes getContextAttributes(); + + virtual unsigned long getError(); + + virtual void getFloatv(unsigned long pname, float* value); + + virtual void getFramebufferAttachmentParameteriv(unsigned long target, unsigned long attachment, unsigned long pname, int* value); + + virtual void getIntegerv(unsigned long pname, int* value); + + virtual void getProgramiv(WebGLId program, unsigned long pname, int* value); + + virtual WebString getProgramInfoLog(WebGLId program); + + virtual void getRenderbufferParameteriv(unsigned long target, unsigned long pname, int* value); + + virtual void getShaderiv(WebGLId shader, unsigned long pname, int* value); + + virtual WebString getShaderInfoLog(WebGLId shader); + + // TBD + // void glGetShaderPrecisionFormat (GLenum shadertype, GLenum precisiontype, GLint* range, GLint* precision); + + virtual WebString getShaderSource(WebGLId shader); + virtual WebString getString(unsigned long name); + + virtual void getTexParameterfv(unsigned long target, unsigned long pname, float* value); + virtual void getTexParameteriv(unsigned long target, unsigned long pname, int* value); + + virtual void getUniformfv(WebGLId program, long location, float* value); + virtual void getUniformiv(WebGLId program, long location, int* value); + + virtual long getUniformLocation(WebGLId program, const char* name); + + virtual void getVertexAttribfv(unsigned long index, unsigned long pname, float* value); + virtual void getVertexAttribiv(unsigned long index, unsigned long pname, int* value); + + virtual long getVertexAttribOffset(unsigned long index, unsigned long pname); + + virtual void hint(unsigned long target, unsigned long mode); + virtual bool isBuffer(WebGLId buffer); + virtual bool isEnabled(unsigned long cap); + virtual bool isFramebuffer(WebGLId framebuffer); + virtual bool isProgram(WebGLId program); + virtual bool isRenderbuffer(WebGLId renderbuffer); + virtual bool isShader(WebGLId shader); + virtual bool isTexture(WebGLId texture); + virtual void lineWidth(double); + virtual void linkProgram(WebGLId program); + virtual void pixelStorei(unsigned long pname, long param); + virtual void polygonOffset(double factor, double units); + + virtual void readPixels(long x, long y, unsigned long width, unsigned long height, unsigned long format, unsigned long type, void* pixels); + + virtual void releaseShaderCompiler(); + virtual void renderbufferStorage(unsigned long target, unsigned long internalformat, unsigned long width, unsigned long height); + virtual void sampleCoverage(double value, bool invert); + virtual void scissor(long x, long y, unsigned long width, unsigned long height); + virtual void shaderSource(WebGLId shader, const char* string); + virtual void stencilFunc(unsigned long func, long ref, unsigned long mask); + virtual void stencilFuncSeparate(unsigned long face, unsigned long func, long ref, unsigned long mask); + virtual void stencilMask(unsigned long mask); + virtual void stencilMaskSeparate(unsigned long face, unsigned long mask); + virtual void stencilOp(unsigned long fail, unsigned long zfail, unsigned long zpass); + virtual void stencilOpSeparate(unsigned long face, unsigned long fail, unsigned long zfail, unsigned long zpass); + + virtual void texImage2D(unsigned target, unsigned level, unsigned internalformat, unsigned width, unsigned height, unsigned border, unsigned format, unsigned type, const void* pixels); + + virtual void texParameterf(unsigned target, unsigned pname, float param); + virtual void texParameteri(unsigned target, unsigned pname, int param); + + virtual void texSubImage2D(unsigned target, unsigned level, unsigned xoffset, unsigned yoffset, unsigned width, unsigned height, unsigned format, unsigned type, const void* pixels); + + virtual void uniform1f(long location, float x); + virtual void uniform1fv(long location, int count, float* v); + virtual void uniform1i(long location, int x); + virtual void uniform1iv(long location, int count, int* v); + virtual void uniform2f(long location, float x, float y); + virtual void uniform2fv(long location, int count, float* v); + virtual void uniform2i(long location, int x, int y); + virtual void uniform2iv(long location, int count, int* v); + virtual void uniform3f(long location, float x, float y, float z); + virtual void uniform3fv(long location, int count, float* v); + virtual void uniform3i(long location, int x, int y, int z); + virtual void uniform3iv(long location, int count, int* v); + virtual void uniform4f(long location, float x, float y, float z, float w); + virtual void uniform4fv(long location, int count, float* v); + virtual void uniform4i(long location, int x, int y, int z, int w); + virtual void uniform4iv(long location, int count, int* v); + virtual void uniformMatrix2fv(long location, int count, bool transpose, const float* value); + virtual void uniformMatrix3fv(long location, int count, bool transpose, const float* value); + virtual void uniformMatrix4fv(long location, int count, bool transpose, const float* value); + + virtual void useProgram(WebGLId program); + virtual void validateProgram(WebGLId program); + + virtual void vertexAttrib1f(unsigned long indx, float x); + virtual void vertexAttrib1fv(unsigned long indx, const float* values); + virtual void vertexAttrib2f(unsigned long indx, float x, float y); + virtual void vertexAttrib2fv(unsigned long indx, const float* values); + virtual void vertexAttrib3f(unsigned long indx, float x, float y, float z); + virtual void vertexAttrib3fv(unsigned long indx, const float* values); + virtual void vertexAttrib4f(unsigned long indx, float x, float y, float z, float w); + virtual void vertexAttrib4fv(unsigned long indx, const float* values); + virtual void vertexAttribPointer(unsigned long indx, int size, int type, bool normalized, + unsigned long stride, unsigned long offset); + + virtual void viewport(long x, long y, unsigned long width, unsigned long height); + + // Support for buffer creation and deletion + virtual unsigned createBuffer(); + virtual unsigned createFramebuffer(); + virtual unsigned createProgram(); + virtual unsigned createRenderbuffer(); + virtual unsigned createShader(unsigned long); + virtual unsigned createTexture(); + + virtual void deleteBuffer(unsigned); + virtual void deleteFramebuffer(unsigned); + virtual void deleteProgram(unsigned); + virtual void deleteRenderbuffer(unsigned); + virtual void deleteShader(unsigned); + virtual void deleteTexture(unsigned); + +private: + WebGraphicsContext3D::Attributes m_attributes; + bool m_initialized; + unsigned int m_texture; + unsigned int m_fbo; + unsigned int m_depthStencilBuffer; + unsigned int m_cachedWidth, m_cachedHeight; + + // For multisampling + unsigned int m_multisampleFBO; + unsigned int m_multisampleDepthStencilBuffer; + unsigned int m_multisampleColorBuffer; + + // For tracking which FBO is bound + unsigned int m_boundFBO; + +#ifdef FLIP_FRAMEBUFFER_VERTICALLY + unsigned char* m_scanline; + void flipVertically(unsigned char* framebuffer, + unsigned int width, + unsigned int height); +#endif + + // Take into account the user's requested context creation attributes, in + // particular stencil and antialias, and determine which could or could + // not be honored based on the capabilities of the OpenGL implementation. + void validateAttributes(); + + // Note: we aren't currently using this information, but we will + // need to in order to verify that all enabled vertex arrays have + // a valid buffer bound -- to avoid crashes on certain cards. + unsigned int m_boundArrayBuffer; + class VertexAttribPointerState { + public: + VertexAttribPointerState(); + + bool enabled; + unsigned long buffer; + unsigned long indx; + int size; + int type; + bool normalized; + unsigned long stride; + unsigned long offset; + }; + + enum { + NumTrackedPointerStates = 2 + }; + VertexAttribPointerState m_vertexAttribPointerState[NumTrackedPointerStates]; + + // Errors raised by synthesizeGLError(). + ListHashSet<unsigned long> m_syntheticErrors; + + static bool s_initializedGLEW; +#if OS(WINDOWS) + HWND m_canvasWindow; + HDC m_canvasDC; + HGLRC m_contextObj; +#elif PLATFORM(CG) + CGLPBufferObj m_pbuffer; + CGLContextObj m_contextObj; + unsigned char* m_renderOutput; +#elif OS(LINUX) + GLXContext m_contextObj; + GLXPbuffer m_pbuffer; + + // In order to avoid problems caused by linking against libGL, we + // dynamically look up all the symbols we need. + // http://code.google.com/p/chromium/issues/detail?id=16800 + class GLConnection { + public: + ~GLConnection(); + + static GLConnection* create(); + + GLXFBConfig* chooseFBConfig(int screen, const int *attrib_list, int *nelements) + { + return m_glXChooseFBConfig(m_display, screen, attrib_list, nelements); + } + + GLXContext createNewContext(GLXFBConfig config, int renderType, GLXContext shareList, Bool direct) + { + return m_glXCreateNewContext(m_display, config, renderType, shareList, direct); + } + + GLXPbuffer createPbuffer(GLXFBConfig config, const int *attribList) + { + return m_glXCreatePbuffer(m_display, config, attribList); + } + + void destroyPbuffer(GLXPbuffer pbuf) + { + m_glXDestroyPbuffer(m_display, pbuf); + } + + Bool makeCurrent(GLXDrawable drawable, GLXContext ctx) + { + return m_glXMakeCurrent(m_display, drawable, ctx); + } + + void destroyContext(GLXContext ctx) + { + m_glXDestroyContext(m_display, ctx); + } + + GLXContext getCurrentContext() + { + return m_glXGetCurrentContext(); + } + + private: + Display* m_display; + void* m_libGL; + PFNGLXCHOOSEFBCONFIGPROC m_glXChooseFBConfig; + PFNGLXCREATENEWCONTEXTPROC m_glXCreateNewContext; + PFNGLXCREATEPBUFFERPROC m_glXCreatePbuffer; + PFNGLXDESTROYPBUFFERPROC m_glXDestroyPbuffer; + typedef Bool (* PFNGLXMAKECURRENTPROC)(Display* dpy, GLXDrawable drawable, GLXContext ctx); + PFNGLXMAKECURRENTPROC m_glXMakeCurrent; + typedef void (* PFNGLXDESTROYCONTEXTPROC)(Display* dpy, GLXContext ctx); + PFNGLXDESTROYCONTEXTPROC m_glXDestroyContext; + typedef GLXContext (* PFNGLXGETCURRENTCONTEXTPROC)(void); + PFNGLXGETCURRENTCONTEXTPROC m_glXGetCurrentContext; + + GLConnection(Display* display, + void* libGL, + PFNGLXCHOOSEFBCONFIGPROC chooseFBConfig, + PFNGLXCREATENEWCONTEXTPROC createNewContext, + PFNGLXCREATEPBUFFERPROC createPbuffer, + PFNGLXDESTROYPBUFFERPROC destroyPbuffer, + PFNGLXMAKECURRENTPROC makeCurrent, + PFNGLXDESTROYCONTEXTPROC destroyContext, + PFNGLXGETCURRENTCONTEXTPROC getCurrentContext) + : m_libGL(libGL) + , m_display(display) + , m_glXChooseFBConfig(chooseFBConfig) + , m_glXCreateNewContext(createNewContext) + , m_glXCreatePbuffer(createPbuffer) + , m_glXDestroyPbuffer(destroyPbuffer) + , m_glXMakeCurrent(makeCurrent) + , m_glXDestroyContext(destroyContext) + , m_glXGetCurrentContext(getCurrentContext) + { + } + }; + + static GLConnection* s_gl; +#else + #error Must port WebGraphicsContext3DDefaultImpl to your platform +#endif +}; + +} // namespace WebKit + +#endif // ENABLE(3D_CANVAS) + +#endif diff --git a/WebKit/chromium/src/WebHTTPBody.cpp b/WebKit/chromium/src/WebHTTPBody.cpp index 3d40869..d062576 100644 --- a/WebKit/chromium/src/WebHTTPBody.cpp +++ b/WebKit/chromium/src/WebHTTPBody.cpp @@ -79,17 +79,25 @@ bool WebHTTPBody::elementAt(size_t index, Element& result) const result.type = Element::TypeData; result.data.assign(element.m_data.data(), element.m_data.size()); result.filePath.reset(); +#if ENABLE(BLOB_SLICE) result.fileStart = 0; result.fileLength = 0; result.fileInfo.modificationTime = 0.0; +#endif break; case FormDataElement::encodedFile: result.type = Element::TypeFile; result.data.reset(); result.filePath = element.m_filename; - result.fileStart = 0; // FIXME: to be set from FormData. - result.fileLength = -1; // FIXME: to be set from FormData. - result.fileInfo.modificationTime = 0.0; // FIXME: to be set from FormData. +#if ENABLE(BLOB_SLICE) + result.fileStart = element.m_fileStart; + result.fileLength = element.m_fileLength; + result.fileInfo.modificationTime = element.m_expectedFileModificationTime; +#else + result.fileStart = 0; + result.fileLength = -1; + result.fileInfo.modificationTime = 0.0; +#endif break; default: ASSERT_NOT_REACHED(); @@ -113,9 +121,12 @@ void WebHTTPBody::appendFile(const WebString& filePath) m_private->appendFile(filePath); } -void WebHTTPBody::appendFile(const WebString& filePath, long long fileStart, long long fileLength, const WebFileInfo& fileInfo) +void WebHTTPBody::appendFileRange(const WebString& filePath, long long fileStart, long long fileLength, const WebFileInfo& fileInfo) { - // FIXME: to be implemented. +#if ENABLE(BLOB_SLICE) + ensureMutable(); + m_private->appendFileRange(filePath, fileStart, fileLength, fileInfo.modificationTime); +#endif } long long WebHTTPBody::identifier() const diff --git a/WebKit/chromium/src/WebHistoryItem.cpp b/WebKit/chromium/src/WebHistoryItem.cpp index 4ca8cc7..45e4472 100644 --- a/WebKit/chromium/src/WebHistoryItem.cpp +++ b/WebKit/chromium/src/WebHistoryItem.cpp @@ -37,6 +37,7 @@ #include "WebHTTPBody.h" #include "WebPoint.h" +#include "WebSerializedScriptValue.h" #include "WebString.h" #include "WebVector.h" @@ -44,30 +45,23 @@ using namespace WebCore; namespace WebKit { -class WebHistoryItemPrivate : public HistoryItem { -}; - void WebHistoryItem::initialize() { - assign(static_cast<WebHistoryItemPrivate*>(HistoryItem::create().releaseRef())); + m_private = HistoryItem::create(); } void WebHistoryItem::reset() { - assign(0); + m_private.reset(); } void WebHistoryItem::assign(const WebHistoryItem& other) { - WebHistoryItemPrivate* p = const_cast<WebHistoryItemPrivate*>(other.m_private); - if (p) - p->ref(); - assign(p); + m_private = other.m_private; } WebString WebHistoryItem::urlString() const { - ASSERT(!isNull()); return m_private->urlString(); } @@ -79,7 +73,6 @@ void WebHistoryItem::setURLString(const WebString& url) WebString WebHistoryItem::originalURLString() const { - ASSERT(!isNull()); return m_private->originalURLString(); } @@ -91,7 +84,6 @@ void WebHistoryItem::setOriginalURLString(const WebString& originalURLString) WebString WebHistoryItem::referrer() const { - ASSERT(!isNull()); return m_private->referrer(); } @@ -103,7 +95,6 @@ void WebHistoryItem::setReferrer(const WebString& referrer) WebString WebHistoryItem::target() const { - ASSERT(!isNull()); return m_private->target(); } @@ -115,7 +106,6 @@ void WebHistoryItem::setTarget(const WebString& target) WebString WebHistoryItem::parent() const { - ASSERT(!isNull()); return m_private->parent(); } @@ -127,7 +117,6 @@ void WebHistoryItem::setParent(const WebString& parent) WebString WebHistoryItem::title() const { - ASSERT(!isNull()); return m_private->title(); } @@ -139,7 +128,6 @@ void WebHistoryItem::setTitle(const WebString& title) WebString WebHistoryItem::alternateTitle() const { - ASSERT(!isNull()); return m_private->alternateTitle(); } @@ -151,7 +139,6 @@ void WebHistoryItem::setAlternateTitle(const WebString& alternateTitle) double WebHistoryItem::lastVisitedTime() const { - ASSERT(!isNull()); return m_private->lastVisitedTime(); } @@ -168,7 +155,6 @@ void WebHistoryItem::setLastVisitedTime(double lastVisitedTime) WebPoint WebHistoryItem::scrollOffset() const { - ASSERT(!isNull()); return m_private->scrollPoint(); } @@ -180,7 +166,6 @@ void WebHistoryItem::setScrollOffset(const WebPoint& scrollOffset) bool WebHistoryItem::isTargetItem() const { - ASSERT(!isNull()); return m_private->isTargetItem(); } @@ -192,7 +177,6 @@ void WebHistoryItem::setIsTargetItem(bool isTargetItem) int WebHistoryItem::visitCount() const { - ASSERT(!isNull()); return m_private->visitCount(); } @@ -204,7 +188,6 @@ void WebHistoryItem::setVisitCount(int count) WebVector<WebString> WebHistoryItem::documentState() const { - ASSERT(!isNull()); return m_private->documentState(); } @@ -220,7 +203,6 @@ void WebHistoryItem::setDocumentState(const WebVector<WebString>& state) long long WebHistoryItem::documentSequenceNumber() const { - ASSERT(!isNull()); return m_private->documentSequenceNumber(); } @@ -230,9 +212,19 @@ void WebHistoryItem::setDocumentSequenceNumber(long long documentSequenceNumber) m_private->setDocumentSequenceNumber(documentSequenceNumber); } +WebSerializedScriptValue WebHistoryItem::stateObject() const +{ + return WebSerializedScriptValue(m_private->stateObject()); +} + +void WebHistoryItem::setStateObject(const WebSerializedScriptValue& object) +{ + ensureMutable(); + m_private->setStateObject(object); +} + WebString WebHistoryItem::httpContentType() const { - ASSERT(!isNull()); return m_private->formContentType(); } @@ -244,7 +236,6 @@ void WebHistoryItem::setHTTPContentType(const WebString& httpContentType) WebHTTPBody WebHistoryItem::httpBody() const { - ASSERT(!isNull()); return WebHTTPBody(m_private->formData()); } @@ -256,7 +247,6 @@ void WebHistoryItem::setHTTPBody(const WebHTTPBody& httpBody) WebVector<WebHistoryItem> WebHistoryItem::children() const { - ASSERT(!isNull()); return m_private->children(); } @@ -275,34 +265,25 @@ void WebHistoryItem::appendToChildren(const WebHistoryItem& item) } WebHistoryItem::WebHistoryItem(const PassRefPtr<HistoryItem>& item) - : m_private(static_cast<WebHistoryItemPrivate*>(item.releaseRef())) + : m_private(item) { } WebHistoryItem& WebHistoryItem::operator=(const PassRefPtr<HistoryItem>& item) { - assign(static_cast<WebHistoryItemPrivate*>(item.releaseRef())); + m_private = item; return *this; } WebHistoryItem::operator PassRefPtr<HistoryItem>() const { - return m_private; -} - -void WebHistoryItem::assign(WebHistoryItemPrivate* p) -{ - // p is already ref'd for us by the caller - if (m_private) - m_private->deref(); - m_private = p; + return m_private.get(); } void WebHistoryItem::ensureMutable() { - ASSERT(!isNull()); if (!m_private->hasOneRef()) - assign(static_cast<WebHistoryItemPrivate*>(m_private->copy().releaseRef())); + m_private = m_private->copy(); } } // namespace WebKit diff --git a/WebKit/chromium/src/WebIDBDatabaseError.cpp b/WebKit/chromium/src/WebIDBDatabaseError.cpp new file mode 100644 index 0000000..17fdd38 --- /dev/null +++ b/WebKit/chromium/src/WebIDBDatabaseError.cpp @@ -0,0 +1,86 @@ +/* + * Copyright (C) 2010 Google 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: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER OR 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 "WebIDBDatabaseError.h" + +#include "IDBDatabaseError.h" +#include "WebString.h" + +#if ENABLE(INDEXED_DATABASE) + +using namespace WebCore; + +namespace WebKit { + +WebIDBDatabaseError::~WebIDBDatabaseError() +{ + m_private.reset(); +} + +void WebIDBDatabaseError::assign(const WebIDBDatabaseError& value) +{ + m_private = value.m_private; +} + +void WebIDBDatabaseError::assign(unsigned short code, const WebString& message) +{ + m_private = IDBDatabaseError::create(code, message); +} + +unsigned short WebIDBDatabaseError::code() const +{ + return m_private->code(); +} + +WebString WebIDBDatabaseError::message() const +{ + return m_private->message(); +} + +WebIDBDatabaseError::WebIDBDatabaseError(const PassRefPtr<IDBDatabaseError>& value) + : m_private(value) +{ +} + +WebIDBDatabaseError& WebIDBDatabaseError::operator=(const PassRefPtr<IDBDatabaseError>& value) +{ + m_private = value; + return *this; +} + +WebIDBDatabaseError::operator PassRefPtr<IDBDatabaseError>() const +{ + return m_private.get(); +} + +} // namespace WebKit + +#endif // ENABLE(INDEXED_DATABASE) diff --git a/WebKit/chromium/src/WebImageDecoder.cpp b/WebKit/chromium/src/WebImageDecoder.cpp new file mode 100644 index 0000000..9e1d1f4 --- /dev/null +++ b/WebKit/chromium/src/WebImageDecoder.cpp @@ -0,0 +1,121 @@ +/* + * Copyright (C) 2010 Google 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: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER OR 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 "WebImageDecoder.h" + +#include "BMPImageDecoder.h" +#include "ICOImageDecoder.h" +#include "SharedBuffer.h" +#include "WebData.h" +#include "WebImage.h" +#include "WebSize.h" + +#if WEBKIT_USING_SKIA +#include <wtf/OwnPtr.h> +#include <wtf/PassRefPtr.h> +#endif + +using namespace WebCore; + +namespace WebKit { + +void WebImageDecoder::reset() +{ + delete m_private; +} + +void WebImageDecoder::init(Type type) +{ + switch (type) { + case TypeBMP: + m_private = new BMPImageDecoder(); + break; + case TypeICO: + m_private = new ICOImageDecoder(); + break; + } +} + +void WebImageDecoder::setData(const WebData& data, bool allDataReceived) +{ + ASSERT(m_private); + m_private->setData(PassRefPtr<SharedBuffer>(data).get(), allDataReceived); +} + +bool WebImageDecoder::isFailed() const +{ + ASSERT(m_private); + return m_private->failed(); +} + +bool WebImageDecoder::isSizeAvailable() const +{ + ASSERT(m_private); + return m_private->isSizeAvailable(); +} + +WebSize WebImageDecoder::size() const +{ + ASSERT(m_private); + return m_private->size(); +} + +size_t WebImageDecoder::frameCount() const +{ + ASSERT(m_private); + return m_private->frameCount(); +} + +bool WebImageDecoder::isFrameCompleteAtIndex(int index) const +{ + ASSERT(m_private); + RGBA32Buffer* const frameBuffer = m_private->frameBufferAtIndex(index); + if (!frameBuffer) + return false; + return (frameBuffer->status() == RGBA32Buffer::FrameComplete); +} + +WebImage WebImageDecoder::getFrameAtIndex(int index = 0) const +{ + ASSERT(m_private); + RGBA32Buffer* const frameBuffer = m_private->frameBufferAtIndex(index); + if (!frameBuffer) + return WebImage(); +#if WEBKIT_USING_SKIA + OwnPtr<NativeImageSkia>image(frameBuffer->asNewNativeImage()); + return WebImage(*image); +#elif WEBKIT_USING_CG + // FIXME: Implement CG side of this. + return WebImage(frameBuffer->asNewNativeImage()); +#endif +} + +} // namespace WebKit diff --git a/WebKit/chromium/src/WebIndexedDatabaseImpl.cpp b/WebKit/chromium/src/WebIndexedDatabaseImpl.cpp new file mode 100644 index 0000000..6a6327b --- /dev/null +++ b/WebKit/chromium/src/WebIndexedDatabaseImpl.cpp @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2010 Google 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: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER OR 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 "WebIndexedDatabaseImpl.h" + +#include "WebIDBDatabaseError.h" +#include <wtf/OwnPtr.h> + +#if ENABLE(INDEXED_DATABASE) + +namespace WebKit { + +WebIndexedDatabase* WebIndexedDatabase::create() +{ + return new WebIndexedDatabaseImpl(); +} + +WebIndexedDatabaseImpl::~WebIndexedDatabaseImpl() +{ +} + +void WebIndexedDatabaseImpl::open(const WebString& name, const WebString& description, bool modifyDatabase, WebIDBCallbacks<WebIDBDatabase>* callbacksPtr, WebFrame*, int& exceptionCode) +{ + OwnPtr<WebIDBCallbacks<WebIDBDatabase>*> callbacks(callbacksPtr); + callbacks->onError(WebIDBDatabaseError(0, "Not implemented")); + // FIXME: Implement for realz. +} + +} // namespace WebKit + +#endif // ENABLE(INDEXED_DATABASE) diff --git a/WebKit/chromium/src/WebIndexedDatabaseImpl.h b/WebKit/chromium/src/WebIndexedDatabaseImpl.h new file mode 100644 index 0000000..b4b8c99 --- /dev/null +++ b/WebKit/chromium/src/WebIndexedDatabaseImpl.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2010 Google 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. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE 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 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. + */ + +#ifndef WebIndexedDatabaseImpl_h +#define WebIndexedDatabaseImpl_h + +#include "WebIndexedDatabase.h" + +namespace WebKit { + +class WebIndexedDatabaseImpl : public WebIndexedDatabase { +public: + virtual ~WebIndexedDatabaseImpl(); + + virtual void open(const WebString& name, const WebString& description, bool modifyDatabase, WebIDBCallbacks<WebIDBDatabase>*, WebFrame*, int& exceptionCode); +}; + +} // namespace WebKit + +#endif // WebIndexedDatabaseImpl_h diff --git a/WebKit/chromium/src/WebInputElement.cpp b/WebKit/chromium/src/WebInputElement.cpp index 4ee1b93..1eab91f 100644 --- a/WebKit/chromium/src/WebInputElement.cpp +++ b/WebKit/chromium/src/WebInputElement.cpp @@ -40,22 +40,6 @@ using namespace WebCore; namespace WebKit { -WebInputElement::WebInputElement(const WTF::PassRefPtr<HTMLInputElement>& elem) - : WebElement(elem) -{ -} - -WebInputElement& WebInputElement::operator=(const WTF::PassRefPtr<HTMLInputElement>& elem) -{ - WebNode::assign(elem.releaseRef()); - return *this; -} - -WebInputElement::operator WTF::PassRefPtr<HTMLInputElement>() const -{ - return PassRefPtr<HTMLInputElement>(static_cast<HTMLInputElement*>(m_private)); -} - bool WebInputElement::autoComplete() const { return constUnwrap<HTMLInputElement>()->autoComplete(); @@ -71,9 +55,9 @@ WebInputElement::InputType WebInputElement::inputType() const return static_cast<InputType>(constUnwrap<HTMLInputElement>()->inputType()); } -WebString WebInputElement::formControlType() const +int WebInputElement::maxLength() const { - return constUnwrap<HTMLInputElement>()->formControlType(); + return constUnwrap<HTMLInputElement>()->maxLength(); } bool WebInputElement::isActivatedSubmit() const @@ -129,4 +113,20 @@ WebString WebInputElement::nameForAutofill() const return String(); } +WebInputElement::WebInputElement(const PassRefPtr<HTMLInputElement>& elem) + : WebFormControlElement(elem) +{ +} + +WebInputElement& WebInputElement::operator=(const PassRefPtr<HTMLInputElement>& elem) +{ + m_private = elem; + return *this; +} + +WebInputElement::operator PassRefPtr<HTMLInputElement>() const +{ + return static_cast<HTMLInputElement*>(m_private.get()); +} + } // namespace WebKit diff --git a/WebKit/chromium/src/WebInputEvent.cpp b/WebKit/chromium/src/WebInputEvent.cpp index b5c56fa..c00200e 100644 --- a/WebKit/chromium/src/WebInputEvent.cpp +++ b/WebKit/chromium/src/WebInputEvent.cpp @@ -86,6 +86,8 @@ static const char* staticKeyIdentifiers(unsigned short keyCode) case VKEY_F9: return "F9"; case VKEY_F10: + return "F10"; + case VKEY_F11: return "F11"; case VKEY_F12: return "F12"; diff --git a/WebKit/chromium/src/WebInputEventConversion.cpp b/WebKit/chromium/src/WebInputEventConversion.cpp index 147f88b..f68e3ab 100644 --- a/WebKit/chromium/src/WebInputEventConversion.cpp +++ b/WebKit/chromium/src/WebInputEventConversion.cpp @@ -40,6 +40,7 @@ #include "PlatformWheelEvent.h" #include "ScrollView.h" #include "WebInputEvent.h" +#include "WheelEvent.h" #include "Widget.h" using namespace WebCore; @@ -168,6 +169,64 @@ bool PlatformKeyboardEventBuilder::isCharacterKey() const return true; } +#if ENABLE(TOUCH_EVENTS) +static inline TouchEventType toPlatformTouchEventType(const WebInputEvent::Type type) +{ + switch (type) { + case WebInputEvent::TouchStart: + return TouchStart; + case WebInputEvent::TouchMove: + return TouchMove; + case WebInputEvent::TouchEnd: + return TouchEnd; + case WebInputEvent::TouchCancel: + return TouchCancel; + default: + ASSERT_NOT_REACHED(); + } + return TouchStart; +} + +static inline PlatformTouchPoint::State toPlatformTouchPointState(const WebTouchPoint::State state) +{ + switch (state) { + case WebTouchPoint::StateReleased: + return PlatformTouchPoint::TouchReleased; + case WebTouchPoint::StatePressed: + return PlatformTouchPoint::TouchPressed; + case WebTouchPoint::StateMoved: + return PlatformTouchPoint::TouchMoved; + case WebTouchPoint::StateStationary: + return PlatformTouchPoint::TouchStationary; + case WebTouchPoint::StateCancelled: + return PlatformTouchPoint::TouchCancelled; + case WebTouchPoint::StateUndefined: + ASSERT_NOT_REACHED(); + } + return PlatformTouchPoint::TouchReleased; +} + +PlatformTouchPointBuilder::PlatformTouchPointBuilder(Widget* widget, const WebTouchPoint& point) +{ + m_id = point.id; + m_state = toPlatformTouchPointState(point.state); + m_pos = widget->convertFromContainingWindow(point.position); + m_screenPos = point.screenPosition; +} + +PlatformTouchEventBuilder::PlatformTouchEventBuilder(Widget* widget, const WebTouchEvent& event) +{ + m_type = toPlatformTouchEventType(event.type); + m_ctrlKey = event.modifiers & WebInputEvent::ControlKey; + m_altKey = event.modifiers & WebInputEvent::AltKey; + m_shiftKey = event.modifiers & WebInputEvent::ShiftKey; + m_metaKey = event.modifiers & WebInputEvent::MetaKey; + + for (int i = 0; i < event.touchPointsLength; ++i) + m_touchPoints.append(PlatformTouchPointBuilder(widget, event.touchPoints[i])); +} +#endif + static int getWebInputModifiers(const UIEventWithKeyState& event) { int modifiers = 0; @@ -232,6 +291,28 @@ WebMouseEventBuilder::WebMouseEventBuilder(const ScrollView* view, const MouseEv clickCount = event.detail(); } +WebMouseWheelEventBuilder::WebMouseWheelEventBuilder(const ScrollView* view, const WheelEvent& event) +{ + if (event.type() != eventNames().mousewheelEvent) + return; + type = WebInputEvent::MouseWheel; + timeStampSeconds = event.timeStamp() * 1.0e-3; + modifiers = getWebInputModifiers(event); + IntPoint p = view->contentsToWindow(IntPoint(event.pageX(), event.pageY())); + globalX = event.screenX(); + globalY = event.screenY(); + windowX = p.x(); + windowY = p.y(); + x = event.offsetX(); + y = event.offsetY(); + deltaX = static_cast<float>(event.rawDeltaX()); + deltaY = static_cast<float>(event.rawDeltaY()); + // The 120 is from WheelEvent::initWheelEvent(). + wheelTicksX = static_cast<float>(event.wheelDeltaX()) / 120; + wheelTicksY = static_cast<float>(event.wheelDeltaY()) / 120; + scrollByPage = event.granularity() == WheelEvent::Page; +} + WebKeyboardEventBuilder::WebKeyboardEventBuilder(const KeyboardEvent& event) { if (event.type() == eventNames().keydownEvent) diff --git a/WebKit/chromium/src/WebInputEventConversion.h b/WebKit/chromium/src/WebInputEventConversion.h index 4c9cf82..3018973 100644 --- a/WebKit/chromium/src/WebInputEventConversion.h +++ b/WebKit/chromium/src/WebInputEventConversion.h @@ -37,12 +37,14 @@ #include "PlatformKeyboardEvent.h" #include "PlatformMouseEvent.h" +#include "PlatformTouchEvent.h" #include "PlatformWheelEvent.h" namespace WebCore { class KeyboardEvent; class MouseEvent; class ScrollView; +class WheelEvent; class Widget; } @@ -72,8 +74,20 @@ public: bool isCharacterKey() const; }; +#if ENABLE(TOUCH_EVENTS) +class PlatformTouchPointBuilder : public WebCore::PlatformTouchPoint { +public: + PlatformTouchPointBuilder(WebCore::Widget*, const WebTouchPoint&); +}; + +class PlatformTouchEventBuilder : public WebCore::PlatformTouchEvent { +public: + PlatformTouchEventBuilder(WebCore::Widget*, const WebTouchEvent&); +}; +#endif + // Converts a WebCore::MouseEvent to a corresponding WebMouseEvent. view is -// the ScrollView corresponding to the event. Returns true if successful. +// the ScrollView corresponding to the event. // NOTE: This is only implemented for mousemove, mouseover, mouseout, // mousedown and mouseup. If the event mapping fails, the event type will // be set to Undefined. @@ -82,10 +96,16 @@ public: WebMouseEventBuilder(const WebCore::ScrollView*, const WebCore::MouseEvent&); }; +// Converts a WebCore::WheelEvent to a corresponding WebMouseWheelEvent. +// If the event mapping fails, the event type will be set to Undefined. +class WebMouseWheelEventBuilder : public WebMouseWheelEvent { +public: + WebMouseWheelEventBuilder(const WebCore::ScrollView*, const WebCore::WheelEvent&); +}; + // Converts a WebCore::KeyboardEvent to a corresponding WebKeyboardEvent. -// Returns true if successful. NOTE: This is only implemented for keydown -// and keyup. If the event mapping fails, the event type will be set to -// Undefined. +// NOTE: This is only implemented for keydown and keyup. If the event mapping +// fails, the event type will be set to Undefined. class WebKeyboardEventBuilder : public WebKeyboardEvent { public: WebKeyboardEventBuilder(const WebCore::KeyboardEvent&); diff --git a/WebKit/chromium/src/WebLabelElement.cpp b/WebKit/chromium/src/WebLabelElement.cpp new file mode 100644 index 0000000..9546986 --- /dev/null +++ b/WebKit/chromium/src/WebLabelElement.cpp @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2010 Google 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: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER OR 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 "WebLabelElement.h" + +#include "HTMLLabelElement.h" +#include "HTMLNames.h" +#include "WebString.h" +#include <wtf/PassRefPtr.h> + +using namespace WebCore; + +namespace WebKit { + +WebElement WebLabelElement::correspondingControl() +{ + return WebElement(unwrap<HTMLLabelElement>()->correspondingControl()); +} + +WebLabelElement::WebLabelElement(const PassRefPtr<HTMLLabelElement>& elem) + : WebElement(elem) +{ +} + +WebLabelElement& WebLabelElement::operator=(const PassRefPtr<HTMLLabelElement>& elem) +{ + m_private = elem; + return *this; +} + +WebLabelElement::operator PassRefPtr<HTMLLabelElement>() const +{ + return static_cast<HTMLLabelElement*>(m_private.get()); +} + +} // namespace WebKit diff --git a/WebKit/chromium/src/WebMediaPlayerClientImpl.cpp b/WebKit/chromium/src/WebMediaPlayerClientImpl.cpp index b1f1f03..d7dbade 100644 --- a/WebKit/chromium/src/WebMediaPlayerClientImpl.cpp +++ b/WebKit/chromium/src/WebMediaPlayerClientImpl.cpp @@ -7,7 +7,6 @@ #if ENABLE(VIDEO) -#include "CString.h" #include "Frame.h" #include "GraphicsContext.h" #include "HTMLMediaElement.h" @@ -36,6 +35,7 @@ #endif #include <wtf/Assertions.h> +#include <wtf/text/CString.h> using namespace WebCore; diff --git a/WebKit/chromium/src/WebNode.cpp b/WebKit/chromium/src/WebNode.cpp index 9fbf573..e050c79 100644 --- a/WebKit/chromium/src/WebNode.cpp +++ b/WebKit/chromium/src/WebNode.cpp @@ -48,26 +48,23 @@ #include "markup.h" -#include <wtf/PassRefPtr.h> - using namespace WebCore; namespace WebKit { -class WebNodePrivate : public Node { -}; - void WebNode::reset() { - assign(0); + m_private.reset(); } void WebNode::assign(const WebNode& other) { - WebNodePrivate* p = const_cast<WebNodePrivate*>(other.m_private); - if (p) - p->ref(); - assign(p); + m_private = other.m_private; +} + +bool WebNode::equals(const WebNode& n) const +{ + return (m_private.get() == n.m_private.get()); } WebNode::NodeType WebNode::nodeType() const @@ -77,7 +74,7 @@ WebNode::NodeType WebNode::nodeType() const WebNode WebNode::parentNode() const { - return PassRefPtr<Node>(const_cast<Node*>(m_private->parentNode())); + return WebNode(const_cast<Node*>(m_private->parentNode())); } WebString WebNode::nodeName() const @@ -97,30 +94,6 @@ bool WebNode::setNodeValue(const WebString& value) return !exceptionCode; } -WebNode::WebNode(const PassRefPtr<Node>& node) - : m_private(static_cast<WebNodePrivate*>(node.releaseRef())) -{ -} - -WebNode& WebNode::operator=(const PassRefPtr<Node>& node) -{ - assign(static_cast<WebNodePrivate*>(node.releaseRef())); - return *this; -} - -WebNode::operator PassRefPtr<Node>() const -{ - return PassRefPtr<Node>(const_cast<WebNodePrivate*>(m_private)); -} - -void WebNode::assign(WebNodePrivate* p) -{ - // p is already ref'd for us by the caller - if (m_private) - m_private->deref(); - m_private = p; -} - WebFrame* WebNode::frame() const { return WebFrameImpl::fromFrame(m_private->document()->frame()); @@ -163,7 +136,7 @@ WebNodeList WebNode::childNodes() WebString WebNode::createMarkup() const { - return WebCore::createMarkup(m_private); + return WebCore::createMarkup(m_private.get()); } bool WebNode::isTextNode() const @@ -179,7 +152,7 @@ bool WebNode::isElementNode() const void WebNode::addEventListener(const WebString& eventType, WebEventListener* listener, bool useCapture) { EventListenerWrapper* listenerWrapper = - listener->createEventListenerWrapper(eventType, useCapture, m_private); + listener->createEventListenerWrapper(eventType, useCapture, m_private.get()); // The listenerWrapper is only referenced by the actual Node. Once it goes // away, the wrapper notifies the WebEventListener so it can clear its // pointer to it. @@ -189,9 +162,36 @@ void WebNode::addEventListener(const WebString& eventType, WebEventListener* lis void WebNode::removeEventListener(const WebString& eventType, WebEventListener* listener, bool useCapture) { EventListenerWrapper* listenerWrapper = - listener->getEventListenerWrapper(eventType, useCapture, m_private); + listener->getEventListenerWrapper(eventType, useCapture, m_private.get()); m_private->removeEventListener(eventType, listenerWrapper, useCapture); // listenerWrapper is now deleted. } +void WebNode::simulateClick() +{ + RefPtr<Event> noEvent; + m_private->dispatchSimulatedClick(noEvent); +} + +WebNodeList WebNode::getElementsByTagName(const WebString& tag) const +{ + return WebNodeList(m_private->getElementsByTagName(tag)); +} + +WebNode::WebNode(const PassRefPtr<Node>& node) + : m_private(node) +{ +} + +WebNode& WebNode::operator=(const PassRefPtr<Node>& node) +{ + m_private = node; + return *this; +} + +WebNode::operator PassRefPtr<Node>() const +{ + return m_private.get(); +} + } // namespace WebKit diff --git a/WebKit/chromium/src/WebNotification.cpp b/WebKit/chromium/src/WebNotification.cpp index 1f6916e..5200d17 100644 --- a/WebKit/chromium/src/WebNotification.cpp +++ b/WebKit/chromium/src/WebNotification.cpp @@ -76,10 +76,10 @@ WebURL WebNotification::url() const return m_private->url(); } -WebString WebNotification::icon() const +WebURL WebNotification::iconURL() const { ASSERT(!isHTML()); - return m_private->contents().icon(); + return m_private->iconURL(); } WebString WebNotification::title() const diff --git a/WebKit/chromium/src/WebPageSerializer.cpp b/WebKit/chromium/src/WebPageSerializer.cpp index 1010285..4f93702 100644 --- a/WebKit/chromium/src/WebPageSerializer.cpp +++ b/WebKit/chromium/src/WebPageSerializer.cpp @@ -59,7 +59,7 @@ bool WebPageSerializer::serialize(WebFrame* frame, WebString WebPageSerializer::generateMetaCharsetDeclaration(const WebString& charset) { - return String::format("<META http-equiv=\"Content-Type\" content=\"text/html; charset=%s\">", + return String::format("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=%s\">", charset.utf8().data()); } @@ -75,7 +75,7 @@ WebString WebPageSerializer::generateBaseTagDeclaration(const WebString& baseTar String targetDeclaration; if (!baseTarget.isEmpty()) targetDeclaration = String::format(" target=\"%s\"", baseTarget.utf8().data()); - return String::format("<BASE href=\".\"%s>", targetDeclaration.utf8().data()); + return String::format("<base href=\".\"%s>", targetDeclaration.utf8().data()); } } // namespace WebKit diff --git a/WebKit/chromium/src/WebPageSerializerImpl.cpp b/WebKit/chromium/src/WebPageSerializerImpl.cpp index d5b2b7f..008e0c7 100644 --- a/WebKit/chromium/src/WebPageSerializerImpl.cpp +++ b/WebKit/chromium/src/WebPageSerializerImpl.cpp @@ -170,7 +170,7 @@ String WebPageSerializerImpl::preActionBeforeSerializeOpenTag( // Get encoding info. String xmlEncoding = param->doc->xmlEncoding(); if (xmlEncoding.isEmpty()) - xmlEncoding = param->doc->frame()->loader()->encoding(); + xmlEncoding = param->doc->frame()->loader()->writer()->encoding(); if (xmlEncoding.isEmpty()) xmlEncoding = UTF8Encoding().name(); result.append("<?xml version=\""); @@ -306,7 +306,7 @@ void WebPageSerializerImpl::openTagToString(const Element* element, if (needSkip) return; // Add open tag - result += "<" + element->nodeName(); + result += "<" + element->nodeName().lower(); // Go through all attributes and serialize them. const NamedNodeMap *attrMap = element->attributes(true); if (attrMap) { @@ -374,7 +374,7 @@ void WebPageSerializerImpl::endTagToString(const Element* element, // Write end tag when element has child/children. if (element->hasChildNodes() || param->hasAddedContentsBeforeEnd) { result += "</"; - result += element->nodeName(); + result += element->nodeName().lower(); result += ">"; } else { // Check whether we have to write end tag for empty element. @@ -385,7 +385,7 @@ void WebPageSerializerImpl::endTagToString(const Element* element, if (htmlElement->endTagRequirement() == TagStatusRequired) { // We need to write end tag when it is required. result += "</"; - result += element->nodeName(); + result += element->nodeName().lower(); result += ">"; } } else { @@ -514,7 +514,7 @@ bool WebPageSerializerImpl::serialize() // A new document, we will serialize it. didSerialization = true; // Get target encoding for current document. - String encoding = currentFrame->frame()->loader()->encoding(); + String encoding = currentFrame->frame()->loader()->writer()->encoding(); // Create the text encoding object with target encoding. TextEncoding textEncoding(encoding); // Construct serialize parameter for late processing document. diff --git a/WebKit/chromium/src/WebPluginContainerImpl.cpp b/WebKit/chromium/src/WebPluginContainerImpl.cpp index 86cac26..2cdf255 100644 --- a/WebKit/chromium/src/WebPluginContainerImpl.cpp +++ b/WebKit/chromium/src/WebPluginContainerImpl.cpp @@ -60,6 +60,7 @@ #include "MouseEvent.h" #include "Page.h" #include "ScrollView.h" +#include "WheelEvent.h" #if WEBKIT_USING_SKIA #include "PlatformContextSkia.h" @@ -124,7 +125,7 @@ void WebPluginContainerImpl::invalidateRect(const IntRect& rect) IntRect clipRect = parent()->windowClipRect(); damageRect.intersect(clipRect); - parent()->hostWindow()->repaint(damageRect, true); + parent()->hostWindow()->invalidateContentsAndWindow(damageRect, false /*immediate*/); } void WebPluginContainerImpl::setFocus() @@ -160,6 +161,8 @@ void WebPluginContainerImpl::handleEvent(Event* event) // where mozilla behaves differently than the spec. if (event->isMouseEvent()) handleMouseEvent(static_cast<MouseEvent*>(event)); + else if (event->isWheelEvent()) + handleWheelEvent(static_cast<WheelEvent*>(event)); else if (event->isKeyboardEvent()) handleKeyboardEvent(static_cast<KeyboardEvent*>(event)); } @@ -170,6 +173,12 @@ void WebPluginContainerImpl::frameRectsChanged() reportGeometry(); } +void WebPluginContainerImpl::widgetPositionsUpdated() +{ + Widget::widgetPositionsUpdated(); + reportGeometry(); +} + void WebPluginContainerImpl::setParentVisible(bool parentVisible) { // We override this function to make sure that geometry updates are sent @@ -200,6 +209,36 @@ void WebPluginContainerImpl::setParent(ScrollView* view) reportGeometry(); } +bool WebPluginContainerImpl::supportsPaginatedPrint() const +{ + return m_webPlugin->supportsPaginatedPrint(); +} + +int WebPluginContainerImpl::printBegin(const IntRect& printableArea, + int printerDPI) const +{ + return m_webPlugin->printBegin(printableArea, printerDPI); +} + +bool WebPluginContainerImpl::printPage(int pageNumber, + WebCore::GraphicsContext* gc) +{ + gc->save(); +#if WEBKIT_USING_SKIA + WebCanvas* canvas = gc->platformContext()->canvas(); +#elif WEBKIT_USING_CG + WebCanvas* canvas = gc->platformContext(); +#endif + bool ret = m_webPlugin->printPage(pageNumber, canvas); + gc->restore(); + return ret; +} + +void WebPluginContainerImpl::printEnd() +{ + return m_webPlugin->printEnd(); +} + void WebPluginContainerImpl::invalidate() { Widget::invalidate(); @@ -353,22 +392,7 @@ void WebPluginContainerImpl::handleMouseEvent(MouseEvent* event) } WebCursorInfo cursorInfo; - bool handled = m_webPlugin->handleInputEvent(webEvent, cursorInfo); -#if !OS(DARWIN) - // TODO(pkasting): http://b/1119691 This conditional seems exactly - // backwards, but if I reverse it, giving focus to a transparent - // (windowless) plugin fails. - handled = !handled; - // TODO(awalker): oddly, the above is not true in Mac builds. Looking - // at Apple's corresponding code for Mac and Windows (PluginViewMac and - // PluginViewWin), setDefaultHandled() gets called when handleInputEvent() - // returns true, which then indicates to WebCore that the plugin wants to - // swallow the event--which is what we want. Calling setDefaultHandled() - // fixes several Mac Chromium bugs, but does indeed prevent windowless plugins - // from getting focus in Windows builds, as pkasting notes above. So for - // now, we only do so in Mac builds. -#endif - if (handled) + if (m_webPlugin->handleInputEvent(webEvent, cursorInfo)) event->setDefaultHandled(); // A windowless plugin can change the cursor in response to a mouse move @@ -382,19 +406,26 @@ void WebPluginContainerImpl::handleMouseEvent(MouseEvent* event) chromeClient->setCursorForPlugin(cursorInfo); } +void WebPluginContainerImpl::handleWheelEvent(WheelEvent* event) +{ + FrameView* parentView = static_cast<FrameView*>(parent()); + WebMouseWheelEventBuilder webEvent(parentView, *event); + if (webEvent.type == WebInputEvent::Undefined) + return; + + WebCursorInfo cursorInfo; + if (m_webPlugin->handleInputEvent(webEvent, cursorInfo)) + event->setDefaultHandled(); +} + void WebPluginContainerImpl::handleKeyboardEvent(KeyboardEvent* event) { WebKeyboardEventBuilder webEvent(*event); if (webEvent.type == WebInputEvent::Undefined) return; - WebCursorInfo cursor_info; - bool handled = m_webPlugin->handleInputEvent(webEvent, cursor_info); -#if !OS(DARWIN) - // TODO(pkasting): http://b/1119691 See above. - handled = !handled; -#endif - if (handled) + WebCursorInfo cursorInfo; + if (m_webPlugin->handleInputEvent(webEvent, cursorInfo)) event->setDefaultHandled(); } diff --git a/WebKit/chromium/src/WebPluginContainerImpl.h b/WebKit/chromium/src/WebPluginContainerImpl.h index 00450bb..3160394 100644 --- a/WebKit/chromium/src/WebPluginContainerImpl.h +++ b/WebKit/chromium/src/WebPluginContainerImpl.h @@ -48,6 +48,7 @@ class KeyboardEvent; class MouseEvent; class ResourceError; class ResourceResponse; +class WheelEvent; } namespace WebKit { @@ -73,6 +74,7 @@ public: virtual void frameRectsChanged(); virtual void setParentVisible(bool); virtual void setParent(WebCore::ScrollView*); + virtual void widgetPositionsUpdated(); // WebPluginContainer methods virtual void invalidate(); @@ -83,6 +85,20 @@ public: virtual WebString executeScriptURL(const WebURL&, bool popupsAllowed); virtual void loadFrameRequest(const WebURLRequest&, const WebString& target, bool notifyNeeded, void* notifyData); + // Printing interface. The plugin can support custom printing + // (which means it controls the layout, number of pages etc). + // Whether the plugin supports its own paginated print. The other print + // interface methods are called only if this method returns true. + bool supportsPaginatedPrint() const; + // Sets up printing at the given print rect and printer DPI. printableArea + // is in points (a point is 1/72 of an inch).Returns the number of pages to + // be printed at these settings. + int printBegin(const WebCore::IntRect& printableArea, int printerDPI) const; + // Prints the page specified by pageNumber (0-based index) into the supplied canvas. + bool printPage(int pageNumber, WebCore::GraphicsContext* gc); + // Ends the print operation. + void printEnd(); + // Resource load events for the plugin's source data: void didReceiveResponse(const WebCore::ResourceResponse&); void didReceiveData(const char *data, int dataLength); @@ -103,6 +119,7 @@ private: ~WebPluginContainerImpl(); void handleMouseEvent(WebCore::MouseEvent*); + void handleWheelEvent(WebCore::WheelEvent*); void handleKeyboardEvent(WebCore::KeyboardEvent*); void calculateGeometry(const WebCore::IntRect& frameRect, diff --git a/WebKit/chromium/src/WebPluginDocument.cpp b/WebKit/chromium/src/WebPluginDocument.cpp new file mode 100644 index 0000000..8f794ad --- /dev/null +++ b/WebKit/chromium/src/WebPluginDocument.cpp @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2010 Google 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: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER OR 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 "WebPluginDocument.h" + +#include "Document.h" +#include "PluginDocument.h" + +#include "WebPluginContainerImpl.h" + +#include <wtf/PassRefPtr.h> + +using namespace WebCore; + +namespace WebKit { + + +WebPlugin* WebPluginDocument::plugin() +{ + if (!isPluginDocument()) + return 0; + PluginDocument* doc = unwrap<PluginDocument>(); + WebPluginContainerImpl* container = static_cast<WebPluginContainerImpl*>(static_cast<PluginDocument*>(doc)->pluginWidget()); + return container->plugin(); +} + + +WebPluginDocument::WebPluginDocument(const PassRefPtr<PluginDocument>& elem) + : WebDocument(elem) +{ +} + +WebPluginDocument& WebPluginDocument::operator=(const PassRefPtr<PluginDocument>& elem) +{ + m_private = elem; + return *this; +} + +WebPluginDocument::operator PassRefPtr<PluginDocument>() const +{ + return static_cast<PluginDocument*>(m_private.get()); +} + +} // namespace WebKit diff --git a/WebKit/chromium/src/WebPopupMenuImpl.cpp b/WebKit/chromium/src/WebPopupMenuImpl.cpp index f6d360e..f9da394 100644 --- a/WebKit/chromium/src/WebPopupMenuImpl.cpp +++ b/WebKit/chromium/src/WebPopupMenuImpl.cpp @@ -250,18 +250,29 @@ void WebPopupMenuImpl::setTextDirection(WebTextDirection direction) //----------------------------------------------------------------------------- // WebCore::HostWindow -void WebPopupMenuImpl::repaint(const IntRect& paintRect, - bool contentChanged, - bool immediate, - bool repaintContentOnly) +void WebPopupMenuImpl::invalidateContents(const IntRect&, bool) { - // Ignore spurious calls. - if (!contentChanged || paintRect.isEmpty()) + notImplemented(); +} + +void WebPopupMenuImpl::invalidateWindow(const IntRect&, bool) +{ + notImplemented(); +} + +void WebPopupMenuImpl::invalidateContentsAndWindow(const IntRect& paintRect, bool /*immediate*/) +{ + if (paintRect.isEmpty()) return; if (m_client) m_client->didInvalidateRect(paintRect); } +void WebPopupMenuImpl::invalidateContentsForSlowScroll(const IntRect& updateRect, bool immediate) +{ + invalidateContentsAndWindow(updateRect, immediate); +} + void WebPopupMenuImpl::scroll(const IntSize& scrollDelta, const IntRect& scrollRect, const IntRect& clipRect) diff --git a/WebKit/chromium/src/WebPopupMenuImpl.h b/WebKit/chromium/src/WebPopupMenuImpl.h index 13eb674..7390394 100644 --- a/WebKit/chromium/src/WebPopupMenuImpl.h +++ b/WebKit/chromium/src/WebPopupMenuImpl.h @@ -98,9 +98,10 @@ public: ~WebPopupMenuImpl(); // WebCore::HostWindow methods: - virtual void repaint( - const WebCore::IntRect&, bool contentChanged, bool immediate = false, - bool repaintContentOnly = false); + virtual void invalidateContents(const WebCore::IntRect&, bool); + virtual void invalidateWindow(const WebCore::IntRect&, bool); + virtual void invalidateContentsAndWindow(const WebCore::IntRect&, bool); + virtual void invalidateContentsForSlowScroll(const WebCore::IntRect&, bool); virtual void scroll( const WebCore::IntSize& scrollDelta, const WebCore::IntRect& scrollRect, const WebCore::IntRect& clipRect); diff --git a/WebKit/chromium/src/WebRuntimeFeatures.cpp b/WebKit/chromium/src/WebRuntimeFeatures.cpp index ad84764..464834d 100644 --- a/WebKit/chromium/src/WebRuntimeFeatures.cpp +++ b/WebKit/chromium/src/WebRuntimeFeatures.cpp @@ -184,4 +184,30 @@ bool WebRuntimeFeatures::isIndexedDatabaseEnabled() #endif } +void WebRuntimeFeatures::enableWebGL(bool enable) +{ +#if ENABLE(3D_CANVAS) + RuntimeEnabledFeatures::setWebGLEnabled(enable); +#endif +} + +bool WebRuntimeFeatures::isWebGLEnabled() +{ +#if ENABLE(3D_CANVAS) + return RuntimeEnabledFeatures::webGLRenderingContextEnabled(); +#else + return false; +#endif +} + +void WebRuntimeFeatures::enablePushState(bool enable) +{ + RuntimeEnabledFeatures::setPushStateEnabled(enable); +} + +bool WebRuntimeFeatures::isPushStateEnabled(bool enable) +{ + return RuntimeEnabledFeatures::pushStateEnabled(); +} + } // namespace WebKit diff --git a/WebKit/chromium/src/WebSearchableFormData.cpp b/WebKit/chromium/src/WebSearchableFormData.cpp index eddaffe..8eef6cc 100644 --- a/WebKit/chromium/src/WebSearchableFormData.cpp +++ b/WebKit/chromium/src/WebSearchableFormData.cpp @@ -62,7 +62,7 @@ void GetFormEncoding(const HTMLFormElement* form, TextEncoding* encoding) return; } const Frame* frame = form->document()->frame(); - *encoding = frame ? TextEncoding(frame->loader()->encoding()) : Latin1Encoding(); + *encoding = frame ? TextEncoding(frame->loader()->writer()->encoding()) : Latin1Encoding(); } // Returns true if the submit request results in an HTTP URL. diff --git a/WebKit/chromium/src/WebSecurityOrigin.cpp b/WebKit/chromium/src/WebSecurityOrigin.cpp index 81546da..bc36be7 100644 --- a/WebKit/chromium/src/WebSecurityOrigin.cpp +++ b/WebKit/chromium/src/WebSecurityOrigin.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009 Google Inc. All rights reserved. + * Copyright (C) 2010 Google Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -31,8 +31,10 @@ #include "config.h" #include "WebSecurityOrigin.h" +#include "KURL.h" #include "SecurityOrigin.h" #include "WebString.h" +#include "WebURL.h" #include <wtf/PassRefPtr.h> using namespace WebCore; @@ -42,9 +44,9 @@ namespace WebKit { class WebSecurityOriginPrivate : public SecurityOrigin { }; -WebSecurityOrigin* WebSecurityOrigin::createFromDatabaseIdentifier(const WebString& databaseIdentifier) +WebSecurityOrigin WebSecurityOrigin::createFromDatabaseIdentifier(const WebString& databaseIdentifier) { - return new WebSecurityOrigin(SecurityOrigin::createFromDatabaseIdentifier(databaseIdentifier)); + return WebSecurityOrigin(SecurityOrigin::createFromDatabaseIdentifier(databaseIdentifier)); } WebSecurityOrigin WebSecurityOrigin::createFromString(const WebString& origin) @@ -52,6 +54,11 @@ WebSecurityOrigin WebSecurityOrigin::createFromString(const WebString& origin) return WebSecurityOrigin(SecurityOrigin::createFromString(origin)); } +WebSecurityOrigin WebSecurityOrigin::create(const WebURL& url) +{ + return WebSecurityOrigin(SecurityOrigin::create(url)); +} + void WebSecurityOrigin::reset() { assign(0); @@ -89,6 +96,19 @@ bool WebSecurityOrigin::isEmpty() const return m_private->isEmpty(); } +bool WebSecurityOrigin::canAccess(const WebSecurityOrigin& other) const +{ + ASSERT(m_private); + ASSERT(other.m_private); + return m_private->canAccess(other.m_private); +} + +bool WebSecurityOrigin::canRequest(const WebURL& url) const +{ + ASSERT(m_private); + return m_private->canRequest(url); +} + WebString WebSecurityOrigin::toString() const { ASSERT(m_private); diff --git a/WebKit/chromium/src/WebSecurityPolicy.cpp b/WebKit/chromium/src/WebSecurityPolicy.cpp index 48b445c..24ef7d1 100644 --- a/WebKit/chromium/src/WebSecurityPolicy.cpp +++ b/WebKit/chromium/src/WebSecurityPolicy.cpp @@ -51,19 +51,24 @@ void WebSecurityPolicy::registerURLSchemeAsNoAccess(const WebString& scheme) SecurityOrigin::registerURLSchemeAsNoAccess(scheme); } +void WebSecurityPolicy::registerURLSchemeAsSecure(const WebString& scheme) +{ + SecurityOrigin::registerURLSchemeAsSecure(scheme); +} + void WebSecurityPolicy::whiteListAccessFromOrigin(const WebURL& sourceOrigin, const WebString& destinationProtocol, const WebString& destinationHost, bool allowDestinationSubdomains) { - SecurityOrigin::whiteListAccessFromOrigin( + SecurityOrigin::addOriginAccessWhitelistEntry( *SecurityOrigin::create(sourceOrigin), destinationProtocol, destinationHost, allowDestinationSubdomains); } void WebSecurityPolicy::resetOriginAccessWhiteLists() { - SecurityOrigin::resetOriginAccessWhiteLists(); + SecurityOrigin::resetOriginAccessWhitelists(); } bool WebSecurityPolicy::shouldHideReferrer(const WebURL& url, const WebString& referrer) diff --git a/WebKit/chromium/src/WebSelectElement.cpp b/WebKit/chromium/src/WebSelectElement.cpp new file mode 100644 index 0000000..6516cc3 --- /dev/null +++ b/WebKit/chromium/src/WebSelectElement.cpp @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2010 Google 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: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER OR 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 "WebSelectElement.h" + +#include "HTMLSelectElement.h" +#include "WebString.h" +#include <wtf/PassRefPtr.h> + +using namespace WebCore; + +namespace WebKit { + +void WebSelectElement::setValue(const WebString& value) +{ + unwrap<HTMLSelectElement>()->setValue(value); +} + +WebString WebSelectElement::value() +{ + return unwrap<HTMLSelectElement>()->value(); +} + +WebSelectElement::WebSelectElement(const PassRefPtr<HTMLSelectElement>& elem) + : WebFormControlElement(elem) +{ +} + +WebSelectElement& WebSelectElement::operator=(const PassRefPtr<HTMLSelectElement>& elem) +{ + m_private = elem; + return *this; +} + +WebSelectElement::operator PassRefPtr<HTMLSelectElement>() const +{ + return static_cast<HTMLSelectElement*>(m_private.get()); +} + +} // namespace WebKit diff --git a/WebKit/chromium/src/WebSerializedScriptValue.cpp b/WebKit/chromium/src/WebSerializedScriptValue.cpp new file mode 100644 index 0000000..ce8517a --- /dev/null +++ b/WebKit/chromium/src/WebSerializedScriptValue.cpp @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2010 Google 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: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER OR 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 "WebSerializedScriptValue.h" + +#include "SerializedScriptValue.h" +#include "WebString.h" + +using namespace WebCore; + +namespace WebKit { + +WebSerializedScriptValue WebSerializedScriptValue::fromString(const WebString& s) +{ + return SerializedScriptValue::createFromWire(s); +} + +void WebSerializedScriptValue::reset() +{ + m_private.reset(); +} + +void WebSerializedScriptValue::assign(const WebSerializedScriptValue& other) +{ + m_private = other.m_private; +} + +WebString WebSerializedScriptValue::toString() const +{ + return m_private->toWireString(); +} + +WebSerializedScriptValue::WebSerializedScriptValue(const PassRefPtr<SerializedScriptValue>& value) + : m_private(value) +{ +} + +WebSerializedScriptValue& WebSerializedScriptValue::operator=(const PassRefPtr<SerializedScriptValue>& value) +{ + m_private = value; + return *this; +} + +WebSerializedScriptValue::operator PassRefPtr<SerializedScriptValue>() const +{ + return m_private.get(); +} + +} // namespace WebKit diff --git a/WebKit/chromium/src/WebSettingsImpl.cpp b/WebKit/chromium/src/WebSettingsImpl.cpp index a680321..9e0fa91 100644 --- a/WebKit/chromium/src/WebSettingsImpl.cpp +++ b/WebKit/chromium/src/WebSettingsImpl.cpp @@ -185,6 +185,11 @@ void WebSettingsImpl::setUserStyleSheetLocation(const WebURL& location) m_settings->setUserStyleSheetLocation(location); } +void WebSettingsImpl::setAuthorAndUserStylesEnabled(bool enabled) +{ + m_settings->setAuthorAndUserStylesEnabled(enabled); +} + void WebSettingsImpl::setUsesPageCache(bool usesPageCache) { m_settings->setUsesPageCache(usesPageCache); @@ -226,11 +231,6 @@ void WebSettingsImpl::setShouldPaintCustomScrollbars(bool enabled) m_settings->setShouldPaintCustomScrollbars(enabled); } -void WebSettingsImpl::setDatabasesEnabled(bool enabled) -{ - m_settings->setDatabasesEnabled(enabled); -} - void WebSettingsImpl::setAllowUniversalAccessFromFileURLs(bool allow) { m_settings->setAllowUniversalAccessFromFileURLs(allow); @@ -264,9 +264,4 @@ void WebSettingsImpl::setShowDebugBorders(bool show) m_settings->setShowDebugBorders(show); } -void WebSettingsImpl::setGeolocationEnabled(bool enabled) -{ - m_settings->setGeolocationEnabled(enabled); -} - } // namespace WebKit diff --git a/WebKit/chromium/src/WebSettingsImpl.h b/WebKit/chromium/src/WebSettingsImpl.h index 64ccab5..7a809c7 100644 --- a/WebKit/chromium/src/WebSettingsImpl.h +++ b/WebKit/chromium/src/WebSettingsImpl.h @@ -71,6 +71,7 @@ public: virtual void setJavaEnabled(bool); virtual void setAllowScriptsToCloseWindows(bool); virtual void setUserStyleSheetLocation(const WebURL&); + virtual void setAuthorAndUserStylesEnabled(bool); virtual void setUsesPageCache(bool); virtual void setDownloadableBinaryFontsEnabled(bool); virtual void setXSSAuditorEnabled(bool); @@ -78,13 +79,11 @@ public: virtual void setEditableLinkBehaviorNeverLive(); virtual void setFontRenderingModeNormal(); virtual void setShouldPaintCustomScrollbars(bool); - virtual void setDatabasesEnabled(bool); virtual void setAllowUniversalAccessFromFileURLs(bool); virtual void setAllowFileAccessFromFileURLs(bool); virtual void setTextDirectionSubmenuInclusionBehaviorNeverIncluded(); virtual void setOfflineWebApplicationCacheEnabled(bool); virtual void setExperimentalWebGLEnabled(bool); - virtual void setGeolocationEnabled(bool); virtual void setShowDebugBorders(bool); private: diff --git a/WebKit/chromium/src/WebStorageAreaImpl.cpp b/WebKit/chromium/src/WebStorageAreaImpl.cpp index 9a7fd5c..2cecfe9 100644 --- a/WebKit/chromium/src/WebStorageAreaImpl.cpp +++ b/WebKit/chromium/src/WebStorageAreaImpl.cpp @@ -66,7 +66,7 @@ WebString WebStorageAreaImpl::getItem(const WebString& key) return m_storageArea->getItem(key); } -void WebStorageAreaImpl::setItem(const WebString& key, const WebString& value, const WebURL& url, Result& result, WebString& oldValue) +void WebStorageAreaImpl::setItem(const WebString& key, const WebString& value, const WebURL& url, Result& result, WebString& oldValue, WebFrame*) { int exceptionCode = 0; diff --git a/WebKit/chromium/src/WebStorageAreaImpl.h b/WebKit/chromium/src/WebStorageAreaImpl.h index e9a11c2..2869fc9 100644 --- a/WebKit/chromium/src/WebStorageAreaImpl.h +++ b/WebKit/chromium/src/WebStorageAreaImpl.h @@ -45,7 +45,7 @@ public: virtual unsigned length(); virtual WebString key(unsigned index); virtual WebString getItem(const WebString& key); - virtual void setItem(const WebString& key, const WebString& value, const WebURL& url, Result& result, WebString& oldValue); + virtual void setItem(const WebString& key, const WebString& value, const WebURL& url, Result& result, WebString& oldValue, WebFrame*); virtual void removeItem(const WebString& key, const WebURL& url, WebString& oldValue); virtual void clear(const WebURL& url, bool& somethingCleared); diff --git a/WebKit/chromium/src/WebStorageNamespaceImpl.cpp b/WebKit/chromium/src/WebStorageNamespaceImpl.cpp index e6f6548..66be027 100644 --- a/WebKit/chromium/src/WebStorageNamespaceImpl.cpp +++ b/WebKit/chromium/src/WebStorageNamespaceImpl.cpp @@ -47,7 +47,7 @@ WebStorageNamespace* WebStorageNamespace::createLocalStorageNamespace(const WebS WebStorageNamespace* WebStorageNamespace::createSessionStorageNamespace() { - return new WebStorageNamespaceImpl(WebCore::StorageNamespaceImpl::sessionStorageNamespace()); + return new WebStorageNamespaceImpl(WebCore::StorageNamespaceImpl::sessionStorageNamespace(noQuota)); } WebStorageNamespaceImpl::WebStorageNamespaceImpl(PassRefPtr<WebCore::StorageNamespace> storageNamespace) diff --git a/WebKit/chromium/src/WebString.cpp b/WebKit/chromium/src/WebString.cpp index 36d5f86..a61a059 100644 --- a/WebKit/chromium/src/WebString.cpp +++ b/WebKit/chromium/src/WebString.cpp @@ -32,8 +32,8 @@ #include "WebString.h" #include "AtomicString.h" -#include "CString.h" #include "PlatformString.h" +#include <wtf/text/CString.h> #include "WebCString.h" diff --git a/WebKit/chromium/src/WebURLError.cpp b/WebKit/chromium/src/WebURLError.cpp index a038aee..ef32b5c 100644 --- a/WebKit/chromium/src/WebURLError.cpp +++ b/WebKit/chromium/src/WebURLError.cpp @@ -31,9 +31,9 @@ #include "config.h" #include "WebURLError.h" -#include "CString.h" #include "KURL.h" #include "ResourceError.h" +#include <wtf/text/CString.h> using namespace WebCore; diff --git a/WebKit/chromium/src/WebURLResponse.cpp b/WebKit/chromium/src/WebURLResponse.cpp index 95e0be2..3b0600c 100644 --- a/WebKit/chromium/src/WebURLResponse.cpp +++ b/WebKit/chromium/src/WebURLResponse.cpp @@ -165,6 +165,8 @@ void WebURLResponse::setHTTPHeaderField(const WebString& name, const WebString& void WebURLResponse::addHTTPHeaderField(const WebString& name, const WebString& value) { + if (name.isNull() || value.isNull()) + return; // FIXME: Add an addHTTPHeaderField method to ResourceResponse. const HTTPHeaderMap& map = m_private->m_resourceResponse->httpHeaderFields(); String valueStr(value); @@ -265,6 +267,16 @@ void WebURLResponse::setWasFetchedViaSPDY(bool value) m_private->m_resourceResponse->setWasFetchedViaSPDY(value); } +bool WebURLResponse::isMultipartPayload() const +{ + return m_private->m_resourceResponse->isMultipartPayload(); +} + +void WebURLResponse::setIsMultipartPayload(bool value) +{ + m_private->m_resourceResponse->setIsMultipartPayload(value); +} + void WebURLResponse::assign(WebURLResponsePrivate* p) { // Subclasses may call this directly so a self-assignment check is needed diff --git a/WebKit/chromium/src/WebViewImpl.cpp b/WebKit/chromium/src/WebViewImpl.cpp index 97665d4..671a8c9 100644 --- a/WebKit/chromium/src/WebViewImpl.cpp +++ b/WebKit/chromium/src/WebViewImpl.cpp @@ -87,6 +87,7 @@ #include "WebDevToolsAgentPrivate.h" #include "WebDragData.h" #include "WebFrameImpl.h" +#include "WebImage.h" #include "WebInputEvent.h" #include "WebInputEventConversion.h" #include "WebMediaPlayerAction.h" @@ -100,13 +101,11 @@ #include "WebViewClient.h" #if OS(WINDOWS) -#include "KeyboardCodesWin.h" #include "RenderThemeChromiumWin.h" #else #if OS(LINUX) #include "RenderThemeChromiumLinux.h" #endif -#include "KeyboardCodesPosix.h" #include "RenderTheme.h" #endif @@ -149,11 +148,7 @@ COMPILE_ASSERT_MATCHING_ENUM(DragOperationMove); COMPILE_ASSERT_MATCHING_ENUM(DragOperationDelete); COMPILE_ASSERT_MATCHING_ENUM(DragOperationEvery); -// Note that focusOnShow is false so that the suggestions popup is shown not -// activated. We need the page to still have focus so the user can keep typing -// while the popup is showing. static const PopupContainerSettings suggestionsPopupSettings = { - false, // focusOnShow false, // setTextOnIndexChange false, // acceptOnAbandon true, // loopSelectionNavigation @@ -245,6 +240,11 @@ WebViewImpl::WebViewImpl(WebViewClient* client) , m_suggestionsPopup(0) , m_isTransparent(false) , m_tabsToLinks(false) + , m_haveMouseCapture(false) +#if USE(ACCELERATED_COMPOSITING) + , m_layerRenderer(0) + , m_isAcceleratedCompositing(false) +#endif { // WebKit/win/WebView.cpp does the same thing, except they call the // KJS specific wrapper around this method. We need to have threading @@ -326,7 +326,12 @@ void WebViewImpl::mouseDown(const WebMouseEvent& event) if (!mainFrameImpl() || !mainFrameImpl()->frameView()) return; + // If there is a select popup opened, close it as the user is clicking on + // the page (outside of the popup). + hideSelectPopup(); + m_lastMouseDownPoint = WebPoint(event.x, event.y); + m_haveMouseCapture = true; // If a text field that has focus is clicked again, we should display the // suggestions popup. @@ -347,6 +352,8 @@ void WebViewImpl::mouseDown(const WebMouseEvent& event) } } + mainFrameImpl()->frame()->loader()->resetMultipleFormSubmissionProtection(); + mainFrameImpl()->frame()->eventHandler()->handleMousePressEvent( PlatformMouseEventBuilder(mainFrameImpl()->frameView(), event)); @@ -439,7 +446,6 @@ void WebViewImpl::mouseUp(const WebMouseEvent& event) } #endif - mouseCaptureLost(); mainFrameImpl()->frame()->eventHandler()->handleMouseReleaseEvent( PlatformMouseEventBuilder(mainFrameImpl()->frameView(), event)); @@ -471,6 +477,10 @@ bool WebViewImpl::keyEvent(const WebKeyboardEvent& event) // event. m_suppressNextKeypressEvent = false; + // Give any select popup a chance at consuming the key event. + if (selectPopupHandleKeyEvent(event)) + return true; + // Give Autocomplete a chance to consume the key events it is interested in. if (autocompleteHandleKeyEvent(event)) return true; @@ -507,14 +517,27 @@ bool WebViewImpl::keyEvent(const WebKeyboardEvent& event) PlatformKeyboardEventBuilder evt(event); if (handler->keyEvent(evt)) { - if (WebInputEvent::RawKeyDown == event.type) - m_suppressNextKeypressEvent = true; + if (WebInputEvent::RawKeyDown == event.type) { + // Suppress the next keypress event unless the focused node is a plug-in node. + // (Flash needs these keypress events to handle non-US keyboards.) + Node* node = frame->document()->focusedNode(); + if (!node || !node->renderer() || !node->renderer()->isEmbeddedObject()) + m_suppressNextKeypressEvent = true; + } return true; } return keyEventDefault(event); } +bool WebViewImpl::selectPopupHandleKeyEvent(const WebKeyboardEvent& event) +{ + if (!m_selectPopup) + return false; + + return m_selectPopup->handleKeyEvent(PlatformKeyboardEventBuilder(event)); +} + bool WebViewImpl::autocompleteHandleKeyEvent(const WebKeyboardEvent& event) { if (!m_suggestionsPopupShowing @@ -604,6 +627,17 @@ bool WebViewImpl::charEvent(const WebKeyboardEvent& event) return true; } +#if ENABLE(TOUCH_EVENTS) +bool WebViewImpl::touchEvent(const WebTouchEvent& event) +{ + if (!mainFrameImpl() || !mainFrameImpl()->frameView()) + return false; + + PlatformTouchEventBuilder touchEventBuilder(mainFrameImpl()->frameView(), event); + return mainFrameImpl()->frame()->eventHandler()->handleTouchEvent(touchEventBuilder); +} +#endif + // The WebViewImpl::SendContextMenuEvent function is based on the Webkit // function // bool WebView::handleContextMenuEvent(WPARAM wParam, LPARAM lParam) in @@ -774,6 +808,12 @@ bool WebViewImpl::scrollViewWithKeyboard(int keyCode, int modifiers) return propagateScroll(scrollDirection, scrollGranularity); } +void WebViewImpl::hideSelectPopup() +{ + if (m_selectPopup.get()) + m_selectPopup->hidePopup(); +} + bool WebViewImpl::propagateScroll(ScrollDirection scrollDirection, ScrollGranularity scrollGranularity) { @@ -793,6 +833,22 @@ bool WebViewImpl::propagateScroll(ScrollDirection scrollDirection, return scrollHandled; } +void WebViewImpl::popupOpened(WebCore::PopupContainer* popupContainer) +{ + if (popupContainer->popupType() == WebCore::PopupContainer::Select) { + ASSERT(!m_selectPopup); + m_selectPopup = popupContainer; + } +} + +void WebViewImpl::popupClosed(WebCore::PopupContainer* popupContainer) +{ + if (popupContainer->popupType() == WebCore::PopupContainer::Select) { + ASSERT(m_selectPopup.get()); + m_selectPopup = 0; + } +} + Frame* WebViewImpl::focusedWebCoreFrame() { return m_page.get() ? m_page->focusController()->focusedOrMainFrame() : 0; @@ -873,9 +929,26 @@ void WebViewImpl::layout() void WebViewImpl::paint(WebCanvas* canvas, const WebRect& rect) { - WebFrameImpl* webframe = mainFrameImpl(); - if (webframe) - webframe->paint(canvas, rect); + +#if USE(ACCELERATED_COMPOSITING) + if (!isAcceleratedCompositing()) { +#endif + WebFrameImpl* webframe = mainFrameImpl(); + if (webframe) + webframe->paint(canvas, rect); +#if USE(ACCELERATED_COMPOSITING) + } else { + // Draw the contents of the root layer. + updateRootLayerContents(rect); + + // Composite everything into the canvas that's passed to us. +#if PLATFORM(SKIA) + m_layerRenderer->drawLayersInCanvas(static_cast<skia::PlatformCanvas*>(canvas), IntRect(rect)); +#elif PLATFORM(CG) +#error "Need to implement CG version" +#endif + } +#endif } // FIXME: m_currentInputEvent should be removed once ChromeClient::show() can @@ -892,6 +965,38 @@ bool WebViewImpl::handleInputEvent(const WebInputEvent& inputEvent) if (m_ignoreInputEvents) return true; + if (m_haveMouseCapture && WebInputEvent::isMouseEventType(inputEvent.type)) { + // Not all platforms call mouseCaptureLost() directly. + if (inputEvent.type == WebInputEvent::MouseUp) + mouseCaptureLost(); + + Node* node = focusedWebCoreNode(); + if (node && node->renderer() && node->renderer()->isEmbeddedObject()) { + AtomicString eventType; + switch (inputEvent.type) { + case WebInputEvent::MouseMove: + eventType = eventNames().mousemoveEvent; + break; + case WebInputEvent::MouseLeave: + eventType = eventNames().mouseoutEvent; + break; + case WebInputEvent::MouseDown: + eventType = eventNames().mousedownEvent; + break; + case WebInputEvent::MouseUp: + eventType = eventNames().mouseupEvent; + break; + default: + ASSERT_NOT_REACHED(); + } + + node->dispatchMouseEvent( + PlatformMouseEventBuilder(mainFrameImpl()->frameView(), *static_cast<const WebMouseEvent*>(&inputEvent)), + eventType); + return true; + } + } + // FIXME: Remove m_currentInputEvent. // This only exists to allow ChromeClient::show() to know which mouse button // triggered a window.open event. @@ -936,6 +1041,15 @@ bool WebViewImpl::handleInputEvent(const WebInputEvent& inputEvent) handled = charEvent(*static_cast<const WebKeyboardEvent*>(&inputEvent)); break; +#if ENABLE(TOUCH_EVENTS) + case WebInputEvent::TouchStart: + case WebInputEvent::TouchMove: + case WebInputEvent::TouchEnd: + case WebInputEvent::TouchCancel: + handled = touchEvent(*static_cast<const WebTouchEvent*>(&inputEvent)); + break; +#endif + default: handled = false; } @@ -947,6 +1061,7 @@ bool WebViewImpl::handleInputEvent(const WebInputEvent& inputEvent) void WebViewImpl::mouseCaptureLost() { + m_haveMouseCapture = false; } void WebViewImpl::setFocus(bool enable) @@ -982,6 +1097,7 @@ void WebViewImpl::setFocus(bool enable) m_imeAcceptEvents = true; } else { hideSuggestionsPopup(); + hideSelectPopup(); // Clear focus on the currently focused frame if any. if (!m_page.get()) @@ -1166,7 +1282,7 @@ WebString WebViewImpl::pageEncoding() const if (!m_page.get()) return WebString(); - return m_page->mainFrame()->loader()->encoding(); + return m_page->mainFrame()->loader()->writer()->encoding(); } void WebViewImpl::setPageEncoding(const WebString& encodingName) @@ -1302,7 +1418,7 @@ int WebViewImpl::setZoomLevel(bool textOnly, int zoomLevel) Frame* frame = mainFrameImpl()->frame(); if (zoomFactor != frame->zoomFactor()) { m_zoomLevel = zoomLevel; - frame->setZoomFactor(zoomFactor, textOnly); + frame->setZoomFactor(zoomFactor, textOnly ? ZoomTextOnly : ZoomPage); } return m_zoomLevel; } @@ -1331,6 +1447,9 @@ void WebViewImpl::performMediaPlayerAction(const WebMediaPlayerAction& action, case WebMediaPlayerAction::Loop: mediaElement->setLoop(action.enable); break; + case WebMediaPlayerAction::Controls: + mediaElement->setControls(action.enable); + break; default: ASSERT_NOT_REACHED(); } @@ -1392,26 +1511,7 @@ WebDragOperation WebViewImpl::dragTargetDragEnter( m_dragIdentity = identity; m_operationsAllowed = operationsAllowed; - DragData dragData( - m_currentDragData.get(), - clientPoint, - screenPoint, - static_cast<DragOperation>(operationsAllowed)); - - m_dropEffect = DropEffectDefault; - m_dragTargetDispatch = true; - DragOperation effect = m_page->dragController()->dragEntered(&dragData); - // Mask the operation against the drag source's allowed operations. - if ((effect & dragData.draggingSourceOperationMask()) != effect) - effect = DragOperationNone; - m_dragTargetDispatch = false; - - if (m_dropEffect != DropEffectDefault) { - m_dragOperation = (m_dropEffect != DropEffectNone) ? WebDragOperationCopy - : WebDragOperationNone; - } else - m_dragOperation = static_cast<WebDragOperation>(effect); - return m_dragOperation; + return dragTargetDragEnterOrOver(clientPoint, screenPoint, DragEnter); } WebDragOperation WebViewImpl::dragTargetDragOver( @@ -1419,29 +1519,9 @@ WebDragOperation WebViewImpl::dragTargetDragOver( const WebPoint& screenPoint, WebDragOperationsMask operationsAllowed) { - ASSERT(m_currentDragData.get()); - m_operationsAllowed = operationsAllowed; - DragData dragData( - m_currentDragData.get(), - clientPoint, - screenPoint, - static_cast<DragOperation>(operationsAllowed)); - - m_dropEffect = DropEffectDefault; - m_dragTargetDispatch = true; - DragOperation effect = m_page->dragController()->dragUpdated(&dragData); - // Mask the operation against the drag source's allowed operations. - if ((effect & dragData.draggingSourceOperationMask()) != effect) - effect = DragOperationNone; - m_dragTargetDispatch = false; - if (m_dropEffect != DropEffectDefault) { - m_dragOperation = (m_dropEffect != DropEffectNone) ? WebDragOperationCopy - : WebDragOperationNone; - } else - m_dragOperation = static_cast<WebDragOperation>(effect); - return m_dragOperation; + return dragTargetDragEnterOrOver(clientPoint, screenPoint, DragOver); } void WebViewImpl::dragTargetDragLeave() @@ -1504,7 +1584,36 @@ int WebViewImpl::dragIdentity() return 0; } -unsigned long WebViewImpl::createUniqueIdentifierForRequest() { +WebDragOperation WebViewImpl::dragTargetDragEnterOrOver(const WebPoint& clientPoint, const WebPoint& screenPoint, DragAction dragAction) +{ + ASSERT(m_currentDragData.get()); + + DragData dragData( + m_currentDragData.get(), + clientPoint, + screenPoint, + static_cast<DragOperation>(m_operationsAllowed)); + + m_dropEffect = DropEffectDefault; + m_dragTargetDispatch = true; + DragOperation effect = dragAction == DragEnter ? m_page->dragController()->dragEntered(&dragData) + : m_page->dragController()->dragUpdated(&dragData); + // Mask the operation against the drag source's allowed operations. + if (!(effect & dragData.draggingSourceOperationMask())) + effect = DragOperationNone; + m_dragTargetDispatch = false; + + if (m_dropEffect != DropEffectDefault) { + m_dragOperation = (m_dropEffect != DropEffectNone) ? WebDragOperationCopy + : WebDragOperationNone; + } else + m_dragOperation = static_cast<WebDragOperation>(effect); + + return m_dragOperation; +} + +unsigned long WebViewImpl::createUniqueIdentifierForRequest() +{ if (m_page) return m_page->progress()->createUniqueIdentifier(); return 0; @@ -1607,6 +1716,7 @@ void WebViewImpl::applyAutoFillSuggestions( if (!m_autoFillPopup.get()) { m_autoFillPopup = PopupContainer::create(m_suggestionsPopupClient, + PopupContainer::Suggestion, suggestionsPopupSettings); } @@ -1662,6 +1772,7 @@ void WebViewImpl::applyAutocompleteSuggestions( if (!m_autocompletePopup.get()) { m_autocompletePopup = PopupContainer::create(m_suggestionsPopupClient, + PopupContainer::Suggestion, suggestionsPopupSettings); } @@ -1775,6 +1886,13 @@ void WebViewImpl::addUserScript(const WebString& sourceCode, bool runAtStart) runAtStart ? InjectAtDocumentStart : InjectAtDocumentEnd); } +void WebViewImpl::addUserStyleSheet(const WebString& sourceCode) +{ + PageGroup* pageGroup = PageGroup::pageGroup(pageGroupName); + RefPtr<DOMWrapperWorld> world(DOMWrapperWorld::create()); + pageGroup->addUserStyleSheetToWorld(world.get(), sourceCode, WebURL(), 0, 0); +} + void WebViewImpl::removeAllUserContent() { PageGroup* pageGroup = PageGroup::pageGroup(pageGroupName); @@ -1799,7 +1917,7 @@ bool WebViewImpl::navigationPolicyFromMouseEvent(unsigned short button, bool alt, bool meta, WebNavigationPolicy* policy) { -#if OS(WINDOWS) || OS(LINUX) || OS(FREEBSD) +#if OS(WINDOWS) || OS(LINUX) || OS(FREEBSD) || OS(SOLARIS) const bool newTabModifier = (button == 1) || ctrl; #elif OS(DARWIN) const bool newTabModifier = (button == 1) || meta; @@ -1822,15 +1940,16 @@ bool WebViewImpl::navigationPolicyFromMouseEvent(unsigned short button, return true; } -void WebViewImpl::startDragging(const WebPoint& eventPos, - const WebDragData& dragData, - WebDragOperationsMask mask) +void WebViewImpl::startDragging(const WebDragData& dragData, + WebDragOperationsMask mask, + const WebImage& dragImage, + const WebPoint& dragImageOffset) { if (!m_client) return; ASSERT(!m_doingDragAndDrop); m_doingDragAndDrop = true; - m_client->startDragging(eventPos, dragData, mask); + m_client->startDragging(dragData, mask, dragImage, dragImageOffset); } void WebViewImpl::setCurrentHistoryItem(HistoryItem* item) @@ -1916,4 +2035,76 @@ bool WebViewImpl::tabsToLinks() const return m_tabsToLinks; } +#if USE(ACCELERATED_COMPOSITING) +void WebViewImpl::setRootGraphicsLayer(WebCore::PlatformLayer* layer) +{ + setAcceleratedCompositing(layer ? true : false); + if (m_layerRenderer) + m_layerRenderer->setRootLayer(layer); +} + +void WebViewImpl::setAcceleratedCompositing(bool accelerated) +{ + if (m_isAcceleratedCompositing == accelerated) + return; + + if (accelerated) { + m_layerRenderer = LayerRendererChromium::create(); + if (m_layerRenderer) + m_isAcceleratedCompositing = true; + } else { + m_layerRenderer = 0; + m_isAcceleratedCompositing = false; + } +} + +void WebViewImpl::updateRootLayerContents(const WebRect& rect) +{ + if (!isAcceleratedCompositing()) + return; + + WebFrameImpl* webframe = mainFrameImpl(); + if (!webframe) + return; + FrameView* view = webframe->frameView(); + if (!view) + return; + + WebRect viewRect = view->frameRect(); + SkIRect scrollFrame; + scrollFrame.set(view->scrollX(), view->scrollY(), view->layoutWidth() + view->scrollX(), view->layoutHeight() + view->scrollY()); + m_layerRenderer->setScrollFrame(scrollFrame); + LayerChromium* rootLayer = m_layerRenderer->rootLayer(); + if (rootLayer) { + IntRect visibleRect = view->visibleContentRect(true); + + // Set the backing store size used by the root layer to be the size of the visible + // area. Note that the root layer bounds could be larger than the backing store size, + // but there's no reason to waste memory by allocating backing store larger than the + // visible portion. + rootLayer->setBackingStoreRect(IntSize(visibleRect.width(), visibleRect.height())); + GraphicsContext* rootLayerContext = rootLayer->graphicsContext(); + rootLayerContext->save(); + + webframe->paintWithContext(*(rootLayer->graphicsContext()), rect); + rootLayerContext->restore(); + } +} + +void WebViewImpl::setRootLayerNeedsDisplay() +{ + // FIXME: For now we're posting a repaint event for the entire page which is an overkill. + if (WebFrameImpl* webframe = mainFrameImpl()) { + if (FrameView* view = webframe->frameView()) { + IntRect visibleRect = view->visibleContentRect(true); + m_client->didInvalidateRect(visibleRect); + } + } + + if (m_layerRenderer) + m_layerRenderer->setNeedsDisplay(); +} + +#endif + } // namespace WebKit diff --git a/WebKit/chromium/src/WebViewImpl.h b/WebKit/chromium/src/WebViewImpl.h index 286ac43..ba2dc25 100644 --- a/WebKit/chromium/src/WebViewImpl.h +++ b/WebKit/chromium/src/WebViewImpl.h @@ -43,7 +43,9 @@ #include "ContextMenuClientImpl.h" #include "DragClientImpl.h" #include "EditorClientImpl.h" +#include "GraphicsLayer.h" #include "InspectorClientImpl.h" +#include "LayerRendererChromium.h" #include "NotificationPresenterImpl.h" #include <wtf/OwnPtr.h> @@ -72,10 +74,12 @@ class SuggestionsPopupMenuClient; class WebAccessibilityObject; class WebDevToolsAgentPrivate; class WebFrameImpl; +class WebImage; class WebKeyboardEvent; class WebMouseEvent; class WebMouseWheelEvent; class WebSettingsImpl; +class WebTouchEvent; class WebViewImpl : public WebView, public RefCounted<WebViewImpl> { public: @@ -177,6 +181,7 @@ public: virtual void performCustomContextMenuAction(unsigned action); virtual void addUserScript(const WebString& sourceCode, bool runAtStart); + virtual void addUserStyleSheet(const WebString& sourceCode); virtual void removeAllUserContent(); // WebViewImpl @@ -201,7 +206,7 @@ public: return m_client; } - // Returns the page object associated with this view. This may be null when + // Returns the page object associated with this view. This may be null when // the page is shutting down, but will be valid at all other times. WebCore::Page* page() const { @@ -210,7 +215,7 @@ public: WebCore::RenderTheme* theme() const; - // Returns the main frame associated with this view. This may be null when + // Returns the main frame associated with this view. This may be null when // the page is shutting down, but will be valid at all other times. WebFrameImpl* mainFrameImpl(); @@ -229,16 +234,17 @@ public: void mouseWheel(const WebMouseWheelEvent&); bool keyEvent(const WebKeyboardEvent&); bool charEvent(const WebKeyboardEvent&); + bool touchEvent(const WebTouchEvent&); // Handles context menu events orignated via the the keyboard. These - // include the VK_APPS virtual key and the Shift+F10 combine. Code is + // include the VK_APPS virtual key and the Shift+F10 combine. Code is // based on the Webkit function bool WebView::handleContextMenuEvent(WPARAM // wParam, LPARAM lParam) in webkit\webkit\win\WebView.cpp. The only // significant change in this function is the code to convert from a // Keyboard event to the Right Mouse button down event. bool sendContextMenuEvent(const WebKeyboardEvent&); - // Notifies the WebView that a load has been committed. isNewNavigation + // Notifies the WebView that a load has been committed. isNewNavigation // will be true if a new session history item should be created for that // load. void didCommitLoad(bool* isNewNavigation); @@ -270,9 +276,10 @@ public: // Start a system drag and drop operation. void startDragging( - const WebPoint& eventPos, const WebDragData& dragData, - WebDragOperationsMask dragSourceOperationMask); + WebDragOperationsMask mask, + const WebImage& dragImage, + const WebPoint& dragImageOffset); void suggestionsPopupDidHide() { @@ -288,6 +295,10 @@ public: // was scrolled. bool propagateScroll(WebCore::ScrollDirection, WebCore::ScrollGranularity); + // Notification that a popup was opened/closed. + void popupOpened(WebCore::PopupContainer* popupContainer); + void popupClosed(WebCore::PopupContainer* popupContainer); + // HACK: currentInputEvent() is for ChromeClientImpl::show(), until we can // fix WebKit to pass enough information up into ChromeClient::show() so we // can decide if the window.open event was caused by a middle-mouse click @@ -296,31 +307,62 @@ public: return m_currentInputEvent; } +#if USE(ACCELERATED_COMPOSITING) + void setRootLayerNeedsDisplay(); + void setRootGraphicsLayer(WebCore::PlatformLayer*); +#endif + + WebCore::PopupContainer* selectPopup() const { return m_selectPopup.get(); } + private: friend class WebView; // So WebView::Create can call our constructor friend class WTF::RefCounted<WebViewImpl>; + enum DragAction { + DragEnter, + DragOver + }; + WebViewImpl(WebViewClient* client); ~WebViewImpl(); // Returns true if the event was actually processed. bool keyEventDefault(const WebKeyboardEvent&); + // Returns true if the select popup has consumed the event. + bool selectPopupHandleKeyEvent(const WebKeyboardEvent&); + // Returns true if the autocomple has consumed the event. bool autocompleteHandleKeyEvent(const WebKeyboardEvent&); - // Repaints the suggestions popup. Should be called when the suggestions - // have changed. Note that this should only be called when the suggestions + // Repaints the suggestions popup. Should be called when the suggestions + // have changed. Note that this should only be called when the suggestions // popup is showing. void refreshSuggestionsPopup(); // Returns true if the view was scrolled. bool scrollViewWithKeyboard(int keyCode, int modifiers); + // Hides the select popup if one is opened. + void hideSelectPopup(); + // Converts |pos| from window coordinates to contents coordinates and gets // the HitTestResult for it. WebCore::HitTestResult hitTestResultForWindowPos(const WebCore::IntPoint&); + // Consolidate some common code between starting a drag over a target and + // updating a drag over a target. If we're starting a drag, |isEntering| + // should be true. + WebDragOperation dragTargetDragEnterOrOver(const WebPoint& clientPoint, + const WebPoint& screenPoint, + DragAction); + +#if USE(ACCELERATED_COMPOSITING) + void setAcceleratedCompositing(bool); + bool isAcceleratedCompositing() const { return m_isAcceleratedCompositing; } + void updateRootLayerContents(const WebRect&); +#endif + WebViewClient* m_client; BackForwardListClientImpl m_backForwardListClientImpl; @@ -335,7 +377,7 @@ private: WebPoint m_lastMousePosition; OwnPtr<WebCore::Page> m_page; - // This flag is set when a new navigation is detected. It is used to satisfy + // This flag is set when a new navigation is detected. It is used to satisfy // the corresponding argument to WebFrameClient::didCommitProvisionalLoad. bool m_observedNewNavigation; #ifndef NDEBUG @@ -345,7 +387,7 @@ private: #endif // An object that can be used to manipulate m_page->settings() without linking - // against WebCore. This is lazily allocated the first time GetWebSettings() + // against WebCore. This is lazily allocated the first time GetWebSettings() // is called. OwnPtr<WebSettingsImpl> m_webSettings; @@ -361,7 +403,7 @@ private: // dragged by the time a drag is initiated. WebPoint m_lastMouseDownPoint; - // Keeps track of the current zoom level. 0 means no zoom, positive numbers + // Keeps track of the current zoom level. 0 means no zoom, positive numbers // mean zoom in, negative numbers mean zoom out. int m_zoomLevel; @@ -391,7 +433,7 @@ private: // copied from the WebDropData object sent from the browser process. int m_dragIdentity; - // Valid when m_dragTargetDispatch is true. Used to override the default + // Valid when m_dragTargetDispatch is true. Used to override the default // browser drop effect with the effects "none" or "copy". enum DragTargetDropEffect { DropEffectDefault = -1, @@ -410,8 +452,8 @@ private: // Whether a suggestions popup is currently showing. bool m_suggestionsPopupShowing; - // A pointer to the current suggestions popup menu client. This can be - // either an AutoFillPopupMenuClient or an AutocompletePopupMenuClient. We + // A pointer to the current suggestions popup menu client. This can be + // either an AutoFillPopupMenuClient or an AutocompletePopupMenuClient. We // do not own this pointer. SuggestionsPopupMenuClient* m_suggestionsPopupClient; @@ -421,9 +463,12 @@ private: // The Autocomplete popup client. OwnPtr<AutocompletePopupMenuClient> m_autocompletePopupClient; - // A pointer to the current suggestions popup. We do not own this pointer. + // A pointer to the current suggestions popup. We do not own this pointer. WebCore::PopupContainer* m_suggestionsPopup; + // The popup associated with a select element. + RefPtr<WebCore::PopupContainer> m_selectPopup; + // The AutoFill suggestions popup. RefPtr<WebCore::PopupContainer> m_autoFillPopup; @@ -446,6 +491,12 @@ private: NotificationPresenterImpl m_notificationPresenter; #endif + bool m_haveMouseCapture; + +#if USE(ACCELERATED_COMPOSITING) + OwnPtr<WebCore::LayerRendererChromium> m_layerRenderer; + bool m_isAcceleratedCompositing; +#endif static const WebInputEvent* m_currentInputEvent; }; diff --git a/WebKit/chromium/src/WebWorkerBase.cpp b/WebKit/chromium/src/WebWorkerBase.cpp index 40019e8..da51414 100644 --- a/WebKit/chromium/src/WebWorkerBase.cpp +++ b/WebKit/chromium/src/WebWorkerBase.cpp @@ -199,8 +199,7 @@ void WebWorkerBase::postExceptionTask(ScriptExecutionContext* context, sourceURL); } -void WebWorkerBase::postConsoleMessageToWorkerObject(MessageDestination destination, - MessageSource source, +void WebWorkerBase::postConsoleMessageToWorkerObject(MessageSource source, MessageType type, MessageLevel level, const String& message, @@ -208,16 +207,13 @@ void WebWorkerBase::postConsoleMessageToWorkerObject(MessageDestination destinat const String& sourceURL) { dispatchTaskToMainThread(createCallbackTask(&postConsoleMessageTask, this, - static_cast<int>(destination), - static_cast<int>(source), - static_cast<int>(type), - static_cast<int>(level), + source, type, level, message, lineNumber, sourceURL)); } void WebWorkerBase::postConsoleMessageTask(ScriptExecutionContext* context, WebWorkerBase* thisPtr, - int destination, int source, + int source, int type, int level, const String& message, int lineNumber, @@ -225,7 +221,7 @@ void WebWorkerBase::postConsoleMessageTask(ScriptExecutionContext* context, { if (!thisPtr->commonClient()) return; - thisPtr->commonClient()->postConsoleMessageToWorkerObject(destination, source, + thisPtr->commonClient()->postConsoleMessageToWorkerObject(source, type, level, message, lineNumber, sourceURL); } diff --git a/WebKit/chromium/src/WebWorkerBase.h b/WebKit/chromium/src/WebWorkerBase.h index 0217401..1252770 100644 --- a/WebKit/chromium/src/WebWorkerBase.h +++ b/WebKit/chromium/src/WebWorkerBase.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2009 Google Inc. All rights reserved. + * Copyright (C) 2010 Google Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are @@ -45,8 +45,11 @@ class WorkerThread; namespace WebKit { class WebCommonWorkerClient; +class WebSecurityOrigin; +class WebString; class WebURL; class WebView; +class WebWorker; class WebWorkerClient; // Base class for WebSharedWorkerImpl and WebWorkerImpl. It contains common @@ -65,7 +68,7 @@ public: virtual void postExceptionToWorkerObject( const WebCore::String&, int, const WebCore::String&); virtual void postConsoleMessageToWorkerObject( - WebCore::MessageDestination, WebCore::MessageSource, WebCore::MessageType, + WebCore::MessageSource, WebCore::MessageType, WebCore::MessageLevel, const WebCore::String&, int, const WebCore::String&); virtual void confirmMessageFromWorkerObject(bool); virtual void reportPendingActivity(bool); @@ -112,7 +115,6 @@ private: static void postConsoleMessageTask( WebCore::ScriptExecutionContext* context, WebWorkerBase* thisPtr, - int destination, int source, int type, int level, diff --git a/WebKit/chromium/src/WebWorkerClientImpl.cpp b/WebKit/chromium/src/WebWorkerClientImpl.cpp index 598a078..d0dda8e 100644 --- a/WebKit/chromium/src/WebWorkerClientImpl.cpp +++ b/WebKit/chromium/src/WebWorkerClientImpl.cpp @@ -45,6 +45,7 @@ #include "Worker.h" #include "WorkerContext.h" #include "WorkerContextExecutionProxy.h" +#include "WorkerScriptController.h" #include "WorkerMessagingProxy.h" #include <wtf/Threading.h> @@ -94,15 +95,13 @@ WorkerContextProxy* WebWorkerClientImpl::createWorkerContextProxy(Worker* worker WebFrameImpl* webFrame = WebFrameImpl::fromFrame(document->frame()); webWorker = webFrame->client()->createWorker(webFrame, proxy); } else { - WorkerContextExecutionProxy* currentContext = - WorkerContextExecutionProxy::retrieve(); - if (!currentContext) { + WorkerScriptController* controller = WorkerScriptController::controllerForContext(); + if (!controller) { ASSERT_NOT_REACHED(); return 0; } - DedicatedWorkerThread* thread = - static_cast<DedicatedWorkerThread*>(currentContext->workerContext()->thread()); + DedicatedWorkerThread* thread = static_cast<DedicatedWorkerThread*>(controller->workerContext()->thread()); WorkerObjectProxy* workerObjectProxy = &thread->workerObjectProxy(); WebWorkerImpl* impl = reinterpret_cast<WebWorkerImpl*>(workerObjectProxy); webWorker = impl->client()->createWorker(proxy); @@ -244,15 +243,14 @@ void WebWorkerClientImpl::postExceptionToWorkerObject(const WebString& errorMess return; } - bool handled = false; - handled = m_worker->dispatchEvent(ErrorEvent::create(errorMessage, - sourceURL, - lineNumber)); - if (!handled) + bool unhandled = m_worker->dispatchEvent(ErrorEvent::create(errorMessage, + sourceURL, + lineNumber)); + if (unhandled) m_scriptExecutionContext->reportException(errorMessage, lineNumber, sourceURL); } -void WebWorkerClientImpl::postConsoleMessageToWorkerObject(int destinationId, +void WebWorkerClientImpl::postConsoleMessageToWorkerObject(int destination, int sourceId, int messageType, int messageLevel, @@ -263,7 +261,6 @@ void WebWorkerClientImpl::postConsoleMessageToWorkerObject(int destinationId, if (currentThread() != m_workerThreadId) { m_scriptExecutionContext->postTask(createCallbackTask(&postConsoleMessageToWorkerObjectTask, this, - destinationId, sourceId, messageType, messageLevel, @@ -273,14 +270,23 @@ void WebWorkerClientImpl::postConsoleMessageToWorkerObject(int destinationId, return; } - m_scriptExecutionContext->addMessage(static_cast<MessageDestination>(destinationId), - static_cast<MessageSource>(sourceId), + m_scriptExecutionContext->addMessage(static_cast<MessageSource>(sourceId), static_cast<MessageType>(messageType), static_cast<MessageLevel>(messageLevel), String(message), lineNumber, String(sourceURL)); } +void WebWorkerClientImpl::postConsoleMessageToWorkerObject(int sourceId, + int messageType, + int messageLevel, + const WebString& message, + int lineNumber, + const WebString& sourceURL) +{ + postConsoleMessageToWorkerObject(0, sourceId, messageType, messageLevel, message, lineNumber, sourceURL); +} + void WebWorkerClientImpl::confirmMessageFromWorkerObject(bool hasPendingActivity) { // unconfirmed_message_count_ can only be updated on the thread where it's @@ -382,7 +388,6 @@ void WebWorkerClientImpl::postExceptionToWorkerObjectTask( void WebWorkerClientImpl::postConsoleMessageToWorkerObjectTask(ScriptExecutionContext* context, WebWorkerClientImpl* thisPtr, - int destinationId, int sourceId, int messageType, int messageLevel, @@ -390,8 +395,7 @@ void WebWorkerClientImpl::postConsoleMessageToWorkerObjectTask(ScriptExecutionCo int lineNumber, const String& sourceURL) { - thisPtr->m_scriptExecutionContext->addMessage(static_cast<MessageDestination>(destinationId), - static_cast<MessageSource>(sourceId), + thisPtr->m_scriptExecutionContext->addMessage(static_cast<MessageSource>(sourceId), static_cast<MessageType>(messageType), static_cast<MessageLevel>(messageLevel), message, lineNumber, diff --git a/WebKit/chromium/src/WebWorkerClientImpl.h b/WebKit/chromium/src/WebWorkerClientImpl.h index 63acebc..4bdc332 100644 --- a/WebKit/chromium/src/WebWorkerClientImpl.h +++ b/WebKit/chromium/src/WebWorkerClientImpl.h @@ -78,8 +78,12 @@ public: // These are called on the main WebKit thread. virtual void postMessageToWorkerObject(const WebString&, const WebMessagePortChannelArray&); virtual void postExceptionToWorkerObject(const WebString&, int, const WebString&); - virtual void postConsoleMessageToWorkerObject(int, int, int, int, const WebString&, - int, const WebString&); + + // FIXME: the below is for compatibility only and should be + // removed once Chromium is updated to remove message + // destination parameter <http://webkit.org/b/37155>. + virtual void postConsoleMessageToWorkerObject(int, int, int, int, const WebString&, int, const WebString&); + virtual void postConsoleMessageToWorkerObject(int, int, int, const WebString&, int, const WebString&); virtual void confirmMessageFromWorkerObject(bool); virtual void reportPendingActivity(bool); virtual void workerContextClosed(); @@ -125,7 +129,6 @@ private: const WebCore::String& sourceURL); static void postConsoleMessageToWorkerObjectTask(WebCore::ScriptExecutionContext* context, WebWorkerClientImpl* thisPtr, - int destinationId, int sourceId, int messageType, int messageLevel, diff --git a/WebKit/chromium/src/gtk/WebFontInfo.cpp b/WebKit/chromium/src/gtk/WebFontInfo.cpp index 76ed618..3ac0b00 100644 --- a/WebKit/chromium/src/gtk/WebFontInfo.cpp +++ b/WebKit/chromium/src/gtk/WebFontInfo.cpp @@ -30,6 +30,7 @@ #include "config.h" #include "WebFontInfo.h" +#include "WebFontRenderStyle.h" #include <fontconfig/fontconfig.h> #include <string.h> @@ -55,11 +56,11 @@ WebCString WebFontInfo::familyForChars(const WebUChar* characters, size_t numCha FcValue fcvalue; fcvalue.type = FcTypeCharSet; fcvalue.u.c = cset; - FcPatternAdd(pattern, FC_CHARSET, fcvalue, 0); + FcPatternAdd(pattern, FC_CHARSET, fcvalue, FcFalse); fcvalue.type = FcTypeBool; fcvalue.u.b = FcTrue; - FcPatternAdd(pattern, FC_SCALABLE, fcvalue, 0); + FcPatternAdd(pattern, FC_SCALABLE, fcvalue, FcFalse); FcConfigSubstitute(0, pattern, FcMatchPattern); FcDefaultSubstitute(pattern); @@ -104,4 +105,68 @@ WebCString WebFontInfo::familyForChars(const WebUChar* characters, size_t numCha return WebCString(); } +void WebFontInfo::renderStyleForStrike(const char* family, int sizeAndStyle, WebFontRenderStyle* out) +{ + bool isBold = sizeAndStyle & 1; + bool isItalic = sizeAndStyle & 2; + int pixelSize = sizeAndStyle >> 2; + + FcPattern* pattern = FcPatternCreate(); + FcValue fcvalue; + + fcvalue.type = FcTypeString; + fcvalue.u.s = reinterpret_cast<const FcChar8 *>(family); + FcPatternAdd(pattern, FC_FAMILY, fcvalue, FcFalse); + + fcvalue.type = FcTypeInteger; + fcvalue.u.i = isBold ? FC_WEIGHT_BOLD : FC_WEIGHT_NORMAL; + FcPatternAdd(pattern, FC_WEIGHT, fcvalue, FcFalse); + + fcvalue.type = FcTypeInteger; + fcvalue.u.i = isItalic ? FC_SLANT_ITALIC : FC_SLANT_ROMAN; + FcPatternAdd(pattern, FC_SLANT, fcvalue, FcFalse); + + fcvalue.type = FcTypeBool; + fcvalue.u.b = FcTrue; + FcPatternAdd(pattern, FC_SCALABLE, fcvalue, FcFalse); + + fcvalue.type = FcTypeDouble; + fcvalue.u.d = pixelSize; + FcPatternAdd(pattern, FC_SIZE, fcvalue, FcFalse); + + FcConfigSubstitute(0, pattern, FcMatchPattern); + FcDefaultSubstitute(pattern); + + FcResult result; + // Some versions of fontconfig don't actually write a value into result. + // However, it's not clear from the documentation if result should be a + // non-0 pointer: future versions might expect to be able to write to + // it. So we pass in a valid pointer and ignore it. + FcPattern* match = FcFontMatch(0, pattern, &result); + FcPatternDestroy(pattern); + + out->setDefaults(); + + if (!match) { + FcPatternDestroy(match); + return; + } + + FcBool b; + int i; + + if (FcPatternGetBool(match, FC_ANTIALIAS, 0, &b) == FcResultMatch) + out->useAntiAlias = b; + if (FcPatternGetBool(match, FC_EMBEDDED_BITMAP, 0, &b) == FcResultMatch) + out->useBitmaps = b; + if (FcPatternGetBool(match, FC_AUTOHINT, 0, &b) == FcResultMatch) + out->useAutoHint = b; + if (FcPatternGetBool(match, FC_HINTING, 0, &b) == FcResultMatch) + out->useHinting = b; + if (FcPatternGetInteger(match, FC_HINT_STYLE, 0, &i) == FcResultMatch) + out->hintStyle = i; + + FcPatternDestroy(match); +} + } // namespace WebKit diff --git a/WebKit/chromium/src/gtk/WebInputEventFactory.cpp b/WebKit/chromium/src/gtk/WebInputEventFactory.cpp index 7125a16..f4db5ee 100644 --- a/WebKit/chromium/src/gtk/WebInputEventFactory.cpp +++ b/WebKit/chromium/src/gtk/WebInputEventFactory.cpp @@ -49,7 +49,7 @@ gint getDoubleClickTime() { static GtkSettings* settings = gtk_settings_get_default(); gint doubleClickTime = 250; - g_object_get(G_OBJECT(settings), "gtk-double-click-time", &doubleClickTime, 0); + g_object_get(G_OBJECT(settings), "gtk-double-click-time", &doubleClickTime, NULL); return doubleClickTime; } diff --git a/WebKit/chromium/src/js/DebuggerAgent.js b/WebKit/chromium/src/js/DebuggerAgent.js index bb655c7..8230616 100644 --- a/WebKit/chromium/src/js/DebuggerAgent.js +++ b/WebKit/chromium/src/js/DebuggerAgent.js @@ -117,12 +117,17 @@ devtools.DebuggerAgent = function() */ this.urlToBreakpoints_ = {}; - /** * Exception message that is shown to user while on exception break. * @type {WebInspector.ConsoleMessage} */ this.currentExceptionMessage_ = null; + + /** + * Whether breakpoints should suspend execution. + * @type {boolean} + */ + this.breakpointsActivated_ = true; }; @@ -176,7 +181,7 @@ devtools.DebuggerAgent.prototype.initUI = function() // pending addition into the UI. for (var scriptId in this.parsedScripts_) { var script = this.parsedScripts_[scriptId]; - WebInspector.parsedScriptSource(scriptId, script.getUrl(), undefined /* script source */, script.getLineOffset()); + WebInspector.parsedScriptSource(scriptId, script.getUrl(), undefined /* script source */, script.getLineOffset() + 1); } return; } @@ -210,11 +215,14 @@ devtools.DebuggerAgent.prototype.resolveScriptSource = function(scriptId, callba // Force v8 execution so that it gets to processing the requested command. RemoteDebuggerAgent.processDebugCommands(); + var self = this; this.requestSeqToCallback_[cmd.getSequenceNumber()] = function(msg) { if (msg.isSuccess()) { var scriptJson = msg.getBody()[0]; - if (scriptJson) + if (scriptJson) { + script.source = scriptJson.source; callback(scriptJson.source); + } else callback(null); } else @@ -295,6 +303,36 @@ devtools.DebuggerAgent.prototype.addBreakpoint = function(sourceId, line, condit /** + * Changes given line of the script. + */ +devtools.DebuggerAgent.prototype.editScriptLine = function(sourceId, line, newContent, callback) +{ + var script = this.parsedScripts_[sourceId]; + if (!script || !script.source) + return; + + var lines = script.source.split("\n"); + lines[line] = newContent; + + var commandArguments = { + "script_id": sourceId, + "new_source": lines.join("\n") + }; + + var cmd = new devtools.DebugCommand("changelive", commandArguments); + devtools.DebuggerAgent.sendCommand_(cmd); + this.requestSeqToCallback_[cmd.getSequenceNumber()] = function(msg) { + if (!msg.isSuccess()) + WebInspector.log("Unable to modify source code within given scope. Only function bodies are editable at the moment.", WebInspector.ConsoleMessage.MessageLevel.Warning); + this.resolveScriptSource(sourceId, callback); + if (WebInspector.panels.scripts.paused) + this.requestBacktrace_(); + }.bind(this); + RemoteDebuggerAgent.processDebugCommands(); +}; + + +/** * @param {number} sourceId Id of the script for the breakpoint. * @param {number} line Number of the line for the breakpoint. */ @@ -309,6 +347,8 @@ devtools.DebuggerAgent.prototype.removeBreakpoint = function(sourceId, line) var breakpointInfo; if (script.getUrl()) { var breakpoints = this.urlToBreakpoints_[script.getUrl()]; + if (!breakpoints) + return; breakpointInfo = breakpoints[line]; delete breakpoints[line]; } else { @@ -334,34 +374,11 @@ devtools.DebuggerAgent.prototype.removeBreakpoint = function(sourceId, line) /** - * @param {number} sourceId Id of the script for the breakpoint. - * @param {number} line Number of the line for the breakpoint. - * @param {?string} condition New breakpoint condition. + * @param {boolean} activated Whether breakpoints should be activated. */ -devtools.DebuggerAgent.prototype.updateBreakpoint = function(sourceId, line, condition) +devtools.DebuggerAgent.prototype.setBreakpointsActivated = function(activated) { - var script = this.parsedScripts_[sourceId]; - if (!script) - return; - - line = devtools.DebuggerAgent.webkitToV8LineNumber_(line); - - var breakpointInfo; - if (script.getUrl()) { - var breakpoints = this.urlToBreakpoints_[script.getUrl()]; - breakpointInfo = breakpoints[line]; - } else - breakpointInfo = script.getBreakpointInfo(line); - - var id = breakpointInfo.getV8Id(); - - // If we don't know id of this breakpoint in the v8 debugger we cannot send - // the "changebreakpoint" request. - if (id !== -1) { - // TODO(apavlov): make use of the real values for "enabled" and - // "ignoreCount" when appropriate. - this.requestChangeBreakpoint_(id, true, condition, null); - } + this.breakpointsActivated_ = activated; }; @@ -663,25 +680,6 @@ devtools.DebuggerAgent.prototype.requestClearBreakpoint_ = function(breakpointId /** - * Changes breakpoint parameters in the v8 debugger. - * @param {number} breakpointId Id of the breakpoint in the v8 debugger. - * @param {boolean} enabled Whether to enable the breakpoint. - * @param {?string} condition New breakpoint condition. - * @param {number} ignoreCount New ignore count for the breakpoint. - */ -devtools.DebuggerAgent.prototype.requestChangeBreakpoint_ = function(breakpointId, enabled, condition, ignoreCount) -{ - var cmd = new devtools.DebugCommand("changebreakpoint", { - "breakpoint": breakpointId, - "enabled": enabled, - "condition": condition, - "ignoreCount": ignoreCount - }); - devtools.DebuggerAgent.sendCommand_(cmd); -}; - - -/** * Sends "backtrace" request to v8. */ devtools.DebuggerAgent.prototype.requestBacktrace_ = function() @@ -800,6 +798,8 @@ devtools.DebuggerAgent.prototype.handleDebuggerOutput_ = function(output) this.invokeCallbackForResponse_(msg); else if (msg.getCommand() === "setbreakpoint") this.handleSetBreakpointResponse_(msg); + else if (msg.getCommand() === "changelive") + this.invokeCallbackForResponse_(msg); else if (msg.getCommand() === "clearbreakpoint") this.handleClearBreakpointResponse_(msg); else if (msg.getCommand() === "backtrace") @@ -819,7 +819,12 @@ devtools.DebuggerAgent.prototype.handleDebuggerOutput_ = function(output) */ devtools.DebuggerAgent.prototype.handleBreakEvent_ = function(msg) { - // Force scrips panel to be shown first. + if (!this.breakpointsActivated_) { + this.resumeExecution(); + return; + } + + // Force scripts panel to be shown first. WebInspector.currentPanel = WebInspector.panels.scripts; var body = msg.getBody(); @@ -834,9 +839,6 @@ devtools.DebuggerAgent.prototype.handleBreakEvent_ = function(msg) */ devtools.DebuggerAgent.prototype.handleExceptionEvent_ = function(msg) { - // Force scrips panel to be shown first. - WebInspector.currentPanel = WebInspector.panels.scripts; - var body = msg.getBody(); // No script field in the body means that v8 failed to parse the script. We // resume execution on parser errors automatically. @@ -844,6 +846,9 @@ devtools.DebuggerAgent.prototype.handleExceptionEvent_ = function(msg) var line = devtools.DebuggerAgent.v8ToWwebkitLineNumber_(body.sourceLine); this.createExceptionMessage_(body.script.name, line, body.exception.text); this.requestBacktrace_(); + + // Force scripts panel to be shown. + WebInspector.currentPanel = WebInspector.panels.scripts; } else this.resumeExecution(); }; @@ -956,7 +961,7 @@ devtools.DebuggerAgent.prototype.addScriptInfo_ = function(script, msg) this.parsedScripts_[script.id] = new devtools.ScriptInfo(script.id, script.name, script.lineOffset, contextType); if (this.scriptsPanelInitialized_) { // Only report script as parsed after scripts panel has been shown. - WebInspector.parsedScriptSource(script.id, script.name, script.source, script.lineOffset); + WebInspector.parsedScriptSource(script.id, script.name, script.source, script.lineOffset + 1); } }; @@ -994,7 +999,7 @@ devtools.DebuggerAgent.prototype.doHandleBacktraceResponse_ = function(msg) this.callFrames_.push(this.formatCallFrame_(frames[i])); WebInspector.pausedScript(this.callFrames_); this.showPendingExceptionMessage_(); - InspectorFrontendHost.activateWindow(); + InspectorFrontendHost.bringToFront(); }; diff --git a/WebKit/chromium/src/js/DebuggerScript.js b/WebKit/chromium/src/js/DebuggerScript.js new file mode 100644 index 0000000..75c5467 --- /dev/null +++ b/WebKit/chromium/src/js/DebuggerScript.js @@ -0,0 +1,211 @@ +/* + * Copyright (C) 2010 Google 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: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER OR 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. + */ + +function debuggerScriptConstructor() { + +var DebuggerScript = {}; +DebuggerScript._breakpoints = {}; + + +DebuggerScript.getAfterCompileScript = function(execState, args) +{ + return DebuggerScript._formatScript(args.eventData.script_.script_); +} + +DebuggerScript.getScripts = function(execState, args) +{ + var scripts = Debug.scripts(); + var result = []; + for (var i = 0; i < scripts.length; ++i) { + result.push(DebuggerScript._formatScript(scripts[i])); + } + return result; +} + +DebuggerScript._formatScript = function(script) +{ + return { + id: script.id, + name: script.name, + source: script.source, + lineOffset: script.line_offset, + lineCount: script.lineCount(), + contextData: script.context_data + }; +} + +DebuggerScript.setBreakpoint = function(execState, args) +{ + args.lineNumber = DebuggerScript._webkitToV8LineNumber(args.lineNumber); + var key = args.scriptId + ":" + args.lineNumber; + var breakId = DebuggerScript._breakpoints[key]; + if (breakId) { + if (args.enabled) + Debug.enableScriptBreakPoint(breakId); + else + Debug.disableScriptBreakPoint(breakId); + Debug.changeScriptBreakPointCondition(breakId, args.condition); + return breakId; + } + + breakId = Debug.setScriptBreakPointById(args.scriptId, args.lineNumber, 0 /* column */, args.condition); + DebuggerScript._breakpoints[key] = breakId; + if (!args.enabled) + Debug.disableScriptBreakPoint(breakId); + return breakId; +} + +DebuggerScript.removeBreakpoint = function(execState, args) +{ + args.lineNumber = DebuggerScript._webkitToV8LineNumber(args.lineNumber); + var key = args.scriptId + ":" + args.lineNumber; + var breakId = DebuggerScript._breakpoints[key]; + if (breakId) + Debug.findBreakPoint(breakId, true); + delete DebuggerScript._breakpoints[key]; +} + +DebuggerScript.currentCallFrame = function(execState, args) +{ + var frameCount = execState.frameCount(); + if (frameCount === 0) + return undefined; + + var topFrame; + for (var i = frameCount - 1; i >= 0; i--) { + var frameMirror = execState.frame(i); + topFrame = DebuggerScript._frameMirrorToJSCallFrame(frameMirror, topFrame); + } + return topFrame; +} + +DebuggerScript.stepIntoStatement = function(execState, args) +{ + execState.prepareStep(Debug.StepAction.StepIn, 1); +} + +DebuggerScript.stepOverStatement = function(execState, args) +{ + execState.prepareStep(Debug.StepAction.StepNext, 1); +} + +DebuggerScript.stepOutOfFunction = function(execState, args) +{ + execState.prepareStep(Debug.StepAction.StepOut, 1); +} + +DebuggerScript.clearBreakpoints = function(execState, args) +{ + for (var key in DebuggerScript._breakpoints) { + var breakId = DebuggerScript._breakpoints[key]; + Debug.findBreakPoint(breakId, true); + } + DebuggerScript._breakpoints = {}; +} + +DebuggerScript.setBreakpointsActivated = function(execState, args) +{ + for (var key in DebuggerScript._breakpoints) { + var breakId = DebuggerScript._breakpoints[key]; + if (args.enabled) + Debug.enableScriptBreakPoint(breakId); + else + Debug.disableScriptBreakPoint(breakId); + } +} + +DebuggerScript._frameMirrorToJSCallFrame = function(frameMirror, callerFrame) +{ + // Get function name. + var func; + try { + func = frameMirror.func(); + } catch(e) { + } + var functionName; + if (func) + functionName = func.name() || func.inferredName(); + if (!functionName) + functionName = "[anonymous]"; + + // Get script ID. + var script = func.script(); + var sourceID = script && script.id(); + + // Get line number. + var line = DebuggerScript._v8ToWwebkitLineNumber(frameMirror.sourceLine()); + + // Get this object. + var thisObject = frameMirror.details_.receiver(); + + // Get scope chain array in format: [<scope type>, <scope object>, <scope type>, <scope object>,...] + var scopeChain = []; + var scopeType = []; + for (var i = 0; i < frameMirror.scopeCount(); i++) { + var scopeMirror = frameMirror.scope(i); + var scopeObjectMirror = scopeMirror.scopeObject(); + var properties = scopeObjectMirror.properties(); + var scopeObject = {}; + for (var j = 0; j < properties.length; j++) + scopeObject[properties[j].name()] = properties[j].value_; + scopeType.push(scopeMirror.scopeType()); + scopeChain.push(scopeObject); + } + + function evaluate(expression) { + return frameMirror.evaluate(expression, false).value(); + } + + return { + "sourceID": sourceID, + "line": line, + "functionName": functionName, + "type": "function", + "thisObject": thisObject, + "scopeChain": scopeChain, + "scopeType": scopeType, + "evaluate": evaluate, + "caller": callerFrame + }; +} + +DebuggerScript._webkitToV8LineNumber = function(line) +{ + return line - 1; +}; + +DebuggerScript._v8ToWwebkitLineNumber = function(line) +{ + return line + 1; +}; + +return DebuggerScript; + +} diff --git a/WebKit/chromium/src/js/DevTools.js b/WebKit/chromium/src/js/DevTools.js index dcb181b..a530fe5 100644 --- a/WebKit/chromium/src/js/DevTools.js +++ b/WebKit/chromium/src/js/DevTools.js @@ -151,31 +151,12 @@ devtools.ToolsAgent.prototype.evaluate = function(expr) /** - * Enables / disables resources panel in the ui. - * @param {boolean} enabled New panel status. - */ -WebInspector.setResourcesPanelEnabled = function(enabled) -{ - InspectorBackend._resourceTrackingEnabled = enabled; - WebInspector.panels.resources.reset(); -}; - - -/** * Prints string to the inspector console or shows alert if the console doesn't * exist. * @param {string} text */ function debugPrint(text) { - var console = WebInspector.console; - if (console) { - console.addMessage(new WebInspector.ConsoleMessage( - WebInspector.ConsoleMessage.MessageSource.JS, - WebInspector.ConsoleMessage.MessageType.Log, - WebInspector.ConsoleMessage.MessageLevel.Log, - 1, "chrome://devtools/<internal>", undefined, -1, text)); - } else - alert(text); + WebInspector.log(text); } @@ -200,54 +181,17 @@ WebInspector.loaded = function() Preferences.ignoreWhitespace = false; Preferences.samplingCPUProfiler = true; Preferences.heapProfilerPresent = true; + Preferences.debuggerAlwaysEnabled = true; + Preferences.profilerAlwaysEnabled = true; + RemoteDebuggerAgent.setDebuggerScriptSource("(" + debuggerScriptConstructor + ")();"); + oldLoaded.call(this); InspectorFrontendHost.loaded(); }; -(function() -{ - - /** - * Handles an F3 keydown event to focus the Inspector search box. - * @param {KeyboardEvent} event Event to optionally handle - * @return {boolean} whether the event has been handled - */ - function handleF3Keydown(event) { - if (event.keyIdentifier === "F3" && !event.altKey && !event.ctrlKey && !event.shiftKey && !event.metaKey) { - var searchField = document.getElementById("search"); - searchField.focus(); - searchField.select(); - event.preventDefault(); - return true; - } - return false; - } - - - var oldKeyDown = WebInspector.documentKeyDown; - /** - * This override allows to intercept keydown events we want to handle in a - * custom way. Some nested documents (iframes) delegate keydown handling to - * WebInspector.documentKeyDown (e.g. SourceFrame). - * @param {KeyboardEvent} event - * @override - */ - WebInspector.documentKeyDown = function(event) { - var isHandled = handleF3Keydown(event); - if (!isHandled) { - // Mute refresh action. - if (event.keyIdentifier === "F5") - event.preventDefault(); - else if (event.keyIdentifier === "U+0052" /* "R" */ && (event.ctrlKey || event.metaKey)) - event.preventDefault(); - else - oldKeyDown.call(this, event); - } - }; -})(); - +if (!window.v8ScriptDebugServerEnabled) { /** * This override is necessary for adding script source asynchronously. @@ -279,24 +223,12 @@ WebInspector.ScriptView.prototype.setupSourceFrameIfNeeded = function() */ WebInspector.ScriptView.prototype.didResolveScriptSource_ = function() { - this.sourceFrame.setContent("text/javascript", this.script.source); + this.sourceFrame.setContent("text/javascript", this._prependWhitespace(this.script.source)); this._sourceFrameSetup = true; delete this._frameNeedsSetup; }; -/** - * @param {string} type Type of the the property value("object" or "function"). - * @param {string} className Class name of the property value. - * @constructor - */ -WebInspector.UnresolvedPropertyValue = function(type, className) -{ - this.type = type; - this.className = className; -}; - - (function() { var oldShow = WebInspector.ScriptsPanel.prototype.show; @@ -309,6 +241,47 @@ WebInspector.UnresolvedPropertyValue = function(type, className) })(); +(function () { +var orig = InjectedScriptAccess.prototype.getProperties; +InjectedScriptAccess.prototype.getProperties = function(objectProxy, ignoreHasOwnProperty, abbreviate, callback) +{ + if (objectProxy.isScope) + devtools.tools.getDebuggerAgent().resolveScope(objectProxy.objectId, callback); + else if (objectProxy.isV8Ref) + devtools.tools.getDebuggerAgent().resolveChildren(objectProxy.objectId, callback, false); + else + orig.apply(this, arguments); +}; +})(); + + +(function() +{ +InjectedScriptAccess.prototype.evaluateInCallFrame = function(callFrameId, code, objectGroup, callback) +{ + //TODO(pfeldman): remove once 49084 is rolled. + if (!callback) + callback = objectGroup; + devtools.tools.getDebuggerAgent().evaluateInCallFrame(callFrameId, code, callback); +}; +})(); + + +(function() +{ +var orig = InjectedScriptAccess.prototype.getCompletions; +InjectedScriptAccess.prototype.getCompletions = function(expressionString, includeInspectorCommandLineAPI, callFrameId, reportCompletions) +{ + if (typeof callFrameId === "number") + devtools.tools.getDebuggerAgent().resolveCompletionsOnFrame(expressionString, callFrameId, reportCompletions); + else + return orig.apply(this, arguments); +}; +})(); + +} + + (function InterceptProfilesPanelEvents() { var oldShow = WebInspector.ProfilesPanel.prototype.show; @@ -333,6 +306,17 @@ WebInspector.UIString = function(string) return String.vsprintf(string, Array.prototype.slice.call(arguments, 1)); }; +// Activate window upon node search complete. This will go away once InspectorFrontendClient is landed. +(function() { + var original = WebInspector.searchingForNodeWasDisabled; + WebInspector.searchingForNodeWasDisabled = function() + { + if (this.panels.elements._nodeSearchButton.toggled) + InspectorFrontendHost.bringToFront(); + original.apply(this, arguments); + } +})(); + // There is no clear way of setting frame title yet. So sniffing main resource // load. @@ -392,81 +376,6 @@ WebInspector.UIString = function(string) })(); -(function () { -var orig = InjectedScriptAccess.prototype.getProperties; -InjectedScriptAccess.prototype.getProperties = function(objectProxy, ignoreHasOwnProperty, abbreviate, callback) -{ - if (objectProxy.isScope) - devtools.tools.getDebuggerAgent().resolveScope(objectProxy.objectId, callback); - else if (objectProxy.isV8Ref) - devtools.tools.getDebuggerAgent().resolveChildren(objectProxy.objectId, callback, false); - else - orig.apply(this, arguments); -}; -})(); - - -(function() -{ -InjectedScriptAccess.prototype.evaluateInCallFrame = function(callFrameId, code, objectGroup, callback) -{ - //TODO(pfeldman): remove once 49084 is rolled. - if (!callback) - callback = objectGroup; - devtools.tools.getDebuggerAgent().evaluateInCallFrame(callFrameId, code, callback); -}; -})(); - - -WebInspector.resourceTrackingWasEnabled = function() -{ - InspectorBackend._resourceTrackingEnabled = true; - this.panels.resources.resourceTrackingWasEnabled(); -}; - -WebInspector.resourceTrackingWasDisabled = function() -{ - InspectorBackend._resourceTrackingEnabled = false; - this.panels.resources.resourceTrackingWasDisabled(); -}; - -(function() -{ -var orig = WebInspector.ConsoleMessage.prototype.setMessageBody; -WebInspector.ConsoleMessage.prototype.setMessageBody = function(args) -{ - for (var i = 0; i < args.length; ++i) { - if (typeof args[i] === "string") - args[i] = WebInspector.ObjectProxy.wrapPrimitiveValue(args[i]); - } - orig.call(this, args); -}; -})(); - - -(function() -{ -var orig = InjectedScriptAccess.prototype.getCompletions; -InjectedScriptAccess.prototype.getCompletions = function(expressionString, includeInspectorCommandLineAPI, callFrameId, reportCompletions) -{ - if (typeof callFrameId === "number") - devtools.tools.getDebuggerAgent().resolveCompletionsOnFrame(expressionString, callFrameId, reportCompletions); - else - return orig.apply(this, arguments); -}; -})(); - - -(function() -{ -WebInspector.ElementsPanel.prototype._nodeSearchButtonClicked = function( event) -{ - InspectorBackend.toggleNodeSearch(); - this.nodeSearchButton.toggled = !this.nodeSearchButton.toggled; -}; -})(); - - // We need to have a place for postponed tasks // which should be executed when all the messages between agent and frontend // are processed. @@ -498,7 +407,92 @@ InspectorFrontendHost.addResourceSourceToFrame = function(identifier, element) }; })(); -WebInspector.pausedScript = function(callFrames) +// Chromium theme support. +WebInspector.setToolbarColors = function(backgroundColor, color) { - this.panels.scripts.debuggerPaused(callFrames); -}; + if (!WebInspector._themeStyleElement) { + WebInspector._themeStyleElement = document.createElement("style"); + document.head.appendChild(WebInspector._themeStyleElement); + } + WebInspector._themeStyleElement.textContent = + "body #toolbar, body.inactive #toolbar {\ + background-image: none !important;\ + background-color: " + backgroundColor + " !important;\ + }\ + \ + body .status-bar {\ + background-image: url(Images/statusbarBackgroundChromium2.png) !important;\ + background-color: " + backgroundColor + " !important;\ + }\ + \ + body button.status-bar-item {\ + background-image: none !important;\ + }\ + \ + button.status-bar-item {\ + background-image: none;\ + border-right: 1px solid " + backgroundColor + ";\ + }\ + \ + .status-bar {\ + background-image: none;\ + color: " + color + ";\ + }\ + \ + body #drawer {\ + background-image: none !important;\ + }\ + \ + #drawer-status-bar {\ + background-image: url(Images/statusbarBackgroundChromium2.png);\ + background-color: " + backgroundColor + ";\ + }\ + \ + \ + body.drawer-visible #main-status-bar {\ + background-image: url(Images/statusbarBackgroundChromium2.png) !important;\ + }\ + \ + body .crumbs .crumb, body .crumbs .crumb.end {\ + -webkit-border-image: url(Images/segmentChromium2.png) 0 12 0 2 !important;\ + background-color: " + backgroundColor + " !important;\ + }\ + \ + body .crumbs .crumb:hover, body .crumbs .crumb.dimmed:hover {\ + -webkit-border-image: url(Images/segmentHoverChromium2.png) 0 12 0 2 !important;\ + }\ + \ + body .crumbs .crumb.end {\ + -webkit-border-image: url(Images/segmentChromium2.png) 0 12 0 2 !important;\ + }\ + \ + body .crumbs .crumb.selected:hover, body .crumbs .crumb.selected.end, .crumbs .crumb.selected.end:hover {\ + -webkit-border-image: url(Images/segmentSelectedChromium2.png) 0 12 0 2 !important;\ + }\ + \ + body select.status-bar-item {\ + -webkit-border-image: url(Images/statusbarMenuButtonChromium2.png) 0 17 0 2 !important;\ + background-color: " + backgroundColor + " !important;\ + text-shadow: none !important;\ + }\ + \ + .glyph {\ + background-color: " + color + ";\ + }\ + \ + button.status-bar-item .glyph.shadow {\ + display: none;\ + }\ + \ + .crumbs, .crumbs .crumb:hover, #drawer .scope-bar:not(.console-filter-top) li, .toolbar-label, select.status-bar-item {\ + text-shadow: none;\ + color: " + color + ";\ + }"; +} + +WebInspector.resetToolbarColors = function() +{ + if (WebInspector._themeStyleElement) + WebInspector._themeStyleElement.textContent = ""; + +} diff --git a/WebKit/chromium/src/js/DevToolsHostStub.js b/WebKit/chromium/src/js/DevToolsHostStub.js index 8b2f46b..cae4a1e 100644 --- a/WebKit/chromium/src/js/DevToolsHostStub.js +++ b/WebKit/chromium/src/js/DevToolsHostStub.js @@ -55,6 +55,11 @@ RemoteDebuggerAgentStub.prototype.processDebugCommands = function() }; +RemoteDebuggerAgentStub.prototype.setDebuggerScriptSource = function(source) +{ +}; + + /** * @constructor */ diff --git a/WebKit/chromium/src/js/HeapProfilerPanel.js b/WebKit/chromium/src/js/HeapProfilerPanel.js index abbf580..0fc4418 100644 --- a/WebKit/chromium/src/js/HeapProfilerPanel.js +++ b/WebKit/chromium/src/js/HeapProfilerPanel.js @@ -205,7 +205,7 @@ WebInspector.HeapSnapshotView.prototype = { // Call searchCanceled since it will reset everything we need before doing a new search. this.searchCanceled(); - query = query.trimWhitespace(); + query = query.trim(); if (!query.length) return; @@ -937,7 +937,7 @@ WebInspector.HeapSnapshotProfileType.prototype = { get welcomeMessage() { - return WebInspector.UIString("Get a heap snapshot by pressing<br>the %s button on the status bar."); + return WebInspector.UIString("Get a heap snapshot by pressing the %s button on the status bar."); }, createSidebarTreeElementForProfile: function(profile) diff --git a/WebKit/chromium/src/js/Images/segmentChromium2.png b/WebKit/chromium/src/js/Images/segmentChromium2.png Binary files differnew file mode 100755 index 0000000..e94f570 --- /dev/null +++ b/WebKit/chromium/src/js/Images/segmentChromium2.png diff --git a/WebKit/chromium/src/js/Images/segmentHoverChromium2.png b/WebKit/chromium/src/js/Images/segmentHoverChromium2.png Binary files differnew file mode 100755 index 0000000..4d4a211 --- /dev/null +++ b/WebKit/chromium/src/js/Images/segmentHoverChromium2.png diff --git a/WebKit/chromium/src/js/Images/segmentSelectedChromium2.png b/WebKit/chromium/src/js/Images/segmentSelectedChromium2.png Binary files differnew file mode 100755 index 0000000..f2b695b --- /dev/null +++ b/WebKit/chromium/src/js/Images/segmentSelectedChromium2.png diff --git a/WebKit/chromium/src/js/Images/statusbarBackgroundChromium2.png b/WebKit/chromium/src/js/Images/statusbarBackgroundChromium2.png Binary files differnew file mode 100755 index 0000000..12d62b1 --- /dev/null +++ b/WebKit/chromium/src/js/Images/statusbarBackgroundChromium2.png diff --git a/WebKit/chromium/src/js/Images/statusbarMenuButtonChromium2.png b/WebKit/chromium/src/js/Images/statusbarMenuButtonChromium2.png Binary files differnew file mode 100755 index 0000000..9527ac8 --- /dev/null +++ b/WebKit/chromium/src/js/Images/statusbarMenuButtonChromium2.png diff --git a/WebKit/chromium/src/js/InjectDispatch.js b/WebKit/chromium/src/js/InjectDispatch.js index e070c42..30caaf2 100644 --- a/WebKit/chromium/src/js/InjectDispatch.js +++ b/WebKit/chromium/src/js/InjectDispatch.js @@ -104,3 +104,10 @@ function dispatch(method, var_args) { var call = JSON.stringify(args); DevToolsAgentHost.dispatch(call); }; + +function close() { + // This method is called when InspectorFrontend closes in layout tests. +} + +function inspectedPageDestroyed() { +} diff --git a/WebKit/chromium/src/js/InspectorControllerImpl.js b/WebKit/chromium/src/js/InspectorControllerImpl.js index c92a94c..becc076 100644 --- a/WebKit/chromium/src/js/InspectorControllerImpl.js +++ b/WebKit/chromium/src/js/InspectorControllerImpl.js @@ -38,23 +38,30 @@ if (!this.devtools) devtools.InspectorBackendImpl = function() { WebInspector.InspectorBackendStub.call(this); + this.installInspectorControllerDelegate_("addScriptToEvaluateOnLoad"); this.installInspectorControllerDelegate_("clearMessages"); this.installInspectorControllerDelegate_("copyNode"); this.installInspectorControllerDelegate_("deleteCookie"); this.installInspectorControllerDelegate_("didEvaluateForTestInFrontend"); this.installInspectorControllerDelegate_("disableResourceTracking"); + this.installInspectorControllerDelegate_("disableSearchingForNode"); this.installInspectorControllerDelegate_("disableTimeline"); this.installInspectorControllerDelegate_("enableResourceTracking"); + this.installInspectorControllerDelegate_("enableSearchingForNode"); this.installInspectorControllerDelegate_("enableTimeline"); this.installInspectorControllerDelegate_("getChildNodes"); this.installInspectorControllerDelegate_("getCookies"); this.installInspectorControllerDelegate_("getDatabaseTableNames"); this.installInspectorControllerDelegate_("getDOMStorageEntries"); this.installInspectorControllerDelegate_("getEventListenersForNode"); + this.installInspectorControllerDelegate_("getProfile"); + this.installInspectorControllerDelegate_("getProfileHeaders"); this.installInspectorControllerDelegate_("getResourceContent"); this.installInspectorControllerDelegate_("highlightDOMNode"); this.installInspectorControllerDelegate_("hideDOMNodeHighlight"); this.installInspectorControllerDelegate_("releaseWrapperObjectGroup"); + this.installInspectorControllerDelegate_("removeAllScriptsToEvaluateOnLoad"); + this.installInspectorControllerDelegate_("reloadPage"); this.installInspectorControllerDelegate_("removeAttribute"); this.installInspectorControllerDelegate_("removeDOMStorageItem"); this.installInspectorControllerDelegate_("removeNode"); @@ -63,25 +70,39 @@ devtools.InspectorBackendImpl = function() this.installInspectorControllerDelegate_("setDOMStorageItem"); this.installInspectorControllerDelegate_("setInjectedScriptSource"); this.installInspectorControllerDelegate_("setTextNodeValue"); + this.installInspectorControllerDelegate_("startProfiling"); this.installInspectorControllerDelegate_("startTimelineProfiler"); + this.installInspectorControllerDelegate_("stopProfiling"); this.installInspectorControllerDelegate_("stopTimelineProfiler"); this.installInspectorControllerDelegate_("storeLastActivePanel"); -}; -devtools.InspectorBackendImpl.prototype.__proto__ = WebInspector.InspectorBackendStub.prototype; - -/** - * {@inheritDoc}. - */ -devtools.InspectorBackendImpl.prototype.toggleNodeSearch = function() -{ - WebInspector.InspectorBackendStub.prototype.toggleNodeSearch.call(this); - this.callInspectorController_.call(this, "toggleNodeSearch"); - if (!this.searchingForNode()) { - // This is called from ElementsPanel treeOutline's focusNodeChanged(). - DevToolsHost.activateWindow(); + this.installInspectorControllerDelegate_("getAllStyles"); + this.installInspectorControllerDelegate_("getStyles"); + this.installInspectorControllerDelegate_("getComputedStyle"); + this.installInspectorControllerDelegate_("getInlineStyle"); + this.installInspectorControllerDelegate_("applyStyleText"); + this.installInspectorControllerDelegate_("setStyleText"); + this.installInspectorControllerDelegate_("setStyleProperty"); + this.installInspectorControllerDelegate_("toggleStyleEnabled"); + this.installInspectorControllerDelegate_("setRuleSelector"); + this.installInspectorControllerDelegate_("addRule"); + + if (window.v8ScriptDebugServerEnabled) { + this.installInspectorControllerDelegate_("disableDebugger"); + this.installInspectorControllerDelegate_("enableDebugger"); + this.installInspectorControllerDelegate_("setBreakpoint"); + this.installInspectorControllerDelegate_("removeBreakpoint"); + this.installInspectorControllerDelegate_("activateBreakpoints"); + this.installInspectorControllerDelegate_("deactivateBreakpoints"); + this.installInspectorControllerDelegate_("pauseInDebugger"); + this.installInspectorControllerDelegate_("resumeDebugger"); + this.installInspectorControllerDelegate_("stepIntoStatementInDebugger"); + this.installInspectorControllerDelegate_("stepOutOfFunctionInDebugger"); + this.installInspectorControllerDelegate_("stepOverStatementInDebugger"); + this.installInspectorControllerDelegate_("setPauseOnExceptionsState"); } }; +devtools.InspectorBackendImpl.prototype.__proto__ = WebInspector.InspectorBackendStub.prototype; /** @@ -102,9 +123,13 @@ devtools.InspectorBackendImpl.prototype.profilerEnabled = function() }; -devtools.InspectorBackendImpl.prototype.addBreakpoint = function(sourceID, line, condition) +if (!window.v8ScriptDebugServerEnabled) { + +devtools.InspectorBackendImpl.prototype.setBreakpoint = function(sourceID, line, enabled, condition) { - devtools.tools.getDebuggerAgent().addBreakpoint(sourceID, line, condition); + this.removeBreakpoint(sourceID, line); + if (enabled) + devtools.tools.getDebuggerAgent().addBreakpoint(sourceID, line, condition); }; @@ -113,11 +138,27 @@ devtools.InspectorBackendImpl.prototype.removeBreakpoint = function(sourceID, li devtools.tools.getDebuggerAgent().removeBreakpoint(sourceID, line); }; -devtools.InspectorBackendImpl.prototype.updateBreakpoint = function(sourceID, line, condition) + +devtools.InspectorBackendImpl.prototype.editScriptLine = function(callID, sourceID, line, newContent) +{ + devtools.tools.getDebuggerAgent().editScriptLine(sourceID, line, newContent, function(newFullBody) { + WebInspector.didEditScriptLine(callID, newFullBody); + }); +}; + + +devtools.InspectorBackendImpl.prototype.activateBreakpoints = function() +{ + devtools.tools.getDebuggerAgent().setBreakpointsActivated(true); +}; + + +devtools.InspectorBackendImpl.prototype.deactivateBreakpoints = function() { - devtools.tools.getDebuggerAgent().updateBreakpoint(sourceID, line, condition); + devtools.tools.getDebuggerAgent().setBreakpointsActivated(false); }; + devtools.InspectorBackendImpl.prototype.pauseInDebugger = function() { devtools.tools.getDebuggerAgent().pauseExecution(); @@ -155,16 +196,10 @@ devtools.InspectorBackendImpl.prototype.setPauseOnExceptionsState = function(sta this._setPauseOnExceptionsState = state; // TODO(yurys): support all three states. See http://crbug.com/32877 var enabled = (state !== WebInspector.ScriptsPanel.PauseOnExceptionsState.DontPauseOnExceptions); - return devtools.tools.getDebuggerAgent().setPauseOnExceptions(enabled); + WebInspector.updatePauseOnExceptionsState(enabled ? WebInspector.ScriptsPanel.PauseOnExceptionsState.PauseOnUncaughtExceptions : WebInspector.ScriptsPanel.PauseOnExceptionsState.DontPauseOnExceptions); + devtools.tools.getDebuggerAgent().setPauseOnExceptions(enabled); }; -/** - * @override - */ -devtools.InspectorBackendImpl.prototype.pauseOnExceptionsState = function() -{ - return (this._setPauseOnExceptionsState || WebInspector.ScriptsPanel.PauseOnExceptionsState.DontPauseOnExceptions); -}; /** * @override @@ -183,53 +218,7 @@ devtools.InspectorBackendImpl.prototype.setPauseOnExceptions = function(value) return devtools.tools.getDebuggerAgent().setPauseOnExceptions(value); }; - -/** - * @override - */ -devtools.InspectorBackendImpl.prototype.startProfiling = function() -{ - devtools.tools.getProfilerAgent().startProfiling(devtools.ProfilerAgent.ProfilerModules.PROFILER_MODULE_CPU); -}; - - -/** - * @override - */ -devtools.InspectorBackendImpl.prototype.stopProfiling = function() -{ - devtools.tools.getProfilerAgent().stopProfiling( devtools.ProfilerAgent.ProfilerModules.PROFILER_MODULE_CPU); -}; - - -/** - * @override - */ -devtools.InspectorBackendImpl.prototype.getProfileHeaders = function(callId) -{ - WebInspector.didGetProfileHeaders(callId, []); -}; - - -/** - * Emulate WebKit InspectorController behavior. It stores profiles on renderer side, - * and is able to retrieve them by uid using "getProfile". - */ -devtools.InspectorBackendImpl.prototype.addFullProfile = function(profile) -{ - WebInspector.__fullProfiles = WebInspector.__fullProfiles || {}; - WebInspector.__fullProfiles[profile.uid] = profile; -}; - - -/** - * @override - */ -devtools.InspectorBackendImpl.prototype.getProfile = function(callId, uid) -{ - if (WebInspector.__fullProfiles && (uid in WebInspector.__fullProfiles)) - WebInspector.didGetProfile(callId, WebInspector.__fullProfiles[uid]); -}; +} /** diff --git a/WebKit/chromium/src/js/ProfilerAgent.js b/WebKit/chromium/src/js/ProfilerAgent.js index e08c5d2..29de4a3 100644 --- a/WebKit/chromium/src/js/ProfilerAgent.js +++ b/WebKit/chromium/src/js/ProfilerAgent.js @@ -41,18 +41,6 @@ devtools.ProfilerAgent = function() RemoteProfilerAgent.didGetLogLines = this._didGetLogLines.bind(this); /** - * Active profiler modules flags. - * @type {number} - */ - this._activeProfilerModules = devtools.ProfilerAgent.ProfilerModules.PROFILER_MODULE_NONE; - - /** - * Interval for polling profiler state. - * @type {number} - */ - this._getActiveProfilerModulesInterval = null; - - /** * Profiler log position. * @type {number} */ @@ -65,12 +53,6 @@ devtools.ProfilerAgent = function() this._lastRequestedLogPosition = -1; /** - * Whether log contents retrieval must be forced next time. - * @type {boolean} - */ - this._forceGetLogLines = false; - - /** * Profiler processor instance. * @type {devtools.profiler.Processor} */ @@ -92,50 +74,11 @@ devtools.ProfilerAgent.ProfilerModules = { /** - * Sets up callbacks that deal with profiles processing. - */ -devtools.ProfilerAgent.prototype.setupProfilerProcessorCallbacks = function() -{ - // A temporary icon indicating that the profile is being processed. - var processingIcon = new WebInspector.SidebarTreeElement( - "profile-sidebar-tree-item", - WebInspector.UIString("Processing..."), - '', null, false); - var profilesSidebar = WebInspector.panels.profiles.getProfileType(WebInspector.CPUProfileType.TypeId).treeElement; - - this._profilerProcessor.setCallbacks( - function onProfileProcessingStarted() { - // Set visually empty string. Subtitle hiding is done via styles - // manipulation which doesn't play well with dynamic append / removal. - processingIcon.subtitle = " "; - profilesSidebar.appendChild(processingIcon); - }, - function onProfileProcessingStatus(ticksCount) { - processingIcon.subtitle = WebInspector.UIString("%d ticks processed", ticksCount); - }, - function onProfileProcessingFinished(profile) { - profilesSidebar.removeChild(processingIcon); - profile.typeId = WebInspector.CPUProfileType.TypeId; - InspectorBackend.addFullProfile(profile); - WebInspector.addProfileHeader(profile); - // If no profile is currently shown, show the new one. - var profilesPanel = WebInspector.panels.profiles; - if (!profilesPanel.visibleView) { - profilesPanel.showProfile(profile); - } - } - ); -}; - - -/** * Initializes profiling state. */ devtools.ProfilerAgent.prototype.initializeProfiling = function() { - this.setupProfilerProcessorCallbacks(); - this._forceGetLogLines = true; - this._getActiveProfilerModulesInterval = setInterval(function() { RemoteProfilerAgent.getActiveProfilerModules(); }, 1000); + this._getNextLogLines(false); }; @@ -193,16 +136,6 @@ devtools.ProfilerAgent.prototype.stopProfiling = function(modules) */ devtools.ProfilerAgent.prototype._didGetActiveProfilerModules = function(modules) { - var profModules = devtools.ProfilerAgent.ProfilerModules; - var profModuleNone = profModules.PROFILER_MODULE_NONE; - if (this._forceGetLogLines || (modules !== profModuleNone && this._activeProfilerModules === profModuleNone)) { - this._forceGetLogLines = false; - // Start to query log data. - this._getNextLogLines(true); - } - this._activeProfilerModules = modules; - // Update buttons. - WebInspector.setRecordingProfile(modules & profModules.PROFILER_MODULE_CPU); }; @@ -214,14 +147,11 @@ devtools.ProfilerAgent.prototype._didGetActiveProfilerModules = function(modules devtools.ProfilerAgent.prototype._didGetLogLines = function(pos, log) { this._logPosition = pos; - if (log.length > 0) + if (log.length > 0) { this._profilerProcessor.processLogChunk(log); - else { + this._getNextLogLines(); + } else { // Allow re-reading from the last position. this._lastRequestedLogPosition = this._logPosition - 1; - if (this._activeProfilerModules === devtools.ProfilerAgent.ProfilerModules.PROFILER_MODULE_NONE) - // No new data and profiling is stopped---suspend log reading. - return; } - this._getNextLogLines(); }; diff --git a/WebKit/chromium/src/js/Tests.js b/WebKit/chromium/src/js/Tests.js index fa0c99f..758b8c0 100644 --- a/WebKit/chromium/src/js/Tests.js +++ b/WebKit/chromium/src/js/Tests.js @@ -295,19 +295,19 @@ TestSuite.prototype.testResourceContentLength = function() var resource = WebInspector.resources[identifier]; if (!resource || !resource.url) return; - if (resource.url.search("image.html$") !== -1) { + if (resource.url.search("image.html") !== -1) { var expectedLength = 87; test.assertTrue( - resource.contentLength <= expectedLength, + resource.resourceSize <= expectedLength, "image.html content length is greater thatn expected."); - if (expectedLength === resource.contentLength) + if (expectedLength === resource.resourceSize) html = true; } else if (resource.url.search("image.png") !== -1) { var expectedLength = 257796; test.assertTrue( - resource.contentLength <= expectedLength, + resource.resourceSize <= expectedLength, "image.png content length is greater than expected."); - if (expectedLength === resource.contentLength) + if (expectedLength === resource.resourceSize) png = true; } if (html && png) { @@ -425,39 +425,38 @@ TestSuite.prototype.testProfilerTab = function() { this.showPanel("profiles"); + var panel = WebInspector.panels.profiles; var test = this; - this.addSniffer(WebInspector.panels.profiles, "addProfileHeader", - function(typeOrProfile, profile) { - if (!profile) - profile = typeOrProfile; - var panel = WebInspector.panels.profiles; - panel.showProfile(profile); - var node = panel.visibleView.profileDataGridTree.children[0]; - // Iterate over displayed functions and search for a function - // that is called "fib" or "eternal_fib". If found, it will mean - // that we actually have profiled page's code. - while (node) { - if (node.functionName.indexOf("fib") !== -1) - test.releaseControl(); - node = node.traverseNextNode(true, null, true); - } - test.fail(); - }); - var ticksCount = 0; - var tickRecord = "\nt,"; - this.addSniffer(RemoteProfilerAgent, "didGetLogLines", - function(posIgnored, log) { - var pos = 0; - while ((pos = log.indexOf(tickRecord, pos)) !== -1) { - pos += tickRecord.length; - ticksCount++; - } - if (ticksCount > 100) - InspectorBackend.stopProfiling(); - }, true); + function findDisplayedNode() { + var node = panel.visibleView.profileDataGridTree.children[0]; + if (!node) { + // Profile hadn't been queried yet, re-schedule. + window.setTimeout(findDisplayedNode, 100); + return; + } - InspectorBackend.startProfiling(); + // Iterate over displayed functions and search for a function + // that is called "fib" or "eternal_fib". If found, this will mean + // that we actually have profiled page's code. + while (node) { + if (node.functionName.indexOf("fib") !== -1) + test.releaseControl(); + node = node.traverseNextNode(true, null, true); + } + + test.fail(); + } + + function findVisibleView() { + if (!panel.visibleView) { + setTimeout(findVisibleView, 0); + return; + } + setTimeout(findDisplayedNode, 0); + } + + findVisibleView(); this.takeControl(); }; @@ -470,7 +469,7 @@ TestSuite.prototype.testShowScriptsTab = function() this.showPanel("scripts"); var test = this; // There should be at least main page script. - this._waitUntilScriptsAreParsed(["debugger_test_page.html$"], + this._waitUntilScriptsAreParsed(["debugger_test_page.html"], function() { test.releaseControl(); }); @@ -502,7 +501,7 @@ TestSuite.prototype.testScriptsTabIsPopulatedOnInspectedPageRefresh = function() var parsed = devtools.tools.getDebuggerAgent().parsedScripts_; for (var id in parsed) { var url = parsed[id].getUrl(); - if (url && url.search("debugger_test_page.html$") !== -1) { + if (url && url.search("debugger_test_page.html") !== -1) { checkScriptsPanel(); return; } @@ -512,7 +511,7 @@ TestSuite.prototype.testScriptsTabIsPopulatedOnInspectedPageRefresh = function() function checkScriptsPanel() { test.showPanel("scripts"); - test.assertTrue(test._scriptsAreParsed(["debugger_test_page.html$"]), "Inspected script not found in the scripts list"); + test.assertTrue(test._scriptsAreParsed(["debugger_test_page.html"]), "Inspected script not found in the scripts list"); test.releaseControl(); } @@ -530,7 +529,7 @@ TestSuite.prototype.testContentScriptIsPresent = function() var test = this; test._waitUntilScriptsAreParsed( - ["page_with_content_script.html$", "simple_content_script.js$"], + ["page_with_content_script.html", "simple_content_script.js"], function() { test.releaseControl(); }); @@ -568,7 +567,7 @@ TestSuite.prototype.testNoScriptDuplicatesOnPanelSwitch = function() function checkScriptsPanel() { test.assertTrue(!!WebInspector.panels.scripts.visibleView, "No visible script view."); - test.assertTrue(test._scriptsAreParsed(["debugger_test_page.html$"]), "Some scripts are missing."); + test.assertTrue(test._scriptsAreParsed(["debugger_test_page.html"]), "Some scripts are missing."); checkNoDuplicates(); test.releaseControl(); } @@ -584,7 +583,7 @@ TestSuite.prototype.testNoScriptDuplicatesOnPanelSwitch = function() } test._waitUntilScriptsAreParsed( - ["debugger_test_page.html$"], + ["debugger_test_page.html"], function() { checkNoDuplicates(); setTimeout(switchToElementsTab, 0); @@ -635,15 +634,15 @@ TestSuite.prototype.testPauseOnException = function() // TODO(yurys): remove else branch once the states are supported. if (WebInspector.ScriptsPanel.PauseOnExceptionsState) { - while (WebInspector.currentPanel.pauseOnExceptionButton.state !== WebInspector.ScriptsPanel.PauseOnExceptionsState.PauseOnUncaughtExceptions) - WebInspector.currentPanel.pauseOnExceptionButton.element.click(); + while (WebInspector.currentPanel._pauseOnExceptionButton.state !== WebInspector.ScriptsPanel.PauseOnExceptionsState.PauseOnUncaughtExceptions) + WebInspector.currentPanel._pauseOnExceptionButton.element.click(); } else { // Make sure pause on exceptions is on. - if (!WebInspector.currentPanel.pauseOnExceptionButton.toggled) - WebInspector.currentPanel.pauseOnExceptionButton.element.click(); + if (!WebInspector.currentPanel._pauseOnExceptionButton.toggled) + WebInspector.currentPanel._pauseOnExceptionButton.element.click(); } - this._executeCodeWhenScriptsAreParsed("handleClick()", ["pause_on_exception.html$"]); + this._executeCodeWhenScriptsAreParsed("handleClick()", ["pause_on_exception.html"]); this._waitForScriptPause( { @@ -913,7 +912,7 @@ TestSuite.prototype.testCompletionOnPause = function() { this.showPanel("scripts"); var test = this; - this._executeCodeWhenScriptsAreParsed("handleClick()", ["completion_on_pause.html$"]); + this._executeCodeWhenScriptsAreParsed("handleClick()", ["completion_on_pause.html"]); this._waitForScriptPause( { @@ -974,7 +973,7 @@ TestSuite.prototype.testAutoContinueOnSyntaxError = function() // InjectedScript._ensureCommandLineAPIInstalled) since the page script // contains a syntax error. for (var i = 0 ; i < options.length; i++) { - if (options[i].text.search("script_syntax_error.html$") !== -1) + if (options[i].text.search("script_syntax_error.html") !== -1) test.fail("Script with syntax error should not be in the list of parsed scripts."); } } @@ -1173,7 +1172,7 @@ TestSuite.prototype._waitUntilScriptsAreParsed = function(expectedScripts, callb */ TestSuite.prototype._executeFunctionForStepTest = function() { - this._executeCodeWhenScriptsAreParsed("a()", ["debugger_step.html$", "debugger_step.js$"]); + this._executeCodeWhenScriptsAreParsed("a()", ["debugger_step.html", "debugger_step.js"]); }; @@ -1437,7 +1436,7 @@ TestSuite.prototype.testExpandScope = function() this.showPanel("scripts"); var test = this; - this._executeCodeWhenScriptsAreParsed("handleClick()", ["debugger_closure.html$"]); + this._executeCodeWhenScriptsAreParsed("handleClick()", ["debugger_closure.html"]); this._waitForScriptPause( { @@ -1551,7 +1550,7 @@ TestSuite.prototype.testDebugIntrinsicProperties = function() this.showPanel("scripts"); var test = this; - this._executeCodeWhenScriptsAreParsed("handleClick()", ["debugger_intrinsic_properties.html$"]); + this._executeCodeWhenScriptsAreParsed("handleClick()", ["debugger_intrinsic_properties.html"]); this._waitForScriptPause( { diff --git a/WebKit/chromium/src/linux/WebFontRenderStyle.cpp b/WebKit/chromium/src/linux/WebFontRenderStyle.cpp new file mode 100644 index 0000000..0b864d1 --- /dev/null +++ b/WebKit/chromium/src/linux/WebFontRenderStyle.cpp @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2010 Google 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: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * 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. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT + * OWNER OR 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 "WebFontRenderStyle.h" + +#include "FontRenderStyle.h" + +using WebCore::FontRenderStyle; + +namespace WebKit { + +void WebFontRenderStyle::toFontRenderStyle(FontRenderStyle* out) +{ + out->useBitmaps = useBitmaps; + out->useAutoHint = useAutoHint; + out->useHinting = useHinting; + out->hintStyle = hintStyle; + out->useAntiAlias = useAntiAlias; + out->useSubpixel = useSubpixel; +} + +void WebFontRenderStyle::setDefaults() +{ + useBitmaps = 2; + useAutoHint = 2; + useHinting = 2; + hintStyle = 0; + useAntiAlias = 2; + useSubpixel = 2; +} + +} // namespace WebKit diff --git a/WebKit/chromium/src/mac/WebInputEventFactory.mm b/WebKit/chromium/src/mac/WebInputEventFactory.mm index 46b0afe..694155f 100644 --- a/WebKit/chromium/src/mac/WebInputEventFactory.mm +++ b/WebKit/chromium/src/mac/WebInputEventFactory.mm @@ -861,6 +861,29 @@ static inline int modifiersFromEvent(NSEvent* event) { return modifiers; } +static inline void setWebEventLocationFromEventInView(WebMouseEvent* result, + NSEvent* event, + NSView* view) { + NSPoint windowLocal = [event locationInWindow]; + + NSPoint screenLocal = [[view window] convertBaseToScreen:windowLocal]; + result->globalX = screenLocal.x; + // Flip y. + NSScreen* primaryScreen = ([[NSScreen screens] count] > 0) ? + [[NSScreen screens] objectAtIndex:0] : nil; + if (primaryScreen) + result->globalY = [primaryScreen frame].size.height - screenLocal.y; + else + result->globalY = screenLocal.y; + + NSPoint contentLocal = [view convertPoint:windowLocal fromView:nil]; + result->x = contentLocal.x; + result->y = [view frame].size.height - contentLocal.y; // Flip y. + + result->windowX = result->x; + result->windowY = result->y; +} + WebKeyboardEvent WebInputEventFactory::keyboardEvent(NSEvent* event) { WebKeyboardEvent result; @@ -1021,16 +1044,7 @@ WebMouseEvent WebInputEventFactory::mouseEvent(NSEvent* event, NSView* view) ASSERT_NOT_REACHED(); } - NSPoint location = [NSEvent mouseLocation]; // global coordinates - result.globalX = location.x; - result.globalY = [[[view window] screen] frame].size.height - location.y; - - NSPoint windowLocal = [event locationInWindow]; - location = [view convertPoint:windowLocal fromView:nil]; - result.y = [view frame].size.height - location.y; // flip y - result.x = location.x; - result.windowX = result.x; - result.windowY = result.y; + setWebEventLocationFromEventInView(&result, event, view); result.modifiers = modifiersFromEvent(event); @@ -1050,16 +1064,7 @@ WebMouseWheelEvent WebInputEventFactory::mouseWheelEvent(NSEvent* event, NSView* result.modifiers = modifiersFromEvent(event); - // Set coordinates by translating event coordinates from screen to client. - NSPoint location = [NSEvent mouseLocation]; // global coordinates - result.globalX = location.x; - result.globalY = location.y; - NSPoint windowLocal = [event locationInWindow]; - location = [view convertPoint:windowLocal fromView:nil]; - result.x = location.x; - result.y = [view frame].size.height - location.y; // flip y - result.windowX = result.x; - result.windowY = result.y; + setWebEventLocationFromEventInView(&result, event, view); // Of Mice and Men // --------------- |