From cb56c05c613d9314b5708fa671b83a2867fc3e3e Mon Sep 17 00:00:00 2001 From: Gustavo Date: Wed, 17 Jun 2015 11:05:36 -0300 Subject: [PATCH] Simple CEC input --- CMakeLists.txt | 10 ++++- cmake/FindCEC.cmake | 19 +++++++++ src/input.c | 94 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 121 insertions(+), 2 deletions(-) create mode 100644 cmake/FindCEC.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 4f71043..6800c47 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,6 +10,7 @@ aux_source_directory(./third_party/moonlight-common-c/limelight-common SRC_LIST) aux_source_directory(./third_party/moonlight-common-c/limelight-common/OpenAES SRC_LIST) include_directories(./third_party/moonlight-common-c) +include_directories(./third_party/libcec/include) set(MOONLIGHT_DEFINITIONS) @@ -21,12 +22,17 @@ find_package(ALSA REQUIRED) find_package(Opus REQUIRED) find_package(Broadcom) find_package(Freescale) +find_package(CEC) find_package(PkgConfig REQUIRED) pkg_check_modules(EVDEV REQUIRED libevdev) pkg_check_modules(AVAHI REQUIRED avahi-client) pkg_check_modules(UDEV REQUIRED libudev) +if(CEC_FOUND) + list(APPEND MOONLIGHT_DEFINITIONS HAVE_LIBCEC) +endif() + if(BROADCOM_FOUND) aux_source_directory(./third_party/ilclient SRC_LIST) aux_source_directory(./third_party/h264bitstream SRC_LIST) @@ -54,8 +60,8 @@ if(FREESCALE_FOUND) endif() set_property(TARGET moonlight PROPERTY COMPILE_DEFINITIONS ${MOONLIGHT_DEFINITIONS}) -include_directories(./third_party/moonlight-common-c ${OPUS_INCLUDE_DIRS} ${EVDEV_INCLUDE_DIRS} ${AVAHI_INCLUDE_DIRS} ${UDEV_INCLUDE_DIRS}) -target_link_libraries (moonlight PUBLIC ${CMAKE_THREAD_LIBS_INIT} ${CURL_LIBRARIES} ${OPENSSL_LIBRARIES} ${EXPAT_LIBRARIES} ${EVDEV_LIBRARIES} ${ALSA_LIBRARY} ${OPUS_LIBRARY} ${AVAHI_LIBRARIES} ${UDEV_LIBRARIES} ${CMAKE_DL_LIBS}) +include_directories(./third_party/moonlight-common-c ${OPUS_INCLUDE_DIRS} ${EVDEV_INCLUDE_DIRS} ${AVAHI_INCLUDE_DIRS} ${UDEV_INCLUDE_DIRS} ${CEC_INCLUDE_DIRS}) +target_link_libraries (moonlight PUBLIC ${CMAKE_THREAD_LIBS_INIT} ${CURL_LIBRARIES} ${OPENSSL_LIBRARIES} ${EXPAT_LIBRARIES} ${EVDEV_LIBRARIES} ${ALSA_LIBRARY} ${OPUS_LIBRARY} ${AVAHI_LIBRARIES} ${UDEV_LIBRARIES} ${CMAKE_DL_LIBS} ${CEC_LIBRARIES}) include(${CMAKE_ROOT}/Modules/GNUInstallDirs.cmake) install(TARGETS moonlight DESTINATION ${CMAKE_INSTALL_BINDIR}) diff --git a/cmake/FindCEC.cmake b/cmake/FindCEC.cmake new file mode 100644 index 0000000..0f94c8f --- /dev/null +++ b/cmake/FindCEC.cmake @@ -0,0 +1,19 @@ +# - Try to find CEC +# Once done this will define +# +# CEC_FOUND - system has libcec +# CEC_INCLUDE_DIRS - the libcec include directory +# CEC_LIBRARIES - The libcec libraries + +if(PKG_CONFIG_FOUND) + pkg_check_modules (CEC libcec>=3.0.0) +else() + find_path(CEC_INCLUDE_DIRS libcec/cec.h) + find_library(CEC_LIBRARIES cec) +endif() + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(CEC DEFAULT_MSG CEC_INCLUDE_DIRS CEC_LIBRARIES) + +list(APPEND CEC_DEFINITIONS -DHAVE_LIBCEC=1) +mark_as_advanced(CEC_INCLUDE_DIRS CEC_LIBRARIES CEC_DEFINITIONS) diff --git a/src/input.c b/src/input.c index c9fd826..14a31d8 100644 --- a/src/input.c +++ b/src/input.c @@ -40,6 +40,10 @@ #include #include +#ifdef HAVE_LIBCEC +#include +#endif + struct input_abs_parms { int min, max; int flat; @@ -81,6 +85,93 @@ static int udev_fdindex; static int sig_fdindex; +#ifdef HAVE_LIBCEC +static libcec_configuration g_config; +static char g_strPort[50] = { 0 }; +static libcec_interface_t g_iface; +static ICECCallbacks g_callbacks; + +static int on_cec_keypress(void *UNUSED, const cec_keypress key) +{ + char value; + switch (key.keycode) + { + case CEC_USER_CONTROL_CODE_UP: + value = KEY_UP; + break; + case CEC_USER_CONTROL_CODE_DOWN: + value = KEY_DOWN; + break; + case CEC_USER_CONTROL_CODE_LEFT: + value = KEY_LEFT; + break; + case CEC_USER_CONTROL_CODE_RIGHT: + value = KEY_RIGHT; + break; + case CEC_USER_CONTROL_CODE_ENTER: + case CEC_USER_CONTROL_CODE_SELECT: + value = KEY_ENTER; + break; + case CEC_USER_CONTROL_CODE_ROOT_MENU: + value = KEY_TAB; + break; + case CEC_USER_CONTROL_CODE_AN_RETURN: + case CEC_USER_CONTROL_CODE_EXIT: + value = KEY_ESC; + break; + default: + value = 0; + break; + } + + if (value != 0) + { + short code = 0x80 << 8 | keyCodes[value]; + LiSendKeyboardEvent(code, (key.duration > 0)?KEY_ACTION_DOWN:KEY_ACTION_UP, 0); + } +} + +static void init_cec() +{ + libcecc_reset_configuration(&g_config); + g_config.clientVersion = LIBCEC_VERSION_CURRENT; + g_config.bActivateSource = 0; + g_callbacks.CBCecKeyPress = &on_cec_keypress; + g_config.callbacks = &g_callbacks; + snprintf(g_config.strDeviceName, sizeof(g_config.strDeviceName), "Moonlight"); + g_config.callbacks = &g_callbacks; + g_config.deviceTypes.types[0] = CEC_DEVICE_TYPE_PLAYBACK_DEVICE; + + if (libcecc_initialise(&g_config, &g_iface, NULL) != 1) { + fprintf(stderr, "Failed to initialize libcec interface\n"); + fflush(stderr); + return; + } + + g_iface.init_video_standalone(g_iface.connection); + + cec_adapter devices[10]; + int8_t iDevicesFound = g_iface.find_adapters(g_iface.connection, devices, sizeof(devices) / sizeof(devices), NULL); + + if (iDevicesFound <= 0) { + fprintf(stderr, "No CEC devices found\n"); + fflush(stderr); + libcecc_destroy(&g_iface); + return; + } + + strcpy(g_strPort, devices[0].comm); + if (!g_iface.open(g_iface.connection, g_strPort, 5000)) { + fprintf(stderr, "Unable to open the device on port %s\n", g_strPort); + fflush(stderr); + libcecc_destroy(&g_iface); + return; + } + + g_iface.set_active_source(g_iface.connection, g_config.deviceTypes.types[0]); +} +#endif + static void input_init_parms(struct input_device *dev, struct input_abs_parms *parms, int code) { parms->flat = libevdev_get_abs_flat(dev->dev, code); parms->min = libevdev_get_abs_minimum(dev->dev, code); @@ -614,5 +705,8 @@ void input_map(char* fileName) { } void input_loop() { +#ifdef HAVE_LIBCEC + init_cec(); +#endif input_poll(input_handle_event); }