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

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: Move HideHostCursor to x11_util.{cc,h} 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, int hot_x, int hot_y) {
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 gfx::Point hot(hot_x * device_scale_factor(), hot_y * device_scale_factor());
113 XcursorImage* x_image =
114 ui::SkBitmapToXcursorImage(&image_rep.sk_bitmap(), hot);
115 cursors_[id] = ui::CreateReffedCustomXCursor(x_image);
116 // |bitmap| is owned by the resource bundle. So we do not need to free it.
117 }
118
119 void CursorLoaderX11::LoadAnimatedCursor(
120 int id, int resource_id, int hot_x, int hot_y, int frame_delay_ms) {
121 const gfx::ImageSkia* image =
122 ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(resource_id);
123 const gfx::ImageSkiaRep& image_rep = image->GetRepresentation(
124 ui::GetScaleFactorFromScale(device_scale_factor()));
125 const SkBitmap bitmap = image_rep.sk_bitmap();
126 DCHECK_EQ(bitmap.config(), SkBitmap::kARGB_8888_Config);
127 int frame_width = bitmap.height();
128 int frame_height = frame_width;
129 int total_width = bitmap.width();
130 DCHECK_EQ(total_width % frame_width, 0);
131 int frame_count = total_width / frame_width;
132 DCHECK_GT(frame_count, 0);
133 XcursorImages* x_images = XcursorImagesCreate(frame_count);
134 x_images->nimage = frame_count;
135 bitmap.lockPixels();
136 unsigned int* pixels = bitmap.getAddr32(0, 0);
137 // Create each frame.
138 for (int i = 0; i < frame_count; ++i) {
139 XcursorImage* x_image = XcursorImageCreate(frame_width, frame_height);
140 for (int j = 0; j < frame_height; ++j) {
141 // Copy j'th row of i'th frame.
142 memcpy(x_image->pixels + j * frame_width,
143 pixels + i * frame_width + j * total_width,
144 frame_width * 4);
145 }
146 x_image->xhot = hot_x * device_scale_factor();
147 x_image->yhot = hot_y * device_scale_factor();
148 x_image->delay = frame_delay_ms;
149 x_images->images[i] = x_image;
150 }
151 bitmap.unlockPixels();
152
153 animated_cursors_[id] = std::make_pair(
154 XcursorImagesLoadCursor(ui::GetXDisplay(), x_images), x_images);
155 // |bitmap| is owned by the resource bundle. So we do not need to free it.
156 }
157
158 void CursorLoaderX11::UnloadAll() {
159 for (ImageCursorMap::const_iterator it = cursors_.begin();
160 it != cursors_.end(); ++it)
161 ui::UnrefCustomXCursor(it->second);
162
163 // Free animated cursors and images.
164 for (AnimatedCursorMap::iterator it = animated_cursors_.begin();
165 it != animated_cursors_.end(); ++it) {
166 XcursorImagesDestroy(it->second.second); // also frees individual frames.
167 XFreeCursor(ui::GetXDisplay(), it->second.first);
168 }
169 }
170
171 void CursorLoaderX11::SetPlatformCursor(gfx::NativeCursor* cursor) {
172 DCHECK(cursor);
173
174 ::Cursor xcursor;
175 if (IsImageCursor(*cursor))
176 xcursor = ImageCursorFromNative(*cursor);
177 else if (*cursor == ui::kCursorNone)
178 xcursor = ui::GetInvisibleCursor();
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_.find(type) != cursors_.end() ||
192 animated_cursors_.find(type) != animated_cursors_.end();
193 }
194
195 ::Cursor CursorLoaderX11::ImageCursorFromNative(
196 gfx::NativeCursor native_cursor) {
197 int type = native_cursor.native_type();
198 if (animated_cursors_.count(type))
199 return animated_cursors_[type].first;
200 DCHECK(cursors_.find(type) != cursors_.end());
201 return cursors_[type];
202 }
203
204 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698