X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/8f7b34a878bbcb2f71a0c7694e2a3bec51460218..fe169919d8d60ce40edbd8b27dfc445487788bbf:/src/mgl/app.cpp diff --git a/src/mgl/app.cpp b/src/mgl/app.cpp index 1474a34667..2c505d83c2 100644 --- a/src/mgl/app.cpp +++ b/src/mgl/app.cpp @@ -1,9 +1,9 @@ ///////////////////////////////////////////////////////////////////////////// // Name: app.cpp -// Purpose: // 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 ///////////////////////////////////////////////////////////////////////////// @@ -11,51 +11,190 @@ #pragma implementation "app.h" #endif +// For compilers that support precompilation, includes "wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ + #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" +#endif + #include "wx/app.h" -#include "wx/settings.h" -#include "wx/module.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" + +//----------------------------------------------------------------------------- +// wxApp::Exit() +//----------------------------------------------------------------------------- -#include +void wxApp::Exit() +{ + MGL_exit(); + exit(0); +} //----------------------------------------------------------------------------- -// Global data +// wxYield //----------------------------------------------------------------------------- -// MGL's display DC: -MGLDevCtx *g_displayDC = NULL; +static bool gs_inYield = FALSE; + +bool wxApp::Yield(bool onlyIfNeeded) +{ + if ( gs_inYield ) + { + if ( !onlyIfNeeded ) + { + wxFAIL_MSG( wxT("wxYield called recursively" ) ); + } -// ---- + return FALSE; + } -wxApp *wxTheApp = (wxApp *) NULL; -wxAppInitializerFunction wxAppBase::m_appInitFn = (wxAppInitializerFunction) NULL; +#if wxUSE_THREADS + if ( !wxThread::IsMain() ) + { + // can't process events from other threads, MGL is thread-unsafe + return TRUE; + } +#endif // wxUSE_THREADS -// FIXME_MGL - whole file + gs_inYield = TRUE; + wxLog::Suspend(); -extern bool g_isIdle; + if ( wxEventLoop::GetActive() ) + { + while (wxEventLoop::GetActive()->Pending()) + wxEventLoop::GetActive()->Dispatch(); + } -bool g_mainThreadLocked = FALSE; + /* it's necessary to call ProcessIdle() to update the frames sizes which + might have been changed (it also will update other things set from + OnUpdateUI() which is a nice (and desired) side effect) */ + while (wxTheApp->ProcessIdle()) { } -void wxExit() -{ - exit(0); + wxLog::Resume(); + + gs_inYield = FALSE; + + return TRUE; } + //----------------------------------------------------------------------------- -// wxYield +// wxWakeUpIdle //----------------------------------------------------------------------------- -bool wxYield() +void wxApp::WakeUpIdle() { - return TRUE; +#if wxUSE_THREADS + if (!wxThread::IsMain()) + wxMutexGuiEnter(); +#endif + + while (wxTheApp->ProcessIdle()) + ; + +#if wxUSE_THREADS + if (!wxThread::IsMain()) + wxMutexGuiLeave(); +#endif } //----------------------------------------------------------------------------- -// wxWakeUpIdle +// 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 //----------------------------------------------------------------------------- -void wxWakeUpIdle() +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; + } } //----------------------------------------------------------------------------- @@ -69,26 +208,177 @@ BEGIN_EVENT_TABLE(wxApp, wxEvtHandler) END_EVENT_TABLE() -int wxEntry( int argc, char *argv[] ) +wxApp::wxApp() : m_mainLoop(NULL) { - return 0; } +wxApp::~wxApp() +{ +} + +wxDisplayModeInfo wxGetDefaultDisplayMode() +{ + 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 ( 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; + } + + if ( !wxCreateMGL_WM(mode) ) + return FALSE; + gs_rootWindow = new wxRootWindow; -// FIXME_MGL - this is temporary solution, will be removed -// once I have wxApp up and running -bool wxMGL_Initialize() + m_displayMode = mode; + + return TRUE; +} + +bool wxApp::OnInitGui() { - wxBuffer = new wxChar[BUFSIZ + 512]; + 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; - wxClassInfo::InitializeClasses(); - wxSystemSettings::Init(); - wxTheColourDatabase = new wxColourDatabase( wxKEY_STRING ); - wxTheColourDatabase->Initialize(); - wxInitializeStockLists(); - wxInitializeStockObjects(); - wxModule::RegisterModules(); - if (!wxModule::InitializeModules()) return FALSE; return TRUE; } +void wxApp::OnIdle(wxIdleEvent &event) +{ + static bool s_inOnIdle = FALSE; + + /* Avoid recursion (via ProcessEvent default case) */ + if (s_inOnIdle) + return; + + s_inOnIdle = TRUE; + + /* Resend in the main thread events which have been prepared in other + threads */ + ProcessPendingEvents(); + + // 'Garbage' collection of windows deleted with Close(). + DeletePendingObjects(); + +#if wxUSE_LOG + // flush the logged messages if any + wxLog::FlushActive(); +#endif // wxUSE_LOG + + // Now done in ProcessIdle() +#if 0 + // Send OnIdle events to all windows + if ( SendIdleEvents() ) + event.RequestMore(TRUE); +#endif + + s_inOnIdle = FALSE; +} + +int wxApp::MainLoop() +{ + int rt; + m_mainLoop = new wxEventLoop; + + rt = m_mainLoop->Run(); + + delete m_mainLoop; + m_mainLoop = NULL; + return rt; +} + +void wxApp::ExitMainLoop() +{ + if ( m_mainLoop ) + m_mainLoop->Exit(0); +} + +bool wxApp::Initialized() +{ + return (wxTopLevelWindows.GetCount() != 0); +} + +bool wxApp::Pending() +{ + return wxEventLoop::GetActive()->Pending(); +} + +void wxApp::Dispatch() +{ + wxEventLoop::GetActive()->Dispatch(); +} + +bool wxApp::Initialize(int& argc, wxChar **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 + + // must do it before calling wxAppBase::Initialize(), because fonts are + // needed by stock lists which are created there + wxTheFontsManager = new wxFontsManager; + + if ( !wxAppBase::Initialize(argc, argv) ) + return false; + + if ( MGL_init(".", NULL) == 0 ) + { + wxLogError(_("Cannot initialize SciTech MGL!")); + + wxAppBase::CleanUp(); + + return false; + } + +#if wxUSE_INTL + wxFont::SetDefaultEncoding(wxLocale::GetSystemEncoding()); +#endif + + return true; +} + +void wxApp::CleanUp() +{ + delete gs_rootWindow; + + wxAppBase::CleanUp(); + + // must do this after calling base class CleanUp() + delete wxTheFontsManager; + wxTheFontsManager = (wxFontsManager*) NULL; + + wxDestroyMGL_WM(); + MGL_exit(); +} +