Advertisement
Guest User

Untitled

a guest
Nov 9th, 2016
134
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 70.39 KB | None | 0 0
  1. From c77ae55125886d20a9dc5d4f6bbffa9bad1f4e82 Mon Sep 17 00:00:00 2001
  2. From: popcornmix <popcornmix@gmail.com>
  3. Date: Sun, 10 Aug 2014 16:45:16 +0100
  4. Subject: [PATCH 05/73] filesystem: Make support of browsing into archives
  5.  optional
  6.  
  7. The ability to browse, scan and play content in archives can cause problems on low powered/low memory devices.
  8. It's quite common to see reports of a large rar file that causes xbmc to crash with an out-of-memory error when browsing or scanning.
  9. It also can be slow as any archive in the directory is opened and extracted.
  10.  
  11. This causes issues for people who scan library with archives disabled, then subsequently enable it.
  12. The library has the .rar files in which don't play without removing and re-adding.
  13.  
  14. We'll let people who don't use archives disable it manually
  15. ---
  16.  addons/resource.language.en_gb/resources/strings.po |  9 +++++++++
  17.  system/settings/rbp.xml                             | 11 +++++++++++
  18.  xbmc/Util.cpp                                       |  4 ++--
  19.  xbmc/filesystem/FileDirectoryFactory.cpp            |  4 ++++
  20.  4 files changed, 26 insertions(+), 2 deletions(-)
  21.  
  22. diff --git a/addons/resource.language.en_gb/resources/strings.po b/addons/resource.language.en_gb/resources/strings.po
  23. index 5d2af8d8705ecf61dc5b7c91f0517b8d1e1e640a..488e590d5a48467b19e27d01863487f51442b130 100644
  24. --- a/addons/resource.language.en_gb/resources/strings.po
  25. +++ b/addons/resource.language.en_gb/resources/strings.po
  26. @@ -19333,6 +19333,15 @@ msgstr ""
  27.  #: system/settings/rbp.xml
  28.  msgctxt "#38010"
  29.  msgid "GPU accelerated"
  30. +
  31. +#: system/settings/settings.xml
  32. +msgctxt "#38040"
  33. +msgid "Support browsing into archives"
  34. +msgstr ""
  35. +
  36. +#: system/settings/settings.xml
  37. +msgctxt "#38041"
  38. +msgid "Allow viewing and playing files in archives (e.g. zip, rar)"
  39.  msgstr ""
  40.  
  41.  #. Setting #38011 "Show All Items entry"
  42. diff --git a/system/settings/rbp.xml b/system/settings/rbp.xml
  43. index 62e9c8ed2199f8c57a640b06b0216ee4c8f0ca1e..e8b0d3d472b02fd161a4b51e957b9129e3cb9792 100644
  44. --- a/system/settings/rbp.xml
  45. +++ b/system/settings/rbp.xml
  46. @@ -102,4 +102,15 @@
  47.        </group>
  48.      </category>
  49.    </section>
  50. +  <section id="library">
  51. +    <category id="filelists">
  52. +      <group id="1">
  53. +        <setting id="filelists.browsearchives" type="boolean" label="38040" help="38041">
  54. +          <level>1</level>
  55. +          <default>true</default>
  56. +          <control type="toggle" />
  57. +        </setting>
  58. +      </group>
  59. +    </category>
  60. +  </section>
  61.  </settings>
  62. diff --git a/xbmc/Util.cpp b/xbmc/Util.cpp
  63. index c3567941192c724f2600494a8d7e355584b57b52..da1508dcedbd196789988d895e64548a08439d8f 100644
  64. --- a/xbmc/Util.cpp
  65. +++ b/xbmc/Util.cpp
  66. @@ -1899,7 +1899,7 @@ void CUtil::ScanPathsForAssociatedItems(const std::string& videoName,
  67.      URIUtils::RemoveExtension(strCandidate);
  68.      if (StringUtils::StartsWithNoCase(strCandidate, videoName))
  69.      {
  70. -      if (URIUtils::IsRAR(pItem->GetPath()) || URIUtils::IsZIP(pItem->GetPath()))
  71. +      if (CSettings::GetInstance().GetBool("filelists.browsearchives") && (URIUtils::IsRAR(pItem->GetPath()) || URIUtils::IsZIP(pItem->GetPath())))
  72.          CUtil::ScanArchiveForAssociatedItems(pItem->GetPath(), "", item_exts, associatedFiles);
  73.        else
  74.        {
  75. @@ -1909,7 +1909,7 @@ void CUtil::ScanPathsForAssociatedItems(const std::string& videoName,
  76.      }
  77.      else
  78.      {
  79. -      if (URIUtils::IsRAR(pItem->GetPath()) || URIUtils::IsZIP(pItem->GetPath()))
  80. +      if (CSettings::GetInstance().GetBool("filelists.browsearchives") && (URIUtils::IsRAR(pItem->GetPath()) || URIUtils::IsZIP(pItem->GetPath())))
  81.          CUtil::ScanArchiveForAssociatedItems(pItem->GetPath(), videoName, item_exts, associatedFiles);
  82.      }
  83.    }
  84. diff --git a/xbmc/filesystem/FileDirectoryFactory.cpp b/xbmc/filesystem/FileDirectoryFactory.cpp
  85. index a0fd0a9011e71f4af1535110c696b6ea5c4b37db..688b71a297c7c617c6764bfe6be157d727eb49d3 100644
  86. --- a/xbmc/filesystem/FileDirectoryFactory.cpp
  87. +++ b/xbmc/filesystem/FileDirectoryFactory.cpp
  88. @@ -40,6 +40,7 @@
  89.  #include "playlists/PlayListFactory.h"
  90.  #include "Directory.h"
  91.  #include "File.h"
  92. +#include "settings/Settings.h"
  93.  #include "FileItem.h"
  94.  #include "utils/StringUtils.h"
  95.  #include "URL.h"
  96. @@ -116,6 +117,8 @@ IFileDirectory* CFileDirectoryFactory::Create(const CURL& url, CFileItem* pItem,
  97.      return NULL;
  98.    }
  99.  #endif
  100. +  if (CSettings::GetInstance().GetBool("filelists.browsearchives"))
  101. +  {
  102.    if (url.IsFileType("zip"))
  103.    {
  104.      CURL zipURL = URIUtils::CreateArchivePath("zip", url);
  105. @@ -189,6 +192,7 @@ IFileDirectory* CFileDirectoryFactory::Create(const CURL& url, CFileItem* pItem,
  106.      }
  107.      return NULL;
  108.    }
  109. +  }
  110.    if (url.IsFileType("xbt"))
  111.    {
  112.      CURL xbtUrl = URIUtils::CreateArchivePath("xbt", url);
  113.  
  114. From 859c87e3ac2360ecaa7eb846c24ae565228b9d85 Mon Sep 17 00:00:00 2001
  115. From: popcornmix <popcornmix@gmail.com>
  116. Date: Wed, 24 Sep 2014 23:13:52 +0100
  117. Subject: [PATCH 08/73] [audio] Add settings option to boost centre channel
  118.  when downmixing
  119.  
  120. This allows a dB volume increase to be added to centre channel.
  121. This can help improve dialgue in the presence of background music/effects.
  122. It can go up to 30dB for testing purposes, but value of 6 is probably more reasonable.
  123. It is recommended to ensure "Normalise levels on downmix" is enabled when boosting by large values to avoid clipping.
  124.  
  125. Should work with Pi Sink (dvdplayer/paplayer) and omxplayer
  126. ---
  127.  addons/resource.language.en_gb/resources/strings.po       | 15 +++++++++++++++
  128.  system/settings/settings.xml                              | 12 ++++++++++++
  129.  .../Engines/ActiveAE/ActiveAEResampleFFMPEG.cpp           |  7 +++++++
  130.  .../AudioEngine/Engines/ActiveAE/ActiveAEResamplePi.cpp   |  6 ++++++
  131.  xbmc/cores/omxplayer/OMXAudio.cpp                         |  6 ++++++
  132.  5 files changed, 46 insertions(+)
  133.  
  134. diff --git a/addons/resource.language.en_gb/resources/strings.po b/addons/resource.language.en_gb/resources/strings.po
  135. index 488e590d5a48467b19e27d01863487f51442b130..a867d3205bbad13ac4f3b0862911f04c694e0f07 100644
  136. --- a/addons/resource.language.en_gb/resources/strings.po
  137. +++ b/addons/resource.language.en_gb/resources/strings.po
  138. @@ -19531,6 +19531,21 @@ msgstr ""
  139.  
  140.  #empty strings from id 38047 to 38099
  141.  
  142. +#: system/settings/settings.xml
  143. +msgctxt "#38007"
  144. +msgid "Boost centre channel when downmixing"
  145. +msgstr ""
  146. +
  147. +#: system/settings/settings.xml
  148. +msgctxt "#38008"
  149. +msgid "Increase this value to make the dialogue louder compared to background sounds when downmixing multichannel audio"
  150. +msgstr ""
  151. +
  152. +#: system/settings/settings.xml
  153. +msgctxt "#38009"
  154. +msgid "%i dB"
  155. +msgstr ""
  156. +
  157.  #. Description of section #14200 "Player""
  158.  #: system/settings/settings.xml
  159.  msgctxt "#38100"
  160. diff --git a/system/settings/settings.xml b/system/settings/settings.xml
  161. index 6ff6b4c63fdb49ebe02f63b93c6995e0ddd21d40..52f7d29eaa509c8d648c2cf2e125b9e7e4b90f3b 100644
  162. --- a/system/settings/settings.xml
  163. +++ b/system/settings/settings.xml
  164. @@ -2361,6 +2361,18 @@
  165.            </dependencies>
  166.            <control type="toggle" />
  167.          </setting>
  168. +        <setting id="audiooutput.boostcenter" type="integer" label="38007" help="38008">
  169. +          <level>2</level>
  170. +          <default>0</default>
  171. +          <constraints>
  172. +            <minimum>0</minimum>
  173. +            <step>1</step>
  174. +            <maximum>30</maximum>
  175. +          </constraints>
  176. +          <control type="spinner" format="string">
  177. +            <formatlabel>38009</formatlabel>
  178. +          </control>
  179. +        </setting>
  180.          <setting id="audiooutput.processquality" type="integer" label="13505" help="36169">
  181.            <requirement>HAS_AE_QUALITY_LEVELS</requirement>
  182.            <level>2</level>
  183. diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResampleFFMPEG.cpp b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResampleFFMPEG.cpp
  184. index af5bf93116543bd282953b01d0c5bcef93bb3a84..d7165dedd242abdfa7c0607eee332451c3187298 100644
  185. --- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResampleFFMPEG.cpp
  186. +++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResampleFFMPEG.cpp
  187. @@ -20,6 +20,7 @@
  188.  
  189.  #include "cores/AudioEngine/Utils/AEUtil.h"
  190.  #include "ActiveAEResampleFFMPEG.h"
  191. +#include "settings/Settings.h"
  192.  #include "utils/log.h"
  193.  
  194.  extern "C" {
  195. @@ -104,6 +105,12 @@ bool CActiveAEResampleFFMPEG::Init(uint64_t dst_chan_layout, int dst_channels, i
  196.    {
  197.       av_opt_set_double(m_pContext, "rematrix_maxval", 1.0, 0);
  198.    }
  199. +  int boost_center = CSettings::GetInstance().GetInt("audiooutput.boostcenter");
  200. +  if (boost_center)
  201. +  {
  202. +    float gain = pow(10.0f, ((float)(-3 + boost_center))/20.0f);
  203. +    av_opt_set_double(m_pContext, "center_mix_level", gain, 0);
  204. +  }
  205.  
  206.    if (remapLayout)
  207.    {
  208. diff --git a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResamplePi.cpp b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResamplePi.cpp
  209. index 78071493fca4756c6741d7085e35cbe2f27038e6..698a6ae1e2bc0cc9256caec42c0dcfb0893301b5 100644
  210. --- a/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResamplePi.cpp
  211. +++ b/xbmc/cores/AudioEngine/Engines/ActiveAE/ActiveAEResamplePi.cpp
  212. @@ -164,6 +164,12 @@ bool CActiveAEResamplePi::Init(uint64_t dst_chan_layout, int dst_channels, int d
  213.    {
  214.      av_opt_set_double(m_pContext, "rematrix_maxval", 1.0, 0);
  215.    }
  216. +  int boost_center = CSettings::GetInstance().GetInt("audiooutput.boostcenter");
  217. +  if (boost_center)
  218. +  {
  219. +    float gain = pow(10.0f, ((float)(-3 + boost_center))/20.0f);
  220. +    av_opt_set_double(m_pContext, "center_mix_level", gain, 0);
  221. +  }
  222.  
  223.    if (remapLayout)
  224.    {
  225. diff --git a/xbmc/cores/omxplayer/OMXAudio.cpp b/xbmc/cores/omxplayer/OMXAudio.cpp
  226. index f16b822ed7b4aebe18b5d339b3f71ee66e97c23f..993d4b33a294e88c2c004b7943895ba55558c2d0 100644
  227. --- a/xbmc/cores/omxplayer/OMXAudio.cpp
  228. +++ b/xbmc/cores/omxplayer/OMXAudio.cpp
  229. @@ -633,6 +633,12 @@ bool COMXAudio::Initialize(AEAudioFormat format, OMXClock *clock, CDVDStreamInfo
  230.      {
  231.         av_opt_set_double(m_pContext, "rematrix_maxval", 1.0, 0);
  232.      }
  233. +    int boost_center = CSettings::GetInstance().GetInt("audiooutput.boostcenter");
  234. +    if (boost_center)
  235. +    {
  236. +      float gain = pow(10.0f, ((float)(-3 + boost_center))/20.0f);
  237. +      av_opt_set_double(m_pContext, "center_mix_level", gain, 0);
  238. +    }
  239.  
  240.      // stereo upmix
  241.      if (upmix && m_src_channels == 2 && m_dst_channels > 2)
  242.  
  243. From 5b64f68afe3f41097e46b278f02db69190d2628d Mon Sep 17 00:00:00 2001
  244. From: popcornmix <popcornmix@gmail.com>
  245. Date: Mon, 27 Oct 2014 15:23:51 +0000
  246. Subject: [PATCH 09/73] [rbp] Default extract thumbnails to false
  247.  
  248. It can take 80 seconds for a single file on a Pi. It can cause crashes with out-of-memory errors.
  249. It genereates a lot of support issues. Best to default to disabled and let users enable it if they must
  250. ---
  251.  system/settings/rbp.xml | 6 ++++++
  252.  1 file changed, 6 insertions(+)
  253.  
  254. diff --git a/system/settings/rbp.xml b/system/settings/rbp.xml
  255. index e8b0d3d472b02fd161a4b51e957b9129e3cb9792..289dc55ec41aa44848519a05f8ee1ccc72740085 100644
  256. --- a/system/settings/rbp.xml
  257. +++ b/system/settings/rbp.xml
  258. @@ -43,6 +43,12 @@
  259.          <setting id="myvideos.extractchapterthumbs">
  260.            <default>false</default>
  261.          </setting>
  262. +        <setting id="myvideos.extractflags">
  263. +          <default>false</default>
  264. +        </setting>
  265. +        <setting id="myvideos.extractthumb">
  266. +          <default>false</default>
  267. +        </setting>
  268.        </group>
  269.      </category>
  270.    </section>
  271.  
  272. From 7552084189bbac0c9b2a443fa071b1ebe85b1cf3 Mon Sep 17 00:00:00 2001
  273. From: popcornmix <popcornmix@gmail.com>
  274. Date: Tue, 10 Feb 2015 15:29:16 +0000
  275. Subject: [PATCH 51/73] [libcec] Add repeating keypress patch from popcornmix'
  276. repo
  277.  
  278. ---
  279. tools/depends/target/libcec/Makefile         |   1 +
  280. tools/depends/target/libcec/popcornmix.patch | 859 +++++++++++++++++++++++++++
  281. 2 files changed, 860 insertions(+)
  282. create mode 100644 tools/depends/target/libcec/popcornmix.patch
  283.  
  284. diff --git a/tools/depends/target/libcec/Makefile b/tools/depends/target/libcec/Makefile
  285. index f54af9e7ed3d0a9bef922517728c8b8db51d9d75..ddf996361ad5b46dd2b33fb035b2ed133914a612 100644
  286. --- a/tools/depends/target/libcec/Makefile
  287. +++ b/tools/depends/target/libcec/Makefile
  288. @@ -21,6 +21,7 @@ $(TARBALLS_LOCATION)/$(ARCHIVE):
  289. $(PLATFORM): $(TARBALLS_LOCATION)/$(ARCHIVE) $(DEPS)
  290.     rm -rf $(PLATFORM); mkdir -p $(PLATFORM)/build
  291.     cd $(PLATFORM); $(ARCHIVE_TOOL) $(ARCHIVE_TOOL_FLAGS) $(TARBALLS_LOCATION)/$(ARCHIVE)
  292. +   cd $(PLATFORM); patch -p1 < ../popcornmix.patch
  293.     cd $(PLATFORM)/build; $(CMAKE) -DBUILD_SHARED_LIBS=1 -DSKIP_PYTHON_WRAPPER:STRING=1 -DCMAKE_INSTALL_LIBDIR=$(PREFIX)/lib ..
  294.  
  295. $(LIBDYLIB): $(PLATFORM)
  296. diff --git a/tools/depends/target/libcec/popcornmix.patch b/tools/depends/target/libcec/popcornmix.patch
  297. new file mode 100644
  298. index 0000000000000000000000000000000000000000..8366a696562a934144cc9a21ea6f2cab3c69e655
  299. --- /dev/null
  300. +++ b/tools/depends/target/libcec/popcornmix.patch
  301. @@ -0,0 +1,859 @@
  302. +From ec982e9800ae312972d306b67779215a2add6cde Mon Sep 17 00:00:00 2001
  303. +From: popcornmix <popcornmix@gmail.com>
  304. +Date: Fri, 24 Oct 2014 13:45:21 +0100
  305. +Subject: [PATCH 1/6] Make released key polling wait for exact time until key
  306. + gets released
  307. +
  308. +---
  309. + src/libcec/CECClient.cpp    | 16 ++++++++++++++--
  310. + src/libcec/CECClient.h      |  2 +-
  311. + src/libcec/CECProcessor.cpp |  8 +++++---
  312. + src/libcec/LibCEC.cpp       | 10 ++++++++--
  313. + src/libcec/LibCEC.h         |  4 +++-
  314. + 5 files changed, 31 insertions(+), 9 deletions(-)
  315. +
  316. +diff --git a/src/libcec/CECClient.cpp b/src/libcec/CECClient.cpp
  317. +index 35c2d3e..e307c0e 100644
  318. +--- a/src/libcec/CECClient.cpp
  319. ++++ b/src/libcec/CECClient.cpp
  320. +@@ -1067,7 +1067,7 @@ void CCECClient::SetCurrentButton(const cec_user_control_code iButtonCode)
  321. +   AddKey(key);
  322. + }
  323. +
  324. +-void CCECClient::CheckKeypressTimeout(void)
  325. ++uint16_t CCECClient::CheckKeypressTimeout(void)
  326. + {
  327. +   cec_keypress key;
  328. +
  329. +@@ -1091,12 +1091,24 @@ void CCECClient::CheckKeypressTimeout(void)
  330. +     }
  331. +     else
  332. +     {
  333. +-      return;
  334. ++      // time when this keypress will be released and we'd like to be called again
  335. ++      unsigned int timeout = CEC_PROCESSOR_SIGNAL_WAIT_TIME;
  336. ++      if (m_iCurrentButton != CEC_USER_CONTROL_CODE_UNKNOWN && m_iCurrentButton == comboKey && iTimeoutMs > 0)
  337. ++        timeout = iTimeoutMs - (iNow - m_buttontime) + 1;
  338. ++      else if (m_iCurrentButton != CEC_USER_CONTROL_CODE_UNKNOWN && m_iCurrentButton != comboKey)
  339. ++        timeout = CEC_BUTTON_TIMEOUT - (iNow - m_buttontime) + 1;
  340. ++      if (timeout > CEC_PROCESSOR_SIGNAL_WAIT_TIME)
  341. ++      {
  342. ++        LIB_CEC->AddLog(CEC_LOG_ERROR, "Unexpected timeout: %d (%.3f %.3f %.3f) k:%02x", timeout, iNow*1e-3, m_buttontime*1e-3, CEC_BUTTON_TIMEOUT*1e-3, m_iCurrentButton);
  343. ++        timeout = CEC_PROCESSOR_SIGNAL_WAIT_TIME;
  344. ++      }
  345. ++      return timeout;
  346. +     }
  347. +   }
  348. +
  349. +   LIB_CEC->AddLog(CEC_LOG_DEBUG, "key auto-released: %s (%1x)", ToString(key.keycode), key.keycode);
  350. +   QueueAddKey(key);
  351. ++  return CEC_PROCESSOR_SIGNAL_WAIT_TIME;
  352. + }
  353. +
  354. + bool CCECClient::EnableCallbacks(void *cbParam, ICECCallbacks *callbacks)
  355. +diff --git a/src/libcec/CECClient.h b/src/libcec/CECClient.h
  356. +index 12f8a3b..c9ce5e3 100644
  357. +--- a/src/libcec/CECClient.h
  358. ++++ b/src/libcec/CECClient.h
  359. +@@ -272,7 +272,7 @@ namespace CEC
  360. +     virtual void                  AddKey(bool bSendComboKey = false);
  361. +     virtual void                  AddKey(const cec_keypress &key);
  362. +     virtual void                  SetCurrentButton(const cec_user_control_code iButtonCode);
  363. +-    virtual void                  CheckKeypressTimeout(void);
  364. ++    virtual uint16_t              CheckKeypressTimeout(void);
  365. +     virtual void                  SourceActivated(const cec_logical_address logicalAddress);
  366. +     virtual void                  SourceDeactivated(const cec_logical_address logicalAddress);
  367. +
  368. +diff --git a/src/libcec/CECProcessor.cpp b/src/libcec/CECProcessor.cpp
  369. +index 99f71aa..604b950 100644
  370. +--- a/src/libcec/CECProcessor.cpp
  371. ++++ b/src/libcec/CECProcessor.cpp
  372. +@@ -52,7 +52,6 @@
  373. + using namespace CEC;
  374. + using namespace PLATFORM;
  375. +
  376. +-#define CEC_PROCESSOR_SIGNAL_WAIT_TIME 1000
  377. + #define ACTIVE_SOURCE_CHECK_INTERVAL   500
  378. + #define TV_PRESENT_CHECK_INTERVAL      30000
  379. +
  380. +@@ -260,6 +259,7 @@ bool CCECProcessor::OnCommandReceived(const cec_command &command)
  381. +
  382. + void *CCECProcessor::Process(void)
  383. + {
  384. ++  uint16_t timeout = CEC_PROCESSOR_SIGNAL_WAIT_TIME;
  385. +   m_libcec->AddLog(CEC_LOG_DEBUG, "processor thread started");
  386. +
  387. +   if (!m_connCheck)
  388. +@@ -274,13 +274,13 @@ void *CCECProcessor::Process(void)
  389. +   while (!IsStopped() && m_communication->IsOpen())
  390. +   {
  391. +     // wait for a new incoming command, and process it
  392. +-    if (m_inBuffer.Pop(command, CEC_PROCESSOR_SIGNAL_WAIT_TIME))
  393. ++    if (m_inBuffer.Pop(command, timeout))
  394. +       ProcessCommand(command);
  395. +
  396. +     if (CECInitialised() && !IsStopped())
  397. +     {
  398. +       // check clients for keypress timeouts
  399. +-      m_libcec->CheckKeypressTimeout();
  400. ++      timeout = m_libcec->CheckKeypressTimeout();
  401. +
  402. +       // check if we need to replace handlers
  403. +       ReplaceHandlers();
  404. +@@ -311,6 +311,8 @@ void *CCECProcessor::Process(void)
  405. +         tvPresentCheck.Init(TV_PRESENT_CHECK_INTERVAL);
  406. +       }
  407. +     }
  408. ++    else
  409. ++      timeout = CEC_PROCESSOR_SIGNAL_WAIT_TIME;
  410. +   }
  411. +
  412. +   return NULL;
  413. +diff --git a/src/libcec/LibCEC.cpp b/src/libcec/LibCEC.cpp
  414. +index af36b79..5ccb8dd 100644
  415. +--- a/src/libcec/LibCEC.cpp
  416. ++++ b/src/libcec/LibCEC.cpp
  417. +@@ -361,11 +361,17 @@ bool CLibCEC::IsValidPhysicalAddress(uint16_t iPhysicalAddress)
  418. +          iPhysicalAddress <= CEC_MAX_PHYSICAL_ADDRESS;
  419. + }
  420. +
  421. +-void CLibCEC::CheckKeypressTimeout(void)
  422. ++uint16_t CLibCEC::CheckKeypressTimeout(void)
  423. + {
  424. ++  uint16_t timeout = CEC_PROCESSOR_SIGNAL_WAIT_TIME;
  425. +   // check all clients
  426. +   for (std::vector<CECClientPtr>::iterator it = m_clients.begin(); it != m_clients.end(); it++)
  427. +-    (*it)->CheckKeypressTimeout();
  428. ++  {
  429. ++    uint16_t t = (*it)->CheckKeypressTimeout();
  430. ++    if (t < timeout)
  431. ++      timeout = t;
  432. ++  }
  433. ++  return timeout;
  434. + }
  435. +
  436. + void CLibCEC::AddLog(const cec_log_level level, const char *strFormat, ...)
  437. +diff --git a/src/libcec/LibCEC.h b/src/libcec/LibCEC.h
  438. +index 6d9a229..d9d1e7b 100644
  439. +--- a/src/libcec/LibCEC.h
  440. ++++ b/src/libcec/LibCEC.h
  441. +@@ -39,6 +39,8 @@
  442. + #include "CECTypeUtils.h"
  443. + #include <memory>
  444. +
  445. ++#define CEC_PROCESSOR_SIGNAL_WAIT_TIME 1000
  446. ++
  447. + namespace CEC
  448. + {
  449. +   class CAdapterCommunication;
  450. +@@ -125,7 +127,7 @@ namespace CEC
  451. +
  452. +       void AddLog(const cec_log_level level, const char *strFormat, ...);
  453. +       void AddCommand(const cec_command &command);
  454. +-      void CheckKeypressTimeout(void);
  455. ++      uint16_t CheckKeypressTimeout(void);
  456. +       void Alert(const libcec_alert type, const libcec_parameter &param);
  457. +
  458. +       static bool IsValidPhysicalAddress(uint16_t iPhysicalAddress);
  459. +--
  460. +1.9.1
  461. +
  462. +
  463. +From 41f0f3ec9ac136da3565c96fd5a7075499f3938d Mon Sep 17 00:00:00 2001
  464. +From: popcornmix <popcornmix@gmail.com>
  465. +Date: Fri, 24 Oct 2014 13:51:34 +0100
  466. +Subject: [PATCH 2/6] Keep track of time since initial button press and last
  467. + button update
  468. +
  469. +---
  470. + src/libcec/CECClient.cpp | 44 +++++++++++++++++++++++++++-----------------
  471. + src/libcec/CECClient.h   |  3 ++-
  472. + 2 files changed, 29 insertions(+), 18 deletions(-)
  473. +
  474. +diff --git a/src/libcec/CECClient.cpp b/src/libcec/CECClient.cpp
  475. +index e307c0e..e7935b9 100644
  476. +--- a/src/libcec/CECClient.cpp
  477. ++++ b/src/libcec/CECClient.cpp
  478. +@@ -54,7 +54,8 @@ CCECClient::CCECClient(CCECProcessor *processor, const libcec_configuration &con
  479. +     m_bInitialised(false),
  480. +     m_bRegistered(false),
  481. +     m_iCurrentButton(CEC_USER_CONTROL_CODE_UNKNOWN),
  482. +-    m_buttontime(0),
  483. ++    m_initialButtontime(0),
  484. ++    m_updateButtontime(0),
  485. +     m_iPreventForwardingPowerOffCommand(0),
  486. +     m_iLastKeypressTime(0)
  487. + {
  488. +@@ -981,9 +982,10 @@ void CCECClient::AddKey(bool bSendComboKey /* = false */)
  489. +     CLockObject lock(m_mutex);
  490. +     if (m_iCurrentButton != CEC_USER_CONTROL_CODE_UNKNOWN)
  491. +     {
  492. +-      key.duration = (unsigned int) (GetTimeMs() - m_buttontime);
  493. ++      unsigned int duration = (unsigned int) (GetTimeMs() - m_updateButtontime);
  494. ++      key.duration = (unsigned int) (GetTimeMs() - m_initialButtontime);
  495. +
  496. +-      if (key.duration > m_configuration.iComboKeyTimeoutMs ||
  497. ++      if (duration > m_configuration.iComboKeyTimeoutMs ||
  498. +           m_configuration.iComboKeyTimeoutMs == 0 ||
  499. +           m_iCurrentButton != m_configuration.comboKey ||
  500. +           bSendComboKey)
  501. +@@ -991,14 +993,15 @@ void CCECClient::AddKey(bool bSendComboKey /* = false */)
  502. +         key.keycode = m_iCurrentButton;
  503. +
  504. +         m_iCurrentButton = CEC_USER_CONTROL_CODE_UNKNOWN;
  505. +-        m_buttontime = 0;
  506. ++        m_initialButtontime = 0;
  507. ++        m_updateButtontime = 0;
  508. +       }
  509. +     }
  510. +   }
  511. +
  512. +   if (key.keycode != CEC_USER_CONTROL_CODE_UNKNOWN)
  513. +   {
  514. +-    LIB_CEC->AddLog(CEC_LOG_DEBUG, "key released: %s (%1x)", ToString(key.keycode), key.keycode);
  515. ++    LIB_CEC->AddLog(CEC_LOG_DEBUG, "key released: %s (%1x) D:%dms", ToString(key.keycode), key.keycode, key.duration);
  516. +     QueueAddKey(key);
  517. +   }
  518. + }
  519. +@@ -1012,7 +1015,7 @@ void CCECClient::AddKey(const cec_keypress &key)
  520. +     AddKey();
  521. +     return;
  522. +   }
  523. +-
  524. ++  bool isrepeat = false;
  525. +   cec_keypress transmitKey(key);
  526. +   cec_user_control_code comboKey(m_configuration.clientVersion >= LIBCEC_VERSION_TO_UINT(2, 0, 5) ?
  527. +       m_configuration.comboKey : CEC_USER_CONTROL_CODE_STOP);
  528. +@@ -1035,22 +1038,27 @@ void CCECClient::AddKey(const cec_keypress &key)
  529. +         AddKey(true);
  530. +     }
  531. +
  532. ++    LIB_CEC->AddLog(CEC_LOG_DEBUG, "key pressed: %s (%1x) current(%lx) duration(%d)", ToString(transmitKey.keycode), transmitKey.keycode, m_iCurrentButton, key.duration);
  533. ++
  534. +     if (m_iCurrentButton == key.keycode)
  535. +     {
  536. +-      m_buttontime = GetTimeMs();
  537. ++      m_updateButtontime = GetTimeMs();
  538. ++      isrepeat = true;
  539. +     }
  540. +     else
  541. +     {
  542. +-      AddKey();
  543. ++      if (m_iCurrentButton != transmitKey.keycode)
  544. ++        AddKey();
  545. +       if (key.duration == 0)
  546. +       {
  547. +         m_iCurrentButton = transmitKey.keycode;
  548. +-        m_buttontime = m_iCurrentButton == CEC_USER_CONTROL_CODE_UNKNOWN || key.duration > 0 ? 0 : GetTimeMs();
  549. ++        m_initialButtontime = m_iCurrentButton == CEC_USER_CONTROL_CODE_UNKNOWN || key.duration > 0 ? 0 : GetTimeMs();
  550. ++        m_updateButtontime = m_initialButtontime;
  551. +       }
  552. +     }
  553. +   }
  554. +
  555. +-  if (key.keycode != comboKey || key.duration > 0)
  556. ++  if (!isrepeat && (key.keycode != comboKey || key.duration > 0))
  557. +   {
  558. +     LIB_CEC->AddLog(CEC_LOG_DEBUG, "key pressed: %s (%1x)", ToString(transmitKey.keycode), transmitKey.keycode);
  559. +     QueueAddKey(transmitKey);
  560. +@@ -1074,32 +1082,34 @@ uint16_t CCECClient::CheckKeypressTimeout(void)
  561. +   {
  562. +     CLockObject lock(m_mutex);
  563. +     uint64_t iNow = GetTimeMs();
  564. ++    LIB_CEC->AddLog(CEC_LOG_DEBUG, "%s T:%.3f", __FUNCTION__, iNow*1e-3);
  565. +     cec_user_control_code comboKey(m_configuration.clientVersion >= LIBCEC_VERSION_TO_UINT(2, 0, 5) ?
  566. +         m_configuration.comboKey : CEC_USER_CONTROL_CODE_STOP);
  567. +     uint32_t iTimeoutMs(m_configuration.clientVersion >= LIBCEC_VERSION_TO_UINT(2, 0, 5) ?
  568. +         m_configuration.iComboKeyTimeoutMs : CEC_DEFAULT_COMBO_TIMEOUT_MS);
  569. +
  570. +     if (m_iCurrentButton != CEC_USER_CONTROL_CODE_UNKNOWN &&
  571. +-          ((m_iCurrentButton == comboKey && iTimeoutMs > 0 && iNow - m_buttontime > iTimeoutMs) ||
  572. +-          (m_iCurrentButton != comboKey && iNow - m_buttontime > CEC_BUTTON_TIMEOUT)))
  573. ++          ((m_iCurrentButton == comboKey && iTimeoutMs > 0 && iNow - m_updateButtontime > iTimeoutMs) ||
  574. ++          (m_iCurrentButton != comboKey && iNow - m_updateButtontime > CEC_BUTTON_TIMEOUT)))
  575. +     {
  576. +-      key.duration = (unsigned int) (iNow - m_buttontime);
  577. ++      key.duration = (unsigned int) (iNow - m_initialButtontime);
  578. +       key.keycode = m_iCurrentButton;
  579. +
  580. +       m_iCurrentButton = CEC_USER_CONTROL_CODE_UNKNOWN;
  581. +-      m_buttontime = 0;
  582. ++      m_initialButtontime = 0;
  583. ++      m_updateButtontime = 0;
  584. +     }
  585. +     else
  586. +     {
  587. +       // time when this keypress will be released and we'd like to be called again
  588. +       unsigned int timeout = CEC_PROCESSOR_SIGNAL_WAIT_TIME;
  589. +       if (m_iCurrentButton != CEC_USER_CONTROL_CODE_UNKNOWN && m_iCurrentButton == comboKey && iTimeoutMs > 0)
  590. +-        timeout = iTimeoutMs - (iNow - m_buttontime) + 1;
  591. ++        timeout = iTimeoutMs - (iNow - m_updateButtontime) + 1;
  592. +       else if (m_iCurrentButton != CEC_USER_CONTROL_CODE_UNKNOWN && m_iCurrentButton != comboKey)
  593. +-        timeout = CEC_BUTTON_TIMEOUT - (iNow - m_buttontime) + 1;
  594. ++        timeout = CEC_BUTTON_TIMEOUT - (iNow - m_updateButtontime) + 1;
  595. +       if (timeout > CEC_PROCESSOR_SIGNAL_WAIT_TIME)
  596. +       {
  597. +-        LIB_CEC->AddLog(CEC_LOG_ERROR, "Unexpected timeout: %d (%.3f %.3f %.3f) k:%02x", timeout, iNow*1e-3, m_buttontime*1e-3, CEC_BUTTON_TIMEOUT*1e-3, m_iCurrentButton);
  598. ++        LIB_CEC->AddLog(CEC_LOG_ERROR, "Unexpected timeout: %d (%.3f %.3f %.3f) k:%02x", timeout, iNow*1e-3, m_updateButtontime*1e-3, CEC_BUTTON_TIMEOUT*1e-3, m_iCurrentButton);
  599. +         timeout = CEC_PROCESSOR_SIGNAL_WAIT_TIME;
  600. +       }
  601. +       return timeout;
  602. +diff --git a/src/libcec/CECClient.h b/src/libcec/CECClient.h
  603. +index c9ce5e3..611c68b 100644
  604. +--- a/src/libcec/CECClient.h
  605. ++++ b/src/libcec/CECClient.h
  606. +@@ -404,7 +404,8 @@ namespace CEC
  607. +     PLATFORM::CMutex      m_mutex;                             /**< mutex for changes to this instance */
  608. +     PLATFORM::CMutex      m_cbMutex;                           /**< mutex that is held when doing anything with callbacks */
  609. +     cec_user_control_code m_iCurrentButton;                    /**< the control code of the button that's currently held down (if any) */
  610. +-    int64_t               m_buttontime;                        /**< the timestamp when the button was pressed (in seconds since epoch), or 0 if none was pressed. */
  611. ++    int64_t               m_initialButtontime;                 /**< the timestamp when the button was initially pressed (in seconds since epoch), or 0 if none was pressed. */
  612. ++    int64_t               m_updateButtontime;                  /**< the timestamp when the button was updated (in seconds since epoch), or 0 if none was pressed. */
  613. +     int64_t               m_iPreventForwardingPowerOffCommand; /**< prevent forwarding standby commands until this time */
  614. +     int64_t               m_iLastKeypressTime;                 /**< last time a key press was sent to the client */
  615. +     cec_keypress          m_lastKeypress;                      /**< the last key press that was sent to the client */
  616. +--
  617. +1.9.1
  618. +
  619. +
  620. +From 273ead6980b69eddf98810eb1eb33d94a7d74fce Mon Sep 17 00:00:00 2001
  621. +From: popcornmix <popcornmix@gmail.com>
  622. +Date: Tue, 28 Oct 2014 00:09:18 +0000
  623. +Subject: [PATCH 3/6] Support repeating button presses with configurable repeat
  624. + rate
  625. +
  626. +---
  627. + include/cectypes.h                               |   6 ++
  628. + src/libcec/CECClient.cpp                         | 100 +++++++++++++++++++----
  629. + src/libcec/CECClient.h                           |   6 +-
  630. + src/libcec/implementations/CECCommandHandler.cpp |   2 +-
  631. + 4 files changed, 96 insertions(+), 18 deletions(-)
  632. +
  633. +diff --git a/include/cectypes.h b/include/cectypes.h
  634. +index acff259..8f098ef 100644
  635. +--- a/include/cectypes.h
  636. ++++ b/include/cectypes.h
  637. +@@ -1493,6 +1493,8 @@ struct libcec_configuration
  638. +                                                    XXX changed meaning in 2.2.0 to not break binary compatibility. next major (3.0) release will fix it in a nicer way */
  639. +   cec_user_control_code comboKey;             /*!< key code that initiates combo keys. defaults to CEC_USER_CONTROL_CODE_F1_BLUE. CEC_USER_CONTROL_CODE_UNKNOWN to disable. added in 2.0.5 */
  640. +   uint32_t              iComboKeyTimeoutMs;   /*!< timeout until the combo key is sent as normal keypress */
  641. ++  uint32_t              iButtonRepeatRateMs;  /*!< rate at which buttons autorepeat. 0 means rely on CEC device */
  642. ++  uint32_t              iButtonReleaseDelayMs;/*!< duration after last update until a button is considered released */
  643. +
  644. + #ifdef __cplusplus
  645. +    libcec_configuration(void) { Clear(); }
  646. +@@ -1527,6 +1529,8 @@ struct libcec_configuration
  647. +                  cecVersion                == other.cecVersion &&
  648. +                  adapterType               == other.adapterType &&
  649. +                  iDoubleTapTimeout50Ms     == other.iDoubleTapTimeout50Ms &&
  650. ++                 iButtonRepeatRateMs       == other.iButtonRepeatRateMs &&
  651. ++                 iButtonReleaseDelayMs     == other.iButtonReleaseDelayMs &&
  652. +                  (other.clientVersion <= LIBCEC_VERSION_TO_UINT(2, 0, 4) || comboKey            == other.comboKey) &&
  653. +                  (other.clientVersion <= LIBCEC_VERSION_TO_UINT(2, 0, 4) || iComboKeyTimeoutMs  == other.iComboKeyTimeoutMs) &&
  654. +                  (other.clientVersion <  LIBCEC_VERSION_TO_UINT(2, 1, 0) || bPowerOnScreensaver == other.bPowerOnScreensaver));
  655. +@@ -1567,6 +1571,8 @@ struct libcec_configuration
  656. +     iDoubleTapTimeout50Ms =           CEC_DOUBLE_TAP_TIMEOUT_50_MS;
  657. +     comboKey =                        CEC_USER_CONTROL_CODE_STOP;
  658. +     iComboKeyTimeoutMs =              CEC_DEFAULT_COMBO_TIMEOUT_MS;
  659. ++    iButtonRepeatRateMs =             0;
  660. ++    iButtonReleaseDelayMs =           CEC_BUTTON_TIMEOUT;
  661. +
  662. +     memset(strDeviceName, 0, 13);
  663. +     deviceTypes.Clear();
  664. +diff --git a/src/libcec/CECClient.cpp b/src/libcec/CECClient.cpp
  665. +index e7935b9..598628d 100644
  666. +--- a/src/libcec/CECClient.cpp
  667. ++++ b/src/libcec/CECClient.cpp
  668. +@@ -56,6 +56,10 @@ CCECClient::CCECClient(CCECProcessor *processor, const libcec_configuration &con
  669. +     m_iCurrentButton(CEC_USER_CONTROL_CODE_UNKNOWN),
  670. +     m_initialButtontime(0),
  671. +     m_updateButtontime(0),
  672. ++    m_repeatButtontime(0),
  673. ++    m_releaseButtontime(0),
  674. ++    m_pressedButtoncount(0),
  675. ++    m_releasedButtoncount(0),
  676. +     m_iPreventForwardingPowerOffCommand(0),
  677. +     m_iLastKeypressTime(0)
  678. + {
  679. +@@ -851,6 +855,9 @@ bool CCECClient::GetCurrentConfiguration(libcec_configuration &configuration)
  680. +   configuration.bMonitorOnly              = m_configuration.bMonitorOnly;
  681. +   configuration.cecVersion                = m_configuration.cecVersion;
  682. +   configuration.adapterType               = m_configuration.adapterType;
  683. ++  configuration.iDoubleTapTimeout50Ms     = m_configuration.iDoubleTapTimeout50Ms;
  684. ++  configuration.iButtonRepeatRateMs       = m_configuration.iButtonRepeatRateMs;
  685. ++  configuration.iButtonReleaseDelayMs     = m_configuration.iButtonReleaseDelayMs;
  686. +
  687. +   return true;
  688. + }
  689. +@@ -894,6 +901,9 @@ bool CCECClient::SetConfiguration(const libcec_configuration &configuration)
  690. +     m_configuration.cecVersion                 = configuration.cecVersion;
  691. +     m_configuration.adapterType                = configuration.adapterType;
  692. +     m_configuration.iDoubleTapTimeout50Ms      = configuration.iDoubleTapTimeout50Ms;
  693. ++    m_configuration.iButtonRepeatRateMs        = configuration.iButtonRepeatRateMs;
  694. ++    m_configuration.iButtonReleaseDelayMs      = configuration.iButtonReleaseDelayMs;
  695. ++
  696. +     m_configuration.deviceTypes.Add(configuration.deviceTypes[0]);
  697. +
  698. +     if (m_configuration.clientVersion >= LIBCEC_VERSION_TO_UINT(2, 0, 5))
  699. +@@ -950,6 +960,7 @@ bool CCECClient::SetConfiguration(const libcec_configuration &configuration)
  700. +     primary->ActivateSource();
  701. +   }
  702. +
  703. ++  LIB_CEC->AddLog(CEC_LOG_DEBUG, "%s: %d:%d:%d", __FUNCTION__, DoubleTapTimeoutMS(), m_configuration.iButtonRepeatRateMs, m_configuration.iButtonReleaseDelayMs);
  704. +   return true;
  705. + }
  706. +
  707. +@@ -973,11 +984,15 @@ void CCECClient::AddCommand(const cec_command &command)
  708. +   }
  709. + }
  710. +
  711. +-void CCECClient::AddKey(bool bSendComboKey /* = false */)
  712. ++void CCECClient::AddKey(bool bSendComboKey /* = false */, bool bButtonRelease /* = false */)
  713. + {
  714. +   cec_keypress key;
  715. +   key.keycode = CEC_USER_CONTROL_CODE_UNKNOWN;
  716. +
  717. ++  // we ignore button releases when supporting repeating keys
  718. ++  if (bButtonRelease && m_configuration.iButtonRepeatRateMs && m_configuration.iButtonReleaseDelayMs)
  719. ++    return;
  720. ++
  721. +   {
  722. +     CLockObject lock(m_mutex);
  723. +     if (m_iCurrentButton != CEC_USER_CONTROL_CODE_UNKNOWN)
  724. +@@ -995,6 +1010,10 @@ void CCECClient::AddKey(bool bSendComboKey /* = false */)
  725. +         m_iCurrentButton = CEC_USER_CONTROL_CODE_UNKNOWN;
  726. +         m_initialButtontime = 0;
  727. +         m_updateButtontime = 0;
  728. ++        m_repeatButtontime = 0;
  729. ++        m_releaseButtontime = 0;
  730. ++        m_pressedButtoncount = 0;
  731. ++        m_releasedButtoncount = 0;
  732. +       }
  733. +     }
  734. +   }
  735. +@@ -1012,6 +1031,7 @@ void CCECClient::AddKey(const cec_keypress &key)
  736. +       key.keycode < CEC_USER_CONTROL_CODE_SELECT)
  737. +   {
  738. +     // send back the previous key if there is one
  739. ++    LIB_CEC->AddLog(CEC_LOG_DEBUG, "Unexpected key %s (%1x) D:%dms", ToString(key.keycode), key.keycode, key.duration);
  740. +     AddKey();
  741. +     return;
  742. +   }
  743. +@@ -1035,7 +1055,10 @@ void CCECClient::AddKey(const cec_keypress &key)
  744. +         transmitKey.keycode = CEC_USER_CONTROL_CODE_DOT;
  745. +       // default, send back the previous key
  746. +       else
  747. ++      {
  748. ++        LIB_CEC->AddLog(CEC_LOG_DEBUG, "Combo key %s (%1x) D%dms:", ToString(key.keycode), key.keycode, key.duration);
  749. +         AddKey(true);
  750. ++      }
  751. +     }
  752. +
  753. +     LIB_CEC->AddLog(CEC_LOG_DEBUG, "key pressed: %s (%1x) current(%lx) duration(%d)", ToString(transmitKey.keycode), transmitKey.keycode, m_iCurrentButton, key.duration);
  754. +@@ -1043,17 +1066,44 @@ void CCECClient::AddKey(const cec_keypress &key)
  755. +     if (m_iCurrentButton == key.keycode)
  756. +     {
  757. +       m_updateButtontime = GetTimeMs();
  758. +-      isrepeat = true;
  759. ++      m_releaseButtontime = m_updateButtontime + (m_configuration.iButtonReleaseDelayMs ? m_configuration.iButtonReleaseDelayMs : CEC_BUTTON_TIMEOUT);
  760. ++      // want to have seen some updated before considering a repeat
  761. ++      if (m_configuration.iButtonRepeatRateMs)
  762. ++      {
  763. ++        if (!m_repeatButtontime && m_pressedButtoncount > 1)
  764. ++          m_repeatButtontime = m_initialButtontime + DoubleTapTimeoutMS();
  765. ++        isrepeat = true;
  766. ++      }
  767. ++      m_pressedButtoncount++;
  768. +     }
  769. +     else
  770. +     {
  771. +       if (m_iCurrentButton != transmitKey.keycode)
  772. ++      {
  773. ++        LIB_CEC->AddLog(CEC_LOG_DEBUG, "Changed key %s (%1x) D:%dms cur:%lx", ToString(transmitKey.keycode), transmitKey.keycode, transmitKey.duration, m_iCurrentButton);
  774. +         AddKey();
  775. ++      }
  776. +       if (key.duration == 0)
  777. +       {
  778. +         m_iCurrentButton = transmitKey.keycode;
  779. +-        m_initialButtontime = m_iCurrentButton == CEC_USER_CONTROL_CODE_UNKNOWN || key.duration > 0 ? 0 : GetTimeMs();
  780. +-        m_updateButtontime = m_initialButtontime;
  781. ++        if (m_iCurrentButton == CEC_USER_CONTROL_CODE_UNKNOWN)
  782. ++        {
  783. ++          m_initialButtontime = 0;
  784. ++          m_updateButtontime = 0;
  785. ++          m_repeatButtontime = 0;
  786. ++          m_releaseButtontime = 0;
  787. ++          m_pressedButtoncount = 0;
  788. ++          m_releasedButtoncount = 0;
  789. ++        }
  790. ++        else
  791. ++        {
  792. ++          m_initialButtontime = GetTimeMs();
  793. ++          m_updateButtontime = m_initialButtontime;
  794. ++          m_repeatButtontime = 0; // set this on next update
  795. ++          m_releaseButtontime = m_initialButtontime + (m_configuration.iButtonReleaseDelayMs ? m_configuration.iButtonReleaseDelayMs : CEC_BUTTON_TIMEOUT);
  796. ++          m_pressedButtoncount = 1;
  797. ++          m_releasedButtoncount = 0;
  798. ++        }
  799. +       }
  800. +     }
  801. +   }
  802. +@@ -1072,12 +1122,16 @@ void CCECClient::SetCurrentButton(const cec_user_control_code iButtonCode)
  803. +   key.duration = 0;
  804. +   key.keycode = iButtonCode;
  805. +
  806. ++  LIB_CEC->AddLog(CEC_LOG_DEBUG, "SetCurrentButton %s (%1x) D:%dms cur:%lx", ToString(key.keycode), key.keycode, key.duration);
  807. +   AddKey(key);
  808. + }
  809. +
  810. + uint16_t CCECClient::CheckKeypressTimeout(void)
  811. + {
  812. ++  // time when we'd like to be called again
  813. ++  unsigned int timeout = CEC_PROCESSOR_SIGNAL_WAIT_TIME;
  814. +   cec_keypress key;
  815. ++  key.keycode = CEC_USER_CONTROL_CODE_UNKNOWN;
  816. +
  817. +   {
  818. +     CLockObject lock(m_mutex);
  819. +@@ -1089,8 +1143,8 @@ uint16_t CCECClient::CheckKeypressTimeout(void)
  820. +         m_configuration.iComboKeyTimeoutMs : CEC_DEFAULT_COMBO_TIMEOUT_MS);
  821. +
  822. +     if (m_iCurrentButton != CEC_USER_CONTROL_CODE_UNKNOWN &&
  823. +-          ((m_iCurrentButton == comboKey && iTimeoutMs > 0 && iNow - m_updateButtontime > iTimeoutMs) ||
  824. +-          (m_iCurrentButton != comboKey && iNow - m_updateButtontime > CEC_BUTTON_TIMEOUT)))
  825. ++          ((m_iCurrentButton == comboKey && iTimeoutMs > 0 && iNow - m_updateButtontime >= iTimeoutMs) ||
  826. ++          (m_iCurrentButton != comboKey && m_releaseButtontime && iNow >= (uint64_t)m_releaseButtontime)))
  827. +     {
  828. +       key.duration = (unsigned int) (iNow - m_initialButtontime);
  829. +       key.keycode = m_iCurrentButton;
  830. +@@ -1098,27 +1152,41 @@ uint16_t CCECClient::CheckKeypressTimeout(void)
  831. +       m_iCurrentButton = CEC_USER_CONTROL_CODE_UNKNOWN;
  832. +       m_initialButtontime = 0;
  833. +       m_updateButtontime = 0;
  834. ++      m_repeatButtontime = 0;
  835. ++      m_releaseButtontime = 0;
  836. ++      m_pressedButtoncount = 0;
  837. ++      m_releasedButtoncount = 0;
  838. ++    }
  839. ++    else if (m_iCurrentButton != CEC_USER_CONTROL_CODE_UNKNOWN &&
  840. ++          (m_iCurrentButton != comboKey && m_repeatButtontime && iNow >= (uint64_t)m_repeatButtontime))
  841. ++    {
  842. ++      key.duration = 0;
  843. ++      key.keycode = m_iCurrentButton;
  844. ++      m_repeatButtontime = iNow + m_configuration.iButtonRepeatRateMs;
  845. ++      timeout = std::min((uint64_t)timeout, m_repeatButtontime - iNow);
  846. +     }
  847. +     else
  848. +     {
  849. +-      // time when this keypress will be released and we'd like to be called again
  850. +-      unsigned int timeout = CEC_PROCESSOR_SIGNAL_WAIT_TIME;
  851. +       if (m_iCurrentButton != CEC_USER_CONTROL_CODE_UNKNOWN && m_iCurrentButton == comboKey && iTimeoutMs > 0)
  852. +-        timeout = iTimeoutMs - (iNow - m_updateButtontime) + 1;
  853. +-      else if (m_iCurrentButton != CEC_USER_CONTROL_CODE_UNKNOWN && m_iCurrentButton != comboKey)
  854. +-        timeout = CEC_BUTTON_TIMEOUT - (iNow - m_updateButtontime) + 1;
  855. ++        timeout = std::min((uint64_t)timeout, m_updateButtontime - iNow + iTimeoutMs);
  856. ++      if (m_iCurrentButton != CEC_USER_CONTROL_CODE_UNKNOWN && m_iCurrentButton != comboKey && m_releaseButtontime)
  857. ++        timeout = std::min((uint64_t)timeout, m_releaseButtontime - iNow);
  858. ++      if (m_iCurrentButton != CEC_USER_CONTROL_CODE_UNKNOWN && m_iCurrentButton != comboKey && m_repeatButtontime)
  859. ++        timeout = std::min((uint64_t)timeout, m_repeatButtontime - iNow);
  860. +       if (timeout > CEC_PROCESSOR_SIGNAL_WAIT_TIME)
  861. +       {
  862. +-        LIB_CEC->AddLog(CEC_LOG_ERROR, "Unexpected timeout: %d (%.3f %.3f %.3f) k:%02x", timeout, iNow*1e-3, m_updateButtontime*1e-3, CEC_BUTTON_TIMEOUT*1e-3, m_iCurrentButton);
  863. ++        LIB_CEC->AddLog(CEC_LOG_ERROR, "Unexpected timeout: %d (%.3f %.3f %.3f) k:%02x", timeout, iNow*1e-3, m_updateButtontime*1e-3, m_releaseButtontime*1e-3, m_iCurrentButton);
  864. +         timeout = CEC_PROCESSOR_SIGNAL_WAIT_TIME;
  865. +       }
  866. +-      return timeout;
  867. +     }
  868. ++    LIB_CEC->AddLog(CEC_LOG_DEBUG, "key %s: %s (%1x) timeout:%dms (rel:%d,rep:%d,prs:%d,rel:%d)", key.keycode == CEC_USER_CONTROL_CODE_UNKNOWN ? "idle" : key.duration ? "released" : "repeated",
  869. ++        ToString(m_iCurrentButton), m_iCurrentButton, timeout, (int)(m_releaseButtontime ? m_releaseButtontime - iNow : 0), (int)(m_repeatButtontime ? m_repeatButtontime - iNow : 0), m_pressedButtoncount, m_releasedButtoncount);
  870. +   }
  871. +
  872. +-  LIB_CEC->AddLog(CEC_LOG_DEBUG, "key auto-released: %s (%1x)", ToString(key.keycode), key.keycode);
  873. +-  QueueAddKey(key);
  874. +-  return CEC_PROCESSOR_SIGNAL_WAIT_TIME;
  875. ++  if (key.keycode != CEC_USER_CONTROL_CODE_UNKNOWN)
  876. ++    QueueAddKey(key);
  877. ++
  878. ++  return timeout;
  879. + }
  880. +
  881. + bool CCECClient::EnableCallbacks(void *cbParam, ICECCallbacks *callbacks)
  882. +diff --git a/src/libcec/CECClient.h b/src/libcec/CECClient.h
  883. +index 611c68b..adeb5af 100644
  884. +--- a/src/libcec/CECClient.h
  885. ++++ b/src/libcec/CECClient.h
  886. +@@ -269,7 +269,7 @@ namespace CEC
  887. +     // callbacks
  888. +     virtual void                  Alert(const libcec_alert type, const libcec_parameter &param) { QueueAlert(type, param); }
  889. +     virtual void                  AddLog(const cec_log_message &message) { QueueAddLog(message); }
  890. +-    virtual void                  AddKey(bool bSendComboKey = false);
  891. ++    virtual void                  AddKey(bool bSendComboKey = false, bool bButtonRelease = false);
  892. +     virtual void                  AddKey(const cec_keypress &key);
  893. +     virtual void                  SetCurrentButton(const cec_user_control_code iButtonCode);
  894. +     virtual uint16_t              CheckKeypressTimeout(void);
  895. +@@ -406,6 +406,10 @@ namespace CEC
  896. +     cec_user_control_code m_iCurrentButton;                    /**< the control code of the button that's currently held down (if any) */
  897. +     int64_t               m_initialButtontime;                 /**< the timestamp when the button was initially pressed (in seconds since epoch), or 0 if none was pressed. */
  898. +     int64_t               m_updateButtontime;                  /**< the timestamp when the button was updated (in seconds since epoch), or 0 if none was pressed. */
  899. ++    int64_t               m_repeatButtontime;                  /**< the timestamp when the button will next repeat (in seconds since epoch), or 0 if repeat is disabled. */
  900. ++    int64_t               m_releaseButtontime;                 /**< the timestamp when the button will be released (in seconds since epoch), or 0 if none was pressed. */
  901. ++    int32_t               m_pressedButtoncount;                /**< the number of times a button released message has been seen for this press. */
  902. ++    int32_t               m_releasedButtoncount;               /**< the number of times a button pressed message has been seen for this press. */
  903. +     int64_t               m_iPreventForwardingPowerOffCommand; /**< prevent forwarding standby commands until this time */
  904. +     int64_t               m_iLastKeypressTime;                 /**< last time a key press was sent to the client */
  905. +     cec_keypress          m_lastKeypress;                      /**< the last key press that was sent to the client */
  906. +diff --git a/src/libcec/implementations/CECCommandHandler.cpp b/src/libcec/implementations/CECCommandHandler.cpp
  907. +index 6d6244e..d64186f 100644
  908. +--- a/src/libcec/implementations/CECCommandHandler.cpp
  909. ++++ b/src/libcec/implementations/CECCommandHandler.cpp
  910. +@@ -770,7 +770,7 @@ int CCECCommandHandler::HandleUserControlRelease(const cec_command &command)
  911. +
  912. +   CECClientPtr client = m_processor->GetClient(command.destination);
  913. +   if (client)
  914. +-    client->AddKey();
  915. ++    client->AddKey(false, true);
  916. +
  917. +   return COMMAND_HANDLED;
  918. + }
  919. +--
  920. +1.9.1
  921. +
  922. +
  923. +From 3336d0827f7fd159430f3431642b07090c06c869 Mon Sep 17 00:00:00 2001
  924. +From: popcornmix <popcornmix@gmail.com>
  925. +Date: Tue, 28 Oct 2014 01:21:35 +0000
  926. +Subject: [PATCH 4/6] Skip double press removal. It is handled through other
  927. + means.
  928. +
  929. +---
  930. + src/libcec/CECClient.cpp | 18 +-----------------
  931. + src/libcec/CECClient.h   |  2 --
  932. + 2 files changed, 1 insertion(+), 19 deletions(-)
  933. +
  934. +diff --git a/src/libcec/CECClient.cpp b/src/libcec/CECClient.cpp
  935. +index 598628d..dccd874 100644
  936. +--- a/src/libcec/CECClient.cpp
  937. ++++ b/src/libcec/CECClient.cpp
  938. +@@ -60,11 +60,8 @@ CCECClient::CCECClient(CCECProcessor *processor, const libcec_configuration &con
  939. +     m_releaseButtontime(0),
  940. +     m_pressedButtoncount(0),
  941. +     m_releasedButtoncount(0),
  942. +-    m_iPreventForwardingPowerOffCommand(0),
  943. +-    m_iLastKeypressTime(0)
  944. ++    m_iPreventForwardingPowerOffCommand(0)
  945. + {
  946. +-  m_lastKeypress.keycode = CEC_USER_CONTROL_CODE_UNKNOWN;
  947. +-  m_lastKeypress.duration = 0;
  948. +   m_configuration.Clear();
  949. +   // set the initial configuration
  950. +   SetConfiguration(configuration);
  951. +@@ -1647,20 +1644,7 @@ void CCECClient::CallbackAddKey(const cec_keypress &key)
  952. + {
  953. +   CLockObject lock(m_cbMutex);
  954. +   if (m_configuration.callbacks && m_configuration.callbacks->CBCecKeyPress)
  955. +-  {
  956. +-    // prevent double taps
  957. +-    int64_t now = GetTimeMs();
  958. +-    if (m_lastKeypress.keycode != key.keycode ||
  959. +-        key.duration > 0 ||
  960. +-        now - m_iLastKeypressTime >= DoubleTapTimeoutMS())
  961. +-    {
  962. +-      // no double tap
  963. +-      if (key.duration == 0)
  964. +-        m_iLastKeypressTime = now;
  965. +-      m_lastKeypress = key;
  966. +       m_configuration.callbacks->CBCecKeyPress(m_configuration.callbackParam, key);
  967. +-    }
  968. +-  }
  969. + }
  970. +
  971. + void CCECClient::CallbackAddLog(const cec_log_message &message)
  972. +diff --git a/src/libcec/CECClient.h b/src/libcec/CECClient.h
  973. +index adeb5af..43a713b 100644
  974. +--- a/src/libcec/CECClient.h
  975. ++++ b/src/libcec/CECClient.h
  976. +@@ -411,8 +411,6 @@ namespace CEC
  977. +     int32_t               m_pressedButtoncount;                /**< the number of times a button released message has been seen for this press. */
  978. +     int32_t               m_releasedButtoncount;               /**< the number of times a button pressed message has been seen for this press. */
  979. +     int64_t               m_iPreventForwardingPowerOffCommand; /**< prevent forwarding standby commands until this time */
  980. +-    int64_t               m_iLastKeypressTime;                 /**< last time a key press was sent to the client */
  981. +-    cec_keypress          m_lastKeypress;                      /**< the last key press that was sent to the client */
  982. +     PLATFORM::SyncedBuffer<CCallbackWrap*> m_callbackCalls;
  983. +   };
  984. + }
  985. +--
  986. +1.9.1
  987. +
  988. +
  989. +From 0dd0234f620a546bfa843172648383f83d88088c Mon Sep 17 00:00:00 2001
  990. +From: popcornmix <popcornmix@gmail.com>
  991. +Date: Mon, 3 Nov 2014 23:28:04 +0000
  992. +Subject: [PATCH 5/6] Pass through duration on all button repeats
  993. +
  994. +---
  995. + src/libcec/CECClient.cpp | 34 ++++++++++++++++++++++++----------
  996. + 1 file changed, 24 insertions(+), 10 deletions(-)
  997. +
  998. +diff --git a/src/libcec/CECClient.cpp b/src/libcec/CECClient.cpp
  999. +index dccd874..1946148 100644
  1000. +--- a/src/libcec/CECClient.cpp
  1001. ++++ b/src/libcec/CECClient.cpp
  1002. +@@ -986,10 +986,6 @@ void CCECClient::AddKey(bool bSendComboKey /* = false */, bool bButtonRelease /*
  1003. +   cec_keypress key;
  1004. +   key.keycode = CEC_USER_CONTROL_CODE_UNKNOWN;
  1005. +
  1006. +-  // we ignore button releases when supporting repeating keys
  1007. +-  if (bButtonRelease && m_configuration.iButtonRepeatRateMs && m_configuration.iButtonReleaseDelayMs)
  1008. +-    return;
  1009. +-
  1010. +   {
  1011. +     CLockObject lock(m_mutex);
  1012. +     if (m_iCurrentButton != CEC_USER_CONTROL_CODE_UNKNOWN)
  1013. +@@ -1015,6 +1011,10 @@ void CCECClient::AddKey(bool bSendComboKey /* = false */, bool bButtonRelease /*
  1014. +     }
  1015. +   }
  1016. +
  1017. ++  // we don't forward releases when supporting repeating keys
  1018. ++  if (bButtonRelease && m_configuration.iButtonRepeatRateMs)
  1019. ++    return;
  1020. ++
  1021. +   if (key.keycode != CEC_USER_CONTROL_CODE_UNKNOWN)
  1022. +   {
  1023. +     LIB_CEC->AddLog(CEC_LOG_DEBUG, "key released: %s (%1x) D:%dms", ToString(key.keycode), key.keycode, key.duration);
  1024. +@@ -1107,7 +1107,7 @@ void CCECClient::AddKey(const cec_keypress &key)
  1025. +
  1026. +   if (!isrepeat && (key.keycode != comboKey || key.duration > 0))
  1027. +   {
  1028. +-    LIB_CEC->AddLog(CEC_LOG_DEBUG, "key pressed: %s (%1x)", ToString(transmitKey.keycode), transmitKey.keycode);
  1029. ++    LIB_CEC->AddLog(CEC_LOG_DEBUG, "key pressed: %s (%1x, %d)", ToString(transmitKey.keycode), transmitKey.keycode, transmitKey.duration);
  1030. +     QueueAddKey(transmitKey);
  1031. +   }
  1032. + }
  1033. +@@ -1129,6 +1129,7 @@ uint16_t CCECClient::CheckKeypressTimeout(void)
  1034. +   unsigned int timeout = CEC_PROCESSOR_SIGNAL_WAIT_TIME;
  1035. +   cec_keypress key;
  1036. +   key.keycode = CEC_USER_CONTROL_CODE_UNKNOWN;
  1037. ++  key.duration = 0;
  1038. +
  1039. +   {
  1040. +     CLockObject lock(m_mutex);
  1041. +@@ -1140,8 +1141,7 @@ uint16_t CCECClient::CheckKeypressTimeout(void)
  1042. +         m_configuration.iComboKeyTimeoutMs : CEC_DEFAULT_COMBO_TIMEOUT_MS);
  1043. +
  1044. +     if (m_iCurrentButton != CEC_USER_CONTROL_CODE_UNKNOWN &&
  1045. +-          ((m_iCurrentButton == comboKey && iTimeoutMs > 0 && iNow - m_updateButtontime >= iTimeoutMs) ||
  1046. +-          (m_iCurrentButton != comboKey && m_releaseButtontime && iNow >= (uint64_t)m_releaseButtontime)))
  1047. ++          m_iCurrentButton == comboKey && iTimeoutMs > 0 && iNow - m_updateButtontime >= iTimeoutMs)
  1048. +     {
  1049. +       key.duration = (unsigned int) (iNow - m_initialButtontime);
  1050. +       key.keycode = m_iCurrentButton;
  1051. +@@ -1155,9 +1155,23 @@ uint16_t CCECClient::CheckKeypressTimeout(void)
  1052. +       m_releasedButtoncount = 0;
  1053. +     }
  1054. +     else if (m_iCurrentButton != CEC_USER_CONTROL_CODE_UNKNOWN &&
  1055. ++          m_iCurrentButton != comboKey && m_releaseButtontime && iNow >= (uint64_t)m_releaseButtontime)
  1056. ++    {
  1057. ++      key.duration = (unsigned int) (iNow - m_initialButtontime);
  1058. ++      key.keycode = CEC_USER_CONTROL_CODE_UNKNOWN;
  1059. ++
  1060. ++      m_iCurrentButton = CEC_USER_CONTROL_CODE_UNKNOWN;
  1061. ++      m_initialButtontime = 0;
  1062. ++      m_updateButtontime = 0;
  1063. ++      m_repeatButtontime = 0;
  1064. ++      m_releaseButtontime = 0;
  1065. ++      m_pressedButtoncount = 0;
  1066. ++      m_releasedButtoncount = 0;
  1067. ++    }
  1068. ++    else if (m_iCurrentButton != CEC_USER_CONTROL_CODE_UNKNOWN &&
  1069. +           (m_iCurrentButton != comboKey && m_repeatButtontime && iNow >= (uint64_t)m_repeatButtontime))
  1070. +     {
  1071. +-      key.duration = 0;
  1072. ++      key.duration = (unsigned int) (iNow - m_initialButtontime);
  1073. +       key.keycode = m_iCurrentButton;
  1074. +       m_repeatButtontime = iNow + m_configuration.iButtonRepeatRateMs;
  1075. +       timeout = std::min((uint64_t)timeout, m_repeatButtontime - iNow);
  1076. +@@ -1176,8 +1190,8 @@ uint16_t CCECClient::CheckKeypressTimeout(void)
  1077. +         timeout = CEC_PROCESSOR_SIGNAL_WAIT_TIME;
  1078. +       }
  1079. +     }
  1080. +-    LIB_CEC->AddLog(CEC_LOG_DEBUG, "key %s: %s (%1x) timeout:%dms (rel:%d,rep:%d,prs:%d,rel:%d)", key.keycode == CEC_USER_CONTROL_CODE_UNKNOWN ? "idle" : key.duration ? "released" : "repeated",
  1081. +-        ToString(m_iCurrentButton), m_iCurrentButton, timeout, (int)(m_releaseButtontime ? m_releaseButtontime - iNow : 0), (int)(m_repeatButtontime ? m_repeatButtontime - iNow : 0), m_pressedButtoncount, m_releasedButtoncount);
  1082. ++    LIB_CEC->AddLog(CEC_LOG_DEBUG, "Key %s: %s (duration:%d) (%1x) timeout:%dms (rel:%d,rep:%d,prs:%d,rel:%d)", ToString(m_iCurrentButton), key.keycode == CEC_USER_CONTROL_CODE_UNKNOWN ? "idle" : m_repeatButtontime ? "repeated" : "released", key.duration,
  1083. ++        m_iCurrentButton, timeout, (int)(m_releaseButtontime ? m_releaseButtontime - iNow : 0), (int)(m_repeatButtontime ? m_repeatButtontime - iNow : 0), m_pressedButtoncount, m_releasedButtoncount);
  1084. +   }
  1085. +
  1086. +   if (key.keycode != CEC_USER_CONTROL_CODE_UNKNOWN)
  1087. +--
  1088. +1.9.1
  1089. +
  1090. +
  1091. +From 1ea01f59d8186d4d53af41961aaccbbc11651115 Mon Sep 17 00:00:00 2001
  1092. +From: popcornmix <popcornmix@gmail.com>
  1093. +Date: Wed, 5 Nov 2014 21:04:25 +0000
  1094. +Subject: [PATCH 6/6] squash: Fix for stop needing to be pressed twice
  1095. +
  1096. +---
  1097. + src/libcec/CECClient.cpp | 17 ++++++++---------
  1098. + 1 file changed, 8 insertions(+), 9 deletions(-)
  1099. +
  1100. +diff --git a/src/libcec/CECClient.cpp b/src/libcec/CECClient.cpp
  1101. +index 1946148..f4f114b 100644
  1102. +--- a/src/libcec/CECClient.cpp
  1103. ++++ b/src/libcec/CECClient.cpp
  1104. +@@ -1131,6 +1131,8 @@ uint16_t CCECClient::CheckKeypressTimeout(void)
  1105. +   key.keycode = CEC_USER_CONTROL_CODE_UNKNOWN;
  1106. +   key.duration = 0;
  1107. +
  1108. ++  if (m_iCurrentButton == CEC_USER_CONTROL_CODE_UNKNOWN)
  1109. ++    return timeout;
  1110. +   {
  1111. +     CLockObject lock(m_mutex);
  1112. +     uint64_t iNow = GetTimeMs();
  1113. +@@ -1140,8 +1142,7 @@ uint16_t CCECClient::CheckKeypressTimeout(void)
  1114. +     uint32_t iTimeoutMs(m_configuration.clientVersion >= LIBCEC_VERSION_TO_UINT(2, 0, 5) ?
  1115. +         m_configuration.iComboKeyTimeoutMs : CEC_DEFAULT_COMBO_TIMEOUT_MS);
  1116. +
  1117. +-    if (m_iCurrentButton != CEC_USER_CONTROL_CODE_UNKNOWN &&
  1118. +-          m_iCurrentButton == comboKey && iTimeoutMs > 0 && iNow - m_updateButtontime >= iTimeoutMs)
  1119. ++    if (m_iCurrentButton == comboKey && iTimeoutMs > 0 && iNow - m_updateButtontime >= iTimeoutMs)
  1120. +     {
  1121. +       key.duration = (unsigned int) (iNow - m_initialButtontime);
  1122. +       key.keycode = m_iCurrentButton;
  1123. +@@ -1154,8 +1155,7 @@ uint16_t CCECClient::CheckKeypressTimeout(void)
  1124. +       m_pressedButtoncount = 0;
  1125. +       m_releasedButtoncount = 0;
  1126. +     }
  1127. +-    else if (m_iCurrentButton != CEC_USER_CONTROL_CODE_UNKNOWN &&
  1128. +-          m_iCurrentButton != comboKey && m_releaseButtontime && iNow >= (uint64_t)m_releaseButtontime)
  1129. ++    else if (m_iCurrentButton != comboKey && m_releaseButtontime && iNow >= (uint64_t)m_releaseButtontime)
  1130. +     {
  1131. +       key.duration = (unsigned int) (iNow - m_initialButtontime);
  1132. +       key.keycode = CEC_USER_CONTROL_CODE_UNKNOWN;
  1133. +@@ -1168,8 +1168,7 @@ uint16_t CCECClient::CheckKeypressTimeout(void)
  1134. +       m_pressedButtoncount = 0;
  1135. +       m_releasedButtoncount = 0;
  1136. +     }
  1137. +-    else if (m_iCurrentButton != CEC_USER_CONTROL_CODE_UNKNOWN &&
  1138. +-          (m_iCurrentButton != comboKey && m_repeatButtontime && iNow >= (uint64_t)m_repeatButtontime))
  1139. ++    else if (m_iCurrentButton != comboKey && m_repeatButtontime && iNow >= (uint64_t)m_repeatButtontime)
  1140. +     {
  1141. +       key.duration = (unsigned int) (iNow - m_initialButtontime);
  1142. +       key.keycode = m_iCurrentButton;
  1143. +@@ -1178,11 +1177,11 @@ uint16_t CCECClient::CheckKeypressTimeout(void)
  1144. +     }
  1145. +     else
  1146. +     {
  1147. +-      if (m_iCurrentButton != CEC_USER_CONTROL_CODE_UNKNOWN && m_iCurrentButton == comboKey && iTimeoutMs > 0)
  1148. ++      if (m_iCurrentButton == comboKey && iTimeoutMs > 0)
  1149. +         timeout = std::min((uint64_t)timeout, m_updateButtontime - iNow + iTimeoutMs);
  1150. +-      if (m_iCurrentButton != CEC_USER_CONTROL_CODE_UNKNOWN && m_iCurrentButton != comboKey && m_releaseButtontime)
  1151. ++      if (m_iCurrentButton != comboKey && m_releaseButtontime)
  1152. +         timeout = std::min((uint64_t)timeout, m_releaseButtontime - iNow);
  1153. +-      if (m_iCurrentButton != CEC_USER_CONTROL_CODE_UNKNOWN && m_iCurrentButton != comboKey && m_repeatButtontime)
  1154. ++      if (m_iCurrentButton != comboKey && m_repeatButtontime)
  1155. +         timeout = std::min((uint64_t)timeout, m_repeatButtontime - iNow);
  1156. +       if (timeout > CEC_PROCESSOR_SIGNAL_WAIT_TIME)
  1157. +       {
  1158. +--
  1159. +1.9.1
  1160. +
  1161.  
  1162. From 32d910f5fb777a2d18b2d81b8242e0abd48e6388 Mon Sep 17 00:00:00 2001
  1163. From: popcornmix <popcornmix@gmail.com>
  1164. Date: Sat, 19 Mar 2016 17:15:29 +0000
  1165. Subject: [PATCH 52/73] cec: hack: pretend bump to 3.1.0
  1166.  
  1167. ---
  1168.  tools/depends/target/libcec/Makefile   |  1 +
  1169.  tools/depends/target/libcec/bump.patch | 21 +++++++++++++++++++++
  1170.  2 files changed, 22 insertions(+)
  1171.  create mode 100644 tools/depends/target/libcec/bump.patch
  1172.  
  1173. diff --git a/tools/depends/target/libcec/Makefile b/tools/depends/target/libcec/Makefile
  1174. index ddf996361ad5b46dd2b33fb035b2ed133914a612..39ba882d0c7e270b4d1d1d566027cbaffb76b587 100644
  1175. --- a/tools/depends/target/libcec/Makefile
  1176. +++ b/tools/depends/target/libcec/Makefile
  1177. @@ -22,6 +22,7 @@ $(PLATFORM): $(TARBALLS_LOCATION)/$(ARCHIVE) $(DEPS)
  1178.     rm -rf $(PLATFORM); mkdir -p $(PLATFORM)/build
  1179.     cd $(PLATFORM); $(ARCHIVE_TOOL) $(ARCHIVE_TOOL_FLAGS) $(TARBALLS_LOCATION)/$(ARCHIVE)
  1180.     cd $(PLATFORM); patch -p1 < ../popcornmix.patch
  1181. +   cd $(PLATFORM); patch -p1 < ../bump.patch
  1182.     cd $(PLATFORM)/build; $(CMAKE) -DBUILD_SHARED_LIBS=1 -DSKIP_PYTHON_WRAPPER:STRING=1 -DCMAKE_INSTALL_LIBDIR=$(PREFIX)/lib ..
  1183.  
  1184.  $(LIBDYLIB): $(PLATFORM)
  1185. diff --git a/tools/depends/target/libcec/bump.patch b/tools/depends/target/libcec/bump.patch
  1186. new file mode 100644
  1187. index 0000000000000000000000000000000000000000..9e55e51068e7befd9d4ff003156ce1ff4cc56c0e
  1188. --- /dev/null
  1189. +++ b/tools/depends/target/libcec/bump.patch
  1190. @@ -0,0 +1,21 @@
  1191. +commit 49a1728feabca68b8424a8b22abec9ee87b9aa99
  1192. +Author: Lars Op den Kamp <lars@opdenkamp.eu>
  1193. +Date:   Wed Jan 20 01:06:50 2016 +0100
  1194. +
  1195. +    bump to 3.1.0
  1196. +
  1197. +diff --git a/CMakeLists.txt b/CMakeLists.txt
  1198. +index 23d71fc..173f625 100644
  1199. +--- a/CMakeLists.txt
  1200. ++++ b/CMakeLists.txt
  1201. +@@ -2,8 +2,8 @@ project(libcec)
  1202. + cmake_minimum_required(VERSION 2.8.9)
  1203. +
  1204. + set(LIBCEC_VERSION_MAJOR 3)
  1205. +-set(LIBCEC_VERSION_MINOR 0)
  1206. +-set(LIBCEC_VERSION_PATCH 0)
  1207. ++set(LIBCEC_VERSION_MINOR 1)
  1208. ++set(LIBCEC_VERSION_PATCH 0)
  1209. +
  1210. + # cec-client
  1211. + add_subdirectory(src/cec-client)
  1212.  
  1213. From 2e98d936f34bb32d80b7edfc86f10e4cd6073a85 Mon Sep 17 00:00:00 2001
  1214. From: popcornmix <popcornmix@gmail.com>
  1215. Date: Tue, 28 Oct 2014 00:19:40 +0000
  1216. Subject: [PATCH 53/73] [cec] Add settings for configuring button repeats
  1217.  
  1218. ---
  1219.  addons/resource.language.en_gb/resources/strings.po | 15 +++++++++++++++
  1220.  system/peripherals.xml                              |  4 +++-
  1221.  xbmc/peripherals/devices/PeripheralCecAdapter.cpp   | 16 ++++++++++++++++
  1222.  3 files changed, 34 insertions(+), 1 deletion(-)
  1223.  
  1224. diff --git a/addons/resource.language.en_gb/resources/strings.po b/addons/resource.language.en_gb/resources/strings.po
  1225. index 7ace950c83e1497b4d96a31b33b524e7eafb1783..bdc5953503cf382091706240505c850084d84d94 100644
  1226. --- a/addons/resource.language.en_gb/resources/strings.po
  1227. +++ b/addons/resource.language.en_gb/resources/strings.po
  1228. @@ -19714,3 +19714,18 @@ msgstr ""
  1229.  msgctxt "#38206"
  1230.  msgid "Max"
  1231.  msgstr ""
  1232. +
  1233. +#: system/peripherals.xml
  1234. +msgctxt "#38050"
  1235. +msgid "Remote button press delay before repeating (ms)"
  1236. +msgstr ""
  1237. +
  1238. +#: system/peripherals.xml
  1239. +msgctxt "#38051"
  1240. +msgid "Remote button press repeat rate (ms)"
  1241. +msgstr ""
  1242. +
  1243. +#: system/peripherals.xml
  1244. +msgctxt "#38052"
  1245. +msgid "Remote button press release time (ms)"
  1246. +msgstr ""
  1247. diff --git a/system/peripherals.xml b/system/peripherals.xml
  1248. index f939c0b685d96d022856544e7eb31a71338d9ba4..a4b8f7add4d915c1749628d62a9cbe9afe97d063 100644
  1249. --- a/system/peripherals.xml
  1250. +++ b/system/peripherals.xml
  1251. @@ -31,7 +31,9 @@
  1252.      <setting key="device_type" type="int" value="1" configurable="0" />
  1253.      <setting key="wake_devices_advanced" type="string" value="" configurable="0" />
  1254.      <setting key="standby_devices_advanced" type="string" value="" configurable="0" />
  1255. -    <setting key="double_tap_timeout_ms" type="int" min="0" value="300" configurable="0" />
  1256. +    <setting key="double_tap_timeout_ms" type="int" min="50" max="1000" step="50" value="300" label="38050" order="16" />
  1257. +    <setting key="button_repeat_rate_ms" type="int" min="0" max="250" step="10" value="0" label="38051" order="17" />
  1258. +    <setting key="button_release_delay_ms" type="int" min="0" max="500" step="50" value="0" label="38052" order="18" />
  1259.    </peripheral>
  1260.  
  1261.    <peripheral vendor_product="2548:1001,2548:1002" bus="usb" name="Pulse-Eight CEC Adapter" mapTo="cec">
  1262. diff --git a/xbmc/peripherals/devices/PeripheralCecAdapter.cpp b/xbmc/peripherals/devices/PeripheralCecAdapter.cpp
  1263. index e6bcbce6911a1714e129ecd5aceead94769231f4..19b3c37bc18fcab30920b12902e8c3397a69dccc 100644
  1264. --- a/xbmc/peripherals/devices/PeripheralCecAdapter.cpp
  1265. +++ b/xbmc/peripherals/devices/PeripheralCecAdapter.cpp
  1266. @@ -1287,6 +1287,20 @@ void CPeripheralCecAdapter::SetConfigurationFromLibCEC(const CEC::libcec_configu
  1267.    m_configuration.bSendInactiveSource = config.bSendInactiveSource;
  1268.    bChanged |= SetSetting("send_inactive_source", m_configuration.bSendInactiveSource == 1);
  1269.  
  1270. +#if defined(CEC_DOUBLE_TAP_TIMEOUT_MS_OLD)
  1271. +  m_configuration.iDoubleTapTimeout50Ms = config.iDoubleTapTimeout50Ms;
  1272. +  bChanged |= SetSetting("double_tap_timeout_ms", (int)m_configuration.iDoubleTapTimeout50Ms * 50);
  1273. +#else
  1274. +  m_configuration.iDoubleTapTimeoutMs = config.iDoubleTapTimeoutMs;
  1275. +  bChanged |= SetSetting("double_tap_timeout_ms", (int)m_configuration.iDoubleTapTimeoutMs;
  1276. +#endif
  1277. +
  1278. +  m_configuration.iButtonRepeatRateMs = config.iButtonRepeatRateMs;
  1279. +  bChanged |= SetSetting("button_repeat_rate_ms", (int)m_configuration.iButtonRepeatRateMs);
  1280. +
  1281. +  m_configuration.iButtonReleaseDelayMs = config.iButtonReleaseDelayMs;
  1282. +  bChanged |= SetSetting("button_release_delay_ms", (int)m_configuration.iButtonReleaseDelayMs);
  1283. +
  1284.    m_configuration.iFirmwareVersion = config.iFirmwareVersion;
  1285.    m_configuration.bShutdownOnStandby = config.bShutdownOnStandby;
  1286.  
  1287. @@ -1391,6 +1405,8 @@ void CPeripheralCecAdapter::SetConfigurationFromSettings(void)
  1288.    // backwards compatibility. will be removed once the next major release of libCEC is out
  1289.    m_configuration.iDoubleTapTimeoutMs = GetSettingInt("double_tap_timeout_ms");
  1290.  #endif
  1291. +  m_configuration.iButtonRepeatRateMs = GetSettingInt("button_repeat_rate_ms");
  1292. +  m_configuration.iButtonReleaseDelayMs = GetSettingInt("button_release_delay_ms");
  1293.  
  1294.    if (GetSettingBool("pause_playback_on_deactivate"))
  1295.    {
  1296.  
  1297. From 4b033455b05332c157035752984e7c8da9ddce20 Mon Sep 17 00:00:00 2001
  1298. From: popcornmix <popcornmix@gmail.com>
  1299. Date: Mon, 3 Nov 2014 23:17:46 +0000
  1300. Subject: [PATCH 54/73] [cec] Don't discard buttons when repeat mode is enabled
  1301.  
  1302. ---
  1303. xbmc/peripherals/devices/PeripheralCecAdapter.cpp | 5 ++++-
  1304. 1 file changed, 4 insertions(+), 1 deletion(-)
  1305.  
  1306. diff --git a/xbmc/peripherals/devices/PeripheralCecAdapter.cpp b/xbmc/peripherals/devices/PeripheralCecAdapter.cpp
  1307. index 19b3c37bc18fcab30920b12902e8c3397a69dccc..f859f44f6d5379154317b5760d7df720f0894e0d 100644
  1308. --- a/xbmc/peripherals/devices/PeripheralCecAdapter.cpp
  1309. +++ b/xbmc/peripherals/devices/PeripheralCecAdapter.cpp
  1310. @@ -778,7 +778,10 @@ void CPeripheralCecAdapter::PushCecKeypress(const CecButtonPress &key)
  1311.   CLog::Log(LOGDEBUG, "%s - received key %2x duration %d", __FUNCTION__, key.iButton, key.iDuration);
  1312.  
  1313.   CSingleLock lock(m_critSection);
  1314. -  if (key.iDuration > 0)
  1315. +  // avoid the queue getting too long
  1316. +  if (m_configuration.iButtonRepeatRateMs && m_buttonQueue.size() > 5)
  1317. +    return;
  1318. +  if (m_configuration.iButtonRepeatRateMs == 0 && key.iDuration > 0)
  1319.   {
  1320.     if (m_currentButton.iButton == key.iButton && m_currentButton.iDuration == 0)
  1321.     {
  1322.  
  1323. From 6e8d828760fc9a98acb6d7599926b9bc33ff4f4e Mon Sep 17 00:00:00 2001
  1324. From: popcornmix <popcornmix@gmail.com>
  1325. Date: Tue, 4 Nov 2014 18:50:00 +0000
  1326. Subject: [PATCH 55/73] [cec] Temp - more logging
  1327.  
  1328. ---
  1329. xbmc/peripherals/devices/PeripheralCecAdapter.cpp | 8 +++++++-
  1330. 1 file changed, 7 insertions(+), 1 deletion(-)
  1331.  
  1332. diff --git a/xbmc/peripherals/devices/PeripheralCecAdapter.cpp b/xbmc/peripherals/devices/PeripheralCecAdapter.cpp
  1333. index f859f44f6d5379154317b5760d7df720f0894e0d..f1c3a6d242183507c4ce9ebf4651b0c0f7e9c5c9 100644
  1334. --- a/xbmc/peripherals/devices/PeripheralCecAdapter.cpp
  1335. +++ b/xbmc/peripherals/devices/PeripheralCecAdapter.cpp
  1336. @@ -775,12 +775,15 @@ void CPeripheralCecAdapter::GetNextKey(void)
  1337.  
  1338. void CPeripheralCecAdapter::PushCecKeypress(const CecButtonPress &key)
  1339. {
  1340. -  CLog::Log(LOGDEBUG, "%s - received key %2x duration %d", __FUNCTION__, key.iButton, key.iDuration);
  1341. +  CLog::Log(LOGDEBUG, "%s - received key %2x duration %d (rep:%d size:%d)", __FUNCTION__, key.iButton, key.iDuration, m_configuration.iButtonRepeatRateMs, m_buttonQueue.size());
  1342.  
  1343.   CSingleLock lock(m_critSection);
  1344.   // avoid the queue getting too long
  1345.   if (m_configuration.iButtonRepeatRateMs && m_buttonQueue.size() > 5)
  1346. +  {
  1347. +    CLog::Log(LOGDEBUG, "%s - discarded key %2x", __FUNCTION__, key.iButton);
  1348.     return;
  1349. +  }
  1350.   if (m_configuration.iButtonRepeatRateMs == 0 && key.iDuration > 0)
  1351.   {
  1352.     if (m_currentButton.iButton == key.iButton && m_currentButton.iDuration == 0)
  1353. @@ -789,6 +792,7 @@ void CPeripheralCecAdapter::PushCecKeypress(const CecButtonPress &key)
  1354.       if (m_bHasButton)
  1355.         m_currentButton.iDuration = key.iDuration;
  1356.       // ignore this one, since it's already been handled by xbmc
  1357. +      CLog::Log(LOGDEBUG, "%s - ignored key %2x", __FUNCTION__, key.iButton);
  1358.        return;
  1359.      }
  1360.      // if we received a keypress with a duration set, try to find the same one without a duration set, and replace it
  1361. @@ -799,6 +803,7 @@ void CPeripheralCecAdapter::PushCecKeypress(const CecButtonPress &key)
  1362.          if ((*it).iDuration == 0)
  1363.          {
  1364.            // replace this entry
  1365. +          CLog::Log(LOGDEBUG, "%s - replaced key %2x", __FUNCTION__, key.iButton);
  1366.            (*it).iDuration = key.iDuration;
  1367.            return;
  1368.          }
  1369. @@ -808,6 +813,7 @@ void CPeripheralCecAdapter::PushCecKeypress(const CecButtonPress &key)
  1370.      }
  1371.    }
  1372.  
  1373. +  CLog::Log(LOGDEBUG, "%s - added key %2x", __FUNCTION__, key.iButton);
  1374.    m_buttonQueue.push_back(key);
  1375.  }
  1376.  
  1377.  
  1378. From f422270e1333ba02c8c2321538ae171572e9879d Mon Sep 17 00:00:00 2001
  1379. From: popcornmix <popcornmix@gmail.com>
  1380. Date: Fri, 22 Jan 2016 12:29:41 +0000
  1381. Subject: [PATCH 56/73] [cec] Update for libcec 3.1.0
  1382.  
  1383. ---
  1384.  configure.ac                                      | 4 ++--
  1385.  xbmc/peripherals/devices/PeripheralCecAdapter.cpp | 4 ++--
  1386.  2 files changed, 4 insertions(+), 4 deletions(-)
  1387.  
  1388. diff --git a/configure.ac b/configure.ac
  1389. index 3df753bde53593ecea534455056268f9f8a24c1a..738d23e3272cd56b095cef821a3993bb9aa69b55 100644
  1390. --- a/configure.ac
  1391. +++ b/configure.ac
  1392. @@ -1453,9 +1453,9 @@ if test "x$use_libcec" != "xno"; then
  1393.    # libcec is dyloaded, so we need to check for its headers and link any depends.
  1394.    if test "x$use_libcec" != "xno"; then
  1395.      if test "x$use_libcec" != "xauto"; then
  1396. -      PKG_CHECK_MODULES([CEC],[libcec >= 3.0.0],,[use_libcec="no";AC_MSG_ERROR($libcec_disabled)])
  1397. +      PKG_CHECK_MODULES([CEC],[libcec >= 3.1.0],,[use_libcec="no";AC_MSG_ERROR($libcec_disabled)])
  1398.      else
  1399. -      PKG_CHECK_MODULES([CEC],[libcec >= 3.0.0],,[use_libcec="no";AC_MSG_RESULT($libcec_disabled)])
  1400. +      PKG_CHECK_MODULES([CEC],[libcec >= 3.1.0],,[use_libcec="no";AC_MSG_RESULT($libcec_disabled)])
  1401.      fi
  1402.  
  1403.      if test "x$use_libcec" != "xno"; then
  1404. diff --git a/xbmc/peripherals/devices/PeripheralCecAdapter.cpp b/xbmc/peripherals/devices/PeripheralCecAdapter.cpp
  1405. index f1c3a6d242183507c4ce9ebf4651b0c0f7e9c5c9..28a6a8148810da940f977976a627018c59a719db 100644
  1406. --- a/xbmc/peripherals/devices/PeripheralCecAdapter.cpp
  1407. +++ b/xbmc/peripherals/devices/PeripheralCecAdapter.cpp
  1408. @@ -43,7 +43,7 @@ using namespace PERIPHERALS;
  1409.  using namespace ANNOUNCEMENT;
  1410.  using namespace CEC;
  1411.  
  1412. -#define CEC_LIB_SUPPORTED_VERSION LIBCEC_VERSION_TO_UINT(3, 0, 0)
  1413. +#define CEC_LIB_SUPPORTED_VERSION LIBCEC_VERSION_TO_UINT(3, 1, 0)
  1414.  
  1415.  /* time in seconds to ignore standby commands from devices after the screensaver has been activated */
  1416.  #define SCREENSAVER_TIMEOUT       20
  1417. @@ -1329,7 +1329,7 @@ void CPeripheralCecAdapter::SetConfigurationFromLibCEC(const CEC::libcec_configu
  1418.  void CPeripheralCecAdapter::SetConfigurationFromSettings(void)
  1419.  {
  1420.    // client version matches the version of libCEC that we originally used the API from
  1421. -  m_configuration.clientVersion = LIBCEC_VERSION_TO_UINT(3, 0, 0);
  1422. +  m_configuration.clientVersion = CEC_LIB_SUPPORTED_VERSION;
  1423.  
  1424.    // device name 'XBMC'
  1425.    snprintf(m_configuration.strDeviceName, 13, "%s", GetSettingString("device_name").c_str());
  1426.  
  1427. From 2748fd05bec256b540214e0e3e4cbbacac5aea31 Mon Sep 17 00:00:00 2001
  1428. From: popcornmix <popcornmix@gmail.com>
  1429. Date: Sat, 19 Mar 2016 14:46:41 +0000
  1430. Subject: [PATCH 57/73] libcec: use system audio mode request instead of power
  1431.  on to start AVR reliable
  1432.  
  1433. ---
  1434.  tools/depends/target/libcec/208.patch | 38 +++++++++++++++++++++++++++++++++++
  1435.  tools/depends/target/libcec/Makefile  |  1 +
  1436.  2 files changed, 39 insertions(+)
  1437.  create mode 100644 tools/depends/target/libcec/208.patch
  1438.  
  1439. diff --git a/tools/depends/target/libcec/208.patch b/tools/depends/target/libcec/208.patch
  1440. new file mode 100644
  1441. index 0000000000000000000000000000000000000000..3dc5adf022e80c3337ad69b7c7d7346daafbfdd3
  1442. --- /dev/null
  1443. +++ b/tools/depends/target/libcec/208.patch
  1444. @@ -0,0 +1,38 @@
  1445. +From f70c4d76e1d9c0219a3927b6b66090b7575e7933 Mon Sep 17 00:00:00 2001
  1446. +From: Gerald Dachs <gda@dachsweb.de>
  1447. +Date: Thu, 17 Mar 2016 12:12:51 +0100
  1448. +Subject: [PATCH] use system audio mode request instead of power on to start
  1449. + AVR reliable
  1450. +
  1451. +---
  1452. + src/libcec/devices/CECBusDevice.cpp | 13 +++++++++----
  1453. + 1 file changed, 9 insertions(+), 4 deletions(-)
  1454. +
  1455. +diff --git a/src/libcec/devices/CECBusDevice.cpp b/src/libcec/devices/CECBusDevice.cpp
  1456. +index 55939d1..e2d5ea3 100644
  1457. +--- a/src/libcec/devices/CECBusDevice.cpp
  1458. ++++ b/src/libcec/devices/CECBusDevice.cpp
  1459. +@@ -1025,14 +1025,19 @@ bool CCECBusDevice::ActivateSource(uint64_t iDelay /* = 0 */)
  1460. +   bool bReturn(true);
  1461. +   if (iDelay == 0)
  1462. +   {
  1463. +-    /** some AVRs fail to be powered up by the TV when it powers up. power up the AVR explicitly */
  1464. ++    /** send system audio mode request if AVR exists */
  1465. +     if (m_iLogicalAddress != CECDEVICE_AUDIOSYSTEM)
  1466. +     {
  1467. +       CCECBusDevice* audioSystem(m_processor->GetDevice(CECDEVICE_AUDIOSYSTEM));
  1468. +-      if (audioSystem && audioSystem->IsPresent() && audioSystem->GetPowerStatus(m_iLogicalAddress) != CEC_POWER_STATUS_ON)
  1469. ++      if (audioSystem && audioSystem->IsPresent())
  1470. +       {
  1471. +-        LIB_CEC->AddLog(CEC_LOG_DEBUG, "powering up the AVR");
  1472. +-        audioSystem->PowerOn(m_iLogicalAddress);
  1473. ++        cec_command command;
  1474. ++
  1475. ++        LIB_CEC->AddLog(CEC_LOG_DEBUG, "sending system audio mode request for '%s'", ToString(m_iLogicalAddress));
  1476. ++        cec_command::Format(command, m_iLogicalAddress, CECDEVICE_AUDIOSYSTEM, CEC_OPCODE_SYSTEM_AUDIO_MODE_REQUEST);
  1477. ++        command.parameters.PushBack((uint8_t) ((m_iPhysicalAddress >> 8) & 0xFF));
  1478. ++        command.parameters.PushBack((uint8_t) (m_iPhysicalAddress & 0xFF));
  1479. ++        bReturn = m_handler->Transmit(command, false, false);
  1480. +       }
  1481. +     }
  1482. +
  1483. diff --git a/tools/depends/target/libcec/Makefile b/tools/depends/target/libcec/Makefile
  1484. index 39ba882d0c7e270b4d1d1d566027cbaffb76b587..4565dc9f6fc0b3e6b49133443c19e10767d475eb 100644
  1485. --- a/tools/depends/target/libcec/Makefile
  1486. +++ b/tools/depends/target/libcec/Makefile
  1487. @@ -23,6 +23,7 @@ $(PLATFORM): $(TARBALLS_LOCATION)/$(ARCHIVE) $(DEPS)
  1488.     cd $(PLATFORM); $(ARCHIVE_TOOL) $(ARCHIVE_TOOL_FLAGS) $(TARBALLS_LOCATION)/$(ARCHIVE)
  1489.     cd $(PLATFORM); patch -p1 < ../popcornmix.patch
  1490.     cd $(PLATFORM); patch -p1 < ../bump.patch
  1491. +   cd $(PLATFORM); patch -p1 < ../208.patch
  1492.     cd $(PLATFORM)/build; $(CMAKE) -DBUILD_SHARED_LIBS=1 -DSKIP_PYTHON_WRAPPER:STRING=1 -DCMAKE_INSTALL_LIBDIR=$(PREFIX)/lib ..
  1493.  
  1494.  $(LIBDYLIB): $(PLATFORM)
  1495.  
  1496. From 25e789e48fd92bd81c780834328846abde00c69f Mon Sep 17 00:00:00 2001
  1497. From: Rainer Hochecker <fernetmenta@online.de>
  1498. Date: Tue, 22 Mar 2016 09:51:52 +0100
  1499. Subject: [PATCH 58/73] python: use kodi provided cert if available
  1500.  
  1501. ---
  1502.  xbmc/interfaces/python/XBPython.cpp | 6 ++++++
  1503.  1 file changed, 6 insertions(+)
  1504.  
  1505. diff --git a/xbmc/interfaces/python/XBPython.cpp b/xbmc/interfaces/python/XBPython.cpp
  1506. index bc84af9411ef55eaf5ba71a320b5cbfec5f49548..ff4ed7db26845905108ea0ae504e4f589f9c7d0f 100644
  1507. --- a/xbmc/interfaces/python/XBPython.cpp
  1508. +++ b/xbmc/interfaces/python/XBPython.cpp
  1509. @@ -595,6 +595,12 @@ bool XBPython::OnScriptInitialized(ILanguageInvoker *invoker)
  1510.      CEnvironment::putenv(buf);
  1511.  #endif
  1512.  
  1513. +#if !defined(TARGET_WINDOWS)
  1514. +    // use Kodi provided cert if available
  1515. +    if (XFILE::CFile::Exists("special://xbmc/system/certs/cacert.pem"))
  1516. +      setenv("SSL_CERT_FILE", CSpecialProtocol::TranslatePath("special://xbmc/system/certs/cacert.pem").c_str(), 1);
  1517. +#endif
  1518. +
  1519.      if (PyEval_ThreadsInitialized())
  1520.        PyEval_AcquireLock();
  1521.      else
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement