]> git.vomp.tv Git - vompclient.git/commitdiff
WIP [broken]
authorChris Tallon <chris@vomp.tv>
Sat, 15 Feb 2020 15:16:37 +0000 (15:16 +0000)
committerChris Tallon <chris@vomp.tv>
Sat, 15 Feb 2020 15:16:37 +0000 (15:16 +0000)
44 files changed:
GNUmakefile
command.cc
command.h
defines.h
input.cc
input.h
inputcec.cc [new file with mode: 0644]
inputcec.h [new file with mode: 0644]
inputlinux.cc
inputlinux.h
inputman.cc [new file with mode: 0644]
inputman.h [new file with mode: 0644]
main.cc
objects.mk
vaudioselector.cc
vchannellist.cc
vepg.cc
vepglistadvanced.cc
vepgsettimer.cc
videoomx.cc
vmedialist.cc
vmediaview.cc
vopts.cc
vquestion.cc
vrecmove.cc
vrecording.cc
vrecordinglist.cc
vrecordingmenu.cc
vserverselect.cc
vtimeredit.cc
vtimerlist.cc
vvideolivetv.cc
vvolume.cc
vwelcome.cc
woptionpane.cc
wpictureview.cc
wremoteconfig.cc
wremoteconfig.h
wtabbar.cc
wtextbox.cc
wwinaudiofilter.cc
wwinmp3audiofilter.cc
wwinvideofilter.cc
wwinvideoh264filter.cc

index 82382801a1c3a89709fa3dd342a569f905bbfc41..bec58645ea8f10efaacd6e89d63b11dbbf04ea71 100644 (file)
@@ -52,8 +52,10 @@ LD=g++
 #CXX=clang++-9
 #LD=clang++-9
 
-vomp_options += -DIPV6
 LDFLAGS = -fuse-ld=gold $(PICTURES)
+#-fuse-ld=gold
+
+vomp_options += -DIPV6
 LIBPATHS = -L/opt/vc/lib -L/usr/lib/arm-linux-gnueabihf
 LIBS = -lpthread -lrt -lbrcmEGL -lbrcmOpenVG -lopenmaxil -lbcm_host -lavformat -lavcodec -lavutil -lavresample
 LIBS += -ldl -lfontconfig -lfreetype -lMagick++-6.Q16
index edf09749486f20d72e4fd1ce74ca5c6c0bbe0606..39b54c5d185c91011712bb6b06352cb59a507b37 100644 (file)
     along with VOMP.  If not, see <https://www.gnu.org/licenses/>.
 */
 
+// FIXME rename to Control and move stuff from main to here
+
+
 #include "command.h"
 
 #ifdef WIN32
-#include "remotewin.h"
+#include "inputManwin.h"
 #endif
 
 #ifdef __ANDROID__
-#include "remoteandroid.h"
+#include "inputManandroid.h"
 #endif
 
 #include "led.h"
@@ -43,6 +46,7 @@
 #include "wol.h"
 #include "vconnect.h"
 #include "message.h"
+#include "inputman.h"
 #include "input.h"
 #include "vinfo.h"
 #include "boxx.h"
@@ -63,6 +67,7 @@ Command::Command()
 
 Command::~Command()
 {
+  flushMessageQueue();
   instance = NULL;
 }
 
@@ -80,11 +85,9 @@ int Command::init(bool tcrashed, char* tServer)
 
   logger = Log::getInstance();
   boxstack = BoxStack::getInstance();
-  remote = Input::getInstance();
+  inputMan = InputMan::getInstance();
   
-  remote->InitHWCListwithDefaults();
-  
-  if (!logger || !boxstack || !remote)
+  if (!logger || !boxstack || !inputMan)
   {
     initted = false;
     return 0;
@@ -186,16 +189,16 @@ void Command::run()
     vconnect->run();
   }
 
-  // Start remote thread loop
-  remote->start();
-
-  // Start method 2 of getting commands in...
-  udp.run(this);
 
   // FIXME Input::NA_SIGNAL is possibly obsolete now
 
   std::unique_lock<std::mutex> lockWrapper(messageQueueMutex);  // locks. unlocks on out-of-scope
 
+  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(); });
@@ -217,7 +220,7 @@ void Command::run()
     }
   }
 
-  remote->stop();
+  inputMan->stop();
 
   boxstack->removeAllExceptWallpaper();
   boxstack->remove(wallpaper);
