summarylogtreecommitdiffstats
path: root/libcec4.patch
blob: 93fa165cae3913c67c737f60cf4a43f35b82d143 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
diff --git a/mythtv/libs/libmythui/cecadapter.cpp b/mythtv/libs/libmythui/cecadapter.cpp
index 00a8c73..06a8f3d 100644
--- a/mythtv/libs/libmythui/cecadapter.cpp
+++ b/mythtv/libs/libmythui/cecadapter.cpp
@@ -33,17 +33,31 @@ QWaitCondition* CECAdapter::gActionsReady = new QWaitCondition();
 // libcec1's callback parameters are pass-by-ref
 #define CEC_CALLBACK_PARAM_TYPE &
 #else
-// libcec2's callback parameters are pass-by-value
+#if CEC_LIB_VERSION_MAJOR <= 3
+// libcec2 and 3 callback parameters are pass-by-value
 #define CEC_CALLBACK_PARAM_TYPE
 #endif
+#endif
 
 // The libCEC callback functions
+#if CEC_LIB_VERSION_MAJOR <= 3
 static int CECLogMessageCallback(void *adapter, const cec_log_message CEC_CALLBACK_PARAM_TYPE message);
 static int CECKeyPressCallback(void *adapter, const cec_keypress CEC_CALLBACK_PARAM_TYPE keypress);
 static int CECCommandCallback(void *adapter, const cec_command CEC_CALLBACK_PARAM_TYPE command);
+#endif
+#if CEC_LIB_VERSION_MAJOR >= 4
+static void CECLogMessageCallback(void *adapter, const cec_log_message* message);
+static void CECKeyPressCallback(void *adapter, const cec_keypress* keypress);
+static void CECCommandCallback(void *adapter, const cec_command* command);
+#endif
 
 #if CEC_LIB_VERSION_MAJOR >= 2
+#if CEC_LIB_VERSION_MAJOR <= 3
 static int CECAlertCallback(void *adapter, const libcec_alert alert, const libcec_parameter CEC_CALLBACK_PARAM_TYPE data);
+#endif
+#if CEC_LIB_VERSION_MAJOR >= 4
+static void CECAlertCallback(void *adapter, const libcec_alert alert, const libcec_parameter data);
+#endif
 static void CECSourceActivatedCallback(void *adapter, const cec_logical_address address, const uint8_t activated);
 #endif
 
@@ -107,13 +121,24 @@ class CECAdapterPriv
         }
 
         // Set up the callbacks
+#if CEC_LIB_VERSION_MAJOR <= 3
         callbacks.CBCecLogMessage = &CECLogMessageCallback;
         callbacks.CBCecKeyPress   = &CECKeyPressCallback;
         callbacks.CBCecCommand    = &CECCommandCallback;
-#if CEC_LIB_VERSION_MAJOR >= 2
+#endif
+#if CEC_LIB_VERSION_MAJOR >= 4
+        callbacks.logMessage      = &CECLogMessageCallback;
+        callbacks.keyPress        = &CECKeyPressCallback;
+        callbacks.commandReceived = &CECCommandCallback;
+#endif
+#if CEC_LIB_VERSION_MAJOR >= 2 && CEC_LIB_VERSION_MAJOR <= 3
         callbacks.CBCecAlert      = &CECAlertCallback;
         callbacks.CBCecSourceActivated = &CECSourceActivatedCallback;
 #endif
+#if CEC_LIB_VERSION_MAJOR >= 4
+        callbacks.alert           = &CECAlertCallback;
+        callbacks.sourceActivated = &CECSourceActivatedCallback;
+#endif
         configuration.callbackParam = this;
         configuration.callbacks = &callbacks;
 
@@ -127,8 +152,13 @@ class CECAdapterPriv
         }
 
         // find adapters
