diff --git a/CMake/Packages/FindlibCEC.cmake b/CMake/Packages/FindlibCEC.cmake new file mode 100644 index 000000000..49c0da86a --- /dev/null +++ b/CMake/Packages/FindlibCEC.cmake @@ -0,0 +1,39 @@ +# - Try to find libCEC +# Once done, this will define +# +# libCEC_FOUND - system has libCEC +# libCEC_INCLUDE_DIRS - the libCEC include directories +# libCEC_LIBRARIES - link these to use libCEC + +include(FindPkgMacros) +findpkg_begin(libCEC) + +# Get path, convert backslashes as ${ENV_${var}} +getenv_path(LIBCEC_HOME) + +# construct search paths +set(libCEC_PREFIX_PATH ${LIBCEC_HOME} ${ENV_LIBCEC_HOME}) +create_search_paths(LIBCEC) +# redo search if prefix path changed +clear_if_changed(libCEC_PREFIX_PATH + libCEC_LIBRARY_FWK + libCEC_LIBRARY_REL + libCEC_LIBRARY_DBG + libCEC_INCLUDE_DIR +) + +set(libCEC_LIBRARY_NAMES libcec.so) +get_debug_names(libCEC_LIBRARY_NAMES) + +use_pkgconfig(libCEC_PKGC libcec) + +findpkg_framework(libCEC) + +find_path(libCEC_INCLUDE_DIR NAMES cec.h HINTS ${libCEC_INC_SEARCH_PATH} ${libCEC_PKGC_INCLUDE_DIRS}) + +find_library(libCEC_LIBRARY_REL NAMES ${libCEC_LIBRARY_NAMES} HINTS ${libCEC_LIB_SEARCH_PATH} ${libCEC_PKGC_LIBRARY_DIRS} PATH_SUFFIXES release relwithdebinfo minsizerel) +find_library(libCEC_LIBRARY_DBG NAMES ${libCEC_LIBRARY_NAMES_DBG} HINTS ${libCEC_LIB_SEARCH_PATH} ${libCEC_PKGC_LIBRARY_DIRS} PATH_SUFFIXES debug) + +make_library_set(libCEC_LIBRARY) + +findpkg_finish(libCEC) \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 8e95d3409..b9c7a03f3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -56,6 +56,7 @@ find_package(Boost REQUIRED COMPONENTS system filesystem date_time) endif() find_package(CURL REQUIRED) find_package(VLC REQUIRED) +find_package(libCEC) #add ALSA for Linux if(${CMAKE_SYSTEM_NAME} MATCHES "Linux") @@ -68,6 +69,10 @@ if(DEFINED BCMHOST) add_definitions(-D_RPI_) endif() +if(DEFINED libCEC_FOUND) + add_definitions(-DHAVE_LIBCEC) +endif() + #------------------------------------------------------------------------------- if(MSVC) @@ -114,6 +119,13 @@ set(COMMON_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/es-core/src ) +#add libCEC_INCLUDE_DIR +if(DEFINED libCEC_FOUND) + LIST(APPEND COMMON_INCLUDE_DIRS + ${libCEC_INCLUDE_DIR} + ) +endif() + #add ALSA for Linux if(${CMAKE_SYSTEM_NAME} MATCHES "Linux") LIST(APPEND COMMON_INCLUDE_DIRS @@ -157,13 +169,21 @@ set(COMMON_LIBRARIES ${Boost_LIBRARIES} ${FREETYPE_LIBRARIES} ${FreeImage_LIBRARIES} - ${SDL2_LIBRARY} + ${SDL2_LIBRARY} ${CURL_LIBRARIES} ${VLC_LIBRARIES} pugixml nanosvg ) +#add libCEC_LIBRARIES +if(DEFINED libCEC_FOUND) + LIST(APPEND COMMON_LIBRARIES + dl + ${libCEC_LIBRARIES} + ) +endif() + #add ALSA for Linux if(${CMAKE_SYSTEM_NAME} MATCHES "Linux") LIST(APPEND COMMON_LIBRARIES diff --git a/es-app/src/main.cpp b/es-app/src/main.cpp index 68bb91b3b..e29308cbc 100644 --- a/es-app/src/main.cpp +++ b/es-app/src/main.cpp @@ -326,24 +326,10 @@ int main(int argc, char* argv[]) { do { - switch(event.type) - { - case SDL_JOYHATMOTION: - case SDL_JOYBUTTONDOWN: - case SDL_JOYBUTTONUP: - case SDL_KEYDOWN: - case SDL_KEYUP: - case SDL_JOYAXISMOTION: - case SDL_TEXTINPUT: - case SDL_TEXTEDITING: - case SDL_JOYDEVICEADDED: - case SDL_JOYDEVICEREMOVED: - InputManager::getInstance()->parseEvent(event, &window); - break; - case SDL_QUIT: - running = false; - break; - } + InputManager::getInstance()->parseEvent(event, &window); + + if(event.type == SDL_QUIT) + running = false; } while(SDL_PollEvent(&event)); // triggered if exiting from SDL_WaitEvent due to event diff --git a/es-core/CMakeLists.txt b/es-core/CMakeLists.txt index 91c945c5f..fabae068f 100644 --- a/es-core/CMakeLists.txt +++ b/es-core/CMakeLists.txt @@ -3,6 +3,7 @@ project("core") set(CORE_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/src/AsyncHandle.h ${CMAKE_CURRENT_SOURCE_DIR}/src/AudioManager.h + ${CMAKE_CURRENT_SOURCE_DIR}/src/CECInput.h ${CMAKE_CURRENT_SOURCE_DIR}/src/GuiComponent.h ${CMAKE_CURRENT_SOURCE_DIR}/src/HelpStyle.h ${CMAKE_CURRENT_SOURCE_DIR}/src/HttpReq.h @@ -66,6 +67,7 @@ set(CORE_HEADERS set(CORE_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/AudioManager.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/CECInput.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/GuiComponent.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/HelpStyle.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/HttpReq.cpp diff --git a/es-core/src/CECInput.cpp b/es-core/src/CECInput.cpp new file mode 100644 index 000000000..ec41d7a43 --- /dev/null +++ b/es-core/src/CECInput.cpp @@ -0,0 +1,125 @@ +#include "CECInput.h" + +#ifdef HAVE_LIBCEC +#include "Log.h" +#include +#include // bad bad cecloader +#include +#include +#endif // HAVE_LIBCEC +#include + +// hack for cec support +extern int SDL_USER_CECBUTTONDOWN; +extern int SDL_USER_CECBUTTONUP; + +CECInput* CECInput::sInstance = nullptr; + +#ifdef HAVE_LIBCEC +static int onAlert(void* /*cbParam*/, const CEC::libcec_alert /*type*/, const CEC::libcec_parameter /*param*/) +{ + return 0; +} + +static int onCommand(void* /*cbParam*/, const CEC::cec_command /*command*/) +{ + return 0; +} + +static int onKeyPress(void* /*cbParam*/, const CEC::cec_keypress key) +{ + SDL_Event event; + event.type = (key.duration > 0) ? SDL_USER_CECBUTTONUP : SDL_USER_CECBUTTONDOWN; + event.user.code = key.keycode; + SDL_PushEvent(&event); + + return 0; +} + +static int onLogMessage(void* /*cbParam*/, const CEC::cec_log_message /*message*/) +{ + return 0; +} +#endif // HAVE_LIBCEC + +void CECInput::init() +{ + assert(!sInstance); + sInstance = new CECInput(); +} + +void CECInput::deinit() +{ + assert(sInstance); + delete sInstance; + sInstance = nullptr; +} + +CECInput::CECInput() : mlibCEC(nullptr) +{ + +#ifdef HAVE_LIBCEC + CEC::ICECCallbacks callbacks; + CEC::libcec_configuration config; + config.Clear(); + callbacks.Clear(); + + sprintf(config.strDeviceName, "RetroPie ES"); + config.clientVersion = CEC::LIBCEC_VERSION_CURRENT; + config.bActivateSource = 0; + config.callbacks = &callbacks; + config.deviceTypes.Add(CEC::CEC_DEVICE_TYPE_PLAYBACK_DEVICE); + + callbacks.CBCecAlert = &onAlert; + callbacks.CBCecCommand = &onCommand; + callbacks.CBCecKeyPress = &onKeyPress; + callbacks.CBCecLogMessage = &onLogMessage; + + mlibCEC = LibCecInitialise(&config); + + if(!mlibCEC) + { + LOG(LogInfo) << "CECInput::LibCecInitialise failed"; + return; + } + + CEC::cec_adapter adapters[10]; + int8_t numAdapters = mlibCEC->FindAdapters(adapters, 10, nullptr); + + if(numAdapters <= 0) + { + LOG(LogInfo) << "CECInput::mAdapter->FindAdapters failed"; + UnloadLibCec(mlibCEC); + mlibCEC = nullptr; + return; + } + + for(int i = 0; i < numAdapters; ++i) + LOG(LogDebug) << "adapter: " << i << " path: " << adapters[i].comm << " comm: " << adapters[i].comm; + + if(!mlibCEC->Open(adapters[0].comm)) + { + LOG(LogInfo) << "CECInput::mAdapter->Open failed"; + UnloadLibCec(mlibCEC); + mlibCEC = nullptr; + return; + } + + LOG(LogDebug) << "CECInput succeeded"; +#endif // HAVE_LIBCEC + +} + +CECInput::~CECInput() +{ + +#ifdef HAVE_LIBCEC + if(mlibCEC) + { + mlibCEC->Close(); + UnloadLibCec(mlibCEC); + mlibCEC = nullptr; + } +#endif // HAVE_LIBCEC + +} diff --git a/es-core/src/CECInput.h b/es-core/src/CECInput.h new file mode 100644 index 000000000..f19b946ea --- /dev/null +++ b/es-core/src/CECInput.h @@ -0,0 +1,26 @@ +#pragma once +#ifndef ES_CORE_CECINPUT_H +#define ES_CORE_CECINPUT_H + +namespace CEC { class ICECAdapter; } +class Window; + +class CECInput +{ +public: + + ~CECInput(); + + static void init(); + static void deinit(); + +private: + + CECInput(); + static CECInput* sInstance; + + CEC::ICECAdapter* mlibCEC; + +}; + +#endif // ES_CORE_CECINPUT_H diff --git a/es-core/src/InputConfig.cpp b/es-core/src/InputConfig.cpp index 23c6dd6ce..ea141ce67 100644 --- a/es-core/src/InputConfig.cpp +++ b/es-core/src/InputConfig.cpp @@ -15,6 +15,8 @@ std::string inputTypeToString(InputType type) return "hat"; case TYPE_KEY: return "key"; + case TYPE_CEC_BUTTON: + return "cec-button"; default: return "error"; } @@ -30,6 +32,8 @@ InputType stringToInputType(const std::string& type) return TYPE_HAT; if(type == "key") return TYPE_KEY; + if(type == "cec-button") + return TYPE_CEC_BUTTON; return TYPE_COUNT; } diff --git a/es-core/src/InputConfig.h b/es-core/src/InputConfig.h index d3d0be99e..e217715cc 100644 --- a/es-core/src/InputConfig.h +++ b/es-core/src/InputConfig.h @@ -2,6 +2,9 @@ #ifndef ES_CORE_INPUT_CONFIG_H #define ES_CORE_INPUT_CONFIG_H +#ifdef HAVE_LIBCEC +#include +#endif // HAVE_LIBCEC #include #include #include @@ -10,6 +13,7 @@ #include #define DEVICE_KEYBOARD -1 +#define DEVICE_CEC -2 enum InputType { @@ -17,6 +21,7 @@ enum InputType TYPE_BUTTON, TYPE_HAT, TYPE_KEY, + TYPE_CEC_BUTTON, TYPE_COUNT }; @@ -55,6 +60,106 @@ public: return "neutral?"; } + std::string getCECButtonName(int keycode) + { + +#ifdef HAVE_LIBCEC + switch(keycode) + { + case CEC::CEC_USER_CONTROL_CODE_SELECT: { return "Select"; } break; + case CEC::CEC_USER_CONTROL_CODE_UP: { return "Up"; } break; + case CEC::CEC_USER_CONTROL_CODE_DOWN: { return "Down"; } break; + case CEC::CEC_USER_CONTROL_CODE_LEFT: { return "Left"; } break; + case CEC::CEC_USER_CONTROL_CODE_RIGHT: { return "Right"; } break; + case CEC::CEC_USER_CONTROL_CODE_RIGHT_UP: { return "Right-Up"; } break; + case CEC::CEC_USER_CONTROL_CODE_RIGHT_DOWN: { return "Left-Down"; } break; + case CEC::CEC_USER_CONTROL_CODE_LEFT_UP: { return "Left-Up"; } break; + case CEC::CEC_USER_CONTROL_CODE_LEFT_DOWN: { return "Left-Down"; } break; + case CEC::CEC_USER_CONTROL_CODE_ROOT_MENU: { return "Root-Menu"; } break; + case CEC::CEC_USER_CONTROL_CODE_SETUP_MENU: { return "Setup-Menu"; } break; + case CEC::CEC_USER_CONTROL_CODE_CONTENTS_MENU: { return "Contents-Menu"; } break; + case CEC::CEC_USER_CONTROL_CODE_FAVORITE_MENU: { return "Favorite-Menu"; } break; + case CEC::CEC_USER_CONTROL_CODE_EXIT: { return "Exit"; } break; + case CEC::CEC_USER_CONTROL_CODE_TOP_MENU: { return "Top-Menu"; } break; + case CEC::CEC_USER_CONTROL_CODE_DVD_MENU: { return "DVD-Menu"; } break; + case CEC::CEC_USER_CONTROL_CODE_NUMBER_ENTRY_MODE: { return "Number-Entry-Mode"; } break; + case CEC::CEC_USER_CONTROL_CODE_NUMBER11: { return "Number 11"; } break; + case CEC::CEC_USER_CONTROL_CODE_NUMBER12: { return "Number 12"; } break; + case CEC::CEC_USER_CONTROL_CODE_NUMBER0: { return "Number 0"; } break; + case CEC::CEC_USER_CONTROL_CODE_NUMBER1: { return "Number 1"; } break; + case CEC::CEC_USER_CONTROL_CODE_NUMBER2: { return "Number 2"; } break; + case CEC::CEC_USER_CONTROL_CODE_NUMBER3: { return "Number 3"; } break; + case CEC::CEC_USER_CONTROL_CODE_NUMBER4: { return "Number 4"; } break; + case CEC::CEC_USER_CONTROL_CODE_NUMBER5: { return "Number 5"; } break; + case CEC::CEC_USER_CONTROL_CODE_NUMBER6: { return "Number 6"; } break; + case CEC::CEC_USER_CONTROL_CODE_NUMBER7: { return "Number 7"; } break; + case CEC::CEC_USER_CONTROL_CODE_NUMBER8: { return "Number 8"; } break; + case CEC::CEC_USER_CONTROL_CODE_NUMBER9: { return "Number 9"; } break; + case CEC::CEC_USER_CONTROL_CODE_DOT: { return "Dot"; } break; + case CEC::CEC_USER_CONTROL_CODE_ENTER: { return "Enter"; } break; + case CEC::CEC_USER_CONTROL_CODE_CLEAR: { return "Clear"; } break; + case CEC::CEC_USER_CONTROL_CODE_NEXT_FAVORITE: { return "Next-Favorite"; } break; + case CEC::CEC_USER_CONTROL_CODE_CHANNEL_UP: { return "Channel-Up"; } break; + case CEC::CEC_USER_CONTROL_CODE_CHANNEL_DOWN: { return "Channel-Down"; } break; + case CEC::CEC_USER_CONTROL_CODE_PREVIOUS_CHANNEL: { return "Previous-Channel"; } break; + case CEC::CEC_USER_CONTROL_CODE_SOUND_SELECT: { return "Sound-Select"; } break; + case CEC::CEC_USER_CONTROL_CODE_INPUT_SELECT: { return "Input-Select"; } break; + case CEC::CEC_USER_CONTROL_CODE_DISPLAY_INFORMATION: { return "Display-Information"; } break; + case CEC::CEC_USER_CONTROL_CODE_HELP: { return "Help"; } break; + case CEC::CEC_USER_CONTROL_CODE_PAGE_UP: { return "Page-Up"; } break; + case CEC::CEC_USER_CONTROL_CODE_PAGE_DOWN: { return "Page-Down"; } break; + case CEC::CEC_USER_CONTROL_CODE_POWER: { return "Power"; } break; + case CEC::CEC_USER_CONTROL_CODE_VOLUME_UP: { return "Volume-Up"; } break; + case CEC::CEC_USER_CONTROL_CODE_VOLUME_DOWN: { return "Volume-Down"; } break; + case CEC::CEC_USER_CONTROL_CODE_MUTE: { return "Mute"; } break; + case CEC::CEC_USER_CONTROL_CODE_PLAY: { return "Play"; } break; + case CEC::CEC_USER_CONTROL_CODE_STOP: { return "Stop"; } break; + case CEC::CEC_USER_CONTROL_CODE_PAUSE: { return "Pause"; } break; + case CEC::CEC_USER_CONTROL_CODE_RECORD: { return "Record"; } break; + case CEC::CEC_USER_CONTROL_CODE_REWIND: { return "Rewind"; } break; + case CEC::CEC_USER_CONTROL_CODE_FAST_FORWARD: { return "Fast-Forward"; } break; + case CEC::CEC_USER_CONTROL_CODE_EJECT: { return "Eject"; } break; + case CEC::CEC_USER_CONTROL_CODE_FORWARD: { return "Forward"; } break; + case CEC::CEC_USER_CONTROL_CODE_BACKWARD: { return "Backward"; } break; + case CEC::CEC_USER_CONTROL_CODE_STOP_RECORD: { return "Stop-Record"; } break; + case CEC::CEC_USER_CONTROL_CODE_PAUSE_RECORD: { return "Pause-Record"; } break; + case CEC::CEC_USER_CONTROL_CODE_ANGLE: { return "Angle"; } break; + case CEC::CEC_USER_CONTROL_CODE_SUB_PICTURE: { return "Sub-Picture"; } break; + case CEC::CEC_USER_CONTROL_CODE_VIDEO_ON_DEMAND: { return "Video-On-Demand"; } break; + case CEC::CEC_USER_CONTROL_CODE_ELECTRONIC_PROGRAM_GUIDE: { return "Electronic-Program-Guide"; } break; + case CEC::CEC_USER_CONTROL_CODE_TIMER_PROGRAMMING: { return "Timer-Programming"; } break; + case CEC::CEC_USER_CONTROL_CODE_INITIAL_CONFIGURATION: { return "Initial-Configuration"; } break; + case CEC::CEC_USER_CONTROL_CODE_SELECT_BROADCAST_TYPE: { return "Select-Broadcast-Type"; } break; + case CEC::CEC_USER_CONTROL_CODE_SELECT_SOUND_PRESENTATION: { return "Select-Sound-Presentation"; } break; + case CEC::CEC_USER_CONTROL_CODE_PLAY_FUNCTION: { return "Play-Function"; } break; + case CEC::CEC_USER_CONTROL_CODE_PAUSE_PLAY_FUNCTION: { return "Pause-Play-Function"; } break; + case CEC::CEC_USER_CONTROL_CODE_RECORD_FUNCTION: { return "Record-Function"; } break; + case CEC::CEC_USER_CONTROL_CODE_PAUSE_RECORD_FUNCTION: { return "Pause-Record-Function"; } break; + case CEC::CEC_USER_CONTROL_CODE_STOP_FUNCTION: { return "Stop-Function"; } break; + case CEC::CEC_USER_CONTROL_CODE_MUTE_FUNCTION: { return "Mute-Function"; } break; + case CEC::CEC_USER_CONTROL_CODE_RESTORE_VOLUME_FUNCTION: { return "Restore-Volume-Function"; } break; + case CEC::CEC_USER_CONTROL_CODE_TUNE_FUNCTION: { return "Tune-Function"; } break; + case CEC::CEC_USER_CONTROL_CODE_SELECT_MEDIA_FUNCTION: { return "Select-Media-Function"; } break; + case CEC::CEC_USER_CONTROL_CODE_SELECT_AV_INPUT_FUNCTION: { return "Select-AV-Input-function"; } break; + case CEC::CEC_USER_CONTROL_CODE_SELECT_AUDIO_INPUT_FUNCTION: { return "Select-Audio-Input-Function"; } break; + case CEC::CEC_USER_CONTROL_CODE_POWER_TOGGLE_FUNCTION: { return "Power-Toggle-Function"; } break; + case CEC::CEC_USER_CONTROL_CODE_POWER_OFF_FUNCTION: { return "Power-Off-Function"; } break; + case CEC::CEC_USER_CONTROL_CODE_POWER_ON_FUNCTION: { return "Power-On-Function"; } break; + case CEC::CEC_USER_CONTROL_CODE_F1_BLUE: { return "F1-Blue"; } break; + case CEC::CEC_USER_CONTROL_CODE_F2_RED: { return "F2-Red"; } break; + case CEC::CEC_USER_CONTROL_CODE_F3_GREEN: { return "F3-Green"; } break; + case CEC::CEC_USER_CONTROL_CODE_F4_YELLOW: { return "F4-Yellow"; } break; + case CEC::CEC_USER_CONTROL_CODE_F5: { return "F5"; } break; + case CEC::CEC_USER_CONTROL_CODE_DATA: { return "Data"; } break; + case CEC::CEC_USER_CONTROL_CODE_AN_RETURN: { return "AN-Return"; } break; + case CEC::CEC_USER_CONTROL_CODE_AN_CHANNELS_LIST: { return "AN-Channels-List"; } break; + default: { return "UNKNOWN"; } + } +#endif // HAVE_LIBCEC + + return "UNKNOWN"; + } + std::string string() { std::stringstream stream; @@ -72,6 +177,9 @@ public: case TYPE_KEY: stream << "Key " << SDL_GetKeyName((SDL_Keycode)id); break; + case TYPE_CEC_BUTTON: + stream << "CEC-Button " << getCECButtonName(id); + break; default: stream << "Input to string error"; break; diff --git a/es-core/src/InputManager.cpp b/es-core/src/InputManager.cpp index f102c4911..b148f5745 100644 --- a/es-core/src/InputManager.cpp +++ b/es-core/src/InputManager.cpp @@ -1,5 +1,6 @@ #include "InputManager.h" +#include "CECInput.h" #include "Log.h" #include "platform.h" #include "Window.h" @@ -8,6 +9,7 @@ #include #define KEYBOARD_GUID_STRING "-1" +#define CEC_GUID_STRING "-2" // SO HEY POTENTIAL POOR SAP WHO IS TRYING TO MAKE SENSE OF ALL THIS (by which I mean my future self) // There are like four distinct IDs used for joysticks (crazy, right?) @@ -20,6 +22,10 @@ // 4. Joystick GUID - this is some squashed version of joystick vendor, version, and a bunch of other device-specific things. // It should remain the same across runs of the program/system restarts/device reordering and is what I use to identify which joystick to load. +// hack for cec support +int SDL_USER_CECBUTTONDOWN = -1; +int SDL_USER_CECBUTTONUP = -1; + namespace fs = boost::filesystem; InputManager* InputManager::mInstance = NULL; @@ -60,6 +66,12 @@ void InputManager::init() mKeyboardInputConfig = new InputConfig(DEVICE_KEYBOARD, "Keyboard", KEYBOARD_GUID_STRING); loadInputConfig(mKeyboardInputConfig); + + SDL_USER_CECBUTTONDOWN = SDL_RegisterEvents(2); + SDL_USER_CECBUTTONUP = SDL_USER_CECBUTTONDOWN + 1; + CECInput::init(); + mCECInputConfig = new InputConfig(DEVICE_CEC, "CEC", CEC_GUID_STRING); + loadInputConfig(mCECInputConfig); } void InputManager::addJoystickByDeviceIndex(int id) @@ -146,6 +158,14 @@ void InputManager::deinit() mKeyboardInputConfig = NULL; } + if(mCECInputConfig != NULL) + { + delete mCECInputConfig; + mCECInputConfig = NULL; + } + + CECInput::deinit(); + SDL_JoystickEventState(SDL_DISABLE); SDL_QuitSubSystem(SDL_INIT_JOYSTICK); } @@ -155,6 +175,12 @@ int InputManager::getButtonCountByDevice(SDL_JoystickID id) { if(id == DEVICE_KEYBOARD) return 120; //it's a lot, okay. + else if(id == DEVICE_CEC) +#ifdef HAVE_CECLIB + return CEC::CEC_USER_CONTROL_CODE_MAX; +#else // HAVE_LIBCEF + return 0; +#endif // HAVE_CECLIB else return SDL_JoystickNumButtons(mJoysticks[id]); } @@ -163,6 +189,8 @@ InputConfig* InputManager::getInputConfigByDevice(int device) { if(device == DEVICE_KEYBOARD) return mKeyboardInputConfig; + else if(device == DEVICE_CEC) + return mCECInputConfig; else return mInputConfigs[device]; } @@ -238,6 +266,12 @@ bool InputManager::parseEvent(const SDL_Event& ev, Window* window) return false; } + if((ev.type == (unsigned int)SDL_USER_CECBUTTONDOWN) || (ev.type == (unsigned int)SDL_USER_CECBUTTONUP)) + { + window->input(getInputConfigByDevice(DEVICE_CEC), Input(DEVICE_CEC, TYPE_CEC_BUTTON, ev.user.code, ev.type == (unsigned int)SDL_USER_CECBUTTONDOWN, false)); + return true; + } + return false; } @@ -427,6 +461,9 @@ int InputManager::getNumConfiguredDevices() if(mKeyboardInputConfig->isConfigured()) num++; + if(mCECInputConfig->isConfigured()) + num++; + return num; } @@ -435,6 +472,9 @@ std::string InputManager::getDeviceGUIDString(int deviceId) if(deviceId == DEVICE_KEYBOARD) return KEYBOARD_GUID_STRING; + if(deviceId == DEVICE_CEC) + return CEC_GUID_STRING; + auto it = mJoysticks.find(deviceId); if(it == mJoysticks.end()) { diff --git a/es-core/src/InputManager.h b/es-core/src/InputManager.h index 6d24c0f4b..fde96f092 100644 --- a/es-core/src/InputManager.h +++ b/es-core/src/InputManager.h @@ -24,6 +24,7 @@ private: std::map mJoysticks; std::map mInputConfigs; InputConfig* mKeyboardInputConfig; + InputConfig* mCECInputConfig; std::map mPrevAxisValues; diff --git a/es-core/src/guis/GuiDetectDevice.cpp b/es-core/src/guis/GuiDetectDevice.cpp index 8aa263cd8..7f7ed06d5 100644 --- a/es-core/src/guis/GuiDetectDevice.cpp +++ b/es-core/src/guis/GuiDetectDevice.cpp @@ -80,7 +80,7 @@ bool GuiDetectDevice::input(InputConfig* config, Input input) return true; } - if(input.type == TYPE_BUTTON || input.type == TYPE_KEY) + if(input.type == TYPE_BUTTON || input.type == TYPE_KEY ||input.type == TYPE_CEC_BUTTON) { if(input.value && mHoldingConfig == NULL) {