1 /*
2 * Copyright (C) 2010 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 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 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 #include "config.h"
27 #include "Cursor.h"
28
29 #include "Image.h"
30
31 namespace WebCore {
32
determineHotSpot(Image * image,const IntPoint & specifiedHotSpot)33 IntPoint determineHotSpot(Image* image, const IntPoint& specifiedHotSpot)
34 {
35 // Hot spot must be inside cursor rectangle.
36 IntRect imageRect = image->rect();
37 if (imageRect.contains(specifiedHotSpot))
38 return specifiedHotSpot;
39
40 // If hot spot is not specified externally, it can be extracted from some image formats (e.g. .cur).
41 IntPoint intrinsicHotSpot;
42 bool imageHasIntrinsicHotSpot = image->getHotSpot(intrinsicHotSpot);
43 if (imageHasIntrinsicHotSpot && imageRect.contains(intrinsicHotSpot))
44 return intrinsicHotSpot;
45
46 return IntPoint();
47 }
48
fromType(Cursor::Type type)49 const Cursor& Cursor::fromType(Cursor::Type type)
50 {
51 switch (type) {
52 case Cursor::Pointer:
53 return pointerCursor();
54 case Cursor::Cross:
55 return crossCursor();
56 case Cursor::Hand:
57 return handCursor();
58 case Cursor::IBeam:
59 return iBeamCursor();
60 case Cursor::Wait:
61 return waitCursor();
62 case Cursor::Help:
63 return helpCursor();
64 case Cursor::EastResize:
65 return eastResizeCursor();
66 case Cursor::NorthResize:
67 return northResizeCursor();
68 case Cursor::NorthEastResize:
69 return northEastResizeCursor();
70 case Cursor::NorthWestResize:
71 return northWestResizeCursor();
72 case Cursor::SouthResize:
73 return southResizeCursor();
74 case Cursor::SouthEastResize:
75 return southEastResizeCursor();
76 case Cursor::SouthWestResize:
77 return southWestResizeCursor();
78 case Cursor::WestResize:
79 return westResizeCursor();
80 case Cursor::NorthSouthResize:
81 return northSouthResizeCursor();
82 case Cursor::EastWestResize:
83 return eastWestResizeCursor();
84 case Cursor::NorthEastSouthWestResize:
85 return northEastSouthWestResizeCursor();
86 case Cursor::NorthWestSouthEastResize:
87 return northWestSouthEastResizeCursor();
88 case Cursor::ColumnResize:
89 return columnResizeCursor();
90 case Cursor::RowResize:
91 return rowResizeCursor();
92 case Cursor::MiddlePanning:
93 return middlePanningCursor();
94 case Cursor::EastPanning:
95 return eastPanningCursor();
96 case Cursor::NorthPanning:
97 return northPanningCursor();
98 case Cursor::NorthEastPanning:
99 return northEastPanningCursor();
100 case Cursor::NorthWestPanning:
101 return northWestPanningCursor();
102 case Cursor::SouthPanning:
103 return southPanningCursor();
104 case Cursor::SouthEastPanning:
105 return southEastPanningCursor();
106 case Cursor::SouthWestPanning:
107 return southWestPanningCursor();
108 case Cursor::WestPanning:
109 return westPanningCursor();
110 case Cursor::Move:
111 return moveCursor();
112 case Cursor::VerticalText:
113 return verticalTextCursor();
114 case Cursor::Cell:
115 return cellCursor();
116 case Cursor::ContextMenu:
117 return contextMenuCursor();
118 case Cursor::Alias:
119 return aliasCursor();
120 case Cursor::Progress:
121 return progressCursor();
122 case Cursor::NoDrop:
123 return noDropCursor();
124 case Cursor::Copy:
125 return copyCursor();
126 case Cursor::None:
127 return noneCursor();
128 case Cursor::NotAllowed:
129 return notAllowedCursor();
130 case Cursor::ZoomIn:
131 return zoomInCursor();
132 case Cursor::ZoomOut:
133 return zoomOutCursor();
134 case Cursor::Grab:
135 return grabCursor();
136 case Cursor::Grabbing:
137 return grabbingCursor();
138 case Cursor::Custom:
139 ASSERT_NOT_REACHED();
140 }
141 return pointerCursor();
142 }
143
nameForCursorType(Cursor::Type type)144 const char* nameForCursorType(Cursor::Type type)
145 {
146 switch (type) {
147 case Cursor::Pointer:
148 return "Pointer";
149 case Cursor::Cross:
150 return "Cross";
151 case Cursor::Hand:
152 return "Hand";
153 case Cursor::IBeam:
154 return "IBeam";
155 case Cursor::Wait:
156 return "Wait";
157 case Cursor::Help:
158 return "Help";
159 case Cursor::EastResize:
160 return "EastResize";
161 case Cursor::NorthResize:
162 return "NorthResize";
163 case Cursor::NorthEastResize:
164 return "NorthEastResize";
165 case Cursor::NorthWestResize:
166 return "NorthWestResize";
167 case Cursor::SouthResize:
168 return "SouthResize";
169 case Cursor::SouthEastResize:
170 return "SouthEastResize";
171 case Cursor::SouthWestResize:
172 return "SouthWestResize";
173 case Cursor::WestResize:
174 return "WestResize";
175 case Cursor::NorthSouthResize:
176 return "NorthSouthResize";
177 case Cursor::EastWestResize:
178 return "EastWestResize";
179 case Cursor::NorthEastSouthWestResize:
180 return "NorthEastSouthWestResize";
181 case Cursor::NorthWestSouthEastResize:
182 return "NorthWestSouthEastResize";
183 case Cursor::ColumnResize:
184 return "ColumnResize";
185 case Cursor::RowResize:
186 return "RowResize";
187 case Cursor::MiddlePanning:
188 return "MiddlePanning";
189 case Cursor::EastPanning:
190 return "EastPanning";
191 case Cursor::NorthPanning:
192 return "NorthPanning";
193 case Cursor::NorthEastPanning:
194 return "NorthEastPanning";
195 case Cursor::NorthWestPanning:
196 return "NorthWestPanning";
197 case Cursor::SouthPanning:
198 return "SouthPanning";
199 case Cursor::SouthEastPanning:
200 return "SouthEastPanning";
201 case Cursor::SouthWestPanning:
202 return "SouthWestPanning";
203 case Cursor::WestPanning:
204 return "WestPanning";
205 case Cursor::Move:
206 return "Move";
207 case Cursor::VerticalText:
208 return "VerticalText";
209 case Cursor::Cell:
210 return "Cell";
211 case Cursor::ContextMenu:
212 return "ContextMenu";
213 case Cursor::Alias:
214 return "Alias";
215 case Cursor::Progress:
216 return "Progress";
217 case Cursor::NoDrop:
218 return "NoDrop";
219 case Cursor::Copy:
220 return "Copy";
221 case Cursor::None:
222 return "None";
223 case Cursor::NotAllowed:
224 return "NotAllowed";
225 case Cursor::ZoomIn:
226 return "ZoomIn";
227 case Cursor::ZoomOut:
228 return "ZoomOut";
229 case Cursor::Grab:
230 return "Grab";
231 case Cursor::Grabbing:
232 return "Grabbing";
233 case Cursor::Custom:
234 return "Custom";
235 }
236
237 return "ERROR";
238 }
239
240 #if USE(LAZY_NATIVE_CURSOR)
241
Cursor(Image * image,const IntPoint & hotSpot)242 Cursor::Cursor(Image* image, const IntPoint& hotSpot)
243 : m_type(Custom)
244 , m_image(image)
245 , m_hotSpot(determineHotSpot(image, hotSpot))
246 , m_platformCursor(0)
247 {
248 }
249
Cursor(Type type)250 Cursor::Cursor(Type type)
251 : m_type(type)
252 , m_platformCursor(0)
253 {
254 }
255
256 #if !PLATFORM(MAC)
257
platformCursor() const258 PlatformCursor Cursor::platformCursor() const
259 {
260 ensurePlatformCursor();
261 return m_platformCursor;
262 }
263
264 #endif
265
pointerCursor()266 const Cursor& pointerCursor()
267 {
268 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::Pointer));
269 return c;
270 }
271
crossCursor()272 const Cursor& crossCursor()
273 {
274 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::Cross));
275 return c;
276 }
277
handCursor()278 const Cursor& handCursor()
279 {
280 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::Hand));
281 return c;
282 }
283
moveCursor()284 const Cursor& moveCursor()
285 {
286 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::Move));
287 return c;
288 }
289
verticalTextCursor()290 const Cursor& verticalTextCursor()
291 {
292 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::VerticalText));
293 return c;
294 }
295
cellCursor()296 const Cursor& cellCursor()
297 {
298 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::Cell));
299 return c;
300 }
301
contextMenuCursor()302 const Cursor& contextMenuCursor()
303 {
304 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::ContextMenu));
305 return c;
306 }
307
aliasCursor()308 const Cursor& aliasCursor()
309 {
310 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::Alias));
311 return c;
312 }
313
zoomInCursor()314 const Cursor& zoomInCursor()
315 {
316 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::ZoomIn));
317 return c;
318 }
319
zoomOutCursor()320 const Cursor& zoomOutCursor()
321 {
322 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::ZoomOut));
323 return c;
324 }
325
copyCursor()326 const Cursor& copyCursor()
327 {
328 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::Copy));
329 return c;
330 }
331
noneCursor()332 const Cursor& noneCursor()
333 {
334 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::None));
335 return c;
336 }
337
progressCursor()338 const Cursor& progressCursor()
339 {
340 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::Progress));
341 return c;
342 }
343
noDropCursor()344 const Cursor& noDropCursor()
345 {
346 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::NoDrop));
347 return c;
348 }
349
notAllowedCursor()350 const Cursor& notAllowedCursor()
351 {
352 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::NotAllowed));
353 return c;
354 }
355
iBeamCursor()356 const Cursor& iBeamCursor()
357 {
358 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::IBeam));
359 return c;
360 }
361
waitCursor()362 const Cursor& waitCursor()
363 {
364 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::Wait));
365 return c;
366 }
367
helpCursor()368 const Cursor& helpCursor()
369 {
370 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::Help));
371 return c;
372 }
373
eastResizeCursor()374 const Cursor& eastResizeCursor()
375 {
376 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::EastResize));
377 return c;
378 }
379
northResizeCursor()380 const Cursor& northResizeCursor()
381 {
382 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::NorthResize));
383 return c;
384 }
385
northEastResizeCursor()386 const Cursor& northEastResizeCursor()
387 {
388 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::NorthEastResize));
389 return c;
390 }
391
northWestResizeCursor()392 const Cursor& northWestResizeCursor()
393 {
394 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::NorthWestResize));
395 return c;
396 }
397
southResizeCursor()398 const Cursor& southResizeCursor()
399 {
400 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::SouthResize));
401 return c;
402 }
403
southEastResizeCursor()404 const Cursor& southEastResizeCursor()
405 {
406 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::SouthEastResize));
407 return c;
408 }
409
southWestResizeCursor()410 const Cursor& southWestResizeCursor()
411 {
412 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::SouthWestResize));
413 return c;
414 }
415
westResizeCursor()416 const Cursor& westResizeCursor()
417 {
418 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::WestResize));
419 return c;
420 }
421
northSouthResizeCursor()422 const Cursor& northSouthResizeCursor()
423 {
424 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::NorthSouthResize));
425 return c;
426 }
427
eastWestResizeCursor()428 const Cursor& eastWestResizeCursor()
429 {
430 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::EastWestResize));
431 return c;
432 }
433
northEastSouthWestResizeCursor()434 const Cursor& northEastSouthWestResizeCursor()
435 {
436 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::NorthEastSouthWestResize));
437 return c;
438 }
439
northWestSouthEastResizeCursor()440 const Cursor& northWestSouthEastResizeCursor()
441 {
442 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::NorthWestSouthEastResize));
443 return c;
444 }
445
columnResizeCursor()446 const Cursor& columnResizeCursor()
447 {
448 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::ColumnResize));
449 return c;
450 }
451
rowResizeCursor()452 const Cursor& rowResizeCursor()
453 {
454 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::RowResize));
455 return c;
456 }
457
middlePanningCursor()458 const Cursor& middlePanningCursor()
459 {
460 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::MiddlePanning));
461 return c;
462 }
463
eastPanningCursor()464 const Cursor& eastPanningCursor()
465 {
466 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::EastPanning));
467 return c;
468 }
469
northPanningCursor()470 const Cursor& northPanningCursor()
471 {
472 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::NorthPanning));
473 return c;
474 }
475
northEastPanningCursor()476 const Cursor& northEastPanningCursor()
477 {
478 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::NorthEastPanning));
479 return c;
480 }
481
northWestPanningCursor()482 const Cursor& northWestPanningCursor()
483 {
484 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::NorthWestPanning));
485 return c;
486 }
487
southPanningCursor()488 const Cursor& southPanningCursor()
489 {
490 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::SouthPanning));
491 return c;
492 }
493
southEastPanningCursor()494 const Cursor& southEastPanningCursor()
495 {
496 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::SouthEastPanning));
497 return c;
498 }
499
southWestPanningCursor()500 const Cursor& southWestPanningCursor()
501 {
502 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::SouthWestPanning));
503 return c;
504 }
505
westPanningCursor()506 const Cursor& westPanningCursor()
507 {
508 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::WestPanning));
509 return c;
510 }
511
grabCursor()512 const Cursor& grabCursor()
513 {
514 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::Grab));
515 return c;
516 }
517
grabbingCursor()518 const Cursor& grabbingCursor()
519 {
520 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::Grabbing));
521 return c;
522 }
523
524 #endif
525
526 } // namespace WebCore
527