added a callback for clients that is called when a source is (de)activated, so the...
[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
6e919697
MK
86 public enum class CecAlert
87 {
88 ServiceDevice = 1
89 };
90
91 public enum class CecParameterType
92 {
93 ParameterTypeString = 1
94 };
95
96 public ref class CecParameter
97 {
98 public:
99 CecParameter(CecParameterType type, System::String ^ strData)
100 {
101 Type = type;
102 Data = strData;
103 }
104
105 property CecParameterType Type;
106 property System::String ^ Data;
107 };
108
4ef3b314
LOK
109 public enum class CecPowerStatus
110 {
111 On = 0x00,
112 Standby = 0x01,
113 InTransitionStandbyToOn = 0x02,
114 InTransitionOnToStandby = 0x03,
115 Unknown = 0x99
116 };
117
118 public enum class CecVersion
119 {
120 Unknown = 0x00,
121 V1_2 = 0x01,
122 V1_2A = 0x02,
123 V1_3 = 0x03,
124 V1_3A = 0x04,
125 V1_4 = 0x05
126 };
127
128 public enum class CecDisplayControl
129 {
130 DisplayForDefaultTime = 0x00,
131 DisplayUntilCleared = 0x40,
132 ClearPreviousMessage = 0x80,
133 ReservedForFutureUse = 0xC0
134 };
135
136 public enum class CecMenuState
137 {
138 Activated = 0,
139 Deactivated = 1
140 };
141
142 public enum class CecDeckControlMode
143 {
144 SkipForwardWind = 1,
145 SkipReverseRewind = 2,
146 Stop = 3,
147 Eject = 4
148 };
149
150 public enum class CecDeckInfo
151 {
152 Play = 0x11,
153 Record = 0x12,
154 Reverse = 0x13,
155 Still = 0x14,
156 Slow = 0x15,
157 SlowReverse = 0x16,
158 FastForward = 0x17,
159 FastReverse = 0x18,
160 NoMedia = 0x19,
161 Stop = 0x1A,
162 SkipForwardWind = 0x1B,
163 SkipReverseRewind = 0x1C,
164 IndexSearchForward = 0x1D,
165 IndexSearchReverse = 0x1E,
166 OtherStatus = 0x1F
167 };
168
169 public enum class CecUserControlCode
170 {
171 Select = 0x00,
172 Up = 0x01,
173 Down = 0x02,
174 Left = 0x03,
175 Right = 0x04,
176 RightUp = 0x05,
177 RightDown = 0x06,
178 LeftUp = 0x07,
179 LeftDown = 0x08,
180 RootMenu = 0x09,
181 SetupMenu = 0x0A,
182 ContentsMenu = 0x0B,
183 FavoriteMenu = 0x0C,
184 Exit = 0x0D,
185 Number0 = 0x20,
186 Number1 = 0x21,
187 Number2 = 0x22,
188 Number3 = 0x23,
189 Number4 = 0x24,
190 Number5 = 0x25,
191 Number6 = 0x26,
192 Number7 = 0x27,
193 Number8 = 0x28,
194 Number9 = 0x29,
195 Dot = 0x2A,
196 Enter = 0x2B,
197 Clear = 0x2C,
198 NextFavorite = 0x2F,
199 ChannelUp = 0x30,
200 ChannelDown = 0x31,
201 PreviousChannel = 0x32,
202 SoundSelect = 0x33,
203 InputSelect = 0x34,
204 DisplayInformation = 0x35,
205 Help = 0x36,
206 PageUp = 0x37,
207 PageDown = 0x38,
208 Power = 0x40,
209 VolumeUp = 0x41,
210 VolumeDown = 0x42,
211 Mute = 0x43,
212 Play = 0x44,
213 Stop = 0x45,
214 Pause = 0x46,
215 Record = 0x47,
216 Rewind = 0x48,
217 FastForward = 0x49,
218 Eject = 0x4A,
219 Forward = 0x4B,
220 Backward = 0x4C,
221 StopRecord = 0x4D,
222 PauseRecord = 0x4E,
223 Angle = 0x50,
224 SubPicture = 0x51,
225 VideoOnDemand = 0x52,
226 ElectronicProgramGuide = 0x53,
227 TimerProgramming = 0x54,
228 InitialConfiguration = 0x55,
229 PlayFunction = 0x60,
230 PausePlayFunction = 0x61,
231 RecordFunction = 0x62,
232 PauseRecordFunction = 0x63,
233 StopFunction = 0x64,
234 MuteFunction = 0x65,
235 RestoreVolumeFunction = 0x66,
236 TuneFunction = 0x67,
237 SelectMediaFunction = 0x68,
238 SelectAVInputFunction = 0x69,
239 SelectAudioInputFunction = 0x6A,
240 PowerToggleFunction = 0x6B,
241 PowerOffFunction = 0x6C,
242 PowerOnFunction = 0x6D,
243 F1Blue = 0x71,
244 F2Red = 0X72,
245 F3Green = 0x73,
246 F4Yellow = 0x74,
247 F5 = 0x75,
248 Data = 0x76,
249 Max = 0x76,
04be3a97 250 SamsungReturn = 0x91,
4ef3b314
LOK
251 Unknown
252 };
253
254 public enum class CecVendorId
255 {
256 Samsung = 0x00F0,
257 LG = 0xE091,
258 Panasonic = 0x8045,
259 Pioneer = 0xE036,
260 Onkyo = 0x09B0,
261 Yamaha = 0xA0DE,
262 Philips = 0x903E,
de90f347 263 Sony = 0x080046,
4ef3b314
LOK
264 Unknown = 0
265 };
266
267 public enum class CecAudioStatus
268 {
269 MuteStatusMask = 0x80,
270 VolumeStatusMask = 0x7F,
271 VolumeMin = 0x00,
272 VolumeMax = 0x64,
273 VolumeStatusUnknown = 0x7F
274 };
275
276 public enum class CecOpcode
277 {
278 ActiveSource = 0x82,
279 ImageViewOn = 0x04,
280 TextViewOn = 0x0D,
281 InactiveSource = 0x9D,
282 RequestActiveSource = 0x85,
283 RoutingChange = 0x80,
284 RoutingInformation = 0x81,
285 SetStreamPath = 0x86,
286 Standby = 0x36,
287 RecordOff = 0x0B,
288 RecordOn = 0x09,
289 RecordStatus = 0x0A,
290 RecordTvScreen = 0x0F,
291 ClearAnalogueTimer = 0x33,
292 ClearDigitalTimer = 0x99,
293 ClearExternalTimer = 0xA1,
294 SetAnalogueTimer = 0x34,
295 SetDigitalTimer = 0x97,
296 SetExternalTimer = 0xA2,
297 SetTimerProgramTitle = 0x67,
298 TimerClearedStatus = 0x43,
299 TimerStatus = 0x35,
300 CecVersion = 0x9E,
301 GetCecVersion = 0x9F,
302 GivePhysicalAddress = 0x83,
303 GetMenuLanguage = 0x91,
304 ReportPhysicalAddress = 0x84,
305 SetMenuLanguage = 0x32,
306 DeckControl = 0x42,
307 DeckStatus = 0x1B,
308 GiveDeckStatus = 0x1A,
309 Play = 0x41,
310 GiveTunerDeviceStatus = 0x08,
311 SelectAnalogueService = 0x92,
312 SelectDigtalService = 0x93,
313 TunerDeviceStatus = 0x07,
314 TunerStepDecrement = 0x06,
315 TunerStepIncrement = 0x05,
316 DeviceVendorId = 0x87,
317 GiveDeviceVendorId = 0x8C,
318 VendorCommand = 0x89,
319 VendorCommandWithId = 0xA0,
320 VendorRemoteButtonDown = 0x8A,
321 VendorRemoteButtonUp = 0x8B,
322 SetOsdString = 0x64,
323 GiveOsdName = 0x46,
324 SetOsdName = 0x47,
325 MenuRequest = 0x8D,
326 MenuStatus = 0x8E,
327 UserControlPressed = 0x44,
328 UserControlRelease = 0x45,
329 GiveDevicePowerStatus = 0x8F,
330 ReportPowerStatus = 0x90,
331 FeatureAbort = 0x00,
332 Abort = 0xFF,
333 GiveAudioStatus = 0x71,
334 GiveSystemAudioMode = 0x7D,
335 ReportAudioStatus = 0x7A,
336 SetSystemAudioMode = 0x72,
337 SystemAudioModeRequest = 0x70,
338 SystemAudioModeStatus = 0x7E,
339 SetAudioRate = 0x9A,
340 /* when this opcode is set, no opcode will be sent to the device. this is one of the reserved numbers */
341 None = 0xFD
342 };
343
344 public enum class CecSystemAudioStatus
345 {
346 Off = 0,
347 On = 1
348 };
349
350 public enum class CecClientVersion
351 {
352 VersionPre1_5 = 0,
a8fffd1b 353 Version1_5_0 = 0x1500,
e4a7396c
LOK
354 Version1_5_1 = 0x1501,
355 Version1_5_2 = 0x1502,
356 Version1_5_3 = 0x1503,
357 Version1_6_0 = 0x1600,
6d0364f9 358 Version1_6_1 = 0x1601,
c2ce7bd1
LOK
359 Version1_6_2 = 0x1602,
360 Version1_6_3 = 0x1603,
361 Version1_7_0 = 0x1700,
362 Version1_7_1 = 0x1701
4ef3b314
LOK
363 };
364
e4a7396c 365 public enum class CecServerVersion
3efda01a
LOK
366 {
367 VersionPre1_5 = 0,
a8fffd1b 368 Version1_5_0 = 0x1500,
e4a7396c
LOK
369 Version1_5_1 = 0x1501,
370 Version1_5_2 = 0x1502,
371 Version1_5_3 = 0x1503,
372 Version1_6_0 = 0x1600,
6d0364f9 373 Version1_6_1 = 0x1601,
c2ce7bd1
LOK
374 Version1_6_2 = 0x1602,
375 Version1_6_3 = 0x1603,
376 Version1_7_0 = 0x1700,
377 Version1_7_1 = 0x1701
3efda01a
LOK
378 };
379
4ef3b314
LOK
380 public ref class CecAdapter
381 {
382 public:
383 CecAdapter(System::String ^ strPath, System::String ^ strComPort)
384 {
385 Path = strPath;
386 ComPort = strComPort;
387 }
388
389 property System::String ^ Path;
390 property System::String ^ ComPort;
391 };
392
393 public ref class CecDeviceTypeList
394 {
395 public:
396 CecDeviceTypeList(void)
397 {
398 Types = gcnew array<CecDeviceType>(5);
399 for (unsigned int iPtr = 0; iPtr < 5; iPtr++)
400 Types[iPtr] = CecDeviceType::Reserved;
401 }
402
403 property array<CecDeviceType> ^ Types;
404 };
405
406 public ref class CecLogicalAddresses
407 {
408 public:
409 CecLogicalAddresses(void)
410 {
411 Addresses = gcnew array<CecLogicalAddress>(16);
b7907707
LOK
412 Clear();
413 }
414
415 void Clear(void)
416 {
4ef3b314 417 for (unsigned int iPtr = 0; iPtr < 16; iPtr++)
63851508 418 Addresses[iPtr] = CecLogicalAddress::Unknown;
4ef3b314
LOK
419 }
420
421 bool IsSet(CecLogicalAddress iAddress)
422 {
63851508 423 return Addresses[(unsigned int)iAddress] != CecLogicalAddress::Unknown;
4ef3b314
LOK
424 }
425
b7907707
LOK
426 void Set(CecLogicalAddress iAddress)
427 {
428 Addresses[(unsigned int)iAddress] = iAddress;
429 }
430
a9fb46b4 431 property CecLogicalAddress Primary;
4ef3b314
LOK
432 property array<CecLogicalAddress> ^ Addresses;
433 };
434
435 public ref class CecDatapacket
436 {
437 public:
438 CecDatapacket(void)
439 {
440 Data = gcnew array<uint8_t>(100);
441 Size = 0;
442 }
443
444 void PushBack(uint8_t data)
445 {
446 if (Size < 100)
447 {
448 Data[Size] = data;
449 Size++;
450 }
451 }
452
453 property array<uint8_t> ^ Data;
454 property uint8_t Size;
455 };
456
457 public ref class CecCommand
458 {
459 public:
460 CecCommand(CecLogicalAddress iInitiator, CecLogicalAddress iDestination, bool bAck, bool bEom, CecOpcode iOpcode, int32_t iTransmitTimeout)
461 {
462 Initiator = iInitiator;
463 Destination = iDestination;
464 Ack = bAck;
465 Eom = bEom;
466 Opcode = iOpcode;
467 OpcodeSet = true;
468 TransmitTimeout = iTransmitTimeout;
469 Parameters = gcnew CecDatapacket;
470 Empty = false;
471 }
472
473 CecCommand(void)
474 {
475 Initiator = CecLogicalAddress::Unknown;
476 Destination = CecLogicalAddress::Unknown;
477 Ack = false;
478 Eom = false;
479 Opcode = CecOpcode::None;
480 OpcodeSet = false;
481 TransmitTimeout = 0;
482 Parameters = gcnew CecDatapacket;
483 Empty = true;
484 }
485
486 void PushBack(uint8_t data)
487 {
488 if (Initiator == CecLogicalAddress::Unknown && Destination == CecLogicalAddress::Unknown)
489 {
490 Initiator = (CecLogicalAddress) (data >> 4);
491 Destination = (CecLogicalAddress) (data & 0xF);
492 }
493 else if (!OpcodeSet)
494 {
495 OpcodeSet = true;
496 Opcode = (CecOpcode)data;
497 }
498 else
499 {
500 Parameters->PushBack(data);
501 }
502 }
503
504 property bool Empty;
505 property CecLogicalAddress Initiator;
506 property CecLogicalAddress Destination;
507 property bool Ack;
508 property bool Eom;
509 property CecOpcode Opcode;
510 property CecDatapacket ^ Parameters;
511 property bool OpcodeSet;
512 property int32_t TransmitTimeout;
513 };
514
515 public ref class CecKeypress
516 {
517 public:
04be3a97 518 CecKeypress(CecUserControlCode iKeycode, unsigned int iDuration)
4ef3b314
LOK
519 {
520 Keycode = iKeycode;
521 Duration = iDuration;
522 Empty = false;
523 }
524
525 CecKeypress(void)
526 {
04be3a97 527 Keycode = CecUserControlCode::Unknown;
4ef3b314
LOK
528 Duration = 0;
529 Empty = true;
530 }
531
04be3a97
LOK
532 property bool Empty;
533 property CecUserControlCode Keycode;
534 property unsigned int Duration;
4ef3b314
LOK
535 };
536
537 public ref class CecLogMessage
538 {
539 public:
540 CecLogMessage(System::String ^ strMessage, CecLogLevel iLevel, int64_t iTime)
541 {
542 Message = strMessage;
543 Level = iLevel;
544 Time = iTime;
545 Empty = false;
546 }
547
548 CecLogMessage(void)
549 {
550 Message = "";
551 Level = CecLogLevel::None;
552 Time = 0;
553 Empty = true;
554 }
555
556 property bool Empty;
557 property System::String ^Message;
558 property CecLogLevel Level;
559 property int64_t Time;
560 };
561
32403cc3
LOK
562 ref class CecCallbackMethods; //forward
563 public ref class LibCECConfiguration
564 {
565 public:
566 LibCECConfiguration(void)
567 {
568 DeviceName = "";
569 DeviceTypes = gcnew CecDeviceTypeList();
8670c970 570 AutodetectAddress = true;
32403cc3
LOK
571 PhysicalAddress = CEC_DEFAULT_PHYSICAL_ADDRESS;
572 BaseDevice = (CecLogicalAddress)CEC_DEFAULT_BASE_DEVICE;
573 HDMIPort = CEC_DEFAULT_HDMI_PORT;
574 ClientVersion = CecClientVersion::VersionPre1_5;
3efda01a 575 ServerVersion = CecServerVersion::VersionPre1_5;
b7907707 576 TvVendor = CecVendorId::Unknown;
32403cc3
LOK
577
578 GetSettingsFromROM = false;
579 UseTVMenuLanguage = CEC_DEFAULT_SETTING_USE_TV_MENU_LANGUAGE == 1;
b7907707
LOK
580 ActivateSource = CEC_DEFAULT_SETTING_ACTIVATE_SOURCE == 1;
581
582 WakeDevices = gcnew CecLogicalAddresses();
583 if (CEC_DEFAULT_SETTING_ACTIVATE_SOURCE == 1)
584 WakeDevices->Set(CecLogicalAddress::Tv);
585
586 PowerOffDevices = gcnew CecLogicalAddresses();
587 if (CEC_DEFAULT_SETTING_POWER_OFF_SHUTDOWN == 1)
588 PowerOffDevices->Set(CecLogicalAddress::Broadcast);
589
32403cc3
LOK
590 PowerOffScreensaver = CEC_DEFAULT_SETTING_POWER_OFF_SCREENSAVER == 1;
591 PowerOffOnStandby = CEC_DEFAULT_SETTING_POWER_OFF_ON_STANDBY == 1;
92da1117
MK
592
593 SendInactiveSource = CEC_DEFAULT_SETTING_SEND_INACTIVE_SOURCE == 1;
594 LogicalAddresses = gcnew CecLogicalAddresses();
595 FirmwareVersion = 1;
596 PowerOffDevicesOnStandby = CEC_DEFAULT_SETTING_POWER_OFF_DEVICES_STANDBY == 1;
597 ShutdownOnStandby = CEC_DEFAULT_SETTING_SHUTDOWN_ON_STANDBY == 1;
598 DeviceLanguage = "";
32403cc3
LOK
599 }
600
601 void SetCallbacks(CecCallbackMethods ^callbacks)
602 {
603 Callbacks = callbacks;
604 }
605
3efda01a
LOK
606 void Update(const CEC::libcec_configuration &config)
607 {
608 DeviceName = gcnew System::String(config.strDeviceName);
609
610 for (unsigned int iPtr = 0; iPtr < 5; iPtr++)
611 DeviceTypes->Types[iPtr] = (CecDeviceType)config.deviceTypes.types[iPtr];
612
613 AutodetectAddress = config.bAutodetectAddress == 1;
614 PhysicalAddress = config.iPhysicalAddress;
615 BaseDevice = (CecLogicalAddress)config.baseDevice;
616 HDMIPort = config.iHDMIPort;
617 ClientVersion = (CecClientVersion)config.clientVersion;
618 ServerVersion = (CecServerVersion)config.serverVersion;
619 TvVendor = (CecVendorId)config.tvVendor;
620
621 // player specific settings
622 GetSettingsFromROM = config.bGetSettingsFromROM == 1;
623 UseTVMenuLanguage = config.bUseTVMenuLanguage == 1;
624 ActivateSource = config.bActivateSource == 1;
625
626 WakeDevices->Clear();
627 for (uint8_t iPtr = 0; iPtr <= 16; iPtr++)
628 if (config.wakeDevices[iPtr])
629 WakeDevices->Set((CecLogicalAddress)iPtr);
630
631 PowerOffDevices->Clear();
632 for (uint8_t iPtr = 0; iPtr <= 16; iPtr++)
633 if (config.powerOffDevices[iPtr])
634 PowerOffDevices->Set((CecLogicalAddress)iPtr);
635
636 PowerOffScreensaver = config.bPowerOffScreensaver == 1;
637 PowerOffOnStandby = config.bPowerOffOnStandby == 1;
b98fc43d 638
92da1117
MK
639 if (ServerVersion >= CecServerVersion::Version1_5_1)
640 SendInactiveSource = config.bSendInactiveSource == 1;
641
642 if (ServerVersion >= CecServerVersion::Version1_5_3)
643 {
644 LogicalAddresses->Clear();
645 for (uint8_t iPtr = 0; iPtr <= 16; iPtr++)
646 if (config.logicalAddresses[iPtr])
647 LogicalAddresses->Set((CecLogicalAddress)iPtr);
648 }
649
650 if (ServerVersion >= CecServerVersion::Version1_6_0)
651 {
652 FirmwareVersion = config.iFirmwareVersion;
653 PowerOffDevicesOnStandby = config.bPowerOffDevicesOnStandby == 1;
654 ShutdownOnStandby = config.bShutdownOnStandby == 1;
655 }
656
657 if (ServerVersion >= CecServerVersion::Version1_6_2)
658 DeviceLanguage = gcnew System::String(config.strDeviceLanguage);
d3b96c62
LOK
659
660 if (ServerVersion >= CecServerVersion::Version1_6_3)
661 MonitorOnlyClient = config.bMonitorOnly == 1;
3efda01a
LOK
662 }
663
b7907707
LOK
664 property System::String ^ DeviceName;
665 property CecDeviceTypeList ^ DeviceTypes;
8670c970 666 property bool AutodetectAddress;
b7907707
LOK
667 property uint16_t PhysicalAddress;
668 property CecLogicalAddress BaseDevice;
669 property uint8_t HDMIPort;
670 property CecClientVersion ClientVersion;
3efda01a 671 property CecServerVersion ServerVersion;
b7907707 672 property CecVendorId TvVendor;
32403cc3
LOK
673
674 // player specific settings
b7907707
LOK
675 property bool GetSettingsFromROM;
676 property bool UseTVMenuLanguage;
677 property bool ActivateSource;
678 property CecLogicalAddresses ^WakeDevices;
679 property CecLogicalAddresses ^PowerOffDevices;
680 property bool PowerOffScreensaver;
681 property bool PowerOffOnStandby;
92da1117
MK
682 property bool SendInactiveSource;
683 property CecLogicalAddresses ^LogicalAddresses;
684 property uint16_t FirmwareVersion;
685 property bool PowerOffDevicesOnStandby;
686 property bool ShutdownOnStandby;
d3b96c62 687 property bool MonitorOnlyClient;
92da1117 688 property System::String ^ DeviceLanguage;
b7907707 689 property CecCallbackMethods ^ Callbacks;
32403cc3
LOK
690 };
691
4ef3b314
LOK
692 // the callback methods are called by unmanaged code, so we need some delegates for this
693 #pragma unmanaged
694 // unmanaged callback methods
695 typedef int (__stdcall *LOGCB) (const CEC::cec_log_message &message);
696 typedef int (__stdcall *KEYCB) (const CEC::cec_keypress &key);
697 typedef int (__stdcall *COMMANDCB)(const CEC::cec_command &command);
32403cc3 698 typedef int (__stdcall *CONFIGCB) (const CEC::libcec_configuration &config);
6e919697 699 typedef int (__stdcall *ALERTCB) (const CEC::libcec_alert, const CEC::libcec_parameter &data);
c3a20edb 700 typedef int (__stdcall *MENUCB) (const CEC::cec_menu_state newVal);
29d5198c 701 typedef void (__stdcall *ACTICB) (const CEC::cec_logical_address logicalAddress, const uint8_t bActivated);
4ef3b314
LOK
702
703 static LOGCB g_logCB;
704 static KEYCB g_keyCB;
705 static COMMANDCB g_commandCB;
32403cc3 706 static CONFIGCB g_configCB;
6e919697 707 static ALERTCB g_alertCB;
c3a20edb 708 static MENUCB g_menuCB;
29d5198c 709 static ACTICB g_sourceActivatedCB;
4ef3b314
LOK
710 static CEC::ICECCallbacks g_cecCallbacks;
711
712 int CecLogMessageCB(void *cbParam, const CEC::cec_log_message &message)
713 {
714 if (g_logCB)
715 return g_logCB(message);
716 return 0;
717 }
718
719 int CecKeyPressCB(void *cbParam, const CEC::cec_keypress &key)
720 {
721 if (g_keyCB)
722 return g_keyCB(key);
723 return 0;
724 }
725
726 int CecCommandCB(void *cbParam, const CEC::cec_command &command)
727 {
728 if (g_commandCB)
729 return g_commandCB(command);
730 return 0;
731 }
732
32403cc3
LOK
733 int CecConfigCB(void *cbParam, const CEC::libcec_configuration &config)
734 {
735 if (g_configCB)
736 return g_configCB(config);
737 return 0;
738 }
739
6e919697 740 int CecAlertCB(void *cbParam, const CEC::libcec_alert alert, const CEC::libcec_parameter &data)
5ee37222
MK
741 {
742 if (g_alertCB)
743 return g_alertCB(alert, data);
744 return 0;
745 }
746
c3a20edb
LOK
747 int CecMenuCB(void *cbParam, const CEC::cec_menu_state newVal)
748 {
749 if (g_menuCB)
750 return g_menuCB(newVal);
751 return 0;
752 }
753
29d5198c
LOK
754 void CecSourceActivatedCB(void *cbParam, const CEC::cec_logical_address logicalAddress, const uint8_t bActivated)
755 {
756 if (g_sourceActivatedCB)
757 g_sourceActivatedCB(logicalAddress, bActivated);
758 }
759
4ef3b314
LOK
760 #pragma managed
761 // delegates for the unmanaged callback methods
762 public delegate int CecLogMessageManagedDelegate(const CEC::cec_log_message &);
763 public delegate int CecKeyPressManagedDelegate(const CEC::cec_keypress &);
764 public delegate int CecCommandManagedDelegate(const CEC::cec_command &);
32403cc3 765 public delegate int CecConfigManagedDelegate(const CEC::libcec_configuration &);
5ee37222 766 public delegate int CecAlertManagedDelegate(const CEC::libcec_alert, const CEC::libcec_parameter &);
c3a20edb 767 public delegate int CecMenuManagedDelegate(const CEC::cec_menu_state newVal);
29d5198c 768 public delegate void CecSourceActivatedManagedDelegate(const CEC::cec_logical_address logicalAddress, const uint8_t bActivated);
4ef3b314
LOK
769
770 // callback method interface
771 public ref class CecCallbackMethods
772 {
773 public:
11fea069
LOK
774 CecCallbackMethods(void)
775 {
776 m_bHasCallbacks = false;
777 m_bDelegatesCreated = false;
778 }
4ef3b314
LOK
779
780 ~CecCallbackMethods(void)
781 {
782 DestroyDelegates();
783 }
784
785 protected:
786 !CecCallbackMethods(void)
787 {
788 DestroyDelegates();
789 }
790
791 public:
dae4328c
LOK
792 virtual void DisableCallbacks(void)
793 {
11fea069 794 DestroyDelegates();
dae4328c 795 }
11fea069 796
4ef3b314
LOK
797 virtual bool EnableCallbacks(CecCallbackMethods ^ callbacks)
798 {
11fea069 799 CreateDelegates();
4ef3b314
LOK
800 if (!m_bHasCallbacks)
801 {
802 m_bHasCallbacks = true;
803 m_callbacks = callbacks;
804 return true;
805 }
806
807 return false;
808 }
809
810 virtual int ReceiveLogMessage(CecLogMessage ^ message)
811 {
812 return 0;
813 }
814
815 virtual int ReceiveKeypress(CecKeypress ^ key)
816 {
817 return 0;
818 }
819
820 virtual int ReceiveCommand(CecCommand ^ command)
821 {
822 return 0;
823 }
824
32403cc3
LOK
825 virtual int ConfigurationChanged(LibCECConfiguration ^ config)
826 {
827 return 0;
828 }
6e919697
MK
829
830 virtual int ReceiveAlert(CecAlert alert, CecParameter ^ data)
831 {
832 return 0;
833 }
834
c3a20edb
LOK
835 virtual int ReceiveMenuStateChange(CecMenuState newVal)
836 {
837 return 0;
838 }
839
29d5198c
LOK
840 virtual void SourceActivated(CecLogicalAddress logicalAddress, bool bActivated)
841 {
842 }
843
4ef3b314
LOK
844 protected:
845 // managed callback methods
846 int CecLogMessageManaged(const CEC::cec_log_message &message)
847 {
848 int iReturn(0);
849 if (m_bHasCallbacks)
850 iReturn = m_callbacks->ReceiveLogMessage(gcnew CecLogMessage(gcnew System::String(message.message), (CecLogLevel)message.level, message.time));
851 return iReturn;
852 }
853
854 int CecKeyPressManaged(const CEC::cec_keypress &key)
855 {
856 int iReturn(0);
857 if (m_bHasCallbacks)
04be3a97 858 iReturn = m_callbacks->ReceiveKeypress(gcnew CecKeypress((CecUserControlCode)key.keycode, key.duration));
4ef3b314
LOK
859 return iReturn;
860 }
861
862 int CecCommandManaged(const CEC::cec_command &command)
863 {
864 int iReturn(0);
865 if (m_bHasCallbacks)
866 {
867 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);
868 for (uint8_t iPtr = 0; iPtr < command.parameters.size; iPtr++)
869 newCommand->Parameters->PushBack(command.parameters[iPtr]);
870 iReturn = m_callbacks->ReceiveCommand(newCommand);
871 }
872 return iReturn;
873 }
874
32403cc3
LOK
875 int CecConfigManaged(const CEC::libcec_configuration &config)
876 {
877 int iReturn(0);
878 if (m_bHasCallbacks)
879 {
880 LibCECConfiguration ^netConfig = gcnew LibCECConfiguration();
3efda01a 881 netConfig->Update(config);
32403cc3
LOK
882 iReturn = m_callbacks->ConfigurationChanged(netConfig);
883 }
884 return iReturn;
885 }
886
6e919697
MK
887 int CecAlertManaged(const CEC::libcec_alert alert, const CEC::libcec_parameter &data)
888 {
889 int iReturn(0);
890 if (m_bHasCallbacks)
891 {
892 CecParameterType newType = (CecParameterType)data.paramType;
893 if (newType == CecParameterType::ParameterTypeString)
894 {
895 System::String ^ newData = gcnew System::String((const char *)data.paramData, 0, 128);
896 CecParameter ^ newParam = gcnew CecParameter(newType, newData);
897 iReturn = m_callbacks->ReceiveAlert((CecAlert)alert, newParam);
898 }
899 }
900 return iReturn;
901 }
902
c3a20edb
LOK
903 int CecMenuManaged(const CEC::cec_menu_state newVal)
904 {
905 int iReturn(0);
906 if (m_bHasCallbacks)
907 {
908 iReturn = m_callbacks->ReceiveMenuStateChange((CecMenuState)newVal);
909 }
910 return iReturn;
911 }
912
29d5198c
LOK
913 void CecSourceActivatedManaged(const CEC::cec_logical_address logicalAddress, const uint8_t bActivated)
914 {
915 if (m_bHasCallbacks)
916 m_callbacks->SourceActivated((CecLogicalAddress)logicalAddress, bActivated == 1);
917 }
918
4ef3b314
LOK
919 void DestroyDelegates()
920 {
11fea069
LOK
921 m_bHasCallbacks = false;
922 if (m_bDelegatesCreated)
006b76b9 923 {
11fea069 924 m_bDelegatesCreated = false;
006b76b9
LOK
925 m_logMessageGCHandle.Free();
926 m_keypressGCHandle.Free();
927 m_commandGCHandle.Free();
c3a20edb
LOK
928 m_alertGCHandle.Free();
929 m_menuGCHandle.Free();
29d5198c 930 m_sourceActivatedGCHandle.Free();
006b76b9 931 }
4ef3b314
LOK
932 }
933
11fea069
LOK
934 void CreateDelegates()
935 {
936 DestroyDelegates();
937
938 if (!m_bDelegatesCreated)
939 {
940 msclr::interop::marshal_context ^ context = gcnew msclr::interop::marshal_context();
941
942 // create the delegate method for the log message callback
943 m_logMessageDelegate = gcnew CecLogMessageManagedDelegate(this, &CecCallbackMethods::CecLogMessageManaged);
944 m_logMessageGCHandle = System::Runtime::InteropServices::GCHandle::Alloc(m_logMessageDelegate);
945 g_logCB = static_cast<LOGCB>(System::Runtime::InteropServices::Marshal::GetFunctionPointerForDelegate(m_logMessageDelegate).ToPointer());
946 g_cecCallbacks.CBCecLogMessage = CecLogMessageCB;
947
948 // create the delegate method for the keypress callback
949 m_keypressDelegate = gcnew CecKeyPressManagedDelegate(this, &CecCallbackMethods::CecKeyPressManaged);
950 m_keypressGCHandle = System::Runtime::InteropServices::GCHandle::Alloc(m_keypressDelegate);
951 g_keyCB = static_cast<KEYCB>(System::Runtime::InteropServices::Marshal::GetFunctionPointerForDelegate(m_keypressDelegate).ToPointer());
952 g_cecCallbacks.CBCecKeyPress = CecKeyPressCB;
953
954 // create the delegate method for the command callback
955 m_commandDelegate = gcnew CecCommandManagedDelegate(this, &CecCallbackMethods::CecCommandManaged);
956 m_commandGCHandle = System::Runtime::InteropServices::GCHandle::Alloc(m_commandDelegate);
957 g_commandCB = static_cast<COMMANDCB>(System::Runtime::InteropServices::Marshal::GetFunctionPointerForDelegate(m_commandDelegate).ToPointer());
958 g_cecCallbacks.CBCecCommand = CecCommandCB;
959
960 // create the delegate method for the configuration change callback
961 m_configDelegate = gcnew CecConfigManagedDelegate(this, &CecCallbackMethods::CecConfigManaged);
962 m_configGCHandle = System::Runtime::InteropServices::GCHandle::Alloc(m_configDelegate);
963 g_configCB = static_cast<CONFIGCB>(System::Runtime::InteropServices::Marshal::GetFunctionPointerForDelegate(m_configDelegate).ToPointer());
964 g_cecCallbacks.CBCecConfigurationChanged = CecConfigCB;
965
5ee37222
MK
966 // create the delegate method for the alert callback
967 m_alertDelegate = gcnew CecAlertManagedDelegate(this, &CecCallbackMethods::CecAlertManaged);
968 m_alertGCHandle = System::Runtime::InteropServices::GCHandle::Alloc(m_alertDelegate);
6e919697 969 g_alertCB = static_cast<ALERTCB>(System::Runtime::InteropServices::Marshal::GetFunctionPointerForDelegate(m_alertDelegate).ToPointer());
5ee37222
MK
970 g_cecCallbacks.CBCecAlert = CecAlertCB;
971
c3a20edb
LOK
972 // create the delegate method for the menu callback
973 m_menuDelegate = gcnew CecMenuManagedDelegate(this, &CecCallbackMethods::CecMenuManaged);
974 m_menuGCHandle = System::Runtime::InteropServices::GCHandle::Alloc(m_menuDelegate);
975 g_menuCB = static_cast<MENUCB>(System::Runtime::InteropServices::Marshal::GetFunctionPointerForDelegate(m_menuDelegate).ToPointer());
976 g_cecCallbacks.CBCecMenuStateChanged = CecMenuCB;
977
29d5198c
LOK
978 // create the delegate method for the source activated callback
979 m_sourceActivatedDelegate = gcnew CecSourceActivatedManagedDelegate(this, &CecCallbackMethods::CecSourceActivatedManaged);
980 m_sourceActivatedGCHandle = System::Runtime::InteropServices::GCHandle::Alloc(m_sourceActivatedDelegate);
981 g_sourceActivatedCB = static_cast<ACTICB>(System::Runtime::InteropServices::Marshal::GetFunctionPointerForDelegate(m_sourceActivatedDelegate).ToPointer());
982 g_cecCallbacks.CBCecSourceActivated = CecSourceActivatedCB;
983
11fea069
LOK
984 delete context;
985 m_bDelegatesCreated = true;
986 }
987 }
988
4ef3b314
LOK
989 CecLogMessageManagedDelegate ^ m_logMessageDelegate;
990 static System::Runtime::InteropServices::GCHandle m_logMessageGCHandle;
991 LOGCB m_logMessageCallback;
992
993 CecKeyPressManagedDelegate ^ m_keypressDelegate;
994 static System::Runtime::InteropServices::GCHandle m_keypressGCHandle;
995 KEYCB m_keypressCallback;
996
997 CecCommandManagedDelegate ^ m_commandDelegate;
998 static System::Runtime::InteropServices::GCHandle m_commandGCHandle;
999 COMMANDCB m_commandCallback;
1000
32403cc3
LOK
1001 CecConfigManagedDelegate ^ m_configDelegate;
1002 static System::Runtime::InteropServices::GCHandle m_configGCHandle;
1003 CONFIGCB m_configCallback;
1004
5ee37222
MK
1005 CecAlertManagedDelegate ^ m_alertDelegate;
1006 static System::Runtime::InteropServices::GCHandle m_alertGCHandle;
1007 CONFIGCB m_alertCallback;
1008
c3a20edb
LOK
1009 CecMenuManagedDelegate ^ m_menuDelegate;
1010 static System::Runtime::InteropServices::GCHandle m_menuGCHandle;
1011 MENUCB m_menuCallback;
1012
29d5198c
LOK
1013 CecSourceActivatedManagedDelegate ^ m_sourceActivatedDelegate;
1014 static System::Runtime::InteropServices::GCHandle m_sourceActivatedGCHandle;
1015 ACTICB m_sourceActivatedCallback;
1016
4ef3b314
LOK
1017 CecCallbackMethods ^ m_callbacks;
1018 bool m_bHasCallbacks;
11fea069 1019 bool m_bDelegatesCreated;
4ef3b314 1020 };
4ef3b314 1021}