added xmldoc for LibCecSharp
[deb_libcec.git] / src / LibCecSharp / LibCecSharp.cpp
CommitLineData
61f3c2ad
LOK
1/*
2 * This file is part of the libCEC(R) library.
3 *
5d6aa900 4 * libCEC(R) is Copyright (C) 2011-2012 Pulse-Eight Limited. All rights reserved.
61f3c2ad
LOK
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
4ef3b314 33#include "CecSharpTypes.h"
61f3c2ad
LOK
34#using <System.dll>
35
36using namespace System;
0cac9547 37using namespace System::Runtime::InteropServices;
61f3c2ad
LOK
38using namespace CEC;
39using namespace msclr::interop;
40
4ef3b314 41namespace CecSharp
61f3c2ad 42{
4ef3b314
LOK
43 public ref class LibCecSharp : public CecCallbackMethods
44 {
45 public:
41297a45
LOK
46 LibCecSharp(LibCECConfiguration ^config)
47 {
11fea069
LOK
48 m_callbacks = config->Callbacks;
49 CecCallbackMethods::EnableCallbacks(m_callbacks);
32403cc3 50 if (!InitialiseLibCec(config))
41297a45
LOK
51 throw gcnew Exception("Could not initialise LibCecSharp");
52 }
53
4ef3b314 54 LibCecSharp(String ^ strDeviceName, CecDeviceTypeList ^ deviceTypes)
41297a45 55 {
11fea069 56 m_callbacks = gcnew CecCallbackMethods();
32403cc3
LOK
57 LibCECConfiguration ^config = gcnew LibCECConfiguration();
58 config->SetCallbacks(this);
59 config->DeviceName = strDeviceName;
60 config->DeviceTypes = deviceTypes;
61 if (!InitialiseLibCec(config))
41297a45
LOK
62 throw gcnew Exception("Could not initialise LibCecSharp");
63 }
64
65 ~LibCecSharp(void)
66 {
67 Close();
68 m_libCec = NULL;
69 }
70
71 private:
72 !LibCecSharp(void)
73 {
74 Close();
75 m_libCec = NULL;
76 }
77
32403cc3 78 bool InitialiseLibCec(LibCECConfiguration ^config)
4ef3b314
LOK
79 {
80 marshal_context ^ context = gcnew marshal_context();
32403cc3
LOK
81 libcec_configuration libCecConfig;
82 ConvertConfiguration(context, config, libCecConfig);
4ef3b314 83
32403cc3 84 m_libCec = (ICECAdapter *) CECInitialise(&libCecConfig);
112b397a 85 config->Update(libCecConfig);
4ef3b314
LOK
86
87 delete context;
41297a45
LOK
88 return m_libCec != NULL;
89 }
90
32403cc3 91 void ConvertConfiguration(marshal_context ^context, LibCECConfiguration ^netConfig, CEC::libcec_configuration &config)
41297a45
LOK
92 {
93 config.Clear();
94
1d0b2f17
LOK
95 const char *strDeviceName = context->marshal_as<const char*>(netConfig->DeviceName);
96 memcpy_s(config.strDeviceName, 13, strDeviceName, 13);
41297a45 97 for (unsigned int iPtr = 0; iPtr < 5; iPtr++)
32403cc3 98 config.deviceTypes.types[iPtr] = (cec_device_type)netConfig->DeviceTypes->Types[iPtr];
41297a45 99
8670c970 100 config.bAutodetectAddress = netConfig->AutodetectAddress ? 1 : 0;
32403cc3
LOK
101 config.iPhysicalAddress = netConfig->PhysicalAddress;
102 config.baseDevice = (cec_logical_address)netConfig->BaseDevice;
103 config.iHDMIPort = netConfig->HDMIPort;
104 config.clientVersion = (cec_client_version)netConfig->ClientVersion;
8670c970
LOK
105 config.bGetSettingsFromROM = netConfig->GetSettingsFromROM ? 1 : 0;
106 config.bActivateSource = netConfig->ActivateSource ? 1 : 0;
b7907707
LOK
107 config.tvVendor = (cec_vendor_id)netConfig->TvVendor;
108 config.wakeDevices.Clear();
109 for (int iPtr = 0; iPtr < 16; iPtr++)
110 {
111 if (netConfig->WakeDevices->IsSet((CecLogicalAddress)iPtr))
112 config.wakeDevices.Set((cec_logical_address)iPtr);
113 }
114 config.powerOffDevices.Clear();
115 for (int iPtr = 0; iPtr < 16; iPtr++)
116 {
117 if (netConfig->PowerOffDevices->IsSet((CecLogicalAddress)iPtr))
118 config.powerOffDevices.Set((cec_logical_address)iPtr);
119 }
8670c970
LOK
120 config.bPowerOffScreensaver = netConfig->PowerOffScreensaver ? 1 : 0;
121 config.bPowerOffOnStandby = netConfig->PowerOffOnStandby ? 1 : 0;
b98fc43d 122
92da1117
MK
123 if (netConfig->ServerVersion >= CecServerVersion::Version1_5_1)
124 config.bSendInactiveSource = netConfig->SendInactiveSource ? 1 : 0;
b98fc43d 125
92da1117
MK
126 if (netConfig->ServerVersion >= CecServerVersion::Version1_6_0)
127 {
128 config.bPowerOffDevicesOnStandby = netConfig->PowerOffDevicesOnStandby ? 1 : 0;
129 config.bShutdownOnStandby = netConfig->ShutdownOnStandby ? 1 : 0;
130 }
131
132 if (netConfig->ServerVersion >= CecServerVersion::Version1_6_2)
1d0b2f17
LOK
133 {
134 const char *strDeviceLanguage = context->marshal_as<const char*>(netConfig->DeviceLanguage);
135 memcpy_s(config.strDeviceLanguage, 3, strDeviceLanguage, 3);
136 }
b98fc43d 137
d3b96c62 138 if (netConfig->ServerVersion >= CecServerVersion::Version1_6_3)
dc6366e8 139 config.bMonitorOnly = netConfig->MonitorOnlyClient ? 1 : 0;
d3b96c62 140
dc6366e8 141 config.callbacks = &g_cecCallbacks;
4ef3b314 142 }
4ef3b314
LOK
143
144 public:
e3aabeac
LOK
145 /// <summary>
146 /// Try to find all connected CEC adapters.
147 /// </summary>
148 /// <param name="path">The path filter for adapters. Leave empty to return all adapters.</param>
149 /// <returns>The adapters that were found.</returns>
4ef3b314
LOK
150 array<CecAdapter ^> ^ FindAdapters(String ^ path)
151 {
152 cec_adapter *devices = new cec_adapter[10];
153
154 marshal_context ^ context = gcnew marshal_context();
155 const char* strPathC = path->Length > 0 ? context->marshal_as<const char*>(path) : NULL;
156
157 uint8_t iDevicesFound = m_libCec->FindAdapters(devices, 10, NULL);
158
159 array<CecAdapter ^> ^ adapters = gcnew array<CecAdapter ^>(iDevicesFound);
160 for (unsigned int iPtr = 0; iPtr < iDevicesFound; iPtr++)
161 adapters[iPtr] = gcnew CecAdapter(gcnew String(devices[iPtr].path), gcnew String(devices[iPtr].comm));
162
163 delete devices;
164 delete context;
165 return adapters;
166 }
167
e3aabeac
LOK
168 /// <summary>
169 /// Open a connection to the CEC adapter.
170 /// </summary>
171 /// <param name="strPort">The COM port of the adapter</param>
172 /// <param name="iTimeoutMs">Connection timeout in milliseconds</param>
173 /// <returns>True when a connection was opened, false otherwise.</returns>
4ef3b314
LOK
174 bool Open(String ^ strPort, int iTimeoutMs)
175 {
11fea069
LOK
176 CecCallbackMethods::EnableCallbacks(m_callbacks);
177 EnableCallbacks(m_callbacks);
4ef3b314
LOK
178 marshal_context ^ context = gcnew marshal_context();
179 const char* strPortC = context->marshal_as<const char*>(strPort);
180 bool bReturn = m_libCec->Open(strPortC, iTimeoutMs);
181 delete context;
182 return bReturn;
183 }
184
e3aabeac
LOK
185 /// <summary>
186 /// Close the connection to the CEC adapter
187 /// </summary>
4ef3b314 188 void Close(void)
8670c970
LOK
189 {
190 DisableCallbacks();
191 m_libCec->Close();
192 }
193
e3aabeac
LOK
194 /// <summary>
195 /// Disable all calls to callback methods.
196 /// </summary>
8670c970 197 virtual void DisableCallbacks(void) override
4ef3b314 198 {
7e24a7d2 199 // delete the callbacks, since these might already have been destroyed in .NET
dae4328c 200 CecCallbackMethods::DisableCallbacks();
8670c970
LOK
201 if (m_libCec)
202 m_libCec->EnableCallbacks(NULL, NULL);
4ef3b314
LOK
203 }
204
e3aabeac
LOK
205 /// <summary>
206 /// Enable or change the callback methods that libCEC uses to send changes to the client application.
207 /// </summary>
208 /// <param name="callbacks">The new callback methods to use.</param>
209 /// <returns>True when the callbacks were changed, false otherwise</returns>
4ef3b314
LOK
210 virtual bool EnableCallbacks(CecCallbackMethods ^ callbacks) override
211 {
212 if (m_libCec && CecCallbackMethods::EnableCallbacks(callbacks))
dc6366e8 213 return m_libCec->EnableCallbacks((void*)GetCallbackPtr(), &g_cecCallbacks);
4ef3b314
LOK
214
215 return false;
216 }
217
e3aabeac
LOK
218 /// <summary>
219 /// Sends a ping command to the adapter, to check if it's responding.
220 /// </summary>
221 /// <returns>True when the ping was succesful, false otherwise</returns>
4ef3b314
LOK
222 bool PingAdapter(void)
223 {
224 return m_libCec->PingAdapter();
225 }
226
e3aabeac
LOK
227 /// <summary>
228 /// Start the bootloader of the CEC adapter. Closes the connection when successful.
229 /// </summary>
230 /// <returns>True when the command was sent successfully, false otherwise.</returns>
4ef3b314
LOK
231 bool StartBootloader(void)
232 {
233 return m_libCec->StartBootloader();
234 }
235
e3aabeac
LOK
236 /// <summary>
237 /// Get the minimal version of libCEC that this version of libCEC can interface with.
238 /// </summary>
239 /// <remarks>Deprecated: use LibCECConfiguration instead</remarks>
240 /// <returns>The minimal version</returns>
4ef3b314
LOK
241 int GetMinLibVersion(void)
242 {
243 return m_libCec->GetMinLibVersion();
244 }
245
e3aabeac
LOK
246 /// <summary>
247 /// Get the major version of libCEC.
248 /// </summary>
249 /// <remarks>Deprecated: use LibCECConfiguration instead</remarks>
250 /// <returns>The major version</returns>
4ef3b314
LOK
251 int GetLibVersionMajor(void)
252 {
253 return m_libCec->GetLibVersionMajor();
254 }
255
e3aabeac
LOK
256 /// <summary>
257 /// Get the minor version of libCEC.
258 /// </summary>
259 /// <remarks>Deprecated: use LibCECConfiguration instead</remarks>
260 /// <returns>The minor version</returns>
4ef3b314
LOK
261 int GetLibVersionMinor(void)
262 {
263 return m_libCec->GetLibVersionMinor();
264 }
265
e3aabeac
LOK
266 /// <summary>
267 /// Get the next log message from the buffer, if there is one.
268 /// </summary>
269 /// <remarks>Deprecated: use callback methods instead</remarks>
270 /// <returns>The next log message in the buffer, or an empty message if there is none</returns>
4ef3b314
LOK
271 CecLogMessage ^ GetNextLogMessage(void)
272 {
273 cec_log_message msg;
274 if (m_libCec->GetNextLogMessage(&msg))
275 {
276 return gcnew CecLogMessage(gcnew String(msg.message), (CecLogLevel)msg.level, msg.time);
277 }
278
279 return gcnew CecLogMessage();
280 }
281
e3aabeac
LOK
282 /// <summary>
283 /// Get the next keypress from the buffer, if there is one.
284 /// </summary>
285 /// <remarks>Deprecated: use callback methods instead</remarks>
286 /// <returns>The next keypress in the buffer, or an empty keypress if there is none</returns>
4ef3b314
LOK
287 CecKeypress ^ GetNextKeypress(void)
288 {
289 cec_keypress key;
290 if (m_libCec->GetNextKeypress(&key))
291 {
04be3a97 292 return gcnew CecKeypress((CecUserControlCode)key.keycode, key.duration);
4ef3b314
LOK
293 }
294
295 return gcnew CecKeypress();
296 }
297
e3aabeac
LOK
298 /// <summary>
299 /// Get the next CEC command that was received from the buffer, if there is one.
300 /// </summary>
301 /// <remarks>Deprecated: use callback methods instead</remarks>
302 /// <returns>The next CEC command in the buffer, or an empty CEC command if there is none</returns>
4ef3b314
LOK
303 CecCommand ^ GetNextCommand(void)
304 {
305 cec_command command;
306 if (m_libCec->GetNextCommand(&command))
307 {
308 CecCommand ^ retVal = gcnew CecCommand((CecLogicalAddress)command.initiator, (CecLogicalAddress)command.destination, command.ack == 1 ? true : false, command.eom == 1 ? true : false, (CecOpcode)command.opcode, command.transmit_timeout);
309 for (uint8_t iPtr = 0; iPtr < command.parameters.size; iPtr++)
310 retVal->Parameters->PushBack(command.parameters[iPtr]);
311 return retVal;
312 }
313
314 return gcnew CecCommand();
315 }
316
e3aabeac
LOK
317 /// <summary>
318 /// Transmit a raw CEC command over the CEC line.
319 /// </summary>
320 /// <param name="command">The command to transmit</param>
321 /// <returns>True when the data was sent and acked, false otherwise.</returns>
4ef3b314
LOK
322 bool Transmit(CecCommand ^ command)
323 {
324 cec_command ccommand;
325 cec_command::Format(ccommand, (cec_logical_address)command->Initiator, (cec_logical_address)command->Destination, (cec_opcode)command->Opcode);
326 ccommand.transmit_timeout = command->TransmitTimeout;
327 ccommand.eom = command->Eom;
328 ccommand.ack = command->Ack;
329 for (unsigned int iPtr = 0; iPtr < command->Parameters->Size; iPtr++)
330 ccommand.parameters.PushBack(command->Parameters->Data[iPtr]);
331
332 return m_libCec->Transmit(ccommand);
333 }
334
e3aabeac
LOK
335 /// <summary>
336 /// Change the logical address on the CEC bus of the CEC adapter. libCEC automatically assigns a logical address, and this method is only available for debugging purposes.
337 /// </summary>
338 /// <param name="logicalAddress">The CEC adapter's new logical address.</param>
339 /// <returns>True when the logical address was set successfully, false otherwise.</returns>
4ef3b314
LOK
340 bool SetLogicalAddress(CecLogicalAddress logicalAddress)
341 {
342 return m_libCec->SetLogicalAddress((cec_logical_address) logicalAddress);
343 }
344
e3aabeac
LOK
345 /// <summary>
346 /// Change the physical address (HDMI port) of the CEC adapter. libCEC will try to autodetect the physical address when connecting. If it did, it's set in libcec_configuration.
347 /// </summary>
348 /// <param name="physicalAddress">The CEC adapter's new physical address.</param>
349 /// <returns>True when the physical address was set successfully, false otherwise.</returns>
006b76b9 350 bool SetPhysicalAddress(uint16_t physicalAddress)
4ef3b314
LOK
351 {
352 return m_libCec->SetPhysicalAddress(physicalAddress);
353 }
354
e3aabeac
LOK
355 /// <summary>
356 /// Power on the given CEC capable devices. If CECDEVICE_BROADCAST is used, then wakeDevice in libcec_configuration will be used.
357 /// </summary>
358 /// <param name="logicalAddress">The logical address to power on.</param>
359 /// <returns>True when the command was sent succesfully, false otherwise.</returns>
4ef3b314
LOK
360 bool PowerOnDevices(CecLogicalAddress logicalAddress)
361 {
362 return m_libCec->PowerOnDevices((cec_logical_address) logicalAddress);
363 }
364
e3aabeac
LOK
365 /// <summary>
366 /// Put the given CEC capable devices in standby mode. If CECDEVICE_BROADCAST is used, then standbyDevices in libcec_configuration will be used.
367 /// </summary>
368 /// <param name="logicalAddress">The logical address of the device to put in standby.</param>
369 /// <returns>True when the command was sent succesfully, false otherwise.</returns>
4ef3b314
LOK
370 bool StandbyDevices(CecLogicalAddress logicalAddress)
371 {
372 return m_libCec->StandbyDevices((cec_logical_address) logicalAddress);
373 }
374
e3aabeac
LOK
375 /// <summary>
376 /// Sends a POLL message to a device, to check if it's present and responding.
377 /// </summary>
378 /// <param name="logicalAddress">The device to send the message to.</param>
379 /// <returns>True if the POLL was acked, false otherwise.</returns>
4ef3b314
LOK
380 bool PollDevice(CecLogicalAddress logicalAddress)
381 {
382 return m_libCec->PollDevice((cec_logical_address) logicalAddress);
383 }
384
e3aabeac
LOK
385 /// <summary>
386 /// Change the active source to a device type handled by libCEC. Use CEC_DEVICE_TYPE_RESERVED to make the default type used by libCEC active.
387 /// </summary>
388 /// <param name="type">The new active source. Use CEC_DEVICE_TYPE_RESERVED to use the primary type</param>
389 /// <returns>True when the command was sent succesfully, false otherwise.</returns>
4ef3b314
LOK
390 bool SetActiveSource(CecDeviceType type)
391 {
392 return m_libCec->SetActiveSource((cec_device_type) type);
393 }
394
e3aabeac
LOK
395 /// <summary>
396 /// Change the deck control mode, if this adapter is registered as playback or recording device.
397 /// </summary>
398 /// <param name="mode">The new control mode.</param>
399 /// <param name="sendUpdate">True to send the new status over the CEC line.</param>
400 /// <returns>True if set, false otherwise.</returns>
4ef3b314
LOK
401 bool SetDeckControlMode(CecDeckControlMode mode, bool sendUpdate)
402 {
403 return m_libCec->SetDeckControlMode((cec_deck_control_mode) mode, sendUpdate);
404 }
405
e3aabeac
LOK
406 /// <summary>
407 /// Change the deck info, if this adapter is a playback or recording device.
408 /// </summary>
409 /// <param name="info">The new deck info.</param>
410 /// <param name="sendUpdate">True to send the new status over the CEC line.</param>
411 /// <returns>True if set, false otherwise.</returns>
4ef3b314
LOK
412 bool SetDeckInfo(CecDeckInfo info, bool sendUpdate)
413 {
414 return m_libCec->SetDeckInfo((cec_deck_info) info, sendUpdate);
415 }
416
e3aabeac
LOK
417 /// <summary>
418 /// Broadcast a message that notifies connected CEC capable devices that this device is no longer the active source.
419 /// </summary>
420 /// <returns>True when the command was sent succesfully, false otherwise.</returns>
4ef3b314
LOK
421 bool SetInactiveView(void)
422 {
423 return m_libCec->SetInactiveView();
424 }
425
e3aabeac
LOK
426 /// <summary>
427 /// Change the menu state. This value is already changed by libCEC automatically if a device is (de)activated.
428 /// </summary>
429 /// <param name="state">The new state.</param>
430 /// <param name="sendUpdate">True to send the new status over the CEC line.</param>
431 /// <returns>True if set, false otherwise.</returns>
4ef3b314
LOK
432 bool SetMenuState(CecMenuState state, bool sendUpdate)
433 {
434 return m_libCec->SetMenuState((cec_menu_state) state, sendUpdate);
435 }
436
e3aabeac
LOK
437 /// <summary>
438 /// Display a message on the device with the given logical address. Not supported by most TVs.
439 /// </summary>
440 /// <param name="logicalAddress">The logical address of the device to display the message on.</param>
441 /// <param name="duration">The duration of the message</param>
442 /// <param name="message">The message to display.</param>
443 /// <returns>True when the command was sent, false otherwise.</returns>
4ef3b314
LOK
444 bool SetOSDString(CecLogicalAddress logicalAddress, CecDisplayControl duration, String ^ message)
445 {
446 marshal_context ^ context = gcnew marshal_context();
447 const char* strMessageC = context->marshal_as<const char*>(message);
448
449 bool bReturn = m_libCec->SetOSDString((cec_logical_address) logicalAddress, (cec_display_control) duration, strMessageC);
450
451 delete context;
452 return bReturn;
453 }
454
e3aabeac
LOK
455 /// <summary>
456 /// Enable or disable monitoring mode, for debugging purposes. If monitoring mode is enabled, libCEC won't respond to any command, but only log incoming data.
457 /// </summary>
458 /// <param name="enable">True to enable, false to disable.</param>
459 /// <returns>True when switched successfully, false otherwise.</returns>
4ef3b314
LOK
460 bool SwitchMonitoring(bool enable)
461 {
462 return m_libCec->SwitchMonitoring(enable);
463 }
464
e3aabeac
LOK
465 /// <summary>
466 /// Get the CEC version of the device with the given logical address
467 /// </summary>
468 /// <param name="logicalAddress">The logical address of the device to get the CEC version for.</param>
469 /// <returns>The version or CEC_VERSION_UNKNOWN when the version couldn't be fetched.</returns>
4ef3b314
LOK
470 CecVersion GetDeviceCecVersion(CecLogicalAddress logicalAddress)
471 {
472 return (CecVersion) m_libCec->GetDeviceCecVersion((cec_logical_address) logicalAddress);
473 }
474
e3aabeac
LOK
475 /// <summary>
476 /// Get the menu language of the device with the given logical address
477 /// </summary>
478 /// <param name="logicalAddress">The logical address of the device to get the menu language for.</param>
479 /// <returns>The requested menu language.</returns>
4ef3b314
LOK
480 String ^ GetDeviceMenuLanguage(CecLogicalAddress logicalAddress)
481 {
482 cec_menu_language lang;
483 if (m_libCec->GetDeviceMenuLanguage((cec_logical_address) logicalAddress, &lang))
484 {
485 return gcnew String(lang.language);
486 }
487
488 return gcnew String("");
489 }
490
e3aabeac
LOK
491 /// <summary>
492 /// Get the vendor ID of the device with the given logical address.
493 /// </summary>
494 /// <param name="logicalAddress">The logical address of the device to get the vendor ID for.</param>
495 /// <returns>The vendor ID or 0 if it wasn't found.</returns>
4ef3b314
LOK
496 CecVendorId GetDeviceVendorId(CecLogicalAddress logicalAddress)
497 {
498 return (CecVendorId)m_libCec->GetDeviceVendorId((cec_logical_address) logicalAddress);
499 }
500
e3aabeac
LOK
501 /// <summary>
502 /// Get the power status of the device with the given logical address.
503 /// </summary>
504 /// <param name="logicalAddress">The logical address of the device to get the power status for.</param>
505 /// <returns>The power status or CEC_POWER_STATUS_UNKNOWN if it wasn't found.</returns>
4ef3b314
LOK
506 CecPowerStatus GetDevicePowerStatus(CecLogicalAddress logicalAddress)
507 {
508 return (CecPowerStatus) m_libCec->GetDevicePowerStatus((cec_logical_address) logicalAddress);
509 }
510
e3aabeac
LOK
511 /// <summary>
512 /// Tell libCEC to poll for active devices on the bus.
513 /// </summary>
3efda01a
LOK
514 void RescanActiveDevices(void)
515 {
516 m_libCec->RescanActiveDevices();
517 }
518
e3aabeac
LOK
519 /// <summary>
520 /// Get the logical addresses of the devices that are active on the bus, including those handled by libCEC.
521 /// </summary>
522 /// <returns>The logical addresses of the active devices</returns>
4ef3b314
LOK
523 CecLogicalAddresses ^ GetActiveDevices(void)
524 {
525 CecLogicalAddresses ^ retVal = gcnew CecLogicalAddresses();
526 unsigned int iDevices = 0;
527
528 cec_logical_addresses activeDevices = m_libCec->GetActiveDevices();
529
530 for (uint8_t iPtr = 0; iPtr < 16; iPtr++)
531 if (activeDevices[iPtr])
532 retVal->Addresses[iDevices++] = (CecLogicalAddress)iPtr;
533
534 return retVal;
535 }
536
e3aabeac
LOK
537 /// <summary>
538 /// Check whether a device is active on the bus.
539 /// </summary>
540 /// <param name="logicalAddress">The address to check.</param>
541 /// <returns>True when active, false otherwise.</returns>
4ef3b314
LOK
542 bool IsActiveDevice(CecLogicalAddress logicalAddress)
543 {
544 return m_libCec->IsActiveDevice((cec_logical_address)logicalAddress);
545 }
546
e3aabeac
LOK
547 /// <summary>
548 /// Check whether a device of the given type is active on the bus.
549 /// </summary>
550 /// <param name="type">The type to check.</param>
551 /// <returns>True when active, false otherwise.</returns>
4ef3b314
LOK
552 bool IsActiveDeviceType(CecDeviceType type)
553 {
554 return m_libCec->IsActiveDeviceType((cec_device_type)type);
555 }
556
e3aabeac
LOK
557 /// <summary>
558 /// Changes the active HDMI port.
559 /// </summary>
560 /// <param name="address">The device to which this libCEC is connected.</param>
561 /// <param name="port">The new port number.</param>
562 /// <returns>True when changed, false otherwise.</returns>
4ef3b314
LOK
563 bool SetHDMIPort(CecLogicalAddress address, uint8_t port)
564 {
565 return m_libCec->SetHDMIPort((cec_logical_address)address, port);
566 }
567
e3aabeac
LOK
568 /// <summary>
569 /// Sends a volume up keypress to an audiosystem if it's present.
570 /// </summary>
571 /// <param name="sendRelease">Send a key release after the keypress.</param>
572 /// <returns>The new audio status.</returns>
573 uint8_t VolumeUp(bool sendRelease)
4ef3b314 574 {
e3aabeac 575 return m_libCec->VolumeUp(sendRelease);
4ef3b314
LOK
576 }
577
e3aabeac
LOK
578 /// <summary>
579 /// Sends a volume down keypress to an audiosystem if it's present.
580 /// </summary>
581 /// <param name="sendRelease">Send a key release after the keypress.</param>
582 /// <returns>The new audio status.</returns>
583 uint8_t VolumeDown(bool sendRelease)
4ef3b314 584 {
e3aabeac 585 return m_libCec->VolumeDown(sendRelease);
4ef3b314
LOK
586 }
587
e3aabeac
LOK
588 /// <summary>
589 /// Sends a mute keypress to an audiosystem if it's present.
590 /// </summary>
591 /// <param name="sendRelease">Send a key release after the keypress.</param>
592 /// <returns>The new audio status.</returns>
593 uint8_t MuteAudio(bool sendRelease)
4ef3b314 594 {
e3aabeac 595 return m_libCec->MuteAudio(sendRelease);
4ef3b314
LOK
596 }
597
e3aabeac
LOK
598 /// <summary>
599 /// Send a keypress to a device on the CEC bus.
600 /// </summary>
601 /// <param name="destination">The logical address of the device to send the message to.</param>
602 /// <param name="key">The key to send.</param>
603 /// <param name="wait">True to wait for a response, false otherwise.</param>
604 /// <returns>True when the keypress was acked, false otherwise.</returns>
4ef3b314
LOK
605 bool SendKeypress(CecLogicalAddress destination, CecUserControlCode key, bool wait)
606 {
607 return m_libCec->SendKeypress((cec_logical_address)destination, (cec_user_control_code)key, wait);
608 }
609
e3aabeac
LOK
610 /// <summary>
611 /// Send a key release to a device on the CEC bus.
612 /// </summary>
613 /// <param name="destination">The logical address of the device to send the message to.</param>
614 /// <param name="wait">True to wait for a response, false otherwise.</param>
615 /// <returns>True when the key release was acked, false otherwise.</returns>
4ef3b314
LOK
616 bool SendKeyRelease(CecLogicalAddress destination, bool wait)
617 {
618 return m_libCec->SendKeyRelease((cec_logical_address)destination, wait);
619 }
620
e3aabeac
LOK
621 /// <summary>
622 /// Get the OSD name of a device on the CEC bus.
623 /// </summary>
624 /// <param name="logicalAddress">The logical address of the device to get the OSD name for.</param>
625 /// <returns>The OSD name.</returns>
4ef3b314
LOK
626 String ^ GetDeviceOSDName(CecLogicalAddress logicalAddress)
627 {
628 cec_osd_name osd = m_libCec->GetDeviceOSDName((cec_logical_address) logicalAddress);
629 return gcnew String(osd.name);
630 }
631
e3aabeac
LOK
632 /// <summary>
633 /// Get the logical address of the device that is currently the active source on the CEC bus.
634 /// </summary>
635 /// <returns>The active source or CECDEVICE_UNKNOWN when unknown.</returns>
4ef3b314
LOK
636 CecLogicalAddress GetActiveSource()
637 {
638 return (CecLogicalAddress)m_libCec->GetActiveSource();
639 }
640
e3aabeac
LOK
641 /// <summary>
642 /// Check whether a device is currently the active source on the CEC bus.
643 /// </summary>
644 /// <param name="logicalAddress">The logical address of the device to check.</param>
645 /// <returns>True when it is the active source, false otherwise.</returns>
4ef3b314
LOK
646 bool IsActiveSource(CecLogicalAddress logicalAddress)
647 {
648 return m_libCec->IsActiveSource((cec_logical_address)logicalAddress);
649 }
650
e3aabeac
LOK
651 /// <summary>
652 /// Get the physical address of the device with the given logical address.
653 /// </summary>
654 /// <param name="address">The logical address of the device to get the physical address for.</param>
655 /// <returns>The physical address or 0 if it wasn't found.</returns>
656 uint16_t GetDevicePhysicalAddress(CecLogicalAddress address)
4ef3b314 657 {
e3aabeac 658 return m_libCec->GetDevicePhysicalAddress((cec_logical_address)address);
4ef3b314
LOK
659 }
660
e3aabeac
LOK
661 /// <summary>
662 /// Sets the stream path to the device on the given logical address.
663 /// </summary>
664 /// <param name="address">The address to activate.</param>
665 /// <returns>True when the command was sent, false otherwise.</returns>
666 bool SetStreamPath(CecLogicalAddress address)
a9fb46b4 667 {
e3aabeac 668 return m_libCec->SetStreamPath((cec_logical_address)address);
a9fb46b4
LOK
669 }
670
e3aabeac
LOK
671 /// <summary>
672 /// Sets the stream path to the device on the given physical address.
673 /// </summary>
674 /// <param name="physicalAddress">The address to activate.</param>
675 /// <returns>True when the command was sent, false otherwise.</returns>
676 bool SetStreamPath(uint16_t physicalAddress)
a9fb46b4 677 {
e3aabeac 678 return m_libCec->SetStreamPath(physicalAddress);
a9fb46b4
LOK
679 }
680
e3aabeac
LOK
681 /// <summary>
682 /// Get the list of logical addresses that libCEC is controlling
683 /// </summary>
684 /// <returns>The list of logical addresses that libCEC is controlling</returns>
a9fb46b4
LOK
685 CecLogicalAddresses ^GetLogicalAddresses(void)
686 {
687 CecLogicalAddresses ^addr = gcnew CecLogicalAddresses();
688 cec_logical_addresses libAddr = m_libCec->GetLogicalAddresses();
689 for (unsigned int iPtr = 0; iPtr < 16; iPtr++)
690 addr->Addresses[iPtr] = (CecLogicalAddress)libAddr.addresses[iPtr];
691 addr->Primary = (CecLogicalAddress)libAddr.primary;
692 return addr;
693 }
694
e3aabeac
LOK
695 /// <summary>
696 /// Get libCEC's current configuration.
697 /// </summary>
698 /// <param name="configuration">The configuration.</param>
699 /// <returns>True when the configuration was updated, false otherwise.</returns>
5085a852
LOK
700 bool GetCurrentConfiguration(LibCECConfiguration ^configuration)
701 {
702 libcec_configuration config;
006b76b9
LOK
703 config.Clear();
704
5085a852
LOK
705 if (m_libCec->GetCurrentConfiguration(&config))
706 {
3efda01a 707 configuration->Update(config);
5085a852
LOK
708 return true;
709 }
710 return false;
711 }
712
e3aabeac
LOK
713 /// <summary>
714 /// Check whether the CEC adapter can persist a configuration.
715 /// </summary>
716 /// <returns>True when this CEC adapter can persist the user configuration, false otherwise.</returns>
5085a852
LOK
717 bool CanPersistConfiguration(void)
718 {
719 return m_libCec->CanPersistConfiguration();
720 }
721
e3aabeac
LOK
722 /// <summary>
723 /// Persist the given configuration in adapter (if supported)
724 /// </summary>
725 /// <param name="configuration">The configuration to store.</param>
726 /// <returns>True when the configuration was persisted, false otherwise.</returns>
5085a852
LOK
727 bool PersistConfiguration(LibCECConfiguration ^configuration)
728 {
729 marshal_context ^ context = gcnew marshal_context();
730 libcec_configuration config;
32403cc3 731 ConvertConfiguration(context, configuration, config);
5085a852
LOK
732
733 bool bReturn = m_libCec->PersistConfiguration(&config);
734
735 delete context;
736 return bReturn;
737 }
738
e3aabeac
LOK
739 /// <summary>
740 /// Change libCEC's configuration.
741 /// </summary>
742 /// <param name="configuration">The new configuration.</param>
743 /// <returns>True when the configuration was changed successfully, false otherwise.</returns>
32403cc3
LOK
744 bool SetConfiguration(LibCECConfiguration ^configuration)
745 {
746 marshal_context ^ context = gcnew marshal_context();
747 libcec_configuration config;
748 ConvertConfiguration(context, configuration, config);
749
750 bool bReturn = m_libCec->SetConfiguration(&config);
751
752 delete context;
753 return bReturn;
754 }
755
e3aabeac
LOK
756 /// <summary>
757 /// Check whether libCEC is the active source on the bus.
758 /// </summary>
759 /// <returns>True when libCEC is the active source on the bus, false otherwise.</returns>
bd624ba8
LOK
760 bool IsLibCECActiveSource()
761 {
762 return m_libCec->IsLibCECActiveSource();
763 }
764
e3aabeac
LOK
765 /// <summary>
766 /// Get information about the given CEC adapter.
767 /// </summary>
768 /// <param name="port">The COM port to which the device is connected</param>
769 /// <param name="configuration">The device configuration</param>
770 /// <param name="timeoutMs">The timeout in milliseconds</param>
771 /// <returns>True when the device was found, false otherwise</returns>
bd624ba8
LOK
772 bool GetDeviceInformation(String ^ port, LibCECConfiguration ^configuration, uint32_t timeoutMs)
773 {
774 bool bReturn(false);
775 marshal_context ^ context = gcnew marshal_context();
776
777 libcec_configuration config;
778 config.Clear();
779
780 const char* strPortC = port->Length > 0 ? context->marshal_as<const char*>(port) : NULL;
781
782 if (m_libCec->GetDeviceInformation(strPortC, &config, timeoutMs))
783 {
784 configuration->Update(config);
785 bReturn = true;
786 }
787
788 delete context;
789 return bReturn;
790 }
791
4ef3b314
LOK
792 String ^ ToString(CecLogicalAddress iAddress)
793 {
794 const char *retVal = m_libCec->ToString((cec_logical_address)iAddress);
795 return gcnew String(retVal);
796 }
797
798 String ^ ToString(CecVendorId iVendorId)
799 {
800 const char *retVal = m_libCec->ToString((cec_vendor_id)iVendorId);
801 return gcnew String(retVal);
802 }
e3aabeac 803
4ef3b314
LOK
804 String ^ ToString(CecVersion iVersion)
805 {
806 const char *retVal = m_libCec->ToString((cec_version)iVersion);
807 return gcnew String(retVal);
808 }
e3aabeac 809
4ef3b314
LOK
810 String ^ ToString(CecPowerStatus iState)
811 {
812 const char *retVal = m_libCec->ToString((cec_power_status)iState);
813 return gcnew String(retVal);
814 }
815
816 String ^ ToString(CecMenuState iState)
817 {
818 const char *retVal = m_libCec->ToString((cec_menu_state)iState);
819 return gcnew String(retVal);
820 }
821
822 String ^ ToString(CecDeckControlMode iMode)
823 {
824 const char *retVal = m_libCec->ToString((cec_deck_control_mode)iMode);
825 return gcnew String(retVal);
826 }
827
828 String ^ ToString(CecDeckInfo status)
829 {
830 const char *retVal = m_libCec->ToString((cec_deck_info)status);
831 return gcnew String(retVal);
832 }
833
834 String ^ ToString(CecOpcode opcode)
835 {
836 const char *retVal = m_libCec->ToString((cec_opcode)opcode);
837 return gcnew String(retVal);
838 }
839
840 String ^ ToString(CecSystemAudioStatus mode)
841 {
842 const char *retVal = m_libCec->ToString((cec_system_audio_status)mode);
843 return gcnew String(retVal);
844 }
845
846 String ^ ToString(CecAudioStatus status)
847 {
848 const char *retVal = m_libCec->ToString((cec_audio_status)status);
849 return gcnew String(retVal);
850 }
851
3efda01a
LOK
852 String ^ ToString(CecClientVersion version)
853 {
854 const char *retVal = m_libCec->ToString((cec_client_version)version);
855 return gcnew String(retVal);
856 }
857
858 String ^ ToString(CecServerVersion version)
859 {
860 const char *retVal = m_libCec->ToString((cec_server_version)version);
861 return gcnew String(retVal);
862 }
863
e3aabeac
LOK
864 /// <summary>
865 /// Get a string with information about how libCEC was compiled.
866 /// </summary>
867 /// <returns>A string with information about how libCEC was compiled.</returns>
2b44051c
LOK
868 String ^ GetLibInfo()
869 {
870 const char *retVal = m_libCec->GetLibInfo();
871 return gcnew String(retVal);
872 }
873
e3aabeac
LOK
874 /// <summary>
875 /// Calling this method will initialise the host on which libCEC is running.
876 /// On the RPi, it calls bcm_host_init(), which may only be called once per process, and is called by any process using
877 /// the video api on that system. So only call this method if libCEC is used in an application that
878 /// does not already initialise the video api.
879 /// </summary>
880 /// <remarks>Should be called as first call to libCEC, directly after CECInitialise() and before using Open()</remarks>
63a0b02b
LOK
881 void InitVideoStandalone()
882 {
883 m_libCec->InitVideoStandalone();
884 }
885
4ef3b314
LOK
886 private:
887 ICECAdapter * m_libCec;
11fea069 888 CecCallbackMethods ^ m_callbacks;
4ef3b314 889 };
0cac9547 890}