Home | History | Annotate | Download | only in mac
      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 
     41 namespace WebCore {
     42 
     43 // Simple NSCursor calls shouldn't need protection,
     44 // but creating a cursor with a bad image might throw.
     45 
     46 static 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.
     60 static 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 
     79 Cursor::Cursor(Image* image, const IntPoint& hotspot)
     80     : m_impl(HardRetainWithNSRelease(createCustomCursor(image, hotspot)))
     81 {
     82 }
     83 
     84 Cursor::Cursor(const Cursor& other)
     85     : m_impl(HardRetain(other.m_impl))
     86 {
     87 }
     88 
     89 Cursor::~Cursor()
     90 {
     91     HardRelease(m_impl);
     92 }
     93 
     94 Cursor& 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 
    102 Cursor::Cursor(NSCursor* c)
    103     : m_impl(HardRetain(c))
    104 {
    105 }
    106 
    107 const Cursor& pointerCursor()
    108 {
    109     DEFINE_STATIC_LOCAL(Cursor, c, ([NSCursor arrowCursor]));
    110     return c;
    111 }
    112 
    113 const Cursor& crossCursor()
    114 {
    115     DEFINE_STATIC_LOCAL(Cursor, c, (leakNamedCursor("crossHairCursor", 11, 11)));
    116     return c;
    117 }
    118 
    119 const Cursor& handCursor()
    120 {
    121     DEFINE_STATIC_LOCAL(Cursor, c, (leakNamedCursor("linkCursor", 6, 1)));
    122     return c;
    123 }
    124 
    125 const Cursor& moveCursor()
    126 {
    127     DEFINE_STATIC_LOCAL(Cursor, c, (leakNamedCursor("moveCursor", 7, 7)));
    128     return c;
    129 }
    130 
    131 const Cursor& verticalTextCursor()
    132 {
    133     DEFINE_STATIC_LOCAL(Cursor, c, (leakNamedCursor("verticalTextCursor", 7, 7)));
    134     return c;
    135 }
    136 
    137 const Cursor& cellCursor()
    138 {
    139     DEFINE_STATIC_LOCAL(Cursor, c, (leakNamedCursor("cellCursor", 7, 7)));
    140     return c;
    141 }
    142 
    143 const Cursor& contextMenuCursor()
    144 {
    145     DEFINE_STATIC_LOCAL(Cursor, c, (leakNamedCursor("contextMenuCursor", 3, 2)));
    146     return c;
    147 }
    148 
    149 const Cursor& aliasCursor()
    150 {
    151     DEFINE_STATIC_LOCAL(Cursor, c, (leakNamedCursor("aliasCursor", 11, 3)));
    152     return c;
    153 }
    154 
    155 const Cursor& zoomInCursor()
    156 {
    157     DEFINE_STATIC_LOCAL(Cursor, c, (leakNamedCursor("zoomInCursor", 7, 7)));
    158     return c;
    159 }
    160 
    161 const Cursor& zoomOutCursor()
    162 {
    163     DEFINE_STATIC_LOCAL(Cursor, c, (leakNamedCursor("zoomOutCursor", 7, 7)));
    164     return c;
    165 }
    166 
    167 const Cursor& copyCursor()
    168 {
    169     DEFINE_STATIC_LOCAL(Cursor, c, (leakNamedCursor("copyCursor", 3, 2)));
    170     return c;
    171 }
    172 
    173 const Cursor& noneCursor()
    174 {
    175     DEFINE_STATIC_LOCAL(Cursor, c, (leakNamedCursor("noneCursor", 7, 7)));
    176     return c;
    177 }
    178 
    179 const Cursor& progressCursor()
    180 {
    181     DEFINE_STATIC_LOCAL(Cursor, c, (leakNamedCursor("progressCursor", 3, 2)));
    182     return c;
    183 }
    184 
    185 const Cursor& noDropCursor()
    186 {
    187     DEFINE_STATIC_LOCAL(Cursor, c, (leakNamedCursor("noDropCursor", 3, 1)));
    188     return c;
    189 }
    190 
    191 const Cursor& notAllowedCursor()
    192 {
    193     DEFINE_STATIC_LOCAL(Cursor, c, (leakNamedCursor("notAllowedCursor", 11, 11)));
    194     return c;
    195 }
    196 
    197 const Cursor& iBeamCursor()
    198 {
    199     DEFINE_STATIC_LOCAL(Cursor, c, ([NSCursor IBeamCursor]));
    200     return c;
    201 }
    202 
    203 const Cursor& waitCursor()
    204 {
    205     DEFINE_STATIC_LOCAL(Cursor, c, (leakNamedCursor("waitCursor", 7, 7)));
    206     return c;
    207 }
    208 
    209 const Cursor& helpCursor()
    210 {
    211     DEFINE_STATIC_LOCAL(Cursor, c, (leakNamedCursor("helpCursor", 8, 8)));
    212     return c;
    213 }
    214 
    215 const Cursor& eastResizeCursor()
    216 {
    217     DEFINE_STATIC_LOCAL(Cursor, c, (leakNamedCursor("eastResizeCursor", 14, 7)));
    218     return c;
    219 }
    220 
    221 const Cursor& northResizeCursor()
    222 {
    223     DEFINE_STATIC_LOCAL(Cursor, c, (leakNamedCursor("northResizeCursor", 7, 1)));
    224     return c;
    225 }
    226 
    227 const Cursor& northEastResizeCursor()
    228 {
    229     DEFINE_STATIC_LOCAL(Cursor, c, (leakNamedCursor("northEastResizeCursor", 14, 1)));
    230     return c;
    231 }
    232 
    233 const Cursor& northWestResizeCursor()
    234 {
    235     DEFINE_STATIC_LOCAL(Cursor, c, (leakNamedCursor("northWestResizeCursor", 0, 0)));
    236     return c;
    237 }
    238 
    239 const Cursor& southResizeCursor()
    240 {
    241     DEFINE_STATIC_LOCAL(Cursor, c, (leakNamedCursor("southResizeCursor", 7, 14)));
    242     return c;
    243 }
    244 
    245 const Cursor& southEastResizeCursor()
    246 {
    247     DEFINE_STATIC_LOCAL(Cursor, c, (leakNamedCursor("southEastResizeCursor", 14, 14)));
    248     return c;
    249 }
    250 
    251 const Cursor& southWestResizeCursor()
    252 {
    253     DEFINE_STATIC_LOCAL(Cursor, c, (leakNamedCursor("southWestResizeCursor", 1, 14)));
    254     return c;
    255 }
    256 
    257 const Cursor& westResizeCursor()
    258 {
    259     DEFINE_STATIC_LOCAL(Cursor, c, (leakNamedCursor("westResizeCursor", 1, 7)));
    260     return c;
    261 }
    262 
    263 const Cursor& northSouthResizeCursor()
    264 {
    265     DEFINE_STATIC_LOCAL(Cursor, c, (leakNamedCursor("northSouthResizeCursor", 7, 7)));
    266     return c;
    267 }
    268 
    269 const Cursor& eastWestResizeCursor()
    270 {
    271     DEFINE_STATIC_LOCAL(Cursor, c, (leakNamedCursor("eastWestResizeCursor", 7, 7)));
    272     return c;
    273 }
    274 
    275 const Cursor& northEastSouthWestResizeCursor()
    276 {
    277     DEFINE_STATIC_LOCAL(Cursor, c, (leakNamedCursor("northEastSouthWestResizeCursor", 7, 7)));
    278     return c;
    279 }
    280 
    281 const Cursor& northWestSouthEastResizeCursor()
    282 {
    283     DEFINE_STATIC_LOCAL(Cursor, c, (leakNamedCursor("northWestSouthEastResizeCursor", 7, 7)));
    284     return c;
    285 }
    286 
    287 const Cursor& columnResizeCursor()
    288 {
    289     DEFINE_STATIC_LOCAL(Cursor, c, ([NSCursor resizeLeftRightCursor]));
    290     return c;
    291 }
    292 
    293 const Cursor& rowResizeCursor()
    294 {
    295     DEFINE_STATIC_LOCAL(Cursor, c, ([NSCursor resizeUpDownCursor]));
    296     return c;
    297 }
    298 
    299 const Cursor& middlePanningCursor()
    300 {
    301     return moveCursor();
    302 }
    303 
    304 const Cursor& eastPanningCursor()
    305 {
    306     return eastResizeCursor();
    307 }
    308 
    309 const Cursor& northPanningCursor()
    310 {
    311     return northResizeCursor();
    312 }
    313 
    314 const Cursor& northEastPanningCursor()
    315 {
    316     return northEastResizeCursor();
    317 }
    318 
    319 const Cursor& northWestPanningCursor()
    320 {
    321     return northWestResizeCursor();
    322 }
    323 
    324 const Cursor& southPanningCursor()
    325 {
    326     return southResizeCursor();
    327 }
    328 
    329 const Cursor& southEastPanningCursor()
    330 {
    331     return southEastResizeCursor();
    332 }
    333 
    334 const Cursor& southWestPanningCursor()
    335 {
    336     return southWestResizeCursor();
    337 }
    338 
    339 const Cursor& westPanningCursor()
    340 {
    341     return westResizeCursor();
    342 }
    343 
    344 const Cursor& grabCursor()
    345 {
    346     DEFINE_STATIC_LOCAL(Cursor, c, ([NSCursor openHandCursor]));
    347     return c;
    348 }
    349 
    350 const Cursor& grabbingCursor()
    351 {
    352     DEFINE_STATIC_LOCAL(Cursor, c, ([NSCursor closedHandCursor]));
    353     return c;
    354 }
    355 
    356 }
    357