mirror of
https://github.com/VDR4Arch/vdr.git
synced 2023-10-10 13:36:52 +02:00
Remote control uses threads
This commit is contained in:
parent
60958ab132
commit
97c3bb6148
11
Makefile
11
Makefile
@ -4,13 +4,13 @@
|
|||||||
# 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.12 2000/10/01 14:27:12 kls Exp $
|
# $Id: Makefile 1.13 2000/10/07 16:24:08 kls Exp $
|
||||||
|
|
||||||
DVBDIR = ../DVB
|
DVBDIR = ../DVB
|
||||||
|
|
||||||
INCLUDES = -I$(DVBDIR)/driver
|
INCLUDES = -I$(DVBDIR)/driver
|
||||||
OBJS = config.o dvbapi.o dvbosd.o eit.o font.o interface.o menu.o osd.o\
|
OBJS = config.o dvbapi.o dvbosd.o eit.o font.o interface.o menu.o osd.o\
|
||||||
recording.o remote.o svdrp.o tools.o vdr.o videodir.o
|
recording.o remote.o svdrp.o thread.o tools.o vdr.o videodir.o
|
||||||
|
|
||||||
OSDFONT = -adobe-helvetica-medium-r-normal--23-*-100-100-p-*-iso8859-1
|
OSDFONT = -adobe-helvetica-medium-r-normal--23-*-100-100-p-*-iso8859-1
|
||||||
|
|
||||||
@ -40,12 +40,13 @@ dvbapi.o : dvbapi.c config.h dvbapi.h dvbosd.h font.h interface.h svdrp.h tool
|
|||||||
dvbosd.o : dvbosd.c dvbosd.h font.h tools.h
|
dvbosd.o : dvbosd.c dvbosd.h font.h tools.h
|
||||||
eit.o : eit.c eit.h tools.h
|
eit.o : eit.c eit.h tools.h
|
||||||
font.o : font.c font.h fontosd.c tools.h
|
font.o : font.c font.h fontosd.c tools.h
|
||||||
interface.o: interface.c config.h dvbapi.h dvbosd.h eit.h font.h interface.h remote.h svdrp.h tools.h
|
interface.o: interface.c config.h dvbapi.h dvbosd.h eit.h font.h interface.h remote.h svdrp.h thread.h tools.h
|
||||||
menu.o : menu.c config.h dvbapi.h dvbosd.h font.h interface.h menu.h osd.h recording.h svdrp.h tools.h
|
menu.o : menu.c config.h dvbapi.h dvbosd.h font.h interface.h menu.h osd.h recording.h svdrp.h tools.h
|
||||||
osd.o : osd.c config.h dvbapi.h dvbosd.h font.h interface.h osd.h svdrp.h tools.h
|
osd.o : osd.c config.h dvbapi.h dvbosd.h font.h interface.h osd.h svdrp.h tools.h
|
||||||
recording.o: recording.c config.h dvbapi.h dvbosd.h font.h interface.h recording.h svdrp.h tools.h videodir.h
|
recording.o: recording.c config.h dvbapi.h dvbosd.h font.h interface.h recording.h svdrp.h tools.h videodir.h
|
||||||
remote.o : remote.c config.h dvbapi.h dvbosd.h font.h remote.h tools.h
|
remote.o : remote.c config.h dvbapi.h dvbosd.h font.h remote.h thread.h tools.h
|
||||||
svdrp.o : svdrp.c config.h dvbapi.h dvbosd.h font.h interface.h svdrp.h tools.h
|
svdrp.o : svdrp.c config.h dvbapi.h dvbosd.h font.h interface.h svdrp.h tools.h
|
||||||
|
thread.o : thread.c thread.h
|
||||||
tools.o : tools.c tools.h
|
tools.o : tools.c tools.h
|
||||||
vdr.o : vdr.c config.h dvbapi.h dvbosd.h font.h interface.h menu.h osd.h recording.h svdrp.h tools.h videodir.h
|
vdr.o : vdr.c config.h dvbapi.h dvbosd.h font.h interface.h menu.h osd.h recording.h svdrp.h tools.h videodir.h
|
||||||
videodir.o : videodir.c tools.h videodir.h
|
videodir.o : videodir.c tools.h videodir.h
|
||||||
@ -53,7 +54,7 @@ videodir.o : videodir.c tools.h videodir.h
|
|||||||
# The main program:
|
# The main program:
|
||||||
|
|
||||||
vdr: $(OBJS)
|
vdr: $(OBJS)
|
||||||
g++ -g -O2 $(OBJS) -lncurses -ljpeg -o vdr
|
g++ -g -O2 $(OBJS) -lncurses -ljpeg -lpthread -o vdr
|
||||||
|
|
||||||
# The font file:
|
# The font file:
|
||||||
|
|
||||||
|
4
config.h
4
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.22 2000/10/01 14:14:18 kls Exp $
|
* $Id: config.h 1.23 2000/10/07 17:34:23 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __CONFIG_H
|
#ifndef __CONFIG_H
|
||||||
@ -17,7 +17,7 @@
|
|||||||
#include "dvbapi.h"
|
#include "dvbapi.h"
|
||||||
#include "tools.h"
|
#include "tools.h"
|
||||||
|
|
||||||
#define VDRVERSION "0.65"
|
#define VDRVERSION "0.66"
|
||||||
|
|
||||||
#define MaxBuffer 10000
|
#define MaxBuffer 10000
|
||||||
|
|
||||||
|
8
dvbosd.c
8
dvbosd.c
@ -4,10 +4,11 @@
|
|||||||
* 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: dvbosd.c 1.2 2000/10/03 13:34:13 kls Exp $
|
* $Id: dvbosd.c 1.3 2000/10/07 14:42:48 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "dvbosd.h"
|
#include "dvbosd.h"
|
||||||
|
#include <signal.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/unistd.h>
|
#include <sys/unistd.h>
|
||||||
@ -138,11 +139,16 @@ void cDvbOsd::Cmd(OSD_Command cmd, int color, int x0, int y0, int x1, int y1, co
|
|||||||
dc.x1 = x1;
|
dc.x1 = x1;
|
||||||
dc.y1 = y1;
|
dc.y1 = y1;
|
||||||
dc.data = (void *)data;
|
dc.data = (void *)data;
|
||||||
|
// must block all signals, otherwise the command might not be fully executed
|
||||||
|
sigset_t set, oldset;
|
||||||
|
sigfillset(&set);
|
||||||
|
sigprocmask(SIG_BLOCK, &set, &oldset);
|
||||||
ioctl(videoDev, VIDIOCSOSDCOMMAND, &dc);
|
ioctl(videoDev, VIDIOCSOSDCOMMAND, &dc);
|
||||||
usleep(10); // XXX Workaround for a driver bug (cInterface::DisplayChannel() displayed texts at wrong places
|
usleep(10); // XXX Workaround for a driver bug (cInterface::DisplayChannel() displayed texts at wrong places
|
||||||
// XXX and sometimes the OSD was no longer displayed).
|
// XXX and sometimes the OSD was no longer displayed).
|
||||||
// XXX Increase the value if the problem still persists on your particular system.
|
// XXX Increase the value if the problem still persists on your particular system.
|
||||||
// TODO Check if this is still necessary with driver versions after 0.7.
|
// TODO Check if this is still necessary with driver versions after 0.7.
|
||||||
|
sigprocmask(SIG_SETMASK, &oldset, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
26
interface.c
26
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.21 2000/10/03 13:28:02 kls Exp $
|
* $Id: interface.c 1.22 2000/10/07 16:42:37 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "interface.h"
|
#include "interface.h"
|
||||||
@ -60,17 +60,16 @@ void cInterface::Close(void)
|
|||||||
|
|
||||||
unsigned int cInterface::GetCh(bool Wait)
|
unsigned int cInterface::GetCh(bool Wait)
|
||||||
{
|
{
|
||||||
if (RcIo.InputAvailable(Wait)) {
|
if (open)
|
||||||
|
cDvbApi::PrimaryDvbApi->Flush();
|
||||||
|
if (!RcIo.InputAvailable())
|
||||||
|
cFile::AnyFileReady(-1, Wait ? 1000 : 0);
|
||||||
unsigned int Command;
|
unsigned int Command;
|
||||||
return RcIo.GetCommand(&Command, NULL) ? Command : 0;
|
return RcIo.GetCommand(&Command) ? Command : 0;
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
eKeys cInterface::GetKey(bool Wait)
|
eKeys cInterface::GetKey(bool Wait)
|
||||||
{
|
{
|
||||||
if (open)
|
|
||||||
cDvbApi::PrimaryDvbApi->Flush();
|
|
||||||
if (SVDRP)
|
if (SVDRP)
|
||||||
SVDRP->Process();
|
SVDRP->Process();
|
||||||
eKeys Key = keyFromWait != kNone ? keyFromWait : Keys.Get(GetCh(Wait));
|
eKeys Key = keyFromWait != kNone ? keyFromWait : Keys.Get(GetCh(Wait));
|
||||||
@ -85,12 +84,15 @@ void cInterface::PutKey(eKeys Key)
|
|||||||
|
|
||||||
eKeys cInterface::Wait(int Seconds, bool KeepChar)
|
eKeys cInterface::Wait(int Seconds, bool KeepChar)
|
||||||
{
|
{
|
||||||
eKeys Key = kNone;
|
|
||||||
if (open)
|
if (open)
|
||||||
cDvbApi::PrimaryDvbApi->Flush();
|
cDvbApi::PrimaryDvbApi->Flush();
|
||||||
RcIo.Flush(500);
|
eKeys Key = kNone;
|
||||||
if (cFile::AnyFileReady(-1, Seconds * 1000))
|
time_t timeout = time(NULL) + Seconds;
|
||||||
|
for (;;) {
|
||||||
Key = GetKey();
|
Key = GetKey();
|
||||||
|
if (Key != kNone || time(NULL) > timeout)
|
||||||
|
break;
|
||||||
|
}
|
||||||
if (KeepChar)
|
if (KeepChar)
|
||||||
keyFromWait = Key;
|
keyFromWait = Key;
|
||||||
return Key;
|
return Key;
|
||||||
@ -220,9 +222,11 @@ void cInterface::Help(const char *Red, const char *Green, const char *Yellow, co
|
|||||||
void cInterface::QueryKeys(void)
|
void cInterface::QueryKeys(void)
|
||||||
{
|
{
|
||||||
Keys.Clear();
|
Keys.Clear();
|
||||||
|
Clear();
|
||||||
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");
|
||||||
|
cDvbApi::PrimaryDvbApi->Flush();
|
||||||
#ifndef REMOTE_KBD
|
#ifndef REMOTE_KBD
|
||||||
unsigned char Code = 0;
|
unsigned char Code = 0;
|
||||||
unsigned short Address;
|
unsigned short Address;
|
||||||
@ -238,9 +242,11 @@ void cInterface::QueryKeys(void)
|
|||||||
Keys.address = Address;
|
Keys.address = Address;
|
||||||
WriteText(1, 5, "RC code detected!");
|
WriteText(1, 5, "RC code detected!");
|
||||||
WriteText(1, 6, "Do not press any key...");
|
WriteText(1, 6, "Do not press any key...");
|
||||||
|
cDvbApi::PrimaryDvbApi->Flush();
|
||||||
RcIo.Flush(3000);
|
RcIo.Flush(3000);
|
||||||
ClearEol(0, 5);
|
ClearEol(0, 5);
|
||||||
ClearEol(0, 6);
|
ClearEol(0, 6);
|
||||||
|
cDvbApi::PrimaryDvbApi->Flush();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -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.13 2000/09/18 22:29:31 kls Exp $
|
* $Id: interface.h 1.14 2000/10/07 16:17:53 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __INTERFACE_H
|
#ifndef __INTERFACE_H
|
||||||
@ -38,7 +38,7 @@ public:
|
|||||||
void ClearEol(int x, int y, eDvbColor Color = clrBackground);
|
void ClearEol(int x, int y, eDvbColor Color = clrBackground);
|
||||||
void SetCols(int *c);
|
void SetCols(int *c);
|
||||||
void Write(int x, int y, const char *s, eDvbColor FgColor = clrWhite, eDvbColor BgColor = clrBackground);
|
void Write(int x, int y, const char *s, eDvbColor FgColor = clrWhite, eDvbColor BgColor = clrBackground);
|
||||||
void WriteText(int x, int y, const char *s, eDvbColor FgColor = clrWhite, eDvbColor BgColor = clrBlack);
|
void WriteText(int x, int y, const char *s, eDvbColor FgColor = clrWhite, eDvbColor BgColor = clrBackground);
|
||||||
void Title(const char *s);
|
void Title(const char *s);
|
||||||
void Status(const char *s, eDvbColor FgColor = clrBlack, eDvbColor BgColor = clrCyan);
|
void Status(const char *s, eDvbColor FgColor = clrBlack, eDvbColor BgColor = clrCyan);
|
||||||
void Info(const char *s);
|
void Info(const char *s);
|
||||||
|
289
remote.c
289
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.15 2000/10/03 10:49:58 kls Exp $
|
* $Id: remote.c 1.16 2000/10/08 09:25:20 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "remote.h"
|
#include "remote.h"
|
||||||
@ -27,16 +27,11 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "tools.h"
|
#include "tools.h"
|
||||||
|
|
||||||
#define REPEATLIMIT 100 // ms
|
|
||||||
#define REPEATDELAY 250 // ms
|
|
||||||
|
|
||||||
// --- cRcIoBase -------------------------------------------------------------
|
// --- cRcIoBase -------------------------------------------------------------
|
||||||
|
|
||||||
cRcIoBase::cRcIoBase(void)
|
cRcIoBase::cRcIoBase(void)
|
||||||
{
|
{
|
||||||
t = 0;
|
t = 0;
|
||||||
firstTime = lastTime = 0;
|
|
||||||
lastCommand = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cRcIoBase::~cRcIoBase()
|
cRcIoBase::~cRcIoBase()
|
||||||
@ -69,12 +64,12 @@ void cRcIoKBD::Flush(int WaitMs)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cRcIoKBD::InputAvailable(bool Wait)
|
bool cRcIoKBD::InputAvailable(void)
|
||||||
{
|
{
|
||||||
return f.Ready(Wait);
|
return f.Ready(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cRcIoKBD::GetCommand(unsigned int *Command, unsigned short *)
|
bool cRcIoKBD::GetCommand(unsigned int *Command)
|
||||||
{
|
{
|
||||||
if (Command) {
|
if (Command) {
|
||||||
*Command = getch();
|
*Command = getch();
|
||||||
@ -87,36 +82,119 @@ bool cRcIoKBD::GetCommand(unsigned int *Command, unsigned short *)
|
|||||||
|
|
||||||
#elif defined REMOTE_RCU
|
#elif defined REMOTE_RCU
|
||||||
|
|
||||||
|
#define REPEATLIMIT 20 // ms
|
||||||
|
#define REPEATDELAY 350 // ms
|
||||||
|
|
||||||
cRcIoRCU::cRcIoRCU(char *DeviceName)
|
cRcIoRCU::cRcIoRCU(char *DeviceName)
|
||||||
{
|
{
|
||||||
dp = 0;
|
dp = 0;
|
||||||
mode = modeB;
|
mode = modeB;
|
||||||
code = 0;
|
code = 0;
|
||||||
address = 0xFFFF;
|
address = 0xFFFF;
|
||||||
|
receivedAddress = 0;
|
||||||
|
receivedCommand = 0;
|
||||||
|
receivedData = receivedRepeat = false;
|
||||||
lastNumber = 0;
|
lastNumber = 0;
|
||||||
if (f.Open(DeviceName, O_RDWR | O_NONBLOCK)) {
|
if ((f = open(DeviceName, O_RDWR | O_NONBLOCK)) >= 0) {
|
||||||
struct termios t;
|
struct termios t;
|
||||||
if (tcgetattr(f, &t) == 0) {
|
if (tcgetattr(f, &t) == 0) {
|
||||||
cfsetspeed(&t, B9600);
|
cfsetspeed(&t, B9600);
|
||||||
cfmakeraw(&t);
|
cfmakeraw(&t);
|
||||||
if (tcsetattr(f, TCSAFLUSH, &t) == 0)
|
if (tcsetattr(f, TCSAFLUSH, &t) == 0) {
|
||||||
|
Start();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
LOG_ERROR_STR(DeviceName);
|
LOG_ERROR_STR(DeviceName);
|
||||||
f.Close();
|
close(f);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
LOG_ERROR_STR(DeviceName);
|
LOG_ERROR_STR(DeviceName);
|
||||||
|
f = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
cRcIoRCU::~cRcIoRCU()
|
cRcIoRCU::~cRcIoRCU()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
int cRcIoRCU::ReceiveByte(bool Wait)
|
void cRcIoRCU::Action(void)
|
||||||
|
{
|
||||||
|
#pragma pack(1)
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
unsigned short address;
|
||||||
|
unsigned int command;
|
||||||
|
} data;
|
||||||
|
unsigned char raw[6];
|
||||||
|
} buffer;
|
||||||
|
#pragma pack()
|
||||||
|
|
||||||
|
dsyslog(LOG_INFO, "RCU remote control thread started (pid=%d)", getpid());
|
||||||
|
|
||||||
|
unsigned int LastCommand = 0;
|
||||||
|
int FirstTime = 0;
|
||||||
|
|
||||||
|
for (; f >= 0;) {
|
||||||
|
|
||||||
|
LOCK_THREAD;
|
||||||
|
|
||||||
|
if (ReceiveByte(REPEATLIMIT) == 'X') {
|
||||||
|
for (int i = 0; i < 6; i++) {
|
||||||
|
int b = ReceiveByte();
|
||||||
|
if (b >= 0) {
|
||||||
|
buffer.raw[i] = b;
|
||||||
|
if (i == 5) {
|
||||||
|
unsigned short Address = ntohs(buffer.data.address); // the PIC sends bytes in "network order"
|
||||||
|
unsigned int Command = ntohl(buffer.data.command);
|
||||||
|
if (code == 'B' && address == 0x0000 && Command == 0x00004000)
|
||||||
|
// Well, well, if it isn't the "d-box"...
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (Now - FirstTime < REPEATDELAY)
|
||||||
|
break; // repeat function kicks in after a short delay
|
||||||
|
receivedData = receivedRepeat = true;
|
||||||
|
}
|
||||||
|
LastCommand = Command;
|
||||||
|
WakeUp();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
LastCommand = 0;
|
||||||
|
//XXX 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;
|
||||||
|
receivedRepeat = false;
|
||||||
|
LastCommand = 0;
|
||||||
|
WakeUp();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
LastCommand = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int cRcIoRCU::ReceiveByte(int TimeoutMs)
|
||||||
{
|
{
|
||||||
// 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 (cFile::FileReady(f, TimeoutMs)) {
|
||||||
unsigned char b;
|
unsigned char b;
|
||||||
if (read(f, &b, 1) == 1)
|
if (read(f, &b, 1) == 1)
|
||||||
return b;
|
return b;
|
||||||
@ -128,16 +206,16 @@ int cRcIoRCU::ReceiveByte(bool Wait)
|
|||||||
|
|
||||||
bool cRcIoRCU::SendByteHandshake(unsigned char c)
|
bool cRcIoRCU::SendByteHandshake(unsigned char c)
|
||||||
{
|
{
|
||||||
if (f.IsOpen()) {
|
if (f >= 0) {
|
||||||
int w = write(f, &c, 1);
|
int w = write(f, &c, 1);
|
||||||
if (w == 1) {
|
if (w == 1) {
|
||||||
for (int reply = ReceiveByte(); reply >= 0;) {
|
for (int reply = ReceiveByte(REPEATLIMIT); reply >= 0;) {
|
||||||
if (reply == c)
|
if (reply == c)
|
||||||
return true;
|
return true;
|
||||||
else if (reply == 'X') {
|
else if (reply == 'X') {
|
||||||
// skip any incoming RC code - it will come again
|
// skip any incoming RC code - it will come again
|
||||||
for (int i = 6; i--;) {
|
for (int i = 6; i--;) {
|
||||||
if (ReceiveByte(false) < 0)
|
if (ReceiveByte() < 0)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -152,6 +230,8 @@ bool cRcIoRCU::SendByteHandshake(unsigned char c)
|
|||||||
|
|
||||||
bool cRcIoRCU::SendByte(unsigned char c)
|
bool cRcIoRCU::SendByte(unsigned char c)
|
||||||
{
|
{
|
||||||
|
LOCK_THREAD;
|
||||||
|
|
||||||
for (int retry = 5; retry--;) {
|
for (int retry = 5; retry--;) {
|
||||||
if (SendByteHandshake(c))
|
if (SendByteHandshake(c))
|
||||||
return true;
|
return true;
|
||||||
@ -174,67 +254,32 @@ bool cRcIoRCU::SetMode(unsigned char Mode)
|
|||||||
|
|
||||||
void cRcIoRCU::Flush(int WaitMs)
|
void cRcIoRCU::Flush(int WaitMs)
|
||||||
{
|
{
|
||||||
int t0 = time_ms();
|
LOCK_THREAD;
|
||||||
|
|
||||||
|
int t0 = time_ms();
|
||||||
for (;;) {
|
for (;;) {
|
||||||
while (ReceiveByte(false) >= 0)
|
while (ReceiveByte() >= 0)
|
||||||
t0 = time_ms();
|
t0 = time_ms();
|
||||||
if (time_ms() - t0 >= WaitMs)
|
if (time_ms() - t0 >= WaitMs)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
receivedData = receivedRepeat = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cRcIoRCU::InputAvailable(bool Wait)
|
bool cRcIoRCU::GetCommand(unsigned int *Command)
|
||||||
{
|
{
|
||||||
return f.Ready(Wait);
|
if (receivedData) { // first we check the boolean flag without a lock, to avoid delays
|
||||||
}
|
|
||||||
|
|
||||||
bool cRcIoRCU::GetCommand(unsigned int *Command, unsigned short *Address)
|
LOCK_THREAD;
|
||||||
{
|
|
||||||
#pragma pack(1)
|
|
||||||
union {
|
|
||||||
struct {
|
|
||||||
unsigned short address;
|
|
||||||
unsigned int command;
|
|
||||||
} data;
|
|
||||||
unsigned char raw[6];
|
|
||||||
} buffer;
|
|
||||||
#pragma pack()
|
|
||||||
|
|
||||||
Flush();
|
if (receivedData) { // need to check again, since the status might have changed while waiting for the lock
|
||||||
if (Command && ReceiveByte() == 'X') {
|
if (Command)
|
||||||
for (int i = 0; i < 6; i++) {
|
*Command = receivedCommand;
|
||||||
int b = ReceiveByte(false);
|
//XXX repeat!!!
|
||||||
if (b >= 0)
|
receivedData = false;
|
||||||
buffer.raw[i] = b;
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (Address)
|
|
||||||
*Address = ntohs(buffer.data.address); // the PIC sends bytes in "network order"
|
|
||||||
else if (address != ntohs(buffer.data.address))
|
|
||||||
return false;
|
|
||||||
*Command = ntohl(buffer.data.command);
|
|
||||||
if (code == 'B' && address == 0x0000 && *Command == 0x00004000)
|
|
||||||
// Well, well, if it isn't the "d-box"...
|
|
||||||
// This remote control sends the above command before and after
|
|
||||||
// each keypress - let's just drop this:
|
|
||||||
return false;
|
|
||||||
if (*Command == lastCommand) {
|
|
||||||
// let's have a timeout to avoid getting overrun by commands
|
|
||||||
int now = time_ms();
|
|
||||||
int delta = now - lastTime;
|
|
||||||
lastTime = now;
|
|
||||||
if (delta < REPEATLIMIT) { // if commands come in rapidly...
|
|
||||||
if (now - firstTime < REPEATDELAY)
|
|
||||||
return false; // ...repeat function kicks in after a short delay
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
lastTime = firstTime = time_ms();
|
|
||||||
lastCommand = *Command;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (time(NULL) - t > 60) {
|
if (time(NULL) - t > 60) {
|
||||||
SendCommand(code); // in case the PIC listens to the wrong code
|
SendCommand(code); // in case the PIC listens to the wrong code
|
||||||
t = time(NULL);
|
t = time(NULL);
|
||||||
@ -254,6 +299,8 @@ bool cRcIoRCU::Digit(int n, int v)
|
|||||||
|
|
||||||
bool cRcIoRCU::Number(int n, bool Hex)
|
bool cRcIoRCU::Number(int n, bool Hex)
|
||||||
{
|
{
|
||||||
|
LOCK_THREAD;
|
||||||
|
|
||||||
if (!Hex) {
|
if (!Hex) {
|
||||||
char buf[8];
|
char buf[8];
|
||||||
sprintf(buf, "%4d", n & 0xFFFF);
|
sprintf(buf, "%4d", n & 0xFFFF);
|
||||||
@ -275,6 +322,8 @@ bool cRcIoRCU::Number(int n, bool Hex)
|
|||||||
|
|
||||||
bool cRcIoRCU::String(char *s)
|
bool cRcIoRCU::String(char *s)
|
||||||
{
|
{
|
||||||
|
LOCK_THREAD;
|
||||||
|
|
||||||
const char *chars = mode == modeH ? "0123456789ABCDEF" : "0123456789-EHLP ";
|
const char *chars = mode == modeH ? "0123456789ABCDEF" : "0123456789-EHLP ";
|
||||||
int n = 0;
|
int n = 0;
|
||||||
|
|
||||||
@ -318,8 +367,11 @@ bool cRcIoRCU::DetectCode(unsigned char *Code, unsigned short *Address)
|
|||||||
sprintf(buf, "C0D%c", *Code);
|
sprintf(buf, "C0D%c", *Code);
|
||||||
String(buf);
|
String(buf);
|
||||||
SetCode(*Code, 0);
|
SetCode(*Code, 0);
|
||||||
unsigned int Command;
|
delay_ms(REPEATDELAY);
|
||||||
if (GetCommand(&Command, Address)) {
|
receivedData = receivedRepeat = 0;
|
||||||
|
delay_ms(REPEATDELAY);
|
||||||
|
if (GetCommand()) {
|
||||||
|
*Address = receivedAddress;
|
||||||
SetMode(modeB);
|
SetMode(modeB);
|
||||||
String("----");
|
String("----");
|
||||||
return true;
|
return true;
|
||||||
@ -337,77 +389,90 @@ bool cRcIoRCU::DetectCode(unsigned char *Code, unsigned short *Address)
|
|||||||
|
|
||||||
#elif defined REMOTE_LIRC
|
#elif defined REMOTE_LIRC
|
||||||
|
|
||||||
|
#define REPEATLIMIT 20 // ms
|
||||||
|
#define REPEATDELAY 350 // ms
|
||||||
|
|
||||||
cRcIoLIRC::cRcIoLIRC(char *DeviceName)
|
cRcIoLIRC::cRcIoLIRC(char *DeviceName)
|
||||||
{
|
{
|
||||||
repeat = 1;
|
*keyName = 0;
|
||||||
|
receivedData = receivedRepeat = false;
|
||||||
struct sockaddr_un addr;
|
struct sockaddr_un addr;
|
||||||
addr.sun_family = AF_UNIX;
|
addr.sun_family = AF_UNIX;
|
||||||
strcpy(addr.sun_path, DeviceName);
|
strcpy(addr.sun_path, DeviceName);
|
||||||
int sock = socket(AF_UNIX, SOCK_STREAM, 0);
|
if ((f = socket(AF_UNIX, SOCK_STREAM, 0)) >= 0) {
|
||||||
if (sock >= 0) {
|
if (connect(f, (struct sockaddr *)&addr, sizeof(addr)) >= 0) {
|
||||||
if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) >= 0) {
|
Start();
|
||||||
f.Open(sock);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
LOG_ERROR_STR(DeviceName);
|
LOG_ERROR_STR(DeviceName);
|
||||||
close(sock);
|
close(f);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
LOG_ERROR_STR(DeviceName);
|
LOG_ERROR_STR(DeviceName);
|
||||||
|
f = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
cRcIoLIRC::~cRcIoLIRC()
|
cRcIoLIRC::~cRcIoLIRC()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *cRcIoLIRC::ReceiveString(void)
|
void cRcIoLIRC::Action(void)
|
||||||
{
|
{
|
||||||
int oldrepeat = 1;
|
dsyslog(LOG_INFO, "LIRC remote control thread started (pid=%d)", getpid());
|
||||||
|
|
||||||
if (repeat != 0) {
|
int FirstTime = 0;
|
||||||
Flush();
|
|
||||||
if (repeat != 0) {
|
|
||||||
oldrepeat = repeat;
|
|
||||||
Flush(REPEATLIMIT);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (repeat == 0) {
|
|
||||||
firstTime = time_ms();
|
|
||||||
repeat = 1;
|
|
||||||
return keyName;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((repeat > 1) && (repeat != oldrepeat) && (time_ms() > firstTime + REPEATDELAY)) {
|
|
||||||
repeat = 1;
|
|
||||||
return keyName;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void cRcIoLIRC::Flush(int WaitMs)
|
|
||||||
{
|
|
||||||
char buf[LIRC_BUFFER_SIZE];
|
char buf[LIRC_BUFFER_SIZE];
|
||||||
int t0 = time_ms();
|
|
||||||
|
|
||||||
do {
|
for (; f >= 0;) {
|
||||||
if (InputAvailable(false) && (read(f, buf, sizeof(buf)) > 21))
|
|
||||||
sscanf(buf, "%*x %x %7s", &repeat, keyName); // '7' in '%7s' is LIRC_KEY_BUF-1!
|
LOCK_THREAD;
|
||||||
} while ((repeat != 0) && (time_ms() < t0 + WaitMs));
|
|
||||||
|
if (cFile::FileReady(f, REPEATLIMIT) && read(f, buf, sizeof(buf)) > 21) {
|
||||||
|
int count;
|
||||||
|
sscanf(buf, "%*x %x %7s", &count, keyName); // '7' in '%7s' is LIRC_KEY_BUF-1!
|
||||||
|
int Now = time_ms();
|
||||||
|
if (count == 0) {
|
||||||
|
receivedData = true;
|
||||||
|
FirstTime = Now;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (Now - FirstTime < REPEATDELAY)
|
||||||
|
continue; // repeat function kicks in after a short delay
|
||||||
|
receivedData = receivedRepeat = true;
|
||||||
|
}
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (receivedRepeat) { // all data has already been fetched, but the last one was a repeat
|
||||||
|
//XXX replace it with "released"???
|
||||||
|
//XXX receivedData = true;
|
||||||
|
receivedRepeat = false;
|
||||||
|
*keyName = 0;
|
||||||
|
WakeUp();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
*keyName = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cRcIoLIRC::InputAvailable(bool Wait)
|
bool cRcIoLIRC::GetCommand(unsigned int *Command)
|
||||||
{
|
{
|
||||||
return f.Ready(Wait);
|
if (receivedData) { // first we check the boolean flag without a lock, to avoid delays
|
||||||
}
|
|
||||||
|
|
||||||
bool cRcIoLIRC::GetCommand(unsigned int *Command, unsigned short *)
|
LOCK_THREAD;
|
||||||
{
|
|
||||||
if (Command) {
|
if (receivedData) { // need to check again, since the status might have changed while waiting for the lock
|
||||||
const char *cmd = ReceiveString();
|
if (Command)
|
||||||
if (cmd) {
|
*Command = Keys.Encode(keyName);
|
||||||
*Command = Keys.Encode(cmd);
|
//XXX repeat!!!
|
||||||
|
receivedData = false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
42
remote.h
42
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.10 2000/10/03 10:45:35 kls Exp $
|
* $Id: remote.h 1.11 2000/10/07 18:50:51 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __REMOTE_H
|
#ifndef __REMOTE_H
|
||||||
@ -12,13 +12,12 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
#include "thread.h"
|
||||||
#include "tools.h"
|
#include "tools.h"
|
||||||
|
|
||||||
class cRcIoBase {
|
class cRcIoBase {
|
||||||
protected:
|
protected:
|
||||||
time_t t;
|
time_t t;
|
||||||
int firstTime, lastTime;
|
|
||||||
unsigned int lastCommand;
|
|
||||||
cRcIoBase(void);
|
cRcIoBase(void);
|
||||||
virtual ~cRcIoBase();
|
virtual ~cRcIoBase();
|
||||||
public:
|
public:
|
||||||
@ -29,9 +28,9 @@ public:
|
|||||||
virtual void SetPoints(unsigned char Dp, bool On) {}
|
virtual void SetPoints(unsigned char Dp, bool On) {}
|
||||||
virtual bool String(char *s) { return true; }
|
virtual bool String(char *s) { return true; }
|
||||||
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) = 0;
|
virtual void Flush(int WaitMs = 0) {}
|
||||||
virtual bool InputAvailable(bool Wait = false) = 0;
|
virtual bool InputAvailable(void) = 0;
|
||||||
virtual bool GetCommand(unsigned int *Command, unsigned short *Address = NULL) = 0;
|
virtual bool GetCommand(unsigned int *Command = NULL) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#if defined REMOTE_KBD
|
#if defined REMOTE_KBD
|
||||||
@ -43,23 +42,27 @@ public:
|
|||||||
cRcIoKBD(void);
|
cRcIoKBD(void);
|
||||||
virtual ~cRcIoKBD();
|
virtual ~cRcIoKBD();
|
||||||
virtual void Flush(int WaitMs = 0);
|
virtual void Flush(int WaitMs = 0);
|
||||||
virtual bool InputAvailable(bool Wait = false);
|
virtual bool InputAvailable(void);
|
||||||
virtual bool GetCommand(unsigned int *Command, unsigned short *Address = NULL);
|
virtual bool GetCommand(unsigned int *Command = NULL);
|
||||||
};
|
};
|
||||||
|
|
||||||
#elif defined REMOTE_RCU
|
#elif defined REMOTE_RCU
|
||||||
|
|
||||||
class cRcIoRCU : public cRcIoBase {
|
class cRcIoRCU : public cRcIoBase, private cThread {
|
||||||
private:
|
private:
|
||||||
cFile f;
|
int f;
|
||||||
unsigned char dp, code, mode;
|
unsigned char dp, code, mode;
|
||||||
unsigned short address;
|
unsigned short address;
|
||||||
|
unsigned short receivedAddress;
|
||||||
|
unsigned int receivedCommand;
|
||||||
|
bool receivedData, receivedRepeat;
|
||||||
int lastNumber;
|
int lastNumber;
|
||||||
bool SendCommand(unsigned char Cmd);
|
bool SendCommand(unsigned char Cmd);
|
||||||
int ReceiveByte(bool Wait = true);
|
int ReceiveByte(int TimeoutMs = 0);
|
||||||
bool SendByteHandshake(unsigned char c);
|
bool SendByteHandshake(unsigned char c);
|
||||||
bool SendByte(unsigned char c);
|
bool SendByte(unsigned char c);
|
||||||
bool Digit(int n, int v);
|
bool Digit(int n, int v);
|
||||||
|
virtual void Action(void);
|
||||||
public:
|
public:
|
||||||
cRcIoRCU(char *DeviceName);
|
cRcIoRCU(char *DeviceName);
|
||||||
virtual ~cRcIoRCU();
|
virtual ~cRcIoRCU();
|
||||||
@ -70,25 +73,24 @@ public:
|
|||||||
virtual bool String(char *s);
|
virtual bool String(char *s);
|
||||||
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(bool Wait = false);
|
virtual bool InputAvailable(void) { return receivedData; }
|
||||||
virtual bool GetCommand(unsigned int *Command, unsigned short *Address = NULL);
|
virtual bool GetCommand(unsigned int *Command = NULL);
|
||||||
};
|
};
|
||||||
|
|
||||||
#elif defined REMOTE_LIRC
|
#elif defined REMOTE_LIRC
|
||||||
|
|
||||||
class cRcIoLIRC : public cRcIoBase {
|
class cRcIoLIRC : public cRcIoBase, private cThread {
|
||||||
private:
|
private:
|
||||||
enum { LIRC_KEY_BUF = 8, LIRC_BUFFER_SIZE = 128 };
|
enum { LIRC_KEY_BUF = 8, LIRC_BUFFER_SIZE = 128 };
|
||||||
cFile f;
|
int f;
|
||||||
char keyName[LIRC_KEY_BUF];
|
char keyName[LIRC_KEY_BUF];
|
||||||
int repeat;
|
bool receivedData, receivedRepeat;
|
||||||
const char *ReceiveString(void);
|
virtual void Action(void);
|
||||||
public:
|
public:
|
||||||
cRcIoLIRC(char *DeviceName);
|
cRcIoLIRC(char *DeviceName);
|
||||||
virtual ~cRcIoLIRC();
|
virtual ~cRcIoLIRC();
|
||||||
virtual void Flush(int WaitMs = 0);
|
virtual bool InputAvailable(void) { return receivedData; }
|
||||||
virtual bool InputAvailable(bool Wait = false);
|
virtual bool GetCommand(unsigned int *Command = NULL);
|
||||||
virtual bool GetCommand(unsigned int *Command, unsigned short *Address = NULL);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
105
thread.c
Normal file
105
thread.c
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
/*
|
||||||
|
* thread.c: A simple thread base class
|
||||||
|
*
|
||||||
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
|
* how to reach the author.
|
||||||
|
*
|
||||||
|
* $Id: thread.c 1.1 2000/10/07 17:31:39 kls Exp $
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "thread.h"
|
||||||
|
#include <signal.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
// --- cThread ---------------------------------------------------------------
|
||||||
|
|
||||||
|
// The signal handler is necessary to be able to use SIGIO to wake up any
|
||||||
|
// pending 'select()' call.
|
||||||
|
|
||||||
|
bool cThread::signalHandlerInstalled = false;
|
||||||
|
|
||||||
|
cThread::cThread(void)
|
||||||
|
{
|
||||||
|
if (!signalHandlerInstalled) {
|
||||||
|
signal(SIGIO, SignalHandler);
|
||||||
|
signalHandlerInstalled = true;
|
||||||
|
}
|
||||||
|
pthread_mutex_init(&mutex, NULL);
|
||||||
|
running = false;
|
||||||
|
parentPid = lockingPid = 0;
|
||||||
|
locked = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
cThread::~cThread()
|
||||||
|
{
|
||||||
|
pthread_mutex_destroy(&mutex);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cThread::SignalHandler(int signum)
|
||||||
|
{
|
||||||
|
signal(signum, SignalHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *cThread::StartThread(cThread *Thread)
|
||||||
|
{
|
||||||
|
Thread->Action();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool cThread::Start(void)
|
||||||
|
{
|
||||||
|
if (!running) {
|
||||||
|
running = true;
|
||||||
|
parentPid = getpid();
|
||||||
|
pthread_create(&thread, NULL, &StartThread, (void *)this);
|
||||||
|
}
|
||||||
|
return true; //XXX return value of pthread_create()???
|
||||||
|
}
|
||||||
|
|
||||||
|
void cThread::Stop(void)
|
||||||
|
{
|
||||||
|
pthread_exit(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool cThread::Lock(void)
|
||||||
|
{
|
||||||
|
if (!lockingPid || lockingPid != getpid()) {
|
||||||
|
pthread_mutex_lock(&mutex);
|
||||||
|
lockingPid = getpid();
|
||||||
|
}
|
||||||
|
locked++;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cThread::Unlock(void)
|
||||||
|
{
|
||||||
|
if (!--locked) {
|
||||||
|
lockingPid = 0;
|
||||||
|
pthread_mutex_unlock(&mutex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cThread::WakeUp(void)
|
||||||
|
{
|
||||||
|
kill(parentPid, SIGIO); // makes any waiting 'select()' call return immediately
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- cThreadLock -----------------------------------------------------------
|
||||||
|
|
||||||
|
cThreadLock::cThreadLock(cThread *Thread)
|
||||||
|
{
|
||||||
|
thread = Thread;
|
||||||
|
locked = Thread->Lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
cThreadLock::~cThreadLock()
|
||||||
|
{
|
||||||
|
if (locked)
|
||||||
|
thread->Unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool cThreadLock::Locked(void)
|
||||||
|
{
|
||||||
|
return locked;
|
||||||
|
}
|
||||||
|
|
57
thread.h
Normal file
57
thread.h
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
* thread.h: A simple thread base class
|
||||||
|
*
|
||||||
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
|
* how to reach the author.
|
||||||
|
*
|
||||||
|
* $Id: thread.h 1.1 2000/10/08 08:36:21 kls Exp $
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __THREAD_H
|
||||||
|
#define __THREAD_H
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
class cThread {
|
||||||
|
friend class cThreadLock;
|
||||||
|
private:
|
||||||
|
pthread_t thread;
|
||||||
|
pthread_mutex_t mutex;
|
||||||
|
pid_t parentPid, lockingPid;
|
||||||
|
int locked;
|
||||||
|
bool running;
|
||||||
|
static bool signalHandlerInstalled;
|
||||||
|
static void SignalHandler(int signum);
|
||||||
|
static void *StartThread(cThread *Thread);
|
||||||
|
bool Lock(void);
|
||||||
|
void Unlock(void);
|
||||||
|
protected:
|
||||||
|
void WakeUp(void);
|
||||||
|
virtual void Action(void) = 0;
|
||||||
|
void Stop(void);
|
||||||
|
public:
|
||||||
|
cThread(void);
|
||||||
|
virtual ~cThread();
|
||||||
|
bool Start(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
// cThreadLock can be used to easily set a lock in a thread and make absolutely
|
||||||
|
// sure that it will be unlocked when the block will be left. Several locks can
|
||||||
|
// be stacked, so a function that makes many calls to another function which uses
|
||||||
|
// cThreadLock may itself use a cThreadLock to make one longer lock instead of many
|
||||||
|
// short ones.
|
||||||
|
|
||||||
|
class cThreadLock {
|
||||||
|
private:
|
||||||
|
cThread *thread;
|
||||||
|
bool locked;
|
||||||
|
public:
|
||||||
|
cThreadLock(cThread *Thread);
|
||||||
|
~cThreadLock();
|
||||||
|
bool Locked(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
#define LOCK_THREAD cThreadLock ThreadLock(this)
|
||||||
|
|
||||||
|
#endif //__THREAD_H
|
18
tools.c
18
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.20 2000/09/29 16:19:28 kls Exp $
|
* $Id: tools.c 1.21 2000/10/07 18:02:24 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define _GNU_SOURCE
|
#define _GNU_SOURCE
|
||||||
@ -393,6 +393,22 @@ bool cFile::AnyFileReady(int FileDes, int TimeoutMs)
|
|||||||
return select(FD_SETSIZE, &set, NULL, NULL, &timeout) > 0 && (FileDes < 0 || FD_ISSET(FileDes, &set));
|
return select(FD_SETSIZE, &set, NULL, NULL, &timeout) > 0 && (FileDes < 0 || FD_ISSET(FileDes, &set));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool cFile::FileReady(int FileDes, int TimeoutMs)
|
||||||
|
{
|
||||||
|
#ifdef DEBUG_OSD
|
||||||
|
refresh();
|
||||||
|
#endif
|
||||||
|
fd_set set;
|
||||||
|
struct timeval timeout;
|
||||||
|
FD_ZERO(&set);
|
||||||
|
FD_SET(FileDes, &set);
|
||||||
|
if (TimeoutMs < 100)
|
||||||
|
TimeoutMs = 100;
|
||||||
|
timeout.tv_sec = 0;
|
||||||
|
timeout.tv_usec = TimeoutMs * 1000;
|
||||||
|
return select(FD_SETSIZE, &set, NULL, NULL, &timeout) > 0 && FD_ISSET(FileDes, &set);
|
||||||
|
}
|
||||||
|
|
||||||
// --- cListObject -----------------------------------------------------------
|
// --- cListObject -----------------------------------------------------------
|
||||||
|
|
||||||
cListObject::cListObject(void)
|
cListObject::cListObject(void)
|
||||||
|
3
tools.h
3
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.16 2000/09/29 16:19:31 kls Exp $
|
* $Id: tools.h 1.17 2000/10/07 18:00:21 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __TOOLS_H
|
#ifndef __TOOLS_H
|
||||||
@ -68,6 +68,7 @@ public:
|
|||||||
int ReadString(char *Buffer, int Size);
|
int ReadString(char *Buffer, int Size);
|
||||||
bool Ready(bool Wait = true);
|
bool Ready(bool Wait = true);
|
||||||
static bool AnyFileReady(int FileDes = -1, int TimeoutMs = 1000);
|
static bool AnyFileReady(int FileDes = -1, int TimeoutMs = 1000);
|
||||||
|
static bool FileReady(int FileDes, int TimeoutMs = 1000);
|
||||||
};
|
};
|
||||||
|
|
||||||
class cListObject {
|
class cListObject {
|
||||||
|
Loading…
Reference in New Issue
Block a user