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#ifndef CONTENT_COMMON_CURSORS_WEBCURSOR_H_
6#define CONTENT_COMMON_CURSORS_WEBCURSOR_H_
7
8#include <vector>
9
10#include "base/basictypes.h"
11#include "content/common/content_export.h"
12#include "third_party/WebKit/public/platform/WebCursorInfo.h"
13#include "ui/gfx/display.h"
14#include "ui/gfx/native_widget_types.h"
15#include "ui/gfx/point.h"
16#include "ui/gfx/size.h"
17
18#if defined(USE_AURA)
19#include "ui/base/cursor/cursor.h"
20#endif
21
22#if defined(OS_WIN)
23typedef struct HINSTANCE__* HINSTANCE;
24typedef struct HICON__* HICON;
25typedef HICON HCURSOR;
26#elif defined(OS_MACOSX)
27#ifdef __OBJC__
28@class NSCursor;
29#else
30class NSCursor;
31#endif
32#endif
33
34class Pickle;
35class PickleIterator;
36
37namespace content {
38
39// This class encapsulates a cross-platform description of a cursor.  Platform
40// specific methods are provided to translate the cross-platform cursor into a
41// platform specific cursor.  It is also possible to serialize / de-serialize a
42// WebCursor.
43class CONTENT_EXPORT WebCursor {
44 public:
45  struct CursorInfo {
46    explicit CursorInfo(blink::WebCursorInfo::Type cursor_type)
47        : type(cursor_type),
48          image_scale_factor(1) {
49#if defined(OS_WIN)
50      external_handle = NULL;
51#endif
52    }
53
54    CursorInfo()
55        : type(blink::WebCursorInfo::TypePointer),
56          image_scale_factor(1) {
57#if defined(OS_WIN)
58      external_handle = NULL;
59#endif
60    }
61
62    blink::WebCursorInfo::Type type;
63    gfx::Point hotspot;
64    float image_scale_factor;
65    SkBitmap custom_image;
66#if defined(OS_WIN)
67    HCURSOR external_handle;
68#endif
69  };
70
71  WebCursor();
72  explicit WebCursor(const CursorInfo& cursor_info);
73  ~WebCursor();
74
75  // Copy constructor/assignment operator combine.
76  WebCursor(const WebCursor& other);
77  const WebCursor& operator=(const WebCursor& other);
78
79  // Conversion from/to CursorInfo.
80  void InitFromCursorInfo(const CursorInfo& cursor_info);
81  void GetCursorInfo(CursorInfo* cursor_info) const;
82
83  // Serialization / De-serialization
84  bool Deserialize(PickleIterator* iter);
85  bool Serialize(Pickle* pickle) const;
86
87  // Returns true if GetCustomCursor should be used to allocate a platform
88  // specific cursor object.  Otherwise GetCursor should be used.
89  bool IsCustom() const;
90
91  // Returns true if the current cursor object contains the same cursor as the
92  // cursor object passed in. If the current cursor is a custom cursor, we also
93  // compare the bitmaps to verify whether they are equal.
94  bool IsEqual(const WebCursor& other) const;
95
96  // Returns a native cursor representing the current WebCursor instance.
97  gfx::NativeCursor GetNativeCursor();
98
99#if defined(OS_WIN)
100  // Initialize this from the given Windows cursor. The caller must ensure that
101  // the HCURSOR remains valid by not invoking the DestroyCursor/DestroyIcon
102  // APIs on it.
103  void InitFromExternalCursor(HCURSOR handle);
104#endif
105
106#if defined(USE_AURA)
107  ui::PlatformCursor GetPlatformCursor();
108
109  // Updates |device_scale_factor_| and |rotation_| based on |display|.
110  void SetDisplayInfo(const gfx::Display& display);
111
112#elif defined(OS_WIN)
113  // Returns a HCURSOR representing the current WebCursor instance.
114  // The ownership of the HCURSOR (does not apply to external cursors) remains
115  // with the WebCursor instance.
116  HCURSOR GetCursor(HINSTANCE module_handle);
117
118#elif defined(OS_MACOSX)
119  // Initialize this from the given Cocoa NSCursor.
120  void InitFromNSCursor(NSCursor* cursor);
121#endif
122
123 private:
124  // Copies the contents of the WebCursor instance passed in.
125  void Copy(const WebCursor& other);
126
127  // Cleans up the WebCursor instance.
128  void Clear();
129
130  // Platform specific initialization goes here.
131  void InitPlatformData();
132
133  // Platform specific Serialization / De-serialization
134  bool SerializePlatformData(Pickle* pickle) const;
135  bool DeserializePlatformData(PickleIterator* iter);
136
137  // Returns true if the platform data in the current cursor object
138  // matches that of the cursor passed in.
139  bool IsPlatformDataEqual(const WebCursor& other) const ;
140
141  // Copies platform specific data from the WebCursor instance passed in.
142  void CopyPlatformData(const WebCursor& other);
143
144  // Platform specific cleanup.
145  void CleanupPlatformData();
146
147  void SetCustomData(const SkBitmap& image);
148  void ImageFromCustomData(SkBitmap* image) const;
149
150  // Clamp the hotspot to the custom image's bounds, if this is a custom cursor.
151  void ClampHotspot();
152
153  // WebCore::PlatformCursor type.
154  int type_;
155
156  // Hotspot in cursor image in pixels.
157  gfx::Point hotspot_;
158
159  // Custom cursor data, as 32-bit RGBA.
160  // Platform-inspecific because it can be serialized.
161  gfx::Size custom_size_;  // In pixels.
162  float custom_scale_;
163  std::vector<char> custom_data_;
164
165#if defined(OS_WIN)
166  // An externally generated HCURSOR. We assume that it remains valid, i.e we
167  // don't attempt to copy the HCURSOR.
168  HCURSOR external_cursor_;
169#endif
170
171#if defined(USE_AURA) && (defined(USE_X11) || defined(USE_OZONE))
172  // Only used for custom cursors.
173  ui::PlatformCursor platform_cursor_;
174  float device_scale_factor_;
175#elif defined(OS_WIN)
176  // A custom cursor created from custom bitmap data by Webkit.
177  HCURSOR custom_cursor_;
178#endif
179
180#if defined(USE_OZONE)
181  gfx::Display::Rotation rotation_;
182#endif
183};
184
185}  // namespace content
186
187#endif  // CONTENT_COMMON_CURSORS_WEBCURSOR_H_
188