Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(126)

Side by Side Diff: ui/base/cursor/cursor_loader_x11.cc

Issue 10919135: Move ash specific cursor code to CursorManager. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix tests and rebase Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "ui/base/cursor/cursor_loader_x11.h"
6
7 #include <X11/Xlib.h>
8 #include <X11/cursorfont.h>
9
10 #include "base/logging.h"
11 #include "grit/ui_resources.h"
12 #include "ui/base/cursor/cursor.h"
13 #include "ui/base/resource/resource_bundle.h"
14 #include "ui/base/x/x11_util.h"
15 #include "ui/gfx/image/image.h"
16 #include "ui/gfx/image/image_skia.h"
17
18 namespace {
19
20 // Returns X font cursor shape from an Aura cursor.
21 int CursorShapeFromNative(gfx::NativeCursor native_cursor) {
22 switch (native_cursor.native_type()) {
23 case ui::kCursorMiddlePanning:
24 return XC_fleur;
25 case ui::kCursorEastPanning:
26 return XC_sb_right_arrow;
27 case ui::kCursorNorthPanning:
28 return XC_sb_up_arrow;
29 case ui::kCursorNorthEastPanning:
30 return XC_top_right_corner;
31 case ui::kCursorNorthWestPanning:
32 return XC_top_left_corner;
33 case ui::kCursorSouthPanning:
34 return XC_sb_down_arrow;
35 case ui::kCursorSouthEastPanning:
36 return XC_bottom_right_corner;
37 case ui::kCursorSouthWestPanning:
38 return XC_bottom_left_corner;
39 case ui::kCursorWestPanning:
40 return XC_sb_left_arrow;
41 case ui::kCursorNone:
42 case ui::kCursorGrab:
43 case ui::kCursorGrabbing:
44 // TODO(jamescook): Need cursors for these. crbug.com/111650
45 return XC_left_ptr;
46
47 case ui::kCursorNull:
48 case ui::kCursorPointer:
49 case ui::kCursorNoDrop:
50 case ui::kCursorNotAllowed:
51 case ui::kCursorCopy:
52 case ui::kCursorMove:
53 case ui::kCursorEastResize:
54 case ui::kCursorNorthResize:
55 case ui::kCursorSouthResize:
56 case ui::kCursorWestResize:
57 case ui::kCursorNorthEastResize:
58 case ui::kCursorNorthWestResize:
59 case ui::kCursorSouthWestResize:
60 case ui::kCursorSouthEastResize:
61 case ui::kCursorIBeam:
62 case ui::kCursorAlias:
63 case ui::kCursorCell:
64 case ui::kCursorContextMenu:
65 case ui::kCursorCross:
66 case ui::kCursorHelp:
67 case ui::kCursorWait:
68 case ui::kCursorNorthSouthResize:
69 case ui::kCursorEastWestResize:
70 case ui::kCursorNorthEastSouthWestResize:
71 case ui::kCursorNorthWestSouthEastResize:
72 case ui::kCursorProgress:
73 case ui::kCursorColumnResize:
74 case ui::kCursorRowResize:
75 case ui::kCursorVerticalText:
76 case ui::kCursorZoomIn:
77 case ui::kCursorZoomOut:
78 NOTREACHED() << "Cursor (" << native_cursor.native_type() << ") should "
79 << "have an image asset.";
80 return XC_left_ptr;
81 case ui::kCursorCustom:
82 NOTREACHED();
83 return XC_left_ptr;
84 }
85 NOTREACHED();
86 return XC_left_ptr;
87 }
88
89 } // namespace
90
91 namespace ui {
92
93 CursorLoader* CursorLoader::Create() {
94 return new CursorLoaderX11;
95 }
96
97 CursorLoaderX11::CursorLoaderX11() {
98 }
99
100 CursorLoaderX11::~CursorLoaderX11() {
101 UnloadAll();
102 // Clears XCursorCache.
103 ui::GetXCursor(ui::kCursorClearXCursorCache);
104 }
105
106 void CursorLoaderX11::LoadImageCursor(
107 int id, int resource_id, const gfx::Point& hot) {
108 const gfx::ImageSkia* image =
109 ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(resource_id);
110 const gfx::ImageSkiaRep& image_rep = image->GetRepresentation(
111 ui::GetScaleFactorFromScale(device_scale_factor()));
112 XcursorImage* x_image =
113 ui::SkBitmapToXcursorImage(&image_rep.sk_bitmap(), hot);
114 cursors_[id] = ui::CreateReffedCustomXCursor(x_image);
115 // |bitmap| is owned by the resource bundle. So we do not need to free it.
Daniel Erat 2012/09/10 23:16:45 nit: is this comment stale? i don't see anything
mazda 2012/09/11 00:45:09 It looks the comment got stale when ImageSkiaRep w
116 }
117
118 void CursorLoaderX11::LoadAnimatedCursor(
119 int id, int resource_id, const gfx::Point& hot, int frame_delay_ms) {
120 const gfx::ImageSkia* image =
121 ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(resource_id);
122 const gfx::ImageSkiaRep& image_rep = image->GetRepresentation(
123 ui::GetScaleFactorFromScale(device_scale_factor()));
124 const SkBitmap bitmap = image_rep.sk_bitmap();
125 DCHECK_EQ(bitmap.config(), SkBitmap::kARGB_8888_Config);
126 int frame_width = bitmap.height();
127 int frame_height = frame_width;
128 int total_width = bitmap.width();
129 DCHECK_EQ(total_width % frame_width, 0);
130 int frame_count = total_width / frame_width;
131 DCHECK_GT(frame_count, 0);
132 XcursorImages* x_images = XcursorImagesCreate(frame_count);
133 x_images->nimage = frame_count;
134 bitmap.lockPixels();
135 unsigned int* pixels = bitmap.getAddr32(0, 0);
136 // Create each frame.
137 for (int i = 0; i < frame_count; ++i) {
Daniel Erat 2012/09/10 23:16:45 nit: "frame" and "row" would be clearer names here
mazda 2012/09/11 00:45:09 Done.
138 XcursorImage* x_image = XcursorImageCreate(frame_width, frame_height);
139 for (int j = 0; j < frame_height; ++j) {
140 // Copy j'th row of i'th frame.
141 memcpy(x_image->pixels + j * frame_width,
142 pixels + i * frame_width + j * total_width,
143 frame_width * 4);
144 }
145 x_image->xhot = hot.x();
146 x_image->yhot = hot.y();
147 x_image->delay = frame_delay_ms;
148 x_images->images[i] = x_image;
149 }
150 bitmap.unlockPixels();
151
152 animated_cursors_[id] = std::make_pair(
153 XcursorImagesLoadCursor(ui::GetXDisplay(), x_images), x_images);
154 // |bitmap| is owned by the resource bundle. So we do not need to free it.
155 }
156
157 void CursorLoaderX11::UnloadAll() {
158 for (ImageCursorMap::const_iterator it = cursors_.begin();
159 it != cursors_.end(); ++it)
160 ui::UnrefCustomXCursor(it->second);
161
162 // Free animated cursors and images.
163 for (AnimatedCursorMap::iterator it = animated_cursors_.begin();
164 it != animated_cursors_.end(); ++it) {
165 XcursorImagesDestroy(it->second.second); // also frees individual frames.
166 XFreeCursor(ui::GetXDisplay(), it->second.first);
167 }
168 }
169
170 void CursorLoaderX11::SetPlatformCursor(gfx::NativeCursor* cursor) {
171 DCHECK(cursor);
172
173 ::Cursor xcursor;
174 if (IsImageCursor(*cursor))
175 xcursor = ImageCursorFromNative(*cursor);
176 else if (*cursor == ui::kCursorCustom)
177 xcursor = cursor->platform();
178 else if (device_scale_factor() == 1.0f)
179 xcursor = ui::GetXCursor(CursorShapeFromNative(*cursor));
180 else
181 xcursor = ImageCursorFromNative(ui::kCursorPointer);
182
183 cursor->SetPlatformCursor(xcursor);
184 }
185
186 bool CursorLoaderX11::IsImageCursor(gfx::NativeCursor native_cursor) {
187 int type = native_cursor.native_type();
188 return cursors_.find(type) != cursors_.end() ||
Daniel Erat 2012/09/10 23:16:45 nit: could shorten this to return cursors_.coun
mazda 2012/09/11 00:45:09 Done.
189 animated_cursors_.find(type) != animated_cursors_.end();
190 }
191
192 ::Cursor CursorLoaderX11::ImageCursorFromNative(
193 gfx::NativeCursor native_cursor) {
194 int type = native_cursor.native_type();
195 if (animated_cursors_.count(type))
196 return animated_cursors_[type].first;
197 DCHECK(cursors_.find(type) != cursors_.end());
198 return cursors_[type];
199 }
200
201 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698