예제 #1
0
        public void RefreshDisplayDevices()
        {
            lock (display_lock)
            {
                // Store an array of the current available DisplayDevice objects.
                // This is needed to preserve the original resolution.
                var previousDevices = AvailableDevices.ToArray();

                AvailableDevices.Clear();

                // We save all necessary parameters in temporary variables
                // and construct the device when every needed detail is available.
                // The main DisplayDevice constructor adds the newly constructed device
                // to the list of available devices.
                DisplayDevice     opentk_dev;
                DisplayResolution opentk_dev_current_res = null;
                var  opentk_dev_available_res            = new List <DisplayResolution>();
                bool opentk_dev_primary = false;
                uint device_count = 0, mode_count = 0;

                // Get available video adapters and enumerate all monitors
                while (User32.DeviceContext.EnumDisplayDevices(null, device_count++, out var dev1, 0))
                {
                    if ((dev1.StateFlags & DisplayDeviceStateFlags.AttachedToDesktop) == 0)
                    {
                        continue;
                    }

                    // The second function should only be executed when the first one fails
                    // (e.g. when the monitor is disabled)
                    if (User32.DeviceContext.EnumDisplaySettingsEx(dev1.DeviceName, DisplayModeSetting.CurrentSettings,
                                                                   out DeviceMode monitor_mode, 0) ||
                        User32.DeviceContext.EnumDisplaySettingsEx(dev1.DeviceName, DisplayModeSetting.RegistrySettings,
                                                                   out monitor_mode, 0))
                    {
                        VerifyMode(dev1, monitor_mode);

                        var scale = GetScale(ref monitor_mode);
                        opentk_dev_current_res = new DisplayResolution(
                            (int)(monitor_mode.DisplayOptions.Position.X / scale),
                            (int)(monitor_mode.DisplayOptions.Position.Y / scale),
                            (int)(monitor_mode.WidthInPixels / scale),
                            (int)(monitor_mode.HeightInPixels / scale),
                            (int)monitor_mode.BitsPerPixel,
                            monitor_mode.DisplayFrequency
                            );

                        opentk_dev_primary = (dev1.StateFlags & DisplayDeviceStateFlags.PrimaryDevice) != 0;
                    }

                    opentk_dev_available_res.Clear();
                    mode_count = 0;
                    while (User32.DeviceContext.EnumDisplaySettingsEx(dev1.DeviceName, (DisplayModeSetting)mode_count++, out monitor_mode, 0))
                    {
                        VerifyMode(dev1, monitor_mode);

                        var scale = GetScale(ref monitor_mode);
                        var res   = new DisplayResolution(
                            (int)(monitor_mode.DisplayOptions.Position.X / scale),
                            (int)(monitor_mode.DisplayOptions.Position.Y / scale),
                            (int)(monitor_mode.WidthInPixels / scale),
                            (int)(monitor_mode.HeightInPixels / scale),
                            (int)monitor_mode.BitsPerPixel,
                            monitor_mode.DisplayFrequency
                            );

                        opentk_dev_available_res.Add(res);
                    }

                    // Construct the OpenTK DisplayDevice through the accumulated parameters.
                    // The constructor will automatically add the DisplayDevice to the list
                    // of available devices.
#pragma warning disable 612,618
                    opentk_dev = new DisplayDevice(
                        opentk_dev_current_res,
                        opentk_dev_primary,
                        opentk_dev_available_res,
                        opentk_dev_current_res.Bounds,
                        dev1.DeviceName
                        );
#pragma warning restore 612,618

                    // Set the original resolution if the DisplayDevice was previously available.
                    foreach (var existingDevice in previousDevices)
                    {
                        if ((string)existingDevice.Id == (string)opentk_dev.Id)
                        {
                            opentk_dev.OriginalResolution = existingDevice.OriginalResolution;
                        }
                    }

                    AvailableDevices.Add(opentk_dev);

                    if (opentk_dev_primary)
                    {
                        Primary = opentk_dev;
                    }

                    Debug.Print("DisplayDevice {0} ({1}) supports {2} resolutions.",
                                device_count, opentk_dev.IsPrimary ? "primary" : "secondary",
                                opentk_dev.AvailableResolutions.Count);
                }
            }
        }