Chromium Code Reviews| Index: ui/base/x/x11_util.cc |
| diff --git a/ui/base/x/x11_util.cc b/ui/base/x/x11_util.cc |
| index 288344828ee8620707daa7b597a22f93af4627ab..676bb8f04ac014fedff9f9b6cc820990ed2665b6 100644 |
| --- a/ui/base/x/x11_util.cc |
| +++ b/ui/base/x/x11_util.cc |
| @@ -35,6 +35,10 @@ |
| #include <sys/sysctl.h> |
| #endif |
| +#if defined(USE_AURA) |
| +#include <X11/Xcursor/Xcursor.h> |
| +#endif |
| + |
| #if defined(TOOLKIT_USES_GTK) |
| #include <gdk/gdk.h> |
| #include <gdk/gdkx.h> |
| @@ -188,6 +192,80 @@ class XCursorCache { |
| DISALLOW_COPY_AND_ASSIGN(XCursorCache); |
| }; |
| +#if defined(USE_AURA) |
| +// A process wide singleton cache for custom X cursors. |
| +class XCustomCursorCache { |
| + public: |
| + static XCustomCursorCache* GetInstance() { |
| + return Singleton<XCustomCursorCache>::get(); |
| + } |
| + |
| + Cursor InstallCustomCursor(XcursorImage* image) { |
| + Cursor xcursor = XcursorImageLoadCursor(GetXDisplay(), image); |
| + XCustomCursor* custom_cursor = new XCustomCursor(image); |
| + cache_[xcursor] = custom_cursor; |
| + return xcursor; |
| + } |
| + |
| + void Ref(Cursor cursor) { |
| + cache_[cursor]->Ref(); |
| + } |
| + |
| + void Unref(Cursor cursor) { |
| + if (cache_[cursor]->Unref()) { |
| + XFreeCursor(GetXDisplay(), cursor); |
| + cache_.erase(cursor); |
| + } |
| + } |
| + |
| + void Clear() { |
| + cache_.clear(); |
|
Daniel Erat
2012/02/24 21:04:36
do you need to call XFreeCursor() on all of the ke
sadrul
2012/02/24 22:48:49
Good catch. This needs to happen. I have moved the
|
| + } |
| + |
| + private: |
| + friend struct DefaultSingletonTraits<XCustomCursorCache>; |
| + |
| + class XCustomCursor { |
| + public: |
| + XCustomCursor(XcursorImage* image) |
|
Daniel Erat
2012/02/24 21:04:36
nit: document that it takes ownership of |image|
sadrul
2012/02/24 22:48:49
Done.
|
| + : image_(image), |
| + ref_(1) { |
| + } |
| + |
| + ~XCustomCursor() { |
| + XcursorImageDestroy(image_); |
| + } |
| + |
| + void Ref() { |
| + ++ref_; |
| + } |
| + |
| + // Returns true if the cursor was destroyed because of the unref. |
| + bool Unref() { |
| + if (--ref_ == 0) { |
| + delete this; |
| + return true; |
| + } |
| + return false; |
| + } |
| + |
| + private: |
| + XcursorImage* image_; |
| + int ref_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(XCustomCursor); |
| + }; |
| + |
| + XCustomCursorCache() {} |
| + ~XCustomCursorCache() { |
| + Clear(); |
| + } |
| + |
| + std::map<Cursor, XCustomCursor*> cache_; |
| + DISALLOW_COPY_AND_ASSIGN(XCustomCursorCache); |
| +}; |
| +#endif // defined(USE_AURA) |
| + |
| // A singleton object that remembers remappings of mouse buttons. |
| class XButtonMap { |
| public: |
| @@ -317,6 +395,20 @@ Cursor GetXCursor(int cursor_shape) { |
| return cache.GetCursor(cursor_shape); |
| } |
| +#if defined(USE_AURA) |
| +Cursor CreateReffedCustomXCursor(XcursorImage* image) { |
| + return XCustomCursorCache::GetInstance()->InstallCustomCursor(image); |
| +} |
| + |
| +void RefCustomXCursor(Cursor cursor) { |
| + XCustomCursorCache::GetInstance()->Ref(cursor); |
| +} |
| + |
| +void UnrefCustomXCursor(Cursor cursor) { |
| + XCustomCursorCache::GetInstance()->Unref(cursor); |
| +} |
| +#endif |
| + |
| XID GetX11RootWindow() { |
| return DefaultRootWindow(GetXDisplay()); |
| } |