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

Unified 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 side-by-side diff with in-line comments
Download patch
« 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 »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/base/cursor/cursor_loader_x11.cc
diff --git a/ui/base/cursor/cursor_loader_x11.cc b/ui/base/cursor/cursor_loader_x11.cc
new file mode 100644
index 0000000000000000000000000000000000000000..dce19d426c4e01a3d8cd33b88c4a8ed02a3684f7
--- /dev/null
+++ b/ui/base/cursor/cursor_loader_x11.cc
@@ -0,0 +1,203 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/base/cursor/cursor_loader_x11.h"
+
+#include <X11/Xlib.h>
+#include <X11/cursorfont.h>
+
+#include "base/logging.h"
+#include "grit/ui_resources.h"
+#include "ui/base/cursor/cursor.h"
+#include "ui/base/resource/resource_bundle.h"
+#include "ui/base/x/x11_util.h"
+#include "ui/gfx/image/image.h"
+#include "ui/gfx/image/image_skia.h"
+
+namespace {
+
+// Returns X font cursor shape from an Aura cursor.
+int CursorShapeFromNative(gfx::NativeCursor native_cursor) {
+ switch (native_cursor.native_type()) {
+ case ui::kCursorMiddlePanning:
+ return XC_fleur;
+ case ui::kCursorEastPanning:
+ return XC_sb_right_arrow;
+ case ui::kCursorNorthPanning:
+ return XC_sb_up_arrow;
+ case ui::kCursorNorthEastPanning:
+ return XC_top_right_corner;
+ case ui::kCursorNorthWestPanning:
+ return XC_top_left_corner;
+ case ui::kCursorSouthPanning:
+ return XC_sb_down_arrow;
+ case ui::kCursorSouthEastPanning:
+ return XC_bottom_right_corner;
+ case ui::kCursorSouthWestPanning:
+ return XC_bottom_left_corner;
+ case ui::kCursorWestPanning:
+ return XC_sb_left_arrow;
+ case ui::kCursorNone:
+ case ui::kCursorGrab:
+ case ui::kCursorGrabbing:
+ // TODO(jamescook): Need cursors for these. crbug.com/111650
+ return XC_left_ptr;
+
+ case ui::kCursorNull:
+ case ui::kCursorPointer:
+ case ui::kCursorNoDrop:
+ case ui::kCursorNotAllowed:
+ case ui::kCursorCopy:
+ case ui::kCursorMove:
+ case ui::kCursorEastResize:
+ case ui::kCursorNorthResize:
+ case ui::kCursorSouthResize:
+ case ui::kCursorWestResize:
+ case ui::kCursorNorthEastResize:
+ case ui::kCursorNorthWestResize:
+ case ui::kCursorSouthWestResize:
+ case ui::kCursorSouthEastResize:
+ case ui::kCursorIBeam:
+ case ui::kCursorAlias:
+ case ui::kCursorCell:
+ case ui::kCursorContextMenu:
+ case ui::kCursorCross:
+ case ui::kCursorHelp:
+ case ui::kCursorWait:
+ case ui::kCursorNorthSouthResize:
+ case ui::kCursorEastWestResize:
+ case ui::kCursorNorthEastSouthWestResize:
+ case ui::kCursorNorthWestSouthEastResize:
+ case ui::kCursorProgress:
+ case ui::kCursorColumnResize:
+ case ui::kCursorRowResize:
+ case ui::kCursorVerticalText:
+ case ui::kCursorZoomIn:
+ case ui::kCursorZoomOut:
+ NOTREACHED() << "Cursor (" << native_cursor.native_type() << ") should "
+ << "have an image asset.";
+ return XC_left_ptr;
+ case ui::kCursorCustom:
+ NOTREACHED();
+ return XC_left_ptr;
+ }
+ NOTREACHED();
+ return XC_left_ptr;
+}
+
+} // namespace
+
+namespace ui {
+
+CursorLoader* CursorLoader::Create() {
+ return new CursorLoaderX11;
+}
+
+CursorLoaderX11::CursorLoaderX11() {
+}
+
+CursorLoaderX11::~CursorLoaderX11() {
+ UnloadAll();
+ // Clears XCursorCache.
+ ui::GetXCursor(ui::kCursorClearXCursorCache);
+}
+
+void CursorLoaderX11::LoadImageCursor(int id,
+ int resource_id,
+ const gfx::Point& hot) {
+ const gfx::ImageSkia* image =
+ ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(resource_id);
+ const gfx::ImageSkiaRep& image_rep = image->GetRepresentation(
+ ui::GetScaleFactorFromScale(device_scale_factor()));
+ XcursorImage* x_image =
+ ui::SkBitmapToXcursorImage(&image_rep.sk_bitmap(), hot);
+ cursors_[id] = ui::CreateReffedCustomXCursor(x_image);
+ // |image_rep| is owned by the resource bundle. So we do not need to free it.
+}
+
+void CursorLoaderX11::LoadAnimatedCursor(int id,
+ int resource_id,
+ const gfx::Point& hot,
+ int frame_delay_ms) {
+ const gfx::ImageSkia* image =
+ ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(resource_id);
+ const gfx::ImageSkiaRep& image_rep = image->GetRepresentation(
+ ui::GetScaleFactorFromScale(device_scale_factor()));
+ const SkBitmap bitmap = image_rep.sk_bitmap();
+ DCHECK_EQ(bitmap.config(), SkBitmap::kARGB_8888_Config);
+ int frame_width = bitmap.height();
+ int frame_height = frame_width;
+ int total_width = bitmap.width();
+ DCHECK_EQ(total_width % frame_width, 0);
+ int frame_count = total_width / frame_width;
+ DCHECK_GT(frame_count, 0);
+ XcursorImages* x_images = XcursorImagesCreate(frame_count);
+ x_images->nimage = frame_count;
+ bitmap.lockPixels();
+ unsigned int* pixels = bitmap.getAddr32(0, 0);
+ // Create each frame.
+ for (int frame = 0; frame < frame_count; ++frame) {
+ XcursorImage* x_image = XcursorImageCreate(frame_width, frame_height);
+ for (int row = 0; row < frame_height; ++row) {
+ // Copy |row|'th row of |frame|'th frame.
+ memcpy(x_image->pixels + row * frame_width,
+ pixels + frame * frame_width + row * total_width,
+ frame_width * 4);
+ }
+ x_image->xhot = hot.x();
+ x_image->yhot = hot.y();
+ x_image->delay = frame_delay_ms;
+ x_images->images[frame] = x_image;
+ }
+ bitmap.unlockPixels();
+
+ animated_cursors_[id] = std::make_pair(
+ XcursorImagesLoadCursor(ui::GetXDisplay(), x_images), x_images);
+ // |bitmap| is owned by the resource bundle. So we do not need to free it.
+}
+
+void CursorLoaderX11::UnloadAll() {
+ for (ImageCursorMap::const_iterator it = cursors_.begin();
+ it != cursors_.end(); ++it)
+ ui::UnrefCustomXCursor(it->second);
+
+ // Free animated cursors and images.
+ for (AnimatedCursorMap::iterator it = animated_cursors_.begin();
+ it != animated_cursors_.end(); ++it) {
+ XcursorImagesDestroy(it->second.second); // also frees individual frames.
+ XFreeCursor(ui::GetXDisplay(), it->second.first);
+ }
+}
+
+void CursorLoaderX11::SetPlatformCursor(gfx::NativeCursor* cursor) {
+ DCHECK(cursor);
+
+ ::Cursor xcursor;
+ if (IsImageCursor(*cursor))
+ xcursor = ImageCursorFromNative(*cursor);
+ else if (*cursor == ui::kCursorCustom)
+ xcursor = cursor->platform();
+ else if (device_scale_factor() == 1.0f)
+ xcursor = ui::GetXCursor(CursorShapeFromNative(*cursor));
+ else
+ xcursor = ImageCursorFromNative(ui::kCursorPointer);
+
+ cursor->SetPlatformCursor(xcursor);
+}
+
+bool CursorLoaderX11::IsImageCursor(gfx::NativeCursor native_cursor) {
+ int type = native_cursor.native_type();
+ return cursors_.count(type) || animated_cursors_.count(type);
+}
+
+::Cursor CursorLoaderX11::ImageCursorFromNative(
+ gfx::NativeCursor native_cursor) {
+ int type = native_cursor.native_type();
+ if (animated_cursors_.count(type))
+ return animated_cursors_[type].first;
+ DCHECK(cursors_.find(type) != cursors_.end());
+ return cursors_[type];
+}
+
+}
« 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