cec: added RescanDevices()/cec_rescan_devices() to the interface, to let libCEC force...
[deb_libcec.git] / src / cec-config-gui / CecConfigGUI.cs
index 6d5bb47a0024eefcfb01cd54950ab644ca82887e..e3decec7fe03ef9907b602182cc21f214f52136b 100644 (file)
@@ -39,14 +39,6 @@ namespace CecConfigGui
       InitializeComponent();
       LoadButtonConfiguration();
 
-      //TODO read the com port setting from the configuration
-      CecAdapter[] adapters = Lib.FindAdapters(string.Empty);
-      if (adapters.Length == 0 || !Lib.Open(adapters[0].ComPort, 10000))
-      {
-        MessageBox.Show("Could not connect to any CEC adapter. Please check your configuration and try again.", "Pulse-Eight USB-CEC Adapter", MessageBoxButtons.OK);
-        Application.Exit();
-      }
-
       ActiveProcess = new ConnectToDevice(ref Lib, Config);
       ActiveProcess.EventHandler += new EventHandler<UpdateEvent>(ProcessEventHandler);
       (new Thread(new ThreadStart(ActiveProcess.Run))).Start();
@@ -279,6 +271,7 @@ namespace CecConfigGui
           SetControlText(tbPhysicalAddress, string.Format("{0,4:X}", updateEvent.IntValue));
           break;
         case UpdateEventType.ProgressBar:
+          SetControlVisible(pProgress, true);
           SetProgressValue(pProgress, updateEvent.IntValue);
           break;
         case UpdateEventType.TVVendorId:
@@ -313,30 +306,40 @@ namespace CecConfigGui
           ConfigurationChanged(updateEvent.ConfigValue);
           SuppressUpdates = false;
           break;
+        case UpdateEventType.PollDevices:
+          CheckActiveDevices();
+          break;
         case UpdateEventType.ProcessCompleted:
           ActiveProcess = null;
           SetControlsEnabled(true);
+          if (UpdatingInfoPanel != null)
+          {
+            UpdatingInfoPanel.SetControlEnabled(UpdatingInfoPanel.bUpdate, true);
+            UpdatingInfoPanel = null;
+          }
+          SetControlVisible(pProgress, false);
           break;
       }
     }
 
     private void SetControlsEnabled(bool val)
     {
-      SetControlEnabled(cbPortNumber, val);
-      SetControlEnabled(cbConnectedDevice, cbConnectedDevice.Items.Count > 1 ? val : false);
-      SetControlEnabled(tbPhysicalAddress, val);
-      SetControlEnabled(cbDeviceType, false); // TODO not implemented yet
+      SetControlEnabled(cbPortNumber, val && !Config.AutodetectAddress);
+      SetControlEnabled(cbConnectedDevice, cbConnectedDevice.Items.Count > 1 && !Config.AutodetectAddress ? val : false);
+      SetControlEnabled(tbPhysicalAddress, val && !Config.AutodetectAddress);
+      SetControlEnabled(cbDeviceType, val);
       SetControlEnabled(cbUseTVMenuLanguage, val);
       SetControlEnabled(cbActivateSource, val);
       SetControlEnabled(cbPowerOffScreensaver, val);
       SetControlEnabled(cbPowerOffOnStandby, val);
-      SetControlEnabled(cbWakeDevices, false); // TODO not implemented yet
-      SetControlEnabled(cbPowerOffDevices, false); // TODO not implemented yet
+      SetControlEnabled(cbWakeDevices, val);
+      SetControlEnabled(cbPowerOffDevices, val);
       SetControlEnabled(cbVendorOverride, val);
       SetControlEnabled(cbVendorId, val && cbVendorOverride.Checked);
       SetControlEnabled(bClose, val);
       SetControlEnabled(bSaveConfig, val);
       SetControlEnabled(bReloadConfig, val);
+      SetControlEnabled(bRescanDevices, val);
 
       SetControlEnabled(bSendImageViewOn, val);
       SetControlEnabled(bStandby, val);
@@ -372,6 +375,21 @@ namespace CecConfigGui
       }
     }
 
