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