summaryrefslogtreecommitdiffstats
path: root/ui/base
diff options
context:
space:
mode:
authormazda@chromium.org <mazda@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-09-11 20:18:35 +0000
committermazda@chromium.org <mazda@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-09-11 20:18:35 +0000
commit151ffdff429adc13dea9afbe18602745981a9dcc (patch)
tree65ea7ff184d3e543d2a6213e29a96119eed4081b /ui/base
parent843fe4276bb2a001d6bdbb74dda7ef44a707cec7 (diff)
downloadchromium_src-151ffdff429adc13dea9afbe18602745981a9dcc.zip
chromium_src-151ffdff429adc13dea9afbe18602745981a9dcc.tar.gz
chromium_src-151ffdff429adc13dea9afbe18602745981a9dcc.tar.bz2
Move ash specific cursor code to CursorManager.
Main changes are as follows. - Move the responsibility of managing cursors to ash::CursorManager from aura::RootWindowHostLinux. - Set the same cursor to all root windows with CursorManager so that cursor is updated properly while dragging across displays - Introduce CursorLoader class, which implements platform specific cursor loading. - Add SetDeviceScaleFactor to CursorClient, which sets the device scale factor used for the cursor. BUG=132862,144756 Review URL: https://chromiumcodereview.appspot.com/10919135 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@156109 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui/base')
-rw-r--r--ui/base/cursor/cursor.cc20
-rw-r--r--ui/base/cursor/cursor.h15
-rw-r--r--ui/base/cursor/cursor_loader.h61
-rw-r--r--ui/base/cursor/cursor_loader_win.cc40
-rw-r--r--ui/base/cursor/cursor_loader_win.h35
-rw-r--r--ui/base/cursor/cursor_loader_x11.cc203
-rw-r--r--ui/base/cursor/cursor_loader_x11.h58
-rw-r--r--ui/base/x/events_x.cc4
-rw-r--r--ui/base/x/x11_util.cc41
-rw-r--r--ui/base/x/x11_util.h24
10 files changed, 491 insertions, 10 deletions
diff --git a/ui/base/cursor/cursor.cc b/ui/base/cursor/cursor.cc
index e2811bf..223042e 100644
--- a/ui/base/cursor/cursor.cc
+++ b/ui/base/cursor/cursor.cc
@@ -8,17 +8,20 @@ namespace ui {
Cursor::Cursor()
: native_type_(0),
- platform_cursor_(0) {
+ platform_cursor_(0),
+ device_scale_factor_(0.0f) {
}
Cursor::Cursor(int type)
: native_type_(type),
- platform_cursor_(0) {
+ platform_cursor_(0),
+ device_scale_factor_(0.0f) {
}
Cursor::Cursor(const Cursor& cursor)
: native_type_(cursor.native_type_),
- platform_cursor_(cursor.platform_cursor_) {
+ platform_cursor_(cursor.platform_cursor_),
+ device_scale_factor_(cursor.device_scale_factor_) {
if (native_type_ == kCursorCustom)
RefCustomCursor();
}
@@ -29,22 +32,23 @@ Cursor::~Cursor() {
}
void Cursor::SetPlatformCursor(const PlatformCursor& platform) {
- if (platform_cursor_)
+ if (native_type_ == kCursorCustom)
UnrefCustomCursor();
- native_type_ = kCursorCustom;
platform_cursor_ = platform;
- RefCustomCursor();
+ if (native_type_ == kCursorCustom)
+ RefCustomCursor();
}
void Cursor::Assign(const Cursor& cursor) {
if (*this == cursor)
return;
native_type_ = cursor.native_type_;
- if (platform_cursor_)
+ if (native_type_ == kCursorCustom)
UnrefCustomCursor();
platform_cursor_ = cursor.platform_cursor_;
- if (platform_cursor_)
+ if (native_type_ == kCursorCustom)
RefCustomCursor();
+ device_scale_factor_ = cursor.device_scale_factor_;
}
} // namespace ui
diff --git a/ui/base/cursor/cursor.h b/ui/base/cursor/cursor.h
index 2383274..43c201d 100644
--- a/ui/base/cursor/cursor.h
+++ b/ui/base/cursor/cursor.h
@@ -102,16 +102,24 @@ class UI_EXPORT Cursor {
int native_type() const { return native_type_; }
PlatformCursor platform() const { return platform_cursor_; }
+ float device_scale_factor() const {
+ return device_scale_factor_;
+ }
+ void set_device_scale_factor(float device_scale_factor) {
+ device_scale_factor_ = device_scale_factor;
+ }
bool operator==(int type) const { return native_type_ == type; }
bool operator==(const Cursor& cursor) const {
return native_type_ == cursor.native_type_ &&
- platform_cursor_ == cursor.platform_cursor_;
+ platform_cursor_ == cursor.platform_cursor_ &&
+ device_scale_factor_ == cursor.device_scale_factor_;
}
bool operator!=(int type) const { return native_type_ != type; }
bool operator!=(const Cursor& cursor) const {
return native_type_ != cursor.native_type_ ||
- platform_cursor_ != cursor.platform_cursor_;
+ platform_cursor_ != cursor.platform_cursor_ ||
+ device_scale_factor_ != cursor.device_scale_factor_;
}
void operator=(const Cursor& cursor) {
@@ -125,6 +133,9 @@ class UI_EXPORT Cursor {
int native_type_;
PlatformCursor platform_cursor_;
+
+ // The device scale factor for the cursor.
+ float device_scale_factor_;
};
} // namespace ui
diff --git a/ui/base/cursor/cursor_loader.h b/ui/base/cursor/cursor_loader.h
new file mode 100644
index 0000000..48167e7
--- /dev/null
+++ b/ui/base/cursor/cursor_loader.h
@@ -0,0 +1,61 @@
+// 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.
+
+#ifndef UI_BASE_CURSOR_CURSOR_LOADER_H_
+#define UI_BASE_CURSOR_CURSOR_LOADER_H_
+
+#include "base/logging.h"
+#include "ui/base/ui_export.h"
+#include "ui/gfx/native_widget_types.h"
+#include "ui/gfx/point.h"
+
+namespace ui {
+
+class UI_EXPORT CursorLoader {
+ public:
+ CursorLoader() : device_scale_factor_(0.0f) {}
+ virtual ~CursorLoader() {}
+
+ // Returns the device scale factor used by the loader.
+ float device_scale_factor() const {
+ return device_scale_factor_;
+ }
+
+ // Sets the device scale factor used by the loader.
+ void set_device_scale_factor(float device_scale_factor) {
+ device_scale_factor_ = device_scale_factor;
+ }
+
+ // Creates a cursor from an image resource and puts it in the cursor map.
+ virtual void LoadImageCursor(int id,
+ int resource_id,
+ const gfx::Point& hot) = 0;
+
+ // Creates an animated cursor from an image resource and puts it in the
+ // cursor map. The image is assumed to be a concatenation of animation frames
+ // from left to right. Also, each frame is assumed to be square
+ // (width == height).
+ // |frame_delay_ms| is the delay between frames in millisecond.
+ virtual void LoadAnimatedCursor(int id,
+ int resource_id,
+ const gfx::Point& hot,
+ int frame_delay_ms) = 0;
+
+ // Unloads all the cursors.
+ virtual void UnloadAll() = 0;
+
+ // Sets the platform cursor based on the native type of |cursor|.
+ virtual void SetPlatformCursor(gfx::NativeCursor* cursor) = 0;
+
+ // Creates a CursorLoader.
+ static CursorLoader* Create();
+
+ private:
+ // The device scale factor used by the loader.
+ float device_scale_factor_;
+};
+
+} // namespace ui
+
+#endif // UI_BASE_CURSOR_CURSOR_LOADER_H_
diff --git a/ui/base/cursor/cursor_loader_win.cc b/ui/base/cursor/cursor_loader_win.cc
new file mode 100644
index 0000000..8fc9adc
--- /dev/null
+++ b/ui/base/cursor/cursor_loader_win.cc
@@ -0,0 +1,40 @@
+// 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_win.h"
+
+namespace ui {
+
+CursorLoader* CursorLoader::Create() {
+ return new CursorLoaderWin;
+}
+
+CursorLoaderWin::CursorLoaderWin() {
+}
+
+CursorLoaderWin::~CursorLoaderWin() {
+}
+
+void CursorLoaderWin::LoadImageCursor(int id,
+ int resource_id,
+ const gfx::Point& hot) {
+ // NOTIMPLEMENTED();
+}
+
+void CursorLoaderWin::LoadAnimatedCursor(int id,
+ int resource_id,
+ const gfx::Point& hot,
+ int frame_delay_ms) {
+ // NOTIMPLEMENTED();
+}
+
+void CursorLoaderWin::UnloadAll() {
+ // NOTIMPLEMENTED();
+}
+
+void CursorLoaderWin::SetPlatformCursor(gfx::NativeCursor* cursor) {
+ // NOTIMPLEMENTED();
+}
+
+} // namespace ui
diff --git a/ui/base/cursor/cursor_loader_win.h b/ui/base/cursor/cursor_loader_win.h
new file mode 100644
index 0000000..6447283
--- /dev/null
+++ b/ui/base/cursor/cursor_loader_win.h
@@ -0,0 +1,35 @@
+// 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.
+
+#ifndef UI_BASE_CURSOR_CURSOR_LOADER_WIN_H_
+#define UI_BASE_CURSOR_CURSOR_LOADER_WIN_H_
+
+#include "base/compiler_specific.h"
+#include "ui/base/cursor/cursor_loader.h"
+
+namespace ui {
+
+class CursorLoaderWin : public CursorLoader {
+ public:
+ CursorLoaderWin();
+ virtual ~CursorLoaderWin();
+
+ // Overridden from CursorLoader:
+ virtual void LoadImageCursor(int id,
+ int resource_id,
+ const gfx::Point& hot) OVERRIDE;
+ virtual void LoadAnimatedCursor(int id,
+ int resource_id,
+ const gfx::Point& hot,
+ int frame_delay_ms) OVERRIDE;
+ virtual void UnloadAll() OVERRIDE;
+ virtual void SetPlatformCursor(gfx::NativeCursor* cursor) OVERRIDE;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(CursorLoaderWin);
+};
+
+} // namespace ui
+
+#endif // UI_BASE_CURSOR_CURSOR_LOADER_WIN_H_
diff --git a/ui/base/cursor/cursor_loader_x11.cc b/ui/base/cursor/cursor_loader_x11.cc
new file mode 100644
index 0000000..dce19d4
--- /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];
+}
+
+}
diff --git a/ui/base/cursor/cursor_loader_x11.h b/ui/base/cursor/cursor_loader_x11.h
new file mode 100644
index 0000000..32f0e1a
--- /dev/null
+++ b/ui/base/cursor/cursor_loader_x11.h
@@ -0,0 +1,58 @@
+// 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.
+
+#ifndef UI_BASE_CURSOR_CURSOR_LOADER_X11_H_
+#define UI_BASE_CURSOR_CURSOR_LOADER_X11_H_
+
+#include <X11/Xcursor/Xcursor.h>
+#include <map>
+
+#include "base/compiler_specific.h"
+#include "ui/base/cursor/cursor.h"
+#include "ui/base/cursor/cursor_loader.h"
+
+namespace ui {
+
+class CursorLoaderX11 : public CursorLoader {
+ public:
+ CursorLoaderX11();
+ virtual ~CursorLoaderX11();
+
+ // Overridden from CursorLoader:
+ virtual void LoadImageCursor(int id,
+ int resource_id,
+ const gfx::Point& hot) OVERRIDE;
+ virtual void LoadAnimatedCursor(int id,
+ int resource_id,
+ const gfx::Point& hot,
+ int frame_delay_ms) OVERRIDE;
+ virtual void UnloadAll() OVERRIDE;
+ virtual void SetPlatformCursor(gfx::NativeCursor* cursor) OVERRIDE;
+
+ private:
+ // Returns true if we have an image resource loaded for the |native_cursor|.
+ bool IsImageCursor(gfx::NativeCursor native_cursor);
+
+ // Gets the X Cursor corresponding to the |native_cursor|.
+ ::Cursor ImageCursorFromNative(gfx::NativeCursor native_cursor);
+
+ // A map to hold all image cursors. It maps the cursor ID to the X Cursor.
+ typedef std::map<int, ::Cursor> ImageCursorMap;
+ ImageCursorMap cursors_;
+
+ // A map to hold all animated cursors. It maps the cursor ID to the pair of
+ // the X Cursor and the corresponding XcursorImages. We need a pointer to the
+ // images so that we can free them on destruction.
+ typedef std::map<int, std::pair< ::Cursor, XcursorImages*> >
+ AnimatedCursorMap;
+ AnimatedCursorMap animated_cursors_;
+
+ ::Cursor invisible_cursor_;
+
+ DISALLOW_COPY_AND_ASSIGN(CursorLoaderX11);
+};
+
+} // namespace ui
+
+#endif // UI_BASE_CURSOR_CURSOR_LOADER_X11_H_
diff --git a/ui/base/x/events_x.cc b/ui/base/x/events_x.cc
index dff3298..1dd3a66 100644
--- a/ui/base/x/events_x.cc
+++ b/ui/base/x/events_x.cc
@@ -775,6 +775,10 @@ base::TimeDelta EventTimeFromNative(const base::NativeEvent& native_event) {
case MotionNotify:
return base::TimeDelta::FromMilliseconds(native_event->xmotion.time);
break;
+ case EnterNotify:
+ case LeaveNotify:
+ return base::TimeDelta::FromMilliseconds(native_event->xcrossing.time);
+ break;
case GenericEvent: {
double start, end;
if (GetGestureTimes(native_event, &start, &end)) {
diff --git a/ui/base/x/x11_util.cc b/ui/base/x/x11_util.cc
index efe05af..05f50ec 100644
--- a/ui/base/x/x11_util.cc
+++ b/ui/base/x/x11_util.cc
@@ -453,6 +453,28 @@ XcursorImage* SkBitmapToXcursorImage(const SkBitmap* bitmap,
}
#endif
+void HideHostCursor() {
+ CR_DEFINE_STATIC_LOCAL(XScopedCursor, invisible_cursor,
+ (CreateInvisibleCursor(), ui::GetXDisplay()));
+ XDefineCursor(ui::GetXDisplay(), DefaultRootWindow(ui::GetXDisplay()),
+ invisible_cursor.get());
+}
+
+::Cursor CreateInvisibleCursor() {
+ Display* xdisplay = ui::GetXDisplay();
+ ::Cursor invisible_cursor;
+ char nodata[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
+ XColor black;
+ black.red = black.green = black.blue = 0;
+ Pixmap blank = XCreateBitmapFromData(xdisplay,
+ DefaultRootWindow(xdisplay),
+ nodata, 8, 8);
+ invisible_cursor = XCreatePixmapCursor(xdisplay, blank, blank,
+ &black, &black, 0, 0);
+ XFreePixmap(xdisplay, blank);
+ return invisible_cursor;
+}
+
XID GetX11RootWindow() {
return DefaultRootWindow(GetXDisplay());
}
@@ -1352,6 +1374,25 @@ XScopedString::~XScopedString() {
XFree(string_);
}
+XScopedCursor::XScopedCursor(::Cursor cursor, Display* display)
+ : cursor_(cursor),
+ display_(display) {
+}
+
+XScopedCursor::~XScopedCursor() {
+ reset(0U);
+}
+
+::Cursor XScopedCursor::get() const {
+ return cursor_;
+}
+
+void XScopedCursor::reset(::Cursor cursor) {
+ if (cursor_)
+ XFreeCursor(display_, cursor_);
+ cursor_ = cursor;
+}
+
// ----------------------------------------------------------------------------
// These functions are declared in x11_util_internal.h because they require
// XLib.h to be included, and it conflicts with many other headers.
diff --git a/ui/base/x/x11_util.h b/ui/base/x/x11_util.h
index 869ef7c..d6dc0c3 100644
--- a/ui/base/x/x11_util.h
+++ b/ui/base/x/x11_util.h
@@ -97,6 +97,12 @@ UI_EXPORT XcursorImage* SkBitmapToXcursorImage(const SkBitmap* bitmap,
const gfx::Point& hotspot);
#endif
+// Hides the host cursor.
+UI_EXPORT void HideHostCursor();
+
+// Returns an invisible cursor.
+UI_EXPORT ::Cursor CreateInvisibleCursor();
+
// These functions do not cache their results --------------------------
// Get the X window id for the default root window
@@ -319,6 +325,24 @@ class UI_EXPORT XScopedString {
DISALLOW_COPY_AND_ASSIGN(XScopedString);
};
+// Keeps track of a cursor returned by an X function and makes sure it's
+// XFreeCursor'd.
+class UI_EXPORT XScopedCursor {
+ public:
+ // Keeps track of |cursor| created with |display|.
+ XScopedCursor(::Cursor cursor, Display* display);
+ ~XScopedCursor();
+
+ ::Cursor get() const;
+ void reset(::Cursor cursor);
+
+ private:
+ ::Cursor cursor_;
+ Display* display_;
+
+ DISALLOW_COPY_AND_ASSIGN(XScopedCursor);
+};
+
} // namespace ui
#endif // UI_BASE_X_X11_UTIL_H_