cec: send deck status 0x20 when an LG tv is found, so keypresses will be routed to...
[deb_libcec.git] / src / lib / implementations / SLCommandHandler.cpp
index c6affec4330c3977c9fa6fb734af6b852a133e91..d442eaf44a09fd6650832309044518baac45533f 100644 (file)
@@ -32,6 +32,7 @@
 
 #include "SLCommandHandler.h"
 #include "../devices/CECBusDevice.h"
+#include "../devices/CECPlaybackDevice.h"
 #include "../CECProcessor.h"
 
 using namespace CEC;
@@ -53,35 +54,42 @@ bool CSLCommandHandler::HandleVendorCommand(const cec_command &command)
     response.PushBack(0x02);
     response.PushBack(0x05);
 
-    return m_busDevice->GetProcessor()->Transmit(response);
+    m_busDevice->GetProcessor()->Transmit(response);
+    TransmitLGVendorId(command.destination, command.initiator);
+    return true;
   }
   else if (command.parameters.size >= 1 &&
       command.parameters[0] == 0x04)
   {
-    /* enable SL */
-    cec_command response;
-    cec_command::Format(response, command.destination, command.initiator, CEC_OPCODE_VENDOR_COMMAND);
-    response.PushBack(0x05);
-    response.PushBack(0x04);
-
-    return m_busDevice->GetProcessor()->Transmit(response);
+    CCECBusDevice *primary = m_busDevice->GetProcessor()->m_busDevices[m_busDevice->GetProcessor()->GetLogicalAddresses().primary];
+    if (primary->GetType() == CEC_DEVICE_TYPE_PLAYBACK_DEVICE || primary->GetType() == CEC_DEVICE_TYPE_RECORDING_DEVICE)
+    {
+      ((CCECPlaybackDevice *)primary)->SetDeckStatus(CEC_DECK_INFO_OTHER_STATUS_LG);
+      ((CCECPlaybackDevice *)primary)->TransmitDeckStatus(command.initiator);
+    }
+    return true;
   }
   else if (command.parameters.size == 1 &&
       command.parameters[0] == 0xa0)
   {
-    /* enable SL */
-    cec_command response;
-    cec_command::Format(response, command.destination, command.initiator, CEC_OPCODE_VENDOR_COMMAND);
-    response.parameters.PushBack((uint8_t) (((uint64_t)CEC_VENDOR_LG >> 16) & 0xFF));
-    response.parameters.PushBack((uint8_t) (((uint64_t)CEC_VENDOR_LG >> 8) & 0xFF));
-    response.parameters.PushBack((uint8_t) ((uint64_t)CEC_VENDOR_LG & 0xFF));
-
-    return m_busDevice->GetProcessor()->Transmit(response);
+    TransmitLGVendorId(command.destination, command.initiator);
+    return true;
   }
 
   return false;
 }
 
+bool CSLCommandHandler::TransmitLGVendorId(const cec_logical_address iInitiator, const cec_logical_address iDestination)
+{
+  cec_command response;
+  cec_command::Format(response, iInitiator, iDestination, CEC_OPCODE_VENDOR_COMMAND);
+  response.parameters.PushBack((uint8_t) (((uint64_t)CEC_VENDOR_LG >> 16) & 0xFF));
+  response.parameters.PushBack((uint8_t) (((uint64_t)CEC_VENDOR_LG >> 8) & 0xFF));
+  response.parameters.PushBack((uint8_t) ((uint64_t)CEC_VENDOR_LG & 0xFF));
+
+  return m_busDevice->GetProcessor()->Transmit(response);
+}
+
 bool CSLCommandHandler::HandleGiveDeviceVendorId(const cec_command &command)
 {
   /* imitate LG devices */
@@ -102,6 +110,15 @@ bool CSLCommandHandler::HandleCommand(const cec_command &command)
     case CEC_OPCODE_VENDOR_COMMAND:
       bHandled = HandleVendorCommand(command);
       break;
+    case CEC_OPCODE_DEVICE_VENDOR_ID:
+      {
+        if (command.initiator == m_busDevice->GetLogicalAddress())
+        {
+          TransmitLGVendorId(m_busDevice->GetProcessor()->GetLogicalAddresses().primary, command.initiator);
+          bHandled = true;
+        }
+      }
+      break;
     default:
       break;
     }
@@ -113,7 +130,6 @@ bool CSLCommandHandler::HandleCommand(const cec_command &command)
   return bHandled;
 }
 
-
 void CSLCommandHandler::HandlePoll(const cec_logical_address iInitiator, const cec_logical_address iDestination)
 {
   CCECCommandHandler::HandlePoll(iInitiator, iDestination);
@@ -130,3 +146,26 @@ bool CSLCommandHandler::HandleReceiveFailed(void)
 
   return true;
 }
+
+bool CSLCommandHandler::InitHandler(void)
+{
+  if (m_busDevice->GetLogicalAddress() != CECDEVICE_TV)
+    return true;
+
+  /* LG TVs only route keypresses when the deck status is set to 0x20 */
+  cec_logical_addresses addr = m_busDevice->GetProcessor()->GetLogicalAddresses();
+  for (uint8_t iPtr = 0; iPtr < 15; iPtr++)
+  {
+    if (addr[iPtr])
+    {
+      CCECBusDevice *device = m_busDevice->GetProcessor()->m_busDevices[iPtr];
+      if (device && (device->GetType() == CEC_DEVICE_TYPE_PLAYBACK_DEVICE ||
+                     device->GetType() == CEC_DEVICE_TYPE_RECORDING_DEVICE))
+      {
+        ((CCECPlaybackDevice *)device)->SetDeckStatus(CEC_DECK_INFO_OTHER_STATUS_LG);
+        ((CCECPlaybackDevice *)device)->TransmitDeckStatus(CECDEVICE_TV);
+      }
+    }
+  }
+  return true;
+}