Index: mediaportal/MiniDisplayLibrary/MiniDisplayPlugin/Drivers/iMONDisplay.cs
===================================================================
--- mediaportal/MiniDisplayLibrary/MiniDisplayPlugin/Drivers/iMONDisplay.cs	(revision 26815)
+++ mediaportal/MiniDisplayLibrary/MiniDisplayPlugin/Drivers/iMONDisplay.cs	(working copy)
@@ -78,7 +78,7 @@
     private static extern bool _A_iMONVFD_Init(int vfdType, int resevered);
 
     [DllImport(@"..\VFD\SG_VFD.dll", EntryPoint = "iMONVFD_IsInited")]
-    private static extern bool _A_iMONVFD_IsInited();
+    private static extern int _A_iMONVFD_IsInited();
 
     [DllImport(@"..\VFD\SG_VFD.dll", EntryPoint = "iMONVFD_SetEQ")]
     private static extern bool _A_iMONVFD_SetEQ(int[] arEQValue);
@@ -96,7 +96,7 @@
     private static extern bool _iMONVFD_Init(int vfdType, int resevered);
 
     [DllImport(@".\SG_VFD.dll", EntryPoint = "iMONVFD_IsInited")]
-    private static extern bool _iMONVFD_IsInited();
+    private static extern int _iMONVFD_IsInited();
 
     [DllImport(@".\SG_VFD.dll", EntryPoint = "iMONVFD_SetEQ")]
     private static extern bool _iMONVFD_SetEQ(int[] arEQValue);
@@ -114,7 +114,7 @@
     private static extern bool _S_iMONVFD_Init(int vfdType, int resevered);
 
     [DllImport(@"..\iMON\SG_VFD.dll", EntryPoint = "iMONVFD_IsInited")]
-    private static extern bool _S_iMONVFD_IsInited();
+    private static extern int _S_iMONVFD_IsInited();
 
     [DllImport(@"..\iMON\SG_VFD.dll", EntryPoint = "iMONVFD_SetEQ")]
     private static extern bool _S_iMONVFD_SetEQ(int[] arEQValue);
@@ -177,7 +177,7 @@
         builder3 = builder2.DefinePInvokeMethod("iMONRC_IsInited", imonRC_DLLFile,
                                                 MethodAttributes.PinvokeImpl | MethodAttributes.HideBySig |
                                                 MethodAttributes.Static | MethodAttributes.Public,
-                                                CallingConventions.Standard, typeof (bool), null,
+                                                CallingConventions.Standard, typeof (int), null,
                                                 CallingConvention.StdCall, CharSet.Auto);
         builder3.SetImplementationFlags(MethodImplAttributes.PreserveSig | builder3.GetMethodImplementationFlags());
         builder3 = builder2.DefinePInvokeMethod("iMONRC_GetHWType", imonRC_DLLFile,
@@ -523,24 +523,22 @@
       }
     }
 
-    public bool iMONRC_IsInited()
+    public int iMONRC_IsInited()
     {
       if (_iMONDLL == null)
       {
-        return false;
+        return 0;
       }
       try
       {
-        return
-          (bool)
-          _iMONDLL.InvokeMember("iMONRC_IsInited",
+          return (int)_iMONDLL.InvokeMember("iMONRC_IsInited",
                                 BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static, null, null,
                                 null);
       }
       catch (Exception exception)
       {
         Log.Debug("iMONLCDg.iMONDisplay.iMONRC_IsInited(): Caught exception: {0}", new object[] {exception});
-        return false;
+        return 0;
       }
     }
 
@@ -569,61 +567,101 @@
         Log.Info("iMONLCDg.iMONDisplay.iMONVFD_Init(): Opening Display with iMONVFD_Init({0},{1})",
                  new object[] {VFD_Type.ToString("x00"), VFD_Reserved.ToString("x00")});
       }
-      bool flag = false;
-      while ((num < 10) && !flag)
+
+      bool ret = false;
+      int state = 0;
+
+      try
       {
-        if (num > 0)
+        while ((num < 100) && !ret)
         {
-          if (_A_DLL)
+          num++;
+          if (state == 0)
           {
-            _A_iMONVFD_Uninit();
+            if (_A_DLL)
+            {
+              state = _A_iMONVFD_IsInited();
+            }
+            else if (_S_DLL)
+            {
+              state = _S_iMONVFD_IsInited();
+            }
+            else
+            {
+              state = _iMONVFD_IsInited();
+            }
+            if (DoDebug)
+            {
+              Log.Info("iMONLCDg.iMONDisplay.iMONVFD_Init(): Device not ready - retrying...");
+            }
+            Thread.Sleep(300);
+            continue;
           }
-          else if (_S_DLL)
+
+          if (state == 1)
           {
-            _S_iMONVFD_Uninit();
+            if (_A_DLL)
+            {
+              _A_iMONVFD_Uninit();
+            }
+            else if (_S_DLL)
+            {
+              _S_iMONVFD_Uninit();
+            }
+            else
+            {
+              _iMONVFD_Uninit();
+            }
+            Thread.Sleep(300);
+            VFD_Reserved = VFD_Reserved == 0 ? 0x8888 : 0;
+            if (DoDebug)
+            {
+              Log.Info("iMONLCDg.iMONDisplay.iMONVFD_Init(): Device already inited - retrying...");
+            }
+            state = 0;
+            continue;
           }
-          else
+
+          if (_A_DLL)
           {
-            _iMONVFD_Uninit();
+            if (DoDebug)
+            {
+              Log.Info("iMONLCDg.iMONDisplay.iMONVFD_Init(): Opening Display with Installed Antec DLL");
+            }
+            ret = _A_iMONVFD_Init(VFD_Type, VFD_Reserved);
+            break;
           }
-          Thread.Sleep(150);
-          VFD_Reserved = VFD_Reserved == 0 ? 0x8888 : 0;
-          if (DoDebug)
+          else if (_S_DLL)
           {
-            Log.Info("iMONLCDg.iMONDisplay.iMONVFD_Init(): Open failed - retrying...");
+            if (DoDebug)
+            {
+              Log.Info("iMONLCDg.iMONDisplay.iMONVFD_Init(): Opening Display with Installed SoundGraph DLL");
+            }
+            ret = _S_iMONVFD_Init(VFD_Type, VFD_Reserved);
+            break;
           }
-        }
-        if (_A_DLL)
-        {
-          if (DoDebug)
+          else
           {
-            Log.Info("iMONLCDg.iMONDisplay.iMONVFD_Init(): Opening Display with Installed Antec DLL");
+            if (DoDebug)
+            {
+              Log.Info("iMONLCDg.iMONDisplay.iMONVFD_Init(): Opening Display with default DLL");
+            }
+            ret = _iMONVFD_Init(VFD_Type, VFD_Reserved);
+            break;
           }
-          flag = _A_iMONVFD_Init(VFD_Type, VFD_Reserved);
         }
-        else if (_S_DLL)
+        if (DoDebug)
         {
-          if (DoDebug)
-          {
-            Log.Info("iMONLCDg.iMONDisplay.iMONVFD_Init(): Opening Display with Installed SoundGraph DLL");
-          }
-          flag = _S_iMONVFD_Init(VFD_Type, VFD_Reserved);
+          Log.Info("iMONLCDg.iMONDisplay.iMONVFD_Init(): Display Open Returned: {0}", ret);
         }
-        else
-        {
-          if (DoDebug)
-          {
-            Log.Info("iMONLCDg.iMONDisplay.iMONVFD_Init(): Opening Display with default DLL");
-          }
-          flag = _iMONVFD_Init(VFD_Type, VFD_Reserved);
-        }
-        num++;
       }
-      if (DoDebug)
+      catch (Exception exception)
       {
-        Log.Info("iMONLCDg.iMONDisplay.iMONVFD_Init(): Display Open Returned: {0}", new object[] {flag});
+        Log.Debug("iMONLCDg.iMONDisplay.iMONVFD_Init(): Caught exception: {0}", exception);
+        ret = false;
       }
-      return flag;
+
+      return ret;
     }
 
     public bool iMONVFD_Init_OLD(int VFD_Type, int VFD_Reserved)
@@ -650,7 +688,7 @@
       return _iMONVFD_Init(VFD_Type, VFD_Reserved);
     }
 
