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

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: 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
« no previous file with comments | « ui/base/cursor/cursor_loader_x11.h ('k') | ui/base/x/events_x.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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(int id,
107 int resource_id,
108 const gfx::Point& hot) {
109 const gfx::ImageSkia* image =
110 ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(resource_id);
111 const gfx::ImageSkiaRep& image_rep = image->GetRepresentation(
112 ui::GetScaleFactorFromScale(device_scale_factor()));
113 XcursorImage* x_image =
114 ui::SkBitmapToXcursorImage(&image_rep.sk_bitmap(), hot);
115 cursors_[id] = ui::CreateReffedCustomXCursor(x_image);
116 // |image_rep| is owned by the resource bundle. So we do not need to free it.
117 }
118
119 void CursorLoaderX11::LoadAnimatedCursor(int id,
120 int resource_id,
121 const gfx::Point& hot,
122 int frame_delay_ms) {
123 const gfx::ImageSkia* image =
124 ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(resource_id);
125 const gfx::ImageSkiaRep& image_rep = image->GetRepresentation(
126 ui::GetScaleFactorFromScale(device_scale_factor()));
127 const SkBitmap bitmap = image_rep.sk_bitmap();
128 DCHECK_EQ(bitmap.config(), SkBitmap::kARGB_8888_Config);
129 int frame_width = bitmap.height();
130 int frame_height = frame_width;
131 int total_width = bitmap.width();
132 DCHECK_EQ(total_width % frame_width, 0);
133 int frame_count = total_width / frame_width;
134 DCHECK_GT(frame_count, 0);
135 XcursorImages* x_images = XcursorImagesCreate(frame_count);
136 x_images->nimage = frame_count;
137 bitmap.lockPixels();
138 unsigned int* pixels = bitmap.getAddr32(0, 0);
139 // Create each frame.
140 for (int frame = 0; frame < frame_count; ++frame) {
141 XcursorImage* x_image = XcursorImageCreate(frame_width, frame_height);
142 for (int row = 0; row < frame_height; ++row) {
143 // Copy |row|'th row of |frame|'th frame.
144 memcpy(x_image->pixels + row * frame_width,
145 pixels + frame * frame_width + row * total_width,
146 frame_width * 4);
147 }
148 x_image->xhot = hot.x();
149 x_image->yhot = hot.y();
150 x_image->delay = frame_delay_ms;
151 x_images->images[frame] = x_image;
152 }
153 bitmap.unlockPixels();
154
155 animated_cursors_[id] = std::make_pair(
156 XcursorImagesLoadCursor(ui::GetXDisplay(), x_images), x_images);
157 // |bitmap| is owned by the resource bundle. So we do not need to free it.
158 }
159
160 void CursorLoaderX11::UnloadAll() {
161 for (ImageCursorMap::const_iterator it = cursors_.begin();
162 it != cursors_.end(); ++it)
163 ui::UnrefCustomXCursor(it->second);
164
165 // Free animated cursors and images.
166 for (AnimatedCursorMap::iterator it = animated_cursors_.begin();
167 it != animated_cursors_.end(); ++it) {
168 XcursorImagesDestroy(it->second.second); // also frees individual frames.
169 XFreeCursor(ui::GetXDisplay(), it->second.first);
170 }
171 }
172
173 void CursorLoaderX11::SetPlatformCursor(gfx::NativeCursor* cursor) {
174 DCHECK(cursor);
175
176 ::Cursor xcursor;
177 if (IsImageCursor(*cursor))
178 xcursor = ImageCursorFromNative(*cursor);
179 else if (*cursor == ui::kCursorCustom)
180 xcursor = cursor->platform();
181 else if (device_scale_factor() == 1.0f)
182 xcursor = ui::GetXCursor(CursorShapeFromNative(*cursor));
183 else
184 xcursor = ImageCursorFromNative(ui::kCursorPointer);
185
186 cursor->SetPlatformCursor(xcursor);
187 }
188
189 bool CursorLoaderX11::IsImageCursor(gfx::NativeCursor native_cursor) {
190 int type = native_cursor.native_type();
191 return cursors_.count(type) || animated_cursors_.count(type);
192 }
193
194 ::Cursor CursorLoaderX11::ImageCursorFromNative(
195 gfx::NativeCursor native_cursor) {
196 int type = native_cursor.native_type();
197 if (animated_cursors_.count(type))
198 return animated_cursors_[type].first;
199 DCHECK(cursors_.find(type) != cursors_.end());
200 return cursors_[type];
201 }
202
203 }
OLDNEW
« no previous file with comments | « ui/base/cursor/cursor_loader_x11.h ('k') | ui/base/x/events_x.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698