diff --git a/include/wx/display.h b/include/wx/display.h index 3213d79d97..726dfee418 100644 --- a/include/wx/display.h +++ b/include/wx/display.h @@ -74,6 +74,9 @@ public: // get the client area of the display, i.e. without taskbars and such wxRect GetClientArea() const; + // get the depth, i.e. number of bits per pixel (0 if unknown) + int GetDepth() const; + // name may be empty wxString GetName() const; diff --git a/include/wx/private/display.h b/include/wx/private/display.h index 9f0dce0ad2..686e703101 100644 --- a/include/wx/private/display.h +++ b/include/wx/private/display.h @@ -78,6 +78,9 @@ public: // return the area of the display available for normal windows virtual wxRect GetClientArea() const { return GetGeometry(); } + // return the depth or 0 if unknown + virtual int GetDepth() const = 0; + // return the name (may be empty) virtual wxString GetName() const { return wxString(); } diff --git a/interface/wx/gdicmn.h b/interface/wx/gdicmn.h index fe7a62a783..fc27e066d9 100644 --- a/interface/wx/gdicmn.h +++ b/interface/wx/gdicmn.h @@ -1191,6 +1191,10 @@ bool wxColourDisplay(); Returns the depth of the display (a value of 1 denotes a monochrome display). + @note Use of this function is not recommended in the new code as it only + works for the primary display. Use wxDisplay::GetDepth() to retrieve + the depth of the appropriate display instead. + @header{wx/gdicmn.h} */ int wxDisplayDepth(); diff --git a/samples/display/display.cpp b/samples/display/display.cpp index 7c97a54c34..5b715f88ec 100644 --- a/samples/display/display.cpp +++ b/samples/display/display.cpp @@ -275,6 +275,10 @@ MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size, rc.x, rc.y, rc.width, rc.height) )); + sizer->Add(new wxStaticText(page, wxID_ANY, "Depth: ")); + sizer->Add(new wxStaticText(page, wxID_ANY, + wxString::Format("%d", display.GetDepth()))); + sizer->Add(new wxStaticText(page, wxID_ANY, "Name: ")); sizer->Add(new wxStaticText(page, wxID_ANY, display.GetName())); diff --git a/src/common/dpycmn.cpp b/src/common/dpycmn.cpp index cd49ae60ec..9968f3cbfa 100644 --- a/src/common/dpycmn.cpp +++ b/src/common/dpycmn.cpp @@ -122,6 +122,13 @@ wxRect wxDisplay::GetClientArea() const return m_impl->GetClientArea(); } +int wxDisplay::GetDepth() const +{ + wxCHECK_MSG( IsOk(), 0, wxT("invalid wxDisplay object") ); + + return m_impl->GetDepth(); +} + wxString wxDisplay::GetName() const { wxCHECK_MSG( IsOk(), wxString(), wxT("invalid wxDisplay object") ); diff --git a/src/common/gdicmn.cpp b/src/common/gdicmn.cpp index 771db4ac72..22ba30ef37 100644 --- a/src/common/gdicmn.cpp +++ b/src/common/gdicmn.cpp @@ -845,6 +845,11 @@ wxFont *wxFontList::FindOrCreateFont(int pointSize, return font; } +int wxDisplayDepth() +{ + return wxDisplay().GetDepth(); +} + void wxDisplaySize(int *width, int *height) { const wxSize size = wxGetDisplaySize(); diff --git a/src/dfb/utils.cpp b/src/dfb/utils.cpp index 76c84a5c50..7226d63002 100644 --- a/src/dfb/utils.cpp +++ b/src/dfb/utils.cpp @@ -68,6 +68,11 @@ public: return wxRect(0, 0, mode.w, mode.h); } + + virtual int GetDepth() const wxOVERRIDE + { + return wxTheApp->GetDisplayMode().bpp; + } }; class wxDisplayFactorySingleDFB : public wxDisplayFactorySingle @@ -90,11 +95,6 @@ bool wxColourDisplay() return true; } -int wxDisplayDepth() -{ - return wxTheApp->GetDisplayMode().bpp; -} - void wxDisplaySizeMM(int *width, int *height) { // FIXME: there's no way to get physical resolution using the DirectDB diff --git a/src/gtk/display.cpp b/src/gtk/display.cpp index 2576d0d6c2..2cc424c8db 100644 --- a/src/gtk/display.cpp +++ b/src/gtk/display.cpp @@ -45,6 +45,7 @@ public: wxDisplayImplGTK(unsigned i); virtual wxRect GetGeometry() const wxOVERRIDE; virtual wxRect GetClientArea() const wxOVERRIDE; + virtual int GetDepth() const wxOVERRIDE; #if wxUSE_DISPLAY virtual bool IsPrimary() const wxOVERRIDE; @@ -114,6 +115,11 @@ wxRect wxDisplayImplGTK::GetClientArea() const return wxRect(rect.x, rect.y, rect.width, rect.height); } +int wxDisplayImplGTK::GetDepth() const +{ + return 24; +} + #if wxUSE_DISPLAY bool wxDisplayImplGTK::IsPrimary() const { @@ -205,6 +211,7 @@ public: wxDisplayImplGTK(unsigned i); virtual wxRect GetGeometry() const wxOVERRIDE; virtual wxRect GetClientArea() const wxOVERRIDE; + virtual int GetDepth() const wxOVERRIDE; #if wxUSE_DISPLAY virtual bool IsPrimary() const wxOVERRIDE; @@ -269,6 +276,12 @@ wxRect wxDisplayImplGTK::GetClientArea() const return wxRect(rect.x, rect.y, rect.width, rect.height); } +int wxDisplayImplGTK::GetDepth() const +{ + // TODO: How to get the depth of the specific display? + return gdk_visual_get_depth(gdk_window_get_visual(wxGetTopLevelGDK())); +} + #if wxUSE_DISPLAY bool wxDisplayImplGTK::IsPrimary() const { diff --git a/src/gtk/utilsgtk.cpp b/src/gtk/utilsgtk.cpp index 31a1d9a9ea..2ce561ff13 100644 --- a/src/gtk/utilsgtk.cpp +++ b/src/gtk/utilsgtk.cpp @@ -95,15 +95,6 @@ bool wxColourDisplay() return true; } -int wxDisplayDepth() -{ -#ifdef __WXGTK4__ - return 24; -#else - return gdk_visual_get_depth(gdk_window_get_visual(wxGetTopLevelGDK())); -#endif -} - wxWindow* wxFindWindowAtPoint(const wxPoint& pt) { return wxGenericFindWindowAtPoint(pt); diff --git a/src/gtk1/utilsgtk.cpp b/src/gtk1/utilsgtk.cpp index 9f18a26436..c027686ad5 100644 --- a/src/gtk1/utilsgtk.cpp +++ b/src/gtk1/utilsgtk.cpp @@ -102,11 +102,6 @@ bool wxColourDisplay() return true; } -int wxDisplayDepth() -{ - return gdk_window_get_visual( wxGetRootWindow()->window )->depth; -} - wxWindow* wxFindWindowAtPoint(const wxPoint& pt) { return wxGenericFindWindowAtPoint(pt); diff --git a/src/motif/utils.cpp b/src/motif/utils.cpp index 16c52e86a8..621b89cc27 100644 --- a/src/motif/utils.cpp +++ b/src/motif/utils.cpp @@ -231,14 +231,6 @@ bool wxColourDisplay() return wxDisplayDepth() > 1; } -// Returns depth of screen -int wxDisplayDepth() -{ - Display *dpy = wxGlobalDisplay(); - - return DefaultDepth (dpy, DefaultScreen (dpy)); -} - void wxDisplaySizeMM(int *width, int *height) { Display *dpy = wxGlobalDisplay(); diff --git a/src/msw/display.cpp b/src/msw/display.cpp index 771cb32132..e6ea6486a8 100644 --- a/src/msw/display.cpp +++ b/src/msw/display.cpp @@ -29,6 +29,11 @@ #include "wx/msw/private.h" #include "wx/msw/wrapwin.h" +int wxGetHDCDepth(HDC hdc) +{ + return ::GetDeviceCaps(hdc, PLANES) * GetDeviceCaps(hdc, BITSPIXEL); +} + // This implementation is always available, whether wxUSE_DISPLAY is 1 or not, // as we fall back to it in case of error. class wxDisplayImplSingleMSW : public wxDisplayImplSingle @@ -52,6 +57,11 @@ public: wxCopyRECTToRect(rc, rectClient); return rectClient; } + + virtual int GetDepth() const wxOVERRIDE + { + return wxGetHDCDepth(ScreenHDC()); + } }; class wxDisplayFactorySingleMSW : public wxDisplayFactorySingle @@ -79,6 +89,20 @@ protected: static const wxChar displayDllName[] = wxT("user32.dll"); +namespace +{ + +// Simple struct storing the information needed by wxDisplayMSW. +struct wxDisplayInfo +{ + wxDisplayInfo(HMONITOR hmon_, int depth_) : hmon(hmon_), depth(depth_) {} + + HMONITOR hmon; + int depth; +}; + +} // anonymous namespace + // ---------------------------------------------------------------------------- // wxDisplayMSW declaration // ---------------------------------------------------------------------------- @@ -86,14 +110,15 @@ static const wxChar displayDllName[] = wxT("user32.dll"); class wxDisplayMSW : public wxDisplayImpl { public: - wxDisplayMSW(unsigned n, HMONITOR hmon) + wxDisplayMSW(unsigned n, const wxDisplayInfo& info) : wxDisplayImpl(n), - m_hmon(hmon) + m_info(info) { } virtual wxRect GetGeometry() const wxOVERRIDE; virtual wxRect GetClientArea() const wxOVERRIDE; + virtual int GetDepth() const wxOVERRIDE; virtual wxString GetName() const wxOVERRIDE; virtual bool IsPrimary() const wxOVERRIDE; @@ -118,7 +143,7 @@ protected: // it succeeded, otherwise return false. bool GetMonInfo(MONITORINFOEX& monInfo) const; - HMONITOR m_hmon; + wxDisplayInfo m_info; private: wxDECLARE_NO_COPY_CLASS(wxDisplayMSW); @@ -129,8 +154,6 @@ private: // wxDisplayFactoryMSW declaration // ---------------------------------------------------------------------------- -WX_DEFINE_ARRAY(HMONITOR, wxMonitorHandleArray); - class wxDisplayFactoryMSW : public wxDisplayFactory { public: @@ -177,7 +200,7 @@ private: // the array containing information about all available displays, filled by // MultimonEnumProc() - wxMonitorHandleArray m_displays; + wxVector m_displays; // The hidden window we use for receiving WM_SETTINGCHANGE and its class // name. @@ -213,7 +236,7 @@ wxDisplayFactoryMSW* wxDisplayFactoryMSW::ms_factory = NULL; bool wxDisplayMSW::GetMonInfo(MONITORINFOEX& monInfo) const { - if ( !::GetMonitorInfo(m_hmon, &monInfo) ) + if ( !::GetMonitorInfo(m_info.hmon, &monInfo) ) { wxLogLastError(wxT("GetMonitorInfo")); return false; @@ -244,6 +267,11 @@ wxRect wxDisplayMSW::GetClientArea() const return rectClient; } +int wxDisplayMSW::GetDepth() const +{ + return m_info.depth; +} + wxString wxDisplayMSW::GetName() const { WinStruct monInfo; @@ -469,9 +497,12 @@ wxDisplayFactoryMSW::~wxDisplayFactoryMSW() void wxDisplayFactoryMSW::DoRefreshMonitors() { - m_displays.Clear(); + m_displays.clear(); - if ( !::EnumDisplayMonitors(NULL, NULL, MultimonEnumProc, (LPARAM)this) ) + // We need to pass a valid HDC here in order to get valid hdcMonitor in our + // callback. + ScreenHDC dc; + if ( !::EnumDisplayMonitors(dc, NULL, MultimonEnumProc, (LPARAM)this) ) { wxLogLastError(wxT("EnumDisplayMonitors")); } @@ -481,13 +512,13 @@ void wxDisplayFactoryMSW::DoRefreshMonitors() BOOL CALLBACK wxDisplayFactoryMSW::MultimonEnumProc( HMONITOR hMonitor, // handle to display monitor - HDC WXUNUSED(hdcMonitor), // handle to monitor-appropriate device context + HDC hdcMonitor, // handle to monitor-appropriate device context LPRECT WXUNUSED(lprcMonitor), // pointer to monitor intersection rectangle LPARAM dwData) // data passed from EnumDisplayMonitors (this) { wxDisplayFactoryMSW *const self = (wxDisplayFactoryMSW *)dwData; - self->m_displays.Add(hMonitor); + self->m_displays.push_back(wxDisplayInfo(hMonitor, wxGetHDCDepth(hdcMonitor))); // continue the enumeration return TRUE; @@ -508,7 +539,7 @@ int wxDisplayFactoryMSW::FindDisplayFromHMONITOR(HMONITOR hmon) const const size_t count = m_displays.size(); for ( size_t n = 0; n < count; n++ ) { - if ( hmon == m_displays[n] ) + if ( hmon == m_displays[n].hmon ) return n; } } diff --git a/src/msw/utilsgui.cpp b/src/msw/utilsgui.cpp index 1ebbd36259..a475bc6290 100644 --- a/src/msw/utilsgui.cpp +++ b/src/msw/utilsgui.cpp @@ -138,13 +138,6 @@ bool wxColourDisplay() return s_isColour != 0; } -// Returns depth of screen -int wxDisplayDepth() -{ - ScreenHDC dc; - return GetDeviceCaps(dc, PLANES) * GetDeviceCaps(dc, BITSPIXEL); -} - void wxDisplaySizeMM(int *width, int *height) { ScreenHDC dc; diff --git a/src/osx/core/display.cpp b/src/osx/core/display.cpp index 3f35ccc1e4..2e55b346b8 100644 --- a/src/osx/core/display.cpp +++ b/src/osx/core/display.cpp @@ -52,6 +52,29 @@ wxRect wxGetDisplayGeometry(CGDirectDisplayID id) (int)theRect.size.height ); //floats } +int wxGetDisplayDepth(CGDirectDisplayID id) +{ + CGDisplayModeRef currentMode = CGDisplayCopyDisplayMode(id); + CFStringRef encoding = CGDisplayModeCopyPixelEncoding(currentMode); + + int theDepth = 32; // some reasonable default + if(encoding) + { + if(CFStringCompare(encoding, CFSTR(IO32BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo) + theDepth = 32; + else if(CFStringCompare(encoding, CFSTR(IO16BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo) + theDepth = 16; + else if(CFStringCompare(encoding, CFSTR(IO8BitIndexedPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo) + theDepth = 8; + + CFRelease(encoding); + } + + CGDisplayModeRelease(currentMode); + + return theDepth; +} + } // anonymous namespace #if wxUSE_DISPLAY @@ -73,6 +96,7 @@ public: virtual wxRect GetGeometry() const wxOVERRIDE; virtual wxRect GetClientArea() const wxOVERRIDE; + virtual int GetDepth() const wxOVERRIDE; virtual wxArrayVideoModes GetModes(const wxVideoMode& mode) const wxOVERRIDE; virtual wxVideoMode GetCurrentMode() const wxOVERRIDE; @@ -229,6 +253,11 @@ wxRect wxDisplayImplMacOSX::GetClientArea() const return wxDisplayImpl::GetClientArea(); } +int wxDisplayImplMacOSX::GetDepth() const +{ + return wxGetDisplayDepth(m_id); +} + static int wxOSXCGDisplayModeGetBitsPerPixel( CGDisplayModeRef theValue ) { wxCFRef pixelEncoding( CGDisplayModeCopyPixelEncoding(theValue) ); @@ -339,6 +368,11 @@ public: { return wxOSXGetMainDisplayClientArea(); } + + virtual int GetDepth() const wxOVERRIDE + { + return wxGetDisplayDepth(CGMainDisplayID()); + } }; class wxDisplayFactorySingleMacOSX : public wxDisplayFactorySingle diff --git a/src/osx/iphone/utils.mm b/src/osx/iphone/utils.mm index 2136055e74..dd77cfd5e6 100644 --- a/src/osx/iphone/utils.mm +++ b/src/osx/iphone/utils.mm @@ -130,12 +130,6 @@ wxMouseState wxGetMouseState() return ms; } -// Returns depth of screen -int wxDisplayDepth() -{ - return 32; // TODO can we determine this ? -} - // Get size of display class wxDisplayImplSingleiOS : public wxDisplayImplSingle @@ -161,6 +155,11 @@ public: return wxRect(0, 0, width, height); } + + virtual int GetDepth() const wxOVERRIDE + { + return 32; // TODO can we determine this ? + } }; class wxDisplayFactorySingleiOS : public wxDisplayFactorySingle diff --git a/src/osx/utils_osx.cpp b/src/osx/utils_osx.cpp index 6860b5e088..d53c47f753 100644 --- a/src/osx/utils_osx.cpp +++ b/src/osx/utils_osx.cpp @@ -63,30 +63,6 @@ bool wxColourDisplay() #if wxOSX_USE_COCOA_OR_CARBON -// Returns depth of screen -int wxDisplayDepth() -{ - CGDisplayModeRef currentMode = CGDisplayCopyDisplayMode(kCGDirectMainDisplay); - CFStringRef encoding = CGDisplayModeCopyPixelEncoding(currentMode); - - int theDepth = 32; // some reasonable default - if(encoding) - { - if(CFStringCompare(encoding, CFSTR(IO32BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo) - theDepth = 32; - else if(CFStringCompare(encoding, CFSTR(IO16BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo) - theDepth = 16; - else if(CFStringCompare(encoding, CFSTR(IO8BitIndexedPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo) - theDepth = 8; - - CFRelease(encoding); - } - - CGDisplayModeRelease(currentMode); - - return theDepth; -} - #if wxUSE_GUI // ---------------------------------------------------------------------------- diff --git a/src/qt/display.cpp b/src/qt/display.cpp index 52b6af8373..6d3de3ac2e 100644 --- a/src/qt/display.cpp +++ b/src/qt/display.cpp @@ -21,6 +21,7 @@ public: virtual wxRect GetGeometry() const wxOVERRIDE; virtual wxRect GetClientArea() const wxOVERRIDE; + virtual int GetDepth() const wxOVERRIDE; #if wxUSE_DISPLAY virtual wxArrayVideoModes GetModes(const wxVideoMode& mode) const wxOVERRIDE; @@ -44,6 +45,11 @@ wxRect wxDisplayImplQt::GetClientArea() const return wxQtConvertRect( QApplication::desktop()->availableGeometry( GetIndex() )); } +int wxDisplayImplQt::GetDepth() const +{ + return IsPrimary() ? QApplication::desktop()->depth() : 0; +} + #if wxUSE_DISPLAY wxArrayVideoModes wxDisplayImplQt::GetModes(const wxVideoMode& WXUNUSED(mode)) const { diff --git a/src/qt/utils.cpp b/src/qt/utils.cpp index 92957b8683..bcaedc95e2 100644 --- a/src/qt/utils.cpp +++ b/src/qt/utils.cpp @@ -110,11 +110,6 @@ bool wxGetKeyState(wxKeyCode key) } } -int wxDisplayDepth() -{ - return QApplication::desktop()->depth(); -} - void wxDisplaySizeMM(int *width, int *height) { if ( width != NULL ) diff --git a/src/unix/displayx11.cpp b/src/unix/displayx11.cpp index 4e317ca6a0..b352e5392f 100644 --- a/src/unix/displayx11.cpp +++ b/src/unix/displayx11.cpp @@ -34,6 +34,16 @@ static wxRect wxGetMainScreenWorkArea(); +namespace +{ + +inline int wxGetMainScreenDepth() +{ + Display* const dpy = wxGetX11Display(); + + return DefaultDepth(dpy, DefaultScreen (dpy)); +} + class wxDisplayImplSingleX11 : public wxDisplayImplSingle { public: @@ -50,6 +60,11 @@ public: { return wxGetMainScreenWorkArea(); } + + virtual int GetDepth() const wxOVERRIDE + { + return wxGetMainScreenDepth(); + } }; class wxDisplayFactorySingleX11 : public wxDisplayFactorySingle @@ -61,6 +76,8 @@ protected: } }; +} // anonymous namespace + #if wxUSE_DISPLAY #include @@ -118,6 +135,14 @@ public: // we don't currently react to its changes return IsPrimary() ? wxGetMainScreenWorkArea() : m_rect; } + virtual int GetDepth() const wxOVERRIDE + { + const wxVideoMode& mode = GetCurrentMode(); + if ( mode.bpp ) + return mode.bpp; + + return wxGetMainScreenDepth(); + } virtual wxArrayVideoModes GetModes(const wxVideoMode& mode) const wxOVERRIDE; virtual wxVideoMode GetCurrentMode() const wxOVERRIDE; @@ -125,7 +150,6 @@ public: private: wxRect m_rect; - int m_depth; wxDECLARE_NO_COPY_CLASS(wxDisplayImplX11); }; diff --git a/src/x11/utils.cpp b/src/x11/utils.cpp index 4312a3da8e..7a917354ab 100644 --- a/src/x11/utils.cpp +++ b/src/x11/utils.cpp @@ -154,14 +154,6 @@ bool wxColourDisplay() return wxDisplayDepth() > 1; } -// Returns depth of screen -int wxDisplayDepth() -{ - Display *dpy = (Display*) wxGetDisplay(); - - return DefaultDepth (dpy, DefaultScreen (dpy)); -} - void wxDisplaySizeMM(int *width, int *height) { Display *dpy = (Display*) wxGetDisplay();