1 /////////////////////////////////////////////////////////////////////////////
4 // Author: Robert Roebling
6 // Copyright: (c) 1998 Robert Roebling, Julian Smart
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
11 #pragma implementation "app.h"
15 #include "wx/gdicmn.h"
19 #include "wx/memory.h"
21 #include "wx/settings.h"
22 #if wxUSE_WX_RESOURCES
23 #include "wx/resource.h"
25 #include "wx/module.h"
28 #include "wx/thread.h"
35 #include "wx/gtk/win_gtk.h"
37 //-----------------------------------------------------------------------------
39 //-----------------------------------------------------------------------------
41 wxApp
*wxTheApp
= (wxApp
*) NULL
;
42 wxAppInitializerFunction
wxApp::m_appInitFn
= (wxAppInitializerFunction
) NULL
;
44 extern wxList wxPendingDelete
;
45 extern wxResourceCache
*wxTheResourceCache
;
47 unsigned char g_palette
[64*3] =
115 //-----------------------------------------------------------------------------
117 //-----------------------------------------------------------------------------
119 extern void wxFlushResources(void);
121 //-----------------------------------------------------------------------------
123 //-----------------------------------------------------------------------------
132 while (gtk_events_pending() > 0) gtk_main_iteration();
136 //-----------------------------------------------------------------------------
138 //-----------------------------------------------------------------------------
140 IMPLEMENT_DYNAMIC_CLASS(wxApp
,wxEvtHandler
)
142 BEGIN_EVENT_TABLE(wxApp
, wxEvtHandler
)
143 EVT_IDLE(wxApp::OnIdle
)
146 gint
wxapp_idle_callback( gpointer
WXUNUSED(data
) )
148 if (wxTheApp
) while (wxTheApp
->ProcessIdle()) {}
162 m_topWindow
= (wxWindow
*) NULL
;
163 m_exitOnFrameDelete
= TRUE
;
164 m_colorCube
= (unsigned char*) NULL
;
170 gtk_idle_remove( m_idleTag
);
172 if (m_colorCube
) free(m_colorCube
);
175 bool wxApp::InitVisual()
177 /* Nothing to do for 15, 16, 24, 32 bit displays */
179 GdkVisual
*visual
= gdk_visual_get_system();
180 if (visual
->depth
> 8) return TRUE
;
182 /* this initiates the standard palette as defined by GdkImlib
183 in the GNOME libraries. it ensures that all GNOME applications
184 use the same 64 colormap entries on 8-bit displays so you
185 can use several rather graphics-heavy applications at the
189 GdkColormap *cmap = gdk_colormap_new( gdk_visual_get_system(), TRUE );
191 for (int i = 0; i < 64; i++)
194 col.red = g_palette[i*3 + 0] << 8;
195 col.green = g_palette[i*3 + 1] << 8;
196 col.blue = g_palette[i*3 + 2] << 8;
199 gdk_color_alloc( cmap, &col );
202 gtk_widget_set_default_colormap( cmap );
205 /* initialize color cube for 8-bit color reduction dithering */
207 GdkColormap
*cmap
= gtk_widget_get_default_colormap();
209 m_colorCube
= (unsigned char*)malloc(32 * 32 * 32);
211 for (int r
= 0; r
< 32; r
++)
213 for (int g
= 0; g
< 32; g
++)
215 for (int b
= 0; b
< 32; b
++)
217 int rr
= (r
<< 3) | (r
>> 2);
218 int gg
= (g
<< 3) | (g
>> 2);
219 int bb
= (b
<< 3) | (b
>> 2);
221 GdkColor
*colors
= cmap
->colors
;
222 int max
= 3 * (65536);
225 for (int i
= 0; i
< cmap
->size
; i
++)
227 int rdiff
= ((rr
<< 8) - colors
[i
].red
);
228 int gdiff
= ((gg
<< 8)- colors
[i
].green
);
229 int bdiff
= ((bb
<< 8)- colors
[i
].blue
);
230 int sum
= ABS (rdiff
) + ABS (gdiff
) + ABS (bdiff
);
231 if (sum
< max
) { index
= i
; max
= sum
; }
234 m_colorCube
[ (r
*1024) + (g
*32) + b
] = index
;
242 bool wxApp::OnInitGui(void)
244 m_idleTag
= gtk_idle_add( wxapp_idle_callback
, NULL
);
249 bool wxApp::OnInit(void)
254 int wxApp::OnRun(void)
259 bool wxApp::ProcessIdle(void)
262 event
.SetEventObject( this );
263 ProcessEvent( event
);
265 return event
.MoreRequested();
268 void wxApp::OnIdle( wxIdleEvent
&event
)
270 static bool inOnIdle
= FALSE
;
272 /* Avoid recursion (via ProcessEvent default case) */
278 /* 'Garbage' collection of windows deleted with Close(). */
279 DeletePendingObjects();
281 /* flush the logged messages if any */
282 wxLog
*log
= wxLog::GetActiveTarget();
283 if (log
!= NULL
&& log
->HasPendingMessages())
286 /* Send OnIdle events to all windows */
287 bool needMore
= SendIdleEvents();
290 event
.RequestMore(TRUE
);
295 bool wxApp::SendIdleEvents(void)
297 bool needMore
= FALSE
;
299 wxNode
* node
= wxTopLevelWindows
.First();
302 wxWindow
* win
= (wxWindow
*) node
->Data();
303 if (SendIdleEvents(win
))
310 bool wxApp::SendIdleEvents( wxWindow
* win
)
312 bool needMore
= FALSE
;
315 event
.SetEventObject(win
);
316 win
->ProcessEvent(event
);
318 if (event
.MoreRequested())
321 wxNode
* node
= win
->GetChildren().First();
324 wxWindow
* win
= (wxWindow
*) node
->Data();
325 if (SendIdleEvents(win
))
333 int wxApp::OnExit(void)
338 int wxApp::MainLoop(void)
344 void wxApp::ExitMainLoop(void)
349 bool wxApp::Initialized(void)
351 return m_initialized
;
354 bool wxApp::Pending(void)
359 void wxApp::Dispatch(void)
363 void wxApp::DeletePendingObjects(void)
365 wxNode
*node
= wxPendingDelete
.First();
368 wxObject
*obj
= (wxObject
*)node
->Data();
372 if (wxPendingDelete
.Member(obj
))
375 node
= wxPendingDelete
.First();
379 wxWindow
*wxApp::GetTopWindow(void)
381 if (m_topWindow
) return m_topWindow
;
382 wxNode
*node
= wxTopLevelWindows
.First();
383 if (!node
) return (wxWindow
*) NULL
;
384 return (wxWindow
*)node
->Data();
387 void wxApp::SetTopWindow( wxWindow
*win
)
392 void wxApp::CommonInit(void)
394 wxSystemSettings::Init();
396 wxTheFontNameDirectory
= new wxFontNameDirectory
;
397 wxTheFontNameDirectory
->Initialize();
399 wxTheColourDatabase
= new wxColourDatabase(wxKEY_STRING
);
400 wxTheColourDatabase
->Initialize();
402 wxInitializeStockLists();
403 wxInitializeStockObjects();
405 #if wxUSE_WX_RESOURCES
406 wxTheResourceCache
= new wxResourceCache(wxKEY_STRING
);
408 wxInitializeResourceSystem();
411 wxImage::InitStandardHandlers();
413 // g_globalCursor = new wxCursor;
416 void wxApp::CommonCleanUp(void)
418 if (wxTheColourDatabase
) delete wxTheColourDatabase
;
419 wxTheColourDatabase
= (wxColourDatabase
*) NULL
;
421 if (wxTheFontNameDirectory
) delete wxTheFontNameDirectory
;
422 wxTheFontNameDirectory
= (wxFontNameDirectory
*) NULL
;
424 wxDeleteStockObjects();
426 #if wxUSE_WX_RESOURCES
429 if (wxTheResourceCache
) delete wxTheResourceCache
;
430 wxTheResourceCache
= (wxResourceCache
*) NULL
;
432 wxCleanUpResourceSystem();
435 wxDeleteStockLists();
437 wxImage::CleanUpHandlers();
439 wxSystemSettings::Done();
442 wxLog
*wxApp::CreateLogTarget()
447 //-----------------------------------------------------------------------------
449 //-----------------------------------------------------------------------------
451 int wxEntry( int argc
, char *argv
[] )
453 wxBuffer
= new char[BUFSIZ
+ 512];
455 wxClassInfo::InitializeClasses();
460 if (!wxApp::GetInitializerFunction())
462 printf( "wxWindows error: No initializer - use IMPLEMENT_APP macro.\n" );
466 wxAppInitializerFunction app_ini
= wxApp::GetInitializerFunction();
468 wxObject
*test_app
= app_ini();
470 wxTheApp
= (wxApp
*) test_app
;
475 printf( "wxWindows error: wxTheApp == NULL\n" );
479 wxTheApp
->argc
= argc
;
480 wxTheApp
->argv
= argv
;
483 strcpy( name
, argv
[0] );
484 strcpy( name
, wxFileNameFromPath(name
) );
485 wxStripExtension( name
);
486 wxTheApp
->SetAppName( name
);
490 gtk_init( &argc
, &argv
);
492 if (!wxTheApp
->InitVisual()) return 0;
496 if (!wxTheApp
->OnInitGui()) return 0;
498 wxModule::RegisterModules();
499 if (!wxModule::InitializeModules()) return FALSE
;
501 // Here frames insert themselves automatically
502 // into wxTopLevelWindows by getting created
505 if (!wxTheApp
->OnInit()) return 0;
507 wxTheApp
->m_initialized
= (wxTopLevelWindows
.Number() > 0);
511 if (wxTheApp
->Initialized()) retValue
= wxTheApp
->OnRun();
513 wxTheApp
->DeletePendingObjects();
517 wxModule::CleanUpModules();
519 wxApp::CommonCleanUp();
522 wxTheApp
= (wxApp
*) NULL
;
524 wxClassInfo::CleanUpClasses();
528 #if (defined(__WXDEBUG__) && wxUSE_MEMORY_TRACING) || wxUSE_DEBUG_CONTEXT
530 if (wxDebugContext::CountObjectsLeft() > 0)
532 wxLogDebug("There were memory leaks.\n");
533 wxDebugContext::Dump();
534 wxDebugContext::PrintStatistics();
539 wxLog
*oldLog
= wxLog::SetActiveTarget( (wxLog
*) NULL
);
540 if (oldLog
) delete oldLog
;