// classes
//-----------------------------------------------------------------------------
-class wxApp;
-class wxLog;
+class WXDLLEXPORT wxApp;
+class WXDLLEXPORT wxLog;
//-----------------------------------------------------------------------------
// wxApp
class WXDLLEXPORT wxApp: public wxAppBase
{
public:
- wxApp() {}
- ~wxApp() {}
+ wxApp();
+ ~wxApp();
/* override for altering the way wxGTK intializes the GUI
* (palette/visual/colorcube). under wxMSW, OnInitGui() does nothing by
* default. when overriding this method, the code in it is likely to be
* platform dependent, otherwise use OnInit(). */
- virtual bool OnInitGui() {return 0;}
+ virtual bool OnInitGui();
// override base class (pure) virtuals
- virtual int MainLoop() {return 0;}
- virtual void ExitMainLoop() {}
- virtual bool Initialized() {return 0;}
- virtual bool Pending() {return 0;}
- virtual void Dispatch() {}
+ virtual int MainLoop();
+ virtual void ExitMainLoop();
+ virtual bool Initialized();
+ virtual bool Pending();
+ virtual void Dispatch();
- virtual wxIcon GetStdIcon(int which) const {return wxNullIcon;}
+ virtual wxIcon GetStdIcon(int which) const;
// implementation only from now on
- void OnIdle( wxIdleEvent &event ) {}
- bool SendIdleEvents() {return 0;}
- bool SendIdleEvents( wxWindow* win ) {return 0;}
+ void OnIdle(wxIdleEvent &event);
+ bool SendIdleEvents();
+ bool SendIdleEvents(wxWindow* win);
- static bool Initialize() {return 0;}
- static bool InitialzeVisual() {return 0;}
- static void CleanUp() {}
+ static bool Initialize();
+ static void CleanUp();
- bool ProcessIdle() {return 0;}
- void DeletePendingObjects() {}
-
- // This can be used to suppress the generation of Idle events.
- void SuppressIdleEvents(bool arg = TRUE) { m_suppressIdleEvents = arg; }
- bool GetSuppressIdleEvents() const { return m_suppressIdleEvents; }
-
-#if 0 //FIXME MGL
- bool m_initialized;
-
- gint m_idleTag;
-#if wxUSE_THREADS
- gint m_wakeUpTimerTag;
-#endif
- unsigned char *m_colorCube;
-#endif
-
-private:
- /// Set to TRUE while we are in wxYield().
- bool m_suppressIdleEvents;
+ bool ProcessIdle();
+ void DeletePendingObjects();
private:
DECLARE_DYNAMIC_CLASS(wxApp)
DECLARE_EVENT_TABLE()
};
-int WXDLLEXPORT wxEntry( int argc, char *argv[] );
+int WXDLLEXPORT wxEntry(int argc, char *argv[]);
#endif // __WX_APP_H__
// MGL fwd declarations:
class MGLDevCtx;
+class MGLRegion;
struct font_t;
class WXDLLEXPORT wxDC : public wxDCBase
wxPalette m_oldPalette;
wxRegion m_currentClippingRegion;
+ // clipping region m_MGLDC had when it was attached:
+ MGLRegion *m_globalClippingRegion;
// wxDC::Blit handles memoryDCs as special cases :(
bool m_isMemDC;
#include "wx/dc.h"
-class WXDLLEXPORT wxWindowMGL;
-
//-----------------------------------------------------------------------------
// classes
//-----------------------------------------------------------------------------
class WXDLLEXPORT wxWindowDC;
class WXDLLEXPORT wxPaintDC;
class WXDLLEXPORT wxClientDC;
+class WXDLLEXPORT wxWindowMGL;
//-----------------------------------------------------------------------------
// wxWindowDC
protected:
wxWindow *m_wnd;
+ bool m_inPaintHandler;
private:
DECLARE_DYNAMIC_CLASS(wxWindowDC)
wxClientDC(wxWindow *win);
private:
- wxWindowMGL *m_wnd;
DECLARE_DYNAMIC_CLASS(wxClientDC)
};
// wxPaintDC
//-----------------------------------------------------------------------------
-// FIXME_MGL
class WXDLLEXPORT wxPaintDC : public wxClientDC
{
public:
- wxPaintDC() { }
- wxPaintDC( wxWindow *win ) {}
+ wxPaintDC() : wxClientDC() {}
+ wxPaintDC(wxWindow *win) : wxClientDC(win) {}
private:
DECLARE_DYNAMIC_CLASS(wxPaintDC)
/////////////////////////////////////////////////////////////////////////////
// Name: settings.h
-// Purpose:
-// Author: Robert Roebling
+// Author: Vaclav Slavik
// Id: $Id$
-// Copyright: (c) 1998 Robert Roebling
+// Copyright: (c) 2001 SciTech Software, Inc. (www.scitechsoft.com)
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
class wxSystemSettings: public wxObject
{
public:
- inline wxSystemSettings() {}
+ wxSystemSettings() {}
- inline static void Init() {}
+ static void Init() {}
static void Done() {}
// Get a system colour
- static wxColour GetSystemColour(int index) {}
+ static wxColour GetSystemColour(int index);
// Get a system font
- static wxFont GetSystemFont(int index) {}
+ static wxFont GetSystemFont(int index);
// Get a system metric, e.g. scrollbar size
- static int GetSystemMetric(int index) {}
+ static int GetSystemMetric(int index);
};
#endif
// (see wxWindow::Refresh)
bool m_frozen;
bool m_refreshAfterThaw;
- wxFont m_font;
// implement the base class pure virtuals
virtual void DoClientToScreen( int *x, int *y ) const;
MGLDevCtx *m_paintMGLDC;
friend class wxPaintDC;
- void OnEraseBackground(wxEraseEvent& event);
- void OnSetFocus(wxFocusEvent& event);
-
DECLARE_DYNAMIC_CLASS(wxWindowMGL);
DECLARE_NO_COPY_CLASS(wxWindowMGL);
DECLARE_EVENT_TABLE()
public:
void HandlePaint(MGLDevCtx *dc);
// needed by wxWindowPainter
+ MGLDevCtx *GetPaintMGLDC() const { return m_paintMGLDC; }
};
/////////////////////////////////////////////////////////////////////////////
// Name: app.cpp
-// Purpose:
// Author: Vaclav Slavik
+// based on GTK and MSW implementations
// Id: $Id$
// Copyright: (c) 2001 SciTech Software, Inc. (www.scitechsoft.com)
// Licence: wxWindows licence
#pragma implementation "app.h"
#endif
-#include "wx/app.h"
-#include "wx/settings.h"
-#include "wx/module.h"
+// 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/intl.h"
+#endif
-#include <mgraph.hpp>
+#include "wx/app.h"
+#include "wx/mgl/private.h"
//-----------------------------------------------------------------------------
// Global data
//-----------------------------------------------------------------------------
-wxApp *wxTheApp = (wxApp *) NULL;
+wxApp *wxTheApp = NULL;
wxAppInitializerFunction wxAppBase::m_appInitFn = (wxAppInitializerFunction) NULL;
-// FIXME_MGL - whole file
-
+static wxEventLoop *gs_mainEventLoop = NULL;
-extern bool g_isIdle;
-bool g_mainThreadLocked = FALSE;
+//-----------------------------------------------------------------------------
+// wxExit
+//-----------------------------------------------------------------------------
void wxExit()
{
+ MGL_exit();
exit(0);
}
// wxYield
//-----------------------------------------------------------------------------
+static bool gs_inYield = FALSE;
+
bool wxYield()
{
+#if wxUSE_THREADS
+ if ( !wxThread::IsMain() )
+ {
+ // can't process events from other threads, MGL is thread-unsafe
+ return TRUE;
+ }
+#endif // wxUSE_THREADS
+
+ gs_inYield = TRUE;
+
+ wxLog::Suspend();
+
+ while (gs_mainEventLoop->Pending())
+ gs_mainEventLoop->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
+ OnUpdateUI() which is a nice (and desired) side effect) */
+ while (wxTheApp->ProcessIdle()) { }
+
+ wxLog::Resume();
+
+ gs_inYield = FALSE;
+
return TRUE;
}
+bool wxYieldIfNeeded()
+{
+ if (gs_inYield)
+ return FALSE;
+
+ return wxYield();
+}
+
+
//-----------------------------------------------------------------------------
// wxWakeUpIdle
//-----------------------------------------------------------------------------
void wxWakeUpIdle()
{
+#if wxUSE_THREADS
+ if (!wxThread::IsMain())
+ wxMutexGuiEnter();
+#endif
+
+ while (wxTheApp->ProcessIdle()) {}
+
+#if wxUSE_THREADS
+ if (!wxThread::IsMain())
+ wxMutexGuiLeave();
+#endif
}
//-----------------------------------------------------------------------------
END_EVENT_TABLE()
-int wxEntry( int argc, char *argv[] )
+wxApp::wxApp()
+{
+}
+
+wxApp::~wxApp()
+{
+}
+
+bool wxApp::OnInitGui()
+{
+ if ( MGL_init(".", NULL) == 0 )
+ return FALSE;
+ if ( !wxCreateMGL_WM() )
+ return FALSE;
+
+ // This has to be done *after* wxCreateMGL_WM() because it initializes
+ // wxUniv's themes
+ if ( !wxAppBase::OnInitGui() )
+ return FALSE;
+
+ return TRUE;
+}
+
+bool wxApp::ProcessIdle()
+{
+ wxIdleEvent event;
+ event.SetEventObject(this);
+ ProcessEvent(event);
+
+ return event.MoreRequested();
+}
+
+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();
+
+ // Send OnIdle events to all windows
+ if ( SendIdleEvents() )
+ event.RequestMore(TRUE);
+
+ s_inOnIdle = FALSE;
+}
+
+bool wxApp::SendIdleEvents()
+{
+ bool needMore = FALSE;
+
+ wxWindowList::Node* node = wxTopLevelWindows.GetFirst();
+ while (node)
+ {
+ wxWindow* win = node->GetData();
+ if ( SendIdleEvents(win) )
+ needMore = TRUE;
+ node = node->GetNext();
+ }
+
+ return needMore;
+}
+
+bool wxApp::SendIdleEvents(wxWindow* win)
+{
+ bool needMore = FALSE;
+
+ wxIdleEvent event;
+ event.SetEventObject(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)
+ {
+ wxWindow* win = (wxWindow*) node->Data();
+ if ( SendIdleEvents(win) )
+ needMore = TRUE;
+
+ node = node->Next();
+ }
+ return needMore;
+}
+
+int wxApp::MainLoop()
+{
+ gs_mainEventLoop = new wxEventLoop;
+ return gs_mainEventLoop->Run();
+ delete gs_mainEventLoop;
+ gs_mainEventLoop = NULL;
+}
+
+void wxApp::ExitMainLoop()
+{
+ gs_mainEventLoop->Exit(0);
+}
+
+bool wxApp::Initialized()
+{
+ return (GetTopWindow() != NULL);
+}
+
+bool wxApp::Pending()
+{
+ return gs_mainEventLoop->Pending();
+}
+
+void wxApp::Dispatch()
{
- return 0;
+ gs_mainEventLoop->Dispatch();
}
+void wxApp::DeletePendingObjects()
+{
+ wxNode *node = wxPendingDelete.First();
+ while (node)
+ {
+ wxObject *obj = (wxObject *)node->Data();
+
+ delete obj;
+
+ if ( wxPendingDelete.Find(obj) )
+ delete node;
-// FIXME_MGL - this is temporary solution, will be removed
-// once I have wxApp up and running
-bool wxMGL_Initialize()
+ node = wxPendingDelete.First();
+ }
+}
+
+bool wxApp::Initialize()
{
wxBuffer = new wxChar[BUFSIZ + 512];
wxClassInfo::InitializeClasses();
+
wxSystemSettings::Init();
- wxTheColourDatabase = new wxColourDatabase( wxKEY_STRING );
+
+#if wxUSE_INTL
+ wxFont::SetDefaultEncoding(wxLocale::GetSystemEncoding());
+#endif
+
+ // 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
+ wxPendingEvents = new wxList;
+ wxPendingEventsLocker = new wxCriticalSection;
+#endif
+
+ wxTheColourDatabase = new wxColourDatabase(wxKEY_STRING);
wxTheColourDatabase->Initialize();
+
wxInitializeStockLists();
wxInitializeStockObjects();
+
+#if wxUSE_WX_RESOURCES
+ wxInitializeResourceSystem();
+#endif
+
wxModule::RegisterModules();
if (!wxModule::InitializeModules()) return FALSE;
+
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);
+ }
+}
+
+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
+ wxLog *oldlog = wxLog::SetActiveTarget(new wxLogStderr);
+ if ( oldlog )
+ delete oldlog;
+#endif // wxUSE_LOG
+
+ wxModule::CleanUpModules();
+
+#if wxUSE_WX_RESOURCES
+ wxCleanUpResourceSystem();
+#endif
+
+ if (wxTheColourDatabase)
+ delete wxTheColourDatabase;
+
+ 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
+ delete wxPendingEvents;
+ delete wxPendingEventsLocker;
+#endif
+
+ wxSystemSettings::Done();
+
+ delete[] wxBuffer;
+
+ wxClassInfo::CleanUpClasses();
+
+ // check for memory leaks
+#if (defined(__WXDEBUG__) && wxUSE_MEMORY_TRACING) || wxUSE_DEBUG_CONTEXT
+ if (wxDebugContext::CountObjectsLeft(TRUE) > 0)
+ {
+ wxLogDebug(wxT("There were memory leaks.\n"));
+ wxDebugContext::Dump();
+ wxDebugContext::PrintStatistics();
+ }
+#endif // Debug
+
+#if wxUSE_LOG
+ // do this as the very last thing because everything else can log messages
+ wxLog::DontCreateOnDemand();
+
+ wxLog *oldLog = wxLog::SetActiveTarget( (wxLog*) NULL );
+ if (oldLog)
+ delete oldLog;
+#endif // wxUSE_LOG
+
+ wxDestroyMGL_WM();
+ MGL_exit();
+}
+
+
+int wxEntryStart(int argc, char *argv[])
+{
+ return wxApp::Initialize() ? 0 : -1;
+}
+
+
+int wxEntryInitGui()
+{
+ return wxTheApp->OnInitGui() ? 0 : -1;
+}
+
+
+void wxEntryCleanup()
+{
+ wxApp::CleanUp();
+}
+
+
+
+int wxEntry(int argc, char *argv[])
+{
+#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?)
+ // Setting a checkpoint will ignore them as far as the
+ // memory checking facility is concerned.
+ // Of course you may argue that memory allocated in globals should be
+ // checked, but this is a reasonable compromise.
+ wxDebugContext::SetCheckpoint();
+#endif
+ int err = wxEntryStart(argc, argv);
+ if ( err )
+ return err;
+
+ if ( !wxTheApp )
+ {
+ wxCHECK_MSG( wxApp::GetInitializerFunction(), -1,
+ wxT("wxWindows error: No initializer - use IMPLEMENT_APP macro.\n") );
+
+ wxAppInitializerFunction app_ini = wxApp::GetInitializerFunction();
+
+ wxObject *test_app = app_ini();
+
+ wxTheApp = (wxApp*) test_app;
+ }
+
+ wxCHECK_MSG( wxTheApp, -1, wxT("wxWindows error: no application object") );
+
+ wxTheApp->argc = argc;
+#if wxUSE_UNICODE
+ wxTheApp->argv = new wxChar*[argc+1];
+ int mb_argc = 0;
+ while (mb_argc < argc)
+ {
+ wxTheApp->argv[mb_argc] = wxStrdup(wxConvLibc.cMB2WX(argv[mb_argc]));
+ mb_argc++;
+ }
+ wxTheApp->argv[mb_argc] = (wxChar *)NULL;
+#else
+ wxTheApp->argv = argv;
+#endif
+
+ wxString name(wxFileNameFromPath(argv[0]));
+ wxStripExtension(name);
+ wxTheApp->SetAppName(name);
+
+ int retValue;
+ retValue = wxEntryInitGui();
+
+ // Here frames insert themselves automatically into wxTopLevelWindows by
+ // getting created in OnInit().
+ if ( retValue == 0 )
+ {
+ if ( !wxTheApp->OnInit() )
+ retValue = -1;
+ }
+
+ if ( retValue == 0 )
+ {
+ /* delete pending toplevel windows (typically a single
+ dialog) so that, if there isn't any left, we don't
+ call OnRun() */
+ wxTheApp->DeletePendingObjects();
+
+ if ( wxTheApp->Initialized() &&
+ wxTopLevelWindows.GetCount() != 0 )
+ {
+ wxTheApp->OnRun();
+
+ wxWindow *topWindow = wxTheApp->GetTopWindow();
+ if ( topWindow )
+ {
+ /* Forcibly delete the window. */
+ if (topWindow->IsKindOf(CLASSINFO(wxFrame)) ||
+ topWindow->IsKindOf(CLASSINFO(wxDialog)) )
+ {
+ topWindow->Close(TRUE);
+ wxTheApp->DeletePendingObjects();
+ }
+ else
+ {
+ delete topWindow;
+ wxTheApp->SetTopWindow((wxWindow*) NULL);
+ }
+ }
+
+ retValue = wxTheApp->OnExit();
+ }
+ }
+
+ wxEntryCleanup();
+
+ return retValue;
+}
switch (cursorId)
{
+ // FIXME_MGL -- what about storing these default cursors in executable
+ // as XPMs so that wxMGL binary wouldn't depend on
+ // tons of files in $MGL_ROOT/cursors? I don't know yet...
case wxCURSOR_ARROW: cursorname = "arrow.cur"; break;
case wxCURSOR_BULLSEYE: cursorname = "bullseye.cur"; break;
case wxCURSOR_CHAR: cursorname = "char.cur"; break;
m_downloadedPatterns[0] = m_downloadedPatterns[1] = FALSE;
m_mglFont = NULL;
+ m_globalClippingRegion = NULL;
}
{
if (m_OwnsMGLDC)
delete m_MGLDC;
+ delete m_globalClippingRegion;
}
void wxDC::SetMGLDC(MGLDevCtx *mgldc, bool OwnsMGLDC)
m_MGLDC = mgldc;
m_OwnsMGLDC = OwnsMGLDC;
m_ok = TRUE;
+
+ if ( mgldc->getDC()->a.clipRegion )
+ {
+ m_globalClippingRegion = new MGLRegion;
+ mgldc->getClipRegion(*m_globalClippingRegion);
+ }
+ else
+ m_globalClippingRegion = NULL;
+
InitializeMGLDC();
}
else
m_currentClippingRegion.Union(rect);
- m_MGLDC->setClipRegion(m_currentClippingRegion.GetMGLRegion());
+ if ( m_globalClippingRegion )
+ {
+ m_MGLDC->setClipRegion(m_currentClippingRegion.GetMGLRegion()
+ & *m_globalClippingRegion);
+ }
+ else
+ m_MGLDC->setClipRegion(m_currentClippingRegion.GetMGLRegion());
m_clipping = TRUE;
DO_SET_CLIPPING_BOX(m_currentClippingRegion)
else
m_currentClippingRegion.Union(rg);
- m_MGLDC->setClipRegion(m_currentClippingRegion.GetMGLRegion());
+ if ( m_globalClippingRegion )
+ {
+ m_MGLDC->setClipRegion(m_currentClippingRegion.GetMGLRegion()
+ & *m_globalClippingRegion);
+ }
+ else
+ m_MGLDC->setClipRegion(m_currentClippingRegion.GetMGLRegion());
m_clipping = TRUE;
DO_SET_CLIPPING_BOX(m_currentClippingRegion)
{
wxCHECK_RET( Ok(), wxT("invalid dc") );
- m_MGLDC->setClipRect(MGLRect(0, 0, m_MGLDC->sizex(), m_MGLDC->sizey()));
+ if ( m_globalClippingRegion )
+ m_MGLDC->setClipRegion(*m_globalClippingRegion);
+ else
+ m_MGLDC->setClipRect(MGLRect(0, 0, m_MGLDC->sizex(), m_MGLDC->sizey()));
m_clipping = FALSE;
m_currentClippingRegion.Clear();
}
#include <mgraph.hpp>
IMPLEMENT_DYNAMIC_CLASS(wxWindowDC, wxDC)
-IMPLEMENT_DYNAMIC_CLASS(wxPaintDC, wxClientDC)
IMPLEMENT_DYNAMIC_CLASS(wxClientDC,wxWindowDC)
+IMPLEMENT_DYNAMIC_CLASS(wxPaintDC, wxClientDC)
wxWindowDC::wxWindowDC(wxWindow *win) : m_wnd(win)
{
- MGLDC *dc = MGL_wmBeginPaint(m_wnd->GetHandle());
- SetMGLDC(new MGLDevCtx(dc), FALSE);
- // FIXME_MGL -- correctly handle setting device origin and
- // clipping regions
+ MGLDevCtx *dc = win->GetPaintMGLDC();
+ if ( dc )
+ {
+ m_inPaintHandler = TRUE;
+ SetMGLDC(dc, FALSE);
+ }
+ else
+ {
+ m_inPaintHandler = FALSE;
+ SetMGLDC(new MGLDevCtx(MGL_wmBeginPaint(m_wnd->GetHandle())), TRUE);
+ // TRUE means that dtor will delete MGLDevCtx object
+ // but it won't destroy MGLDC returned by MGL_wmBeginPaint because
+ // ~MGLDevCtx() doesn't call destroy()
+ }
}
wxWindowDC::~wxWindowDC()
{
- MGL_wmEndPaint(m_wnd->GetHandle());
+ if ( m_inPaintHandler )
+ {
+ // This is neccessary so that subsequently created wxPaintDCs won't get
+ // confused about clipping. Another reason is that the same MGL dc is reused
+ // for wxEraseEvent, wxNcPaintEvent and wxPaintEvent
+ DestroyClippingRegion();
+ }
+ else
+ {
+ GetMGLDC()->setDC(NULL);
+ MGL_wmEndPaint(m_wnd->GetHandle());
+ }
}
wxClientDC::wxClientDC(wxWindow *win) : wxWindowDC(win)
--- /dev/null
+///////////////////////////////////////////////////////////////////////////////
+// Name: mgl/evtloop.cpp
+// Purpose: implements wxEventLoop for MGL
+// Author: Vaclav Slavik
+// RCS-ID: $Id$
+// Copyright: (c) 2001 SciTech Software, Inc. (www.scitechsoft.com)
+// License: wxWindows license
+///////////////////////////////////////////////////////////////////////////////
+
+// ----------------------------------------------------------------------------
+// headers
+// ----------------------------------------------------------------------------
+
+#ifdef __GNUG__
+ #pragma implementation "evtloop.h"
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+ #pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+ #include "wx/window.h"
+ #include "wx/app.h"
+ #include "wx/thread.h"
+#endif //WX_PRECOMP
+
+#include "wx/evtloop.h"
+
+#include "wx/mgl/private.h"
+
+// ----------------------------------------------------------------------------
+// wxEventLoopImpl
+// ----------------------------------------------------------------------------
+
+class WXDLLEXPORT wxEventLoopImpl
+{
+public:
+ // ctor
+ wxEventLoopImpl()
+ {
+ SetExitCode(0);
+ SetKeepLooping(TRUE);
+ }
+
+ // process a message
+ void ProcessEvent(event_t *evt);
+
+ // generate an idle message, return TRUE if more idle time requested
+ bool SendIdleMessage();
+
+ // set/get the exit code
+ void SetExitCode(int exitcode) { m_exitcode = exitcode; }
+ int GetExitCode() const { return m_exitcode; }
+
+ void SetKeepLooping(bool k) { m_keepLooping = k; }
+ bool GetKeepLooping() const { return m_keepLooping; }
+
+private:
+
+ // the exit code of the event loop
+ int m_exitcode;
+ // FALSE if the loop should end
+ bool m_keepLooping;
+};
+
+// ============================================================================
+// wxEventLoopImpl implementation
+// ============================================================================
+
+void wxEventLoopImpl::ProcessEvent(event_t *evt)
+{
+ MGL_wmProcessEvent(g_winMng, evt);
+}
+
+bool wxEventLoopImpl::SendIdleMessage()
+{
+ wxIdleEvent event;
+
+ return wxTheApp->ProcessEvent(event) && event.MoreRequested();
+}
+
+// ============================================================================
+// wxEventLoop implementation
+// ============================================================================
+
+// ----------------------------------------------------------------------------
+// wxEventLoop running and exiting
+// ----------------------------------------------------------------------------
+
+wxEventLoop::~wxEventLoop()
+{
+ wxASSERT_MSG( !m_impl, _T("should have been deleted in Run()") );
+}
+
+bool wxEventLoop::IsRunning() const
+{
+ return m_impl != NULL;
+}
+
+int wxEventLoop::Run()
+{
+ // event loops are not recursive, you need to create another loop!
+ wxCHECK_MSG( !IsRunning(), -1, _T("can't reenter a message loop") );
+
+ m_impl = new wxEventLoopImpl;
+
+ for ( ;; )
+ {
+#if wxUSE_THREADS
+ //wxMutexGuiLeaveOrEnter(); // FIXME_MGL - huh?
+#endif // wxUSE_THREADS
+
+ // generate and process idle events for as long as we don't have
+ // anything else to do
+ while ( !Pending() && m_impl->SendIdleMessage() ) {}
+
+ // a message came or no more idle processing to do, sit in Dispatch()
+ // waiting for the next message
+ if ( !Dispatch() )
+ {
+ // app terminated
+ break;
+ }
+ }
+
+ int exitcode = m_impl->GetExitCode();
+ delete m_impl;
+ m_impl = NULL;
+
+ return exitcode;
+}
+
+void wxEventLoop::Exit(int rc)
+{
+ wxCHECK_RET( IsRunning(), _T("can't call Exit() if not running") );
+
+ m_impl->SetExitCode(rc);
+ m_impl->SetKeepLooping(FALSE);
+}
+
+// ----------------------------------------------------------------------------
+// wxEventLoop message processing dispatching
+// ----------------------------------------------------------------------------
+
+bool wxEventLoop::Pending() const
+{
+ event_t evt;
+ return EVT_peekNext(&evt, EVT_EVERYEVT);
+}
+
+bool wxEventLoop::Dispatch()
+{
+ wxCHECK_MSG( IsRunning(), FALSE, _T("can't call Dispatch() if not running") );
+
+ event_t evt;
+ ibool rc = EVT_getNext(&evt, EVT_EVERYEVT);
+
+ if ( !rc )
+ {
+ wxLogError(_T("events queue empty even though Pending() returned true"));
+ return FALSE;
+ }
+
+ // FIXME_MGL -- there must be some way to programatically exit
+ // the loop, like WM_QUIT under Windows -- perhaps we need custom
+ // event to indicate this??
+
+ m_impl->ProcessEvent(&evt);
+
+ return m_impl->GetKeepLooping();
+}
+
/////////////////////////////////////////////////////////////////////////////
-// Name: settings.cpp
-// Purpose:
-// Author: Robert Roebling
+// Name: settings.h
+// Author: Vaclav Slavik
// Id: $Id$
-// Copyright: (c) 1998 Robert Roebling
+// Copyright: (c) 2001 SciTech Software, Inc. (www.scitechsoft.com)
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
#endif
#include "wx/settings.h"
+#include "wx/colour.h"
+#include "wx/font.h"
+wxColour wxSystemSettings::GetSystemColour(int WXUNUSED(index))
+{
+ // FIXME_MGL
+ return wxColour(255,255,0);
+}
+
+wxFont wxSystemSettings::GetSystemFont(int WXUNUSED(index))
+{
+ // FIXME_MGL
+ return wxFont(12, wxMODERN, wxNORMAL, wxNORMAL);
+}
+
+int wxSystemSettings::GetSystemMetric(int WXUNUSED(index))
+{
+ // FIXME_MGL
+ return 1;
+}
if (height) *height = g_displayDC->sizey();
}
-void wxGetMousePosition(int* x, int* y)
+void wxDisplaySizeMM(int *width, int *height)
{
- MS_getPos(x, y);
+ wxASSERT_MSG( g_displayDC, wxT("MGL display DC not created yet.") );
+ if (width) *width = g_displayDC->sizex() * 25/72;
+ if (height) *height = g_displayDC->sizey() * 25/72;
+ // FIXME_MGL -- what about returning *real* monitor dimensions?
}
-wxPoint wxGetMousePosition()
+void wxClientDisplayRect(int *x, int *y, int *width, int *height)
{
- wxPoint pt;
- wxGetMousePosition(&pt.x, &pt.y);
- return pt;
+ // This is supposed to return desktop dimensions minus any window
+ // manager panels, menus, taskbars, etc. If there is a way to do that
+ // for this platform please fix this function, otherwise it defaults
+ // to the entire desktop.
+ if (x) *x = 0;
+ if (y) *y = 0;
+ wxDisplaySize(width, height);
}
bool wxColourDisplay()
}
+void wxGetMousePosition(int* x, int* y)
+{
+ MS_getPos(x, y);
+}
+
+wxPoint wxGetMousePosition()
+{
+ wxPoint pt;
+ wxGetMousePosition(&pt.x, &pt.y);
+ return pt;
+}
+
+
+
#ifdef __UNIX__
int wxAddProcessCallback(wxEndProcessData *proc_data, int fd)
extern wxList WXDLLEXPORT wxPendingDelete;
// FIXME_MGL -- ???
-
-static wxWindowMGL *g_focusedWindow;
+
+// the window that has keyboard+joystick focus:
+static wxWindowMGL *g_focusedWindow = NULL;
+// the window that is currently under mouse cursor:
+static wxWindowMGL *g_windowUnderMouse = NULL;
// ---------------------------------------------------------------------------
// constants
// private functions
// ---------------------------------------------------------------------------
-static void wxWindowPainter(window_t *wnd, MGLDC *dc);
-
// wxCreateMGL_WM creates MGL display DC and associates it with winmng_t
// structure. Dimensions and depth of the DC are fetched from wxSystemOptions
// object.
void wxDestroyMGL_WM()
{
- if (g_winMng)
+ if ( g_winMng )
{
MGL_wmDestroy(g_winMng);
g_winMng = NULL;
}
- delete g_displayDC;
- g_displayDC = NULL;
+ if ( g_displayDC )
+ {
+ delete g_displayDC;
+ g_displayDC = NULL;
+ }
}
+// ---------------------------------------------------------------------------
+// MGL_WM hooks:
+// ---------------------------------------------------------------------------
+
+static void wxWindowPainter(window_t *wnd, MGLDC *dc)
+{
+ wxWindowMGL *w = (wxWindow*) wnd->userData;
+ if (w)
+ {
+ MGLDevCtx ctx(dc);
+ w->HandlePaint(&ctx);
+ }
+}
// ---------------------------------------------------------------------------
// event tables
IMPLEMENT_ABSTRACT_CLASS(wxWindowMGL, wxWindowBase)
BEGIN_EVENT_TABLE(wxWindowMGL, wxWindowBase)
- EVT_ERASE_BACKGROUND(wxWindowMGL::OnEraseBackground)
- EVT_SET_FOCUS(wxWindowMGL::OnSetFocus)
END_EVENT_TABLE()
// ===========================================================================
m_isBeingDeleted = TRUE;
if ( g_focusedWindow == this )
- g_focusedWindow = NULL;
+ KillFocus();
+
#if 0 // -- fixme - do we need this?
// VS: make sure there's no wxFrame with last focus set to us:
for (wxWindow *win = GetParent(); win; win = win->GetParent())
long style,
const wxString& name)
{
- wxCHECK_MSG( parent, FALSE, wxT("can't create wxWindow without parent") );
+ // FIXME_MGL -- temporary!
+ //wxCHECK_MSG( parent, FALSE, wxT("can't create wxWindow without parent") );
if ( !CreateBase(parent, id, pos, size, style, wxDefaultValidator, name) )
return FALSE;
- parent->AddChild(this);
+ if ( parent ) // FIXME_MGL temporary
+ parent->AddChild(this);
+ else
+ m_isShown=FALSE;// FIXME_MGL -- temporary, simulates wxTLW/wxFrame
if ( style & wxPOPUP_WINDOW )
{
MGL_wmCaptureEvents(GetHandle(), EVT_KEYEVT | EVT_JOYEVT, wxMGL_CAPTURE_KEYB);
- wxPanel *panel = wxDynamicCast(GetParent(), wxPanel);
- if (panel)
- panel->SetLastFocus((wxWindow*)this);
-
#if wxUSE_CARET
// caret needs to be informed about focus change
wxCaret *caret = GetCaret();
if ( g_focusedWindow != this ) return;
g_focusedWindow = NULL;
+ if ( m_isBeingDeleted ) return;
+
MGL_wmUncaptureEvents(GetHandle(), wxMGL_CAPTURE_KEYB);
#if wxUSE_CARET
// caret needs to be informed about focus change
wxCaret *caret = GetCaret();
- if (caret)
+ if ( caret )
caret->OnKillFocus();
#endif // wxUSE_CARET
- if (IsTopLevel())
+ if ( IsTopLevel() )
{
wxActivateEvent event(wxEVT_ACTIVATE, FALSE, GetId());
event.SetEventObject(this);
#endif // wxUSE_CARET
-// ---------------------------------------------------------------------------
-// activation/focus
-// ---------------------------------------------------------------------------
-
-void wxWindowMGL::OnSetFocus(wxFocusEvent& event)
-{
- // panel wants to track the window which was the last to have focus in it,
- // so we want to set ourselves as the window which last had focus
- //
- // notice that it's also important to do it upwards the tree becaus
- // otherwise when the top level panel gets focus, it won't set it back to
- // us, but to some other sibling
- wxWindow *win = (wxWindow *)this;
- while ( win )
- {
- wxWindow *parent = win->GetParent();
- wxPanel *panel = wxDynamicCast(parent, wxPanel);
- if ( panel )
- {
- panel->SetLastFocus(win);
- }
-
- win = parent;
- }
-
- event.Skip();
-}
-
-
// ---------------------------------------------------------------------------
// painting
// ---------------------------------------------------------------------------
Refresh();
}
-static void wxWindowPainter(window_t *wnd, MGLDC *dc)
-{
- wxWindow *w = (wxWindow*) wnd->userData;
- if (w)
- {
- MGLDevCtx ctx(dc);
- w->HandlePaint(&ctx);
- }
-}
-
void wxWindowMGL::HandlePaint(MGLDevCtx *dc)
{
if ( m_frozen )
return;
}
- region_t *clip = NULL;
- MGL_getClipRegionDC(*dc, clip);
- m_updateRegion = wxRegion(MGLRegion(clip));
+ region_t clip;
+ MGL_getClipRegionDC(*dc, &clip);
+ m_updateRegion = wxRegion(MGLRegion(&clip));
m_paintMGLDC = dc;
- wxEraseEvent eventEr(m_windowId, NULL);
+ {
+ wxWindowDC dc((wxWindow*)this);
+ wxEraseEvent eventEr(m_windowId, &dc);
eventEr.SetEventObject(this);
GetEventHandler()->ProcessEvent(eventEr);
+ }
wxNcPaintEvent eventNc(GetId());
eventNc.SetEventObject(this);
wxPaintEvent eventPt(GetId());
eventPt.SetEventObject(this);
GetEventHandler()->ProcessEvent(eventPt);
-}
-void wxWindowMGL::OnEraseBackground(wxEraseEvent& event)
-{
- Clear();
+ m_paintMGLDC = NULL;
}