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:
@@ -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_
|
||||||
|
|
||||||
|
@@ -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,19 +817,21 @@ 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)
|
|
||||||
{
|
{
|
||||||
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:
|
// 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.
|
||||||
|
@@ -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)
|
||||||
|
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)
|
return s_pangoContext;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
#endif // wxUSE_UNICODE
|
||||||
|
|
||||||
WXColormap wxApp::GetMainColormap(WXDisplay* display)
|
WXColormap wxApp::GetMainColormap(WXDisplay* display)
|
||||||
{
|
{
|
||||||
|
@@ -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();
|
|
||||||
}
|
|
||||||
|
@@ -239,51 +239,75 @@ 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() )
|
|
||||||
{
|
{
|
||||||
gs_currentDisplay = NULL;
|
if ( XCloseDisplay(gs_currentDisplay) != 0 )
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Display* display = XOpenDisplay((char*) display_name.c_str());
|
|
||||||
|
|
||||||
if (display)
|
|
||||||
{
|
{
|
||||||
gs_currentDisplay = (WXDisplay*) display;
|
wxLogWarning(_("Failed to close the display \"%s\""),
|
||||||
return true;
|
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()
|
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
|
||||||
|
@@ -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)
|
||||||
|
Reference in New Issue
Block a user