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 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 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 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 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 250 Cursor::Cursor(Type type) 251 : m_type(type) 252 , m_platformCursor(0) 253 { 254 } 255 256 #if !PLATFORM(MAC) 257 258 PlatformCursor Cursor::platformCursor() const 259 { 260 ensurePlatformCursor(); 261 return m_platformCursor; 262 } 263 264 #endif 265 266 const Cursor& pointerCursor() 267 { 268 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::Pointer)); 269 return c; 270 } 271 272 const Cursor& crossCursor() 273 { 274 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::Cross)); 275 return c; 276 } 277 278 const Cursor& handCursor() 279 { 280 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::Hand)); 281 return c; 282 } 283 284 const Cursor& moveCursor() 285 { 286 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::Move)); 287 return c; 288 } 289 290 const Cursor& verticalTextCursor() 291 { 292 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::VerticalText)); 293 return c; 294 } 295 296 const Cursor& cellCursor() 297 { 298 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::Cell)); 299 return c; 300 } 301 302 const Cursor& contextMenuCursor() 303 { 304 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::ContextMenu)); 305 return c; 306 } 307 308 const Cursor& aliasCursor() 309 { 310 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::Alias)); 311 return c; 312 } 313 314 const Cursor& zoomInCursor() 315 { 316 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::ZoomIn)); 317 return c; 318 } 319 320 const Cursor& zoomOutCursor() 321 { 322 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::ZoomOut)); 323 return c; 324 } 325 326 const Cursor& copyCursor() 327 { 328 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::Copy)); 329 return c; 330 } 331 332 const Cursor& noneCursor() 333 { 334 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::None)); 335 return c; 336 } 337 338 const Cursor& progressCursor() 339 { 340 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::Progress)); 341 return c; 342 } 343 344 const Cursor& noDropCursor() 345 { 346 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::NoDrop)); 347 return c; 348 } 349 350 const Cursor& notAllowedCursor() 351 { 352 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::NotAllowed)); 353 return c; 354 } 355 356 const Cursor& iBeamCursor() 357 { 358 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::IBeam)); 359 return c; 360 } 361 362 const Cursor& waitCursor() 363 { 364 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::Wait)); 365 return c; 366 } 367 368 const Cursor& helpCursor() 369 { 370 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::Help)); 371 return c; 372 } 373 374 const Cursor& eastResizeCursor() 375 { 376 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::EastResize)); 377 return c; 378 } 379 380 const Cursor& northResizeCursor() 381 { 382 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::NorthResize)); 383 return c; 384 } 385 386 const Cursor& northEastResizeCursor() 387 { 388 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::NorthEastResize)); 389 return c; 390 } 391 392 const Cursor& northWestResizeCursor() 393 { 394 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::NorthWestResize)); 395 return c; 396 } 397 398 const Cursor& southResizeCursor() 399 { 400 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::SouthResize)); 401 return c; 402 } 403 404 const Cursor& southEastResizeCursor() 405 { 406 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::SouthEastResize)); 407 return c; 408 } 409 410 const Cursor& southWestResizeCursor() 411 { 412 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::SouthWestResize)); 413 return c; 414 } 415 416 const Cursor& westResizeCursor() 417 { 418 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::WestResize)); 419 return c; 420 } 421 422 const Cursor& northSouthResizeCursor() 423 { 424 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::NorthSouthResize)); 425 return c; 426 } 427 428 const Cursor& eastWestResizeCursor() 429 { 430 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::EastWestResize)); 431 return c; 432 } 433 434 const Cursor& northEastSouthWestResizeCursor() 435 { 436 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::NorthEastSouthWestResize)); 437 return c; 438 } 439 440 const Cursor& northWestSouthEastResizeCursor() 441 { 442 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::NorthWestSouthEastResize)); 443 return c; 444 } 445 446 const Cursor& columnResizeCursor() 447 { 448 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::ColumnResize)); 449 return c; 450 } 451 452 const Cursor& rowResizeCursor() 453 { 454 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::RowResize)); 455 return c; 456 } 457 458 const Cursor& middlePanningCursor() 459 { 460 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::MiddlePanning)); 461 return c; 462 } 463 464 const Cursor& eastPanningCursor() 465 { 466 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::EastPanning)); 467 return c; 468 } 469 470 const Cursor& northPanningCursor() 471 { 472 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::NorthPanning)); 473 return c; 474 } 475 476 const Cursor& northEastPanningCursor() 477 { 478 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::NorthEastPanning)); 479 return c; 480 } 481 482 const Cursor& northWestPanningCursor() 483 { 484 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::NorthWestPanning)); 485 return c; 486 } 487 488 const Cursor& southPanningCursor() 489 { 490 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::SouthPanning)); 491 return c; 492 } 493 494 const Cursor& southEastPanningCursor() 495 { 496 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::SouthEastPanning)); 497 return c; 498 } 499 500 const Cursor& southWestPanningCursor() 501 { 502 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::SouthWestPanning)); 503 return c; 504 } 505 506 const Cursor& westPanningCursor() 507 { 508 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::WestPanning)); 509 return c; 510 } 511 512 const Cursor& grabCursor() 513 { 514 DEFINE_STATIC_LOCAL(Cursor, c, (Cursor::Grab)); 515 return c; 516 } 517 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