@@ -352,17 +355,15 @@ void Command::handleCommand(int button)
 
   switch(button)
   {
-    case Input::DF_LEFT:
-    case Input::DF_RIGHT:
     case Input::VOLUMEUP:
     case Input::VOLUMEDOWN:
     {
-      if (remote->handlesVolume())
+      if (inputMan->handlesVolume()) // CEC volume handler?
       {
-        if (button==Input::DF_LEFT || button==Input::VOLUMEDOWN)
-          remote->volumeDown();
+        if (button == Input::VOLUMEDOWN)
+          inputMan->volumeDown();
         else
-          remote->volumeUp();
+          inputMan->volumeUp();
       }
       else
       {
@@ -374,9 +375,9 @@ void Command::handleCommand(int button)
     }
     case Input::MUTE:
     {
-      if (remote->handlesVolume())
+      if (inputMan->handlesVolume())
       {
-        remote->volumeMute();
+        inputMan->volumeMute();
       }
       else
       {
@@ -448,7 +449,7 @@ void Command::doPowerOn()
   {
     Video::getInstance()->signalOn();
     Led::getInstance()->on();
-    Input::getInstance()->changePowerState(true);
+    InputMan::getInstance()->changePowerState(true);
     isStandby = false;
 
     VConnect* vconnect = new VConnect(server);
@@ -470,7 +471,7 @@ void Command::doPowerOff()
     logger->unsetExternLogger();
     VDR::getInstance()->disconnect();
     Led::getInstance()->off();
-    Input::getInstance()->changePowerState(false);
+    InputMan::getInstance()->changePowerState(false);
     isStandby = true;
     Sleeptimer::getInstance()->shutdown();
 #ifdef WIN32
@@ -545,7 +546,7 @@ void Command::doReboot()
   Osd::getInstance()->shutdown();
   Audio::getInstance()->shutdown();
   Video::getInstance()->shutdown();
-  Input::getInstance()->shutdown();
+  InputMan::getInstance()->shutdown();
 
   reboot(LINUX_REBOOT_CMD_RESTART);
   // if  reboot is not allowed -> stop
@@ -726,8 +727,8 @@ void Command::doJustConnected(VConnect* vconnect)
 #endif
       video->shutdown();
 
-      remote->shutdown(); // need on raspberry shut not do any harm, hopefully
-      remote->init(RemoteStartDev);
+      inputMan->shutdown(); // need on raspberry shut not do any harm, hopefully
+      inputMan->init(); // FIXME this breaks badly now
 
       // Get video and osd back up with the new mode
       if (!strcmp(config, "PAL"))
@@ -881,7 +882,7 @@ void Command::doJustConnected(VConnect* vconnect)
   {
     if (!STRCASECMP(config, "On"))
     {
-      logger->log("Command", Log::INFO, "Shutdown VDR when  shutting down vomp");
+      logger->log("Command", Log::INFO, "Shutdown VDR when shutting down vomp");
       vdr->setVDRShutdown(true);
     }
     else if (!STRCASECMP(config, "Off"))
@@ -896,32 +897,6 @@ void Command::doJustConnected(VConnect* vconnect)
     vdr->setVDRShutdown(false); // Default
   }
           
-  // Set remote type
-
-  config = vdr->configLoad("General", "Remote type");
-
-  if (config)
-  {
-    if (!STRCASECMP(config, "New"))
-    {
-      logger->log("Command", Log::INFO, "Switching to New remote type");
-      remote->setRemoteType(Input::NEWREMOTE);
-    }
-    else
-    {
-      logger->log("Command", Log::INFO, "Switching to Old remote type");
-      remote->setRemoteType(Input::OLDREMOTE);
-    }
-    delete[] config;
-  }
-  else
-  {
-    logger->log("Command", Log::INFO, "Config General/Remote type not found");
-    remote->setRemoteType(Input::OLDREMOTE);
-  }
-
-
-
   // Get TV aspect ratio
 
   config = vdr->configLoad("TV", "Aspect");
@@ -1046,7 +1021,7 @@ void Command::doJustConnected(VConnect* vconnect)
   /* device dependend config */
   audio->loadOptionsfromServer(vdr);
   video->loadOptionsfromServer(vdr);
-  remote->loadOptionsfromServer(vdr);
+  inputMan->loadOptionsfromServer(vdr);
 
   video->executePendingModeChanges();
   // config done
index 6ac4c50630a7580a1d5f6a6d19b3762ce25a3043..98fc0db19be49d01ec0f53c039ba8a31c063685d 100644 (file)
--- a/command.h
+++ b/command.h
@@ -40,7 +40,7 @@
 
 class VConnect;
 class Message;
-class Input;
+class InputMan;
 class Boxx;
 class BoxStack;
 class Log;
@@ -93,7 +93,7 @@ class Command : public MessageQueue
 
     Log* logger;
     BoxStack* boxstack;
-    Input* remote;
+    InputMan* inputMan;
 
     bool initted{};
     bool irun{};
index 720d2af16c2f9aa1ce8feb46c2ae356b48eefb2d..a19cbe1a1d1d62610a63061014e01cf5f88ca207 100644 (file)
--- a/defines.h
+++ b/defines.h
@@ -153,7 +153,7 @@ int getClockRealTime(struct timespec *tp);
   #define VOMP_LINUX_CLOCK  CLOCK_MONOTONIC
 
 #endif
-#ifdef VOMP_PLATTFORM_MVP
+#ifdef VOMP_PLATTFORM_MVP                   // FIXME OBSOLETE
   #define Remote_TYPE RemoteMVP
   #define RemoteStartDev "/dev/rawir"
   #define Led_TYPE
index 0e0e947ec7c8354c62d5e12ffbe6e0bdadf6e34a..a41795e43f8e5d2b3e2b3dc01842dec9df47841a 100644 (file)
--- a/input.cc
+++ b/input.cc
 #include "log.h"
 #include "vdr.h"
 #include "wtabbar.h"
+#include "inputman.h"
 #include "input.h"
 
-Input* Input::instance = NULL;
-
 Input::Input()
 {
-  if (instance) return;
-  instance = this;
-  remoteType = OLDREMOTE;
   learnmode = NOLEARNMODE;
 }
 
 Input::~Input()
 {
-  instance = NULL;
-}
-
-Input* Input::getInstance()
-{
-  return instance;
-}
-
-void Input::setRemoteType(UCHAR newType)
-{
-  if ((newType != OLDREMOTE) && (newType != NEWREMOTE)) return;
-  remoteType = newType;
 }
 
 void Input::EnterLearningMode(UCHAR command)
@@ -61,7 +45,7 @@ void Input::ResetToDefault()
   InitHWCListwithDefaults();
 }
 
-
+/*
 UCHAR Input::TranslateHWCFixed(ULLONG code)
 {
   switch (code)
@@ -74,14 +58,6 @@ UCHAR Input::TranslateHWCFixed(ULLONG code)
       return LEFT;
     case RIGHT:
       return RIGHT;
-    case DF_DOWN:
-      return DOWN;
-    case DF_UP:
-      return UP;
-    case DF_LEFT:
-      return LEFT;
-    case DF_RIGHT:
-      return RIGHT;
     case MENU:
       return MENU;
     case BACK:
@@ -92,6 +68,7 @@ UCHAR Input::TranslateHWCFixed(ULLONG code)
       return NA_UNKNOWN;
   }
 }
+*/
 
 const char* Input::HardcodedTranslateStr(UCHAR command)
 {
@@ -116,7 +93,7 @@ const char* Input::HardcodedTranslateStr(UCHAR command)
   }
 }
 
-UCHAR Input::TranslateHWCList(ULLONG code)
+UCHAR Input::TranslateHWCList(int code)
 {
   if (learnmode != NOLEARNMODE)
   {
@@ -135,7 +112,7 @@ UCHAR Input::TranslateHWCList(ULLONG code)
   }
 }
 
-UCHAR Input::TranslateHWC(ULLONG code)
+UCHAR Input::TranslateHWC(int code)
 {
   UCHAR ret = TranslateHWCFixed(code);
   if (ret == NA_UNKNOWN)
@@ -203,166 +180,10 @@ void Input::SaveKeysConfig()
   VDR::getInstance()->configSave("General","RemoteKeyNum",buffer);
 }
 
-
-void Input::InitHWCListwithDefaults()
-{
-  translist[VOLUMEUP] = VOLUMEUP;
-  translist[VOLUMEDOWN] = VOLUMEDOWN;
-  translist[CHANNELUP] = CHANNELUP;
-  translist[CHANNELDOWN] = CHANNELDOWN;
-
-  // Common buttons
-  translist[ZERO] = ZERO;
-  translist[ONE] = ONE;
-  translist[TWO] = TWO;
-  translist[THREE] = THREE;
-  translist[FOUR] = FOUR;
-  translist[FIVE] = FIVE;
-  translist[SIX] = SIX;
-  translist[SEVEN] = SEVEN;
-  translist[EIGHT] = EIGHT;
-  translist[NINE] = NINE;
-  translist[POWER] = POWER;
-  translist[GO] = GO;
-  translist[RED] = RED;
-  translist[GREEN] = GREEN;
-  translist[YELLOW] = YELLOW;
-  translist[BLUE] = BLUE;
-
-  translist[MUTE] = MUTE;
-  translist[RADIO] = RADIO;
-  translist[REVERSE] = REVERSE;
-  translist[FORWARD] = FORWARD;
-  translist[RECORD] = RECORD;
-  translist[STOP] = STOP;
-  translist[PAUSE] = PAUSE;
-  translist[PLAY] = PLAY;
-  translist[SKIPBACK] = SKIPBACK;
-  translist[SKIPFORWARD] = SKIPFORWARD;
-
-  // Old remote only
-  translist[FULL] = FULL;
-
-  // New remote only
-  translist[TV] = TV;
-  translist[VIDEOS] = VIDEOS;
-  translist[MUSIC] = MUSIC;
-  translist[PICTURES] = PICTURES;
-  translist[GUIDE] = GUIDE;
-  translist[PREVCHANNEL] = PREVCHANNEL;
-  translist[STAR] = STAR;
-  translist[HASH] = HASH;
-}
-
-const char* Input::CommandDesc(UCHAR number)
-{
-  switch (number)
-  {
-    case VOLUMEUP:
-      return tr("Volume Up");
-
-    case VOLUMEDOWN:
-      return tr("Volume Down");
-    case CHANNELUP:
-      return tr("Channel up");
-    case CHANNELDOWN:
-      return tr("Channel down");
-    case ZERO:
-      return "0";
-    case ONE:
-      return "1";
-    case TWO:
-      return "2";
-    case THREE:
-      return "3";
-    case FOUR:
-      return "4";
-    case FIVE:
-      return "5";
-    case SIX:
-      return "6";
-    case SEVEN:
-      return "7";
-    case EIGHT:
-      return "8";
-    case NINE:
-      return "9";
-    case POWER:
-      return tr("Power");
-    case GO:
-      return tr("Go");
-    case BACK:
-      return tr("Back");
-    case MENU:
-      return tr("Menu");
-    case RED:
-      return tr("Red");
-    case GREEN:
-      return tr("Green");
-    case YELLOW:
-      return tr("Yellow");
-    case BLUE:
-      return tr("Blue");
-    case MUTE:
-      return tr("Mute");
-    case RADIO:
-      return tr("Radio");
-    case REVERSE:
-      return tr("Reverse");
-    case PLAY:
-      return tr("Play");
-    case FORWARD:
-      return tr("Forward");
-    case RECORD:
-      return tr("Record");
-    case STOP:
-      return tr("Stop");
-    case PAUSE:
-      return tr("Pause");
-    case SKIPBACK:
-      return tr("Skip back");
-    case SKIPFORWARD:
-      return tr("Skip forward");
-    case OK:
-      return tr("Ok");
-    case FULL:
-      return tr("Fullscreen");
-    case TV:
-      return tr("TV");
-    case VIDEOS:
-      return tr("Videos");
-    case MUSIC:
-      return tr("Music");
-    case PICTURES:
-      return tr("Pictures");
-    case GUIDE:
-      return tr("Guide");
-    case UP:
-      return tr("Up");
-    case DOWN:
-      return tr("Down");
-    case LEFT:
-      return tr("Left");
-    case RIGHT:
-      return tr("Right");
-    case PREVCHANNEL:
-      return tr("Previous Channel");
-    case STAR:
-      return tr("Star");
-    case HASH:
-      return tr("Hash");
-    case PLAYPAUSE:
-       return tr("Play/Pause");
-
-    default:
-      return NULL;
-  }
-}
-
 char* Input::HCWDesc(ULLONG hcw)
 {
-  char *dest,*temp;
-  temp=(char*)CommandDesc((UCHAR)hcw);
+  char *dest;
+  const char* temp = InputMan::CommandDesc((UCHAR)hcw);
   if (temp != NULL)
   {
     dest=new char[strlen(temp)+1];
@@ -378,21 +199,17 @@ char* Input::HCWDesc(ULLONG hcw)
 
 char* Input::CommandTranslateStr(UCHAR command)
 {
-  char *desc;
-  int length=5;//:+\t+0
-  int keys=0; //max 10;
-  char *commanddesc=(char*)CommandDesc(command);
-  if (commanddesc != NULL)
-  {
-    length+=strlen(commanddesc);
-  }
-  char *preassigneddesc=(char*)HardcodedTranslateStr(command);
-  if (preassigneddesc != NULL)
-  {
-    length+=strlen(preassigneddesc);
-  }
+  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];
+  char* keydesc[10];
+  int keys = 0; // max 10
   RemoteTranslationList::const_iterator it;
   for (it = translist.begin(); it != translist.end(); it++)
   {
@@ -400,43 +217,46 @@ char* Input::CommandTranslateStr(UCHAR command)
     {
       keydesc[keys] = HCWDesc(it->first);
       length += strlen(keydesc[keys])+2;
-      keys ++;
+      keys++;
       if (keys == 10) break;
     }
   }
 
-  desc=new char [length];
-  char *current=desc;
+  desc = new char[length];
+  char* current = desc;
   if (commanddesc != NULL)
   {
-    current+=sprintf(current,"%s:\t ",commanddesc);
+    current += sprintf(current, "%s:\t ", commanddesc);
   }
   else
   {
-    current+=sprintf(current,":\t ");
+    current += sprintf(current,":\t ");
   }
+
   if (preassigneddesc != NULL)
   {
-    current+=sprintf(current,"%s\t",preassigneddesc);
+    current += sprintf(current, "%s\t", preassigneddesc);
   }
   else
   {
     current+=sprintf(current,"\t");
   }
-  for (int i = 0;i < keys; i++)
+
+  for (int i = 0; i < keys; i++)
   {
-    current += sprintf(current,"%s, ",keydesc[i]);
-    delete [] keydesc[i];
+    current += sprintf(current, "%s, ", keydesc[i]);
+    delete[] keydesc[i];
   }
+
   return desc;
 }
 
-bool Input::addOptionPagesToWTB(WTabBar *wtb)
-{
-    WRemoteConfig* wrc = new WRemoteConfig();
-    wtb->addTab(tr("Remote Control"), wrc);
-    return true;
-}
+// bool Input::addOptionPagesToWTB(WTabBar *wtb)
+// {
+//     WRemoteConfig* wrc = new WRemoteConfig();
+//     wtb->addTab(tr("Remote Control"), wrc);
+//     return true;
+// }
 
 bool Input::loadOptionsfromServer(VDR* vdr)
 {
@@ -463,27 +283,3 @@ bool Input::saveOptionstoServer()
     SaveKeysConfig();
     return true;
 }
-
-bool Input::start()
-{
-  Log::getInstance()->log("Input", Log::INFO, "start called");
-
-  threadStartProtect.lock();
-  listenThread = std::thread( [this ]
-  {
-    threadStartProtect.lock();
-    threadStartProtect.unlock();
-    // FIXME block signals
-
-    eventLoop();
-  });
-  threadStartProtect.unlock();
-  return true;
-}
-
-void Input::stop()
-{
-  listenLoopStop = true;
-  informStopEventLoop();
-  listenThread.join();
-}
diff --git a/input.h b/input.h
index 169129a4d1aab59ca32471f8fa6f3ed56b469282..d25d917e2b0d0f78fe16366e38051413340d31db 100644 (file)
--- a/input.h
+++ b/input.h
 #include "defines.h"
 #include "abstractoption.h"
 
+// FIXME make common base class sendKey function
 
-typedef std::map<ULLONG,UCHAR> RemoteTranslationList;
+
+typedef std::map<ULLONG, UCHAR> RemoteTranslationList;
 
 class Input: public AbstractOption
 {
   public:
     Input();
     virtual ~Input();
-    static Input* getInstance();
 
-    bool start();
-    void stop();
+    virtual bool start() { return false; }
+    virtual void stop() {}
 
-    bool addOptionPagesToWTB(WTabBar *wtb);
-    bool loadOptionsfromServer(VDR* vdr);
-    bool saveOptionstoServer();
+    // Abstract Option interface
+ //   virtual bool addOptionPagesToWTB(WTabBar *wtb);
+    virtual bool loadOptionsfromServer(VDR* vdr);
+    virtual bool saveOptionstoServer();
 
-    void setRemoteType(UCHAR type);
-    void setHWCtoCommand(ULLONG hcw,UCHAR command);
+    void setHWCtoCommand(ULLONG hcw, UCHAR command);
     void unsetHWC(ULLONG hcw);
-    void LoadKeysConfig(VDR *vdr,const char*keynum);
+    void LoadKeysConfig(VDR* vdr, const char* keynum);
     void SaveKeysConfig();
     void EnterLearningMode(UCHAR command);
 
-    virtual int init(const char *devName)=0;
-    virtual int shutdown()=0;
-    virtual UCHAR getButtonPress(int how)=0; // DEPRECATED
-
-    virtual bool mayHaveFewButtons() {return false;};
+    virtual int init()=0;
+    virtual void shutdown()=0;
 
     virtual bool handlesVolume() {return false;};
     virtual void volumeUp() {};
     virtual void volumeDown() {};
     virtual void volumeMute() {};
+    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();
+    virtual void InitHWCListwithDefaults()=0;
     virtual char* HCWDesc(ULLONG hcw);
-    const char *CommandDesc(UCHAR number);
-    char *CommandTranslateStr(UCHAR command);
-    virtual const char*HardcodedTranslateStr(UCHAR command);
+    char* CommandTranslateStr(UCHAR command);
+    static const char* HardcodedTranslateStr(UCHAR command);
     void EnterLearnMode(UCHAR command);
     void ResetToDefault();
 
-    virtual void changePowerState(bool /* poweron */) {}; //informs the remote control, that about vomp's power state, this is important e.g. for cec
 
     const static ULONG NOLEARNMODE = 256;
     // Not buttons
@@ -79,10 +76,6 @@ class Input: public AbstractOption
     const static UCHAR NA_NONE     = 98;
     const static UCHAR NA_UNKNOWN  = 99;
     const static UCHAR NA_SIGNAL   = 100;
-    const static UCHAR DF_UP       = 94;
-    const static UCHAR DF_DOWN     = 95;
-    const static UCHAR DF_LEFT     = 96;
-    const static UCHAR DF_RIGHT    = 97;
 
     // Problem common buttons
     const static UCHAR VOLUMEUP    = 16;
@@ -144,34 +137,13 @@ class Input: public AbstractOption
     const static UCHAR POWERON     = 202;
     const static UCHAR POWEROFF    = 203;
 
-
-    // Remote types
-    const static UCHAR OLDREMOTE   = 1;
-    const static UCHAR NEWREMOTE   = 2;
-
   protected:
-    virtual UCHAR TranslateHWCFixed(ULLONG code);
-    UCHAR TranslateHWCList(ULLONG code);
-    UCHAR TranslateHWC(ULLONG code);
+    virtual UCHAR TranslateHWCFixed(int code)=0;
+    UCHAR TranslateHWCList(int code);
+    UCHAR TranslateHWC(int code);
     
-    static Input* instance;
     ULONG learnmode;
-    UCHAR remoteType;
     RemoteTranslationList translist;
-
-    std::thread listenThread;
-    std::mutex threadStartProtect;
-
-    virtual void eventLoop() {}; // FIXME change to abstract
-    virtual void informStopEventLoop() {}; // abstract
-
-    bool listenLoopStop{};
 };
 
 #endif
-
-// FIXME rename all remote stuff to some sort of INPUT
-// Roll in UDP receiver
-
-// FIXME have Top remote system create new listeners for various devices? Hot plug?
-// Where remotelinux has multi listeners, move that to top?
diff --git a/inputcec.cc b/inputcec.cc
new file mode 100644 (file)
index 0000000..9dc57b5
--- /dev/null
@@ -0,0 +1,461 @@
+ /*
+    Copyright 2004-2020 Chris Tallon; 2012 Marten Richter
+
+    This file is part of VOMP.
+
+    VOMP is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    VOMP is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with VOMP.  If not, see <https://www.gnu.org/licenses/>.
+*/
+
+#include <iostream>
+#include <libcec/cec.h>
+#include <libcec/cecloader.h>
+using namespace CEC;
+
+#include <bcm_host.h>
+
+#include "log.h"
+#include "message.h"
+#include "messagequeue.h"
+#include "vdr.h"
+#include "woptionpane.h"
+#include "inputcec.h"
+
+
+//#define W_G_HCW(type,code) ((static_cast<ULLONG>(type) << 32) | code)
+
+//#define W_HCW_KC 1 /* key code as defined by kernel for keyboard and remotes through /dev/input */
+//#define W_HCW_CEC 2 /* HDMI_CEC */
+//#define W_HCW_LIRC 3 /* remote control LIRC*/
+
+
+InputCEC* InputCEC::instance = NULL;
+
+int InputCEC::init()
+{
+  InitHWCListwithDefaults();
+  InitKeymap();
+
+  // bcm_host_init(); //may be move to custom hardware init?
+  // now init cec
+  Log::getInstance()->log("InputCEC", Log::NOTICE, "Init LibCEC");
+  instance = this;
+
+  cec_config.Clear();
+  cec_callbacks.Clear();
+  cec_callbacks.logMessage = cecLogMessage;
+  cec_callbacks.keyPress = cecKeyPress;
+  cec_callbacks.commandReceived = cecCommand;
+  cec_callbacks.configurationChanged = cecConfigurationChanged;
+  cec_callbacks.sourceActivated = cecSourceActivated;
+  cec_config.clientVersion = LIBCEC_VERSION_CURRENT;
+  cec_config.bActivateSource = 1;
+  //cec_config.deviceTypes.Add(CEC_DEVICE_TYPE_PLAYBACK_DEVICE);
+  cec_config.deviceTypes.Add(CEC_DEVICE_TYPE_RECORDING_DEVICE);
+  //cec_config.deviceTypes.Add(CEC_DEVICE_TYPE_TUNER);
+
+  strncpy(cec_config.strDeviceName, "vomp", sizeof(cec_config.strDeviceName));
+
+  cec_config.callbackParam = NULL; // I do not care
+  cec_config.callbacks = &cec_callbacks;
+
+  cec_adap = LibCecInitialise(&cec_config);
+  if (!cec_adap)
+  {
+    Log::getInstance()->log("InputCEC", Log::ERR, "Init LibCEC failed");
+    return 1;
+  }
+
+  cec_adap->InitVideoStandalone();
+
+  cec_adapter_descriptor cec_adapter_descriptors[10];
+  int adap_num = cec_adap->DetectAdapters(cec_adapter_descriptors, 10);
+  if (adap_num < 0)
+  {
+    Log::getInstance()->log("InputCEC", Log::ERR, "CEC:Failed to find adapter");
+    return 1;
+  }
+
+  if (adap_num == 0)
+  {
+    Log::getInstance()->log("InputCEC", Log::NOTICE, "CEC: No adapter found");
+    return 1;
+  }
+
+  if (!cec_adap->Open(cec_adapter_descriptors[0].strComName))
+  {
+    Log::getInstance()->log("InputCEC", Log::ERR, "CEC:Failed to open adapter");
+    return 1;
+  }
+
+  if (!cec_adap->SetActiveSource(cec_config.deviceTypes[0]))
+  {
+    Log::getInstance()->log("InputCEC", Log::ERR, "CEC:Failed set active source");
+    return 1;
+  }
+
+  return 1;
+}
+
+void InputCEC::shutdown()
+{
+  if (cec_adap)
+  {
+    Log::getInstance()->log("InputCEC", Log::NOTICE, "Shutdown libcec begin");
+    cec_adap->SetInactiveView();
+    cec_adap->Close();
+    vc_cec_register_callback(NULL, NULL); //deactivate callback!
+    UnloadLibCec(cec_adap);
+    cec_adap = NULL;
+    Log::getInstance()->log("InputCEC", Log::NOTICE, "Shutdown libcec end");
+  }
+
+  instance = NULL;
+}
+
+void InputCEC::changePowerState(bool poweron)
+{
+  if (cec_adap)
+  {
+    if (poweron)
+    {
+      //Log::getInstance()->log("InputCEC", Log::DEBUG, "CEC set active source");
+      cec_adap->SetActiveSource(cec_config.deviceTypes[0]);
+    }
+    else
+    {
+      //Log::getInstance()->log("InputCEC", Log::DEBUG, "CEC set inactive view");
+      cec_adap->SetInactiveView();
+    }
+  }
+}
+
+void InputCEC::incomingCECkey(int keys)
+{
+  // 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);
+}
+
+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);
+}
+
+void InputCEC::volumeUp()
+{
+  cec_adap->VolumeUp();
+}
+
+void InputCEC::volumeDown()
+{
+  cec_adap->VolumeDown();
+}
+
+void InputCEC::volumeMute()
+{
+  cec_adap->AudioToggleMute();
+}
+
+bool InputCEC::loadOptionsfromServer(VDR* vdr)
+{
+   // Set remote keys
+  char* name;
+  name = vdr->configLoad("InputCEC", "HandleVolume");
+
+  if (name != NULL)
+  {
+    if      (STRCASECMP(name, "Vomp") == 0) cechandlesvolume = false;
+    else if (STRCASECMP(name, "Cec") == 0) cechandlesvolume = true;
+    delete[] name;
+  }
+  return Input::loadOptionsfromServer(vdr);
+}
+
+bool InputCEC::saveOptionstoServer()
+{
+  if (cechandlesvolume) VDR::getInstance()->configSave("InputCEC", "HandleVolume","Cec");
+  else VDR::getInstance()->configSave("InputCEC", "HandleVolume","Vomp");
+
+  return Input::saveOptionstoServer();
+}
+
+bool InputCEC::addOptionsToPanes(int panenumber,Options *options,WOptionPane* pane)
+{
+  //if (!Input::addOptionsToPanes(panenumber, options, pane)) return false;
+
+  Option* option;
+  if (panenumber == 2)
+  {
+    static const char* volumeopts[]={"Vomp","Cec"};
+    option = new Option(100,tr("Volume handled by"), "InputCEC","HandleVolume",Option::TYPE_TEXT,/*4,2*/2,0,0,volumeopts,NULL,false,this);
+    options->push_back(option);
+    pane->addOptionLine(option);
+  }
+
+  return true;
+}
+
+bool InputCEC::handleOptionChanges(Option* option)
+{
+    if (Input::handleOptionChanges(option))
+               return true;
+       switch (option->id) {
+       case 100: {
+               if (STRCASECMP(option->options[option->userSetChoice], "Vomp") == 0) {
+                       cechandlesvolume=false;
+               }  else if (STRCASECMP(option->options[option->userSetChoice], "Cec")
+                               == 0) {
+                       cechandlesvolume=true;
+               }
+               Log::getInstance()->log("InputCEC", Log::DEBUG, "Set volume handling to to %s %d",option->options[option->userSetChoice],cechandlesvolume);
+               return true;
+       }
+       break;
+       };
+       return false;
+}
+
+// STATIC FUNCTIONS FOLLOW
+
+void InputCEC::cecLogMessage(void* /* param */, const cec_log_message* message)
+{
+  Log::getInstance()->log("InputCEC", Log::DEBUG, "CECLOG: %lld %d %s", message->time, message->level, message->message);
+}
+
+void InputCEC::cecKeyPress(void* /* param */, const cec_keypress* key)
+{
+  //Log::getInstance()->log("InputCEC", Log::DEBUG, "Incoming cec key %d %d", key->keycode,key->duration);
+  if (key->duration == 0) instance->incomingCECkey(key->keycode);
+}
+
+void InputCEC::cecCommand(void* /* param */, const cec_command* command)
+{
+  Log::getInstance()->log("InputCEC", Log::DEBUG, "CECCommand: %d", command->opcode);
+  switch (command->opcode)
+  {
+    case CEC_OPCODE_STANDBY:
+    {
+      if (command->initiator==CECDEVICE_TV)
+      {
+        instance->incomingPowerkey(POWEROFF);
+      }
+      break;
+    }
+    case CEC_OPCODE_DECK_CONTROL:
+    {
+      if (command->initiator == CECDEVICE_TV && command->parameters.size == 1
+            && command->parameters[0] == CEC_DECK_CONTROL_MODE_STOP)
+      {
+        instance->incomingCECkey(CEC_USER_CONTROL_CODE_STOP);
+      }
+      break;
+    }
+    case CEC_OPCODE_PLAY:
+    {
+      if (command->initiator == CECDEVICE_TV && command->parameters.size == 1)
+      {
+        if (command->parameters[0] == CEC_PLAY_MODE_PLAY_FORWARD)
+        {
+          instance->incomingCECkey(CEC_USER_CONTROL_CODE_PLAY);
+        }
+        else if (command->parameters[0] == CEC_PLAY_MODE_PLAY_STILL)
+        {
+          instance->incomingCECkey(CEC_USER_CONTROL_CODE_PAUSE);
+        }
+      }
+      break;
+    }
+    default:
+      break;
+  }
+}
+
+void InputCEC::cecConfigurationChanged(void* /* param */, const libcec_configuration*)
+{
+  Log::getInstance()->log("InputCEC", Log::DEBUG, "CECConfig:"/*,config->string()*/);
+}
+
+void InputCEC::cecSourceActivated(void* /* param */, const cec_logical_address address, const uint8_t activated)
+{
+  Log::getInstance()->log("InputCEC", Log::DEBUG, "CECSourceActivated: %d %d", address, activated);
+  if (activated == 1)
+  {
+    instance->incomingPowerkey(POWERON);
+  }
+}
+
+void InputCEC::InitHWCListwithDefaults()
+{
+  //Processing CEC_Messages
+  translist[CEC_USER_CONTROL_CODE_NUMBER9] = NINE;
+  translist[CEC_USER_CONTROL_CODE_NUMBER8] = EIGHT;
+  translist[CEC_USER_CONTROL_CODE_NUMBER7] = SEVEN;
+  translist[CEC_USER_CONTROL_CODE_NUMBER6] = SIX;
+  translist[CEC_USER_CONTROL_CODE_NUMBER5] = FIVE;
+  translist[CEC_USER_CONTROL_CODE_NUMBER4] = FOUR;
+  translist[CEC_USER_CONTROL_CODE_NUMBER3] = THREE;
+  translist[CEC_USER_CONTROL_CODE_NUMBER2] = TWO;
+  translist[CEC_USER_CONTROL_CODE_NUMBER1] = ONE;
+  translist[CEC_USER_CONTROL_CODE_NUMBER0] = ZERO;
+  //translist[KEY_KPDOT] = STAR;
+
+  //translist[KEY_J] = GO; //j for JUMP TO instead of go to
+  translist[CEC_USER_CONTROL_CODE_F2_RED] = RED;
+  translist[CEC_USER_CONTROL_CODE_F3_GREEN] = GREEN;
+  translist[CEC_USER_CONTROL_CODE_F4_YELLOW] = YELLOW;
+  translist[CEC_USER_CONTROL_CODE_F1_BLUE] = BLUE;
+  //Processing Remote Style Messages
+  translist[CEC_USER_CONTROL_CODE_FAVORITE_MENU] = MENU;
+
+  translist[CEC_USER_CONTROL_CODE_RECORD] = RECORD;
+  translist[CEC_USER_CONTROL_CODE_PLAY] = PLAY; //Playback Televison
+  translist[CEC_USER_CONTROL_CODE_PAUSE] = PAUSE;
+  translist[CEC_USER_CONTROL_CODE_STOP] = STOP;
+  translist[CEC_USER_CONTROL_CODE_PAUSE_PLAY_FUNCTION] = PLAYPAUSE;
+  translist[CEC_USER_CONTROL_CODE_FORWARD] = SKIPFORWARD;
+  translist[CEC_USER_CONTROL_CODE_BACKWARD] = SKIPBACK;
+  translist[CEC_USER_CONTROL_CODE_FAST_FORWARD ] = FORWARD;
+  translist[CEC_USER_CONTROL_CODE_REWIND] = REVERSE;
+  translist[CEC_USER_CONTROL_CODE_MUTE] = MUTE;
+  translist[CEC_USER_CONTROL_CODE_VOLUME_UP] = VOLUMEUP;
+  translist[CEC_USER_CONTROL_CODE_VOLUME_DOWN] = VOLUMEDOWN;
+  translist[CEC_USER_CONTROL_CODE_CHANNEL_UP ] = CHANNELUP;
+  translist[CEC_USER_CONTROL_CODE_CHANNEL_DOWN] = CHANNELDOWN;
+}
+
+UCHAR InputCEC::TranslateHWCFixed(int code)
+{
+  switch (code)
+  {
+    case CEC_USER_CONTROL_CODE_DOWN:            return DOWN;
+    case CEC_USER_CONTROL_CODE_UP:              return UP;
+    case CEC_USER_CONTROL_CODE_LEFT:            return LEFT;
+    case CEC_USER_CONTROL_CODE_RIGHT:           return RIGHT;
+    case CEC_USER_CONTROL_CODE_ROOT_MENU:
+    case CEC_USER_CONTROL_CODE_CONTENTS_MENU:
+    case CEC_USER_CONTROL_CODE_SETUP_MENU:      return MENU;
+    case CEC_USER_CONTROL_CODE_EXIT:            return BACK;
+    case CEC_USER_CONTROL_CODE_ENTER:
+    case CEC_USER_CONTROL_CODE_SELECT:
+    case CEC_USER_CONTROL_CODE_AN_RETURN:       return OK;
+    case CEC_USER_CONTROL_CODE_POWER:
+    case POWER:                                 return POWER;   //?
+    default:
+      return NA_UNKNOWN;
+  }
+}
+
+
+#define NAMETRICK2(pre, code) cec_keymap[pre ## code]=  #code
+static const char * cec_keymap[CEC_USER_CONTROL_CODE_MAX+1];
+
+void InputCEC::InitKeymap()
+{
+  for (int i=0; i < CEC_USER_CONTROL_CODE_MAX + 1; i++)
+  {
+    cec_keymap[i] = NULL;
+  }
+
+  NAMETRICK2(CEC_USER_CONTROL_CODE_,SELECT);
+  NAMETRICK2(CEC_USER_CONTROL_CODE_,UP);
+  NAMETRICK2(CEC_USER_CONTROL_CODE_,DOWN);
+  NAMETRICK2(CEC_USER_CONTROL_CODE_,LEFT);
+  NAMETRICK2(CEC_USER_CONTROL_CODE_,RIGHT);
+  NAMETRICK2(CEC_USER_CONTROL_CODE_,RIGHT_UP);
+  NAMETRICK2(CEC_USER_CONTROL_CODE_,RIGHT_DOWN);
+  NAMETRICK2(CEC_USER_CONTROL_CODE_,LEFT_UP);
+  NAMETRICK2(CEC_USER_CONTROL_CODE_,LEFT_DOWN);
+  NAMETRICK2(CEC_USER_CONTROL_CODE_,ROOT_MENU);
+  NAMETRICK2(CEC_USER_CONTROL_CODE_,SETUP_MENU);
+  NAMETRICK2(CEC_USER_CONTROL_CODE_,CONTENTS_MENU);
+  NAMETRICK2(CEC_USER_CONTROL_CODE_,FAVORITE_MENU);
+  NAMETRICK2(CEC_USER_CONTROL_CODE_,EXIT);
+  NAMETRICK2(CEC_USER_CONTROL_CODE_,NUMBER0);
+  NAMETRICK2(CEC_USER_CONTROL_CODE_,NUMBER1);
+  NAMETRICK2(CEC_USER_CONTROL_CODE_,NUMBER2);
+  NAMETRICK2(CEC_USER_CONTROL_CODE_,NUMBER3);
+  NAMETRICK2(CEC_USER_CONTROL_CODE_,NUMBER4);
+  NAMETRICK2(CEC_USER_CONTROL_CODE_,NUMBER5);
+  NAMETRICK2(CEC_USER_CONTROL_CODE_,NUMBER6);
+  NAMETRICK2(CEC_USER_CONTROL_CODE_,NUMBER7);
+  NAMETRICK2(CEC_USER_CONTROL_CODE_,NUMBER8);
+  NAMETRICK2(CEC_USER_CONTROL_CODE_,NUMBER9);
+  NAMETRICK2(CEC_USER_CONTROL_CODE_,DOT);
+  NAMETRICK2(CEC_USER_CONTROL_CODE_,ENTER);
+  NAMETRICK2(CEC_USER_CONTROL_CODE_,CLEAR);
+  NAMETRICK2(CEC_USER_CONTROL_CODE_,NEXT_FAVORITE);
+  NAMETRICK2(CEC_USER_CONTROL_CODE_,CHANNEL_UP);
+  NAMETRICK2(CEC_USER_CONTROL_CODE_,CHANNEL_DOWN);
+  NAMETRICK2(CEC_USER_CONTROL_CODE_,PREVIOUS_CHANNEL);
+  NAMETRICK2(CEC_USER_CONTROL_CODE_,SOUND_SELECT);
+  NAMETRICK2(CEC_USER_CONTROL_CODE_,INPUT_SELECT);
+  NAMETRICK2(CEC_USER_CONTROL_CODE_,DISPLAY_INFORMATION);
+  NAMETRICK2(CEC_USER_CONTROL_CODE_,HELP);
+  NAMETRICK2(CEC_USER_CONTROL_CODE_,PAGE_UP);
+  NAMETRICK2(CEC_USER_CONTROL_CODE_,PAGE_DOWN);
+  NAMETRICK2(CEC_USER_CONTROL_CODE_,POWER );
+  NAMETRICK2(CEC_USER_CONTROL_CODE_,VOLUME_UP );
+  NAMETRICK2(CEC_USER_CONTROL_CODE_,VOLUME_DOWN );
+  NAMETRICK2(CEC_USER_CONTROL_CODE_,MUTE );
+  NAMETRICK2(CEC_USER_CONTROL_CODE_,PLAY );
+  NAMETRICK2(CEC_USER_CONTROL_CODE_,STOP );
+  NAMETRICK2(CEC_USER_CONTROL_CODE_,PAUSE );
+  NAMETRICK2(CEC_USER_CONTROL_CODE_,RECORD );
+  NAMETRICK2(CEC_USER_CONTROL_CODE_,REWIND );
+  NAMETRICK2(CEC_USER_CONTROL_CODE_,FAST_FORWARD );
+  NAMETRICK2(CEC_USER_CONTROL_CODE_,EJECT );
+  NAMETRICK2(CEC_USER_CONTROL_CODE_,FORWARD );
+  NAMETRICK2(CEC_USER_CONTROL_CODE_,BACKWARD );
+  NAMETRICK2(CEC_USER_CONTROL_CODE_,STOP_RECORD );
+  NAMETRICK2(CEC_USER_CONTROL_CODE_,PAUSE_RECORD );
+  NAMETRICK2(CEC_USER_CONTROL_CODE_,ANGLE );
+  NAMETRICK2(CEC_USER_CONTROL_CODE_,SUB_PICTURE );
+  NAMETRICK2(CEC_USER_CONTROL_CODE_,VIDEO_ON_DEMAND );
+  NAMETRICK2(CEC_USER_CONTROL_CODE_,ELECTRONIC_PROGRAM_GUIDE );
+  NAMETRICK2(CEC_USER_CONTROL_CODE_,TIMER_PROGRAMMING );
+  NAMETRICK2(CEC_USER_CONTROL_CODE_,INITIAL_CONFIGURATION );
+  NAMETRICK2(CEC_USER_CONTROL_CODE_,PLAY_FUNCTION );
+  NAMETRICK2(CEC_USER_CONTROL_CODE_,PAUSE_PLAY_FUNCTION );
+  NAMETRICK2(CEC_USER_CONTROL_CODE_,RECORD_FUNCTION );
+  NAMETRICK2(CEC_USER_CONTROL_CODE_,PAUSE_RECORD_FUNCTION );
+  NAMETRICK2(CEC_USER_CONTROL_CODE_,STOP_FUNCTION );
+  NAMETRICK2(CEC_USER_CONTROL_CODE_,MUTE_FUNCTION );
+  NAMETRICK2(CEC_USER_CONTROL_CODE_,RESTORE_VOLUME_FUNCTION );
+  NAMETRICK2(CEC_USER_CONTROL_CODE_,TUNE_FUNCTION );
+  NAMETRICK2(CEC_USER_CONTROL_CODE_,SELECT_MEDIA_FUNCTION );
+  NAMETRICK2(CEC_USER_CONTROL_CODE_,SELECT_AV_INPUT_FUNCTION );
+  NAMETRICK2(CEC_USER_CONTROL_CODE_,SELECT_AUDIO_INPUT_FUNCTION );
+  NAMETRICK2(CEC_USER_CONTROL_CODE_,POWER_TOGGLE_FUNCTION );
+  NAMETRICK2(CEC_USER_CONTROL_CODE_,POWER_OFF_FUNCTION );
+  NAMETRICK2(CEC_USER_CONTROL_CODE_,POWER_ON_FUNCTION );
+  NAMETRICK2(CEC_USER_CONTROL_CODE_,F1_BLUE );
+  NAMETRICK2(CEC_USER_CONTROL_CODE_,F2_RED );
+  NAMETRICK2(CEC_USER_CONTROL_CODE_,F3_GREEN );
+  NAMETRICK2(CEC_USER_CONTROL_CODE_,F4_YELLOW );
+  NAMETRICK2(CEC_USER_CONTROL_CODE_,F5 );
+  NAMETRICK2(CEC_USER_CONTROL_CODE_,DATA );
+  NAMETRICK2(CEC_USER_CONTROL_CODE_,AN_RETURN );
+  NAMETRICK2(CEC_USER_CONTROL_CODE_,AN_CHANNELS_LIST );
+  NAMETRICK2(CEC_USER_CONTROL_CODE_,MAX );
+}
diff --git a/inputcec.h b/inputcec.h
new file mode 100644 (file)
index 0000000..69c3ad1
--- /dev/null
@@ -0,0 +1,66 @@
+ /*
+    Copyright 2004-2020 Chris Tallon; 2012 Marten Richter
+
+    This file is part of VOMP.
+
+    VOMP is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    VOMP is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with VOMP.  If not, see <https://www.gnu.org/licenses/>.
+*/
+
+#ifndef INPUTCEC_H
+#define INPUTCEC_H
+
+#include <libcec/cec.h>
+
+#include "input.h"
+
+class InputCEC : public Input
+{
+  public:
+    int init();
+    void shutdown();
+
+    bool handlesVolume() { return cechandlesvolume; };
+    void volumeUp();
+    void volumeDown();
+    void volumeMute();
+    void changePowerState(bool poweron);
+
+    bool loadOptionsfromServer(VDR* vdr);
+    bool saveOptionstoServer();
+    bool addOptionsToPanes(int panenumber,Options *options,WOptionPane* pane);
+    bool handleOptionChanges(Option* option);
+
+  private:
+    void InitKeymap();
+    void InitHWCListwithDefaults();
+    UCHAR TranslateHWCFixed(int code);
+
+    bool cechandlesvolume{};
+
+    CEC::ICECAdapter* cec_adap{};
+    CEC::libcec_configuration cec_config;
+    CEC::ICECCallbacks cec_callbacks;
+
+    void incomingCECkey(int keys);
+    void incomingPowerkey(UCHAR key);
+
+    static InputCEC* instance;
+    static void cecLogMessage(void *param, const CEC::cec_log_message* message);
+    static void cecKeyPress(void*param, const CEC::cec_keypress* key);
+    static void cecCommand(void *param, const CEC::cec_command* command);
+    static void cecConfigurationChanged(void *param, const CEC::libcec_configuration* config);
+    static void cecSourceActivated(void*param, const CEC::cec_logical_address address, const uint8_t activated);
+};
+
+#endif
index 8adc4791710891f3b9875483cf8862132081b668..c4a0badeb36185db9da0bad02965781ebaa62ee7 100644 (file)
 #include <iostream>
 #include <ostream>
 
-#include <bcm_host.h>
-
-#include <libcec/cec.h>
-#include <libcec/cecloader.h>
-using namespace CEC;
-
 #include "i18n.h"
 #include "vdr.h"
 #include "woptionpane.h"
@@ -43,32 +37,14 @@ using namespace CEC;
 
 #include "inputlinux.h"
 
-#define W_G_HCW(type,code) ((static_cast<ULLONG>(type) << 32) | code)
-
-#define W_HCW_KC 1 /* key code as defined by kernel for keyboard and remotes through /dev/input */
-#define W_HCW_CEC 2 /* HDMI_CEC */
-#define W_HCW_LIRC 3 /* remote control LIRC*/
-
-
-InputLinux::InputLinux()
-{
-}
-
-InputLinux::~InputLinux()
-{
-  for (unsigned int i = 0; i < devices.size(); i++)
-  {
-    close(devices[i]);
-  }
-}
-
 #define test_bit(input,b)  ((1 << ((b) % 8))&(input)[b / 8] )
 
-int InputLinux::init(const char*)
+int InputLinux::init()
 {
   if (initted) return 0;
   initted = 1;
 
+  InitHWCListwithDefaults();
   InitKeymap();
 
   for (int eventid = 0; eventid < 100; eventid++)
@@ -110,92 +86,13 @@ int InputLinux::init(const char*)
       }
     }
   }