+    protected override void Dispose(bool disposing)
+    {
+      if (disposing)
+      {
+        Lib.DisableCallbacks();
+        Lib.StandbyDevices(CecLogicalAddress.Broadcast);
+        Lib.Close();
+      }
+      if (disposing && (components != null))
+      {
+        components.Dispose();
+      }
+      base.Dispose(disposing);
+    }
+
     #region Actions
     public void ReloadXMLConfiguration()
     {
@@ -380,6 +398,19 @@ namespace CecConfigGui
       ConfigurationChanged(Config);
     }
 
+    public void UpdateInfoPanel(DeviceInformation panel)
+    {
+      if (!SuppressUpdates && ActiveProcess == null)
+      {
+        SetControlsEnabled(false);
+        UpdatingInfoPanel = panel;
+        panel.SetControlEnabled(panel.bUpdate, false);
+        ActiveProcess = new UpdateDeviceInfo(this, ref Lib, panel);
+        ActiveProcess.EventHandler += new EventHandler<UpdateEvent>(ProcessEventHandler);
+        (new Thread(new ThreadStart(ActiveProcess.Run))).Start();
+      }
+    }
+
     public void SetPhysicalAddress(ushort physicalAddress)
     {
       if (!SuppressUpdates && ActiveProcess == null)
@@ -393,6 +424,17 @@ namespace CecConfigGui
       }
     }
 
+    public void UpdateConfigurationAsync()
+    {
+      if (!SuppressUpdates && ActiveProcess == null)
+      {
+        SetControlsEnabled(false);
+        ActiveProcess = new UpdateConfiguration(ref Lib, Config);
+        ActiveProcess.EventHandler += new EventHandler<UpdateEvent>(ProcessEventHandler);
+        (new Thread(new ThreadStart(ActiveProcess.Run))).Start();
+      }
+    }
+
     public void SendImageViewOn(CecLogicalAddress address)
     {
       if (!SuppressUpdates && ActiveProcess == null)
@@ -487,6 +529,8 @@ namespace CecConfigGui
       Config.ActivateSource = cbActivateSource.Checked;
       Config.PowerOffScreensaver = cbPowerOffScreensaver.Checked;
       Config.PowerOffOnStandby = cbPowerOffOnStandby.Checked;
+      Config.WakeDevices = WakeDevices;
+      Config.PowerOffDevices = PowerOffDevices;
 
       if (!Lib.CanPersistConfiguration())
       {
@@ -537,20 +581,21 @@ namespace CecConfigGui
               output.AppendLine("<setting id=\"port\" value=\"\" />");
 
               // only supported by 1.5.0+ clients
+              output.AppendLine("<!-- the following lines are only supported by v1.5.0+ clients -->");
               output.AppendLine("<setting id=\"physical_address\" value=\"" + string.Format("{0,4:X}", Config.PhysicalAddress) + "\" />");
               output.AppendLine("<setting id=\"device_type\" value=\"" + (int)Config.DeviceTypes.Types[0] + "\" />");
-              output.AppendLine("<setting id=\"tv_vendor\" value=\"" + string.Format("{0,6:X}", (int)Config.TvVendor) + "\" />");
+              output.AppendLine("<setting id=\"tv_vendor\" value=\"" + string.Format("{0,6:X}", (int)Config.TvVendor).Trim() + "\" />");
 
               output.Append("<setting id=\"wake_devices\" value=\"");
               foreach (CecLogicalAddress addr in Config.WakeDevices.Addresses)
-                if (addr != CecLogicalAddress.Unregistered)
-                  output.Append(" " + addr);
+                if (addr != CecLogicalAddress.Unknown)
+                  output.Append(" " + (int)addr);
               output.AppendLine("\" />");
 
               output.Append("<setting id=\"standby_devices\" value=\"");
               foreach (CecLogicalAddress addr in Config.PowerOffDevices.Addresses)
-                if (addr != CecLogicalAddress.Unregistered)
-                  output.Append(" " + addr);
+                if (addr != CecLogicalAddress.Unknown)
+                  output.Append(" " + (int)addr);
               output.AppendLine("\" />");
 
               output.AppendLine("</settings>");
@@ -629,6 +674,20 @@ namespace CecConfigGui
         Config.TvVendor = CecVendorId.Unknown;
       }
     }
