cec: don't send an active source command when the physical address couldn't be set...
[deb_libcec.git] / src / LibCecSharp / CecSharpTypes.h
CommitLineData
4ef3b314
LOK
1#pragma once
2/*
3 * This file is part of the libCEC(R) library.
4 *
5 * libCEC(R) is Copyright (C) 2011-2012 Pulse-Eight Limited. All rights reserved.
6 * libCEC(R) is an original work, containing original code.
7 *
8 * libCEC(R) is a trademark of Pulse-Eight Limited.
9 *
10 * This program is dual-licensed; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 *
24 *
25 * Alternatively, you can license this library under a commercial license,
26 * please contact Pulse-Eight Licensing for more information.
27 *
28 * For more information contact:
29 * Pulse-Eight Licensing <license@pulse-eight.com>
30 * http://www.pulse-eight.com/
31 * http://www.pulse-eight.net/
32 */
33
34#include <windows.h>
35#include <vcclr.h>
36#include <msclr/marshal.h>
37#include "../../include/cec.h"
38
39#using <System.dll>
40
41namespace CecSharp
42{
43 public enum class CecDeviceType
44 {
45 Tv = 0,
46 RecordingDevice = 1,
47 Reserved = 2,
48 Tuner = 3,
49 PlaybackDevice = 4,
50 AudioSystem = 5
51 };
52
53 public enum class CecLogLevel
54 {
55 None = 0,
56 Error = 1,
57 Warning = 2,
58 Notice = 4,
59 Traffic = 8,
60 Debug = 16,
61 All = 31
62 };
63
64 public enum class CecLogicalAddress
65 {
66 Unknown = -1, //not a valid logical address
67 Tv = 0,
68 RecordingDevice1 = 1,
69 RecordingDevice2 = 2,
70 Tuner1 = 3,
71 PlaybackDevice1 = 4,
72 AudioSystem = 5,
73 Tuner2 = 6,
74 Tuner3 = 7,
75 PlaybackDevice2 = 8,
76 RecordingDevice3 = 9,
77 Tuner4 = 10,
78 PlaybackDevice3 = 11,
79 Reserved1 = 12,
80 Reserved2 = 13,
81 FreeUse = 14,
82 Unregistered = 15,
83 Broadcast = 15
84 };
85
86 public enum class CecPowerStatus
87 {
88 On = 0x00,
89 Standby = 0x01,
90 InTransitionStandbyToOn = 0x02,
91 InTransitionOnToStandby = 0x03,
92 Unknown = 0x99
93 };
94
95 public enum class CecVersion
96 {
97 Unknown = 0x00,
98 V1_2 = 0x01,
99 V1_2A = 0x02,
100 V1_3 = 0x03,
101 V1_3A = 0x04,
102 V1_4 = 0x05
103 };
104
105 public enum class CecDisplayControl
106 {
107 DisplayForDefaultTime = 0x00,
108 DisplayUntilCleared = 0x40,
109 ClearPreviousMessage = 0x80,
110 ReservedForFutureUse = 0xC0
111 };
112
113 public enum class CecMenuState
114 {
115 Activated = 0,
116 Deactivated = 1
117 };
118
119 public enum class CecDeckControlMode
120 {
121 SkipForwardWind = 1,
122 SkipReverseRewind = 2,
123 Stop = 3,
124 Eject = 4
125 };
126
127 public enum class CecDeckInfo
128 {
129 Play = 0x11,
130 Record = 0x12,
131 Reverse = 0x13,
132 Still = 0x14,
133 Slow = 0x15,
134 SlowReverse = 0x16,
135 FastForward = 0x17,
136 FastReverse = 0x18,
137 NoMedia = 0x19,
138 Stop = 0x1A,
139 SkipForwardWind = 0x1B,
140 SkipReverseRewind = 0x1C,
141 IndexSearchForward = 0x1D,
142 IndexSearchReverse = 0x1E,
143 OtherStatus = 0x1F
144 };
145
146 public enum class CecUserControlCode
147 {
148 Select = 0x00,
149 Up = 0x01,
150 Down = 0x02,
151 Left = 0x03,
152 Right = 0x04,
153 RightUp = 0x05,
154 RightDown = 0x06,
155 LeftUp = 0x07,
156 LeftDown = 0x08,
157 RootMenu = 0x09,
158 SetupMenu = 0x0A,
159 ContentsMenu = 0x0B,
160 FavoriteMenu = 0x0C,
161 Exit = 0x0D,
162 Number0 = 0x20,
163 Number1 = 0x21,
164 Number2 = 0x22,
165 Number3 = 0x23,
166 Number4 = 0x24,
167 Number5 = 0x25,
168 Number6 = 0x26,
169 Number7 = 0x27,
170 Number8 = 0x28,
171 Number9 = 0x29,
172 Dot = 0x2A,
173 Enter = 0x2B,
174 Clear = 0x2C,
175 NextFavorite = 0x2F,
176 ChannelUp = 0x30,
177 ChannelDown = 0x31,
178 PreviousChannel = 0x32,
179 SoundSelect = 0x33,
180 InputSelect = 0x34,
181 DisplayInformation = 0x35,
182 Help = 0x36,
183 PageUp = 0x37,
184 PageDown = 0x38,
185 Power = 0x40,
186 VolumeUp = 0x41,
187 VolumeDown = 0x42,
188 Mute = 0x43,
189 Play = 0x44,
190 Stop = 0x45,
191 Pause = 0x46,
192 Record = 0x47,
193 Rewind = 0x48,
194 FastForward = 0x49,
195 Eject = 0x4A,
196 Forward = 0x4B,
197 Backward = 0x4C,
198 StopRecord = 0x4D,
199 PauseRecord = 0x4E,
200 Angle = 0x50,
201 SubPicture = 0x51,
202 VideoOnDemand = 0x52,
203 ElectronicProgramGuide = 0x53,
204 TimerProgramming = 0x54,
205 InitialConfiguration = 0x55,
206 PlayFunction = 0x60,
207 PausePlayFunction = 0x61,
208 RecordFunction = 0x62,
209 PauseRecordFunction = 0x63,
210 StopFunction = 0x64,
211 MuteFunction = 0x65,
212 RestoreVolumeFunction = 0x66,
213 TuneFunction = 0x67,
214 SelectMediaFunction = 0x68,
215 SelectAVInputFunction = 0x69,
216 SelectAudioInputFunction = 0x6A,
217 PowerToggleFunction = 0x6B,
218 PowerOffFunction = 0x6C,
219 PowerOnFunction = 0x6D,
220 F1Blue = 0x71,
221 F2Red = 0X72,
222 F3Green = 0x73,
223 F4Yellow = 0x74,
224 F5 = 0x75,
225 Data = 0x76,
226 Max = 0x76,
227 Unknown
228 };
229
230 public enum class CecVendorId
231 {
232 Samsung = 0x00F0,
233 LG = 0xE091,
234 Panasonic = 0x8045,
235 Pioneer = 0xE036,
236 Onkyo = 0x09B0,
237 Yamaha = 0xA0DE,
238 Philips = 0x903E,
de90f347 239 Sony = 0x080046,
4ef3b314
LOK
240 Unknown = 0
241 };
242
243 public enum class CecAudioStatus
244 {
245 MuteStatusMask = 0x80,
246 VolumeStatusMask = 0x7F,
247 VolumeMin = 0x00,
248 VolumeMax = 0x64,
249 VolumeStatusUnknown = 0x7F
250 };
251
252 public enum class CecOpcode
253 {
254 ActiveSource = 0x82,
255 ImageViewOn = 0x04,
256 TextViewOn = 0x0D,
257 InactiveSource = 0x9D,
258 RequestActiveSource = 0x85,
259 RoutingChange = 0x80,
260 RoutingInformation = 0x81,
261 SetStreamPath = 0x86,
262 Standby = 0x36,
263 RecordOff = 0x0B,
264 RecordOn = 0x09,
265 RecordStatus = 0x0A,
266 RecordTvScreen = 0x0F,
267 ClearAnalogueTimer = 0x33,
268 ClearDigitalTimer = 0x99,
269 ClearExternalTimer = 0xA1,
270 SetAnalogueTimer = 0x34,
271 SetDigitalTimer = 0x97,
272 SetExternalTimer = 0xA2,
273 SetTimerProgramTitle = 0x67,
274 TimerClearedStatus = 0x43,
275 TimerStatus = 0x35,
276 CecVersion = 0x9E,
277 GetCecVersion = 0x9F,
278 GivePhysicalAddress = 0x83,
279 GetMenuLanguage = 0x91,
280 ReportPhysicalAddress = 0x84,
281 SetMenuLanguage = 0x32,
282 DeckControl = 0x42,
283 DeckStatus = 0x1B,
284 GiveDeckStatus = 0x1A,
285 Play = 0x41,
286 GiveTunerDeviceStatus = 0x08,
287 SelectAnalogueService = 0x92,
288 SelectDigtalService = 0x93,
289 TunerDeviceStatus = 0x07,
290 TunerStepDecrement = 0x06,
291 TunerStepIncrement = 0x05,
292 DeviceVendorId = 0x87,
293 GiveDeviceVendorId = 0x8C,
294 VendorCommand = 0x89,
295 VendorCommandWithId = 0xA0,
296 VendorRemoteButtonDown = 0x8A,
297 VendorRemoteButtonUp = 0x8B,
298 SetOsdString = 0x64,
299 GiveOsdName = 0x46,
300 SetOsdName = 0x47,
301 MenuRequest = 0x8D,
302 MenuStatus = 0x8E,
303 UserControlPressed = 0x44,
304 UserControlRelease = 0x45,
305 GiveDevicePowerStatus = 0x8F,
306 ReportPowerStatus = 0x90,
307 FeatureAbort = 0x00,
308 Abort = 0xFF,
309 GiveAudioStatus = 0x71,
310 GiveSystemAudioMode = 0x7D,
311 ReportAudioStatus = 0x7A,
312 SetSystemAudioMode = 0x72,
313 SystemAudioModeRequest = 0x70,
314 SystemAudioModeStatus = 0x7E,
315 SetAudioRate = 0x9A,
316 /* when this opcode is set, no opcode will be sent to the device. this is one of the reserved numbers */
317 None = 0xFD
318 };
319
320 public enum class CecSystemAudioStatus
321 {
322 Off = 0,
323 On = 1
324 };
325
326 public enum class CecClientVersion
327 {
328 VersionPre1_5 = 0,
a8fffd1b 329 Version1_5_0 = 0x1500,
2e82cff0 330 Version1_5_1 = 0x1501,
b98fc43d
LOK
331 Version1_5_2 = 0x1502,
332 Version1_5_3 = 0x1503,
333 Version1_6_0 = 0x1600
4ef3b314
LOK
334 };
335
3efda01a
LOK
336 public enum class CecServerVersion
337 {
338 VersionPre1_5 = 0,
a8fffd1b 339 Version1_5_0 = 0x1500,
2e82cff0 340 Version1_5_1 = 0x1501,
b98fc43d
LOK
341 Version1_5_2 = 0x1502,
342 Version1_5_3 = 0x1503,
343 Version1_6_0 = 0x1600
3efda01a
LOK
344 };
345
4ef3b314
LOK
346 public ref class CecAdapter
347 {
348 public:
349 CecAdapter(System::String ^ strPath, System::String ^ strComPort)
350 {
351 Path = strPath;
352 ComPort = strComPort;
353 }
354
355 property System::String ^ Path;
356 property System::String ^ ComPort;
357 };
358
359 public ref class CecDeviceTypeList
360 {
361 public:
362 CecDeviceTypeList(void)
363 {
364 Types = gcnew array<CecDeviceType>(5);
365 for (unsigned int iPtr = 0; iPtr < 5; iPtr++)
366 Types[iPtr] = CecDeviceType::Reserved;
367 }
368
369 property array<CecDeviceType> ^ Types;
370 };
371
372 public ref class CecLogicalAddresses
373 {
374 public:
375 CecLogicalAddresses(void)
376 {
377 Addresses = gcnew array<CecLogicalAddress>(16);
b7907707
LOK
378 Clear();
379 }
380
381 void Clear(void)
382 {
4ef3b314 383 for (unsigned int iPtr = 0; iPtr < 16; iPtr++)
63851508 384 Addresses[iPtr] = CecLogicalAddress::Unknown;
4ef3b314
LOK
385 }
386
387 bool IsSet(CecLogicalAddress iAddress)
388 {
63851508 389 return Addresses[(unsigned int)iAddress] != CecLogicalAddress::Unknown;
4ef3b314
LOK
390 }
391
b7907707
LOK
392 void Set(CecLogicalAddress iAddress)
393 {
394 Addresses[(unsigned int)iAddress] = iAddress;
395 }
396
a9fb46b4 397 property CecLogicalAddress Primary;
4ef3b314
LOK
398 property array<CecLogicalAddress> ^ Addresses;
399 };
400
401 public ref class CecDatapacket
402 {
403 public:
404 CecDatapacket(void)
405 {
406 Data = gcnew array<uint8_t>(100);
407 Size = 0;
408 }
409
410 void PushBack(uint8_t data)
411 {
412 if (Size < 100)
413 {
414 Data[Size] = data;
415 Size++;
416 }
417 }
418
419 property array<uint8_t> ^ Data;
420 property uint8_t Size;
421 };
422
423 public ref class CecCommand
424 {
425 public:
426 CecCommand(CecLogicalAddress iInitiator, CecLogicalAddress iDestination, bool bAck, bool bEom, CecOpcode iOpcode, int32_t iTransmitTimeout)
427 {
428 Initiator = iInitiator;
429 Destination = iDestination;
430 Ack = bAck;
431 Eom = bEom;
432 Opcode = iOpcode;
433 OpcodeSet = true;
434 TransmitTimeout = iTransmitTimeout;
435 Parameters = gcnew CecDatapacket;
436 Empty = false;
437 }
438
439 CecCommand(void)
440 {
441 Initiator = CecLogicalAddress::Unknown;
442 Destination = CecLogicalAddress::Unknown;
443 Ack = false;
444 Eom = false;
445 Opcode = CecOpcode::None;
446 OpcodeSet = false;
447 TransmitTimeout = 0;
448 Parameters = gcnew CecDatapacket;
449 Empty = true;
450 }
451
452 void PushBack(uint8_t data)
453 {
454 if (Initiator == CecLogicalAddress::Unknown && Destination == CecLogicalAddress::Unknown)
455 {
456 Initiator = (CecLogicalAddress) (data >> 4);
457 Destination = (CecLogicalAddress) (data & 0xF);
458 }
459 else if (!OpcodeSet)
460 {
461 OpcodeSet = true;
462 Opcode = (CecOpcode)data;
463 }
464 else
465 {
466 Parameters->PushBack(data);
467 }
468 }
469
470 property bool Empty;
471 property CecLogicalAddress Initiator;
472 property CecLogicalAddress Destination;
473 property bool Ack;
474 property bool Eom;
475 property CecOpcode Opcode;
476 property CecDatapacket ^ Parameters;
477 property bool OpcodeSet;
478 property int32_t TransmitTimeout;
479 };
480
481 public ref class CecKeypress
482 {
483 public:
484 CecKeypress(int iKeycode, unsigned int iDuration)
485 {
486 Keycode = iKeycode;
487 Duration = iDuration;
488 Empty = false;
489 }
490
491 CecKeypress(void)
492 {
493 Keycode = 0;
494 Duration = 0;
495 Empty = true;
496 }
497
498 property bool Empty;
499 property int Keycode;
500 property unsigned int Duration;
501 };
502
503 public ref class CecLogMessage
504 {
505 public:
506 CecLogMessage(System::String ^ strMessage, CecLogLevel iLevel, int64_t iTime)
507 {
508 Message = strMessage;
509 Level = iLevel;
510 Time = iTime;
511 Empty = false;
512 }
513
514 CecLogMessage(void)
515 {
516 Message = "";
517 Level = CecLogLevel::None;
518 Time = 0;
519 Empty = true;
520 }
521
522 property bool Empty;
523 property System::String ^Message;
524 property CecLogLevel Level;
525 property int64_t Time;
526 };
527
32403cc3
LOK
528 ref class CecCallbackMethods; //forward
529 public ref class LibCECConfiguration
530 {
531 public:
532 LibCECConfiguration(void)
533 {
534 DeviceName = "";
535 DeviceTypes = gcnew CecDeviceTypeList();
8670c970 536 AutodetectAddress = true;
32403cc3
LOK
537 PhysicalAddress = CEC_DEFAULT_PHYSICAL_ADDRESS;
538 BaseDevice = (CecLogicalAddress)CEC_DEFAULT_BASE_DEVICE;
539 HDMIPort = CEC_DEFAULT_HDMI_PORT;
540 ClientVersion = CecClientVersion::VersionPre1_5;
3efda01a 541 ServerVersion = CecServerVersion::VersionPre1_5;
b7907707 542 TvVendor = CecVendorId::Unknown;
32403cc3
LOK
543
544 GetSettingsFromROM = false;
545 UseTVMenuLanguage = CEC_DEFAULT_SETTING_USE_TV_MENU_LANGUAGE == 1;
b7907707
LOK
546 ActivateSource = CEC_DEFAULT_SETTING_ACTIVATE_SOURCE == 1;
547
548 WakeDevices = gcnew CecLogicalAddresses();
549 if (CEC_DEFAULT_SETTING_ACTIVATE_SOURCE == 1)
550 WakeDevices->Set(CecLogicalAddress::Tv);
551
552 PowerOffDevices = gcnew CecLogicalAddresses();
553 if (CEC_DEFAULT_SETTING_POWER_OFF_SHUTDOWN == 1)
554 PowerOffDevices->Set(CecLogicalAddress::Broadcast);
555
32403cc3
LOK
556 PowerOffScreensaver = CEC_DEFAULT_SETTING_POWER_OFF_SCREENSAVER == 1;
557 PowerOffOnStandby = CEC_DEFAULT_SETTING_POWER_OFF_ON_STANDBY == 1;
a8fffd1b 558 SendInactiveSource = CEC_DEFAULT_SETTING_SEND_INACTIVE_SOURCE == 1;
b98fc43d
LOK
559 LogicalAddresses = gcnew CecLogicalAddresses();
560 FirmwareVersion = 1;
561 PowerOffDevicesOnStandby = CEC_DEFAULT_SETTING_POWER_OFF_DEVICES_STANDBY == 1;
32403cc3
LOK
562 }
563
564 void SetCallbacks(CecCallbackMethods ^callbacks)
565 {
566 Callbacks = callbacks;
567 }
568
3efda01a
LOK
569 void Update(const CEC::libcec_configuration &config)
570 {
571 DeviceName = gcnew System::String(config.strDeviceName);
572
573 for (unsigned int iPtr = 0; iPtr < 5; iPtr++)
574 DeviceTypes->Types[iPtr] = (CecDeviceType)config.deviceTypes.types[iPtr];
575
576 AutodetectAddress = config.bAutodetectAddress == 1;
577 PhysicalAddress = config.iPhysicalAddress;
578 BaseDevice = (CecLogicalAddress)config.baseDevice;
579 HDMIPort = config.iHDMIPort;
580 ClientVersion = (CecClientVersion)config.clientVersion;
581 ServerVersion = (CecServerVersion)config.serverVersion;
582 TvVendor = (CecVendorId)config.tvVendor;
583
584 // player specific settings
585 GetSettingsFromROM = config.bGetSettingsFromROM == 1;
586 UseTVMenuLanguage = config.bUseTVMenuLanguage == 1;
587 ActivateSource = config.bActivateSource == 1;
588
589 WakeDevices->Clear();
590 for (uint8_t iPtr = 0; iPtr <= 16; iPtr++)
591 if (config.wakeDevices[iPtr])
592 WakeDevices->Set((CecLogicalAddress)iPtr);
593
594 PowerOffDevices->Clear();
595 for (uint8_t iPtr = 0; iPtr <= 16; iPtr++)
596 if (config.powerOffDevices[iPtr])
597 PowerOffDevices->Set((CecLogicalAddress)iPtr);
598
599 PowerOffScreensaver = config.bPowerOffScreensaver == 1;
600 PowerOffOnStandby = config.bPowerOffOnStandby == 1;
b98fc43d
LOK
601
602 if (ServerVersion >= CecServerVersion::Version1_5_1)
603 SendInactiveSource = config.bSendInactiveSource == 1;
604
605 if (ServerVersion >= CecServerVersion::Version1_5_3)
606 {
607 LogicalAddresses->Clear();
608 for (uint8_t iPtr = 0; iPtr <= 16; iPtr++)
609 if (config.logicalAddresses[iPtr])
610 LogicalAddresses->Set((CecLogicalAddress)iPtr);
611 }
612
613 if (ServerVersion >= CecServerVersion::Version1_6_0)
614 {
615 FirmwareVersion = config.iFirmwareVersion;
616 PowerOffDevicesOnStandby = config.bPowerOffDevicesOnStandby == 1;
617 }
3efda01a
LOK
618 }
619
b7907707
LOK
620 property System::String ^ DeviceName;
621 property CecDeviceTypeList ^ DeviceTypes;
8670c970 622 property bool AutodetectAddress;
b7907707
LOK
623 property uint16_t PhysicalAddress;
624 property CecLogicalAddress BaseDevice;
625 property uint8_t HDMIPort;
626 property CecClientVersion ClientVersion;
3efda01a 627 property CecServerVersion ServerVersion;
b7907707 628 property CecVendorId TvVendor;
32403cc3
LOK
629
630 // player specific settings
b7907707
LOK
631 property bool GetSettingsFromROM;
632 property bool UseTVMenuLanguage;
633 property bool ActivateSource;
634 property CecLogicalAddresses ^WakeDevices;
635 property CecLogicalAddresses ^PowerOffDevices;
636 property bool PowerOffScreensaver;
637 property bool PowerOffOnStandby;
a8fffd1b 638 property bool SendInactiveSource;
b98fc43d
LOK
639 property CecLogicalAddresses ^LogicalAddresses;
640 property uint16_t FirmwareVersion;
641 property bool PowerOffDevicesOnStandby;
b7907707
LOK
642
643 property CecCallbackMethods ^ Callbacks;
32403cc3
LOK
644 };
645
4ef3b314
LOK
646 // the callback methods are called by unmanaged code, so we need some delegates for this
647 #pragma unmanaged
648 // unmanaged callback methods
649 typedef int (__stdcall *LOGCB) (const CEC::cec_log_message &message);
650 typedef int (__stdcall *KEYCB) (const CEC::cec_keypress &key);
651 typedef int (__stdcall *COMMANDCB)(const CEC::cec_command &command);
32403cc3 652 typedef int (__stdcall *CONFIGCB) (const CEC::libcec_configuration &config);
4ef3b314
LOK
653
654 static LOGCB g_logCB;
655 static KEYCB g_keyCB;
656 static COMMANDCB g_commandCB;
32403cc3 657 static CONFIGCB g_configCB;
4ef3b314
LOK
658 static CEC::ICECCallbacks g_cecCallbacks;
659
660 int CecLogMessageCB(void *cbParam, const CEC::cec_log_message &message)
661 {
662 if (g_logCB)
663 return g_logCB(message);
664 return 0;
665 }
666
667 int CecKeyPressCB(void *cbParam, const CEC::cec_keypress &key)
668 {
669 if (g_keyCB)
670 return g_keyCB(key);
671 return 0;
672 }
673
674 int CecCommandCB(void *cbParam, const CEC::cec_command &command)
675 {
676 if (g_commandCB)
677 return g_commandCB(command);
678 return 0;
679 }
680
32403cc3
LOK
681 int CecConfigCB(void *cbParam, const CEC::libcec_configuration &config)
682 {
683 if (g_configCB)
684 return g_configCB(config);
685 return 0;
686 }
687
4ef3b314
LOK
688 #pragma managed
689 // delegates for the unmanaged callback methods
690 public delegate int CecLogMessageManagedDelegate(const CEC::cec_log_message &);
691 public delegate int CecKeyPressManagedDelegate(const CEC::cec_keypress &);
692 public delegate int CecCommandManagedDelegate(const CEC::cec_command &);
32403cc3 693 public delegate int CecConfigManagedDelegate(const CEC::libcec_configuration &);
4ef3b314
LOK
694
695 // callback method interface
696 public ref class CecCallbackMethods
697 {
698 public:
11fea069
LOK
699 CecCallbackMethods(void)
700 {
701 m_bHasCallbacks = false;
702 m_bDelegatesCreated = false;
703 }
4ef3b314
LOK
704
705 ~CecCallbackMethods(void)
706 {
707 DestroyDelegates();
708 }
709
710 protected:
711 !CecCallbackMethods(void)
712 {
713 DestroyDelegates();
714 }
715
716 public:
dae4328c
LOK
717 virtual void DisableCallbacks(void)
718 {
11fea069 719 DestroyDelegates();
dae4328c 720 }
11fea069 721
4ef3b314
LOK
722 virtual bool EnableCallbacks(CecCallbackMethods ^ callbacks)
723 {
11fea069 724 CreateDelegates();
4ef3b314
LOK
725 if (!m_bHasCallbacks)
726 {
727 m_bHasCallbacks = true;
728 m_callbacks = callbacks;
729 return true;
730 }
731
732 return false;
733 }
734
735 virtual int ReceiveLogMessage(CecLogMessage ^ message)
736 {
737 return 0;
738 }
739
740 virtual int ReceiveKeypress(CecKeypress ^ key)
741 {
742 return 0;
743 }
744
745 virtual int ReceiveCommand(CecCommand ^ command)
746 {
747 return 0;
748 }
749
32403cc3
LOK
750 virtual int ConfigurationChanged(LibCECConfiguration ^ config)
751 {
752 return 0;
753 }
4ef3b314
LOK
754 protected:
755 // managed callback methods
756 int CecLogMessageManaged(const CEC::cec_log_message &message)
757 {
758 int iReturn(0);
759 if (m_bHasCallbacks)
760 iReturn = m_callbacks->ReceiveLogMessage(gcnew CecLogMessage(gcnew System::String(message.message), (CecLogLevel)message.level, message.time));
761 return iReturn;
762 }
763
764 int CecKeyPressManaged(const CEC::cec_keypress &key)
765 {
766 int iReturn(0);
767 if (m_bHasCallbacks)
768 iReturn = m_callbacks->ReceiveKeypress(gcnew CecKeypress(key.keycode, key.duration));
769 return iReturn;
770 }
771
772 int CecCommandManaged(const CEC::cec_command &command)
773 {
774 int iReturn(0);
775 if (m_bHasCallbacks)
776 {
777 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);
778 for (uint8_t iPtr = 0; iPtr < command.parameters.size; iPtr++)
779 newCommand->Parameters->PushBack(command.parameters[iPtr]);
780 iReturn = m_callbacks->ReceiveCommand(newCommand);
781 }
782 return iReturn;
783 }
784
32403cc3
LOK
785 int CecConfigManaged(const CEC::libcec_configuration &config)
786 {
787 int iReturn(0);
788 if (m_bHasCallbacks)
789 {
790 LibCECConfiguration ^netConfig = gcnew LibCECConfiguration();
3efda01a 791 netConfig->Update(config);
32403cc3
LOK
792 iReturn = m_callbacks->ConfigurationChanged(netConfig);
793 }
794 return iReturn;
795 }
796
4ef3b314
LOK
797 void DestroyDelegates()
798 {
11fea069
LOK
799 m_bHasCallbacks = false;
800 if (m_bDelegatesCreated)
006b76b9 801 {
11fea069 802 m_bDelegatesCreated = false;
006b76b9
LOK
803 m_logMessageGCHandle.Free();
804 m_keypressGCHandle.Free();
805 m_commandGCHandle.Free();
806 }
4ef3b314
LOK
807 }
808
11fea069
LOK
809 void CreateDelegates()
810 {
811 DestroyDelegates();
812
813 if (!m_bDelegatesCreated)
814 {
815 msclr::interop::marshal_context ^ context = gcnew msclr::interop::marshal_context();
816
817 // create the delegate method for the log message callback
818 m_logMessageDelegate = gcnew CecLogMessageManagedDelegate(this, &CecCallbackMethods::CecLogMessageManaged);
819 m_logMessageGCHandle = System::Runtime::InteropServices::GCHandle::Alloc(m_logMessageDelegate);
820 g_logCB = static_cast<LOGCB>(System::Runtime::InteropServices::Marshal::GetFunctionPointerForDelegate(m_logMessageDelegate).ToPointer());
821 g_cecCallbacks.CBCecLogMessage = CecLogMessageCB;
822
823 // create the delegate method for the keypress callback
824 m_keypressDelegate = gcnew CecKeyPressManagedDelegate(this, &CecCallbackMethods::CecKeyPressManaged);
825 m_keypressGCHandle = System::Runtime::InteropServices::GCHandle::Alloc(m_keypressDelegate);
826 g_keyCB = static_cast<KEYCB>(System::Runtime::InteropServices::Marshal::GetFunctionPointerForDelegate(m_keypressDelegate).ToPointer());
827 g_cecCallbacks.CBCecKeyPress = CecKeyPressCB;
828
829 // create the delegate method for the command callback
830 m_commandDelegate = gcnew CecCommandManagedDelegate(this, &CecCallbackMethods::CecCommandManaged);
831 m_commandGCHandle = System::Runtime::InteropServices::GCHandle::Alloc(m_commandDelegate);
832 g_commandCB = static_cast<COMMANDCB>(System::Runtime::InteropServices::Marshal::GetFunctionPointerForDelegate(m_commandDelegate).ToPointer());
833 g_cecCallbacks.CBCecCommand = CecCommandCB;
834
835 // create the delegate method for the configuration change callback
836 m_configDelegate = gcnew CecConfigManagedDelegate(this, &CecCallbackMethods::CecConfigManaged);
837 m_configGCHandle = System::Runtime::InteropServices::GCHandle::Alloc(m_configDelegate);
838 g_configCB = static_cast<CONFIGCB>(System::Runtime::InteropServices::Marshal::GetFunctionPointerForDelegate(m_configDelegate).ToPointer());
839 g_cecCallbacks.CBCecConfigurationChanged = CecConfigCB;
840
841 delete context;
842 m_bDelegatesCreated = true;
843 }
844 }
845
4ef3b314
LOK
846 CecLogMessageManagedDelegate ^ m_logMessageDelegate;
847 static System::Runtime::InteropServices::GCHandle m_logMessageGCHandle;
848 LOGCB m_logMessageCallback;
849
850 CecKeyPressManagedDelegate ^ m_keypressDelegate;
851 static System::Runtime::InteropServices::GCHandle m_keypressGCHandle;
852 KEYCB m_keypressCallback;
853
854 CecCommandManagedDelegate ^ m_commandDelegate;
855 static System::Runtime::InteropServices::GCHandle m_commandGCHandle;
856 COMMANDCB m_commandCallback;
857
32403cc3
LOK
858 CecConfigManagedDelegate ^ m_configDelegate;
859 static System::Runtime::InteropServices::GCHandle m_configGCHandle;
860 CONFIGCB m_configCallback;
861
4ef3b314
LOK
862 CecCallbackMethods ^ m_callbacks;
863 bool m_bHasCallbacks;
11fea069 864 bool m_bDelegatesCreated;
4ef3b314 865 };
4ef3b314 866}