-  return initCec();
-}
-
-int InputLinux::initCec() {
-
-  // bcm_host_init(); //may be move to custom hardware init?
-// now init cec
-       Log::getInstance()->log("InputLinux", Log::NOTICE, "Init LibCEC");
-       cec_config.Clear();
-       cec_callbacks.Clear();
-#if CEC_LIB_VERSION_MAJOR >= 4
-       cec_callbacks.logMessage = cecLogMessage;
-       cec_callbacks.keyPress = cecKeyPress;
-       cec_callbacks.commandReceived = cecCommand;
-       cec_callbacks.configurationChanged = cecConfigurationChanged;
-       cec_callbacks.sourceActivated = cecSourceActivated;
-#else
-       cec_callbacks.CBCecLogMessage = cecLogMessage;
-       cec_callbacks.CBCecKeyPress = cecKeyPress;
-       cec_callbacks.CBCecCommand = cecCommand;
-       cec_callbacks.CBCecConfigurationChanged = cecConfigurationChanged;
-       cec_callbacks.CBCecSourceActivated = cecSourceActivated;
-       cec_config.bUseTVMenuLanguage=1;
-#endif
-    cec_config.clientVersion=LIBCEC_VERSION_CURRENT;
-       cec_config.bActivateSource=1;
-       //cec_config.deviceTypes.Add(CEC_DEVICE_TYPE_PLAYBACK_DEVICE);
-       cec_config.deviceTypes.Add(CEC_DEVICE_TYPE_RECORDING_DEVICE);
-       //cec_config.deviceTypes.Add(CEC_DEVICE_TYPE_TUNER);
-
-       strncpy(cec_config.strDeviceName,"vomp",sizeof(cec_config.strDeviceName));
-
-
-       cec_config.callbackParam = NULL; // I do not care
-       cec_config.callbacks = &cec_callbacks;
-
-       cec_adap = LibCecInitialise(&cec_config);
-       if (!cec_adap) {
-               Log::getInstance()->log("InputLinux", Log::ERR, "Init LibCEC failed");
-               return 1;
-       }
-       cec_adap->InitVideoStandalone();
-
-
-#if CEC_LIB_VERSION_MAJOR >= 4
-       cec_adapter_descriptor cec_adapter_descriptors[10];
-       int adap_num=cec_adap->DetectAdapters(cec_adapter_descriptors, 10);
-#else
-       cec_adapter  cec_devices[10];
-       int adap_num=cec_adap->FindAdapters(cec_devices,10,NULL);
-#endif
-       if (adap_num<0) {
-               Log::getInstance()->log("InputLinux", Log::ERR, "CEC:Failed to find adapter");
-               return 1;
-
-       }
-       if (adap_num==0) {
-               Log::getInstance()->log("InputLinux", Log::NOTICE, "CEC: No adapter found");
-               return 1;
-
-       }
-#if CEC_LIB_VERSION_MAJOR >= 4
-       if (!cec_adap->Open(cec_adapter_descriptors[0].strComName)) {
-#else
-       if (!cec_adap->Open(cec_devices[0].comm)) {
-#endif
-      Log::getInstance()->log("InputLinux", Log::ERR, "CEC:Failed to open adapter");
-               return 1;
-       }
-
-       if (!cec_adap->SetActiveSource(cec_config.deviceTypes[0])) {
-               Log::getInstance()->log("InputLinux", Log::ERR, "CEC:Failed set active source");
-               return 1;
-       }
-
-
-
-
   return 1;
 }
 
-int InputLinux::shutdown()
+void InputLinux::shutdown()
 {
-  if (!initted) return 0;
+  if (!initted) return;
 
-  deinitCec();
   while (devices.size())
   {
     int cur_fd = devices.back();
@@ -205,226 +102,118 @@ int InputLinux::shutdown()
   }
 
   initted = 0;
-  return 1;
-}
-
-void InputLinux::deinitCec()
-{
-       if (cec_adap) {
-               Log::getInstance()->log("InputLinux", Log::NOTICE, "Shutdown libcec begin");
-               cec_adap->SetInactiveView();
-               cec_adap->Close();
-               vc_cec_register_callback(NULL, NULL);//deactivate callback!
-               UnloadLibCec(cec_adap);
-               cec_adap = NULL;
-               Log::getInstance()->log("InputLinux", Log::NOTICE, "Shutdown libcec end");
-       }
-
-}
-
-UCHAR InputLinux::TranslateHWCFixed(ULLONG code)
-{
-    switch (code) 
-    {
-    case W_G_HCW(W_HCW_KC, KEY_DOWN):
-        return DOWN;
-    case W_G_HCW(W_HCW_KC, KEY_UP):
-        return UP;
-    case W_G_HCW(W_HCW_KC, KEY_LEFT):
-        return LEFT;
-    case W_G_HCW(W_HCW_KC, KEY_RIGHT):
-        return RIGHT;
-    case W_G_HCW(W_HCW_KC, KEY_M):
-    case W_G_HCW(W_HCW_KC, KEY_MEDIA):
-        return MENU;
-    case W_G_HCW(W_HCW_KC, KEY_BACKSPACE):
-    case W_G_HCW(W_HCW_KC, KEY_EXIT):
-        return BACK;
-    case W_G_HCW(W_HCW_KC, KEY_ENTER):
-    case W_G_HCW(W_HCW_KC, KEY_SPACE):
-    case W_G_HCW(W_HCW_KC, KEY_OK):
-        return OK;
-
-    //CEC
-    case W_G_HCW(W_HCW_CEC, CEC_USER_CONTROL_CODE_DOWN):
-        return DOWN;
-    case W_G_HCW(W_HCW_CEC, CEC_USER_CONTROL_CODE_UP):
-        return UP;
-    case W_G_HCW(W_HCW_CEC, CEC_USER_CONTROL_CODE_LEFT):
-        return LEFT;
-    case W_G_HCW(W_HCW_CEC, CEC_USER_CONTROL_CODE_RIGHT):
-        return RIGHT;
-    case W_G_HCW(W_HCW_CEC, CEC_USER_CONTROL_CODE_ROOT_MENU):
-    case W_G_HCW(W_HCW_CEC, CEC_USER_CONTROL_CODE_CONTENTS_MENU):
-    case W_G_HCW(W_HCW_CEC, CEC_USER_CONTROL_CODE_SETUP_MENU):
-        return MENU;
-    case W_G_HCW(W_HCW_CEC, CEC_USER_CONTROL_CODE_EXIT ):
-        return BACK;
-    case W_G_HCW(W_HCW_CEC, CEC_USER_CONTROL_CODE_ENTER):
-    case W_G_HCW(W_HCW_CEC, CEC_USER_CONTROL_CODE_SELECT):
-    case W_G_HCW(W_HCW_CEC, CEC_USER_CONTROL_CODE_AN_RETURN):
-        return OK;
-    case W_G_HCW(W_HCW_KC, KEY_SLEEP):
-    case W_G_HCW(W_HCW_KC, KEY_POWER):
-    case W_G_HCW(W_HCW_KC, KEY_ESC):
-    case W_G_HCW(W_HCW_CEC, CEC_USER_CONTROL_CODE_POWER):
-    case POWER:
-        return POWER;
-    default:
-        return NA_UNKNOWN;
-    };
 }
 
-const char* InputLinux::HardcodedTranslateStr(UCHAR command)
+UCHAR InputLinux::TranslateHWCFixed(int code)
 {
-  switch (command)
+  // Translate /dev/input codes to VOMP codes for the hard coded buttons
+  switch (code)
   {
-    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");
+    case KEY_DOWN:      return DOWN;
+    case KEY_UP:        return UP;
+    case KEY_LEFT:      return LEFT;
+    case KEY_RIGHT:     return RIGHT;
+    case KEY_M:
+    case KEY_MEDIA:     return MENU;
+    case KEY_BACKSPACE:
+    case KEY_EXIT:      return BACK;
+    case KEY_ENTER:
+    case KEY_SPACE:
+    case KEY_OK:        return OK;
+    case KEY_SLEEP:
+    case KEY_POWER:
+    case KEY_ESC:       return POWER;
+    case POWER:         return POWER; // Where does this come from?
     default:
-      return NULL;
+      return NA_UNKNOWN;
   }
 }
 
-
 void InputLinux::InitHWCListwithDefaults()
 {
   // Processing VK_Messages
-  translist[W_G_HCW(W_HCW_KC,KEY_9)] = NINE;
-  translist[W_G_HCW(W_HCW_KC,KEY_8)] = EIGHT;
-  translist[W_G_HCW(W_HCW_KC,KEY_7)] = SEVEN;
-  translist[W_G_HCW(W_HCW_KC,KEY_6)] = SIX;
-  translist[W_G_HCW(W_HCW_KC,KEY_5)] = FIVE;
-  translist[W_G_HCW(W_HCW_KC,KEY_4)] = FOUR;
-  translist[W_G_HCW(W_HCW_KC,KEY_3)] = THREE;
-  translist[W_G_HCW(W_HCW_KC,KEY_2)] = TWO;
-  translist[W_G_HCW(W_HCW_KC,KEY_1)] = ONE;
-  translist[W_G_HCW(W_HCW_KC,KEY_0)] = ZERO;
-  translist[W_G_HCW(W_HCW_KC,KEY_KPDOT)] = STAR;
-  // translist[W_G_HCW(W_HCW_KC,KEY_#)] = HASH;
-
-  translist[W_G_HCW(W_HCW_KC,KEY_KP9)] = NINE;
-  translist[W_G_HCW(W_HCW_KC,KEY_KP8)] = EIGHT;
-  translist[W_G_HCW(W_HCW_KC,KEY_KP7)] = SEVEN;
-  translist[W_G_HCW(W_HCW_KC,KEY_KP6)] = SIX;
-  translist[W_G_HCW(W_HCW_KC,KEY_KP5)] = FIVE;
-  translist[W_G_HCW(W_HCW_KC,KEY_KP4)] = FOUR;
-  translist[W_G_HCW(W_HCW_KC,KEY_KP3)] = THREE;
-  translist[W_G_HCW(W_HCW_KC,KEY_KP2)] = TWO;
-  translist[W_G_HCW(W_HCW_KC,KEY_KP1)] = ONE;
-  translist[W_G_HCW(W_HCW_KC,KEY_KP0)] = ZERO;
-
-  translist[W_G_HCW(W_HCW_KC,KEY_NUMERIC_9)] = NINE;
-  translist[W_G_HCW(W_HCW_KC,KEY_NUMERIC_8)] = EIGHT;
-  translist[W_G_HCW(W_HCW_KC,KEY_NUMERIC_7)] = SEVEN;
-  translist[W_G_HCW(W_HCW_KC,KEY_NUMERIC_6)] = SIX;
-  translist[W_G_HCW(W_HCW_KC,KEY_NUMERIC_5)] = FIVE;
-  translist[W_G_HCW(W_HCW_KC,KEY_NUMERIC_4)] = FOUR;
-  translist[W_G_HCW(W_HCW_KC,KEY_NUMERIC_3)] = THREE;
-  translist[W_G_HCW(W_HCW_KC,KEY_NUMERIC_2)] = TWO;
-  translist[W_G_HCW(W_HCW_KC,KEY_NUMERIC_1)] = ONE;
-  translist[W_G_HCW(W_HCW_KC,KEY_NUMERIC_0)] = ZERO;
-  translist[W_G_HCW(W_HCW_KC,KEY_NUMERIC_STAR)] = STAR;
-  translist[W_G_HCW(W_HCW_KC,KEY_NUMERIC_POUND)] = HASH;
-
-
-  translist[W_G_HCW(W_HCW_KC,KEY_J)] = GO; //j for JUMP TO instead of go to
-  translist[W_G_HCW(W_HCW_KC,KEY_R)] = RED;
-  translist[W_G_HCW(W_HCW_KC,KEY_G)] = GREEN;
-  translist[W_G_HCW(W_HCW_KC,KEY_Y)] = YELLOW;
-  translist[W_G_HCW(W_HCW_KC,KEY_B)] = BLUE;
+  translist[KEY_9] = NINE;
+  translist[KEY_8] = EIGHT;
+  translist[KEY_7] = SEVEN;
+  translist[KEY_6] = SIX;
+  translist[KEY_5] = FIVE;
+  translist[KEY_4] = FOUR;
+  translist[KEY_3] = THREE;
+  translist[KEY_2] = TWO;
+  translist[KEY_1] = ONE;
+  translist[KEY_0] = ZERO;
+  translist[KEY_KPDOT] = STAR;
+  // translist[KEY_#] = HASH;
+
+  translist[KEY_KP9] = NINE;
+  translist[KEY_KP8] = EIGHT;
+  translist[KEY_KP7] = SEVEN;
+  translist[KEY_KP6] = SIX;
+  translist[KEY_KP5] = FIVE;
+  translist[KEY_KP4] = FOUR;
+  translist[KEY_KP3] = THREE;
+  translist[KEY_KP2] = TWO;
+  translist[KEY_KP1] = ONE;
+  translist[KEY_KP0] = ZERO;
+
+  translist[KEY_NUMERIC_9] = NINE;
+  translist[KEY_NUMERIC_8] = EIGHT;
+  translist[KEY_NUMERIC_7] = SEVEN;
+  translist[KEY_NUMERIC_6] = SIX;
+  translist[KEY_NUMERIC_5] = FIVE;
+  translist[KEY_NUMERIC_4] = FOUR;
+  translist[KEY_NUMERIC_3] = THREE;
+  translist[KEY_NUMERIC_2] = TWO;
+  translist[KEY_NUMERIC_1] = ONE;
+  translist[KEY_NUMERIC_0] = ZERO;
+  translist[KEY_NUMERIC_STAR] = STAR;
+  translist[KEY_NUMERIC_POUND] = HASH;
+
+
+  translist[KEY_J] = GO; //j for JUMP TO instead of go to
+  translist[KEY_R] = RED;
+  translist[KEY_G] = GREEN;
+  translist[KEY_Y] = YELLOW;
+  translist[KEY_B] = BLUE;
   //Processing Remote Style Messages
-  translist[W_G_HCW(W_HCW_KC,KEY_GREEN)] = GREEN;
-  translist[W_G_HCW(W_HCW_KC,KEY_RED)] = RED;
-  translist[W_G_HCW(W_HCW_KC,KEY_YELLOW)] = YELLOW;
-  translist[W_G_HCW(W_HCW_KC,KEY_BLUE)] = BLUE;
-  translist[W_G_HCW(W_HCW_KC,KEY_MENU)] = MENU;
-
-  translist[W_G_HCW(W_HCW_KC,KEY_RECORD)] = RECORD;
-  translist[W_G_HCW(W_HCW_KC,KEY_PLAY)] = PLAY; //Playback Televison
-  translist[W_G_HCW(W_HCW_KC,KEY_PAUSE)] = PAUSE;
-  translist[W_G_HCW(W_HCW_KC,KEY_STOP)] = STOP;
-  translist[W_G_HCW(W_HCW_KC,KEY_PLAYPAUSE)] = PLAYPAUSE;
-  translist[W_G_HCW(W_HCW_KC,KEY_P)] = PLAYPAUSE;
-  translist[W_G_HCW(W_HCW_KC,KEY_NEXT)] = SKIPFORWARD;
-  translist[W_G_HCW(W_HCW_KC,KEY_F2)] = SKIPFORWARD;
-  translist[W_G_HCW(W_HCW_KC,KEY_PREVIOUS)] = SKIPBACK;
-  translist[W_G_HCW(W_HCW_KC,KEY_F1)] = SKIPBACK;
-  translist[W_G_HCW(W_HCW_KC,KEY_FORWARD)] = FORWARD;
-  translist[W_G_HCW(W_HCW_KC,KEY_FASTFORWARD)] = FORWARD;
-  translist[W_G_HCW(W_HCW_KC,KEY_F)] = FORWARD;
-  translist[W_G_HCW(W_HCW_KC,KEY_BACK)] = REVERSE;
-  translist[W_G_HCW(W_HCW_KC,KEY_REWIND)] = REVERSE;
-  translist[W_G_HCW(W_HCW_KC,KEY_T)] = REVERSE;
-  translist[W_G_HCW(W_HCW_KC,KEY_MUTE)] = MUTE;
-  translist[W_G_HCW(W_HCW_KC,KEY_F8)] = MUTE;
-  translist[W_G_HCW(W_HCW_KC,KEY_F10)] = VOLUMEUP;
-  translist[W_G_HCW(W_HCW_KC,KEY_F9)] = VOLUMEDOWN;
-  translist[W_G_HCW(W_HCW_KC,KEY_VOLUMEUP)] = VOLUMEUP;
-  translist[W_G_HCW(W_HCW_KC,KEY_VOLUMEDOWN)] = VOLUMEDOWN;
-  translist[W_G_HCW(W_HCW_KC,KEY_CHANNELUP)] = CHANNELUP;
-  translist[W_G_HCW(W_HCW_KC,KEY_CHANNELDOWN)] = CHANNELDOWN;
-  translist[W_G_HCW(W_HCW_KC,KEY_PAGEUP)] = CHANNELUP;
-  translist[W_G_HCW(W_HCW_KC,KEY_PAGEDOWN)] = CHANNELDOWN;
-
-
-  //Processing CEC_Messages
-  translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_NUMBER9)] = NINE;
-  translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_NUMBER8)] = EIGHT;
-  translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_NUMBER7)] = SEVEN;
-  translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_NUMBER6)] = SIX;
-  translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_NUMBER5)] = FIVE;
-  translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_NUMBER4)] = FOUR;
-  translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_NUMBER3)] = THREE;
-  translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_NUMBER2)] = TWO;
-  translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_NUMBER1)] = ONE;
-  translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_NUMBER0)] = ZERO;
-  //translist[W_G_HCW(W_HCW_CEC,KEY_KPDOT)] = STAR;
-
-
-
-  //translist[W_G_HCW(W_HCW_CEC,KEY_J)] = GO; //j for JUMP TO instead of go to
-  translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_F2_RED)] = RED;
-  translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_F3_GREEN)] = GREEN;
-  translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_F4_YELLOW)] = YELLOW;
-  translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_F1_BLUE)] = BLUE;
-  //Processing Remote Style Messages
-  translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_FAVORITE_MENU)] = MENU;
-
-  translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_RECORD)] = RECORD;
-  translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_PLAY)] = PLAY; //Playback Televison
-  translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_PAUSE)] = PAUSE;
-  translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_STOP)] = STOP;
-  translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_PAUSE_PLAY_FUNCTION)] = PLAYPAUSE;
-  translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_FORWARD)] = SKIPFORWARD;
-  translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_BACKWARD)] = SKIPBACK;
-  translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_FAST_FORWARD )] = FORWARD;
-  translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_REWIND)] = REVERSE;
-  translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_MUTE)] = MUTE;
-  translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_VOLUME_UP)] = VOLUMEUP;
-  translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_VOLUME_DOWN)] = VOLUMEDOWN;
-  translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_CHANNEL_UP )] = CHANNELUP;
-  translist[W_G_HCW(W_HCW_CEC,CEC_USER_CONTROL_CODE_CHANNEL_DOWN)] = CHANNELDOWN;
+  translist[KEY_GREEN] = GREEN;
+  translist[KEY_RED] = RED;
+  translist[KEY_YELLOW] = YELLOW;
+  translist[KEY_BLUE] = BLUE;
+  translist[KEY_MENU] = MENU;
+
+  translist[KEY_RECORD] = RECORD;
+  translist[KEY_PLAY] = PLAY; //Playback Televison
+  translist[KEY_PAUSE] = PAUSE;
+  translist[KEY_STOP] = STOP;
+  translist[KEY_PLAYPAUSE] = PLAYPAUSE;
+  translist[KEY_P] = PLAYPAUSE;
+  translist[KEY_NEXT] = SKIPFORWARD;
+  translist[KEY_F2] = SKIPFORWARD;
+  translist[KEY_PREVIOUS] = SKIPBACK;
+  translist[KEY_F1] = SKIPBACK;
+  translist[KEY_FORWARD] = FORWARD;
+  translist[KEY_FASTFORWARD] = FORWARD;
+  translist[KEY_F] = FORWARD;
+  translist[KEY_BACK] = REVERSE;
+  translist[KEY_REWIND] = REVERSE;
+  translist[KEY_T] = REVERSE;
+  translist[KEY_MUTE] = MUTE;
+  translist[KEY_F8] = MUTE;
+  translist[KEY_F10] = VOLUMEUP;
+  translist[KEY_F9] = VOLUMEDOWN;
+  translist[KEY_VOLUMEUP] = VOLUMEUP;
+  translist[KEY_VOLUMEDOWN] = VOLUMEDOWN;
+  translist[KEY_CHANNELUP] = CHANNELUP;
+  translist[KEY_CHANNELDOWN] = CHANNELDOWN;
+  translist[KEY_PAGEUP] = CHANNELUP;
+  translist[KEY_PAGEDOWN] = CHANNELDOWN;
 }
 
 #define NAMETRICK(pre, code) linux_keymap[pre ## code]=  #code
