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

Unified Diff: ui/aura/root_window_host_linux.cc

Issue 10316019: Aura: Adds custom cursors for drag and drop. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: patch Created 8 years, 8 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
Index: ui/aura/root_window_host_linux.cc
diff --git a/ui/aura/root_window_host_linux.cc b/ui/aura/root_window_host_linux.cc
index 51d1013ef804b651b7b96a4c66895179dec4171b..b2c3366deca132f4963f8d724c3f0efdbcf593a7 100644
--- a/ui/aura/root_window_host_linux.cc
+++ b/ui/aura/root_window_host_linux.cc
@@ -5,6 +5,7 @@
#include "ui/aura/root_window_host_linux.h"
#include <X11/Xatom.h>
+#include <X11/Xcursor/Xcursor.h>
#include <X11/cursorfont.h>
#include <X11/extensions/XInput2.h>
#include <X11/extensions/Xfixes.h>
@@ -14,6 +15,9 @@
#include "base/message_pump_x.h"
#include "base/stl_util.h"
#include "base/stringprintf.h"
+#include "grit/ui_resources_standard.h"
+#include "third_party/skia/include/core/SkBitmap.h"
+#include "third_party/skia/include/core/SkUnPreMultiply.h"
#include "ui/aura/client/user_gesture_client.h"
#include "ui/aura/dispatcher_linux.h"
#include "ui/aura/env.h"
@@ -21,10 +25,12 @@
#include "ui/aura/root_window.h"
#include "ui/base/cursor/cursor.h"
#include "ui/base/keycodes/keyboard_codes.h"
+#include "ui/base/resource/resource_bundle.h"
#include "ui/base/touch/touch_factory.h"
#include "ui/base/x/x11_util.h"
#include "ui/base/view_prop.h"
#include "ui/gfx/compositor/layer.h"
+#include "ui/gfx/image/image.h"
using std::max;
using std::min;
@@ -292,6 +298,84 @@ const char* kAtomList[] = {
} // namespace
+// A utility class that provides X Cursor for NativeCursors for which we have
+// image resources.
+class RootWindowHostLinux::ImageCursors {
+ public:
+ explicit ImageCursors(Display* xdisplay)
+ : xdisplay_(xdisplay) {
+ LoadImageCursor(ui::kCursorNoDrop, IDR_AURA_CURSOR_NO_DROP);
+ LoadImageCursor(ui::kCursorCopy, IDR_AURA_CURSOR_COPY);
+ // TODO (varunjain): add more cursors once we have assets.
+ }
+
+ virtual ~ImageCursors() {
sky 2012/05/03 19:12:52 no virtual.
varunjain 2012/05/03 19:48:54 Done.
+ std::map<int, std::pair<Cursor, XcursorImage*> >::const_iterator it;
+ for (it = cursors_.begin(); it != cursors_.end(); it++) {
sky 2012/05/03 19:12:52 ++it
varunjain 2012/05/03 19:48:54 Done.
+ XFreeCursor(xdisplay_, it->second.first);
sail 2012/05/03 18:11:05 instead of doing your own reference counting can y
varunjain 2012/05/03 19:48:54 Done with ui::CreateReffedXCursor()
+ XcursorImageDestroy(it->second.second);
+ }
+ }
+
+ // Returns true if we have an image resource loaded for the |native_cursor|.
+ bool IsImageCursor(gfx::NativeCursor native_cursor) {
+ return cursors_.find(native_cursor.native_type()) != cursors_.end();
+ }
+
+ // Gets the X Cursor corresponding to the |native_cursor|.
+ ::Cursor ImageCursorFromNative(gfx::NativeCursor native_cursor) {
+ DCHECK(cursors_.find(native_cursor.native_type()) != cursors_.end());
+ return cursors_[native_cursor.native_type()].first;
+ }
+
+ private:
+ // Creates an X Cursor from an image resource and puts it in the cursor map.
+ void LoadImageCursor(int id, int resource_id) {
+ const SkBitmap* bitmap =
+ ui::ResourceBundle::GetSharedInstance().GetBitmapNamed(resource_id);
sky 2012/05/03 19:12:52 GetBitmapNamed is deprecated, and as far as I know
varunjain 2012/05/03 19:48:54 Done.
+ if (bitmap->isNull())
+ return;
+
+ DCHECK(bitmap->config() == SkBitmap::kARGB_8888_Config);
+ XcursorImage* image = XcursorImageCreate(bitmap->width(), bitmap->height());
+ image->xhot = 0;
+ image->yhot = 0;
+ uint32* pixels = image->pixels;
+
+ bitmap->lockPixels();
+ if (bitmap->width() && bitmap->height()) {
+ int height = bitmap->height(), width = bitmap->width();
sail 2012/05/03 18:11:05 width,height should be on separate lines
varunjain 2012/05/03 19:48:54 Done.
+ for (int y = 0, i = 0; y < height; y++) {
+ for (int x = 0; x < width; x++) {
+ uint32 pixel = bitmap->getAddr32(0, y)[x];
sail 2012/05/03 18:11:05 this code seems to duplicate WebCursor::GetPlatfor
varunjain 2012/05/03 19:48:54 Done.
+ int alpha = SkColorGetA(pixel);
+ if (alpha != 0 && alpha != 255)
+ pixels[i] = SkUnPreMultiply::PMColorToColor(pixel);
sky 2012/05/03 19:12:52 Don't we have code like this some where already?
varunjain 2012/05/03 19:48:54 Done.
+ else
+ pixels[i] = pixel;
+ ++i;
+ }
+ }
+ }
+ bitmap->unlockPixels();
+
+ cursors_[id] = std::make_pair(
+ XcursorImageLoadCursor(xdisplay_, image), image);
+
+ // |bitmap| is owned by the resource bundle. So we do not need to free it.
+ }
+
+ // A map to hold all image cursors. It maps the cursor ID to the cursor
+ // object, where, the cursor object consists of the actual X Cursor and the
+ // XcursorImage. We need to keep the images as well to be able to free them
+ // on destruction.
+ std::map<int, std::pair<Cursor, XcursorImage*> > cursors_;
+
+ Display* xdisplay_;
+
+ DISALLOW_COPY_AND_ASSIGN(ImageCursors);
+};
+
RootWindowHostLinux::RootWindowHostLinux(const gfx::Rect& bounds)
: root_window_(NULL),
xdisplay_(base::MessagePumpX::GetDefaultXDisplay()),
@@ -301,7 +385,8 @@ RootWindowHostLinux::RootWindowHostLinux(const gfx::Rect& bounds)
cursor_shown_(true),
bounds_(bounds),
focus_when_shown_(false),
- pointer_barriers_(NULL) {
+ pointer_barriers_(NULL),
+ image_cursors_(new ImageCursors(xdisplay_)) {
XSetWindowAttributes swa;
memset(&swa, 0, sizeof(swa));
swa.background_pixmap = None;
@@ -795,6 +880,8 @@ bool RootWindowHostLinux::IsWindowManagerPresent() {
void RootWindowHostLinux::SetCursorInternal(gfx::NativeCursor cursor) {
::Cursor xcursor =
+ image_cursors_->IsImageCursor(cursor) ?
+ image_cursors_->ImageCursorFromNative(cursor) :
cursor == ui::kCursorNone ?
invisible_cursor_ :
cursor == ui::kCursorCustom ?

Powered by Google App Engine
This is Rietveld 408576698