2 * This file is part of the libCEC(R) library.
4 * libCEC(R) is Copyright (C) 2011-2012 Pulse-Eight Limited. All rights reserved.
5 * libCEC(R) is an original work, containing original code.
7 * libCEC(R) is a trademark of Pulse-Eight Limited.
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.
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.
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.
24 * Alternatively, you can license this library under a commercial license,
25 * please contact Pulse-Eight Licensing for more information.
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/
33 #include "CecSharpTypes.h"
36 using namespace System
;
37 using namespace System::Runtime::InteropServices
;
39 using namespace msclr::interop
;
43 public ref
class LibCecSharp
: public CecCallbackMethods
46 LibCecSharp(LibCECConfiguration
^config
)
48 m_callbacks
= config
->Callbacks
;
49 CecCallbackMethods::EnableCallbacks(m_callbacks
);
50 if (!InitialiseLibCec(config
))
51 throw gcnew
Exception("Could not initialise LibCecSharp");
54 LibCecSharp(String
^ strDeviceName
, CecDeviceTypeList
^ deviceTypes
)
56 m_callbacks
= gcnew
CecCallbackMethods();
57 LibCECConfiguration
^config
= gcnew
LibCECConfiguration();
58 config
->SetCallbacks(this);
59 config
->DeviceName
= strDeviceName
;
60 config
->DeviceTypes
= deviceTypes
;
61 if (!InitialiseLibCec(config
))
62 throw gcnew
Exception("Could not initialise LibCecSharp");
78 bool InitialiseLibCec(LibCECConfiguration
^config
)
80 marshal_context
^ context
= gcnew
marshal_context();
81 libcec_configuration libCecConfig
;
82 ConvertConfiguration(context
, config
, libCecConfig
);
84 m_libCec
= (ICECAdapter
*) CECInitialise(&libCecConfig
);
85 config
->Update(libCecConfig
);
88 return m_libCec
!= NULL
;
91 void ConvertConfiguration(marshal_context
^context
, LibCECConfiguration
^netConfig
, CEC::libcec_configuration
&config
)
95 const char *strDeviceName
= context
->marshal_as
<const char*>(netConfig
->DeviceName
);
96 memcpy_s(config
.strDeviceName
, 13, strDeviceName
, 13);
97 for (unsigned int iPtr
= 0; iPtr
< 5; iPtr
++)
98 config
.deviceTypes
.types
[iPtr
] = (cec_device_type
)netConfig
->DeviceTypes
->Types
[iPtr
];
100 config
.bAutodetectAddress
= netConfig
->AutodetectAddress
? 1 : 0;
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
;
105 config
.bGetSettingsFromROM
= netConfig
->GetSettingsFromROM
? 1 : 0;
106 config
.bActivateSource
= netConfig
->ActivateSource
? 1 : 0;
107 config
.tvVendor
= (cec_vendor_id
)netConfig
->TvVendor
;
108 config
.wakeDevices
.Clear();
109 for (int iPtr
= 0; iPtr
< 16; iPtr
++)
111 if (netConfig
->WakeDevices
->IsSet((CecLogicalAddress
)iPtr
))
112 config
.wakeDevices
.Set((cec_logical_address
)iPtr
);
114 config
.powerOffDevices
.Clear();
115 for (int iPtr
= 0; iPtr
< 16; iPtr
++)
117 if (netConfig
->PowerOffDevices
->IsSet((CecLogicalAddress
)iPtr
))
118 config
.powerOffDevices
.Set((cec_logical_address
)iPtr
);
120 config
.bPowerOffScreensaver
= netConfig
->PowerOffScreensaver
? 1 : 0;
121 config
.bPowerOffOnStandby
= netConfig
->PowerOffOnStandby
? 1 : 0;
123 if (netConfig
->ServerVersion
>= CecServerVersion::Version1_5_1
)
124 config
.bSendInactiveSource
= netConfig
->SendInactiveSource
? 1 : 0;
126 if (netConfig
->ServerVersion
>= CecServerVersion::Version1_6_0
)
128 config
.bPowerOffDevicesOnStandby
= netConfig
->PowerOffDevicesOnStandby
? 1 : 0;
129 config
.bShutdownOnStandby
= netConfig
->ShutdownOnStandby
? 1 : 0;
132 if (netConfig
->ServerVersion
>= CecServerVersion::Version1_6_2
)
134 const char *strDeviceLanguage
= context
->marshal_as
<const char*>(netConfig
->DeviceLanguage
);
135 memcpy_s(config
.strDeviceLanguage
, 3, strDeviceLanguage
, 3);
138 if (netConfig
->ServerVersion
>= CecServerVersion::Version1_6_3
)
139 config
.bMonitorOnly
= netConfig
->MonitorOnlyClient
? 1 : 0;
141 config
.callbacks
= &g_cecCallbacks
;
145 array
<CecAdapter
^> ^ FindAdapters(String
^ path
)
147 cec_adapter
*devices
= new cec_adapter
[10];
149 marshal_context
^ context
= gcnew
marshal_context();
150 const char* strPathC
= path
->Length
> 0 ? context
->marshal_as
<const char*>(path
) : NULL
;
152 uint8_t iDevicesFound
= m_libCec
->FindAdapters(devices
, 10, NULL
);
154 array
<CecAdapter
^> ^ adapters
= gcnew array
<CecAdapter
^>(iDevicesFound
);
155 for (unsigned int iPtr
= 0; iPtr
< iDevicesFound
; iPtr
++)
156 adapters
[iPtr
] = gcnew
CecAdapter(gcnew
String(devices
[iPtr
].path
), gcnew
String(devices
[iPtr
].comm
));
163 bool Open(String
^ strPort
, int iTimeoutMs
)
165 CecCallbackMethods::EnableCallbacks(m_callbacks
);
166 EnableCallbacks(m_callbacks
);
167 marshal_context
^ context
= gcnew
marshal_context();
168 const char* strPortC
= context
->marshal_as
<const char*>(strPort
);
169 bool bReturn
= m_libCec
->Open(strPortC
, iTimeoutMs
);
180 virtual void DisableCallbacks(void) override
182 // delete the callbacks, since these might already have been destroyed in .NET
183 CecCallbackMethods::DisableCallbacks();
185 m_libCec
->EnableCallbacks(NULL
, NULL
);
188 virtual bool EnableCallbacks(CecCallbackMethods
^ callbacks
) override
190 if (m_libCec
&& CecCallbackMethods::EnableCallbacks(callbacks
))
191 return m_libCec
->EnableCallbacks((void*)GetCallbackPtr(), &g_cecCallbacks
);
196 bool PingAdapter(void)
198 return m_libCec
->PingAdapter();
201 bool StartBootloader(void)
203 return m_libCec
->StartBootloader();
206 int GetMinLibVersion(void)
208 return m_libCec
->GetMinLibVersion();
211 int GetLibVersionMajor(void)
213 return m_libCec
->GetLibVersionMajor();
216 int GetLibVersionMinor(void)
218 return m_libCec
->GetLibVersionMinor();
221 CecLogMessage
^ GetNextLogMessage(void)
224 if (m_libCec
->GetNextLogMessage(&msg
))
226 return gcnew
CecLogMessage(gcnew
String(msg
.message
), (CecLogLevel
)msg
.level
, msg
.time
);
229 return gcnew
CecLogMessage();
232 CecKeypress
^ GetNextKeypress(void)
235 if (m_libCec
->GetNextKeypress(&key
))
237 return gcnew
CecKeypress((CecUserControlCode
)key
.keycode
, key
.duration
);
240 return gcnew
CecKeypress();
243 CecCommand
^ GetNextCommand(void)
246 if (m_libCec
->GetNextCommand(&command
))
248 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
);
249 for (uint8_t iPtr
= 0; iPtr
< command
.parameters
.size
; iPtr
++)
250 retVal
->Parameters
->PushBack(command
.parameters
[iPtr
]);
254 return gcnew
CecCommand();
257 bool Transmit(CecCommand
^ command
)
259 cec_command ccommand
;
260 cec_command::Format(ccommand
, (cec_logical_address
)command
->Initiator
, (cec_logical_address
)command
->Destination
, (cec_opcode
)command
->Opcode
);
261 ccommand
.transmit_timeout
= command
->TransmitTimeout
;
262 ccommand
.eom
= command
->Eom
;
263 ccommand
.ack
= command
->Ack
;
264 for (unsigned int iPtr
= 0; iPtr
< command
->Parameters
->Size
; iPtr
++)
265 ccommand
.parameters
.PushBack(command
->Parameters
->Data
[iPtr
]);
267 return m_libCec
->Transmit(ccommand
);
270 bool SetLogicalAddress(CecLogicalAddress logicalAddress
)
272 return m_libCec
->SetLogicalAddress((cec_logical_address
) logicalAddress
);
275 bool SetPhysicalAddress(uint16_t physicalAddress
)
277 return m_libCec
->SetPhysicalAddress(physicalAddress
);
280 bool PowerOnDevices(CecLogicalAddress logicalAddress
)
282 return m_libCec
->PowerOnDevices((cec_logical_address
) logicalAddress
);
285 bool StandbyDevices(CecLogicalAddress logicalAddress
)
287 return m_libCec
->StandbyDevices((cec_logical_address
) logicalAddress
);
290 bool PollDevice(CecLogicalAddress logicalAddress
)
292 return m_libCec
->PollDevice((cec_logical_address
) logicalAddress
);
295 bool SetActiveSource(CecDeviceType type
)
297 return m_libCec
->SetActiveSource((cec_device_type
) type
);
300 bool SetDeckControlMode(CecDeckControlMode mode
, bool sendUpdate
)
302 return m_libCec
->SetDeckControlMode((cec_deck_control_mode
) mode
, sendUpdate
);
305 bool SetDeckInfo(CecDeckInfo info
, bool sendUpdate
)
307 return m_libCec
->SetDeckInfo((cec_deck_info
) info
, sendUpdate
);
310 bool SetInactiveView(void)
312 return m_libCec
->SetInactiveView();
315 bool SetMenuState(CecMenuState state
, bool sendUpdate
)
317 return m_libCec
->SetMenuState((cec_menu_state
) state
, sendUpdate
);
320 bool SetOSDString(CecLogicalAddress logicalAddress
, CecDisplayControl duration
, String
^ message
)
322 marshal_context
^ context
= gcnew
marshal_context();
323 const char* strMessageC
= context
->marshal_as
<const char*>(message
);
325 bool bReturn
= m_libCec
->SetOSDString((cec_logical_address
) logicalAddress
, (cec_display_control
) duration
, strMessageC
);
331 bool SwitchMonitoring(bool enable
)
333 return m_libCec
->SwitchMonitoring(enable
);
336 CecVersion
GetDeviceCecVersion(CecLogicalAddress logicalAddress
)
338 return (CecVersion
) m_libCec
->GetDeviceCecVersion((cec_logical_address
) logicalAddress
);
341 String
^ GetDeviceMenuLanguage(CecLogicalAddress logicalAddress
)
343 cec_menu_language lang
;
344 if (m_libCec
->GetDeviceMenuLanguage((cec_logical_address
) logicalAddress
, &lang
))
346 return gcnew
String(lang
.language
);
349 return gcnew
String("");
352 CecVendorId
GetDeviceVendorId(CecLogicalAddress logicalAddress
)
354 return (CecVendorId
)m_libCec
->GetDeviceVendorId((cec_logical_address
) logicalAddress
);
357 CecPowerStatus
GetDevicePowerStatus(CecLogicalAddress logicalAddress
)
359 return (CecPowerStatus
) m_libCec
->GetDevicePowerStatus((cec_logical_address
) logicalAddress
);
362 void RescanActiveDevices(void)
364 m_libCec
->RescanActiveDevices();
367 CecLogicalAddresses
^ GetActiveDevices(void)
369 CecLogicalAddresses
^ retVal
= gcnew
CecLogicalAddresses();
370 unsigned int iDevices
= 0;
372 cec_logical_addresses activeDevices
= m_libCec
->GetActiveDevices();
374 for (uint8_t iPtr
= 0; iPtr
< 16; iPtr
++)
375 if (activeDevices
[iPtr
])
376 retVal
->Addresses
[iDevices
++] = (CecLogicalAddress
)iPtr
;
381 bool IsActiveDevice(CecLogicalAddress logicalAddress
)
383 return m_libCec
->IsActiveDevice((cec_logical_address
)logicalAddress
);
386 bool IsActiveDeviceType(CecDeviceType type
)
388 return m_libCec
->IsActiveDeviceType((cec_device_type
)type
);
391 bool SetHDMIPort(CecLogicalAddress address
, uint8_t port
)
393 return m_libCec
->SetHDMIPort((cec_logical_address
)address
, port
);
396 uint8_t VolumeUp(bool wait
)
398 return m_libCec
->VolumeUp(wait
);
401 uint8_t VolumeDown(bool wait
)
403 return m_libCec
->VolumeDown(wait
);
406 uint8_t MuteAudio(bool wait
)
408 return m_libCec
->MuteAudio(wait
);
411 bool SendKeypress(CecLogicalAddress destination
, CecUserControlCode key
, bool wait
)
413 return m_libCec
->SendKeypress((cec_logical_address
)destination
, (cec_user_control_code
)key
, wait
);
416 bool SendKeyRelease(CecLogicalAddress destination
, bool wait
)
418 return m_libCec
->SendKeyRelease((cec_logical_address
)destination
, wait
);
421 String
^ GetDeviceOSDName(CecLogicalAddress logicalAddress
)
423 cec_osd_name osd
= m_libCec
->GetDeviceOSDName((cec_logical_address
) logicalAddress
);
424 return gcnew
String(osd
.name
);
427 CecLogicalAddress
GetActiveSource()
429 return (CecLogicalAddress
)m_libCec
->GetActiveSource();
432 bool IsActiveSource(CecLogicalAddress logicalAddress
)
434 return m_libCec
->IsActiveSource((cec_logical_address
)logicalAddress
);
437 uint16_t GetDevicePhysicalAddress(CecLogicalAddress iAddress
)
439 return m_libCec
->GetDevicePhysicalAddress((cec_logical_address
)iAddress
);
442 bool SetStreamPath(CecLogicalAddress iAddress
)
444 return m_libCec
->SetStreamPath((cec_logical_address
)iAddress
);
447 bool SetStreamPath(uint16_t iPhysicalAddress
)
449 return m_libCec
->SetStreamPath(iPhysicalAddress
);
452 CecLogicalAddresses
^GetLogicalAddresses(void)
454 CecLogicalAddresses
^addr
= gcnew
CecLogicalAddresses();
455 cec_logical_addresses libAddr
= m_libCec
->GetLogicalAddresses();
456 for (unsigned int iPtr
= 0; iPtr
< 16; iPtr
++)
457 addr
->Addresses
[iPtr
] = (CecLogicalAddress
)libAddr
.addresses
[iPtr
];
458 addr
->Primary
= (CecLogicalAddress
)libAddr
.primary
;
462 bool GetCurrentConfiguration(LibCECConfiguration
^configuration
)
464 libcec_configuration config
;
467 if (m_libCec
->GetCurrentConfiguration(&config
))
469 configuration
->Update(config
);
475 bool CanPersistConfiguration(void)
477 return m_libCec
->CanPersistConfiguration();
480 bool PersistConfiguration(LibCECConfiguration
^configuration
)
482 marshal_context
^ context
= gcnew
marshal_context();
483 libcec_configuration config
;
484 ConvertConfiguration(context
, configuration
, config
);
486 bool bReturn
= m_libCec
->PersistConfiguration(&config
);
492 bool SetConfiguration(LibCECConfiguration
^configuration
)
494 marshal_context
^ context
= gcnew
marshal_context();
495 libcec_configuration config
;
496 ConvertConfiguration(context
, configuration
, config
);
498 bool bReturn
= m_libCec
->SetConfiguration(&config
);
504 bool IsLibCECActiveSource()
506 return m_libCec
->IsLibCECActiveSource();
509 bool GetDeviceInformation(String
^ port
, LibCECConfiguration
^configuration
, uint32_t timeoutMs
)
512 marshal_context
^ context
= gcnew
marshal_context();
514 libcec_configuration config
;
517 const char* strPortC
= port
->Length
> 0 ? context
->marshal_as
<const char*>(port
) : NULL
;
519 if (m_libCec
->GetDeviceInformation(strPortC
, &config
, timeoutMs
))
521 configuration
->Update(config
);
529 String
^ ToString(CecLogicalAddress iAddress
)
531 const char *retVal
= m_libCec
->ToString((cec_logical_address
)iAddress
);
532 return gcnew
String(retVal
);
535 String
^ ToString(CecVendorId iVendorId
)
537 const char *retVal
= m_libCec
->ToString((cec_vendor_id
)iVendorId
);
538 return gcnew
String(retVal
);
541 String
^ ToString(CecVersion iVersion
)
543 const char *retVal
= m_libCec
->ToString((cec_version
)iVersion
);
544 return gcnew
String(retVal
);
547 String
^ ToString(CecPowerStatus iState
)
549 const char *retVal
= m_libCec
->ToString((cec_power_status
)iState
);
550 return gcnew
String(retVal
);
553 String
^ ToString(CecMenuState iState
)
555 const char *retVal
= m_libCec
->ToString((cec_menu_state
)iState
);
556 return gcnew
String(retVal
);
559 String
^ ToString(CecDeckControlMode iMode
)
561 const char *retVal
= m_libCec
->ToString((cec_deck_control_mode
)iMode
);
562 return gcnew
String(retVal
);
565 String
^ ToString(CecDeckInfo status
)
567 const char *retVal
= m_libCec
->ToString((cec_deck_info
)status
);
568 return gcnew
String(retVal
);
571 String
^ ToString(CecOpcode opcode
)
573 const char *retVal
= m_libCec
->ToString((cec_opcode
)opcode
);
574 return gcnew
String(retVal
);
577 String
^ ToString(CecSystemAudioStatus mode
)
579 const char *retVal
= m_libCec
->ToString((cec_system_audio_status
)mode
);
580 return gcnew
String(retVal
);
583 String
^ ToString(CecAudioStatus status
)
585 const char *retVal
= m_libCec
->ToString((cec_audio_status
)status
);
586 return gcnew
String(retVal
);
589 String
^ ToString(CecClientVersion version
)
591 const char *retVal
= m_libCec
->ToString((cec_client_version
)version
);
592 return gcnew
String(retVal
);
595 String
^ ToString(CecServerVersion version
)
597 const char *retVal
= m_libCec
->ToString((cec_server_version
)version
);
598 return gcnew
String(retVal
);
601 String
^ GetLibInfo()
603 const char *retVal
= m_libCec
->GetLibInfo();
604 return gcnew
String(retVal
);
607 void InitVideoStandalone()
609 m_libCec
->InitVideoStandalone();
613 ICECAdapter
* m_libCec
;
614 CecCallbackMethods
^ m_callbacks
;