• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (C) 2004, 2006 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#import "config.h"
27#import "Cursor.h"
28
29#import "BlockExceptions.h"
30#import "FoundationExtras.h"
31#import "Image.h"
32#import "IntPoint.h"
33#import <wtf/StdLibExtras.h>
34
35@interface WebCoreCursorBundle : NSObject { }
36@end
37
38@implementation WebCoreCursorBundle
39@end
40
41namespace WebCore {
42
43// Simple NSCursor calls shouldn't need protection,
44// but creating a cursor with a bad image might throw.
45
46static NSCursor* createCustomCursor(Image* image, const IntPoint& hotspot)
47{
48    // FIXME: The cursor won't animate.  Not sure if that's a big deal.
49    NSImage* img = image->getNSImage();
50    if (!img)
51        return 0;
52    BEGIN_BLOCK_OBJC_EXCEPTIONS;
53    return [[NSCursor alloc] initWithImage:img hotSpot:hotspot];
54    END_BLOCK_OBJC_EXCEPTIONS;
55    return 0;
56}
57
58// Leak these cursors intentionally, that way we won't waste time trying to clean them
59// up at process exit time.
60static NSCursor* leakNamedCursor(const char* name, int x, int y)
61{
62    BEGIN_BLOCK_OBJC_EXCEPTIONS;
63    NSString* resourceName = [[NSString alloc] initWithUTF8String:name];
64    NSImage* cursorImage = [[NSImage alloc] initWithContentsOfFile:
65        [[NSBundle bundleForClass:[WebCoreCursorBundle class]]
66        pathForResource:resourceName ofType:@"png"]];
67    [resourceName release];
68    NSCursor* cursor = 0;
69    if (cursorImage) {
70        NSPoint hotSpotPoint = {x, y}; // workaround for 4213314
71        cursor = [[NSCursor alloc] initWithImage:cursorImage hotSpot:hotSpotPoint];
72        [cursorImage release];
73    }
74    return cursor;
75    END_BLOCK_OBJC_EXCEPTIONS;
76    return nil;
77}
78
79Cursor::Cursor(Image* image, const IntPoint& hotspot)
80    : m_impl(HardRetainWithNSRelease(createCustomCursor(image, hotspot)))
81{
82}
83
84Cursor::Cursor(const Cursor& other)
85    : m_impl(HardRetain(other.m_impl))
86{
87}
88
89Cursor::~Cursor()
90{
91    HardRelease(m_impl);
92}
93
94Cursor& Cursor::operator=(const Cursor& other)
95{
96    HardRetain(other.m_impl);
97    HardRelease(m_impl);
98    m_impl = other.m_impl;
99    return *this;
100}
101
102Cursor::Cursor(NSCursor* c)
103    : m_impl(HardRetain(c))
104{
105}
106
107const Cursor& pointerCursor()
108{
109    DEFINE_STATIC_LOCAL(Cursor, c, ([NSCursor arrowCursor]));
110    return c;
111}
112
113const Cursor& crossCursor()
114{
115    DEFINE_STATIC_LOCAL(Cursor, c, (leakNamedCursor("crossHairCursor", 11, 11)));
116    return c;
117}
118
119const Cursor& handCursor()
120{
121    DEFINE_STATIC_LOCAL(Cursor, c, (leakNamedCursor("linkCursor", 6, 1)));
122    return c;
123}
124
125const Cursor& moveCursor()
126{
127    DEFINE_STATIC_LOCAL(Cursor, c, (leakNamedCursor("moveCursor", 7, 7)));
128    return c;
129}
130
131const Cursor& verticalTextCursor()
132{
133    DEFINE_STATIC_LOCAL(Cursor, c, (leakNamedCursor("verticalTextCursor", 7, 7)));
134    return c;
135}
136
137const Cursor& cellCursor()
138{
139    DEFINE_STATIC_LOCAL(Cursor, c, (leakNamedCursor("cellCursor", 7, 7)));
140    return c;
141}
142
143const Cursor& contextMenuCursor()
144{
145    DEFINE_STATIC_LOCAL(Cursor, c, (leakNamedCursor("contextMenuCursor", 3, 2)));
146    return c;
147}
148
149const Cursor& aliasCursor()
150{
151    DEFINE_STATIC_LOCAL(Cursor, c, (leakNamedCursor("aliasCursor", 11, 3)));
152    return c;
153}
154
155const Cursor& zoomInCursor()
156{
157    DEFINE_STATIC_LOCAL(Cursor, c, (leakNamedCursor("zoomInCursor", 7, 7)));
158    return c;
159}
160
161const Cursor& zoomOutCursor()
162{
163    DEFINE_STATIC_LOCAL(Cursor, c, (leakNamedCursor("zoomOutCursor", 7, 7)));
164    return c;
165}
166
167const Cursor& copyCursor()
168{
169    DEFINE_STATIC_LOCAL(Cursor, c, (leakNamedCursor("copyCursor", 3, 2)));
170    return c;
171}
172
173const Cursor& noneCursor()
174{
175    DEFINE_STATIC_LOCAL(Cursor, c, (leakNamedCursor("noneCursor", 7, 7)));
176    return c;
177}
178
179const Cursor& progressCursor()
180{
181    DEFINE_STATIC_LOCAL(Cursor, c, (leakNamedCursor("progressCursor", 3, 2)));
182    return c;
183}
184
185const Cursor& noDropCursor()
186{
187    DEFINE_STATIC_LOCAL(Cursor, c, (leakNamedCursor("noDropCursor", 3, 1)));
188    return c;
189}
190
191const Cursor& notAllowedCursor()
192{
193    DEFINE_STATIC_LOCAL(Cursor, c, (leakNamedCursor("notAllowedCursor", 11, 11)));
194    return c;
195}
196
197const Cursor& iBeamCursor()
198{
199    DEFINE_STATIC_LOCAL(Cursor, c, ([NSCursor IBeamCursor]));
200    return c;
201}
202
203const Cursor& waitCursor()
204{
205    DEFINE_STATIC_LOCAL(Cursor, c, (leakNamedCursor("waitCursor", 7, 7)));
206    return c;
207}
208
209const Cursor& helpCursor()
210{
211    DEFINE_STATIC_LOCAL(Cursor, c, (leakNamedCursor("helpCursor", 8, 8)));
212    return c;
213}
214
215const Cursor& eastResizeCursor()
216{
217    DEFINE_STATIC_LOCAL(Cursor, c, (leakNamedCursor("eastResizeCursor", 14, 7)));
218    return c;
219}
220
221const Cursor& northResizeCursor()
222{
223    DEFINE_STATIC_LOCAL(Cursor, c, (leakNamedCursor("northResizeCursor", 7, 1)));
224    return c;
225}
226
227const Cursor& northEastResizeCursor()
228{
229    DEFINE_STATIC_LOCAL(Cursor, c, (leakNamedCursor("northEastResizeCursor", 14, 1)));
230    return c;
231}
232
233const Cursor& northWestResizeCursor()
234{
235    DEFINE_STATIC_LOCAL(Cursor, c, (leakNamedCursor("northWestResizeCursor", 0, 0)));
236    return c;
237}
238
239const Cursor& southResizeCursor()
240{
241    DEFINE_STATIC_LOCAL(Cursor, c, (leakNamedCursor("southResizeCursor", 7, 14)));
242    return c;
243}
244
245const Cursor& southEastResizeCursor()
246{
247    DEFINE_STATIC_LOCAL(Cursor, c, (leakNamedCursor("southEastResizeCursor", 14, 14)));
248    return c;
249}
250
251const Cursor& southWestResizeCursor()
252{
253    DEFINE_STATIC_LOCAL(Cursor, c, (leakNamedCursor("southWestResizeCursor", 1, 14)));
254    return c;
255}
256
257const Cursor& westResizeCursor()
258{
259    DEFINE_STATIC_LOCAL(Cursor, c, (leakNamedCursor("westResizeCursor", 1, 7)));
260    return c;
261}
262
263const Cursor& northSouthResizeCursor()
264{
265    DEFINE_STATIC_LOCAL(Cursor, c, (leakNamedCursor("northSouthResizeCursor", 7, 7)));
266    return c;
267}
268
269const Cursor& eastWestResizeCursor()
270{
271    DEFINE_STATIC_LOCAL(Cursor, c, (leakNamedCursor("eastWestResizeCursor", 7, 7)));
272    return c;
273}
274
275const Cursor& northEastSouthWestResizeCursor()
276{
277    DEFINE_STATIC_LOCAL(Cursor, c, (leakNamedCursor("northEastSouthWestResizeCursor", 7, 7)));
278    return c;
279}
280
281const Cursor& northWestSouthEastResizeCursor()
282{
283    DEFINE_STATIC_LOCAL(Cursor, c, (leakNamedCursor("northWestSouthEastResizeCursor", 7, 7)));
284    return c;
285}
286
287const Cursor& columnResizeCursor()
288{
289    DEFINE_STATIC_LOCAL(Cursor, c, ([NSCursor resizeLeftRightCursor]));
290    return c;
291}
292
293const Cursor& rowResizeCursor()
294{
295    DEFINE_STATIC_LOCAL(Cursor, c, ([NSCursor resizeUpDownCursor]));
296    return c;
297}
298
299const Cursor& middlePanningCursor()
300{
301    return moveCursor();
302}
303
304const Cursor& eastPanningCursor()
305{
306    return eastResizeCursor();
307}
308
309const Cursor& northPanningCursor()
310{
311    return northResizeCursor();
312}
313
314const Cursor& northEastPanningCursor()
315{
316    return northEastResizeCursor();
317}
318
319const Cursor& northWestPanningCursor()
320{
321    return northWestResizeCursor();
322}
323
324const Cursor& southPanningCursor()
325{
326    return southResizeCursor();
327}
328
329const Cursor& southEastPanningCursor()
330{
331    return southEastResizeCursor();
332}
333
334const Cursor& southWestPanningCursor()
335{
336    return southWestResizeCursor();
337}
338
339const Cursor& westPanningCursor()
340{
341    return westResizeCursor();
342}
343
344const Cursor& grabCursor()
345{
346    DEFINE_STATIC_LOCAL(Cursor, c, ([NSCursor openHandCursor]));
347    return c;
348}
349
350const Cursor& grabbingCursor()
351{
352    DEFINE_STATIC_LOCAL(Cursor, c, ([NSCursor closedHandCursor]));
353    return c;
354}
355
356}
357