forked from chromium/chromium
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This CL adds a CursorFactoryOzone implementation for Ozone X11. A X11CursorOzone class is added along with X11WindowOzone. This class exists to own the X11 cursor id and own associated resources. It cleans up X resources on destruction. BUG=361137 Review URL: https://codereview.chromium.org/1664373002 Cr-Commit-Position: refs/heads/master@{#376735}
- Loading branch information
kylechar
authored and
Commit bot
committed
Feb 22, 2016
1 parent
d4df77d
commit d642dcb
Showing
12 changed files
with
303 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
// Copyright 2016 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/ozone/platform/x11/x11_cursor_factory_ozone.h" | ||
|
||
#include "third_party/skia/include/core/SkBitmap.h" | ||
#include "ui/base/cursor/cursors_aura.h" | ||
#include "ui/gfx/geometry/point.h" | ||
|
||
namespace ui { | ||
|
||
namespace { | ||
|
||
X11CursorOzone* ToX11CursorOzone(PlatformCursor cursor) { | ||
return static_cast<X11CursorOzone*>(cursor); | ||
} | ||
|
||
PlatformCursor ToPlatformCursor(X11CursorOzone* cursor) { | ||
return static_cast<PlatformCursor>(cursor); | ||
} | ||
|
||
// Gets default aura cursor bitmap/hotspot and creates a X11CursorOzone with it. | ||
scoped_refptr<X11CursorOzone> CreateAuraX11Cursor(int type) { | ||
SkBitmap bitmap; | ||
gfx::Point hotspot; | ||
if (GetCursorBitmap(type, &bitmap, &hotspot)) { | ||
return new X11CursorOzone(bitmap, hotspot); | ||
} | ||
return nullptr; | ||
} | ||
|
||
} // namespace | ||
|
||
X11CursorFactoryOzone::X11CursorFactoryOzone() | ||
: invisible_cursor_(X11CursorOzone::CreateInvisible()) {} | ||
|
||
X11CursorFactoryOzone::~X11CursorFactoryOzone() {} | ||
|
||
PlatformCursor X11CursorFactoryOzone::GetDefaultCursor(int type) { | ||
return ToPlatformCursor(GetDefaultCursorInternal(type).get()); | ||
} | ||
|
||
PlatformCursor X11CursorFactoryOzone::CreateImageCursor( | ||
const SkBitmap& bitmap, | ||
const gfx::Point& hotspot) { | ||
// There is a problem with custom cursors that have no custom data. The | ||
// resulting SkBitmap is empty and X crashes when creating a zero size cursor | ||
// image. Return invisible cursor here instead. | ||
if (bitmap.drawsNothing()) { | ||
return ToPlatformCursor(invisible_cursor_.get()); | ||
} | ||
|
||
X11CursorOzone* cursor = new X11CursorOzone(bitmap, hotspot); | ||
cursor->AddRef(); | ||
return ToPlatformCursor(cursor); | ||
} | ||
|
||
PlatformCursor X11CursorFactoryOzone::CreateAnimatedCursor( | ||
const std::vector<SkBitmap>& bitmaps, | ||
const gfx::Point& hotspot, | ||
int frame_delay_ms) { | ||
X11CursorOzone* cursor = new X11CursorOzone(bitmaps, hotspot, frame_delay_ms); | ||
cursor->AddRef(); | ||
return ToPlatformCursor(cursor); | ||
} | ||
|
||
void X11CursorFactoryOzone::RefImageCursor(PlatformCursor cursor) { | ||
ToX11CursorOzone(cursor)->AddRef(); | ||
} | ||
|
||
void X11CursorFactoryOzone::UnrefImageCursor(PlatformCursor cursor) { | ||
ToX11CursorOzone(cursor)->Release(); | ||
} | ||
|
||
scoped_refptr<X11CursorOzone> X11CursorFactoryOzone::GetDefaultCursorInternal( | ||
int type) { | ||
if (type == kCursorNone) | ||
return invisible_cursor_; | ||
|
||
// TODO(kylechar): Use predefined X cursors here instead. | ||
if (!default_cursors_.count(type)) { | ||
// Loads the default aura cursor bitmap for cursor type. Falls back on | ||
// pointer cursor then invisible cursor if this fails. | ||
scoped_refptr<X11CursorOzone> cursor = CreateAuraX11Cursor(type); | ||
if (!cursor.get()) { | ||
if (type != kCursorPointer) { | ||
cursor = GetDefaultCursorInternal(kCursorPointer); | ||
} else { | ||
NOTREACHED() << "Failed to load default cursor bitmap"; | ||
} | ||
} | ||
default_cursors_[type] = cursor; | ||
} | ||
|
||
// Returns owned default cursor for this type. | ||
return default_cursors_[type]; | ||
} | ||
|
||
} // namespace ui |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
// Copyright 2016 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_OZONE_PLATFORM_X11_X11_CURSOR_FACTORY_OZONE_H_ | ||
#define UI_OZONE_PLATFORM_X11_X11_CURSOR_FACTORY_OZONE_H_ | ||
|
||
#include <X11/X.h> | ||
|
||
#include <unordered_map> | ||
#include <vector> | ||
|
||
#include "base/macros.h" | ||
#include "base/memory/scoped_ptr.h" | ||
#include "ui/base/cursor/cursor.h" | ||
#include "ui/ozone/public/cursor_factory_ozone.h" | ||
#include "ui/platform_window/x11/x11_cursor_ozone.h" | ||
|
||
namespace ui { | ||
|
||
// CursorFactoryOzone implementation for X11 cursors. | ||
class X11CursorFactoryOzone : public CursorFactoryOzone { | ||
public: | ||
X11CursorFactoryOzone(); | ||
~X11CursorFactoryOzone() override; | ||
|
||
// CursorFactoryOzone: | ||
PlatformCursor GetDefaultCursor(int type) override; | ||
PlatformCursor CreateImageCursor(const SkBitmap& bitmap, | ||
const gfx::Point& hotspot) override; | ||
PlatformCursor CreateAnimatedCursor(const std::vector<SkBitmap>& bitmaps, | ||
const gfx::Point& hotspot, | ||
int frame_delay_ms) override; | ||
void RefImageCursor(PlatformCursor cursor) override; | ||
void UnrefImageCursor(PlatformCursor cursor) override; | ||
|
||
private: | ||
// Loads/caches default cursor or returns cached version. | ||
scoped_refptr<X11CursorOzone> GetDefaultCursorInternal(int type); | ||
|
||
// Holds a single instance of the invisible cursor. X11 has no way to hide | ||
// the cursor so an invisible cursor mimics that. | ||
scoped_refptr<X11CursorOzone> invisible_cursor_; | ||
|
||
std::unordered_map<int, scoped_refptr<X11CursorOzone>> default_cursors_; | ||
|
||
DISALLOW_COPY_AND_ASSIGN(X11CursorFactoryOzone); | ||
}; | ||
|
||
} // namespace ui | ||
|
||
#endif // UI_OZONE_PLATFORM_X11_X11_CURSOR_FACTORY_OZONE_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,6 @@ | ||
include_rules = [ | ||
"+third_party/skia/include", | ||
"+ui/base/x", | ||
"+ui/events", | ||
"+ui/gfx", | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
// Copyright 2016 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/platform_window/x11/x11_cursor_ozone.h" | ||
|
||
#include <X11/Xcursor/Xcursor.h> | ||
#include <X11/Xlib.h> | ||
|
||
#include "base/logging.h" | ||
#include "third_party/skia/include/core/SkBitmap.h" | ||
#include "ui/base/x/x11_util.h" | ||
#include "ui/gfx/geometry/point.h" | ||
|
||
namespace ui { | ||
|
||
namespace { | ||
|
||
// Converts a SKBitmap to unpremul alpha. | ||
SkBitmap ConvertSkBitmapToUnpremul(const SkBitmap& bitmap) { | ||
DCHECK_NE(bitmap.alphaType(), kUnpremul_SkAlphaType); | ||
|
||
SkImageInfo image_info = SkImageInfo::MakeN32(bitmap.width(), bitmap.height(), | ||
kUnpremul_SkAlphaType); | ||
SkBitmap converted_bitmap; | ||
converted_bitmap.allocPixels(image_info); | ||
bitmap.readPixels(image_info, converted_bitmap.getPixels(), | ||
image_info.minRowBytes(), 0, 0); | ||
|
||
return converted_bitmap; | ||
} | ||
|
||
// Creates an XCursorImage for cursor bitmap. | ||
XcursorImage* CreateXCursorImage(const SkBitmap& bitmap, | ||
const gfx::Point& hotspot) { | ||
// X11 expects bitmap with unpremul alpha. If bitmap is premul then convert, | ||
// otherwise semi-transparent parts of cursor will look strange. | ||
if (bitmap.alphaType() != kUnpremul_SkAlphaType) { | ||
SkBitmap converted_bitmap = ConvertSkBitmapToUnpremul(bitmap); | ||
return SkBitmapToXcursorImage(&converted_bitmap, hotspot); | ||
} else { | ||
return SkBitmapToXcursorImage(&bitmap, hotspot); | ||
} | ||
} | ||
|
||
} // namespace | ||
|
||
X11CursorOzone::X11CursorOzone(const SkBitmap& bitmap, | ||
const gfx::Point& hotspot) { | ||
XcursorImage* image = CreateXCursorImage(bitmap, hotspot); | ||
xcursor_ = XcursorImageLoadCursor(gfx::GetXDisplay(), image); | ||
XcursorImageDestroy(image); | ||
} | ||
|
||
X11CursorOzone::X11CursorOzone(const std::vector<SkBitmap>& bitmaps, | ||
const gfx::Point& hotspot, | ||
int frame_delay_ms) { | ||
// Initialize an XCursorImage for each frame, store all of them in | ||
// XCursorImages and load the cursor from that. | ||
XcursorImages* images = XcursorImagesCreate(bitmaps.size()); | ||
images->nimage = bitmaps.size(); | ||
for (size_t frame = 0; frame < bitmaps.size(); ++frame) { | ||
XcursorImage* x_image = CreateXCursorImage(bitmaps[frame], hotspot); | ||
x_image->delay = frame_delay_ms; | ||
images->images[frame] = x_image; | ||
} | ||
|
||
xcursor_ = XcursorImagesLoadCursor(gfx::GetXDisplay(), images); | ||
XcursorImagesDestroy(images); | ||
} | ||
|
||
scoped_refptr<X11CursorOzone> X11CursorOzone::CreateInvisible() { | ||
scoped_refptr<X11CursorOzone> invisible_ = new X11CursorOzone(); | ||
invisible_->xcursor_ = CreateInvisibleCursor(); | ||
return invisible_; | ||
} | ||
|
||
X11CursorOzone::X11CursorOzone() {} | ||
|
||
X11CursorOzone::~X11CursorOzone() { | ||
XFreeCursor(gfx::GetXDisplay(), xcursor_); | ||
} | ||
|
||
} // namespace ui |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
// Copyright 2016 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_PLATFORM_WINDOW_X11_X11_CURSOR_OZONE_H_ | ||
#define UI_PLATFORM_WINDOW_X11_X11_CURSOR_OZONE_H_ | ||
|
||
#include <X11/X.h> | ||
|
||
#include <vector> | ||
|
||
#include "base/macros.h" | ||
#include "base/memory/ref_counted.h" | ||
#include "ui/base/cursor/cursor.h" | ||
#include "ui/platform_window/x11/x11_window_export.h" | ||
|
||
class SkBitmap; | ||
|
||
namespace ui { | ||
|
||
// Ref counted class to hold an X11 cursor resource. Handles creating X11 cursor | ||
// resources from SkBitmap/hotspot and clears the X11 resources on destruction. | ||
class X11_WINDOW_EXPORT X11CursorOzone | ||
: public base::RefCounted<X11CursorOzone> { | ||
public: | ||
X11CursorOzone(const SkBitmap& bitmap, const gfx::Point& hotspot); | ||
X11CursorOzone(const std::vector<SkBitmap>& bitmaps, | ||
const gfx::Point& hotspot, | ||
int frame_delay_ms); | ||
|
||
// Creates a new cursor that is invisible. | ||
static scoped_refptr<X11CursorOzone> CreateInvisible(); | ||
|
||
::Cursor xcursor() const { return xcursor_; } | ||
|
||
private: | ||
friend class base::RefCounted<X11CursorOzone>; | ||
|
||
X11CursorOzone(); | ||
~X11CursorOzone(); | ||
|
||
::Cursor xcursor_ = None; | ||
|
||
DISALLOW_COPY_AND_ASSIGN(X11CursorOzone); | ||
}; | ||
|
||
} // namespace ui | ||
#endif // UI_PLATFORM_WINDOW_X11_X11_CURSOR_OZONE_H_ |
Oops, something went wrong.