vdr/keys.c
Klaus Schmidinger d5c85f5ff8 Version 1.3.32
- Added some missing braces in remux.c (thanks to Wayne Keer for reporting this one).
- Removed unused MAINMENUENTRY from svdrpdemo.c (thanks to Udo Richter for reporting
  this one).
- Fixed appending sequence end code in cDvbPlayer::Goto() (thanks to Reinhard Nissl).
- Fixed syncing in cRepacker (thanks to Reinhard Nissl).
- Now always using stream id 0xE0 for the video stream, to avoid problems with
  post processing tools that choke on different ids (suggested by Reinhard Nissl).
- Updated the Estonian OSD texts (thanks to Arthur Konovalov).
- Fixed cDvbPlayer::SkipFrames() to properly handle radio recordings (thanks to
  Reinhard Nissl).
- Updated the Swedish OSD texts (thanks to Tomas Prybil).
- Updated the Slovenian OSD texts (thanks to Matjaz Thaler).
- Updated the Danish OSD texts (thanks to Mogens Elneff).
- Made LIRC command parsing more robust (thanks to Ville Skyttä).
- Introduced a separate 'plugins-install' target in the Makefile (thanks to Daniel
  Thompson).
- Re-introduced the code that waits for a tuner lock in VDR/device.c, since
  apparently some users actually need it. It's not active by default, you'll have
  to define the WAIT_FOR_TUNER_LOCK macro in that file if you need it (suggested
  by Malcolm Caldwell).
- Adjusted the Makefile to the dvb-kernel driver on kernel 2.6 and up (thanks to
  Lauri Tischler).
- Repeat keys are now ignored when waiting for a keypress to cancel an operation
  (thanks to Marko Mäkelä).
- The main menu function of a plugin can now be activated through a key macro of
  the form "@plugin" even if that plugin doesn't have a main menu entry (using
  part of a patch by Hardy Flor, which originally implemented calling plugins from
  SVDRP).
- The menu timeout handling is now done centrally in the main program loop.
- Added missing help for the 'help' keyword in the SVDRP command PLUG.
- The main menu function of a plugin can now be called programmatically through
  the static function cRemote::CallPlugin().
- The SVDRP command PLUG now has a new option 'main' which can be used to initiate
  a call to the main menu function of a plugin (using part of a patch by Hardy Flor).
- The new command line option '--vfat' can be used to make VDR encode special
  characters in recording file names, even if it wasn't compiled with VFAT=1
  (suggested by Peter Bieringer). The compile time option VFAT still exists and
  creates a VDR that always behaves as if it were called with '--vfat'.
- Replaced the ':' delimiter between hour and minute in recording file names with
  a '.' under Linux, too. Existing recordings with ':' as delimiter will still work.
- Implemented the SVDRP command MOVC (thanks to Andreas Brachold).
- Added support for multiple audio language codes in ISO639LanguageDescriptors to
  'libsi' (thanks to Marcel Wiesweg).
- Changed the audio PID language codes to hold up to two 3 letter codes, separated
  by '+', to store separate languages broadcast in two channel audio mode.
- If the preferred audio language is broadcast on a PID that has two different
  languages in the two stereo channels, the audio channel is now properly set when
  switching to such a channel (thanks to Mogens Elneff for his help in testing this).
- Fixed some typos in MANUAL (thanks to Ville Skyttä).
- Fixed the default value for "Setup/EPG bugfix level" (thanks to Ville Skyttä for
  reporting this one).
- Fixed defining timers that only differ in the day of week (thanks to Patrick
  Rother for reporting this one).
- Fixed converting summary.vdr files that would result in a very long 'short text'
  (thanks to Carsten Koch).
- Implemented a hash for the channels to reduce the system load in the EIT scanning
  thread (based on a patch by Georg Acher).
2005-09-11 18:00:00 +02:00

258 lines
7.3 KiB
C

