class WXDLLEXPORT wxApp;
class WXDLLEXPORT wxLog;
+class WXDLLEXPORT wxEventLoop;
//-----------------------------------------------------------------------------
// wxApp
private:
DECLARE_DYNAMIC_CLASS(wxApp)
DECLARE_EVENT_TABLE()
+
+ wxEventLoop *m_mainLoop;
};
int WXDLLEXPORT wxEntry(int argc, char *argv[]);
wxPalette m_oldPalette;
wxRegion m_currentClippingRegion;
- // clipping region m_MGLDC had when it was attached:
- MGLRegion *m_globalClippingRegion;
+ wxRegion m_globalClippingRegion;
// wxDC::Blit handles memoryDCs as special cases :(
bool m_isMemDC;
#endif
#include "wx/app.h"
+#include "wx/fontutil.h"
#include "wx/mgl/private.h"
//-----------------------------------------------------------------------------
wxApp *wxTheApp = NULL;
wxAppInitializerFunction wxAppBase::m_appInitFn = (wxAppInitializerFunction) NULL;
-static wxEventLoop *gs_mainEventLoop = NULL;
-
//-----------------------------------------------------------------------------
// wxExit
wxLog::Suspend();
- while (gs_mainEventLoop->Pending())
- gs_mainEventLoop->Dispatch();
+ if ( wxEventLoop::GetActive() )
+ {
+ while (wxEventLoop::GetActive()->Pending())
+ wxEventLoop::GetActive()->Dispatch();
+ }
+ else
+ MGL_wmUpdateDC(g_winMng); // FIXME_MGL -- temporary hack, please remove
/* it's necessary to call ProcessIdle() to update the frames sizes which
might have been changed (it also will update other things set from
END_EVENT_TABLE()
-wxApp::wxApp()
+wxApp::wxApp() : m_mainLoop(NULL)
{
}
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()
bool wxApp::Pending()
{
- return gs_mainEventLoop->Pending();
+ return wxEventLoop::GetActive()->Pending();
}
void wxApp::Dispatch()
{
- gs_mainEventLoop->Dispatch();
+ wxEventLoop::GetActive()->Dispatch();
}
void wxApp::DeletePendingObjects()
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();
wxTheColourDatabase = (wxColourDatabase*) NULL;
wxDeleteStockObjects();
-
wxDeleteStockLists();
+ // Can't do this in wxModule, because fonts are needed by stock lists
+ delete wxTheFontsManager;
+ wxTheFontsManager = (wxFontsManager*) NULL;
+
delete wxTheApp;
wxTheApp = (wxApp*) NULL;
static pixel_format_t gs_pixel_format_32 =
{0xFF,0x18,0, 0xFF,0x10,0, 0xFF,0x08,0, 0xFF,0x00,0}; // RGBA 32bpp
-// FIXME_MGL -- these formats will probably have to go into another place,
-// where wxApp could use them to initialize g_displayDC
-
-
//-----------------------------------------------------------------------------
// wxMask
//-----------------------------------------------------------------------------
#include "wx/log.h"
#include "wx/intl.h"
-#include <mgraph.hpp>
+#include "wx/mgl/private.h"
//-----------------------------------------------------------------------------
case wxCURSOR_BLANK: cursorname = "blank.cur"; break;
case wxCURSOR_NONE:
- // FIXME_MGL - make sure wxWindow uses cursor with
- // GetMGLCursor() == NULL correctly, i.e. calls MS_hide()
*this = wxNullCursor;
return;
break;
// Global cursor setting
// ----------------------------------------------------------------------------
+static wxCursor g_globalCursor = wxNullCursor;
void wxSetCursor(const wxCursor& cursor)
{
if ( cursor.Ok() )
{
- //MGL_setGlobalCursor(cursor.GetMGLCursor());
- // FIXME_MGL -- needs MGL WM first
+ MGL_wmSetGlobalCursor(g_winMng, *cursor.GetMGLCursor());
+ g_globalCursor = cursor;
}
}
// busy cursor routines
//-----------------------------------------------------------------------------
-// FIXME_MGL -- do we need this? It may be better to incorporate
-// support for it into MGL (a stack of global cursors?)
-static wxCursor gs_savedCursor;
-static wxCursor g_globalCursor;
+static wxCursor gs_savedCursor = wxNullCursor;
static int gs_busyCount = 0;
const wxCursor &wxBusyCursor::GetStoredCursor()
wxSetCursor(gs_savedCursor);
gs_savedCursor = wxNullCursor;
- //wxYield(); FIXME_MGL - needed?
}
-void wxBeginBusyCursor(wxCursor *WXUNUSED(cursor))
+void wxBeginBusyCursor(wxCursor *cursor)
{
if ( gs_busyCount++ > 0 ) return;
wxT("forgot to call wxEndBusyCursor, will leak memory") );
gs_savedCursor = g_globalCursor;
- wxSetCursor(wxCursor(wxCURSOR_WAIT));
- //wxYield(); FIXME_MGL - needed?
+ if ( cursor->Ok() )
+ wxSetCursor(*cursor);
+ else
+ wxSetCursor(wxCursor(wxCURSOR_WAIT));
}
bool wxIsBusy()
m_OwnsMGLDC = FALSE;
m_ok = FALSE; // must call SetMGLDevCtx() before using it
-#if 0
m_mm_to_pix_x = (double)wxGetDisplaySize().GetWidth() /
(double)wxGetDisplaySizeMM().GetWidth();
m_mm_to_pix_y = (double)wxGetDisplaySize().GetHeight() /
(double)wxGetDisplaySizeMM().GetHeight();
-#endif
- // FIXME_MGL -- not in wxUniversal branch (and not implementend anyway,
- // hardcode it for 75dpi for now)
- m_mm_to_pix_x = ((double)wxGetDisplaySize().GetWidth() / 75) * inches2mm;
- m_mm_to_pix_y = ((double)wxGetDisplaySize().GetHeight() / 75) * inches2mm;
m_pen = *wxBLACK_PEN;
m_font = *wxNORMAL_FONT;
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)
if ( mgldc->getDC()->a.clipRegion )
{
- m_globalClippingRegion = new MGLRegion;
- mgldc->getClipRegion(*m_globalClippingRegion);
+ MGLRegion clip;
+ mgldc->getClipRegion(clip);
+ m_globalClippingRegion = wxRegion(clip);
+ // FIXME_MGL -- reuse wxWindows::m_updateRegion ?
+ m_currentClippingRegion = m_globalClippingRegion;
+ m_clipping = TRUE;
}
- else
- m_globalClippingRegion = NULL;
InitializeMGLDC();
}
else
m_currentClippingRegion.Union(rect);
- if ( m_globalClippingRegion )
- {
- m_MGLDC->setClipRegion(m_currentClippingRegion.GetMGLRegion()
- & *m_globalClippingRegion);
- }
- else
- m_MGLDC->setClipRegion(m_currentClippingRegion.GetMGLRegion());
+ m_MGLDC->setClipRegion(m_currentClippingRegion.GetMGLRegion());
m_clipping = TRUE;
DO_SET_CLIPPING_BOX(m_currentClippingRegion)
{
wxCHECK_RET( Ok(), wxT("invalid dc") );
- if ( region.Empty() )
+ if ( region.IsEmpty() )
{
DestroyClippingRegion();
return;
else
m_currentClippingRegion.Union(rg);
- if ( m_globalClippingRegion )
- {
- m_MGLDC->setClipRegion(m_currentClippingRegion.GetMGLRegion()
- & *m_globalClippingRegion);
- }
- else
- m_MGLDC->setClipRegion(m_currentClippingRegion.GetMGLRegion());
+ m_MGLDC->setClipRegion(m_currentClippingRegion.GetMGLRegion());
m_clipping = TRUE;
DO_SET_CLIPPING_BOX(m_currentClippingRegion)
{
wxCHECK_RET( Ok(), wxT("invalid dc") );
- if ( m_globalClippingRegion )
- m_MGLDC->setClipRegion(*m_globalClippingRegion);
+ if ( !m_globalClippingRegion.IsNull() )
+ {
+ m_MGLDC->setClipRegion(m_globalClippingRegion.GetMGLRegion());
+ m_currentClippingRegion = m_globalClippingRegion;
+ m_clipping = TRUE;
+ }
else
+ {
m_MGLDC->setClipRect(MGLRect(0, 0, m_MGLDC->sizex(), m_MGLDC->sizey()));
- m_clipping = FALSE;
- m_currentClippingRegion.Clear();
+ m_clipping = FALSE;
+ m_currentClippingRegion.Clear();
+ }
}
// ---------------------------------------------------------------------------
SetKeepLooping(TRUE);
}
- // process a message
- void ProcessEvent(event_t *evt);
+ // process an event
+ void Dispatch();
- // generate an idle message, return TRUE if more idle time requested
- bool SendIdleMessage();
+ // generate an idle event, return TRUE if more idle time requested
+ bool SendIdleEvent();
// set/get the exit code
void SetExitCode(int exitcode) { m_exitcode = exitcode; }
// wxEventLoopImpl implementation
// ============================================================================
-void wxEventLoopImpl::ProcessEvent(event_t *evt)
+void wxEventLoopImpl::Dispatch()
{
- MGL_wmProcessEvent(g_winMng, evt);
+ event_t evt;
+ ibool rc;
+
+ MGL_wmUpdateDC(g_winMng);
+
+ EVT_halt(&evt, EVT_EVERYEVT);
+ MGL_wmProcessEvent(g_winMng, &evt);
}
-bool wxEventLoopImpl::SendIdleMessage()
+bool wxEventLoopImpl::SendIdleEvent()
{
wxIdleEvent event;
// wxEventLoop running and exiting
// ----------------------------------------------------------------------------
+wxEventLoop *wxEventLoop::ms_activeLoop = NULL;
+
wxEventLoop::~wxEventLoop()
{
wxASSERT_MSG( !m_impl, _T("should have been deleted in Run()") );
wxCHECK_MSG( !IsRunning(), -1, _T("can't reenter a message loop") );
m_impl = new wxEventLoopImpl;
+
+ wxEventLoop *oldLoop = ms_activeLoop;
+ ms_activeLoop = this;
for ( ;; )
{
// generate and process idle events for as long as we don't have
// anything else to do
- while ( !Pending() && m_impl->SendIdleMessage() ) {}
+ while ( !Pending() && m_impl->SendIdleEvent() ) {}
// a message came or no more idle processing to do, sit in Dispatch()
// waiting for the next message
delete m_impl;
m_impl = NULL;
+ ms_activeLoop = oldLoop;
+
return exitcode;
}
{
wxCHECK_MSG( IsRunning(), FALSE, _T("can't call Dispatch() if not running") );
- event_t evt;
- ibool rc;
-
- rc = EVT_getNext(&evt, EVT_EVERYEVT);
- while ( !rc )
- {
- wxUsleep(1000);
- if ( !m_impl->GetKeepLooping() )
- return FALSE;
- rc = EVT_getNext(&evt, EVT_EVERYEVT);
- }
-
- m_impl->ProcessEvent(&evt);
-
+ m_impl->Dispatch();
return m_impl->GetKeepLooping();
}
m_valid = data.m_valid;
if ( m_library )
m_library->IncRef();
+ wxLogTrace("mgl_font", "created fntrefdata %p, library is %p", this, m_library);
}
wxFontRefData::wxFontRefData(int size, int family, int style,
wxFontEncoding encoding)
{
Init(size, family, style, weight, underlined, faceName, encoding);
+ wxLogTrace("mgl_font", "created fntrefdata %p, library is %p", this, m_library);
}
wxFontRefData::~wxFontRefData()
{
+ wxLogTrace("mgl_font", "destructing fntrefdata %p, library is %p", this, m_library);
if ( m_library )
m_library->DecRef();
}
#endif
#ifndef WX_PRECOMP
+ #include "wx/log.h"
+ #include "wx/fontutil.h"
+ #include "wx/fontmap.h"
+ #include "wx/tokenzr.h"
+ #include "wx/hash.h"
#endif // PCH
-#include "wx/fontutil.h"
-#include "wx/fontmap.h"
-#include "wx/tokenzr.h"
-#include "wx/hash.h"
-#include "wx/module.h"
#include "wx/listimpl.cpp"
-#include "wx/log.h"
#include "wx/mgl/private.h"
#include <mgraph.h>
wxFontsManager *wxTheFontsManager = NULL;
-
-
-// A module that takes care of fonts DB initialization and destruction:
-
-class wxFontutilModule: public wxModule
-{
-DECLARE_DYNAMIC_CLASS(wxFontutilModule)
-public:
- wxFontutilModule() {}
- bool OnInit()
- {
- wxTheFontsManager = new wxFontsManager;
- return TRUE;
- }
- void OnExit()
- {
- delete wxTheFontsManager;
- }
-};
-
-IMPLEMENT_DYNAMIC_CLASS(wxFontutilModule, wxModule)
wxColour wxSystemSettings::GetSystemColour(int WXUNUSED(index))
{
// FIXME_MGL
- return wxColour(255,255,0);
+ return wxColour(0,0,0);
}
wxFont wxSystemSettings::GetSystemFont(int WXUNUSED(index))
{
// FIXME_MGL
- return wxFont(12, wxSWISS, wxNORMAL, wxNORMAL);
+ return wxFont(9, wxSWISS, wxNORMAL, wxNORMAL);
}
int wxSystemSettings::GetSystemMetric(int WXUNUSED(index))
// with desired settings
// FIXME_MGL -- move to app.cpp??
+static void wxDesktopPainter(window_t *wnd, MGLDC *dc)
+{
+ // FIXME_MGL - for now...
+ MGL_setColorRGB(0x63, 0x63, 0x96);
+ MGL_fillRectCoord(0, 0, wnd->width, wnd->height);
+}
+
+
bool wxCreateMGL_WM()
{
int mode;
int refresh = MGL_DEFAULT_REFRESH;
#if wxUSE_SYSTEM_OPTIONS
+ // FIXME_MGL -- so what is The Proper Way?
if ( wxSystemOptions::HasOption(wxT("mgl.screen-width") )
width = wxSystemOptions::GetOptionInt(wxT("mgl.screen-width"));
if ( wxSystemOptions::HasOption(wxT("mgl.screen-height") )
g_winMng = MGL_wmCreate(g_displayDC->getDC());
if (!g_winMng)
return FALSE;
+
+ MGL_wmSetWindowPainter(MGL_wmGetRootWindow(g_winMng), wxDesktopPainter);
return TRUE;
}
MGLDevCtx ctx(dc);
w->HandlePaint(&ctx);
}
+ // FIXME_MGL -- root window should be a regular window so that
+ // enter/leave and activate/deactivate events work correctly
+}
+
+static ibool wxWindowMouseHandler(window_t *wnd, event_t *e)
+{
+ wxWindowMGL *win = (wxWindowMGL*)MGL_wmGetWindowUserData(wnd);
+ wxPoint where = win->ScreenToClient(wxPoint(e->where_x, e->where_y));
+
+ wxEventType type = wxEVT_NULL;
+ wxMouseEvent event;
+ event.SetEventObject(win);
+ event.SetTimestamp(e->when);
+ event.m_x = where.x;
+ event.m_y = where.y;
+ event.m_shiftDown = e->modifiers & EVT_SHIFTKEY;
+ event.m_controlDown = e->modifiers & EVT_CTRLSTATE;
+ event.m_altDown = e->modifiers & EVT_LEFTALT;
+ event.m_metaDown = e->modifiers & EVT_RIGHTALT;
+ event.m_leftDown = e->modifiers & EVT_LEFTBUT;
+ event.m_middleDown = e->modifiers & EVT_MIDDLEBUT;
+ event.m_rightDown = e->modifiers & EVT_RIGHTBUT;
+
+ switch (e->what)
+ {
+ case EVT_MOUSEDOWN:
+ if ( e->message & EVT_LEFTBMASK )
+ type = (e->message & EVT_DBLCLICK) ?
+ wxEVT_LEFT_DCLICK : wxEVT_LEFT_DOWN;
+ else if ( e->message & EVT_MIDDLEBMASK )
+ type = (e->message & EVT_DBLCLICK) ?
+ wxEVT_MIDDLE_DCLICK : wxEVT_MIDDLE_DOWN;
+ else if ( e->message & EVT_RIGHTBMASK )
+ type = (e->message & EVT_DBLCLICK) ?
+ wxEVT_RIGHT_DCLICK : wxEVT_RIGHT_DOWN;
+ break;
+
+ case EVT_MOUSEUP:
+ if ( e->message & EVT_LEFTBMASK )
+ type = wxEVT_LEFT_UP;
+ else if ( e->message & EVT_MIDDLEBMASK )
+ type = wxEVT_MIDDLE_UP;
+ else if ( e->message & EVT_RIGHTBMASK )
+ type = wxEVT_RIGHT_UP;
+ break;
+
+ case EVT_MOUSEMOVE:
+ if ( win != g_windowUnderMouse )
+ {
+ if ( g_windowUnderMouse )
+ {
+ wxMouseEvent event2(event);
+ wxPoint where2 = g_windowUnderMouse->ScreenToClient(
+ wxPoint(e->where_x, e->where_y));
+ event2.m_x = where2.x;
+ event2.m_y = where2.y;
+ event2.SetEventObject(g_windowUnderMouse);
+ event2.SetEventType(wxEVT_LEAVE_WINDOW);
+ g_windowUnderMouse->GetEventHandler()->ProcessEvent(event2);
+ }
+
+ wxMouseEvent event3(event);
+ event3.SetEventType(wxEVT_ENTER_WINDOW);
+ win->GetEventHandler()->ProcessEvent(event3);
+
+ g_windowUnderMouse = win;
+ }
+
+ type = wxEVT_MOTION;
+ break;
+
+ default:
+ break;
+ }
+
+ if ( type == wxEVT_NULL )
+ {
+ return FALSE;
+ }
+ else
+ {
+ event.SetEventType(type);
+ return win->GetEventHandler()->ProcessEvent(event);
+ }
+}
+
+static ibool wxWindowKeybHandler(window_t *wnd, event_t *e)
+{
+ // FIXME_MGL
+ return FALSE;
+}
+
+static ibool wxWindowJoyHandler(window_t *wnd, event_t *e)
+{
+ // FIXME_MGL
+ return FALSE;
}
// ---------------------------------------------------------------------------
// event tables
// ---------------------------------------------------------------------------
-// in wxUniv/MSW this class is abstract because it doesn't have DoPopupMenu()
-// method
+// in wxUniv this class is abstract because it doesn't have DoPopupMenu()
IMPLEMENT_ABSTRACT_CLASS(wxWindowMGL, wxWindowBase)
BEGIN_EVENT_TABLE(wxWindowMGL, wxWindowBase)
InitBase();
// mgl specific:
- if ( !g_winMng && !wxCreateMGL_WM() )
- wxFatalError(_T("Can't initalize MGL, aborting!"));
-
m_wnd = NULL;
m_isShown = TRUE;
m_isBeingDeleted = FALSE;
if ( g_focusedWindow == this )
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())
- {
- wxFrame *frame = wxDynamicCast(win, wxFrame);
- if ( frame )
- {
- if ( frame->GetLastFocus() == this )
- frame->SetLastFocus((wxWindow*)NULL);
- break;
- }
- }
-#endif
+ if ( g_windowUnderMouse == this )
+ g_windowUnderMouse = NULL;
// VS: destroy children first and _then_ detach *this from its parent.
// If we'd do it the other way around, children wouldn't be able
m_isShown = FALSE;
}
+ int x, y, w, h;
+ x = pos.x, y = pos.y;
+ if ( x == -1 )
+ x = 0; // FIXME_MGL, something better, see GTK+
+ if ( y == -1 )
+ y = 0; // FIXME_MGL, something better, see GTK+
+ w = WidthDefault(size.x);
+ h = HeightDefault(size.y);
+
m_wnd = MGL_wmCreateWindow(g_winMng,
parent ? parent->GetHandle() : NULL,
- pos.x, pos.y, size.x, size.y);
- MGL_wmShowWindow(m_wnd, m_isShown);
+ x, y, w, h);
+
MGL_wmSetWindowUserData(m_wnd, (void*) this);
MGL_wmSetWindowPainter(m_wnd, wxWindowPainter);
+ MGL_wmShowWindow(m_wnd, m_isShown);
+ MGL_wmSetWindowCursor(m_wnd, *wxSTANDARD_CURSOR->GetMGLCursor());
+
+ MGL_wmPushWindowEventHandler(m_wnd, wxWindowMouseHandler, EVT_MOUSEEVT, 0);
+ MGL_wmPushWindowEventHandler(m_wnd, wxWindowKeybHandler, EVT_KEYEVT, 0);
+ MGL_wmPushWindowEventHandler(m_wnd, wxWindowJoyHandler, EVT_JOYEVT, 0);
+
return TRUE;
}
g_focusedWindow = this;
- MGL_wmCaptureEvents(GetHandle(), EVT_KEYEVT | EVT_JOYEVT, wxMGL_CAPTURE_KEYB);
+ MGL_wmCaptureEvents(GetHandle(), EVT_KEYEVT|EVT_JOYEVT, wxMGL_CAPTURE_KEYB);
#if wxUSE_CARET
// caret needs to be informed about focus change
caret->OnSetFocus();
#endif // wxUSE_CARET
- if (IsTopLevel())
+ if ( IsTopLevel() )
{
wxActivateEvent event(wxEVT_ACTIVATE, TRUE, GetId());
event.SetEventObject(this);
if ( m_cursor.Ok() )
MGL_wmSetWindowCursor(m_wnd, *m_cursor.GetMGLCursor());
+ else
+ MGL_wmSetWindowCursor(m_wnd, *wxSTANDARD_CURSOR->GetMGLCursor());
+
+ // FIXME_MGL -- should it set children's cursor or not?!
return TRUE;
}
m_refreshAfterThaw = TRUE;
return;
}
-
+
MGLRegion clip;
dc->getClipRegion(clip);
m_updateRegion = wxRegion(clip);