+#if CEC_LIB_VERSION_MAJOR >= 4
+        cec_adapter_descriptor *devices = new cec_adapter_descriptor[MAX_CEC_DEVICES];
+        uint8_t num_devices = adapter->DetectAdapters(devices, MAX_CEC_DEVICES, NULL, true);
+#else
         cec_adapter *devices = new cec_adapter[MAX_CEC_DEVICES];
         uint8_t num_devices = adapter->FindAdapters(devices, MAX_CEC_DEVICES, NULL);
+#endif
         if (num_devices < 1)
         {
             LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to find any CEC devices.");
@@ -143,22 +173,37 @@ class CECAdapterPriv
             .arg(num_devices));
         for (uint8_t i = 0; i < num_devices; i++)
         {
+#if CEC_LIB_VERSION_MAJOR >= 4
+            QString comm = QString::fromLatin1(devices[i].strComName);
+            QString path = QString::fromLatin1(devices[i].strComPath);
+#else
             QString comm = QString::fromLatin1(devices[i].comm);
+            QString path = QString::fromLatin1(devices[i].path);
+#endif
             bool match = find ? (comm == defaultDevice) : (i == 0);
             devicenum = match ? i : devicenum;
             LOG(VB_GENERAL, LOG_INFO, LOC +
                 QString("Device %1: path '%2' com port '%3' %4").arg(i + 1)
-                .arg(QString::fromLatin1(devices[i].path)).arg(comm)
+                .arg(path).arg(comm)
                 .arg(match ? "SELECTED" : ""));
         }
 
         // open adapter
-        QString path = QString::fromLatin1(devices[devicenum].path);
+#if CEC_LIB_VERSION_MAJOR >= 4
+        QString comm = QString::fromLatin1(devices[devicenum].strComName);
+        QString path = QString::fromLatin1(devices[devicenum].strComPath);
+#else
         QString comm = QString::fromLatin1(devices[devicenum].comm);
+        QString path = QString::fromLatin1(devices[devicenum].path);
+#endif
         LOG(VB_GENERAL, LOG_INFO, LOC + QString("Trying to open device %1 (%2).")
             .arg(path).arg(comm));
 
+#if CEC_LIB_VERSION_MAJOR >= 4
+        if (!adapter->Open(devices[devicenum].strComName))
+#else
         if (!adapter->Open(devices[devicenum].comm))
+#endif
         {
             LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to open device.");
             return false;
@@ -213,6 +258,20 @@ class CECAdapterPriv
         return 1;
     }
 
+    void LogMessage(const cec_log_message* message)
+    {
+        QString msg(message->message);
+        int lvl = LOG_UNKNOWN;
+        switch (message->level)
+        {
+            case CEC_LOG_ERROR:   lvl = LOG_ERR;     break;
+            case CEC_LOG_WARNING: lvl = LOG_WARNING; break;
+            case CEC_LOG_NOTICE:  lvl = LOG_INFO;    break;
+            case CEC_LOG_DEBUG:   lvl = LOG_DEBUG;   break;
+        }
+        LOG(VB_GENERAL, lvl, LOC + QString("%1").arg(msg));
+    }
+
     // NOTE - libcec2 changes the callbacks
     // to be pass-by-value.
     // For simplicity, this function remains as pass-by-ref
@@ -241,6 +300,29 @@ class CECAdapterPriv
         return 1;
     }
 
+    void HandleCommand(const cec_command* command)
+    {
+        if (!adapter || !valid)
+            return;
+
+        LOG(VB_GENERAL, LOG_DEBUG, LOC +
+            QString("Command %1 from '%2' (%3) - destination '%4' (%5)")
+            .arg(command->opcode)
+            .arg(adapter->ToString(command->initiator))
+            .arg(command->initiator)
+            .arg(adapter->ToString(command->destination))
+            .arg(command->destination));
+
+        switch (command->opcode)
+        {
+            // TODO
+            default:
+                break;
+        }
+        gCoreContext->SendSystemEvent(QString("CEC_COMMAND_RECEIVED COMMAND %1")
+                                      .arg(command->opcode));
+    }
+
     int HandleKeyPress(const cec_keypress &key)
     {
         if (!adapter || !valid)
@@ -572,6 +654,335 @@ class CECAdapterPriv
         return 1;
     }
 
