wxDisplay cleanup/rewrite:
authorVadim Zeitlin <vadim@wxwidgets.org>
Thu, 16 Mar 2006 04:23:07 +0000 (04:23 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Thu, 16 Mar 2006 04:23:07 +0000 (04:23 +0000)
- 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

23 files changed:
include/wx/cocoa/display.h [deleted file]
include/wx/display.h
include/wx/display_impl.h [new file with mode: 0644]
include/wx/mac/carbon/display.h [deleted file]
include/wx/mac/classic/display.h [deleted file]
include/wx/mac/display.h [deleted file]
include/wx/mgl/chkconf.h
include/wx/mgl/display.h [deleted file]
include/wx/msw/display.h [deleted file]
include/wx/os2/chkconf.h
include/wx/os2/display.h [deleted file]
include/wx/palmos/chkconf.h
include/wx/palmos/display.h [deleted file]
include/wx/unix/displayx11.h [deleted file]
src/cocoa/display.mm
src/common/dpycmn.cpp
src/mac/carbon/display.cpp
src/mac/classic/display.cpp
src/mgl/display.cpp [deleted file]
src/msw/display.cpp
src/os2/display.cpp [deleted file]
src/palmos/display.cpp [deleted file]
src/unix/displayx11.cpp

diff --git a/include/wx/cocoa/display.h b/include/wx/cocoa/display.h
deleted file mode 100644 (file)
index 895d2be..0000000
+++ /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_
index acf445c8c8cff880ed34cf52a4543a7db4fd9df8..3429258eb6fc2b04ff38645fb17a25e1dfea04ad 100644 (file)
@@ -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 (file)
index 0000000..aa7e05f
--- /dev/null
@@ -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 <vadim@wxwindows.org>
+// 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 (file)
index 223e3c3..0000000
+++ /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 (file)
index 5ea137e..0000000
+++ /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 (file)
index 4347bb2..0000000
+++ /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
index 643aafdc64b1f17f9e233dc864752c1661bec5a4..ab3271487f9a13b8c4b1fa0cae3afffe4153572b 100644 (file)
 #   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 (file)
index 9cb2198..0000000
+++ /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 (file)
index d261e74..0000000
+++ /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_
index ea0ac4db7ac324850f487c3457f0a68aa37b9d8a..924d2f0d45365f30d7cbd5c0fc94dd352baae562 100644 (file)
    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 (file)
index 1fb88cc..0000000
+++ /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_
-
index 141f96452979f00bcb499901f88505ea5a24f9c8..c2ca4c7b9214690be5aef4ee23006593a6b6eaf1 100644 (file)
@@ -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 (file)
index 13bafd5..0000000
+++ /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 (file)
index da64236..0000000
+++ /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_
-
index 0d39a028a41c4434799386e0574d18e834442b5d..d5bd1dbebaca7297a78e716af5e50fd833a44112 100644 (file)
@@ -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
 #endif
 
 #include "wx/display.h"
+#include "wx/display_impl.h"
 #include "wx/gdicmn.h"
 #include "wx/string.h"
 
 #import <Foundation/Foundation.h>
 
 // ----------------------------------------------------------------------------
-// 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
+
index 6527fc64de765c6d8ac09eb2e019404d5cee8832..b30084f099d260005b683121eab0258b1b51bf61 100644 (file)
@@ -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 <vadim@wxwindows.org>
+// Copyright:   (c) 2003-2006 Vadim Zeitlin <vadim@wxwindows.org>
 // License:     wxWindows licence
 ///////////////////////////////////////////////////////////////////////////////
 
     #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
index 7b6eb4ef42ba2a22e9c09dfbcda19ce01fb58271..79c727f1f10ff95fed73452bf2c78f7930030d41 100644 (file)
@@ -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__
 #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
index 00f4d034dba6935d96c93507ddda3f5ad62e4ce0..61eb2d44e2f4107d0faf55d30af30c2517573dcc 100644 (file)
@@ -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__
 #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 (file)
index 86365ff..0000000
+++ /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
index c6403d8ed409531364221af655490a4b31536cbb..ac0dc4c61293f9dcc7ec82ca7392b440f2acc560 100644 (file)
 #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__
     #endif
 #endif // !__WXWINCE__
 
-#ifdef HAVE_DDRAW_H
+#ifdef wxUSE_DIRECTDRAW
 #include <ddraw.h>
 
 // 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<MONITORINFOEX> 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 (file)
index 3c5b64b..0000000
+++ /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 (file)
index 3703530..0000000
+++ /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
-
index 341ce07819de8e0326e0f2e0bee31e6c1962b7fb..fdd1dc18b54afc8dbd30cd4ff6f77cb5f62f42d1 100644 (file)
@@ -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"
 
 
 /* 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 <X11/Xlib.h>
-#ifndef __VMS
-  #include <X11/Xlibint.h>
-# include <X11/extensions/Xinerama.h>
-#ifdef HAVE_X11_EXTENSIONS_XF86VMODE_H
-  #include <X11/extensions/xf86vmode.h>
-#endif
-#endif
-}
-
-class wxDisplayUnixPriv
+extern "C"
 {
-  public:
-    wxRect m_rect;
-    int m_depth;
-};
+    #include <X11/Xlib.h>
+    #include <X11/Xlibint.h>
 
-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 <X11/extensions/Xinerama.h>
+    #ifdef HAVE_X11_EXTENSIONS_XF86VMODE_H
+        #include <X11/extensions/xf86vmode.h>
+    #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 */