-#define NAMETRICK2(pre, code) cec_keymap[pre ## code]=  #code
 //extracte from linux/input.h
 
 static const char * linux_keymap[KEY_MAX+1];
-static const char * cec_keymap[CEC_USER_CONTROL_CODE_MAX+1];
 
 void InputLinux::InitKeymap()
 {
@@ -672,383 +461,51 @@ void InputLinux::InitKeymap()
   NAMETRICK(KEY_,NUMERIC_9);
   NAMETRICK(KEY_,NUMERIC_STAR);
   NAMETRICK(KEY_,NUMERIC_POUND);
-
-  for (int i=0; i < CEC_USER_CONTROL_CODE_MAX + 1; i++)
-  {
-    cec_keymap[i] = NULL;
-  }
-
-  NAMETRICK2(CEC_USER_CONTROL_CODE_,SELECT);
-  NAMETRICK2(CEC_USER_CONTROL_CODE_,UP);
-  NAMETRICK2(CEC_USER_CONTROL_CODE_,DOWN);
-  NAMETRICK2(CEC_USER_CONTROL_CODE_,LEFT);
-  NAMETRICK2(CEC_USER_CONTROL_CODE_,RIGHT);
-  NAMETRICK2(CEC_USER_CONTROL_CODE_,RIGHT_UP);
-  NAMETRICK2(CEC_USER_CONTROL_CODE_,RIGHT_DOWN);
-  NAMETRICK2(CEC_USER_CONTROL_CODE_,LEFT_UP);
-  NAMETRICK2(CEC_USER_CONTROL_CODE_,LEFT_DOWN);
-  NAMETRICK2(CEC_USER_CONTROL_CODE_,ROOT_MENU);
-  NAMETRICK2(CEC_USER_CONTROL_CODE_,SETUP_MENU);
-  NAMETRICK2(CEC_USER_CONTROL_CODE_,CONTENTS_MENU);
-  NAMETRICK2(CEC_USER_CONTROL_CODE_,FAVORITE_MENU);
-  NAMETRICK2(CEC_USER_CONTROL_CODE_,EXIT);
-  NAMETRICK2(CEC_USER_CONTROL_CODE_,NUMBER0);
-  NAMETRICK2(CEC_USER_CONTROL_CODE_,NUMBER1);
-  NAMETRICK2(CEC_USER_CONTROL_CODE_,NUMBER2);
-  NAMETRICK2(CEC_USER_CONTROL_CODE_,NUMBER3);
-  NAMETRICK2(CEC_USER_CONTROL_CODE_,NUMBER4);
-  NAMETRICK2(CEC_USER_CONTROL_CODE_,NUMBER5);
-  NAMETRICK2(CEC_USER_CONTROL_CODE_,NUMBER6);
-  NAMETRICK2(CEC_USER_CONTROL_CODE_,NUMBER7);
-  NAMETRICK2(CEC_USER_CONTROL_CODE_,NUMBER8);
-  NAMETRICK2(CEC_USER_CONTROL_CODE_,NUMBER9);
-  NAMETRICK2(CEC_USER_CONTROL_CODE_,DOT);
-  NAMETRICK2(CEC_USER_CONTROL_CODE_,ENTER);
-  NAMETRICK2(CEC_USER_CONTROL_CODE_,CLEAR);
-  NAMETRICK2(CEC_USER_CONTROL_CODE_,NEXT_FAVORITE);
-  NAMETRICK2(CEC_USER_CONTROL_CODE_,CHANNEL_UP);
-  NAMETRICK2(CEC_USER_CONTROL_CODE_,CHANNEL_DOWN);
-  NAMETRICK2(CEC_USER_CONTROL_CODE_,PREVIOUS_CHANNEL);
-  NAMETRICK2(CEC_USER_CONTROL_CODE_,SOUND_SELECT);
-  NAMETRICK2(CEC_USER_CONTROL_CODE_,INPUT_SELECT);
-  NAMETRICK2(CEC_USER_CONTROL_CODE_,DISPLAY_INFORMATION);
-  NAMETRICK2(CEC_USER_CONTROL_CODE_,HELP);
-  NAMETRICK2(CEC_USER_CONTROL_CODE_,PAGE_UP);
-  NAMETRICK2(CEC_USER_CONTROL_CODE_,PAGE_DOWN);
-  NAMETRICK2(CEC_USER_CONTROL_CODE_,POWER );
-  NAMETRICK2(CEC_USER_CONTROL_CODE_,VOLUME_UP );
-  NAMETRICK2(CEC_USER_CONTROL_CODE_,VOLUME_DOWN );
-  NAMETRICK2(CEC_USER_CONTROL_CODE_,MUTE );
-  NAMETRICK2(CEC_USER_CONTROL_CODE_,PLAY );
-  NAMETRICK2(CEC_USER_CONTROL_CODE_,STOP );
-  NAMETRICK2(CEC_USER_CONTROL_CODE_,PAUSE );
-  NAMETRICK2(CEC_USER_CONTROL_CODE_,RECORD );
-  NAMETRICK2(CEC_USER_CONTROL_CODE_,REWIND );
-  NAMETRICK2(CEC_USER_CONTROL_CODE_,FAST_FORWARD );
-  NAMETRICK2(CEC_USER_CONTROL_CODE_,EJECT );
-  NAMETRICK2(CEC_USER_CONTROL_CODE_,FORWARD );
-  NAMETRICK2(CEC_USER_CONTROL_CODE_,BACKWARD );
-  NAMETRICK2(CEC_USER_CONTROL_CODE_,STOP_RECORD );
-  NAMETRICK2(CEC_USER_CONTROL_CODE_,PAUSE_RECORD );
-  NAMETRICK2(CEC_USER_CONTROL_CODE_,ANGLE );
-  NAMETRICK2(CEC_USER_CONTROL_CODE_,SUB_PICTURE );
-  NAMETRICK2(CEC_USER_CONTROL_CODE_,VIDEO_ON_DEMAND );
-  NAMETRICK2(CEC_USER_CONTROL_CODE_,ELECTRONIC_PROGRAM_GUIDE );
-  NAMETRICK2(CEC_USER_CONTROL_CODE_,TIMER_PROGRAMMING );
-  NAMETRICK2(CEC_USER_CONTROL_CODE_,INITIAL_CONFIGURATION );
-  NAMETRICK2(CEC_USER_CONTROL_CODE_,PLAY_FUNCTION );
-  NAMETRICK2(CEC_USER_CONTROL_CODE_,PAUSE_PLAY_FUNCTION );
-  NAMETRICK2(CEC_USER_CONTROL_CODE_,RECORD_FUNCTION );
-  NAMETRICK2(CEC_USER_CONTROL_CODE_,PAUSE_RECORD_FUNCTION );
-  NAMETRICK2(CEC_USER_CONTROL_CODE_,STOP_FUNCTION );
-  NAMETRICK2(CEC_USER_CONTROL_CODE_,MUTE_FUNCTION );
-  NAMETRICK2(CEC_USER_CONTROL_CODE_,RESTORE_VOLUME_FUNCTION );
-  NAMETRICK2(CEC_USER_CONTROL_CODE_,TUNE_FUNCTION );
-  NAMETRICK2(CEC_USER_CONTROL_CODE_,SELECT_MEDIA_FUNCTION );
-  NAMETRICK2(CEC_USER_CONTROL_CODE_,SELECT_AV_INPUT_FUNCTION );
-  NAMETRICK2(CEC_USER_CONTROL_CODE_,SELECT_AUDIO_INPUT_FUNCTION );
-  NAMETRICK2(CEC_USER_CONTROL_CODE_,POWER_TOGGLE_FUNCTION );
-  NAMETRICK2(CEC_USER_CONTROL_CODE_,POWER_OFF_FUNCTION );
-  NAMETRICK2(CEC_USER_CONTROL_CODE_,POWER_ON_FUNCTION );
-  NAMETRICK2(CEC_USER_CONTROL_CODE_,F1_BLUE );
-  NAMETRICK2(CEC_USER_CONTROL_CODE_,F2_RED );
-  NAMETRICK2(CEC_USER_CONTROL_CODE_,F3_GREEN );
-  NAMETRICK2(CEC_USER_CONTROL_CODE_,F4_YELLOW );
-  NAMETRICK2(CEC_USER_CONTROL_CODE_,F5 );
-  NAMETRICK2(CEC_USER_CONTROL_CODE_,DATA );
-  NAMETRICK2(CEC_USER_CONTROL_CODE_,AN_RETURN );
-  NAMETRICK2(CEC_USER_CONTROL_CODE_,AN_CHANNELS_LIST );
-  NAMETRICK2(CEC_USER_CONTROL_CODE_,MAX );
 }
 
