1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "webkit/common/cursors/webcursor.h"
6
7#include <X11/Xcursor/Xcursor.h>
8#include <X11/Xlib.h>
9#include <X11/cursorfont.h>
10
11#include "base/logging.h"
12#include "third_party/WebKit/public/web/WebCursorInfo.h"
13#include "ui/base/cursor/cursor.h"
14#include "ui/base/cursor/cursor_loader_x11.h"
15#include "ui/base/x/x11_util.h"
16
17const ui::PlatformCursor WebCursor::GetPlatformCursor() {
18  if (platform_cursor_)
19    return platform_cursor_;
20
21  if (custom_data_.size() == 0)
22    return 0;
23
24  SkBitmap bitmap;
25  bitmap.setConfig(SkBitmap::kARGB_8888_Config,
26                   custom_size_.width(), custom_size_.height());
27  bitmap.allocPixels();
28  memcpy(bitmap.getAddr32(0, 0), custom_data_.data(), custom_data_.size());
29  gfx::Point hotspot = hotspot_;
30  ui::ScaleAndRotateCursorBitmapAndHotpoint(
31      device_scale_factor_, rotation_, &bitmap, &hotspot);
32
33  XcursorImage* image = ui::SkBitmapToXcursorImage(&bitmap, hotspot);
34  platform_cursor_ = ui::CreateReffedCustomXCursor(image);
35  return platform_cursor_;
36}
37
38void WebCursor::SetDisplayInfo(const gfx::Display& display) {
39  if (rotation_ == display.rotation() &&
40      device_scale_factor_ == display.device_scale_factor())
41    return;
42
43  device_scale_factor_ = display.device_scale_factor();
44  rotation_ = display.rotation();
45  if (platform_cursor_)
46    ui::UnrefCustomXCursor(platform_cursor_);
47  platform_cursor_ = 0;
48  // It is not necessary to recreate platform_cursor_ yet, since it will be
49  // recreated on demand when GetPlatformCursor is called.
50}
51
52void WebCursor::InitPlatformData() {
53  platform_cursor_ = 0;
54  device_scale_factor_ = 1.f;
55  rotation_ = gfx::Display::ROTATE_0;
56}
57
58bool WebCursor::SerializePlatformData(Pickle* pickle) const {
59  return true;
60}
61
62bool WebCursor::DeserializePlatformData(PickleIterator* iter) {
63  return true;
64}
65
66bool WebCursor::IsPlatformDataEqual(const WebCursor& other) const {
67  return true;
68}
69
70void WebCursor::CleanupPlatformData() {
71  if (platform_cursor_) {
72    ui::UnrefCustomXCursor(platform_cursor_);
73    platform_cursor_ = 0;
74  }
75}
76
77void WebCursor::CopyPlatformData(const WebCursor& other) {
78  if (platform_cursor_)
79    ui::UnrefCustomXCursor(platform_cursor_);
80  platform_cursor_ = other.platform_cursor_;
81  if (platform_cursor_)
82    ui::RefCustomXCursor(platform_cursor_);
83
84  device_scale_factor_ = other.device_scale_factor_;
85}
86