save the correct xml file in LibCecTray, so XBMC picks up the correct config
[deb_libcec.git] / src / LibCecTray / controller / applications / internal / XBMCController.cs
1 /*
2 * This file is part of the libCEC(R) library.
3 *
4 * libCEC(R) is Copyright (C) 2011-2012 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
33 using System;
34 using System.Globalization;
35 using System.IO;
36 using System.Text;
37 using System.Windows.Forms;
38 using System.Xml;
39 using CecSharp;
40 using LibCECTray.Properties;
41 using LibCECTray.settings;
42
43 namespace LibCECTray.controller.applications.@internal
44 {
45 internal class XBMCController : ApplicationController
46 {
47 public XBMCController(CECSettings settings) :
48 base(settings,
49 Resources.application_xbmc,
50 "XBMC",
51 "XBMC.exe",
52 Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles) + @"\XBMC")
53 {
54 IsInternal = true;
55 AutoStartApplication.Value = false;
56 ControlApplication.Value = false;
57
58 LoadXMLConfiguration();
59 }
60
61 public override ApplicationAction DefaultValue(CecKeypress key)
62 {
63 return null;
64 }
65
66 public override ControllerTabPage UiControl
67 {
68 get { return UIControlInternal ?? (UIControlInternal = new XBMCControllerUI(this)); }
69 }
70
71 public bool LoadXMLConfiguration()
72 {
73 var xbmcDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + @"\XBMC\userdata\peripheral_data";
74 return LoadXMLConfiguration(xbmcDir + string.Format(@"\usb_{0:X}_{1:X}.xml", Program.Instance.Controller.AdapterVendorId, Program.Instance.Controller.AdapterProductId)) ||
75 LoadXMLConfiguration(xbmcDir + @"\usb_2548_1001.xml") ||
76 LoadXMLConfiguration(xbmcDir + @"\usb_2548_1002.xml");
77 }
78
79 public bool LoadXMLConfiguration(string filename)
80 {
81 bool gotConfig = false;
82 if (File.Exists(filename))
83 {
84 XmlTextReader reader = new XmlTextReader(filename);
85 while (reader.Read())
86 {
87 gotConfig = true;
88 switch (reader.NodeType)
89 {
90 case XmlNodeType.Element:
91 if (reader.Name.ToLower() == "setting")
92 {
93 string name = string.Empty;
94 string value = string.Empty;
95
96 while (reader.MoveToNextAttribute())
97 {
98 if (reader.Name.ToLower().Equals("id"))
99 name = reader.Value.ToLower();
100 if (reader.Name.ToLower().Equals("value"))
101 value = reader.Value;
102 }
103
104 switch (name)
105 {
106 case "cec_hdmi_port":
107 {
108 byte iPort;
109 if (byte.TryParse(value, out iPort))
110 Settings.HDMIPort.Value = iPort;
111 }
112 break;
113 case "connected_device":
114 {
115 ushort iDevice;
116 if (ushort.TryParse(value, out iDevice))
117 Settings.ConnectedDevice.Value = (CecLogicalAddress)iDevice;
118 }
119 break;
120 case "cec_power_on_startup":
121 if (value.Equals("1") || value.ToLower().Equals("true") || value.ToLower().Equals("yes"))
122 {
123 Settings.ActivateSource.Value = true;
124 Settings.WakeDevices.Value.Set(CecLogicalAddress.Tv);
125 }
126 break;
127 case "cec_power_off_shutdown":
128 if (value.Equals("1") || value.ToLower().Equals("true") || value.ToLower().Equals("yes"))
129 Settings.PowerOffDevices.Value.Set(CecLogicalAddress.Broadcast);
130 break;
131 case "cec_standby_screensaver":
132 StandbyScreensaver.Value = value.Equals("1") || value.ToLower().Equals("true") || value.ToLower().Equals("yes");
133 break;
134 case "standby_pc_on_tv_standby":
135 PowerOffOnStandby.Value = value.Equals("1") || value.ToLower().Equals("true") || value.ToLower().Equals("yes");
136 break;
137 case "use_tv_menu_language":
138 UseTVLanguage.Value = value.Equals("1") || value.ToLower().Equals("true") || value.ToLower().Equals("yes");
139 break;
140 // 1.5.0+ settings
141 case "physical_address":
142 {
143 ushort physicalAddress;
144 if (ushort.TryParse(value, NumberStyles.AllowHexSpecifier, null, out physicalAddress))
145 Settings.PhysicalAddress.Value = physicalAddress;
146 }
147 break;
148 case "device_type":
149 {
150 ushort iType;
151 if (ushort.TryParse(value, out iType))
152 Settings.DeviceType.Value = (CecDeviceType)iType;
153 }
154 break;
155 case "tv_vendor":
156 {
157 UInt64 iVendor;
158 if (UInt64.TryParse(value, out iVendor))
159 Settings.TVVendor.Value = (CecVendorId)iVendor;
160 }
161 break;
162 case "wake_devices":
163 {
164 Settings.WakeDevices.Value.Clear();
165 string[] split = value.Split(new[] { ' ' });
166 foreach (string dev in split)
167 {
168 byte iLogicalAddress;
169 if (byte.TryParse(dev, out iLogicalAddress))
170 Settings.WakeDevices.Value.Set((CecLogicalAddress)iLogicalAddress);
171 }
172 }
173 break;
174 case "standby_devices":
175 {
176 Settings.PowerOffDevices.Value.Clear();
177 string[] split = value.Split(new[] { ' ' });
178 foreach (string dev in split)
179 {
180 byte iLogicalAddress;
181 if (byte.TryParse(dev, out iLogicalAddress))
182 Settings.PowerOffDevices.Value.Set((CecLogicalAddress)iLogicalAddress);
183 }
184 }
185 break;
186 case "enabled":
187 break;
188 case "port":
189 //TODO
190 break;
191 // 1.5.1 settings
192 case "send_inactive_source":
193 SendInactiveSource.Value = value.Equals("1") || value.ToLower().Equals("true") || value.ToLower().Equals("yes");
194 break;
195 }
196 }
197 break;
198 }
199 }
200 }
201 return gotConfig;
202 }
203
204 public void SaveXMLConfiguration()
205 {
206 Settings.Persist();
207
208 var xbmcDir = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + @"\XBMC\userdata\peripheral_data";
209 if (!Directory.Exists(xbmcDir))
210 Directory.CreateDirectory(xbmcDir);
211
212 if (!Directory.Exists(xbmcDir))
213 {
214 // couldn't create directory
215 MessageBox.Show(string.Format(Resources.could_not_create_directory, xbmcDir), Resources.error,
216 MessageBoxButtons.OK, MessageBoxIcon.Error);
217 return;
218 }
219
220 SaveFileDialog dialog = new SaveFileDialog
221 {
222 Title = Resources.store_settings_where,
223 InitialDirectory = xbmcDir,
224 FileName = string.Format("usb_{0:X}_{1:X}.xml", Program.Instance.Controller.AdapterVendorId, Program.Instance.Controller.AdapterProductId),
225 Filter = Resources.xml_file_filter,
226 FilterIndex = 1
227 };
228 if (dialog.ShowDialog() != DialogResult.OK) return;
229
230 FileStream fs = null;
231 string error = string.Empty;
232 try
233 {
234 fs = (FileStream)dialog.OpenFile();
235 }
236 catch (Exception ex)
237 {
238 error = ex.Message;
239 }
240 if (fs == null)
241 {
242 MessageBox.Show(string.Format(Resources.cannot_open_file, dialog.FileName) + (error.Length > 0 ? ": " + error : string.Empty), Resources.app_name, MessageBoxButtons.OK, MessageBoxIcon.Error);
243 }
244 else
245 {
246 StreamWriter writer = new StreamWriter(fs);
247 StringBuilder output = new StringBuilder();
248 output.AppendLine("<settings>");
249 output.AppendLine("<setting id=\"cec_hdmi_port\" value=\"" + Settings.HDMIPort.Value + "\" />");
250 output.AppendLine("<setting id=\"connected_device\" value=\"" + (Settings.ConnectedDevice.Value == CecLogicalAddress.AudioSystem ? 5 : 0) + "\" />");
251 output.AppendLine("<setting id=\"cec_power_on_startup\" value=\"" + (Settings.ActivateSource.Value ? 1 : 0) + "\" />");
252 output.AppendLine("<setting id=\"cec_power_off_shutdown\" value=\"" + (Settings.PowerOffDevices.Value.IsSet(CecLogicalAddress.Broadcast) ? 1 : 0) + "\" />");
253 output.AppendLine("<setting id=\"cec_standby_screensaver\" value=\"" + (StandbyScreensaver.Value ? 1 : 0) + "\" />");
254 output.AppendLine("<setting id=\"standby_pc_on_tv_standby\" value=\"" + (PowerOffOnStandby.Value ? 1 : 0) + "\" />");
255 output.AppendLine("<setting id=\"use_tv_menu_language\" value=\"" + (UseTVLanguage.Value ? 1 : 0) + "\" />");
256 output.AppendLine("<setting id=\"enabled\" value=\"1\" />");
257 output.AppendLine("<setting id=\"port\" value=\"\" />");
258
259 // only supported by 1.5.0+ clients
260 output.AppendLine("<!-- the following lines are only supported by v1.5.0+ clients -->");
261 output.AppendLine("<setting id=\"activate_source\" value=\"" + (Settings.ActivateSource.Value ? 1 : 0) + "\" />");
262 output.AppendLine("<setting id=\"physical_address\" value=\"" + string.Format("{0,4:X}", Settings.OverridePhysicalAddress.Value ? Settings.PhysicalAddress.Value : 0).Trim() + "\" />");
263 output.AppendLine("<setting id=\"device_type\" value=\"" + (int)Settings.DeviceType.Value + "\" />");
264 output.AppendLine("<setting id=\"tv_vendor\" value=\"" + string.Format("{0,6:X}", Settings.OverrideTVVendor.Value ? (int)Settings.TVVendor.Value : 0).Trim() + "\" />");
265
266 output.Append("<setting id=\"wake_devices\" value=\"");
267 StringBuilder strWakeDevices = new StringBuilder();
268 foreach (CecLogicalAddress addr in Settings.WakeDevices.Value.Addresses)
269 if (addr != CecLogicalAddress.Unknown)
270 strWakeDevices.Append(" " + (int)addr);
271 output.Append(strWakeDevices.ToString().Trim());
272 output.AppendLine("\" />");
273
274 output.Append("<setting id=\"standby_devices\" value=\"");
275 StringBuilder strSleepDevices = new StringBuilder();
276 foreach (CecLogicalAddress addr in Settings.PowerOffDevices.Value.Addresses)
277 if (addr != CecLogicalAddress.Unknown)
278 strSleepDevices.Append(" " + (int)addr);
279 output.Append(strSleepDevices.ToString().Trim());
280 output.AppendLine("\" />");
281
282 // only supported by 1.5.1+ clients
283 output.AppendLine("<!-- the following lines are only supported by v1.5.1+ clients -->");
284 //TODO
285 //output.AppendLine("<setting id=\"send_inactive_source\" value=\"" + (config.SendInactiveSource ? 1 : 0) + "\" />");
286
287 output.AppendLine("</settings>");
288 writer.Write(output.ToString());
289 writer.Close();
290 fs.Close();
291 fs.Dispose();
292 MessageBox.Show(Resources.settings_stored, Resources.app_name, MessageBoxButtons.OK, MessageBoxIcon.Information);
293 }
294 }
295
296 public CECSettingBool UseTVLanguage
297 {
298 get
299 {
300 if (!Settings.ContainsKey(ProcessName + "_use_tv_language"))
301 {
302 CECSettingBool setting = new CECSettingBool(ProcessName + "_use_tv_language", Resources.app_use_tv_language, true, null);
303 Settings.Load(setting);
304 Settings[ProcessName + "_use_tv_language"] = setting;
305 }
306 return Settings[ProcessName + "_use_tv_language"].AsSettingBool;
307 }
308 }
309
310 public CECSettingBool StandbyScreensaver
311 {
312 get
313 {
314 if (!Settings.ContainsKey(ProcessName + "_standby_screensaver"))
315 {
316 CECSettingBool setting = new CECSettingBool(ProcessName + "_standby_screensaver", Resources.app_standby_screensaver, true, null);
317 Settings.Load(setting);
318 Settings[ProcessName + "_standby_screensaver"] = setting;
319 }
320 return Settings[ProcessName + "_standby_screensaver"].AsSettingBool;
321 }
322 }
323
324 public CECSettingBool ActivateSource
325 {
326 get
327 {
328 if (!Settings.ContainsKey(ProcessName + "_activate_source"))
329 {
330 CECSettingBool setting = new CECSettingBool(ProcessName + "_activate_source", Resources.global_activate_source, true, null);
331 Settings.Load(setting);
332 Settings[ProcessName + "_activate_source"] = setting;
333 }
334 return Settings[ProcessName + "_activate_source"].AsSettingBool;
335 }
336 }
337
338 public CECSettingBool PowerOffOnStandby
339 {
340 get
341 {
342 if (!Settings.ContainsKey(ProcessName + "_standby_on_tv_standby"))
343 {
344 CECSettingBool setting = new CECSettingBool(ProcessName + "_standby_on_tv_standby", Resources.app_standby_on_tv_standby, true, null);
345 Settings.Load(setting);
346 Settings[ProcessName + "_standby_on_tv_standby"] = setting;
347 }
348 return Settings[ProcessName + "_standby_on_tv_standby"].AsSettingBool;
349 }
350 }
351
352 public CECSettingBool SendInactiveSource
353 {
354 get
355 {
356 if (!Settings.ContainsKey(ProcessName + "_send_inactive_source"))
357 {
358 CECSettingBool setting = new CECSettingBool(ProcessName + "_send_inactive_source", Resources.app_send_inactive_source, true, null);
359 Settings.Load(setting);
360 Settings[ProcessName + "_send_inactive_source"] = setting;
361 }
362 return Settings[ProcessName + "_send_inactive_source"].AsSettingBool;
363 }
364 }
365 }
366 }