Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "webkit/glue/webcursor.h" | 5 #include "webkit/glue/webcursor.h" |
| 6 | 6 |
| 7 #import <AppKit/AppKit.h> | 7 #import <AppKit/AppKit.h> |
| 8 | 8 |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/mac/mac_util.h" | 10 #include "base/mac/mac_util.h" |
| 11 #include "base/mac/scoped_cftyperef.h" | 11 #include "base/mac/scoped_cftyperef.h" |
| 12 #include "base/memory/scoped_nsobject.h" | 12 #include "base/memory/scoped_nsobject.h" |
| 13 #include "grit/webkit_chromium_resources.h" | 13 #include "grit/webkit_chromium_resources.h" |
| 14 #include "skia/ext/skia_utils_mac.h" | 14 #include "skia/ext/skia_utils_mac.h" |
| 15 #include "third_party/WebKit/Source/WebKit/chromium/public/WebCursorInfo.h" | 15 #include "third_party/WebKit/Source/WebKit/chromium/public/WebCursorInfo.h" |
| 16 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebImage.h" | 16 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebImage.h" |
| 17 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebSize.h" | 17 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebSize.h" |
| 18 #include "ui/base/resource/resource_bundle.h" | 18 #include "ui/base/resource/resource_bundle.h" |
| 19 #include "ui/gfx/point_conversions.h" | |
| 20 #include "ui/gfx/size_conversions.h" | |
| 19 | 21 |
| 20 | 22 |
| 21 using WebKit::WebCursorInfo; | 23 using WebKit::WebCursorInfo; |
| 22 using WebKit::WebImage; | 24 using WebKit::WebImage; |
| 23 using WebKit::WebSize; | 25 using WebKit::WebSize; |
| 24 | 26 |
| 25 // Declare symbols that are part of the 10.7 SDK. | 27 // Declare symbols that are part of the 10.7 SDK. |
| 26 #if !defined(MAC_OS_X_VERSION_10_7) || \ | 28 #if !defined(MAC_OS_X_VERSION_10_7) || \ |
| 27 MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7 | 29 MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7 |
| 28 | 30 |
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 168 8, | 170 8, |
| 169 size.width()*4, | 171 size.width()*4, |
| 170 cg_color.get(), | 172 cg_color.get(), |
| 171 kCGImageAlphaPremultipliedLast | | 173 kCGImageAlphaPremultipliedLast | |
| 172 kCGBitmapByteOrder32Big)); | 174 kCGBitmapByteOrder32Big)); |
| 173 return CGBitmapContextCreateImage(context.get()); | 175 return CGBitmapContextCreateImage(context.get()); |
| 174 } | 176 } |
| 175 | 177 |
| 176 NSCursor* CreateCustomCursor(const std::vector<char>& custom_data, | 178 NSCursor* CreateCustomCursor(const std::vector<char>& custom_data, |
| 177 const gfx::Size& custom_size, | 179 const gfx::Size& custom_size, |
| 180 float custom_scale, | |
| 178 const gfx::Point& hotspot) { | 181 const gfx::Point& hotspot) { |
| 179 // If the data is missing, leave the backing transparent. | 182 // If the data is missing, leave the backing transparent. |
| 180 void* data = NULL; | 183 void* data = NULL; |
| 181 size_t data_size = 0; | 184 size_t data_size = 0; |
| 182 if (!custom_data.empty()) { | 185 if (!custom_data.empty()) { |
| 183 // This is safe since we're not going to draw into the context we're | 186 // This is safe since we're not going to draw into the context we're |
| 184 // creating. | 187 // creating. |
| 185 data = const_cast<char*>(&custom_data[0]); | 188 data = const_cast<char*>(&custom_data[0]); |
| 186 data_size = custom_data.size(); | 189 data_size = custom_data.size(); |
| 187 } | 190 } |
| 188 | 191 |
| 189 // If the size is empty, use a 1x1 transparent image. | 192 // If the size is empty, use a 1x1 transparent image. |
| 190 gfx::Size size = custom_size; | 193 gfx::Size size = custom_size; |
| 191 if (size.IsEmpty()) { | 194 if (size.IsEmpty()) { |
| 192 size.SetSize(1, 1); | 195 size.SetSize(1, 1); |
| 193 data = NULL; | 196 data = NULL; |
| 194 } | 197 } |
| 195 | 198 |
| 196 SkBitmap bitmap; | 199 SkBitmap bitmap; |
| 197 bitmap.setConfig(SkBitmap::kARGB_8888_Config, size.width(), size.height()); | 200 bitmap.setConfig(SkBitmap::kARGB_8888_Config, size.width(), size.height()); |
| 198 bitmap.allocPixels(); | 201 bitmap.allocPixels(); |
| 199 if (data) | 202 if (data) |
| 200 memcpy(bitmap.getAddr32(0, 0), data, data_size); | 203 memcpy(bitmap.getAddr32(0, 0), data, data_size); |
| 201 else | 204 else |
| 202 bitmap.eraseARGB(0, 0, 0, 0); | 205 bitmap.eraseARGB(0, 0, 0, 0); |
| 206 | |
| 207 // Convert from pixels to view units. | |
| 208 if (custom_scale == 0) | |
| 209 custom_scale = 1; | |
| 210 NSSize dip_size = NSSizeFromCGSize(gfx::ToFlooredSize( | |
| 211 gfx::ScaleSize(custom_size, 1 / custom_scale)).ToCGSize()); | |
| 212 NSPoint dip_hotspot = NSPointFromCGPoint(gfx::ToFlooredPoint( | |
| 213 gfx::ScalePoint(hotspot, 1 / custom_scale)).ToCGPoint()); | |
| 214 | |
| 203 NSImage* cursor_image = gfx::SkBitmapToNSImage(bitmap); | 215 NSImage* cursor_image = gfx::SkBitmapToNSImage(bitmap); |
| 216 [cursor_image setSize:dip_size]; | |
| 204 | 217 |
| 205 NSCursor* cursor = [[NSCursor alloc] initWithImage:cursor_image | 218 NSCursor* cursor = [[NSCursor alloc] initWithImage:cursor_image |
| 206 hotSpot:NSMakePoint(hotspot.x(), | 219 hotSpot:dip_hotspot]; |
| 207 hotspot.y())]; | |
| 208 | 220 |
| 209 return [cursor autorelease]; | 221 return [cursor autorelease]; |
| 210 } | 222 } |
| 211 | 223 |
| 212 } // namespace | 224 } // namespace |
| 213 | 225 |
| 214 // Match Safari's cursor choices; see platform/mac/CursorMac.mm . | 226 // Match Safari's cursor choices; see platform/mac/CursorMac.mm . |
| 215 gfx::NativeCursor WebCursor::GetNativeCursor() { | 227 gfx::NativeCursor WebCursor::GetNativeCursor() { |
| 216 switch (type_) { | 228 switch (type_) { |
| 217 case WebCursorInfo::TypePointer: | 229 case WebCursorInfo::TypePointer: |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 290 case WebCursorInfo::TypeVerticalText: | 302 case WebCursorInfo::TypeVerticalText: |
| 291 // IBeamCursorForVerticalLayout is >= 10.7. | 303 // IBeamCursorForVerticalLayout is >= 10.7. |
| 292 if ([NSCursor respondsToSelector:@selector(IBeamCursorForVerticalLayout)]) | 304 if ([NSCursor respondsToSelector:@selector(IBeamCursorForVerticalLayout)]) |
| 293 return [NSCursor IBeamCursorForVerticalLayout]; | 305 return [NSCursor IBeamCursorForVerticalLayout]; |
| 294 else | 306 else |
| 295 return LoadCursor(IDR_VERTICALTEXT_CURSOR, 7, 7); | 307 return LoadCursor(IDR_VERTICALTEXT_CURSOR, 7, 7); |
| 296 case WebCursorInfo::TypeCell: | 308 case WebCursorInfo::TypeCell: |
| 297 return GetCoreCursorWithFallback(kCellCursor, | 309 return GetCoreCursorWithFallback(kCellCursor, |
| 298 IDR_CELL_CURSOR, 7, 7); | 310 IDR_CELL_CURSOR, 7, 7); |
| 299 case WebCursorInfo::TypeContextMenu: | 311 case WebCursorInfo::TypeContextMenu: |
| 300 // contextualMenuCursor is >= 10.6. | 312 return [NSCursor contextualMenuCursor]; |
| 301 if ([NSCursor respondsToSelector:@selector(contextualMenuCursor)]) | |
| 302 return [NSCursor contextualMenuCursor]; | |
| 303 else | |
| 304 return LoadCursor(IDR_CONTEXTMENU_CURSOR, 3, 2); | |
|
Avi (use Gerrit)
2012/12/14 21:46:26
Are we dropping the bundling of the bitmaps we no
Nico
2012/12/14 21:49:37
Good question! It looks like IDR_CONTEXTMENU_CURSO
| |
| 305 case WebCursorInfo::TypeAlias: | 313 case WebCursorInfo::TypeAlias: |
| 306 return GetCoreCursorWithFallback(kMakeAliasCursor, | 314 return GetCoreCursorWithFallback(kMakeAliasCursor, |
| 307 IDR_ALIAS_CURSOR, 11, 3); | 315 IDR_ALIAS_CURSOR, 11, 3); |
| 308 case WebCursorInfo::TypeProgress: | 316 case WebCursorInfo::TypeProgress: |
| 309 return GetCoreCursorWithFallback(kBusyButClickableCursor, | 317 return GetCoreCursorWithFallback(kBusyButClickableCursor, |
| 310 IDR_PROGRESS_CURSOR, 3, 2); | 318 IDR_PROGRESS_CURSOR, 3, 2); |
| 311 case WebCursorInfo::TypeNoDrop: | 319 case WebCursorInfo::TypeNoDrop: |
| 312 case WebCursorInfo::TypeNotAllowed: | 320 case WebCursorInfo::TypeNotAllowed: |
| 313 // Docs say that operationNotAllowedCursor is >= 10.6, and it's not in the | |
| 314 // 10.5 SDK, but later SDKs note that it really is available on 10.5. | |
| 315 return [NSCursor operationNotAllowedCursor]; | 321 return [NSCursor operationNotAllowedCursor]; |
| 316 case WebCursorInfo::TypeCopy: | 322 case WebCursorInfo::TypeCopy: |
| 317 // dragCopyCursor is >= 10.6. | 323 return [NSCursor dragCopyCursor]; |
| 318 if ([NSCursor respondsToSelector:@selector(dragCopyCursor)]) | |
| 319 return [NSCursor dragCopyCursor]; | |
| 320 else | |
| 321 return LoadCursor(IDR_COPY_CURSOR, 3, 2); | |
|
Avi (use Gerrit)
2012/12/14 21:52:15
And IDR_COPY_CURSOR too.
| |
| 322 case WebCursorInfo::TypeNone: | 324 case WebCursorInfo::TypeNone: |
| 323 return LoadCursor(IDR_NONE_CURSOR, 7, 7); | 325 return LoadCursor(IDR_NONE_CURSOR, 7, 7); |
| 324 case WebCursorInfo::TypeZoomIn: | 326 case WebCursorInfo::TypeZoomIn: |
| 325 return GetCoreCursorWithFallback(kZoomInCursor, | 327 return GetCoreCursorWithFallback(kZoomInCursor, |
| 326 IDR_ZOOMIN_CURSOR, 7, 7); | 328 IDR_ZOOMIN_CURSOR, 7, 7); |
| 327 case WebCursorInfo::TypeZoomOut: | 329 case WebCursorInfo::TypeZoomOut: |
| 328 return GetCoreCursorWithFallback(kZoomOutCursor, | 330 return GetCoreCursorWithFallback(kZoomOutCursor, |
| 329 IDR_ZOOMOUT_CURSOR, 7, 7); | 331 IDR_ZOOMOUT_CURSOR, 7, 7); |
| 330 case WebCursorInfo::TypeGrab: | 332 case WebCursorInfo::TypeGrab: |
| 331 return [NSCursor openHandCursor]; | 333 return [NSCursor openHandCursor]; |
| 332 case WebCursorInfo::TypeGrabbing: | 334 case WebCursorInfo::TypeGrabbing: |
| 333 return [NSCursor closedHandCursor]; | 335 return [NSCursor closedHandCursor]; |
| 334 case WebCursorInfo::TypeCustom: | 336 case WebCursorInfo::TypeCustom: |
| 335 return CreateCustomCursor(custom_data_, custom_size_, hotspot_); | 337 return CreateCustomCursor( |
| 338 custom_data_, custom_size_, custom_scale_, hotspot_); | |
| 336 } | 339 } |
| 337 NOTREACHED(); | 340 NOTREACHED(); |
| 338 return nil; | 341 return nil; |
| 339 } | 342 } |
| 340 | 343 |
| 341 void WebCursor::InitFromNSCursor(NSCursor* cursor) { | 344 void WebCursor::InitFromNSCursor(NSCursor* cursor) { |
| 342 WebKit::WebCursorInfo cursor_info; | 345 WebKit::WebCursorInfo cursor_info; |
| 343 | 346 |
| 344 if ([cursor isEqual:[NSCursor arrowCursor]]) { | 347 if ([cursor isEqual:[NSCursor arrowCursor]]) { |
| 345 cursor_info.type = WebCursorInfo::TypePointer; | 348 cursor_info.type = WebCursorInfo::TypePointer; |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 360 } else if ([cursor isEqual:[NSCursor resizeDownCursor]]) { | 363 } else if ([cursor isEqual:[NSCursor resizeDownCursor]]) { |
| 361 cursor_info.type = WebCursorInfo::TypeSouthResize; | 364 cursor_info.type = WebCursorInfo::TypeSouthResize; |
| 362 } else if ([cursor isEqual:[NSCursor resizeUpDownCursor]]) { | 365 } else if ([cursor isEqual:[NSCursor resizeUpDownCursor]]) { |
| 363 cursor_info.type = WebCursorInfo::TypeNorthSouthResize; | 366 cursor_info.type = WebCursorInfo::TypeNorthSouthResize; |
| 364 } else if ([cursor isEqual:[NSCursor openHandCursor]]) { | 367 } else if ([cursor isEqual:[NSCursor openHandCursor]]) { |
| 365 cursor_info.type = WebCursorInfo::TypeGrab; | 368 cursor_info.type = WebCursorInfo::TypeGrab; |
| 366 } else if ([cursor isEqual:[NSCursor closedHandCursor]]) { | 369 } else if ([cursor isEqual:[NSCursor closedHandCursor]]) { |
| 367 cursor_info.type = WebCursorInfo::TypeGrabbing; | 370 cursor_info.type = WebCursorInfo::TypeGrabbing; |
| 368 } else if ([cursor isEqual:[NSCursor operationNotAllowedCursor]]) { | 371 } else if ([cursor isEqual:[NSCursor operationNotAllowedCursor]]) { |
| 369 cursor_info.type = WebCursorInfo::TypeNotAllowed; | 372 cursor_info.type = WebCursorInfo::TypeNotAllowed; |
| 370 } else if ([NSCursor respondsToSelector:@selector(dragCopyCursor)] && | 373 } else if ([cursor isEqual:[NSCursor dragCopyCursor]]) { |
| 371 [cursor isEqual:[NSCursor dragCopyCursor]]) { | |
| 372 cursor_info.type = WebCursorInfo::TypeCopy; | 374 cursor_info.type = WebCursorInfo::TypeCopy; |
| 373 } else if ([NSCursor respondsToSelector:@selector(contextualMenuCursor)] && | 375 } else if ([cursor isEqual:[NSCursor contextualMenuCursor]]) { |
| 374 [cursor isEqual:[NSCursor contextualMenuCursor]]) { | |
| 375 cursor_info.type = WebCursorInfo::TypeContextMenu; | 376 cursor_info.type = WebCursorInfo::TypeContextMenu; |
| 376 } else if ( | 377 } else if ( |
| 377 [NSCursor respondsToSelector:@selector(IBeamCursorForVerticalLayout)] && | 378 [NSCursor respondsToSelector:@selector(IBeamCursorForVerticalLayout)] && |
| 378 [cursor isEqual:[NSCursor IBeamCursorForVerticalLayout]]) { | 379 [cursor isEqual:[NSCursor IBeamCursorForVerticalLayout]]) { |
| 379 cursor_info.type = WebCursorInfo::TypeVerticalText; | 380 cursor_info.type = WebCursorInfo::TypeVerticalText; |
| 380 } else { | 381 } else { |
| 381 // Also handles the [NSCursor disappearingItemCursor] case. Quick-and-dirty | 382 // Also handles the [NSCursor disappearingItemCursor] case. Quick-and-dirty |
| 382 // image conversion; TODO(avi): do better. | 383 // image conversion; TODO(avi): do better. |
| 383 CGImageRef cg_image = nil; | 384 CGImageRef cg_image = nil; |
| 384 NSImage* image = [cursor image]; | 385 NSImage* image = [cursor image]; |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 418 return true; | 419 return true; |
| 419 } | 420 } |
| 420 | 421 |
| 421 void WebCursor::CleanupPlatformData() { | 422 void WebCursor::CleanupPlatformData() { |
| 422 return; | 423 return; |
| 423 } | 424 } |
| 424 | 425 |
| 425 void WebCursor::CopyPlatformData(const WebCursor& other) { | 426 void WebCursor::CopyPlatformData(const WebCursor& other) { |
| 426 return; | 427 return; |
| 427 } | 428 } |
| OLD | NEW |