X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/ef1717a963dfb76bac26b9f4277ae590b3c0a2e6..534090e354ebd5b4c42e6c27a6aa6073c0ef669e:/src/unix/displayx11.cpp diff --git a/src/unix/displayx11.cpp b/src/unix/displayx11.cpp index fdd1dc18b5..db0f37b899 100644 --- a/src/unix/displayx11.cpp +++ b/src/unix/displayx11.cpp @@ -21,22 +21,23 @@ #include "wx/wxprec.h" #ifdef __BORLANDC__ - #pragma hdrstop + #pragma hdrstop #endif +#if wxUSE_DISPLAY + #include "wx/display.h" -#include "wx/display_impl.h" -#include "wx/intl.h" -#include "wx/log.h" #ifndef WX_PRECOMP - #include "wx/dynarray.h" - #include "wx/gdicmn.h" - #include "wx/string.h" - #include "wx/utils.h" + #include "wx/dynarray.h" + #include "wx/gdicmn.h" + #include "wx/string.h" + #include "wx/utils.h" + #include "wx/intl.h" + #include "wx/log.h" #endif /* WX_PRECOMP */ -#if wxUSE_DISPLAY +#include "wx/display_impl.h" /* These must be included after the wx files. Otherwise the Data macro in * Xlibint.h conflicts with a function declaration in wx/list.h. */ @@ -70,7 +71,7 @@ public: operator const XineramaScreenInfo *() const { return m_screens; } - size_t GetCount() const { return wx_static_cast(size_t, m_num); } + unsigned GetCount() const { return static_cast(m_num); } private: XineramaScreenInfo *m_screens; @@ -84,12 +85,21 @@ private: class WXDLLEXPORT wxDisplayImplX11 : public wxDisplayImpl { public: - wxDisplayImplX11(const XineramaScreenInfo& info) - : m_rect(info.x_org, info.y_org, info.width, info.height) + wxDisplayImplX11(unsigned n, const XineramaScreenInfo& info) + : wxDisplayImpl(n), + m_rect(info.x_org, info.y_org, info.width, info.height) { } virtual wxRect GetGeometry() const { return m_rect; } + virtual wxRect GetClientArea() const + { + // we intentionally don't cache the result here because the client + // display area may change (e.g. the user resized or hid a panel) and + // we don't currently react to its changes + return IsPrimary() ? wxGetClientDisplayRect() : m_rect; + } + virtual wxString GetName() const { return wxString(); } virtual wxArrayVideoModes GetModes(const wxVideoMode& mode) const; @@ -100,27 +110,27 @@ private: wxRect m_rect; int m_depth; - DECLARE_NO_COPY_CLASS(wxDisplayImplX11) + wxDECLARE_NO_COPY_CLASS(wxDisplayImplX11); }; class wxDisplayFactoryX11 : public wxDisplayFactory { public: - wxDisplayFactoryX11(); + wxDisplayFactoryX11() { } - virtual wxDisplayImpl *CreateDisplay(size_t n); - virtual size_t GetCount(); + virtual wxDisplayImpl *CreateDisplay(unsigned n); + virtual unsigned GetCount(); virtual int GetFromPoint(const wxPoint& pt); protected: - DECLARE_NO_COPY_CLASS(wxDisplayFactoryX11) + wxDECLARE_NO_COPY_CLASS(wxDisplayFactoryX11); }; // ============================================================================ // wxDisplayFactoryX11 implementation // ============================================================================ -size_t wxDisplayFactoryX11::GetCount() +unsigned wxDisplayFactoryX11::GetCount() { return ScreensInfo().GetCount(); } @@ -129,8 +139,8 @@ int wxDisplayFactoryX11::GetFromPoint(const wxPoint& p) { ScreensInfo screens; - const size_t numscreens(screens.GetCount()); - for ( size_t i = 0; i < numscreens; ++i ) + const unsigned numscreens(screens.GetCount()); + for ( unsigned i = 0; i < numscreens; ++i ) { const XineramaScreenInfo& s = screens[i]; if ( p.x >= s.x_org && p.x < s.x_org + s.width && @@ -143,11 +153,11 @@ int wxDisplayFactoryX11::GetFromPoint(const wxPoint& p) return wxNOT_FOUND; } -wxDisplayImpl *wxDisplayFactoryX11::CreateDisplay(size_t n) +wxDisplayImpl *wxDisplayFactoryX11::CreateDisplay(unsigned n) { ScreensInfo screens; - return n < screens.GetCount() ? new wxDisplayImplX11(screens[n]) : NULL; + return n < screens.GetCount() ? new wxDisplayImplX11(n, screens[n]) : NULL; } // ============================================================================ @@ -170,7 +180,7 @@ wxDisplayImpl *wxDisplayFactoryX11::CreateDisplay(size_t n) #define wxCVM2(v, dc) wxVideoMode(v.hdisplay, v.vdisplay, DefaultDepth((Display*)wxGetDisplay(), DefaultScreen((Display*)wxGetDisplay())), wxCRR2(v,dc)) #define wxCVM(v) wxCVM2(v, v.dotclock) -wxArrayVideoModes wxDisplay::GetModes(const wxVideoMode& mode) const +wxArrayVideoModes wxDisplayImplX11::GetModes(const wxVideoMode& mode) const { //Convenience... Display* pDisplay = (Display*) wxGetDisplay(); //default display @@ -204,7 +214,7 @@ wxArrayVideoModes wxDisplay::GetModes(const wxVideoMode& mode) const return Modes; } -wxVideoMode wxDisplay::GetCurrentMode() const +wxVideoMode wxDisplayImplX11::GetCurrentMode() const { XF86VidModeModeLine VM; int nDotClock; @@ -214,7 +224,7 @@ wxVideoMode wxDisplay::GetCurrentMode() const return wxCVM2(VM, nDotClock); } -bool wxDisplay::ChangeMode(const wxVideoMode& mode) +bool wxDisplayImplX11::ChangeMode(const wxVideoMode& mode) { XF86VidModeModeInfo** ppXModes; //Enumerated Modes (Don't forget XFree() :)) int nNumModes; //Number of modes enumerated.... @@ -242,9 +252,9 @@ bool wxDisplay::ChangeMode(const wxVideoMode& mode) for (int i = 0; i < nNumModes; ++i) { if (!bRet && - ppXModes[i]->hdisplay == mode.w && - ppXModes[i]->vdisplay == mode.h && - wxCRR((*ppXModes[i])) == mode.refresh) + ppXModes[i]->hdisplay == mode.GetWidth() && + ppXModes[i]->vdisplay == mode.GetHeight() && + wxCRR((*ppXModes[i])) == mode.GetRefresh()) { //switch! bRet = XF86VidModeSwitchToMode((Display*)wxGetDisplay(), DefaultScreen((Display*)wxGetDisplay()), @@ -263,7 +273,7 @@ bool wxDisplay::ChangeMode(const wxVideoMode& mode) #else // !HAVE_X11_EXTENSIONS_XF86VMODE_H -wxArrayVideoModes wxDisplay::GetModes(const wxVideoMode& mode) const +wxArrayVideoModes wxDisplayImplX11::GetModes(const wxVideoMode& modeMatch) const { int count_return; int* depths = XListDepths((Display*)wxGetDisplay(), 0, &count_return); @@ -272,7 +282,11 @@ wxArrayVideoModes wxDisplay::GetModes(const wxVideoMode& mode) const { for ( int x = 0; x < count_return; ++x ) { - modes.Add(wxVideoMode(m_rect.GetWidth(), m_rect.GetHeight(), depths[x])); + wxVideoMode mode(m_rect.GetWidth(), m_rect.GetHeight(), depths[x]); + if ( mode.Matches(modeMatch) ) + { + modes.Add(modeMatch); + } } XFree(depths); @@ -280,13 +294,13 @@ wxArrayVideoModes wxDisplay::GetModes(const wxVideoMode& mode) const return modes; } -wxVideoMode wxDisplay::GetCurrentMode() const +wxVideoMode wxDisplayImplX11::GetCurrentMode() const { // Not implemented return wxVideoMode(); } -bool wxDisplay::ChangeMode(const wxVideoMode& mode) +bool wxDisplayImplX11::ChangeMode(const wxVideoMode& WXUNUSED(mode)) { // Not implemented return false; @@ -300,10 +314,118 @@ bool wxDisplay::ChangeMode(const wxVideoMode& mode) /* static */ wxDisplayFactory *wxDisplay::CreateFactory() { - Display *disp = (Display*)wxGetDisplay(); + if ( XineramaIsActive((Display*)wxGetDisplay()) ) + { + return new wxDisplayFactoryX11; + } - return XineramaIsActive(disp) ? new wxDisplayFactoryX11 - : new wxDisplayFactorySingle; + return new wxDisplayFactorySingle; } #endif /* wxUSE_DISPLAY */ + +#include "wx/utils.h" + +#if wxUSE_LIBHILDON || wxUSE_LIBHILDON2 + +void wxClientDisplayRect(int *x, int *y, int *width, int *height) +{ + // TODO: don't hardcode display size + if ( x ) + *x = 0; + if ( y ) + *y = 0; + if ( width ) + *width = 672; + if ( height ) + *height = 396; +} + +#else // !wxUSE_LIBHILDON || !wxUSE_LIBHILDON2 + +#include "wx/log.h" + +#include +#include + +// TODO: make this a full-fledged class and move to a public header +class wxX11Ptr +{ +public: + wxX11Ptr(void *ptr = NULL) : m_ptr(ptr) { } + ~wxX11Ptr() { if ( m_ptr ) XFree(m_ptr); } + +private: + void *m_ptr; + + wxDECLARE_NO_COPY_CLASS(wxX11Ptr); +}; + +// NB: this function is implemented using X11 and not GDK calls as it's shared +// by wxGTK[12], wxX11 and wxMotif ports +void wxClientDisplayRect(int *x, int *y, int *width, int *height) +{ + Display * const dpy = wxGetX11Display(); + wxCHECK_RET( dpy, wxT("can't be called before initializing the GUI") ); + + const Atom atomWorkArea = XInternAtom(dpy, "_NET_WORKAREA", True); + if ( atomWorkArea ) + { + long *workareas = NULL; + unsigned long numItems; + unsigned long bytesRemaining; + Atom actualType; + int format; + + if ( XGetWindowProperty + ( + dpy, + XDefaultRootWindow(dpy), + atomWorkArea, + 0, // offset of data to retrieve + 4, // number of items to retrieve + False, // don't delete property + XA_CARDINAL, // type of the items to get + &actualType, + &format, + &numItems, + &bytesRemaining, + (unsigned char **)&workareas + ) == Success && workareas ) + { + wxX11Ptr x11ptr(workareas); // ensure it will be freed + + // check that we retrieved the property of the expected type and + // that we did get back 4 longs (32 is the format for long), as + // requested + if ( actualType != XA_CARDINAL || + format != 32 || + numItems != 4 ) + { + wxLogDebug(wxT("XGetWindowProperty(\"_NET_WORKAREA\") failed")); + return; + } + + if ( x ) + *x = workareas[0]; + if ( y ) + *y = workareas[1]; + if ( width ) + *width = workareas[2]; + if ( height ) + *height = workareas[3]; + + return; + } + } + + // if we get here, _NET_WORKAREA is not supported so return the entire + // screen size as fall back + if (x) + *x = 0; + if (y) + *y = 0; + wxDisplaySize(width, height); +} + +#endif // wxUSE_LIBHILDON/!wxUSE_LIBHILDON