+    void HandleKeyPress(const cec_keypress* key)
+    {
+        if (!adapter || !valid)
+            return;
+
+        // Ignore key down events and wait for the key 'up'
+        if (key->duration < 1)
+            return;
+
+        QString code;
+        int action = 0;
+        switch (key->keycode)
+        {
+            case CEC_USER_CONTROL_CODE_NUMBER0:
+                action = Qt::Key_0;
+                code   = "0";
+                break;
+            case CEC_USER_CONTROL_CODE_NUMBER1:
+                action = Qt::Key_1;
+                code   = "1";
+                break;
+            case CEC_USER_CONTROL_CODE_NUMBER2:
+                action = Qt::Key_2;
+                code   = "2";
+                break;
+            case CEC_USER_CONTROL_CODE_NUMBER3:
+                action = Qt::Key_3;
+                code   = "3";
+                break;
+            case CEC_USER_CONTROL_CODE_NUMBER4:
+                action = Qt::Key_4;
+                code   = "4";
+                break;
+            case CEC_USER_CONTROL_CODE_NUMBER5:
+                action = Qt::Key_5;
+                code   = "5";
+                break;
+            case CEC_USER_CONTROL_CODE_NUMBER6:
+                action = Qt::Key_6;
+                code   = "6";
+                break;
+            case CEC_USER_CONTROL_CODE_NUMBER7:
+                action = Qt::Key_7;
+                code   = "7";
+                break;
+            case CEC_USER_CONTROL_CODE_NUMBER8:
+                action = Qt::Key_8;
+                code   = "8";
+                break;
+            case CEC_USER_CONTROL_CODE_NUMBER9:
+                action = Qt::Key_9;
+                code   = "9";
+                break;
+            case CEC_USER_CONTROL_CODE_SELECT:
+                action = Qt::Key_Select;
+                code   = "SELECT";
+                break;
+            case CEC_USER_CONTROL_CODE_ENTER:
+                action = Qt::Key_Enter;
+                code   = "ENTER";
+                break;
+            case CEC_USER_CONTROL_CODE_UP:
+                action = Qt::Key_Up;
+                code   = "UP";
+                break;
+            case CEC_USER_CONTROL_CODE_DOWN:
+                action = Qt::Key_Down;
+                code   = "DOWN";
+                break;
+            case CEC_USER_CONTROL_CODE_LEFT:
+                action = Qt::Key_Left;
+                code   = "LEFT";
+                break;
+            case CEC_USER_CONTROL_CODE_LEFT_UP:
+                action = Qt::Key_Left;
+                code   = "LEFT_UP";
+                break;
+            case CEC_USER_CONTROL_CODE_LEFT_DOWN:
+                action = Qt::Key_Left;
+                code   = "LEFT_DOWN";
+                break;
+            case CEC_USER_CONTROL_CODE_RIGHT:
+                action = Qt::Key_Right;
+                code   = "RIGHT";
+                break;
+            case CEC_USER_CONTROL_CODE_RIGHT_UP:
+                action = Qt::Key_Right;
+                code   = "RIGHT_UP";
+                break;
+            case CEC_USER_CONTROL_CODE_RIGHT_DOWN:
+                action = Qt::Key_Right;
+                code   = "RIGHT_DOWN";
+                break;
+            case CEC_USER_CONTROL_CODE_ROOT_MENU:
+                action = Qt::Key_M;
+                code   = "ROOT_MENU";
+                break;
+            case CEC_USER_CONTROL_CODE_EXIT:
+                action = Qt::Key_Escape;
+                code   = "EXIT";
+                break;
+            case CEC_USER_CONTROL_CODE_PREVIOUS_CHANNEL:
+                action = Qt::Key_H;
+                code   = "PREVIOUS_CHANNEL";
+                break;
+            case CEC_USER_CONTROL_CODE_SOUND_SELECT:
+                action = Qt::Key_Plus;
+                code   = "SOUND_SELECT";
+                break;
+            case CEC_USER_CONTROL_CODE_VOLUME_UP:
+                action = Qt::Key_VolumeUp;
+                code   = "VOLUME_UP";
+                break;
+            case CEC_USER_CONTROL_CODE_VOLUME_DOWN:
+                action = Qt::Key_VolumeDown;
+                code   = "VOLUME_DOWN";
+                break;
+            case CEC_USER_CONTROL_CODE_MUTE:
+                action = Qt::Key_VolumeMute;
+                code   = "MUTE";
+                break;
+            case CEC_USER_CONTROL_CODE_PLAY:
+                action = Qt::Key_P;
+                code   = "PLAY";
+                break;
+            case CEC_USER_CONTROL_CODE_PAUSE:
+                action = Qt::Key_P; // same as play
+                code   = "PAUSE";
+                break;
+            case CEC_USER_CONTROL_CODE_STOP:
+                action = Qt::Key_Stop;
+                code   = "STOP";
+                break;
+            case CEC_USER_CONTROL_CODE_RECORD:
+                action = Qt::Key_R;
+                code   = "RECORD";
+                break;
+            case CEC_USER_CONTROL_CODE_CLEAR:
+                action = Qt::Key_Clear;
+                code   = "CLEAR";
+                break;
+            case CEC_USER_CONTROL_CODE_DISPLAY_INFORMATION:
+                action = Qt::Key_I;
+                code   = "DISPLAY_INFORMATION";
+                break;
+            case CEC_USER_CONTROL_CODE_PAGE_UP:
+                action = Qt::Key_PageUp;
+                code   = "PAGE_UP";
+                break;
+            case CEC_USER_CONTROL_CODE_PAGE_DOWN:
+                action = Qt::Key_PageDown;
+                code   = "PAGE_DOWN";
+                break;
+            case CEC_USER_CONTROL_CODE_EJECT:
+                action = Qt::Key_Eject;
+                code   = "EJECT";
+                break;
+            case CEC_USER_CONTROL_CODE_FORWARD:
+                action = Qt::Key_Forward;
+                code   = "FORWARD";
+                break;
+            case CEC_USER_CONTROL_CODE_BACKWARD:
+                action = Qt::Key_Back;
+                code   = "BACKWARD";
+                break;
+            case CEC_USER_CONTROL_CODE_F1_BLUE:
+                action = Qt::Key_F5; // NB F1 is help and we normally map blue to F5
+                code   = "F1_BLUE";
+                break;
+            case CEC_USER_CONTROL_CODE_F2_RED:
+                action = Qt::Key_F2;
+                code   = "F2_RED";
+                break;
+            case CEC_USER_CONTROL_CODE_F3_GREEN:
+                action = Qt::Key_F3;
+                code   = "F3_GREEN";
+                break;
+            case CEC_USER_CONTROL_CODE_F4_YELLOW:
+                action = Qt::Key_F4;
+                code   = "F4_YELLOW";
+                break;
+            case CEC_USER_CONTROL_CODE_SETUP_MENU:
+                action = Qt::Key_M; // Duplicate of Root Menu
+                code   = "SETUP_MENU";
+                break;
+            case CEC_USER_CONTROL_CODE_CONTENTS_MENU:
+                action = Qt::Key_M; // Duplicate of Root Menu
+                code   = "CONTENTS_MENU";
+                break;
+            case CEC_USER_CONTROL_CODE_FAVORITE_MENU:
+                action = Qt::Key_M; // Duplicate of Root Menu
+                code   = "FAVORITE_MENU";
+                break;
+            case CEC_USER_CONTROL_CODE_DOT:
+                action = Qt::Key_Period;
+                code  = "DOT";
+                break;
+            case CEC_USER_CONTROL_CODE_NEXT_FAVORITE:
+                action = Qt::Key_Slash;
+                code   = "NEXT_FAVORITE";
+                break;
+            case CEC_USER_CONTROL_CODE_INPUT_SELECT:
+                action = Qt::Key_C;
+                code = "INPUT_SELECT";
+                break;
+            case CEC_USER_CONTROL_CODE_HELP:
+                action = Qt::Key_F1;
+                code   = "HELP";
+                break;
+            case CEC_USER_CONTROL_CODE_STOP_RECORD:
+                action = Qt::Key_R; // Duplicate of Record
+                code = "STOP_RECORD";
+                break;
+            case CEC_USER_CONTROL_CODE_SUB_PICTURE:
+                action = Qt::Key_V;
+                code   = "SUB_PICTURE";
+                break;
+            case CEC_USER_CONTROL_CODE_ELECTRONIC_PROGRAM_GUIDE:
+                action = Qt::Key_S;
+                code   = "ELECTRONIC_PROGRAM_GUIDE";
+                break;
+            case CEC_USER_CONTROL_CODE_POWER:
+                action = Qt::Key_PowerOff;
+                code = "POWER";
+                break;
+
+             // these codes have 'non-standard' Qt key mappings to ensure
+             // each code has a unique key mapping
+            case CEC_USER_CONTROL_CODE_CHANNEL_DOWN:
+                action = Qt::Key_F20; // to differentiate from Up
+                code   = "CHANNEL_DOWN";
+                break;
+            case CEC_USER_CONTROL_CODE_CHANNEL_UP:
+                action = Qt::Key_F21; // to differentiate from Down
+                code   = "CHANNEL_UP";
+                break;
+            case CEC_USER_CONTROL_CODE_REWIND:
+                action = Qt::Key_F22; // to differentiate from Left
+                code   = "REWIND";
+                break;
+            case CEC_USER_CONTROL_CODE_FAST_FORWARD:
+                action = Qt::Key_F23; // to differentiate from Right
+                code   = "FAST_FORWARD";
+                break;
+            case CEC_USER_CONTROL_CODE_ANGLE:
+                action = Qt::Key_F24;
+                code = "ANGLE";
+                break;
+            case CEC_USER_CONTROL_CODE_F5:
+                action = Qt::Key_F6; // NB!
+                code = "F5";
+                break;
+
+            // codes with no obvious MythTV action
+            case CEC_USER_CONTROL_CODE_INITIAL_CONFIGURATION:
+                code = "INITIAL_CONFIGURATION";
+                break;
+            case CEC_USER_CONTROL_CODE_PAUSE_RECORD:
+                code = "PAUSE_RECORD";
+                break;
+            case CEC_USER_CONTROL_CODE_VIDEO_ON_DEMAND:
+                code = "VIDEO_ON_DEMAND";
+                break;
+            case CEC_USER_CONTROL_CODE_TIMER_PROGRAMMING:
+                code = "TIMER_PROGRAMMING";
+                break;
+            case CEC_USER_CONTROL_CODE_UNKNOWN:
+                code = "UNKNOWN";
+                break;
+            case CEC_USER_CONTROL_CODE_DATA:
+                code = "DATA";
+                break;
+
+            // Functions aren't implemented (similar to macros?)
+            case CEC_USER_CONTROL_CODE_POWER_ON_FUNCTION:
+                code = "POWER_ON_FUNCTION";
+                break;
+            case CEC_USER_CONTROL_CODE_PLAY_FUNCTION:
+                code = "PLAY_FUNCTION";
+                break;
+            case CEC_USER_CONTROL_CODE_PAUSE_PLAY_FUNCTION:
+                code = "PAUSE_PLAY_FUNCTION";
+                break;
+            case CEC_USER_CONTROL_CODE_RECORD_FUNCTION:
+                code = "RECORD_FUNCTION";
+                break;
+            case CEC_USER_CONTROL_CODE_PAUSE_RECORD_FUNCTION:
+                code = "PAUSE_RECORD_FUNCTION";
+                break;
+            case CEC_USER_CONTROL_CODE_STOP_FUNCTION:
+                code = "STOP_FUNCTION";
+                break;
+            case CEC_USER_CONTROL_CODE_MUTE_FUNCTION:
+                code = "MUTE_FUNCTION";
+                break;
+            case CEC_USER_CONTROL_CODE_RESTORE_VOLUME_FUNCTION:
+                code = "RESTORE_VOLUME_FUNCTION";
+                break;
+            case CEC_USER_CONTROL_CODE_TUNE_FUNCTION:
+                code = "TUNE_FUNCTION";
+                break;
+            case CEC_USER_CONTROL_CODE_SELECT_MEDIA_FUNCTION:
+                code = "SELECT_MEDIA_FUNCTION";
+                break;
+            case CEC_USER_CONTROL_CODE_SELECT_AV_INPUT_FUNCTION:
+                code = "SELECT_AV_INPUT_FUNCTION";
+                break;
+            case CEC_USER_CONTROL_CODE_SELECT_AUDIO_INPUT_FUNCTION:
+                code = "SELECT_AUDIO_INPUT_FUNCTION";
+                break;
+            case CEC_USER_CONTROL_CODE_POWER_TOGGLE_FUNCTION:
+                code = "POWER_TOGGLE_FUNCTION";
+                break;
+            case CEC_USER_CONTROL_CODE_POWER_OFF_FUNCTION:
+                code = "POWER_OFF_FUNCTION";
+                break;
+        }
+
+        LOG(VB_GENERAL, LOG_DEBUG, LOC + QString("Keypress %1 %2")
+            .arg(code).arg(0 == action ? "(Not actioned)" : ""));
+
+        if (0 == action)
+            return;
+
+        GetMythUI()->ResetScreensaver();
+        QKeyEvent* ke = new QKeyEvent(QEvent::KeyPress, action, Qt::NoModifier);
+        qApp->postEvent(GetMythMainWindow(), (QEvent*)ke);
+    }
+
 #if CEC_LIB_VERSION_MAJOR >= 2
     int HandleAlert(const libcec_alert alert, const libcec_parameter &data)
     {
@@ -764,6 +1175,7 @@ void CECAdapter::Action(const QString &action)
         gActionsReady->wakeAll();
 }
 
