Home | History | Annotate | Download | only in platform
      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