various cleanups
[wxWidgets.git] / src / cocoa / display.mm
1 /////////////////////////////////////////////////////////////////////////////
2 // Name:        src/cocoa/display.mm
3 // Purpose:     Cocoa implementation of wxDisplay class
4 // Author:      Ryan Norton
5 // Modified by: 
6 // Created:     2004-10-03
7 // RCS-ID:      $Id$
8 // Copyright:   (c) Ryan Norton
9 // Licence:     wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #ifdef __GNUG__
13     #pragma implementation "display.h"
14 #endif
15
16 // For compilers that support precompilation, includes "wx.h".
17 #include "wx/wxprec.h"
18
19 #ifdef __BORLANDC__
20     #pragma hdrstop
21 #endif
22
23 #if wxUSE_DISPLAY
24
25 #ifndef WX_PRECOMP
26    #include "wx/dynarray.h"
27 #endif
28
29 #include "wx/display.h"
30 #include "wx/gdicmn.h"
31 #include "wx/string.h"
32
33 #import <Foundation/Foundation.h>
34
35 // ----------------------------------------------------------------------------
36 // private classes
37 // ----------------------------------------------------------------------------
38
39 size_t wxDisplayBase::GetCount()
40 {
41     CGDisplayCount count;
42 #ifdef __WXDEBUG__
43     CGDisplayErr err = 
44 #endif
45     CGGetActiveDisplayList(0, NULL, &count);
46
47     wxASSERT(err == CGDisplayNoErr);
48     return count;
49 }
50
51 int wxDisplayBase::GetFromPoint(const wxPoint &p)
52 {   
53     CGPoint thePoint = {(float)p.x, (float)p.y};
54     CGDirectDisplayID theID;
55     CGDisplayCount theCount;
56     CGDisplayErr err = CGGetDisplaysWithPoint(thePoint, 1, &theID, &theCount);
57     wxASSERT(err == CGDisplayNoErr);
58     int nWhich = -1;
59     
60     if (theCount)
61     {
62         theCount = GetCount();
63         CGDirectDisplayID* theIDs = new CGDirectDisplayID[theCount];
64         err = CGGetActiveDisplayList(theCount, theIDs, &theCount);
65         wxASSERT(err == CGDisplayNoErr);
66
67         for(nWhich = 0; nWhich < (int) theCount; ++nWhich)
68         {
69             if(theIDs[nWhich] == theID)
70                 break;
71         }
72         
73         delete[] theIDs;
74         
75         if(nWhich == (int) theCount)
76         {
77             wxFAIL_MSG(wxT("Failed to find display in display list"));
78             nWhich = -1;
79         }
80     }
81     
82     return nWhich;
83 }//CFUserNotification[NSBundle bundleForClass:[self class]]
84
85 wxDisplay::wxDisplay(size_t index) : wxDisplayBase ( index )
86 {
87     CGDisplayCount theCount = GetCount();
88     CGDirectDisplayID* theIDs = new CGDirectDisplayID[theCount];
89 #ifdef __WXDEBUG__
90     CGDisplayErr err = 
91 #endif
92     CGGetActiveDisplayList(theCount, theIDs, &theCount);
93
94     wxASSERT(err == CGDisplayNoErr);
95     wxASSERT(index < theCount);
96     
97     m_id = theIDs[index];
98     
99     delete[] theIDs;
100 }
101
102 wxRect wxDisplay::GetGeometry() const
103 {
104     CGRect theRect = CGDisplayBounds(m_id);
105     return wxRect(      (int)theRect.origin.x,
106                     (int)theRect.origin.y,
107                     (int)theRect.size.width,
108                     (int)theRect.size.height  ); //floats
109 }
110
111 int wxDisplay::GetDepth() const
112 {
113     return (int) CGDisplayBitsPerPixel(m_id); //size_t
114 }
115
116 wxString wxDisplay::GetName() const
117 {
118     // Macs don't name their displays...
119     return wxEmptyString;
120 }
121
122 static int wxCFDictKeyToInt( CFDictionaryRef desc, CFStringRef key )
123 {
124     CFNumberRef value;
125     int num = 0;
126
127     if ( (value = (CFNumberRef) CFDictionaryGetValue(desc, key)) == NULL )
128         return 0;
129     CFNumberGetValue(value, kCFNumberIntType, &num);
130     return num;
131 }
132
133 wxArrayVideoModes
134     wxDisplay::GetModes(const wxVideoMode& mode) const
135 {
136     wxArrayVideoModes Modes;
137     
138     CFArrayRef theArray = CGDisplayAvailableModes(m_id);
139
140     for(CFIndex i = 0; i < CFArrayGetCount(theArray); ++i)
141     {
142         CFDictionaryRef theValue = (CFDictionaryRef) CFArrayGetValueAtIndex(theArray, i);
143         
144         wxVideoMode theMode(wxCFDictKeyToInt(theValue, kCGDisplayWidth),
145                             wxCFDictKeyToInt(theValue, kCGDisplayHeight),
146                             wxCFDictKeyToInt(theValue, kCGDisplayBitsPerPixel),
147                             wxCFDictKeyToInt(theValue, kCGDisplayRefreshRate));
148         
149         if (theMode.Matches(mode))
150             Modes.Add(theMode);
151     }
152     
153     return Modes;
154 }
155
156 wxVideoMode wxDisplay::GetCurrentMode() const
157 {
158     CFDictionaryRef theValue = CGDisplayCurrentMode (m_id);
159     
160     return wxVideoMode(wxCFDictKeyToInt(theValue, kCGDisplayWidth),
161                             wxCFDictKeyToInt(theValue, kCGDisplayHeight),
162                             wxCFDictKeyToInt(theValue, kCGDisplayBitsPerPixel),
163                             wxCFDictKeyToInt(theValue, kCGDisplayRefreshRate));
164 }
165
166 bool wxDisplay::ChangeMode(const wxVideoMode& mode)
167 {
168     //Changing to default mode (wxDefualtVideoMode) doesn't
169     //work because we don't have access to the system's 'scrn'
170     //resource which holds the user's mode which the system
171     //will return to after this app is done
172     boolean_t bExactMatch;
173     CFDictionaryRef theCGMode = CGDisplayBestModeForParametersAndRefreshRate (
174                                         m_id,
175                                         (size_t)mode.bpp,
176                                         (size_t)mode.w,
177                                         (size_t)mode.h,
178                                         (double)mode.refresh,
179                                         &bExactMatch);
180     
181     bool bOK = bExactMatch;
182     
183     if(bOK)
184         bOK = CGDisplaySwitchToMode(m_id, theCGMode) == CGDisplayNoErr;
185
186     return bOK;
187 }
188
189 wxDisplay::~wxDisplay()
190 {
191 }
192
193 #endif // wxUSE_DISPLAY