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"
14 #include "wx/wxprec.h"
22 #include "wx/toplevel.h"
27 #include "wx/apptrait.h"
29 #include "wx/osx/private.h"
32 #if wxOSX_USE_COCOA_OR_CARBON
33 #include <CoreServices/CoreServices.h>
34 #include "wx/osx/dcclient.h"
35 #include "wx/osx/private/timer.h"
49 // ----------------------------------------------------------------------------
50 // Common Event Support
51 // ----------------------------------------------------------------------------
55 // ensure that we have an auto release pool in place because the event will
56 // be autoreleased from NSEvent:otherEventWithType and we might not have a
57 // global pool during startup or shutdown and we actually never have it if
58 // we're called from another thread
60 // FIXME: we can't use wxMacAutoreleasePool here because it's in core and
62 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
64 NSEvent* wakeupEvent = [NSEvent otherEventWithType:NSApplicationDefined
66 modifierFlags:NSAnyEventMask
73 [NSApp postEvent:wakeupEvent atStart:NO];
82 @interface wxNSAppController : NSObject
86 - (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender;
87 - (BOOL)application:(NSApplication *)sender openFile:(NSString *)filename;
88 - (BOOL)applicationShouldOpenUntitledFile:(NSApplication *)sender;
89 - (BOOL)application:(NSApplication *)sender printFile:(NSString *)filename;
90 - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender;
91 - (void)handleGetURLEvent:(NSAppleEventDescriptor *)event
92 withReplyEvent:(NSAppleEventDescriptor *)replyEvent;
95 @implementation wxNSAppController
97 - (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender
100 // let wx do this, not cocoa
104 - (BOOL)application:(NSApplication *)sender openFile:(NSString *)filename;
107 wxCFStringRef cf(wxCFRetain(filename));
108 wxTheApp->MacOpenFile(cf.AsString()) ;
112 - (BOOL)applicationShouldOpenUntitledFile:(NSApplication *)sender;
115 wxTheApp->MacNewFile() ;
119 - (BOOL)application:(NSApplication *)sender printFile:(NSString *)filename
122 wxCFStringRef cf(wxCFRetain(filename));
123 wxTheApp->MacPrintFile(cf.AsString()) ;
128 Allowable return values are:
129 NSTerminateNow - it is ok to proceed with termination
130 NSTerminateCancel - the application should not be terminated
131 NSTerminateLater - it may be ok to proceed with termination later. The application must call -replyToApplicationShouldTerminate: with YES or NO once the answer is known
132 this return value is for delegates who need to provide document modal alerts (sheets) in order to decide whether to quit.
134 - (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
137 wxWindow* win = wxTheApp->GetTopWindow() ;
140 wxCommandEvent exitEvent(wxEVT_COMMAND_MENU_SELECTED, wxApp::s_macExitMenuItemId);
141 if (!win->GetEventHandler()->ProcessEvent(exitEvent))
146 wxTheApp->ExitMainLoop() ;
148 return NSTerminateCancel;
151 - (BOOL)applicationShouldHandleReopen:(NSApplication *)sender hasVisibleWindows:(BOOL)flag
155 wxTheApp->MacReopenApp() ;
159 - (void)handleGetURLEvent:(NSAppleEventDescriptor *)event
160 withReplyEvent:(NSAppleEventDescriptor *)replyEvent
162 wxUnusedVar(replyEvent);
163 NSString* url = [[event descriptorAtIndex:1] stringValue];
164 wxCFStringRef cf(wxCFRetain(url));
165 wxTheApp->MacOpenURL(cf.AsString()) ;
170 allows ShowModal to work when using sheets.
171 see include/wx/osx/cocoa/private.h for more info
173 @implementation ModalDialogDelegate
184 return sheetFinished;
192 - (void)waitForSheetToFinish
194 while (!sheetFinished)
200 - (void)sheetDidEnd:(NSWindow *)sheet returnCode:(int)returnCode contextInfo:(void *)contextInfo
202 wxUnusedVar(contextInfo);
203 resultCode = returnCode;
205 // NSAlerts don't need nor respond to orderOut
206 if ([sheet respondsToSelector:@selector(orderOut:)])
207 [sheet orderOut: self];
211 bool wxApp::DoInitGui()
213 wxMacAutoreleasePool pool;
214 [NSApplication sharedApplication];
218 wxNSAppController* controller = [[wxNSAppController alloc] init];
219 [[NSApplication sharedApplication] setDelegate:controller];
221 NSAppleEventManager *appleEventManager = [NSAppleEventManager sharedAppleEventManager];
222 [appleEventManager setEventHandler:controller andSelector:@selector(handleGetURLEvent:withReplyEvent:)
223 forEventClass:kInternetEventClass andEventID:kAEGetURL];
224 [NSApp finishLaunching];
229 void wxApp::DoCleanUp()
233 void wxClientDisplayRect(int *x, int *y, int *width, int *height)
235 NSRect displayRect = [[NSScreen mainScreen] visibleFrame];
236 wxRect r = wxFromNSRect( NULL, displayRect );
242 *width = r.GetWidth();
244 *height = r.GetHeight();
248 void wxGetMousePosition( int* x, int* y )
250 wxPoint pt = wxFromNSPoint(NULL, [NSEvent mouseLocation]);
257 wxTimerImpl* wxGUIAppTraits::CreateTimerImpl(wxTimer *timer)
259 return new wxOSXTimerImpl(timer);
262 int gs_wxBusyCursorCount = 0;
263 extern wxCursor gMacCurrentCursor;
264 wxCursor gMacStoredActiveCursor;
266 // Set the cursor to the busy cursor for all windows
267 void wxBeginBusyCursor(const wxCursor *cursor)
269 if (gs_wxBusyCursorCount++ == 0)
271 gMacStoredActiveCursor = gMacCurrentCursor;
272 cursor->MacInstall();
274 wxSetCursor(*cursor);
276 //else: nothing to do, already set
279 // Restore cursor to normal
280 void wxEndBusyCursor()
282 wxCHECK_RET( gs_wxBusyCursorCount > 0,
283 wxT("no matching wxBeginBusyCursor() for wxEndBusyCursor()") );
285 if (--gs_wxBusyCursorCount == 0)
287 gMacStoredActiveCursor.MacInstall();
288 gMacStoredActiveCursor = wxNullCursor;
290 wxSetCursor(wxNullCursor);
294 // true if we're between the above two calls
297 return (gs_wxBusyCursorCount > 0);
300 wxBitmap wxWindowDCImpl::DoGetAsBitmap(const wxRect *subrect) const
302 // wxScreenDC is derived from wxWindowDC, so a screen dc will
303 // call this method when a Blit is performed with it as a source.
307 wxSize sz = m_window->GetSize();
309 int left = subrect != NULL ? subrect->x : 0 ;
310 int top = subrect != NULL ? subrect->y : 0 ;
311 int width = subrect != NULL ? subrect->width : sz.x;
312 int height = subrect != NULL ? subrect->height : sz.y ;
314 NSRect rect = NSMakeRect(left, top, width, height );
315 NSView* view = (NSView*) m_window->GetHandle();
317 // we use this method as other methods force a repaint, and this method can be
318 // called from OnPaint, even with the window's paint dc as source (see wxHTMLWindow)
319 NSBitmapImageRep *rep = [[[NSBitmapImageRep alloc] initWithFocusedViewRect: [view bounds]] retain];
322 wxBitmap bitmap(width, height);
323 if ( [rep respondsToSelector:@selector(CGImage)] )
325 CGImageRef cgImageRef = (CGImageRef)[rep CGImage];
327 CGRect r = CGRectMake( 0 , 0 , CGImageGetWidth(cgImageRef) , CGImageGetHeight(cgImageRef) );
328 // since our context is upside down we dont use CGContextDrawImage
329 wxMacDrawCGImage( (CGContextRef) bitmap.GetHBITMAP() , &r, cgImageRef ) ;
330 CGImageRelease(cgImageRef);
335 // TODO for 10.4 in case we can support this for osx_cocoa
344 #endif // wxOSX_USE_COCOA