CEC Support

This commit is contained in:
Tomas Jakobsson 2017-11-08 23:22:15 +01:00
parent b833b45832
commit 074e22ee37
11 changed files with 371 additions and 20 deletions

View file

@ -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)

View file

@ -56,6 +56,7 @@ find_package(Boost REQUIRED COMPONENTS system filesystem date_time)
endif() endif()
find_package(CURL REQUIRED) find_package(CURL REQUIRED)
find_package(VLC REQUIRED) find_package(VLC REQUIRED)
find_package(libCEC)
#add ALSA for Linux #add ALSA for Linux
if(${CMAKE_SYSTEM_NAME} MATCHES "Linux") if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
@ -68,6 +69,10 @@ if(DEFINED BCMHOST)
add_definitions(-D_RPI_) add_definitions(-D_RPI_)
endif() endif()
if(DEFINED libCEC_FOUND)
add_definitions(-DHAVE_LIBCEC)
endif()
#------------------------------------------------------------------------------- #-------------------------------------------------------------------------------
if(MSVC) if(MSVC)
@ -114,6 +119,13 @@ set(COMMON_INCLUDE_DIRS
${CMAKE_CURRENT_SOURCE_DIR}/es-core/src ${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 #add ALSA for Linux
if(${CMAKE_SYSTEM_NAME} MATCHES "Linux") if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
LIST(APPEND COMMON_INCLUDE_DIRS LIST(APPEND COMMON_INCLUDE_DIRS
@ -157,13 +169,21 @@ set(COMMON_LIBRARIES
${Boost_LIBRARIES} ${Boost_LIBRARIES}
${FREETYPE_LIBRARIES} ${FREETYPE_LIBRARIES}
${FreeImage_LIBRARIES} ${FreeImage_LIBRARIES}
${SDL2_LIBRARY} ${SDL2_LIBRARY}
${CURL_LIBRARIES} ${CURL_LIBRARIES}
${VLC_LIBRARIES} ${VLC_LIBRARIES}
pugixml pugixml
nanosvg nanosvg
) )
#add libCEC_LIBRARIES
if(DEFINED libCEC_FOUND)
LIST(APPEND COMMON_LIBRARIES
dl
${libCEC_LIBRARIES}
)
endif()
#add ALSA for Linux #add ALSA for Linux
if(${CMAKE_SYSTEM_NAME} MATCHES "Linux") if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
LIST(APPEND COMMON_LIBRARIES LIST(APPEND COMMON_LIBRARIES

View file

@ -326,24 +326,10 @@ int main(int argc, char* argv[])
{ {
do do
{ {
switch(event.type) InputManager::getInstance()->parseEvent(event, &window);
{
case SDL_JOYHATMOTION: if(event.type == SDL_QUIT)
case SDL_JOYBUTTONDOWN: running = false;
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;
}
} while(SDL_PollEvent(&event)); } while(SDL_PollEvent(&event));
// triggered if exiting from SDL_WaitEvent due to event // triggered if exiting from SDL_WaitEvent due to event

View file

@ -3,6 +3,7 @@ project("core")
set(CORE_HEADERS set(CORE_HEADERS
${CMAKE_CURRENT_SOURCE_DIR}/src/AsyncHandle.h ${CMAKE_CURRENT_SOURCE_DIR}/src/AsyncHandle.h
${CMAKE_CURRENT_SOURCE_DIR}/src/AudioManager.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/GuiComponent.h
${CMAKE_CURRENT_SOURCE_DIR}/src/HelpStyle.h ${CMAKE_CURRENT_SOURCE_DIR}/src/HelpStyle.h
${CMAKE_CURRENT_SOURCE_DIR}/src/HttpReq.h ${CMAKE_CURRENT_SOURCE_DIR}/src/HttpReq.h
@ -66,6 +67,7 @@ set(CORE_HEADERS
set(CORE_SOURCES set(CORE_SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/src/AudioManager.cpp ${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/GuiComponent.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/HelpStyle.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/HelpStyle.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/HttpReq.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/HttpReq.cpp

125
es-core/src/CECInput.cpp Normal file
View file

@ -0,0 +1,125 @@
#include "CECInput.h"
#ifdef HAVE_LIBCEC
#include "Log.h"
#include <libcec/cec.h>
#include <iostream> // bad bad cecloader
#include <libcec/cecloader.h>
#include <SDL_events.h>
#endif // HAVE_LIBCEC
#include <assert.h>
// 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
}

26
es-core/src/CECInput.h Normal file
View file

@ -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

View file

@ -15,6 +15,8 @@ std::string inputTypeToString(InputType type)
return "hat"; return "hat";
case TYPE_KEY: case TYPE_KEY:
return "key"; return "key";
case TYPE_CEC_BUTTON:
return "cec-button";
default: default:
return "error"; return "error";
} }
@ -30,6 +32,8 @@ InputType stringToInputType(const std::string& type)
return TYPE_HAT; return TYPE_HAT;
if(type == "key") if(type == "key")
return TYPE_KEY; return TYPE_KEY;
if(type == "cec-button")
return TYPE_CEC_BUTTON;
return TYPE_COUNT; return TYPE_COUNT;
} }

View file

@ -2,6 +2,9 @@
#ifndef ES_CORE_INPUT_CONFIG_H #ifndef ES_CORE_INPUT_CONFIG_H
#define ES_CORE_INPUT_CONFIG_H #define ES_CORE_INPUT_CONFIG_H
#ifdef HAVE_LIBCEC
#include <libcec/cectypes.h>
#endif // HAVE_LIBCEC
#include <pugixml/src/pugixml.hpp> #include <pugixml/src/pugixml.hpp>
#include <SDL_joystick.h> #include <SDL_joystick.h>
#include <SDL_keyboard.h> #include <SDL_keyboard.h>
@ -10,6 +13,7 @@
#include <vector> #include <vector>
#define DEVICE_KEYBOARD -1 #define DEVICE_KEYBOARD -1
#define DEVICE_CEC -2
enum InputType enum InputType
{ {
@ -17,6 +21,7 @@ enum InputType
TYPE_BUTTON, TYPE_BUTTON,
TYPE_HAT, TYPE_HAT,
TYPE_KEY, TYPE_KEY,
TYPE_CEC_BUTTON,
TYPE_COUNT TYPE_COUNT
}; };
@ -55,6 +60,106 @@ public:
return "neutral?"; 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::string string()
{ {
std::stringstream stream; std::stringstream stream;
@ -72,6 +177,9 @@ public:
case TYPE_KEY: case TYPE_KEY:
stream << "Key " << SDL_GetKeyName((SDL_Keycode)id); stream << "Key " << SDL_GetKeyName((SDL_Keycode)id);
break; break;
case TYPE_CEC_BUTTON:
stream << "CEC-Button " << getCECButtonName(id);
break;
default: default:
stream << "Input to string error"; stream << "Input to string error";
break; break;

View file

@ -1,5 +1,6 @@
#include "InputManager.h" #include "InputManager.h"
#include "CECInput.h"
#include "Log.h" #include "Log.h"
#include "platform.h" #include "platform.h"
#include "Window.h" #include "Window.h"
@ -8,6 +9,7 @@
#include <iostream> #include <iostream>
#define KEYBOARD_GUID_STRING "-1" #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) // 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?) // 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. // 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. // 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; namespace fs = boost::filesystem;
InputManager* InputManager::mInstance = NULL; InputManager* InputManager::mInstance = NULL;
@ -60,6 +66,12 @@ void InputManager::init()
mKeyboardInputConfig = new InputConfig(DEVICE_KEYBOARD, "Keyboard", KEYBOARD_GUID_STRING); mKeyboardInputConfig = new InputConfig(DEVICE_KEYBOARD, "Keyboard", KEYBOARD_GUID_STRING);
loadInputConfig(mKeyboardInputConfig); 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) void InputManager::addJoystickByDeviceIndex(int id)
@ -146,6 +158,14 @@ void InputManager::deinit()
mKeyboardInputConfig = NULL; mKeyboardInputConfig = NULL;
} }
if(mCECInputConfig != NULL)
{
delete mCECInputConfig;
mCECInputConfig = NULL;
}
CECInput::deinit();
SDL_JoystickEventState(SDL_DISABLE); SDL_JoystickEventState(SDL_DISABLE);
SDL_QuitSubSystem(SDL_INIT_JOYSTICK); SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
} }
@ -155,6 +175,12 @@ int InputManager::getButtonCountByDevice(SDL_JoystickID id)
{ {
if(id == DEVICE_KEYBOARD) if(id == DEVICE_KEYBOARD)
return 120; //it's a lot, okay. 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 else
return SDL_JoystickNumButtons(mJoysticks[id]); return SDL_JoystickNumButtons(mJoysticks[id]);
} }
@ -163,6 +189,8 @@ InputConfig* InputManager::getInputConfigByDevice(int device)
{ {
if(device == DEVICE_KEYBOARD) if(device == DEVICE_KEYBOARD)
return mKeyboardInputConfig; return mKeyboardInputConfig;
else if(device == DEVICE_CEC)
return mCECInputConfig;
else else
return mInputConfigs[device]; return mInputConfigs[device];
} }
@ -238,6 +266,12 @@ bool InputManager::parseEvent(const SDL_Event& ev, Window* window)
return false; 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; return false;
} }
@ -427,6 +461,9 @@ int InputManager::getNumConfiguredDevices()
if(mKeyboardInputConfig->isConfigured()) if(mKeyboardInputConfig->isConfigured())
num++; num++;
if(mCECInputConfig->isConfigured())
num++;
return num; return num;
} }
@ -435,6 +472,9 @@ std::string InputManager::getDeviceGUIDString(int deviceId)
if(deviceId == DEVICE_KEYBOARD) if(deviceId == DEVICE_KEYBOARD)
return KEYBOARD_GUID_STRING; return KEYBOARD_GUID_STRING;
if(deviceId == DEVICE_CEC)
return CEC_GUID_STRING;
auto it = mJoysticks.find(deviceId); auto it = mJoysticks.find(deviceId);
if(it == mJoysticks.end()) if(it == mJoysticks.end())
{ {

View file

@ -24,6 +24,7 @@ private:
std::map<SDL_JoystickID, SDL_Joystick*> mJoysticks; std::map<SDL_JoystickID, SDL_Joystick*> mJoysticks;
std::map<SDL_JoystickID, InputConfig*> mInputConfigs; std::map<SDL_JoystickID, InputConfig*> mInputConfigs;
InputConfig* mKeyboardInputConfig; InputConfig* mKeyboardInputConfig;
InputConfig* mCECInputConfig;
std::map<SDL_JoystickID, int*> mPrevAxisValues; std::map<SDL_JoystickID, int*> mPrevAxisValues;

View file

@ -80,7 +80,7 @@ bool GuiDetectDevice::input(InputConfig* config, Input input)
return true; 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) if(input.value && mHoldingConfig == NULL)
{ {