cec: added callbacks to LibCecSharp
[deb_libcec.git] / src / LibCecSharp / LibCecSharp.cpp
CommitLineData
61f3c2ad
LOK
1/*
2 * This file is part of the libCEC(R) library.
3 *
4 * libCEC(R) is Copyright (C) 2011 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#include "stdafx.h"
34#include <windows.h>
35#include <vcclr.h>
36#include <msclr/marshal.h>
37#include <cec.h>
38#using <System.dll>
39
40using namespace System;
0cac9547 41using namespace System::Runtime::InteropServices;
61f3c2ad
LOK
42using namespace CEC;
43using namespace msclr::interop;
44
45public enum class CecDeviceType
46{
47 Tv = 0,
48 RecordingDevice = 1,
49 Reserved = 2,
50 Tuner = 3,
51 PlaybackDevice = 4,
52 AudioSystem = 5
53};
54
55public enum class CecLogLevel
56{
57 None = 0,
58 Error = 1,
59 Warning = 2,
60 Notice = 4,
61 Traffic = 8,
62 Debug = 16,
63 All = 31
64};
65
66public enum class CecLogicalAddress
67{
68 Unknown = -1, //not a valid logical address
69 Tv = 0,
70 RecordingDevice1 = 1,
71 RecordingDevice2 = 2,
72 Tuner1 = 3,
73 PlaybackDevice1 = 4,
74 AudioSystem = 5,
75 Tuner2 = 6,
76 Tuner3 = 7,
77 PlaybackDevice2 = 8,
78 RecordingDevice3 = 9,
79 Tuner4 = 10,
80 PlaybackDevice3 = 11,
81 Reserved1 = 12,
82 Reserved2 = 13,
83 FreeUse = 14,
84 Unregistered = 15,
85 Broadcast = 15
86};
87
88public enum class CecPowerStatus
89{
90 On = 0x00,
91 Standby = 0x01,
92 InTransitionStandbyToOn = 0x02,
93 InTransitionOnToStandby = 0x03,
94 Unknown = 0x99
95};
96
97public enum class CecVersion
98{
99 Unknown = 0x00,
100 V1_2 = 0x01,
101 V1_2A = 0x02,
102 V1_3 = 0x03,
103 V1_3A = 0x04,
104 V1_4 = 0x05
105};
106
107public enum class CecDisplayControl
108{
109 DisplayForDefaultTime = 0x00,
110 DisplayUntilCleared = 0x40,
111 ClearPreviousMessage = 0x80,
112 ReservedForFutureUse = 0xC0
113};
114
115public enum class CecMenuState
116{
117 Activated = 0,
118 Deactivated = 1
119};
120
121public enum class CecDeckControlMode
122{
123 SkipForwardWind = 1,
124 SkipReverseRewind = 2,
125 Stop = 3,
126 Eject = 4
127};
128
129public enum class CecDeckInfo
130{
131 Play = 0x11,
132 Record = 0x12,
133 Reverse = 0x13,
134 Still = 0x14,
135 Slow = 0x15,
136 SlowReverse = 0x16,
137 FastForward = 0x17,
138 FastReverse = 0x18,
139 NoMedia = 0x19,
140 Stop = 0x1A,
141 SkipForwardWind = 0x1B,
142 SkipReverseRewind = 0x1C,
143 IndexSearchForward = 0x1D,
144 IndexSearchReverse = 0x1E,
145 OtherStatus = 0x1F
146};
147
988de7b9
LOK
148public enum class CecUserControlCode
149{
150 Select = 0x00,
151 Up = 0x01,
152 Down = 0x02,
153 Left = 0x03,
154 Right = 0x04,
155 RightUp = 0x05,
156 RightDown = 0x06,
157 LeftUp = 0x07,
158 LeftDown = 0x08,
159 RootMenu = 0x09,
160 SetupMenu = 0x0A,
161 ContentsMenu = 0x0B,
162 FavoriteMenu = 0x0C,
163 Exit = 0x0D,
164 Number0 = 0x20,
165 Number1 = 0x21,
166 Number2 = 0x22,
167 Number3 = 0x23,
168 Number4 = 0x24,
169 Number5 = 0x25,
170 Number6 = 0x26,
171 Number7 = 0x27,
172 Number8 = 0x28,
173 Number9 = 0x29,
174 Dot = 0x2A,
175 Enter = 0x2B,
176 Clear = 0x2C,
177 NextFavorite = 0x2F,
178 ChannelUp = 0x30,
179 ChannelDown = 0x31,
180 PreviousChannel = 0x32,
181 SoundSelect = 0x33,
182 InputSelect = 0x34,
183 DisplayInformation = 0x35,
184 Help = 0x36,
185 PageUp = 0x37,
186 PageDown = 0x38,
187 Power = 0x40,
188 VolumeUp = 0x41,
189 VolumeDown = 0x42,
190 Mute = 0x43,
191 Play = 0x44,
192 Stop = 0x45,
193 Pause = 0x46,
194 Record = 0x47,
195 Rewind = 0x48,
196 FastForward = 0x49,
197 Eject = 0x4A,
198 Forward = 0x4B,
199 Backward = 0x4C,
200 StopRecord = 0x4D,
201 PauseRecord = 0x4E,
202 Angle = 0x50,
203 SubPicture = 0x51,
204 VideoOnDemand = 0x52,
205 ElectronicProgramGuide = 0x53,
206 TimerProgramming = 0x54,
207 InitialConfiguration = 0x55,
208 PlayFunction = 0x60,
209 PausePlayFunction = 0x61,
210 RecordFunction = 0x62,
211 PauseRecordFunction = 0x63,
212 StopFunction = 0x64,
213 MuteFunction = 0x65,
214 RestoreVolumeFunction = 0x66,
215 TuneFunction = 0x67,
216 SelectMediaFunction = 0x68,
217 SelectAVInputFunction = 0x69,
218 SelectAudioInputFunction = 0x6A,
219 PowerToggleFunction = 0x6B,
220 PowerOffFunction = 0x6C,
221 PowerOnFunction = 0x6D,
222 F1Blue = 0x71,
223 F2Red = 0X72,
224 F3Green = 0x73,
225 F4Yellow = 0x74,
226 F5 = 0x75,
227 Data = 0x76,
228 Max = 0x76,
229 Unknown
230};
231
8d4c47d9
LOK
232public enum class CecVendorId
233{
234 Samsung = 0x00F0,
235 LG = 0xE091,
236 Panasonic = 0x8045,
237 Pioneer = 0xE036,
238 Onkyo = 0x09B0,
239 Yamaha = 0xA0DE,
240 Philips = 0x903E,
241 Unknown = 0
242};
243
244public enum class CecAudioStatus
245{
246 MuteStatusMask = 0x80,
247 VolumeStatusMask = 0x7F,
248 VolumeMin = 0x00,
249 VolumeMax = 0x64,
250 VolumeStatusUnknown = 0x7F
251};
252
253public enum class CecOpcode
254{
255 ActiveSource = 0x82,
256 ImageViewOn = 0x04,
257 TextViewOn = 0x0D,
258 InactiveSource = 0x9D,
259 RequestActiveSource = 0x85,
260 RoutingChange = 0x80,
261 RoutingInformation = 0x81,
262 SetStreamPath = 0x86,
263 Standby = 0x36,
264 RecordOff = 0x0B,
265 RecordOn = 0x09,
266 RecordStatus = 0x0A,
267 RecordTvScreen = 0x0F,
268 ClearAnalogueTimer = 0x33,
269 ClearDigitalTimer = 0x99,
270 ClearExternalTimer = 0xA1,
271 SetAnalogueTimer = 0x34,
272 SetDigitalTimer = 0x97,
273 SetExternalTimer = 0xA2,
274 SetTimerProgramTitle = 0x67,
275 TimerClearedStatus = 0x43,
276 TimerStatus = 0x35,
277 CecVersion = 0x9E,
278 GetCecVersion = 0x9F,
279 GivePhysicalAddress = 0x83,
280 GetMenuLanguage = 0x91,
281 ReportPhysicalAddress = 0x84,
282 SetMenuLanguage = 0x32,
283 DeckControl = 0x42,
284 DeckStatus = 0x1B,
285 GiveDeckStatus = 0x1A,
286 Play = 0x41,
287 GiveTunerDeviceStatus = 0x08,
288 SelectAnalogueService = 0x92,
289 SelectDigtalService = 0x93,
290 TunerDeviceStatus = 0x07,
291 TunerStepDecrement = 0x06,
292 TunerStepIncrement = 0x05,
293 DeviceVendorId = 0x87,
294 GiveDeviceVendorId = 0x8C,
295 VendorCommand = 0x89,
296 VendorCommandWithId = 0xA0,
297 VendorRemoteButtonDown = 0x8A,
298 VendorRemoteButtonUp = 0x8B,
299 SetOsdString = 0x64,
300 GiveOsdName = 0x46,
301 SetOsdName = 0x47,
302 MenuRequest = 0x8D,
303 MenuStatus = 0x8E,
304 UserControlPressed = 0x44,
305 UserControlRelease = 0x45,
306 GiveDevicePowerStatus = 0x8F,
307 ReportPowerStatus = 0x90,
308 FeatureAbort = 0x00,
309 Abort = 0xFF,
310 GiveAudioStatus = 0x71,
311 GiveSystemAudioMode = 0x7D,
312 ReportAudioStatus = 0x7A,
313 SetSystemAudioMode = 0x72,
314 SystemAudioModeRequest = 0x70,
315 SystemAudioModeStatus = 0x7E,
316 SetAudioRate = 0x9A,
317 /* when this opcode is set, no opcode will be sent to the device. this is one of the reserved numbers */
318 None = 0xFD
319};
320
321public enum class CecSystemAudioStatus
322{
323 Off = 0,
324 On = 1
325};
326
61f3c2ad
LOK
327public ref class CecAdapter
328{
329public:
330 CecAdapter(String ^ strPath, String ^ strComPort)
331 {
332 Path = strPath;
333 ComPort = strComPort;
334 }
335
336 property String ^ Path;
337 property String ^ ComPort;
338};
339
340public ref class CecDeviceTypeList
341{
342public:
343 CecDeviceTypeList(void)
344 {
345 Types = gcnew array<CecDeviceType>(5);
346 for (unsigned int iPtr = 0; iPtr < 5; iPtr++)
347 Types[iPtr] = CecDeviceType::Reserved;
348 }
349
350 property array<CecDeviceType> ^ Types;
351};
352
988de7b9
LOK
353public ref class CecLogicalAddresses
354{
355public:
356 CecLogicalAddresses(void)
357 {
358 Addresses = gcnew array<CecLogicalAddress>(16);
359 for (unsigned int iPtr = 0; iPtr < 16; iPtr++)
360 Addresses[iPtr] = CecLogicalAddress::Unregistered;
361 }
362
8d4c47d9
LOK
363 bool IsSet(CecLogicalAddress iAddress)
364 {
365 return Addresses[(unsigned int)iAddress] != CecLogicalAddress::Unregistered;
366 }
367
988de7b9
LOK
368 property array<CecLogicalAddress> ^ Addresses;
369};
370
61f3c2ad
LOK
371public ref class CecDatapacket
372{
373public:
374 CecDatapacket(void)
375 {
376 Data = gcnew array<uint8_t>(100);
377 Size = 0;
378 }
379
380 void PushBack(uint8_t data)
381 {
382 if (Size < 100)
383 {
384 Data[Size] = data;
385 Size++;
386 }
387 }
388
389 property array<uint8_t> ^ Data;
390 property uint8_t Size;
391};
392
393public ref class CecCommand
394{
395public:
8d4c47d9 396 CecCommand(CecLogicalAddress iInitiator, CecLogicalAddress iDestination, bool bAck, bool bEom, CecOpcode iOpcode, int32_t iTransmitTimeout)
61f3c2ad
LOK
397 {
398 Initiator = iInitiator;
399 Destination = iDestination;
400 Ack = bAck;
401 Eom = bEom;
402 Opcode = iOpcode;
403 OpcodeSet = true;
404 TransmitTimeout = iTransmitTimeout;
405 Parameters = gcnew CecDatapacket;
406 Empty = false;
407 }
408
409 CecCommand(void)
410 {
411 Initiator = CecLogicalAddress::Unknown;
412 Destination = CecLogicalAddress::Unknown;
413 Ack = false;
414 Eom = false;
8d4c47d9 415 Opcode = CecOpcode::None;
61f3c2ad
LOK
416 OpcodeSet = false;
417 TransmitTimeout = 0;
418 Parameters = gcnew CecDatapacket;
419 Empty = true;
420 }
421
422 void PushBack(uint8_t data)
423 {
424 if (Initiator == CecLogicalAddress::Unknown && Destination == CecLogicalAddress::Unknown)
425 {
426 Initiator = (CecLogicalAddress) (data >> 4);
427 Destination = (CecLogicalAddress) (data & 0xF);
428 }
429 else if (!OpcodeSet)
430 {
431 OpcodeSet = true;
8d4c47d9 432 Opcode = (CecOpcode)data;
61f3c2ad
LOK
433 }
434 else
435 {
436 Parameters->PushBack(data);
437 }
438 }
439
440 property bool Empty;
441 property CecLogicalAddress Initiator;
442 property CecLogicalAddress Destination;
443 property bool Ack;
444 property bool Eom;
8d4c47d9 445 property CecOpcode Opcode;
61f3c2ad
LOK
446 property CecDatapacket ^ Parameters;
447 property bool OpcodeSet;
448 property int32_t TransmitTimeout;
449};
450
451public ref class CecKeypress
452{
453public:
454 CecKeypress(int iKeycode, unsigned int iDuration)
455 {
456 Keycode = iKeycode;
457 Duration = iDuration;
458 Empty = false;
459 }
460
461 CecKeypress(void)
462 {
463 Keycode = 0;
464 Duration = 0;
465 Empty = true;
466 }
467
468 property bool Empty;
469 property int Keycode;
470 property unsigned int Duration;
471};
472
473public ref class CecLogMessage
474{
475public:
476 CecLogMessage(String ^ strMessage, CecLogLevel iLevel, int64_t iTime)
477 {
478 Message = strMessage;
479 Level = iLevel;
480 Time = iTime;
481 Empty = false;
482 }
483
484 CecLogMessage(void)
485 {
486 Message = "";
487 Level = CecLogLevel::None;
488 Time = 0;
489 Empty = true;
490 }
491
492 property bool Empty;
493 property String ^ Message;
494 property CecLogLevel Level;
495 property int64_t Time;
496};
497
0cac9547
LOK
498public ref class CecCallbackMethods
499{
500public:
501 virtual int ReceiveLogMessage(CecLogMessage ^ message)
502 {
503 return 0;
504 }
505
506 virtual int ReceiveKeypress(CecKeypress ^ key)
507 {
508 return 0;
509 }
510
511 virtual int ReceiveCommand(CecCommand ^ command)
512 {
513 return 0;
514 }
515};
516
517#pragma unmanaged
518// unmanaged callback methods
519typedef int (__stdcall *LOGCB) (const cec_log_message &message);
520typedef int (__stdcall *KEYCB) (const cec_keypress &key);
521typedef int (__stdcall *COMMANDCB)(const cec_command &command);
522
523static LOGCB g_logCB;
524static KEYCB g_keyCB;
525static COMMANDCB g_commandCB;
526static ICECCallbacks g_cecCallbacks;
527
528int CecLogMessageCB(const cec_log_message &message)
529{
530 if (g_logCB)
531 return g_logCB(message);
532 return 0;
533}
534
535int CecKeyPressCB(const cec_keypress &key)
536{
537 if (g_keyCB)
538 return g_keyCB(key);
539 return 0;
540}
541
542int CecCommandCB(const cec_command &command)
543{
544 if (g_commandCB)
545 return g_commandCB(command);
546 return 0;
547}
548
549#pragma managed
550// delegates for the unmanaged callback methods
551public delegate int CecLogMessageManagedDelegate(const cec_log_message &);
552public delegate int CecKeyPressManagedDelegate(const cec_keypress &);
553public delegate int CecCommandManagedDelegate(const cec_command &);
554
61f3c2ad
LOK
555public ref class LibCecSharp
556{
557public:
0cac9547
LOK
558 LibCecSharp(String ^ strDeviceName, CecDeviceTypeList ^ deviceTypes)
559 {
560 marshal_context ^ context = gcnew marshal_context();
561 m_bHasCallbacks = false;
562 const char* strDeviceNameC = context->marshal_as<const char*>(strDeviceName);
61f3c2ad 563
0cac9547
LOK
564 cec_device_type_list types;
565 for (unsigned int iPtr = 0; iPtr < 5; iPtr++)
566 types.types[iPtr] = (cec_device_type)deviceTypes->Types[iPtr];
567 m_libCec = (ICECAdapter *) CECInit(strDeviceNameC, types);
568
569 // create the delegate method for the log message callback
570 m_logMessageDelegate = gcnew CecLogMessageManagedDelegate(this, &LibCecSharp::CecLogMessageManaged);
571 m_logMessageGCHandle = GCHandle::Alloc(m_logMessageDelegate);
572 g_logCB = static_cast<LOGCB>(Marshal::GetFunctionPointerForDelegate(m_logMessageDelegate).ToPointer());
573 g_cecCallbacks.CBCecLogMessage = CecLogMessageCB;
574
575 // create the delegate method for the keypress callback
576 m_keypressDelegate = gcnew CecKeyPressManagedDelegate(this, &LibCecSharp::CecKeyPressManaged);
577 m_keypressGCHandle = GCHandle::Alloc(m_keypressDelegate);
578 g_keyCB = static_cast<KEYCB>(Marshal::GetFunctionPointerForDelegate(m_keypressDelegate).ToPointer());
579 g_cecCallbacks.CBCecKeyPress = CecKeyPressCB;
580
581 // create the delegate method for the command callback
582 m_commandDelegate = gcnew CecCommandManagedDelegate(this, &LibCecSharp::CecCommandManaged);
583 m_commandGCHandle = GCHandle::Alloc(m_commandDelegate);
584 g_commandCB = static_cast<COMMANDCB>(Marshal::GetFunctionPointerForDelegate(m_commandDelegate).ToPointer());
585 g_cecCallbacks.CBCecCommand = CecCommandCB;
61f3c2ad 586
0cac9547
LOK
587 delete context;
588 }
61f3c2ad
LOK
589
590 ~LibCecSharp(void)
591 {
592 CECDestroy(m_libCec);
0cac9547 593 DestroyDelegates();
61f3c2ad
LOK
594 m_libCec = NULL;
595 }
596
597protected:
598 !LibCecSharp(void)
599 {
600 CECDestroy(m_libCec);
0cac9547 601 DestroyDelegates();
61f3c2ad
LOK
602 m_libCec = NULL;
603 }
604
605public:
606 array<CecAdapter ^> ^ FindAdapters(String ^ path)
607 {
608 cec_adapter *devices = new cec_adapter[10];
609
610 marshal_context ^ context = gcnew marshal_context();
611 const char* strPathC = path->Length > 0 ? context->marshal_as<const char*>(path) : NULL;
612
613 uint8_t iDevicesFound = m_libCec->FindAdapters(devices, 10, NULL);
614
615 array<CecAdapter ^> ^ adapters = gcnew array<CecAdapter ^>(iDevicesFound);
616 for (unsigned int iPtr = 0; iPtr < iDevicesFound; iPtr++)
617 adapters[iPtr] = gcnew CecAdapter(gcnew String(devices[iPtr].path), gcnew String(devices[iPtr].comm));
618
619 delete devices;
620 delete context;
621 return adapters;
622 }
623
624 bool Open(String ^ strPort, int iTimeoutMs)
625 {
626 marshal_context ^ context = gcnew marshal_context();
627 const char* strPortC = context->marshal_as<const char*>(strPort);
628 bool bReturn = m_libCec->Open(strPortC, iTimeoutMs);
629 delete context;
630 return bReturn;
631 }
632
633 void Close(void)
634 {
635 m_libCec->Close();
636 }
637
0cac9547
LOK
638 bool EnableCallbacks(CecCallbackMethods ^ callbacks)
639 {
640 if (m_libCec && !m_bHasCallbacks)
641 {
642 m_bHasCallbacks = true;
643 m_callbacks = callbacks;
644 return m_libCec->EnableCallbacks(&g_cecCallbacks);
645 }
646
647 return false;
648 }
649
61f3c2ad
LOK
650 bool PingAdapter(void)
651 {
652 return m_libCec->PingAdapter();
653 }
654
655 bool StartBootloader(void)
656 {
657 return m_libCec->StartBootloader();
658 }
659
660 int GetMinLibVersion(void)
661 {
662 return m_libCec->GetMinLibVersion();
663 }
664
665 int GetLibVersionMajor(void)
666 {
667 return m_libCec->GetLibVersionMajor();
668 }
669
670 int GetLibVersionMinor(void)
671 {
672 return m_libCec->GetLibVersionMinor();
673 }
674
675 CecLogMessage ^ GetNextLogMessage(void)
676 {
677 cec_log_message msg;
678 if (m_libCec->GetNextLogMessage(&msg))
679 {
680 return gcnew CecLogMessage(gcnew String(msg.message), (CecLogLevel)msg.level, msg.time);
681 }
682
683 return gcnew CecLogMessage();
684 }
685
686 CecKeypress ^ GetNextKeypress(void)
687 {
688 cec_keypress key;
689 if (m_libCec->GetNextKeypress(&key))
690 {
691 return gcnew CecKeypress(key.keycode, key.duration);
692 }
693
694 return gcnew CecKeypress();
695 }
696
697 CecCommand ^ GetNextCommand(void)
698 {
699 cec_command command;
700 if (m_libCec->GetNextCommand(&command))
701 {
8d4c47d9 702 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);
0e197148
LOK
703 for (uint8_t iPtr = 0; iPtr < command.parameters.size; iPtr++)
704 retVal->Parameters->PushBack(command.parameters[iPtr]);
705 return retVal;
61f3c2ad
LOK
706 }
707
708 return gcnew CecCommand();
709 }
710
711 bool Transmit(CecCommand ^ command)
712 {
713 cec_command ccommand;
ab1469a0 714 cec_command::Format(ccommand, (cec_logical_address)command->Initiator, (cec_logical_address)command->Destination, (cec_opcode)command->Opcode);
61f3c2ad
LOK
715 ccommand.transmit_timeout = command->TransmitTimeout;
716 ccommand.eom = command->Eom;
717 ccommand.ack = command->Ack;
718 for (unsigned int iPtr = 0; iPtr < command->Parameters->Size; iPtr++)
ab1469a0 719 ccommand.parameters.PushBack(command->Parameters->Data[iPtr]);
61f3c2ad
LOK
720
721 return m_libCec->Transmit(ccommand);
722 }
723
724 bool SetLogicalAddress(CecLogicalAddress logicalAddress)
725 {
726 return m_libCec->SetLogicalAddress((cec_logical_address) logicalAddress);
727 }
728
729 bool SetPhysicalAddress(int16_t physicalAddress)
730 {
731 return m_libCec->SetPhysicalAddress(physicalAddress);
732 }
733
734 bool PowerOnDevices(CecLogicalAddress logicalAddress)
735 {
736 return m_libCec->PowerOnDevices((cec_logical_address) logicalAddress);
737 }
738
739 bool StandbyDevices(CecLogicalAddress logicalAddress)
740 {
741 return m_libCec->StandbyDevices((cec_logical_address) logicalAddress);
742 }
743
744 bool PollDevice(CecLogicalAddress logicalAddress)
745 {
746 return m_libCec->PollDevice((cec_logical_address) logicalAddress);
747 }
748
749 bool SetActiveSource(CecDeviceType type)
750 {
751 return m_libCec->SetActiveSource((cec_device_type) type);
752 }
753
754 bool SetDeckControlMode(CecDeckControlMode mode, bool sendUpdate)
755 {
756 return m_libCec->SetDeckControlMode((cec_deck_control_mode) mode, sendUpdate);
757 }
758
759 bool SetDeckInfo(CecDeckInfo info, bool sendUpdate)
760 {
761 return m_libCec->SetDeckInfo((cec_deck_info) info, sendUpdate);
762 }
763
764 bool SetInactiveView(void)
765 {
766 return m_libCec->SetInactiveView();
767 }
768
769 bool SetMenuState(CecMenuState state, bool sendUpdate)
770 {
771 return m_libCec->SetMenuState((cec_menu_state) state, sendUpdate);
772 }
773
774 bool SetOSDString(CecLogicalAddress logicalAddress, CecDisplayControl duration, String ^ message)
775 {
776 marshal_context ^ context = gcnew marshal_context();
777 const char* strMessageC = context->marshal_as<const char*>(message);
778
779 bool bReturn = m_libCec->SetOSDString((cec_logical_address) logicalAddress, (cec_display_control) duration, strMessageC);
780
781 delete context;
782 return bReturn;
783 }
784
785 bool SwitchMonitoring(bool enable)
786 {
787 return m_libCec->SwitchMonitoring(enable);
788 }
789
790 CecVersion GetDeviceCecVersion(CecLogicalAddress logicalAddress)
791 {
792 return (CecVersion) m_libCec->GetDeviceCecVersion((cec_logical_address) logicalAddress);
793 }
794
795 String ^ GetDeviceMenuLanguage(CecLogicalAddress logicalAddress)
796 {
797 cec_menu_language lang;
798 if (m_libCec->GetDeviceMenuLanguage((cec_logical_address) logicalAddress, &lang))
799 {
800 return gcnew String(lang.language);
801 }
802
803 return gcnew String("");
804 }
805
8d4c47d9 806 CecVendorId GetDeviceVendorId(CecLogicalAddress logicalAddress)
61f3c2ad 807 {
8d4c47d9 808 return (CecVendorId)m_libCec->GetDeviceVendorId((cec_logical_address) logicalAddress);
61f3c2ad
LOK
809 }
810
811 CecPowerStatus GetDevicePowerStatus(CecLogicalAddress logicalAddress)
812 {
813 return (CecPowerStatus) m_libCec->GetDevicePowerStatus((cec_logical_address) logicalAddress);
814 }
815
988de7b9
LOK
816 CecLogicalAddresses ^ GetActiveDevices(void)
817 {
818 CecLogicalAddresses ^ retVal = gcnew CecLogicalAddresses();
819 unsigned int iDevices = 0;
820
821 cec_logical_addresses activeDevices = m_libCec->GetActiveDevices();
822
823 for (uint8_t iPtr = 0; iPtr < 16; iPtr++)
824 if (activeDevices[iPtr])
825 retVal->Addresses[iDevices++] = (CecLogicalAddress)iPtr;
826
827 return retVal;
828 }
829
830 bool IsActiveDevice(CecLogicalAddress logicalAddress)
831 {
832 return m_libCec->IsActiveDevice((cec_logical_address)logicalAddress);
833 }
834
835 bool IsActiveDeviceType(CecDeviceType type)
836 {
837 return m_libCec->IsActiveDeviceType((cec_device_type)type);
838 }
839
bdccb711 840 bool SetHDMIPort(CecLogicalAddress address, uint8_t port)
988de7b9 841 {
bdccb711 842 return m_libCec->SetHDMIPort((cec_logical_address)address, port);
988de7b9
LOK
843 }
844
845 uint8_t VolumeUp(bool wait)
846 {
847 return m_libCec->VolumeUp(wait);
848 }
849
850 uint8_t VolumeDown(bool wait)
851 {
852 return m_libCec->VolumeDown(wait);
853 }
854
855 uint8_t MuteAudio(bool wait)
856 {
857 return m_libCec->MuteAudio(wait);
858 }
859
8b86fb7a 860 bool SendKeypress(CecLogicalAddress destination, CecUserControlCode key, bool wait)
988de7b9 861 {
8b86fb7a 862 return m_libCec->SendKeypress((cec_logical_address)destination, (cec_user_control_code)key, wait);
988de7b9
LOK
863 }
864
8b86fb7a 865 bool SendKeyRelease(CecLogicalAddress destination, bool wait)
988de7b9 866 {
8b86fb7a 867 return m_libCec->SendKeyRelease((cec_logical_address)destination, wait);
988de7b9
LOK
868 }
869
f71a1df9 870 String ^ GetDeviceOSDName(CecLogicalAddress logicalAddress)
988de7b9 871 {
f71a1df9 872 cec_osd_name osd = m_libCec->GetDeviceOSDName((cec_logical_address) logicalAddress);
988de7b9
LOK
873 return gcnew String(osd.name);
874 }
875
6c3c8d5a
LOK
876 CecLogicalAddress GetActiveSource()
877 {
878 return (CecLogicalAddress)m_libCec->GetActiveSource();
879 }
880
881 bool IsActiveSource(CecLogicalAddress logicalAddress)
882 {
883 return m_libCec->IsActiveSource((cec_logical_address)logicalAddress);
884 }
885
8d4c47d9
LOK
886 uint16_t GetDevicePhysicalAddress(CecLogicalAddress iAddress)
887 {
888 return m_libCec->GetDevicePhysicalAddress((cec_logical_address)iAddress);
889 }
890
891 String ^ ToString(CecLogicalAddress iAddress)
892 {
893 const char *retVal = m_libCec->ToString((cec_logical_address)iAddress);
894 return gcnew String(retVal);
895 }
896
897 String ^ ToString(CecVendorId iVendorId)
898 {
899 const char *retVal = m_libCec->ToString((cec_vendor_id)iVendorId);
900 return gcnew String(retVal);
901 }
902
903 String ^ ToString(CecVersion iVersion)
904 {
905 const char *retVal = m_libCec->ToString((cec_version)iVersion);
906 return gcnew String(retVal);
907 }
908
909 String ^ ToString(CecPowerStatus iState)
910 {
911 const char *retVal = m_libCec->ToString((cec_power_status)iState);
912 return gcnew String(retVal);
913 }
914
915 String ^ ToString(CecMenuState iState)
916 {
917 const char *retVal = m_libCec->ToString((cec_menu_state)iState);
918 return gcnew String(retVal);
919 }
920
921 String ^ ToString(CecDeckControlMode iMode)
922 {
923 const char *retVal = m_libCec->ToString((cec_deck_control_mode)iMode);
924 return gcnew String(retVal);
925 }
926
927 String ^ ToString(CecDeckInfo status)
928 {
929 const char *retVal = m_libCec->ToString((cec_deck_info)status);
930 return gcnew String(retVal);
931 }
932
933 String ^ ToString(CecOpcode opcode)
934 {
935 const char *retVal = m_libCec->ToString((cec_opcode)opcode);
936 return gcnew String(retVal);
937 }
938
939 String ^ ToString(CecSystemAudioStatus mode)
940 {
941 const char *retVal = m_libCec->ToString((cec_system_audio_status)mode);
942 return gcnew String(retVal);
943 }
944
945 String ^ ToString(CecAudioStatus status)
946 {
947 const char *retVal = m_libCec->ToString((cec_audio_status)status);
948 return gcnew String(retVal);
949 }
950
61f3c2ad 951private:
0cac9547
LOK
952 void DestroyDelegates()
953 {
954 m_logMessageGCHandle.Free();
955 m_keypressGCHandle.Free();
956 m_commandGCHandle.Free();
957 }
958
959 // managed callback methods
960 int CecLogMessageManaged(const cec_log_message &message)
961 {
962 int iReturn(0);
963 if (m_bHasCallbacks)
964 iReturn = m_callbacks->ReceiveLogMessage(gcnew CecLogMessage(gcnew String(message.message), (CecLogLevel)message.level, message.time));
965 return iReturn;
966 }
967
968 int CecKeyPressManaged(const cec_keypress &key)
969 {
970 int iReturn(0);
971 if (m_bHasCallbacks)
972 iReturn = m_callbacks->ReceiveKeypress(gcnew CecKeypress(key.keycode, key.duration));
973 return iReturn;
974 }
975
976 int CecCommandManaged(const cec_command &command)
977 {
978 int iReturn(0);
979 if (m_bHasCallbacks)
980 {
981 CecCommand ^ newCommand = gcnew CecCommand((CecLogicalAddress)command.initiator, (CecLogicalAddress)command.destination, command.ack == 1 ? true : false, command.eom == 1 ? true : false, (CecOpcode)command.opcode, command.transmit_timeout);
982 for (uint8_t iPtr = 0; iPtr < command.parameters.size; iPtr++)
983 newCommand->Parameters->PushBack(command.parameters[iPtr]);
984 iReturn = m_callbacks->ReceiveCommand(newCommand);
985 }
986 return iReturn;
987 }
988
989 ICECAdapter * m_libCec;
990 CecCallbackMethods ^ m_callbacks;
991 bool m_bHasCallbacks;
992
993 CecLogMessageManagedDelegate ^ m_logMessageDelegate;
994 static GCHandle m_logMessageGCHandle;
995 LOGCB m_logMessageCallback;
996
997 CecKeyPressManagedDelegate ^ m_keypressDelegate;
998 static GCHandle m_keypressGCHandle;
999 KEYCB m_keypressCallback;
1000
1001 CecCommandManagedDelegate ^ m_commandDelegate;
1002 static GCHandle m_commandGCHandle;
1003 COMMANDCB m_commandCallback;
61f3c2ad 1004};