+
+    private void cbDeviceType_SelectedIndexChanged(object sender, EventArgs e)
+    {
+      CecDeviceType type = SelectedDeviceType;
+      if (type != Config.DeviceTypes.Types[0])
+      {
+        Config.DeviceTypes.Types[0] = type;
+        if (!DeviceChangeWarningDisplayed)
+        {
+          DeviceChangeWarningDisplayed = true;
+          MessageBox.Show("You have changed the device type. Save the configuration, and restart the application to use the new setting.", "Pulse-Eight USB-CEC Adapter", MessageBoxButtons.OK, MessageBoxIcon.Warning);
+        }
+      }
+    }
     #endregion
 
     #region Key configuration tab
@@ -676,6 +735,40 @@ namespace CecConfigGui
     #endregion
 
     #region CEC Tester tab
+    public void CheckActiveDevices()
+    {
+      CecLogicalAddresses activeDevices = Lib.GetActiveDevices();
+      List<string> deviceList = new List<string>();
+      foreach (CecLogicalAddress activeDevice in activeDevices.Addresses)
+      {
+        if (activeDevice != CecLogicalAddress.Unknown)
+          deviceList.Add(string.Format("{0,1:X} : {1}", (int)activeDevice, Lib.ToString(activeDevice)));
+      }
+      deviceList.Add(string.Format("{0,1:X} : {1}", (int)CecLogicalAddress.Broadcast, Lib.ToString(CecLogicalAddress.Broadcast)));
+
+      SetActiveDevices(deviceList.ToArray());
+    }
+
+    delegate void SetActiveDevicesCallback(string[] activeDevices);
+    private void SetActiveDevices(string[] activeDevices)
+    {
+      if (this.cbCommandDestination.InvokeRequired)
+      {
+        SetActiveDevicesCallback d = new SetActiveDevicesCallback(SetActiveDevices);
+        try
+        {
+          this.Invoke(d, new object[] { activeDevices });
+        }
+        catch (Exception) { }
+      }
+      else
+      {
+        this.cbCommandDestination.Items.Clear();
+        foreach (string item in activeDevices)
+          this.cbCommandDestination.Items.Add(item);
+      }
+    }
+
     delegate CecLogicalAddress GetTargetDeviceCallback();
     private CecLogicalAddress GetTargetDevice()
     {
@@ -691,7 +784,12 @@ namespace CecConfigGui
         return retval;
       }
 
-      switch (this.cbCommandDestination.Text.Substring(0, 1).ToLower())
+      return GetLogicalAddressFromString(this.cbCommandDestination.Text);
+    }
+
+    private CecLogicalAddress GetLogicalAddressFromString(string name)
+    {
+      switch (name.Substring(0, 1).ToLower())
       {
         case "0":
           return CecLogicalAddress.Tv;
@@ -756,6 +854,8 @@ namespace CecConfigGui
       this.bVolUp.Enabled = enableVolumeButtons;
       this.bVolDown.Enabled = enableVolumeButtons;
       this.bMute.Enabled = enableVolumeButtons;
+      this.bActivateSource.Enabled = (GetTargetDevice() != CecLogicalAddress.Broadcast);
+      this.bScan.Enabled = (GetTargetDevice() != CecLogicalAddress.Broadcast);
     }
 
     private void bVolUp_Click(object sender, EventArgs e)
@@ -778,6 +878,17 @@ namespace CecConfigGui
       Lib.MuteAudio(true);
       SetControlsEnabled(true);
     }
