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 #include "wx/dialog.h" 
  23 #if wxUSE_WX_RESOURCES 
  24 #include "wx/resource.h" 
  26 #include "wx/module.h" 
  29 #include "wx/thread.h" 
  36 #include "wx/gtk/win_gtk.h" 
  38 #include   <unistd.h> // usleep() on solaris 
  40 //----------------------------------------------------------------------------- 
  42 //----------------------------------------------------------------------------- 
  44 wxApp 
*wxTheApp 
= (wxApp 
*)  NULL
; 
  45 wxAppInitializerFunction 
wxApp::m_appInitFn 
= (wxAppInitializerFunction
) NULL
; 
  47 extern wxList wxPendingDelete
; 
  48 extern wxResourceCache 
*wxTheResourceCache
; 
  50 unsigned char g_palette
[64*3] = 
 118 //----------------------------------------------------------------------------- 
 120 //----------------------------------------------------------------------------- 
 122 extern void wxFlushResources(void); 
 124 //----------------------------------------------------------------------------- 
 126 //----------------------------------------------------------------------------- 
 135     while (gtk_events_pending() > 0) gtk_main_iteration(); 
 139 //----------------------------------------------------------------------------- 
 141 //----------------------------------------------------------------------------- 
 143 IMPLEMENT_DYNAMIC_CLASS(wxApp
,wxEvtHandler
) 
 145 BEGIN_EVENT_TABLE(wxApp
, wxEvtHandler
) 
 146     EVT_IDLE(wxApp::OnIdle
) 
 149 gint 
wxapp_idle_callback( gpointer 
WXUNUSED(data
) ) 
 151     if (wxTheApp
) while (wxTheApp
->ProcessIdle()) {} 
 166     m_topWindow 
= (wxWindow 
*) NULL
; 
 167     m_exitOnFrameDelete 
= TRUE
; 
 169     m_idleTag 
= gtk_idle_add( wxapp_idle_callback
, (gpointer
) NULL 
); 
 171     m_colorCube 
= (unsigned char*) NULL
; 
 176     gtk_idle_remove( m_idleTag 
); 
 178     if (m_colorCube
) free(m_colorCube
); 
 181 bool wxApp::OnInitGui() 
 183     /* Nothing to do for 15, 16, 24, 32 bit displays */ 
 185     GdkVisual 
*visual 
= gdk_visual_get_system(); 
 186     if (visual
->depth 
> 8) return TRUE
; 
 188         /* this initiates the standard palette as defined by GdkImlib 
 189            in the GNOME libraries. it ensures that all GNOME applications 
 190            use the same 64 colormap entries on 8-bit displays so you 
 191            can use several rather graphics-heavy applications at the 
 193            NOTE: this doesn't really seem to work this way... */ 
 196         GdkColormap *cmap = gdk_colormap_new( gdk_visual_get_system(), TRUE ); 
 198         for (int i = 0; i < 64; i++) 
 201             col.red    = g_palette[i*3 + 0] << 8; 
 202             col.green  = g_palette[i*3 + 1] << 8; 
 203             col.blue   = g_palette[i*3 + 2] << 8; 
 206             gdk_color_alloc( cmap, &col ); 
 209         gtk_widget_set_default_colormap( cmap ); 
 212     /* initialize color cube for 8-bit color reduction dithering */ 
 214     GdkColormap 
*cmap 
= gtk_widget_get_default_colormap(); 
 216     m_colorCube 
= (unsigned char*)malloc(32 * 32 * 32); 
 218      for (int r 
= 0; r 
< 32; r
++) 
 220         for (int g 
= 0; g 
< 32; g
++) 
 222             for (int b 
= 0; b 
< 32; b
++) 
 224                 int rr 
= (r 
<< 3) | (r 
>> 2); 
 225                 int gg 
= (g 
<< 3) | (g 
>> 2); 
 226                 int bb 
= (b 
<< 3) | (b 
>> 2); 
 228                 GdkColor 
*colors 
= cmap
->colors
; 
 229                 int max 
= 3 * (65536); 
 232                 for (int i 
= 0; i 
< cmap
->size
; i
++) 
 234                     int rdiff 
