X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/fd495ab3ea1282ddb8bb0cd0fb79fc758ae5fcee..8b3fddc49326c0b6019cd7082218726aa17a5727:/src/mgl/app.cpp diff --git a/src/mgl/app.cpp b/src/mgl/app.cpp index d9288130de..3eea2d9844 100644 --- a/src/mgl/app.cpp +++ b/src/mgl/app.cpp @@ -3,7 +3,7 @@ // Author: Vaclav Slavik // based on GTK and MSW implementations // Id: $Id$ -// Copyright: (c) 2001 SciTech Software, Inc. (www.scitechsoft.com) +// Copyright: (c) 2001-2002 SciTech Software, Inc. (www.scitechsoft.com) // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// @@ -18,16 +18,24 @@ #pragma hdrstop #endif + #ifndef WX_PRECOMP #include "wx/settings.h" #include "wx/module.h" #include "wx/evtloop.h" #include "wx/frame.h" #include "wx/dialog.h" + #include "wx/log.h" #include "wx/intl.h" + #include "wx/resource.h" #endif #include "wx/app.h" +#include "wx/fontutil.h" +#include "wx/univ/theme.h" +#include "wx/univ/renderer.h" +#include "wx/univ/colschem.h" +#include "wx/sysopt.h" #include "wx/mgl/private.h" //----------------------------------------------------------------------------- @@ -37,8 +45,6 @@ wxApp *wxTheApp = NULL; wxAppInitializerFunction wxAppBase::m_appInitFn = (wxAppInitializerFunction) NULL; -static wxEventLoop *gs_mainEventLoop = NULL; - //----------------------------------------------------------------------------- // wxExit @@ -56,8 +62,18 @@ void wxExit() static bool gs_inYield = FALSE; -bool wxYield() +bool wxApp::Yield(bool onlyIfNeeded) { + if ( gs_inYield ) + { + if ( !onlyIfNeeded ) + { + wxFAIL_MSG( wxT("wxYield called recursively" ) ); + } + + return FALSE; + } + #if wxUSE_THREADS if ( !wxThread::IsMain() ) { @@ -70,8 +86,11 @@ bool wxYield() wxLog::Suspend(); - while (gs_mainEventLoop->Pending()) - gs_mainEventLoop->Dispatch(); + if ( wxEventLoop::GetActive() ) + { + while (wxEventLoop::GetActive()->Pending()) + wxEventLoop::GetActive()->Dispatch(); + } /* it's necessary to call ProcessIdle() to update the frames sizes which might have been changed (it also will update other things set from @@ -85,14 +104,6 @@ bool wxYield() return TRUE; } -bool wxYieldIfNeeded() -{ - if (gs_inYield) - return FALSE; - - return wxYield(); -} - //----------------------------------------------------------------------------- // wxWakeUpIdle @@ -113,6 +124,87 @@ void wxWakeUpIdle() #endif } +//----------------------------------------------------------------------------- +// Root window +//----------------------------------------------------------------------------- + +class wxRootWindow : public wxWindow +{ + public: + wxRootWindow() : wxWindow(NULL, -1) + { + SetMGLwindow_t(MGL_wmGetRootWindow(g_winMng)); + SetBackgroundColour(wxTHEME_COLOUR(DESKTOP)); + } + ~wxRootWindow() + { + // we don't want to delete MGL_WM's rootWnd + m_wnd = NULL; + } + + virtual bool AcceptsFocus() const { return FALSE; } + + DECLARE_DYNAMIC_CLASS(wxRootWindow) +}; + +IMPLEMENT_DYNAMIC_CLASS(wxRootWindow, wxWindow) + +static wxRootWindow *gs_rootWindow = NULL; + +//----------------------------------------------------------------------------- +// MGL initialization +//----------------------------------------------------------------------------- + +static bool wxCreateMGL_WM(const wxDisplayModeInfo& displayMode) +{ + int mode; + int refresh = MGL_DEFAULT_REFRESH; + +#if wxUSE_SYSTEM_OPTIONS + if ( wxSystemOptions::HasOption(wxT("mgl.screen-refresh")) ) + refresh = wxSystemOptions::GetOptionInt(wxT("mgl.screen-refresh")); +#endif + + mode = MGL_findMode(displayMode.GetWidth(), + displayMode.GetHeight(), + displayMode.GetDepth()); + if ( mode == -1 ) + { + wxLogError(_("Mode %ix%i-%i not available."), + displayMode.GetWidth(), + displayMode.GetHeight(), + displayMode.GetDepth()); + return FALSE; + } + g_displayDC = new MGLDisplayDC(mode, 1, refresh); + if ( !g_displayDC->isValid() ) + { + delete g_displayDC; + g_displayDC = NULL; + return FALSE; + } + + g_winMng = MGL_wmCreate(g_displayDC->getDC()); + if (!g_winMng) + return FALSE; + + return TRUE; +} + +static void wxDestroyMGL_WM() +{ + if ( g_winMng ) + { + MGL_wmDestroy(g_winMng); + g_winMng = NULL; + } + if ( g_displayDC ) + { + delete g_displayDC; + g_displayDC = NULL; + } +} + //----------------------------------------------------------------------------- // wxApp //----------------------------------------------------------------------------- @@ -124,7 +216,7 @@ BEGIN_EVENT_TABLE(wxApp, wxEvtHandler) END_EVENT_TABLE() -wxApp::wxApp() +wxApp::wxApp() : m_mainLoop(NULL) { } @@ -132,18 +224,59 @@ wxApp::~wxApp() { } -bool wxApp::OnInitGui() +wxDisplayModeInfo wxGetDefaultDisplayMode() { - if ( MGL_init(".", NULL) == 0 ) + wxString mode; + unsigned w, h, bpp; + + if ( !wxGetEnv(wxT("WXMODE"), &mode) || + (wxSscanf(mode.c_str(), _T("%ux%u-%u"), &w, &h, &bpp) != 3) ) + { + w = 640, h = 480, bpp = 16; + } + + return wxDisplayModeInfo(w, h, bpp); +} + +bool wxApp::SetDisplayMode(const wxDisplayModeInfo& mode) +{ + if ( !mode.IsOk() ) + { return FALSE; - if ( !wxCreateMGL_WM() ) + } + if ( g_displayDC != NULL ) + { + // FIXME_MGL -- we currently don't allow to switch video mode + // more than once. This can hopefully be changed... + wxFAIL_MSG(wxT("Can't change display mode after intialization!")); return FALSE; + } - // This has to be done *after* wxCreateMGL_WM() because it initializes - // wxUniv's themes + if ( !wxCreateMGL_WM(mode) ) + return FALSE; + gs_rootWindow = new wxRootWindow; + + m_displayMode = mode; + + return TRUE; +} + +bool wxApp::OnInitGui() +{ if ( !wxAppBase::OnInitGui() ) return FALSE; +#ifdef __WXDEBUG__ + // MGL redirects stdout and stderr to physical console, so lets redirect + // it to file. Do it only when WXDEBUG environment variable is set + wxString redirect; + if ( wxGetEnv(wxT("WXSTDERR"), &redirect) ) + freopen(redirect.mb_str(), "wt", stderr); +#endif + + wxLog *oldLog = wxLog::SetActiveTarget(new wxLogGui); + if ( oldLog ) delete oldLog; + return TRUE; } @@ -173,6 +306,11 @@ void wxApp::OnIdle(wxIdleEvent &event) // 'Garbage' collection of windows deleted with Close(). DeletePendingObjects(); +#if wxUSE_LOG + // flush the logged messages if any + wxLog::FlushActive(); +#endif // wxUSE_LOG + // Send OnIdle events to all windows if ( SendIdleEvents() ) event.RequestMore(TRUE); @@ -205,12 +343,8 @@ bool wxApp::SendIdleEvents(wxWindow* win) win->GetEventHandler()->ProcessEvent(event); -#if 0 // FIXME_MGL - what the hell it is? - win->OnInternalIdle(); - if ( event.MoreRequested() ) needMore = TRUE; -#endif wxNode* node = win->GetChildren().First(); while (node) @@ -227,33 +361,34 @@ bool wxApp::SendIdleEvents(wxWindow* win) int wxApp::MainLoop() { int rt; - gs_mainEventLoop = new wxEventLoop; - rt = gs_mainEventLoop->Run(); - delete gs_mainEventLoop; - gs_mainEventLoop = NULL; + m_mainLoop = new wxEventLoop; + + rt = m_mainLoop->Run(); + + delete m_mainLoop; + m_mainLoop = NULL; return rt; } void wxApp::ExitMainLoop() { - gs_mainEventLoop->Exit(0); + if ( m_mainLoop ) + m_mainLoop->Exit(0); } bool wxApp::Initialized() { - // FIXME_MGL -- only for now because we don't have wxFrame/wxDialog yet - return TRUE; - //return (wxTopLevelWindows.GetCount() != 0); + return (wxTopLevelWindows.GetCount() != 0); } bool wxApp::Pending() { - return gs_mainEventLoop->Pending(); + return wxEventLoop::GetActive()->Pending(); } void wxApp::Dispatch() { - gs_mainEventLoop->Dispatch(); + wxEventLoop::GetActive()->Dispatch(); } void wxApp::DeletePendingObjects() @@ -274,12 +409,11 @@ void wxApp::DeletePendingObjects() bool wxApp::Initialize() { - wxBuffer = new wxChar[BUFSIZ + 512]; + if ( MGL_init(".", NULL) == 0 ) + return FALSE; wxClassInfo::InitializeClasses(); - wxSystemSettings::Init(); - #if wxUSE_INTL wxFont::SetDefaultEncoding(wxLocale::GetSystemEncoding()); #endif @@ -293,6 +427,9 @@ bool wxApp::Initialize() wxTheColourDatabase = new wxColourDatabase(wxKEY_STRING); wxTheColourDatabase->Initialize(); + + // Can't do this in wxModule, because fonts are needed by stock lists + wxTheFontsManager = new wxFontsManager; wxInitializeStockLists(); wxInitializeStockObjects(); @@ -307,37 +444,14 @@ bool wxApp::Initialize() return TRUE; } -#include "info.xpm" -#include "error.xpm" -#include "question.xpm" -#include "warning.xpm" - wxIcon wxApp::GetStdIcon(int which) const { - switch(which) - { - case wxICON_INFORMATION: - return wxIcon(info_xpm); - case wxICON_QUESTION: - return wxIcon(question_xpm); - case wxICON_EXCLAMATION: - return wxIcon(warning_xpm); - default: - wxFAIL_MSG(wxT("requested non existent standard icon")); - // still fall through - case wxICON_HAND: - return wxIcon(error_xpm); - } + return wxTheme::Get()->GetRenderer()->GetStdIcon(which); } void wxApp::CleanUp() { #if wxUSE_LOG - // flush the logged messages if any - wxLog *log = wxLog::GetActiveTarget(); - if (log != NULL && log->HasPendingMessages()) - log->Flush(); - // continuing to use user defined log target is unsafe from now on because // some resources may be already unavailable, so replace it by something // more safe @@ -346,6 +460,8 @@ void wxApp::CleanUp() delete oldlog; #endif // wxUSE_LOG + delete gs_rootWindow; + wxModule::CleanUpModules(); #if wxUSE_WX_RESOURCES @@ -358,12 +474,12 @@ void wxApp::CleanUp() wxTheColourDatabase = (wxColourDatabase*) NULL; wxDeleteStockObjects(); - wxDeleteStockLists(); delete wxTheApp; wxTheApp = (wxApp*) NULL; + // GL: I'm annoyed ... I don't know where to put this and I don't want to // create a module for that as it's part of the core. #if wxUSE_THREADS @@ -371,12 +487,14 @@ void wxApp::CleanUp() delete wxPendingEventsLocker; #endif - wxSystemSettings::Done(); - - delete[] wxBuffer; - wxClassInfo::CleanUpClasses(); + // Can't do this in wxModule, because fonts are needed by stock lists + // (do it after deleting wxTheApp and cleaning modules up, since somebody + // may be deleting fonts that lately) + delete wxTheFontsManager; + wxTheFontsManager = (wxFontsManager*) NULL; + // check for memory leaks #if (defined(__WXDEBUG__) && wxUSE_MEMORY_TRACING) || wxUSE_DEBUG_CONTEXT if (wxDebugContext::CountObjectsLeft(TRUE) > 0) @@ -422,6 +540,12 @@ void wxEntryCleanup() int wxEntry(int argc, char *argv[]) { +#ifdef __DJGPP__ + // VS: disable long filenames under DJGPP as the very first thing, + // since SciTech MGL doesn't like them much... + wxSetEnv(wxT("LFN"), wxT("N")); +#endif + #if (defined(__WXDEBUG__) && wxUSE_MEMORY_TRACING) || wxUSE_DEBUG_CONTEXT // This seems to be necessary since there are 'rogue' // objects present at this point (perhaps global objects?) @@ -506,6 +630,12 @@ int wxEntry(int argc, char *argv[]) } } +#if wxUSE_LOG + // flush the logged messages if any + wxLog *log = wxLog::GetActiveTarget(); + if (log != NULL && log->HasPendingMessages()) + log->Flush(); +#endif // wxUSE_LOG retValue = wxTheApp->OnExit(); } }