X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/dcb68102796280b3e54979ae95738089914ce842..4521f6c88cbefa7f13e3733d344776b795f981e4:/src/cocoa/display.mm diff --git a/src/cocoa/display.mm b/src/cocoa/display.mm index 8b13789179..721fe3b425 100644 --- a/src/cocoa/display.mm +++ b/src/cocoa/display.mm @@ -1 +1,221 @@ +///////////////////////////////////////////////////////////////////////////// +// Name: src/cocoa/display.mm +// Purpose: Cocoa implementation of wxDisplay class +// Author: Ryan Norton +// Modified by: +// Created: 2004-10-03 +// Copyright: (c) Ryan Norton +// Licence: wxWindows licence +///////////////////////////////////////////////////////////////////////////// +// For compilers that support precompilation, includes "wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ + #pragma hdrstop +#endif + +#if wxUSE_DISPLAY + +#include "wx/display.h" + +#ifndef WX_PRECOMP + #include "wx/dynarray.h" + #include "wx/string.h" + #include "wx/gdicmn.h" +#endif + +#include "wx/display_impl.h" + +#import + +// ---------------------------------------------------------------------------- +// display classes implementation +// ---------------------------------------------------------------------------- + +class wxDisplayImplMacOSX : public wxDisplayImpl +{ +public: + wxDisplayImplMacOSX(unsigned n, CGDirectDisplayID id_) + : wxDisplayImpl(n), + 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; + + wxDECLARE_NO_COPY_CLASS(wxDisplayImplMacOSX); +}; + +class wxDisplayFactoryMacOSX : public wxDisplayFactory +{ +public: + wxDisplayFactoryMacOSX() { } + + virtual wxDisplayImpl *CreateDisplay(unsigned n); + virtual unsigned GetCount(); + virtual int GetFromPoint(const wxPoint& pt); + +protected: + wxDECLARE_NO_COPY_CLASS(wxDisplayFactoryMacOSX); +}; + +// ============================================================================ +// wxDisplayFactoryMacOSX implementation +// ============================================================================ + +unsigned wxDisplayFactoryMacOSX::GetCount() +{ + CGDisplayCount count; + CGDisplayErr err = CGGetActiveDisplayList(0, NULL, &count); + wxCHECK_MSG( err != CGDisplayNoErr, 0, "CGGetActiveDisplayList() failed" ); + + return count; +} + +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 = wxNOT_FOUND; + + if (theCount) + { + theCount = GetCount(); + CGDirectDisplayID* theIDs = new CGDirectDisplayID[theCount]; + err = CGGetActiveDisplayList(theCount, theIDs, &theCount); + wxASSERT(err == CGDisplayNoErr); + + for (nWhich = 0; nWhich < (int) theCount; ++nWhich) + { + if (theIDs[nWhich] == theID) + break; + } + + delete [] theIDs; + + if (nWhich == (int) theCount) + { + wxFAIL_MSG(wxT("Failed to find display in display list")); + nWhich = wxNOT_FOUND; + } + } + + return nWhich; +} + +wxDisplayImpl *wxDisplayFactoryMacOSX::CreateDisplay(unsigned n) +{ + CGDisplayCount theCount = GetCount(); + CGDirectDisplayID* theIDs = new CGDirectDisplayID[theCount]; + + CGDisplayErr err = CGGetActiveDisplayList(theCount, theIDs, &theCount); + wxCHECK_MSG( err != CGDisplayNoErr, NULL, "CGGetActiveDisplayList() failed" ); + + wxASSERT( n < theCount ); + + wxDisplayImplMacOSX *display = new wxDisplayImplMacOSX(n, theIDs[n]); + + delete [] theIDs; + + return display; +} + + +wxRect wxDisplayImplMacOSX::GetGeometry() const +{ + CGRect theRect = CGDisplayBounds(m_id); + return wxRect( (int)theRect.origin.x, + (int)theRect.origin.y, + (int)theRect.size.width, + (int)theRect.size.height ); //floats +} + +static int wxCFDictKeyToInt( CFDictionaryRef desc, CFStringRef key ) +{ + CFNumberRef value; + int num = 0; + + if ( (value = (CFNumberRef) CFDictionaryGetValue(desc, key)) == NULL ) + return 0; + CFNumberGetValue(value, kCFNumberIntType, &num); + return num; +} + +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 wxDisplayImplMacOSX::GetCurrentMode() const +{ + CFDictionaryRef theValue = CGDisplayCurrentMode (m_id); + + return wxVideoMode(wxCFDictKeyToInt(theValue, kCGDisplayWidth), + wxCFDictKeyToInt(theValue, kCGDisplayHeight), + wxCFDictKeyToInt(theValue, kCGDisplayBitsPerPixel), + wxCFDictKeyToInt(theValue, kCGDisplayRefreshRate)); +} + +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' + //resource which holds the user's mode which the system + //will return to after this app is done + boolean_t bExactMatch; + CFDictionaryRef theCGMode = CGDisplayBestModeForParametersAndRefreshRate ( + m_id, + (size_t)mode.bpp, + (size_t)mode.w, + (size_t)mode.h, + (double)mode.refresh, + &bExactMatch); + + bool bOK = bExactMatch; + + if(bOK) + bOK = CGDisplaySwitchToMode(m_id, theCGMode) == CGDisplayNoErr; + + return bOK; +} + +// ============================================================================ +// wxDisplay::CreateFactory() +// ============================================================================ + +/* static */ wxDisplayFactory *wxDisplay::CreateFactory() +{ + return new wxDisplayFactoryMacOSX; +} + +#endif // wxUSE_DISPLAY