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