fixed: LibCecTray - keypress not sent when multiple instances of eshell.exe are runni...
[deb_libcec.git] / src / LibCecTray / controller / applications / ApplicationController.cs
index 4d23071946db8ecfff2e61d5fc32c9a4e5240581..b4c6120e81959a85c116f87149d358395d48ff8f 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * This file is part of the libCEC(R) library.
  *
- * libCEC(R) is Copyright (C) 2011-2012 Pulse-Eight Limited.  All rights reserved.
+ * libCEC(R) is Copyright (C) 2011-2013 Pulse-Eight Limited.  All rights reserved.
  * libCEC(R) is an original work, containing original code.
  *
  * libCEC(R) is a trademark of Pulse-Eight Limited.
@@ -42,14 +42,16 @@ using Timer = System.Timers.Timer;
 
 namespace LibCECTray.controller.applications
 {
+  public delegate void OnApplicationRunningChanged(bool running);
+
   /// <summary>
   /// Controls an application on the PC: send key presses, open the application, close it, etc.
   /// </summary>
   class ApplicationController
   {
-    public ApplicationController(CECSettings settings, string uiName, string processName, string filename, string workingDirectory)
+    public ApplicationController(CECController controller, string uiName, string processName, string filename, string workingDirectory)
     {
-      Settings = settings;
+      Controller = controller;
       UiName = uiName;
       ProcessName = processName;
       ApplicationFilename = filename;
@@ -58,13 +60,13 @@ namespace LibCECTray.controller.applications
       IsInternal = false;
     }
 
-    public static ApplicationController FromString(CECSettings settings, string serialisedConfig)
+    public static ApplicationController FromString(CECController controller, CECSettings settings, string serialisedConfig)
     {
       var splitString = serialisedConfig.Split(';');
       if (splitString.Length != 4)
         throw new InvalidDataException("incorrect number of parameters");
 
-      return new ApplicationController(settings, splitString[0], splitString[1], splitString[2], splitString[3]);
+      return new ApplicationController(controller, splitString[0], splitString[1], splitString[2], splitString[3]);
     }
 
     public string AsString()
@@ -112,7 +114,20 @@ namespace LibCECTray.controller.applications
                                 var item = args.RowIndex < ButtonConfig.Count ? ButtonConfig[args.RowIndex] : null;
                                 if (item == null)
                                   return;
-                                (new CecButtonConfigUI(item)).ShowDialog();
+                                if (args.ColumnIndex >= 0)
+                                {
+                                  (new CecButtonConfigUI(item)).ShowDialog();
+                                }
+                                else
+                                {
+                                  var mappedButton = ButtonConfig[item.Key]; 
+                                  if (mappedButton == null || mappedButton.Value.Empty())
+                                    return;
+
+                                    var controlWindow = FindInstance();
+                                    if (controlWindow != IntPtr.Zero && item.Key.Duration == 0)
+                                      mappedButton.Value.Transmit(controlWindow);
+                                }
                               };
 
       foreach (var item in _buttonConfig)
@@ -190,12 +205,24 @@ namespace LibCECTray.controller.applications
     public virtual void Initialise()
     {
       Timer timer = new Timer { Interval = 1000, AutoReset = true };
-      timer.Elapsed += delegate { UiControl.SetStartButtonEnabled(true); };
+      timer.Elapsed += delegate { CheckApplicationEnabled(); };
       timer.Start();
 
       if (AutoStartApplication.Value)
         Start(false);
     }
+
+    public event OnApplicationRunningChanged ApplicationRunningChanged;
+
+    private void CheckApplicationEnabled()
+    {
+      var isRunning = IsRunning();
+      if (isRunning != _applicationRunning && ApplicationRunningChanged != null)
+        ApplicationRunningChanged(isRunning);
+
+      _applicationRunning = isRunning;
+      UiControl.SetStartButtonEnabled(!isRunning && !SuppressApplicationStart);
+    }
     #endregion
 
     #region Send input to the application
@@ -221,7 +248,7 @@ namespace LibCECTray.controller.applications
         return false;
 
       var controlWindow = FindInstance();
-      if (controlWindow != IntPtr.Zero && key.Duration == 0)
+      if (controlWindow != IntPtr.Zero && (key.Duration == 0 || key.Duration > 500))
         return mappedButton.Value.Transmit(controlWindow);
 
       return false;
@@ -246,7 +273,12 @@ namespace LibCECTray.controller.applications
     protected virtual IntPtr FindInstance()
     {
       var processes = Process.GetProcessesByName(ProcessName);
-      return processes.Length > 0 ? processes[0].MainWindowHandle : IntPtr.Zero;
+      foreach (var process in processes)
+      {
+        if (process.MainWindowHandle != IntPtr.Zero)
+          return process.MainWindowHandle;
+      }
+      return IntPtr.Zero;
     }
     #endregion
 
@@ -356,7 +388,10 @@ namespace LibCECTray.controller.applications
       get { return _buttonConfig ?? (_buttonConfig = new CecButtonConfig(this)); }
     }
 
-    public CECSettings Settings;
+    public CECSettings Settings
+    {
+      get { return Controller.Settings; }
+    }
     protected DataGridView CecButtonGridView;
 
     public virtual ApplicationAction DefaultValue(CecKeypress key)
@@ -377,6 +412,11 @@ namespace LibCECTray.controller.applications
         return !IsInternal;
       }
     }
+
+    private bool _applicationRunning;
+
+    protected readonly CECController Controller;
+
     #endregion
   }
 }