+#if CEC_LIB_VERSION_MAJOR <= 3
 static int CECLogMessageCallback(void *adapter, const cec_log_message CEC_CALLBACK_PARAM_TYPE message)
 {
     return ((CECAdapterPriv*)adapter)->LogMessage(message);
@@ -778,13 +1190,37 @@ static int CECCommandCallback(void *adapter, const cec_command CEC_CALLBACK_PARA
 {
     return ((CECAdapterPriv*)adapter)->HandleCommand(command);
 }
+#endif
+#if CEC_LIB_VERSION_MAJOR >= 4
+static void CECLogMessageCallback(void *adapter, const cec_log_message* message)
+{
+    ((CECAdapterPriv*)adapter)->LogMessage(message);
+}
+
+static void CECKeyPressCallback(void *adapter, const cec_keypress* keypress)
+{
+    ((CECAdapterPriv*)adapter)->HandleKeyPress(keypress);
+}
+
+static void CECCommandCallback(void *adapter, const cec_command* command)
+{
+    ((CECAdapterPriv*)adapter)->HandleCommand(command);
+}
+#endif
 
 #if CEC_LIB_VERSION_MAJOR >= 2
+#if CEC_LIB_VERSION_MAJOR <= 3
 static int CECAlertCallback(void *adapter, const libcec_alert alert, const libcec_parameter CEC_CALLBACK_PARAM_TYPE data)
 {
     return ((CECAdapterPriv*)adapter)->HandleAlert(alert, data);
 }
-
+#endif
+#if CEC_LIB_VERSION_MAJOR >= 4
+static void CECAlertCallback(void *adapter, const libcec_alert alert, const libcec_parameter data)
+{
+    ((CECAdapterPriv*)adapter)->HandleAlert(alert, data);
+}
+#endif
 static void CECSourceActivatedCallback(void *adapter, const cec_logical_address address, const uint8_t activated)
 {
     ((CECAdapterPriv*)adapter)->HandleSourceActivated(address, activated);