mirror of
				https://github.com/vdr-projects/vdr.git
				synced 2025-03-01 10:50:46 +00:00 
			
		
		
		
	Explicit Repeat/Release handling for remote control
This commit is contained in:
		
							
								
								
									
										10
									
								
								HISTORY
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								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.
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										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
 | 
			
		||||
            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.
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										11
									
								
								config.h
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								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;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										20
									
								
								interface.c
									
									
									
									
									
								
							
							
						
						
									
										20
									
								
								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;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										27
									
								
								menu.c
									
									
									
									
									
								
							
							
						
						
									
										27
									
								
								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;
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										4
									
								
								osd.c
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								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) {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										110
									
								
								remote.c
									
									
									
									
									
								
							
							
						
						
									
										110
									
								
								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;
 | 
			
		||||
         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();
 | 
			
		||||
            }
 | 
			
		||||
         else {
 | 
			
		||||
            if (Now - FirstTime < REPEATDELAY)
 | 
			
		||||
               continue; // repeat function kicks in after a short delay
 | 
			
		||||
            receivedData = receivedRepeat = true;
 | 
			
		||||
            }
 | 
			
		||||
         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;
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										14
									
								
								remote.h
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								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
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										10
									
								
								vdr.c
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								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();
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user