summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKlaus Schmidinger <vdr@tvdr.de>2000-10-08 11:39:11 +0200
committerKlaus Schmidinger <vdr@tvdr.de>2000-10-08 11:39:11 +0200
commit605d8df72ada13ae54fd4452f43f09f94ade87d1 (patch)
tree34dff9ced1c7c930e9e7e85e4ec6afa1173e0eb2
parent97c3bb61482855769f0208062610543475f02006 (diff)
downloadvdr-605d8df72ada13ae54fd4452f43f09f94ade87d1.tar.gz
vdr-605d8df72ada13ae54fd4452f43f09f94ade87d1.tar.bz2
Explicit Repeat/Release handling for remote control
-rw-r--r--HISTORY10
-rw-r--r--MANUAL4
-rw-r--r--config.h11
-rw-r--r--interface.c20
-rw-r--r--interface.h4
-rw-r--r--menu.c27
-rw-r--r--osd.c4
-rw-r--r--remote.c110
-rw-r--r--remote.h14
-rw-r--r--vdr.c10
10 files changed, 134 insertions, 80 deletions
diff --git a/HISTORY b/HISTORY
index 1ffc34c0..7d81ca11 100644
--- a/HISTORY
+++ b/HISTORY
@@ -221,3 +221,13 @@ Video Disk Recorder Revision History
that would display only partially).
- In normal viewing mode the '0' key now toggles between the current and the
previous channel.
+
+2000-10-08: Version 0.66
+
+- Remote control data is now received in a separate thread, which makes things
+ a lot smoother.
+- Repeat and release of remote control keys is now explicitly distinguished.
+- In replay mode the search forward/back and skip functions now have two modes:
+ Pressing the key shortly and releasing it starts the function, and pressing it
+ again stops it. Pressing and holding down the key starts the function and
+ releasing the key stops it.
diff --git a/MANUAL b/MANUAL
index 24ee3ff5..f8b2a1b8 100644
--- a/MANUAL
+++ b/MANUAL
@@ -118,8 +118,12 @@ Video Disk Recorder User's Manual
Right Runs playback forward or backward at a higher speed; press
again to resume normal speed. If in Pause mode, runs forward or
backward at a slower speed; press again to return to pause mode.
+ Pressing and holding down the button performs the function until
+ the button is released again.
- Green
Yellow Skips about 60 seconds back or forward.
+ Pressing and holding down the button performs the function until
+ the button is released again.
- Ok Brings up the replay progress display, which shows the date,
time and title of the recording, a progress bar and the
current and total time of the recording.
diff --git a/config.h b/config.h
index 99a57eba..73fc8f5a 100644
--- a/config.h
+++ b/config.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: config.h 1.23 2000/10/07 17:34:23 kls Exp $
+ * $Id: config.h 1.24 2000/10/08 10:38:17 kls Exp $
*/
#ifndef __CONFIG_H
@@ -34,9 +34,16 @@ enum eKeys { // "Up" and "Down" must be the first two keys!
kYellow,
kBlue,
k0, k1, k2, k3, k4, k5, k6, k7, k8, k9,
- kNone
+ kNone,
+ // The following flags are OR'd with the above codes:
+ k_Repeat = 0x8000,
+ k_Release = 0x4000,
+ k_Flags = k_Repeat | k_Release,
};
+#define ISNORMALKEY(k) ((k) != kNone && ((k) & k_Flags) == 0)
+#define NORMALKEY(k) ((k) & ~k_Flags)
+
struct tKey {
eKeys type;
char *name;
diff --git a/interface.c b/interface.c
index 485a5dd0..84ee101c 100644
--- a/interface.c
+++ b/interface.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: interface.c 1.22 2000/10/07 16:42:37 kls Exp $
+ * $Id: interface.c 1.23 2000/10/08 11:17:11 kls Exp $
*/
#include "interface.h"
@@ -58,21 +58,29 @@ void cInterface::Close(void)
cDvbApi::PrimaryDvbApi->Close();
}
-unsigned int cInterface::GetCh(bool Wait)
+unsigned int cInterface::GetCh(bool Wait, bool *Repeat, bool *Release)
{
if (open)
cDvbApi::PrimaryDvbApi->Flush();
if (!RcIo.InputAvailable())
cFile::AnyFileReady(-1, Wait ? 1000 : 0);
unsigned int Command;
- return RcIo.GetCommand(&Command) ? Command : 0;
+ return RcIo.GetCommand(&Command, Repeat, Release) ? Command : 0;
}
eKeys cInterface::GetKey(bool Wait)
{
if (SVDRP)
SVDRP->Process();
- eKeys Key = keyFromWait != kNone ? keyFromWait : Keys.Get(GetCh(Wait));
+ eKeys Key = keyFromWait;
+ if (Key == kNone) {
+ bool Repeat = false, Release = false;
+ Key = Keys.Get(GetCh(Wait, &Repeat, &Release));
+ if (Repeat)
+ Key = eKeys(Key | k_Repeat);
+ if (Release)
+ Key = eKeys(Key | k_Release);
+ }
keyFromWait = kNone;
return Key;
}
@@ -90,10 +98,10 @@ eKeys cInterface::Wait(int Seconds, bool KeepChar)
time_t timeout = time(NULL) + Seconds;
for (;;) {
Key = GetKey();
- if (Key != kNone || time(NULL) > timeout)
+ if ((Key != kNone && (NORMALKEY(Key) != kOk || NORMALKEY(Key) == Key)) || time(NULL) > timeout)
break;
}
- if (KeepChar)
+ if (KeepChar && ISNORMALKEY(Key))
keyFromWait = Key;
return Key;
}
diff --git a/interface.h b/interface.h
index c5592983..e3bce38c 100644
--- a/interface.h
+++ b/interface.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: interface.h 1.14 2000/10/07 16:17:53 kls Exp $
+ * $Id: interface.h 1.15 2000/10/08 09:51:42 kls Exp $
*/
#ifndef __INTERFACE_H
@@ -22,7 +22,7 @@ private:
int cols[MaxCols];
eKeys keyFromWait;
cSVDRP *SVDRP;
- unsigned int GetCh(bool Wait = true);
+ unsigned int GetCh(bool Wait = true, bool *Repeat = NULL, bool *Release = NULL);
void QueryKeys(void);
void HelpButton(int Index, const char *Text, eDvbColor FgColor, eDvbColor BgColor);
eKeys Wait(int Seconds = 1, bool KeepChar = false);
diff --git a/menu.c b/menu.c
index 1f5fd888..cc7618ba 100644
--- a/menu.c
+++ b/menu.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: menu.c 1.30 2000/10/03 14:06:44 kls Exp $
+ * $Id: menu.c 1.31 2000/10/08 10:47:17 kls Exp $
*/
#include "menu.h"
@@ -94,11 +94,11 @@ eOSState cMenuEditIntItem::ProcessKey(eKeys Key)
}
newValue = *value * 10 + (Key - k0);
}
- else if (Key == kLeft) { // TODO might want to increase the delta if repeated quickly?
+ else if (NORMALKEY(Key) == kLeft) { // TODO might want to increase the delta if repeated quickly?
newValue = *value - 1;
fresh = true;
}
- else if (Key == kRight) {
+ else if (NORMALKEY(Key) == kRight) {
newValue = *value + 1;
fresh = true;
}
@@ -211,6 +211,7 @@ void cMenuEditDayItem::Set(void)
eOSState cMenuEditDayItem::ProcessKey(eKeys Key)
{
switch (Key) {
+ case kLeft|k_Repeat:
case kLeft: if (d > 0)
*value = days[--d];
else if (d == 0) {
@@ -225,6 +226,7 @@ eOSState cMenuEditDayItem::ProcessKey(eKeys Key)
return cMenuEditIntItem::ProcessKey(Key);
Set();
break;
+ case kRight|k_Repeat:
case kRight: if (d >= 0) {
*value = days[++d];
if (*value == 0) {
@@ -310,7 +312,7 @@ eOSState cMenuEditTimeItem::ProcessKey(eKeys Key)
break;
}
}
- else if (Key == kLeft) { // TODO might want to increase the delta if repeated quickly?
+ else if (NORMALKEY(Key) == kLeft) { // TODO might want to increase the delta if repeated quickly?
if (--mm < 0) {
mm = 59;
if (--hh < 0)
@@ -318,7 +320,7 @@ eOSState cMenuEditTimeItem::ProcessKey(eKeys Key)
}
fresh = true;
}
- else if (Key == kRight) {
+ else if (NORMALKEY(Key) == kRight) {
if (++mm > 59) {
mm = 0;
if (++hh > 23)
@@ -377,11 +379,11 @@ eOSState cMenuEditChrItem::ProcessKey(eKeys Key)
eOSState state = cMenuEditItem::ProcessKey(Key);
if (state == osUnknown) {
- if (Key == kLeft) {
+ if (NORMALKEY(Key) == kLeft) {
if (current > allowed)
current--;
}
- else if (Key == kRight) {
+ else if (NORMALKEY(Key) == kRight) {
if (*(current + 1))
current++;
}
@@ -455,12 +457,14 @@ char cMenuEditStrItem::Inc(char c, bool Up)
eOSState cMenuEditStrItem::ProcessKey(eKeys Key)
{
switch (Key) {
+ case kLeft|k_Repeat:
case kLeft: if (pos > 0) {
if (value[pos] == '^')
value[pos] = 0;
pos--;
}
break;
+ case kRight|k_Repeat:
case kRight: if (pos < length && value[pos] != '^' && (pos < int(strlen(value) - 1) || value[pos] != ' ')) {
if (++pos >= int(strlen(value))) {
value[pos] = ' ';
@@ -468,9 +472,11 @@ eOSState cMenuEditStrItem::ProcessKey(eKeys Key)
}
}
break;
+ case kUp|k_Repeat:
case kUp:
+ case kDown|k_Repeat:
case kDown: if (pos >= 0)
- value[pos] = Inc(value[pos], Key == kUp);
+ value[pos] = Inc(value[pos], NORMALKEY(Key) == kUp);
else
return cMenuEditItem::ProcessKey(Key);
break;
@@ -1388,7 +1394,12 @@ eOSState cReplayControl::ProcessKey(eKeys Key)
return osEnd;
case kLeft: dvbApi->Backward(); break;
case kRight: dvbApi->Forward(); break;
+ case kLeft|k_Release:
+ case kRight|k_Release:
+ dvbApi->Play(); break;
+ case kGreen|k_Repeat:
case kGreen: dvbApi->Skip(-60); break;
+ case kYellow|k_Repeat:
case kYellow: dvbApi->Skip(60); break;
case kMenu: Hide(); return osMenu; // allow direct switching to menu
case kOk: visible ? Hide() : Show(); break;
diff --git a/osd.c b/osd.c
index e1c99b44..6874ba9f 100644
--- a/osd.c
+++ b/osd.c
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: osd.c 1.7 2000/09/10 08:24:50 kls Exp $
+ * $Id: osd.c 1.8 2000/10/08 10:27:04 kls Exp $
*/
#include "osd.h"
@@ -274,7 +274,9 @@ eOSState cOsdMenu::ProcessKey(eKeys Key)
return state;
}
switch (Key) {
+ case kUp|k_Repeat:
case kUp: CursorUp(); break;
+ case kDown|k_Repeat:
case kDown: CursorDown(); break;
case kBack: return osBack;
case kOk: if (marked >= 0) {
diff --git a/remote.c b/remote.c
index 968184a5..87c70923 100644
--- a/remote.c
+++ b/remote.c
@@ -6,7 +6,7 @@
*
* Ported to LIRC by Carsten Koch <Carsten.Koch@icem.de> 2000-06-16.
*
- * $Id: remote.c 1.16 2000/10/08 09:25:20 kls Exp $
+ * $Id: remote.c 1.17 2000/10/08 11:39:11 kls Exp $
*/
#include "remote.h"
@@ -69,7 +69,7 @@ bool cRcIoKBD::InputAvailable(void)
return f.Ready(false);
}
-bool cRcIoKBD::GetCommand(unsigned int *Command)
+bool cRcIoKBD::GetCommand(unsigned int *Command, bool *Repeat, bool *Release)
{
if (Command) {
*Command = getch();
@@ -93,7 +93,7 @@ cRcIoRCU::cRcIoRCU(char *DeviceName)
address = 0xFFFF;
receivedAddress = 0;
receivedCommand = 0;
- receivedData = receivedRepeat = false;
+ receivedData = receivedRepeat = receivedRelease = false;
lastNumber = 0;
if ((f = open(DeviceName, O_RDWR | O_NONBLOCK)) >= 0) {
struct termios t;
@@ -131,8 +131,8 @@ void cRcIoRCU::Action(void)
dsyslog(LOG_INFO, "RCU remote control thread started (pid=%d)", getpid());
- unsigned int LastCommand = 0;
int FirstTime = 0;
+ unsigned int LastCommand = 0;
for (; f >= 0;) {
@@ -151,20 +151,23 @@ void cRcIoRCU::Action(void)
// This remote control sends the above command before and after
// each keypress - let's just drop this:
break;
- int Now = time_ms();
- if (Command != LastCommand) {
- receivedAddress = Address;
- receivedCommand = Command;
- receivedData = true;
- FirstTime = Now;
+ if (!receivedData) { // only accept new data the previous data has been fetched
+ int Now = time_ms();
+ if (Command != LastCommand) {
+ receivedAddress = Address;
+ receivedCommand = Command;
+ receivedData = true;
+ receivedRepeat = receivedRelease = false;
+ FirstTime = Now;
+ }
+ else {
+ if (Now - FirstTime < REPEATDELAY)
+ break; // repeat function kicks in after a short delay
+ receivedData = receivedRepeat = true;
+ }
+ LastCommand = Command;
+ WakeUp();
}
- else {
- if (Now - FirstTime < REPEATDELAY)
- break; // repeat function kicks in after a short delay
- receivedData = receivedRepeat = true;
- }
- LastCommand = Command;
- WakeUp();
}
}
else
@@ -172,16 +175,15 @@ void cRcIoRCU::Action(void)
}
}
else if (receivedData) { // the last data before releasing the key hasn't been fetched yet
- if (receivedRepeat) { // it was a repeat, so let's drop it
- //XXX replace it with "released"???
- receivedData = receivedRepeat = false;
+ if (receivedRepeat) { // it was a repeat, so let's make it a release
+ receivedRepeat = false;
+ receivedRelease = true;
LastCommand = 0;
- //XXX WakeUp();
+ WakeUp();
}
}
- else if (receivedRepeat) { // all data has already been fetched, but the last one was a repeat
- //XXX replace it with "released"???
- //XXX receivedData = true;
+ else if (receivedRepeat) { // all data has already been fetched, but the last one was a repeat, so let's generate a release
+ receivedData = receivedRelease = true;
receivedRepeat = false;
LastCommand = 0;
WakeUp();
@@ -266,7 +268,7 @@ void cRcIoRCU::Flush(int WaitMs)
receivedData = receivedRepeat = false;
}
-bool cRcIoRCU::GetCommand(unsigned int *Command)
+bool cRcIoRCU::GetCommand(unsigned int *Command, bool *Repeat, bool *Release)
{
if (receivedData) { // first we check the boolean flag without a lock, to avoid delays
@@ -275,7 +277,10 @@ bool cRcIoRCU::GetCommand(unsigned int *Command)
if (receivedData) { // need to check again, since the status might have changed while waiting for the lock
if (Command)
*Command = receivedCommand;
- //XXX repeat!!!
+ if (Repeat)
+ *Repeat = receivedRepeat;
+ if (Release)
+ *Release = receivedRelease;
receivedData = false;
return true;
}
@@ -422,47 +427,47 @@ void cRcIoLIRC::Action(void)
int FirstTime = 0;
char buf[LIRC_BUFFER_SIZE];
+ char LastKeyName[LIRC_KEY_BUF];
for (; f >= 0;) {
LOCK_THREAD;
if (cFile::FileReady(f, REPEATLIMIT) && read(f, buf, sizeof(buf)) > 21) {
- int count;
- sscanf(buf, "%*x %x %7s", &count, keyName); // '7' in '%7s' is LIRC_KEY_BUF-1!
- int Now = time_ms();
- if (count == 0) {
- receivedData = true;
- FirstTime = Now;
- }
- else {
- if (Now - FirstTime < REPEATDELAY)
- continue; // repeat function kicks in after a short delay
- receivedData = receivedRepeat = true;
+ if (!receivedData) { // only accept new data the previous data has been fetched
+ int count;
+ sscanf(buf, "%*x %x %7s", &count, LastKeyName); // '7' in '%7s' is LIRC_KEY_BUF-1!
+ int Now = time_ms();
+ if (count == 0) {
+ strcpy(keyName, LastKeyName);
+ receivedData = true;
+ receivedRepeat = receivedRelease = false;
+ FirstTime = Now;
+ }
+ else {
+ if (Now - FirstTime < REPEATDELAY)
+ continue; // repeat function kicks in after a short delay
+ receivedData = receivedRepeat = true;
+ }
+ WakeUp();
}
- WakeUp();
}
else if (receivedData) { // the last data before releasing the key hasn't been fetched yet
- if (receivedRepeat) { // it was a repeat, so let's drop it
- //XXX replace it with "released"???
- receivedData = receivedRepeat = false;
- *keyName = 0;
- //XXX WakeUp();
+ if (receivedRepeat) { // it was a repeat, so let's make it a release
+ receivedRepeat = false;
+ receivedRelease = true;
+ WakeUp();
}
}
- else if (receivedRepeat) { // all data has already been fetched, but the last one was a repeat
- //XXX replace it with "released"???
- //XXX receivedData = true;
+ else if (receivedRepeat) { // all data has already been fetched, but the last one was a repeat, so let's generate a release
+ receivedData = receivedRelease = true;
receivedRepeat = false;
- *keyName = 0;
WakeUp();
}
- else
- *keyName = 0;
}
}
-bool cRcIoLIRC::GetCommand(unsigned int *Command)
+bool cRcIoLIRC::GetCommand(unsigned int *Command, bool *Repeat, bool *Release)
{
if (receivedData) { // first we check the boolean flag without a lock, to avoid delays
@@ -471,7 +476,10 @@ bool cRcIoLIRC::GetCommand(unsigned int *Command)
if (receivedData) { // need to check again, since the status might have changed while waiting for the lock
if (Command)
*Command = Keys.Encode(keyName);
- //XXX repeat!!!
+ if (Repeat)
+ *Repeat = receivedRepeat;
+ if (Release)
+ *Release = receivedRelease;
receivedData = false;
return true;
}
diff --git a/remote.h b/remote.h
index b9e79b4d..1e779b0b 100644
--- a/remote.h
+++ b/remote.h
@@ -4,7 +4,7 @@
* See the main source file 'vdr.c' for copyright information and
* how to reach the author.
*
- * $Id: remote.h 1.11 2000/10/07 18:50:51 kls Exp $
+ * $Id: remote.h 1.12 2000/10/08 11:19:17 kls Exp $
*/
#ifndef __REMOTE_H
@@ -30,7 +30,7 @@ public:
virtual bool DetectCode(unsigned char *Code, unsigned short *Address) { return true; }
virtual void Flush(int WaitMs = 0) {}
virtual bool InputAvailable(void) = 0;
- virtual bool GetCommand(unsigned int *Command = NULL) = 0;
+ virtual bool GetCommand(unsigned int *Command = NULL, bool *Repeat = NULL, bool *Release = NULL) = 0;
};
#if defined REMOTE_KBD
@@ -43,7 +43,7 @@ public:
virtual ~cRcIoKBD();
virtual void Flush(int WaitMs = 0);
virtual bool InputAvailable(void);
- virtual bool GetCommand(unsigned int *Command = NULL);
+ virtual bool GetCommand(unsigned int *Command = NULL, bool *Repeat = NULL, bool *Release = NULL);
};
#elif defined REMOTE_RCU
@@ -55,7 +55,7 @@ private:
unsigned short address;
unsigned short receivedAddress;
unsigned int receivedCommand;
- bool receivedData, receivedRepeat;
+ bool receivedData, receivedRepeat, receivedRelease;
int lastNumber;
bool SendCommand(unsigned char Cmd);
int ReceiveByte(int TimeoutMs = 0);
@@ -74,7 +74,7 @@ public:
virtual bool DetectCode(unsigned char *Code, unsigned short *Address);
virtual void Flush(int WaitMs = 0);
virtual bool InputAvailable(void) { return receivedData; }
- virtual bool GetCommand(unsigned int *Command = NULL);
+ virtual bool GetCommand(unsigned int *Command = NULL, bool *Repeat = NULL, bool *Release = NULL);
};
#elif defined REMOTE_LIRC
@@ -84,13 +84,13 @@ private:
enum { LIRC_KEY_BUF = 8, LIRC_BUFFER_SIZE = 128 };
int f;
char keyName[LIRC_KEY_BUF];
- bool receivedData, receivedRepeat;
+ bool receivedData, receivedRepeat, receivedRelease;
virtual void Action(void);
public:
cRcIoLIRC(char *DeviceName);
virtual ~cRcIoLIRC();
virtual bool InputAvailable(void) { return receivedData; }
- virtual bool GetCommand(unsigned int *Command = NULL);
+ virtual bool GetCommand(unsigned int *Command = NULL, bool *Repeat = NULL, bool *Release = NULL);
};
#else
diff --git a/vdr.c b/vdr.c
index 042b03ce..379b6b45 100644
--- a/vdr.c
+++ b/vdr.c
@@ -22,7 +22,7 @@
*
* The project's page is at http://www.cadsoft.de/people/kls/vdr
*
- * $Id: vdr.c 1.36 2000/10/03 13:52:26 kls Exp $
+ * $Id: vdr.c 1.37 2000/10/08 10:32:44 kls Exp $
*/
#include <getopt.h>
@@ -257,10 +257,12 @@ int main(int argc, char *argv[])
Menu = new cDirectChannelSelect(key);
break;
// Left/Right rotates trough channel groups:
+ case kLeft|k_Repeat:
case kLeft:
+ case kRight|k_Repeat:
case kRight: if (!Interface.Recording()) {
int SaveGroup = CurrentGroup;
- if (key == kRight)
+ if (NORMALKEY(key) == kRight)
CurrentGroup = Channels.GetNextGroup(CurrentGroup) ;
else
CurrentGroup = Channels.GetPrevGroup(CurrentGroup < 1 ? 1 : CurrentGroup);
@@ -271,9 +273,11 @@ int main(int argc, char *argv[])
}
break;
// Up/Down Channel Select:
+ case kUp|k_Repeat:
case kUp:
+ case kDown|k_Repeat:
case kDown: if (!Interface.Recording()) {
- int n = CurrentChannel + (key == kUp ? 1 : -1);
+ int n = CurrentChannel + (NORMALKEY(key) == kUp ? 1 : -1);
cChannel *channel = Channels.GetByNumber(n);
if (channel)
channel->Switch();