mirror of
https://github.com/VDR4Arch/vdr.git
synced 2023-10-10 13:36:52 +02:00
Explicit Repeat/Release handling for remote control
This commit is contained in:
parent
97c3bb6148
commit
605d8df72a
10
HISTORY
10
HISTORY
@ -221,3 +221,13 @@ Video Disk Recorder Revision History
|
|||||||
that would display only partially).
|
that would display only partially).
|
||||||
- In normal viewing mode the '0' key now toggles between the current and the
|
- In normal viewing mode the '0' key now toggles between the current and the
|
||||||
previous channel.
|
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.
|
||||||
|
4
MANUAL
4
MANUAL
@ -118,8 +118,12 @@ Video Disk Recorder User's Manual
|
|||||||
Right Runs playback forward or backward at a higher speed; press
|
Right Runs playback forward or backward at a higher speed; press
|
||||||
again to resume normal speed. If in Pause mode, runs forward or
|
again to resume normal speed. If in Pause mode, runs forward or
|
||||||
backward at a slower speed; press again to return to pause mode.
|
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
|
- Green
|
||||||
Yellow Skips about 60 seconds back or forward.
|
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,
|
- Ok Brings up the replay progress display, which shows the date,
|
||||||
time and title of the recording, a progress bar and the
|
time and title of the recording, a progress bar and the
|
||||||
current and total time of the recording.
|
current and total time of the recording.
|
||||||
|
11
config.h
11
config.h
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* 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
|
#ifndef __CONFIG_H
|
||||||
@ -34,9 +34,16 @@ enum eKeys { // "Up" and "Down" must be the first two keys!
|
|||||||
kYellow,
|
kYellow,
|
||||||
kBlue,
|
kBlue,
|
||||||
k0, k1, k2, k3, k4, k5, k6, k7, k8, k9,
|
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 {
|
struct tKey {
|
||||||
eKeys type;
|
eKeys type;
|
||||||
char *name;
|
char *name;
|
||||||
|
20
interface.c
20
interface.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* 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"
|
#include "interface.h"
|
||||||
@ -58,21 +58,29 @@ void cInterface::Close(void)
|
|||||||
cDvbApi::PrimaryDvbApi->Close();
|
cDvbApi::PrimaryDvbApi->Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int cInterface::GetCh(bool Wait)
|
unsigned int cInterface::GetCh(bool Wait, bool *Repeat, bool *Release)
|
||||||
{
|
{
|
||||||
if (open)
|
if (open)
|
||||||
cDvbApi::PrimaryDvbApi->Flush();
|
cDvbApi::PrimaryDvbApi->Flush();
|
||||||
if (!RcIo.InputAvailable())
|
if (!RcIo.InputAvailable())
|
||||||
cFile::AnyFileReady(-1, Wait ? 1000 : 0);
|
cFile::AnyFileReady(-1, Wait ? 1000 : 0);
|
||||||
unsigned int Command;
|
unsigned int Command;
|
||||||
return RcIo.GetCommand(&Command) ? Command : 0;
|
return RcIo.GetCommand(&Command, Repeat, Release) ? Command : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
eKeys cInterface::GetKey(bool Wait)
|
eKeys cInterface::GetKey(bool Wait)
|
||||||
{
|
{
|
||||||
if (SVDRP)
|
if (SVDRP)
|
||||||
SVDRP->Process();
|
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;
|
keyFromWait = kNone;
|
||||||
return Key;
|
return Key;
|
||||||
}
|
}
|
||||||
@ -90,10 +98,10 @@ eKeys cInterface::Wait(int Seconds, bool KeepChar)
|
|||||||
time_t timeout = time(NULL) + Seconds;
|
time_t timeout = time(NULL) + Seconds;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
Key = GetKey();
|
Key = GetKey();
|
||||||
if (Key != kNone || time(NULL) > timeout)
|
if ((Key != kNone && (NORMALKEY(Key) != kOk || NORMALKEY(Key) == Key)) || time(NULL) > timeout)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (KeepChar)
|
if (KeepChar && ISNORMALKEY(Key))
|
||||||
keyFromWait = Key;
|
keyFromWait = Key;
|
||||||
return Key;
|
return Key;
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* 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
|
#ifndef __INTERFACE_H
|
||||||
@ -22,7 +22,7 @@ private:
|
|||||||
int cols[MaxCols];
|
int cols[MaxCols];
|
||||||
eKeys keyFromWait;
|
eKeys keyFromWait;
|
||||||
cSVDRP *SVDRP;
|
cSVDRP *SVDRP;
|
||||||
unsigned int GetCh(bool Wait = true);
|
unsigned int GetCh(bool Wait = true, bool *Repeat = NULL, bool *Release = NULL);
|
||||||
void QueryKeys(void);
|
void QueryKeys(void);
|
||||||
void HelpButton(int Index, const char *Text, eDvbColor FgColor, eDvbColor BgColor);
|
void HelpButton(int Index, const char *Text, eDvbColor FgColor, eDvbColor BgColor);
|
||||||
eKeys Wait(int Seconds = 1, bool KeepChar = false);
|
eKeys Wait(int Seconds = 1, bool KeepChar = false);
|
||||||
|
27
menu.c
27
menu.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* 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"
|
#include "menu.h"
|
||||||
@ -94,11 +94,11 @@ eOSState cMenuEditIntItem::ProcessKey(eKeys Key)
|
|||||||
}
|
}
|
||||||
newValue = *value * 10 + (Key - k0);
|
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;
|
newValue = *value - 1;
|
||||||
fresh = true;
|
fresh = true;
|
||||||
}
|
}
|
||||||
else if (Key == kRight) {
|
else if (NORMALKEY(Key) == kRight) {
|
||||||
newValue = *value + 1;
|
newValue = *value + 1;
|
||||||
fresh = true;
|
fresh = true;
|
||||||
}
|
}
|
||||||
@ -211,6 +211,7 @@ void cMenuEditDayItem::Set(void)
|
|||||||
eOSState cMenuEditDayItem::ProcessKey(eKeys Key)
|
eOSState cMenuEditDayItem::ProcessKey(eKeys Key)
|
||||||
{
|
{
|
||||||
switch (Key) {
|
switch (Key) {
|
||||||
|
case kLeft|k_Repeat:
|
||||||
case kLeft: if (d > 0)
|
case kLeft: if (d > 0)
|
||||||
*value = days[--d];
|
*value = days[--d];
|
||||||
else if (d == 0) {
|
else if (d == 0) {
|
||||||
@ -225,6 +226,7 @@ eOSState cMenuEditDayItem::ProcessKey(eKeys Key)
|
|||||||
return cMenuEditIntItem::ProcessKey(Key);
|
return cMenuEditIntItem::ProcessKey(Key);
|
||||||
Set();
|
Set();
|
||||||
break;
|
break;
|
||||||
|
case kRight|k_Repeat:
|
||||||
case kRight: if (d >= 0) {
|
case kRight: if (d >= 0) {
|
||||||
*value = days[++d];
|
*value = days[++d];
|
||||||
if (*value == 0) {
|
if (*value == 0) {
|
||||||
@ -310,7 +312,7 @@ eOSState cMenuEditTimeItem::ProcessKey(eKeys Key)
|
|||||||
break;
|
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) {
|
if (--mm < 0) {
|
||||||
mm = 59;
|
mm = 59;
|
||||||
if (--hh < 0)
|
if (--hh < 0)
|
||||||
@ -318,7 +320,7 @@ eOSState cMenuEditTimeItem::ProcessKey(eKeys Key)
|
|||||||
}
|
}
|
||||||
fresh = true;
|
fresh = true;
|
||||||
}
|
}
|
||||||
else if (Key == kRight) {
|
else if (NORMALKEY(Key) == kRight) {
|
||||||
if (++mm > 59) {
|
if (++mm > 59) {
|
||||||
mm = 0;
|
mm = 0;
|
||||||
if (++hh > 23)
|
if (++hh > 23)
|
||||||
@ -377,11 +379,11 @@ eOSState cMenuEditChrItem::ProcessKey(eKeys Key)
|
|||||||
eOSState state = cMenuEditItem::ProcessKey(Key);
|
eOSState state = cMenuEditItem::ProcessKey(Key);
|
||||||
|
|
||||||
if (state == osUnknown) {
|
if (state == osUnknown) {
|
||||||
if (Key == kLeft) {
|
if (NORMALKEY(Key) == kLeft) {
|
||||||
if (current > allowed)
|
if (current > allowed)
|
||||||
current--;
|
current--;
|
||||||
}
|
}
|
||||||
else if (Key == kRight) {
|
else if (NORMALKEY(Key) == kRight) {
|
||||||
if (*(current + 1))
|
if (*(current + 1))
|
||||||
current++;
|
current++;
|
||||||
}
|
}
|
||||||
@ -455,12 +457,14 @@ char cMenuEditStrItem::Inc(char c, bool Up)
|
|||||||
eOSState cMenuEditStrItem::ProcessKey(eKeys Key)
|
eOSState cMenuEditStrItem::ProcessKey(eKeys Key)
|
||||||
{
|
{
|
||||||
switch (Key) {
|
switch (Key) {
|
||||||
|
case kLeft|k_Repeat:
|
||||||
case kLeft: if (pos > 0) {
|
case kLeft: if (pos > 0) {
|
||||||
if (value[pos] == '^')
|
if (value[pos] == '^')
|
||||||
value[pos] = 0;
|
value[pos] = 0;
|
||||||
pos--;
|
pos--;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case kRight|k_Repeat:
|
||||||
case kRight: if (pos < length && value[pos] != '^' && (pos < int(strlen(value) - 1) || value[pos] != ' ')) {
|
case kRight: if (pos < length && value[pos] != '^' && (pos < int(strlen(value) - 1) || value[pos] != ' ')) {
|
||||||
if (++pos >= int(strlen(value))) {
|
if (++pos >= int(strlen(value))) {
|
||||||
value[pos] = ' ';
|
value[pos] = ' ';
|
||||||
@ -468,9 +472,11 @@ eOSState cMenuEditStrItem::ProcessKey(eKeys Key)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case kUp|k_Repeat:
|
||||||
case kUp:
|
case kUp:
|
||||||
|
case kDown|k_Repeat:
|
||||||
case kDown: if (pos >= 0)
|
case kDown: if (pos >= 0)
|
||||||
value[pos] = Inc(value[pos], Key == kUp);
|
value[pos] = Inc(value[pos], NORMALKEY(Key) == kUp);
|
||||||
else
|
else
|
||||||
return cMenuEditItem::ProcessKey(Key);
|
return cMenuEditItem::ProcessKey(Key);
|
||||||
break;
|
break;
|
||||||
@ -1388,7 +1394,12 @@ eOSState cReplayControl::ProcessKey(eKeys Key)
|
|||||||
return osEnd;
|
return osEnd;
|
||||||
case kLeft: dvbApi->Backward(); break;
|
case kLeft: dvbApi->Backward(); break;
|
||||||
case kRight: dvbApi->Forward(); 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 kGreen: dvbApi->Skip(-60); break;
|
||||||
|
case kYellow|k_Repeat:
|
||||||
case kYellow: dvbApi->Skip(60); break;
|
case kYellow: dvbApi->Skip(60); break;
|
||||||
case kMenu: Hide(); return osMenu; // allow direct switching to menu
|
case kMenu: Hide(); return osMenu; // allow direct switching to menu
|
||||||
case kOk: visible ? Hide() : Show(); break;
|
case kOk: visible ? Hide() : Show(); break;
|
||||||
|
4
osd.c
4
osd.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* 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"
|
#include "osd.h"
|
||||||
@ -274,7 +274,9 @@ eOSState cOsdMenu::ProcessKey(eKeys Key)
|
|||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
switch (Key) {
|
switch (Key) {
|
||||||
|
case kUp|k_Repeat:
|
||||||
case kUp: CursorUp(); break;
|
case kUp: CursorUp(); break;
|
||||||
|
case kDown|k_Repeat:
|
||||||
case kDown: CursorDown(); break;
|
case kDown: CursorDown(); break;
|
||||||
case kBack: return osBack;
|
case kBack: return osBack;
|
||||||
case kOk: if (marked >= 0) {
|
case kOk: if (marked >= 0) {
|
||||||
|
66
remote.c
66
remote.c
@ -6,7 +6,7 @@
|
|||||||
*
|
*
|
||||||
* Ported to LIRC by Carsten Koch <Carsten.Koch@icem.de> 2000-06-16.
|
* 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"
|
#include "remote.h"
|
||||||
@ -69,7 +69,7 @@ bool cRcIoKBD::InputAvailable(void)
|
|||||||
return f.Ready(false);
|
return f.Ready(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cRcIoKBD::GetCommand(unsigned int *Command)
|
bool cRcIoKBD::GetCommand(unsigned int *Command, bool *Repeat, bool *Release)
|
||||||
{
|
{
|
||||||
if (Command) {
|
if (Command) {
|
||||||
*Command = getch();
|
*Command = getch();
|
||||||
@ -93,7 +93,7 @@ cRcIoRCU::cRcIoRCU(char *DeviceName)
|
|||||||
address = 0xFFFF;
|
address = 0xFFFF;
|
||||||
receivedAddress = 0;
|
receivedAddress = 0;
|
||||||
receivedCommand = 0;
|
receivedCommand = 0;
|
||||||
receivedData = receivedRepeat = false;
|
receivedData = receivedRepeat = receivedRelease = false;
|
||||||
lastNumber = 0;
|
lastNumber = 0;
|
||||||
if ((f = open(DeviceName, O_RDWR | O_NONBLOCK)) >= 0) {
|
if ((f = open(DeviceName, O_RDWR | O_NONBLOCK)) >= 0) {
|
||||||
struct termios t;
|
struct termios t;
|
||||||
@ -131,8 +131,8 @@ void cRcIoRCU::Action(void)
|
|||||||
|
|
||||||
dsyslog(LOG_INFO, "RCU remote control thread started (pid=%d)", getpid());
|
dsyslog(LOG_INFO, "RCU remote control thread started (pid=%d)", getpid());
|
||||||
|
|
||||||
unsigned int LastCommand = 0;
|
|
||||||
int FirstTime = 0;
|
int FirstTime = 0;
|
||||||
|
unsigned int LastCommand = 0;
|
||||||
|
|
||||||
for (; f >= 0;) {
|
for (; f >= 0;) {
|
||||||
|
|
||||||
@ -151,11 +151,13 @@ void cRcIoRCU::Action(void)
|
|||||||
// This remote control sends the above command before and after
|
// This remote control sends the above command before and after
|
||||||
// each keypress - let's just drop this:
|
// each keypress - let's just drop this:
|
||||||
break;
|
break;
|
||||||
|
if (!receivedData) { // only accept new data the previous data has been fetched
|
||||||
int Now = time_ms();
|
int Now = time_ms();
|
||||||
if (Command != LastCommand) {
|
if (Command != LastCommand) {
|
||||||
receivedAddress = Address;
|
receivedAddress = Address;
|
||||||
receivedCommand = Command;
|
receivedCommand = Command;
|
||||||
receivedData = true;
|
receivedData = true;
|
||||||
|
receivedRepeat = receivedRelease = false;
|
||||||
FirstTime = Now;
|
FirstTime = Now;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -167,21 +169,21 @@ void cRcIoRCU::Action(void)
|
|||||||
WakeUp();
|
WakeUp();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (receivedData) { // the last data before releasing the key hasn't been fetched yet
|
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
|
if (receivedRepeat) { // it was a repeat, so let's make it a release
|
||||||
//XXX replace it with "released"???
|
receivedRepeat = false;
|
||||||
receivedData = receivedRepeat = false;
|
receivedRelease = true;
|
||||||
LastCommand = 0;
|
LastCommand = 0;
|
||||||
//XXX WakeUp();
|
WakeUp();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (receivedRepeat) { // all data has already been fetched, but the last one was a repeat
|
else if (receivedRepeat) { // all data has already been fetched, but the last one was a repeat, so let's generate a release
|
||||||
//XXX replace it with "released"???
|
receivedData = receivedRelease = true;
|
||||||
//XXX receivedData = true;
|
|
||||||
receivedRepeat = false;
|
receivedRepeat = false;
|
||||||
LastCommand = 0;
|
LastCommand = 0;
|
||||||
WakeUp();
|
WakeUp();
|
||||||
@ -266,7 +268,7 @@ void cRcIoRCU::Flush(int WaitMs)
|
|||||||
receivedData = receivedRepeat = false;
|
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
|
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 (receivedData) { // need to check again, since the status might have changed while waiting for the lock
|
||||||
if (Command)
|
if (Command)
|
||||||
*Command = receivedCommand;
|
*Command = receivedCommand;
|
||||||
//XXX repeat!!!
|
if (Repeat)
|
||||||
|
*Repeat = receivedRepeat;
|
||||||
|
if (Release)
|
||||||
|
*Release = receivedRelease;
|
||||||
receivedData = false;
|
receivedData = false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -422,17 +427,21 @@ void cRcIoLIRC::Action(void)
|
|||||||
|
|
||||||
int FirstTime = 0;
|
int FirstTime = 0;
|
||||||
char buf[LIRC_BUFFER_SIZE];
|
char buf[LIRC_BUFFER_SIZE];
|
||||||
|
char LastKeyName[LIRC_KEY_BUF];
|
||||||
|
|
||||||
for (; f >= 0;) {
|
for (; f >= 0;) {
|
||||||
|
|
||||||
LOCK_THREAD;
|
LOCK_THREAD;
|
||||||
|
|
||||||
if (cFile::FileReady(f, REPEATLIMIT) && read(f, buf, sizeof(buf)) > 21) {
|
if (cFile::FileReady(f, REPEATLIMIT) && read(f, buf, sizeof(buf)) > 21) {
|
||||||
|
if (!receivedData) { // only accept new data the previous data has been fetched
|
||||||
int count;
|
int count;
|
||||||
sscanf(buf, "%*x %x %7s", &count, keyName); // '7' in '%7s' is LIRC_KEY_BUF-1!
|
sscanf(buf, "%*x %x %7s", &count, LastKeyName); // '7' in '%7s' is LIRC_KEY_BUF-1!
|
||||||
int Now = time_ms();
|
int Now = time_ms();
|
||||||
if (count == 0) {
|
if (count == 0) {
|
||||||
|
strcpy(keyName, LastKeyName);
|
||||||
receivedData = true;
|
receivedData = true;
|
||||||
|
receivedRepeat = receivedRelease = false;
|
||||||
FirstTime = Now;
|
FirstTime = Now;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -442,27 +451,23 @@ void cRcIoLIRC::Action(void)
|
|||||||
}
|
}
|
||||||
WakeUp();
|
WakeUp();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else if (receivedData) { // the last data before releasing the key hasn't been fetched yet
|
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
|
if (receivedRepeat) { // it was a repeat, so let's make it a release
|
||||||
//XXX replace it with "released"???
|
receivedRepeat = false;
|
||||||
receivedData = receivedRepeat = false;
|
receivedRelease = true;
|
||||||
*keyName = 0;
|
WakeUp();
|
||||||
//XXX WakeUp();
|
}
|
||||||
}
|
}
|
||||||
}
|
else if (receivedRepeat) { // all data has already been fetched, but the last one was a repeat, so let's generate a release
|
||||||
else if (receivedRepeat) { // all data has already been fetched, but the last one was a repeat
|
receivedData = receivedRelease = true;
|
||||||
//XXX replace it with "released"???
|
|
||||||
//XXX receivedData = true;
|
|
||||||
receivedRepeat = false;
|
receivedRepeat = false;
|
||||||
*keyName = 0;
|
|
||||||
WakeUp();
|
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
|
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 (receivedData) { // need to check again, since the status might have changed while waiting for the lock
|
||||||
if (Command)
|
if (Command)
|
||||||
*Command = Keys.Encode(keyName);
|
*Command = Keys.Encode(keyName);
|
||||||
//XXX repeat!!!
|
if (Repeat)
|
||||||
|
*Repeat = receivedRepeat;
|
||||||
|
if (Release)
|
||||||
|
*Release = receivedRelease;
|
||||||
receivedData = false;
|
receivedData = false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
14
remote.h
14
remote.h
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* 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
|
#ifndef __REMOTE_H
|
||||||
@ -30,7 +30,7 @@ public:
|
|||||||
virtual bool DetectCode(unsigned char *Code, unsigned short *Address) { return true; }
|
virtual bool DetectCode(unsigned char *Code, unsigned short *Address) { return true; }
|
||||||
virtual void Flush(int WaitMs = 0) {}
|
virtual void Flush(int WaitMs = 0) {}
|
||||||
virtual bool InputAvailable(void) = 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
|
#if defined REMOTE_KBD
|
||||||
@ -43,7 +43,7 @@ public:
|
|||||||
virtual ~cRcIoKBD();
|
virtual ~cRcIoKBD();
|
||||||
virtual void Flush(int WaitMs = 0);
|
virtual void Flush(int WaitMs = 0);
|
||||||
virtual bool InputAvailable(void);
|
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
|
#elif defined REMOTE_RCU
|
||||||
@ -55,7 +55,7 @@ private:
|
|||||||
unsigned short address;
|
unsigned short address;
|
||||||
unsigned short receivedAddress;
|
unsigned short receivedAddress;
|
||||||
unsigned int receivedCommand;
|
unsigned int receivedCommand;
|
||||||
bool receivedData, receivedRepeat;
|
bool receivedData, receivedRepeat, receivedRelease;
|
||||||
int lastNumber;
|
int lastNumber;
|
||||||
bool SendCommand(unsigned char Cmd);
|
bool SendCommand(unsigned char Cmd);
|
||||||
int ReceiveByte(int TimeoutMs = 0);
|
int ReceiveByte(int TimeoutMs = 0);
|
||||||
@ -74,7 +74,7 @@ public:
|
|||||||
virtual bool DetectCode(unsigned char *Code, unsigned short *Address);
|
virtual bool DetectCode(unsigned char *Code, unsigned short *Address);
|
||||||
virtual void Flush(int WaitMs = 0);
|
virtual void Flush(int WaitMs = 0);
|
||||||
virtual bool InputAvailable(void) { return receivedData; }
|
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
|
#elif defined REMOTE_LIRC
|
||||||
@ -84,13 +84,13 @@ private:
|
|||||||
enum { LIRC_KEY_BUF = 8, LIRC_BUFFER_SIZE = 128 };
|
enum { LIRC_KEY_BUF = 8, LIRC_BUFFER_SIZE = 128 };
|
||||||
int f;
|
int f;
|
||||||
char keyName[LIRC_KEY_BUF];
|
char keyName[LIRC_KEY_BUF];
|
||||||
bool receivedData, receivedRepeat;
|
bool receivedData, receivedRepeat, receivedRelease;
|
||||||
virtual void Action(void);
|
virtual void Action(void);
|
||||||
public:
|
public:
|
||||||
cRcIoLIRC(char *DeviceName);
|
cRcIoLIRC(char *DeviceName);
|
||||||
virtual ~cRcIoLIRC();
|
virtual ~cRcIoLIRC();
|
||||||
virtual bool InputAvailable(void) { return receivedData; }
|
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
|
#else
|
||||||
|
10
vdr.c
10
vdr.c
@ -22,7 +22,7 @@
|
|||||||
*
|
*
|
||||||
* The project's page is at http://www.cadsoft.de/people/kls/vdr
|
* 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>
|
#include <getopt.h>
|
||||||
@ -257,10 +257,12 @@ int main(int argc, char *argv[])
|
|||||||
Menu = new cDirectChannelSelect(key);
|
Menu = new cDirectChannelSelect(key);
|
||||||
break;
|
break;
|
||||||
// Left/Right rotates trough channel groups:
|
// Left/Right rotates trough channel groups:
|
||||||
|
case kLeft|k_Repeat:
|
||||||
case kLeft:
|
case kLeft:
|
||||||
|
case kRight|k_Repeat:
|
||||||
case kRight: if (!Interface.Recording()) {
|
case kRight: if (!Interface.Recording()) {
|
||||||
int SaveGroup = CurrentGroup;
|
int SaveGroup = CurrentGroup;
|
||||||
if (key == kRight)
|
if (NORMALKEY(key) == kRight)
|
||||||
CurrentGroup = Channels.GetNextGroup(CurrentGroup) ;
|
CurrentGroup = Channels.GetNextGroup(CurrentGroup) ;
|
||||||
else
|
else
|
||||||
CurrentGroup = Channels.GetPrevGroup(CurrentGroup < 1 ? 1 : CurrentGroup);
|
CurrentGroup = Channels.GetPrevGroup(CurrentGroup < 1 ? 1 : CurrentGroup);
|
||||||
@ -271,9 +273,11 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
// Up/Down Channel Select:
|
// Up/Down Channel Select:
|
||||||
|
case kUp|k_Repeat:
|
||||||
case kUp:
|
case kUp:
|
||||||
|
case kDown|k_Repeat:
|
||||||
case kDown: if (!Interface.Recording()) {
|
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);
|
cChannel *channel = Channels.GetByNumber(n);
|
||||||
if (channel)
|
if (channel)
|
||||||
channel->Switch();
|
channel->Switch();
|
||||||
|
Loading…
Reference in New Issue
Block a user