Subversion Repositories AndroidProjects

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1452 chris 1
using System;
2
using System.Collections.Generic;
3
using System.Diagnostics;
4
 
5
namespace OpenTK.Platform.MacOS
6
{
7
    using System.Drawing;
8
    using Carbon;
9
 
10
    class QuartzDisplayDeviceDriver : IDisplayDeviceDriver
11
    {
12
        static object display_lock = new object();
13
 
14
        static Dictionary<DisplayDevice, IntPtr> displayMap =
15
            new Dictionary<DisplayDevice, IntPtr>();
16
 
17
        static IntPtr mainDisplay;
18
        internal static IntPtr MainDisplay { get { return mainDisplay; } }
19
 
20
        static QuartzDisplayDeviceDriver()
21
        {
22
            lock (display_lock)
23
            {
24
                // To minimize the need to add static methods to OpenTK.Graphics.DisplayDevice
25
                // we only allow settings to be set through its constructor.
26
                // Thus, we save all necessary parameters in temporary variables
27
                // and construct the device when every needed detail is available.
28
                // The main DisplayDevice constructor adds the newly constructed device
29
                // to the list of available devices.
30
                const int maxDisplayCount = 20;
31
                IntPtr[] displays = new IntPtr[maxDisplayCount];
32
                int displayCount;
33
 
34
                unsafe
35
                {
36
                    fixed(IntPtr* displayPtr = displays)
37
                    {
38
                        CG.GetActiveDisplayList(maxDisplayCount, displayPtr, out displayCount);
39
                    }
40
                }
41
 
42
                Debug.Print("CoreGraphics reported {0} display(s).", displayCount);
43
                Debug.Indent();
44
 
45
                for (int i = 0; i < displayCount; i++)
46
                {
47
                    IntPtr currentDisplay = displays[i];
48
 
49
                    // according to docs, first element in the array is always the
50
                    // main display.
51
                    bool primary = (i == 0);
52
 
53
                    if (primary)
54
                        mainDisplay = currentDisplay;
55
 
56
                    // gets current settings
57
                    int currentWidth = CG.DisplayPixelsWide(currentDisplay);
58
                    int currentHeight = CG.DisplayPixelsHigh(currentDisplay);
59
                    Debug.Print("Display {0} is at  {1}x{2}", i, currentWidth, currentHeight);
60
 
61
                    IntPtr displayModesPtr = CG.DisplayAvailableModes(currentDisplay);                
62
                    CFArray displayModes = new CFArray(displayModesPtr);
63
                    Debug.Print("Supports {0} display modes.", displayModes.Count);
64
 
65
                    DisplayResolution opentk_dev_current_res = null;
66
                    List<DisplayResolution> opentk_dev_available_res = new List<DisplayResolution>();
67
                    IntPtr currentModePtr = CG.DisplayCurrentMode(currentDisplay);
68
                    CFDictionary currentMode = new CFDictionary(currentModePtr);
69
 
70
                    for (int j = 0; j < displayModes.Count; j++)
71
                    {
72
                        CFDictionary dict = new CFDictionary(displayModes[j]);
73
 
74
                        int width = (int) dict.GetNumberValue("Width");
75
                        int height = (int) dict.GetNumberValue("Height");
76
                        int bpp = (int) dict.GetNumberValue("BitsPerPixel");
77
                        double freq = dict.GetNumberValue("RefreshRate");
78
                        bool current = currentMode.Ref == dict.Ref;
79
 
80
                        //if (current) Debug.Write("  * ");
81
                        //else Debug.Write("    ");
82
 
83
                        //Debug.Print("Mode {0} is {1}x{2}x{3} @ {4}.", j, width, height, bpp, freq);
84
 
85
                        DisplayResolution thisRes = new DisplayResolution(0, 0, width, height, bpp, (float)freq);
86
                        opentk_dev_available_res.Add(thisRes);
87
 
88
                        if (current)
89
                            opentk_dev_current_res = thisRes;
90
 
91
                    }
92
 
93
                                        HIRect bounds = CG.DisplayBounds(currentDisplay);
94
                                        Rectangle newRect = new Rectangle(
95
                                                (int)bounds.Origin.X, (int)bounds.Origin.Y, (int)bounds.Size.Width, (int)bounds.Size.Height);
96
 
97
                                        Debug.Print("Display {0} bounds: {1}", i, newRect);
98
 
99
                    DisplayDevice opentk_dev =
100
                        new DisplayDevice(opentk_dev_current_res, primary, opentk_dev_available_res, newRect);
101
 
102
                    displayMap.Add(opentk_dev, currentDisplay);
103
                }
104
 
105
                Debug.Unindent();
106
            }
107
        }
108
 
109
 
110
                internal static IntPtr HandleTo(DisplayDevice displayDevice)
111
                {
112
                        if (displayMap.ContainsKey(displayDevice))
113
                                return displayMap[displayDevice];
114
                        else
115
                                return IntPtr.Zero;
116
                }
117
 
118
        #region IDisplayDeviceDriver Members
119
 
120
        Dictionary<IntPtr, IntPtr> storedModes = new Dictionary<IntPtr, IntPtr>();
121
        List<IntPtr> displaysCaptured = new List<IntPtr>();
122
 
123
        public bool TryChangeResolution(DisplayDevice device, DisplayResolution resolution)
124
        {
125
            IntPtr display = displayMap[device];
126
            IntPtr currentModePtr = CG.DisplayCurrentMode(display);
127
 
128
            if (storedModes.ContainsKey(display) == false)
129
            {
130
                storedModes.Add(display, currentModePtr);        
131
            }
132
 
133
            IntPtr displayModesPtr = CG.DisplayAvailableModes(display);
134
            CFArray displayModes = new CFArray(displayModesPtr);
135
 
136
            for (int j = 0; j < displayModes.Count; j++)
137
            {
138
                CFDictionary dict = new CFDictionary(displayModes[j]);
139
 
140
                int width = (int)dict.GetNumberValue("Width");
141
                int height = (int)dict.GetNumberValue("Height");
142
                int bpp = (int)dict.GetNumberValue("BitsPerPixel");
143
                double freq = dict.GetNumberValue("RefreshRate");
144
 
145
                if (width == resolution.Width &&
146
                    height == resolution.Height &&
147
                    bpp == resolution.BitsPerPixel &&
148
                    System.Math.Abs(freq - resolution.RefreshRate) < 1e-6)
149
                {
150
                    if (displaysCaptured.Contains(display) == false)
151
                    {
152
                        CG.DisplayCapture(display);
153
                    }
154
 
155
                    Debug.Print("Changing resolution to {0}x{1}x{2}@{3}.", width, height, bpp, freq);
156
 
157
                    CG.DisplaySwitchToMode(display, displayModes[j]);
158
 
159
                    return true;
160
                }
161
 
162
            }
163
            return false;
164
        }
165
 
166
        public bool TryRestoreResolution(DisplayDevice device)
167
        {
168
            IntPtr display = displayMap[device];
169
 
170
            if (storedModes.ContainsKey(display))
171
            {
172
                Debug.Print("Restoring resolution.");
173
 
174
                CG.DisplaySwitchToMode(display, storedModes[display]);
175
                CG.DisplayRelease(display);
176
                displaysCaptured.Remove(display);
177
 
178
                return true;
179
            }
180
 
181
            return false;
182
        }
183
 
184
        #endregion
185
 
186
        }
187
}