blob: e825adf244ef951c0772ae2fcdf9f908bef0050a [file] [log] [blame]
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/logging.h"
#include "base/pickle.h"
#include "grit/ui_unscaled_resources.h"
#include "third_party/WebKit/public/platform/WebCursorInfo.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "ui/gfx/icon_util.h"
#include "webkit/common/cursors/webcursor.h"
using blink::WebCursorInfo;
static LPCWSTR ToCursorID(WebCursorInfo::Type type) {
switch (type) {
case WebCursorInfo::TypePointer:
return IDC_ARROW;
case WebCursorInfo::TypeCross:
return IDC_CROSS;
case WebCursorInfo::TypeHand:
return IDC_HAND;
case WebCursorInfo::TypeIBeam:
return IDC_IBEAM;
case WebCursorInfo::TypeWait:
return IDC_WAIT;
case WebCursorInfo::TypeHelp:
return IDC_HELP;
case WebCursorInfo::TypeEastResize:
return IDC_SIZEWE;
case WebCursorInfo::TypeNorthResize:
return IDC_SIZENS;
case WebCursorInfo::TypeNorthEastResize:
return IDC_SIZENESW;
case WebCursorInfo::TypeNorthWestResize:
return IDC_SIZENWSE;
case WebCursorInfo::TypeSouthResize:
return IDC_SIZENS;
case WebCursorInfo::TypeSouthEastResize:
return IDC_SIZENWSE;
case WebCursorInfo::TypeSouthWestResize:
return IDC_SIZENESW;
case WebCursorInfo::TypeWestResize:
return IDC_SIZEWE;
case WebCursorInfo::TypeNorthSouthResize:
return IDC_SIZENS;
case WebCursorInfo::TypeEastWestResize:
return IDC_SIZEWE;
case WebCursorInfo::TypeNorthEastSouthWestResize:
return IDC_SIZENESW;
case WebCursorInfo::TypeNorthWestSouthEastResize:
return IDC_SIZENWSE;
case WebCursorInfo::TypeColumnResize:
return MAKEINTRESOURCE(IDC_COLRESIZE);
case WebCursorInfo::TypeRowResize:
return MAKEINTRESOURCE(IDC_ROWRESIZE);
case WebCursorInfo::TypeMiddlePanning:
return MAKEINTRESOURCE(IDC_PAN_MIDDLE);
case WebCursorInfo::TypeEastPanning:
return MAKEINTRESOURCE(IDC_PAN_EAST);
case WebCursorInfo::TypeNorthPanning:
return MAKEINTRESOURCE(IDC_PAN_NORTH);
case WebCursorInfo::TypeNorthEastPanning:
return MAKEINTRESOURCE(IDC_PAN_NORTH_EAST);
case WebCursorInfo::TypeNorthWestPanning:
return MAKEINTRESOURCE(IDC_PAN_NORTH_WEST);
case WebCursorInfo::TypeSouthPanning:
return MAKEINTRESOURCE(IDC_PAN_SOUTH);
case WebCursorInfo::TypeSouthEastPanning:
return MAKEINTRESOURCE(IDC_PAN_SOUTH_EAST);
case WebCursorInfo::TypeSouthWestPanning:
return MAKEINTRESOURCE(IDC_PAN_SOUTH_WEST);
case WebCursorInfo::TypeWestPanning:
return MAKEINTRESOURCE(IDC_PAN_WEST);
case WebCursorInfo::TypeMove:
return IDC_SIZEALL;
case WebCursorInfo::TypeVerticalText:
return MAKEINTRESOURCE(IDC_VERTICALTEXT);
case WebCursorInfo::TypeCell:
return MAKEINTRESOURCE(IDC_CELL);
case WebCursorInfo::TypeContextMenu:
return MAKEINTRESOURCE(IDC_ARROW);
case WebCursorInfo::TypeAlias:
return MAKEINTRESOURCE(IDC_ALIAS);
case WebCursorInfo::TypeProgress:
return IDC_APPSTARTING;
case WebCursorInfo::TypeNoDrop:
return IDC_NO;
case WebCursorInfo::TypeCopy:
return MAKEINTRESOURCE(IDC_COPYCUR);
case WebCursorInfo::TypeNone:
return MAKEINTRESOURCE(IDC_CURSOR_NONE);
case WebCursorInfo::TypeNotAllowed:
return IDC_NO;
case WebCursorInfo::TypeZoomIn:
return MAKEINTRESOURCE(IDC_ZOOMIN);
case WebCursorInfo::TypeZoomOut:
return MAKEINTRESOURCE(IDC_ZOOMOUT);
case WebCursorInfo::TypeGrab:
return MAKEINTRESOURCE(IDC_HAND_GRAB);
case WebCursorInfo::TypeGrabbing:
return MAKEINTRESOURCE(IDC_HAND_GRABBING);
}
NOTREACHED();
return NULL;
}
static bool IsSystemCursorID(LPCWSTR cursor_id) {
return cursor_id >= IDC_ARROW; // See WinUser.h
}
HCURSOR WebCursor::GetCursor(HINSTANCE module_handle){
if (!IsCustom()) {
const wchar_t* cursor_id =
ToCursorID(static_cast<WebCursorInfo::Type>(type_));
if (IsSystemCursorID(cursor_id))
module_handle = NULL;
return LoadCursor(module_handle, cursor_id);
}
if (custom_cursor_) {
DCHECK(external_cursor_ == NULL);
return custom_cursor_;
}
if (external_cursor_)
return external_cursor_;
custom_cursor_ =
IconUtil::CreateCursorFromDIB(
custom_size_,
hotspot_,
!custom_data_.empty() ? &custom_data_[0] : NULL,
custom_data_.size());
return custom_cursor_;
}
gfx::NativeCursor WebCursor::GetNativeCursor() {
return GetCursor(NULL);
}
void WebCursor::InitPlatformData() {
custom_cursor_ = NULL;
}
bool WebCursor::SerializePlatformData(Pickle* pickle) const {
// There are some issues with converting certain HCURSORS to bitmaps. The
// HCURSOR being a user object can be marshaled as is.
// HCURSORs are always 32 bits on Windows, even on 64 bit systems.
return pickle->WriteUInt32(reinterpret_cast<uint32>(external_cursor_));
}
bool WebCursor::DeserializePlatformData(PickleIterator* iter) {
return iter->ReadUInt32(reinterpret_cast<uint32*>(&external_cursor_));
}
bool WebCursor::IsPlatformDataEqual(const WebCursor& other) const {
if (!IsCustom())
return true;
return (external_cursor_ == other.external_cursor_);
}
void WebCursor::CopyPlatformData(const WebCursor& other) {
external_cursor_ = other.external_cursor_;
// The custom_cursor_ member will be initialized to a HCURSOR the next time
// the GetCursor member function is invoked on this WebCursor instance. The
// cursor is created using the data in the custom_data_ vector.
custom_cursor_ = NULL;
}
void WebCursor::CleanupPlatformData() {
external_cursor_ = NULL;
if (custom_cursor_) {
DestroyIcon(custom_cursor_);
custom_cursor_ = NULL;
}
}