proper app shutdown support for iphone
[wxWidgets.git] / src / osx / iphone / 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/wxprec.h"
15
16 #include "wx/utils.h"
17
18 #ifndef WX_PRECOMP
19     #include "wx/intl.h"
20     #include "wx/app.h"
21     #if wxUSE_GUI
22         #include "wx/toplevel.h"
23         #include "wx/font.h"
24     #endif
25 #endif
26
27 #include "wx/apptrait.h"
28
29 #include "wx/osx/private.h"
30
31 #if wxUSE_GUI
32     #include "wx/osx/private/timer.h"
33     #include "wx/osx/dcclient.h"
34 #endif // wxUSE_GUI
35
36 #if wxOSX_USE_IPHONE
37
38 #include <AudioToolbox/AudioServices.h>
39
40 #if wxUSE_BASE
41
42 // Emit a beeeeeep
43 void wxBell()
44 {
45     // would be kSystemSoundID_UserPreferredAlert but since the headers aren't correct, add it manually
46     AudioServicesPlayAlertSound(0x00001000 );
47 }
48
49 // ----------------------------------------------------------------------------
50 // Common Event Support
51 // ----------------------------------------------------------------------------
52
53 @interface wxAppDelegate : NSObject <UIApplicationDelegate> {
54 }
55
56 @end
57
58 @implementation wxAppDelegate
59
60 - (void)applicationDidFinishLaunching:(UIApplication *)application {    
61         wxTheApp->OnInit();
62 }
63
64 - (void)applicationWillTerminate:(UIApplication *)application { 
65     wxCloseEvent event;
66     wxTheApp->OnEndSession(event);
67 }
68
69 - (void)dealloc {
70         [super dealloc];
71 }
72
73
74 @end
75
76 bool wxApp::CallOnInit()
77 {
78     return true;
79 }
80
81 int wxApp::OnRun()
82 {
83     wxMacAutoreleasePool pool;
84     const char* appname = "app";
85     UIApplicationMain( 1, (char**) &appname, nil, @"wxAppDelegate" );
86     return 1;
87 }
88
89 bool wxApp::DoInitGui()
90 {
91     return true;
92 }
93
94 void wxApp::DoCleanUp()
95 {
96 }
97
98 void wxMacWakeUp()
99 {
100     // TODO
101 }
102
103 #endif // wxUSE_BASE
104
105 #if wxUSE_GUI
106
107 // ----------------------------------------------------------------------------
108 // Launch default browser
109 // ----------------------------------------------------------------------------
110
111 bool wxDoLaunchDefaultBrowser(const wxString& url, int flags)
112 {
113     return [[UIApplication sharedApplication] openURL:[NSURL URLWithString:wxCFStringRef(url).AsNSString()]]
114         == YES;
115 }
116
117 // TODO : reorganize
118
119 extern wxFont* CreateNormalFont()
120 {
121     return new wxFont([UIFont systemFontSize] , wxSWISS, wxNORMAL, wxNORMAL, FALSE, "Helvetica" );
122 }
123
124 extern wxFont* CreateSmallFont()
125 {
126     return new wxFont([UIFont smallSystemFontSize] , wxSWISS, wxNORMAL, wxNORMAL, FALSE, "Helvetica" );
127 }
128
129 extern UIFont* CreateUIFont( const wxFont& font )
130 {
131     return [UIFont fontWithName:wxCFStringRef(font.GetFaceName() ).AsNSString() size:font.GetPointSize()];
132 }
133
134 extern void DrawTextInContext( CGContextRef context, CGPoint where, UIFont *font, NSString* text )
135 {
136     bool contextChanged = ( UIGraphicsGetCurrentContext() != context );
137     if ( contextChanged )
138         UIGraphicsPushContext(context);
139
140     [text drawAtPoint:where withFont:font];
141
142     if ( contextChanged )
143         UIGraphicsPopContext();
144 }
145
146 extern CGSize MeasureTextInContext( UIFont *font, NSString* text )
147 {
148     return  [text sizeWithFont:font];
149 }
150
151 void wxClientDisplayRect(int *x, int *y, int *width, int *height)
152 {
153 #if 0
154     CGRect r = [[UIScreen mainScreen] applicationFrame];
155     CGRect bounds = [[UIScreen mainScreen] bounds];
156     if ( bounds.size.height > r.size.height )
157     {
158         // portrait
159         if ( x )
160             *x = r.origin.x;
161         if ( y )
162             *y = r.origin.y;
163         if ( width )
164             *width = r.size.width;
165         if ( height )
166             *height = r.size.height;
167     }
168     else
169     {
170         // landscape
171         if ( x )
172             *x = r.origin.y;
173         if ( y )
174             *y = r.origin.x;
175         if ( width )
176             *width = r.size.height;
177         if ( height )
178             *height = r.size.width;
179     }
180 #else
181     // it's easier to treat the status bar as an element of the toplevel window 
182     // instead of the desktop in order to support easy rotation
183     if ( x )
184         *x = 0;
185     if ( y )
186         *y = 0;
187     wxDisplaySize(width, height);
188 #endif
189 }
190
191 void wxGetMousePosition( int* x, int* y )
192 {
193     if ( x )
194         *x = 0;
195     if ( y )
196         *y = 0;
197 };
198
199 wxMouseState wxGetMouseState()
200 {
201     wxMouseState ms;
202     return ms;
203 }    
204
205 // Returns depth of screen
206 int wxDisplayDepth()
207 {
208     return 32; // TODO can we determine this ?
209 }
210
211 // Get size of display
212 void wxDisplaySize(int *width, int *height)
213 {
214     CGRect r = [[UIScreen mainScreen] applicationFrame];
215     CGRect bounds = [[UIScreen mainScreen] bounds];
216
217     if ( UIInterfaceOrientationIsPortrait([[UIApplication sharedApplication] statusBarOrientation]) )
218     {
219         // portrait
220         if ( width )
221             *width = (int)bounds.size.width ;
222         if ( height )
223             *height = (int)bounds.size.height;
224     }
225     else
226     {
227         // landscape
228         if ( width )
229             *width = (int)bounds.size.height ;
230         if ( height )
231             *height = (int)bounds.size.width;
232     }
233 }
234
235 wxTimerImpl* wxGUIAppTraits::CreateTimerImpl(wxTimer *timer)
236 {
237     return new wxOSXTimerImpl(timer);
238 }
239
240 int gs_wxBusyCursorCount = 0;
241 extern wxCursor    gMacCurrentCursor;
242 wxCursor        gMacStoredActiveCursor;
243
244 // Set the cursor to the busy cursor for all windows
245 void wxBeginBusyCursor(const wxCursor *cursor)
246 {
247     if (gs_wxBusyCursorCount++ == 0)
248     {
249         gMacStoredActiveCursor = gMacCurrentCursor;
250         cursor->MacInstall();
251
252         wxSetCursor(*cursor);
253     }
254     //else: nothing to do, already set
255 }
256
257 // Restore cursor to normal
258 void wxEndBusyCursor()
259 {
260     wxCHECK_RET( gs_wxBusyCursorCount > 0,
261         wxT("no matching wxBeginBusyCursor() for wxEndBusyCursor()") );
262
263     if (--gs_wxBusyCursorCount == 0)
264     {
265         gMacStoredActiveCursor.MacInstall();
266         gMacStoredActiveCursor = wxNullCursor;
267
268         wxSetCursor(wxNullCursor);
269     }
270 }
271
272 // true if we're between the above two calls
273 bool wxIsBusy()
274 {
275     return (gs_wxBusyCursorCount > 0);
276 }
277
278 bool wxGetKeyState (wxKeyCode key)
279 {
280     return false;
281 }
282
283 wxBitmap wxWindowDCImpl::DoGetAsBitmap(const wxRect *subrect) const
284 {
285     // wxScreenDC is derived from wxWindowDC, so a screen dc will
286     // call this method when a Blit is performed with it as a source.
287     if (!m_window)
288         return wxNullBitmap;
289
290     wxSize sz = m_window->GetSize();
291
292     int left = subrect != NULL ? subrect->x : 0 ;
293     int top = subrect != NULL ? subrect->y : 0 ;
294     int width = subrect != NULL ? subrect->width : sz.x;
295     int height = subrect !=  NULL ? subrect->height : sz.y ;
296
297     wxBitmap bmp = wxBitmap(width, height, 32);
298
299     CGContextRef context = (CGContextRef)bmp.GetHBITMAP();
300
301     CGContextSaveGState(context);
302
303
304     CGContextTranslateCTM( context, 0,  height );
305     CGContextScaleCTM( context, 1, -1 );
306
307     if ( subrect )
308         CGContextTranslateCTM( context, -subrect->x, -subrect->y ) ;
309
310     UIGraphicsPushContext(context);
311     [ (NSView*) m_window->GetHandle() drawRect:CGRectMake(left, top, width, height ) ];
312     UIGraphicsPopContext();
313     CGContextRestoreGState(context);
314
315     return bmp;
316 }
317
318 #endif // wxUSE_GUI
319
320 wxOperatingSystemId wxGetOsVersion(int *verMaj, int *verMin)
321 {
322     // get OS version
323     int major, minor;
324
325     wxString release = wxCFStringRef( wxCFRetain( [ [UIDevice currentDevice] systemVersion] ) ).AsString() ;
326
327     if ( release.empty() ||
328         // TODO use wx method
329          scanf(release.c_str(), wxT("%d.%d"), &major, &minor) != 2 )
330     {
331         // failed to get version string or unrecognized format
332         major =
333         minor = -1;
334     }
335
336     if ( verMaj )
337         *verMaj = major;
338     if ( verMin )
339         *verMin = minor;
340
341     return wxOS_MAC_OSX_DARWIN;
342 }
343
344 wxString wxGetOsDescription()
345 {
346     wxString release = wxCFStringRef( wxCFRetain([ [UIDevice currentDevice] systemName] )).AsString() ;
347
348     return release;
349 }
350
351
352 #endif // wxOSX_USE_IPHONE