]> git.saurik.com Git - wxWidgets.git/blob - src/gtk1/app.cpp
* Thread updates and cleanup (m_locked, MUTEX_UNLOCKED added)
[wxWidgets.git] / src / gtk1 / app.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: app.cpp
3 // Purpose:
4 // Author: Robert Roebling
5 // Created: 01/02/97
6 // Id:
7 // Copyright: (c) 1998 Robert Roebling, Julian Smart and Markus Holzem
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
10
11 #ifdef __GNUG__
12 #pragma implementation "app.h"
13 #endif
14
15 #include "wx/app.h"
16 #include "wx/gdicmn.h"
17 #include "wx/utils.h"
18 #include "wx/postscrp.h"
19 #include "wx/intl.h"
20 #include "wx/log.h"
21
22 #include "unistd.h"
23
24 #ifdef USE_GDK_IMLIB
25 #include "gdk_imlib.h"
26 #endif
27
28 //-----------------------------------------------------------------------------
29 // global data
30 //-----------------------------------------------------------------------------
31
32 wxApp *wxTheApp = NULL;
33 wxAppInitializerFunction wxApp::m_appInitFn = (wxAppInitializerFunction) NULL;
34
35 extern wxList wxPendingDelete;
36
37 //-----------------------------------------------------------------------------
38 // local functions
39 //-----------------------------------------------------------------------------
40
41 extern void wxFlushResources(void);
42
43 //-----------------------------------------------------------------------------
44 // global functions
45 //-----------------------------------------------------------------------------
46
47 void wxExit(void)
48 {
49 gtk_main_quit();
50 };
51
52 bool wxYield(void)
53 {
54 while (gtk_events_pending() > 0) gtk_main_iteration();
55 return TRUE;
56 };
57
58 //-----------------------------------------------------------------------------
59 // wxApp
60 //-----------------------------------------------------------------------------
61
62 IMPLEMENT_DYNAMIC_CLASS(wxApp,wxEvtHandler)
63
64 BEGIN_EVENT_TABLE(wxApp, wxEvtHandler)
65 EVT_IDLE(wxApp::OnIdle)
66 END_EVENT_TABLE()
67
68 gint wxapp_idle_callback( gpointer WXUNUSED(data) )
69 {
70 if (wxTheApp) while (wxTheApp->ProcessIdle()) {};
71 usleep( 10000 );
72 return TRUE;
73 };
74
75 wxApp::wxApp()
76 {
77 m_idleTag = 0;
78 m_topWindow = NULL;
79 m_exitOnFrameDelete = TRUE;
80 };
81
82 wxApp::~wxApp(void)
83 {
84 gtk_idle_remove( m_idleTag );
85 };
86
87 bool wxApp::OnInit(void)
88 {
89 return TRUE;
90 };
91
92 bool wxApp::OnInitGui(void)
93 {
94 m_idleTag = gtk_idle_add( wxapp_idle_callback, NULL );
95 return TRUE;
96 };
97
98 int wxApp::OnRun(void)
99 {
100 return MainLoop();
101 };
102
103 bool wxApp::ProcessIdle(void)
104 {
105 wxIdleEvent event;
106 event.SetEventObject( this );
107 ProcessEvent( event );
108
109 return event.MoreRequested();
110 };
111
112 void wxApp::OnIdle( wxIdleEvent &event )
113 {
114 static bool inOnIdle = FALSE;
115
116 // Avoid recursion (via ProcessEvent default case)
117 if (inOnIdle)
118 return;
119
120 inOnIdle = TRUE;
121
122 // 'Garbage' collection of windows deleted with Close().
123 DeletePendingObjects();
124
125 // flush the logged messages if any
126 wxLog *pLog = wxLog::GetActiveTarget();
127 if ( pLog != NULL && pLog->HasPendingMessages() )
128 pLog->Flush();
129
130 // Send OnIdle events to all windows
131 bool needMore = SendIdleEvents();
132
133 if (needMore)
134 event.RequestMore(TRUE);
135
136 inOnIdle = FALSE;
137 };
138
139 bool wxApp::SendIdleEvents(void)
140 {
141 bool needMore = FALSE;
142 wxNode* node = wxTopLevelWindows.First();
143 while (node)
144 {
145 wxWindow* win = (wxWindow*) node->Data();
146 if (SendIdleEvents(win))
147 needMore = TRUE;
148
149 node = node->Next();
150 }
151 return needMore;
152 };
153
154 bool wxApp::SendIdleEvents( wxWindow* win )
155 {
156 bool needMore = FALSE;
157
158 wxIdleEvent event;
159 event.SetEventObject(win);
160 win->ProcessEvent(event);
161
162 if (event.MoreRequested())
163 needMore = TRUE;
164
165 wxNode* node = win->GetChildren()->First();
166 while (node)
167 {
168 wxWindow* win = (wxWindow*) node->Data();
169 if (SendIdleEvents(win))
170 needMore = TRUE;
171
172 node = node->Next();
173 }
174 return needMore ;
175 };
176
177 int wxApp::OnExit(void)
178 {
179 return 0;
180 };
181
182 int wxApp::MainLoop(void)
183 {
184 gtk_main();
185 return 0;
186 };
187
188 void wxApp::ExitMainLoop(void)
189 {
190 gtk_main_quit();
191 };
192
193 bool wxApp::Initialized(void)
194 {
195 return m_initialized;
196 };
197
198 bool wxApp::Pending(void)
199 {
200 return FALSE;
201 };
202
203 void wxApp::Dispatch(void)
204 {
205 };
206
207 void wxApp::DeletePendingObjects(void)
208 {
209 wxNode *node = wxPendingDelete.First();
210 while (node)
211 {
212 wxObject *obj = (wxObject *)node->Data();
213
214 delete obj;
215
216 if (wxPendingDelete.Member(obj))
217 delete node;
218
219 node = wxPendingDelete.First();
220 };
221 };
222
223 wxWindow *wxApp::GetTopWindow(void)
224 {
225 if (m_topWindow) return m_topWindow;
226 wxNode *node = wxTopLevelWindows.First();
227 if (!node) return NULL;
228 return (wxWindow*)node->Data();
229 };
230
231 void wxApp::SetTopWindow( wxWindow *win )
232 {
233 m_topWindow = win;
234 };
235
236 void wxApp::CommonInit(void)
237 {
238
239 /*
240 #if USE_RESOURCES
241 (void) wxGetResource("wxWindows", "OsVersion", &wxOsVersion);
242 #endif
243 */
244
245 wxTheColourDatabase = new wxColourDatabase(wxKEY_STRING);
246 wxTheColourDatabase->Initialize();
247 wxInitializeStockObjects();
248
249 // For PostScript printing
250 #if USE_POSTSCRIPT
251 wxInitializePrintSetupData();
252 wxThePrintPaperDatabase = new wxPrintPaperDatabase;
253 wxThePrintPaperDatabase->CreateDatabase();
254 #endif
255
256
257 /*
258 wxBitmap::InitStandardHandlers();
259
260 g_globalCursor = new wxCursor;
261 */
262
263 wxInitializeStockObjects();
264 };
265
266 void wxApp::CommonCleanUp(void)
267 {
268 wxDeleteStockObjects();
269
270 wxFlushResources();
271 };
272
273 wxLog *wxApp::CreateLogTarget()
274 {
275 return new wxLogGui;
276 }
277
278 //-----------------------------------------------------------------------------
279 // wxEntry
280 //-----------------------------------------------------------------------------
281
282 int wxEntry( int argc, char *argv[] )
283 {
284 wxBuffer = new char[BUFSIZ + 512];
285
286 wxClassInfo::InitializeClasses();
287
288 if (!wxTheApp)
289 {
290 if (!wxApp::GetInitializerFunction())
291 {
292 printf( "wxWindows error: No initializer - use IMPLEMENT_APP macro.\n" );
293 return 0;
294 };
295
296 wxAppInitializerFunction app_ini = wxApp::GetInitializerFunction();
297
298 wxObject *test_app = app_ini();
299
300 wxTheApp = (wxApp*) test_app;
301
302 // wxTheApp = (wxApp*)( app_ini() );
303 };
304
305 if (!wxTheApp)
306 {
307 printf( "wxWindows error: wxTheApp == NULL\n" );
308 return 0;
309 };
310
311 // printf( "Programmstart.\n" );
312
313 wxTheApp->argc = argc;
314 wxTheApp->argv = argv;
315
316 gtk_init( &argc, &argv );
317
318 #ifdef USE_GDK_IMLIB
319
320 gdk_imlib_init();
321
322 gtk_widget_push_visual(gdk_imlib_get_visual());
323
324 gtk_widget_push_colormap(gdk_imlib_get_colormap());
325
326 #endif
327
328 wxApp::CommonInit();
329
330 wxTheApp->OnInitGui();
331
332 // Here frames insert themselves automatically
333 // into wxTopLevelWindows by getting created
334 // in OnInit().
335
336 if (!wxTheApp->OnInit()) return 0;
337
338 wxTheApp->m_initialized = (wxTopLevelWindows.Number() > 0);
339
340 int retValue = 0;
341
342 if (wxTheApp->Initialized()) retValue = wxTheApp->OnRun();
343
344 wxTheApp->DeletePendingObjects();
345
346 wxTheApp->OnExit();
347
348 wxApp::CommonCleanUp();
349
350 return retValue;
351 };
352
353 //-----------------------------------------------------------------------------
354 // main()
355 //-----------------------------------------------------------------------------
356
357 #if defined(AIX) || defined(AIX4) || defined(____HPUX__)
358
359 // main in IMPLEMENT_WX_MAIN in IMPLEMENT_APP in app.h
360
361 #else
362
363 int main(int argc, char *argv[]) { return wxEntry(argc, argv); }
364
365 #endif
366
367