diff --git a/.gitmodules b/.gitmodules index 4deefb0e..c690fe8c 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,6 @@ [submodule "support"] path = support url = https://github.com/Pulse-Eight/libcec-support.git +[submodule "src/dotnet"] + path = src/dotnet + url = https://github.com/Pulse-Eight/cec-dotnet.git diff --git a/CMakeLists.txt b/CMakeLists.txt index 4f016627..861ba19a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 2.8.9) set(LIBCEC_VERSION_MAJOR 4) set(LIBCEC_VERSION_MINOR 0) -set(LIBCEC_VERSION_PATCH 1) +set(LIBCEC_VERSION_PATCH 2) # cec-client add_subdirectory(src/cec-client) diff --git a/debian/changelog.in b/debian/changelog.in index fe4bc105..b1d11c57 100644 --- a/debian/changelog.in +++ b/debian/changelog.in @@ -1,3 +1,19 @@ +libcec (4.0.2.1~#DIST#) #DIST#; urgency=medium + + * fixed: + * windows: device detection. credits: @Portisch + * don't automatically assume that an AVR is active in some situations + * don't take Panasonic's vendor id when emulating an AVR + * drm EDID parser not compiled in. credits @gdachs + * python: have Swig generate Python threading support + * python: only pass unsigned + * python: allow empty callback parameters + * python: install demo app as executable + * python: correct install path. credits @Lo0k @mkreisl. #284 #288 #289 #291 + * python: possible crash when passing an invalid callback + + -- Pulse-Eight Packaging Mon, 23 Jan 2017 16:28:00 +0100 + libcec (4.0.1.1~#DIST#) #DIST#; urgency=medium * fixed: diff --git a/debian/libcec4-dev.install b/debian/libcec4-dev.install index e5bbd96e..f435b2e3 100644 --- a/debian/libcec4-dev.install +++ b/debian/libcec4-dev.install @@ -1,3 +1,3 @@ usr/include -usr/lib/pkgconfig +usr/lib/*/pkgconfig usr/lib/*/*.so diff --git a/debian/python-libcec.install b/debian/python-libcec.install index 62217fee..58f77101 100644 --- a/debian/python-libcec.install +++ b/debian/python-libcec.install @@ -1,2 +1,2 @@ usr/lib/python*/dist-packages/cec/* -usr/bin/*.py +usr/bin/pyCecClient diff --git a/docs/README.osx.md b/docs/README.osx.md index 9fa69202..6cb2880e 100644 --- a/docs/README.osx.md +++ b/docs/README.osx.md @@ -1,11 +1,17 @@ ## Apple OS X +### MacPorts + +libCEC is available through [MacPorts] (https://www.macports.org/) and has been tested on OS X 10.9 through 10.12 + ### Prerequisites To compile libCEC on OS X, you'll need the following dependencies: * [p8-platform] (https://github.com/Pulse-Eight/platform) 2.0 or later * [cmake 2.6 or better] (http://www.cmake.org/) -* a supported C++ 11 compiler +* a supported C++ 11 compiler. Support for C++11 was added in OS X 10.9 * xcode 3.2.6 or later +* optional: [Python 3.4 or later] (https://www.python.org/) and [Swig] (http://www.swig.org/) to generate Python bindings +* optional: libX11 and xrandr to read the sink's EDID, used to determine the PC's HDMI physical address ### Compilation To compile, execute the following command: diff --git a/project/libCEC.nsi b/project/libCEC.nsi index 7b5eac4d..9e807bcd 100644 --- a/project/libCEC.nsi +++ b/project/libCEC.nsi @@ -141,9 +141,11 @@ Section "CEC Debug Client" SecCecClient ; Copy to the installation directory SetOutPath "$INSTDIR" - File "..\build\x86\*.exe" + File "..\build\x86\cec-client.exe" + File "..\build\x86\cecc-client.exe" SetOutPath "$INSTDIR\x64" - File /nonfatal "..\build\amd64\*.exe" + File /nonfatal "..\build\amd64\cec-client.exe" + File /nonfatal "..\build\amd64\cecc-client.exe" !insertmacro MUI_STARTMENU_WRITE_BEGIN Application SetOutPath "$INSTDIR" @@ -162,6 +164,35 @@ Section "CEC Debug Client" SecCecClient SectionEnd +Section "libCEC Tray" SecDotNet + SetShellVarContext current + SectionIn 1 3 + + ; Copy to the installation directory + SetOutPath "$INSTDIR" + File "..\build\x86\CecSharpTester.exe" + File "..\build\x86\cec-tray.exe" + SetOutPath "$INSTDIR\x64" + File /nonfatal "..\build\amd64\CecSharpTester.exe" + File /nonfatal "..\build\amd64\cec-tray.exe" + + !insertmacro MUI_STARTMENU_WRITE_BEGIN Application + SetOutPath "$INSTDIR" + + CreateDirectory "$SMPROGRAMS\$StartMenuFolder" + ${If} ${RunningX64} + CreateShortCut "$SMPROGRAMS\$StartMenuFolder\cec-tray.lnk" "$INSTDIR\x64\cec-tray.exe" \ + "" "$INSTDIR\x64\cec-tray.exe" 0 SW_SHOWNORMAL \ + "" "Start libCEC Tray (x64)." + ${Else} + CreateShortCut "$SMPROGRAMS\$StartMenuFolder\cec-tray.lnk" "$INSTDIR\cec-tray.exe" \ + "" "$INSTDIR\cec-tray.exe" 0 SW_SHOWNORMAL \ + "" "Start libCEC Tray." + ${EndIf} + !insertmacro MUI_STARTMENU_WRITE_END + +SectionEnd + Section "Python bindings" SecPythonCec SetShellVarContext current SectionIn 1 3 @@ -319,6 +350,7 @@ Section "Uninstall" ${If} ${RunningX64} Delete "$SMPROGRAMS\$StartMenuFolder\libCEC Tray (x64).lnk" ${EndIf} + Delete "$SMPROGRAMS\$StartMenuFolder\cec-tray.lnk" Delete "$SMPROGRAMS\$StartMenuFolder\CEC Test client.lnk" ${If} ${RunningX64} Delete "$SMPROGRAMS\$StartMenuFolder\CEC Test client (x64).lnk" diff --git a/src/dotnet b/src/dotnet new file mode 160000 index 00000000..180cbe2b --- /dev/null +++ b/src/dotnet @@ -0,0 +1 @@ +Subproject commit 180cbe2b4e2b2d6a58c4b22d09760aba4b67a8e5 diff --git a/src/libcec/CMakeLists.txt b/src/libcec/CMakeLists.txt index d3eefa34..5c888070 100644 --- a/src/libcec/CMakeLists.txt +++ b/src/libcec/CMakeLists.txt @@ -68,7 +68,8 @@ set(CEC_SOURCES_IMPLEMENTATIONS implementations/ANCommandHandler.cpp # /platform/* set(CEC_SOURCES_PLATFORM platform/adl/adl-edid.cpp - platform/nvidia/nv-edid.cpp) + platform/nvidia/nv-edid.cpp + platform/drm/drm-edid.cpp) # headers set(CEC_EXT_HEADERS ${PROJECT_SOURCE_DIR}/../../include/cec.h @@ -164,7 +165,7 @@ else() ${CMAKE_INSTALL_PREFIX}/include) install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/libcec.pc - DESTINATION ${CMAKE_INSTALL_LIBDIR_NOARCH}/pkgconfig) + DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) endif() # install headers diff --git a/src/libcec/SwigHelper.h b/src/libcec/SwigHelper.h index 8e526acd..c9d3e1cd 100644 --- a/src/libcec/SwigHelper.h +++ b/src/libcec/SwigHelper.h @@ -33,6 +33,8 @@ */ #define SWIG_FILE_WITH_INIT +#define SWIG_PYTHON_THREADS +#define SWIG_PYTHON_USE_GIL #define LIBCEC_SWIG_EXPORTS #include "cectypes.h" @@ -99,29 +101,33 @@ namespace CEC * Call a python callback (if set) * @param callback the callback to call * @param arglist the arguments to pass to the callback - * @return 1 when processed, 0 otherwise + * @return 0 if the callback failed, the result returned by python otherwise */ int CallPythonCallback(enum libcecSwigCallback callback, PyObject* arglist) { - assert(callback < NB_PYTHON_CB); - assert(arglist); + int retval = 0; - if (!m_callbacks[callback]) - return 0; + if (callback >= NB_PYTHON_CB || !m_callbacks[callback]) + return retval; PyObject* result = NULL; - if (m_callbacks[callback] && arglist) + if (m_callbacks[callback]) { /** call the callback */ result = PyEval_CallObject(m_callbacks[callback], arglist); /** unref the argument and result */ - Py_DECREF(arglist); - if (result) + if (!!arglist) + Py_DECREF(arglist); + if (!!result) + { + if (PyInt_Check(result)) + retval = (int)PyInt_AsLong(result); Py_XDECREF(result); + } } - return 1; + return retval; } /** @@ -180,7 +186,7 @@ namespace CEC { PyGILState_STATE gstate = PyGILState_Ensure(); int retval = CallPythonCallback(param, PYTHON_CB_MENU_STATE, - Py_BuildValue("(i)", state)); + Py_BuildValue("(I)", state)); PyGILState_Release(gstate); return retval; } @@ -189,7 +195,7 @@ namespace CEC { PyGILState_STATE gstate = PyGILState_Ensure(); CallPythonCallback(param, PYTHON_CB_SOURCE_ACTIVATED, - Py_BuildValue("(I,i)", logicalAddress, activated ? 1 : 0)); + Py_BuildValue("(I,I)", logicalAddress, activated)); PyGILState_Release(gstate); } diff --git a/src/libcec/adapter/Pulse-Eight/USBCECAdapterCommunication.cpp b/src/libcec/adapter/Pulse-Eight/USBCECAdapterCommunication.cpp index 4866fe47..fecc0446 100644 --- a/src/libcec/adapter/Pulse-Eight/USBCECAdapterCommunication.cpp +++ b/src/libcec/adapter/Pulse-Eight/USBCECAdapterCommunication.cpp @@ -668,7 +668,7 @@ uint16_t CUSBCECAdapterCommunication::GetPhysicalAddress(void) uint16_t iPA(0); // try to get the PA from ADL -#if defined(HAS_ADL_EDID_PARSER) +#if defined(HAVE_ADL_EDID_PARSER) { LIB_CEC->AddLog(CEC_LOG_DEBUG, "%s - trying to get the physical address via ADL", __FUNCTION__); CADLEdidParser adl; @@ -678,7 +678,7 @@ uint16_t CUSBCECAdapterCommunication::GetPhysicalAddress(void) #endif // try to get the PA from the nvidia driver -#if defined(HAS_NVIDIA_EDID_PARSER) +#if defined(HAVE_NVIDIA_EDID_PARSER) if (iPA == 0) { LIB_CEC->AddLog(CEC_LOG_DEBUG, "%s - trying to get the physical address via nvidia driver", __FUNCTION__); @@ -689,7 +689,7 @@ uint16_t CUSBCECAdapterCommunication::GetPhysicalAddress(void) #endif // try to get the PA from the intel driver -#if defined(HAS_DRM_EDID_PARSER) +#if defined(HAVE_DRM_EDID_PARSER) if (iPA == 0) { LIB_CEC->AddLog(CEC_LOG_DEBUG, "%s - trying to get the physical address via drm files", __FUNCTION__); diff --git a/src/libcec/adapter/Pulse-Eight/USBCECAdapterDetection.cpp b/src/libcec/adapter/Pulse-Eight/USBCECAdapterDetection.cpp index 583d2166..5d9ee9bf 100644 --- a/src/libcec/adapter/Pulse-Eight/USBCECAdapterDetection.cpp +++ b/src/libcec/adapter/Pulse-Eight/USBCECAdapterDetection.cpp @@ -174,13 +174,15 @@ static bool GetComPortFromDevNode(DEVINST hDevInst, char* strPortName, unsigned static bool GetPidVidFromDeviceName(const std::string strDevName, int* vid, int* pid) { - size_t iPidPos = strDevName.find("PID_"); - size_t iVidPos = strDevName.find("VID_"); - if (iPidPos == std::string::npos || iVidPos == std::string::npos || (strDevName.find("&MI_") != std::string::npos && strDevName.find("&MI_00") == std::string::npos)) + std::string strDevNameUpper(strDevName); + StringUtils::ToUpper(strDevNameUpper); + size_t iPidPos = strDevNameUpper.find("PID_"); + size_t iVidPos = strDevNameUpper.find("VID_"); + if (iPidPos == std::string::npos || iVidPos == std::string::npos || (strDevNameUpper.find("&MI_") != std::string::npos && strDevNameUpper.find("&MI_00") == std::string::npos)) return false; - std::string strVendorId(strDevName.substr(iVidPos + 4, 4)); - std::string strProductId(strDevName.substr(iPidPos + 4, 4)); + std::string strVendorId(strDevNameUpper.substr(iVidPos + 4, 4)); + std::string strProductId(strDevNameUpper.substr(iPidPos + 4, 4)); sscanf(strVendorId.c_str(), "%x", vid); sscanf(strProductId.c_str(), "%x", pid); diff --git a/src/libcec/cmake/CheckPlatformSupport.cmake b/src/libcec/cmake/CheckPlatformSupport.cmake index 532f2132..6875606c 100644 --- a/src/libcec/cmake/CheckPlatformSupport.cmake +++ b/src/libcec/cmake/CheckPlatformSupport.cmake @@ -168,7 +168,7 @@ else() # Swig find_package(SWIG) if (PYTHONLIBS_FOUND AND SWIG_FOUND) - set(CMAKE_SWIG_FLAGS "") + set(CMAKE_SWIG_FLAGS "-threads") set(HAVE_PYTHON 1) if ("${PYTHONLIBS_VERSION_STRING}" STREQUAL "") message(STATUS "Python version not found, defaulting to 2.7") @@ -194,10 +194,15 @@ else() DESTINATION python/cec RENAME __init__.py) else() + if(EXISTS "/etc/lsb-release") + SET(PYTHON_PKG_DIR "dist-packages") + else() + SET(PYTHON_PKG_DIR "site-packages") + endif() install(TARGETS ${SWIG_MODULE_cec_REAL_NAME} - DESTINATION lib/python${PYTHON_VERSION}/dist-packages/cec) + DESTINATION lib/python${PYTHON_VERSION}/${PYTHON_PKG_DIR}/cec) install(FILES ${CMAKE_BINARY_DIR}/src/libcec/cec.py - DESTINATION lib/python${PYTHON_VERSION}/dist-packages/cec + DESTINATION lib/python${PYTHON_VERSION}/${PYTHON_PKG_DIR}/cec RENAME __init__.py) endif() endif() diff --git a/src/libcec/cmake/DisplayPlatformSupport.cmake b/src/libcec/cmake/DisplayPlatformSupport.cmake index 7ec10f5d..83a778af 100644 --- a/src/libcec/cmake/DisplayPlatformSupport.cmake +++ b/src/libcec/cmake/DisplayPlatformSupport.cmake @@ -45,9 +45,9 @@ else() endif() if (HAVE_AOCEC_API) - message(STATUS "AOCEC support: yes") + message(STATUS "AOCEC support: yes") else() - message(STATUS "AOCEC support: no") + message(STATUS "AOCEC support: no") endif() if (HAVE_PYTHON) diff --git a/src/libcec/implementations/CECCommandHandler.cpp b/src/libcec/implementations/CECCommandHandler.cpp index 71c2230e..d3036131 100644 --- a/src/libcec/implementations/CECCommandHandler.cpp +++ b/src/libcec/implementations/CECCommandHandler.cpp @@ -783,7 +783,7 @@ int CCECCommandHandler::HandleUserControlPressed(const cec_command &command) else if (command.parameters[0] != CEC_USER_CONTROL_CODE_POWER_OFF_FUNCTION) { // we're not marked as active source, but the tv sends keypresses to us, so assume it forgot to activate us - if (!device->IsActiveSource() && command.initiator == CECDEVICE_TV) + if (!device->IsActiveSource() && command.initiator == CECDEVICE_TV && command.destination != CECDEVICE_AUDIOSYSTEM) device->MarkAsActiveSource(); } diff --git a/src/libcec/implementations/VLCommandHandler.cpp b/src/libcec/implementations/VLCommandHandler.cpp index aee15860..bbdcbf93 100644 --- a/src/libcec/implementations/VLCommandHandler.cpp +++ b/src/libcec/implementations/VLCommandHandler.cpp @@ -75,7 +75,8 @@ bool CVLCommandHandler::InitHandler(void) /* use the VL commandhandler for the primary device that is handled by libCEC */ if (m_busDevice->GetLogicalAddress() == CECDEVICE_TV) { - if (primary && m_busDevice->GetLogicalAddress() != primary->GetLogicalAddress()) + if (primary && m_busDevice->GetLogicalAddress() != primary->GetLogicalAddress() && + primary->GetLogicalAddress() != CECDEVICE_AUDIOSYSTEM) { libcec_configuration config; m_processor->GetPrimaryClient()->GetCurrentConfiguration(config); diff --git a/src/libcec/platform/adl/adl-edid.cpp b/src/libcec/platform/adl/adl-edid.cpp index c3914b1b..89978cb8 100644 --- a/src/libcec/platform/adl/adl-edid.cpp +++ b/src/libcec/platform/adl/adl-edid.cpp @@ -34,6 +34,8 @@ #include "env.h" #include "adl-edid.h" +#if defined(HAVE_ADL_EDID_PARSER) + // for dlsym and friends #if defined(__WINDOWS__) #include @@ -203,3 +205,5 @@ uint16_t CADLEdidParser::GetPhysicalAddress(void) return iPA; } + +#endif diff --git a/src/libcec/platform/adl/adl-edid.h b/src/libcec/platform/adl/adl-edid.h index c8ed8011..0231cdc8 100644 --- a/src/libcec/platform/adl/adl-edid.h +++ b/src/libcec/platform/adl/adl-edid.h @@ -33,7 +33,7 @@ */ #include "env.h" -#define HAS_ADL_EDID_PARSER +#define HAVE_ADL_EDID_PARSER #include "platform/util/edid.h" diff --git a/src/libcec/platform/nvidia/nv-edid.cpp b/src/libcec/platform/nvidia/nv-edid.cpp index db0cbef2..cfa552ff 100644 --- a/src/libcec/platform/nvidia/nv-edid.cpp +++ b/src/libcec/platform/nvidia/nv-edid.cpp @@ -32,9 +32,11 @@ */ #include "env.h" +#include "nv-edid.h" + +#if defined(HAVE_NVIDIA_EDID_PARSER) #include -#include "nv-edid.h" #include using namespace P8PLATFORM; @@ -66,3 +68,5 @@ uint16_t CNVEdidParser::GetPhysicalAddress(void) return iPA; } + +#endif diff --git a/src/libcec/platform/nvidia/nv-edid.h b/src/libcec/platform/nvidia/nv-edid.h index 81c09a8c..5787b61d 100644 --- a/src/libcec/platform/nvidia/nv-edid.h +++ b/src/libcec/platform/nvidia/nv-edid.h @@ -33,7 +33,7 @@ */ #include "env.h" -#define HAS_NVIDIA_EDID_PARSER +#define HAVE_NVIDIA_EDID_PARSER #include "platform/util/edid.h" diff --git a/src/pyCecClient/CMakeLists.txt b/src/pyCecClient/CMakeLists.txt index 141df8ca..91ef1118 100644 --- a/src/pyCecClient/CMakeLists.txt +++ b/src/pyCecClient/CMakeLists.txt @@ -7,10 +7,11 @@ find_package(PythonLibs) if (PYTHONLIBS_FOUND) if (WIN32) - install(FILES pyCecClient.py + install(PROGRAMS pyCecClient.py DESTINATION python/.) else() - install(FILES pyCecClient.py - DESTINATION bin/.) + install(PROGRAMS pyCecClient.py + DESTINATION bin/. + RENAME pyCecClient) endif() endif() diff --git a/windows/create-installer.cmd b/windows/create-installer.cmd index d64f6787..bc49309e 100644 --- a/windows/create-installer.cmd +++ b/windows/create-installer.cmd @@ -43,14 +43,26 @@ echo. Cleaning libCEC (x64) echo. Compiling libCEC (x64) %COMPILER12% libcec.sln /Build "Release|x64" /Project LibCecSharp %COMPILER12% libcec.sln /Build "Release|x64" +echo. Compiling .Net applications +cd "%MYDIR%..\src\dotnet\project" +%COMPILER12% cec-dotnet.sln /Build "Release|x64" +copy ..\build\x64\CecSharpTester.exe %MYDIR%..\build\amd64\CecSharpTester.exe +copy ..\build\x64\cec-tray.exe %MYDIR%..\build\amd64\cec-tray.exe :libcecx86 rem Compile libCEC and cec-client Win32 +cd "%MYDIR%..\project" echo. Cleaning libCEC (x86) %COMPILER12% libcec.sln /Clean "Release|x86" echo. Compiling libCEC (x86) %COMPILER12% libcec.sln /Build "Release|x86" /Project LibCecSharp %COMPILER12% libcec.sln /Build "Release|x86" +echo. Compiling .Net applications +cd "%MYDIR%..\src\dotnet\project" +%COMPILER12% cec-dotnet.sln /Build "Release|x86" +copy ..\build\x86\CecSharpTester.exe %MYDIR%..\build\x86\CecSharpTester.exe +copy ..\build\x86\cec-tray.exe %MYDIR%..\build\x86\cec-tray.exe +cd "%MYDIR%..\project" rem Clean things up before creating the installer del /q /f %MYDIR%..\build\x86\LibCecSharp.pdb @@ -64,10 +76,14 @@ CALL ..\support\private\sign-binary.cmd %MYDIR%..\build\x86\cec.dll CALL ..\support\private\sign-binary.cmd %MYDIR%..\build\x86\LibCecSharp.dll CALL ..\support\private\sign-binary.cmd %MYDIR%..\build\x86\cec-client.exe CALL ..\support\private\sign-binary.cmd %MYDIR%..\build\x86\cecc-client.exe +CALL ..\support\private\sign-binary.cmd %MYDIR%..\build\x86\cec-tray.exe +CALL ..\support\private\sign-binary.cmd %MYDIR%..\build\x86\CecSharpTester.exe CALL ..\support\private\sign-binary.cmd %MYDIR%..\build\amd64\cec.dll CALL ..\support\private\sign-binary.cmd %MYDIR%..\build\amd64\LibCecSharp.dll CALL ..\support\private\sign-binary.cmd %MYDIR%..\build\amd64\cec-client.exe CALL ..\support\private\sign-binary.cmd %MYDIR%..\build\amd64\cecc-client.exe +CALL ..\support\private\sign-binary.cmd %MYDIR%..\build\amd64\cec-tray.exe +CALL ..\support\private\sign-binary.cmd %MYDIR%..\build\amd64\CecSharpTester.exe :CREATEINSTALLER echo. Creating the installer