diff options
Diffstat (limited to 'webkit/glue/webcursor_win.cc')
-rw-r--r-- | webkit/glue/webcursor_win.cc | 203 |
1 files changed, 203 insertions, 0 deletions
diff --git a/webkit/glue/webcursor_win.cc b/webkit/glue/webcursor_win.cc new file mode 100644 index 0000000..8671367 --- /dev/null +++ b/webkit/glue/webcursor_win.cc @@ -0,0 +1,203 @@ +// Copyright (c) 2008 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 "config.h" +#include "NativeImageSkia.h" +#include "PlatformCursor.h" + +#undef LOG +#include "base/gfx/gdi_util.h" +#include "base/logging.h" +#include "skia/include/SkBitmap.h" +#include "webkit/glue/webcursor.h" +#include "webkit/glue/webkit_resources.h" + +using WebCore::PlatformCursor; + +static LPCWSTR ToCursorID(PlatformCursor::Type type) { + switch (type) { + case PlatformCursor::typePointer: + return IDC_ARROW; + case PlatformCursor::typeCross: + return IDC_CROSS; + case PlatformCursor::typeHand: + return IDC_HAND; + case PlatformCursor::typeIBeam: + return IDC_IBEAM; + case PlatformCursor::typeWait: + return IDC_WAIT; + case PlatformCursor::typeHelp: + return IDC_HELP; + case PlatformCursor::typeEastResize: + return IDC_SIZEWE; + case PlatformCursor::typeNorthResize: + return IDC_SIZENS; + case PlatformCursor::typeNorthEastResize: + return IDC_SIZENESW; + case PlatformCursor::typeNorthWestResize: + return IDC_SIZENWSE; + case PlatformCursor::typeSouthResize: + return IDC_SIZENS; + case PlatformCursor::typeSouthEastResize: + return IDC_SIZENWSE; + case PlatformCursor::typeSouthWestResize: + return IDC_SIZENESW; + case PlatformCursor::typeWestResize: + return IDC_SIZEWE; + case PlatformCursor::typeNorthSouthResize: + return IDC_SIZENS; + case PlatformCursor::typeEastWestResize: + return IDC_SIZEWE; + case PlatformCursor::typeNorthEastSouthWestResize: + return IDC_SIZENESW; + case PlatformCursor::typeNorthWestSouthEastResize: + return IDC_SIZENWSE; + case PlatformCursor::typeColumnResize: + return MAKEINTRESOURCE(IDC_COLRESIZE); + case PlatformCursor::typeRowResize: + return MAKEINTRESOURCE(IDC_ROWRESIZE); + case PlatformCursor::typeMiddlePanning: + return MAKEINTRESOURCE(IDC_PAN_MIDDLE); + case PlatformCursor::typeEastPanning: + return MAKEINTRESOURCE(IDC_PAN_EAST); + case PlatformCursor::typeNorthPanning: + return MAKEINTRESOURCE(IDC_PAN_NORTH); + case PlatformCursor::typeNorthEastPanning: + return MAKEINTRESOURCE(IDC_PAN_NORTH_EAST); + case PlatformCursor::typeNorthWestPanning: + return MAKEINTRESOURCE(IDC_PAN_NORTH_WEST); + case PlatformCursor::typeSouthPanning: + return MAKEINTRESOURCE(IDC_PAN_SOUTH); + case PlatformCursor::typeSouthEastPanning: + return MAKEINTRESOURCE(IDC_PAN_SOUTH_EAST); + case PlatformCursor::typeSouthWestPanning: + return MAKEINTRESOURCE(IDC_PAN_SOUTH_WEST); + case PlatformCursor::typeWestPanning: + return MAKEINTRESOURCE(IDC_PAN_WEST); + case PlatformCursor::typeMove: + return IDC_SIZEALL; + case PlatformCursor::typeVerticalText: + return MAKEINTRESOURCE(IDC_VERTICALTEXT); + case PlatformCursor::typeCell: + return MAKEINTRESOURCE(IDC_CELL); + case PlatformCursor::typeContextMenu: + return MAKEINTRESOURCE(IDC_ARROW); + case PlatformCursor::typeAlias: + return MAKEINTRESOURCE(IDC_ALIAS); + case PlatformCursor::typeProgress: + return IDC_APPSTARTING; + case PlatformCursor::typeNoDrop: + return IDC_NO; + case PlatformCursor::typeCopy: + return MAKEINTRESOURCE(IDC_COPYCUR); + case PlatformCursor::typeNone: + return IDC_ARROW; + case PlatformCursor::typeNotAllowed: + return IDC_NO; + case PlatformCursor::typeZoomIn: + return MAKEINTRESOURCE(IDC_ZOOMIN); + case PlatformCursor::typeZoomOut: + return MAKEINTRESOURCE(IDC_ZOOMOUT); + } + NOTREACHED(); + return NULL; +} + +static bool IsSystemCursorID(LPCWSTR cursor_id) { + return cursor_id >= IDC_ARROW; // See WinUser.h +} + +static PlatformCursor::Type ToPlatformCursorType(HCURSOR cursor) { + static struct { + HCURSOR cursor; + PlatformCursor::Type type; + } kStandardCursors[] = { + { LoadCursor(NULL, IDC_ARROW), PlatformCursor::typePointer }, + { LoadCursor(NULL, IDC_IBEAM), PlatformCursor::typeIBeam }, + { LoadCursor(NULL, IDC_WAIT), PlatformCursor::typeWait }, + { LoadCursor(NULL, IDC_CROSS), PlatformCursor::typeCross }, + { LoadCursor(NULL, IDC_SIZENWSE), PlatformCursor::typeNorthWestResize }, + { LoadCursor(NULL, IDC_SIZENESW), PlatformCursor::typeNorthEastResize }, + { LoadCursor(NULL, IDC_SIZEWE), PlatformCursor::typeEastWestResize }, + { LoadCursor(NULL, IDC_SIZENS), PlatformCursor::typeNorthSouthResize }, + { LoadCursor(NULL, IDC_SIZEALL), PlatformCursor::typeMove }, + { LoadCursor(NULL, IDC_NO), PlatformCursor::typeNotAllowed }, + { LoadCursor(NULL, IDC_HAND), PlatformCursor::typeHand }, + { LoadCursor(NULL, IDC_APPSTARTING), PlatformCursor::typeProgress }, + { LoadCursor(NULL, IDC_HELP), PlatformCursor::typeHelp }, + }; + for (int i = 0; i < arraysize(kStandardCursors); i++) { + if (cursor == kStandardCursors[i].cursor) + return kStandardCursors[i].type; + } + return PlatformCursor::typePointer; +} + +HCURSOR WebCursor::GetCursor(HINSTANCE module_handle) const { + if (IsCustom()) + return NULL; + + LPCWSTR cursor_id = ToCursorID(static_cast<PlatformCursor::Type>(type_)); + + if (IsSystemCursorID(cursor_id)) + module_handle = NULL; + + return LoadCursor(module_handle, cursor_id); +} + +HCURSOR WebCursor::GetCustomCursor() const { + if (!IsCustom()) + return NULL; + + BITMAPINFO cursor_bitmap_info = {0}; + gfx::CreateBitmapHeader( + custom_size_.width(), custom_size_.height(), + reinterpret_cast<BITMAPINFOHEADER*>(&cursor_bitmap_info)); + HDC dc = GetDC(0); + HDC workingDC = CreateCompatibleDC(dc); + HBITMAP bitmap_handle = CreateDIBSection( + dc, &cursor_bitmap_info, DIB_RGB_COLORS, 0, 0, 0); + SetDIBits( + 0, bitmap_handle, 0, custom_size_.height(), &custom_data_[0], + &cursor_bitmap_info, DIB_RGB_COLORS); + + HBITMAP old_bitmap = reinterpret_cast<HBITMAP>( + SelectObject(workingDC, bitmap_handle)); + SetBkMode(workingDC, TRANSPARENT); + SelectObject(workingDC, old_bitmap); + + HBITMAP mask = CreateBitmap( + custom_size_.width(), custom_size_.height(), 1, 1, NULL); + ICONINFO ii = {0}; + ii.fIcon = FALSE; + ii.xHotspot = hotspot_.x(); + ii.yHotspot = hotspot_.y(); + ii.hbmMask = mask; + ii.hbmColor = bitmap_handle; + + HCURSOR cursor_handle = CreateIconIndirect(&ii); + + DeleteObject(mask); + DeleteObject(bitmap_handle); + DeleteDC(workingDC); + ReleaseDC(0, dc); + return cursor_handle; +} + +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()); +} |