-    public bool iMONVFD_IsInited()
+    public int iMONVFD_IsInited()
     {
       if (_A_DLL)
       {
@@ -703,15 +741,29 @@
 
     public void iMONVFD_Uninit()
     {
-      if (_A_DLL)
+      try
       {
-        _A_iMONVFD_Uninit();
+        if (_A_DLL)
+        {
+          _A_iMONVFD_Uninit();
+        }
+        if (_S_DLL)
+        {
+          _S_iMONVFD_Uninit();
+        }
+        else
+        {
+          _iMONVFD_Uninit();
+        }
+        if (DoDebug)
+        {
+          Log.Info("iMONLCDg.iMONDisplay.iMONVFD_Uninit()");
+        }
       }
-      if (_S_DLL)
+      catch (Exception exception)
       {
-        _S_iMONVFD_Uninit();
+        Log.Debug("iMONLCDg.iMONDisplay.iMONVFD_Uninit(): Caught exception: {0}", exception);
       }
-      _iMONVFD_Uninit();
     }
 
     public bool Initialize(string DLLFullPath)
Index: mediaportal/MiniDisplayLibrary/MiniDisplayPlugin/Drivers/iMONLCDg.cs
===================================================================
--- mediaportal/MiniDisplayLibrary/MiniDisplayPlugin/Drivers/iMONLCDg.cs	(revision 26815)
+++ mediaportal/MiniDisplayLibrary/MiniDisplayPlugin/Drivers/iMONLCDg.cs	(working copy)
@@ -50,8 +50,6 @@
                                                      {"Antec", "VFD"}
                                                    };
 
-    public static readonly int _BrandTableLength = 1;
-
     public static readonly byte[,] _Font8x5 = new byte[,]
                                                 {
                                                   {0, 0, 0, 0, 0, 0}, {0, 100, 0x18, 4, 100, 0x18},
@@ -268,15 +266,41 @@
 
     private static readonly object ThreadMutex = new object();
     private static int _DisplayType = -1;
-    private static bool _stopUpdateIconThread;
     private static bool _VFD_UseV3DLL;
     private static int _VfdReserved = 0x8888;
     private static int _VfdType = 0x18;
     private static DeviceVolumeMonitor DVM;
     private readonly string[] _lines = new string[2];
     private readonly SHA256Managed _sha256 = new SHA256Managed();
+    private bool _postSetupDone = false;
+    private ManualResetEvent _stopIconThreadEvent = new ManualResetEvent(false);
+    private enum DriverStateEnum
+    {
+        Unknown,
+        Disabled,
+        NotInitialized,
+        DriverInitialized,
+        DisplayInitialized,
+        Running,
+        OpeningDisplay,
+        ClosingDisplay
+    }
 
+    private DriverStateEnum _driverStateInternal = DriverStateEnum.Unknown;
 
+    private DriverStateEnum _DriverState
+    {
+        get { return _driverStateInternal; }
+        set {
+            if (Settings.Instance.ExtensiveLogging)
+            {
+                Log.Info("iMONLCDg.DriverState: changed state " + _driverStateInternal.ToString() + " to " + value.ToString());
+            }
+            _driverStateInternal = value;
+        }
+    }
+
+
     private bool _Backlight;
     private ulong _BacklightLevel = 0L;
     private bool _BlankDisplayOnExit;
@@ -300,7 +324,6 @@
     private iMONDisplay _IMON;
 
     private bool _IsConfiguring;
-    private bool _isDisabled;
     private bool _IsDisplayOff;
     private bool _IsHandlingPowerEvent;
     private byte[] _lastHash;
@@ -363,7 +386,7 @@
 
     public void CleanUp()
     {
-      if (!_isDisabled)
+      if (_DriverState != DriverStateEnum.Disabled)
       {
         Log.Info("(IDisplay) iMONLCDg.CleanUp(): called");
         AdvancedSettings.OnSettingsChanged -=
@@ -422,49 +445,49 @@
         Process[] procs = Process.GetProcessesByName(irss_app);
         foreach (Process proc in procs)
         {
-          Log.Debug("iMONLCDg.Dispose(): Restarting \"" + irss_app + "\" (application) from IRSS");
-          proc.Kill();
-          proc.WaitForExit(2000);
+          try
+          {
+            Log.Debug("iMONLCDg.Dispose(): Restarting \"" + irss_app + "\" (application) from IRSS");
+            proc.Kill();
+            proc.WaitForExit(2000);
 
-          UIntPtr res = UIntPtr.Zero;
-          UIntPtr rKey = new UIntPtr(Convert.ToUInt32(Reg.RegistryRoot.HKLM));
-          int lastError;
-          int retval = Reg.RegOpenKeyEx(rKey, "SOFTWARE\\IR Server Suite", 0, Convert.ToInt32(RegistryRights.ReadKey),
-                                        out res);
-          if (retval == 0)
-          {
-            uint tKey;
-            uint lKey = 100;
-            StringBuilder sKey = new StringBuilder((int)lKey);
-            retval = Reg.RegQueryValueEx(res, "Install_Dir", 0, out tKey, sKey, ref lKey);
+            UIntPtr res = UIntPtr.Zero;
+            UIntPtr rKey = new UIntPtr(Convert.ToUInt32(Reg.RegistryRoot.HKLM));
+            int lastError;
+            int retval = Reg.RegOpenKeyEx(rKey, "SOFTWARE\\IR Server Suite", 0, Convert.ToInt32(RegistryRights.ReadKey),
+                                          out res);
             if (retval == 0)
             {
-              workdir = sKey.ToString();
+              uint tKey;
+              uint lKey = 100;
+              StringBuilder sKey = new StringBuilder((int)lKey);
+              retval = Reg.RegQueryValueEx(res, "Install_Dir", 0, out tKey, sKey, ref lKey);
+              if (retval == 0)
+              {
+                workdir = sKey.ToString();
+              }
+              else
+              {
+                lastError = Marshal.GetLastWin32Error();
+                Log.Debug("RegQueryValueEx retval=<{0}>, lastError=<{1}>", retval, lastError);
+              }
             }
             else
             {
-              lastError = Marshal.GetLastWin32Error();
-              Log.Debug("RegQueryValueEx retval=<{0}>, lastError=<{1}>", retval, lastError);
+              Log.Error("iMONLCDg.Dispose(): IRSS registry keys missing, aborting...");
+              break;
             }
-          }
-          else
-          {
-            Log.Error("iMONLCDg.Dispose(): IRSS registry keys missing, aborting...");
-            break;
-          }
 
-          Win32Functions.RedrawNotificationArea();
+            Win32Functions.RedrawNotificationArea();
 
-          try
-          {
             Process proc2 = new Process
-                              {
-                                StartInfo =
-                                  {
-                                    FileName = workdir + "\\" + irss_app + ".exe",
-                                    WorkingDirectory = workdir
-                                  }
-                              };
+                            {
+                              StartInfo =
+                                {
+                                  FileName = workdir + "\\" + irss_app + ".exe",
+                                  WorkingDirectory = workdir
+                                }
+                            };
             proc2.Start();
           }
           catch (Exception ex)
@@ -472,7 +495,6 @@
             Log.Error("iMONLCDg.Dispose(): Unable to restart \"" + irss_app + "\" (application) from IRSS: " +
                       ex.Message);
           }
-          break;
         }
       }
       Log.Debug("iMONLCDg.Dispose(): completed");
@@ -480,7 +502,7 @@
 
     public void DrawImage(Bitmap bitmap)
     {
-      if (!_isDisabled)
+      if (_DriverState != DriverStateEnum.Disabled)
       {
         if (EQSettings._EqDataAvailable || _IsDisplayOff)
         {
@@ -567,13 +589,17 @@
     public void Initialize()
     {
       Log.Info("(IDisplay) iMONLCDg.Initialize(): called");
-      if (_isDisabled)
+      if (_DriverState == DriverStateEnum.Disabled)
       {
         Log.Info("(IDisplay) iMONLCDg.Initialize(): completed\n\n iMONLCDg DRIVER DISABLED\n\n");
       }
       else
       {
         OpenLcd();
+        if (!_postSetupDone)
+        {
+            PostSetup();
+        }
         Clear();
         Log.Info("(IDisplay) iMONLCDg.Initialize(): completed");
       }
@@ -583,7 +609,7 @@
 
     public void SetLine(int line, string message)
     {
-      if (!_isDisabled)
+      if (_DriverState != DriverStateEnum.Disabled)
       {
         try
         {
@@ -625,7 +651,7 @@
       if (_DelayStartup)
       {
         Log.Info("iMONLCDg.Setup(): Delaying device initialization by 10 seconds");
-        Thread.Sleep(0x2710);
+        Thread.Sleep(10000);
       }
       Check_iMON_Manager_Status();
       if (_IMON == null)
@@ -663,161 +689,55 @@
           break;
         default:
           Log.Info("(IDisplay) iMONLCDg.Setup(): Autodetecting iMON Display device");
-          try
+          AutodetectHardware(ref fWVersion, ref rEGVersion);
+          break;
+      }
+
+      if (_DriverState != DriverStateEnum.Disabled)
+      {
+        try
+        {
+          Log.Info("(IDisplay) iMONLCDg.Setup(): Testing iMON Display device");
+          int state = _IMON.iMONVFD_IsInited();
+          int num = 0;
+          while (state < 255)
           {
-            Log.Info("(IDisplay) iMONLCDg.Setup(): attempting hardware information test");
-            if (_IMON.RC_Available())
-            {
-              Log.Info("(IDisplay) iMONLCDg.Setup(): hardware information test - Opening SG_RC.dll");
-              if (_IMON.iMONRC_Init(0x77, 0x83, 0x8888))
+              if (state == 1)
               {
-                long num4 = _IMON.iMONRC_CheckDriverVersion();
-                int num5 = _IMON.iMONRC_GetFirmwareVer();
-                int num6 = _IMON.iMONRC_GetHWType();
-                int num7 = _IMON.iMONRC_GetLastRFMode();
-                Log.Info(
-                  "(IDisplay) iMONLCDg.Setup(): RC TEST returned DRVR: 0x{0}, FW: 0x{1} (HW: 0x{2}), RC_HW: 0x{3}, RF: 0x{4}",
-                  num4.ToString("x0000000000000000"), num5.ToString("x00000000"),
-                  GetVFDTypeFromFirmware(num5).ToString("x00000000"), num6.ToString("x00000000"),
-                  num7.ToString("x00000000"));
-                if (num5 > 0)
-                {
-                  fWVersion = num5;
-                }
-                Log.Info("(IDisplay) iMONLCDg.Setup(): Closing SG_RC.dll");
-                _IMON.iMONRC_Uninit();
+                  _IMON.iMONVFD_Uninit();
               }
-              else
+              Thread.Sleep(300);
+              state = _IMON.iMONVFD_IsInited();
+              if ((num++) > 100)
               {
-                long num8 = _IMON.iMONRC_CheckDriverVersion();
-                int num9 = _IMON.iMONRC_GetFirmwareVer();
-                int num10 = _IMON.iMONRC_GetHWType();
-                int num11 = _IMON.iMONRC_GetLastRFMode();
-                Log.Info("iMONLCDg.Setup(): RC TEST returned DRVR: 0x{0}, FW: 0x{1} (HW: {2}), RC_HW: 0x{3}, RF: 0x{4}",
-                         num8.ToString("x0000000000000000"), num9.ToString("x00000000"),
-                         GetVFDTypeFromFirmware(num9).ToString("x00000000"), num10.ToString("x00000000"),
-                         num11.ToString("x00000000"));
-                if (num9 > 0)
-                {
-                  Log.Info("iMONLCDg.Setup(): Found valid display information");
-                  fWVersion = num9;
-                }
-                Log.Info("iMONLCDg.Setup(): Closing SG_RC.dll");
+                  break;
               }
-            }
-            else
-            {
-              Log.Info("iMONLCDg.Setup(): Hardware AutoDetect not available");
-            }
           }
-          catch (Exception exception)
+          if (state > 255)
           {
-            Log.Info("iMONLCDg.Setup(): RC TEST FAILED... SG_RC.dll not found. Exception: {0}", exception);
-          }
-          try
-          {
-            int num3;
-            for (int i = 0; i < _BrandTableLength; i++)
-            {
-              string curBrand = _BrandTable[i, 0];
-              string curApp = _BrandTable[i, 1];
-              Log.Info("iMONLCDg.Setup(): checking registry for " + curBrand + " entries");
-              RegistryKey key = Registry.CurrentUser.OpenSubKey(@"Software" + curBrand + "\\" + curApp, false);
-              if (key != null)
+              Log.Info("(IDisplay) iMONLCDg.Setup(): opening display type {0}", DisplayType.TypeName(_DisplayType));
+              if (!_IMON.iMONVFD_Init(_VfdType, _VfdReserved))
               {
-                num3 = (int)key.GetValue("LastVFD", 0);
-                if (num3 > 0)
-                {
-                  Log.Info("iMONLCDg.Setup(): " + curBrand + " registry entries found - HW: {0}", num3.ToString("x00"));
-                  rEGVersion = num3;
-                }
-                else
-                {
-                  Log.Info("iMONLCDg.Setup(): " + curBrand + " \"LastVFD\" key not found");
-                }
+                  Log.Info("(IDisplay) iMONLCDg.Setup(): Open failed - No iMON device found");
+                  _DriverState = DriverStateEnum.Disabled;
+                  _errorMessage = "iMONLCDg could not find an iMON LCD display";
               }
               else
               {
-                Log.Info("iMONLCDg.Setup(): " + curBrand + " registry entries NOT found");
+                  _IMON.iMONVFD_Uninit();
+                  Log.Info("(IDisplay) iMONLCDg.Setup(): iMON Display device found");
               }
-              Registry.CurrentUser.Close();
-              if (rEGVersion >= 0)
-              {
-                break;
-              }
-            }
           }
-          catch (Exception exception2)
-          {
-            Log.Info("iMONLCDg.Setup(): registry test caught exception {0}", exception2);
-          }
-          if (fWVersion > -1)
-          {
-            if (GetDisplayInfoFromFirmware(fWVersion))
-            {
-              Log.Info("iMONLCDg.Setup(): Hardware tests determined - iMON Type: {0}, Display Type: {1} Rsrvd: {2}",
-                       _VfdType.ToString("x00"), DisplayType.TypeName(_DisplayType), _VfdReserved.ToString("x00"));
-            }
-            else
-            {
-              Log.Info("iMONLCDg.Setup(): Hardware tests determined UNSUPPORTED display type!");
-              _DisplayType = DisplayType.Unsupported;
-            }
-          }
-          else if (rEGVersion > -1)
-          {
-            if (GetDisplayInfoFromRegistry(rEGVersion))
-            {
-              Log.Info("iMONLCDg.Setup(): Registry tests determined - iMON Type: {0}, Display Type: {1} Rsrvd: {2}",
-                       _VfdType.ToString("x00"), DisplayType.TypeName(_DisplayType), _VfdReserved.ToString("x00"));
-            }
-            else
-            {
-              Log.Info("iMONLCDg.Setup(): Registry tests determined UNSUPPORTED display type!");
-              _DisplayType = DisplayType.Unsupported;
-              _isDisabled = true;
-            }
-          }
           else
           {
-            Log.Info("(IDisplay) iMONLCDg.Setup(): Display Type could not be determined");
-            _DisplayType = DisplayType.Unsupported;
-            _isDisabled = true;
+              Log.Info("(IDisplay) iMONLCDg.Setup(): Open failed - Bad iMON init state");
+              _DriverState = DriverStateEnum.Disabled;
+              _errorMessage = "iMONLCDg could not find an iMON LCD display";
           }
-          if (_DisplayType == DisplayType.Unsupported)
-          {
-            _isDisabled = true;
-            Log.Info("(IDisplay) iMONLCDg.Setup(): Display Type is NOT SUPPORTED - Plugin disabled");
-          }
-          break;
-      }
-
-      if (!_isDisabled)
-      {
-        try
-        {
-          Log.Info("(IDisplay) iMONLCDg.Setup(): Testing iMON Display device");
-          if (_IMON.iMONVFD_IsInited())
-          {
-            Log.Info("(IDisplay) iMONLCDg.Setup(): iMON Display found");
-            _IMON.iMONVFD_Uninit();
-          }
-          Log.Info("(IDisplay) iMONLCDg.Setup(): opening display type {0}", DisplayType.TypeName(_DisplayType));
-          if (!_IMON.iMONVFD_Init(_VfdType, _VfdReserved))
-          {
-            Log.Info("(IDisplay) iMONLCDg.Setup(): Open failed - No iMON device found");
-            _isDisabled = true;
-            _errorMessage = "iMONLCDg could not find an iMON LCD display";
-          }
-          else
-          {
-            Log.Info("(IDisplay) iMONLCDg.Setup(): iMON Display device found");
-            _IMON.iMONVFD_Uninit();
-          }
         }
         catch (Exception exception3)
         {
-          _isDisabled = true;
+          _DriverState = DriverStateEnum.Disabled;
           _errorMessage = exception3.Message;
           Log.Info("(IDisplay) iMONLCDg.Setup(): caught an exception.");
         }
@@ -893,9 +813,139 @@
       Log.Info("(IDisplay) iMONLCDg.Setup(): Completed");
     }
 
+    private void AutodetectHardware(ref int fWVersion, ref int rEGVersion)
+    {
+      try
+      {
+        Log.Info("(IDisplay) iMONLCDg.Setup(): attempting hardware information test");
+        if (_IMON.RC_Available())
+        {
+          Log.Info("(IDisplay) iMONLCDg.Setup(): hardware information test - Opening SG_RC.dll");
+          if (_IMON.iMONRC_Init(0x77, 0x83, 0x8888))
+          {
+            long num4 = _IMON.iMONRC_CheckDriverVersion();
+            int num5 = _IMON.iMONRC_GetFirmwareVer();
+            int num6 = _IMON.iMONRC_GetHWType();
+            int num7 = _IMON.iMONRC_GetLastRFMode();
+            Log.Info(
+              "(IDisplay) iMONLCDg.Setup(): RC TEST returned DRVR: 0x{0}, FW: 0x{1} (HW: 0x{2}), RC_HW: 0x{3}, RF: 0x{4}",
+              num4.ToString("x0000000000000000"), num5.ToString("x00000000"),
+              GetVFDTypeFromFirmware(num5).ToString("x00000000"), num6.ToString("x00000000"),
+              num7.ToString("x00000000"));
+            if (num5 > 0)
+            {
+              fWVersion = num5;
+            }
+            Log.Info("(IDisplay) iMONLCDg.Setup(): Closing SG_RC.dll");
+            _IMON.iMONRC_Uninit();
+          }
+          else
+          {
+            long num8 = _IMON.iMONRC_CheckDriverVersion();
+            int num9 = _IMON.iMONRC_GetFirmwareVer();
+            int num10 = _IMON.iMONRC_GetHWType();
+            int num11 = _IMON.iMONRC_GetLastRFMode();
+            Log.Info("iMONLCDg.Setup(): RC TEST returned DRVR: 0x{0}, FW: 0x{1} (HW: {2}), RC_HW: 0x{3}, RF: 0x{4}",
+                     num8.ToString("x0000000000000000"), num9.ToString("x00000000"),
+                     GetVFDTypeFromFirmware(num9).ToString("x00000000"), num10.ToString("x00000000"),
+                     num11.ToString("x00000000"));
+            if (num9 > 0)
+            {
+              Log.Info("iMONLCDg.Setup(): Found valid display information");
+              fWVersion = num9;
+            }
+            Log.Info("iMONLCDg.Setup(): Closing SG_RC.dll");
+          }
+        }
+        else
+        {
+          Log.Info("iMONLCDg.Setup(): Hardware AutoDetect not available");
+        }
+      }
+      catch (Exception exception)
+      {
+        Log.Info("iMONLCDg.Setup(): RC TEST FAILED... SG_RC.dll not found. Exception: {0}", exception);
+      }
+      try
+      {
+        int num3;
+        for (int i = 0; i < _BrandTable.GetLength(0); i++)
+        {
+          string curBrand = _BrandTable[i, 0];
+          string curApp = _BrandTable[i, 1];
+          Log.Info("iMONLCDg.Setup(): checking registry for " + curBrand + " entries");
+          RegistryKey key = Registry.CurrentUser.OpenSubKey(@"Software\" + curBrand + "\\" + curApp, false);
+          if (key != null)
+          {
+            num3 = (int)key.GetValue("LastVFD", 0);
+            if (num3 > 0)
+            {
+              Log.Info("iMONLCDg.Setup(): " + curBrand + " registry entries found - HW: {0}", num3.ToString("x00"));
+              rEGVersion = num3;
+            }
+            else
+            {
+              Log.Info("iMONLCDg.Setup(): " + curBrand + " \"LastVFD\" key not found");
+            }
+          }
+          else
+          {
+            Log.Info("iMONLCDg.Setup(): " + curBrand + " registry entries NOT found");
+          }
+          Registry.CurrentUser.Close();
+          if (rEGVersion >= 0)
+          {
+            break;
+          }
+        }
+      }
+      catch (Exception exception2)
+      {
+        Log.Info("iMONLCDg.Setup(): registry test caught exception {0}", exception2);
+      }
+      if (fWVersion > -1)
+      {
+        if (GetDisplayInfoFromFirmware(fWVersion))
+        {
+          Log.Info("iMONLCDg.Setup(): Hardware tests determined - iMON Type: {0}, Display Type: {1} Rsrvd: {2}",
+                   _VfdType.ToString("x00"), DisplayType.TypeName(_DisplayType), _VfdReserved.ToString("x00"));
+        }
+        else
+        {
+          Log.Info("iMONLCDg.Setup(): Hardware tests determined UNSUPPORTED display type!");
+          _DisplayType = DisplayType.Unsupported;
+        }
+      }
+      else if (rEGVersion > -1)
+      {
+        if (GetDisplayInfoFromRegistry(rEGVersion))
+        {
+          Log.Info("iMONLCDg.Setup(): Registry tests determined - iMON Type: {0}, Display Type: {1} Rsrvd: {2}",
+                   _VfdType.ToString("x00"), DisplayType.TypeName(_DisplayType), _VfdReserved.ToString("x00"));
+        }
+        else
+        {
+          Log.Info("iMONLCDg.Setup(): Registry tests determined UNSUPPORTED display type!");
+          _DisplayType = DisplayType.Unsupported;
+          _DriverState = DriverStateEnum.Disabled;
+        }
+      }
+      else
+      {
+        Log.Info("(IDisplay) iMONLCDg.Setup(): Display Type could not be determined");
+        _DisplayType = DisplayType.Unsupported;
+        _DriverState = DriverStateEnum.Disabled;
+      }
+      if (_DisplayType == DisplayType.Unsupported)
+      {
+        _DriverState = DriverStateEnum.Disabled;
+        Log.Info("(IDisplay) iMONLCDg.Setup(): Display Type is NOT SUPPORTED - Plugin disabled");
+      }
+    }
+
     public string Description
     {
-      get { return "SoundGraph iMON USB VFD/LCD Plugin v29_11_2009"; }
+      get { return "SoundGraph iMON USB VFD/LCD Plugin v20_11_2010"; }
     }
 
     public string ErrorMessage
@@ -907,8 +957,8 @@
     {
       get
       {
-        Log.Debug("iMONLCDg.IsDisabled: returning {0}", _isDisabled);
-        return _isDisabled;
+        Log.Debug("iMONLCDg.IsDisabled: returning {0}", _DriverState == DriverStateEnum.Disabled);
+        return _DriverState == DriverStateEnum.Disabled;
       }
     }
 
@@ -921,7 +971,7 @@
     {
       get
       {
-        if (_isDisabled)
+        if (_DriverState == DriverStateEnum.Disabled)
         {
           return true;
         }
@@ -933,7 +983,7 @@
         {
           Log.Info("(IDisplay) iMONLCDg.SupportsGraphics(): _displayType = {0}", DisplayType.TypeName(_DisplayType));
         }
-        if (!_IMON.iMONVFD_IsInited())
+        if (_IMON.iMONVFD_IsInited() == 0)
         {
           if (DoDebug)
           {
@@ -1078,7 +1128,7 @@
       Process[] processesByName;
       Process process;
 
-      for (int i = 0; i <= _BrandTableLength; i++)
+      for (int i = 0; i < _BrandTable.GetLength(0); i++)
       {
         string curBrand = _BrandTable[i, 0];
         string curApp = _BrandTable[i, 1];
@@ -1218,7 +1268,7 @@
       {
         Log.Debug(
           "iMONLCDg.Check_iMON_Manager_Status(): Ensure Manager Start is selected.. ensuring that the manager is running");
-        for (int i = 0; i <= _BrandTableLength; i++)
+        for (int i = 0; i < _BrandTable.GetLength(0); i++)
         {
           string curBrand = _BrandTable[i, 0];
           string curApp = _BrandTable[i, 1];
@@ -1301,7 +1351,7 @@
 
     public void Clear()
     {
-      if (!_isDisabled)
+      if (_DriverState != DriverStateEnum.Disabled)
       {
         Log.Debug("iMONLCDg.Clear(): called");
         for (int i = 0; i < 2; i++)
@@ -1318,25 +1368,42 @@
       Clear();
     }
 
+    private void StopIconThread(bool forceAbort)
+    {
+        _stopIconThreadEvent.Set();
+        if (forceAbort)
+        {
+            Log.Info("iMONLCDg.StopIconThread: Going to abort thread");
+            _iconThread.Abort();
+        }
+        _iconThread.Join();
+    }
+
     private void CloseLcd()
     {
       Log.Info("iMONLCDg.CloseLcd(): called");
-      if (_IMON.iMONVFD_IsInited())
+      if (_DriverState == DriverStateEnum.ClosingDisplay)
       {
+        //another thread closing lcd
+        int num = 0;
+        while (num < 100 && _DriverState == DriverStateEnum.ClosingDisplay)
+        {
+          Thread.Sleep(100);
+          num++;
+        }
+        return;
+      }
+
+      _DriverState = DriverStateEnum.ClosingDisplay;
+
+      if (_IMON.iMONVFD_IsInited() == 1)
+      {
         if ((_DisplayType == DisplayType.LCD) || (_DisplayType == DisplayType.LCD2))
         {
           if (!_displayTest)
           {
-            while (_iconThread.IsAlive)
-            {
-              Log.Info("iMONLCDg.CloseLcd(): Stopping iMONLCDg.UpdateIcons() Thread");
-              lock (ThreadMutex)
-              {
-                _stopUpdateIconThread = true;
-              }
-              _stopUpdateIconThread = true;
-              Thread.Sleep(500);
-            }
+            Log.Info("iMONLCDg.CloseLcd(): Stopping iMONLCDg.UpdateIcons() Thread");
+            StopIconThread(_IsHandlingPowerEvent);
           }
           Log.Info("iMONLCDg.CloseLcd(): Preparing for shutdown");
           SendData(iMonCommand.General.SetIcons);
@@ -1379,12 +1446,15 @@
             SendData(num);
           }
           SendData(iMonCommand.General.KeypadLightOff);
+
           if (DisplayOptions.UseCustomFont)
           {
+            Log.Debug("iMONLCDg.CloseLcd(): freeing font");
             CFont.CloseFont();
           }
           if (DisplayOptions.UseLargeIcons & DisplayOptions.UseCustomIcons)
           {
+            Log.Debug("iMONLCDg.CloseLcd(): freeing icons");
             CustomLargeIcon.CloseIcons();
           }
         }
@@ -1392,16 +1462,8 @@
         {
           if (EQSettings.UseEqDisplay || DisplaySettings.BlankDisplayWithVideo)
           {
-            while (_iconThread.IsAlive)
-            {
-              Log.Info("iMONLCDg.CloseLcd(): Stoping iMONLCDg.VFD_EQ_Update() Thread");
-              lock (ThreadMutex)
-              {
-                _stopUpdateIconThread = true;
-              }
-              _stopUpdateIconThread = true;
-              Thread.Sleep(500);
-            }
+            Log.Info("iMONLCDg.CloseLcd(): Stoping iMONLCDg.VFD_EQ_Update() Thread");
+            StopIconThread(_IsHandlingPowerEvent);
           }
           if (_BlankDisplayOnExit)
           {
@@ -1426,16 +1488,8 @@
         {
           if (EQSettings.UseEqDisplay || DisplaySettings.BlankDisplayWithVideo)
           {
-            while (_iconThread.IsAlive)
-            {
-              Log.Info("iMONLCDg.CloseLcd(): Stoping iMONLCDg.VFD_EQ_Update() Thread");
-              lock (ThreadMutex)
-              {
-                _stopUpdateIconThread = true;
-              }
-              _stopUpdateIconThread = true;
-              Thread.Sleep(500);
-            }
+            Log.Info("iMONLCDg.CloseLcd(): Stoping iMONLCDg.VFD_EQ_Update() Thread");
+            StopIconThread(_IsHandlingPowerEvent);
           }
           if (_BlankDisplayOnExit)
           {
@@ -1458,7 +1512,11 @@
             SendData(0x0000000000000002L);
           }
         }
-        _IMON.iMONVFD_Uninit();
+        if (_IMON.iMONVFD_IsInited() == 1)
+        {
+          Log.Info("iMONLCDg.CloseLcd(): Going to uninit");
+          _IMON.iMONVFD_Uninit();
+        }
       }
       else
       {
@@ -1470,8 +1528,10 @@
         SystemEvents.PowerModeChanged -= SystemEvents_PowerModeChanged;
       }
 
+      _DriverState = DriverStateEnum.DisplayInitialized; 
       RestartFrontview();
       Log.Info("iMONLCDg.CloseLcd(): completed");
+
     }
 
     private static ulong ConvertPluginIconsToDriverIcons(ulong IconMask)
@@ -1646,6 +1706,11 @@
 
     private void DisplayLines()
     {
+      if (_DriverState != DriverStateEnum.Running)
+      {
+          return;
+      }
+
       UpdateAdvancedSettings();
       if (DoDebug)
       {
@@ -2189,7 +2254,7 @@
       }
       else
       {
-        for (int i = 0; i <= _BrandTableLength; i++)
+        for (int i = 0; i <= _BrandTable.GetLength(0); i++)
         {
           string curBrand = _BrandTable[i, 0];
           string curApp = _BrandTable[i, 1];
@@ -2492,7 +2557,7 @@
       if (((imonVFD_DLLFile = FindImonVFDdll()) == string.Empty) & !_VFD_UseV3DLL)
       {
         Log.Info("iMONLCDg.InitializeDriver(): Failed - installed sg_vfd.dll not found - driver disabled");
-        _isDisabled = true;
+        _DriverState = DriverStateEnum.Disabled;
       }
       else
       {
@@ -2500,12 +2565,12 @@
         if (!_IMON.Initialize(imonVFD_DLLFile))
         {
           Log.Info("iMONLCDg.InitializeDriver(): DLL linking Failed - driver disabled");
-          _isDisabled = true;
+          _DriverState = DriverStateEnum.Disabled;
         }
         else
         {
-          _isDisabled = false;
-          Log.Info("iMONLCDg.InitializeDriver(): completed.");
+            _DriverState = DriverStateEnum.DriverInitialized;
+            Log.Info("iMONLCDg.InitializeDriver(): completed.");
         }
       }
     }
@@ -2622,100 +2687,101 @@
       }
     }
 
-    private void OpenLcd()
+    private void PostSetup()
     {
-      if (!_isDisabled)
-      {
-        Log.Info("iMONLCDg.OpenLcd(): called");
-        if (!_IMON.iMONVFD_IsInited())
+        if (!_displayTest & ((_DisplayType == DisplayType.LCD) || (_DisplayType == DisplayType.LCD2)))
         {
-          Log.Info("iMONLCDg.OpenLcd(): opening display");
-          Log.Info("iMONLCDg.OpenLcd(): opening display with iMONVFD_Init({0},{1})", _VfdType.ToString("x00"),
-                   _VfdReserved.ToString("x0000"));
-          if (!_IMON.iMONVFD_Init(_VfdType, _VfdReserved))
+          if (DisplayOptions.UseCustomFont)
           {
-            Log.Info("iMONLCDg.OpenLcd(): Could not open display with Open({0},{1})", _VfdType.ToString("x00"),
-                     _VfdReserved.ToString("x0000"));
-            _isDisabled = true;
-            _errorMessage = "Could not open iMON display device";
+            CFont = new CustomFont();
+            CFont.InitializeCustomFont();
           }
+          if (DisplayOptions.UseLargeIcons)
+          {
+            CustomLargeIcon = new LargeIcon();
+            CustomLargeIcon.InitializeLargeIcons();
+          }
+          _iconThread = new Thread(UpdateIcons)
+                          {
+                            IsBackground = true,
+                            Priority = ThreadPriority.BelowNormal,
+                            Name = "UpdateIconThread"
+                          };
+          _iconThread.Start();
+          if (_iconThread.IsAlive)
+          {
+              Log.Info("iMONLCDg.PostSetup(): iMONLCDg.UpdateIcons() Thread Started");
+          }
           else
           {
-            Log.Info("iMONLCDg.OpenLcd(): display opened");
-            if (!_displayTest & ((_DisplayType == DisplayType.LCD) || (_DisplayType == DisplayType.LCD2)))
+              Log.Info("iMONLCDg.PostSetup(): iMONLCDg.UpdateIcons() FAILED TO START");
+          }
+        }
+        else if (!_displayTest & (_DisplayType == DisplayType.VFD))
+        {
+          if (EQSettings.UseEqDisplay || DisplaySettings.BlankDisplayWithVideo)
+          {
+            _iconThread = new Thread(VFD_EQ_Update)
+                            {
+                              IsBackground = true,
+                              Priority = ThreadPriority.BelowNormal,
+                              Name = "VFD_EQ_Update"
+                            };
+            _iconThread.Start();
+            if (_iconThread.IsAlive)
             {
-              if (DisplayOptions.UseCustomFont)
-              {
-                CFont = new CustomFont();
-                CFont.InitializeCustomFont();
-              }
-              if (DisplayOptions.UseLargeIcons)
-              {
-                CustomLargeIcon = new LargeIcon();
-                CustomLargeIcon.InitializeLargeIcons();
-              }
-              _iconThread = new Thread(UpdateIcons)
-                              {
-                                IsBackground = true,
-                                Priority = ThreadPriority.BelowNormal,
-                                Name = "UpdateIconThread"
-                              };
-              _iconThread.Start();
-              if (_iconThread.IsAlive)
-              {
-                Log.Info("iMONLCDg.OpenLcd(): iMONLCDg.UpdateIcons() Thread Started");
-              }
-              else
-              {
-                Log.Info("iMONLCDg.OpenLcd(): iMONLCDg.UpdateIcons() FAILED TO START");
-              }
+                Log.Info("iMONLCDg.PostSetup(): iMONLCDg.VFD_EQ_Update() Thread Started");
             }
-            else if (!_displayTest & (_DisplayType == DisplayType.VFD))
+            else
             {
-              if (EQSettings.UseEqDisplay || DisplaySettings.BlankDisplayWithVideo)
-              {
-                _iconThread = new Thread(VFD_EQ_Update)
-                                {
-                                  IsBackground = true,
-                                  Priority = ThreadPriority.BelowNormal,
-                                  Name = "VFD_EQ_Update"
-                                };
-                _iconThread.Start();
-                if (_iconThread.IsAlive)
-                {
-                  Log.Info("iMONLCDg.OpenLcd(): iMONLCDg.VFD_EQ_Update() Thread Started");
-                }
-                else
-                {
-                  Log.Info("iMONLCDg.OpenLcd(): iMONLCDg.VFD_EQ_Update() FAILED TO START");
-                }
-              }
+                Log.Info("iMONLCDg.PostSetup(): iMONLCDg.VFD_EQ_Update() FAILED TO START");
             }
-            else if ((!_displayTest & (_DisplayType == DisplayType.ThreeRsystems)) &&
-                     (EQSettings.UseEqDisplay || DisplaySettings.BlankDisplayWithVideo))
-            {
-              _iconThread = new Thread(VFD_EQ_Update)
-                              {
+          }
+        }
+        else if ((!_displayTest & (_DisplayType == DisplayType.ThreeRsystems)) &&
+                 (EQSettings.UseEqDisplay || DisplaySettings.BlankDisplayWithVideo))
+        {
+            _iconThread = new Thread(VFD_EQ_Update)
+                            {
                                 IsBackground = true,
                                 Priority = ThreadPriority.BelowNormal,
                                 Name = "VFD_EQ_Update"
-                              };
-              _iconThread.TrySetApartmentState(ApartmentState.MTA);
-              _iconThread.Start();
-              if (_iconThread.IsAlive)
-              {
-                Log.Info("iMONLCDg.OpenLcd(): iMONLCDg.VFD_EQ_Update() Thread Started");
-              }
-              else
-              {
-                Log.Info("iMONLCDg.OpenLcd(): iMONLCDg.VFD_EQ_Update() FAILED TO START");
-              }
+                            };
+            _iconThread.TrySetApartmentState(ApartmentState.MTA);
+            _iconThread.Start();
+            if (_iconThread.IsAlive)
+            {
+                Log.Info("iMONLCDg.PostSetup(): iMONLCDg.VFD_EQ_Update() Thread Started");
             }
-          }
+            else
+            {
+                Log.Info("iMONLCDg.PostSetup(): iMONLCDg.VFD_EQ_Update() FAILED TO START");
+            }
         }
+
+        _postSetupDone = true;
+    }
+
+    private void OpenLcd()
+    {
+      if (_DriverState != DriverStateEnum.Disabled && _DriverState != DriverStateEnum.OpeningDisplay)
+      {
+        _DriverState = DriverStateEnum.OpeningDisplay;
+        Log.Info("iMONLCDg.OpenLcd(): called");
+        Log.Info("iMONLCDg.OpenLcd(): opening display with iMONVFD_Init({0},{1})", _VfdType.ToString("x00"),
+               _VfdReserved.ToString("x0000"));
+        if (!_IMON.iMONVFD_Init(_VfdType, _VfdReserved))
+        {
+            Log.Info("iMONLCDg.OpenLcd(): Could not open display with Open({0},{1})", _VfdType.ToString("x00"),
+                     _VfdReserved.ToString("x0000"));
+            _DriverState = DriverStateEnum.Disabled;
+            _errorMessage = "Could not open iMON display device";
+            return;
+        }
         else
         {
-          Log.Info("iMONLCDg.OpenLcd: Display already open");
+            Log.Info("iMONLCDg.OpenLcd(): display opened");
+            PostSetup();
         }
         if (_MonitorPower && !_IsHandlingPowerEvent)
         {
@@ -2771,6 +2837,8 @@
           AdvancedSettings_OnSettingsChanged;
         ForceManagerRestart();
         Log.Info("iMONLCDg.OpenLcd(): completed");
+        _DriverState = DriverStateEnum.Running;
+
       }
     }
 
@@ -2892,7 +2960,7 @@
           SendData_Error_Count++;
           if (SendData_Error_Count > 20)
           {
-            _isDisabled = true;
+            _DriverState = DriverStateEnum.Disabled;
             if (DoDebug)
             {
               Log.Info("iMONLCDg.SendData(): ERROR Sending {0} to display", data.ToString("x0000000000000000"));
@@ -2912,7 +2980,7 @@
       }
       catch (Exception exception)
       {
-        _isDisabled = true;
+        _DriverState = DriverStateEnum.Disabled;
         _errorMessage = exception.Message;
         Log.Info("iMONLCDg.SendData(): caught exception '{0}'\nIs your SG_VFD.dll version 5.1 or higher??");
       }
@@ -3033,6 +3101,10 @@
 
     private void SendText(string Line1, string Line2)
     {
+      if (_DriverState != DriverStateEnum.Running)
+      {
+          return;
+      }
       if (DoDebug)
       {
         Log.Info("iMONLCDg.SendText(): Called");
@@ -3043,16 +3115,18 @@
       }
       int num = 0;
       var pixelArray = new byte[0xc0];
+      byte[] bytesLn1 = Encoding.Default.GetBytes(Line1);
+      byte[] bytesLn2 = Encoding.Default.GetBytes(Line2);
       for (int i = 0; i < Math.Min(0x10, Line1.Length); i++)
       {
-        byte charID = Encoding.Default.GetBytes(Line1)[i];
+        byte charLn1 = bytesLn1[i];
         for (int k = 5; k >= 0; k--)
         {
           if ((k + num) < 0x60)
           {
             pixelArray[num + k] = DisplayOptions.UseCustomFont
-                                    ? BitReverse(CustomFont.PixelData(charID, k))
-                                    : BitReverse(_Font8x5[charID, k]);
+                                    ? BitReverse(CustomFont.PixelData(charLn1, k))
+                                    : BitReverse(_Font8x5[charLn1, k]);
           }
         }
         num += 6;
@@ -3060,14 +3134,14 @@
       num = 0x60;
       for (int j = 0; j < Math.Min(0x10, Line2.Length); j++)
       {
-        byte ch2 = Encoding.Default.GetBytes(Line2)[j];
+        byte charLn2 = bytesLn2[j];
         for (int m = 5; m >= 0; m--)
         {
           if ((m + num) < 0xc0)
           {
             pixelArray[num + m] = DisplayOptions.UseCustomFont
-                                    ? BitReverse(CustomFont.PixelData(ch2, m))
-                                    : BitReverse(_Font8x5[ch2, m]);
+                                    ? BitReverse(CustomFont.PixelData(charLn2, m))
+                                    : BitReverse(_Font8x5[charLn2, m]);
           }
         }
         num += 6;
@@ -3077,6 +3151,10 @@
 
     private void SendText3R(string Line1)
     {
+      if (_DriverState != DriverStateEnum.Running)
+      {
+          return;
+      }
       if (DoDebug)
       {
         Log.Info("iMONLCDg.SendText3R(): Called");
@@ -3172,8 +3250,8 @@
           Log.Info("iMONLCDg.SetText(): Sending text to display");
         }
         _IMON.iMONVFD_SetText(Line1, Line2);
-        Thread.Sleep(_delay);
       }
+      Thread.Sleep(_delay);
     }
 
     private void SetVFDClock()
@@ -3224,42 +3302,44 @@
     {
       progLevel = 0;
       volLevel = 0;
-      if ((MPStatus.MediaPlayer_Playing || MiniDisplayHelper.IsCaptureCardViewing()) &
-          DisplayOptions.VolumeDisplay)
+      if (DisplayOptions.VolumeDisplay || DisplayOptions.ProgressDisplay)
       {
-        try
+        lock (DWriteMutex)
         {
-          if (!MPStatus.IsMuted)
+          try
           {
-            volLevel = MPStatus.SystemVolumeLevel / 2048;
+            if (!MPStatus.IsMuted && (MPStatus.MediaPlayer_Playing || MiniDisplayHelper.IsCaptureCardViewing()))
+            {
+              volLevel = MPStatus.SystemVolumeLevel / 2048;
+            }
           }
+          catch (Exception exception)
+          {
+            if (DoDebug)
+            {
+              Log.Info("iMONLCDg.ShowProgressBars(): Audio Mixer NOT available! exception: {0}", exception);
+            }
+          }
         }
-        catch (Exception exception)
+        if (MPStatus.MediaPlayer_Playing & DisplayOptions.ProgressDisplay)
         {
+          progLevel =
+            ((int)(((((float)MPStatus.Media_CurrentPosition) / ((float)MPStatus.Media_Duration)) - 0.01) * 32.0)) +
+            1;
+        }
+        if ((LastVolLevel != volLevel) || (LastProgLevel != progLevel))
+        {
           if (DoDebug)
           {
-            Log.Info("iMONLCDg.ShowProgressBars(): Audio Mixer NOT available! exception: {0}", exception);
+            Log.Info("iMONLCDg.ShowProgressBars(): Sending vol: {0} prog: {1} cur: {2} dur: {3} to LCD.",
+                     volLevel.ToString(), progLevel.ToString(), MPStatus.Media_CurrentPosition.ToString(),
+                     MPStatus.Media_Duration.ToString());
           }
+          SetLineLength(volLevel, progLevel, volLevel, progLevel);
         }
+        LastVolLevel = volLevel;
+        LastProgLevel = progLevel;
       }
-      if (MPStatus.MediaPlayer_Playing & DisplayOptions.ProgressDisplay)
-      {
-        progLevel =
-          ((int)(((((float)MPStatus.Media_CurrentPosition) / ((float)MPStatus.Media_Duration)) - 0.01) * 32.0)) +
-          1;
-      }
-      if ((LastVolLevel != volLevel) || (LastProgLevel != progLevel))
-      {
-        if (DoDebug)
-        {
-          Log.Info("iMONLCDg.ShowProgressBars(): Sending vol: {0} prog: {1} cur: {2} dur: {3} to LCD.",
-                   volLevel.ToString(), progLevel.ToString(), MPStatus.Media_CurrentPosition.ToString(),
-                   MPStatus.Media_Duration.ToString());
-        }
-        SetLineLength(volLevel, progLevel, volLevel, progLevel);
-      }
-      LastVolLevel = volLevel;
-      LastProgLevel = progLevel;
     }
 
     private void SystemEvents_PowerModeChanged(object sender, PowerModeChangedEventArgs e)
@@ -3276,14 +3356,14 @@
           break;
 
         case PowerModes.StatusChange:
-          break;
+            break;
 
         case PowerModes.Suspend:
-          Log.Info("iMONLCDg.SystemEvents_PowerModeChanged: Suspend or Hibernation detected, shutting down display");
-          _IsHandlingPowerEvent = true;
-          CloseLcd();
-          _IsHandlingPowerEvent = false;
-          return;
+            Log.Info("iMONLCDg.SystemEvents_PowerModeChanged: Suspend or Hibernation detected, shutting down display");
+            _IsHandlingPowerEvent = true;
+            CloseLcd();
+            _IsHandlingPowerEvent = false;
+          break;
 
         default:
           return;
@@ -3334,6 +3414,7 @@
 
     private void UpdateIcons()
     {
+      bool bAbort = false;
       ulong optionBitmask = 0L;
       ulong num2;
       bool flag = false;
@@ -3405,204 +3486,225 @@
         ActivateDVM();
       }
       icon.Reset();
-      while (true)
+      try
       {
-        do
+        while (!bAbort)
         {
-          lock (ThreadMutex)
+          do
           {
-            if (DoDebug)
+            lock (ThreadMutex)
             {
-              Log.Info("iMONLCDg.UpdateIcons(): Checking for Thread termination request");
-            }
-            if (_stopUpdateIconThread)
-            {
-              Log.Info("iMONLCDg.UpdateIcons(): Icon Update Thread terminating");
-              _stopUpdateIconThread = false;
-              if (DisplaySettings.BlankDisplayWithVideo & DisplaySettings.EnableDisplayAction)
+              if ((!DVMactive & DisplayOptions.DiskIcon) & DisplayOptions.DiskMonitor)
               {
-                GUIWindowManager.OnNewAction -= OnExternalAction;
+                ActivateDVM();
               }
-              if (DVM != null)
+              num2 = optionBitmask;
+              flag = !flag;
+              int num7 = _CurrentLargeIcon;
+              LastVolLevel = volLevel;
+              LastProgLevel = progLevel;
+              int num8 = 0;
+              icon.Off();
+              icon.Animate();
+
+              bool bIsCaptureCardRecording = MiniDisplayHelper.IsCaptureCardRecording();
+              bool bIsCaptureCardViewing = MiniDisplayHelper.IsCaptureCardViewing();
+              if (_stopIconThreadEvent.WaitOne(0))
               {
-                DVM.Dispose();
-                DVM = null;
+                break;
               }
-              return;
-            }
-            if ((!DVMactive & DisplayOptions.DiskIcon) & DisplayOptions.DiskMonitor)
-            {
-              ActivateDVM();
-            }
-            num2 = optionBitmask;
-            flag = !flag;
-            int num7 = _CurrentLargeIcon;
-            LastVolLevel = volLevel;
-            LastProgLevel = progLevel;
-            int num8 = 0;
-            icon.Off();
-            icon.Animate();
-            if (DoDebug)
-            {
-              Log.Info("iMONLCDg.UpdateIcons(): Checking TV Card status: IsAnyCardRecording = {0}, IsViewing = {1}",
-                       MiniDisplayHelper.IsCaptureCardRecording().ToString(),
-                       MiniDisplayHelper.IsCaptureCardViewing().ToString());
-            }
-            MiniDisplayHelper.GetSystemStatus(ref MPStatus);
-            Check_Idle_State();
-            if (DoDebug)
-            {
-              Log.Info("iMONLCDg.UpdateIcons(): System Status: Plugin Status = {0}, IsIdle = {1}",
-                       MPStatus.CurrentPluginStatus.ToString(), MPStatus.MP_Is_Idle);
-            }
-            optionBitmask = ConvertPluginIconsToDriverIcons(MPStatus.CurrentIconMask);
-            if ((optionBitmask & (0x400000000L)) > 0L)
-            {
-              num8 = 5;
-            }
-            else if ((optionBitmask & (8L)) > 0L)
-            {
-              num8 = 1;
-            }
-            if (MiniDisplayHelper.IsCaptureCardViewing() && !MPStatus.Media_IsTimeshifting)
-            {
-              icon.On();
-              icon.InvertOn();
-              icon.RotateCW();
-            }
-            if (_mpIsIdle)
-            {
-              num8 = 0;
-            }
-            if (MPStatus.MediaPlayer_Playing)
-            {
-              icon.On();
-              if ((MPStatus.CurrentIconMask & (0x10L)) > 0L)
+
+              if (DoDebug)
               {
-                icon.InvertOff();
+                Log.Info("iMONLCDg.UpdateIcons(): Checking TV Card status: IsAnyCardRecording = {0}, IsViewing = {1}",
+                         bIsCaptureCardRecording.ToString(),
+                         bIsCaptureCardViewing.ToString());
               }
-              else
+              MiniDisplayHelper.GetSystemStatus(ref MPStatus);
+              Check_Idle_State();
+              if (DoDebug)
               {
-                icon.InvertOn();
+                Log.Info("iMONLCDg.UpdateIcons(): System Status: Plugin Status = {0}, IsIdle = {1}",
+                         MPStatus.CurrentPluginStatus.ToString(), MPStatus.MP_Is_Idle);
               }
-              if ((MPStatus.CurrentIconMask & (0x10000000000L)) > 0L)
+              optionBitmask = ConvertPluginIconsToDriverIcons(MPStatus.CurrentIconMask);
+              if ((optionBitmask & (0x400000000L)) > 0L)
               {
-                icon.RotateCCW();
+                num8 = 5;
               }
-              else
+              else if ((optionBitmask & (8L)) > 0L)
               {
+                num8 = 1;
+              }
+              if (bIsCaptureCardViewing && !MPStatus.Media_IsTimeshifting)
+              {
+                icon.On();
+                icon.InvertOn();
                 icon.RotateCW();
               }
-              icon.FlashOff();
-              if (((((((MPStatus.CurrentIconMask & (0x40L)) > 0L) |
-                      ((MPStatus.CurrentIconMask & (8L)) > 0L)) |
-                     (MPStatus.CurrentPluginStatus == Status.PlayingDVD)) |
-                    (MPStatus.CurrentPluginStatus == Status.PlayingTV)) |
-                   (MPStatus.CurrentPluginStatus == Status.PlayingVideo)) |
-                  (MPStatus.CurrentPluginStatus == Status.Timeshifting))
+              if (_mpIsIdle)
               {
-                if ((MPStatus.CurrentPluginStatus == Status.PlayingTV) |
-                    ((MPStatus.CurrentIconMask & (8L)) > 0L))
+                num8 = 0;
+              }
+              if (MPStatus.MediaPlayer_Playing)
+              {
+                icon.On();
+                if ((MPStatus.CurrentIconMask & (0x10L)) > 0L)
                 {
-                  num8 = 1;
+                  icon.InvertOff();
                 }
                 else
                 {
-                  num8 = 2;
+                  icon.InvertOn();
                 }
-                if (DisplaySettings.BlankDisplayWithVideo)
+                if ((MPStatus.CurrentIconMask & (0x10000000000L)) > 0L)
                 {
-                  DisplayOff();
+                  icon.RotateCCW();
                 }
+                else
+                {
+                  icon.RotateCW();
+                }
+                icon.FlashOff();
+                if (((((((MPStatus.CurrentIconMask & (0x40L)) > 0L) |
+                        ((MPStatus.CurrentIconMask & (8L)) > 0L)) |
+                       (MPStatus.CurrentPluginStatus == Status.PlayingDVD)) |
+                      (MPStatus.CurrentPluginStatus == Status.PlayingTV)) |
+                     (MPStatus.CurrentPluginStatus == Status.PlayingVideo)) |
+                    (MPStatus.CurrentPluginStatus == Status.Timeshifting))
+                {
+                  if ((MPStatus.CurrentPluginStatus == Status.PlayingTV) |
+                      ((MPStatus.CurrentIconMask & (8L)) > 0L))
+                  {
+                    num8 = 1;
+                  }
+                  else
+                  {
+                    num8 = 2;
+                  }
+                  if (DisplaySettings.BlankDisplayWithVideo)
+                  {
+                    DisplayOff();
+                  }
+                }
+                else
+                {
+                  num8 = 3;
+                }
+                GetEQ();
               }
-              else
+              else if (MPStatus.MediaPlayer_Paused)
               {
-                num8 = 3;
+                icon.On();
+                lock (DWriteMutex)
+                {
+                  EQSettings._EqDataAvailable = false;
+                  _iconThread.Priority = ThreadPriority.BelowNormal;
+                }
+                RestoreDisplayFromVideoOrIdle();
+                icon.FlashOn();
+                num8 = 6;
               }
-              GetEQ();
-            }
-            else if (MPStatus.MediaPlayer_Paused)
-            {
-              icon.On();
-              lock (DWriteMutex)
+              else
               {
-                EQSettings._EqDataAvailable = false;
-                _iconThread.Priority = ThreadPriority.BelowNormal;
+                icon.Off();
+                RestoreDisplayFromVideoOrIdle();
+                lock (DWriteMutex)
+                {
+                  EQSettings._EqDataAvailable = false;
+                  _iconThread.Priority = ThreadPriority.BelowNormal;
+                }
               }
-              RestoreDisplayFromVideoOrIdle();
-              icon.FlashOn();
-              num8 = 6;
-            }
-            else
-            {
-              icon.Off();
-              RestoreDisplayFromVideoOrIdle();
-              lock (DWriteMutex)
+              if ((!MiniDisplayHelper.Player_Playing() & !bIsCaptureCardViewing) ||
+                  (DisplayOptions.DiskIcon & !DisplayOptions.DiskMediaStatus))
               {
-                EQSettings._EqDataAvailable = false;
-                _iconThread.Priority = ThreadPriority.BelowNormal;
-              }
-            }
-            if ((!MiniDisplayHelper.Player_Playing() & !MiniDisplayHelper.IsCaptureCardViewing()) ||
-                (DisplayOptions.DiskIcon & !DisplayOptions.DiskMediaStatus))
-            {
-              int num9 = 0;
-              if (DisplayOptions.DiskIcon)
-              {
-                for (int m = 0; m < 0x1b; m++)
+                int num9 = 0;
+                if (DisplayOptions.DiskIcon)
                 {
-                  num9 |= Inserted_Media[m];
-                }
-                switch (num9)
-                {
-                  case 1:
-                    optionBitmask |= mask.ICON_CDIn;
-                    goto Label_06B0;
+                  for (int m = 0; m < 0x1b; m++)
+                  {
+                    num9 |= Inserted_Media[m];
+                  }
+                  switch (num9)
+                  {
+                    case 1:
+                      optionBitmask |= mask.ICON_CDIn;
+                      goto Label_06B0;
 
-                  case 2:
-                    optionBitmask |= mask.ICON_DVDIn;
-                    goto Label_06B0;
+                    case 2:
+                      optionBitmask |= mask.ICON_DVDIn;
+                      goto Label_06B0;
+                  }
+                  if (num9 > 0)
+                  {
+                    optionBitmask |= mask.ICON_DiskOn;
+                  }
                 }
-                if (num9 > 0)
-                {
-                  optionBitmask |= mask.ICON_DiskOn;
-                }
               }
-            }
             Label_06B0:
-            if (DisplayOptions.DiskIcon & DisplayOptions.DiskMediaStatus)
-            {
-              optionBitmask |= icon.Mask;
-            }
-            if (DoDebug)
-            {
-              Log.Info("iMONLCDg.UpdateIcons(): last = {0}, new = {1}, disk mask = {2}",
-                       num2.ToString("X0000000000000000"), optionBitmask.ToString("X0000000000000000"),
-                       icon.Mask.ToString("X0000000000000000"));
-            }
-            if (optionBitmask != num2)
-            {
-              lock (DWriteMutex)
+              if (DisplayOptions.DiskIcon & DisplayOptions.DiskMediaStatus)
               {
-                SendData(iMonCommand.General.SetIcons, optionBitmask);
+                optionBitmask |= icon.Mask;
               }
-            }
-            DisplayEQ();
-            if (DisplayOptions.VolumeDisplay || DisplayOptions.ProgressDisplay)
-            {
-              lock (DWriteMutex)
+              if (DoDebug)
               {
+                Log.Info("iMONLCDg.UpdateIcons(): last = {0}, new = {1}, disk mask = {2}",
+                         num2.ToString("X0000000000000000"), optionBitmask.ToString("X0000000000000000"),
+                         icon.Mask.ToString("X0000000000000000"));
+              }
+              if (optionBitmask != num2)
+              {
+                lock (DWriteMutex)
+                {
+                  SendData(iMonCommand.General.SetIcons, optionBitmask);
+                }
+              }
+
+              DisplayEQ();
+              if (DisplayOptions.VolumeDisplay || DisplayOptions.ProgressDisplay)
+              {
                 ShowProgressBars();
               }
+              if (num8 != num7)
+              {
+                _CurrentLargeIcon = num8;
+              }
             }
-            if (num8 != num7)
+
+            if (_stopIconThreadEvent.WaitOne(0))
             {
-              _CurrentLargeIcon = num8;
+              bAbort = true;
+              break;
             }
+
+          } while (EQSettings._EqDataAvailable && !MPStatus.MediaPlayer_Paused);
+
+          if (_stopIconThreadEvent.WaitOne(200))
+          {
+            bAbort = true;
+            break;
           }
-        } while (EQSettings._EqDataAvailable && !MPStatus.MediaPlayer_Paused);
-        Thread.Sleep(200);
+        }
       }
+      catch (ThreadAbortException ex)
+      {
+        Log.Info("iMONLCDg.UpdateIcons(): Icon Update ThreadAbortException");
+      }
+      finally
+      {
+        Log.Info("iMONLCDg.UpdateIcons(): Icon Update Thread terminating");
+
+        if (DisplaySettings.BlankDisplayWithVideo & DisplaySettings.EnableDisplayAction)
+        {
+          GUIWindowManager.OnNewAction -= OnExternalAction;
+        }
+        if (DVM != null)
+        {
+          DVM.Dispose();
+          DVM = null;
+        }
+        _stopIconThreadEvent.Reset();
+      }
     }
 
     private void VFD_EQ_Update()
@@ -3611,75 +3713,86 @@
       {
         GUIWindowManager.OnNewAction += OnExternalAction;
       }
-      while (true)
+      try
       {
-        object obj2;
-        Monitor.Enter(obj2 = ThreadMutex);
-        try
-        {
-          if (DoDebug)
+          while (true)
           {
-            Log.Info("iMONLCDg.VFD_EQ_Update(): Checking for Thread termination request");
-          }
-          if (_stopUpdateIconThread)
-          {
-            if (DisplaySettings.BlankDisplayWithVideo & DisplaySettings.EnableDisplayAction)
-            {
-              GUIWindowManager.OnNewAction -= OnExternalAction;
-            }
-            Log.Info("iMONLCDg.VFD_EQ_Update(): VFD_EQ_Update Thread terminating");
-            _stopUpdateIconThread = false;
-            break;
-          }
-          MiniDisplayHelper.GetSystemStatus(ref MPStatus);
-          if (((!MPStatus.MediaPlayer_Active | !MPStatus.MediaPlayer_Playing) &
-               DisplaySettings.BlankDisplayWithVideo) &
-              (DisplaySettings.BlankDisplayWhenIdle & !_mpIsIdle))
-          {
-            DisplayOn();
-          }
-          if (MPStatus.MediaPlayer_Playing)
-          {
-            if (EQSettings.UseEqDisplay && (MPStatus.Media_IsCD || MPStatus.Media_IsMusic || MPStatus.Media_IsRadio))
-            {
-              GetEQ();
-              DisplayEQ();
-            }
-            if (DisplaySettings.BlankDisplayWithVideo &
-                (((MPStatus.Media_IsDVD || MPStatus.Media_IsVideo) || MPStatus.Media_IsTV) ||
-                 MPStatus.Media_IsTVRecording))
-            {
-              if (DoDebug)
+              object obj2;
+              if (_stopIconThreadEvent.WaitOne(0))
               {
-                Log.Info("iMONLCDg.VFD_EQ_Update(): Turning off display while playing video");
+                  break;
               }
-              DisplayOff();
-            }
+
+              Monitor.Enter(obj2 = ThreadMutex);
+              try
+              {
+                  MiniDisplayHelper.GetSystemStatus(ref MPStatus);
+                  if (((!MPStatus.MediaPlayer_Active | !MPStatus.MediaPlayer_Playing) &
+                       DisplaySettings.BlankDisplayWithVideo) &
+                      (DisplaySettings.BlankDisplayWhenIdle & !_mpIsIdle))
+                  {
+                      DisplayOn();
+                  }
+                  if (MPStatus.MediaPlayer_Playing)
+                  {
+                      if (EQSettings.UseEqDisplay && (MPStatus.Media_IsCD || MPStatus.Media_IsMusic || MPStatus.Media_IsRadio))
+                      {
+                          GetEQ();
+                          DisplayEQ();
+                      }
+                      if (DisplaySettings.BlankDisplayWithVideo &
+                          (((MPStatus.Media_IsDVD || MPStatus.Media_IsVideo) || MPStatus.Media_IsTV) ||
+                           MPStatus.Media_IsTVRecording))
+                      {
+                          if (DoDebug)
+                          {
+                              Log.Info("iMONLCDg.VFD_EQ_Update(): Turning off display while playing video");
+                          }
+                          DisplayOff();
+                      }
+                  }
+                  else
+                  {
+                      RestoreDisplayFromVideoOrIdle();
+                      lock (DWriteMutex)
+                      {
+                          EQSettings._EqDataAvailable = false;
+                          _iconThread.Priority = ThreadPriority.BelowNormal;
+                      }
+                  }
+              }
+              catch (Exception exception)
+              {
+                  Log.Info("iMONLCDg.VFD_EQ_Update(): CAUGHT EXCEPTION - EXITING! - {0}", exception);
+                  break;
+              }
+              finally
+              {
+                  Monitor.Exit(obj2);
+              }
+              if (!EQSettings._EqDataAvailable || MPStatus.MediaPlayer_Paused)
+              {
+                  if (_stopIconThreadEvent.WaitOne(250))
+                  {
+                      break;
+                  }
+              }
           }
-          else
+      }
+      catch (ThreadAbortException)
+      {
+          Log.Info("iMONLCDg.VFD_EQ_Update(): VFD_EQ_Update ThreadAbortException");
+      }
+      finally
+      {
+          if (DisplaySettings.BlankDisplayWithVideo & DisplaySettings.EnableDisplayAction)
           {
-            RestoreDisplayFromVideoOrIdle();
-            lock (DWriteMutex)
-            {
-              EQSettings._EqDataAvailable = false;
-              _iconThread.Priority = ThreadPriority.BelowNormal;
-            }
+              GUIWindowManager.OnNewAction -= OnExternalAction;
           }
-        }
-        catch (Exception exception)
-        {
-          Log.Info("iMONLCDg.VFD_EQ_Update(): CAUGHT EXCEPTION - EXITING! - {0}", exception);
-          break;
-        }
-        finally
-        {
-          Monitor.Exit(obj2);
-        }
-        if (!EQSettings._EqDataAvailable || MPStatus.MediaPlayer_Paused)
-        {
-          Thread.Sleep(250);
-        }
+          Log.Info("iMONLCDg.VFD_EQ_Update(): VFD_EQ_Update Thread terminating");
+          _stopIconThreadEvent.Reset();
       }
+
     }
 
     private static void VolumeInserted(int bitMask)
@@ -4720,5 +4833,6 @@
     }
 
     #endregion
+
   }
 }
\ No newline at end of file
