]> git.saurik.com Git - wxWidgets.git/blob - src/mac/carbon/app.cpp
Added (untested) support for sub-locales.
[wxWidgets.git] / src / mac / carbon / app.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: app.cpp
3 // Purpose: wxApp
4 // Author: AUTHOR
5 // Modified by:
6 // Created: ??/??/98
7 // RCS-ID: $Id$
8 // Copyright: (c) AUTHOR
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifdef __GNUG__
13 #pragma implementation "app.h"
14 #endif
15
16 #include "wx/frame.h"
17 #include "wx/app.h"
18 #include "wx/utils.h"
19 #include "wx/gdicmn.h"
20 #include "wx/pen.h"
21 #include "wx/brush.h"
22 #include "wx/cursor.h"
23 #include "wx/icon.h"
24 #include "wx/palette.h"
25 #include "wx/dc.h"
26 #include "wx/dialog.h"
27 #include "wx/msgdlg.h"
28 #include "wx/log.h"
29 #include "wx/module.h"
30 #include "wx/memory.h"
31
32 #if wxUSE_WX_RESOURCES
33 #include "wx/resource.h"
34 #endif
35
36 #include <string.h>
37
38 extern char *wxBuffer;
39 extern wxList wxPendingDelete;
40
41 wxApp *wxTheApp = NULL;
42
43 #if !USE_SHARED_LIBRARY
44 IMPLEMENT_DYNAMIC_CLASS(wxApp, wxEvtHandler)
45 BEGIN_EVENT_TABLE(wxApp, wxEvtHandler)
46 EVT_IDLE(wxApp::OnIdle)
47 END_EVENT_TABLE()
48 #endif
49
50 long wxApp::sm_lastMessageTime = 0;
51
52 bool wxApp::Initialize()
53 {
54 #ifdef __WXMSW__
55 wxBuffer = new char[1500];
56 #else
57 wxBuffer = new char[BUFSIZ + 512];
58 #endif
59
60 /* No longer used
61 #if (defined(__WXDEBUG__) && wxUSE_MEMORY_TRACING) || wxUSE_DEBUG_CONTEXT
62
63 streambuf* sBuf = new wxDebugStreamBuf;
64 ostream* oStr = new ostream(sBuf) ;
65 wxDebugContext::SetStream(oStr, sBuf);
66 #endif
67 */
68
69 wxClassInfo::InitializeClasses();
70
71 wxTheColourDatabase = new wxColourDatabase(wxKEY_STRING);
72 wxTheColourDatabase->Initialize();
73
74 wxInitializeStockLists();
75 wxInitializeStockObjects();
76
77 #if wxUSE_WX_RESOURCES
78 wxInitializeResourceSystem();
79 #endif
80
81 wxBitmap::InitStandardHandlers();
82
83 wxModule::RegisterModules();
84 wxASSERT( wxModule::InitializeModules() == TRUE );
85
86 return TRUE;
87 }
88
89 void wxApp::CleanUp()
90 {
91 wxModule::CleanUpModules();
92
93 #if wxUSE_WX_RESOURCES
94 wxCleanUpResourceSystem();
95 #endif
96
97 wxDeleteStockObjects() ;
98
99 // Destroy all GDI lists, etc.
100
101 delete wxTheBrushList;
102 wxTheBrushList = NULL;
103
104 delete wxThePenList;
105 wxThePenList = NULL;
106
107 delete wxTheFontList;
108 wxTheFontList = NULL;
109
110 delete wxTheBitmapList;
111 wxTheBitmapList = NULL;
112
113 delete wxTheColourDatabase;
114 wxTheColourDatabase = NULL;
115
116 wxBitmap::CleanUpHandlers();
117
118 delete[] wxBuffer;
119 wxBuffer = NULL;
120
121 wxClassInfo::CleanUpClasses();
122
123 delete wxTheApp;
124 wxTheApp = NULL;
125
126 #if (defined(__WXDEBUG__) && wxUSE_MEMORY_TRACING) || wxUSE_DEBUG_CONTEXT
127 // At this point we want to check if there are any memory
128 // blocks that aren't part of the wxDebugContext itself,
129 // as a special case. Then when dumping we need to ignore
130 // wxDebugContext, too.
131 if (wxDebugContext::CountObjectsLeft() > 0)
132 {
133 wxTrace("There were memory leaks.\n");
134 wxDebugContext::Dump();
135 wxDebugContext::PrintStatistics();
136 }
137 // wxDebugContext::SetStream(NULL, NULL);
138 #endif
139
140 // do it as the very last thing because everything else can log messages
141 wxLog::DontCreateOnDemand();
142 // do it as the very last thing because everything else can log messages
143 delete wxLog::SetActiveTarget(NULL);
144 }
145
146 int wxEntry( int argc, char *argv[] )
147 {
148 if (!wxApp::Initialize())
149 return FALSE;
150 if (!wxTheApp)
151 {
152 if (!wxApp::GetInitializerFunction())
153 {
154 printf( "wxWindows error: No initializer - use IMPLEMENT_APP macro.\n" );
155 return 0;
156 };
157
158 wxTheApp = (wxApp*) (* wxApp::GetInitializerFunction()) ();
159 };
160
161 if (!wxTheApp)
162 {
163 printf( "wxWindows error: wxTheApp == NULL\n" );
164 return 0;
165 };
166
167 wxTheApp->argc = argc;
168 wxTheApp->argv = argv;
169
170 // GUI-specific initialization, such as creating an app context.
171 wxTheApp->OnInitGui();
172
173 // Here frames insert themselves automatically
174 // into wxTopLevelWindows by getting created
175 // in OnInit().
176
177 if (!wxTheApp->OnInit()) return 0;
178
179 int retValue = 0;
180
181 if (wxTheApp->Initialized()) retValue = wxTheApp->OnRun();
182
183 if (wxTheApp->GetTopWindow())
184 {
185 delete wxTheApp->GetTopWindow();
186 wxTheApp->SetTopWindow(NULL);
187 }
188
189 wxTheApp->DeletePendingObjects();
190
191 wxTheApp->OnExit();
192
193 wxApp::CleanUp();
194
195 return retValue;
196 };
197
198 // Static member initialization
199 wxAppInitializerFunction wxApp::m_appInitFn = (wxAppInitializerFunction) NULL;
200
201 wxApp::wxApp()
202 {
203 m_topWindow = NULL;
204 wxTheApp = this;
205 m_className = "";
206 m_wantDebugOutput = TRUE ;
207 m_appName = "";
208 argc = 0;
209 argv = NULL;
210 #ifdef __WXMSW__
211 m_printMode = wxPRINT_WINDOWS;
212 #else
213 m_printMode = wxPRINT_POSTSCRIPT;
214 #endif
215 m_exitOnFrameDelete = TRUE;
216 m_auto3D = TRUE;
217 }
218
219 bool wxApp::Initialized()
220 {
221 if (GetTopWindow())
222 return TRUE;
223 else
224 return FALSE;
225 }
226
227 int wxApp::MainLoop()
228 {
229 m_keepGoing = TRUE;
230
231 /* TODO: implement your main loop here, calling ProcessIdle in idle time.
232 while (m_keepGoing)
233 {
234 while (!::PeekMessage(&s_currentMsg, 0, 0, 0, PM_NOREMOVE) &&
235 ProcessIdle()) {}
236 if (!DoMessage())
237 m_keepGoing = FALSE;
238 }
239 */
240
241 return 0;
242 }
243
244 // Returns TRUE if more time is needed.
245 bool wxApp::ProcessIdle()
246 {
247 wxIdleEvent event;
248 event.SetEventObject(this);
249 ProcessEvent(event);
250
251 return event.MoreRequested();
252 }
253
254 void wxApp::ExitMainLoop()
255 {
256 m_keepGoing = FALSE;
257 }
258
259 // Is a message/event pending?
260 bool wxApp::Pending()
261 {
262 /* TODO.
263 */
264 return FALSE;
265 }
266
267 // Dispatch a message.
268 void wxApp::Dispatch()
269 {
270 /* TODO.
271 */
272 }
273
274 void wxApp::OnIdle(wxIdleEvent& event)
275 {
276 static bool inOnIdle = FALSE;
277
278 // Avoid recursion (via ProcessEvent default case)
279 if (inOnIdle)
280 return;
281
282 inOnIdle = TRUE;
283
284 // 'Garbage' collection of windows deleted with Close().
285 DeletePendingObjects();
286
287 // flush the logged messages if any
288 wxLog *pLog = wxLog::GetActiveTarget();
289 if ( pLog != NULL && pLog->HasPendingMessages() )
290 pLog->Flush();
291
292 // Send OnIdle events to all windows
293 bool needMore = SendIdleEvents();
294
295 if (needMore)
296 event.RequestMore(TRUE);
297
298 inOnIdle = FALSE;
299 }
300
301 // Send idle event to all top-level windows
302 bool wxApp::SendIdleEvents()
303 {
304 bool needMore = FALSE;
305 wxNode* node = wxTopLevelWindows.First();
306 while (node)
307 {
308 wxWindow* win = (wxWindow*) node->Data();
309 if (SendIdleEvents(win))
310 needMore = TRUE;
311
312 node = node->Next();
313 }
314 return needMore;
315 }
316
317 // Send idle event to window and all subwindows
318 bool wxApp::SendIdleEvents(wxWindow* win)
319 {
320 bool needMore = FALSE;
321
322 wxIdleEvent event;
323 event.SetEventObject(win);
324 win->ProcessEvent(event);
325
326 if (event.MoreRequested())
327 needMore = TRUE;
328
329 wxNode* node = win->GetChildren().First();
330 while (node)
331 {
332 wxWindow* win = (wxWindow*) node->Data();
333 if (SendIdleEvents(win))
334 needMore = TRUE;
335
336 node = node->Next();
337 }
338 return needMore ;
339 }
340
341 void wxApp::DeletePendingObjects()
342 {
343 wxNode *node = wxPendingDelete.First();
344 while (node)
345 {
346 wxObject *obj = (wxObject *)node->Data();
347
348 delete obj;
349
350 if (wxPendingDelete.Member(obj))
351 delete node;
352
353 // Deleting one object may have deleted other pending
354 // objects, so start from beginning of list again.
355 node = wxPendingDelete.First();
356 }
357 }
358
359 wxLog* wxApp::CreateLogTarget()
360 {
361 return new wxLogGui;
362 }
363
364 wxWindow* wxApp::GetTopWindow() const
365 {
366 if (m_topWindow)
367 return m_topWindow;
368 else if (wxTopLevelWindows.Number() > 0)
369 return (wxWindow*) wxTopLevelWindows.First()->Data();
370 else
371 return NULL;
372 }
373
374 void wxExit()
375 {
376 wxApp::CleanUp();
377 /*
378 * TODO: Exit in some platform-specific way. Not recommended that the app calls this:
379 * only for emergencies.
380 */
381 }
382
383 // Yield to other processes
384 bool wxYield()
385 {
386 /*
387 * TODO
388 */
389 return TRUE;
390 }
391