wxMGL wxWindow and wxApp mostly complete, now hunting bugs

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@11341 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Václav Slavík
2001-08-09 22:40:39 +00:00
parent 2cb980c58d
commit 7bdc18790e
13 changed files with 802 additions and 156 deletions

View File

@@ -21,8 +21,8 @@
// classes
//-----------------------------------------------------------------------------
class wxApp;
class wxLog;
class WXDLLEXPORT wxApp;
class WXDLLEXPORT wxLog;
//-----------------------------------------------------------------------------
// wxApp
@@ -31,59 +31,40 @@ class wxLog;
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__

View File

@@ -45,6 +45,7 @@ class WXDLLEXPORT wxDC;
// MGL fwd declarations:
class MGLDevCtx;
class MGLRegion;
struct font_t;
class WXDLLEXPORT wxDC : public wxDCBase
@@ -268,6 +269,8 @@ protected:
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;

View File

@@ -16,8 +16,6 @@
#include "wx/dc.h"
class WXDLLEXPORT wxWindowMGL;
//-----------------------------------------------------------------------------
// classes
//-----------------------------------------------------------------------------
@@ -25,6 +23,7 @@ class WXDLLEXPORT wxWindowMGL;
class WXDLLEXPORT wxWindowDC;
class WXDLLEXPORT wxPaintDC;
class WXDLLEXPORT wxClientDC;
class WXDLLEXPORT wxWindowMGL;
//-----------------------------------------------------------------------------
// wxWindowDC
@@ -39,6 +38,7 @@ public:
protected:
wxWindow *m_wnd;
bool m_inPaintHandler;
private:
DECLARE_DYNAMIC_CLASS(wxWindowDC)
@@ -55,7 +55,6 @@ public:
wxClientDC(wxWindow *win);
private:
wxWindowMGL *m_wnd;
DECLARE_DYNAMIC_CLASS(wxClientDC)
};
@@ -63,12 +62,11 @@ private:
// 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)

View File

@@ -1,9 +1,8 @@
/////////////////////////////////////////////////////////////////////////////
// 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
/////////////////////////////////////////////////////////////////////////////
@@ -24,19 +23,19 @@
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

View File

@@ -113,7 +113,6 @@ protected:
// (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;
@@ -141,9 +140,6 @@ private:
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()
@@ -151,6 +147,7 @@ private:
public:
void HandlePaint(MGLDevCtx *dc);
// needed by wxWindowPainter
MGLDevCtx *GetPaintMGLDC() const { return m_paintMGLDC; }
};

View File

@@ -1,7 +1,7 @@
/////////////////////////////////////////////////////////////////////////////
// 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
@@ -11,28 +11,42 @@
#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"
#include <mgraph.hpp>
#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 "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);
}
@@ -40,17 +54,63 @@ void wxExit()
// 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
}
//-----------------------------------------------------------------------------
@@ -64,26 +124,390 @@ BEGIN_EVENT_TABLE(wxApp, wxEvtHandler)
END_EVENT_TABLE()
int wxEntry( int argc, char *argv[] )
wxApp::wxApp()
{
return 0;
}
wxApp::~wxApp()
{
}
// FIXME_MGL - this is temporary solution, will be removed
// once I have wxApp up and running
bool wxMGL_Initialize()
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()
{
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;
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;
}

View File

@@ -68,6 +68,9 @@ wxCursor::wxCursor(int cursorId)
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;

View File

@@ -172,6 +172,7 @@ wxDC::wxDC()
m_downloadedPatterns[0] = m_downloadedPatterns[1] = FALSE;
m_mglFont = NULL;
m_globalClippingRegion = NULL;
}
@@ -179,6 +180,7 @@ wxDC::~wxDC()
{
if (m_OwnsMGLDC)
delete m_MGLDC;
delete m_globalClippingRegion;
}
void wxDC::SetMGLDC(MGLDevCtx *mgldc, bool OwnsMGLDC)
@@ -188,6 +190,15 @@ 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();
}
@@ -226,7 +237,13 @@ void wxDC::DoSetClippingRegion(wxCoord cx, wxCoord cy, wxCoord cw, wxCoord ch)
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)
@@ -265,7 +282,13 @@ void wxDC::DoSetClippingRegionAsRegion(const wxRegion& region)
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)
@@ -275,7 +298,10 @@ void wxDC::DestroyClippingRegion()
{
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();
}

View File

@@ -26,20 +26,41 @@
#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)

176
src/mgl/evtloop.cpp Normal file
View File

@@ -0,0 +1,176 @@
///////////////////////////////////////////////////////////////////////////////
// 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();
}

View File

@@ -1,9 +1,8 @@
/////////////////////////////////////////////////////////////////////////////
// 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
/////////////////////////////////////////////////////////////////////////////
@@ -13,4 +12,23 @@
#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;
}

View File

@@ -47,16 +47,23 @@ void wxDisplaySize(int *width, int *height)
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()
@@ -85,6 +92,20 @@ int wxGetOsVersion(int *majorVsn, int *minorVsn)
}
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)

View File

@@ -65,8 +65,11 @@ MGLDevCtx *g_displayDC = NULL;
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
@@ -85,8 +88,6 @@ enum
// 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.
@@ -137,15 +138,31 @@ bool wxCreateMGL_WM()
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
@@ -156,8 +173,6 @@ void wxDestroyMGL_WM()
IMPLEMENT_ABSTRACT_CLASS(wxWindowMGL, wxWindowBase)
BEGIN_EVENT_TABLE(wxWindowMGL, wxWindowBase)
EVT_ERASE_BACKGROUND(wxWindowMGL::OnEraseBackground)
EVT_SET_FOCUS(wxWindowMGL::OnSetFocus)
END_EVENT_TABLE()
// ===========================================================================
@@ -191,7 +206,8 @@ wxWindowMGL::~wxWindowMGL()
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())
@@ -226,12 +242,16 @@ bool wxWindowMGL::Create(wxWindow *parent,
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 )
{
@@ -260,10 +280,6 @@ void wxWindowMGL::SetFocus()
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();
@@ -288,16 +304,18 @@ void wxWindowMGL::KillFocus()
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);
@@ -657,35 +675,6 @@ void wxWindowMGL::GetCaretPos(int *x, int *y) const
#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
// ---------------------------------------------------------------------------
@@ -731,16 +720,6 @@ void wxWindowMGL::Thaw()
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 )
@@ -749,14 +728,17 @@ void wxWindowMGL::HandlePaint(MGLDevCtx *dc)
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);
@@ -765,11 +747,8 @@ void wxWindowMGL::HandlePaint(MGLDevCtx *dc)
wxPaintEvent eventPt(GetId());
eventPt.SetEventObject(this);
GetEventHandler()->ProcessEvent(eventPt);
}
void wxWindowMGL::OnEraseBackground(wxEraseEvent& event)
{
Clear();
m_paintMGLDC = NULL;
}