-
-
 char* InputLinux::HCWDesc(unsigned long long hcw)
 {
-    //Determine type
-    unsigned int type = static_cast<unsigned int>(hcw >> 32);
-    unsigned int vk = static_cast<ULONG>(hcw);
-    char* rt = NULL;
-
-    switch(type)
-    {
-      case W_HCW_KC:
-      {
-        rt = new char[10];
-        const char *desc=linux_keymap[vk];
-        if (desc)
-          strncpy(rt, desc, 9);
-        else
-          sprintf(rt, "0x%x", vk);
-        break;
-      }
-      case W_HCW_CEC:
-      {
-        rt = new char[10];
-        const char* desc = cec_keymap[vk];
-        if (desc)
-          strncpy(rt, desc, 9);
-        else
-          sprintf(rt, "0x%x", vk);
-        break;
-      }
-  /*
-    case W_HCW_LIRC:{
-        ULONG ri=(ULONG)hcw;
-        rt=new char[10];
-        sprintf(rt,"R: %X",ri);
-                  }break;*/
-    }
+  unsigned int vk = static_cast<ULONG>(hcw); // FIXME
+  char* rt = new char[10];
+  const char* desc = linux_keymap[vk];
+  if (desc)
+    strncpy(rt, desc, 9);
+  else
+    sprintf(rt, "0x%x", vk);
 
-    return rt;
+  return rt;
 }
 
-void InputLinux::changePowerState(bool poweron)
+bool InputLinux::start()
 {
-  if (cec_adap)
-  {
-    if (poweron)
-    {
-      //Log::getInstance()->log("InputLinux", Log::DEBUG, "CEC set active source");
-      cec_adap->SetActiveSource(cec_config.deviceTypes[0]);
-    }
-    else
-    {
-      //Log::getInstance()->log("InputLinux", Log::DEBUG, "CEC set inactive view");
-      cec_adap->SetInactiveView();
-    }
-  }
-}
-
-#if CEC_LIB_VERSION_MAJOR >= 4
+  Log::getInstance()->log("Input", Log::INFO, "start called");
 
-// libcec4 API changed these params to pointers rather than copies, and the returns to void
-// Otherwise, these two blocks of code are the same
-
-void InputLinux::cecLogMessage(void* /* param */, const cec_log_message* message)
-{
-  Log::getInstance()->log("InputLinux", Log::DEBUG, "CECLOG: %lld %d %s", message->time, message->level, message->message);
-}
-
-void InputLinux::cecKeyPress(void* /* param */, const cec_keypress* key)
-{
-  //Log::getInstance()->log("InputLinux", Log::DEBUG, "Incoming cec key %d %d", key->keycode,key->duration);
-  if (key->duration == 0) static_cast<InputLinux*>(Input::getInstance())->incomingCECkey(key->keycode);
-}
-
-void InputLinux::cecCommand(void* /* param */, const cec_command* command)
-{
-       Log::getInstance()->log("InputLinux", Log::DEBUG, "CECCommand: %d",command->opcode);
-       switch (command->opcode) {
-       case CEC_OPCODE_STANDBY: {
-               if (command->initiator==CECDEVICE_TV) {
-                       static_cast<InputLinux*>(Input::getInstance())->incomingPowerkey(POWEROFF);
-               }
-       } break;
-       case CEC_OPCODE_DECK_CONTROL: {
-               if (command->initiator==CECDEVICE_TV && command->parameters.size == 1
-                               && command->parameters[0]==CEC_DECK_CONTROL_MODE_STOP) {
-                       static_cast<InputLinux*>(Input::getInstance())->incomingCECkey(CEC_USER_CONTROL_CODE_STOP);
-
-               }
-
-       } break;
-       case CEC_OPCODE_PLAY: {
-               if (command->initiator==CECDEVICE_TV && command->parameters.size == 1) {
-                       if (command->parameters[0]==CEC_PLAY_MODE_PLAY_FORWARD) {
-                               static_cast<InputLinux*>(Input::getInstance())->incomingCECkey(CEC_USER_CONTROL_CODE_PLAY);
-                       } else if (command->parameters[0]==CEC_PLAY_MODE_PLAY_STILL) {
-                               static_cast<InputLinux*>(Input::getInstance())->incomingCECkey(CEC_USER_CONTROL_CODE_PAUSE);
-                       }
-               }
-
-
-       } break;
-       default:
-               break;
-       };
-}
-
-void InputLinux::cecConfigurationChanged(void* /* param */, const libcec_configuration*)
-{
-       Log::getInstance()->log("InputLinux", Log::DEBUG, "CECConfig:"/*,config->string()*/);
-}
-
-#else
-
-int InputLinux::cecLogMessage(void *param, const cec_log_message message)
-{
-  Log::getInstance()->log("InputLinux", Log::DEBUG, "CECLOG: %lld %d %s", message.time, message.level, message.message);
-  return 0;
-}
-
-int InputLinux::cecKeyPress(void*param, const cec_keypress key)
-{
-  //Log::getInstance()->log("InputLinux", Log::DEBUG, "Incoming cec key %d %d", key.keycode,key.duration);
-  if (key.duration == 0) ((InputLinux*)Input::getInstance())->incomingCECkey(key.keycode);
-  return 1;
-}
-
-int InputLinux::cecCommand(void *param, const cec_command command)
-{
-       Log::getInstance()->log("InputLinux", Log::DEBUG, "CECCommand: %d",command.opcode);
-       switch (command.opcode) {
-       case CEC_OPCODE_STANDBY: {
-               if (command.initiator==CECDEVICE_TV) {
-                       ((InputLinux*)Input::getInstance())->incomingPowerkey(POWEROFF);
-               }
-       } break;
-       case CEC_OPCODE_DECK_CONTROL: {
-               if (command.initiator==CECDEVICE_TV && command.parameters.size == 1
-                               && command.parameters[0]==CEC_DECK_CONTROL_MODE_STOP) {
-                       ((InputLinux*)Input::getInstance())->incomingCECkey(CEC_USER_CONTROL_CODE_STOP);
-
-               }
-
-       } break;
-       case CEC_OPCODE_PLAY: {
-               if (command.initiator==CECDEVICE_TV && command.parameters.size == 1) {
-                       if (command.parameters[0]==CEC_PLAY_MODE_PLAY_FORWARD) {
-                               ((InputLinux*)Input::getInstance())->incomingCECkey(CEC_USER_CONTROL_CODE_PLAY);
-                       } else if (command.parameters[0]==CEC_PLAY_MODE_PLAY_STILL) {
-                               ((InputLinux*)Input::getInstance())->incomingCECkey(CEC_USER_CONTROL_CODE_PAUSE);
-                       }
-               }
-
-
-       } break;
-       default:
-               break;
-       };
-       return 1;
-}
-
-int InputLinux::cecConfigurationChanged(void *param, const libcec_configuration config)
-{
-       Log::getInstance()->log("InputLinux", Log::DEBUG, "CECConfig:"/*,config.string()*/);
-       return 1;
-
-}
-
-#endif
-
-void  InputLinux::cecSourceActivated(void* /* param */, const cec_logical_address address, const uint8_t activated)
-{
-  Log::getInstance()->log("InputLinux", Log::DEBUG, "CECSourceActivated: %d %d", address, activated);
-  if (activated == 1)
-  {
-    static_cast<InputLinux*>(Input::getInstance())->incomingPowerkey(POWERON);
-  }
-}
-
-void InputLinux::incomingCECkey(int keys)
-{
-  // Send INPUT message
-  Message* m = new Message();
-  m->message = Message::INPUT_EVENT;
-  m->to = Command::getInstance();
-  m->from = this;
-  m->parameter = static_cast<UCHAR>(TranslateHWC(W_G_HCW(W_HCW_CEC, keys)));
-  MessageQueue::getInstance()->postMessage(m);
-}
-
-void InputLinux::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);
-}
-
-bool InputLinux::loadOptionsfromServer(VDR* vdr)
-{
-   // Set remote keys
-  char* name;
-  name = vdr->configLoad("InputLinux", "HandleVolume");
-
-  if (name != NULL)
+  threadStartProtect.lock(); // Make sure listenThread is fully initted before start returns
+  listenThread = std::thread( [this]
   {
-    if      (STRCASECMP(name, "Vomp") == 0) cechandlesvolume = false;
-    else if (STRCASECMP(name, "Cec") == 0) cechandlesvolume = true;
-    delete[] name;
-  }
-  return Input::loadOptionsfromServer(vdr);
-}
-
-bool InputLinux::saveOptionstoServer()
-{
-  if (cechandlesvolume) VDR::getInstance()->configSave("InputLinux", "HandleVolume","Cec");
-  else VDR::getInstance()->configSave("InputLinux", "HandleVolume","Vomp");
-
-  return Input::saveOptionstoServer();
+    threadStartProtect.lock();
+    threadStartProtect.unlock();
+    listenLoop();
+  });
+  threadStartProtect.unlock();
+  return true;
 }
 
