Add wxDisplay::GetDepth() and use it for wxDisplayDepth()

Allow getting the depth of any display, not just the primary one, even
though this is not implemented for Unix ports currently.

Mostly do this for consistency with the other display-related functions.
This commit is contained in:
Vadim Zeitlin
2018-10-06 15:28:11 +02:00
parent e834585cf7
commit 24b5e256df
20 changed files with 157 additions and 90 deletions

View File

@@ -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;

View File

@@ -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(); }

View File

@@ -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();

View File

@@ -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()));

View File

@@ -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") );

View File

@@ -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();

View File

@@ -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

View File

@@ -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
{

View File

@@ -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);

View File

@@ -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);

View File

@@ -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();

View File

@@ -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<wxDisplayInfo> 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<MONITORINFOEX> 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;
}
}

View File

@@ -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;

View File

@@ -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<CFStringRef> pixelEncoding( CGDisplayModeCopyPixelEncoding(theValue) );
@@ -339,6 +368,11 @@ public:
{
return wxOSXGetMainDisplayClientArea();
}
virtual int GetDepth() const wxOVERRIDE
{
return wxGetDisplayDepth(CGMainDisplayID());
}
};
class wxDisplayFactorySingleMacOSX : public wxDisplayFactorySingle

View File

@@ -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

View File

@@ -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
// ----------------------------------------------------------------------------

View File

@@ -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
{

View File

@@ -110,11 +110,6 @@ bool wxGetKeyState(wxKeyCode key)
}
}
int wxDisplayDepth()
{
return QApplication::desktop()->depth();
}
void wxDisplaySizeMM(int *width, int *height)
{
if ( width != NULL )

View File

@@ -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 <X11/extensions/Xinerama.h>
@@ -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);
};

View File

@@ -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();