From 94e7cfa09b6c39a7b0d5d639130ea9c4febda7c0 Mon Sep 17 00:00:00 2001 From: Chris Tallon Date: Sun, 16 Feb 2020 21:31:28 +0000 Subject: [PATCH] WIP [broken] --- command.cc | 13 +--- command.h | 3 - defines.h | 1 + dsock.cc | 29 ++++---- dsock.h | 6 +- input.cc | 159 ++++++++++-------------------------------- input.h | 13 ++-- inputcec.cc | 60 +++++++++------- inputcec.h | 5 +- inputlinux.cc | 63 +++++++++++------ inputlinux.h | 12 +++- inputman.cc | 85 ++++++++++++++++++++-- inputman.h | 7 +- udp.cc => inputudp.cc | 138 +++++++++++++++++++++--------------- udp.h => inputudp.h | 47 +++++++------ message.h | 1 - objects.mk | 8 +-- videoomx.cc | 11 +-- vsleeptimer.cc | 8 +-- wremoteconfig.cc | 34 ++++++--- 20 files changed, 393 insertions(+), 310 deletions(-) rename udp.cc => inputudp.cc (81%) rename udp.h => inputudp.h (56%) diff --git a/command.cc b/command.cc index 39b54c5..7f4ab5a 100644 --- a/command.cc +++ b/command.cc @@ -23,11 +23,11 @@ #include "command.h" #ifdef WIN32 -#include "inputManwin.h" +#include "inputwin.h" #endif #ifdef __ANDROID__ -#include "inputManandroid.h" +#include "inputandroid.h" #endif #include "led.h" @@ -196,9 +196,6 @@ void Command::run() inputMan->start(); - // Start method 2 of getting commands in... // FIXME move this inside input - udp.run(this); - while(irun) { messageQueueCond.wait(lockWrapper, [&] { return !irun || !messages.empty(); }); @@ -242,7 +239,6 @@ void Command::processMessage(Message* m) { case Message::SHUTDOWN: { - udp.shutdown(); irun = false; break; } @@ -279,11 +275,6 @@ void Command::processMessage(Message* m) handleCommand(m->parameter); break; } - case Message::UDP_BUTTON: - { - handleCommand(m->parameter); - break; - } case Message::CHANGE_LANGUAGE: { boxstack->removeAllExceptWallpaper(); diff --git a/command.h b/command.h index 98fc0db..847fd05 100644 --- a/command.h +++ b/command.h @@ -36,7 +36,6 @@ #include "defines.h" #include "messagequeue.h" -#include "udp.h" class VConnect; class Message; @@ -109,8 +108,6 @@ class Command : public MessageQueue ASLPrefList langcodes; int subdefault; - UDP udp; - void processMessage(Message* m); }; diff --git a/defines.h b/defines.h index a19cbe1..b3bf12e 100644 --- a/defines.h +++ b/defines.h @@ -59,6 +59,7 @@ int getClockRealTime(struct timespec *tp); #define RemoteStartDev ""//No devices passed +// FIXME - check C++ - I think some of these are in std:: now ? #define SNPRINTF _snprintf #define VSNPRINTF _vsnprintf #define STRCASECMP _stricmp diff --git a/dsock.cc b/dsock.cc index ebc41db..c298835 100644 --- a/dsock.cc +++ b/dsock.cc @@ -20,11 +20,9 @@ #include "dsock.h" DatagramSocket::DatagramSocket(short port) +: myPort(port) { - iterate_ip = 0; - myPort = port; addrlen = sizeof(struct sockaddr); - initted = false; } DatagramSocket::~DatagramSocket() @@ -67,23 +65,24 @@ void DatagramSocket::shutdown() initted = false; } -unsigned char DatagramSocket::waitforMessage(unsigned char how) +unsigned char DatagramSocket::waitforMessage(unsigned char how, int quitPipe) { if (!initted) return 0; /* how = 0 - block how = 1 - start new wait how = 2 - continue wait + how = 3 - block, return on byte from quitPipe */ + FD_ZERO(&readfds); + FD_SET(socketnum, &readfds); + struct timeval* passToSelect = NULL; + int sockMaxP1 = socketnum + 1; - if (how == 0) - { - passToSelect = NULL; - } - else if (how == 1) + if (how == 1) { tv.tv_sec = 1; tv.tv_usec = 500000; @@ -98,12 +97,18 @@ unsigned char DatagramSocket::waitforMessage(unsigned char how) } passToSelect = &tv; } - FD_ZERO(&readfds); - FD_SET(socketnum, &readfds); + else if (how == 3) + { + FD_SET(quitPipe, &readfds); + if (quitPipe > socketnum) sockMaxP1 = quitPipe + 1; + } + - if (select(socketnum + 1, &readfds, NULL, NULL, passToSelect) <= 0) + if (select(sockMaxP1, &readfds, NULL, NULL, passToSelect) <= 0) { return 1; } + if ((how == 3) && FD_ISSET(quitPipe, &readfds)) return 3; + if ((mlength = recvfrom(socketnum, buf, MAXBUFLEN, 0, reinterpret_cast(&theirAddr), &addrlen)) == -1) { perror("recvfrom"); return 0; } diff --git a/dsock.h b/dsock.h index 1493889..2fd657d 100644 --- a/dsock.h +++ b/dsock.h @@ -50,7 +50,7 @@ class DatagramSocket ~DatagramSocket(); int init(); void shutdown(); - unsigned char waitforMessage(unsigned char); // int =0-block =1-new wait =2-continue wait + unsigned char waitforMessage(unsigned char, int quitPipe = 0); // uchar =0-block =1-new wait =2-continue wait UINT getDataLength() const; const void* getData() const; // returns a pointer to the data const char* getFromIPA() const; // returns a pointer to from IP address @@ -58,9 +58,9 @@ class DatagramSocket void send(const char *, short, char *, int); // send wants: IP Address ddn style, port, data, length of data private: - bool initted; + bool initted{}; ULONG getIPNumber(ULONG num); - ULONG iterate_ip; + ULONG iterate_ip{}; const static char DSOCKDEBUG = 0; int socketnum; // Socket descriptor short myPort; // My port number diff --git a/input.cc b/input.cc index a41795e..a7767c9 100644 --- a/input.cc +++ b/input.cc @@ -22,6 +22,9 @@ #include "log.h" #include "vdr.h" #include "wtabbar.h" +#include "message.h" +#include "messagequeue.h" +#include "command.h" // FIXME - get rid after predefined message targets #include "inputman.h" #include "input.h" @@ -36,7 +39,7 @@ Input::~Input() void Input::EnterLearningMode(UCHAR command) { - learnmode = command; //Armed + learnmode = command; //Armed } void Input::ResetToDefault() @@ -45,54 +48,6 @@ void Input::ResetToDefault() InitHWCListwithDefaults(); } -/* -UCHAR Input::TranslateHWCFixed(ULLONG code) -{ - switch (code) - { - case DOWN: - return DOWN; - case UP: - return UP; - case LEFT: - return LEFT; - case RIGHT: - return RIGHT; - case MENU: - return MENU; - case BACK: - return BACK; - case OK: - return OK; - default: - return NA_UNKNOWN; - } -} -*/ - -const char* Input::HardcodedTranslateStr(UCHAR command) -{ - switch (command) - { - case DOWN: - return tr("Down"); - case UP: - return tr("Up"); - case LEFT: - return tr("Left"); - case RIGHT: - return tr("Right"); - case MENU: - return tr("Menu"); - case BACK: - return tr("Back"); - case OK: - return tr("Ok"); - default: - return NULL; - } -} - UCHAR Input::TranslateHWCList(int code) { if (learnmode != NOLEARNMODE) @@ -180,76 +135,6 @@ void Input::SaveKeysConfig() VDR::getInstance()->configSave("General","RemoteKeyNum",buffer); } -char* Input::HCWDesc(ULLONG hcw) -{ - char *dest; - const char* temp = InputMan::CommandDesc((UCHAR)hcw); - if (temp != NULL) - { - dest=new char[strlen(temp)+1]; - strcpy(dest,temp); - } - else - { - dest=new char[20]; - sprintf(dest,"C:%lX",(ULONG)hcw); - } - return dest; -} - -char* Input::CommandTranslateStr(UCHAR command) -{ - char* desc; - int length = 5; //:+\t+0 - - const char* commanddesc = InputMan::CommandDesc(command); - if (commanddesc != NULL) length += strlen(commanddesc); - - const char* preassigneddesc = HardcodedTranslateStr(command); - if (preassigneddesc != NULL) length += strlen(preassigneddesc); - - char* keydesc[10]; - int keys = 0; // max 10 - RemoteTranslationList::const_iterator it; - for (it = translist.begin(); it != translist.end(); it++) - { - if (it->second == command) - { - keydesc[keys] = HCWDesc(it->first); - length += strlen(keydesc[keys])+2; - keys++; - if (keys == 10) break; - } - } - - desc = new char[length]; - char* current = desc; - if (commanddesc != NULL) - { - current += sprintf(current, "%s:\t ", commanddesc); - } - else - { - current += sprintf(current,":\t "); - } - - if (preassigneddesc != NULL) - { - current += sprintf(current, "%s\t", preassigneddesc); - } - else - { - current+=sprintf(current,"\t"); - } - - for (int i = 0; i < keys; i++) - { - current += sprintf(current, "%s, ", keydesc[i]); - delete[] keydesc[i]; - } - - return desc; -} // bool Input::addOptionPagesToWTB(WTabBar *wtb) // { @@ -280,6 +165,38 @@ bool Input::loadOptionsfromServer(VDR* vdr) bool Input::saveOptionstoServer() { - SaveKeysConfig(); - return true; + SaveKeysConfig(); + return true; +} + +void Input::sendInputKey(int key) +{ + Message* m = new Message(); + m->message = Message::INPUT_EVENT; + m->to = Command::getInstance(); + m->from = this; + m->parameter = TranslateHWC(key); + MessageQueue::getInstance()->postMessage(m); +} + +std::string Input::getAllHardwareKeyNamesAssignedToVompKey(UCHAR vompKey) +{ + std::string keyNames; + keyNames.reserve(50); + int keys = 0; // max 10 + RemoteTranslationList::const_iterator it; + bool first = true; + for (it = translist.begin(); it != translist.end(); it++) + { + if (it->second == vompKey) + { + if (!first) keyNames += ", "; + first = false; + + keyNames += getHardwareKeyName(it->first); + keys++; + if (keys == 10) break; + } + } + return keyNames; } diff --git a/input.h b/input.h index d25d917..37c7b6c 100644 --- a/input.h +++ b/input.h @@ -20,16 +20,15 @@ #ifndef INPUT_H #define INPUT_H -#include +#include #include -#include -#include #include "defines.h" #include "abstractoption.h" // FIXME make common base class sendKey function +class VDR; typedef std::map RemoteTranslationList; @@ -53,7 +52,7 @@ class Input: public AbstractOption void SaveKeysConfig(); void EnterLearningMode(UCHAR command); - virtual int init()=0; + virtual bool init()=0; virtual void shutdown()=0; virtual bool handlesVolume() {return false;}; @@ -63,11 +62,11 @@ class Input: public AbstractOption virtual void changePowerState(bool /* poweron */) {}; //informs the remote control, that about vomp's power state, this is important e.g. for cec virtual void InitHWCListwithDefaults()=0; - virtual char* HCWDesc(ULLONG hcw); + std::string getAllHardwareKeyNamesAssignedToVompKey(UCHAR vompKey); char* CommandTranslateStr(UCHAR command); - static const char* HardcodedTranslateStr(UCHAR command); void EnterLearnMode(UCHAR command); void ResetToDefault(); + virtual std::string getHardwareKeyName(int hardwareKey)=0; const static ULONG NOLEARNMODE = 256; @@ -144,6 +143,8 @@ class Input: public AbstractOption ULONG learnmode; RemoteTranslationList translist; + + void sendInputKey(int key); }; #endif diff --git a/inputcec.cc b/inputcec.cc index 9dc57b5..1705c4d 100644 --- a/inputcec.cc +++ b/inputcec.cc @@ -25,8 +25,6 @@ using namespace CEC; #include #include "log.h" -#include "message.h" -#include "messagequeue.h" #include "vdr.h" #include "woptionpane.h" #include "inputcec.h" @@ -41,7 +39,7 @@ using namespace CEC; InputCEC* InputCEC::instance = NULL; -int InputCEC::init() +bool InputCEC::init() { InitHWCListwithDefaults(); InitKeymap(); @@ -73,7 +71,7 @@ int InputCEC::init() if (!cec_adap) { Log::getInstance()->log("InputCEC", Log::ERR, "Init LibCEC failed"); - return 1; + return false; } cec_adap->InitVideoStandalone(); @@ -83,28 +81,28 @@ int InputCEC::init() if (adap_num < 0) { Log::getInstance()->log("InputCEC", Log::ERR, "CEC:Failed to find adapter"); - return 1; + return false; } if (adap_num == 0) { Log::getInstance()->log("InputCEC", Log::NOTICE, "CEC: No adapter found"); - return 1; + return false; } if (!cec_adap->Open(cec_adapter_descriptors[0].strComName)) { Log::getInstance()->log("InputCEC", Log::ERR, "CEC:Failed to open adapter"); - return 1; + return false; } if (!cec_adap->SetActiveSource(cec_config.deviceTypes[0])) { Log::getInstance()->log("InputCEC", Log::ERR, "CEC:Failed set active source"); - return 1; + return false; } - return 1; + return true; } void InputCEC::shutdown() @@ -140,26 +138,14 @@ void InputCEC::changePowerState(bool poweron) } } -void InputCEC::incomingCECkey(int keys) +void InputCEC::incomingCECkey(int key) { - // Send INPUT message - Message* m = new Message(); - m->message = Message::INPUT_EVENT; - m->to = Command::getInstance(); - m->from = this; - m->parameter = TranslateHWC(keys); - MessageQueue::getInstance()->postMessage(m); + sendInputKey(TranslateHWC(key)); } void InputCEC::incomingPowerkey(UCHAR key) { - // Send INPUT message - Message* m = new Message(); - m->message = Message::INPUT_EVENT; - m->to = Command::getInstance(); - m->from = this; - m->parameter = key; - MessageQueue::getInstance()->postMessage(m); + sendInputKey(key); } void InputCEC::volumeUp() @@ -459,3 +445,29 @@ void InputCEC::InitKeymap() NAMETRICK2(CEC_USER_CONTROL_CODE_,AN_CHANNELS_LIST ); NAMETRICK2(CEC_USER_CONTROL_CODE_,MAX ); } + +const char* InputCEC::getHardCodedHardwareKeyNamesForVompKey(UCHAR vompKey) +{ + return ""; // FIXME +} + +std::string InputCEC::getHardwareKeyName(int hardwareKey) +{ + const char* desc = cec_keymap[hardwareKey]; + + std::string retval; + + if (desc) + { + retval = desc; + } + else + { + char* rt = new char[10]; + sprintf(rt, "0x%x", hardwareKey); + retval = rt; + } + + return retval; +} + diff --git a/inputcec.h b/inputcec.h index 69c3ad1..172ccfa 100644 --- a/inputcec.h +++ b/inputcec.h @@ -27,7 +27,7 @@ class InputCEC : public Input { public: - int init(); + bool init(); void shutdown(); bool handlesVolume() { return cechandlesvolume; }; @@ -41,6 +41,9 @@ class InputCEC : public Input bool addOptionsToPanes(int panenumber,Options *options,WOptionPane* pane); bool handleOptionChanges(Option* option); + std::string getHardwareKeyName(int hardwareKey); + const char* getHardCodedHardwareKeyNamesForVompKey(UCHAR vompKey); + private: void InitKeymap(); void InitHWCListwithDefaults(); diff --git a/inputlinux.cc b/inputlinux.cc index c4a0bad..f7083d7 100644 --- a/inputlinux.cc +++ b/inputlinux.cc @@ -17,6 +17,7 @@ along with VOMP. If not, see . */ +#include #include #include #include @@ -31,17 +32,14 @@ #include "i18n.h" #include "vdr.h" #include "woptionpane.h" -#include "message.h" -#include "messagequeue.h" -#include "command.h" // FIXME - get rid after predefined message targets #include "inputlinux.h" #define test_bit(input,b) ((1 << ((b) % 8))&(input)[b / 8] ) -int InputLinux::init() +bool InputLinux::init() { - if (initted) return 0; + if (initted) return false; initted = 1; InitHWCListwithDefaults(); @@ -86,7 +84,7 @@ int InputLinux::init() } } } - return 1; + return true; } void InputLinux::shutdown() @@ -463,17 +461,47 @@ void InputLinux::InitKeymap() NAMETRICK(KEY_,NUMERIC_POUND); } -char* InputLinux::HCWDesc(unsigned long long hcw) +const char* InputLinux::getHardCodedHardwareKeyNamesForVompKey(UCHAR vompKey) +{ + switch (vompKey) + { + case DOWN: + return tr("Down"); + case UP: + return tr("Up"); + case LEFT: + return tr("Left"); + case RIGHT: + return tr("Right"); + case MENU: + return tr("M"); + case BACK: + return tr("Backspace, Back"); + case OK: + return tr("Return, Space"); + default: + return ""; + } +} + +std::string InputLinux::getHardwareKeyName(int hardwareKey) { - unsigned int vk = static_cast(hcw); // FIXME - char* rt = new char[10]; - const char* desc = linux_keymap[vk]; + const char* desc = linux_keymap[hardwareKey]; + + std::string retval; + if (desc) - strncpy(rt, desc, 9); + { + retval = desc; + } else - sprintf(rt, "0x%x", vk); + { + char* rt = new char[10]; + sprintf(rt, "0x%x", hardwareKey); + retval = rt; + } - return rt; + return retval; } bool InputLinux::start() @@ -564,14 +592,7 @@ void InputLinux::listenLoop() { if (ev.type == EV_KEY && ev.value == 1) { - // Send INPUT message - Message* m = new Message(); - m->message = Message::INPUT_EVENT; - m->to = Command::getInstance(); - m->from = this; -// m->parameter = static_cast(TranslateHWC_KC(ev.code)); - m->parameter = TranslateHWC(ev.code); - MessageQueue::getInstance()->postMessage(m); + sendInputKey(TranslateHWC(ev.code)); } } } diff --git a/inputlinux.h b/inputlinux.h index 3d8d51d..5cbfe86 100644 --- a/inputlinux.h +++ b/inputlinux.h @@ -20,8 +20,10 @@ #ifndef INPUTLINUX_H #define INPUTLINUX_H -#include +#include #include +#include +#include #include "defines.h" #include "input.h" @@ -29,10 +31,11 @@ class InputLinux : public Input { public: - int init(); + bool init(); void shutdown(); - char* HCWDesc(ULLONG hcw); + std::string getHardwareKeyName(int hardwareKey); + const char* getHardCodedHardwareKeyNamesForVompKey(UCHAR vompKey); bool start(); void stop(); @@ -44,6 +47,7 @@ class InputLinux : public Input void InitHWCListwithDefaults(); UCHAR TranslateHWCFixed(int code); + std::vector devices; std::thread listenThread; @@ -54,3 +58,5 @@ class InputLinux : public Input }; #endif + +// FIXME remove all ULLONG for hwc diff --git a/inputman.cc b/inputman.cc index 752b017..edbf4bd 100644 --- a/inputman.cc +++ b/inputman.cc @@ -22,6 +22,7 @@ #include "wtabbar.h" #include "inputlinux.h" #include "inputcec.h" +#include "inputudp.h" #include "i18n.h" #include "input.h" @@ -46,7 +47,7 @@ InputMan* InputMan::getInstance() bool InputMan::init() { - bool i1{}, i2{}; + bool i1{}, i2{}, i3{}; #ifdef VOMP_PLATFORM_RASPBERRY inputLinux = new InputLinux(); @@ -58,7 +59,12 @@ bool InputMan::init() // if (!i2) { delete inputCEC; inputCEC = NULL; } #endif - if (!i1 && !i2) + inputUDP = new InputUDP(); + i3 = inputUDP->init(); + if (!i3) { delete inputUDP; inputUDP = NULL; } + + + if (!i1 && !i2 && !i3) { Log::getInstance()->log("InputMan", Log::CRIT, "InputMan could not init any input module"); return false; @@ -70,19 +76,27 @@ bool InputMan::init() bool InputMan::start() { - bool i1{}; + Log::getInstance()->log("InputMan", Log::DEBUG, "Start"); + + bool i1{}, i3{}; if (inputLinux) { i1 = inputLinux->start(); } + if (inputUDP) + { + i3 = inputUDP->start(); + } + return i1; } void InputMan::stop() { if (inputLinux) inputLinux->stop(); + if (inputUDP) inputUDP->stop(); } void InputMan::shutdown() @@ -106,6 +120,15 @@ void InputMan::shutdown() inputCEC = NULL; } + if (inputUDP) + { + Log::getInstance()->log("InputMan", Log::DEBUG, "Shutdown start - UDP"); + inputUDP->stop(); + inputUDP->shutdown(); + delete inputUDP; + inputUDP = NULL; + } + initted = false; } @@ -170,7 +193,7 @@ bool InputMan::saveOptionstoServer() return true; // FIXME } -const char* InputMan::CommandDesc(UCHAR number) +const char* InputMan::getVompKeyName(UCHAR number) { switch (number) { @@ -273,3 +296,57 @@ const char* InputMan::CommandDesc(UCHAR number) return NULL; } } + +std::string InputMan::getHardCodedHardwareKeyNamesForVompKey(UCHAR vompKey) +{ + // Go through each active Input class and get the hardware key name for vompKey + + // which doesn't make any sense + + std::string keyNames; + + if (inputLinux) + { + std::string k = inputLinux->getHardCodedHardwareKeyNamesForVompKey(vompKey); + if (k.size()) keyNames += k; + } + + if (inputCEC) + { + std::string k = inputCEC->getHardCodedHardwareKeyNamesForVompKey(vompKey); + if (k.size()) { keyNames += ", "; keyNames += k; } + } + + if (inputUDP) + { + std::string k = inputUDP->getHardCodedHardwareKeyNamesForVompKey(vompKey); + if (k.size()) { keyNames += ", "; keyNames += k; } + } + + return keyNames; +} + +std::string InputMan::getAllHardwareKeyNamesAssignedToVompKey(UCHAR vompKey) +{ + std::string keyNames; + + if (inputLinux) + { + std::string k = inputLinux->getAllHardwareKeyNamesAssignedToVompKey(vompKey); + if (k.size()) keyNames += k; + } + + if (inputCEC) + { + std::string k = inputCEC->getAllHardwareKeyNamesAssignedToVompKey(vompKey); + if (k.size()) { keyNames += ", "; keyNames += k; } + } + + if (inputUDP) + { + std::string k = inputUDP->getAllHardwareKeyNamesAssignedToVompKey(vompKey); + if (k.size()) { keyNames += ", "; keyNames += k; } + } + + return keyNames; +} diff --git a/inputman.h b/inputman.h index de89dee..1086bf2 100644 --- a/inputman.h +++ b/inputman.h @@ -76,6 +76,8 @@ For now, two decisions to make things a bit easier: */ +#include + #include "defines.h" #include "abstractoption.h" @@ -111,7 +113,10 @@ class InputMan: public AbstractOption bool addOptionsToPanes(int panenumber, Options* options, WOptionPane* pane); bool saveOptionstoServer(); - static const char* CommandDesc(UCHAR number); + static const char* getVompKeyName(UCHAR vompKey); + + std::string getHardCodedHardwareKeyNamesForVompKey(UCHAR vompKey); + std::string getAllHardwareKeyNamesAssignedToVompKey(UCHAR vompKey); private: static InputMan* instance; diff --git a/udp.cc b/inputudp.cc similarity index 81% rename from udp.cc rename to inputudp.cc index 70b1364..9e29906 100644 --- a/udp.cc +++ b/inputudp.cc @@ -1,5 +1,5 @@ /* - Copyright 2006 Chris Tallon + Copyright 2006-2020 Chris Tallon This file is part of VOMP. @@ -17,97 +17,107 @@ along with VOMP. If not, see . */ -#include "udp.h" +#include +#include #include "dsock.h" -#include "messagequeue.h" -#include "message.h" #include "log.h" -#include "command.h" -//void dump(unsigned char* data, USHORT size); -//unsigned char dcc(UCHAR c); +#include "inputudp.h" -UDP::UDP() +bool InputUDP::init() { + if (initted) return false; + initted = true; log = Log::getInstance(); - initted = 0; -} + log->log("InputUDP", Log::DEBUG, "Starting InputUDP command server"); -UDP::~UDP() -{ - shutdown(); + ds = new DatagramSocket(2000); + if (!ds->init()) + { + log->log("InputUDP", Log::DEBUG, "DSock init error"); + delete ds; + initted = false; + return false; + } + + if (pipe2(pfds, O_NONBLOCK) == -1) + { + Log::getInstance()->log("InputUDP", Log::ERR, "pipe2() fail"); + ds->shutdown(); + delete ds; + initted = false; + return false; + } + + return true; } -int UDP::shutdown() +void InputUDP::shutdown() { - if (!initted) return 1; - if (threadIsActive()) threadCancel(); ds->shutdown(); delete ds; - initted = 0; - return 1; + close(pfds[1]); + close(pfds[0]); + + initted = false; } -int UDP::run(MessageQueue* tMessageQueue) +bool InputUDP::start() { - if (threadIsActive()) return 1; - log->log("UDP", Log::DEBUG, "Starting UDP command server"); + threadStartProtect.lock(); // Make sure listenThread is fully initted before start returns + listenThread = std::thread( [this] + { + threadStartProtect.lock(); + threadStartProtect.unlock(); + listenLoop(); + }); + threadStartProtect.unlock(); - initted = 1; + log->log("InputUDP", Log::DEBUG, "InputUDP command server started"); + return true; +} - messageQueue = tMessageQueue; - ds = new DatagramSocket(2000); +void InputUDP::stop() +{ + std::lock_guard lg(threadStartProtect); // Also use it to protect against starting while stopping - if (!ds->init()) - { - log->log("UDP", Log::DEBUG, "DSock init error"); - shutdown(); - return 0; - } + if (!initted) return; - if (!threadStart()) + if (listenThread.joinable()) { - log->log("UDP", Log::DEBUG, "Thread start error"); - shutdown(); - return 0; + write(pfds[1], "1", 1); // break the select in listenLoop + listenThread.join(); } - - log->log("UDP", Log::DEBUG, "UDP command server started"); - return 1; } -void UDP::threadMethod() +void InputUDP::listenLoop() { - threadSetKillable(); - int retval; while(1) { - retval = ds->waitforMessage(1); + retval = ds->waitforMessage(3, pfds[0]); - if (retval == 0) + if (retval == 2) { - log->log("UDP", Log::CRIT, "Wait for packet error"); - return; + processRequest(ds->getData(), ds->getDataLength()); } - else if (retval == 1) + else if (retval == 3) // quit { - threadCheckExit(); - continue; + break; } else { - processRequest(ds->getData(), ds->getDataLength()); + log->log("InputUDP", Log::CRIT, "Wait for packet error"); + return; } - threadCheckExit(); } } -void UDP::processRequest(const void* data, UINT length) +void InputUDP::processRequest(const void* data, UINT length) { - log->log("UDP", Log::DEBUG, "Got request"); + log->log("InputUDP", Log::DEBUG, "Got request"); char* temp = new char[length + 1]; memcpy(temp, data, length); @@ -115,17 +125,31 @@ void UDP::processRequest(const void* data, UINT length) UINT command = static_cast(atoi(temp)); delete[] temp; - log->log("UDP", Log::DEBUG, "Command %i recieved", command); + log->log("InputUDP", Log::DEBUG, "Command %i recieved", command); + sendInputKey(command); +} +const char* InputUDP::getHardCodedHardwareKeyNamesForVompKey(UCHAR vompKey) +{ + return ""; +} - Message *m = new Message(); - m->to = Command::getInstance(); - m->message = Message::UDP_BUTTON; - m->parameter = command; - messageQueue->postMessage(m); +std::string InputUDP::getHardwareKeyName(int hardwareKey) +{ + std::string retval; + return retval; } + + + + + /* + +//void dump(unsigned char* data, USHORT size); +//unsigned char dcc(UCHAR c); + void dump(unsigned char* data, USHORT size) { printf("Size = %u\n", size); diff --git a/udp.h b/inputudp.h similarity index 56% rename from udp.h rename to inputudp.h index a14156e..1b634a0 100644 --- a/udp.h +++ b/inputudp.h @@ -17,40 +17,47 @@ along with VOMP. If not, see . */ -#ifndef UDP_H -#define UDP_H +#ifndef INPUTUDP_H +#define INPUTUDP_H -#include -#include -#include +#include +#include +#include #include "defines.h" - -#include "threadsystem.h" +#include "input.h" class DatagramSocket; -class MessageQueue; class Log; -class UDP : public Thread_TYPE +class InputUDP : public Input { public: - UDP(); - virtual ~UDP(); + bool init(); + void shutdown(); + + bool start(); + void stop(); + + // FIXME these 2.. + void InitHWCListwithDefaults() {}; + UCHAR TranslateHWCFixed(int code) { return code; }; + const char* getHardCodedHardwareKeyNamesForVompKey(UCHAR vompKey); + std::string getHardwareKeyName(int hardwareKey); - int run(MessageQueue* messageQueue); - int shutdown(); private: - void threadPostStopCleanup() {}; + bool initted{}; + DatagramSocket* ds{}; + Log* log{}; - void threadMethod(); - void processRequest(const void* data, UINT length); + std::thread listenThread; + std::mutex threadStartProtect; + void listenLoop(); + bool listenLoopStop{}; + int pfds[2]; - int initted; - DatagramSocket* ds; - MessageQueue* messageQueue; - Log* log; + void processRequest(const void* data, UINT length); }; #endif diff --git a/message.h b/message.h index 052c515..91e20f5 100644 --- a/message.h +++ b/message.h @@ -62,7 +62,6 @@ class Message const static ULONG CHANGED_OPTIONS = 18; const static ULONG CONNECTION_LOST = 19; const static ULONG MOVE_RECORDING = 20; - const static ULONG UDP_BUTTON = 21; const static ULONG PLAYER_EVENT = 22; const static ULONG AUDIO_CHANGE_CHANNEL = 23; const static ULONG CHILD_CLOSE = 24; diff --git a/objects.mk b/objects.mk index 6c80695..a209ca1 100644 --- a/objects.mk +++ b/objects.mk @@ -1,8 +1,8 @@ OBJ_COMMON = command.o tcp.o dsock.o thread.o timers.o i18n.o vdp6.o \ - message.o messagequeue.o udp.o wol.o audio.o video.o log.o mutex.o \ + message.o messagequeue.o wol.o audio.o video.o log.o mutex.o \ vdr.o recman.o recording.o recinfo.o channel.o rectimer.o event.o \ directory.o mark.o option.o player.o playerradio.o vfeed.o afeed.o \ - demuxer.o demuxervdr.o demuxerts.o stream.o inputman.o \ + demuxer.o demuxervdr.o demuxerts.o stream.o osd.o surface.o \ region.o colour.o boxstack.o boxx.o tbboxx.o vrecording.o \ vinfo.o vquestion.o vrecordinglist.o vrecordinglistclassic.o \ vrecordinglistadvanced.o vepgsummary.o vepglistadvanced.o \ @@ -12,7 +12,7 @@ OBJ_COMMON = command.o tcp.o dsock.o thread.o timers.o i18n.o vdp6.o vradiorec.o vaudioselector.o vscreensaver.o vopts.o \ wselectlist.o wjpeg.o wsymbol.o wbutton.o wtextbox.o \ woptionpane.o woptionbox.o wremoteconfig.o wtabbar.o led.o \ - input.o osd.o surface.o vpicturebanner.o abstractoption.o \ + inputman.o input.o inputudp.o vpicturebanner.o abstractoption.o \ eventdispatcher.o vdrrequestpacket.o vdrresponsepacket.o \ vvideolivetv.o vsleeptimer.o playerlivetv.o playerliveradio.o \ wprogressbar.o bitmap.o dvbsubtitles.o tfeed.o vteletextview.o \ @@ -24,7 +24,7 @@ OBJ_RASPBERRY = main.o threadp.o osdopenvg.o ledraspberry.o videoomx.o audioomx.o imageomx.o \ wjpegsimple.o inputlinux.o inputcec.o signal.o -OBJ_WINDOWS = winmain.o threadwin.o remotewin.o ledwin.o videowin.o \ +OBJ_WINDOWS = winmain.o threadwin.o inputwin.o ledwin.o videowin.o \ audiowin.o windowsosd.o dsallocator.o dssourcefilter.o dssourcepin.o \ wwinvideofilter.o wwinvideoh264filter.o wwinaudiofilter.o \ wwinmp3audiofilter.o wjpegsimple.o diff --git a/videoomx.cc b/videoomx.cc index 54862a2..8f90ffe 100644 --- a/videoomx.cc +++ b/videoomx.cc @@ -85,6 +85,10 @@ int VideoOMX::init(UCHAR tformat) if (initted) return 0; initted = 1; + // libcec calls bcm_host_init() - but in case CEC is disabled call it here as well. + // Seems safe to call it more than once. + bcm_host_init(); + int ret=vc_gencmd_send("codec_enabled MPG2"); if (ret!=0) { Log::getInstance()->log("Video", Log::DEBUG, "vc_gencmd_send failed %x",ret); @@ -471,7 +475,7 @@ void VideoOMX::selectVideoMode(int interlaced) } } - InputMan::getInstance()->shutdown(); + // InputMan::getInstance()->shutdown(); FIXME FIXME FIXME - disabling this temp, why does this have to run? vc_tv_power_off(); if (mymode) { Log::getInstance()->log("Video", Log::NOTICE, "Switch to optimum mode"); @@ -489,8 +493,7 @@ void VideoOMX::selectVideoMode(int interlaced) } else { /* analog tv case */ Log::getInstance()->log("Video", Log::NOTICE, "Analog tv case"); - InputMan::getInstance()->shutdown(); - vc_tv_power_off(); + // InputMan::getInstance()->shutdown(); FIXME FIXME FIXME - disabling this temp, why does this have to run? vc_tv_power_off(); SDTV_MODE_T setmode=SDTV_MODE_PAL; SDTV_OPTIONS_T options; @@ -515,7 +518,7 @@ void VideoOMX::selectVideoMode(int interlaced) hdmi=false; } - InputMan::getInstance()->init(); // FIXME complete shutdown and reinit maybe heavy handed. +// InputMan::getInstance()->init(); // FIXME complete shutdown and reinit maybe heavy handed. FIXME FIXME FIXME - disabled temp // If this was just to reinit CEC then funcitons should be made to do that diff --git a/vsleeptimer.cc b/vsleeptimer.cc index 826e33d..45136a8 100644 --- a/vsleeptimer.cc +++ b/vsleeptimer.cc @@ -168,11 +168,11 @@ void Sleeptimer::threadMethod() if (sec == -1) { - Message* m2 = new Message(); // Delete self - m2->message = Message::UDP_BUTTON; + Message* m2 = new Message(); + m2->message = Message::INPUT_EVENT; m2->to = Command::getInstance(); m2->from = this; - m2->parameter = 61; // FIXME use constant name when they're sorted out + m2->parameter = Input::POWER; MessageQueue::getInstance()->postMessage(m2); shutdown(); } @@ -291,7 +291,7 @@ void VCountdown::drawClock(const char* sec) Timers::getInstance()->setTimerD(this, 1, 1); } -void VCountdown::timercall(int clientReference) +void VCountdown::timercall(int /* clientReference */) { // delete me! Message* m = new Message(); // Delete self diff --git a/wremoteconfig.cc b/wremoteconfig.cc index b84dd40..1340a24 100644 --- a/wremoteconfig.cc +++ b/wremoteconfig.cc @@ -1,5 +1,5 @@ /* - Copyright 2007 Chris Tallon, Marten Richter + Copyright 2007-2020 Chris Tallon, Marten Richter This file is part of VOMP. @@ -17,14 +17,18 @@ along with VOMP. If not, see . */ -#include "wremoteconfig.h" +#include +#include "log.h" #include "input.h" #include "inputman.h" #include "wsymbol.h" #include "colour.h" #include "i18n.h" #include "boxstack.h" +#include "wremoteconfig.h" + + WRemoteConfig::WRemoteConfig() { @@ -44,6 +48,8 @@ WRemoteConfig::~WRemoteConfig() void WRemoteConfig::initSelectList(bool startup) { + InputMan* inputMan = InputMan::getInstance(); + ULONG selection = 0; ULONG top = 0; @@ -58,19 +64,27 @@ void WRemoteConfig::initSelectList(bool startup) sl.addColumn(150); sl.addColumn(300); - ULONG i; - for (i = 0; i < 256; i++) + for (UINT i = 0; i < 256; i++) { - const char * name = InputMan::CommandDesc((UCHAR)i); - if (name != NULL) + Log::getInstance()->log("WRemoteConfig", Log::DEBUG, "%u", i); + const char* vompKeyName = InputMan::getVompKeyName(static_cast(i)); + if (vompKeyName != NULL) { - //char *line = remote->CommandTranslateStr((UCHAR)i); - - const char* line = "UNK,FIXME"; + std::string line; + line.reserve(150); + line += vompKeyName; + line += ":\t"; + Log::getInstance()->log("WRemoteConfig", Log::DEBUG, "A"); + line += inputMan->getHardCodedHardwareKeyNamesForVompKey(static_cast(i)); + line += '\t'; + Log::getInstance()->log("WRemoteConfig", Log::DEBUG, "B"); + line += inputMan->getAllHardwareKeyNamesAssignedToVompKey(static_cast(i)); + Log::getInstance()->log("WRemoteConfig", Log::DEBUG, "C"); - sl.addOption(line,i,0); + sl.addOption(line.c_str(), i, 0); } } + if (!startup) { sl.hintSetCurrent(selection); -- 2.39.2