-bool InputLinux::addOptionsToPanes(int panenumber,Options *options,WOptionPane* pane)
+void InputLinux::stop()
 {
-  if (!Input::addOptionsToPanes(panenumber, options, pane)) return false;
+  threadStartProtect.lock(); // Also use it to protect against starting while stopping
 
-  Option* option;
-  if (panenumber == 2)
+  if (listenThread.joinable())
   {
-    static const char* volumeopts[]={"Vomp","Cec"};
-    option = new Option(100,tr("Volume handled by"), "InputLinux","HandleVolume",Option::TYPE_TEXT,/*4,2*/2,0,0,volumeopts,NULL,false,this);
-    options->push_back(option);
-    pane->addOptionLine(option);
+    listenLoopStop = true;
+    write(pfds[1], "1", 1); // break the select in listenLoop
+    listenThread.join();
   }
 
-  return true;
-}
-
-bool InputLinux::handleOptionChanges(Option* option)
-{
-    if (Input::handleOptionChanges(option))
-               return true;
-       switch (option->id) {
-       case 100: {
-               if (STRCASECMP(option->options[option->userSetChoice], "Vomp") == 0) {
-                       cechandlesvolume=false;
-               }  else if (STRCASECMP(option->options[option->userSetChoice], "Cec")
-                               == 0) {
-                       cechandlesvolume=true;
-               }
-               Log::getInstance()->log("InputLinux", Log::DEBUG, "Set volume handling to to %s %d",option->options[option->userSetChoice],cechandlesvolume);
-               return true;
-       }
-       break;
-       };
-       return false;
-
-}
-
-void InputLinux::volumeUp()
-{
-  cec_adap->VolumeUp();
-}
-
-void InputLinux::volumeDown()
-{
-  cec_adap->VolumeDown();
-}
-
-void InputLinux::volumeMute()
-{
-#if CEC_LIB_VERSION_MAJOR >= 4
-  cec_adap->AudioToggleMute();
-#else
-  cec_adap->MuteAudio();
-#endif
-}
-
-void InputLinux::informStopEventLoop()
-{
-  listenLoopStop = true;
-  write(pfds[1], "1", 1); // break the select in getButtonPress
+  threadStartProtect.unlock();
 }
 
-void InputLinux::eventLoop()
+void InputLinux::listenLoop()
 {
   fd_set readfds;
   int maxfd;
@@ -1112,7 +569,8 @@ void InputLinux::eventLoop()
             m->message = Message::INPUT_EVENT;
             m->to = Command::getInstance();
             m->from = this;
-            m->parameter = static_cast<UCHAR>(TranslateHWC(W_G_HCW(W_HCW_KC,ev.code)));
+//            m->parameter = static_cast<UCHAR>(TranslateHWC_KC(ev.code));
+            m->parameter = TranslateHWC(ev.code);
             MessageQueue::getInstance()->postMessage(m);
           }
         }
index bfd293fdaf71d7987dbef6b1af04edd0ddb00727..3d8d51db01b593edf92ca09535abdfda7e2ec25d 100644 (file)
 #define INPUTLINUX_H
 
 #include <stdio.h>
-#include <libcec/cec.h>
 #include <vector>
 
 #include "defines.h"
-#include "log.h"
 #include "input.h"
 
 class InputLinux : public Input
 {
   public:
-    InputLinux();
-    virtual ~InputLinux();
+    int init();
+    void shutdown();
 
-    int init(const char *devName);
-    int shutdown();
-    int getDevice();
-    UCHAR getButtonPress(int) { return NA_UNKNOWN; } // DEPRECATED
-  //  void Signal();
-
-//  void SendPower();
-    void InitHWCListwithDefaults();
-    const char*HardcodedTranslateStr(UCHAR command);
     char* HCWDesc(ULLONG hcw);
-    
-    void changePowerState(bool poweron);
-
-    bool loadOptionsfromServer(VDR* vdr);
-    bool saveOptionstoServer();
-    bool addOptionsToPanes(int panenumber,Options *options,WOptionPane* pane);
-    bool handleOptionChanges(Option* option);
 
-    bool mayHaveFewButtons() {return true;};
+    bool start();
+    void stop();
 
-    virtual bool handlesVolume() { return cechandlesvolume; };
-    virtual void volumeUp();
-    virtual void volumeDown();
-    virtual void volumeMute();
-
-    int initCec();
-    void deinitCec();
-
-  private: 
+  private:
     int initted{};
-    bool signal{};
-    bool cechandlesvolume{};
 
-    UCHAR TranslateHWCFixed(ULLONG code);
     void InitKeymap();
-    std::vector<int> devices;
-    int num_loop{};
-
-    CEC::ICECAdapter* cec_adap{};
-    CEC::libcec_configuration cec_config;
-    CEC::ICECCallbacks cec_callbacks;
-
-    void incomingCECkey(int keys);
-    void incomingPowerkey(UCHAR key);
-
-#if CEC_LIB_VERSION_MAJOR >= 4
-    static void cecLogMessage(void *param, const CEC::cec_log_message* message);
-    static void cecKeyPress(void*param, const CEC::cec_keypress* key);
-    static void cecCommand(void *param, const CEC::cec_command* command);
-    static void cecConfigurationChanged(void *param, const CEC::libcec_configuration* config);
-#else
-    static int cecLogMessage(void *param, const CEC::cec_log_message message);
-    static int cecKeyPress(void*param, const CEC::cec_keypress key);
-    static int cecCommand(void *param, const CEC::cec_command command);
-    static int cecConfigurationChanged(void *param, const CEC::libcec_configuration config);
-#endif
-    static void cecSourceActivated(void*param, const CEC::cec_logical_address address, const uint8_t activated);
+    void InitHWCListwithDefaults();
+    UCHAR TranslateHWCFixed(int code);
 
-    void eventLoop();
-    void informStopEventLoop();
+    std::vector<int> devices;
 
+    std::thread listenThread;
+    std::mutex threadStartProtect;
+    void listenLoop();
+    bool listenLoopStop{};
     int pfds[2];
 };
 
diff --git a/inputman.cc b/inputman.cc
new file mode 100644 (file)
index 0000000..752b017
--- /dev/null
@@ -0,0 +1,275 @@
+/*
+    Copyright 2020 Chris Tallon; 2012 Marten Richter
+
+    This file is part of VOMP.
+
+    VOMP is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    VOMP is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with VOMP.  If not, see <https://www.gnu.org/licenses/>.
+*/
+
+#include "log.h"
+#include "wremoteconfig.h"
+#include "wtabbar.h"
+#include "inputlinux.h"
+#include "inputcec.h"
+#include "i18n.h"
+#include "input.h"
+
+#include "inputman.h"
+
+InputMan* InputMan::instance = NULL;
+
+InputMan::InputMan()
+{
+  instance = this;
+}
+
+InputMan::~InputMan()
+{
+  instance = NULL;
+}
+
+InputMan* InputMan::getInstance()
+{
+  return instance;
+}
+
+bool InputMan::init()
+{
+  bool i1{}, i2{};
+
+#ifdef VOMP_PLATFORM_RASPBERRY
+  inputLinux = new InputLinux();
+  i1 = inputLinux->init();
+  if (!i1) { delete inputLinux; inputLinux = NULL; }
+
+//  inputCEC = new InputCEC();
+//  i2 = inputCEC->init();
+//  if (!i2) { delete inputCEC; inputCEC = NULL; }
+#endif
+
+  if (!i1 && !i2)
+  {
+    Log::getInstance()->log("InputMan", Log::CRIT, "InputMan could not init any input module");
+    return false;
+  }
+
+  initted = true;
+  return true;
+}
+
+bool InputMan::start()
+{
+  bool i1{};
+
+  if (inputLinux)
+  {
+    i1 = inputLinux->start();
+  }
+
+  return i1;
+}
+
+void InputMan::stop()
+{
+  if (inputLinux) inputLinux->stop();
+}
+
+void InputMan::shutdown()
+{
+  Log::getInstance()->log("InputMan", Log::DEBUG, "Shutdown start");
+
+  if (inputLinux)
+  {
+    Log::getInstance()->log("InputMan", Log::DEBUG, "Shutdown start - Linux");
+    inputLinux->stop();
+    inputLinux->shutdown();
+    delete inputLinux;
+    inputLinux = NULL;
+  }
+
+  if (inputCEC)
+  {
+    Log::getInstance()->log("InputMan", Log::DEBUG, "Shutdown start - CEC");
+    inputCEC->shutdown();
+    delete inputCEC;
+    inputCEC = NULL;
+  }
+
+  initted = false;
+}
+
+bool InputMan::mayHaveFewButtons()
+{
+  // 052 returned true if remotelinux was in effect - linux or CEC. What was it for?
+
+  if (inputLinux || inputCEC) return true;
+  return false;
+}
+
+bool InputMan::handlesVolume()
+{
+  if (!inputCEC) return false;
+  return inputCEC->handlesVolume();
+}
+
+void InputMan::volumeUp()
+{
+  if (inputCEC) inputCEC->volumeUp();
+}
+
+void InputMan::volumeDown()
+{
+  if (inputCEC) inputCEC->volumeDown();
+}
+
+void InputMan::volumeMute()
+{
+  if (inputCEC) inputCEC->volumeMute();
+}
+
+void InputMan::changePowerState(bool powerOn)
+{
+  if (inputCEC) inputCEC->changePowerState(powerOn);
+}
+
+bool InputMan::addOptionsToPanes(int panenumber, Options* options, WOptionPane* pane)
+{
+  if (inputLinux) inputLinux->addOptionsToPanes(panenumber, options, pane);
+  if (inputCEC) inputCEC->addOptionsToPanes(panenumber, options, pane);
+
+  return true; // FIXME
+}
+
+bool InputMan::addOptionPagesToWTB(WTabBar *wtb)
+{
+  //if (inputLinux) inputLinux->addOptionPagesToWTB(wtb);
+  //if (inputCEC) inputCEC->addOptionPagesToWTB(wtb);
+
+  WRemoteConfig* wrc = new WRemoteConfig();
+  wtb->addTab(tr("Remote Control"), wrc);
+
+  return true; // FIXME
+}
+
+bool InputMan::saveOptionstoServer()
+{
+  if (inputLinux) inputLinux->saveOptionstoServer();
+  if (inputCEC) inputCEC->saveOptionstoServer();
+
+  return true; // FIXME
+}
+
+const char* InputMan::CommandDesc(UCHAR number)
+{
+  switch (number)
+  {
+    case Input::VOLUMEUP:
+      return tr("Volume Up");
+    case Input::VOLUMEDOWN:
+      return tr("Volume Down");
+    case Input::CHANNELUP:
+      return tr("Channel up");
+    case Input::CHANNELDOWN:
+      return tr("Channel down");
+    case Input::ZERO:
+      return "0";
+    case Input::ONE:
+      return "1";
+    case Input::TWO:
+      return "2";
+    case Input::THREE:
+      return "3";
+    case Input::FOUR:
+      return "4";
+    case Input::FIVE:
+      return "5";
+    case Input::SIX:
+      return "6";
+    case Input::SEVEN:
+      return "7";
+    case Input::EIGHT:
+      return "8";
+    case Input::NINE:
+      return "9";
+    case Input::POWER:
+      return tr("Power");
+    case Input::GO:
+      return tr("Go");
+    case Input::BACK:
+      return tr("Back");
+    case Input::MENU:
+      return tr("Menu");
+    case Input::RED:
+      return tr("Red");
+    case Input::GREEN:
+      return tr("Green");
+    case Input::YELLOW:
+      return tr("Yellow");
+    case Input::BLUE:
+      return tr("Blue");
+    case Input::MUTE:
+      return tr("Mute");
+    case Input::RADIO:
+      return tr("Radio");
+    case Input::REVERSE:
+      return tr("Reverse");
+    case Input::PLAY:
+      return tr("Play");
+    case Input::FORWARD:
+      return tr("Forward");
+    case Input::RECORD:
+      return tr("Record");
+    case Input::STOP:
+      return tr("Stop");
+    case Input::PAUSE:
+      return tr("Pause");
+    case Input::SKIPBACK:
+      return tr("Skip back");
+    case Input::SKIPFORWARD:
+      return tr("Skip forward");
+    case Input::OK:
+      return tr("Ok");
+    case Input::FULL:
+      return tr("Fullscreen");
+    case Input::TV:
+      return tr("TV");
+    case Input::VIDEOS:
+      return tr("Videos");
+    case Input::MUSIC:
+      return tr("Music");
+    case Input::PICTURES:
+      return tr("Pictures");
+    case Input::GUIDE:
+      return tr("Guide");
+    case Input::UP:
+      return tr("Up");
+    case Input::DOWN:
+      return tr("Down");
+    case Input::LEFT:
+      return tr("Left");
+    case Input::RIGHT:
+      return tr("Right");
+    case Input::PREVCHANNEL:
+      return tr("Previous Channel");
+    case Input::STAR:
+      return tr("Star");
+    case Input::HASH:
+      return tr("Hash");
+    case Input::PLAYPAUSE:
+       return tr("Play/Pause");
+
+    default:
+      return NULL;
+  }
+}
diff --git a/inputman.h b/inputman.h
new file mode 100644 (file)
index 0000000..de89dee
--- /dev/null
@@ -0,0 +1,133 @@
+/*
+    Copyright 2020 Chris Tallon
+
+    This file is part of VOMP.
+
+    VOMP is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    VOMP is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with VOMP.  If not, see <https://www.gnu.org/licenses/>.
+*/
+
+#ifndef INPUTMAN_H
+#define INPUTMAN_H
+
+/*
+The plan:
+
+The old design had an abstract Remote class with a single Remote* (RemoteWin, RemoteLinux, RemoteLirc)
+instantiating.
+
+The new design is:
+
+A single RemoteMan object will look after several Input devices. RemoteMan will have getInstance().
+
+An abstract Input class (old Remote) defines common stuff about input devices.
+
+Many Input* objects may exist at the same time. They will be:
+
+InputLinux
+InputCEC
+InputUDP
+InputWin
+InputLirc
+
+Obviously Linux and Win won't be active simultaneously. UDP will roll in the UDP button receiver
+into this input system.
+
+The old design grew out of the fact the main thread waited on Remote::getButtonPress. Now the main
+thread waits on the MessageQueue. The input system should be separate, run in its own threads and
+should insert messages to the queue on input.
+
+Benefits:
+
+It would be nice if the input system could boot up in its own time, not delaying the rest of the
+program, but this may not be achievable.
+
+In the future it will be possible to implement hot plugging of USB input devices. (Currently vomp
+only uses what is present at vomp-startup).
+
+The CEC code can be removed from InputLinux. Under the new design they are nothing to do with
+each other.
+
+Direct Lirc input can be brought back - probably very easily. TODO
+
+Input objects can be easily and individually enabled / disabled.
+
+New types of input can be implemented much easier.
+
+For now, two decisions to make things a bit easier:
+
+1. InputMan will hardcode knowledge about the Input types with hard pointers to each. In future
+   perhaps this will change to a dynamic list of Input objects where InputMan refers to them
+   through the Input interface only.
+
+2. InputLinux will continue to represent all devices found in /dev/input. If there is a good
+   reason in future then this should switch to several InputLinux objects representing one
+   device each.
+
+*/
+
+#include "defines.h"
+#include "abstractoption.h"
+
+class InputLinux;
+class InputCEC;
+class InputWin;
+class InputUDP;
+class InputLirc;
+
+class InputMan: public AbstractOption
+{
+  public:
+    InputMan();
+    virtual ~InputMan();
+    static InputMan* getInstance();
+
+    bool init();
+    void shutdown();
+
+    bool start(); // MessageQueue should be ready before this is called
+    void stop(); // Nothing should be sent to MQ after this
+
+    bool mayHaveFewButtons();
+
+    bool handlesVolume(); // Returns true if we have an InputCEC willing to handle volume
+    void volumeUp();
+    void volumeDown();
+    void volumeMute();
+    void changePowerState(bool powerOn);
+
+    // Abstract Option interface
+    bool addOptionPagesToWTB(WTabBar* wtb);
+    bool addOptionsToPanes(int panenumber, Options* options, WOptionPane* pane);
+    bool saveOptionstoServer();
+
+    static const char* CommandDesc(UCHAR number);
+
+  private:
+    static InputMan* instance;
+
+    InputLinux* inputLinux{};
+    InputCEC* inputCEC{};
+    InputWin* inputWin{};
+    InputUDP* inputUDP{};
+    InputLirc* inputLirc{};
+
+    bool initted{};
+};
+
+#endif
+
+// TODO idea:
+// don't have Input inherit AbstractOption, just individual inputs. Then one day could test with
+// dynamic_cast whether to call the AO IF stuff on them
+// could also have a CEC IF and do the same?
diff --git a/main.cc b/main.cc
index 70067d27372f8ab777f078184da93f8e4b210e42..efe6bc82905ae82d63f7d017d81f91e0094c0051 100644 (file)
--- a/main.cc
+++ b/main.cc
@@ -25,6 +25,7 @@
 #include <unistd.h>
 #include <endian.h>
 #endif
+#include <thread>
 
 #include "defines.h"
 
@@ -41,7 +42,6 @@
 
 #ifdef VOMP_PLATTFORM_NMT
 
-#include "remotelirc.h"
 #include "lednmt.h"
 #include "osddirectfb.h"
 #include "audionmt.h"
@@ -51,7 +51,6 @@
 
 #ifdef VOMP_PLATFORM_RASPBERRY
 
-#include "inputlinux.h"
 #include "ledraspberry.h"
 #include "osdopenvg.h"
 #include "audioomx.h"
@@ -59,7 +58,7 @@
 
 #endif
 