/*
* keys.c: Remote control Key handling
*
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
* $Id: keys.c 1.8 2005/09/03 11:28:34 kls Exp $
*/
#include "keys.h"
#include "plugin.h"
static tKey keyTable[] = { // "Up" and "Down" must be the first two keys!
{ kUp, "Up" },
{ kDown, "Down" },
{ kMenu, "Menu" },
{ kOk, "Ok" },
{ kBack, "Back" },
{ kLeft, "Left" },
{ kRight, "Right" },
{ kRed, "Red" },
{ kGreen, "Green" },
{ kYellow, "Yellow" },
{ kBlue, "Blue" },
{ k0, "0" },
{ k1, "1" },
{ k2, "2" },
{ k3, "3" },
{ k4, "4" },
{ k5, "5" },
{ k6, "6" },
{ k7, "7" },
{ k8, "8" },
{ k9, "9" },
{ kPlay, "Play" },
{ kPause, "Pause" },
{ kStop, "Stop" },
{ kRecord, "Record" },
{ kFastFwd, "FastFwd" },
{ kFastRew, "FastRew" },
{ kPower, "Power" },
{ kChanUp, "Channel+" },
{ kChanDn, "Channel-" },
{ kVolUp, "Volume+" },
{ kVolDn, "Volume-" },
{ kMute, "Mute" },
{ kAudio, "Audio" },
{ kSchedule, "Schedule" },
{ kChannels, "Channels" },
{ kTimers, "Timers" },
{ kRecordings, "Recordings" },
{ kSetup, "Setup" },
{ kCommands, "Commands" },
{ kUser1, "User1" },
{ kUser2, "User2" },
{ kUser3, "User3" },
{ kUser4, "User4" },
{ kUser5, "User5" },
{ kUser6, "User6" },
{ kUser7, "User7" },
{ kUser8, "User8" },
{ kUser9, "User9" },
{ kNone, "" },
{ k_Setup, "_Setup" },
{ kNone, NULL },
};
// -- cKey -------------------------------------------------------------------
cKey::cKey(void)
{
remote = code = NULL;
key = kNone;
}
cKey::cKey(const char *Remote, const char *Code, eKeys Key)
{
remote = strdup(Remote);
code = strdup(Code);
key = Key;
}
cKey::~cKey()
{
free(remote);
free(code);
}
bool cKey::Parse(char *s)
{
char *p = strchr(s, '.');
if (p) {
*p++ = 0;
remote = strdup(s);
char *q = strpbrk(p, " \t");
if (q) {
*q++ = 0;
key = FromString(p);
if (key != kNone) {
q = skipspace(q);
if (*q) {
code = strdup(q);
return true;
}
}
}
}
return false;
}
bool cKey::Save(FILE *f)
{
return fprintf(f, "%s.%-10s %s\n", remote, ToString(key), code) > 0;
}
eKeys cKey::FromString(const char *Name)
{
if (Name) {
for (tKey *k = keyTable; k->name; k++) {
if (strcasecmp(k->name, Name) == 0)
return k->type;
}
}
return kNone;
}
const char *cKey::ToString(eKeys Key)
{
for (tKey *k = keyTable; k->name; k++) {
if (k->type == Key)
return k->name;
}
return NULL;
}
// -- cKeys ------------------------------------------------------------------
cKeys Keys;
bool cKeys::KnowsRemote(const char *Remote)
{
if (Remote) {
for (cKey *k = First(); k; k = Next(k)) {
if (strcmp(Remote, k->Remote()) == 0)
return true;
}
}
return false;
}
eKeys cKeys::Get(const char *Remote, const char *Code)
{
if (Remote && Code) {
for (cKey *k = First(); k; k = Next(k)) {
if (strcmp(Remote, k->Remote()) == 0 && strcmp(Code, k->Code()) == 0)
return k->Key();
}
}
return kNone;
}
const char *cKeys::GetSetup(const char *Remote)
{
if (Remote) {
for (cKey *k = First(); k; k = Next(k)) {
if (strcmp(Remote, k->Remote()) == 0 && k->Key() == k_Setup)
return k->Code();
}
}
return NULL;
}
void cKeys::PutSetup(const char *Remote, const char *Setup)
{
if (!GetSetup(Remote))
Add(new cKey(Remote, Setup, k_Setup));
else
esyslog("ERROR: called PutSetup() for %s, but setup has already been defined!", Remote);
}
// -- cKeyMacro --------------------------------------------------------------
cKeyMacro::cKeyMacro(void)
{
for (int i = 0; i < MAXKEYSINMACRO; i++)
macro[i] = kNone;
plugin = NULL;
}
cKeyMacro::~cKeyMacro()
{
free(plugin);
}
bool cKeyMacro::Parse(char *s)
{
int n = 0;
char *p;
char *strtok_next;
while ((p = strtok_r(s, " \t", &strtok_next)) != NULL) {
if (n < MAXKEYSINMACRO) {
if (*p == '@') {
if (plugin) {
esyslog("ERROR: only one @plugin allowed per macro");
return false;
}
if (!n) {
esyslog("ERROR: @plugin can't be first in macro");
return false;
}
macro[n++] = k_Plugin;
if (n < MAXKEYSINMACRO) {
plugin = strdup(p + 1);
if (!cPluginManager::GetPlugin(plugin)) {
esyslog("ERROR: unknown plugin '%s'", plugin);
// this is not a fatal error - plugins may or may not be loaded
macro[--n] = kNone; // makes sure the key doesn't cause any side effects
}
}
else {
esyslog("ERROR: key macro too long");
return false;
}
}
else {
macro[n] = cKey::FromString(p);
if (macro[n] == kNone) {
esyslog("ERROR: unknown key '%s'", p);
return false;
}
}
n++;
s = NULL;
}
else {
esyslog("ERROR: key macro too long");
return false;
}
}
if (n < 2) {
esyslog("ERROR: empty key macro");
}
return true;
}
// -- cKeyMacros -------------------------------------------------------------
cKeyMacros KeyMacros;
const cKeyMacro *cKeyMacros::Get(eKeys Key)
{
for (cKeyMacro *k = First(); k; k = Next(k)) {
if (*k->Macro() == Key)
return k;
}
return NULL;
}