Main change is that we now close X11 display on program exit: as this couldn't

be done in wxApp dtor (too early), a special module had to be created for it
and module dependencies added for the other modules which have to be cleaned
up while the display is still open.

Also a few minor formatting changes and removed a couple of unused variables
from wxApp.


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@42119 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2006-10-19 14:39:53 +00:00
parent 36751d973e
commit b886fae648
6 changed files with 117 additions and 119 deletions

View File

@@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
// Name: app.h // Name: wx/x11/app.h
// Purpose: wxApp class // Purpose: wxApp class
// Author: Julian Smart // Author: Julian Smart
// Modified by: // Modified by:
@@ -9,8 +9,8 @@
// Licence: wxWindows licence // Licence: wxWindows licence
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
#ifndef _WX_APP_H_ #ifndef _WX_X11_APP_H_
#define _WX_APP_H_ #define _WX_X11_APP_H_
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// headers // headers
@@ -36,8 +36,6 @@ class WXDLLEXPORT wxXVisualInfo;
class WXDLLEXPORT wxApp : public wxAppBase class WXDLLEXPORT wxApp : public wxAppBase
{ {
DECLARE_DYNAMIC_CLASS(wxApp)
public: public:
wxApp(); wxApp();
virtual ~wxApp(); virtual ~wxApp();
@@ -62,9 +60,6 @@ public:
virtual void OnAssert(const wxChar *file, int line, const wxChar* cond, const wxChar *msg); virtual void OnAssert(const wxChar *file, int line, const wxChar* cond, const wxChar *msg);
#endif // __WXDEBUG__ #endif // __WXDEBUG__
protected:
bool m_showOnInit;
public: public:
// Implementation // Implementation
virtual bool Initialize(int& argc, wxChar **argv); virtual bool Initialize(int& argc, wxChar **argv);
@@ -96,10 +91,6 @@ public:
return m_visualInfo; return m_visualInfo;
} }
// We need this before creating the app
static WXDisplay* GetDisplay() { return ms_display; }
static WXDisplay* ms_display;
public: public:
static long sm_lastMessageTime; static long sm_lastMessageTime;
bool m_showIconic; bool m_showIconic;
@@ -110,14 +101,13 @@ public:
#endif #endif
protected: protected:
bool m_keepGoing;
WXWindow m_topLevelWidget; WXWindow m_topLevelWidget;
WXColormap m_mainColormap; WXColormap m_mainColormap;
long m_maxRequestSize; long m_maxRequestSize;
DECLARE_DYNAMIC_CLASS(wxApp)
DECLARE_EVENT_TABLE() DECLARE_EVENT_TABLE()
}; };
#endif // _WX_APP_H_ #endif // _WX_X11_APP_H_

View File