-
+#include "inputman.h"
 #include "wol.h"
 #include "vsleeptimer.h"
 
@@ -72,7 +71,7 @@ void shutdown(int code);
 
 // Global variables --------------------------------------------------------------------------------------------------
 Log* logger;
-Input* remote;
+InputMan* inputMan;
 Led* led;
 Osd* osd;
 Timers* timers;
@@ -127,21 +126,19 @@ int main(int argc, char** argv)
   logger     = new Log();
   timers     = new Timers();
   vdr        = new VDR();
+  inputMan   = new InputMan();
 
-  remote     = new Remote_TYPE();
   led        = new Led_TYPE();
   osd        = new Osd_TYPE();
   audio      = new Audio_TYPE();
   video      = new Video_TYPE();
 
-
-
   boxstack   = new BoxStack();
   command    = new Command();
   wol        = new Wol();
   sleeptimer = new Sleeptimer();
 
-  if (!logger || !remote || !led || !osd || !video || !audio || !boxstack || !command || !wol || !sleeptimer)
+  if (!logger || !inputMan || !led || !osd || !video || !audio || !boxstack || !command || !wol || !sleeptimer)
   {
     printf("Could not create objects. Memory problems?\n");
     shutdown(1);
@@ -194,77 +191,49 @@ int main(int argc, char** argv)
   std::thread threadSignalReceiver(threadSignalReceiverFunction);
   threadSignalReceiver.detach();
 
-  /*
-  sighandler_t sigtest;
+  logger->log("Core", Log::INFO, "Signal handlers set up successfully");
 
-  sigtest = signal(SIGPIPE, SIG_IGN);
-  if (sigtest == SIG_ERR)
-  {
-    logger->log("Core", Log::EMERG, "Could not set up signal handler for SIGPIPE. Aborting.");
-    shutdown(1);
-  }
-  sigtest = signal(SIGINT, sighandler);
-  if (sigtest == SIG_ERR)
-  {
-    logger->log("Core", Log::EMERG, "Could not set up signal handler for SIGINT. Aborting.");
-    shutdown(1);
-  }
-  sigtest = signal(SIGTERM, sighandler);
-  if (sigtest == SIG_ERR)
-  {
-    logger->log("Core", Log::EMERG, "Could not set up signal handler for SIGTERM. Aborting.");
-    shutdown(1);
-  }
-  sigtest = signal(SIGUSR1, sighandler);
-  if (sigtest == SIG_ERR)
-  {
-    logger->log("Core", Log::EMERG, "Could not set up signal handler for SIGUSR1. Aborting.");
-    shutdown(1);
-  }
-  sigtest = signal(SIGUSR2, sighandler);
-  if (sigtest == SIG_ERR)
+  // VT Switching -----------------------------------------------------------------------------------------------
+
+#ifdef HANDLE_VT_SWITCHING
+  if (
+
+
+    (fdtty = open("/dev/tty", O_WRONLY),0) == -1   // FIXME. Why the ,0 ? Surely this kills the log line below
+
+
+  )
   {
-    logger->log("Core", Log::EMERG, "Could not set up signal handler for SIGUSR2. Aborting.");
-    shutdown(1);
+    logger->log("Core", Log::EMERG, "Could not open /dev/tty. Please change permissions");
   }
-  sigtest = signal(SIGURG, sighandler);
-  if (sigtest == SIG_ERR)
+  else
   {
-    logger->log("Core", Log::EMERG, "Could not set up signal handler for SIGURG. Aborting.");
-    shutdown(1);
-  }
-  */
-
-  logger->log("Core", Log::INFO, "Signal handlers set up successfully");
-
-#ifdef HANDLE_VT_SWITCHING
-  if ((fdtty = open("/dev/tty", O_WRONLY),0) == -1) {
-         logger->log("Core", Log::EMERG, "Could not open /dev/tty. Please change permissions");
-  } else {
-         int free_vt;
-         if (ioctl(fdtty,VT_OPENQRY,&free_vt)==-1 || free_vt==-1){
-                 logger->log("Core", Log::EMERG, "Could not retrieve free virtual console, please change permissions");
-         } else {
-                 ioctl(fdtty,VT_ACTIVATE,free_vt);
-                 ioctl(fdtty,VT_WAITACTIVE,free_vt);
-                 ioctl(fdtty, VT_LOCKSWITCH, 1);
-         }
+    int free_vt;
+    if (ioctl(fdtty, VT_OPENQRY, &free_vt) == -1 || free_vt == -1)
+    {
+      logger->log("Core", Log::EMERG, "Could not retrieve free virtual console, please change permissions");
+    }
+    else
+    {
+      ioctl(fdtty, VT_ACTIVATE, free_vt);
+      ioctl(fdtty, VT_WAITACTIVE, free_vt);
+      ioctl(fdtty, VT_LOCKSWITCH, 1);
+    }
   }
-
 #endif
 
   // Init modules ----------------------------------------------------------------------------------------------------
   int success;
 
-  success = remote->init(RemoteStartDev);
+  success = inputMan->init();
 
   if (success)
   {
-    logger->log("Core", Log::INFO, "Remote module initialised");
+    logger->log("Core", Log::INFO, "InputMan module initialised");
   }
   else
   {
-    logger->log("Core", Log::EMERG, "Remote module failed to initialise");
+    logger->log("Core", Log::EMERG, "InputMan module failed to initialise");
     shutdown(1);
   }
 
@@ -457,11 +426,11 @@ void shutdown(int code)
     logger->log("Core", Log::NOTICE, "LED module shut down");
   }
 
-  if (remote)
+  if (inputMan)
   {
-    remote->shutdown();
-    delete remote;
-    logger->log("Core", Log::NOTICE, "Remote module shut down");
+    inputMan->shutdown();
+    delete inputMan;
+    logger->log("Core", Log::NOTICE, "InputMan module shut down");
   }
 
   if (wol)
index 2f630979ddd63952d1d4206bedc4aae7f25040a9..6c806956d0e0fa8708211fcb4c50495af2a4783d 100644 (file)
@@ -2,7 +2,7 @@ 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    \
              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                           \
+             demuxer.o demuxervdr.o demuxerts.o stream.o inputman.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             \
@@ -22,7 +22,7 @@ OBJ_COMMON = command.o tcp.o dsock.o thread.o timers.o i18n.o vdp6.o
 
 OBJ_RASPBERRY = main.o threadp.o osdopenvg.o                                       \
                 ledraspberry.o videoomx.o audioomx.o imageomx.o                    \
-                wjpegsimple.o inputlinux.o signal.o
+                wjpegsimple.o inputlinux.o inputcec.o signal.o
 
 OBJ_WINDOWS = winmain.o threadwin.o remotewin.o ledwin.o videowin.o                \
               audiowin.o windowsosd.o dsallocator.o dssourcefilter.o dssourcepin.o \
index 2e0d2604ee58eb7364528cbd18c38839985f2941..eb815a062064b2b94b108ea19ba7a8bf310db68b 100644 (file)
@@ -474,7 +474,6 @@ int VAudioSelector::handleCommand(int command)
     {
       return 4;
     }
