00001 #region --- License ---
00002
00003
00004
00005
00006
00007 #endregion
00008
00009 using System;
00010 using System.Collections.Generic;
00011 using System.Text;
00012 using System.Diagnostics;
00013 using System.Threading;
00014 using System.Drawing;
00015
00016 namespace OpenTK
00017 {
00022 public class DisplayDevice
00023 {
00024
00025
00026
00027
00028
00029
00030 #region --- Fields ---
00031
00032 DisplayResolution current_resolution = new DisplayResolution(), original_resolution;
00033 List<DisplayResolution> available_resolutions = new List<DisplayResolution>();
00034 IList<DisplayResolution> available_resolutions_readonly;
00035 bool primary;
00036
00037 Rectangle bounds;
00038
00039 static readonly List<DisplayDevice> available_displays = new List<DisplayDevice>();
00040 static readonly IList<DisplayDevice> available_displays_readonly;
00041 static readonly object display_lock = new object();
00042 static DisplayDevice primary_display;
00043
00044 static Platform.IDisplayDeviceDriver implementation;
00045
00046 #endregion
00047
00048 #region --- Constructors ---
00049
00050 static DisplayDevice()
00051 {
00052 implementation = Platform.Factory.Default.CreateDisplayDeviceDriver();
00053 available_displays_readonly = available_displays.AsReadOnly();
00054 }
00055
00056 internal DisplayDevice()
00057 {
00058 lock (display_lock)
00059 {
00060 available_displays.Add(this);
00061 }
00062
00063 available_resolutions_readonly = available_resolutions.AsReadOnly();
00064 }
00065
00066 internal DisplayDevice(DisplayResolution currentResolution, bool primary,
00067 IEnumerable<DisplayResolution> availableResolutions, Rectangle bounds)
00068 : this()
00069 {
00070 #warning "Consolidate current resolution with bounds? Can they fall out of sync right now?"
00071 this.current_resolution = currentResolution;
00072 IsPrimary = primary;
00073 this.available_resolutions.AddRange(availableResolutions);
00074 this.bounds = bounds == Rectangle.Empty ? currentResolution.Bounds : bounds;
00075
00076 Debug.Print("DisplayDevice {0} ({1}) supports {2} resolutions.",
00077 available_displays.Count, primary ? "primary" : "secondary", available_resolutions.Count);
00078 }
00079
00080 #endregion
00081
00082 #region --- Public Methods ---
00083
00084 #region public Rectangle Bounds
00085
00089 public Rectangle Bounds
00090 {
00091 get { return bounds; }
00092 internal set
00093 {
00094 bounds = value;
00095 current_resolution.Height = bounds.Height;
00096 current_resolution.Width = bounds.Width;
00097 }
00098 }
00099
00100 #endregion
00101
00102 #region public int Width
00103
00105 public int Width { get { return current_resolution.Width; } }
00106
00107 #endregion
00108
00109 #region public int Height
00110
00112 public int Height { get { return current_resolution.Height; } }
00113
00114 #endregion
00115
00116 #region public int BitsPerPixel
00117
00119 public int BitsPerPixel
00120 {
00121 get { return current_resolution.BitsPerPixel; }
00122 internal set { current_resolution.BitsPerPixel = value; }
00123 }
00124
00125 #endregion
00126
00127 #region public float RefreshRate
00128
00132 public float RefreshRate
00133 {
00134 get { return current_resolution.RefreshRate; }
00135 internal set { current_resolution.RefreshRate = value; }
00136 }
00137
00138 #endregion
00139
00140 #region public bool IsPrimary
00141
00143 public bool IsPrimary
00144 {
00145 get { return primary; }
00146 internal set
00147 {
00148 if (value && primary_display != null && primary_display != this)
00149 primary_display.IsPrimary = false;
00150
00151 lock (display_lock)
00152 {
00153 primary = value;
00154 if (value)
00155 primary_display = this;
00156 }
00157 }
00158 }
00159
00160 #endregion
00161
00162 #region public DisplayResolution SelectResolution(int width, int height, int bitsPerPixel, float refreshRate)
00163
00180 public DisplayResolution SelectResolution(int width, int height, int bitsPerPixel, float refreshRate)
00181 {
00182 DisplayResolution resolution = FindResolution(width, height, bitsPerPixel, refreshRate);
00183 if (resolution == null)
00184 resolution = FindResolution(width, height, bitsPerPixel, 0);
00185 if (resolution == null)
00186 resolution = FindResolution(width, height, 0, 0);
00187 if (resolution == null)
00188 return current_resolution;
00189 return resolution;
00190 }
00191
00192 #endregion
00193
00194 #region public IList<DisplayResolution> AvailableResolutions
00195
00199 public IList<DisplayResolution> AvailableResolutions
00200 {
00201 get { return available_resolutions_readonly; }
00202 internal set
00203 {
00204 available_resolutions = (List<DisplayResolution>)value;
00205 available_resolutions_readonly = available_resolutions.AsReadOnly();
00206 }
00207 }
00208
00209 #endregion
00210
00211 #region public void ChangeResolution(DisplayResolution resolution)
00212
00217 public void ChangeResolution(DisplayResolution resolution)
00218 {
00219 if (resolution == null)
00220 this.RestoreResolution();
00221
00222 if (resolution == current_resolution)
00223 return;
00224
00225
00226
00227 if (implementation.TryChangeResolution(this, resolution))
00228 {
00229 if (original_resolution == null)
00230 original_resolution = current_resolution;
00231 current_resolution = resolution;
00232 }
00233 else throw new Graphics.GraphicsModeException(String.Format("Device {0}: Failed to change resolution to {1}.",
00234 this, resolution));
00235
00236
00237 }
00238
00239 #endregion
00240
00241 #region public void ChangeResolution(int width, int height, int bitsPerPixel, float refreshRate)
00242
00249 public void ChangeResolution(int width, int height, int bitsPerPixel, float refreshRate)
00250 {
00251 this.ChangeResolution(this.SelectResolution(width, height, bitsPerPixel, refreshRate));
00252 }
00253
00254 #endregion
00255
00256 #region public void RestoreResolution()
00257
00260 public void RestoreResolution()
00261 {
00262 if (original_resolution != null)
00263 {
00264
00265
00266 if (implementation.TryRestoreResolution(this))
00267 {
00268 current_resolution = original_resolution;
00269 original_resolution = null;
00270 }
00271 else throw new Graphics.GraphicsModeException(String.Format("Device {0}: Failed to restore resolution.", this));
00272
00273
00274 }
00275 }
00276
00277 #endregion
00278
00279 #region public static IList<DisplayDevice> AvailableDisplays
00280
00284 public static IList<DisplayDevice> AvailableDisplays
00285 {
00286 get { return available_displays_readonly; }
00287 }
00288
00289 #endregion
00290
00291 #region public static DisplayDevice Default
00292
00294 public static DisplayDevice Default { get { return primary_display; } }
00295
00296 #endregion
00297
00298 #endregion
00299
00300 #region --- Private Methods ---
00301
00302 #region DisplayResolution FindResolution(int width, int height, int bitsPerPixel, float refreshRate)
00303
00304 DisplayResolution FindResolution(int width, int height, int bitsPerPixel, float refreshRate)
00305 {
00306 return available_resolutions.Find(delegate(DisplayResolution test)
00307 {
00308 return
00309 ((width > 0 && width == test.Width) || width == 0) &&
00310 ((height > 0 && height == test.Height) || height == 0) &&
00311 ((bitsPerPixel > 0 && bitsPerPixel == test.BitsPerPixel) || bitsPerPixel == 0) &&
00312 ((refreshRate > 0 && System.Math.Abs(refreshRate - test.RefreshRate) < 1.0) || refreshRate == 0);
00313 });
00314 }
00315
00316 #endregion
00317
00318 #endregion
00319
00320 #region --- Overrides ---
00321
00322 #region public override string ToString()
00323
00328 public override string ToString()
00329 {
00330 return String.Format("{0}: {1} ({2} modes available)", IsPrimary ? "Primary" : "Secondary",
00331 Bounds.ToString(), available_resolutions.Count);
00332 }
00333
00334 #endregion
00335
00336 #region public override bool Equals(object obj)
00337
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355 #endregion
00356
00357 #region public override int GetHashCode()
00358
00362
00363
00364
00365
00366 #endregion
00367
00368 #endregion
00369 }
00370
00371 #region --- FadeEffect ---
00372 #if false
00373 class FadeEffect : IDisposable
00374 {
00375 List<Form> forms = new List<Form>();
00376 double opacity_step = 0.04;
00377 int sleep_step;
00378
00379 internal FadeEffect()
00380 {
00381 foreach (Screen s in Screen.AllScreens)
00382 {
00383 Form form = new Form();
00384 form.ShowInTaskbar = false;
00385 form.StartPosition = FormStartPosition.Manual;
00386 form.WindowState = FormWindowState.Maximized;
00387 form.FormBorderStyle = FormBorderStyle.None;
00388 form.TopMost = true;
00389
00390 form.BackColor = System.Drawing.Color.Black;
00391 forms.Add(form);
00392 }
00393
00394 sleep_step = 10 / forms.Count;
00395 MoveToStartPositions();
00396 }
00397
00398 void MoveToStartPositions()
00399 {
00400 int count = 0;
00401 foreach (Screen s in Screen.AllScreens)
00402 {
00403
00404
00405 count++;
00406 }
00407 }
00408
00409 bool FadedOut
00410 {
00411 get
00412 {
00413 bool ready = true;
00414 foreach (Form form in forms)
00415 ready = ready && form.Opacity >= 1.0;
00416
00417 return ready;
00418 }
00419 }
00420
00421 bool FadedIn
00422 {
00423 get
00424 {
00425 bool ready = true;
00426 foreach (Form form in forms)
00427 ready = ready && form.Opacity <= 0.0;
00428
00429 return ready;
00430 }
00431 }
00432
00433 internal void FadeOut()
00434 {
00435 MoveToStartPositions();
00436
00437 foreach (Form form in forms)
00438 {
00439 form.Opacity = 0.0;
00440 form.Visible = true;
00441 }
00442
00443 while (!FadedOut)
00444 {
00445 foreach (Form form in forms)
00446 {
00447 form.Opacity += opacity_step;
00448 form.Refresh();
00449 }
00450 Thread.Sleep(sleep_step);
00451 }
00452 }
00453
00454 internal void FadeIn()
00455 {
00456 MoveToStartPositions();
00457
00458 foreach (Form form in forms)
00459 form.Opacity = 1.0;
00460
00461 while (!FadedIn)
00462 {
00463 foreach (Form form in forms)
00464 {
00465 form.Opacity -= opacity_step;
00466 form.Refresh();
00467 }
00468 Thread.Sleep(sleep_step);
00469 }
00470
00471 foreach (Form form in forms)
00472 form.Visible = false;
00473 }
00474
00475 #region IDisposable Members
00476
00477 public void Dispose()
00478 {
00479 foreach (Form form in forms)
00480 form.Dispose();
00481 }
00482
00483 #endregion
00484 }
00485 #endif
00486 #endregion
00487 }