| 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 "ui/base/cursor/cursor_loader_x11.h" | 5 #include "ui/base/cursor/cursor_loader_x11.h" |
| 6 | 6 |
| 7 #include <float.h> | 7 #include <float.h> |
| 8 #include <X11/cursorfont.h> | 8 #include <X11/cursorfont.h> |
| 9 #include <X11/Xlib.h> | 9 #include <X11/Xlib.h> |
| 10 | 10 |
| 11 #include "base/logging.h" | 11 #include "base/logging.h" |
| 12 #include "build/build_config.h" | 12 #include "build/build_config.h" |
| 13 #include "skia/ext/image_operations.h" | 13 #include "skia/ext/image_operations.h" |
| 14 #include "ui/base/cursor/cursor.h" | 14 #include "ui/base/cursor/cursor.h" |
| 15 #include "ui/base/cursor/cursor_util.h" | 15 #include "ui/base/cursor/cursor_util.h" |
| 16 #include "ui/base/cursor/cursors_aura.h" | 16 #include "ui/base/cursor/cursors_aura.h" |
| 17 #include "ui/base/x/x11_util.h" | 17 #include "ui/base/x/x11_util.h" |
| 18 #include "ui/display/display.h" | 18 #include "ui/display/display.h" |
| 19 #include "ui/gfx/geometry/point_conversions.h" | 19 #include "ui/gfx/geometry/point_conversions.h" |
| 20 #include "ui/gfx/geometry/size_conversions.h" | 20 #include "ui/gfx/geometry/size_conversions.h" |
| 21 #include "ui/gfx/image/image.h" | 21 #include "ui/gfx/image/image.h" |
| 22 #include "ui/gfx/skbitmap_operations.h" | 22 #include "ui/gfx/skbitmap_operations.h" |
| 23 #include "ui/gfx/skia_util.h" | 23 #include "ui/gfx/skia_util.h" |
| 24 | 24 |
| 25 namespace { | 25 namespace { |
| 26 | 26 |
| 27 // Returns CSS cursor name from an Aura cursor ID. | 27 // Returns CSS cursor name from an Aura cursor ID. |
| 28 const char* CursorCssNameFromId(int id) { | 28 const char* CursorCssNameFromId(ui::CursorType id) { |
| 29 switch (id) { | 29 switch (id) { |
| 30 case ui::kCursorMiddlePanning: | 30 case ui::CursorType::kMiddlePanning: |
| 31 return "all-scroll"; | 31 return "all-scroll"; |
| 32 case ui::kCursorEastPanning: | 32 case ui::CursorType::kEastPanning: |
| 33 return "e-resize"; | 33 return "e-resize"; |
| 34 case ui::kCursorNorthPanning: | 34 case ui::CursorType::kNorthPanning: |
| 35 return "n-resize"; | 35 return "n-resize"; |
| 36 case ui::kCursorNorthEastPanning: | 36 case ui::CursorType::kNorthEastPanning: |
| 37 return "ne-resize"; | 37 return "ne-resize"; |
| 38 case ui::kCursorNorthWestPanning: | 38 case ui::CursorType::kNorthWestPanning: |
| 39 return "nw-resize"; | 39 return "nw-resize"; |
| 40 case ui::kCursorSouthPanning: | 40 case ui::CursorType::kSouthPanning: |
| 41 return "s-resize"; | 41 return "s-resize"; |
| 42 case ui::kCursorSouthEastPanning: | 42 case ui::CursorType::kSouthEastPanning: |
| 43 return "se-resize"; | 43 return "se-resize"; |
| 44 case ui::kCursorSouthWestPanning: | 44 case ui::CursorType::kSouthWestPanning: |
| 45 return "sw-resize"; | 45 return "sw-resize"; |
| 46 case ui::kCursorWestPanning: | 46 case ui::CursorType::kWestPanning: |
| 47 return "w-resize"; | 47 return "w-resize"; |
| 48 case ui::kCursorNone: | 48 case ui::CursorType::kNone: |
| 49 return "none"; | 49 return "none"; |
| 50 case ui::kCursorGrab: | 50 case ui::CursorType::kGrab: |
| 51 return "grab"; | 51 return "grab"; |
| 52 case ui::kCursorGrabbing: | 52 case ui::CursorType::kGrabbing: |
| 53 return "grabbing"; | 53 return "grabbing"; |
| 54 | 54 |
| 55 #if defined(OS_CHROMEOS) | 55 #if defined(OS_CHROMEOS) |
| 56 case ui::kCursorNull: | 56 case ui::CursorType::kNull: |
| 57 case ui::kCursorPointer: | 57 case ui::CursorType::kPointer: |
| 58 case ui::kCursorNoDrop: | 58 case ui::CursorType::kNoDrop: |
| 59 case ui::kCursorNotAllowed: | 59 case ui::CursorType::kNotAllowed: |
| 60 case ui::kCursorCopy: | 60 case ui::CursorType::kCopy: |
| 61 case ui::kCursorMove: | 61 case ui::CursorType::kMove: |
| 62 case ui::kCursorEastResize: | 62 case ui::CursorType::kEastResize: |
| 63 case ui::kCursorNorthResize: | 63 case ui::CursorType::kNorthResize: |
| 64 case ui::kCursorSouthResize: | 64 case ui::CursorType::kSouthResize: |
| 65 case ui::kCursorWestResize: | 65 case ui::CursorType::kWestResize: |
| 66 case ui::kCursorNorthEastResize: | 66 case ui::CursorType::kNorthEastResize: |
| 67 case ui::kCursorNorthWestResize: | 67 case ui::CursorType::kNorthWestResize: |
| 68 case ui::kCursorSouthWestResize: | 68 case ui::CursorType::kSouthWestResize: |
| 69 case ui::kCursorSouthEastResize: | 69 case ui::CursorType::kSouthEastResize: |
| 70 case ui::kCursorIBeam: | 70 case ui::CursorType::kIBeam: |
| 71 case ui::kCursorAlias: | 71 case ui::CursorType::kAlias: |
| 72 case ui::kCursorCell: | 72 case ui::CursorType::kCell: |
| 73 case ui::kCursorContextMenu: | 73 case ui::CursorType::kContextMenu: |
| 74 case ui::kCursorCross: | 74 case ui::CursorType::kCross: |
| 75 case ui::kCursorHelp: | 75 case ui::CursorType::kHelp: |
| 76 case ui::kCursorWait: | 76 case ui::CursorType::kWait: |
| 77 case ui::kCursorNorthSouthResize: | 77 case ui::CursorType::kNorthSouthResize: |
| 78 case ui::kCursorEastWestResize: | 78 case ui::CursorType::kEastWestResize: |
| 79 case ui::kCursorNorthEastSouthWestResize: | 79 case ui::CursorType::kNorthEastSouthWestResize: |
| 80 case ui::kCursorNorthWestSouthEastResize: | 80 case ui::CursorType::kNorthWestSouthEastResize: |
| 81 case ui::kCursorProgress: | 81 case ui::CursorType::kProgress: |
| 82 case ui::kCursorColumnResize: | 82 case ui::CursorType::kColumnResize: |
| 83 case ui::kCursorRowResize: | 83 case ui::CursorType::kRowResize: |
| 84 case ui::kCursorVerticalText: | 84 case ui::CursorType::kVerticalText: |
| 85 case ui::kCursorZoomIn: | 85 case ui::CursorType::kZoomIn: |
| 86 case ui::kCursorZoomOut: | 86 case ui::CursorType::kZoomOut: |
| 87 case ui::kCursorHand: | 87 case ui::CursorType::kHand: |
| 88 case ui::CursorType::kDndNone: |
| 89 case ui::CursorType::kDndMove: |
| 90 case ui::CursorType::kDndCopy: |
| 91 case ui::CursorType::kDndLink: |
| 88 // In some environments, the image assets are not set (e.g. in | 92 // In some environments, the image assets are not set (e.g. in |
| 89 // content-browsertests, content-shell etc.). | 93 // content-browsertests, content-shell etc.). |
| 90 return "left_ptr"; | 94 return "left_ptr"; |
| 91 #else // defined(OS_CHROMEOS) | 95 #else // defined(OS_CHROMEOS) |
| 92 case ui::kCursorNull: | 96 case ui::CursorType::kNull: |
| 93 return "left_ptr"; | 97 return "left_ptr"; |
| 94 case ui::kCursorPointer: | 98 case ui::CursorType::kPointer: |
| 95 return "left_ptr"; | 99 return "left_ptr"; |
| 96 case ui::kCursorMove: | 100 case ui::CursorType::kMove: |
| 97 // Returning "move" is the correct thing here, but Blink doesn't | 101 // Returning "move" is the correct thing here, but Blink doesn't |
| 98 // make a distinction between move and all-scroll. Other | 102 // make a distinction between move and all-scroll. Other |
| 99 // platforms use a cursor more consistent with all-scroll, so | 103 // platforms use a cursor more consistent with all-scroll, so |
| 100 // use that. | 104 // use that. |
| 101 return "all-scroll"; | 105 return "all-scroll"; |
| 102 case ui::kCursorCross: | 106 case ui::CursorType::kCross: |
| 103 return "crosshair"; | 107 return "crosshair"; |
| 104 case ui::kCursorHand: | 108 case ui::CursorType::kHand: |
| 105 return "pointer"; | 109 return "pointer"; |
| 106 case ui::kCursorIBeam: | 110 case ui::CursorType::kIBeam: |
| 107 return "text"; | 111 return "text"; |
| 108 case ui::kCursorProgress: | 112 case ui::CursorType::kProgress: |
| 109 return "progress"; | 113 return "progress"; |
| 110 case ui::kCursorWait: | 114 case ui::CursorType::kWait: |
| 111 return "wait"; | 115 return "wait"; |
| 112 case ui::kCursorHelp: | 116 case ui::CursorType::kHelp: |
| 113 return "help"; | 117 return "help"; |
| 114 case ui::kCursorEastResize: | 118 case ui::CursorType::kEastResize: |
| 115 return "e-resize"; | 119 return "e-resize"; |
| 116 case ui::kCursorNorthResize: | 120 case ui::CursorType::kNorthResize: |
| 117 return "n-resize"; | 121 return "n-resize"; |
| 118 case ui::kCursorNorthEastResize: | 122 case ui::CursorType::kNorthEastResize: |
| 119 return "ne-resize"; | 123 return "ne-resize"; |
| 120 case ui::kCursorNorthWestResize: | 124 case ui::CursorType::kNorthWestResize: |
| 121 return "nw-resize"; | 125 return "nw-resize"; |
| 122 case ui::kCursorSouthResize: | 126 case ui::CursorType::kSouthResize: |
| 123 return "s-resize"; | 127 return "s-resize"; |
| 124 case ui::kCursorSouthEastResize: | 128 case ui::CursorType::kSouthEastResize: |
| 125 return "se-resize"; | 129 return "se-resize"; |
| 126 case ui::kCursorSouthWestResize: | 130 case ui::CursorType::kSouthWestResize: |
| 127 return "sw-resize"; | 131 return "sw-resize"; |
| 128 case ui::kCursorWestResize: | 132 case ui::CursorType::kWestResize: |
| 129 return "w-resize"; | 133 return "w-resize"; |
| 130 case ui::kCursorNorthSouthResize: | 134 case ui::CursorType::kNorthSouthResize: |
| 131 return "ns-resize"; | 135 return "ns-resize"; |
| 132 case ui::kCursorEastWestResize: | 136 case ui::CursorType::kEastWestResize: |
| 133 return "ew-resize"; | 137 return "ew-resize"; |
| 134 case ui::kCursorColumnResize: | 138 case ui::CursorType::kColumnResize: |
| 135 return "col-resize"; | 139 return "col-resize"; |
| 136 case ui::kCursorRowResize: | 140 case ui::CursorType::kRowResize: |
| 137 return "row-resize"; | 141 return "row-resize"; |
| 138 case ui::kCursorNorthEastSouthWestResize: | 142 case ui::CursorType::kNorthEastSouthWestResize: |
| 139 return "nesw-resize"; | 143 return "nesw-resize"; |
| 140 case ui::kCursorNorthWestSouthEastResize: | 144 case ui::CursorType::kNorthWestSouthEastResize: |
| 141 return "nwse-resize"; | 145 return "nwse-resize"; |
| 142 case ui::kCursorVerticalText: | 146 case ui::CursorType::kVerticalText: |
| 143 return "vertical-text"; | 147 return "vertical-text"; |
| 144 case ui::kCursorZoomIn: | 148 case ui::CursorType::kZoomIn: |
| 145 return "zoom-in"; | 149 return "zoom-in"; |
| 146 case ui::kCursorZoomOut: | 150 case ui::CursorType::kZoomOut: |
| 147 return "zoom-out"; | 151 return "zoom-out"; |
| 148 case ui::kCursorCell: | 152 case ui::CursorType::kCell: |
| 149 return "cell"; | 153 return "cell"; |
| 150 case ui::kCursorContextMenu: | 154 case ui::CursorType::kContextMenu: |
| 151 return "context-menu"; | 155 return "context-menu"; |
| 152 case ui::kCursorAlias: | 156 case ui::CursorType::kAlias: |
| 153 return "alias"; | 157 return "alias"; |
| 154 case ui::kCursorNoDrop: | 158 case ui::CursorType::kNoDrop: |
| 155 return "no-drop"; | 159 return "no-drop"; |
| 156 case ui::kCursorCopy: | 160 case ui::CursorType::kCopy: |
| 157 return "copy"; | 161 return "copy"; |
| 158 case ui::kCursorNotAllowed: | 162 case ui::CursorType::kNotAllowed: |
| 159 return "not-allowed"; | 163 return "not-allowed"; |
| 160 case ui::kCursorDndNone: | 164 case ui::CursorType::kDndNone: |
| 161 return "dnd-none"; | 165 return "dnd-none"; |
| 162 case ui::kCursorDndMove: | 166 case ui::CursorType::kDndMove: |
| 163 return "dnd-move"; | 167 return "dnd-move"; |
| 164 case ui::kCursorDndCopy: | 168 case ui::CursorType::kDndCopy: |
| 165 return "dnd-copy"; | 169 return "dnd-copy"; |
| 166 case ui::kCursorDndLink: | 170 case ui::CursorType::kDndLink: |
| 167 return "dnd-link"; | 171 return "dnd-link"; |
| 168 #endif // defined(OS_CHROMEOS) | 172 #endif // defined(OS_CHROMEOS) |
| 169 case ui::kCursorCustom: | 173 case ui::CursorType::kCustom: |
| 170 NOTREACHED(); | 174 NOTREACHED(); |
| 171 return "left_ptr"; | 175 return "left_ptr"; |
| 172 } | 176 } |
| 173 NOTREACHED() << "Case not handled for " << id; | 177 NOTREACHED() << "Case not handled for " << static_cast<int>(id); |
| 174 return "left_ptr"; | 178 return "left_ptr"; |
| 175 } | 179 } |
| 176 | 180 |
| 177 static const struct { | 181 static const struct { |
| 178 const char* css_name; | 182 const char* css_name; |
| 179 const char* fallback_name; | 183 const char* fallback_name; |
| 180 int fallback_shape; | 184 int fallback_shape; |
| 181 } kCursorFallbacks[] = { | 185 } kCursorFallbacks[] = { |
| 182 { "pointer", "hand", XC_hand2 }, | 186 { "pointer", "hand", XC_hand2 }, |
| 183 { "progress", "left_ptr_watch", XC_watch }, | 187 { "progress", "left_ptr_watch", XC_watch }, |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 228 } | 232 } |
| 229 | 233 |
| 230 CursorLoaderX11::CursorLoaderX11() | 234 CursorLoaderX11::CursorLoaderX11() |
| 231 : display_(gfx::GetXDisplay()), | 235 : display_(gfx::GetXDisplay()), |
| 232 invisible_cursor_(CreateInvisibleCursor(), gfx::GetXDisplay()) {} | 236 invisible_cursor_(CreateInvisibleCursor(), gfx::GetXDisplay()) {} |
| 233 | 237 |
| 234 CursorLoaderX11::~CursorLoaderX11() { | 238 CursorLoaderX11::~CursorLoaderX11() { |
| 235 UnloadAll(); | 239 UnloadAll(); |
| 236 } | 240 } |
| 237 | 241 |
| 238 void CursorLoaderX11::LoadImageCursor(int id, | 242 void CursorLoaderX11::LoadImageCursor(CursorType id, |
| 239 int resource_id, | 243 int resource_id, |
| 240 const gfx::Point& hot) { | 244 const gfx::Point& hot) { |
| 241 SkBitmap bitmap; | 245 SkBitmap bitmap; |
| 242 gfx::Point hotspot = hot; | 246 gfx::Point hotspot = hot; |
| 243 | 247 |
| 244 GetImageCursorBitmap(resource_id, scale(), rotation(), &hotspot, &bitmap); | 248 GetImageCursorBitmap(resource_id, scale(), rotation(), &hotspot, &bitmap); |
| 245 XcursorImage* x_image = SkBitmapToXcursorImage(&bitmap, hotspot); | 249 XcursorImage* x_image = SkBitmapToXcursorImage(&bitmap, hotspot); |
| 246 image_cursors_[id].reset(new ImageCursor(x_image, scale(), rotation())); | 250 image_cursors_[id].reset(new ImageCursor(x_image, scale(), rotation())); |
| 247 } | 251 } |
| 248 | 252 |
| 249 void CursorLoaderX11::LoadAnimatedCursor(int id, | 253 void CursorLoaderX11::LoadAnimatedCursor(CursorType id, |
| 250 int resource_id, | 254 int resource_id, |
| 251 const gfx::Point& hot, | 255 const gfx::Point& hot, |
| 252 int frame_delay_ms) { | 256 int frame_delay_ms) { |
| 253 std::vector<SkBitmap> bitmaps; | 257 std::vector<SkBitmap> bitmaps; |
| 254 gfx::Point hotspot = hot; | 258 gfx::Point hotspot = hot; |
| 255 | 259 |
| 256 GetAnimatedCursorBitmaps(resource_id, scale(), rotation(), &hotspot, | 260 GetAnimatedCursorBitmaps(resource_id, scale(), rotation(), &hotspot, |
| 257 &bitmaps); | 261 &bitmaps); |
| 258 | 262 |
| 259 XcursorImages* x_images = XcursorImagesCreate(bitmaps.size()); | 263 XcursorImages* x_images = XcursorImagesCreate(bitmaps.size()); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 276 for (const auto& cursor : animated_cursors_) { | 280 for (const auto& cursor : animated_cursors_) { |
| 277 XcursorImagesDestroy( | 281 XcursorImagesDestroy( |
| 278 cursor.second.second); // also frees individual frames. | 282 cursor.second.second); // also frees individual frames. |
| 279 XFreeCursor(gfx::GetXDisplay(), cursor.second.first); | 283 XFreeCursor(gfx::GetXDisplay(), cursor.second.first); |
| 280 } | 284 } |
| 281 } | 285 } |
| 282 | 286 |
| 283 void CursorLoaderX11::SetPlatformCursor(gfx::NativeCursor* cursor) { | 287 void CursorLoaderX11::SetPlatformCursor(gfx::NativeCursor* cursor) { |
| 284 DCHECK(cursor); | 288 DCHECK(cursor); |
| 285 | 289 |
| 286 if (*cursor == kCursorNone) { | 290 if (*cursor == CursorType::kNone) { |
| 287 cursor->SetPlatformCursor(invisible_cursor_.get()); | 291 cursor->SetPlatformCursor(invisible_cursor_.get()); |
| 288 return; | 292 return; |
| 289 } | 293 } |
| 290 | 294 |
| 291 if (*cursor == kCursorCustom) | 295 if (*cursor == CursorType::kCustom) |
| 292 return; | 296 return; |
| 293 | 297 |
| 294 cursor->set_device_scale_factor(scale()); | 298 cursor->set_device_scale_factor(scale()); |
| 295 cursor->SetPlatformCursor(CursorFromId(cursor->native_type())); | 299 cursor->SetPlatformCursor(CursorFromId(cursor->native_type())); |
| 296 } | 300 } |
| 297 | 301 |
| 298 const XcursorImage* CursorLoaderX11::GetXcursorImageForTest(int id) { | 302 const XcursorImage* CursorLoaderX11::GetXcursorImageForTest(CursorType id) { |
| 299 return test::GetCachedXcursorImage(image_cursors_[id]->cursor); | 303 return test::GetCachedXcursorImage(image_cursors_[id]->cursor); |
| 300 } | 304 } |
| 301 | 305 |
| 302 bool CursorLoaderX11::IsImageCursor(gfx::NativeCursor native_cursor) { | 306 bool CursorLoaderX11::IsImageCursor(gfx::NativeCursor native_cursor) { |
| 303 int type = native_cursor.native_type(); | 307 CursorType type = native_cursor.native_type(); |
| 304 return image_cursors_.count(type) || animated_cursors_.count(type); | 308 return image_cursors_.count(type) || animated_cursors_.count(type); |
| 305 } | 309 } |
| 306 | 310 |
| 307 ::Cursor CursorLoaderX11::CursorFromId(int id) { | 311 ::Cursor CursorLoaderX11::CursorFromId(CursorType id) { |
| 308 const char* css_name = CursorCssNameFromId(id); | 312 const char* css_name = CursorCssNameFromId(id); |
| 309 | 313 |
| 310 auto font_it = font_cursors_.find(id); | 314 auto font_it = font_cursors_.find(id); |
| 311 if (font_it != font_cursors_.end()) | 315 if (font_it != font_cursors_.end()) |
| 312 return font_it->second; | 316 return font_it->second; |
| 313 auto image_it = image_cursors_.find(id); | 317 auto image_it = image_cursors_.find(id); |
| 314 if (image_it != image_cursors_.end()) { | 318 if (image_it != image_cursors_.end()) { |
| 315 if (image_it->second->scale == scale() && | 319 if (image_it->second->scale == scale() && |
| 316 image_it->second->rotation == rotation()) { | 320 image_it->second->rotation == rotation()) { |
| 317 return image_it->second->cursor; | 321 return image_it->second->cursor; |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 349 } | 353 } |
| 350 | 354 |
| 351 // As a last resort, return a left pointer. | 355 // As a last resort, return a left pointer. |
| 352 cursor = XCreateFontCursor(display_, XC_left_ptr); | 356 cursor = XCreateFontCursor(display_, XC_left_ptr); |
| 353 DCHECK(cursor); | 357 DCHECK(cursor); |
| 354 font_cursors_[id] = cursor; | 358 font_cursors_[id] = cursor; |
| 355 return cursor; | 359 return cursor; |
| 356 } | 360 } |
| 357 | 361 |
| 358 } // namespace ui | 362 } // namespace ui |
| OLD | NEW |