-    case Input::DF_UP:
     case Input::UP:
     {
         if (editsubtitles) {
@@ -501,7 +500,6 @@ int VAudioSelector::handleCommand(int command)
 
       return 2;
     }
-    case Input::DF_DOWN:
     case Input::DOWN:
     {
         if (editsubtitles) {
@@ -531,7 +529,6 @@ int VAudioSelector::handleCommand(int command)
       return 2;
     }
     case Input::LEFT:
-    case Input::DF_LEFT:
      {
         if (editsubtitles && subtitles) {
             ssl.setDarkSelOption(true);
@@ -544,7 +541,6 @@ int VAudioSelector::handleCommand(int command)
         return 2;
      }
      case Input::RIGHT:
-     case Input::DF_RIGHT:
      {
          if (!editsubtitles && subtitles) {
              ssl.setDarkSelOption(false);
index 7d1edae305d4ac7df692f43fb2b4c9ca4989a4f6..04767b3d4dea1ed2cdd6369491180957ddd596bc 100644 (file)
@@ -186,7 +186,6 @@ int VChannelList::handleCommand(int command)
 {
   switch(command)
   {
-    case Input::DF_UP:
     case Input::UP:
     {
       sl.up();
@@ -195,7 +194,6 @@ int VChannelList::handleCommand(int command)
       boxstack->update(this);
       return 2;
     }
-    case Input::DF_DOWN:
     case Input::DOWN:
     {
       sl.down();
diff --git a/vepg.cc b/vepg.cc
index 676b896e4de8793dae9bee8d3fa9a6de731a8ae9..7b29111bc5d45c6047e3d5122419c6345cb84acd 100644 (file)
--- a/vepg.cc
+++ b/vepg.cc
@@ -356,7 +356,6 @@ int VEpg::handleCommand(int command)
 {
   switch(command)
   {
-    case Input::DF_UP:
     case Input::UP:
     { // cursor up the channel list
       chanListbox.up();
@@ -364,7 +363,6 @@ int VEpg::handleCommand(int command)
       boxstack->update(this);
       return 2;
     }
-    case Input::DF_DOWN:
     case Input::DOWN:
     { // cursor down the channel list
       Log::getInstance()->log("VEPG", Log::DEBUG, "Down start");
@@ -376,7 +374,6 @@ int VEpg::handleCommand(int command)
 
       return 2;
     }
-    case Input::DF_LEFT:
     case Input::LEFT:
     { // cursor left through time
       selTime = thisEvent.time - 1;
@@ -384,7 +381,6 @@ int VEpg::handleCommand(int command)
       boxstack->update(this);
       return 2;
     }
-    case Input::DF_RIGHT:
     case Input::RIGHT:
     {
     // cursor right through time
index 48f286ef2ecda187394a4564422f0f797df1743f..12a1951e4be6d0de43ee866e18c5045c2266235c 100644 (file)
@@ -769,7 +769,6 @@ int VEpgListAdvanced::handleCommand(int command)
 {
   switch(command)
   {
-    case Input::DF_UP:
     case Input::UP:
     {
       sl.up();
@@ -778,7 +777,6 @@ int VEpgListAdvanced::handleCommand(int command)
       boxstack->update(this);
       return 2;
     }
-    case Input::DF_DOWN:
     case Input::DOWN:
     {
       sl.down();
index 2f1bf3bd089bd6ef51b81e6882fe82fde1e52b65..f23e7480c6e96aa41b2ce8e03ff92eeb8904b140 100644 (file)
@@ -210,7 +210,6 @@ int VEpgSetTimer::handleCommand(int command)
 {
   switch(command)
   {
-    case Input::DF_LEFT:
     case Input::LEFT:
     {
       swap();
@@ -218,7 +217,6 @@ int VEpgSetTimer::handleCommand(int command)
       boxstack->update(this);
       return 2;
     }
-    case Input::DF_RIGHT:
     case Input::RIGHT:
     {
       swap();
index da5f26d90afb6a7a69007f0a52afe2ecfd1bddd0..54862a213dcb5aed6ddcd369fa021d01da856a7f 100644 (file)
@@ -25,7 +25,7 @@
 #include "woptionpane.h"
 #include "osdopenvg.h"
 #include "boxstack.h"
-#include "input.h"
+#include "inputman.h"
 
 #include <bcm_host.h>
 
@@ -471,7 +471,7 @@ void VideoOMX::selectVideoMode(int interlaced)
 
                        }
                }
-               Input::getInstance()->shutdown();
+               InputMan::getInstance()->shutdown();
                vc_tv_power_off();
                if (mymode) {
                        Log::getInstance()->log("Video", Log::NOTICE, "Switch to optimum mode");
@@ -489,7 +489,7 @@ void VideoOMX::selectVideoMode(int interlaced)
        } else {
                /* analog tv case */
                Log::getInstance()->log("Video", Log::NOTICE, "Analog tv case");
-               Input::getInstance()->shutdown();
+               InputMan::getInstance()->shutdown();
                vc_tv_power_off();
                SDTV_MODE_T setmode=SDTV_MODE_PAL;
                SDTV_OPTIONS_T options;
@@ -515,7 +515,8 @@ void VideoOMX::selectVideoMode(int interlaced)
                hdmi=false;
        }
 
-       Input::getInstance()->init("");
+       InputMan::getInstance()->init(); // FIXME complete shutdown and reinit maybe heavy handed.
+    // If this was just to reinit CEC then funcitons should be made to do that
 
 
        signalon=true;
@@ -724,9 +725,9 @@ int VideoOMX::signalOff()
        //TODO reinit osd
        Log::getInstance()->log("Video", Log::NOTICE, "signalOff");
        Osd::getInstance()->stopUpdate(); // turn off drawing thread
-       Input::getInstance()->shutdown();
+       InputMan::getInstance()->shutdown();
        vc_tv_power_off();
-       Input::getInstance()->init("");
+       InputMan::getInstance()->init(); // FIXME
        signalon=false;
     return 1;
 }
index 472d3cc61042ebd01dc51394da186cbce436d707..532ae8b6365c171e73426234b63bd488c121da30 100644 (file)
@@ -724,7 +724,6 @@ int VMediaList::handleCommand(int command)
       boxstack->update(this);
       return 2;
     }
-    case Input::DF_UP:
     case Input::UP:
     {
       sl.up();
@@ -735,7 +734,6 @@ int VMediaList::handleCommand(int command)
       boxstack->update(this);
       return 2;
     }
-    case Input::DF_DOWN:
     case Input::DOWN:
     {
       sl.down();
index cf7874a569b498ea8abb0e8ea659162755a3580f..ff18d404aee2cc72f3a16fbdb410e6c51a2c6d82 100644 (file)
@@ -445,7 +445,6 @@ int VMediaView::handleCommand(int command)
     int rt=1;
     switch(command)
     {
-      case Input::DF_UP:
       case Input::UP:
       case Input::SKIPBACK:
         rotate=WJpegComplex::ROT_0;
@@ -456,7 +455,6 @@ int VMediaView::handleCommand(int command)
         if (showtime > 1) showtime--;
         updatePictureBanner(true);
         break;
-      case Input::DF_DOWN:
       case Input::DOWN:
       case Input::SKIPFORWARD:
         rotate=WJpegComplex::ROT_0;
@@ -580,7 +578,6 @@ int VMediaView::handleCommand(int command)
         setAudioMode(false);
         rt=2;
         break;
-      case Input::DF_UP:
       case Input::UP:
         play(playall,false,VMediaList::MV_PREV);
         rt= 2;
@@ -590,7 +587,6 @@ int VMediaView::handleCommand(int command)
         updateInfo=true;
         rt=2;
         break;
-      case Input::DF_DOWN:
       case Input::DOWN:
         play(playall,false,VMediaList::MV_NEXT);
         rt= 2;
index 0ebd83ee3eb80ffd328464fdaf7fe8feccc50a43..1482353c794f14908798dae88eb45288a8552e7f 100644 (file)
--- a/vopts.cc
+++ b/vopts.cc
@@ -25,6 +25,7 @@
 #include "osd.h"
 #include "audio.h"
 #include "input.h"
+#include "inputman.h"
 #include "boxstack.h"
 #include "woptionpane.h"
 #include "wremoteconfig.h"
@@ -192,14 +193,14 @@ VOpts::VOpts()
   options.push_back(option);
   wop->addOptionLine(option);
 
-  Input::getInstance()->addOptionsToPanes(0,&options,wop);
+  InputMan::getInstance()->addOptionsToPanes(0,&options,wop);
   Video::getInstance()->addOptionsToPanes(0,&options,wop);
   Audio::getInstance()->addOptionsToPanes(0,&options,wop);
 
     
 /*  WRemoteConfig* wrc = new WRemoteConfig();
   tabbar.addTab(tr("Remote Control"), wrc);*/
-  Input::getInstance()->addOptionPagesToWTB(&tabbar);
+  InputMan::getInstance()->addOptionPagesToWTB(&tabbar);
  // panes[1] = wrc;
 
   Video::getInstance()->addOptionPagesToWTB(&tabbar);
@@ -226,7 +227,7 @@ VOpts::VOpts()
   options.push_back(option);
   wop->addOptionLine(option);
 
-  Input::getInstance()->addOptionsToPanes(1,&options,wop);
+  InputMan::getInstance()->addOptionsToPanes(1,&options,wop);
   Video::getInstance()->addOptionsToPanes(1,&options,wop);
   Audio::getInstance()->addOptionsToPanes(1,&options,wop);
 
@@ -264,7 +265,7 @@ VOpts::VOpts()
   wop->addOptionLine(option);
 #endif
 
-  Input::getInstance()->addOptionsToPanes(2,&options,wop);
+  InputMan::getInstance()->addOptionsToPanes(2,&options,wop);
   Video::getInstance()->addOptionsToPanes(2,&options,wop);
   Audio::getInstance()->addOptionsToPanes(2,&options,wop);
 }
@@ -311,7 +312,7 @@ void VOpts::doSave()
 {
   VDR* vdr = VDR::getInstance();
 
-  Input::getInstance()->saveOptionstoServer(); //Remote
+  InputMan::getInstance()->saveOptionstoServer(); //Remote
   Video::getInstance()->saveOptionstoServer(); //Video
   Audio::getInstance()->saveOptionstoServer(); //Remote
 #ifdef VOMP_PLATTFORM_MVP
index 81bc1edfe5755ad9c646d991137a153edea9382b..96c73c2340a49a01c16ed5ed7d3829cec450048b 100644 (file)
@@ -81,7 +81,6 @@ int VQuestion::handleCommand(int command)
 {
   switch(command)
   {
-    case Input::DF_LEFT:
     case Input::LEFT:
     {
       swap();
@@ -89,7 +88,6 @@ int VQuestion::handleCommand(int command)
       BoxStack::getInstance()->update(this);
       return 2;
     }
-    case Input::DF_RIGHT:
     case Input::RIGHT:
     {
       swap();
index 361b1bf2031d3fffd1542e1c2d322bf2b5e282c0..188f2e84c0bfddc21eb3bfa41867d72d1dee7e51 100644 (file)
@@ -109,7 +109,6 @@ int VRecMove::handleCommand(int command)
 {
   switch(command)
   {
-    case Input::DF_UP:
     case Input::UP:
     {
       sl.up();
@@ -117,7 +116,6 @@ int VRecMove::handleCommand(int command)
       BoxStack::getInstance()->update(this);
       return 2;
     }
-    case Input::DF_DOWN:
     case Input::DOWN:
     {
       sl.down();
index 3e50fdcf137907b66396761be70ff910c89d6ec9..10329418423cabde187905c27ddae5737bd291ba 100644 (file)
@@ -189,7 +189,6 @@ int VRecording::handleCommand(int command)
        if (buttons) {
                switch(command)
                {
-               case Input::DF_UP:
                case Input::UP:
                {
                        tabbar.activateFocus(false);
@@ -197,7 +196,6 @@ int VRecording::handleCommand(int command)
                        return 2;
                }
 
-               case Input::DF_DOWN:
                case Input::DOWN:
                {
                        tabbar.activateFocus(false);
@@ -205,9 +203,7 @@ int VRecording::handleCommand(int command)
                        return 2;
                }
                case Input::LEFT:
-               case Input::DF_LEFT:
                case Input::RIGHT:
-               case Input::DF_RIGHT:
                {
                        buttons = false;
                        button[selected].setActive(0);
@@ -336,8 +332,7 @@ int VRecording::handleCommand(int command)
                else if (retval == 2)
                {
                        // command was taken and actively ignored
-                       if (command==Input::LEFT || command==Input::DF_LEFT
-                                       || command==Input::RIGHT || command==Input::DF_RIGHT)
+                       if (command==Input::LEFT || command==Input::RIGHT)
                        {
                                buttons=true;
                                button[selected].setActive(1);
index e6834409d4ed6ccb38cfd2ef9f2129753b802270..6653dbfe985c721d8e219e424d40f21775afa271 100644 (file)
@@ -321,7 +321,6 @@ int VRecordingList::handleCommand(int command)
 {
   switch(command)
   {
-    case Input::DF_UP:
     case Input::UP:
     {
       sl.up();
@@ -330,7 +329,6 @@ int VRecordingList::handleCommand(int command)
       boxstack->update(this);
       return 2;
     }
-    case Input::DF_DOWN:
     case Input::DOWN:
     {
       sl.down();
index 1a10d67855d6c53875c3086cc51e1d4212f81d40..67dbcf59a8112da72889bc30efbe07512584463e 100644 (file)
@@ -84,7 +84,6 @@ int VRecordingMenu::handleCommand(int command)
 {
   switch(command)
   {
-    case Input::DF_UP:
     case Input::UP:
     {
       sl.up();
@@ -92,7 +91,6 @@ int VRecordingMenu::handleCommand(int command)
       BoxStack::getInstance()->update(this);
       return 2;
     }
-    case Input::DF_DOWN:
     case Input::DOWN:
     {
       sl.down();
index 2a7fb396d82e38a693377ff63cfc91b202d02672..a0c8792137494e5ce39a8ed813167c38a03b0210 100644 (file)
@@ -77,7 +77,6 @@ int VServerSelect::handleCommand(int command)
 {
   switch(command)
   {
-    case Input::DF_UP:
     case Input::UP:
     {
       sl.up();
@@ -85,7 +84,6 @@ int VServerSelect::handleCommand(int command)
       BoxStack::getInstance()->update(this);
       return 2;
     }
-    case Input::DF_DOWN:
     case Input::DOWN:
     {
       sl.down();
index 480c28cf2ff1042d83bcdced41a9db3c30314dfa..da078708ed127c97ce19430e91ee91024bca28b3 100644 (file)
@@ -1,3 +1,4 @@
+
 /*
     Copyright 2004-2005 Chris Tallon
 
@@ -170,14 +171,12 @@ int VTimerEdit::handleCommand(int command)
   switch(command)
   {
     /*
-    case Input::DF_UP:
     case Input::UP:
     {
 
       ViewMan::getInstance()->updateView(this);
       return 2;
     }
-    case Input::DF_DOWN:
     case Input::DOWN:
     {
 
@@ -186,7 +185,6 @@ int VTimerEdit::handleCommand(int command)
     }
     */
     case Input::LEFT:
-    case Input::DF_RIGHT:
     {
       swap();
       buttonBack.draw();
@@ -195,7 +193,6 @@ int VTimerEdit::handleCommand(int command)
       return 2;
     }
     case Input::RIGHT:
-    case Input::DF_LEFT:
     {
       swap();
       buttonBack.draw();
index 5f4e75e2ea575f8ea3bbfcf143e6a89ea4c5872b..b81807b32643f98461232594c7becca4be39bc5d 100644 (file)
@@ -265,7 +265,6 @@ int VTimerList::handleCommand(int command)
 {
   switch(command)
   {
-    case Input::DF_UP:
     case Input::UP:
     {
       sl.up();
@@ -273,7 +272,6 @@ int VTimerList::handleCommand(int command)
       BoxStack::getInstance()->update(this);
       return 2;
     }
-    case Input::DF_DOWN:
     case Input::DOWN:
     {
       sl.down();
index 29abae01a9cda33709310ee82277a0a3d629e800..019ef52203f8ed2c657aa16c2c79eae9b9407c93 100644 (file)
@@ -33,6 +33,7 @@
 #include "i18n.h"
 #include "wtextbox.h"
 #include "input.h"
+#include "inputman.h"
 #include "vaudioselector.h"
 #include "colour.h"
 #include "event.h"
@@ -321,10 +322,10 @@ int VVideoLiveTV::handleCommand(int command)
       return 4;
     }
     
-    // NEW REMOTE ONLY - navigate EPG, bring it onscreen if it's not there
+    // navigate EPG, bring it onscreen if it's not there
     case Input::UP:
     {
-      if (Input::getInstance()->mayHaveFewButtons())
+      if (InputMan::getInstance()->mayHaveFewButtons())
       {
         if (okTriggeredOSD) doUpDown(false);
         else doChanUpDown(UP);
@@ -337,7 +338,7 @@ int VVideoLiveTV::handleCommand(int command)
     }
     case Input::DOWN:
     {
-      if (Input::getInstance()->mayHaveFewButtons())
+      if (InputMan::getInstance()->mayHaveFewButtons())
       {
         if (okTriggeredOSD) doUpDown(true);
         else doChanUpDown(DOWN);
@@ -358,7 +359,6 @@ int VVideoLiveTV::handleCommand(int command)
       doLeftRight(true);
       return 2;
     }
-    // Continue new remote only...
     case Input::CHANNELUP:
     {
       doChanUpDown(UP);
@@ -369,33 +369,6 @@ int VVideoLiveTV::handleCommand(int command)
       doChanUpDown(DOWN);
       return 2;
     }
-
-    // END NEW REMOTE ONLY, START OLD REMOTE ONLY
-    
-    // DF_LEFT and DF_RIGHT never get here because they are stolen
-    // by command as vol- and vol+
-    
-    // Old remote. Decide what to do based on whether
-    // OK was pressed - osd shown manually, use up/down for epg nav
-    // UP/DOWN was pressed to change channel, osd was shown auto, use up/down for ch+/ch-
-    
-    case Input::DF_UP:
-    {
-      // Old remote, decide what to do based on okTriggeredOSD
-      if (okTriggeredOSD) doUpDown(false);
-      else doChanUpDown(UP);
-      return 2;
-    }
-    case Input::DF_DOWN:
-    {
-      // Old remote, decide what to do based on okTriggeredOSD
-      if (okTriggeredOSD) doUpDown(true);
-      else doChanUpDown(DOWN);
-      return 2;
-    }
-
-    // END NEW/OLD REMOTE STUFF
-
     case Input::PREVCHANNEL:
     {
       channelChange(PREVIOUS, 0);
index eef3899dc65cb9bb48587aaf5e09ac3163abd1a5..3728a542f19b05db5ea92390b555139cd24951f5 100644 (file)
@@ -95,7 +95,6 @@ int VVolume::handleCommand(int command)
 {
   switch(command)
   {
-    case Input::DF_LEFT:
     case Input::VOLUMEDOWN:
     {
       displayVolume = Audio::getInstance()->volumeDown();
@@ -104,7 +103,6 @@ int VVolume::handleCommand(int command)
       // handled
       return 2;
     }
-    case Input::DF_RIGHT:
     case Input::VOLUMEUP:
     {
       displayVolume = Audio::getInstance()->volumeUp();
index 4e0f1e148a73bd94fc2a2491b078d2984bd5e75a..094e9d9033a1f64d28f2c20ebc190d22a932b92f 100644 (file)
@@ -187,7 +187,6 @@ int VWelcome::handleCommand(int command)
 {
   switch(command)
   {
-    case Input::DF_UP:
     case Input::UP:
     {
       sl.up();
@@ -195,7 +194,6 @@ int VWelcome::handleCommand(int command)
       boxstack->update(this);
       return 2;
     }
-    case Input::DF_DOWN:
     case Input::DOWN:
     {
       sl.down();
index c2cdd62a6ace41fba229fe91e63d3f0496761ea9..59b05b6b3691483c1d2126394f97ba23309357ca 100644 (file)
@@ -120,7 +120,6 @@ int WOptionPane::handleCommand(int command)
 {
   switch(command)
   {
-    case Input::DF_UP:
     case Input::UP:
     {
       if (selectedOption > 0)
@@ -142,7 +141,6 @@ int WOptionPane::handleCommand(int command)
         return 1;
       }
     }
-    case Input::DF_DOWN:
     case Input::DOWN:
     {
       if (selectedOption < (numOptions - 1))
@@ -159,13 +157,11 @@ int WOptionPane::handleCommand(int command)
         return 4; // Signal return control to parent
       }
     }
-    case Input::DF_LEFT:
     case Input::LEFT:
     {
       optionBoxes[selectedOption]->left();
       return 1;
     }
-    case Input::DF_RIGHT:
     case Input::RIGHT:
     {
       optionBoxes[selectedOption]->right();
index 8a0bc439f6c633887bd3147b4e46624c958dbe91..54b78d40a7d66ac2866884b7b20947ba70d47a9c 100644 (file)
@@ -151,7 +151,6 @@ int WPictureView::handleCommand(int command)
 {
   switch(command)
   {
-    case Input::DF_UP:
     case Input::UP:
     {
       if (cur_scroll_line > 0)
@@ -165,7 +164,6 @@ int WPictureView::handleCommand(int command)
          return 4; // Signal return control to parent
       }
     }
-    case Input::DF_DOWN:
     case Input::DOWN:
     {
        if (rem_scroll_line > 0)
@@ -179,8 +177,6 @@ int WPictureView::handleCommand(int command)
     }
     case Input::LEFT:
     case Input::RIGHT:
-    case Input::DF_LEFT:
-    case Input::DF_RIGHT:
     {
        return 5;
     }
index cb8ddd93d9eb6253990d7f6a7c4b70e1d5cd8708..b84dd4027639850cad960e1acf7337a7163e8982 100644 (file)
@@ -20,6 +20,7 @@
 #include "wremoteconfig.h"
 
 #include "input.h"
+#include "inputman.h"
 #include "wsymbol.h"
 #include "colour.h"
 #include "i18n.h"
@@ -27,7 +28,7 @@
 
 WRemoteConfig::WRemoteConfig()
 {
-  remote = Input::getInstance();
+  remote = InputMan::getInstance();
   learnmode = false;
   active = false;
 
@@ -60,10 +61,13 @@ void WRemoteConfig::initSelectList(bool startup)
   ULONG i;
   for (i = 0; i < 256; i++)
   {
-    const char * name = remote->CommandDesc((UCHAR)i);
+    const char * name = InputMan::CommandDesc((UCHAR)i);
     if (name != NULL)
     {
-      char *line = remote->CommandTranslateStr((UCHAR)i);
+      //char *line = remote->CommandTranslateStr((UCHAR)i);
+
+      const char* line = "UNK,FIXME";
+
       sl.addOption(line,i,0);
     }
   }
@@ -177,7 +181,6 @@ int WRemoteConfig::handleCommand(int command)
   }
   switch(command)
   {
-    case Input::DF_UP:
     case Input::UP:
     {
       if (sl.getCurrentOption() != 0)
@@ -192,7 +195,6 @@ int WRemoteConfig::handleCommand(int command)
         return 4; // return control to vopts
       }
     }
-    case Input::DF_DOWN:
     case Input::DOWN:
     {
       if (!active)
@@ -219,7 +221,7 @@ int WRemoteConfig::handleCommand(int command)
     case Input::OK:
     {
       learnmode = true;
-      remote->EnterLearningMode(sl.getCurrentOptionData());
+     // remote->EnterLearningMode(sl.getCurrentOptionData()); FIXME
       return 1;
     }
     case Input::BACK:
@@ -243,7 +245,7 @@ int WRemoteConfig::handleCommand(int command)
     }
     case Input::MENU:
     {
-      remote->ResetToDefault();
+   //   remote->ResetToDefault(); FIXME
       initSelectList(false);
       return 1;
     }
index 78006b7e9982af669c5b4b8092e4ab3061443274..764e4765bf1cd5132d6a42477e689615ab8680c1 100644 (file)
@@ -42,7 +42,7 @@ class WRemoteConfig : public Boxx
 
   private:
     WSelectList sl;
-    Input* remote;
+    InputMan* remote;
     bool learnmode;
     void initSelectList(bool startup);
     bool active;
index dd3315e1c2f06b8c652e72f9a1262dd4ebab1c11..d9853f90e2497ba5eb8bdcf1d60d95968b6be96e 100644 (file)
@@ -144,14 +144,12 @@ int WTabBar::handleCommand(int command)
   {
     switch(command)
     {
-      case Input::DF_LEFT:
       case Input::LEFT:
       {
         if (!left()) return 2;
         draw();
         return 1;
       }
-      case Input::DF_RIGHT:
       case Input::RIGHT:
       {
         if (!right()) return 2;
@@ -159,9 +157,7 @@ int WTabBar::handleCommand(int command)
         return 1;
       }
       case Input::UP:
-      case Input::DF_UP:
       case Input::DOWN:
-      case Input::DF_DOWN:
       {
         int handleResult = tabs[visiblePane].pane->handleCommand(command);
         // A WOptionPane will accept control being passed into it from inactive, up or down (== 1).
index 0d1f90e6a165c8a9b4ac6d88cd8ec4c56a698189..6a9e9e03fc47b91e4184d8f4a97b56c39a9e66c3 100644 (file)
@@ -86,7 +86,6 @@ int WTextbox::handleCommand(int command)
 {
   switch(command)
   {
-    case Input::DF_UP:
     case Input::UP:
     {
       if (cur_scroll_line > 0)
@@ -100,7 +99,6 @@ int WTextbox::handleCommand(int command)
          return 4; // Signal return control to parent
       }
     }
-    case Input::DF_DOWN:
     case Input::DOWN:
     {
        if (rem_scroll_line > 0)
@@ -114,8 +112,6 @@ int WTextbox::handleCommand(int command)
     }
     case Input::LEFT:
     case Input::RIGHT:
-    case Input::DF_LEFT:
-    case Input::DF_RIGHT:
     {
        return 5;
     }
index c7599028af21cfcf9675755137b1c44b1036dbc2..98f40f0c4b8bf9dddc1d407b4087e1bcb937f71d 100644 (file)
@@ -180,7 +180,6 @@ int WWinAudioFilter::handleCommand(int command)
   
   switch(command)
   {
-    case Input::DF_UP:
     case Input::UP:
     {
       if (sl.getCurrentOption() != 0)
@@ -195,7 +194,6 @@ int WWinAudioFilter::handleCommand(int command)
           return 4; //Control to vopts control
       }
     }
-    case Input::DF_DOWN:
     case Input::DOWN:
     {
       Log::getInstance()->log("P", Log::DEBUG, "1");
index 85f5644a4f6675f70076e0cc1c14f47101eff094..f1756ff64ed013e0bd055e9512efaeb417126b73 100644 (file)
@@ -188,7 +188,6 @@ int WWinMp3AudioFilter::handleCommand(int command)
   
   switch(command)
   {
-    case Input::DF_UP:
     case Input::UP:
     {
       if (sl.getCurrentOption() != 0)
@@ -203,7 +202,6 @@ int WWinMp3AudioFilter::handleCommand(int command)
           return 4; //Control to vpots control
       }
     }
-    case Input::DF_DOWN:
     case Input::DOWN:
     {
       
index a179816a060c367cd97cdf468da1cdee1a522565..67db7dc8ea0acf41effad07b1882a119cc769434 100644 (file)
@@ -180,7 +180,6 @@ int WWinVideoFilter::handleCommand(int command)
   
   switch(command)
   {
-    case Input::DF_UP:
     case Input::UP:
     {
       if (sl.getCurrentOption() != 0)
@@ -195,7 +194,6 @@ int WWinVideoFilter::handleCommand(int command)
           return 4; //Control to vopts control
       }
     }
-    case Input::DF_DOWN:
     case Input::DOWN:
     {
       sl.down();
index 756cb463f2c62ca97832116a514d411fc1230fef..6bff0acfc021b06da5c69e919b99c2bc3aee4703 100644 (file)
@@ -180,7 +180,6 @@ int WWinVideoH264Filter::handleCommand(int command)
   
   switch(command)
   {
-    case Input::DF_UP:
     case Input::UP:
     {
       if (sl.getCurrentOption() != 0)
@@ -195,7 +194,6 @@ int WWinVideoH264Filter::handleCommand(int command)
           return 4; //Control to vopts control
       }
     }
-    case Input::DF_DOWN:
     case Input::DOWN:
     {
       sl.down();