cec: added RescanDevices()/cec_rescan_devices() to the interface, to let libCEC force...
[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 {
32403cc3
LOK
48 CecCallbackMethods::EnableCallbacks(config->Callbacks);
49 if (!InitialiseLibCec(config))
41297a45
LOK
50 throw gcnew Exception("Could not initialise LibCecSharp");
51 }
52
4ef3b314 53 LibCecSharp(String ^ strDeviceName, CecDeviceTypeList ^ deviceTypes)
41297a45 54 {
32403cc3
LOK
55 LibCECConfiguration ^config = gcnew LibCECConfiguration();
56 config->SetCallbacks(this);
57 config->DeviceName = strDeviceName;
58 config->DeviceTypes = deviceTypes;
59 if (!InitialiseLibCec(config))
41297a45
LOK
60 throw gcnew Exception("Could not initialise LibCecSharp");
61 }
62
63 ~LibCecSharp(void)
64 {
65 Close();
66 m_libCec = NULL;
67 }
68
69 private:
70 !LibCecSharp(void)
71 {
72 Close();
73 m_libCec = NULL;
74 }
75
32403cc3 76 bool InitialiseLibCec(LibCECConfiguration ^config)
4ef3b314
LOK
77 {
78 marshal_context ^ context = gcnew marshal_context();
32403cc3
LOK
79 libcec_configuration libCecConfig;
80 ConvertConfiguration(context, config, libCecConfig);
4ef3b314 81
32403cc3 82 m_libCec = (ICECAdapter *) CECInitialise(&libCecConfig);
3efda01a
LOK
83 config->Update(libCecConfig);
84
4ef3b314
LOK
85
86 delete context;
41297a45
LOK
87 return m_libCec != NULL;
88 }
89
32403cc3 90 void ConvertConfiguration(marshal_context ^context, LibCECConfiguration ^netConfig, CEC::libcec_configuration &config)
41297a45
LOK
91 {
92 config.Clear();
93
32403cc3 94 _snprintf_s(config.strDeviceName, 13, context->marshal_as<const char*>(netConfig->DeviceName));
41297a45 95 for (unsigned int iPtr = 0; iPtr < 5; iPtr++)
32403cc3 96 config.deviceTypes.types[iPtr] = (cec_device_type)netConfig->DeviceTypes->Types[iPtr];
41297a45 97
8670c970 98 config.bAutodetectAddress = netConfig->AutodetectAddress ? 1 : 0;
32403cc3
LOK
99 config.iPhysicalAddress = netConfig->PhysicalAddress;
100 config.baseDevice = (cec_logical_address)netConfig->BaseDevice;
101 config.iHDMIPort = netConfig->HDMIPort;
102 config.clientVersion = (cec_client_version)netConfig->ClientVersion;
8670c970
LOK
103 config.bGetSettingsFromROM = netConfig->GetSettingsFromROM ? 1 : 0;
104 config.bActivateSource = netConfig->ActivateSource ? 1 : 0;
b7907707
LOK
105 config.tvVendor = (cec_vendor_id)netConfig->TvVendor;
106 config.wakeDevices.Clear();
107 for (int iPtr = 0; iPtr < 16; iPtr++)
108 {
109 if (netConfig->WakeDevices->IsSet((CecLogicalAddress)iPtr))
110 config.wakeDevices.Set((cec_logical_address)iPtr);
111 }
112 config.powerOffDevices.Clear();
113 for (int iPtr = 0; iPtr < 16; iPtr++)
114 {
115 if (netConfig->PowerOffDevices->IsSet((CecLogicalAddress)iPtr))
116 config.powerOffDevices.Set((cec_logical_address)iPtr);
117 }
8670c970
LOK
118 config.bPowerOffScreensaver = netConfig->PowerOffScreensaver ? 1 : 0;
119 config.bPowerOffOnStandby = netConfig->PowerOffOnStandby ? 1 : 0;
32403cc3 120 config.callbacks = &g_cecCallbacks;
4ef3b314 121 }
4ef3b314
LOK
122
123 public:
124 array<CecAdapter ^> ^ FindAdapters(String ^ path)
125 {
126 cec_adapter *devices = new cec_adapter[10];
127
128 marshal_context ^ context = gcnew marshal_context();
129 const char* strPathC = path->Length > 0 ? context->marshal_as<const char*>(path) : NULL;
130
131 uint8_t iDevicesFound = m_libCec->FindAdapters(devices, 10, NULL);
132
133 array<CecAdapter ^> ^ adapters = gcnew array<CecAdapter ^>(iDevicesFound);
134 for (unsigned int iPtr = 0; iPtr < iDevicesFound; iPtr++)
135 adapters[iPtr] = gcnew CecAdapter(gcnew String(devices[iPtr].path), gcnew String(devices[iPtr].comm));
136
137 delete devices;
138 delete context;
139 return adapters;
140 }
141
142 bool Open(String ^ strPort, int iTimeoutMs)
143 {
144 marshal_context ^ context = gcnew marshal_context();
145 const char* strPortC = context->marshal_as<const char*>(strPort);
146 bool bReturn = m_libCec->Open(strPortC, iTimeoutMs);
147 delete context;
148 return bReturn;
149 }
150
151 void Close(void)
8670c970
LOK
152 {
153 DisableCallbacks();
154 m_libCec->Close();
155 }
156
157 virtual void DisableCallbacks(void) override
4ef3b314 158 {
7e24a7d2 159 // delete the callbacks, since these might already have been destroyed in .NET
dae4328c 160 CecCallbackMethods::DisableCallbacks();
8670c970
LOK
161 if (m_libCec)
162 m_libCec->EnableCallbacks(NULL, NULL);
4ef3b314
LOK
163 }
164
165 virtual bool EnableCallbacks(CecCallbackMethods ^ callbacks) override
166 {
167 if (m_libCec && CecCallbackMethods::EnableCallbacks(callbacks))
168 return m_libCec->EnableCallbacks(NULL, &g_cecCallbacks);
169
170 return false;
171 }
172
173 bool PingAdapter(void)
174 {
175 return m_libCec->PingAdapter();
176 }
177
178 bool StartBootloader(void)
179 {
180 return m_libCec->StartBootloader();
181 }
182
183 int GetMinLibVersion(void)
184 {
185 return m_libCec->GetMinLibVersion();
186 }
187
188 int GetLibVersionMajor(void)
189 {
190 return m_libCec->GetLibVersionMajor();
191 }
192
193 int GetLibVersionMinor(void)
194 {
195 return m_libCec->GetLibVersionMinor();
196 }
197
198 CecLogMessage ^ GetNextLogMessage(void)
199 {
200 cec_log_message msg;
201 if (m_libCec->GetNextLogMessage(&msg))
202 {
203 return gcnew CecLogMessage(gcnew String(msg.message), (CecLogLevel)msg.level, msg.time);
204 }
205
206 return gcnew CecLogMessage();
207 }
208
209 CecKeypress ^ GetNextKeypress(void)
210 {
211 cec_keypress key;
212 if (m_libCec->GetNextKeypress(&key))
213 {
214 return gcnew CecKeypress(key.keycode, key.duration);
215 }
216
217 return gcnew CecKeypress();
218 }
219
220 CecCommand ^ GetNextCommand(void)
221 {
222 cec_command command;
223 if (m_libCec->GetNextCommand(&command))
224 {
225 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);
226 for (uint8_t iPtr = 0; iPtr < command.parameters.size; iPtr++)
227 retVal->Parameters->PushBack(command.parameters[iPtr]);
228 return retVal;
229 }
230
231 return gcnew CecCommand();
232 }
233
234 bool Transmit(CecCommand ^ command)
235 {
236 cec_command ccommand;
237 cec_command::Format(ccommand, (cec_logical_address)command->Initiator, (cec_logical_address)command->Destination, (cec_opcode)command->Opcode);
238 ccommand.transmit_timeout = command->TransmitTimeout;
239 ccommand.eom = command->Eom;
240 ccommand.ack = command->Ack;
241 for (unsigned int iPtr = 0; iPtr < command->Parameters->Size; iPtr++)
242 ccommand.parameters.PushBack(command->Parameters->Data[iPtr]);
243
244 return m_libCec->Transmit(ccommand);
245 }
246
247 bool SetLogicalAddress(CecLogicalAddress logicalAddress)
248 {
249 return m_libCec->SetLogicalAddress((cec_logical_address) logicalAddress);
250 }
251
006b76b9 252 bool SetPhysicalAddress(uint16_t physicalAddress)
4ef3b314
LOK
253 {
254 return m_libCec->SetPhysicalAddress(physicalAddress);
255 }
256
257 bool PowerOnDevices(CecLogicalAddress logicalAddress)
258 {
259 return m_libCec->PowerOnDevices((cec_logical_address) logicalAddress);
260 }
261
262 bool StandbyDevices(CecLogicalAddress logicalAddress)
263 {
264 return m_libCec->StandbyDevices((cec_logical_address) logicalAddress);
265 }
266
267 bool PollDevice(CecLogicalAddress logicalAddress)
268 {
269 return m_libCec->PollDevice((cec_logical_address) logicalAddress);
270 }
271
272 bool SetActiveSource(CecDeviceType type)
273 {
274 return m_libCec->SetActiveSource((cec_device_type) type);
275 }
276
277 bool SetDeckControlMode(CecDeckControlMode mode, bool sendUpdate)
278 {
279 return m_libCec->SetDeckControlMode((cec_deck_control_mode) mode, sendUpdate);
280 }
281
282 bool SetDeckInfo(CecDeckInfo info, bool sendUpdate)
283 {
284 return m_libCec->SetDeckInfo((cec_deck_info) info, sendUpdate);
285 }
286
287 bool SetInactiveView(void)
288 {
289 return m_libCec->SetInactiveView();
290 }
291
292 bool SetMenuState(CecMenuState state, bool sendUpdate)
293 {
294 return m_libCec->SetMenuState((cec_menu_state) state, sendUpdate);
295 }
296
297 bool SetOSDString(CecLogicalAddress logicalAddress, CecDisplayControl duration, String ^ message)
298 {
299 marshal_context ^ context = gcnew marshal_context();
300 const char* strMessageC = context->marshal_as<const char*>(message);
301
302 bool bReturn = m_libCec->SetOSDString((cec_logical_address) logicalAddress, (cec_display_control) duration, strMessageC);
303
304 delete context;
305 return bReturn;
306 }
307
308 bool SwitchMonitoring(bool enable)
309 {
310 return m_libCec->SwitchMonitoring(enable);
311 }
312
313 CecVersion GetDeviceCecVersion(CecLogicalAddress logicalAddress)
314 {
315 return (CecVersion) m_libCec->GetDeviceCecVersion((cec_logical_address) logicalAddress);
316 }
317
318 String ^ GetDeviceMenuLanguage(CecLogicalAddress logicalAddress)
319 {
320 cec_menu_language lang;
321 if (m_libCec->GetDeviceMenuLanguage((cec_logical_address) logicalAddress, &lang))
322 {
323 return gcnew String(lang.language);
324 }
325
326 return gcnew String("");
327 }
328
329 CecVendorId GetDeviceVendorId(CecLogicalAddress logicalAddress)
330 {
331 return (CecVendorId)m_libCec->GetDeviceVendorId((cec_logical_address) logicalAddress);
332 }
333
334 CecPowerStatus GetDevicePowerStatus(CecLogicalAddress logicalAddress)
335 {
336 return (CecPowerStatus) m_libCec->GetDevicePowerStatus((cec_logical_address) logicalAddress);
337 }
338
3efda01a
LOK
339 void RescanActiveDevices(void)
340 {
341 m_libCec->RescanActiveDevices();
342 }
343
4ef3b314
LOK
344 CecLogicalAddresses ^ GetActiveDevices(void)
345 {
346 CecLogicalAddresses ^ retVal = gcnew CecLogicalAddresses();
347 unsigned int iDevices = 0;
348
349 cec_logical_addresses activeDevices = m_libCec->GetActiveDevices();
350
351 for (uint8_t iPtr = 0; iPtr < 16; iPtr++)
352 if (activeDevices[iPtr])
353 retVal->Addresses[iDevices++] = (CecLogicalAddress)iPtr;
354
355 return retVal;
356 }
357
358 bool IsActiveDevice(CecLogicalAddress logicalAddress)
359 {
360 return m_libCec->IsActiveDevice((cec_logical_address)logicalAddress);
361 }
362
363 bool IsActiveDeviceType(CecDeviceType type)
364 {
365 return m_libCec->IsActiveDeviceType((cec_device_type)type);
366 }
367
368 bool SetHDMIPort(CecLogicalAddress address, uint8_t port)
369 {
370 return m_libCec->SetHDMIPort((cec_logical_address)address, port);
371 }
372
373 uint8_t VolumeUp(bool wait)
374 {
375 return m_libCec->VolumeUp(wait);
376 }
377
378 uint8_t VolumeDown(bool wait)
379 {
380 return m_libCec->VolumeDown(wait);
381 }
382
383 uint8_t MuteAudio(bool wait)
384 {
385 return m_libCec->MuteAudio(wait);
386 }
387
388 bool SendKeypress(CecLogicalAddress destination, CecUserControlCode key, bool wait)
389 {
390 return m_libCec->SendKeypress((cec_logical_address)destination, (cec_user_control_code)key, wait);
391 }
392
393 bool SendKeyRelease(CecLogicalAddress destination, bool wait)
394 {
395 return m_libCec->SendKeyRelease((cec_logical_address)destination, wait);
396 }
397
398 String ^ GetDeviceOSDName(CecLogicalAddress logicalAddress)
399 {
400 cec_osd_name osd = m_libCec->GetDeviceOSDName((cec_logical_address) logicalAddress);
401 return gcnew String(osd.name);
402 }
403
404 CecLogicalAddress GetActiveSource()
405 {
406 return (CecLogicalAddress)m_libCec->GetActiveSource();
407 }
408
409 bool IsActiveSource(CecLogicalAddress logicalAddress)
410 {
411 return m_libCec->IsActiveSource((cec_logical_address)logicalAddress);
412 }
413
414 uint16_t GetDevicePhysicalAddress(CecLogicalAddress iAddress)
415 {
416 return m_libCec->GetDevicePhysicalAddress((cec_logical_address)iAddress);
417 }
418
a9fb46b4
LOK
419 bool SetStreamPath(CecLogicalAddress iAddress)
420 {
421 return m_libCec->SetStreamPath((cec_logical_address)iAddress);
422 }
423
424 bool SetStreamPath(uint16_t iPhysicalAddress)
425 {
426 return m_libCec->SetStreamPath(iPhysicalAddress);
427 }
428
429 CecLogicalAddresses ^GetLogicalAddresses(void)
430 {
431 CecLogicalAddresses ^addr = gcnew CecLogicalAddresses();
432 cec_logical_addresses libAddr = m_libCec->GetLogicalAddresses();
433 for (unsigned int iPtr = 0; iPtr < 16; iPtr++)
434 addr->Addresses[iPtr] = (CecLogicalAddress)libAddr.addresses[iPtr];
435 addr->Primary = (CecLogicalAddress)libAddr.primary;
436 return addr;
437 }
438
5085a852
LOK
439 bool GetCurrentConfiguration(LibCECConfiguration ^configuration)
440 {
441 libcec_configuration config;
006b76b9
LOK
442 config.Clear();
443
5085a852
LOK
444 if (m_libCec->GetCurrentConfiguration(&config))
445 {
3efda01a 446 configuration->Update(config);
5085a852
LOK
447 return true;
448 }
449 return false;
450 }
451
452 bool CanPersistConfiguration(void)
453 {
454 return m_libCec->CanPersistConfiguration();
455 }
456
457 bool PersistConfiguration(LibCECConfiguration ^configuration)
458 {
459 marshal_context ^ context = gcnew marshal_context();
460 libcec_configuration config;
32403cc3 461 ConvertConfiguration(context, configuration, config);
5085a852
LOK
462
463 bool bReturn = m_libCec->PersistConfiguration(&config);
464
465 delete context;
466 return bReturn;
467 }
468
32403cc3
LOK
469 bool SetConfiguration(LibCECConfiguration ^configuration)
470 {
471 marshal_context ^ context = gcnew marshal_context();
472 libcec_configuration config;
473 ConvertConfiguration(context, configuration, config);
474
475 bool bReturn = m_libCec->SetConfiguration(&config);
476
477 delete context;
478 return bReturn;
479 }
480
4ef3b314
LOK
481 String ^ ToString(CecLogicalAddress iAddress)
482 {
483 const char *retVal = m_libCec->ToString((cec_logical_address)iAddress);
484 return gcnew String(retVal);
485 }
486
487 String ^ ToString(CecVendorId iVendorId)
488 {
489 const char *retVal = m_libCec->ToString((cec_vendor_id)iVendorId);
490 return gcnew String(retVal);
491 }
492
493 String ^ ToString(CecVersion iVersion)
494 {
495 const char *retVal = m_libCec->ToString((cec_version)iVersion);
496 return gcnew String(retVal);
497 }
498
499 String ^ ToString(CecPowerStatus iState)
500 {
501 const char *retVal = m_libCec->ToString((cec_power_status)iState);
502 return gcnew String(retVal);
503 }
504
505 String ^ ToString(CecMenuState iState)
506 {
507 const char *retVal = m_libCec->ToString((cec_menu_state)iState);
508 return gcnew String(retVal);
509 }
510
511 String ^ ToString(CecDeckControlMode iMode)
512 {
513 const char *retVal = m_libCec->ToString((cec_deck_control_mode)iMode);
514 return gcnew String(retVal);
515 }
516
517 String ^ ToString(CecDeckInfo status)
518 {
519 const char *retVal = m_libCec->ToString((cec_deck_info)status);
520 return gcnew String(retVal);
521 }
522
523 String ^ ToString(CecOpcode opcode)
524 {
525 const char *retVal = m_libCec->ToString((cec_opcode)opcode);
526 return gcnew String(retVal);
527 }
528
529 String ^ ToString(CecSystemAudioStatus mode)
530 {
531 const char *retVal = m_libCec->ToString((cec_system_audio_status)mode);
532 return gcnew String(retVal);
533 }
534
535 String ^ ToString(CecAudioStatus status)
536 {
537 const char *retVal = m_libCec->ToString((cec_audio_status)status);
538 return gcnew String(retVal);
539 }
540
3efda01a
LOK
541 String ^ ToString(CecClientVersion version)
542 {
543 const char *retVal = m_libCec->ToString((cec_client_version)version);
544 return gcnew String(retVal);
545 }
546
547 String ^ ToString(CecServerVersion version)
548 {
549 const char *retVal = m_libCec->ToString((cec_server_version)version);
550 return gcnew String(retVal);
551 }
552
4ef3b314
LOK
553 private:
554 ICECAdapter * m_libCec;
555 };
0cac9547 556}