@@ -804,15 +804,7 @@ bool wxGetKeyState(wxKeyCode key)
wxASSERT_MSG(key != WXK_LBUTTON && key != WXK_RBUTTON && key != wxASSERT_MSG(key != WXK_LBUTTON && key != WXK_RBUTTON && key !=
WXK_MBUTTON, wxT("can't use wxGetKeyState() for mouse buttons")); WXK_MBUTTON, wxT("can't use wxGetKeyState() for mouse buttons"));
#if defined(__WXX11__) Display *pDisplay = (Display*) wxGetDisplay();
Display *pDisplay = (Display*) wxApp::GetDisplay();
#elif defined(__WXGTK__)
Display *pDisplay = GDK_DISPLAY();
#elif defined(__WXMOTIF__)
Display *pDisplay = (Display*) (wxTheApp ? wxTheApp->GetInitialDisplay() : NULL);
#else
#error Add code to get the DISPLAY for this platform
#endif
int iKey = wxCharCodeWXToX(key); int iKey = wxCharCodeWXToX(key);
int iKeyMask = 0; int iKeyMask = 0;
@@ -825,7 +817,8 @@ bool wxGetKeyState(wxKeyCode key)
return false; return false;
if ( IsModifierKey(iKey) ) // If iKey is a modifier key, use a different method if ( IsModifierKey(iKey) ) // If iKey is a modifier key, use a different method
{ for (int i = 0; i < 8; ++i) {
for (int i = 0; i < 8; ++i)
{ {
if ( map->modifiermap[map->max_keypermod * i] == keyCode) if ( map->modifiermap[map->max_keypermod * i] == keyCode)
{ {
@@ -838,6 +831,7 @@ bool wxGetKeyState(wxKeyCode key)
XFreeModifiermap(map); XFreeModifiermap(map);
return (iMask & iKeyMask) != 0; return (iMask & iKeyMask) != 0;
} }
// From the XLib manual: // From the XLib manual:
// The XQueryKeymap() function returns a bit vector for the logical state of the keyboard, // The XQueryKeymap() function returns a bit vector for the logical state of the keyboard,
// where each bit set to 1 indicates that the corresponding key is currently pressed down. // where each bit set to 1 indicates that the corresponding key is currently pressed down.

View File

@@ -83,7 +83,6 @@ static int wxXErrorHandler(Display *dpy, XErrorEvent *xevent)
//------------------------------------------------------------------------ //------------------------------------------------------------------------
long wxApp::sm_lastMessageTime = 0; long wxApp::sm_lastMessageTime = 0;
WXDisplay *wxApp::ms_display = NULL;
IMPLEMENT_DYNAMIC_CLASS(wxApp, wxEvtHandler) IMPLEMENT_DYNAMIC_CLASS(wxApp, wxEvtHandler)
@@ -165,34 +164,24 @@ bool wxApp::Initialize(int& argC, wxChar **argV)
} }
} }
// X11 display stuff // open and set up the X11 display
Display *xdisplay; if ( !wxSetDisplay(displayName) )
if ( displayName.empty() )
xdisplay = XOpenDisplay( NULL );
else
xdisplay = XOpenDisplay( displayName.ToAscii() );
if (!xdisplay)
{ {
wxLogError( _("wxWidgets could not open display. Exiting.") ); wxLogError(_("wxWidgets could not open display. Exiting."));
return false; return false;
} }
Display *dpy = wxGlobalDisplay();
if (syncDisplay) if (syncDisplay)
XSynchronize(xdisplay, True); XSynchronize(dpy, True);
ms_display = (WXDisplay*) xdisplay; XSelectInput(dpy, XDefaultRootWindow(dpy), PropertyChangeMask);
XSelectInput( xdisplay, XDefaultRootWindow(xdisplay), PropertyChangeMask);
// Misc.
wxSetDetectableAutoRepeat( true ); wxSetDetectableAutoRepeat( true );
if ( !wxAppBase::Initialize(argC, argV) )
{
XCloseDisplay(xdisplay);
if ( !wxAppBase::Initialize(argC, argV) )
return false; return false;
}
#if wxUSE_UNICODE #if wxUSE_UNICODE
// Glib's type system required by Pango // Glib's type system required by Pango
@@ -221,12 +210,8 @@ void wxApp::CleanUp()
wxApp::wxApp() wxApp::wxApp()
{ {
// TODO: parse the command line m_mainColormap = NULL;
argc = 0; m_topLevelWidget = NULL;
argv = NULL;
m_mainColormap = (WXColormap) NULL;
m_topLevelWidget = (WXWindow) NULL;
m_maxRequestSize = 0; m_maxRequestSize = 0;
m_showIconic = false; m_showIconic = false;
m_initialSize = wxDefaultSize; m_initialSize = wxDefaultSize;
@@ -678,13 +663,14 @@ bool wxApp::OnInitGui()
if (!wxAppBase::OnInitGui()) if (!wxAppBase::OnInitGui())
return false; return false;
GetMainColormap( wxApp::GetDisplay() ); Display *dpy = wxGlobalDisplay();
GetMainColormap(dpy);
m_maxRequestSize = XMaxRequestSize( (Display*) wxApp::GetDisplay() ); m_maxRequestSize = XMaxRequestSize(dpy);
#if !wxUSE_NANOX #if !wxUSE_NANOX
m_visualInfo = new wxXVisualInfo; m_visualInfo = new wxXVisualInfo;
wxFillXVisualInfo( m_visualInfo, (Display*) wxApp::GetDisplay() ); wxFillXVisualInfo(m_visualInfo, dpy);
#endif #endif
return true; return true;
@@ -700,33 +686,34 @@ bool wxApp::OnInitGui()
PangoContext* wxApp::GetPangoContext() PangoContext* wxApp::GetPangoContext()
{ {
static PangoContext *ret = NULL; static PangoContext *s_pangoContext = NULL;
if (ret) if ( !s_pangoContext )
return ret; {
Display *dpy = wxGlobalDisplay();
Display *xdisplay = (Display*) wxApp::GetDisplay();
#ifdef HAVE_PANGO_XFT #ifdef HAVE_PANGO_XFT
int xscreen = DefaultScreen(xdisplay); int xscreen = DefaultScreen(dpy);
static int use_xft = -1; static int use_xft = -1;
if (use_xft == -1) if (use_xft == -1)
{ {
wxString val = wxGetenv( L"GDK_USE_XFT" ); wxString val = wxGetenv( L"GDK_USE_XFT" );
use_xft = (val == L"1"); use_xft = val == L"1";
} }
if (use_xft) if (use_xft)
ret = pango_xft_get_context( xdisplay, xscreen ); s_pangoContext = pango_xft_get_context(dpy, xscreen);
else else
#endif #endif // HAVE_PANGO_XFT
ret = pango_x_get_context( xdisplay ); s_pangoContext = pango_x_get_context(dpy);
if (!PANGO_IS_CONTEXT(ret)) if (!PANGO_IS_CONTEXT(s_pangoContext))
wxLogError( wxT("No pango context.") ); wxLogError( wxT("No pango context.") );
}
return ret; return s_pangoContext;
} }
#endif
#endif // wxUSE_UNICODE
WXColormap wxApp::GetMainColormap(WXDisplay* display) WXColormap wxApp::GetMainColormap(WXDisplay* display)
{ {

View File

@@ -2366,8 +2366,15 @@ wxPaintDC::wxPaintDC(wxWindow* window)
class wxDCModule : public wxModule class wxDCModule : public wxModule
{ {
public: public:
bool OnInit(); // we must be cleaned up before wxDisplayModule which closes the global
void OnExit(); // display
wxDCModule()
{
AddDependency(wxClassInfo::FindClass(_T("wxX11DisplayModule")));
}
bool OnInit() { wxInitGCPool(); return true; }
void OnExit() { wxCleanUpGCPool(); }
private: private:
DECLARE_DYNAMIC_CLASS(wxDCModule) DECLARE_DYNAMIC_CLASS(wxDCModule)
@@ -2375,13 +2382,3 @@ private:
IMPLEMENT_DYNAMIC_CLASS(wxDCModule, wxModule) IMPLEMENT_DYNAMIC_CLASS(wxDCModule, wxModule)
bool wxDCModule::OnInit()
{
wxInitGCPool();
return true;
}
void wxDCModule::OnExit()
{
wxCleanUpGCPool();
}

View File

@@ -239,40 +239,54 @@ void wxClientDisplayRect(int *x, int *y, int *width, int *height)
wxDisplaySize(width, height); wxDisplaySize(width, height);
} }
wxWindow* wxFindWindowAtPoint(const wxPoint& pt)
{
return wxGenericFindWindowAtPoint(pt);
}
// Configurable display in wxX11 and wxMotif // Configurable display in wxX11 and wxMotif
static WXDisplay *gs_currentDisplay = NULL; static Display *gs_currentDisplay = NULL;
static wxString gs_displayName; static wxString gs_displayName;
WXDisplay *wxGetDisplay() WXDisplay *wxGetDisplay()
{ {
if (gs_currentDisplay) return (WXDisplay *)gs_currentDisplay;
return gs_currentDisplay;
return wxApp::GetDisplay();
} }
bool wxSetDisplay(const wxString& display_name) // close the current display
void wxCloseDisplay()
{ {
gs_displayName = display_name; if ( gs_currentDisplay )
if ( display_name.empty() )
{ {
if ( XCloseDisplay(gs_currentDisplay) != 0 )
{
wxLogWarning(_("Failed to close the display \"%s\""),
gs_displayName.c_str());
}
gs_currentDisplay = NULL; gs_currentDisplay = NULL;
gs_displayName.clear();
return true;
} }
else }
{
Display* display = XOpenDisplay((char*) display_name.c_str());
if (display) bool wxSetDisplay(const wxString& displayName)
{
Display *
dpy = XOpenDisplay(displayName.empty() ? NULL : displayName.mb_str());
if ( !dpy )
{ {
gs_currentDisplay = (WXDisplay*) display; wxLogError(_("Failed to open display \"%s\"."), displayName.c_str());
return true;
}
else
return false; return false;
} }
wxCloseDisplay();
gs_currentDisplay = dpy;
gs_displayName = displayName;
return true;
} }
wxString wxGetDisplayName() wxString wxGetDisplayName()
@@ -280,10 +294,20 @@ wxString wxGetDisplayName()
return gs_displayName; return gs_displayName;
} }
wxWindow* wxFindWindowAtPoint(const wxPoint& pt) #include "wx/module.h"
// the module responsible for closing the X11 display at the program end
class wxX11DisplayModule : public wxModule
{ {
return wxGenericFindWindowAtPoint(pt); public:
} virtual bool OnInit() { return true; }
virtual void OnExit() { wxCloseDisplay(); }
private:
DECLARE_DYNAMIC_CLASS(wxX11DisplayModule)
};
IMPLEMENT_DYNAMIC_CLASS(wxX11DisplayModule, wxModule)
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// Some colour manipulation routines // Some colour manipulation routines

View File

@@ -1694,8 +1694,14 @@ int wxNoOptimize::ms_count = 0;
class wxWinModule : public wxModule class wxWinModule : public wxModule
{ {
public: public:
bool OnInit(); wxWinModule()
void OnExit(); {
// we must be cleaned up before the display is closed
AddDependency(wxClassInfo::FindClass(_T("wxX11DisplayModule")));
}
virtual bool OnInit();
virtual void OnExit();
private: private:
DECLARE_DYNAMIC_CLASS(wxWinModule) DECLARE_DYNAMIC_CLASS(wxWinModule)