Imported Upstream version 2.2.0
[deb_libcec.git] / src / LibCecTray / controller / CECController.cs
CommitLineData
cbbe90dd
JB
1/*
2 * This file is part of the libCEC(R) library.
3 *
4 * libCEC(R) is Copyright (C) 2011-2013 Pulse-Eight Limited. All rights reserved.
5 * libCEC(R) is an original work, containing original code.
6 *
7 * libCEC(R) is a trademark of Pulse-Eight Limited.
8 *
9 * This program is dual-licensed; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 *
23 *
24 * Alternatively, you can license this library under a commercial license,
25 * please contact Pulse-Eight Licensing for more information.
26 *
27 * For more information contact:
28 * Pulse-Eight Licensing <license@pulse-eight.com>
29 * http://www.pulse-eight.com/
30 * http://www.pulse-eight.net/
31 */
32
33using System;
34using System.Collections.Generic;
35using System.Windows.Forms;
36using CecSharp;
37using LibCECTray.Properties;
38using LibCECTray.controller.applications;
39using LibCECTray.settings;
40using LibCECTray.ui;
41
42namespace LibCECTray.controller
43{
44 internal class CECController : CecCallbackMethods
45 {
46 public CECController(CECTray gui)
47 {
48 _gui = gui;
49 CECActions = new Actions(this);
50
51 InitialiseGui();
52
53 Settings.SettingChanged += OnSettingChanged;
54 }
55
56 #region Settings
57 /// <summary>
58 /// Called when a setting changed
59 /// </summary>
60 /// <param name="setting">The setting that changed</param>
61 /// <param name="oldValue">The old value</param>
62 /// <param name="newValue">The new value</param>
63 private void OnSettingChanged(CECSetting setting, object oldValue, object newValue)
64 {
65 if (setting.KeyName == CECSettings.KeyHDMIPort)
66 {
67 CECSettingByte byteSetting = setting as CECSettingByte;
68 if (byteSetting != null)
69 {
70 if (!Settings.OverridePhysicalAddress.Value)
71 Config.HDMIPort = byteSetting.Value;
72 CECActions.SetConnectedDevice(Settings.ConnectedDevice.Value, byteSetting.Value);
73 }
74 }
75 else if (setting.KeyName == CECSettings.KeyConnectedToHDMIDevice)
76 {
77 CECSettingLogicalAddress laSetting = setting as CECSettingLogicalAddress;
78 if (laSetting != null)
79 {
80 if (!Settings.OverridePhysicalAddress.Value)
81 Config.BaseDevice = laSetting.Value;
82 CECActions.SetConnectedDevice(laSetting.Value, Settings.HDMIPort.Value);
83 }
84 }
85 else if (setting.KeyName == CECSettings.KeyPhysicalAddress)
86 {
87 CECSettingUShort ushortSetting = setting as CECSettingUShort;
88 if (ushortSetting != null && Settings.OverridePhysicalAddress.Value && Config.PhysicalAddress != ushortSetting.Value)
89 {
90 Config.PhysicalAddress = ushortSetting.Value;
91 CECActions.SetPhysicalAddress(ushortSetting.Value);
92 }
93 }
94 else if (setting.KeyName == CECSettings.KeyOverridePhysicalAddress)
95 {
96 CECSettingBool boolSetting = setting as CECSettingBool;
97 if (boolSetting != null)
98 {
99 Settings.PhysicalAddress.Enabled = boolSetting.Value;
100 Settings.HDMIPort.Enabled = !boolSetting.Value;
101 Settings.ConnectedDevice.Enabled = !boolSetting.Value;
102 if (boolSetting.Value)
103 {
104 Config.BaseDevice = Settings.ConnectedDevice.Value;
105 Config.HDMIPort = 0;
106 Config.PhysicalAddress = Settings.PhysicalAddress.Value;
107 }
108 else
109 {
110 Config.BaseDevice = Settings.ConnectedDevice.Value;
111 Config.HDMIPort = Settings.HDMIPort.Value;
112 Config.PhysicalAddress = 0xFFFF;
113 }
114 }
115 }
116 else if (setting.KeyName == CECSettings.KeyDeviceType)
117 {
118 CECSettingDeviceType dtSetting = setting as CECSettingDeviceType;
119 if (dtSetting != null)
120 {
121 if (dtSetting.Value != Config.DeviceTypes.Types[0] && Settings.OverrideTVVendor.Value)
122 {
123 Config.DeviceTypes.Types[0] = dtSetting.Value;
124 if (!_deviceChangeWarningDisplayed)
125 {
126 _deviceChangeWarningDisplayed = true;
127 MessageBox.Show(Resources.device_type_changed, Resources.app_name, MessageBoxButtons.OK,
128 MessageBoxIcon.Warning);
129 }
130 }
131 }
132 }
133 else if (setting.KeyName == CECSettings.KeyOverrideTVVendor)
134 {
135 CECSettingBool boolSetting = setting as CECSettingBool;
136 if (boolSetting != null)
137 {
138 Settings.TVVendor.Enabled = boolSetting.Value;
139 Settings.TVVendor.Value = boolSetting.Value ? Lib.GetDeviceVendorId(CecLogicalAddress.Tv) : CecVendorId.Unknown;
140 Config.TvVendor = boolSetting.Value ? Settings.TVVendor.Value : CecVendorId.Unknown;
141 }
142 }
143 else if (setting.KeyName == CECSettings.KeyActivateSource)
144 {
145 CECSettingBool boolSetting = setting as CECSettingBool;
146 if (boolSetting != null)
147 Config.ActivateSource = boolSetting.Value;
148 }
149 else if (setting.KeyName == CECSettings.KeyTVVendor)
150 {
151 CECSettingVendorId vendorSetting = setting as CECSettingVendorId;
152 if (vendorSetting != null && Settings.OverrideTVVendor.Value)
153 Config.TvVendor = vendorSetting.Value;
154 }
155 else if (setting.KeyName == CECSettings.KeyWakeDevices)
156 {
157 CECSettingLogicalAddresses laSetting = setting as CECSettingLogicalAddresses;
158 if (laSetting != null)
159 Config.WakeDevices = laSetting.Value;
160 }
161 else if (setting.KeyName == CECSettings.KeyPowerOffDevices)
162 {
163 CECSettingLogicalAddresses laSetting = setting as CECSettingLogicalAddresses;
164 if (laSetting != null)
165 Config.PowerOffDevices = laSetting.Value;
166 }
167 }
168
169 /// <summary>
170 /// Persist all known settings in the registry
171 /// </summary>
172 public void PersistSettings()
173 {
174 /* save settings in the eeprom */
175 Lib.SetConfiguration(Config);
176 Lib.PersistConfiguration(Config);
177
178 /* and in the registry */
179 Settings.Persist();
180 }
181
182 /// <summary>
183 /// Reset all settings to their default values
184 /// </summary>
185 public void ResetDefaultSettings()
186 {
187 SetControlsEnabled(false);
188 _gui.ShowHideAdvanced(false);
189
190 CECActions.SuppressUpdates = true;
191 Settings.SetDefaultValues();
192 _config = null;
193 Lib.SetConfiguration(Config);
194 CECActions.SuppressUpdates = false;
195
196 _gui.ShowHideAdvanced(Settings.AdvancedMode.Value);
197 SetControlsEnabled(true);
198 }
199 #endregion
200
201 /// <summary>
202 /// Opens a connection to libCEC and register known applications
203 /// </summary>
204 public void Initialise()
205 {
206 // only load once
207 if (_initialised)
208 return;
209 _initialised = true;
210
211 CECActions.ConnectToDevice(Config);
212 Applications.Initialise(this);
213 }
214
215 /// <summary>
216 /// Closes the connection to libCEC
217 /// </summary>
218 public void Close()
219 {
220 Lib.DisableCallbacks();
221 Lib.StandbyDevices(CecLogicalAddress.Broadcast);
222 Lib.Close();
223 _initialised = false;
224 }
225
226 /// <summary>
227 /// Register a new application controller, which will add a new tab for the application
228 /// </summary>
229 /// <param name="app">The new application to register</param>
230 /// <returns>True when registered, false otherwise</returns>
231 public bool RegisterApplication(ApplicationController app)
232 {
233 if (_applications.Contains(app)) return false;
234 _applications.Add(app);
235
236 _gui.SuspendLayout();
237 _gui.TabControls.Add(app.UiControl);
238 _gui.ResumeLayout();
239
240 app.Initialise();
241
242 return true;
243 }
244
245 #region GUI controls
246 /// <summary>
247 /// Initialises the UI
248 /// </summary>
249 private void InitialiseGui()
250 {
251 _gui.SuspendLayout();
252 _gui.InitialiseSettingsComponent(Settings);
253
254 // add the controller tabs to the gui
255 foreach (var ui in ApplicationUIs)
256 _gui.TabControls.Add(ui);
257
258 // enable/disable advanced mode
259 _gui.ShowHideAdvanced(Settings.AdvancedMode.Value);
260
261 _gui.ResumeLayout();
262 }
263
264 /// <summary>
265 /// Display a dialog
266 /// </summary>
267 /// <param name="control">The dialog to display</param>
268 /// <param name="modal">True when modal</param>
269 public void DisplayDialog(Form control, bool modal)
270 {
271 _gui.DisplayDialog(control, modal);
272 }
273
274 /// <summary>
275 /// Changes the status text of this window
276 /// </summary>
277 /// <param name="status">The new status text</param>
278 public void SetStatusText(string status)
279 {
280 _gui.SetStatusText(status);
281 }
282
283 /// <summary>
284 /// Changes the progress bar value
285 /// </summary>
286 /// <param name="progress">The new progress percentage</param>
287 /// <param name="visible">True to make the bar visible, false otherwise</param>
288 public void SetProgressBar(int progress, bool visible)
289 {
290 _gui.SetProgressBar(progress, visible);
291 }
292
293 /// <summary>
294 /// Enable/disable all controls
295 /// </summary>
296 /// <param name="val">True to enable, false to disable</param>
297 public void SetControlsEnabled(bool val)
298 {
299 Settings.Enabled = val;
300 foreach (var app in _applications)
301 app.UiControl.SetEnabled(val);
302 _gui.SetControlsEnabled(val);
303 }
304
305 /// <summary>
306 /// (re)check the logical addresses of the active devices on the bus
307 /// </summary>
308 public void CheckActiveDevices()
309 {
310 var activeDevices = Lib.GetActiveDevices();
311 List<string> deviceList = new List<string>();
312 foreach (var activeDevice in activeDevices.Addresses)
313 {
314 if (activeDevice != CecLogicalAddress.Unknown)
315 deviceList.Add(string.Format("{0,1:X} : {1}", (int)activeDevice, Lib.ToString(activeDevice)));
316 }
317 deviceList.Add(string.Format("{0,1:X} : {1}", (int)CecLogicalAddress.Broadcast, Lib.ToString(CecLogicalAddress.Broadcast)));
318
319 _gui.SetActiveDevices(deviceList.ToArray());
320 }
321
322 /// <summary>
323 /// Show/hide the taskbar entry
324 /// </summary>
325 /// <param name="val">True to show, false to hide</param>
326 public void SetShowInTaskbar(bool val)
327 {
328 _gui.SetShowInTaskbar(val);
329 }
330
331 /// <summary>
332 /// Show or hide this window
333 /// </summary>
334 /// <param name="val">True to show, false to hide</param>
335 public void Hide(bool val)
336 {
337 _gui.SafeHide(val);
338 }
339 #endregion
340
341 #region Callbacks called by libCEC
342 public override int ReceiveCommand(CecCommand command)
343 {
344 return 0;
345 }
346
347 public override int ReceiveKeypress(CecKeypress key)
348 {
349 foreach (var app in _applications)
350 {
351 bool keySent = app.SendKey(key, app.UiName == _gui.SelectedTabName);
352
353 if (keySent)
354 {
355 string strLog = string.Format("sent key '{0}' to '{1}'", (int) key.Keycode, app.UiName) + Environment.NewLine;
356 _gui.AddLogMessage(strLog);
357 break;
358 }
359 }
360
361 return 1;
362 }
363
364 public override int ReceiveLogMessage(CecLogMessage message)
365 {
366 _gui.AddLogMessage(message);
367 return 1;
368 }
369
370 public override int ReceiveAlert(CecAlert alert, CecParameter data)
371 {
372 switch (alert)
373 {
374 case CecAlert.ServiceDevice:
375 MessageBox.Show(Resources.alert_service_device, Resources.cec_alert, MessageBoxButtons.OK, MessageBoxIcon.Warning);
376 break;
377 case CecAlert.ConnectionLost:
378 MessageBox.Show(Resources.alert_connection_lost, Resources.cec_alert, MessageBoxButtons.OK, MessageBoxIcon.Warning);
379 break;
380 case CecAlert.PermissionError:
381 MessageBox.Show(Resources.alert_permission_error, Resources.cec_alert, MessageBoxButtons.OK, MessageBoxIcon.Warning);
382 break;
383 case CecAlert.PortBusy:
384 MessageBox.Show(Resources.alert_port_busy, Resources.cec_alert, MessageBoxButtons.OK, MessageBoxIcon.Warning);
385 break;
386 case CecAlert.PhysicalAddressError:
387 MessageBox.Show(Resources.alert_physical_address_error, Resources.cec_alert, MessageBoxButtons.OK, MessageBoxIcon.Warning);
388 break;
389 case CecAlert.TVPollFailed:
390 MessageBox.Show(Resources.alert_tv_poll_failed, Resources.cec_alert, MessageBoxButtons.OK, MessageBoxIcon.Warning);
391 break;
392 }
393 return 1;
394 }
395
396 public override int ConfigurationChanged(LibCECConfiguration config)
397 {
398 Settings.PhysicalAddress.Value = Config.PhysicalAddress;
399 Settings.ConnectedDevice.Value = Config.BaseDevice == CecLogicalAddress.AudioSystem ? CecLogicalAddress.AudioSystem : CecLogicalAddress.Tv;
400 Settings.HDMIPort.Value = Config.HDMIPort;
401 Settings.WakeDevices.Value = Config.WakeDevices;
402 Settings.PowerOffDevices.Value = Config.PowerOffDevices;
403 Settings.ActivateSource.Value = Config.ActivateSource;
404 Settings.DeviceType.Value = config.DeviceTypes.Types[0];
405
406 if (config.TvVendor != CecVendorId.Unknown)
407 {
408 Settings.OverrideTVVendor.Value = true;
409 Settings.TVVendor.Value = config.TvVendor;
410 }
411 else
412 {
413 Settings.OverrideTVVendor.Value = false;
414 }
415
416 _gui.SetControlText(_gui, Resources.app_name + " - libCEC " + Lib.ToString(Config.ServerVersion));
417
418 CECActions.UpdatePhysicalAddress();
419 return 1;
420 }
421
422 public override void SourceActivated(CecLogicalAddress logicalAddress, bool activated)
423 {
424 if (!activated)
425 return;
426
427 foreach (var app in _applications)
428 {
429 if (app.AutoStartApplication.Value)
430 app.Start(false);
431 }
432 }
433 #endregion
434
435 #region Members
436 /// <summary>
437 /// List of tab pages for each application that the UI supports
438 /// </summary>
439 public List<ControllerTabPage> ApplicationUIs
440 {
441 get
442 {
443 List<ControllerTabPage> retVal = new List<ControllerTabPage>();
444 foreach (var app in _applications)
445 retVal.Add(app.UiControl);
446 return retVal;
447 }
448 }
449
450 /// <summary>
451 /// List of application controllers that the UI supports
452 /// </summary>
453 private readonly List<ApplicationController> _applications = new List<ApplicationController>();
454
455 /// <summary>
456 /// Settings that are persisted in the registry (when not using the default value)
457 /// </summary>
458 public CECSettings Settings
459 {
460 get { return _settings ?? (_settings = new CECSettings(OnSettingChanged)); }
461 }
462 private CECSettings _settings;
463
464 /// <summary>
465 /// libCEC configuration for the application
466 /// </summary>
467 private LibCECConfiguration Config
468 {
469 get
470 {
471 if (_config == null)
472 {
473 _config = new LibCECConfiguration { DeviceName = "CEC Tray", ClientVersion = CecClientVersion.CurrentVersion };
474 _config.DeviceTypes.Types[0] = CecDeviceType.RecordingDevice;
475 _config.SetCallbacks(this);
476
477 if (Settings.OverridePhysicalAddress.Value)
478 {
479 _config.PhysicalAddress = Settings.PhysicalAddress.Value;
480 _config.HDMIPort = 0;
481 _config.BaseDevice = CecLogicalAddress.Unknown;
482 }
483 else
484 {
485 _config.PhysicalAddress = 0;
486 _config.HDMIPort = Settings.HDMIPort.Value;
487 _config.BaseDevice = Settings.ConnectedDevice.Value;
488 }
489 _config.ActivateSource = Settings.ActivateSource.Value;
490 _config.DeviceTypes.Types[0] = Settings.DeviceType.Value;
491 if (Settings.OverrideTVVendor.Value)
492 _config.TvVendor = Settings.TVVendor.Value;
493 _config.WakeDevices = Settings.WakeDevices.Value;
494 _config.PowerOffDevices = Settings.PowerOffDevices.Value;
495 }
496 return _config;
497 }
498 }
499 private LibCECConfiguration _config;
500
501 /// <summary>
502 /// Get build info from libCEC
503 /// </summary>
504 public string LibInfo
505 {
506 get { return Lib.GetLibInfo(); }
507 }
508
509 /// <summary>
510 /// libCEC API version
511 /// </summary>
512 public string LibServerVersion
513 {
514 get { return Lib.ToString(Config.ServerVersion); }
515 }
516
517 /// <summary>
518 /// libCEC client API version
519 /// </summary>
520 public string LibClientVersion
521 {
522 get { return Lib.ToString(Config.ClientVersion); }
523 }
524
525 /// <summary>
526 /// Get the usb vendor id
527 /// </summary>
528 public ushort AdapterVendorId
529 {
530 get { return Lib.GetAdapterVendorId(); }
531 }
532
533 /// <summary>
534 /// Get the usb product id
535 /// </summary>
536 public ushort AdapterProductId
537 {
538 get { return Lib.GetAdapterProductId(); }
539 }
540
541
542 /// <summary>
543 /// libCEC
544 /// </summary>
545 public LibCecSharp Lib
546 {
547 get { return _lib ?? (_lib = new LibCecSharp(Config)); }
548 }
549 private LibCecSharp _lib;
550
551 private readonly CECTray _gui;
552 public Actions CECActions;
553 private bool _deviceChangeWarningDisplayed;
554 private bool _initialised;
555
556 #endregion
557 }
558}