= ((rr 
<< 8) - colors
[i
].red
); 
 235                     int gdiff 
= ((gg 
<< 8)- colors
[i
].green
); 
 236                     int bdiff 
= ((bb 
<< 8)- colors
[i
].blue
); 
 237                     int sum 
= ABS (rdiff
) + ABS (gdiff
) + ABS (bdiff
); 
 238                     if (sum 
< max
) { index 
= i
; max 
= sum
; } 
 241                 m_colorCube
[ (r
*1024) + (g
*32) + b 
] = index
; 
 250 bool wxApp::ProcessIdle(void) 
 253     event
.SetEventObject( this ); 
 254     ProcessEvent( event 
); 
 256     return event
.MoreRequested(); 
 259 void wxApp::OnIdle( wxIdleEvent 
&event 
) 
 261     static bool inOnIdle 
= FALSE
; 
 263     /* Avoid recursion (via ProcessEvent default case) */ 
 269     /* 'Garbage' collection of windows deleted with Close(). */ 
 270     DeletePendingObjects(); 
 272     /* flush the logged messages if any */ 
 273     wxLog 
*log 
= wxLog::GetActiveTarget(); 
 274     if (log 
!= NULL 
&& log
->HasPendingMessages()) 
 277     /* Send OnIdle events to all windows */ 
 278     bool needMore 
= SendIdleEvents(); 
 281         event
.RequestMore(TRUE
); 
 286 bool wxApp::SendIdleEvents(void) 
 288     bool needMore 
= FALSE
; 
 290     wxNode
* node 
= wxTopLevelWindows
.First(); 
 293         wxWindow
* win 
= (wxWindow
*) node
->Data(); 
 294         if (SendIdleEvents(win
)) 
 301 bool wxApp::SendIdleEvents( wxWindow
* win 
) 
 303     bool needMore 
= FALSE
; 
 306     event
.SetEventObject(win
); 
 308     win
->OnInternalIdle(); 
 310     win
->ProcessEvent(event
); 
 312     if (event
.MoreRequested()) 
 315     wxNode
* node 
= win
->GetChildren().First(); 
 318         wxWindow
* win 
= (wxWindow
*) node
->Data(); 
 319         if (SendIdleEvents(win
)) 
 327 int wxApp::MainLoop(void) 
 333 void wxApp::ExitMainLoop(void) 
 338 bool wxApp::Initialized(void) 
 340     return m_initialized
; 
 343 bool wxApp::Pending(void) 
 348 void wxApp::Dispatch(void) 
 352 void wxApp::DeletePendingObjects(void) 
 354     wxNode 
*node 
= wxPendingDelete
.First(); 
 357         wxObject 
*obj 
= (wxObject 
*)node
->Data(); 
 361         if (wxPendingDelete
.Member(obj
)) 
 364         node 
= wxPendingDelete
.First(); 
 368 wxWindow 
*wxApp::GetTopWindow(void) 
 370     if (m_topWindow
) return m_topWindow
; 
 371     wxNode 
*node 
= wxTopLevelWindows
.First(); 
 372     if (!node
) return (wxWindow 
*) NULL
; 
 373     return (wxWindow
*)node
->Data(); 
 376 void wxApp::SetTopWindow( wxWindow 
*win 
) 
 381 bool wxApp::Initialize(void) 
 383     wxBuffer 
= new char[BUFSIZ 
+ 512]; 
 385     wxClassInfo::InitializeClasses(); 
 387     wxSystemSettings::Init(); 
 390     wxTheFontNameDirectory =  new wxFontNameDirectory; 
 391     wxTheFontNameDirectory->Initialize(); 
 394     wxTheColourDatabase 
= new wxColourDatabase( wxKEY_STRING 
); 
 395     wxTheColourDatabase
->Initialize(); 
 397     wxInitializeStockLists(); 
 398     wxInitializeStockObjects(); 
 400 #if wxUSE_WX_RESOURCES 
 401     wxTheResourceCache 
= new wxResourceCache( wxKEY_STRING 
); 
 403     wxInitializeResourceSystem(); 
 406     wxImage::InitStandardHandlers(); 
 408     /* no global cursor under X 
 409        g_globalCursor = new wxCursor; */ 
 411     wxModule::RegisterModules(); 
 412     if (!wxModule::InitializeModules()) return FALSE
