1/*
2 * Copyright (C) 2004, 2006, 2008 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 *    notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 *    notice, this list of conditions and the following disclaimer in the
11 *    documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#ifndef Cursor_h
27#define Cursor_h
28
29#include "Image.h"
30#include "IntPoint.h"
31#include <wtf/Assertions.h>
32#include <wtf/RefPtr.h>
33
34#if PLATFORM(WIN)
35typedef struct HICON__* HICON;
36typedef HICON HCURSOR;
37#include <wtf/PassRefPtr.h>
38#include <wtf/RefCounted.h>
39#elif PLATFORM(MAC)
40#include <wtf/RetainPtr.h>
41#elif PLATFORM(GTK)
42#include "GRefPtrGtk.h"
43#elif PLATFORM(QT)
44#include <QCursor>
45#elif PLATFORM(BLACKBERRY)
46#include <BlackBerryPlatformCursor.h>
47#endif
48
49#if PLATFORM(MAC) && !PLATFORM(IOS)
50OBJC_CLASS NSCursor;
51#endif
52
53#if PLATFORM(WIN)
54typedef struct HICON__ *HICON;
55typedef HICON HCURSOR;
56#endif
57
58// Looks like it's just PLATFORM(BLACKBERRY) still not using this?
59#if PLATFORM(WIN) || PLATFORM(MAC) || PLATFORM(GTK) || PLATFORM(QT) || PLATFORM(EFL)
60#define WTF_USE_LAZY_NATIVE_CURSOR 1
61#endif
62
63namespace WebCore {
64
65    class Image;
66
67#if PLATFORM(WIN)
68    class SharedCursor : public RefCounted<SharedCursor> {
69    public:
70        static PassRefPtr<SharedCursor> create(HCURSOR nativeCursor) { return adoptRef(new SharedCursor(nativeCursor)); }
71        ~SharedCursor();
72        HCURSOR nativeCursor() const { return m_nativeCursor; }
73    private:
74        SharedCursor(HCURSOR nativeCursor) : m_nativeCursor(nativeCursor) { }
75        HCURSOR m_nativeCursor;
76    };
77    typedef RefPtr<SharedCursor> PlatformCursor;
78#elif PLATFORM(MAC) && !PLATFORM(IOS)
79    typedef NSCursor *PlatformCursor;
80#elif PLATFORM(GTK)
81    typedef GRefPtr<GdkCursor> PlatformCursor;
82#elif PLATFORM(EFL)
83    typedef const char* PlatformCursor;
84#elif PLATFORM(QT) && !defined(QT_NO_CURSOR)
85    // Do not need to be shared but need to be created dynamically via ensurePlatformCursor.
86    typedef QCursor* PlatformCursor;
87#elif PLATFORM(BLACKBERRY)
88    typedef BlackBerry::Platform::BlackBerryCursor PlatformCursor;
89#else
90    typedef void* PlatformCursor;
91#endif
92
93    class Cursor {
94        WTF_MAKE_FAST_ALLOCATED;
95    public:
96        enum Type {
97            Pointer = 0,
98            Cross,
99            Hand,
100            IBeam,
101            Wait,
102            Help,
103            EastResize,
104            NorthResize,
105            NorthEastResize,
106            NorthWestResize,
107            SouthResize,
108            SouthEastResize,
109            SouthWestResize,
110            WestResize,
111            NorthSouthResize,
112            EastWestResize,
113            NorthEastSouthWestResize,
114            NorthWestSouthEastResize,
115            ColumnResize,
116            RowResize,
117            MiddlePanning,
118            EastPanning,
119            NorthPanning,
120            NorthEastPanning,
121            NorthWestPanning,
122            SouthPanning,
123            SouthEastPanning,
124            SouthWestPanning,
125            WestPanning,
126            Move,
127            VerticalText,
128            Cell,
129            ContextMenu,
130            Alias,
131            Progress,
132            NoDrop,
133            Copy,
134            None,
135            NotAllowed,
136            ZoomIn,
137            ZoomOut,
138            Grab,
139            Grabbing,
140            Custom
141        };
142
143        static const Cursor& fromType(Cursor::Type);
144
145        Cursor()
146#if !PLATFORM(IOS) && !PLATFORM(BLACKBERRY)
147#if USE(LAZY_NATIVE_CURSOR)
148            // This is an invalid Cursor and should never actually get used.
149            : m_type(static_cast<Type>(-1))
150            , m_platformCursor(0)
151#else
152            : m_platformCursor(0)
153#endif // USE(LAZY_NATIVE_CURSOR)
154#endif // !PLATFORM(IOS) && !PLATFORM(BLACKBERRY)
155        {
156        }
157
158#if !PLATFORM(IOS)
159        Cursor(Image*, const IntPoint& hotSpot);
160        Cursor(const Cursor&);
161
162#if ENABLE(MOUSE_CURSOR_SCALE)
163        // Hot spot is in image pixels.
164        Cursor(Image*, const IntPoint& hotSpot, float imageScaleFactor);
165#endif
166
167        ~Cursor();
168        Cursor& operator=(const Cursor&);
169
170#if USE(LAZY_NATIVE_CURSOR)
171        explicit Cursor(Type);
172        Type type() const
173        {
174            ASSERT(m_type >= 0 && m_type <= Custom);
175            return m_type;
176        }
177        Image* image() const { return m_image.get(); }
178        const IntPoint& hotSpot() const { return m_hotSpot; }
179#if ENABLE(MOUSE_CURSOR_SCALE)
180        // Image scale in image pixels per logical (UI) pixel.
181        float imageScaleFactor() const { return m_imageScaleFactor; }
182#endif
183        PlatformCursor platformCursor() const;
184#else
185        explicit Cursor(PlatformCursor);
186        PlatformCursor impl() const { return m_platformCursor; }
187#endif
188
189     private:
190#if USE(LAZY_NATIVE_CURSOR)
191        void ensurePlatformCursor() const;
192
193        Type m_type;
194        RefPtr<Image> m_image;
195        IntPoint m_hotSpot;
196#if ENABLE(MOUSE_CURSOR_SCALE)
197        float m_imageScaleFactor;
198#endif
199#endif
200
201#if !PLATFORM(MAC)
202        mutable PlatformCursor m_platformCursor;
203#else
204        mutable RetainPtr<NSCursor> m_platformCursor;
205#endif
206#endif // !PLATFORM(IOS)
207    };
208
209    IntPoint determineHotSpot(Image*, const IntPoint& specifiedHotSpot);
210
211    const Cursor& pointerCursor();
212    const Cursor& crossCursor();
213    const Cursor& handCursor();
214    const Cursor& moveCursor();
215    const Cursor& iBeamCursor();
216    const Cursor& waitCursor();
217    const Cursor& helpCursor();
218    const Cursor& eastResizeCursor();
219    const Cursor& northResizeCursor();
220    const Cursor& northEastResizeCursor();
221    const Cursor& northWestResizeCursor();
222    const Cursor& southResizeCursor();
223    const Cursor& southEastResizeCursor();
224    const Cursor& southWestResizeCursor();
225    const Cursor& westResizeCursor();
226    const Cursor& northSouthResizeCursor();
227    const Cursor& eastWestResizeCursor();
228    const Cursor& northEastSouthWestResizeCursor();
229    const Cursor& northWestSouthEastResizeCursor();
230    const Cursor& columnResizeCursor();
231    const Cursor& rowResizeCursor();
232    const Cursor& middlePanningCursor();
233    const Cursor& eastPanningCursor();
234    const Cursor& northPanningCursor();
235    const Cursor& northEastPanningCursor();
236    const Cursor& northWestPanningCursor();
237    const Cursor& southPanningCursor();
238    const Cursor& southEastPanningCursor();
239    const Cursor& southWestPanningCursor();
240    const Cursor& westPanningCursor();
241    const Cursor& verticalTextCursor();
242    const Cursor& cellCursor();
243    const Cursor& contextMenuCursor();
244    const Cursor& noDropCursor();
245    const Cursor& notAllowedCursor();
246    const Cursor& progressCursor();
247    const Cursor& aliasCursor();
248    const Cursor& zoomInCursor();
249    const Cursor& zoomOutCursor();
250    const Cursor& copyCursor();
251    const Cursor& noneCursor();
252    const Cursor& grabCursor();
253    const Cursor& grabbingCursor();
254
255} // namespace WebCore
256
257#endif // Cursor_h
258