]> git.saurik.com Git - wxWidgets.git/blob - src/osx/cocoa/utils.mm
fixing wrong version commit
[wxWidgets.git] / src / osx / cocoa / utils.mm
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/osx/cocoa/utils.mm
3 // Purpose: various cocoa utility functions
4 // Author: Stefan Csomor
5 // Modified by:
6 // Created: 1998-01-01
7 // RCS-ID: $Id: utils.mm 48805 2007-09-19 14:52:25Z SC $
8 // Copyright: (c) Stefan Csomor
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #include "wx/wxprec.h"
13
14 #include "wx/utils.h"
15
16 #ifndef WX_PRECOMP
17 #include "wx/intl.h"
18 #include "wx/app.h"
19 #if wxUSE_GUI
20 #include "wx/dialog.h"
21 #include "wx/toplevel.h"
22 #include "wx/font.h"
23 #endif
24 #endif
25
26 #include "wx/apptrait.h"
27
28 #include "wx/osx/private.h"
29
30 #if wxUSE_GUI
31 #if wxOSX_USE_COCOA_OR_CARBON
32 #include <CoreServices/CoreServices.h>
33 #include "wx/osx/dcclient.h"
34 #include "wx/osx/private/timer.h"
35 #endif
36 #endif // wxUSE_GUI
37
38 #if wxOSX_USE_COCOA
39
40 #if wxUSE_BASE
41
42 // Emit a beeeeeep
43 void wxBell()
44 {
45 NSBeep();
46 }
47
48 // ----------------------------------------------------------------------------
49 // Common Event Support
50 // ----------------------------------------------------------------------------
51
52 void wxMacWakeUp()
53 {
54 // ensure that we have an auto release pool in place because the event will
55 // be autoreleased from NSEvent:otherEventWithType and we might not have a
56 // global pool during startup or shutdown and we actually never have it if
57 // we're called from another thread
58 //
59 // FIXME: we can't use wxMacAutoreleasePool here because it's in core and
60 // we're in base
61 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
62
63 NSEvent* wakeupEvent = [NSEvent otherEventWithType:NSApplicationDefined
64 location:NSZeroPoint
65 modifierFlags:NSAnyEventMask
66 timestamp:0
67 windowNumber:0
68 context:nil
69 subtype:0
70 data1:0
71 data2:0];
72 [NSApp postEvent:wakeupEvent atStart:NO];
73
74 [pool release];
75 }
76
77 #endif // wxUSE_BASE
78
79 #if wxUSE_GUI
80
81 @interface wxNSAppController : NSObject wxOSX_10_6_AND_LATER(<NSApplicationDelegate>)
82 {
83 }
84
85 - (void)applicationWillFinishLaunching:(NSApplication *)sender;
86
87 - (BOOL)application:(NSApplication *)sender openFile:(NSString *)filename;
88 - (BOOL)applicationShouldOpenUntitledFile:(NSApplication *)sender;
89 - (BOOL)application:(NSApplication *)sender printFile:(NSString *)filename;
90 - (void)handleGetURLEvent:(NSAppleEventDescriptor *)event
91 withReplyEvent:(NSAppleEventDescriptor *)replyEvent;
92
93 - (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender;
94 - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender;
95 - (void)applicationWillTerminate:(NSApplication *)sender;
96 @end
97
98 @implementation wxNSAppController
99
100 - (void)applicationWillFinishLaunching:(NSApplication *)application {
101 wxUnusedVar(application);
102 wxTheApp->OnInit();
103 }
104
105 - (BOOL)application:(NSApplication *)sender openFile:(NSString *)filename;
106 {
107 wxUnusedVar(sender);
108 wxCFStringRef cf(wxCFRetain(filename));
109 wxTheApp->MacOpenFile(cf.AsString()) ;
110 return YES;
111 }
112
113 - (BOOL)applicationShouldOpenUntitledFile:(NSApplication *)sender;
114 {
115 wxUnusedVar(sender);
116 wxTheApp->MacNewFile() ;
117 return NO;
118 }
119
120 - (BOOL)application:(NSApplication *)sender printFile:(NSString *)filename
121 {
122 wxUnusedVar(sender);
123 wxCFStringRef cf(wxCFRetain(filename));
124 wxTheApp->MacPrintFile(cf.AsString()) ;
125 return YES;
126 }
127
128 - (BOOL)applicationShouldHandleReopen:(NSApplication *)sender hasVisibleWindows:(BOOL)flag
129 {
130 wxUnusedVar(flag);
131 wxUnusedVar(sender);
132 wxTheApp->MacReopenApp() ;
133 return NO;
134 }
135
136 - (void)handleGetURLEvent:(NSAppleEventDescriptor *)event
137 withReplyEvent:(NSAppleEventDescriptor *)replyEvent
138 {
139 wxUnusedVar(replyEvent);
140 NSString* url = [[event descriptorAtIndex:1] stringValue];
141 wxCFStringRef cf(wxCFRetain(url));
142 wxTheApp->MacOpenURL(cf.AsString()) ;
143 }
144
145 /*
146 Allowable return values are:
147 NSTerminateNow - it is ok to proceed with termination
148 NSTerminateCancel - the application should not be terminated
149 NSTerminateLater - it may be ok to proceed with termination later. The application must call -replyToApplicationShouldTerminate: with YES or NO once the answer is known
150 this return value is for delegates who need to provide document modal alerts (sheets) in order to decide whether to quit.
151 */
152 - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
153 {
154 wxUnusedVar(sender);
155 wxCloseEvent event;
156 wxTheApp->OnQueryEndSession(event);
157 if ( event.GetVeto() )
158 return NSTerminateCancel;
159
160 return NSTerminateNow;
161 }
162
163 - (void)applicationWillTerminate:(NSApplication *)application {
164 wxUnusedVar(application);
165 wxCloseEvent event;
166 event.SetCanVeto(false);
167 wxTheApp->OnEndSession(event);
168 }
169
170 - (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender
171 {
172 wxUnusedVar(sender);
173 // let wx do this, not cocoa
174 return NO;
175 }
176
177 @end
178
179 /*
180 allows ShowModal to work when using sheets.
181 see include/wx/osx/cocoa/private.h for more info
182 */
183 @implementation ModalDialogDelegate
184 - (id)init
185 {
186 [super init];
187 sheetFinished = NO;
188 resultCode = -1;
189 impl = 0;
190 return self;
191 }
192
193 - (void)setImplementation: (wxDialog *)dialog
194 {
195 impl = dialog;
196 }
197
198 - (BOOL)finished
199 {
200 return sheetFinished;
201 }
202
203 - (int)code
204 {
205 return resultCode;
206 }
207
208 - (void)waitForSheetToFinish
209 {
210 while (!sheetFinished)
211 {
212 wxSafeYield();
213 }
214 }
215
216 - (void)sheetDidEnd:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo
217 {
218 wxUnusedVar(contextInfo);
219 resultCode = returnCode;
220 sheetFinished = YES;
221 // NSAlerts don't need nor respond to orderOut
222 if ([sheet respondsToSelector:@selector(orderOut:)])
223 [sheet orderOut: self];
224
225 if (impl)
226 impl->ModalFinishedCallback(sheet, returnCode);
227 }
228 @end
229
230 bool wxApp::CallOnInit()
231 {
232 if ( sm_isEmbedded )
233 return OnInit();
234
235 return true;
236 }
237
238 bool wxApp::DoInitGui()
239 {
240 wxMacAutoreleasePool pool;
241 [NSApplication sharedApplication];
242
243 if (!sm_isEmbedded)
244 {
245 wxNSAppController* controller = [[wxNSAppController alloc] init];
246 [[NSApplication sharedApplication] setDelegate:controller];
247
248 NSAppleEventManager *appleEventManager = [NSAppleEventManager sharedAppleEventManager];
249 [appleEventManager setEventHandler:controller andSelector:@selector(handleGetURLEvent:withReplyEvent:)
250 forEventClass:kInternetEventClass andEventID:kAEGetURL];
251 }
252 return true;
253 }
254
255 void wxApp::DoCleanUp()
256 {
257 }
258
259 void wxClientDisplayRect(int *x, int *y, int *width, int *height)
260 {
261 NSRect displayRect = [[NSScreen mainScreen] visibleFrame];
262 wxRect r = wxFromNSRect( NULL, displayRect );
263 if ( x )
264 *x = r.x;
265 if ( y )
266 *y = r.y;
267 if ( width )
268 *width = r.GetWidth();
269 if ( height )
270 *height = r.GetHeight();
271
272 }
273
274 void wxGetMousePosition( int* x, int* y )
275 {
276 wxPoint pt = wxFromNSPoint(NULL, [NSEvent mouseLocation]);
277 if ( x )
278 *x = pt.x;
279 if ( y )
280 *y = pt.y;
281 };
282
283 #if wxOSX_USE_COCOA && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6
284
285 wxMouseState wxGetMouseState()
286 {
287 wxMouseState ms;
288
289 wxPoint pt = wxGetMousePosition();
290 ms.SetX(pt.x);
291 ms.SetY(pt.y);
292
293 NSUInteger modifiers = [NSEvent modifierFlags];
294 NSUInteger buttons = [NSEvent pressedMouseButtons];
295
296 ms.SetLeftDown( (buttons & 0x01) != 0 );
297 ms.SetMiddleDown( (buttons & 0x04) != 0 );
298 ms.SetRightDown( (buttons & 0x02) != 0 );
299
300 ms.SetControlDown(modifiers & NSControlKeyMask);
301 ms.SetShiftDown(modifiers & NSShiftKeyMask);
302 ms.SetAltDown(modifiers & NSAlternateKeyMask);
303 ms.SetMetaDown(modifiers & NSCommandKeyMask);
304
305 return ms;
306 }
307
308
309 #endif
310
311 wxTimerImpl* wxGUIAppTraits::CreateTimerImpl(wxTimer *timer)
312 {
313 return new wxOSXTimerImpl(timer);
314 }
315
316 int gs_wxBusyCursorCount = 0;
317 extern wxCursor gMacCurrentCursor;
318 wxCursor gMacStoredActiveCursor;
319
320 // Set the cursor to the busy cursor for all windows
321 void wxBeginBusyCursor(const wxCursor *cursor)
322 {
323 if (gs_wxBusyCursorCount++ == 0)
324 {
325 gMacStoredActiveCursor = gMacCurrentCursor;
326 cursor->MacInstall();
327
328 wxSetCursor(*cursor);
329 }
330 //else: nothing to do, already set
331 }
332
333 // Restore cursor to normal
334 void wxEndBusyCursor()
335 {
336 wxCHECK_RET( gs_wxBusyCursorCount > 0,
337 wxT("no matching wxBeginBusyCursor() for wxEndBusyCursor()") );
338
339 if (--gs_wxBusyCursorCount == 0)
340 {
341 gMacStoredActiveCursor.MacInstall();
342 gMacStoredActiveCursor = wxNullCursor;
343
344 wxSetCursor(wxNullCursor);
345 }
346 }
347
348 // true if we're between the above two calls
349 bool wxIsBusy()
350 {
351 return (gs_wxBusyCursorCount > 0);
352 }
353
354 wxBitmap wxWindowDCImpl::DoGetAsBitmap(const wxRect *subrect) const
355 {
356 // wxScreenDC is derived from wxWindowDC, so a screen dc will
357 // call this method when a Blit is performed with it as a source.
358 if (!m_window)
359 return wxNullBitmap;
360
361 wxSize sz = m_window->GetSize();
362
363 int left = subrect != NULL ? subrect->x : 0 ;
364 int top = subrect != NULL ? subrect->y : 0 ;
365 int width = subrect != NULL ? subrect->width : sz.x;
366 int height = subrect != NULL ? subrect->height : sz.y ;
367
368 NSRect rect = NSMakeRect(left, top, width, height );
369 NSView* view = (NSView*) m_window->GetHandle();
370 [view lockFocus];
371 // we use this method as other methods force a repaint, and this method can be
372 // called from OnPaint, even with the window's paint dc as source (see wxHTMLWindow)
373 NSBitmapImageRep *rep = [[[NSBitmapImageRep alloc] initWithFocusedViewRect: [view bounds]] retain];
374 [view unlockFocus];
375
376 wxBitmap bitmap(width, height);
377 if ( [rep respondsToSelector:@selector(CGImage)] )
378 {
379 CGImageRef cgImageRef = (CGImageRef)[rep CGImage];
380
381 CGRect r = CGRectMake( 0 , 0 , CGImageGetWidth(cgImageRef) , CGImageGetHeight(cgImageRef) );
382 // since our context is upside down we dont use CGContextDrawImage
383 wxMacDrawCGImage( (CGContextRef) bitmap.GetHBITMAP() , &r, cgImageRef ) ;
384 CGImageRelease(cgImageRef);
385 cgImageRef = NULL;
386 }
387 else
388 {
389 // TODO for 10.4 in case we can support this for osx_cocoa
390 }
391 [rep release];
392
393 return bitmap;
394 }
395
396 #endif // wxUSE_GUI
397
398 #endif // wxOSX_USE_COCOA