; 
 417 void wxApp::CleanUp(void) 
 419     wxModule::CleanUpModules(); 
 421 #if wxUSE_WX_RESOURCES 
 424     if (wxTheResourceCache
) delete wxTheResourceCache
; 
 425     wxTheResourceCache 
= (wxResourceCache
*) NULL
; 
 427     wxCleanUpResourceSystem(); 
 430     if (wxTheColourDatabase
) delete wxTheColourDatabase
; 
 431     wxTheColourDatabase 
= (wxColourDatabase
*) NULL
; 
 434     if (wxTheFontNameDirectory) delete wxTheFontNameDirectory; 
 435     wxTheFontNameDirectory = (wxFontNameDirectory*) NULL; 
 438     wxDeleteStockObjects(); 
 440     wxDeleteStockLists(); 
 442     wxImage::CleanUpHandlers(); 
 445     wxTheApp 
= (wxApp
*) NULL
; 
 447     /* check for memory leaks */ 
 448 #if (defined(__WXDEBUG__) && wxUSE_MEMORY_TRACING) || wxUSE_DEBUG_CONTEXT 
 449     if (wxDebugContext::CountObjectsLeft() > 0) 
 451         wxLogDebug("There were memory leaks.\n"); 
 452         wxDebugContext::Dump(); 
 453         wxDebugContext::PrintStatistics(); 
 457     /* do this as the very last thing because everything else can log messages */ 
 458     wxLog::DontCreateOnDemand(); 
 460     wxLog 
*oldLog 
= wxLog::SetActiveTarget( (wxLog
*) NULL 
); 
 461     if (oldLog
) delete oldLog
; 
 463     wxSystemSettings::Done(); 
 465     wxClassInfo::CleanUpClasses(); 
 470 wxLog 
*wxApp::CreateLogTarget() 
 475 //----------------------------------------------------------------------------- 
 477 //----------------------------------------------------------------------------- 
 479 int wxEntry( int argc
, char *argv
[] ) 
 483     gtk_init( &argc
, &argv 
); 
 485     if (!wxApp::Initialize()) return 0; 
 489         if (!wxApp::GetInitializerFunction()) 
 491             printf( "wxWindows error: No initializer - use IMPLEMENT_APP macro.\n" ); 
 495         wxAppInitializerFunction app_ini 
= wxApp::GetInitializerFunction(); 
 497         wxObject 
*test_app 
= app_ini(); 
 499         wxTheApp 
= (wxApp
*) test_app
; 
 504         printf( "wxWindows error: wxTheApp == NULL\n" ); 
 508     wxTheApp
->argc 
= argc
; 
 509     wxTheApp
->argv 
= argv
; 
 512     strcpy( name
, argv
[0] ); 
 513     strcpy( name
, wxFileNameFromPath(name
) ); 
 514     wxStripExtension( name 
); 
 515     wxTheApp
->SetAppName( name 
); 
 517     if (!wxTheApp
->OnInitGui()) return 0; 
 519     /* Here frames insert themselves automatically 
 520      * into wxTopLevelWindows by getting created 
 523     if (!wxTheApp
->OnInit()) return 0; 
 525     wxTheApp
->m_initialized 
= (wxTopLevelWindows
.Number() > 0); 
 529     if (wxTheApp
->Initialized()) retValue 
= wxTheApp
->OnRun(); 
 531     wxWindow 
*topWindow 
= wxTheApp
->GetTopWindow(); 
 534         /* Forcibly delete the window. */ 
 535         if (topWindow
->IsKindOf(CLASSINFO(wxFrame
)) || 
 536             topWindow
->IsKindOf(CLASSINFO(wxDialog
)) ) 
 538             topWindow
->Close( TRUE 
); 
 539             wxTheApp
->DeletePendingObjects(); 
 544             wxTheApp
->SetTopWindow( (wxWindow
*) NULL 
); 
 550     /* flush the logged messages if any */ 
 551     wxLog 
*log 
= wxLog::GetActiveTarget(); 
 552     if (log 
!= NULL 
&& log
->HasPendingMessages())