From b886fae6484edbb3a2fdbe8be74b3a840e9c84ee Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Thu, 19 Oct 2006 14:39:53 +0000 Subject: [PATCH] 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 --- include/wx/x11/app.h | 20 +++------- src/unix/utilsx11.cpp | 28 ++++++-------- src/x11/app.cpp | 85 ++++++++++++++++++------------------------- src/x11/dcclient.cpp | 21 +++++------ src/x11/utils.cpp | 72 ++++++++++++++++++++++++------------ src/x11/window.cpp | 10 ++++- 6 files changed, 117 insertions(+), 119 deletions(-) diff --git a/include/wx/x11/app.h b/include/wx/x11/app.h index 416a3e2ae3..b78e4abae9 100644 --- a/include/wx/x11/app.h +++ b/include/wx/x11/app.h @@ -1,5 +1,5 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: app.h +// Name: wx/x11/app.h // Purpose: wxApp class // Author: Julian Smart // Modified by: @@ -9,8 +9,8 @@ // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// -#ifndef _WX_APP_H_ -#define _WX_APP_H_ +#ifndef _WX_X11_APP_H_ +#define _WX_X11_APP_H_ // ---------------------------------------------------------------------------- // headers @@ -36,8 +36,6 @@ class WXDLLEXPORT wxXVisualInfo; class WXDLLEXPORT wxApp : public wxAppBase { - DECLARE_DYNAMIC_CLASS(wxApp) - public: wxApp(); virtual ~wxApp(); @@ -62,9 +60,6 @@ public: virtual void OnAssert(const wxChar *file, int line, const wxChar* cond, const wxChar *msg); #endif // __WXDEBUG__ -protected: - bool m_showOnInit; - public: // Implementation virtual bool Initialize(int& argc, wxChar **argv); @@ -96,10 +91,6 @@ public: return m_visualInfo; } - // We need this before creating the app - static WXDisplay* GetDisplay() { return ms_display; } - static WXDisplay* ms_display; - public: static long sm_lastMessageTime; bool m_showIconic; @@ -110,14 +101,13 @@ public: #endif protected: - bool m_keepGoing; - WXWindow m_topLevelWidget; WXColormap m_mainColormap; long m_maxRequestSize; + DECLARE_DYNAMIC_CLASS(wxApp) DECLARE_EVENT_TABLE() }; -#endif // _WX_APP_H_ +#endif // _WX_X11_APP_H_ diff --git a/src/unix/utilsx11.cpp b/src/unix/utilsx11.cpp index e1cf437119..aa349b3efc 100644 --- a/src/unix/utilsx11.cpp +++ b/src/unix/utilsx11.cpp @@ -804,15 +804,7 @@ bool wxGetKeyState(wxKeyCode key) wxASSERT_MSG(key != WXK_LBUTTON && key != WXK_RBUTTON && key != WXK_MBUTTON, wxT("can't use wxGetKeyState() for mouse buttons")); -#if defined(__WXX11__) - 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 + Display *pDisplay = (Display*) wxGetDisplay(); int iKey = wxCharCodeWXToX(key); int iKeyMask = 0; @@ -825,19 +817,21 @@ bool wxGetKeyState(wxKeyCode key) return false; if ( IsModifierKey(iKey) ) // If iKey is a modifier key, use a different method - { for (int i = 0; i < 8; ++i) { - if ( map->modifiermap[map->max_keypermod * i] == keyCode) + for (int i = 0; i < 8; ++i) { - iKeyMask = 1 << i; + if ( map->modifiermap[map->max_keypermod * i] == keyCode) + { + iKeyMask = 1 << i; + } } + + XQueryPointer(pDisplay, DefaultRootWindow(pDisplay), &wDummy1, &wDummy2, + &iDummy3, &iDummy4, &iDummy5, &iDummy6, &iMask ); + XFreeModifiermap(map); + return (iMask & iKeyMask) != 0; } - XQueryPointer(pDisplay, DefaultRootWindow(pDisplay), &wDummy1, &wDummy2, - &iDummy3, &iDummy4, &iDummy5, &iDummy6, &iMask ); - XFreeModifiermap(map); - return (iMask & iKeyMask) != 0; - } // From the XLib manual: // 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. diff --git a/src/x11/app.cpp b/src/x11/app.cpp index e5dc6785da..2d35f3b630 100644 --- a/src/x11/app.cpp +++ b/src/x11/app.cpp @@ -83,7 +83,6 @@ static int wxXErrorHandler(Display *dpy, XErrorEvent *xevent) //------------------------------------------------------------------------ long wxApp::sm_lastMessageTime = 0; -WXDisplay *wxApp::ms_display = NULL; IMPLEMENT_DYNAMIC_CLASS(wxApp, wxEvtHandler) @@ -165,34 +164,24 @@ bool wxApp::Initialize(int& argC, wxChar **argV) } } - // X11 display stuff - Display *xdisplay; - if ( displayName.empty() ) - xdisplay = XOpenDisplay( NULL ); - else - xdisplay = XOpenDisplay( displayName.ToAscii() ); - if (!xdisplay) + // open and set up the X11 display + if ( !wxSetDisplay(displayName) ) { - wxLogError( _("wxWidgets could not open display. Exiting.") ); + wxLogError(_("wxWidgets could not open display. Exiting.")); return false; } + Display *dpy = wxGlobalDisplay(); 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 ); - if ( !wxAppBase::Initialize(argC, argV) ) - { - XCloseDisplay(xdisplay); + if ( !wxAppBase::Initialize(argC, argV) ) return false; - } #if wxUSE_UNICODE // Glib's type system required by Pango @@ -221,12 +210,8 @@ void wxApp::CleanUp() wxApp::wxApp() { - // TODO: parse the command line - argc = 0; - argv = NULL; - - m_mainColormap = (WXColormap) NULL; - m_topLevelWidget = (WXWindow) NULL; + m_mainColormap = NULL; + m_topLevelWidget = NULL; m_maxRequestSize = 0; m_showIconic = false; m_initialSize = wxDefaultSize; @@ -678,13 +663,14 @@ bool wxApp::OnInitGui() if (!wxAppBase::OnInitGui()) return false; - GetMainColormap( wxApp::GetDisplay() ); + Display *dpy = wxGlobalDisplay(); + GetMainColormap(dpy); - m_maxRequestSize = XMaxRequestSize( (Display*) wxApp::GetDisplay() ); + m_maxRequestSize = XMaxRequestSize(dpy); #if !wxUSE_NANOX m_visualInfo = new wxXVisualInfo; - wxFillXVisualInfo( m_visualInfo, (Display*) wxApp::GetDisplay() ); + wxFillXVisualInfo(m_visualInfo, dpy); #endif return true; @@ -700,33 +686,34 @@ bool wxApp::OnInitGui() PangoContext* wxApp::GetPangoContext() { - static PangoContext *ret = NULL; - if (ret) - return ret; - - Display *xdisplay = (Display*) wxApp::GetDisplay(); + static PangoContext *s_pangoContext = NULL; + if ( !s_pangoContext ) + { + Display *dpy = wxGlobalDisplay(); #ifdef HAVE_PANGO_XFT - int xscreen = DefaultScreen(xdisplay); - static int use_xft = -1; - if (use_xft == -1) - { - wxString val = wxGetenv( L"GDK_USE_XFT" ); - use_xft = (val == L"1"); + int xscreen = DefaultScreen(dpy); + static int use_xft = -1; + if (use_xft == -1) + { + wxString val = wxGetenv( L"GDK_USE_XFT" ); + use_xft = val == L"1"; + } + + if (use_xft) + s_pangoContext = pango_xft_get_context(dpy, xscreen); + else +#endif // HAVE_PANGO_XFT + s_pangoContext = pango_x_get_context(dpy); + + if (!PANGO_IS_CONTEXT(s_pangoContext)) + wxLogError( wxT("No pango context.") ); } - if (use_xft) - ret = pango_xft_get_context( xdisplay, xscreen ); - else -#endif - ret = pango_x_get_context( xdisplay ); - - if (!PANGO_IS_CONTEXT(ret)) - wxLogError( wxT("No pango context.") ); - - return ret; + return s_pangoContext; } -#endif + +#endif // wxUSE_UNICODE WXColormap wxApp::GetMainColormap(WXDisplay* display) { diff --git a/src/x11/dcclient.cpp b/src/x11/dcclient.cpp index 849911fa69..c799f1fbed 100644 --- a/src/x11/dcclient.cpp +++ b/src/x11/dcclient.cpp @@ -2366,8 +2366,15 @@ wxPaintDC::wxPaintDC(wxWindow* window) class wxDCModule : public wxModule { public: - bool OnInit(); - void OnExit(); + // we must be cleaned up before wxDisplayModule which closes the global + // display + wxDCModule() + { + AddDependency(wxClassInfo::FindClass(_T("wxX11DisplayModule"))); + } + + bool OnInit() { wxInitGCPool(); return true; } + void OnExit() { wxCleanUpGCPool(); } private: DECLARE_DYNAMIC_CLASS(wxDCModule) @@ -2375,13 +2382,3 @@ private: IMPLEMENT_DYNAMIC_CLASS(wxDCModule, wxModule) -bool wxDCModule::OnInit() -{ - wxInitGCPool(); - return true; -} - -void wxDCModule::OnExit() -{ - wxCleanUpGCPool(); -} diff --git a/src/x11/utils.cpp b/src/x11/utils.cpp index 6c8fa963cb..df9d4f9da5 100644 --- a/src/x11/utils.cpp +++ b/src/x11/utils.cpp @@ -239,51 +239,75 @@ void wxClientDisplayRect(int *x, int *y, int *width, int *height) wxDisplaySize(width, height); } +wxWindow* wxFindWindowAtPoint(const wxPoint& pt) +{ + return wxGenericFindWindowAtPoint(pt); +} + // Configurable display in wxX11 and wxMotif -static WXDisplay *gs_currentDisplay = NULL; +static Display *gs_currentDisplay = NULL; static wxString gs_displayName; WXDisplay *wxGetDisplay() { - if (gs_currentDisplay) - return gs_currentDisplay; - return wxApp::GetDisplay(); + return (WXDisplay *)gs_currentDisplay; } -bool wxSetDisplay(const wxString& display_name) +// close the current display +void wxCloseDisplay() { - gs_displayName = display_name; - - if ( display_name.empty() ) + if ( gs_currentDisplay ) { - gs_currentDisplay = NULL; - - return true; - } - else - { - Display* display = XOpenDisplay((char*) display_name.c_str()); - - if (display) + if ( XCloseDisplay(gs_currentDisplay) != 0 ) { - gs_currentDisplay = (WXDisplay*) display; - return true; + wxLogWarning(_("Failed to close the display \"%s\""), + gs_displayName.c_str()); } - else - return false; + + gs_currentDisplay = NULL; + gs_displayName.clear(); } } +bool wxSetDisplay(const wxString& displayName) +{ + Display * + dpy = XOpenDisplay(displayName.empty() ? NULL : displayName.mb_str()); + + if ( !dpy ) + { + wxLogError(_("Failed to open display \"%s\"."), displayName.c_str()); + return false; + } + + wxCloseDisplay(); + + gs_currentDisplay = dpy; + gs_displayName = displayName; + + return true; +} + wxString wxGetDisplayName() { 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 diff --git a/src/x11/window.cpp b/src/x11/window.cpp index d51631aace..9c5f6f49b8 100644 --- a/src/x11/window.cpp +++ b/src/x11/window.cpp @@ -1694,8 +1694,14 @@ int wxNoOptimize::ms_count = 0; class wxWinModule : public wxModule { public: - bool OnInit(); - void OnExit(); + wxWinModule() + { + // we must be cleaned up before the display is closed + AddDependency(wxClassInfo::FindClass(_T("wxX11DisplayModule"))); + } + + virtual bool OnInit(); + virtual void OnExit(); private: DECLARE_DYNAMIC_CLASS(wxWinModule)