]> git.saurik.com Git - wxWidgets.git/blame - src/mac/cursor.cpp
crash upon hide fix
[wxWidgets.git] / src / mac / cursor.cpp
CommitLineData
e9576ca5
SC
1/////////////////////////////////////////////////////////////////////////////
2// Name: cursor.cpp
3// Purpose: wxCursor class
4// Author: AUTHOR
5// Modified by:
6// Created: ??/??/98
7// RCS-ID: $Id$
8// Copyright: (c) AUTHOR
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12#ifdef __GNUG__
13#pragma implementation "cursor.h"
14#endif
15
0e13e965
GD
16#include "wx/defs.h"
17
18#include "wx/app.h"
e9576ca5
SC
19#include "wx/cursor.h"
20#include "wx/icon.h"
c6a071d2 21#include "wx/image.h"
76a5e5d2 22#include "wx/mac/private.h"
e9576ca5 23
2f1ae414 24#if !USE_SHARED_LIBRARIES
e9576ca5 25IMPLEMENT_DYNAMIC_CLASS(wxCursor, wxBitmap)
2f1ae414 26#endif
e9576ca5 27
c6a071d2
SC
28const short kwxCursorBullseye = 10 ;
29const short kwxCursorBlank = 11 ;
30const short kwxCursorPencil = 12 ;
31const short kwxCursorMagnifier = 13 ;
32const short kwxCursorNoEntry = 14 ;
33const short kwxCursorPaintBrush = 15 ;
34const short kwxCursorPointRight = 16 ;
35const short kwxCursorPointLeft = 17 ;
36const short kwxCursorQuestionArrow = 18 ;
37const short kwxCursorRightArrow = 19 ;
38const short kwxCursorSizeNS = 20 ;
39const short kwxCursorSize = 21 ;
40const short kwxCursorSizeNESW = 22 ;
41const short kwxCursorSizeNWSE = 23 ;
42const short kwxCursorRoller = 24 ;
43
44wxCursor gMacCurrentCursor ;
519cb848 45
e9576ca5
SC
46wxCursorRefData::wxCursorRefData()
47{
c6a071d2
SC
48 m_width = 16;
49 m_height = 16;
519cb848 50 m_hCursor = NULL ;
c6a071d2
SC
51 m_disposeHandle = false ;
52 m_releaseHandle = false ;
53 m_isColorCursor = false ;
54 m_themeCursor = -1 ;
e9576ca5
SC
55}
56
57wxCursorRefData::~wxCursorRefData()
58{
c6a071d2
SC
59 if ( m_isColorCursor )
60 {
61 ::DisposeCCursor( (CCrsrHandle) m_hCursor ) ;
62 }
63 else if ( m_disposeHandle )
64 {
65 ::DisposeHandle( (Handle ) m_hCursor ) ;
07c76470
SC
66 }
67 else if ( m_releaseHandle )
c6a071d2 68 {
07c76470
SC
69 // we don't release the resource since it may already
70 // be in use again
c6a071d2 71 }
e9576ca5
SC
72}
73
74// Cursors
75wxCursor::wxCursor()
76{
77}
78
79wxCursor::wxCursor(const char WXUNUSED(bits)[], int WXUNUSED(width), int WXUNUSED(height),
80 int WXUNUSED(hotSpotX), int WXUNUSED(hotSpotY), const char WXUNUSED(maskBits)[])
81{
82}
83
c6a071d2
SC
84wxCursor::wxCursor( const wxImage &image )
85{
ce72eadb 86 CreateFromImage( image ) ;
c6a071d2
SC
87}
88
ce72eadb 89void wxCursor::CreateFromImage(const wxImage & image)
c6a071d2
SC
90{
91 m_refData = new wxCursorRefData;
92
93 wxImage image16 = image.Scale(16,16) ;
94 unsigned char * rgbBits = image16.GetData();
95
96
97 int w = image16.GetWidth() ;
98 int h = image16.GetHeight() ;
99 bool bHasMask = image16.HasMask() ;
100
101 int hotSpotX = image16.GetOptionInt(wxCUR_HOTSPOT_X);
102 int hotSpotY = image16.GetOptionInt(wxCUR_HOTSPOT_Y);
103 if (hotSpotX < 0 || hotSpotX >= w)
104 hotSpotX = 0;
105 if (hotSpotY < 0 || hotSpotY >= h)
106 hotSpotY = 0;
107
108 M_CURSORDATA->m_hCursor = NewHandle( sizeof( Cursor ) ) ;
109 M_CURSORDATA->m_disposeHandle = true ;
110 HLock( (Handle) M_CURSORDATA->m_hCursor ) ;
111 CursPtr cp = *(CursHandle)M_CURSORDATA->m_hCursor ;
112 memset( cp->data , 0 , sizeof( Bits16 ) ) ;
113 memset( cp->mask , 0 , sizeof( Bits16 ) ) ;
114
115 unsigned char mr = image16.GetMaskRed() ;
116 unsigned char mg = image16.GetMaskGreen() ;
117 unsigned char mb = image16.GetMaskBlue() ;
118 for ( int y = 0 ; y < h ; ++y )
119 {
120 short rowbits = 0 ;
121 short maskbits = 0 ;
122
123 for ( int x = 0 ; x < w ; ++x )
124 {
125 long pos = (y * w + x) * 3;
126
127 unsigned char r = rgbBits[pos] ;
128 unsigned char g = rgbBits[pos+1] ;
129 unsigned char b = rgbBits[pos+2] ;
130 if ( bHasMask && r==mr && g==mg && b==mb )
131 {
132 // masked area, does not appear anywhere
133 }
134 else
135 {
136 if ( (int)r + (int)g + (int)b < 0x60 )
137 {
138 rowbits |= ( 1 << (15-x) ) ;
139 }
140 maskbits |= ( 1 << (15-x) ) ;
141 }
142 }
143 cp->data[y] = rowbits ;
144 cp->mask[y] = maskbits ;
145 }
146 if ( !bHasMask )
147 {
148 memcpy( cp->mask , cp->data , sizeof( Bits16) ) ;
149 }
150
151 cp->hotSpot.h = hotSpotX ;
152 cp->hotSpot.v = hotSpotY ;
153 HUnlock( (Handle) M_CURSORDATA->m_hCursor ) ;
154}
155
e9576ca5
SC
156wxCursor::wxCursor(const wxString& cursor_file, long flags, int hotSpotX, int hotSpotY)
157{
158 m_refData = new wxCursorRefData;
c6a071d2
SC
159 if ( flags == wxBITMAP_TYPE_MACCURSOR_RESOURCE )
160 {
161 Str255 theName ;
e9576ca5 162
c6a071d2
SC
163 #if TARGET_CARBON
164 c2pstrcpy( (StringPtr) theName , cursor_file ) ;
165 #else
166 strcpy( (char *) theName , cursor_file ) ;
167 c2pstr( (char *) theName ) ;
168 #endif
169
170 wxStAppResource resload ;
07c76470
SC
171 Handle resHandle = ::GetNamedResource( 'crsr' , theName ) ;
172 if ( resHandle )
c6a071d2 173 {
07c76470
SC
174 short theId = -1 ;
175 OSType theType ;
176 GetResInfo( resHandle , &theId , &theType , theName ) ;
177 ReleaseResource( resHandle ) ;
178 M_CURSORDATA->m_hCursor = GetCCursor( theId ) ;
179 if ( M_CURSORDATA->m_hCursor )
180 M_CURSORDATA->m_isColorCursor = true ;
c6a071d2
SC
181 }
182 else
183 {
07c76470
SC
184 Handle resHandle = ::GetNamedResource( 'CURS' , theName ) ;
185 if ( resHandle )
186 {
187 short theId = -1 ;
188 OSType theType ;
189 GetResInfo( resHandle , &theId , &theType , theName ) ;
190 ReleaseResource( resHandle ) ;
191 M_CURSORDATA->m_hCursor = GetCursor( theId ) ;
192 if ( M_CURSORDATA->m_hCursor )
193 M_CURSORDATA->m_releaseHandle = true ;
194 }
c6a071d2
SC
195 }
196 }
197 else
198 {
199 wxImage image ;
200 image.LoadFile( cursor_file , flags ) ;
201 if( image.Ok() )
202 {
203 image.SetOption(wxCUR_HOTSPOT_X,hotSpotX ) ;
204 image.SetOption(wxCUR_HOTSPOT_Y,hotSpotY ) ;
205 delete m_refData ;
ce72eadb 206 CreateFromImage(image) ;
c6a071d2
SC
207 }
208 }
e9576ca5
SC
209}
210
211// Cursors by stock number
212wxCursor::wxCursor(int cursor_type)
213{
214 m_refData = new wxCursorRefData;
c6a071d2 215
e9576ca5
SC
216 switch (cursor_type)
217 {
218 case wxCURSOR_WAIT:
c6a071d2 219 M_CURSORDATA->m_themeCursor = kThemeWatchCursor ;
e9576ca5
SC
220 break;
221 case wxCURSOR_IBEAM:
c6a071d2 222 M_CURSORDATA->m_themeCursor = kThemeIBeamCursor ;
e9576ca5
SC
223 break;
224 case wxCURSOR_CROSS:
c6a071d2 225 M_CURSORDATA->m_themeCursor = kThemeCrossCursor;
e9576ca5
SC
226 break;
227 case wxCURSOR_SIZENWSE:
fe3fcb05
SC
228 {
229 wxStAppResource resload ;
c6a071d2 230 M_CURSORDATA->m_hCursor = ::GetCursor(kwxCursorSizeNWSE);
fe3fcb05 231 }
e9576ca5
SC
232 break;
233 case wxCURSOR_SIZENESW:
fe3fcb05
SC
234 {
235 wxStAppResource resload ;
c6a071d2 236 M_CURSORDATA->m_hCursor = ::GetCursor(kwxCursorSizeNESW);
fe3fcb05 237 }
e9576ca5
SC
238 break;
239 case wxCURSOR_SIZEWE:
fe3fcb05 240 {
c6a071d2 241 M_CURSORDATA->m_themeCursor = kThemeResizeLeftRightCursor;
fe3fcb05 242 }
e9576ca5
SC
243 break;
244 case wxCURSOR_SIZENS:
fe3fcb05
SC
245 {
246 wxStAppResource resload ;
c6a071d2
SC
247 M_CURSORDATA->m_hCursor = ::GetCursor(kwxCursorSizeNS);
248 }
249 break;
250 case wxCURSOR_SIZING:
251 {
252 wxStAppResource resload ;
253 M_CURSORDATA->m_hCursor = ::GetCursor(kwxCursorSize);
fe3fcb05 254 }
e9576ca5 255 break;
e9576ca5 256 case wxCURSOR_HAND:
c6a071d2
SC
257 {
258 M_CURSORDATA->m_themeCursor = kThemePointingHandCursor;
259 }
260 break;
e9576ca5 261 case wxCURSOR_BULLSEYE:
fe3fcb05
SC
262 {
263 wxStAppResource resload ;
c6a071d2 264 M_CURSORDATA->m_hCursor = ::GetCursor(kwxCursorBullseye);
fe3fcb05
SC
265 }
266 break;
e9576ca5 267 case wxCURSOR_PENCIL:
fe3fcb05
SC
268 {
269 wxStAppResource resload ;
c6a071d2 270 M_CURSORDATA->m_hCursor = ::GetCursor(kwxCursorPencil);
fe3fcb05
SC
271 }
272 break;
e9576ca5 273 case wxCURSOR_MAGNIFIER:
fe3fcb05
SC
274 {
275 wxStAppResource resload ;
c6a071d2 276 M_CURSORDATA->m_hCursor = ::GetCursor(kwxCursorMagnifier);
fe3fcb05
SC
277 }
278 break;
e9576ca5 279 case wxCURSOR_NO_ENTRY:
fe3fcb05
SC
280 {
281 wxStAppResource resload ;
c6a071d2 282 M_CURSORDATA->m_hCursor = ::GetCursor(kwxCursorNoEntry);
fe3fcb05
SC
283 }
284 break;
e9576ca5
SC
285 case wxCURSOR_WATCH:
286 {
c6a071d2 287 M_CURSORDATA->m_themeCursor = kThemeWatchCursor;
e9576ca5
SC
288 break;
289 }
290 case wxCURSOR_PAINT_BRUSH:
291 {
c6a071d2
SC
292 wxStAppResource resload ;
293 M_CURSORDATA->m_hCursor = ::GetCursor(kwxCursorPaintBrush);
e9576ca5
SC
294 break;
295 }
296 case wxCURSOR_POINT_LEFT:
297 {
c6a071d2
SC
298 wxStAppResource resload ;
299 M_CURSORDATA->m_hCursor = ::GetCursor(kwxCursorPointLeft);
e9576ca5
SC
300 break;
301 }
302 case wxCURSOR_POINT_RIGHT:
303 {
c6a071d2
SC
304 wxStAppResource resload ;
305 M_CURSORDATA->m_hCursor = ::GetCursor(kwxCursorPointRight);
e9576ca5
SC
306 break;
307 }
308 case wxCURSOR_QUESTION_ARROW:
309 {
c6a071d2
SC
310 wxStAppResource resload ;
311 M_CURSORDATA->m_hCursor = ::GetCursor(kwxCursorQuestionArrow);
e9576ca5
SC
312 break;
313 }
314 case wxCURSOR_BLANK:
315 {
c6a071d2
SC
316 wxStAppResource resload ;
317 M_CURSORDATA->m_hCursor = ::GetCursor(kwxCursorBlank);
318 break;
319 }
320 case wxCURSOR_RIGHT_ARROW:
321 {
322 wxStAppResource resload ;
323 M_CURSORDATA->m_hCursor = ::GetCursor(kwxCursorRightArrow);
e9576ca5
SC
324 break;
325 }
c6a071d2
SC
326 case wxCURSOR_SPRAYCAN:
327 {
328 wxStAppResource resload ;
329 M_CURSORDATA->m_hCursor = ::GetCursor(kwxCursorRoller);
330 break;
331 }
332 case wxCURSOR_CHAR:
e9576ca5 333 case wxCURSOR_ARROW:
c6a071d2
SC
334 case wxCURSOR_LEFT_BUTTON:
335 case wxCURSOR_RIGHT_BUTTON:
336 case wxCURSOR_MIDDLE_BUTTON:
337 default:
338 M_CURSORDATA->m_themeCursor = kThemeArrowCursor ;
e9576ca5 339 break;
519cb848 340 }
c6a071d2
SC
341 if ( M_CURSORDATA->m_themeCursor == -1 )
342 M_CURSORDATA->m_releaseHandle = true ;
519cb848 343}
e9576ca5 344
519cb848
SC
345void wxCursor::MacInstall() const
346{
c6a071d2
SC
347 gMacCurrentCursor = *this ;
348 if ( m_refData && M_CURSORDATA->m_themeCursor != -1 )
349 {
350 SetThemeCursor( M_CURSORDATA->m_themeCursor ) ;
351 }
352 else if ( m_refData && M_CURSORDATA->m_hCursor )
519cb848 353 {
c6a071d2
SC
354 if ( M_CURSORDATA->m_isColorCursor )
355 ::SetCCursor( (CCrsrHandle) M_CURSORDATA->m_hCursor ) ;
356 else
357 ::SetCursor( * (CursHandle) M_CURSORDATA->m_hCursor ) ;
519cb848
SC
358 }
359 else
360 {
c6a071d2 361 SetThemeCursor( kThemeArrowCursor ) ;
519cb848 362 }
e9576ca5
SC
363}
364
365wxCursor::~wxCursor()
366{
367}
368
369// Global cursor setting
370void wxSetCursor(const wxCursor& cursor)
371{
519cb848 372 cursor.MacInstall() ;
e9576ca5
SC
373}
374
375