| 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/Xlib.h> | 8 #include <X11/Xlib.h> |
| 9 #include <X11/cursorfont.h> | 9 #include <X11/cursorfont.h> |
| 10 | 10 |
| 11 #include "base/logging.h" | 11 #include "base/logging.h" |
| 12 #include "skia/ext/image_operations.h" | 12 #include "skia/ext/image_operations.h" |
| 13 #include "ui/base/cursor/cursor.h" | 13 #include "ui/base/cursor/cursor.h" |
| 14 #include "ui/base/cursor/cursor_util.h" | 14 #include "ui/base/cursor/cursor_util.h" |
| 15 #include "ui/base/resource/resource_bundle.h" | |
| 16 #include "ui/base/x/x11_util.h" | 15 #include "ui/base/x/x11_util.h" |
| 17 #include "ui/gfx/image/image.h" | 16 #include "ui/gfx/image/image.h" |
| 18 #include "ui/gfx/image/image_skia.h" | |
| 19 #include "ui/gfx/point_conversions.h" | 17 #include "ui/gfx/point_conversions.h" |
| 20 #include "ui/gfx/size_conversions.h" | 18 #include "ui/gfx/size_conversions.h" |
| 21 #include "ui/gfx/skbitmap_operations.h" | 19 #include "ui/gfx/skbitmap_operations.h" |
| 22 #include "ui/gfx/skia_util.h" | 20 #include "ui/gfx/skia_util.h" |
| 23 | 21 |
| 24 namespace { | 22 namespace { |
| 25 | 23 |
| 26 // Returns X font cursor shape from an Aura cursor. | 24 // Returns X font cursor shape from an Aura cursor. |
| 27 int CursorShapeFromNative(const gfx::NativeCursor& native_cursor) { | 25 int CursorShapeFromNative(const gfx::NativeCursor& native_cursor) { |
| 28 switch (native_cursor.native_type()) { | 26 switch (native_cursor.native_type()) { |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 149 : invisible_cursor_(CreateInvisibleCursor(), gfx::GetXDisplay()) { | 147 : invisible_cursor_(CreateInvisibleCursor(), gfx::GetXDisplay()) { |
| 150 } | 148 } |
| 151 | 149 |
| 152 CursorLoaderX11::~CursorLoaderX11() { | 150 CursorLoaderX11::~CursorLoaderX11() { |
| 153 UnloadAll(); | 151 UnloadAll(); |
| 154 } | 152 } |
| 155 | 153 |
| 156 void CursorLoaderX11::LoadImageCursor(int id, | 154 void CursorLoaderX11::LoadImageCursor(int id, |
| 157 int resource_id, | 155 int resource_id, |
| 158 const gfx::Point& hot) { | 156 const gfx::Point& hot) { |
| 159 const gfx::ImageSkia* image = | 157 SkBitmap bitmap; |
| 160 ResourceBundle::GetSharedInstance().GetImageSkiaNamed(resource_id); | 158 gfx::Point hotspot = hot; |
| 161 const gfx::ImageSkiaRep& image_rep = image->GetRepresentation(scale()); | |
| 162 SkBitmap bitmap = image_rep.sk_bitmap(); | |
| 163 gfx::Point hotpoint = hot; | |
| 164 // TODO(oshima): The cursor should use resource scale factor when | |
| 165 // fractional scale factor is enabled. crbug.com/372212 | |
| 166 ScaleAndRotateCursorBitmapAndHotpoint( | |
| 167 scale() / image_rep.scale(), rotation(), &bitmap, &hotpoint); | |
| 168 | 159 |
| 169 XcursorImage* x_image = SkBitmapToXcursorImage(&bitmap, hotpoint); | 160 GetImageCursorBitmap(resource_id, scale(), rotation(), &hotspot, &bitmap); |
| 161 XcursorImage* x_image = SkBitmapToXcursorImage(&bitmap, hotspot); |
| 170 cursors_[id] = CreateReffedCustomXCursor(x_image); | 162 cursors_[id] = CreateReffedCustomXCursor(x_image); |
| 171 // |image_rep| is owned by the resource bundle. So we do not need to free it. | |
| 172 } | 163 } |
| 173 | 164 |
| 174 void CursorLoaderX11::LoadAnimatedCursor(int id, | 165 void CursorLoaderX11::LoadAnimatedCursor(int id, |
| 175 int resource_id, | 166 int resource_id, |
| 176 const gfx::Point& hot, | 167 const gfx::Point& hot, |
| 177 int frame_delay_ms) { | 168 int frame_delay_ms) { |
| 178 // TODO(oshima|tdanderson): Support rotation and fractional scale factor. | 169 std::vector<SkBitmap> bitmaps; |
| 179 const gfx::ImageSkia* image = | 170 gfx::Point hotspot = hot; |
| 180 ResourceBundle::GetSharedInstance().GetImageSkiaNamed(resource_id); | |
| 181 const gfx::ImageSkiaRep& image_rep = image->GetRepresentation(scale()); | |
| 182 SkBitmap bitmap = image_rep.sk_bitmap(); | |
| 183 int frame_width = bitmap.height(); | |
| 184 int frame_height = frame_width; | |
| 185 int total_width = bitmap.width(); | |
| 186 DCHECK_EQ(total_width % frame_width, 0); | |
| 187 int frame_count = total_width / frame_width; | |
| 188 DCHECK_GT(frame_count, 0); | |
| 189 XcursorImages* x_images = XcursorImagesCreate(frame_count); | |
| 190 x_images->nimage = frame_count; | |
| 191 | 171 |
| 192 for (int frame = 0; frame < frame_count; ++frame) { | 172 GetAnimatedCursorBitmaps( |
| 193 gfx::Point hotpoint = hot; | 173 resource_id, scale(), rotation(), &hotspot, &bitmaps); |
| 194 int x_offset = frame_width * frame; | |
| 195 DCHECK_LE(x_offset + frame_width, total_width); | |
| 196 | 174 |
| 197 SkBitmap cropped = SkBitmapOperations::CreateTiledBitmap( | 175 XcursorImages* x_images = XcursorImagesCreate(bitmaps.size()); |
| 198 bitmap, x_offset, 0, frame_width, frame_height); | 176 x_images->nimage = bitmaps.size(); |
| 199 DCHECK_EQ(frame_width, cropped.width()); | |
| 200 DCHECK_EQ(frame_height, cropped.height()); | |
| 201 | 177 |
| 202 XcursorImage* x_image = SkBitmapToXcursorImage(&cropped, hotpoint); | 178 for (unsigned int frame = 0; frame < bitmaps.size(); ++frame) { |
| 203 | 179 XcursorImage* x_image = SkBitmapToXcursorImage(&bitmaps[frame], hotspot); |
| 204 x_image->delay = frame_delay_ms; | 180 x_image->delay = frame_delay_ms; |
| 205 x_images->images[frame] = x_image; | 181 x_images->images[frame] = x_image; |
| 206 } | 182 } |
| 207 | 183 |
| 208 animated_cursors_[id] = std::make_pair( | 184 animated_cursors_[id] = std::make_pair( |
| 209 XcursorImagesLoadCursor(gfx::GetXDisplay(), x_images), x_images); | 185 XcursorImagesLoadCursor(gfx::GetXDisplay(), x_images), x_images); |
| 210 // |bitmap| is owned by the resource bundle. So we do not need to free it. | |
| 211 } | 186 } |
| 212 | 187 |
| 213 void CursorLoaderX11::UnloadAll() { | 188 void CursorLoaderX11::UnloadAll() { |
| 214 for (ImageCursorMap::const_iterator it = cursors_.begin(); | 189 for (ImageCursorMap::const_iterator it = cursors_.begin(); |
| 215 it != cursors_.end(); ++it) | 190 it != cursors_.end(); ++it) |
| 216 UnrefCustomXCursor(it->second); | 191 UnrefCustomXCursor(it->second); |
| 217 | 192 |
| 218 // Free animated cursors and images. | 193 // Free animated cursors and images. |
| 219 for (AnimatedCursorMap::iterator it = animated_cursors_.begin(); | 194 for (AnimatedCursorMap::iterator it = animated_cursors_.begin(); |
| 220 it != animated_cursors_.end(); ++it) { | 195 it != animated_cursors_.end(); ++it) { |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 257 if (animated_cursors_.count(type)) | 232 if (animated_cursors_.count(type)) |
| 258 return animated_cursors_[type].first; | 233 return animated_cursors_[type].first; |
| 259 | 234 |
| 260 ImageCursorMap::iterator find = cursors_.find(type); | 235 ImageCursorMap::iterator find = cursors_.find(type); |
| 261 if (find != cursors_.end()) | 236 if (find != cursors_.end()) |
| 262 return cursors_[type]; | 237 return cursors_[type]; |
| 263 return GetXCursor(CursorShapeFromNative(native_cursor)); | 238 return GetXCursor(CursorShapeFromNative(native_cursor)); |
| 264 } | 239 } |
| 265 | 240 |
| 266 } // namespace ui | 241 } // namespace ui |
| OLD | NEW |