]> git.saurik.com Git - wxWidgets.git/blame - src/osx/cocoa/utils.mm
Correct typo in configure introduced in r63832.
[wxWidgets.git] / src / osx / cocoa / utils.mm
CommitLineData
33e90275 1/////////////////////////////////////////////////////////////////////////////
0f9b48d1 2// Name: src/osx/cocoa/utils.mm
33e90275
SC
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
33e90275
SC
14#include "wx/utils.h"
15
16#ifndef WX_PRECOMP
17 #include "wx/intl.h"
18 #include "wx/app.h"
19 #if wxUSE_GUI
bfa92264 20 #include "wx/dialog.h"
33e90275
SC
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
33e90275 32 #include <CoreServices/CoreServices.h>
928e7a7e 33 #include "wx/osx/dcclient.h"
33e90275
SC
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
43void wxBell()
44{
45 NSBeep();
46}
47
48// ----------------------------------------------------------------------------
49// Common Event Support
50// ----------------------------------------------------------------------------
51
52void wxMacWakeUp()
53{
3c7eea25
VZ
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];
33e90275
SC
75}
76
77#endif // wxUSE_BASE
945eac79 78
36eca861
SC
79#if wxUSE_GUI
80
c8fdb345 81@interface wxNSAppController : NSObject wxOSX_10_6_AND_LATER(<NSApplicationDelegate>)
c6aa5caf
SC
82{
83}
84
175e9d71
SC
85- (void)applicationWillFinishLaunching:(NSApplication *)sender;
86
c6aa5caf
SC
87- (BOOL)application:(NSApplication *)sender openFile:(NSString *)filename;
88- (BOOL)applicationShouldOpenUntitledFile:(NSApplication *)sender;
89- (BOOL)application:(NSApplication *)sender printFile:(NSString *)filename;
c6aa5caf 90- (void)handleGetURLEvent:(NSAppleEventDescriptor *)event
175e9d71
SC
91 withReplyEvent:(NSAppleEventDescriptor *)replyEvent;
92
93- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)sender;
94- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender;
95- (void)applicationWillTerminate:(NSApplication *)sender;
c6aa5caf
SC
96@end
97
98@implementation wxNSAppController
99
175e9d71
SC
100- (void)applicationWillFinishLaunching:(NSApplication *)application {
101 wxUnusedVar(application);
102 wxTheApp->OnInit();
c6aa5caf
SC
103}
104
105- (BOOL)application:(NSApplication *)sender openFile:(NSString *)filename;
106{
d8207702 107 wxUnusedVar(sender);
c6aa5caf
SC
108 wxCFStringRef cf(wxCFRetain(filename));
109 wxTheApp->MacOpenFile(cf.AsString()) ;
110 return YES;
111}
112
113- (BOOL)applicationShouldOpenUntitledFile:(NSApplication *)sender;
114{
d8207702 115 wxUnusedVar(sender);
c6aa5caf
SC
116 wxTheApp->MacNewFile() ;
117 return NO;
118}
119
120- (BOOL)application:(NSApplication *)sender printFile:(NSString *)filename
121{
d8207702 122 wxUnusedVar(sender);
c6aa5caf
SC
123 wxCFStringRef cf(wxCFRetain(filename));
124 wxTheApp->MacPrintFile(cf.AsString()) ;
125 return YES;
126}
127
175e9d71
SC
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
945eac79 145/*
c6aa5caf
SC
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{
d8207702 154 wxUnusedVar(sender);
175e9d71
SC
155 wxCloseEvent event;
156 wxTheApp->OnQueryEndSession(event);
157 if ( event.GetVeto() )
158 return NSTerminateCancel;
159
160 return NSTerminateNow;
c6aa5caf
SC
161}
162
175e9d71
SC
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
c6aa5caf 171{
d8207702 172 wxUnusedVar(sender);
175e9d71 173 // let wx do this, not cocoa
c6aa5caf
SC
174 return NO;
175}
176
c6aa5caf
SC
177@end
178
03647350 179/*
724999ee 180 allows ShowModal to work when using sheets.
03647350 181 see include/wx/osx/cocoa/private.h for more info
724999ee
KO
182*/
183@implementation ModalDialogDelegate
184- (id)init
185{
186 [super init];
187 sheetFinished = NO;
188 resultCode = -1;
bfa92264 189 impl = 0;
724999ee
KO
190 return self;
191}
192
bfa92264
KO
193- (void)setImplementation: (wxDialog *)dialog
194{
195 impl = dialog;
196}
197
03647350 198- (BOOL)finished
724999ee
KO
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{
d8207702 218 wxUnusedVar(contextInfo);
724999ee
KO
219 resultCode = returnCode;
220 sheetFinished = YES;
037f9d3b
KO
221 // NSAlerts don't need nor respond to orderOut
222 if ([sheet respondsToSelector:@selector(orderOut:)])
223 [sheet orderOut: self];
bfa92264
KO
224
225 if (impl)
226 impl->ModalFinishedCallback(sheet, returnCode);
724999ee
KO
227}
228@end
229
175e9d71
SC
230bool wxApp::CallOnInit()
231{
232 if ( sm_isEmbedded )
233 return OnInit();
234
235 return true;
236}
237
dbeddfb9
SC
238bool wxApp::DoInitGui()
239{
ab9df4fb 240 wxMacAutoreleasePool pool;
dbeddfb9 241 [NSApplication sharedApplication];
c6aa5caf
SC
242
243 if (!sm_isEmbedded)
244 {
245 wxNSAppController* controller = [[wxNSAppController alloc] init];
246 [[NSApplication sharedApplication] setDelegate:controller];
945eac79 247
c6aa5caf
SC
248 NSAppleEventManager *appleEventManager = [NSAppleEventManager sharedAppleEventManager];
249 [appleEventManager setEventHandler:controller andSelector:@selector(handleGetURLEvent:withReplyEvent:)
250 forEventClass:kInternetEventClass andEventID:kAEGetURL];
251 }
dbeddfb9
SC
252 return true;
253}
254
255void wxApp::DoCleanUp()
256{
257}
33e90275 258
33e90275
SC
259void 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();
945eac79 271
33e90275
SC
272}
273
274void wxGetMousePosition( int* x, int* y )
275{
276 wxPoint pt = wxFromNSPoint(NULL, [NSEvent mouseLocation]);
54f11060
SC
277 if ( x )
278 *x = pt.x;
279 if ( y )
280 *y = pt.y;
33e90275
SC
281};
282
f3769d53
SC
283#if wxOSX_USE_COCOA && MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6
284
285wxMouseState 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
33e90275
SC
311wxTimerImpl* wxGUIAppTraits::CreateTimerImpl(wxTimer *timer)
312{
dbeddfb9 313 return new wxOSXTimerImpl(timer);
33e90275
SC
314}
315
316int gs_wxBusyCursorCount = 0;
317extern wxCursor gMacCurrentCursor;
318wxCursor gMacStoredActiveCursor;
319
320// Set the cursor to the busy cursor for all windows
321void 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
334void 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
349bool wxIsBusy()
350{
351 return (gs_wxBusyCursorCount > 0);
352}
353
928e7a7e
KO
354wxBitmap 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;
945eac79 360
928e7a7e 361 wxSize sz = m_window->GetSize();
945eac79 362
928e7a7e
KO
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 ;
945eac79 367
928e7a7e
KO
368 NSRect rect = NSMakeRect(left, top, width, height );
369 NSView* view = (NSView*) m_window->GetHandle();
370 [view lockFocus];
945eac79 371 // we use this method as other methods force a repaint, and this method can be
928e7a7e
KO
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];
03647350 375
1034a6bb
SC
376 wxBitmap bitmap(width, height);
377 if ( [rep respondsToSelector:@selector(CGImage)] )
378 {
379 CGImageRef cgImageRef = (CGImageRef)[rep CGImage];
945eac79 380
1034a6bb
SC
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 }
928e7a7e 391 [rep release];
945eac79 392
928e7a7e
KO
393 return bitmap;
394}
395
33e90275
SC
396#endif // wxUSE_GUI
397
3c7eea25 398#endif // wxOSX_USE_COCOA