mirror of
https://github.com/VDR4Arch/vdr.git
synced 2023-10-10 13:36:52 +02:00
Added support for LIRC remote control
This commit is contained in:
parent
5c574ffb7b
commit
20019e7ce5
5
CONTRIBUTORS
Normal file
5
CONTRIBUTORS
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
Thanks go to the following people for patches and contributions:
|
||||||
|
|
||||||
|
Carsten Koch <Carsten.Koch@icem.de>
|
||||||
|
for adding LIRC support
|
||||||
|
|
9
HISTORY
9
HISTORY
@ -55,3 +55,12 @@ Video Disk Recorder Revision History
|
|||||||
- Reduced the number of remote control keys. Modified the key assignments for
|
- Reduced the number of remote control keys. Modified the key assignments for
|
||||||
the PC keyboard to better resemble the "up-down-left-right-ok" layout on
|
the PC keyboard to better resemble the "up-down-left-right-ok" layout on
|
||||||
menu controlling remote control units.
|
menu controlling remote control units.
|
||||||
|
|
||||||
|
2000-07-15: Version 0.06
|
||||||
|
|
||||||
|
- Added support for LIRC remote control (thanks to Carsten Koch!).
|
||||||
|
There are now three different remote control modes: KBD (PC-Keyboard), RCU
|
||||||
|
and LIRC. See the INSTALL file for information on how to enable either of
|
||||||
|
these modes. The default mode is now KBD, not RCU as before (to make it
|
||||||
|
work immediately even if there is no actual remote control).
|
||||||
|
|
||||||
|
30
INSTALL
30
INSTALL
@ -20,10 +20,16 @@ and type 'make'. This should produce an executable file
|
|||||||
named 'vdr', which can be run after the DVB driver has been
|
named 'vdr', which can be run after the DVB driver has been
|
||||||
installed.
|
installed.
|
||||||
|
|
||||||
There are two macros you can use to customize the 'vdr' program
|
The 'vdr' program can be controlled via the PC keyboard or
|
||||||
at compile time. Adding "DEBUG_REMOTE=1" to the 'make' call
|
an infrared remote control unit. Define the REMOTE macro to one of the
|
||||||
will use the PC's keyboard as input device instead of the "Remote
|
following values 'make' call to activate the respective control mode:
|
||||||
Control Unit" (see http://www.cadsoft.de/people/kls/vdr/remote.htm).
|
|
||||||
|
REMOTE=KBD control via the PC keyboard (default)
|
||||||
|
REMOTE=RCU control via the "Remote Control Unit" receiver
|
||||||
|
(see http://www.cadsoft.de/people/kls/vdr/remote.htm)
|
||||||
|
REMOTE=LIRC control via the "Linux Infrared Remote Control"
|
||||||
|
(see http://fsinfo.cs.uni-sb.de/~columbus/lirc)
|
||||||
|
|
||||||
Adding "DEBUG_OSD=1" will use the PC screen (or current window)
|
Adding "DEBUG_OSD=1" will use the PC screen (or current window)
|
||||||
to display texts instead of the DVB card's on-screen display
|
to display texts instead of the DVB card's on-screen display
|
||||||
interface. These modes are useful when testing new menus if you
|
interface. These modes are useful when testing new menus if you
|
||||||
@ -65,7 +71,7 @@ Learning the remote control keys:
|
|||||||
---------------------------------
|
---------------------------------
|
||||||
|
|
||||||
There is no default 'keys.conf' file, so if you compile the program
|
There is no default 'keys.conf' file, so if you compile the program
|
||||||
without 'DEBUG_REMOTE=1' you will have to go through a "teach-in"
|
with 'REMOTE=RCU' you will have to go through a "teach-in"
|
||||||
session that allows the program to learn your remote control codes.
|
session that allows the program to learn your remote control codes.
|
||||||
It will first attempt to determine the basic data transfer mode and
|
It will first attempt to determine the basic data transfer mode and
|
||||||
timing of your remote control unit, and then will ask you to press one
|
timing of your remote control unit, and then will ask you to press one
|
||||||
@ -76,9 +82,9 @@ you define, the more you will be able to navigate through the menus and
|
|||||||
control recording/replaying. The program uses only a very small number
|
control recording/replaying. The program uses only a very small number
|
||||||
of keys which have multiple meanings in the various modes (see MANUAL
|
of keys which have multiple meanings in the various modes (see MANUAL
|
||||||
for a detailed description).
|
for a detailed description).
|
||||||
If the program has been built with "DEBUG_REMOTE=1", it will use the
|
If the program has been built with "REMOTE=KBD", it will use the
|
||||||
key configuration file 'keys-pc.conf', so that you won't loose data
|
key configuration file 'keys-pc.conf', so that you won't loose data
|
||||||
when switching between normal and debug mode.
|
when switching between remote control and keyboard mode.
|
||||||
|
|
||||||
The default PC key assignments are:
|
The default PC key assignments are:
|
||||||
|
|
||||||
@ -89,6 +95,12 @@ The default PC key assignments are:
|
|||||||
Red, Green, Yellow, Blue 'F1'..'F4'
|
Red, Green, Yellow, Blue 'F1'..'F4'
|
||||||
0..9 '0'..'9' in top row
|
0..9 '0'..'9' in top row
|
||||||
|
|
||||||
If you prefer different key assignments, simply delete the file
|
If you prefer different key assignments, or if the default doesn't work for
|
||||||
'keys-pc.conf' and restart 'vdr' to get into learning mode.
|
your keyboard, simply delete the file 'keys-pc.conf' and restart 'vdr' to get
|
||||||
|
into learning mode.
|
||||||
|
|
||||||
|
If the program has been compiled with 'REMOTE=LIRC', no 'keys.conf' file
|
||||||
|
will be used. Instead, the key names as listed in the source file 'config.c'
|
||||||
|
must be used when setting up LIRC. See http://www2.arnes.si/~mthale1 for
|
||||||
|
more about LIRC.
|
||||||
|
|
||||||
|
8
Makefile
8
Makefile
@ -4,14 +4,16 @@
|
|||||||
# 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: Makefile 1.3 2000/04/24 09:44:10 kls Exp $
|
# $Id: Makefile 1.4 2000/06/24 15:09:30 kls Exp $
|
||||||
|
|
||||||
OBJS = config.o dvbapi.o interface.o menu.o osd.o recording.o remote.o tools.o vdr.o
|
OBJS = config.o dvbapi.o interface.o menu.o osd.o recording.o remote.o tools.o vdr.o
|
||||||
|
|
||||||
ifdef DEBUG_REMOTE
|
ifndef REMOTE
|
||||||
DEFINES += -DDEBUG_REMOTE
|
REMOTE = KBD
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
DEFINES += -DREMOTE_$(REMOTE)
|
||||||
|
|
||||||
ifdef DEBUG_OSD
|
ifdef DEBUG_OSD
|
||||||
DEFINES += -DDEBUG_OSD
|
DEFINES += -DDEBUG_OSD
|
||||||
endif
|
endif
|
||||||
|
13
config.c
13
config.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: config.c 1.7 2000/05/27 14:44:15 kls Exp $
|
* $Id: config.c 1.8 2000/07/15 12:39:20 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
@ -146,6 +146,17 @@ eKeys cKeys::Get(unsigned int Code)
|
|||||||
return kNone;
|
return kNone;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned int cKeys::Encode(const char *Command)
|
||||||
|
{
|
||||||
|
if (Command != NULL) {
|
||||||
|
const tKey *k = keys;
|
||||||
|
while ((k->type != kNone) && strncmp(k->name, Command, strlen(k->name)) != 0) // must use 'strncmp()' because LIRC delivers trailing characters!
|
||||||
|
k++;
|
||||||
|
return k->code;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void cKeys::Set(eKeys Key, unsigned int Code)
|
void cKeys::Set(eKeys Key, unsigned int Code)
|
||||||
{
|
{
|
||||||
for (tKey *k = keys; k->type != kNone; k++) {
|
for (tKey *k = keys; k->type != kNone; k++) {
|
||||||
|
3
config.h
3
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.6 2000/05/27 14:43:46 kls Exp $
|
* $Id: config.h 1.7 2000/06/24 13:42:32 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __CONFIG_H
|
#ifndef __CONFIG_H
|
||||||
@ -52,6 +52,7 @@ public:
|
|||||||
void Clear(void);
|
void Clear(void);
|
||||||
bool Load(char *FileName = NULL);
|
bool Load(char *FileName = NULL);
|
||||||
bool Save(void);
|
bool Save(void);
|
||||||
|
unsigned int Encode(const char *Command);
|
||||||
eKeys Get(unsigned int Code);
|
eKeys Get(unsigned int Code);
|
||||||
void Set(eKeys Key, unsigned int Code);
|
void Set(eKeys Key, unsigned int Code);
|
||||||
};
|
};
|
||||||
|
6
dvbapi.c
6
dvbapi.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: dvbapi.c 1.10 2000/05/27 14:07:17 kls Exp $
|
* $Id: dvbapi.c 1.11 2000/06/24 14:03:19 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "dvbapi.h"
|
#include "dvbapi.h"
|
||||||
@ -1054,7 +1054,7 @@ cDvbApi::cDvbApi(const char *FileName)
|
|||||||
if (videoDev < 0)
|
if (videoDev < 0)
|
||||||
LOG_ERROR;
|
LOG_ERROR;
|
||||||
cols = rows = 0;
|
cols = rows = 0;
|
||||||
#if defined(DEBUG_OSD) || defined(DEBUG_REMOTE)
|
#if defined(DEBUG_OSD) || defined(REMOTE_KBD)
|
||||||
initscr();
|
initscr();
|
||||||
keypad(stdscr, TRUE);
|
keypad(stdscr, TRUE);
|
||||||
nonl();
|
nonl();
|
||||||
@ -1080,7 +1080,7 @@ cDvbApi::~cDvbApi()
|
|||||||
StopRecord();
|
StopRecord();
|
||||||
close(videoDev);
|
close(videoDev);
|
||||||
}
|
}
|
||||||
#if defined(DEBUG_REMOTE) || defined(DEBUG_OSD)
|
#if defined(DEBUG_OSD) || defined(REMOTE_KBD)
|
||||||
endwin();
|
endwin();
|
||||||
#endif
|
#endif
|
||||||
delete replayTitle;
|
delete replayTitle;
|
||||||
|
4
dvbapi.h
4
dvbapi.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: dvbapi.h 1.10 2000/05/20 14:50:43 kls Exp $
|
* $Id: dvbapi.h 1.11 2000/06/24 14:03:57 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __DVBAPI_H
|
#ifndef __DVBAPI_H
|
||||||
@ -15,7 +15,7 @@ typedef unsigned int __u32;
|
|||||||
typedef unsigned short __u16;
|
typedef unsigned short __u16;
|
||||||
typedef unsigned char __u8;
|
typedef unsigned char __u8;
|
||||||
|
|
||||||
#if defined(DEBUG_OSD) || defined(DEBUG_REMOTE)
|
#if defined(DEBUG_OSD) || defined(REMOTE_KBD)
|
||||||
#include <ncurses.h>
|
#include <ncurses.h>
|
||||||
#endif
|
#endif
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
28
interface.c
28
interface.c
@ -4,15 +4,19 @@
|
|||||||
* 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.9 2000/05/07 09:28:39 kls Exp $
|
* $Id: interface.c 1.10 2000/07/15 12:39:20 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "interface.h"
|
#include "interface.h"
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include "remote.h"
|
#include "remote.h"
|
||||||
|
|
||||||
#ifndef DEBUG_REMOTE
|
#if defined(REMOTE_RCU)
|
||||||
cRcIo RcIo("/dev/ttyS1");
|
cRcIoRCU RcIo("/dev/ttyS1");
|
||||||
|
#elif defined(REMOTE_LIRC)
|
||||||
|
cRcIoLIRC RcIo("/dev/lircd");
|
||||||
|
#else
|
||||||
|
cRcIoKBD RcIo;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
cInterface Interface;
|
cInterface Interface;
|
||||||
@ -26,9 +30,7 @@ cInterface::cInterface(void)
|
|||||||
|
|
||||||
void cInterface::Init(void)
|
void cInterface::Init(void)
|
||||||
{
|
{
|
||||||
#ifndef DEBUG_REMOTE
|
|
||||||
RcIo.SetCode(Keys.code, Keys.address);
|
RcIo.SetCode(Keys.code, Keys.address);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void cInterface::Open(int NumCols, int NumLines)
|
void cInterface::Open(int NumCols, int NumLines)
|
||||||
@ -47,21 +49,15 @@ void cInterface::Close(void)
|
|||||||
|
|
||||||
unsigned int cInterface::GetCh(bool Wait)
|
unsigned int cInterface::GetCh(bool Wait)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_REMOTE
|
|
||||||
timeout(Wait ? 1000 :10);
|
|
||||||
int c = getch();
|
|
||||||
return (c > 0) ? c : 0;
|
|
||||||
#else
|
|
||||||
#ifdef DEBUG_OSD
|
#ifdef DEBUG_OSD
|
||||||
timeout(0);
|
timeout(0);
|
||||||
getch(); // just to make 'ncurses' display the window:
|
getch(); // just to make 'ncurses' display the window:
|
||||||
#endif
|
#endif
|
||||||
if (Wait || RcIo.InputAvailable()) {
|
if (RcIo.InputAvailable(Wait)) {
|
||||||
unsigned int Command;
|
unsigned int Command;
|
||||||
return RcIo.GetCommand(&Command, NULL) ? Command : 0;
|
return RcIo.GetCommand(&Command, NULL) ? Command : 0;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
eKeys cInterface::GetKey(bool Wait)
|
eKeys cInterface::GetKey(bool Wait)
|
||||||
@ -215,12 +211,12 @@ void cInterface::QueryKeys(void)
|
|||||||
WriteText(1, 1, "Learning Remote Control Keys");
|
WriteText(1, 1, "Learning Remote Control Keys");
|
||||||
WriteText(1, 3, "Phase 1: Detecting RC code type");
|
WriteText(1, 3, "Phase 1: Detecting RC code type");
|
||||||
WriteText(1, 5, "Press any key on the RC unit");
|
WriteText(1, 5, "Press any key on the RC unit");
|
||||||
#ifndef DEBUG_REMOTE
|
#ifndef REMOTE_KBD
|
||||||
unsigned char Code = 0;
|
unsigned char Code = 0;
|
||||||
unsigned short Address;
|
unsigned short Address;
|
||||||
#endif
|
#endif
|
||||||
for (;;) {
|
for (;;) {
|
||||||
#ifdef DEBUG_REMOTE
|
#ifdef REMOTE_KBD
|
||||||
if (GetCh())
|
if (GetCh())
|
||||||
break;
|
break;
|
||||||
#else
|
#else
|
||||||
@ -318,9 +314,7 @@ void cInterface::LearnKeys(void)
|
|||||||
|
|
||||||
void cInterface::DisplayChannel(int Number, const char *Name)
|
void cInterface::DisplayChannel(int Number, const char *Name)
|
||||||
{
|
{
|
||||||
#ifndef DEBUG_REMOTE
|
|
||||||
RcIo.Number(Number);
|
RcIo.Number(Number);
|
||||||
#endif
|
|
||||||
if (Name && !Recording()) {
|
if (Name && !Recording()) {
|
||||||
Open(MenuColumns, 1);
|
Open(MenuColumns, 1);
|
||||||
char buffer[MenuColumns + 1];
|
char buffer[MenuColumns + 1];
|
||||||
@ -338,9 +332,7 @@ void cInterface::DisplayChannel(int Number, const char *Name)
|
|||||||
|
|
||||||
void cInterface::DisplayRecording(int Index, bool On)
|
void cInterface::DisplayRecording(int Index, bool On)
|
||||||
{
|
{
|
||||||
#ifndef DEBUG_REMOTE
|
|
||||||
RcIo.SetPoints(1 << Index, On);
|
RcIo.SetPoints(1 << Index, On);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cInterface::Recording(void)
|
bool cInterface::Recording(void)
|
||||||
|
218
remote.c
218
remote.c
@ -4,7 +4,9 @@
|
|||||||
* 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.c 1.8 2000/06/17 17:43:05 kls Exp $
|
* Ported to LIRC by Carsten Koch <Carsten.Koch@icem.de> 2000-06-16.
|
||||||
|
*
|
||||||
|
* $Id: remote.c 1.9 2000/07/15 12:19:50 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "remote.h"
|
#include "remote.h"
|
||||||
@ -15,20 +17,82 @@
|
|||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <termios.h>
|
#include <termios.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#if defined REMOTE_LIRC
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/un.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
#include "tools.h"
|
#include "tools.h"
|
||||||
|
|
||||||
#define REPEATLIMIT 100 // ms
|
#define REPEATLIMIT 100 // ms
|
||||||
#define REPEATDELAY 250 // ms
|
#define REPEATDELAY 250 // ms
|
||||||
|
|
||||||
cRcIo::cRcIo(char *DeviceName)
|
// --- cRcIoBase -------------------------------------------------------------
|
||||||
|
|
||||||
|
cRcIoBase::cRcIoBase(void)
|
||||||
|
{
|
||||||
|
t = 0;
|
||||||
|
firstTime = lastTime = 0;
|
||||||
|
lastCommand = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
cRcIoBase::~cRcIoBase()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- cRcIoKBD --------------------------------------------------------------
|
||||||
|
|
||||||
|
#if defined REMOTE_KBD
|
||||||
|
|
||||||
|
cRcIoKBD::cRcIoKBD(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
cRcIoKBD::~cRcIoKBD()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void cRcIoKBD::Flush(int WaitSeconds)
|
||||||
|
{
|
||||||
|
time_t t0 = time(NULL);
|
||||||
|
|
||||||
|
timeout(10);
|
||||||
|
for (;;) {
|
||||||
|
while (getch() > 0)
|
||||||
|
t0 = time(NULL);
|
||||||
|
if (time(NULL) - t0 >= WaitSeconds)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool cRcIoKBD::InputAvailable(bool Wait)
|
||||||
|
{
|
||||||
|
timeout(Wait ? 1000 : 10);
|
||||||
|
return true;//XXX
|
||||||
|
}
|
||||||
|
|
||||||
|
bool cRcIoKBD::GetCommand(unsigned int *Command, unsigned short *)
|
||||||
|
{
|
||||||
|
if (Command) {
|
||||||
|
*Command = getch();
|
||||||
|
return *Command > 0;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- cRcIoRCU --------------------------------------------------------------
|
||||||
|
|
||||||
|
#elif defined REMOTE_RCU
|
||||||
|
|
||||||
|
cRcIoRCU::cRcIoRCU(char *DeviceName)
|
||||||
{
|
{
|
||||||
dp = 0;
|
dp = 0;
|
||||||
mode = modeB;
|
mode = modeB;
|
||||||
code = 0;
|
code = 0;
|
||||||
address = 0xFFFF;
|
address = 0xFFFF;
|
||||||
t = 0;
|
|
||||||
firstTime = lastTime = 0;
|
|
||||||
lastCommand = 0;
|
|
||||||
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;
|
||||||
@ -46,28 +110,13 @@ cRcIo::cRcIo(char *DeviceName)
|
|||||||
f = -1;
|
f = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
cRcIo::~cRcIo()
|
cRcIoRCU::~cRcIoRCU()
|
||||||
{
|
{
|
||||||
if (f >= 0)
|
if (f >= 0)
|
||||||
close(f);
|
close(f);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cRcIo::InputAvailable(bool Wait)
|
int cRcIoRCU::ReceiveByte(bool Wait)
|
||||||
{
|
|
||||||
if (f >= 0) {
|
|
||||||
fd_set set;
|
|
||||||
struct timeval timeout;
|
|
||||||
timeout.tv_sec = Wait ? 1 : 0;
|
|
||||||
timeout.tv_usec = Wait ? 0 : 10000;
|
|
||||||
FD_ZERO(&set);
|
|
||||||
FD_SET(f, &set);
|
|
||||||
if (select(FD_SETSIZE, &set, NULL, NULL, &timeout) > 0)
|
|
||||||
return FD_ISSET(f, &set);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
int cRcIo::ReceiveByte(bool Wait)
|
|
||||||
{
|
{
|
||||||
// Returns the byte if one was received within a timeout, -1 otherwise
|
// Returns the byte if one was received within a timeout, -1 otherwise
|
||||||
if (InputAvailable(Wait)) {
|
if (InputAvailable(Wait)) {
|
||||||
@ -80,7 +129,7 @@ int cRcIo::ReceiveByte(bool Wait)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cRcIo::SendByteHandshake(unsigned char c)
|
bool cRcIoRCU::SendByteHandshake(unsigned char c)
|
||||||
{
|
{
|
||||||
if (f >= 0) {
|
if (f >= 0) {
|
||||||
int w = write(f, &c, 1);
|
int w = write(f, &c, 1);
|
||||||
@ -104,7 +153,7 @@ bool cRcIo::SendByteHandshake(unsigned char c)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cRcIo::SendByte(unsigned char c)
|
bool cRcIoRCU::SendByte(unsigned char c)
|
||||||
{
|
{
|
||||||
for (int retry = 5; retry--;) {
|
for (int retry = 5; retry--;) {
|
||||||
if (SendByteHandshake(c))
|
if (SendByteHandshake(c))
|
||||||
@ -113,7 +162,20 @@ bool cRcIo::SendByte(unsigned char c)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cRcIo::Flush(int WaitSeconds)
|
bool cRcIoRCU::SetCode(unsigned char Code, unsigned short Address)
|
||||||
|
{
|
||||||
|
code = Code;
|
||||||
|
address = Address;
|
||||||
|
return SendCommand(code);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool cRcIoRCU::SetMode(unsigned char Mode)
|
||||||
|
{
|
||||||
|
mode = Mode;
|
||||||
|
return SendCommand(mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cRcIoRCU::Flush(int WaitSeconds)
|
||||||
{
|
{
|
||||||
time_t t0 = time(NULL);
|
time_t t0 = time(NULL);
|
||||||
|
|
||||||
@ -125,20 +187,12 @@ void cRcIo::Flush(int WaitSeconds)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cRcIo::SetCode(unsigned char Code, unsigned short Address)
|
bool cRcIoRCU::InputAvailable(bool Wait)
|
||||||
{
|
{
|
||||||
code = Code;
|
return DataAvailable(f, Wait);
|
||||||
address = Address;
|
|
||||||
return SendCommand(code);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cRcIo::SetMode(unsigned char Mode)
|
bool cRcIoRCU::GetCommand(unsigned int *Command, unsigned short *Address)
|
||||||
{
|
|
||||||
mode = Mode;
|
|
||||||
return SendCommand(mode);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool cRcIo::GetCommand(unsigned int *Command, unsigned short *Address)
|
|
||||||
{
|
{
|
||||||
#pragma pack(1)
|
#pragma pack(1)
|
||||||
union {
|
union {
|
||||||
@ -191,17 +245,17 @@ bool cRcIo::GetCommand(unsigned int *Command, unsigned short *Address)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cRcIo::SendCommand(unsigned char Cmd)
|
bool cRcIoRCU::SendCommand(unsigned char Cmd)
|
||||||
{
|
{
|
||||||
return SendByte(Cmd | 0x80);
|
return SendByte(Cmd | 0x80);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cRcIo::Digit(int n, int v)
|
bool cRcIoRCU::Digit(int n, int v)
|
||||||
{
|
{
|
||||||
return SendByte(((n & 0x03) << 5) | (v & 0x0F) | (((dp >> n) & 0x01) << 4));
|
return SendByte(((n & 0x03) << 5) | (v & 0x0F) | (((dp >> n) & 0x01) << 4));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cRcIo::Number(int n, bool Hex)
|
bool cRcIoRCU::Number(int n, bool Hex)
|
||||||
{
|
{
|
||||||
if (!Hex) {
|
if (!Hex) {
|
||||||
char buf[8];
|
char buf[8];
|
||||||
@ -222,7 +276,7 @@ bool cRcIo::Number(int n, bool Hex)
|
|||||||
return SendCommand(mode);
|
return SendCommand(mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cRcIo::String(char *s)
|
bool cRcIoRCU::String(char *s)
|
||||||
{
|
{
|
||||||
const char *chars = mode == modeH ? "0123456789ABCDEF" : "0123456789-EHLP ";
|
const char *chars = mode == modeH ? "0123456789ABCDEF" : "0123456789-EHLP ";
|
||||||
int n = 0;
|
int n = 0;
|
||||||
@ -239,7 +293,7 @@ bool cRcIo::String(char *s)
|
|||||||
return Number(n, true);
|
return Number(n, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cRcIo::SetPoints(unsigned char Dp, bool On)
|
void cRcIoRCU::SetPoints(unsigned char Dp, bool On)
|
||||||
{
|
{
|
||||||
if (On)
|
if (On)
|
||||||
dp |= Dp;
|
dp |= Dp;
|
||||||
@ -248,7 +302,7 @@ void cRcIo::SetPoints(unsigned char Dp, bool On)
|
|||||||
Number(lastNumber, true);
|
Number(lastNumber, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cRcIo::DetectCode(unsigned char *Code, unsigned short *Address)
|
bool cRcIoRCU::DetectCode(unsigned char *Code, unsigned short *Address)
|
||||||
{
|
{
|
||||||
// Caller should initialize 'Code' to 0 and call DetectCode()
|
// Caller should initialize 'Code' to 0 and call DetectCode()
|
||||||
// until it returns true. Whenever DetectCode() returns false
|
// until it returns true. Whenever DetectCode() returns false
|
||||||
@ -282,3 +336,83 @@ bool cRcIo::DetectCode(unsigned char *Code, unsigned short *Address)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --- cRcIoLIRC -------------------------------------------------------------
|
||||||
|
|
||||||
|
#elif defined REMOTE_LIRC
|
||||||
|
|
||||||
|
cRcIoLIRC::cRcIoLIRC(char *DeviceName)
|
||||||
|
{
|
||||||
|
struct sockaddr_un addr;
|
||||||
|
addr.sun_family = AF_UNIX;
|
||||||
|
strcpy(addr.sun_path, DeviceName);
|
||||||
|
f = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||||
|
if (f >= 0) {
|
||||||
|
if (connect(f, (struct sockaddr *)&addr, sizeof(addr)) >= 0)
|
||||||
|
return;
|
||||||
|
LOG_ERROR_STR(DeviceName);
|
||||||
|
close(f);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
LOG_ERROR_STR(DeviceName);
|
||||||
|
f = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
cRcIoLIRC::~cRcIoLIRC()
|
||||||
|
{
|
||||||
|
if (f >= 0)
|
||||||
|
close(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *cRcIoLIRC::ReceiveString(void)
|
||||||
|
{
|
||||||
|
while (InputAvailable(true)) {
|
||||||
|
if (read(f, buf, sizeof(buf)) > 21) {
|
||||||
|
const int repeat = 10 * (buf[17] - '0') + (buf[18] - '0');
|
||||||
|
const int now = time_ms();
|
||||||
|
if (repeat == 0) {
|
||||||
|
firstTime = lastTime = now;
|
||||||
|
return buf + 20;
|
||||||
|
}
|
||||||
|
else if ((now > firstTime + REPEATDELAY) && (now > lastTime + REPEATLIMIT)) {
|
||||||
|
lastTime = now;
|
||||||
|
return buf + 20;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cRcIoLIRC::Flush(int WaitSeconds)
|
||||||
|
{
|
||||||
|
time_t t0 = time(NULL);
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
while (InputAvailable(false)) {
|
||||||
|
read(f, buf, sizeof(buf));
|
||||||
|
t0 = time(NULL);
|
||||||
|
}
|
||||||
|
if (time(NULL) - t0 >= WaitSeconds)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool cRcIoLIRC::InputAvailable(bool Wait)
|
||||||
|
{
|
||||||
|
return DataAvailable(f, Wait);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool cRcIoLIRC::GetCommand(unsigned int *Command, unsigned short *)
|
||||||
|
{
|
||||||
|
Flush();
|
||||||
|
if (Command) {
|
||||||
|
const char *cmd = ReceiveString();
|
||||||
|
if (cmd) {
|
||||||
|
*Command = Keys.Encode(cmd);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
85
remote.h
85
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.5 2000/05/07 09:27:54 kls Exp $
|
* $Id: remote.h 1.6 2000/06/24 15:52:56 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __REMOTE_H
|
#ifndef __REMOTE_H
|
||||||
@ -13,14 +13,44 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
|
||||||
class cRcIo {
|
class cRcIoBase {
|
||||||
|
protected:
|
||||||
|
time_t t;
|
||||||
|
int firstTime, lastTime;
|
||||||
|
unsigned int lastCommand;
|
||||||
|
cRcIoBase(void);
|
||||||
|
virtual ~cRcIoBase();
|
||||||
|
public:
|
||||||
|
enum { modeH = 'h', modeB = 'b', modeS = 's' };
|
||||||
|
virtual bool SetCode(unsigned char Code, unsigned short Address) { return true; }
|
||||||
|
virtual bool SetMode(unsigned char Mode) { return true; }
|
||||||
|
virtual bool Number(int n, bool Hex = false) { return true; }
|
||||||
|
virtual void SetPoints(unsigned char Dp, bool On) {}
|
||||||
|
virtual bool String(char *s) { return true; }
|
||||||
|
virtual bool DetectCode(unsigned char *Code, unsigned short *Address) { return true; }
|
||||||
|
virtual void Flush(int WaitSeconds = 0) {}
|
||||||
|
virtual bool InputAvailable(bool Wait = false) = 0;
|
||||||
|
virtual bool GetCommand(unsigned int *Command, unsigned short *Address = NULL) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#if defined REMOTE_KBD
|
||||||
|
|
||||||
|
class cRcIoKBD : public cRcIoBase {
|
||||||
|
public:
|
||||||
|
cRcIoKBD(void);
|
||||||
|
virtual ~cRcIoKBD();
|
||||||
|
virtual void Flush(int WaitSeconds = 0);
|
||||||
|
virtual bool InputAvailable(bool Wait = false);
|
||||||
|
virtual bool GetCommand(unsigned int *Command, unsigned short *Address = NULL);
|
||||||
|
};
|
||||||
|
|
||||||
|
#elif defined REMOTE_RCU
|
||||||
|
|
||||||
|
class cRcIoRCU : public cRcIoBase {
|
||||||
private:
|
private:
|
||||||
int f;
|
int f;
|
||||||
unsigned char dp, code, mode;
|
unsigned char dp, code, mode;
|
||||||
unsigned short address;
|
unsigned short address;
|
||||||
time_t t;
|
|
||||||
int firstTime, lastTime;
|
|
||||||
unsigned int lastCommand;
|
|
||||||
int lastNumber;
|
int lastNumber;
|
||||||
bool SendCommand(unsigned char Cmd);
|
bool SendCommand(unsigned char Cmd);
|
||||||
int ReceiveByte(bool Wait = true);
|
int ReceiveByte(bool Wait = true);
|
||||||
@ -28,18 +58,39 @@ private:
|
|||||||
bool SendByte(unsigned char c);
|
bool SendByte(unsigned char c);
|
||||||
bool Digit(int n, int v);
|
bool Digit(int n, int v);
|
||||||
public:
|
public:
|
||||||
enum { modeH = 'h', modeB = 'b', modeS = 's' };
|
cRcIoRCU(char *DeviceName);
|
||||||
cRcIo(char *DeviceName);
|
virtual ~cRcIoRCU();
|
||||||
~cRcIo();
|
virtual bool SetCode(unsigned char Code, unsigned short Address);
|
||||||
bool InputAvailable(bool Wait = false);
|
virtual bool SetMode(unsigned char Mode);
|
||||||
void Flush(int WaitSeconds = 0);
|
virtual bool Number(int n, bool Hex = false);
|
||||||
bool SetCode(unsigned char Code, unsigned short Address);
|
virtual void SetPoints(unsigned char Dp, bool On);
|
||||||
bool SetMode(unsigned char Mode);
|
virtual bool String(char *s);
|
||||||
bool GetCommand(unsigned int *Command, unsigned short *Address = NULL);
|
virtual bool DetectCode(unsigned char *Code, unsigned short *Address);
|
||||||
bool Number(int n, bool Hex = false);
|
virtual void Flush(int WaitSeconds = 0);
|
||||||
void SetPoints(unsigned char Dp, bool On);
|
virtual bool InputAvailable(bool Wait = false);
|
||||||
bool String(char *s);
|
virtual bool GetCommand(unsigned int *Command, unsigned short *Address = NULL);
|
||||||
bool DetectCode(unsigned char *Code, unsigned short *Address);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#elif defined REMOTE_LIRC
|
||||||
|
|
||||||
|
class cRcIoLIRC : public cRcIoBase {
|
||||||
|
private:
|
||||||
|
enum { LIRC_BUFFER_SIZE = 128 };
|
||||||
|
int f;
|
||||||
|
char buf[LIRC_BUFFER_SIZE];
|
||||||
|
const char *ReceiveString(void);
|
||||||
|
public:
|
||||||
|
cRcIoLIRC(char *DeviceName);
|
||||||
|
virtual ~cRcIoLIRC();
|
||||||
|
virtual void Flush(int WaitSeconds = 0);
|
||||||
|
virtual bool InputAvailable(bool Wait = false);
|
||||||
|
virtual bool GetCommand(unsigned int *Command, unsigned short *Address = NULL);
|
||||||
|
};
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#error Please define a remote control mode!
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif //__REMOTE_H
|
#endif //__REMOTE_H
|
||||||
|
11
tools.c
11
tools.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: tools.c 1.7 2000/04/24 15:01:35 kls Exp $
|
* $Id: tools.c 1.8 2000/06/24 15:26:15 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define _GNU_SOURCE
|
#define _GNU_SOURCE
|
||||||
@ -22,16 +22,19 @@
|
|||||||
|
|
||||||
int SysLogLevel = 3;
|
int SysLogLevel = 3;
|
||||||
|
|
||||||
bool DataAvailable(int filedes)
|
bool DataAvailable(int filedes, bool wait)
|
||||||
{
|
{
|
||||||
|
if (filedes >= 0) {
|
||||||
fd_set set;
|
fd_set set;
|
||||||
FD_ZERO(&set);
|
FD_ZERO(&set);
|
||||||
FD_SET(filedes, &set);
|
FD_SET(filedes, &set);
|
||||||
struct timeval timeout;
|
struct timeval timeout;
|
||||||
timeout.tv_sec = 0;
|
timeout.tv_sec = wait ? 1 : 0;
|
||||||
timeout.tv_usec = 10000;
|
timeout.tv_usec = wait ? 0 : 10000;
|
||||||
return select(FD_SETSIZE, &set, NULL, NULL, &timeout) > 0 && FD_ISSET(filedes, &set);
|
return select(FD_SETSIZE, &set, NULL, NULL, &timeout) > 0 && FD_ISSET(filedes, &set);
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void writechar(int filedes, char c)
|
void writechar(int filedes, char c)
|
||||||
{
|
{
|
||||||
|
4
tools.h
4
tools.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: tools.h 1.7 2000/04/24 15:01:49 kls Exp $
|
* $Id: tools.h 1.8 2000/06/24 15:25:00 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __TOOLS_H
|
#ifndef __TOOLS_H
|
||||||
@ -30,7 +30,7 @@ extern int SysLogLevel;
|
|||||||
|
|
||||||
#define DELETENULL(p) (delete (p), p = NULL)
|
#define DELETENULL(p) (delete (p), p = NULL)
|
||||||
|
|
||||||
bool DataAvailable(int filedes);
|
bool DataAvailable(int filedes, bool wait = false);
|
||||||
void writechar(int filedes, char c);
|
void writechar(int filedes, char c);
|
||||||
void writeint(int filedes, int n);
|
void writeint(int filedes, int n);
|
||||||
char readchar(int filedes);
|
char readchar(int filedes);
|
||||||
|
6
vdr.c
6
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.19 2000/05/27 15:38:35 kls Exp $
|
* $Id: vdr.c 1.20 2000/07/15 11:45:05 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
@ -33,7 +33,7 @@
|
|||||||
#include "recording.h"
|
#include "recording.h"
|
||||||
#include "tools.h"
|
#include "tools.h"
|
||||||
|
|
||||||
#ifdef DEBUG_REMOTE
|
#ifdef REMOTE_KBD
|
||||||
#define KEYS_CONF "keys-pc.conf"
|
#define KEYS_CONF "keys-pc.conf"
|
||||||
#else
|
#else
|
||||||
#define KEYS_CONF "keys.conf"
|
#define KEYS_CONF "keys.conf"
|
||||||
@ -58,8 +58,10 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
Channels.Load("channels.conf");
|
Channels.Load("channels.conf");
|
||||||
Timers.Load("timers.conf");
|
Timers.Load("timers.conf");
|
||||||
|
#ifndef REMOTE_LIRC
|
||||||
if (!Keys.Load(KEYS_CONF))
|
if (!Keys.Load(KEYS_CONF))
|
||||||
Interface.LearnKeys();
|
Interface.LearnKeys();
|
||||||
|
#endif
|
||||||
Interface.Init();
|
Interface.Init();
|
||||||
|
|
||||||
cChannel::SwitchTo(CurrentChannel);
|
cChannel::SwitchTo(CurrentChannel);
|
||||||
|
Loading…
Reference in New Issue
Block a user