diff options
author | evanm@google.com <evanm@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-11-14 18:45:26 +0000 |
---|---|---|
committer | evanm@google.com <evanm@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-11-14 18:45:26 +0000 |
commit | 2b99be2e12968b5d3d4f5818d6a76a8d42d818bc (patch) | |
tree | 89d180b90aa94bed3fa0d887bbf44e229b164cdf | |
parent | 03f95811129d967c67942cbc8fd20572476c95d7 (diff) | |
download | chromium_src-2b99be2e12968b5d3d4f5818d6a76a8d42d818bc.zip chromium_src-2b99be2e12968b5d3d4f5818d6a76a8d42d818bc.tar.gz chromium_src-2b99be2e12968b5d3d4f5818d6a76a8d42d818bc.tar.bz2 |
Custom cursor support.
This is necessary for Google Maps, and also cuts out another NOTIMPLEMENTED().
Review URL: http://codereview.chromium.org/10734
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@5487 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | webkit/glue/webcursor.cc | 22 | ||||
-rw-r--r-- | webkit/glue/webcursor.h | 9 | ||||
-rw-r--r-- | webkit/glue/webcursor_gtk.cc | 25 | ||||
-rw-r--r-- | webkit/glue/webcursor_win.cc | 12 | ||||
-rw-r--r-- | webkit/tools/test_shell/test_webview_delegate_gtk.cc | 22 |
5 files changed, 67 insertions, 23 deletions
diff --git a/webkit/glue/webcursor.cc b/webkit/glue/webcursor.cc index e001a11..acda43f 100644 --- a/webkit/glue/webcursor.cc +++ b/webkit/glue/webcursor.cc @@ -2,13 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "webkit/glue/webcursor.h" + #include "config.h" +#include "NativeImageSkia.h" #include "PlatformCursor.h" #undef LOG #include "base/logging.h" #include "base/pickle.h" -#include "webkit/glue/webcursor.h" WebCursor::WebCursor() : type_(WebCore::PlatformCursor::typePointer) { @@ -76,9 +78,23 @@ bool WebCursor::IsEqual(const WebCursor& other) const { custom_data_ == other.custom_data_; } -#if !defined(OS_WIN) +#if !defined(OS_MACOSX) +void WebCursor::SetCustomData(WebCore::Image* image) { + WebCore::NativeImagePtr image_ptr = image->nativeImageForCurrentFrame(); + if (!image_ptr) + return; + + // Fill custom_data_ directly with the NativeImage pixels. + SkAutoLockPixels bitmap_lock(*image_ptr); + custom_data_.resize(image_ptr->getSize()); + memcpy(&custom_data_[0], image_ptr->getPixels(), image_ptr->getSize()); + custom_size_.set_width(image_ptr->width()); + custom_size_.set_height(image_ptr->height()); +} +#else +// The above code should work on the Mac to but evanm was getting forward +// declaration errors. void WebCursor::SetCustomData(WebCore::Image* image) { - // Please create webcursor_{$platform}.cc for your port. NOTIMPLEMENTED(); } #endif diff --git a/webkit/glue/webcursor.h b/webkit/glue/webcursor.h index 7775751..71f309b 100644 --- a/webkit/glue/webcursor.h +++ b/webkit/glue/webcursor.h @@ -65,13 +65,22 @@ class WebCursor { // Return the stock GdkCursorType for this cursor, or GDK_CURSOR_IS_PIXMAP // if it's a custom cursor. GdkCursorType GetCursorType() const; + + // Return a new GdkCursor* for this cursor. Only valid if GetCursorType + // returns GDK_CURSOR_IS_PIXMAP. + GdkCursor* GetCustomCursor() const; #endif private: void SetCustomData(WebCore::Image* image); + // WebCore::PlatformCursor type. int type_; + gfx::Point hotspot_; + + // Custom cursor data, as 32-bit RGBA. + // Platform-inspecific because it can be serialized. gfx::Size custom_size_; std::vector<char> custom_data_; }; diff --git a/webkit/glue/webcursor_gtk.cc b/webkit/glue/webcursor_gtk.cc index 6224804..6607d67 100644 --- a/webkit/glue/webcursor_gtk.cc +++ b/webkit/glue/webcursor_gtk.cc @@ -4,6 +4,8 @@ #include "webkit/glue/webcursor.h" +#include <gdk/gdk.h> + #include "config.h" #include "PlatformCursor.h" @@ -105,3 +107,26 @@ GdkCursorType WebCursor::GetCursorType() const { NOTREACHED(); return GDK_ARROW; } + +GdkCursor* WebCursor::GetCustomCursor() const { + const guchar* data = reinterpret_cast<const guchar*>(&custom_data_[0]); + GdkPixbuf* pixbuf = + gdk_pixbuf_new_from_data(data, + GDK_COLORSPACE_RGB, + TRUE, // has_alpha + 8, // bits_per_sample + custom_size_.width(), // width + custom_size_.height(), // height + custom_size_.width() * 4, // row stride + NULL, // data destroy function + NULL); // data destroy function extra data + + GdkCursor* cursor = gdk_cursor_new_from_pixbuf(gdk_display_get_default(), + pixbuf, + hotspot_.x(), + hotspot_.y()); + + gdk_pixbuf_unref(pixbuf); + + return cursor; +} diff --git a/webkit/glue/webcursor_win.cc b/webkit/glue/webcursor_win.cc index 8671367..f4d05d8 100644 --- a/webkit/glue/webcursor_win.cc +++ b/webkit/glue/webcursor_win.cc @@ -189,15 +189,3 @@ void WebCursor::InitFromCursor(HCURSOR cursor) { // TODO(iyengar) Add support for custom cursors. *this = WebCursor(ToPlatformCursorType(cursor)); } - -void WebCursor::SetCustomData(WebCore::Image* image) { - WebCore::NativeImagePtr image_ptr = image->nativeImageForCurrentFrame(); - if (!image_ptr) - return; - - SkAutoLockPixels bitmap_lock(*image_ptr); - custom_data_.resize(image_ptr->getSize()); - memcpy(&custom_data_[0], image_ptr->getPixels(), image_ptr->getSize()); - custom_size_.set_width(image_ptr->width()); - custom_size_.set_height(image_ptr->height()); -} diff --git a/webkit/tools/test_shell/test_webview_delegate_gtk.cc b/webkit/tools/test_shell/test_webview_delegate_gtk.cc index 5e1b80e..1b93d9c 100644 --- a/webkit/tools/test_shell/test_webview_delegate_gtk.cc +++ b/webkit/tools/test_shell/test_webview_delegate_gtk.cc @@ -72,15 +72,21 @@ void TestWebViewDelegate::CloseWidgetSoon(WebWidget* webwidget) { void TestWebViewDelegate::SetCursor(WebWidget* webwidget, const WebCursor& cursor) { GdkCursorType cursor_type = cursor.GetCursorType(); - if (cursor_type_ == cursor_type) - return; - - cursor_type_ = cursor_type; - if (cursor_type_ == GDK_CURSOR_IS_PIXMAP) { - NOTIMPLEMENTED(); - cursor_type = GDK_ARROW; // Just a hack for now. + GdkCursor* gdk_cursor; + if (cursor_type == GDK_CURSOR_IS_PIXMAP) { + // TODO(port): WebKit bug https://bugs.webkit.org/show_bug.cgi?id=16388 is + // that calling gdk_window_set_cursor repeatedly is expensive. We should + // avoid it here where possible. + gdk_cursor = cursor.GetCustomCursor(); + } else { + // Optimize the common case, where the cursor hasn't changed. + // However, we can switch between different pixmaps, so only on the + // non-pixmap branch. + if (cursor_type_ == cursor_type) + return; + gdk_cursor = gdk_cursor_new(cursor_type); } - GdkCursor* gdk_cursor = gdk_cursor_new(cursor_type); + cursor_type_ = cursor_type; gdk_window_set_cursor(shell_->webViewWnd()->window, gdk_cursor); // The window now owns the cursor. gdk_cursor_unref(gdk_cursor); |