summaryrefslogtreecommitdiffstats
path: root/webkit/glue/webcursor_win.cc
diff options
context:
space:
mode:
Diffstat (limited to 'webkit/glue/webcursor_win.cc')
-rw-r--r--webkit/glue/webcursor_win.cc203
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());
+}