1c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file. 4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "webkit/glue/webcursor.h" 6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/logging.h" 8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/pickle.h" 972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "third_party/WebKit/Source/WebKit/chromium/public/WebCursorInfo.h" 1072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "third_party/WebKit/Source/WebKit/chromium/public/WebImage.h" 11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing WebKit::WebCursorInfo; 13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing WebKit::WebImage; 14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const int kMaxCursorDimension = 1024; 16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 17c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochWebCursor::WebCursor() 18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : type_(WebCursorInfo::TypePointer) { 19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch InitPlatformData(); 20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 22c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochWebCursor::WebCursor(const WebCursorInfo& cursor_info) 23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch : type_(WebCursorInfo::TypePointer) { 24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch InitPlatformData(); 25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch InitFromCursorInfo(cursor_info); 26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 28c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochWebCursor::~WebCursor() { 29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Clear(); 30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 32c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochWebCursor::WebCursor(const WebCursor& other) { 33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch InitPlatformData(); 34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Copy(other); 35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst WebCursor& WebCursor::operator=(const WebCursor& other) { 38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (this == &other) 39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return *this; 40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Clear(); 42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Copy(other); 43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return *this; 44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid WebCursor::InitFromCursorInfo(const WebCursorInfo& cursor_info) { 47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch Clear(); 48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_WIN) 50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (cursor_info.externalHandle) { 51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch InitFromExternalCursor(cursor_info.externalHandle); 52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif 55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch type_ = cursor_info.type; 57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch hotspot_ = cursor_info.hotSpot; 58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (IsCustom()) 59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SetCustomData(cursor_info.customImage); 603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick ClampHotspot(); 61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid WebCursor::GetCursorInfo(WebCursorInfo* cursor_info) const { 64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch cursor_info->type = static_cast<WebCursorInfo::Type>(type_); 65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch cursor_info->hotSpot = hotspot_; 66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ImageFromCustomData(&cursor_info->customImage); 67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if defined(OS_WIN) 69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch cursor_info->externalHandle = external_cursor_; 70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif 71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool WebCursor::Deserialize(const Pickle* pickle, void** iter) { 74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int type, hotspot_x, hotspot_y, size_x, size_y, data_len; 75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const char* data; 77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Leave |this| unmodified unless we are going to return success. 79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!pickle->ReadInt(iter, &type) || 80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch !pickle->ReadInt(iter, &hotspot_x) || 81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch !pickle->ReadInt(iter, &hotspot_y) || 82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch !pickle->ReadLength(iter, &size_x) || 83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch !pickle->ReadLength(iter, &size_y) || 84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch !pickle->ReadData(iter, &data, &data_len)) 85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Ensure the size is sane, and there is enough data. 88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (size_x > kMaxCursorDimension || 89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch size_y > kMaxCursorDimension) 90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch type_ = type; 93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 9421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (type == WebCursorInfo::TypeCustom) { 9521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (size_x > 0 && size_y > 0) { 9621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // The * 4 is because the expected format is an array of RGBA pixel 9721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen // values. 9821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (size_x * size_y * 4 > data_len) 9921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen return false; 10021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 10121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen hotspot_.set_x(hotspot_x); 10221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen hotspot_.set_y(hotspot_y); 10321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen custom_size_.set_width(size_x); 10421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen custom_size_.set_height(size_y); 10521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen ClampHotspot(); 10621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen 10721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen custom_data_.clear(); 10821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen if (data_len > 0) { 10921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen custom_data_.resize(data_len); 11021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen memcpy(&custom_data_[0], data, data_len); 11121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 11221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen } 113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return DeserializePlatformData(pickle, iter); 115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool WebCursor::Serialize(Pickle* pickle) const { 118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!pickle->WriteInt(type_) || 119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch !pickle->WriteInt(hotspot_.x()) || 120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch !pickle->WriteInt(hotspot_.y()) || 121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch !pickle->WriteInt(custom_size_.width()) || 122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch !pickle->WriteInt(custom_size_.height())) 123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const char* data = NULL; 126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!custom_data_.empty()) 127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch data = &custom_data_[0]; 128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!pickle->WriteData(data, custom_data_.size())) 129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return SerializePlatformData(pickle); 132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool WebCursor::IsCustom() const { 135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return type_ == WebCursorInfo::TypeCustom; 136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochbool WebCursor::IsEqual(const WebCursor& other) const { 139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (type_ != other.type_) 140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!IsPlatformDataEqual(other)) 143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return false; 144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return hotspot_ == other.hotspot_ && 146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch custom_size_ == other.custom_size_ && 147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch custom_data_ == other.custom_data_; 148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid WebCursor::Clear() { 151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch type_ = WebCursorInfo::TypePointer; 152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch hotspot_.set_x(0); 153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch hotspot_.set_y(0); 154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch custom_size_.set_width(0); 155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch custom_size_.set_height(0); 156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch custom_data_.clear(); 157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CleanupPlatformData(); 158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid WebCursor::Copy(const WebCursor& other) { 161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch type_ = other.type_; 162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch hotspot_ = other.hotspot_; 163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch custom_size_ = other.custom_size_; 164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch custom_data_ = other.custom_data_; 165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch CopyPlatformData(other); 166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#if WEBKIT_USING_SKIA 169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// The WEBKIT_USING_CG implementation is in webcursor_mac.mm. 170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid WebCursor::SetCustomData(const WebImage& image) { 171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (image.isNull()) 172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Fill custom_data_ directly with the NativeImage pixels. 175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const SkBitmap& bitmap = image.getSkBitmap(); 176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SkAutoLockPixels bitmap_lock(bitmap); 177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch custom_data_.resize(bitmap.getSize()); 178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!custom_data_.empty()) 179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch memcpy(&custom_data_[0], bitmap.getPixels(), bitmap.getSize()); 180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch custom_size_.set_width(bitmap.width()); 181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch custom_size_.set_height(bitmap.height()); 182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid WebCursor::ImageFromCustomData(WebImage* image) const { 185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (custom_data_.empty()) 186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch SkBitmap bitmap; 189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bitmap.setConfig(SkBitmap::kARGB_8888_Config, 190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch custom_size_.width(), 191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch custom_size_.height()); 192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (!bitmap.allocPixels()) 193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return; 194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch memcpy(bitmap.getPixels(), &custom_data_[0], custom_data_.size()); 195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch image->assign(bitmap); 197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif 1993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid WebCursor::ClampHotspot() { 2013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (!IsCustom()) 2023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick return; 2033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 2043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Clamp the hotspot to the custom image's dimensions. 2053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick hotspot_.set_x(std::max(0, 2063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::min(custom_size_.width() - 1, hotspot_.x()))); 2073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick hotspot_.set_y(std::max(0, 2083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::min(custom_size_.height() - 1, hotspot_.y()))); 2093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick} 210