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 |