1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/osx/cocoa/utils.mm
3 // Purpose: various cocoa utility functions
4 // Author: Stefan Csomor
7 // RCS-ID: $Id: utils.mm 48805 2007-09-19 14:52:25Z SC $
8 // Copyright: (c) Stefan Csomor
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 #include "wx/wxprec.h"
20 #include "wx/dialog.h"
21 #include "wx/toplevel.h"
26 #include "wx/apptrait.h"
28 #include "wx/osx/private.h"
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"
48 // ----------------------------------------------------------------------------
49 // Common Event Support
50 // ----------------------------------------------------------------------------
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
59 // FIXME: we can't use wxMacAutoreleasePool here because it's in core and
61 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
63 NSEvent* wakeupEvent = [NSEvent otherEventWithType:NSApplicationDefined
65 modifierFlags:NSAnyEventMask
72 [NSApp postEvent:wakeupEvent atStart:NO];
81 @interface wxNSAppController : NSObject wxOSX_10_6_AND_LATER(<NSApplicationDelegate>)
85 - (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender;
86 - (BOOL)application:(NSApplication *)sender openFile:(NSString *)filename;
87 - (BOOL)applicationShouldOpenUntitledFile:(NSApplication *)sender;
88 - (BOOL)application:(NSApplication *)sender printFile:(NSString *)filename;
89 - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender;
90 - (void)handleGetURLEvent:(NSAppleEventDescriptor *)event
91 withReplyEvent:(NSAppleEventDescriptor *)replyEvent;
94 @implementation wxNSAppController
96 - (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender
99 // let wx do this, not cocoa
103 - (BOOL)application:(NSApplication *)sender openFile:(NSString *)filename;
106 wxCFStringRef cf(wxCFRetain(filename));
107 wxTheApp->MacOpenFile(cf.AsString()) ;
111 - (BOOL)applicationShouldOpenUntitledFile:(NSApplication *)sender;
114 wxTheApp->MacNewFile() ;
118 - (BOOL)application:(NSApplication *)sender printFile:(NSString *)filename
121 wxCFStringRef cf(wxCFRetain(filename));
122 wxTheApp->MacPrintFile(cf.AsString()) ;
127 Allowable return values are:
128 NSTerminateNow - it is ok to proceed with termination
129 NSTerminateCancel - the application should not be terminated
130 NSTerminateLater - it may be ok to proceed with termination later. The application must call -replyToApplicationShouldTerminate: with YES or NO once the answer is known
131 this return value is for delegates who need to provide document modal alerts (sheets) in order to decide whether to quit.
133 - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
136 wxWindow* win = wxTheApp->GetTopWindow() ;
139 wxCommandEvent exitEvent(wxEVT_COMMAND_MENU_SELECTED, wxApp::s_macExitMenuItemId);
140 if (!win->GetEventHandler()->ProcessEvent(exitEvent))
145 wxTheApp->ExitMainLoop() ;
147 return NSTerminateCancel;
150 - (BOOL)applicationShouldHandleReopen:(NSApplication *)sender hasVisibleWindows:(BOOL)flag
154 wxTheApp->MacReopenApp() ;
158 - (void)handleGetURLEvent:(NSAppleEventDescriptor *)event
159 withReplyEvent:(NSAppleEventDescriptor *)replyEvent
161 wxUnusedVar(replyEvent);
162 NSString* url = [[event descriptorAtIndex:1] stringValue];
163 wxCFStringRef cf(wxCFRetain(url));
164 wxTheApp->MacOpenURL(cf.AsString()) ;
169 allows ShowModal to work when using sheets.
170 see include/wx/osx/cocoa/private.h for more info
172 @implementation ModalDialogDelegate
182 - (void)setImplementation: (wxDialog *)dialog
189 return sheetFinished;
197 - (void)waitForSheetToFinish
199 while (!sheetFinished)
205 - (void)sheetDidEnd:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo
207 wxUnusedVar(contextInfo);
208 resultCode = returnCode;
210 // NSAlerts don't need nor respond to orderOut
211 if ([sheet respondsToSelector:@selector(orderOut:)])
212 [sheet orderOut: self];
215 impl->ModalFinishedCallback(sheet, returnCode);
219 bool wxApp::DoInitGui()
221 wxMacAutoreleasePool pool;
222 [NSApplication sharedApplication];
226 wxNSAppController* controller = [[wxNSAppController alloc] init];
227 [[NSApplication sharedApplication] setDelegate:controller];
229 NSAppleEventManager *appleEventManager = [NSAppleEventManager sharedAppleEventManager];
230 [appleEventManager setEventHandler:controller andSelector:@selector(handleGetURLEvent:withReplyEvent:)
231 forEventClass:kInternetEventClass andEventID:kAEGetURL];
232 [NSApp finishLaunching];
237 void wxApp::DoCleanUp()
241 void wxClientDisplayRect(int *x, int *y, int *width, int *height)
243 NSRect displayRect = [[NSScreen mainScreen] visibleFrame];
244 wxRect r = wxFromNSRect( NULL, displayRect );
250 *width = r.GetWidth();
252 *height = r.GetHeight();
256 void wxGetMousePosition( int* x, int* y )
258 wxPoint pt = wxFromNSPoint(NULL, [NSEvent mouseLocation]);
265 #if wxOSX_USE_COCOA && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6
267 wxMouseState wxGetMouseState()
271 wxPoint pt = wxGetMousePosition();
275 NSUInteger modifiers = [NSEvent modifierFlags];
276 NSUInteger buttons = [NSEvent pressedMouseButtons];
278 ms.SetLeftDown( (buttons & 0x01) != 0 );
279 ms.SetMiddleDown( (buttons & 0x04) != 0 );
280 ms.SetRightDown( (buttons & 0x02) != 0 );
282 ms.SetControlDown(modifiers & NSControlKeyMask);
283 ms.SetShiftDown(modifiers & NSShiftKeyMask);
284 ms.SetAltDown(modifiers & NSAlternateKeyMask);
285 ms.SetMetaDown(modifiers & NSCommandKeyMask);
293 wxTimerImpl* wxGUIAppTraits::CreateTimerImpl(wxTimer *timer)
295 return new wxOSXTimerImpl(timer);
298 int gs_wxBusyCursorCount = 0;
299 extern wxCursor gMacCurrentCursor;
300 wxCursor gMacStoredActiveCursor;
302 // Set the cursor to the busy cursor for all windows
303 void wxBeginBusyCursor(const wxCursor *cursor)
305 if (gs_wxBusyCursorCount++ == 0)
307 gMacStoredActiveCursor = gMacCurrentCursor;
308 cursor->MacInstall();
310 wxSetCursor(*cursor);
312 //else: nothing to do, already set
315 // Restore cursor to normal
316 void wxEndBusyCursor()
318 wxCHECK_RET( gs_wxBusyCursorCount > 0,
319 wxT("no matching wxBeginBusyCursor() for wxEndBusyCursor()") );
321 if (--gs_wxBusyCursorCount == 0)
323 gMacStoredActiveCursor.MacInstall();
324 gMacStoredActiveCursor = wxNullCursor;
326 wxSetCursor(wxNullCursor);
330 // true if we're between the above two calls
333 return (gs_wxBusyCursorCount > 0);
336 wxBitmap wxWindowDCImpl::DoGetAsBitmap(const wxRect *subrect) const
338 // wxScreenDC is derived from wxWindowDC, so a screen dc will
339 // call this method when a Blit is performed with it as a source.
343 wxSize sz = m_window->GetSize();
345 int left = subrect != NULL ? subrect->x : 0 ;
346 int top = subrect != NULL ? subrect->y : 0 ;
347 int width = subrect != NULL ? subrect->width : sz.x;
348 int height = subrect != NULL ? subrect->height : sz.y ;
350 NSRect rect = NSMakeRect(left, top, width, height );
351 NSView* view = (NSView*) m_window->GetHandle();
353 // we use this method as other methods force a repaint, and this method can be
354 // called from OnPaint, even with the window's paint dc as source (see wxHTMLWindow)
355 NSBitmapImageRep *rep = [[[NSBitmapImageRep alloc] initWithFocusedViewRect: [view bounds]] retain];
358 wxBitmap bitmap(width, height);
359 if ( [rep respondsToSelector:@selector(CGImage)] )
361 CGImageRef cgImageRef = (CGImageRef)[rep CGImage];
363 CGRect r = CGRectMake( 0 , 0 , CGImageGetWidth(cgImageRef) , CGImageGetHeight(cgImageRef) );
364 // since our context is upside down we dont use CGContextDrawImage
365 wxMacDrawCGImage( (CGContextRef) bitmap.GetHBITMAP() , &r, cgImageRef ) ;
366 CGImageRelease(cgImageRef);
371 // TODO for 10.4 in case we can support this for osx_cocoa
380 #endif // wxOSX_USE_COCOA