From ef1717a963dfb76bac26b9f4277ae590b3c0a2e6 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Thu, 16 Mar 2006 04:23:07 +0000 Subject: [PATCH] wxDisplay cleanup/rewrite: - wxDisplay is now a concrete class and uses a pImpl-based design - got rid of four duplicate but subtly different versions of trivial single display-only wxDisplay implementation (but 2 versions of Mac Classic and Mac CoreGraphics implementations each still remain...) - assorted code simplifications and memory leaks fixes git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@38127 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/cocoa/display.h | 45 -- include/wx/display.h | 93 +-- include/wx/display_impl.h | 105 +++ include/wx/mac/carbon/display.h | 46 -- include/wx/mac/classic/display.h | 46 -- include/wx/mac/display.h | 5 - include/wx/mgl/chkconf.h | 5 + include/wx/mgl/display.h | 40 -- include/wx/msw/display.h | 51 -- include/wx/os2/chkconf.h | 5 + include/wx/os2/display.h | 44 -- include/wx/palmos/chkconf.h | 3 + include/wx/palmos/display.h | 52 -- include/wx/unix/displayx11.h | 48 -- src/cocoa/display.mm | 136 ++-- src/common/dpycmn.cpp | 226 +++++- src/mac/carbon/display.cpp | 263 ++++--- src/mac/classic/display.cpp | 557 ++++++++------- src/mgl/display.cpp | 99 --- src/msw/display.cpp | 1152 ++++++++++++++++-------------- src/os2/display.cpp | 87 --- src/palmos/display.cpp | 272 ------- src/unix/displayx11.cpp | 236 +++--- 23 files changed, 1641 insertions(+), 1975 deletions(-) delete mode 100644 include/wx/cocoa/display.h create mode 100644 include/wx/display_impl.h delete mode 100644 include/wx/mac/carbon/display.h delete mode 100644 include/wx/mac/classic/display.h delete mode 100644 include/wx/mac/display.h delete mode 100644 include/wx/mgl/display.h delete mode 100644 include/wx/msw/display.h delete mode 100644 include/wx/os2/display.h delete mode 100644 include/wx/palmos/display.h delete mode 100644 include/wx/unix/displayx11.h delete mode 100644 src/mgl/display.cpp delete mode 100644 src/os2/display.cpp delete mode 100644 src/palmos/display.cpp diff --git a/include/wx/cocoa/display.h b/include/wx/cocoa/display.h deleted file mode 100644 index 895d2be527..0000000000 --- a/include/wx/cocoa/display.h +++ /dev/null @@ -1,45 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Name: include/wx/cocoa/display.h -// Purpose: wxDisplay class for wxCocoa -// Author: Ryan Norton -// Modified by: -// Created: 2004-10-03 -// RCS-ID: $Id$ -// Copyright: (c) Ryan Norton -// Licence: wxWindows licence -///////////////////////////////////////////////////////////////////////////// - -#ifndef _WX_COCOA_DISPLAY_H_ -#define _WX_COCOA_DISPLAY_H_ - -#include "wx/object.h" -#include "wx/display.h" - -class wxRect; -class wxString; - -class WXDLLEXPORT wxDisplay : public wxDisplayBase -{ -public: - wxDisplay ( size_t index = 0 ); - - ~wxDisplay(); - - virtual wxRect GetGeometry() const; - virtual int GetDepth() const; - virtual wxString GetName() const; - - virtual wxArrayVideoModes - GetModes(const wxVideoMode& mode = wxDefaultVideoMode) const; - - virtual wxVideoMode GetCurrentMode() const; - - virtual bool ChangeMode(const wxVideoMode& mode = wxDefaultVideoMode); - -private: - struct _CGDirectDisplayID * m_id; - - DECLARE_NO_COPY_CLASS(wxDisplay) -}; - -#endif // _WX_COCOA_DISPLAY_H_ diff --git a/include/wx/display.h b/include/wx/display.h index acf445c8c8..3429258eb6 100644 --- a/include/wx/display.h +++ b/include/wx/display.h @@ -1,37 +1,43 @@ ///////////////////////////////////////////////////////////////////////////// // Name: wx/display.h // Purpose: wxDisplay class -// Author: Royce Mitchell III -// Modified by: Vadim Zeitlin (resolution changes, display modes, ...) +// Author: Royce Mitchell III, Vadim Zeitlin // Created: 06/21/02 // RCS-ID: $Id$ -// Copyright: (c) 2002-2003 wxWidgets team +// Copyright: (c) 2002-2006 wxWidgets team // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// #ifndef _WX_DISPLAY_H_BASE_ #define _WX_DISPLAY_H_BASE_ +// NB: no #if wxUSE_DISPLAY here, the display geometry part of this class (but +// not the video mode stuff) is always available but if wxUSE_DISPLAY == 0 +// it becomes just a trivial wrapper around the old wxDisplayXXX() functions + #if wxUSE_DISPLAY + #include "wx/dynarray.h" + #include "wx/vidmode.h" + + WX_DECLARE_EXPORTED_OBJARRAY(wxVideoMode, wxArrayVideoModes); -#include "wx/dynarray.h" -#include "wx/vidmode.h" + // default, uninitialized, video mode object + extern WXDLLEXPORT_DATA(const wxVideoMode) wxDefaultVideoMode; +#endif // wxUSE_DISPLAY class WXDLLEXPORT wxWindow; class WXDLLEXPORT wxPoint; class WXDLLEXPORT wxRect; class WXDLLEXPORT wxString; -WX_DECLARE_EXPORTED_OBJARRAY(wxVideoMode, wxArrayVideoModes); - -// default, uninitialized, video mode object -extern WXDLLEXPORT_DATA(const wxVideoMode) wxDefaultVideoMode; +class WXDLLEXPORT wxDisplayFactory; +class WXDLLEXPORT wxDisplayImpl; // ---------------------------------------------------------------------------- -// wxDisplayBase: represents a display/monitor attached to the system +// wxDisplay: represents a display/monitor attached to the system // ---------------------------------------------------------------------------- -class WXDLLEXPORT wxDisplayBase +class WXDLLEXPORT wxDisplay { public: // initialize the object containing all information about the given @@ -39,7 +45,12 @@ public: // // the displays are numbered from 0 to GetCount() - 1, 0 is always the // primary display and the only one which is always supported - wxDisplayBase(size_t index = 0); + wxDisplay(size_t n = 0); + + // dtor is not virtual as this is a concrete class not meant to be derived + // from + ~wxDisplay(); + // return the number of available displays, valid parameters to // wxDisplay ctor are from 0 up to this number @@ -55,18 +66,19 @@ public: // return true if the object was initialized successfully - virtual bool IsOk() const { return true; } + bool IsOk() const { return m_impl != NULL; } // get the display size - virtual wxRect GetGeometry() const = 0; + wxRect GetGeometry() const; // name may be empty - virtual wxString GetName() const = 0; + wxString GetName() const; // display 0 is usually the primary display - virtual bool IsPrimary() const { return m_index == 0; } + bool IsPrimary() const; +#if wxUSE_DISPLAY // enumerate all video modes supported by this display matching the given // one (in the sense of wxVideoMode::Match()) // @@ -74,49 +86,40 @@ public: // always at least one video mode supported by display, the returned array // is only empty for the default value of the argument if this function is // not supported at all on this platform - virtual wxArrayVideoModes - GetModes(const wxVideoMode& mode = wxDefaultVideoMode) const = 0; + wxArrayVideoModes + GetModes(const wxVideoMode& mode = wxDefaultVideoMode) const; // get current video mode - virtual wxVideoMode GetCurrentMode() const = 0; + wxVideoMode GetCurrentMode() const; // change current mode, return true if succeeded, false otherwise // // for the default value of the argument restores the video mode to default - virtual bool ChangeMode(const wxVideoMode& mode = wxDefaultVideoMode) = 0; + bool ChangeMode(const wxVideoMode& mode = wxDefaultVideoMode); // restore the default video mode (just a more readable synonym) void ResetMode() { (void)ChangeMode(); } +#endif // wxUSE_DISPLAY - // virtual dtor as for any base class - virtual ~wxDisplayBase() { } +private: + // returns the factory used to implement our static methods and create new + // displays + static wxDisplayFactory& Factory(); -protected: - // the index of this display (0 is always the primary one) - size_t m_index; + // creates the factory object, called by Factory() when it is called for + // the first time and should return a pointer allocated with new (the + // caller will delete it) + // + // this method must be implemented in platform-specific code if + // wxUSE_DISPLAY == 1 (if it is 0 we provide the stub in common code) + static wxDisplayFactory *CreateFactory(); - DECLARE_NO_COPY_CLASS(wxDisplayBase) -}; + // the real implementation + wxDisplayImpl *m_impl; -#if defined(__WXMSW__) - #include "wx/msw/display.h" -#elif defined(__WXMOTIF__) - #include "wx/unix/displayx11.h" -#elif defined(__WXGTK__) - #include "wx/unix/displayx11.h" -#elif defined(__WXX11__) - #include "wx/unix/displayx11.h" -#elif defined(__WXCOCOA__) - #include "wx/cocoa/display.h" -#elif defined(__WXMAC__) - #include "wx/mac/display.h" -#elif defined(__WXPM__) - #include "wx/os2/display.h" -#elif defined(__WXMGL__) - #include "wx/mgl/display.h" -#endif -#endif // wxUSE_DISPLAY + DECLARE_NO_COPY_CLASS(wxDisplay) +}; #endif // _WX_DISPLAY_H_BASE_ diff --git a/include/wx/display_impl.h b/include/wx/display_impl.h new file mode 100644 index 0000000000..aa7e05ff0d --- /dev/null +++ b/include/wx/display_impl.h @@ -0,0 +1,105 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: wx/display_impl.h +// Purpose: wxDisplayImpl class declaration +// Author: Vadim Zeitlin +// Created: 2006-03-15 +// RCS-ID: $Id$ +// Copyright: (c) 2002-2006 Vadim Zeitlin +// Licence: wxWindows licence +///////////////////////////////////////////////////////////////////////////// + +#ifndef _WX_DISPLAY_IMPL_H_BASE_ +#define _WX_DISPLAY_IMPL_H_BASE_ + +// ---------------------------------------------------------------------------- +// wxDisplayFactory: allows to create wxDisplay objects +// ---------------------------------------------------------------------------- + +class WXDLLEXPORT wxDisplayFactory +{ +public: + wxDisplayFactory() { } + virtual ~wxDisplayFactory() { } + + // create a new display object + // + // it can return a NULL pointer if the display creation failed + virtual wxDisplayImpl *CreateDisplay(size_t n) = 0; + + // get the total number of displays + virtual size_t GetCount() = 0; + + // return the display for the given point or wxNOT_FOUND + virtual int GetFromPoint(const wxPoint& pt) = 0; + + // return the display for the given window or wxNOT_FOUND + // + // the window pointer must not be NULL (i.e. caller should check it) + virtual int GetFromWindow(wxWindow *window); +}; + +// ---------------------------------------------------------------------------- +// wxDisplayImpl: base class for all wxDisplay implementations +// ---------------------------------------------------------------------------- + +class WXDLLEXPORT wxDisplayImpl +{ +public: + // virtual dtor for this base class + virtual ~wxDisplayImpl() { } + + + // return the full area of this display + virtual wxRect GetGeometry() const = 0; + + // return the name (may be empty) + virtual wxString GetName() const = 0; + + // return the index of this display + size_t GetIndex() const { return m_index; } + + // return true if this is the primary monitor (usually one with index 0) + virtual bool IsPrimary() const { return GetIndex() == 0; } + + +#if wxUSE_DISPLAY + // implements wxDisplay::GetModes() + virtual wxArrayVideoModes GetModes(const wxVideoMode& mode) const = 0; + + // get current video mode + virtual wxVideoMode GetCurrentMode() const = 0; + + // change current mode, return true if succeeded, false otherwise + virtual bool ChangeMode(const wxVideoMode& mode) = 0; +#endif // wxUSE_DISPLAY + +protected: + // create the object providing access to the display with the given index + wxDisplayImpl(size_t n) : m_index(n) { } + + + // the index of this display (0 is always the primary one) + const size_t m_index; + + + friend class wxDisplayFactory; + + DECLARE_NO_COPY_CLASS(wxDisplayImpl) +}; + +// ---------------------------------------------------------------------------- +// wxDisplayFactorySingle +// ---------------------------------------------------------------------------- + +// this is a stub implementation using single/main display only, it is +// available even if wxUSE_DISPLAY == 0 +class WXDLLEXPORT wxDisplayFactorySingle : public wxDisplayFactory +{ +public: + virtual wxDisplayImpl *CreateDisplay(size_t n); + virtual size_t GetCount() { return 1; } + virtual int GetFromPoint(const wxPoint& pt); +}; + +#endif // _WX_DISPLAY_IMPL_H_BASE_ + diff --git a/include/wx/mac/carbon/display.h b/include/wx/mac/carbon/display.h deleted file mode 100644 index 223e3c3281..0000000000 --- a/include/wx/mac/carbon/display.h +++ /dev/null @@ -1,46 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Name: display.h -// Purpose: wxDisplay class customization for Mac -// Author: Brian Victor/Royce Mitchel for non OSX / Ryan Norton for OS X -// Modified by: -// Created: 06/21/02 -// RCS-ID: $Id$ -// Copyright: (c) wxWidgets team -// Licence: wxWindows licence -///////////////////////////////////////////////////////////////////////////// - -#ifndef _WX_MAC_DISPLAY_H_ -#define _WX_MAC_DISPLAY_H_ - -#include "wx/object.h" -#include "wx/display.h" - -class wxDisplayMacPriv; -class wxRect; -class wxString; - -class WXDLLEXPORT wxDisplay : public wxDisplayBase -{ -public: - wxDisplay ( size_t index = 0 ); - - ~wxDisplay(); - - virtual wxRect GetGeometry() const; - virtual int GetDepth() const; - virtual wxString GetName() const; - - virtual wxArrayVideoModes - GetModes(const wxVideoMode& mode = wxDefaultVideoMode) const; - - virtual wxVideoMode GetCurrentMode() const; - - virtual bool ChangeMode(const wxVideoMode& mode = wxDefaultVideoMode); - -private: - wxDisplayMacPriv* m_priv; - - DECLARE_NO_COPY_CLASS(wxDisplay) -}; - -#endif // _WX_MAC_DISPLAY_H_ diff --git a/include/wx/mac/classic/display.h b/include/wx/mac/classic/display.h deleted file mode 100644 index 5ea137e324..0000000000 --- a/include/wx/mac/classic/display.h +++ /dev/null @@ -1,46 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Name: display.h -// Purpose: wxDisplay class customization for Mac -// Author: Brian Victor -// Modified by: Royce Mitchell III -// Created: 06/21/02 -// RCS-ID: $Id$ -// Copyright: (c) wxWidgets team -// Licence: wxWindows licence -///////////////////////////////////////////////////////////////////////////// - -#ifndef _WX_MAC_DISPLAY_H_ -#define _WX_MAC_DISPLAY_H_ - -#include "wx/object.h" -#include "wx/display.h" - -class wxDisplayMacPriv; -class wxRect; -class wxString; - -class WXDLLEXPORT wxDisplay : public wxDisplayBase -{ -public: - wxDisplay ( size_t index = 0 ); - - ~wxDisplay(); - - virtual wxRect GetGeometry() const; - virtual int GetDepth() const; - virtual wxString GetName() const; - - virtual wxArrayVideoModes - GetModes(const wxVideoMode& mode = wxDefaultVideoMode) const; - - virtual wxVideoMode GetCurrentMode() const; - - virtual bool ChangeMode(const wxVideoMode& mode = wxDefaultVideoMode); - -private: - wxDisplayMacPriv* m_priv; - - DECLARE_NO_COPY_CLASS(wxDisplay) -}; - -#endif // _WX_MAC_DISPLAY_H_ diff --git a/include/wx/mac/display.h b/include/wx/mac/display.h deleted file mode 100644 index 4347bb2797..0000000000 --- a/include/wx/mac/display.h +++ /dev/null @@ -1,5 +0,0 @@ -#ifdef __WXMAC_CLASSIC__ -#include "wx/mac/classic/display.h" -#else -#include "wx/mac/carbon/display.h" -#endif \ No newline at end of file diff --git a/include/wx/mgl/chkconf.h b/include/wx/mgl/chkconf.h index 643aafdc64..ab3271487f 100644 --- a/include/wx/mgl/chkconf.h +++ b/include/wx/mgl/chkconf.h @@ -56,6 +56,11 @@ # define wxUSE_CLIPBOARD 0 #endif /* wxUSE_CLIPBOARD */ +#if wxUSE_DISPLAY +# undef wxUSE_DISPLAY +# define wxUSE_DISPLAY 0 +#endif /* wxUSE_DISPLAY */ + #if wxUSE_SOCKETS # undef wxUSE_SOCKETS # define wxUSE_SOCKETS 0 diff --git a/include/wx/mgl/display.h b/include/wx/mgl/display.h deleted file mode 100644 index 9cb21982aa..0000000000 --- a/include/wx/mgl/display.h +++ /dev/null @@ -1,40 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Name: wx/mgl/display.h -// Purpose: wxDisplay class customization for WXMGL -// Author: Wlodzimierz ABX Skiba -// Modified by: -// Created: 05/03/2006 -// RCS-ID: $Id$ -// Copyright: (c) Wlodzimierz Skiba -// Licence: wxWindows licence -///////////////////////////////////////////////////////////////////////////// - -#ifndef _WX_MGL_DISPLAY_H_ -#define _WX_MGL_DISPLAY_H_ - -class WXDLLEXPORT wxDisplay : public wxDisplayBase -{ -public: - - // create the display object for the given physical display - wxDisplay(size_t index = 0); - - virtual ~wxDisplay(); - - // implement base class pure virtuals - virtual bool IsOk() const; - virtual wxRect GetGeometry() const; - virtual wxString GetName() const; - - virtual wxArrayVideoModes GetModes(const wxVideoMode& mode = wxDefaultVideoMode) const; - virtual wxVideoMode GetCurrentMode() const; - virtual bool ChangeMode(const wxVideoMode& mode = wxDefaultVideoMode); - - virtual bool IsPrimary() const; - -private: - - DECLARE_NO_COPY_CLASS(wxDisplay) -}; - -#endif // _WX_MGL_DISPLAY_H_ diff --git a/include/wx/msw/display.h b/include/wx/msw/display.h deleted file mode 100644 index d261e7404c..0000000000 --- a/include/wx/msw/display.h +++ /dev/null @@ -1,51 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Name: display.h -// Purpose: wxDisplay class customization for WXMSW -// Author: Royce Mitchell III -// Modified by: -// Created: 06/21/02 -// RCS-ID: $Id$ -// Copyright: (c) wxWidgets team -// Licence: wxWindows licence -///////////////////////////////////////////////////////////////////////////// - -#ifndef _WX_MSW_DISPLAY_H_ -#define _WX_MSW_DISPLAY_H_ - -class WXDLLEXPORT wxDisplay : public wxDisplayBase -{ -public: - // this function may be called *before* using any other wxDisplay methods - // to tell it to use DirectX functions instead of the standard Windows ones - static void UseDirectX(bool useDX); - - // create the display object for the given physical display - wxDisplay(size_t index = 0); - - virtual ~wxDisplay(); - - // implement base class pure virtuals - virtual bool IsOk() const; - virtual wxRect GetGeometry() const; - virtual wxString GetName() const; - - virtual wxArrayVideoModes - GetModes(const wxVideoMode& mode = wxVideoMode()) const; - virtual wxVideoMode GetCurrentMode() const; - virtual bool ChangeMode(const wxVideoMode& mode = wxVideoMode()); - - virtual bool IsPrimary() const; - -private: - // we have different implementations using DirectDraw and without it - wxArrayVideoModes DoGetModesDirectX(const wxVideoMode& modeMatch) const; - bool DoChangeModeDirectX(const wxVideoMode& mode); - - wxArrayVideoModes DoGetModesWindows(const wxVideoMode& modeMatch) const; - bool DoChangeModeWindows(const wxVideoMode& mode); - - - DECLARE_NO_COPY_CLASS(wxDisplay) -}; - -#endif // _WX_MSW_DISPLAY_H_ diff --git a/include/wx/os2/chkconf.h b/include/wx/os2/chkconf.h index ea0ac4db7a..924d2f0d45 100644 --- a/include/wx/os2/chkconf.h +++ b/include/wx/os2/chkconf.h @@ -21,6 +21,11 @@ to disable here features not supported currently or enable features required */ +#if wxUSE_DISPLAY +# undef wxUSE_DISPLAY +# define wxUSE_DISPLAY 0 +#endif /* wxUSE_DISPLAY */ + #if wxUSE_STACKWALKER # undef wxUSE_STACKWALKER # define wxUSE_STACKWALKER 0 diff --git a/include/wx/os2/display.h b/include/wx/os2/display.h deleted file mode 100644 index 1fb88ccafa..0000000000 --- a/include/wx/os2/display.h +++ /dev/null @@ -1,44 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Name: displayx11.h -// Purpose: wxDisplay class for Unix/X11 -// Author: Brian Victor -// Modified by: -// Created: 12/05/02 -// RCS-ID: $Id$ -// Copyright: (c) wxWidgets team -// Licence: wxWindows licence -///////////////////////////////////////////////////////////////////////////// - -#ifndef _WX_DISPLAY_H_ -#define _WX_DISPLAY_H_ - -#if wxUSE_DISPLAY - -class wxRect; -class wxString; -class wxDisplayUnixPriv; - -class WXDLLEXPORT wxDisplay : public wxDisplayBase -{ - - public: - wxDisplay (size_t index = 0); - ~wxDisplay(); - - virtual wxRect GetGeometry() const; - virtual int GetDepth() const; - virtual wxString GetName() const; - virtual wxArrayVideoModes GetModes(const wxVideoMode& mode = wxDefaultVideoMode) const; - virtual wxVideoMode GetCurrentMode() const; - - virtual bool ChangeMode(const wxVideoMode& mode = wxDefaultVideoMode); - - - private: - DECLARE_NO_COPY_CLASS(wxDisplay) -}; - -#endif // wxUSE_DISPLAY - -#endif // _WX_DISPLAY_H_ - diff --git a/include/wx/palmos/chkconf.h b/include/wx/palmos/chkconf.h index 141f964529..c2ca4c7b92 100644 --- a/include/wx/palmos/chkconf.h +++ b/include/wx/palmos/chkconf.h @@ -52,6 +52,9 @@ #undef wxUSE_CLIPBOARD #define wxUSE_CLIPBOARD 0 +#undef wxUSE_DISPLAY +#define wxUSE_DISPLAY 0 + #undef wxUSE_COMBOBOX #define wxUSE_COMBOBOX 0 diff --git a/include/wx/palmos/display.h b/include/wx/palmos/display.h deleted file mode 100644 index 13bafd562d..0000000000 --- a/include/wx/palmos/display.h +++ /dev/null @@ -1,52 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Name: wx/palmos/display.h -// Purpose: wxDisplay class customization for Palm OS -// Author: William Osborne - minimal working wxPalmOS port -// Modified by: -// Created: 10/13/04 -// RCS-ID: $Id$ -// Copyright: (c) William Osborne -// Licence: wxWindows licence -///////////////////////////////////////////////////////////////////////////// - -#ifndef _WX_PALMOS_DISPLAY_H_ -#define _WX_PALMOS_DISPLAY_H_ - -class WXDLLEXPORT wxDisplay : public wxDisplayBase -{ -public: - // this function may be called *before* using any other wxDisplay methods - // to tell it to use DirectX functions instead of the standard Windows ones - static void UseDirectX(bool useDX); - - // create the display object for the given physical display - wxDisplay(size_t index = 0); - - virtual ~wxDisplay(); - - // implement base class pure virtuals - virtual bool IsOk() const; - virtual wxRect GetGeometry() const; - virtual wxString GetName() const; - - virtual wxArrayVideoModes - GetModes(const wxVideoMode& mode = wxVideoMode()) const; - virtual wxVideoMode GetCurrentMode() const; - virtual bool ChangeMode(const wxVideoMode& mode = wxVideoMode()); - -private: - // get the display name to use with EnumDisplaySettings() - wxString GetNameForEnumSettings() const; - - // we have different implementations using DirectDraw and without it - wxArrayVideoModes DoGetModesDirectX(const wxVideoMode& modeMatch) const; - bool DoChangeModeDirectX(const wxVideoMode& mode); - - wxArrayVideoModes DoGetModesWindows(const wxVideoMode& modeMatch) const; - bool DoChangeModeWindows(const wxVideoMode& mode); - - - DECLARE_NO_COPY_CLASS(wxDisplay) -}; - -#endif // _WX_PALMOS_DISPLAY_H_ diff --git a/include/wx/unix/displayx11.h b/include/wx/unix/displayx11.h deleted file mode 100644 index da642361e2..0000000000 --- a/include/wx/unix/displayx11.h +++ /dev/null @@ -1,48 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Name: displayx11.h -// Purpose: wxDisplay class for Unix/X11 -// Author: Brian Victor -// Modified by: -// Created: 12/05/02 -// RCS-ID: $Id$ -// Copyright: (c) wxWidgets team -// Licence: wxWindows licence -///////////////////////////////////////////////////////////////////////////// - -#ifndef _WX_DISPLAYX11_H_ -#define _WX_DISPLAYX11_H_ - -#if wxUSE_DISPLAY - -class wxRect; -class wxString; -class wxDisplayUnixPriv; - -class WXDLLEXPORT wxDisplay : public wxDisplayBase -{ - - public: - wxDisplay ( size_t index = 0 ); - - virtual wxRect GetGeometry() const; - virtual int GetDepth() const; - virtual wxString GetName() const; - virtual wxArrayVideoModes - GetModes(const wxVideoMode& mode = wxDefaultVideoMode) const; - - virtual wxVideoMode GetCurrentMode() const; - - virtual bool ChangeMode(const wxVideoMode& mode = wxDefaultVideoMode); - - ~wxDisplay(); - - private: - wxDisplayUnixPriv *m_priv; - - DECLARE_NO_COPY_CLASS(wxDisplay) -}; - -#endif // wxUSE_DISPLAY - -#endif // _WX_GTK_DISPLAY_H_ - diff --git a/src/cocoa/display.mm b/src/cocoa/display.mm index 0d39a028a4..d5bd1dbeba 100644 --- a/src/cocoa/display.mm +++ b/src/cocoa/display.mm @@ -2,7 +2,7 @@ // Name: src/cocoa/display.mm // Purpose: Cocoa implementation of wxDisplay class // Author: Ryan Norton -// Modified by: +// Modified by: // Created: 2004-10-03 // RCS-ID: $Id$ // Copyright: (c) Ryan Norton @@ -23,36 +23,74 @@ #endif #include "wx/display.h" +#include "wx/display_impl.h" #include "wx/gdicmn.h" #include "wx/string.h" #import // ---------------------------------------------------------------------------- -// private classes +// display classes implementation // ---------------------------------------------------------------------------- -size_t wxDisplayBase::GetCount() +class wxDisplayImplMacOSX : public wxDisplayImpl +{ +public: + wxDisplayImplMacOSX(CGDirectDisplayID id_) : m_id(id_) { } + + virtual wxRect GetGeometry() const; + virtual wxString GetName() const { return wxString(); } + + virtual wxArrayVideoModes GetModes(const wxVideoMode& mode) const; + virtual wxVideoMode GetCurrentMode() const; + virtual bool ChangeMode(const wxVideoMode& mode); + +private: + CGDirectDisplayID m_id; + + DECLARE_NO_COPY_CLASS(wxDisplayImplMacOSX) +}; + +class wxDisplayFactoryMacOSX : public wxDisplayFactory +{ +public: + wxDisplayFactoryMacOSX(); + + virtual wxDisplayImpl *CreateDisplay(size_t n); + virtual size_t GetCount(); + virtual int GetFromPoint(const wxPoint& pt); + +protected: + DECLARE_NO_COPY_CLASS(wxDisplayFactoryMacOSX) +}; + +// ============================================================================ +// wxDisplayFactoryMacOSX implementation +// ============================================================================ + +size_t wxDisplayFactoryMacOSX::GetCount() { CGDisplayCount count; #ifdef __WXDEBUG__ - CGDisplayErr err = + CGDisplayErr err = #endif CGGetActiveDisplayList(0, NULL, &count); wxASSERT(err == CGDisplayNoErr); + return count; } -int wxDisplayBase::GetFromPoint(const wxPoint &p) -{ +int wxDisplayFactoryMacOSX::GetFromPoint(const wxPoint& p) +{ CGPoint thePoint = {(float)p.x, (float)p.y}; CGDirectDisplayID theID; CGDisplayCount theCount; CGDisplayErr err = CGGetDisplaysWithPoint(thePoint, 1, &theID, &theCount); wxASSERT(err == CGDisplayNoErr); - int nWhich = -1; - + + int nWhich = wxNOT_FOUND; + if (theCount) { theCount = GetCount(); @@ -60,61 +98,54 @@ int wxDisplayBase::GetFromPoint(const wxPoint &p) err = CGGetActiveDisplayList(theCount, theIDs, &theCount); wxASSERT(err == CGDisplayNoErr); - for(nWhich = 0; nWhich < (int) theCount; ++nWhich) + for (nWhich = 0; nWhich < (int) theCount; ++nWhich) { - if(theIDs[nWhich] == theID) + if (theIDs[nWhich] == theID) break; } - - delete[] theIDs; - - if(nWhich == (int) theCount) + + delete [] theIDs; + + if (nWhich == (int) theCount) { wxFAIL_MSG(wxT("Failed to find display in display list")); - nWhich = -1; + nWhich = wxNOT_FOUND; } } - + return nWhich; -}//CFUserNotification[NSBundle bundleForClass:[self class]] +} -wxDisplay::wxDisplay(size_t index) : wxDisplayBase ( index ) +wxDisplayImpl *wxDisplayFactoryMacOSX::CreateDisplay(size_t n) { CGDisplayCount theCount = GetCount(); CGDirectDisplayID* theIDs = new CGDirectDisplayID[theCount]; + #ifdef __WXDEBUG__ - CGDisplayErr err = + CGDisplayErr err = #endif CGGetActiveDisplayList(theCount, theIDs, &theCount); - wxASSERT(err == CGDisplayNoErr); - wxASSERT(index < theCount); - - m_id = theIDs[index]; - - delete[] theIDs; + wxASSERT( err == CGDisplayNoErr ); + wxASSERT( n < theCount ); + + wxDisplayImplMacOSX *display = new wxDisplayImplMacOSX(theIDs[n]); + + delete [] theIDs; + + return display; } -wxRect wxDisplay::GetGeometry() const + +wxRect wxDisplayImplMacOSX::GetGeometry() const { CGRect theRect = CGDisplayBounds(m_id); - return wxRect( (int)theRect.origin.x, + return wxRect( (int)theRect.origin.x, (int)theRect.origin.y, (int)theRect.size.width, (int)theRect.size.height ); //floats } -int wxDisplay::GetDepth() const -{ - return (int) CGDisplayBitsPerPixel(m_id); //size_t -} - -wxString wxDisplay::GetName() const -{ - // Macs don't name their displays... - return wxEmptyString; -} - static int wxCFDictKeyToInt( CFDictionaryRef desc, CFStringRef key ) { CFNumberRef value; @@ -126,40 +157,39 @@ static int wxCFDictKeyToInt( CFDictionaryRef desc, CFStringRef key ) return num; } -wxArrayVideoModes - wxDisplay::GetModes(const wxVideoMode& mode) const +wxArrayVideoModes wxDisplayImplMacOSX::GetModes(const wxVideoMode& mode) const { wxArrayVideoModes Modes; - + CFArrayRef theArray = CGDisplayAvailableModes(m_id); for(CFIndex i = 0; i < CFArrayGetCount(theArray); ++i) { CFDictionaryRef theValue = (CFDictionaryRef) CFArrayGetValueAtIndex(theArray, i); - + wxVideoMode theMode(wxCFDictKeyToInt(theValue, kCGDisplayWidth), wxCFDictKeyToInt(theValue, kCGDisplayHeight), wxCFDictKeyToInt(theValue, kCGDisplayBitsPerPixel), wxCFDictKeyToInt(theValue, kCGDisplayRefreshRate)); - + if (theMode.Matches(mode)) Modes.Add(theMode); } - + return Modes; } -wxVideoMode wxDisplay::GetCurrentMode() const +wxVideoMode wxDisplayImplMacOSX::GetCurrentMode() const { CFDictionaryRef theValue = CGDisplayCurrentMode (m_id); - + return wxVideoMode(wxCFDictKeyToInt(theValue, kCGDisplayWidth), wxCFDictKeyToInt(theValue, kCGDisplayHeight), wxCFDictKeyToInt(theValue, kCGDisplayBitsPerPixel), wxCFDictKeyToInt(theValue, kCGDisplayRefreshRate)); } -bool wxDisplay::ChangeMode(const wxVideoMode& mode) +bool wxDisplayImplMacOSX::ChangeMode(const wxVideoMode& mode) { //Changing to default mode (wxDefualtVideoMode) doesn't //work because we don't have access to the system's 'scrn' @@ -173,17 +203,23 @@ bool wxDisplay::ChangeMode(const wxVideoMode& mode) (size_t)mode.h, (double)mode.refresh, &bExactMatch); - + bool bOK = bExactMatch; - + if(bOK) bOK = CGDisplaySwitchToMode(m_id, theCGMode) == CGDisplayNoErr; return bOK; } -wxDisplay::~wxDisplay() +// ============================================================================ +// wxDisplay::CreateFactory() +// ============================================================================ + +/* static */ wxDisplayFactory *wxDisplay::CreateFactory() { + return new wxDisplayFactoryMac; } #endif // wxUSE_DISPLAY + diff --git a/src/common/dpycmn.cpp b/src/common/dpycmn.cpp index 6527fc64de..b30084f099 100644 --- a/src/common/dpycmn.cpp +++ b/src/common/dpycmn.cpp @@ -1,11 +1,11 @@ /////////////////////////////////////////////////////////////////////////////// // Name: src/common/dpycmn.cpp -// Purpose: wxDisplayBase implementation +// Purpose: wxDisplay and wxDisplayImplSingle implementation // Author: Vadim Zeitlin // Modified by: // Created: 01.03.03 // RCS-ID: $Id$ -// Copyright: (c) 2003 Vadim Zeitlin +// Copyright: (c) 2003-2006 Vadim Zeitlin // License: wxWindows licence /////////////////////////////////////////////////////////////////////////////// @@ -24,43 +24,239 @@ #pragma hdrstop #endif -#if wxUSE_DISPLAY - #ifndef WX_PRECOMP #include "wx/gdicmn.h" #include "wx/window.h" #endif //WX_PRECOMP #include "wx/display.h" +#include "wx/display_impl.h" +#include "wx/module.h" +#include "wx/gdicmn.h" // for wxDisplaySize() + +#if wxUSE_DISPLAY #include "wx/arrimpl.cpp" WX_DEFINE_OBJARRAY(wxArrayVideoModes) const wxVideoMode wxDefaultVideoMode; +#endif // wxUSE_DISPLAY + +// ---------------------------------------------------------------------------- +// globals +// ---------------------------------------------------------------------------- + +// the factory object used by wxDisplay +// +// created on demand and destroyed by wxDisplayModule +static wxDisplayFactory *gs_factory = NULL; + +// ---------------------------------------------------------------------------- +// wxDisplayImplSingle: trivial implementation working for main display only +// ---------------------------------------------------------------------------- + +class WXDLLEXPORT wxDisplayImplSingle : public wxDisplayImpl +{ +public: + wxDisplayImplSingle() : wxDisplayImpl(0) { } + + virtual wxRect GetGeometry() const + { + wxRect r; + wxDisplaySize(&r.width, &r.height); + return r; + } + + virtual wxString GetName() const { return wxString(); } + +#if wxUSE_DISPLAY + // no video modes support for us, provide just the stubs + + virtual wxArrayVideoModes GetModes(const wxVideoMode& WXUNUSED(mode)) const + { + return wxArrayVideoModes(); + } + + virtual wxVideoMode GetCurrentMode() const { return wxVideoMode(); } + + virtual bool ChangeMode(const wxVideoMode& WXUNUSED(mode)) { return false; } +#endif // wxUSE_DISPLAY + + + DECLARE_NO_COPY_CLASS(wxDisplayImplSingle) +}; + +// ---------------------------------------------------------------------------- +// wxDisplayModule is used to cleanup gs_factory +// ---------------------------------------------------------------------------- + +class wxDisplayModule : public wxModule +{ +public: + virtual bool OnInit() { return true; } + virtual void OnExit() + { + if ( gs_factory ) + { + delete gs_factory; + gs_factory = NULL; + } + } + + DECLARE_DYNAMIC_CLASS(wxDisplayModule) +}; + +IMPLEMENT_DYNAMIC_CLASS(wxDisplayModule, wxModule) + // ============================================================================ -// implementation +// wxDisplay implementation // ============================================================================ -wxDisplayBase::wxDisplayBase(size_t index) - : m_index (index) +// ---------------------------------------------------------------------------- +// ctor/dtor +// ---------------------------------------------------------------------------- + +wxDisplay::wxDisplay(size_t n) { - wxASSERT_MSG( m_index < GetCount(), + wxASSERT_MSG( n < GetCount(), wxT("An invalid index was passed to wxDisplay") ); + + m_impl = Factory().CreateDisplay(n); +} + +wxDisplay::~wxDisplay() +{ + delete m_impl; +} + +// ---------------------------------------------------------------------------- +// static functions forwarded to wxDisplayFactory +// ---------------------------------------------------------------------------- + +/* static */ size_t wxDisplay::GetCount() +{ + return Factory().GetCount(); } -// MSW has its own specific implementation of this -#ifndef __WXMSW__ +/* static */ int wxDisplay::GetFromPoint(const wxPoint& pt) +{ + return Factory().GetFromPoint(pt); +} -int wxDisplayBase::GetFromWindow(wxWindow *window) +/* static */ int wxDisplay::GetFromWindow(wxWindow *window) { - wxCHECK_MSG( window, wxNOT_FOUND, _T("NULL window") ); + wxCHECK_MSG( window, wxNOT_FOUND, _T("invalid window") ); - // consider that the window belong to the display containing its centre + return Factory().GetFromWindow(window); +} + +// ---------------------------------------------------------------------------- +// functions forwarded to wxDisplayImpl +// ---------------------------------------------------------------------------- + +wxRect wxDisplay::GetGeometry() const +{ + wxCHECK_MSG( IsOk(), wxRect(), _T("invalid wxDisplay object") ); + + return m_impl->GetGeometry(); +} + +wxString wxDisplay::GetName() const +{ + wxCHECK_MSG( IsOk(), wxString(), _T("invalid wxDisplay object") ); + + return m_impl->GetName(); +} + +bool wxDisplay::IsPrimary() const +{ + return m_impl && m_impl->GetIndex() == 0; +} + +#if wxUSE_DISPLAY + +wxArrayVideoModes wxDisplay::GetModes(const wxVideoMode& mode) const +{ + wxCHECK_MSG( IsOk(), wxArrayVideoModes(), _T("invalid wxDisplay object") ); + + return m_impl->GetModes(mode); +} + +wxVideoMode wxDisplay::GetCurrentMode() const +{ + wxCHECK_MSG( IsOk(), wxVideoMode(), _T("invalid wxDisplay object") ); + + return m_impl->GetCurrentMode(); +} + +bool wxDisplay::ChangeMode(const wxVideoMode& mode) +{ + wxCHECK_MSG( IsOk(), false, _T("invalid wxDisplay object") ); + + return m_impl->ChangeMode(mode); +} + +#endif // wxUSE_DIRECTDRAW + +// ---------------------------------------------------------------------------- +// static functions implementation +// ---------------------------------------------------------------------------- + +// if wxUSE_DISPLAY == 1 this is implemented in port-specific code +#if !wxUSE_DISPLAY + +/* static */ wxDisplayFactory *wxDisplay::CreateFactory() +{ + return new wxDisplayFactorySingle; +} + +#endif // !wxUSE_DISPLAY + +/* static */ wxDisplayFactory& wxDisplay::Factory() +{ + if ( !gs_factory ) + { + gs_factory = CreateFactory(); + } + + return *gs_factory; +} + +// ============================================================================ +// wxDisplayFactory implementation +// ============================================================================ + +int wxDisplayFactory::GetFromWindow(wxWindow *window) +{ + // consider that the window belongs to the display containing its centre const wxRect r(window->GetRect()); return GetFromPoint(wxPoint(r.x + r.width/2, r.y + r.height/2)); } -#endif // !__WXMSW__ +// ============================================================================ +// wxDisplayFactorySingle implementation +// ============================================================================ + +/* static */ +wxDisplayImpl *wxDisplayFactorySingle::CreateDisplay(size_t n) +{ + // we recognize the main display only + return n != 0 ? NULL : new wxDisplayImplSingle; +} + +int wxDisplayFactorySingle::GetFromPoint(const wxPoint& pt) +{ + if ( pt.x >= 0 && pt.y >= 0 ) + { + int w, h; + wxDisplaySize(&w, &h); + + if ( pt.x < w && pt.y < h ) + return 0; + } + + // the point is outside of the screen + return wxNOT_FOUND; +} -#endif // wxUSE_DISPLAY diff --git a/src/mac/carbon/display.cpp b/src/mac/carbon/display.cpp index 7b6eb4ef42..79c727f1f1 100644 --- a/src/mac/carbon/display.cpp +++ b/src/mac/carbon/display.cpp @@ -1,14 +1,22 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: display.cpp +// Name: src/mac/carbon/display.cpp // Purpose: Mac implementation of wxDisplay class // Author: Ryan Norton & Brian Victor -// Modified by: Royce Mitchell III +// Modified by: Royce Mitchell III, Vadim Zeitlin // Created: 06/21/02 // RCS-ID: $Id$ // Copyright: (c) wxWidgets team // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// +// ============================================================================ +// declarations +// ============================================================================ + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- + #include "wx/wxprec.h" #ifdef __BORLANDC__ @@ -20,7 +28,6 @@ #ifndef WX_PRECOMP #include "wx/dynarray.h" #include "wx/log.h" - #include "wx/msgdlg.h" #endif #ifdef __DARWIN__ @@ -35,32 +42,65 @@ #endif #include "wx/display.h" +#include "wx/display_impl.h" #include "wx/gdicmn.h" #include "wx/string.h" // ---------------------------------------------------------------------------- -// private classes +// display classes implementation // ---------------------------------------------------------------------------- #ifdef __WXMAC_OSX__ -class wxDisplayMacPriv +class wxDisplayImplMacOSX : public wxDisplayImpl { public: + wxDisplayImplMacOSX(CGDirectDisplayID id) : m_id(id) { } + + virtual wxRect GetGeometry() const; + virtual wxString GetName() const { return wxString(); } + + virtual wxArrayVideoModes GetModes(const wxVideoMode& mode) const; + virtual wxVideoMode GetCurrentMode() const; + virtual bool ChangeMode(const wxVideoMode& mode); + +private: CGDirectDisplayID m_id; + + DECLARE_NO_COPY_CLASS(wxDisplayImplMacOSX) }; -size_t wxDisplayBase::GetCount() +class wxDisplayFactoryMacOSX : public wxDisplayFactory +{ +public: + wxDisplayFactoryMacOSX(); + + virtual wxDisplayImpl *CreateDisplay(size_t n); + virtual size_t GetCount(); + virtual int GetFromPoint(const wxPoint& pt); + +protected: + DECLARE_NO_COPY_CLASS(wxDisplayFactoryMacOSX) +}; + +// ============================================================================ +// wxDisplayFactoryMacOSX implementation +// ============================================================================ + +size_t wxDisplayFactoryMacOSX::GetCount() { CGDisplayCount count; - CGDisplayErr err = CGGetActiveDisplayList(0, NULL, &count); +#ifdef __WXDEBUG__ + CGDisplayErr err = +#endif + CGGetActiveDisplayList(0, NULL, &count); wxASSERT(err == CGDisplayNoErr); return count; } -int wxDisplayBase::GetFromPoint(const wxPoint &p) +int wxDisplayFactoryMacOSX::GetFromPoint(const wxPoint& p) { CGPoint thePoint = {(float)p.x, (float)p.y}; CGDirectDisplayID theID; @@ -68,7 +108,7 @@ int wxDisplayBase::GetFromPoint(const wxPoint &p) CGDisplayErr err = CGGetDisplaysWithPoint(thePoint, 1, &theID, &theCount); wxASSERT(err == CGDisplayNoErr); - int nWhich = -1; + int nWhich = wxNOT_FOUND; if (theCount) { @@ -88,50 +128,46 @@ int wxDisplayBase::GetFromPoint(const wxPoint &p) if (nWhich == (int) theCount) { wxFAIL_MSG(wxT("Failed to find display in display list")); - nWhich = -1; + nWhich = wxNOT_FOUND; } } return nWhich; } -wxDisplay::wxDisplay(size_t index) - : wxDisplayBase( index ) , - m_priv( new wxDisplayMacPriv() ) +wxDisplayImpl *wxDisplayFactoryMacOSX::CreateDisplay(size_t n) { CGDisplayCount theCount = GetCount(); CGDirectDisplayID* theIDs = new CGDirectDisplayID[theCount]; - CGDisplayErr err = CGGetActiveDisplayList(theCount, theIDs, &theCount); +#ifdef __WXDEBUG__ + CGDisplayErr err = +#endif + CGGetActiveDisplayList(theCount, theIDs, &theCount); wxASSERT( err == CGDisplayNoErr ); - wxASSERT( index < theCount ); + wxASSERT( n < theCount ); - m_priv->m_id = theIDs[index]; + wxDisplayImplMacOSX *display = new wxDisplayImplMacOSX(theIDs[n]); delete [] theIDs; + + return display; } -wxRect wxDisplay::GetGeometry() const +// ============================================================================ +// wxDisplayImplMacOSX implementation +// ============================================================================ + +wxRect wxDisplayImplMacOSX::GetGeometry() const { - CGRect theRect = CGDisplayBounds(m_priv->m_id); + CGRect theRect = CGDisplayBounds(m_id); return wxRect( (int)theRect.origin.x, (int)theRect.origin.y, (int)theRect.size.width, (int)theRect.size.height ); //floats } -int wxDisplay::GetDepth() const -{ - return (int) CGDisplayBitsPerPixel( m_priv->m_id ); //size_t -} - -wxString wxDisplay::GetName() const -{ - // Macs don't name their displays... - return wxEmptyString; -} - static int wxCFDictKeyToInt( CFDictionaryRef desc, CFStringRef key ) { CFNumberRef value = (CFNumberRef) CFDictionaryGetValue( desc, key ); @@ -144,12 +180,11 @@ static int wxCFDictKeyToInt( CFDictionaryRef desc, CFStringRef key ) return num; } -wxArrayVideoModes - wxDisplay::GetModes(const wxVideoMode& mode) const +wxArrayVideoModes wxDisplayImplMacOSX::GetModes(const wxVideoMode& mode) const { wxArrayVideoModes resultModes; - CFArrayRef theArray = CGDisplayAvailableModes( m_priv->m_id ); + CFArrayRef theArray = CGDisplayAvailableModes( m_id ); for (CFIndex i = 0; i < CFArrayGetCount(theArray); ++i) { @@ -168,9 +203,9 @@ wxArrayVideoModes return resultModes; } -wxVideoMode wxDisplay::GetCurrentMode() const +wxVideoMode wxDisplayImplMacOSX::GetCurrentMode() const { - CFDictionaryRef theValue = CGDisplayCurrentMode( m_priv->m_id ); + CFDictionaryRef theValue = CGDisplayCurrentMode( m_id ); return wxVideoMode( wxCFDictKeyToInt( theValue, kCGDisplayWidth ), @@ -179,7 +214,7 @@ wxVideoMode wxDisplay::GetCurrentMode() const wxCFDictKeyToInt( theValue, kCGDisplayRefreshRate )); } -bool wxDisplay::ChangeMode( const wxVideoMode& mode ) +bool wxDisplayImplMacOSX::ChangeMode( const wxVideoMode& mode ) { // Changing to default mode (wxDefaultVideoMode) doesn't // work because we don't have access to the system's 'scrn' @@ -187,7 +222,7 @@ bool wxDisplay::ChangeMode( const wxVideoMode& mode ) // will return to after this app is done boolean_t bExactMatch; CFDictionaryRef theCGMode = CGDisplayBestModeForParametersAndRefreshRate( - m_priv->m_id, + m_id, (size_t)mode.bpp, (size_t)mode.w, (size_t)mode.h, @@ -197,49 +232,74 @@ bool wxDisplay::ChangeMode( const wxVideoMode& mode ) bool bOK = bExactMatch; if (bOK) - bOK = CGDisplaySwitchToMode( m_priv->m_id, theCGMode ) == CGDisplayNoErr; + bOK = CGDisplaySwitchToMode( m_id, theCGMode ) == CGDisplayNoErr; return bOK; } -wxDisplay::~wxDisplay() +// ============================================================================ +// wxDisplay::CreateFactory() +// ============================================================================ + +/* static */ wxDisplayFactory *wxDisplay::CreateFactory() { - if ( m_priv ) - { - delete m_priv; - m_priv = 0; - } + return new wxDisplayFactoryMacOSX; } -#else +#else // !__WXMAC_OSX__ -class wxDisplayMacPriv +class wxDisplayImplMac : public wxDisplayImpl { public: + wxDisplayImplMac(GDHandle hndl) : m_hndl(hndl) { } + + virtual wxRect GetGeometry() const; + virtual wxString GetName() const { return wxString(); } + + virtual wxArrayVideoModes GetModes(const wxVideoMode& mode) const; + virtual wxVideoMode GetCurrentMode() const; + virtual bool ChangeMode(const wxVideoMode& mode); + +private: GDHandle m_hndl; + + DECLARE_NO_COPY_CLASS(wxDisplayImplMac) +}; + +class wxDisplayFactoryMac : public wxDisplayFactory +{ +public: + wxDisplayFactoryMac(); + + virtual wxDisplayImpl *CreateDisplay(size_t n); + virtual size_t GetCount(); + virtual int GetFromPoint(const wxPoint& pt); + +protected: + DECLARE_NO_COPY_CLASS(wxDisplayFactoryMac) }; -size_t wxDisplayBase::GetCount() +// ============================================================================ +// wxDisplayFactoryMac implementation +// ============================================================================ + +size_t wxDisplayFactoryMac::GetCount() { - GDHandle hndl; size_t num = 0; - hndl = DMGetFirstScreenDevice(true); - while (hndl) + GDHandle hndl = DMGetFirstScreenDevice(true); + while(hndl) { num++; hndl = DMGetNextScreenDevice(hndl, true); } - return num; } -int wxDisplayBase::GetFromPoint(const wxPoint &p) +int wxDisplayFactoryMac::GetFromPoint(const wxPoint &p) { - GDHandle hndl; size_t num = 0; - hndl = DMGetFirstScreenDevice(true); - - while (hndl) + GDHandle hndl = DMGetFirstScreenDevice(true); + while(hndl) { Rect screenrect = (*hndl)->gdRect; if (p.x >= screenrect.left && @@ -249,63 +309,39 @@ int wxDisplayBase::GetFromPoint(const wxPoint &p) { return num; } - num++; hndl = DMGetNextScreenDevice(hndl, true); } - return -1; + return wxNOT_FOUND; } -wxDisplay::wxDisplay( size_t index ) - : wxDisplayBase( index ), - m_priv( new wxDisplayMacPriv() ) +wxDisplayImpl *wxDisplayFactoryMac::CreateDisplay(size_t n) { - GDHandle hndl; - hndl = DMGetFirstScreenDevice(true); - m_priv->m_hndl = NULL; - - while (hndl) + GDHandle hndl = DMGetFirstScreenDevice(true); + while(hndl) { - if (index == 0) - m_priv->m_hndl = hndl; - - index--; + if (n == 0) + { + return new wxDisplayImplMac(hndl); + } + n--; hndl = DMGetNextScreenDevice(hndl, true); } -} -wxRect wxDisplay::GetGeometry() const -{ - if ((m_priv == NULL) || (m_priv->m_hndl == NULL)) - return wxRect(0, 0, 0, 0); - - Rect screenrect = (*(m_priv->m_hndl))->gdRect; - return wxRect( - screenrect.left, screenrect.top, - screenrect.right - screenrect.left, - screenrect.bottom - screenrect.top ); + return NULL; } -int wxDisplay::GetDepth() const -{ - if ((m_priv == NULL) || (m_priv->m_hndl == NULL)) - return 0; - - // This cryptic looking code is based on Apple's sample code: - // http://developer.apple.com/samplecode/Sample_Code/Graphics_2D/GDevVideo/Gen.cp.htm - - // RN - according to the docs - // gdPMap is a bitmap-type representation of the GDevice, and all - // 0x0000FFFF does is get the lower 16 bits of pixelSize. However, - // since pixelSize is only 16 bits (a short)... - return ((*(*(m_priv->m_hndl))->gdPMap)->pixelSize) & 0x0000FFFF; -} +// ============================================================================ +// wxDisplayImplMac implementation +// ============================================================================ -wxString wxDisplay::GetName() const +wxRect wxDisplayImplMac::GetGeometry() const { - // Macs don't name their displays... - return wxEmptyString; + Rect screenrect = (*m_hndl)->gdRect; + return wxRect(screenrect.left, screenrect.top, + screenrect.right - screenrect.left, + screenrect.bottom - screenrect.top); } struct DMModeIteratorRec @@ -415,8 +451,7 @@ pascal void DMModeTransProc( #undef pDBI } -wxArrayVideoModes - wxDisplay::GetModes(const wxVideoMode& mode) const +wxArrayVideoModes wxDisplayImplMac::GetModes(const wxVideoMode& mode) const { wxArrayVideoModes Modes; unsigned long dwDMVer; @@ -432,7 +467,7 @@ wxArrayVideoModes DisplayIDType nDisplayID; OSErr err; - err = DMGetDisplayIDByGDevice(m_priv->m_hndl, &nDisplayID, false); + err = DMGetDisplayIDByGDevice(m_hndl, &nDisplayID, false); verify_noerr( err ); // Create a new list... @@ -468,7 +503,7 @@ wxArrayVideoModes return Modes; } -wxVideoMode wxDisplay::GetCurrentMode() const +wxVideoMode wxDisplayImplMac::GetCurrentMode() const { unsigned long dwDMVer; wxVideoMode RetMode; @@ -481,7 +516,7 @@ wxVideoMode wxDisplay::GetCurrentMode() const VDSwitchInfoRec sMode; // Note: csMode member also contains the bit depth OSErr err; - err = DMGetDisplayMode( m_priv->m_hndl, &sMode ); + err = DMGetDisplayMode( m_hndl, &sMode ); if (err == noErr) { DMListIndexType nNumModes; @@ -489,7 +524,7 @@ wxVideoMode wxDisplay::GetCurrentMode() const DMDisplayModeListIteratorUPP uppMLI; DisplayIDType nDisplayID; - err = DMGetDisplayIDByGDevice(m_priv->m_hndl, &nDisplayID, false); + err = DMGetDisplayIDByGDevice(m_hndl, &nDisplayID, false); verify_noerr( err ); // Create a new list... @@ -538,7 +573,7 @@ wxVideoMode wxDisplay::GetCurrentMode() const return RetMode; } -bool wxDisplay::ChangeMode(const wxVideoMode& mode) +bool wxDisplayImplMac::ChangeMode(const wxVideoMode& mode) { unsigned long dwDMVer; @@ -580,7 +615,7 @@ bool wxDisplay::ChangeMode(const wxVideoMode& mode) DisplayIDType nDisplayID; OSErr err; - err = DMGetDisplayIDByGDevice(m_priv->m_hndl, &nDisplayID, false); + err = DMGetDisplayIDByGDevice(m_hndl, &nDisplayID, false); verify_noerr( err ); // Create a new list... @@ -618,7 +653,7 @@ bool wxDisplay::ChangeMode(const wxVideoMode& mode) // For the really paranoid - // unsigned long flags; // Boolean bok; - // wxASSERT(noErr == DMCheckDisplayMode(m_priv->m_hndl, sMode.csData, + // wxASSERT(noErr == DMCheckDisplayMode(m_hndl, sMode.csData, // sMode.csMode, &flags, NULL, &bok)); // wxASSERT(bok); @@ -632,7 +667,7 @@ bool wxDisplay::ChangeMode(const wxVideoMode& mode) unsigned long dwBPP = (unsigned long) mode.bpp; err = DMSetDisplayMode( - m_priv->m_hndl, sMode.csData, + m_hndl, sMode.csData, (unsigned long*) &(dwBPP), NULL, //(unsigned long) &sMode hDisplayState ); @@ -640,7 +675,7 @@ bool wxDisplay::ChangeMode(const wxVideoMode& mode) if (err != noErr) { DMEndConfigureDisplays(hDisplayState); - wxMessageBox( wxString::Format(wxT("Could not set the display mode")) ); + wxLogError(wxT("Could not set the display mode")); return false; } @@ -660,13 +695,13 @@ bool wxDisplay::ChangeMode(const wxVideoMode& mode) return true; } -wxDisplay::~wxDisplay() +// ============================================================================ +// wxDisplay::CreateFactory() +// ============================================================================ + +/* static */ wxDisplayFactory *wxDisplay::CreateFactory() { - if ( m_priv ) - { - delete m_priv; - m_priv = 0; - } + return new wxDisplayFactoryMac; } #endif // !OSX diff --git a/src/mac/classic/display.cpp b/src/mac/classic/display.cpp index 00f4d034db..61eb2d44e2 100644 --- a/src/mac/classic/display.cpp +++ b/src/mac/classic/display.cpp @@ -1,14 +1,22 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: display.cpp +// Name: src/mac/classic/display.cpp // Purpose: Mac implementation of wxDisplay class // Author: Brian Victor -// Modified by: Royce Mitchell III & Ryan Norton +// Modified by: Royce Mitchell III & Ryan Norton, Vadim Zeitlin // Created: 06/21/02 // RCS-ID: $Id$ // Copyright: (c) wxWidgets team // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// +// ============================================================================ +// declarations +// ============================================================================ + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- + // For compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" @@ -21,7 +29,6 @@ #ifndef WX_PRECOMP #include "wx/dynarray.h" #include "wx/log.h" - #include "wx/msgdlg.h" #endif #ifdef __DARWIN__ @@ -35,24 +42,53 @@ #endif #include "wx/display.h" +#include "wx/display_impl.h" #include "wx/gdicmn.h" #include "wx/string.h" // ---------------------------------------------------------------------------- -// private classes +// display implementation classes // ---------------------------------------------------------------------------- -class wxDisplayMacPriv +class wxDisplayImplMac : public wxDisplayImpl { public: + wxDisplayImplMac(GDHandle hndl) : m_hndl(hndl) { } + + virtual wxRect GetGeometry() const; + virtual wxString GetName() const { return wxString(); } + + virtual wxArrayVideoModes GetModes(const wxVideoMode& mode) const; + virtual wxVideoMode GetCurrentMode() const; + virtual bool ChangeMode(const wxVideoMode& mode); + +private: GDHandle m_hndl; + + DECLARE_NO_COPY_CLASS(wxDisplayImplMac) }; -size_t wxDisplayBase::GetCount() +class wxDisplayFactoryMac : public wxDisplayFactory +{ +public: + wxDisplayFactoryMac(); + + virtual wxDisplayImpl *CreateDisplay(size_t n); + virtual size_t GetCount(); + virtual int GetFromPoint(const wxPoint& pt); + +protected: + DECLARE_NO_COPY_CLASS(wxDisplayFactoryMac) +}; + +// ============================================================================ +// wxDisplayFactoryMac implementation +// ============================================================================ + +size_t wxDisplayFactoryMac::GetCount() { - GDHandle hndl; size_t num = 0; - hndl = DMGetFirstScreenDevice(true); + GDHandle hndl = DMGetFirstScreenDevice(true); while(hndl) { num++; @@ -61,11 +97,10 @@ size_t wxDisplayBase::GetCount() return num; } -int wxDisplayBase::GetFromPoint(const wxPoint &p) +int wxDisplayFactoryMac::GetFromPoint(const wxPoint &p) { - GDHandle hndl; size_t num = 0; - hndl = DMGetFirstScreenDevice(true); + GDHandle hndl = DMGetFirstScreenDevice(true); while(hndl) { Rect screenrect = (*hndl)->gdRect; @@ -79,154 +114,134 @@ int wxDisplayBase::GetFromPoint(const wxPoint &p) num++; hndl = DMGetNextScreenDevice(hndl, true); } - return -1; + + return wxNOT_FOUND; } -wxDisplay::wxDisplay(size_t index) : wxDisplayBase ( index ), - m_priv ( new wxDisplayMacPriv() ) +wxDisplayImpl *wxDisplayFactoryMac::CreateDisplay(size_t n) { - GDHandle hndl; - hndl = DMGetFirstScreenDevice(true); - m_priv->m_hndl = NULL; + GDHandle hndl = DMGetFirstScreenDevice(true); while(hndl) { - if (index == 0) + if (n == 0) { - m_priv->m_hndl = hndl; + return new wxDisplayImplMac(hndl); } - index--; + n--; hndl = DMGetNextScreenDevice(hndl, true); } -} -wxRect wxDisplay::GetGeometry() const -{ - if (!(m_priv)) return wxRect(0, 0, 0, 0); - if (!(m_priv->m_hndl)) return wxRect(0, 0, 0, 0); - Rect screenrect = (*(m_priv->m_hndl))->gdRect; - return wxRect( screenrect.left, screenrect.top, - screenrect.right - screenrect.left, screenrect.bottom - screenrect.top); + return NULL; } -int wxDisplay::GetDepth() const -{ - if (!(m_priv)) return 0; - if (!(m_priv->m_hndl)) return 0; - - // This cryptic looking code is based on Apple's sample code: - // http://developer.apple.com/samplecode/Sample_Code/Graphics_2D/GDevVideo/Gen.cp.htm +// ============================================================================ +// wxDisplayImplMac implementation +// ============================================================================ - //RN - according to the docs - //gdPMap is a bitmap-type representation of the GDevice, and all - //0x0000FFFF does is get the lower 16 bits of pixelSize. However, - //since pixelSize is only 16 bits (a short)... - return ((*(*(m_priv->m_hndl))->gdPMap)->pixelSize) & 0x0000FFFF; -} - -wxString wxDisplay::GetName() const +wxRect wxDisplayImplMac::GetGeometry() const { - // Macs don't name their displays... - return wxEmptyString; + Rect screenrect = (*m_hndl)->gdRect; + return wxRect(screenrect.left, screenrect.top, + screenrect.right - screenrect.left, + screenrect.bottom - screenrect.top); } struct DMModeIteratorRec { - wxArrayVideoModes* pModes; - const wxVideoMode* pMatchMode; + wxArrayVideoModes* pModes; + const wxVideoMode* pMatchMode; }; -pascal void DMModeListIteratorProc ( void* pData, - DMListIndexType nIndex, - DMDisplayModeListEntryPtr pInfo) +pascal void DMModeListIteratorProc ( void* pData, + DMListIndexType nIndex, + DMDisplayModeListEntryPtr pInfo) { DMModeIteratorRec* pInfoData = (DMModeIteratorRec*) pData; - //Note that in testing the refresh rate is always 0 on my ibook - RN + //Note that in testing the refresh rate is always 0 on my ibook - RN int refresh = (int) Fix2Long(pInfo->displayModeResolutionInfo->csRefreshRate); - for(unsigned long i = 0; i < pInfo->displayModeDepthBlockInfo->depthBlockCount; ++i) - { + for(unsigned long i = 0; i < pInfo->displayModeDepthBlockInfo->depthBlockCount; ++i) + { #define pDBI pInfo->displayModeDepthBlockInfo->depthVPBlock[i].depthVPBlock - if (wxVideoMode((int) pInfo->displayModeResolutionInfo->csHorizontalPixels, - (int) pInfo->displayModeResolutionInfo->csVerticalLines, - (int) pDBI->vpPixelSize, - refresh).Matches(*pInfoData->pMatchMode) ) - { - pInfoData->pModes->Add(wxVideoMode((int) pInfo->displayModeResolutionInfo->csHorizontalPixels, - (int) pInfo->displayModeResolutionInfo->csVerticalLines, - (int) pDBI->vpPixelSize, - refresh)); - } + if (wxVideoMode((int) pInfo->displayModeResolutionInfo->csHorizontalPixels, + (int) pInfo->displayModeResolutionInfo->csVerticalLines, + (int) pDBI->vpPixelSize, + refresh).Matches(*pInfoData->pMatchMode) ) + { + pInfoData->pModes->Add(wxVideoMode((int) pInfo->displayModeResolutionInfo->csHorizontalPixels, + (int) pInfo->displayModeResolutionInfo->csVerticalLines, + (int) pDBI->vpPixelSize, + refresh)); + } #undef pDBI - } + } } struct DMModeInfoRec { - const wxVideoMode* pMode; - VDSwitchInfoRec sMode; - bool bMatched; + const wxVideoMode* pMode; + VDSwitchInfoRec sMode; + bool bMatched; }; -pascal void DMModeInfoProc ( void* pData, - DMListIndexType nIndex, - DMDisplayModeListEntryPtr pInfo) +pascal void DMModeInfoProc ( void* pData, + DMListIndexType nIndex, + DMDisplayModeListEntryPtr pInfo) { - DMModeInfoRec* pInfoData = (DMModeInfoRec*) pData; - Fixed refresh = Long2Fix(pInfoData->pMode->refresh); + DMModeInfoRec* pInfoData = (DMModeInfoRec*) pData; + Fixed refresh = Long2Fix(pInfoData->pMode->refresh); - for(unsigned long i = 0; i < pInfo->displayModeDepthBlockInfo->depthBlockCount; ++i) - { + for(unsigned long i = 0; i < pInfo->displayModeDepthBlockInfo->depthBlockCount; ++i) + { #define pDBI pInfo->displayModeDepthBlockInfo->depthVPBlock[i].depthVPBlock - if (pInfoData->pMode->w == (int&) pInfo->displayModeResolutionInfo->csHorizontalPixels && - pInfoData->pMode->h == (int&) pInfo->displayModeResolutionInfo->csVerticalLines && - pInfoData->pMode->bpp == (int) pDBI->vpPixelSize && - refresh == pInfo->displayModeResolutionInfo->csRefreshRate) - { - memcpy(&pInfoData->sMode, pInfo->displayModeDepthBlockInfo->depthVPBlock[i].depthSwitchInfo, - sizeof(VDSwitchInfoRec)); - pInfoData->sMode.csMode = pDBI->vpPixelSize; - pInfoData->bMatched = true; - break; - } + if (pInfoData->pMode->w == (int&) pInfo->displayModeResolutionInfo->csHorizontalPixels && + pInfoData->pMode->h == (int&) pInfo->displayModeResolutionInfo->csVerticalLines && + pInfoData->pMode->bpp == (int) pDBI->vpPixelSize && + refresh == pInfo->displayModeResolutionInfo->csRefreshRate) + { + memcpy(&pInfoData->sMode, pInfo->displayModeDepthBlockInfo->depthVPBlock[i].depthSwitchInfo, + sizeof(VDSwitchInfoRec)); + pInfoData->sMode.csMode = pDBI->vpPixelSize; + pInfoData->bMatched = true; + break; + } #undef pDBI - } + } } struct DMModeTransRec { - wxVideoMode Mode; - const VDSwitchInfoRec* psMode; - bool bMatched; + wxVideoMode Mode; + const VDSwitchInfoRec* psMode; + bool bMatched; }; -pascal void DMModeTransProc ( void* pData, - DMListIndexType nIndex, - DMDisplayModeListEntryPtr pInfo) +pascal void DMModeTransProc ( void* pData, + DMListIndexType nIndex, + DMDisplayModeListEntryPtr pInfo) { - DMModeTransRec* pInfoData = (DMModeTransRec*) pData; + DMModeTransRec* pInfoData = (DMModeTransRec*) pData; - for(unsigned long i = 0; i < pInfo->displayModeDepthBlockInfo->depthBlockCount; ++i) - { + for(unsigned long i = 0; i < pInfo->displayModeDepthBlockInfo->depthBlockCount; ++i) + { #define pDBI pInfo->displayModeDepthBlockInfo->depthVPBlock[i].depthVPBlock - if (pInfoData->psMode->csData == pInfo->displayModeDepthBlockInfo->depthVPBlock[i].depthSwitchInfo->csData) - { - pInfoData->Mode = wxVideoMode((int) pInfo->displayModeResolutionInfo->csHorizontalPixels, - (int) pInfo->displayModeResolutionInfo->csVerticalLines, - (int) pDBI->vpPixelSize, - (int) Fix2Long(pInfo->displayModeResolutionInfo->csRefreshRate) ); - pInfoData->bMatched = true; - break; - } + if (pInfoData->psMode->csData == pInfo->displayModeDepthBlockInfo->depthVPBlock[i].depthSwitchInfo->csData) + { + pInfoData->Mode = wxVideoMode((int) pInfo->displayModeResolutionInfo->csHorizontalPixels, + (int) pInfo->displayModeResolutionInfo->csVerticalLines, + (int) pDBI->vpPixelSize, + (int) Fix2Long(pInfo->displayModeResolutionInfo->csRefreshRate) ); + pInfoData->bMatched = true; + break; + } #undef pDBI - } + } } -wxArrayVideoModes - wxDisplay::GetModes(const wxVideoMode& mode) const +wxArrayVideoModes wxDisplayImplMac::GetModes(const wxVideoMode& mode) const { - wxArrayVideoModes Modes; unsigned long dwDMVer; @@ -236,207 +251,207 @@ wxArrayVideoModes if (dwDMVer >= 0x020000) //version 2? { - DMListIndexType nNumModes; - DMListType pModes; - DMDisplayModeListIteratorUPP uppMLI; - DisplayIDType nDisplayID; - - wxASSERT(DMGetDisplayIDByGDevice(m_priv->m_hndl, &nDisplayID, false) == noErr); - //Create a new list... - wxASSERT_MSG(DMNewDisplayModeList(nDisplayID, NULL, NULL, &nNumModes, &pModes) == noErr, wxT("Could not create a new display mode list") ); - - uppMLI = NewDMDisplayModeListIteratorUPP(DMModeListIteratorProc); - wxASSERT(uppMLI); - - DMModeIteratorRec sModeInfo; - sModeInfo.pModes = &Modes; - sModeInfo.pMatchMode = &mode; - for (DMListIndexType i = 0; i < nNumModes; ++i) - { - wxASSERT(DMGetIndexedDisplayModeFromList(pModes, i, NULL, - uppMLI, &sModeInfo) == noErr); - } - DisposeDMDisplayModeListIteratorUPP(uppMLI); - wxASSERT(DMDisposeList(pModes) == noErr); + DMListIndexType nNumModes; + DMListType pModes; + DMDisplayModeListIteratorUPP uppMLI; + DisplayIDType nDisplayID; + + wxASSERT(DMGetDisplayIDByGDevice(m_hndl, &nDisplayID, false) == noErr); + //Create a new list... + wxASSERT_MSG(DMNewDisplayModeList(nDisplayID, NULL, NULL, &nNumModes, &pModes) == noErr, wxT("Could not create a new display mode list") ); + + uppMLI = NewDMDisplayModeListIteratorUPP(DMModeListIteratorProc); + wxASSERT(uppMLI); + + DMModeIteratorRec sModeInfo; + sModeInfo.pModes = &Modes; + sModeInfo.pMatchMode = &mode; + for (DMListIndexType i = 0; i < nNumModes; ++i) + { + wxASSERT(DMGetIndexedDisplayModeFromList(pModes, i, NULL, + uppMLI, &sModeInfo) == noErr); + } + DisposeDMDisplayModeListIteratorUPP(uppMLI); + wxASSERT(DMDisposeList(pModes) == noErr); } else //DM 1.0, 1.2, 1.x { - wxLogSysError(wxString::Format(wxT("Display Manager Version %u Not Supported! Present? %s"), - (unsigned int) dwDMVer / 0x10000, - (dwDMVer & (1 << gestaltDisplayMgrPresent) ? wxT("Yes") : wxT("No")) ) - ); + wxLogSysError(wxString::Format(wxT("Display Manager Version %u Not Supported! Present? %s"), + (unsigned int) dwDMVer / 0x10000, + (dwDMVer & (1 << gestaltDisplayMgrPresent) ? wxT("Yes") : wxT("No")) ) + ); } return Modes; } -wxVideoMode wxDisplay::GetCurrentMode() const +wxVideoMode wxDisplayImplMac::GetCurrentMode() const { unsigned long dwDMVer; wxVideoMode RetMode; - - Gestalt(gestaltDisplayMgrVers, (long*) &dwDMVer); + + Gestalt(gestaltDisplayMgrVers, (long*) &dwDMVer); //Check DM version (for backward compatibility only - 7.5.3+ use 2.0) if (dwDMVer >= 0x020000) //version 2? { - VDSwitchInfoRec sMode; //Note - csMode member also contains the bit depth - if (DMGetDisplayMode(m_priv->m_hndl, &sMode) == noErr) - { - DMListIndexType nNumModes; - DMListType pModes; - DMDisplayModeListIteratorUPP uppMLI; - DisplayIDType nDisplayID; - - wxASSERT(DMGetDisplayIDByGDevice(m_priv->m_hndl, &nDisplayID, false) == noErr); - //Create a new list... - wxASSERT_MSG(DMNewDisplayModeList(nDisplayID, NULL, NULL, &nNumModes, &pModes) == noErr, - wxT("Could not create a new display mode list") ); - - uppMLI = NewDMDisplayModeListIteratorUPP(DMModeTransProc); - wxASSERT(uppMLI); - - DMModeTransRec sModeInfo; - sModeInfo.bMatched = false; - sModeInfo.psMode = &sMode; - for (DMListIndexType i = 0; i < nNumModes; ++i) - { - wxASSERT(DMGetIndexedDisplayModeFromList(pModes, i, NULL, - uppMLI, &sModeInfo) == noErr); - - if ( sModeInfo.bMatched == true ) - { - RetMode = sModeInfo.Mode; - break; - } - } - - DisposeDMDisplayModeListIteratorUPP(uppMLI); - wxASSERT(DMDisposeList(pModes) == noErr); - } - else //Can't get current mode? - { - wxLogSysError(wxString::Format(wxT("Couldn't obtain current display mode!!!\ndwDMVer:%u"), - (unsigned int) dwDMVer)); - } + VDSwitchInfoRec sMode; //Note - csMode member also contains the bit depth + if (DMGetDisplayMode(m_hndl, &sMode) == noErr) + { + DMListIndexType nNumModes; + DMListType pModes; + DMDisplayModeListIteratorUPP uppMLI; + DisplayIDType nDisplayID; + + wxASSERT(DMGetDisplayIDByGDevice(m_hndl, &nDisplayID, false) == noErr); + //Create a new list... + wxASSERT_MSG(DMNewDisplayModeList(nDisplayID, NULL, NULL, &nNumModes, &pModes) == noErr, + wxT("Could not create a new display mode list") ); + + uppMLI = NewDMDisplayModeListIteratorUPP(DMModeTransProc); + wxASSERT(uppMLI); + + DMModeTransRec sModeInfo; + sModeInfo.bMatched = false; + sModeInfo.psMode = &sMode; + for (DMListIndexType i = 0; i < nNumModes; ++i) + { + wxASSERT(DMGetIndexedDisplayModeFromList(pModes, i, NULL, + uppMLI, &sModeInfo) == noErr); + + if ( sModeInfo.bMatched == true ) + { + RetMode = sModeInfo.Mode; + break; + } + } + + DisposeDMDisplayModeListIteratorUPP(uppMLI); + wxASSERT(DMDisposeList(pModes) == noErr); + } + else //Can't get current mode? + { + wxLogSysError(wxString::Format(wxT("Couldn't obtain current display mode!!!\ndwDMVer:%u"), + (unsigned int) dwDMVer)); + } } else //DM ver 1 { - wxLogSysError(wxString::Format(wxT("Display Manager Version %u Not Supported! Present? %s"), - (unsigned int) dwDMVer / 0x10000, - (dwDMVer & (1 << gestaltDisplayMgrPresent) ? wxT("Yes") : wxT("No")) ) - ); + wxLogSysError(wxString::Format(wxT("Display Manager Version %u Not Supported! Present? %s"), + (unsigned int) dwDMVer / 0x10000, + (dwDMVer & (1 << gestaltDisplayMgrPresent) ? wxT("Yes") : wxT("No")) ) + ); } - + return RetMode; } -bool wxDisplay::ChangeMode(const wxVideoMode& mode) +bool wxDisplayImplMac::ChangeMode(const wxVideoMode& mode) { unsigned long dwDMVer; Gestalt(gestaltDisplayMgrVers, (long*)&dwDMVer); if (GetCount() == 1 || dwDMVer >= 0x020000) { - if (mode == wxDefaultVideoMode) - { + if (mode == wxDefaultVideoMode) + { //#ifndef __DARWIN__ -// Handle hDisplayState; -// if (DMBeginConfigureDisplays(&hDisplayState) != noErr) -// { -// wxLogSysError(wxT("Could not lock display for display mode changing!")); -// return false; -// } -// wxASSERT( DMUseScreenPrefs(true, hDisplayState) == noErr); -// DMEndConfigureDisplays(hDisplayState); -// return true; +// Handle hDisplayState; +// if (DMBeginConfigureDisplays(&hDisplayState) != noErr) +// { +// wxLogSysError(wxT("Could not lock display for display mode changing!")); +// return false; +// } +// wxASSERT( DMUseScreenPrefs(true, hDisplayState) == noErr); +// DMEndConfigureDisplays(hDisplayState); +// return true; //#else - //hmmmmm.... - return true; + //hmmmmm.... + return true; //#endif - } - - //0 & NULL for params 2 & 3 of DMSetVideoMode signal it to use defaults (current mode) - //DM 2.0+ doesn't use params 2 & 3 of DMSetDisplayMode - //so we have to use this icky structure - VDSwitchInfoRec sMode; - memset(&sMode, 0, sizeof(VDSwitchInfoRec) ); - - DMListIndexType nNumModes; - DMListType pModes; - DMDisplayModeListIteratorUPP uppMLI; - DisplayIDType nDisplayID; - - wxASSERT(DMGetDisplayIDByGDevice(m_priv->m_hndl, &nDisplayID, false) == noErr); - //Create a new list... - wxASSERT_MSG(DMNewDisplayModeList(nDisplayID, NULL, NULL, &nNumModes, &pModes) == noErr, - wxT("Could not create a new display mode list") ); - - uppMLI = NewDMDisplayModeListIteratorUPP(DMModeInfoProc); - wxASSERT(uppMLI); - - DMModeInfoRec sModeInfo; - sModeInfo.bMatched = false; - sModeInfo.pMode = &mode; - unsigned int i; - for(i = 0; i < nNumModes; ++i) - { - wxASSERT(DMGetIndexedDisplayModeFromList(pModes, i, NULL, - uppMLI, &sModeInfo) == noErr); - if (sModeInfo.bMatched == true) - { - sMode = sModeInfo.sMode; - break; - } - } - if(i == nNumModes) - return false; - - DisposeDMDisplayModeListIteratorUPP(uppMLI); - wxASSERT(DMDisposeList(pModes) == noErr); - - // For the really paranoid - - // unsigned long flags; - // Boolean bok; - // wxASSERT(noErr == DMCheckDisplayMode(m_priv->m_hndl, sMode.csData, - // sMode.csMode, &flags, NULL, &bok)); - // wxASSERT(bok); - - Handle hDisplayState; - if (DMBeginConfigureDisplays(&hDisplayState) != noErr) - { - wxLogSysError(wxT("Could not lock display for display mode changing!")); - return false; - } - - unsigned long dwBPP = (unsigned long) mode.bpp; - if (DMSetDisplayMode(m_priv->m_hndl, sMode.csData, - (unsigned long*) &(dwBPP), NULL - //(unsigned long) &sMode - , hDisplayState - ) != noErr) - { - DMEndConfigureDisplays(hDisplayState); - wxMessageBox(wxString::Format(wxT("Could not set the display mode"))); + } + + //0 & NULL for params 2 & 3 of DMSetVideoMode signal it to use defaults (current mode) + //DM 2.0+ doesn't use params 2 & 3 of DMSetDisplayMode + //so we have to use this icky structure + VDSwitchInfoRec sMode; + memset(&sMode, 0, sizeof(VDSwitchInfoRec) ); + + DMListIndexType nNumModes; + DMListType pModes; + DMDisplayModeListIteratorUPP uppMLI; + DisplayIDType nDisplayID; + + wxASSERT(DMGetDisplayIDByGDevice(m_hndl, &nDisplayID, false) == noErr); + //Create a new list... + wxASSERT_MSG(DMNewDisplayModeList(nDisplayID, NULL, NULL, &nNumModes, &pModes) == noErr, + wxT("Could not create a new display mode list") ); + + uppMLI = NewDMDisplayModeListIteratorUPP(DMModeInfoProc); + wxASSERT(uppMLI); + + DMModeInfoRec sModeInfo; + sModeInfo.bMatched = false; + sModeInfo.pMode = &mode; + unsigned int i; + for(i = 0; i < nNumModes; ++i) + { + wxASSERT(DMGetIndexedDisplayModeFromList(pModes, i, NULL, + uppMLI, &sModeInfo) == noErr); + if (sModeInfo.bMatched == true) + { + sMode = sModeInfo.sMode; + break; + } + } + if(i == nNumModes) return false; - } - DMEndConfigureDisplays(hDisplayState); + + DisposeDMDisplayModeListIteratorUPP(uppMLI); + wxASSERT(DMDisposeList(pModes) == noErr); + + // For the really paranoid - + // unsigned long flags; + // Boolean bok; + // wxASSERT(noErr == DMCheckDisplayMode(m_hndl, sMode.csData, + // sMode.csMode, &flags, NULL, &bok)); + // wxASSERT(bok); + + Handle hDisplayState; + if (DMBeginConfigureDisplays(&hDisplayState) != noErr) + { + wxLogSysError(wxT("Could not lock display for display mode changing!")); + return false; + } + + unsigned long dwBPP = (unsigned long) mode.bpp; + if (DMSetDisplayMode(m_hndl, sMode.csData, + (unsigned long*) &(dwBPP), NULL + //(unsigned long) &sMode + , hDisplayState + ) != noErr) + { + DMEndConfigureDisplays(hDisplayState); + wxLogError(wxT("Could not set the display mode")); + return false; + } + DMEndConfigureDisplays(hDisplayState); } else //DM 1.0, 1.2, 1.x { - wxLogSysError(wxString::Format(wxT("Monitor gravitation not supported yet. dwDMVer:%u"), - (unsigned int) dwDMVer)); - return false; + wxLogSysError(wxString::Format(wxT("Monitor gravitation not supported yet. dwDMVer:%u"), + (unsigned int) dwDMVer)); + return false; } - + return true; } -wxDisplay::~wxDisplay() +// ============================================================================ +// wxDisplay::CreateFactory() +// ============================================================================ + +/* static */ wxDisplayFactory *wxDisplay::CreateFactory() { - if ( m_priv ) - { - delete m_priv; - m_priv = 0; - } + return new wxDisplayFactoryMac; } #endif // wxUSE_DISPLAY diff --git a/src/mgl/display.cpp b/src/mgl/display.cpp deleted file mode 100644 index 86365ff505..0000000000 --- a/src/mgl/display.cpp +++ /dev/null @@ -1,99 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Name: src/mgl/display.cpp -// Purpose: MGL Implementation of wxDisplay class -// Author: Wlodzimierz ABX Skiba -// Modified by: -// Created: 05/03/2006 -// RCS-ID: $Id$ -// Copyright: (c) Wlodzimierz Skiba -// Licence: wxWindows licence -///////////////////////////////////////////////////////////////////////////// - -// For compilers that support precompilation, includes "wx.h". -#include "wx/wxprec.h" - -#ifdef __BORLANDC__ - #pragma hdrstop -#endif - -#if wxUSE_DISPLAY - -#ifndef WX_PRECOMP - #include "wx/gdicmn.h" -#endif - -#include "wx/display.h" - -/* static */ -int wxDisplayBase::GetFromPoint ( const wxPoint& WXUNUSED(pt) ) -{ - // TODO - return wxNOT_FOUND; -} - -/* static */ -size_t wxDisplayBase::GetCount() -{ - // TODO - return 1; -} - -// ---------------------------------------------------------------------------- -// wxDisplay ctor/dtor -// ---------------------------------------------------------------------------- - -wxDisplay::wxDisplay ( size_t n ) - : wxDisplayBase ( n ) -{ -} - -wxDisplay::~wxDisplay() -{ -} - -bool wxDisplay::IsOk() const -{ - // TODO - return m_index < GetCount(); -} - -wxRect wxDisplay::GetGeometry() const -{ - wxRect rect; - // TODO - return rect; -} - -wxString wxDisplay::GetName() const -{ - // TODO - return wxEmptyString; -} - -wxArrayVideoModes wxDisplay::GetModes(const wxVideoMode& WXUNUSED(modeMatch)) const -{ - wxArrayVideoModes modes; - // TODO - return modes; -} - -wxVideoMode wxDisplay::GetCurrentMode() const -{ - wxVideoMode mode; - // TODO - return mode; -} - -bool wxDisplay::ChangeMode(const wxVideoMode& WXUNUSED(mode)) -{ - // TODO - return false; -} - -bool wxDisplay::IsPrimary() const -{ - // TODO - return false; -} - -#endif // wxUSE_DISPLAY diff --git a/src/msw/display.cpp b/src/msw/display.cpp index c6403d8ed4..ac0dc4c612 100644 --- a/src/msw/display.cpp +++ b/src/msw/display.cpp @@ -34,15 +34,23 @@ #endif #include "wx/dynload.h" +#include "wx/sysopt.h" #include "wx/display.h" +#include "wx/display_impl.h" // Mingw's w32api headers don't include ddraw.h, though the user may have // installed it. If using configure, we actually probe for ddraw.h there -// and set HAVE_DDRAW_H. Otherwise, assume we don't have it if using +// and set wxUSE_DIRECTDRAW. Otherwise, assume we don't have it if using // the w32api headers, and that we do otherwise. #if !defined HAVE_W32API_H && !defined HAVE_DDRAW_H -#define HAVE_DDRAW_H 1 + #define HAVE_DDRAW_H +#endif + +// user may disable compilation of DirectDraw code by setting +// wxUSE_DIRECTDRAW to 0 in the makefile/project settings +#if defined(HAVE_DDRAW_H) && !defined(wxUSE_DIRECTDRAW) + #define wxUSE_DIRECTDRAW 1 #endif #ifndef __WXWINCE__ @@ -56,14 +64,14 @@ #endif #endif // !__WXWINCE__ -#ifdef HAVE_DDRAW_H +#ifdef wxUSE_DIRECTDRAW #include // we don't want to link with ddraw.lib which contains the real // IID_IDirectDraw2 definition const GUID wxIID_IDirectDraw2 = { 0xB3A6F3E0, 0x2B43, 0x11CF, { 0xA2,0xDE,0x00,0xAA,0x00,0xB9,0x33,0x56 } }; -#endif +#endif // wxUSE_DIRECTDRAW // ---------------------------------------------------------------------------- // typedefs for dynamically loaded Windows functions @@ -75,7 +83,7 @@ typedef LONG (WINAPI *ChangeDisplaySettingsEx_t)(LPCTSTR lpszDeviceName, DWORD dwFlags, LPVOID lParam); -#ifdef HAVE_DDRAW_H +#ifdef wxUSE_DIRECTDRAW typedef BOOL (PASCAL *DDEnumExCallback_t)(GUID *pGuid, LPTSTR driverDescription, LPTSTR driverName, @@ -89,37 +97,47 @@ typedef HRESULT (WINAPI *DirectDrawEnumerateEx_t)(DDEnumExCallback_t lpCallback, typedef HRESULT (WINAPI *DirectDrawCreate_t)(GUID *lpGUID, LPDIRECTDRAW *lplpDD, IUnknown *pUnkOuter); -#endif +#endif // wxUSE_DIRECTDRAW typedef BOOL (WINAPI *EnumDisplayMonitors_t)(HDC,LPCRECT,MONITORENUMPROC,LPARAM); typedef HMONITOR (WINAPI *MonitorFromPoint_t)(POINT,DWORD); typedef HMONITOR (WINAPI *MonitorFromWindow_t)(HWND,DWORD); typedef BOOL (WINAPI *GetMonitorInfo_t)(HMONITOR,LPMONITORINFO); -static EnumDisplayMonitors_t gs_EnumDisplayMonitors = NULL; -static MonitorFromPoint_t gs_MonitorFromPoint = NULL; -static MonitorFromWindow_t gs_MonitorFromWindow = NULL; -static GetMonitorInfo_t gs_GetMonitorInfo = NULL; +#ifndef __WXWINCE__ +// emulation of ChangeDisplaySettingsEx() for Win95 +LONG WINAPI ChangeDisplaySettingsExForWin95(LPCTSTR WXUNUSED(lpszDeviceName), + LPDEVMODE lpDevMode, + HWND WXUNUSED(hwnd), + DWORD dwFlags, + LPVOID WXUNUSED(lParam)) +{ + return ::ChangeDisplaySettings(lpDevMode, dwFlags); +} +#endif // !__WXWINCE__ // ---------------------------------------------------------------------------- -// private classes +// display information classes // ---------------------------------------------------------------------------- -class wxDisplayInfo +struct wxDisplayInfo { -public: - // handle of this monitor used by MonitorXXX() functions, never NULL - HMONITOR m_hmon; + wxDisplayInfo(HMONITOR hmon = NULL) + { + m_hmon = hmon; + m_flags = (DWORD)-1; + } - // IDirectDraw object used to control this display, may be NULL -#ifdef HAVE_DDRAW_H - IDirectDraw2 *m_pDD2; -#else - void *m_pDD2; -#endif + virtual ~wxDisplayInfo() { } - // DirectDraw GUID for this display, only valid when using DirectDraw - GUID m_guid; + + // use GetMonitorInfo() to fill in all of our fields if needed (i.e. if it + // hadn't been done before) + void Initialize(); + + + // handle of this monitor used by MonitorXXX() functions, never NULL + HMONITOR m_hmon; // the entire area of this monitor in virtual screen coordinates wxRect m_rect; @@ -128,576 +146,493 @@ public: // on demand by DoGetName() wxString m_devName; - wxDisplayInfo() { m_hmon = NULL; m_pDD2 = NULL; } - ~wxDisplayInfo() { -#ifdef HAVE_DDRAW_H - if ( m_pDD2 ) m_pDD2->Release(); -#endif - } -}; - -WX_DECLARE_OBJARRAY(wxDisplayInfo, wxDisplayInfoArray); -#include "wx/arrimpl.cpp" -WX_DEFINE_OBJARRAY(wxDisplayInfoArray); - -// this module is used to cleanup gs_displays array -class wxDisplayModule : public wxModule -{ -public: - virtual bool OnInit() { return true; } - virtual void OnExit(); - - DECLARE_DYNAMIC_CLASS(wxDisplayModule) + // the flags of this monitor, also used as initialization marker: if this + // is -1, GetMonitorInfo() hadn't been called yet + DWORD m_flags; }; -IMPLEMENT_DYNAMIC_CLASS(wxDisplayModule, wxModule) +WX_DEFINE_ARRAY_PTR(wxDisplayInfo *, wxDisplayInfoArray); // ---------------------------------------------------------------------------- -// globals +// common base class for all Win32 wxDisplayImpl versions // ---------------------------------------------------------------------------- -#ifdef HAVE_DDRAW_H -// do we use DirectX? -static bool gs_useDirectX = false; -#endif - -// Try to look up the functions needed for supporting multiple monitors. If -// they aren't available (probably because we're running on Win95 or NT4 which -// predate this API), set a flag which makes wxDisplay return results for a -// single screen. -static bool OsSupportsMultipleMonitors() +class wxDisplayImplWin32Base : public wxDisplayImpl { - static int isNewEnough = -1; - if ( isNewEnough == -1 ) +public: + wxDisplayImplWin32Base(size_t n, wxDisplayInfo& info) + : wxDisplayImpl(n), + m_info(info) { - isNewEnough = 0; - wxDynamicLibrary dllUser32(_T("user32.dll")); - // Check for one of the symbols to avoid logging errors just because - // we happen to be running on Win95 or NT4. - if ( dllUser32.IsLoaded() && - dllUser32.HasSymbol(wxT("EnumDisplayMonitors")) ) - { - // GetMonitorInfo has Unicode/ANSI variants, the others don't. - gs_EnumDisplayMonitors = (EnumDisplayMonitors_t) - dllUser32.GetSymbol(wxT("EnumDisplayMonitors")); - gs_MonitorFromPoint = (MonitorFromPoint_t) - dllUser32.GetSymbol(wxT("MonitorFromPoint")); - gs_MonitorFromWindow = (MonitorFromWindow_t) - dllUser32.GetSymbol(wxT("MonitorFromWindow")); - gs_GetMonitorInfo = (GetMonitorInfo_t) - dllUser32.GetSymbolAorW(wxT("GetMonitorInfo")); - if ( gs_EnumDisplayMonitors != NULL && - gs_MonitorFromPoint != NULL && - gs_MonitorFromWindow != NULL && - gs_GetMonitorInfo != NULL ) - { - isNewEnough = 1; - } - } } - return (isNewEnough != 0); -} -#ifdef HAVE_DDRAW_H -// dynamically resolved DirectDrawCreate() -static DirectDrawCreate_t gs_DirectDrawCreate = NULL; -#endif + virtual wxRect GetGeometry() const; + virtual wxString GetName() const; + virtual bool IsPrimary() const; -// this is not really MT-unsafe as wxDisplay is only going to be used from the -// main thread, i.e. we consider that it's a GUI class and so don't protect it -static wxDisplayInfoArray *gs_displays = NULL; + virtual wxVideoMode GetCurrentMode() const; -// =========================================================================== -// implementation -// =========================================================================== +protected: + // convert a DEVMODE to our wxVideoMode + static wxVideoMode ConvertToVideoMode(const DEVMODE& dm) + { + // note that dmDisplayFrequency may be 0 or 1 meaning "standard one" + // and although 0 is ok for us we don't want to return modes with 1hz + // refresh + return wxVideoMode(dm.dmPelsWidth, + dm.dmPelsHeight, + dm.dmBitsPerPel, + dm.dmDisplayFrequency > 1 ? dm.dmDisplayFrequency : 0); + } + + wxDisplayInfo& m_info; +}; // ---------------------------------------------------------------------------- -// callbacks for monitor/modes enumeration stuff +// common base class for all Win32 wxDisplayFactory versions // ---------------------------------------------------------------------------- -static BOOL CALLBACK wxmswMonitorEnumProc ( - HMONITOR hMonitor, // handle to display monitor - HDC WXUNUSED(hdcMonitor), // handle to monitor-appropriate device context - LPRECT lprcMonitor, // pointer to monitor intersection rectangle - LPARAM WXUNUSED(dwData) // data passed from EnumDisplayMonitors (unused) -) -{ - wxDisplayInfo *info = new wxDisplayInfo(); +// functions dynamically bound by wxDisplayFactoryWin32Base::Initialize() +static MonitorFromPoint_t gs_MonitorFromPoint = NULL; +static MonitorFromWindow_t gs_MonitorFromWindow = NULL; +static GetMonitorInfo_t gs_GetMonitorInfo = NULL; - // we need hMonitor to be able to map display id to it which is needed for - // MonitorXXX() functions, in particular MonitorFromPoint() - info->m_hmon = hMonitor; +class wxDisplayFactoryWin32Base : public wxDisplayFactory +{ +public: + virtual ~wxDisplayFactoryWin32Base(); - // we also store the display geometry - info->m_rect.SetX ( lprcMonitor->left ); - info->m_rect.SetY ( lprcMonitor->top ); - info->m_rect.SetWidth ( lprcMonitor->right - lprcMonitor->left ); - info->m_rect.SetHeight ( lprcMonitor->bottom - lprcMonitor->top ); + bool IsOk() const { return !m_displays.empty(); } - // now add this monitor to the array - gs_displays->Add(info); + virtual size_t GetCount() { return m_displays.size(); } + virtual int GetFromPoint(const wxPoint& pt); + virtual int GetFromWindow(wxWindow *window); - // continue the enumeration - return true; -} +protected: + // ctor checks if the current system supports multimon API and dynamically + // bind the functions we need if this is the case and sets + // ms_supportsMultimon if they're available + wxDisplayFactoryWin32Base(); -#ifdef HAVE_DDRAW_H -BOOL PASCAL -wxDDEnumExCallback(GUID *pGuid, - LPTSTR WXUNUSED(driverDescription), - LPTSTR driverName, - LPVOID WXUNUSED(lpContext), - HMONITOR hmon) -{ - if ( pGuid ) - { - wxDisplayInfo *info = new wxDisplayInfo(); + // delete all m_displays elements: can be called from the derived class + // dtor if it is important to do this before destroying it (as in + // wxDisplayFactoryDirectDraw case), otherwise will be done by our dtor + void Clear(); - info->m_hmon = hmon; - info->m_guid = *pGuid; - info->m_devName = driverName; + // find the monitor corresponding to the given handle, return wxNOT_FOUND + // if not found + int FindDisplayFromHMONITOR(HMONITOR hmon) const; - gs_displays->Add(info); - } - //else: we're called for the primary monitor, skip it - // continue the enumeration - return true; -} + // flag indicating whether gs_MonitorXXX functions are available + static int ms_supportsMultimon; -HRESULT WINAPI wxDDEnumModesCallback(LPDDSURFACEDESC lpDDSurfaceDesc, - LPVOID lpContext) -{ - // we need at least the mode size - static const DWORD FLAGS_REQUIRED = DDSD_HEIGHT | DDSD_WIDTH; - if ( (lpDDSurfaceDesc->dwFlags & FLAGS_REQUIRED) == FLAGS_REQUIRED ) - { - wxArrayVideoModes * const modes = (wxArrayVideoModes *)lpContext; + // the array containing information about all available displays, should be + // filled by the derived class ctors + wxDisplayInfoArray m_displays; - modes->Add(wxVideoMode(lpDDSurfaceDesc->dwWidth, - lpDDSurfaceDesc->dwHeight, - lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount, - lpDDSurfaceDesc->dwRefreshRate)); - } - // continue the enumeration - return DDENUMRET_OK; -} -#endif + DECLARE_NO_COPY_CLASS(wxDisplayFactoryWin32Base) +}; // ---------------------------------------------------------------------------- -// local functions +// wxDisplay implementation using Windows multi-monitor support functions // ---------------------------------------------------------------------------- -#ifdef HAVE_DDRAW_H -// initialize gs_displays using DirectX functions -static bool DoInitDirectX() +class wxDisplayImplMultimon : public wxDisplayImplWin32Base { -#if wxUSE_LOG - // suppress the errors if ddraw.dll is not found - wxLog::EnableLogging(false); -#endif +public: + wxDisplayImplMultimon(size_t n, wxDisplayInfo& info) + : wxDisplayImplWin32Base(n, info) + { + } - wxDynamicLibrary dllDX(_T("ddraw.dll")); + virtual wxArrayVideoModes GetModes(const wxVideoMode& mode) const; + virtual bool ChangeMode(const wxVideoMode& mode); -#if wxUSE_LOG - wxLog::EnableLogging(); -#endif +private: + DECLARE_NO_COPY_CLASS(wxDisplayImplMultimon) +}; - if ( !dllDX.IsLoaded() ) - return false; +class WXDLLEXPORT wxDisplayFactoryMultimon : public wxDisplayFactoryWin32Base +{ +public: + wxDisplayFactoryMultimon(); - DirectDrawEnumerateEx_t pDDEnumEx = (DirectDrawEnumerateEx_t) - dllDX.GetSymbolAorW(_T("DirectDrawEnumerateEx")); - if ( !pDDEnumEx ) - return false; + virtual wxDisplayImpl *CreateDisplay(size_t n); - // we'll also need DirectDrawCreate() later, resolve it right now - gs_DirectDrawCreate = (DirectDrawCreate_t) - dllDX.GetSymbol(_T("DirectDrawCreate")); - if ( !gs_DirectDrawCreate ) - return false; +private: + // EnumDisplayMonitors() callback + static BOOL CALLBACK MultimonEnumProc(HMONITOR hMonitor, + HDC hdcMonitor, + LPRECT lprcMonitor, + LPARAM dwData); - if ( (*pDDEnumEx)(wxDDEnumExCallback, - NULL, - DDENUM_ATTACHEDSECONDARYDEVICES) != DD_OK ) - { - return false; - } - // ok, it seems like we're going to use DirectDraw and so we're going to - // need ddraw.dll all the time, don't unload it - dllDX.Detach(); + // add a monitor description to m_displays array + void AddDisplay(HMONITOR hMonitor, LPRECT lprcMonitor); +}; - return true; -} -#endif +// ---------------------------------------------------------------------------- +// wxDisplay implementation using DirectDraw +// ---------------------------------------------------------------------------- -// initialize gs_displays using the standard Windows functions -static void DoInitStdWindows() +#ifdef wxUSE_DIRECTDRAW + +struct wxDisplayInfoDirectDraw : wxDisplayInfo { - // enumerate all displays - if ( !gs_EnumDisplayMonitors(NULL, NULL, wxmswMonitorEnumProc, 0) ) + wxDisplayInfoDirectDraw(const GUID& guid, HMONITOR hmon, LPTSTR name) + : wxDisplayInfo(hmon), + m_guid(guid) { - wxLogLastError(wxT("EnumDisplayMonitors")); + m_pDD2 = NULL; + m_devName = name; + } - // TODO: still create at least one (valid) entry in gs_displays for the - // primary display! + virtual ~wxDisplayInfoDirectDraw() + { + if ( m_pDD2 ) + m_pDD2->Release(); } -} -// this function must be called before accessing gs_displays array as it -// creates and initializes it -static void InitDisplays() -{ - if ( gs_displays ) - return; - gs_displays = new wxDisplayInfoArray(); + // IDirectDraw object used to control this display, may be NULL + IDirectDraw2 *m_pDD2; + + // DirectDraw GUID for this display, only valid when using DirectDraw + const GUID m_guid; + + + DECLARE_NO_COPY_CLASS(wxDisplayInfoDirectDraw) +}; -#ifdef HAVE_DDRAW_H - if ( !gs_useDirectX || !DoInitDirectX() ) +class wxDisplayImplDirectDraw : public wxDisplayImplWin32Base +{ +public: + wxDisplayImplDirectDraw(size_t n, wxDisplayInfo& info, IDirectDraw2 *pDD2) + : wxDisplayImplWin32Base(n, info), + m_pDD2(pDD2) { - // either we were told not to try to use DirectX or fall back to std - // functions if DirectX method failed - gs_useDirectX = false; + m_pDD2->AddRef(); + } - DoInitStdWindows(); + virtual ~wxDisplayImplDirectDraw() + { + m_pDD2->Release(); } -#else - DoInitStdWindows(); -#endif -} -// convert a DEVMODE to our wxVideoMode -wxVideoMode ConvertToVideoMode(const DEVMODE& dm) -{ - // note that dmDisplayFrequency may be 0 or 1 meaning "standard one" and - // although 0 is ok for us we don't want to return modes with 1hz refresh - return wxVideoMode(dm.dmPelsWidth, - dm.dmPelsHeight, - dm.dmBitsPerPel, - dm.dmDisplayFrequency > 1 ? dm.dmDisplayFrequency : 0); -} + virtual wxArrayVideoModes GetModes(const wxVideoMode& mode) const; + virtual bool ChangeMode(const wxVideoMode& mode); -#ifndef __WXWINCE__ -// emulation of ChangeDisplaySettingsEx() for Win95 -LONG WINAPI ChangeDisplaySettingsExForWin95(LPCTSTR WXUNUSED(lpszDeviceName), - LPDEVMODE lpDevMode, - HWND WXUNUSED(hwnd), - DWORD dwFlags, - LPVOID WXUNUSED(lParam)) -{ - return ::ChangeDisplaySettings(lpDevMode, dwFlags); -} -#endif // !__WXWINCE__ +private: + IDirectDraw2 *m_pDD2; -// ---------------------------------------------------------------------------- -// wxDisplayModule -// ---------------------------------------------------------------------------- + DECLARE_NO_COPY_CLASS(wxDisplayImplDirectDraw) +}; -void wxDisplayModule::OnExit() +class WXDLLEXPORT wxDisplayFactoryDirectDraw : public wxDisplayFactoryWin32Base { - delete gs_displays; -} +public: + wxDisplayFactoryDirectDraw(); + virtual ~wxDisplayFactoryDirectDraw(); -// --------------------------------------------------------------------------- -// wxDisplay -// --------------------------------------------------------------------------- + virtual wxDisplayImpl *CreateDisplay(size_t n); -/* static */ -void wxDisplay::UseDirectX(bool useDX) -{ - wxCHECK_RET( !gs_displays, _T("it is too late to call UseDirectX") ); +private: + // callback used with DirectDrawEnumerateEx() + static BOOL WINAPI DDEnumExCallback(GUID *pGuid, + LPTSTR driverDescription, + LPTSTR driverName, + LPVOID lpContext, + HMONITOR hmon); -#ifdef HAVE_DDRAW_H - // DirectDrawEnumerateEx requires Win98 or Win2k anyway. - if ( OsSupportsMultipleMonitors() ) gs_useDirectX = useDX; -#else - wxUnusedVar(useDX); -#endif -} + // add a monitor description to m_displays array + void AddDisplay(const GUID& guid, HMONITOR hmon, LPTSTR name); -// helper for GetFromPoint() and GetFromWindow() -static int DisplayFromHMONITOR(HMONITOR hmon) -{ - if ( hmon ) - { - const size_t count = wxDisplay::GetCount(); - for ( size_t n = 0; n < count; n++ ) - { - if ( hmon == (*gs_displays)[n].m_hmon ) - return n; - } - } + // ddraw.dll + wxDynamicLibrary m_dllDDraw; - return wxNOT_FOUND; -} + // dynamically resolved DirectDrawCreate() + DirectDrawCreate_t m_pfnDirectDrawCreate; -/* static */ -size_t wxDisplayBase::GetCount() -{ - if ( !OsSupportsMultipleMonitors() ) return 1; + DECLARE_NO_COPY_CLASS(wxDisplayFactoryDirectDraw) +}; - InitDisplays(); +#endif // wxUSE_DIRECTDRAW - //RN: FIXME: This is wrong - the display info array should reload after every call - //to GetCount() - otherwise it will not be accurate. - //The user can change the number of displays in display properties/settings - //after GetCount or similar is called and really mess this up... - //wxASSERT_MSG( gs_displays->GetCount() == (size_t)::GetSystemMetrics(SM_CMONITORS), - // _T("So how many displays does this system have?") ); - return gs_displays->GetCount(); -} +// ============================================================================ +// common classes implementation +// ============================================================================ -/* static */ -int wxDisplayBase::GetFromPoint ( const wxPoint& pt ) +// ---------------------------------------------------------------------------- +// wxDisplay +// ---------------------------------------------------------------------------- + +/* static */ wxDisplayFactory *wxDisplay::CreateFactory() { - if ( !OsSupportsMultipleMonitors() ) + // we have 2 implementations for modern Windows: one using standard Win32 + // and another using DirectDraw, the choice between them is done using a + // system option + if ( wxSystemOptions::GetOptionInt(_T("msw.display.directdraw")) ) { - const wxSize size = wxGetDisplaySize(); - if (pt.x >= 0 && pt.x < size.GetWidth() && - pt.y >= 0 && pt.y < size.GetHeight()) - { - return 0; - } - return wxNOT_FOUND; + wxDisplayFactoryDirectDraw *factoryDD = new wxDisplayFactoryDirectDraw; + if ( factoryDD->IsOk() ) + return factoryDD; + + delete factoryDD; } - POINT pt2; - pt2.x = pt.x; - pt2.y = pt.y; + wxDisplayFactoryMultimon *factoryMM = new wxDisplayFactoryMultimon; + if ( factoryMM->IsOk() ) + return factoryMM; - return DisplayFromHMONITOR(gs_MonitorFromPoint(pt2, MONITOR_DEFAULTTONULL)); + delete factoryMM; + + + // finally fall back to a stub implementation if all else failed (Win95?) + return new wxDisplayFactorySingle; } -/* static */ -int wxDisplayBase::GetFromWindow(wxWindow *window) +// ---------------------------------------------------------------------------- +// wxDisplayInfo +// ---------------------------------------------------------------------------- + +void wxDisplayInfo::Initialize() { - if ( !OsSupportsMultipleMonitors() ) + if ( m_flags == (DWORD)-1 ) { - const wxRect r(window->GetRect()); - const wxSize size = wxGetDisplaySize(); - if (r.x < size.GetWidth() && r.x + r.width >= 0 && - r.y < size.GetHeight() && r.y + r.height >= 0) + WinStruct monInfo; + if ( !gs_GetMonitorInfo(m_hmon, (LPMONITORINFO)&monInfo) ) { - return 0; + wxLogLastError(_T("GetMonitorInfo")); + m_flags = 0; + return; } - return wxNOT_FOUND; - } - return DisplayFromHMONITOR - ( - gs_MonitorFromWindow(GetHwndOf(window), MONITOR_DEFAULTTONULL) - ); + wxCopyRECTToRect(monInfo.rcMonitor, m_rect); + m_devName = monInfo.szDevice; + m_flags = monInfo.dwFlags; + } } // ---------------------------------------------------------------------------- -// wxDisplay ctor/dtor +// wxDisplayImplWin32Base // ---------------------------------------------------------------------------- -wxDisplay::wxDisplay ( size_t n ) - : wxDisplayBase ( n ) +wxRect wxDisplayImplWin32Base::GetGeometry() const { - if ( !OsSupportsMultipleMonitors() ) return; - - // if we do this in ctor we won't have to call it from all the member - // functions - InitDisplays(); + if ( m_info.m_rect.IsEmpty() ) + m_info.Initialize(); -#ifdef HAVE_DDRAW_H - if ( gs_useDirectX ) - { - wxDisplayInfo& dpyInfo = (*gs_displays)[n]; + return m_info.m_rect; +} - LPDIRECTDRAW2& pDD2 = dpyInfo.m_pDD2; - if ( !pDD2 ) - { - if ( !gs_DirectDrawCreate ) - { - // what to do?? - return; - } +wxString wxDisplayImplWin32Base::GetName() const +{ + if ( m_info.m_devName.IsEmpty() ) + m_info.Initialize(); - IDirectDraw *pDD; - HRESULT hr = (*gs_DirectDrawCreate)(&dpyInfo.m_guid, &pDD, NULL); + return m_info.m_devName; +} - if ( FAILED(hr) || !pDD ) - { - // what to do?? - wxLogApiError(_T("DirectDrawCreate"), hr); - } - else // got IDirectDraw, we want IDirectDraw2 - { - hr = pDD->QueryInterface(wxIID_IDirectDraw2, (void **)&pDD2); - if ( FAILED(hr) || !pDD2 ) - { - wxLogApiError(_T("IDirectDraw::QueryInterface(IDD2)"), hr); - } +bool wxDisplayImplWin32Base::IsPrimary() const +{ + if ( m_info.m_flags == (DWORD)-1 ) + m_info.Initialize(); - pDD->Release(); - } - } - //else: DirectDraw object corresponding to our display already exists - - // increment its ref count to account for Release() in dtor - // - // NB: pDD2 will be only really Release()d when gs_displays is - // destroyed which is ok as we don't want to recreate DD objects - // all the time - pDD2->AddRef(); - } -#endif + return (m_info.m_flags & MONITORINFOF_PRIMARY) != 0; } -wxDisplay::~wxDisplay() +wxVideoMode wxDisplayImplWin32Base::GetCurrentMode() const { -#ifdef HAVE_DDRAW_H - if ( !OsSupportsMultipleMonitors() ) return; + wxVideoMode mode; - wxDisplayInfo& dpyInfo = (*gs_displays)[m_index]; + // The first parameter of EnumDisplaySettings() must be NULL under Win95 + // according to MSDN. The version of GetName() we implement for Win95 + // returns an empty string. + const wxString name = GetName(); + const wxChar * const deviceName = name.empty() ? NULL : name.c_str(); - LPDIRECTDRAW2& pDD2 = dpyInfo.m_pDD2; - if ( pDD2 ) + DEVMODE dm; + dm.dmSize = sizeof(dm); + dm.dmDriverExtra = 0; + if ( !::EnumDisplaySettings(deviceName, ENUM_CURRENT_SETTINGS, &dm) ) { - pDD2->Release(); + wxLogLastError(_T("EnumDisplaySettings(ENUM_CURRENT_SETTINGS)")); } -#endif + else + { + mode = ConvertToVideoMode(dm); + } + + return mode; } // ---------------------------------------------------------------------------- -// wxDisplay simple accessors +// wxDisplayFactoryWin32Base // ---------------------------------------------------------------------------- -bool wxDisplay::IsOk() const -{ -#ifdef HAVE_DDRAW_H - return m_index < GetCount() && - (!gs_useDirectX || (*gs_displays)[m_index].m_pDD2); -#else - return m_index < GetCount(); -#endif -} +int wxDisplayFactoryWin32Base::ms_supportsMultimon = -1; -wxRect wxDisplay::GetGeometry() const +wxDisplayFactoryWin32Base::wxDisplayFactoryWin32Base() { - if ( !OsSupportsMultipleMonitors() ) + if ( ms_supportsMultimon == -1 ) { - wxSize size = wxGetDisplaySize(); - return wxRect(0, 0, size.GetWidth(), size.GetHeight()); - } + ms_supportsMultimon = 0; - wxDisplayInfo& dpyInfo = (*gs_displays)[m_index]; - wxRect& rect = dpyInfo.m_rect; - if ( !rect.width ) - { - MONITORINFO monInfo; - wxZeroMemory(monInfo); - monInfo.cbSize = sizeof(monInfo); + wxDynamicLibrary dllUser32(_T("user32.dll")); - if ( !gs_GetMonitorInfo(dpyInfo.m_hmon, &monInfo) ) - { - wxLogLastError(_T("GetMonitorInfo")); - } - else - { - wxCopyRECTToRect(monInfo.rcMonitor, rect); - } + wxLogNull noLog; + + gs_MonitorFromPoint = (MonitorFromPoint_t) + dllUser32.GetSymbol(wxT("MonitorFromPoint")); + if ( !gs_MonitorFromPoint ) + return; + + gs_MonitorFromWindow = (MonitorFromWindow_t) + dllUser32.GetSymbol(wxT("MonitorFromWindow")); + if ( !gs_MonitorFromWindow ) + return; + + gs_GetMonitorInfo = (GetMonitorInfo_t) + dllUser32.GetSymbolAorW(wxT("GetMonitorInfo")); + if ( !gs_GetMonitorInfo ) + return; + + ms_supportsMultimon = 1; + + // we can safely let dllUser32 go out of scope, the DLL itself will + // still remain loaded as all Win32 programs use it } +} - return rect; +void wxDisplayFactoryWin32Base::Clear() +{ + WX_CLEAR_ARRAY(m_displays); } -wxString wxDisplay::GetName() const +wxDisplayFactoryWin32Base::~wxDisplayFactoryWin32Base() { - if ( !OsSupportsMultipleMonitors() ) return wxT(""); + Clear(); +} - wxDisplayInfo& dpyInfo = (*gs_displays)[m_index]; - if ( dpyInfo.m_devName.empty() ) +// helper for GetFromPoint() and GetFromWindow() +int wxDisplayFactoryWin32Base::FindDisplayFromHMONITOR(HMONITOR hmon) const +{ + if ( hmon ) { - MONITORINFOEX monInfo; - wxZeroMemory(monInfo); - monInfo.cbSize = sizeof(monInfo); - - // NB: Cast from MONITORINFOEX* to MONITORINFO* is done because - // Mingw headers - unlike the ones from Microsoft's Platform SDK - - // don't derive the former from the latter in C++ mode and so - // the pointer's type is not converted implicitly. - if ( !gs_GetMonitorInfo(dpyInfo.m_hmon, (LPMONITORINFO)&monInfo) ) - { - wxLogLastError(_T("GetMonitorInfo")); - } - else + const size_t count = m_displays.size(); + for ( size_t n = 0; n < count; n++ ) { - dpyInfo.m_devName = monInfo.szDevice; + if ( hmon == m_displays[n]->m_hmon ) + return n; } } - return dpyInfo.m_devName; + return wxNOT_FOUND; } +int wxDisplayFactoryWin32Base::GetFromPoint(const wxPoint& pt) +{ + POINT pt2; + pt2.x = pt.x; + pt2.y = pt.y; + + return FindDisplayFromHMONITOR(gs_MonitorFromPoint(pt2, + MONITOR_DEFAULTTONULL)); +} + +int wxDisplayFactoryWin32Base::GetFromWindow(wxWindow *window) +{ + return FindDisplayFromHMONITOR(gs_MonitorFromWindow(GetHwndOf(window), + MONITOR_DEFAULTTONULL)); +} + +// ============================================================================ +// wxDisplay implementation using Win32 multimon API +// ============================================================================ + // ---------------------------------------------------------------------------- -// determine if this is the primary display +// wxDisplayFactoryMultimon initialization // ---------------------------------------------------------------------------- -bool wxDisplay::IsPrimary() const +wxDisplayFactoryMultimon::wxDisplayFactoryMultimon() { - if ( !OsSupportsMultipleMonitors() ) return true; + if ( !ms_supportsMultimon ) + return; - wxDisplayInfo& dpyInfo = (*gs_displays)[m_index]; + // look up EnumDisplayMonitors() which we don't need with DirectDraw + // implementation + EnumDisplayMonitors_t pfnEnumDisplayMonitors; + { + wxLogNull noLog; - MONITORINFOEX monInfo; - wxZeroMemory(monInfo); - monInfo.cbSize = sizeof(monInfo); + wxDynamicLibrary dllUser32(_T("user32.dll")); + pfnEnumDisplayMonitors = (EnumDisplayMonitors_t) + dllUser32.GetSymbol(wxT("EnumDisplayMonitors")); + if ( !pfnEnumDisplayMonitors ) + return; + } - // NB: Cast from MONITORINFOEX* to MONITORINFO* is done because - // Mingw headers - unlike the ones from Microsoft's Platform SDK - - // don't derive the former from the latter in C++ mode and so - // the pointer's type is not converted implicitly. - if ( !gs_GetMonitorInfo(dpyInfo.m_hmon, (LPMONITORINFO)&monInfo) ) + // enumerate all displays + if ( !pfnEnumDisplayMonitors(NULL, NULL, MultimonEnumProc, (LPARAM)this) ) { - wxLogLastError(_T("GetMonitorInfo")); + wxLogLastError(wxT("EnumDisplayMonitors")); } +} + +/* static */ +BOOL CALLBACK +wxDisplayFactoryMultimon::MultimonEnumProc( + HMONITOR hMonitor, // handle to display monitor + HDC WXUNUSED(hdcMonitor), // handle to monitor-appropriate device context + LPRECT lprcMonitor, // pointer to monitor intersection rectangle + LPARAM dwData // data passed from EnumDisplayMonitors (this) +) +{ + wxDisplayFactoryMultimon *const self = (wxDisplayFactoryMultimon *)dwData; + self->AddDisplay(hMonitor, lprcMonitor); - return (monInfo.dwFlags & MONITORINFOF_PRIMARY) == MONITORINFOF_PRIMARY; + // continue the enumeration + return TRUE; } // ---------------------------------------------------------------------------- -// video modes enumeration +// wxDisplayFactoryMultimon helper functions // ---------------------------------------------------------------------------- -#ifdef HAVE_DDRAW_H -wxArrayVideoModes -wxDisplay::DoGetModesDirectX(const wxVideoMode& WXUNUSED(modeMatch)) const +void wxDisplayFactoryMultimon::AddDisplay(HMONITOR hMonitor, LPRECT lprcMonitor) { - wxArrayVideoModes modes; + wxDisplayInfo *info = new wxDisplayInfo(hMonitor); - IDirectDraw2 *pDD = (*gs_displays)[m_index].m_pDD2; + // we also store the display geometry + info->m_rect = wxRect(lprcMonitor->left, lprcMonitor->top, + lprcMonitor->right - lprcMonitor->left, + lprcMonitor->bottom - lprcMonitor->top); - if ( pDD ) - { - HRESULT hr = pDD->EnumDisplayModes - ( - DDEDM_REFRESHRATES, - NULL, // all modes (TODO: use modeMatch!) - &modes, // callback parameter - wxDDEnumModesCallback - ); + // now add this monitor to the array + m_displays.Add(info); +} - if ( FAILED(hr) ) - { - wxLogApiError(_T("IDirectDraw::EnumDisplayModes"), hr); - } - } +// ---------------------------------------------------------------------------- +// wxDisplayFactoryMultimon inherited pure virtuals implementation +// ---------------------------------------------------------------------------- - return modes; +wxDisplayImpl *wxDisplayFactoryMultimon::CreateDisplay(size_t n) +{ + wxCHECK_MSG( n < m_displays.size(), NULL, _T("invalid display index") ); + + return new wxDisplayImplMultimon(n, *(m_displays[n])); } -#endif + +// ---------------------------------------------------------------------------- +// wxDisplayImplMultimon implementation +// ---------------------------------------------------------------------------- wxArrayVideoModes -wxDisplay::DoGetModesWindows(const wxVideoMode& modeMatch) const +wxDisplayImplMultimon::GetModes(const wxVideoMode& modeMatch) const { wxArrayVideoModes modes; @@ -724,81 +659,7 @@ wxDisplay::DoGetModesWindows(const wxVideoMode& modeMatch) const return modes; } -wxArrayVideoModes wxDisplay::GetModes(const wxVideoMode& modeMatch) const -{ -#ifdef HAVE_DDRAW_H - return gs_useDirectX ? DoGetModesDirectX(modeMatch) - : DoGetModesWindows(modeMatch); -#else - return DoGetModesWindows(modeMatch); -#endif -} - -wxVideoMode wxDisplay::GetCurrentMode() const -{ - wxVideoMode mode; - - // The first parameter of EnumDisplaySettings() must be NULL under Win95 - // according to MSDN. The version of GetName() we implement for Win95 - // returns an empty string. - const wxString name = GetName(); - const wxChar * const deviceName = name.empty() ? NULL : name.c_str(); - - DEVMODE dm; - dm.dmSize = sizeof(dm); - dm.dmDriverExtra = 0; - if ( !::EnumDisplaySettings(deviceName, ENUM_CURRENT_SETTINGS, &dm) ) - { - wxLogLastError(_T("EnumDisplaySettings(ENUM_CURRENT_SETTINGS)")); - } - else - { - mode = ConvertToVideoMode(dm); - } - - return mode; -} - -// ---------------------------------------------------------------------------- -// video mode switching -// ---------------------------------------------------------------------------- - -#ifdef HAVE_DDRAW_H -bool wxDisplay::DoChangeModeDirectX(const wxVideoMode& mode) -{ - IDirectDraw2 *pDD = (*gs_displays)[m_index].m_pDD2; - if ( !pDD ) - return false; - - wxWindow *winTop = wxTheApp->GetTopWindow(); - wxCHECK_MSG( winTop, false, _T("top level window required for DirectX") ); - - HRESULT hr = pDD->SetCooperativeLevel - ( - GetHwndOf(winTop), - DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN - ); - if ( FAILED(hr) ) - { - wxLogApiError(_T("IDirectDraw::SetCooperativeLevel"), hr); - - return false; - } - - hr = pDD->SetDisplayMode(mode.w, mode.h, mode.bpp, mode.refresh, 0); - if ( FAILED(hr) ) - { - wxLogApiError(_T("IDirectDraw::SetDisplayMode"), hr); - - return false; - } - - - return true; -} -#endif - -bool wxDisplay::DoChangeModeWindows(const wxVideoMode& mode) +bool wxDisplayImplMultimon::ChangeMode(const wxVideoMode& mode) { // prepare ChangeDisplaySettingsEx() parameters DEVMODE dm; @@ -908,14 +769,243 @@ bool wxDisplay::DoChangeModeWindows(const wxVideoMode& mode) return false; } -bool wxDisplay::ChangeMode(const wxVideoMode& mode) + +// ============================================================================ +// DirectDraw-based wxDisplay implementation +// ============================================================================ + +#if wxUSE_DIRECTDRAW + +// ---------------------------------------------------------------------------- +// wxDisplayFactoryDirectDraw initialization +// ---------------------------------------------------------------------------- + +wxDisplayFactoryDirectDraw::wxDisplayFactoryDirectDraw() { -#ifdef HAVE_DDRAW_H - return gs_useDirectX ? DoChangeModeDirectX(mode) - : DoChangeModeWindows(mode); -#else - return DoChangeModeWindows(mode); + if ( !ms_supportsMultimon ) + return; + +#if wxUSE_LOG + // suppress the errors if ddraw.dll is not found, we're prepared to handle + // this + wxLogNull noLog; #endif + + m_dllDDraw.Load(_T("ddraw.dll")); + + if ( !m_dllDDraw.IsLoaded() ) + return; + + DirectDrawEnumerateEx_t pDDEnumEx = (DirectDrawEnumerateEx_t) + m_dllDDraw.GetSymbolAorW(_T("DirectDrawEnumerateEx")); + if ( !pDDEnumEx ) + return; + + // we can't continue without DirectDrawCreate() later, so resolve it right + // now and fail the initialization if it's not available + m_pfnDirectDrawCreate = (DirectDrawCreate_t) + m_dllDDraw.GetSymbol(_T("DirectDrawCreate")); + if ( !m_pfnDirectDrawCreate ) + return; + + if ( (*pDDEnumEx)(DDEnumExCallback, + this, + DDENUM_ATTACHEDSECONDARYDEVICES) != DD_OK ) + { + wxLogLastError(_T("DirectDrawEnumerateEx")); + } +} + +wxDisplayFactoryDirectDraw::~wxDisplayFactoryDirectDraw() +{ + // we must clear m_displays now, before m_dllDDraw is unloaded as otherwise + // calling m_pDD2->Release() later would crash + Clear(); +} + +// ---------------------------------------------------------------------------- +// callbacks for monitor/modes enumeration stuff +// ---------------------------------------------------------------------------- + +BOOL WINAPI +wxDisplayFactoryDirectDraw::DDEnumExCallback(GUID *pGuid, + LPTSTR WXUNUSED(driverDescription), + LPTSTR driverName, + LPVOID lpContext, + HMONITOR hmon) +{ + if ( pGuid ) + { + wxDisplayFactoryDirectDraw * self = + wx_static_cast(wxDisplayFactoryDirectDraw *, lpContext); + self->AddDisplay(*pGuid, hmon, driverName); + } + //else: we're called for the primary monitor, skip it + + // continue the enumeration + return TRUE; +} + +// ---------------------------------------------------------------------------- +// wxDisplayFactoryDirectDraw helpers +// ---------------------------------------------------------------------------- + +void wxDisplayFactoryDirectDraw::AddDisplay(const GUID& guid, + HMONITOR hmon, + LPTSTR name) +{ + m_displays.Add(new wxDisplayInfoDirectDraw(guid, hmon, name)); +} + +// ---------------------------------------------------------------------------- +// wxDisplayFactoryDirectDraw inherited pure virtuals implementation +// ---------------------------------------------------------------------------- + +wxDisplayImpl *wxDisplayFactoryDirectDraw::CreateDisplay(size_t n) +{ + wxCHECK_MSG( n < m_displays.size(), NULL, _T("invalid display index") ); + + wxDisplayInfoDirectDraw * + info = wx_static_cast(wxDisplayInfoDirectDraw *, m_displays[n]); + + if ( !info->m_pDD2 ) + { + IDirectDraw *pDD; + GUID guid(info->m_guid); + HRESULT hr = (*m_pfnDirectDrawCreate)(&guid, &pDD, NULL); + + if ( FAILED(hr) || !pDD ) + { + // what to do?? + wxLogApiError(_T("DirectDrawCreate"), hr); + return NULL; + } + + // we got IDirectDraw, but we need IDirectDraw2 + hr = pDD->QueryInterface(wxIID_IDirectDraw2, (void **)&info->m_pDD2); + pDD->Release(); + + if ( FAILED(hr) || !info->m_pDD2 ) + { + wxLogApiError(_T("IDirectDraw::QueryInterface(IDD2)"), hr); + return NULL; + } + + // NB: m_pDD2 will now be only destroyed when m_displays is destroyed + // which is ok as we don't want to recreate DD objects all the time + } + //else: DirectDraw object corresponding to our display already exists + + return new wxDisplayImplDirectDraw(n, *info, info->m_pDD2); +} + +// ============================================================================ +// wxDisplayImplDirectDraw +// ============================================================================ + +// ---------------------------------------------------------------------------- +// video modes enumeration +// ---------------------------------------------------------------------------- + +// tiny helper class used to pass information from GetModes() to +// wxDDEnumModesCallback +class wxDDVideoModesAdder +{ +public: + // our Add() method will add modes matching modeMatch to modes array + wxDDVideoModesAdder(wxArrayVideoModes& modes, const wxVideoMode& modeMatch) + : m_modes(modes), + m_modeMatch(modeMatch) + { + } + + void Add(const wxVideoMode& mode) + { + if ( mode.Matches(m_modeMatch) ) + m_modes.Add(mode); + } + +private: + wxArrayVideoModes& m_modes; + const wxVideoMode& m_modeMatch; + + DECLARE_NO_COPY_CLASS(wxDDVideoModesAdder) +}; + +HRESULT WINAPI wxDDEnumModesCallback(LPDDSURFACEDESC lpDDSurfaceDesc, + LPVOID lpContext) +{ + // we need at least the mode size + static const DWORD FLAGS_REQUIRED = DDSD_HEIGHT | DDSD_WIDTH; + if ( (lpDDSurfaceDesc->dwFlags & FLAGS_REQUIRED) == FLAGS_REQUIRED ) + { + wxDDVideoModesAdder * const vmodes = + wx_static_cast(wxDDVideoModesAdder *, lpContext); + + vmodes->Add(wxVideoMode(lpDDSurfaceDesc->dwWidth, + lpDDSurfaceDesc->dwHeight, + lpDDSurfaceDesc->ddpfPixelFormat.dwRGBBitCount, + lpDDSurfaceDesc->dwRefreshRate)); + } + + // continue the enumeration + return DDENUMRET_OK; +} + +wxArrayVideoModes +wxDisplayImplDirectDraw::GetModes(const wxVideoMode& modeMatch) const +{ + wxArrayVideoModes modes; + wxDDVideoModesAdder modesAdder(modes, modeMatch); + + HRESULT hr = m_pDD2->EnumDisplayModes + ( + DDEDM_REFRESHRATES, + NULL, // all modes + &modesAdder, // callback parameter + wxDDEnumModesCallback + ); + + if ( FAILED(hr) ) + { + wxLogApiError(_T("IDirectDraw::EnumDisplayModes"), hr); + } + + return modes; } +// ---------------------------------------------------------------------------- +// video mode switching +// ---------------------------------------------------------------------------- + +bool wxDisplayImplDirectDraw::ChangeMode(const wxVideoMode& mode) +{ + wxWindow *winTop = wxTheApp->GetTopWindow(); + wxCHECK_MSG( winTop, false, _T("top level window required for DirectX") ); + + HRESULT hr = m_pDD2->SetCooperativeLevel + ( + GetHwndOf(winTop), + DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN + ); + if ( FAILED(hr) ) + { + wxLogApiError(_T("IDirectDraw2::SetCooperativeLevel"), hr); + + return false; + } + + hr = m_pDD2->SetDisplayMode(mode.w, mode.h, mode.bpp, mode.refresh, 0); + if ( FAILED(hr) ) + { + wxLogApiError(_T("IDirectDraw2::SetDisplayMode"), hr); + + return false; + } + + return true; +} + +#endif // wxUSE_DIRECTDRAW + #endif // wxUSE_DISPLAY diff --git a/src/os2/display.cpp b/src/os2/display.cpp deleted file mode 100644 index 3c5b64b16b..0000000000 --- a/src/os2/display.cpp +++ /dev/null @@ -1,87 +0,0 @@ -/////////////////////////////////////////////////////////////////////////// -// Name: displayx11.cpp -// Purpose: Unix/X11 implementation of wxDisplay class -// Author: Brian Victor -// Modified by: -// Created: 12/05/02 -// RCS-ID: $Id$ -// Copyright: (c) wxWidgets team -// Licence: wxWindows licence -///////////////////////////////////////////////////////////////////////////// - -// For compilers that support precompilation, includes "wx.h". -#include "wx/wxprec.h" - -#ifdef __BORLANDC__ - #pragma hdrstop -#endif - -#include "wx/display.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" -#endif /* WX_PRECOMP */ - -#if wxUSE_DISPLAY - -size_t wxDisplayBase::GetCount() -{ - return 1; -} - -int wxDisplayBase::GetFromPoint(const wxPoint &p) -{ - return -1; -} - -wxDisplay::wxDisplay(size_t index) -: wxDisplayBase ( index ) -{ -} - -wxDisplay::~wxDisplay() -{ -} - -wxRect wxDisplay::GetGeometry() const -{ - wxRect vRect(0,0,0,0); - - return vRect; -} - -int wxDisplay::GetDepth() const -{ - return 24; -} - -wxString wxDisplay::GetName() const -{ - return wxEmptyString; -} - - -wxArrayVideoModes wxDisplay::GetModes(const wxVideoMode& mode) const -{ - wxArrayVideoModes modes; - return modes; -} - -wxVideoMode wxDisplay::GetCurrentMode() const -{ - // Not implemented - return wxVideoMode(); -} - -bool wxDisplay::ChangeMode(const wxVideoMode& mode) -{ - // Not implemented - return false; -} - -#endif /* wxUSE_DISPLAY */ diff --git a/src/palmos/display.cpp b/src/palmos/display.cpp deleted file mode 100644 index 37035300ed..0000000000 --- a/src/palmos/display.cpp +++ /dev/null @@ -1,272 +0,0 @@ -///////////////////////////////////////////////////////////////////////////// -// Name: src/palmos/display.cpp -// Purpose: Palm OS Implementation of wxDisplay class -// Author: William Osborne - minimal working wxPalmOS port -// Modified by: -// Created: 10.13.04 -// RCS-ID: $Id$ -// Copyright: (c) William Osborne -// Licence: wxWindows licence -///////////////////////////////////////////////////////////////////////////// - -// =========================================================================== -// declarations -// =========================================================================== - -// --------------------------------------------------------------------------- -// headers -// --------------------------------------------------------------------------- - -// For compilers that support precompilation, includes "wx.h". -#include "wx/wxprec.h" - -#ifdef __BORLANDC__ - #pragma hdrstop -#endif - -#if wxUSE_DISPLAY - -#ifndef WX_PRECOMP - #include "wx/app.h" - #include "wx/dynarray.h" - #include "wx/frame.h" -#endif - -#include "wx/dynload.h" - -#include "wx/display.h" - -// ---------------------------------------------------------------------------- -// macros -// ---------------------------------------------------------------------------- - -#ifdef _UNICODE - #define WINFUNC(x) _T(#x) L"W" -#else - #define WINFUNC(x) #x "A" -#endif - -// ---------------------------------------------------------------------------- -// private classes -// ---------------------------------------------------------------------------- - -class wxDisplayInfo -{ -public: - // handle of this monitor used by MonitorXXX() functions, never NULL - HMONITOR m_hmon; - - // IDirectDraw object used to control this display, may be NULL - IDirectDraw2 *m_pDD2; - - // DirectDraw GUID for this display, only valid when using DirectDraw - GUID m_guid; - - // the entire area of this monitor in virtual screen coordinates - wxRect m_rect; - - // the display device name for this monitor, empty initially and retrieved - // on demand by DoGetName() - wxString m_devName; - - wxDisplayInfo() { m_hmon = NULL; m_pDD2 = NULL; } - ~wxDisplayInfo() { if ( m_pDD2 ) m_pDD2->Release(); } -}; - -WX_DECLARE_OBJARRAY(wxDisplayInfo, wxDisplayInfoArray); -#include "wx/arrimpl.cpp" -WX_DEFINE_OBJARRAY(wxDisplayInfoArray); - -// this module is used to cleanup gs_displays array -class wxDisplayModule : public wxModule -{ -public: - virtual bool OnInit() { return true; } - virtual void OnExit(); - - DECLARE_DYNAMIC_CLASS(wxDisplayModule) -}; - -IMPLEMENT_DYNAMIC_CLASS(wxDisplayModule, wxModule) - -// ---------------------------------------------------------------------------- -// globals -// ---------------------------------------------------------------------------- - -// this is not really MT-unsafe as wxDisplay is only going to be used from the -// main thread, i.e. we consider that it's a GUI class and so don't protect it -static wxDisplayInfoArray *gs_displays = NULL; - -// =========================================================================== -// implementation -// =========================================================================== - -// ---------------------------------------------------------------------------- -// local functions -// ---------------------------------------------------------------------------- - -// initialize gs_displays using DirectX functions -static bool DoInitDirectX() -{ - return false; -} - -// initialize gs_displays using the standard Windows functions -static void DoInitStdWindows() -{ -} - -// this function must be called before accessing gs_displays array as it -// creates and initializes it -static void InitDisplays() -{ -} - -// convert a DEVMODE to our wxVideoMode -wxVideoMode ConvertToVideoMode(const DEVMODE& dm) -{ - return wxVideoMode(160, - 160, - 16, - 0); -} - -// ---------------------------------------------------------------------------- -// wxDisplayModule -// ---------------------------------------------------------------------------- - -void wxDisplayModule::OnExit() -{ -} - -// --------------------------------------------------------------------------- -// wxDisplay -// --------------------------------------------------------------------------- - -/* static */ -void wxDisplay::UseDirectX(bool useDX) -{ -} - -// helper of GetFromPoint() and GetFromWindow() -static int DisplayFromHMONITOR(HMONITOR hmon) -{ - return wxNOT_FOUND; -} - -/* static */ -size_t wxDisplayBase::GetCount() -{ - return 0; -} - -/* static */ -int wxDisplayBase::GetFromPoint ( const wxPoint& pt ) -{ - return 0; -} - -/* static */ -int wxDisplayBase::GetFromWindow(wxWindow *window) -{ - return 0; -} - -// ---------------------------------------------------------------------------- -// wxDisplay ctor/dtor -// ---------------------------------------------------------------------------- - -wxDisplay::wxDisplay ( size_t n ) - : wxDisplayBase ( n ) -{ -} - -wxDisplay::~wxDisplay() -{ -} - -// ---------------------------------------------------------------------------- -// wxDisplay simple accessors -// ---------------------------------------------------------------------------- - -bool wxDisplay::IsOk() const -{ - return false; -} - -wxRect wxDisplay::GetGeometry() const -{ - wxRect rect; - - return rect; -} - -wxString wxDisplay::GetName() const -{ - wxString ret; - - return ret; -} - -wxString wxDisplay::GetNameForEnumSettings() const -{ - wxString ret; - - return ret; -} - -// ---------------------------------------------------------------------------- -// video modes enumeration -// ---------------------------------------------------------------------------- - -wxArrayVideoModes -wxDisplay::DoGetModesDirectX(const wxVideoMode& WXUNUSED(modeMatch)) const -{ - wxArrayVideoModes modes; - - return modes; -} - -wxArrayVideoModes -wxDisplay::DoGetModesWindows(const wxVideoMode& modeMatch) const -{ - wxArrayVideoModes modes; - - return modes; -} - -wxArrayVideoModes wxDisplay::GetModes(const wxVideoMode& modeMatch) const -{ - return gs_useDirectX ? DoGetModesDirectX(modeMatch) - : DoGetModesWindows(modeMatch); -} - -wxVideoMode wxDisplay::GetCurrentMode() const -{ - wxVideoMode mode; - - return mode; -} - -// ---------------------------------------------------------------------------- -// video mode switching -// ---------------------------------------------------------------------------- - -bool wxDisplay::DoChangeModeDirectX(const wxVideoMode& mode) -{ - return false; -} - -bool wxDisplay::DoChangeModeWindows(const wxVideoMode& mode) -{ - return false; -} - -bool wxDisplay::ChangeMode(const wxVideoMode& mode) -{ - return gs_useDirectX ? DoChangeModeDirectX(mode) - : DoChangeModeWindows(mode); -} - -#endif // wxUSE_DISPLAY - diff --git a/src/unix/displayx11.cpp b/src/unix/displayx11.cpp index 341ce07819..fdd1dc18b5 100644 --- a/src/unix/displayx11.cpp +++ b/src/unix/displayx11.cpp @@ -1,7 +1,7 @@ /////////////////////////////////////////////////////////////////////////// -// Name: displayx11.cpp +// Name: src/unix/displayx11.cpp // Purpose: Unix/X11 implementation of wxDisplay class -// Author: Brian Victor +// Author: Brian Victor, Vadim Zeitlin // Modified by: // Created: 12/05/02 // RCS-ID: $Id$ @@ -9,6 +9,14 @@ // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// +// ============================================================================ +// declarations +// ============================================================================ + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- + // For compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" @@ -17,6 +25,7 @@ #endif #include "wx/display.h" +#include "wx/display_impl.h" #include "wx/intl.h" #include "wx/log.h" @@ -31,132 +40,119 @@ /* These must be included after the wx files. Otherwise the Data macro in * Xlibint.h conflicts with a function declaration in wx/list.h. */ -extern "C" { - #include -#ifndef __VMS - #include -# include -#ifdef HAVE_X11_EXTENSIONS_XF86VMODE_H - #include -#endif -#endif -} - -class wxDisplayUnixPriv +extern "C" { - public: - wxRect m_rect; - int m_depth; -}; + #include + #include -size_t wxDisplayBase::GetCount() -{ - Display *disp = (Display*)wxGetDisplay(); - -#ifndef __VMS - if ( XineramaIsActive(disp) ) - { - XineramaScreenInfo *screenarr; - int numscreens; - screenarr = XineramaQueryScreens(disp, &numscreens); - XFree(screenarr); - return numscreens; - } - else -#endif - { - return 1; - } + #include + #ifdef HAVE_X11_EXTENSIONS_XF86VMODE_H + #include + #endif } -int wxDisplayBase::GetFromPoint(const wxPoint &p) +// ---------------------------------------------------------------------------- +// helper class to automatically free XineramaQueryScreens() return value +// ---------------------------------------------------------------------------- + +class ScreensInfo { - Display *disp = (Display*)wxGetDisplay(); - -#ifndef __VMS - if ( XineramaIsActive(disp) ) - { - int which_screen = -1; - XineramaScreenInfo *screenarr; - int numscreens; - screenarr = XineramaQueryScreens(disp, &numscreens); - - int i; - for (i = 0; i < numscreens; ++i) +public: + ScreensInfo() { - if (p.x >= screenarr[i].x_org && - p.x < screenarr[i].x_org + screenarr[i].width && - p.y >= screenarr[i].y_org && - p.y < screenarr[i].y_org + screenarr[i].height) - { - which_screen = i; - } + m_screens = XineramaQueryScreens((Display *)wxGetDisplay(), &m_num); } - XFree(screenarr); - return which_screen; - } - else -#endif - { - wxSize size = wxGetDisplaySize(); - if (p.x >= 0 && - p.x < size.GetWidth() && - p.y >= 0 && - p.y < size.GetHeight()) + ~ScreensInfo() { - return 0; + XFree(m_screens); } - return -1; - } -} + operator const XineramaScreenInfo *() const { return m_screens; } + + size_t GetCount() const { return wx_static_cast(size_t, m_num); } + +private: + XineramaScreenInfo *m_screens; + int m_num; +}; + +// ---------------------------------------------------------------------------- +// display and display factory classes +// ---------------------------------------------------------------------------- -wxDisplay::wxDisplay(size_t index) : wxDisplayBase ( index ), m_priv( new wxDisplayUnixPriv ) +class WXDLLEXPORT wxDisplayImplX11 : public wxDisplayImpl { - Display *disp = (Display*)wxGetDisplay(); - -#ifndef __VMS - if ( XineramaIsActive(disp) ) - { - XineramaScreenInfo *screenarr; - int numscreens; - screenarr = XineramaQueryScreens(disp, &numscreens); - - m_priv->m_rect = wxRect(screenarr[index].x_org, screenarr[index].y_org, - screenarr[index].width, screenarr[index].height); - m_priv->m_depth = DefaultDepth(disp, DefaultScreen(disp)); - XFree(screenarr); - } - else -#endif - { - wxSize size = wxGetDisplaySize(); - m_priv->m_rect = wxRect(0, 0, size.GetWidth(), size.GetHeight()); - m_priv->m_depth = wxDisplayDepth(); - } -} +public: + wxDisplayImplX11(const XineramaScreenInfo& info) + : m_rect(info.x_org, info.y_org, info.width, info.height) + { + } -wxDisplay::~wxDisplay() + virtual wxRect GetGeometry() const { return m_rect; } + virtual wxString GetName() const { return wxString(); } + + virtual wxArrayVideoModes GetModes(const wxVideoMode& mode) const; + virtual wxVideoMode GetCurrentMode() const; + virtual bool ChangeMode(const wxVideoMode& mode); + +private: + wxRect m_rect; + int m_depth; + + DECLARE_NO_COPY_CLASS(wxDisplayImplX11) +}; + +class wxDisplayFactoryX11 : public wxDisplayFactory { - delete m_priv; -} +public: + wxDisplayFactoryX11(); + + virtual wxDisplayImpl *CreateDisplay(size_t n); + virtual size_t GetCount(); + virtual int GetFromPoint(const wxPoint& pt); -wxRect wxDisplay::GetGeometry() const +protected: + DECLARE_NO_COPY_CLASS(wxDisplayFactoryX11) +}; + +// ============================================================================ +// wxDisplayFactoryX11 implementation +// ============================================================================ + +size_t wxDisplayFactoryX11::GetCount() { - return m_priv->m_rect; + return ScreensInfo().GetCount(); } -int wxDisplay::GetDepth() const +int wxDisplayFactoryX11::GetFromPoint(const wxPoint& p) { - return m_priv->m_depth; + ScreensInfo screens; + + const size_t numscreens(screens.GetCount()); + for ( size_t i = 0; i < numscreens; ++i ) + { + const XineramaScreenInfo& s = screens[i]; + if ( p.x >= s.x_org && p.x < s.x_org + s.width && + p.y >= s.y_org && p.y < s.y_org + s.height ) + { + return i; + } + } + + return wxNOT_FOUND; } -wxString wxDisplay::GetName() const +wxDisplayImpl *wxDisplayFactoryX11::CreateDisplay(size_t n) { - return wxEmptyString; + ScreensInfo screens; + + return n < screens.GetCount() ? new wxDisplayImplX11(screens[n]) : NULL; } +// ============================================================================ +// wxDisplayImplX11 implementation +// ============================================================================ #ifdef HAVE_X11_EXTENSIONS_XF86VMODE_H @@ -269,19 +265,19 @@ bool wxDisplay::ChangeMode(const wxVideoMode& mode) wxArrayVideoModes wxDisplay::GetModes(const wxVideoMode& mode) const { - Display *disp = (Display*)wxGetDisplay(); - int count_return; - int* depths = XListDepths(disp, 0, &count_return); - wxArrayVideoModes modes; - if (depths) - { - int x; - for (x = 0; x < count_return; ++x) + int count_return; + int* depths = XListDepths((Display*)wxGetDisplay(), 0, &count_return); + wxArrayVideoModes modes; + if ( depths ) { - modes.Add(wxVideoMode(m_priv->m_rect.GetWidth(), m_priv->m_rect.GetHeight(), depths[x])); + for ( int x = 0; x < count_return; ++x ) + { + modes.Add(wxVideoMode(m_rect.GetWidth(), m_rect.GetHeight(), depths[x])); + } + + XFree(depths); } - } - return modes; + return modes; } wxVideoMode wxDisplay::GetCurrentMode() const @@ -298,4 +294,16 @@ bool wxDisplay::ChangeMode(const wxVideoMode& mode) #endif // !HAVE_X11_EXTENSIONS_XF86VMODE_H +// ============================================================================ +// wxDisplay::CreateFactory() +// ============================================================================ + +/* static */ wxDisplayFactory *wxDisplay::CreateFactory() +{ + Display *disp = (Display*)wxGetDisplay(); + + return XineramaIsActive(disp) ? new wxDisplayFactoryX11 + : new wxDisplayFactorySingle; +} + #endif /* wxUSE_DISPLAY */ -- 2.45.2