+
+    private void bRescanDevices_Click(object sender, EventArgs e)
+    {
+      if (!SuppressUpdates && ActiveProcess == null)
+      {
+        SetControlsEnabled(false);
+        ActiveProcess = new RescanDevices(ref Lib);
+        ActiveProcess.EventHandler += new EventHandler<UpdateEvent>(ProcessEventHandler);
+        (new Thread(new ThreadStart(ActiveProcess.Run))).Start();
+      }
+    }
     #endregion
 
     #region Log tab
@@ -843,7 +954,8 @@ namespace CecConfigGui
 
     private void bClearLog_Click(object sender, EventArgs e)
     {
-      tbLog.Text = string.Empty;
+      Log = string.Empty;
+      UpdateLog();
     }
 
     private void bSaveLog_Click(object sender, EventArgs e)
@@ -867,7 +979,7 @@ namespace CecConfigGui
         else
         {
           StreamWriter writer = new StreamWriter(fs);
-          writer.Write(tbLog.Text);
+          writer.Write(Log);
           writer.Close();
           fs.Close();
           fs.Dispose();
@@ -915,6 +1027,13 @@ namespace CecConfigGui
       SetCheckboxChecked(cbPowerOffScreensaver, Config.PowerOffScreensaver);
       SetCheckboxChecked(cbPowerOffOnStandby, Config.PowerOffOnStandby);
       UpdateSelectedDevice();
+
+      for (int iPtr = 0; iPtr < 15; iPtr++)
+        SetCheckboxItemChecked(cbWakeDevices, iPtr, Config.WakeDevices.IsSet((CecLogicalAddress)iPtr));
+      for (int iPtr = 0; iPtr < 15; iPtr++)
+        SetCheckboxItemChecked(cbPowerOffDevices, iPtr, Config.PowerOffDevices.IsSet((CecLogicalAddress)iPtr));
+
+      SetControlText(this, "Pulse-Eight USB-CEC Adapter - libCEC " + Lib.ToString(Config.ServerVersion));
       return 1;
     }
 
@@ -931,7 +1050,11 @@ namespace CecConfigGui
 
     public int ReceiveLogMessage(CecLogMessage message)
     {
-      AddLogMessage(message);
+      try
+      {
+        AddLogMessage(message);
+      }
+      catch (Exception) { }
       return 1;
     }
     #endregion
@@ -979,6 +1102,21 @@ namespace CecConfigGui
         return (cbConnectedDevice.Text.Equals(AVRVendorString)) ? CecLogicalAddress.AudioSystem : CecLogicalAddress.Tv;
       }
     }
+    public CecDeviceType SelectedDeviceType
+    {
+      get
+      {
+        switch (cbDeviceType.Text.ToLower())
+        {
+          case "player":
+            return CecDeviceType.PlaybackDevice;
+          case "tuner":
+            return CecDeviceType.Tuner;
+          default:
+            return CecDeviceType.RecordingDevice;
+        }
+      }
+    }
     public int SelectedPortNumber
     {
       get
@@ -996,6 +1134,34 @@ namespace CecConfigGui
     private bool SuppressUpdates = true;
     private ConfigTab SelectedTab = ConfigTab.Configuration;
     private string Log = string.Empty;
+    private DeviceInformation UpdatingInfoPanel = null;
+    private bool DeviceChangeWarningDisplayed = false;
+    public CecLogicalAddresses WakeDevices
+    {
+      get
+      {
+        CecLogicalAddresses addr = new CecLogicalAddresses();
+        foreach (object item in this.cbWakeDevices.CheckedItems)
+        {
+          string c = item as string;
+          addr.Set(GetLogicalAddressFromString(c));
+        }
+        return addr;
+      }
+    }
+    public CecLogicalAddresses PowerOffDevices
+    {
+      get
+      {
+        CecLogicalAddresses addr = new CecLogicalAddresses();
+        foreach (object item in this.cbPowerOffDevices.CheckedItems)
+        {
+          string c = item as string;
+          addr.Set(GetLogicalAddressFromString(c));
+        }
+        return addr;
+      }
+    }
     #endregion
   }