mirror of
https://github.com/vdr-projects/vdr.git
synced 2025-03-01 10:50:46 +00:00
Version 0.64
- NOTE: If you are using DVB driver version 0.7 you need to load the dvb.o module with option outstream=0, so your insmod statement should read 'insmod dvb.o outstream=0'. This is currently necessary because 'vdr' still works with AV_PES data. - Video files now have the 'group read' bit set. - Fixed handling errors in 'readstring()'. - Handling SIGPIPE and re-establishing handler after intercepting a signal. - The configuration files are now by default read from the video directory. This can be changed by using the new '-c' option. Make sure you copy your current '*.conf' files to your video directory ('/video' by default), or use "-c ." to get the old behaviour of loading the configuration files from the current directory. - Waiting for input is now handled by a common function, which improves response time on user actions. As a consequence the EIT data may sometimes not be displayed, but this will change later when cEIT runs as a separate thread. - The new SVDRP command 'HITK' (thanks to Guido Fiala!) can be used to 'hit' a remote control key. Establish an SVDRP connection and enter HITK without a parameter for a list of all valid key names. - The new SVDRP command 'GRAB' (thanks to Guido Fiala!) can be used to grab the current frame and save it to a file. - The new SVDRP commands 'OVL*' can be used to control video overlays (thanks to Guido Fiala!). This is mainly for use in the 'kvdr' tool (see the 'kvdr' page at http://www.s.netic.de/gfiala). - If the name of the video directory used with the '-v' option had trailing slashes, the recording file names have been damaged. Trailing slashes are now silently removed. - Fixed a buffer overflow in EIT parsing. - Added a security warning regarding SVDRP to the INSTALL file. - Fixed 'confirm' dialog. - The daemon mode (option '-d') now no longer works with REMOTE=KBD (there is no stdin in daemon mode, so KBD makes no sense - plus it sometimes crashed).
This commit is contained in:
parent
76c331181a
commit
7e4b4d2905
@ -18,6 +18,9 @@ Heino Goldenstein <heino.goldenstein@microplex.de>
|
|||||||
|
|
||||||
Guido Fiala <gfiala@s.netic.de>
|
Guido Fiala <gfiala@s.netic.de>
|
||||||
for implementing slow forward/back
|
for implementing slow forward/back
|
||||||
|
for implementing the SVDRP command 'HITK'
|
||||||
|
for implementing image grabbing
|
||||||
|
for implementing overlay capabilities (see his 'kvdr' tool at http://www.s.netic.de/gfiala)
|
||||||
|
|
||||||
Robert Schneider <Robert.Schneider@lotus.com>
|
Robert Schneider <Robert.Schneider@lotus.com>
|
||||||
for implementing EIT support for displaying the current/next info
|
for implementing EIT support for displaying the current/next info
|
||||||
|
35
HISTORY
35
HISTORY
@ -168,3 +168,38 @@ Video Disk Recorder Revision History
|
|||||||
entered so far together with the name of that channel are displayed on the
|
entered so far together with the name of that channel are displayed on the
|
||||||
OSD (suggested by Martin Hammerschmid).
|
OSD (suggested by Martin Hammerschmid).
|
||||||
|
|
||||||
|
2000-09-20: Version 0.64
|
||||||
|
|
||||||
|
- NOTE: If you are using DVB driver version 0.7 you need to load the dvb.o
|
||||||
|
module with option outstream=0, so your insmod statement should read
|
||||||
|
'insmod dvb.o outstream=0'. This is currently necessary because 'vdr'
|
||||||
|
still works with AV_PES data.
|
||||||
|
- Video files now have the 'group read' bit set.
|
||||||
|
- Fixed handling errors in 'readstring()'.
|
||||||
|
- Handling SIGPIPE and re-establishing handler after intercepting a signal.
|
||||||
|
- The configuration files are now by default read from the video directory.
|
||||||
|
This can be changed by using the new '-c' option. Make sure you copy your
|
||||||
|
current '*.conf' files to your video directory ('/video' by default), or
|
||||||
|
use "-c ." to get the old behaviour of loading the configuration files
|
||||||
|
from the current directory.
|
||||||
|
- Waiting for input is now handled by a common function, which improves
|
||||||
|
response time on user actions. As a consequence the EIT data may sometimes
|
||||||
|
not be displayed, but this will change later when cEIT runs as a separate
|
||||||
|
thread.
|
||||||
|
- The new SVDRP command 'HITK' (thanks to Guido Fiala!) can be used to 'hit'
|
||||||
|
a remote control key. Establish an SVDRP connection and enter HITK without
|
||||||
|
a parameter for a list of all valid key names.
|
||||||
|
- The new SVDRP command 'GRAB' (thanks to Guido Fiala!) can be used to grab
|
||||||
|
the current frame and save it to a file.
|
||||||
|
- The new SVDRP commands 'OVL*' can be used to control video overlays (thanks
|
||||||
|
to Guido Fiala!). This is mainly for use in the 'kvdr' tool (see the 'kvdr'
|
||||||
|
page at http://www.s.netic.de/gfiala).
|
||||||
|
- If the name of the video directory used with the '-v' option had trailing
|
||||||
|
slashes, the recording file names have been damaged. Trailing slashes are
|
||||||
|
now silently removed.
|
||||||
|
- Fixed a buffer overflow in EIT parsing.
|
||||||
|
- Added a security warning regarding SVDRP to the INSTALL file.
|
||||||
|
- Fixed 'confirm' dialog.
|
||||||
|
- The daemon mode (option '-d') now no longer works with REMOTE=KBD (there
|
||||||
|
is no stdin in daemon mode, so KBD makes no sense - plus it sometimes
|
||||||
|
crashed).
|
||||||
|
32
INSTALL
32
INSTALL
@ -16,7 +16,11 @@ you will have to change the definition of DVBDIR in the
|
|||||||
Makefile.
|
Makefile.
|
||||||
|
|
||||||
This program requires the card driver version 0.05 or higher
|
This program requires the card driver version 0.05 or higher
|
||||||
to work properly.
|
to work properly. If you are using driver version 0.7 you need
|
||||||
|
to load the dvb.o module with option outstream=0, so your insmod
|
||||||
|
statement should read 'insmod dvb.o outstream=0'. This is currently
|
||||||
|
necessary because 'vdr' works with AV_PES data and will change
|
||||||
|
once it has been modified to work directly with MPEG2.
|
||||||
|
|
||||||
After extracting the package, change into the VDR directory
|
After extracting the package, change into the VDR directory
|
||||||
and type 'make'. This should produce an executable file
|
and type 'make'. This should produce an executable file
|
||||||
@ -48,6 +52,11 @@ port ("Simple Video Disk Recorder Protocol"). By default, it listens
|
|||||||
on port 2001 (use the --port=PORT option to change this). For details
|
on port 2001 (use the --port=PORT option to change this). For details
|
||||||
about the SVDRP syntax see the source file 'svdrp.c'.
|
about the SVDRP syntax see the source file 'svdrp.c'.
|
||||||
|
|
||||||
|
WARNING: DUE TO THE OPEN SVDRP PORT THIS PROGRAM MAY CONSTITUTE A
|
||||||
|
======= POTENTIAL SECURITY HAZARD! IF YOU ARE NOT RUNNING VDR IN
|
||||||
|
A CONTROLLED ENVIRONMENT, YOU MAY WANT TO DISABLE SVDRP
|
||||||
|
BY USING '--port=0'!
|
||||||
|
|
||||||
If the program shall run as a daemon, use the --daemon option. This
|
If the program shall run as a daemon, use the --daemon option. This
|
||||||
will completely detach it from the terminal and will continue as a
|
will completely detach it from the terminal and will continue as a
|
||||||
background process.
|
background process.
|
||||||
@ -64,7 +73,9 @@ All recordings are written into directories below "/video". Please
|
|||||||
make sure this directory exists, and that the user who runs the 'vdr'
|
make sure this directory exists, and that the user who runs the 'vdr'
|
||||||
program has read and write access to that directory.
|
program has read and write access to that directory.
|
||||||
If you prefer a different location for your video files, you can use
|
If you prefer a different location for your video files, you can use
|
||||||
the '-v' option to change that.
|
the '-v' option to change that. Please make sure that the directory
|
||||||
|
name you use with '-v' is a clean and absolute path name (no '..' or
|
||||||
|
multiple slashes).
|
||||||
|
|
||||||
Note that the file system need not be 64-bit proof, since the 'vdr'
|
Note that the file system need not be 64-bit proof, since the 'vdr'
|
||||||
program splits video files into chunks of about 1GB. You should use
|
program splits video files into chunks of about 1GB. You should use
|
||||||
@ -102,14 +113,15 @@ Configuration files:
|
|||||||
--------------------
|
--------------------
|
||||||
|
|
||||||
There are three configuration files that hold information about
|
There are three configuration files that hold information about
|
||||||
channels, remote control keys and timers. These files are currrently
|
channels, remote control keys and timers. By default these files are
|
||||||
assumed to be located in the directory from which the 'vdr' program
|
assumed to be located in the video directory, but a different directory
|
||||||
was started (this will become configurable later). The configuration
|
can be used with the '-c' option.
|
||||||
files can be edited with any text editor, or will be written by the
|
|
||||||
'vdr' program if any changes are made inside the on-screen menus.
|
The configuration files can be edited with any text editor, or will be written
|
||||||
The meaning of the data entries may still vary in future releases,
|
by the 'vdr' program if any changes are made inside the on-screen menus.
|
||||||
so for the moment please look at the source code (config.c) to see
|
The meaning of the data entries may still vary in future releases, so for the
|
||||||
the meaning of the various fields.
|
moment please look at the source code (config.c) to see the meaning of the
|
||||||
|
various fields.
|
||||||
|
|
||||||
The files that come with this package contain the author's selections,
|
The files that come with this package contain the author's selections,
|
||||||
so please make sure you adapt these to your personal taste. Also make sure
|
so please make sure you adapt these to your personal taste. Also make sure
|
||||||
|
24
Makefile
24
Makefile
@ -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: Makefile 1.9 2000/09/10 08:55:45 kls Exp $
|
# $Id: Makefile 1.11 2000/09/20 17:01:57 kls Exp $
|
||||||
|
|
||||||
DVBDIR = ../DVB
|
DVBDIR = ../DVB
|
||||||
|
|
||||||
@ -26,21 +26,21 @@ endif
|
|||||||
|
|
||||||
all: vdr
|
all: vdr
|
||||||
|
|
||||||
config.o : config.c config.h dvbapi.h eit.h interface.h tools.h
|
config.o : config.c config.h dvbapi.h eit.h interface.h svdrp.h tools.h
|
||||||
dvbapi.o : dvbapi.c config.h dvbapi.h interface.h tools.h videodir.h
|
dvbapi.o : dvbapi.c config.h dvbapi.h interface.h svdrp.h tools.h videodir.h
|
||||||
eit.o : eit.c eit.h
|
eit.o : eit.c eit.h tools.h
|
||||||
interface.o: interface.c config.h dvbapi.h eit.h interface.h remote.h tools.h
|
interface.o: interface.c config.h dvbapi.h eit.h interface.h remote.h svdrp.h tools.h
|
||||||
menu.o : menu.c config.h dvbapi.h interface.h menu.h osd.h recording.h tools.h
|
menu.o : menu.c config.h dvbapi.h interface.h menu.h osd.h recording.h svdrp.h tools.h
|
||||||
osd.o : osd.c config.h dvbapi.h interface.h osd.h tools.h
|
osd.o : osd.c config.h dvbapi.h interface.h osd.h svdrp.h tools.h
|
||||||
vdr.o : vdr.c config.h dvbapi.h interface.h menu.h osd.h recording.h svdrp.h tools.h videodir.h
|
recording.o: recording.c config.h dvbapi.h interface.h recording.h svdrp.h tools.h videodir.h
|
||||||
recording.o: recording.c config.h dvbapi.h interface.h recording.h tools.h videodir.h
|
remote.o : remote.c config.h dvbapi.h remote.h tools.h
|
||||||
remote.o : remote.c remote.h tools.h
|
svdrp.o : svdrp.c config.h dvbapi.h interface.h svdrp.h tools.h
|
||||||
svdrp.o : svdrp.c svdrp.h config.h interface.h tools.h
|
|
||||||
tools.o : tools.c tools.h
|
tools.o : tools.c tools.h
|
||||||
|
vdr.o : vdr.c config.h dvbapi.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
|
||||||
|
|
||||||
vdr: $(OBJS)
|
vdr: $(OBJS)
|
||||||
g++ -g -O2 $(OBJS) -lncurses -o vdr
|
g++ -g -O2 $(OBJS) -lncurses -ljpeg -o vdr
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
-rm $(OBJS) vdr
|
-rm $(OBJS) vdr
|
||||||
|
1
TODO
1
TODO
@ -7,5 +7,4 @@ TODO list for the Video Disk Recorder project
|
|||||||
scenes in order to archive them (or, reversely, cut out
|
scenes in order to archive them (or, reversely, cut out
|
||||||
commercial breaks).
|
commercial breaks).
|
||||||
* Implement channel scanning.
|
* Implement channel scanning.
|
||||||
* Better support for encrypted channels.
|
|
||||||
* Implement remaining commands in SVDRP.
|
* Implement remaining commands in SVDRP.
|
||||||
|
22
config.c
22
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.22 2000/09/10 15:07:15 kls Exp $
|
* $Id: config.c 1.23 2000/09/17 09:11:59 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
@ -155,14 +155,22 @@ eKeys cKeys::Get(unsigned int Code)
|
|||||||
return kNone;
|
return kNone;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
eKeys cKeys::Translate(const char *Command)
|
||||||
|
{
|
||||||
|
if (Command) {
|
||||||
|
const tKey *k = keys;
|
||||||
|
while ((k->type != kNone) && strcasecmp(k->name, Command) != 0)
|
||||||
|
k++;
|
||||||
|
return k->type;
|
||||||
|
}
|
||||||
|
return kNone;
|
||||||
|
}
|
||||||
|
|
||||||
unsigned int cKeys::Encode(const char *Command)
|
unsigned int cKeys::Encode(const char *Command)
|
||||||
{
|
{
|
||||||
if (Command != NULL) {
|
eKeys k = Translate(Command);
|
||||||
const tKey *k = keys;
|
if (k != kNone)
|
||||||
while ((k->type != kNone) && strcmp(k->name, Command) != 0)
|
return keys[k].code;
|
||||||
k++;
|
|
||||||
return k->code;
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
5
config.h
5
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.19 2000/09/10 15:05:08 kls Exp $
|
* $Id: config.h 1.21 2000/09/17 09:08:13 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.63"
|
#define VDRVERSION "0.64"
|
||||||
|
|
||||||
#define MaxBuffer 10000
|
#define MaxBuffer 10000
|
||||||
|
|
||||||
@ -55,6 +55,7 @@ public:
|
|||||||
void SetDummyValues(void);
|
void SetDummyValues(void);
|
||||||
bool Load(const char *FileName = NULL);
|
bool Load(const char *FileName = NULL);
|
||||||
bool Save(void);
|
bool Save(void);
|
||||||
|
eKeys Translate(const char *Command);
|
||||||
unsigned int Encode(const char *Command);
|
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);
|
||||||
|
258
dvbapi.c
258
dvbapi.c
@ -4,14 +4,18 @@
|
|||||||
* 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.24 2000/09/10 10:25:09 kls Exp $
|
* $Id: dvbapi.c 1.27 2000/09/17 12:45:55 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "dvbapi.h"
|
#include "dvbapi.h"
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
extern "C" {
|
||||||
|
#include <jpeglib.h>
|
||||||
|
}
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@ -139,7 +143,7 @@ cIndexFile::cIndexFile(const char *FileName, bool Record)
|
|||||||
LOG_ERROR;
|
LOG_ERROR;
|
||||||
}
|
}
|
||||||
if (Record) {
|
if (Record) {
|
||||||
if ((f = open(fileName, O_WRONLY | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR)) >= 0) {
|
if ((f = open(fileName, O_WRONLY | O_CREAT | O_APPEND, S_IRUSR | S_IWUSR | S_IRGRP)) >= 0) {
|
||||||
if (delta) {
|
if (delta) {
|
||||||
esyslog(LOG_ERR, "ERROR: padding index file with %d '0' bytes", delta);
|
esyslog(LOG_ERR, "ERROR: padding index file with %d '0' bytes", delta);
|
||||||
while (delta--)
|
while (delta--)
|
||||||
@ -297,7 +301,7 @@ int cIndexFile::Get(uchar FileNumber, int FileOffset)
|
|||||||
bool cIndexFile::StoreResume(int Index)
|
bool cIndexFile::StoreResume(int Index)
|
||||||
{
|
{
|
||||||
if (fileName) {
|
if (fileName) {
|
||||||
int resumeFile = open(fileName, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
|
int resumeFile = open(fileName, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP);
|
||||||
if (resumeFile >= 0) {
|
if (resumeFile >= 0) {
|
||||||
if (write(resumeFile, &Index, sizeof(Index)) != sizeof(Index))
|
if (write(resumeFile, &Index, sizeof(Index)) != sizeof(Index))
|
||||||
LOG_ERROR_STR(fileName);
|
LOG_ERROR_STR(fileName);
|
||||||
@ -1065,9 +1069,14 @@ cDvbApi::cDvbApi(const char *FileName)
|
|||||||
if (videoDev < 0)
|
if (videoDev < 0)
|
||||||
LOG_ERROR;
|
LOG_ERROR;
|
||||||
cols = rows = 0;
|
cols = rows = 0;
|
||||||
|
|
||||||
|
ovlGeoSet = ovlStat = ovlFbSet = false;
|
||||||
|
ovlBrightness = ovlColour = ovlHue = ovlContrast = 32768;
|
||||||
|
ovlClipCount = 0;
|
||||||
|
|
||||||
#if defined(DEBUG_OSD) || defined(REMOTE_KBD)
|
#if defined(DEBUG_OSD) || defined(REMOTE_KBD)
|
||||||
initscr();
|
initscr();
|
||||||
keypad(stdscr, TRUE);
|
keypad(stdscr, true);
|
||||||
nonl();
|
nonl();
|
||||||
cbreak();
|
cbreak();
|
||||||
noecho();
|
noecho();
|
||||||
@ -1076,7 +1085,7 @@ cDvbApi::cDvbApi(const char *FileName)
|
|||||||
#if defined(DEBUG_OSD)
|
#if defined(DEBUG_OSD)
|
||||||
memset(&colorPairs, 0, sizeof(colorPairs));
|
memset(&colorPairs, 0, sizeof(colorPairs));
|
||||||
start_color();
|
start_color();
|
||||||
leaveok(stdscr, TRUE);
|
leaveok(stdscr, true);
|
||||||
window = NULL;
|
window = NULL;
|
||||||
#endif
|
#endif
|
||||||
lastProgress = lastTotal = -1;
|
lastProgress = lastTotal = -1;
|
||||||
@ -1089,6 +1098,7 @@ cDvbApi::~cDvbApi()
|
|||||||
Close();
|
Close();
|
||||||
Stop();
|
Stop();
|
||||||
StopRecord();
|
StopRecord();
|
||||||
|
OvlO(false); //Overlay off!
|
||||||
close(videoDev);
|
close(videoDev);
|
||||||
}
|
}
|
||||||
#if defined(DEBUG_OSD) || defined(REMOTE_KBD)
|
#if defined(DEBUG_OSD) || defined(REMOTE_KBD)
|
||||||
@ -1187,6 +1197,242 @@ void cDvbApi::Cleanup(void)
|
|||||||
PrimaryDvbApi = NULL;
|
PrimaryDvbApi = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool cDvbApi::GrabImage(const char *FileName, bool Jpeg, int Quality, int SizeX, int SizeY)
|
||||||
|
{
|
||||||
|
int result = 0;
|
||||||
|
// just do this once?
|
||||||
|
struct video_mbuf mbuf;
|
||||||
|
result |= ioctl(videoDev, VIDIOCGMBUF, &mbuf);
|
||||||
|
int msize = mbuf.size;
|
||||||
|
// gf: this needs to be a protected member of cDvbApi! //XXX kls: WHY???
|
||||||
|
unsigned char *mem = (unsigned char *)mmap(0, msize, PROT_READ | PROT_WRITE, MAP_SHARED, videoDev, 0);
|
||||||
|
if (!mem || mem == (unsigned char *)-1)
|
||||||
|
return false;
|
||||||
|
// set up the size and RGB
|
||||||
|
struct video_capability vc;
|
||||||
|
result |= ioctl(videoDev, VIDIOCGCAP, &vc);
|
||||||
|
struct video_mmap vm;
|
||||||
|
vm.frame = 0;
|
||||||
|
if ((SizeX > 0) && (SizeX <= vc.maxwidth) &&
|
||||||
|
(SizeY > 0) && (SizeY <= vc.maxheight)) {
|
||||||
|
vm.width = SizeX;
|
||||||
|
vm.height = SizeY;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
vm.width = vc.maxwidth;
|
||||||
|
vm.height = vc.maxheight;
|
||||||
|
}
|
||||||
|
vm.format = VIDEO_PALETTE_RGB24;
|
||||||
|
// this needs to be done every time:
|
||||||
|
result |= ioctl(videoDev, VIDIOCMCAPTURE, &vm);
|
||||||
|
result |= ioctl(videoDev, VIDIOCSYNC, &vm.frame);
|
||||||
|
// make RGB out of BGR:
|
||||||
|
int memsize = vm.width * vm.height;
|
||||||
|
unsigned char *mem1 = mem;
|
||||||
|
for (int i = 0; i < memsize; i++) {
|
||||||
|
unsigned char tmp = mem1[2];
|
||||||
|
mem1[2] = mem1[0];
|
||||||
|
mem1[0] = tmp;
|
||||||
|
mem1 += 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Quality < 0)
|
||||||
|
Quality = 255; //XXX is this 'best'???
|
||||||
|
|
||||||
|
isyslog(LOG_INFO, "grabbing to %s (%s %d %d %d)", FileName, Jpeg ? "JPEG" : "PNM", Quality, vm.width, vm.height);
|
||||||
|
FILE *f = fopen(FileName, "wb");
|
||||||
|
if (f) {
|
||||||
|
if (Jpeg) {
|
||||||
|
// write JPEG file:
|
||||||
|
struct jpeg_compress_struct cinfo;
|
||||||
|
struct jpeg_error_mgr jerr;
|
||||||
|
cinfo.err = jpeg_std_error(&jerr);
|
||||||
|
jpeg_create_compress(&cinfo);
|
||||||
|
jpeg_stdio_dest(&cinfo, f);
|
||||||
|
cinfo.image_width = vm.width;
|
||||||
|
cinfo.image_height = vm.height;
|
||||||
|
cinfo.input_components = 3;
|
||||||
|
cinfo.in_color_space = JCS_RGB;
|
||||||
|
|
||||||
|
jpeg_set_defaults(&cinfo);
|
||||||
|
jpeg_set_quality(&cinfo, Quality, true);
|
||||||
|
jpeg_start_compress(&cinfo, true);
|
||||||
|
|
||||||
|
int rs = vm.width * 3;
|
||||||
|
JSAMPROW rp[vm.height];
|
||||||
|
for (int k = 0; k < vm.height; k++)
|
||||||
|
rp[k] = &mem[rs * k];
|
||||||
|
jpeg_write_scanlines(&cinfo, rp, vm.height);
|
||||||
|
jpeg_finish_compress(&cinfo);
|
||||||
|
jpeg_destroy_compress(&cinfo);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// write PNM file:
|
||||||
|
if (fprintf(f, "P6\n%d\n%d\n255\n", vm.width, vm.height) < 0 ||
|
||||||
|
fwrite(mem, vm.width * vm.height * 3, 1, f) < 0) {
|
||||||
|
LOG_ERROR_STR(FileName);
|
||||||
|
result |= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fclose(f);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
LOG_ERROR_STR(FileName);
|
||||||
|
result |= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ovlStat && ovlGeoSet) {
|
||||||
|
// switch the Overlay on again (gf: why have i to do anything again?)
|
||||||
|
OvlG(ovlSizeX, ovlSizeY, ovlPosX, ovlPosY);
|
||||||
|
}
|
||||||
|
if (ovlFbSet)
|
||||||
|
OvlP(ovlBrightness, ovlColour, ovlHue, ovlContrast);
|
||||||
|
|
||||||
|
munmap(mem, msize);
|
||||||
|
return result == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool cDvbApi::OvlF(int SizeX, int SizeY, int FbAddr, int Bpp, int Palette)
|
||||||
|
{
|
||||||
|
int result = 0;
|
||||||
|
// get the actual X-Server settings???
|
||||||
|
// plausibility-check problem: can't be verified w/o X-server!!!
|
||||||
|
if (SizeX <= 0 || SizeY <= 0 || FbAddr == 0 || Bpp / 8 > 4 ||
|
||||||
|
Bpp / 8 <= 0 || Palette <= 0 || Palette > 13 || ovlClipCount < 0 ||
|
||||||
|
SizeX > 4096 || SizeY > 4096) {
|
||||||
|
ovlFbSet = ovlGeoSet = false;
|
||||||
|
OvlO(false);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
dsyslog(LOG_INFO, "OvlF: %d %d %x %d %d", SizeX, SizeY, FbAddr, Bpp, Palette);
|
||||||
|
// this is the problematic part!
|
||||||
|
struct video_buffer vb;
|
||||||
|
result |= ioctl(videoDev, VIDIOCGFBUF, &vb);
|
||||||
|
vb.base = (void*)FbAddr;
|
||||||
|
vb.depth = Bpp;
|
||||||
|
vb.height = SizeY;
|
||||||
|
vb.width = SizeX;
|
||||||
|
vb.bytesperline = ((vb.depth + 1) / 8) * vb.width;
|
||||||
|
//now the real thing: setting the framebuffer
|
||||||
|
result |= ioctl(videoDev, VIDIOCSFBUF, &vb);
|
||||||
|
if (result) {
|
||||||
|
ovlFbSet = ovlGeoSet = false;
|
||||||
|
ovlClipCount = 0;
|
||||||
|
OvlO(false);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ovlFbSizeX = SizeX;
|
||||||
|
ovlFbSizeY = SizeY;
|
||||||
|
ovlBpp = Bpp;
|
||||||
|
ovlPalette = Palette;
|
||||||
|
ovlFbSet = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool cDvbApi::OvlG(int SizeX, int SizeY, int PosX, int PosY)
|
||||||
|
{
|
||||||
|
int result = 0;
|
||||||
|
// get the actual X-Server settings???
|
||||||
|
struct video_capability vc;
|
||||||
|
result |= ioctl(videoDev, VIDIOCGCAP, &vc);
|
||||||
|
if (!ovlFbSet)
|
||||||
|
return false;
|
||||||
|
if (SizeX < vc.minwidth || SizeY < vc.minheight ||
|
||||||
|
SizeX > vc.maxwidth || SizeY>vc.maxheight
|
||||||
|
// || PosX > FbSizeX || PosY > FbSizeY
|
||||||
|
// PosX < -SizeX || PosY < -SizeY ||
|
||||||
|
) {
|
||||||
|
ovlGeoSet = false;
|
||||||
|
OvlO(false);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
struct video_window vw;
|
||||||
|
result |= ioctl(videoDev, VIDIOCGWIN, &vw);
|
||||||
|
vw.x = PosX;
|
||||||
|
vw.y = PosY;
|
||||||
|
vw.width = SizeX;
|
||||||
|
vw.height = SizeY;
|
||||||
|
vw.chromakey = ovlPalette;
|
||||||
|
vw.flags = VIDEO_WINDOW_CHROMAKEY; // VIDEO_WINDOW_INTERLACE; //VIDEO_CLIP_BITMAP;
|
||||||
|
vw.clips = ovlClipRects;
|
||||||
|
vw.clipcount = ovlClipCount;
|
||||||
|
result |= ioctl(videoDev, VIDIOCSWIN, &vw);
|
||||||
|
if (result) {
|
||||||
|
ovlGeoSet = false;
|
||||||
|
ovlClipCount = 0;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ovlSizeX = SizeX;
|
||||||
|
ovlSizeY = SizeY;
|
||||||
|
ovlPosX = PosX;
|
||||||
|
ovlPosY = PosY;
|
||||||
|
ovlGeoSet = true;
|
||||||
|
ovlStat = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool cDvbApi::OvlC(int ClipCount, CRect *cr)
|
||||||
|
{
|
||||||
|
if (ovlGeoSet && ovlFbSet) {
|
||||||
|
for (int i = 0; i < ClipCount; i++) {
|
||||||
|
ovlClipRects[i].x = cr[i].x;
|
||||||
|
ovlClipRects[i].y = cr[i].y;
|
||||||
|
ovlClipRects[i].width = cr[i].width;
|
||||||
|
ovlClipRects[i].height = cr[i].height;
|
||||||
|
ovlClipRects[i].next = &(ovlClipRects[i + 1]);
|
||||||
|
}
|
||||||
|
ovlClipCount = ClipCount;
|
||||||
|
//use it:
|
||||||
|
return OvlG(ovlSizeX, ovlSizeY, ovlPosX, ovlPosY);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool cDvbApi::OvlP(__u16 Brightness, __u16 Colour, __u16 Hue, __u16 Contrast)
|
||||||
|
{
|
||||||
|
int result = 0;
|
||||||
|
ovlBrightness = Brightness;
|
||||||
|
ovlColour = Colour;
|
||||||
|
ovlHue = Hue;
|
||||||
|
ovlContrast = Contrast;
|
||||||
|
struct video_picture vp;
|
||||||
|
if (!ovlFbSet)
|
||||||
|
return false;
|
||||||
|
result |= ioctl(videoDev, VIDIOCGPICT, &vp);
|
||||||
|
vp.brightness = Brightness;
|
||||||
|
vp.colour = Colour;
|
||||||
|
vp.hue = Hue;
|
||||||
|
vp.contrast = Contrast;
|
||||||
|
vp.depth = ovlBpp;
|
||||||
|
vp.palette = ovlPalette; // gf: is this always ok? VIDEO_PALETTE_RGB565;
|
||||||
|
result |= ioctl(videoDev, VIDIOCSPICT, &vp);
|
||||||
|
return result == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool cDvbApi::OvlO(bool Value)
|
||||||
|
{
|
||||||
|
int result = 0;
|
||||||
|
if (!ovlGeoSet && Value)
|
||||||
|
return false;
|
||||||
|
int one = 1;
|
||||||
|
int zero = 0;
|
||||||
|
result |= ioctl(videoDev, VIDIOCCAPTURE, Value ? &one : &zero);
|
||||||
|
ovlStat = Value;
|
||||||
|
if (result) {
|
||||||
|
ovlStat = false;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_OSD
|
#ifdef DEBUG_OSD
|
||||||
void cDvbApi::SetColor(eDvbColor colorFg, eDvbColor colorBg)
|
void cDvbApi::SetColor(eDvbColor colorFg, eDvbColor colorBg)
|
||||||
{
|
{
|
||||||
@ -1233,7 +1479,7 @@ void cDvbApi::Open(int w, int h)
|
|||||||
rows = h;
|
rows = h;
|
||||||
#ifdef DEBUG_OSD
|
#ifdef DEBUG_OSD
|
||||||
window = subwin(stdscr, h, w, d, 0);
|
window = subwin(stdscr, h, w, d, 0);
|
||||||
syncok(window, TRUE);
|
syncok(window, true);
|
||||||
#define B2C(b) (((b) * 1000) / 255)
|
#define B2C(b) (((b) * 1000) / 255)
|
||||||
#define SETCOLOR(n, r, g, b, o) init_color(n, B2C(r), B2C(g), B2C(b))
|
#define SETCOLOR(n, r, g, b, o) init_color(n, B2C(r), B2C(g), B2C(b))
|
||||||
#else
|
#else
|
||||||
|
27
dvbapi.h
27
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.14 2000/09/10 10:03:29 kls Exp $
|
* $Id: dvbapi.h 1.16 2000/09/17 12:15:05 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __DVBAPI_H
|
#ifndef __DVBAPI_H
|
||||||
@ -21,6 +21,12 @@ typedef unsigned char __u8;
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <dvb.h>
|
#include <dvb.h>
|
||||||
|
|
||||||
|
// Overlay facilities
|
||||||
|
#define MAXCLIPRECTS 100
|
||||||
|
typedef struct CRect {
|
||||||
|
signed short x, y, width, height;
|
||||||
|
};
|
||||||
|
|
||||||
#define MenuLines 15
|
#define MenuLines 15
|
||||||
#define MenuColumns 40
|
#define MenuColumns 40
|
||||||
|
|
||||||
@ -70,6 +76,25 @@ public:
|
|||||||
// Closes down all DVB devices.
|
// Closes down all DVB devices.
|
||||||
// Must be called at the end of the program.
|
// Must be called at the end of the program.
|
||||||
|
|
||||||
|
// Image Grab facilities
|
||||||
|
|
||||||
|
bool GrabImage(const char *FileName, bool Jpeg = true, int Quality = -1, int SizeX = -1, int SizeY = -1);
|
||||||
|
|
||||||
|
// Overlay facilities
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool ovlStat, ovlGeoSet, ovlFbSet;
|
||||||
|
int ovlSizeX, ovlSizeY, ovlPosX, ovlPosY, ovlBpp, ovlPalette, ovlClips, ovlClipCount;
|
||||||
|
int ovlFbSizeX, ovlFbSizeY;
|
||||||
|
__u16 ovlBrightness, ovlColour, ovlHue, ovlContrast;
|
||||||
|
struct video_clip ovlClipRects[MAXCLIPRECTS];
|
||||||
|
public:
|
||||||
|
bool OvlF(int SizeX, int SizeY, int FbAddr, int Bpp, int Palette);
|
||||||
|
bool OvlG(int SizeX, int SizeY, int PosX, int PosY);
|
||||||
|
bool OvlC(int ClipCount, CRect *Cr);
|
||||||
|
bool OvlP(__u16 Brightness, __u16 Color, __u16 Hue, __u16 Contrast);
|
||||||
|
bool OvlO(bool Value);
|
||||||
|
|
||||||
// On Screen Display facilities
|
// On Screen Display facilities
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
19
eit.c
19
eit.c
@ -13,7 +13,7 @@
|
|||||||
* the Free Software Foundation; either version 2 of the License, or *
|
* the Free Software Foundation; either version 2 of the License, or *
|
||||||
* (at your option) any later version. *
|
* (at your option) any later version. *
|
||||||
* *
|
* *
|
||||||
* $Id: eit.c 1.1 2000/09/03 10:22:25 kls Exp $
|
* $Id: eit.c 1.3 2000/09/17 15:23:05 kls Exp $
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
#include "eit.h"
|
#include "eit.h"
|
||||||
@ -22,7 +22,6 @@
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <sys/poll.h>
|
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <dvb_comcode.h>
|
#include <dvb_comcode.h>
|
||||||
#include "tools.h"
|
#include "tools.h"
|
||||||
@ -253,15 +252,12 @@ int cEIT::GetSection(unsigned char *buf, ushort PID, unsigned char sec)
|
|||||||
int seclen=0;
|
int seclen=0;
|
||||||
unsigned short handle, pid;
|
unsigned short handle, pid;
|
||||||
unsigned char section, sectionnum=0xff, maxsec=0;
|
unsigned char section, sectionnum=0xff, maxsec=0;
|
||||||
struct pollfd pfd;
|
|
||||||
|
|
||||||
if ((handle = SetBitFilter(PID, (sec<<8)|0x00ff, SECTION_CONTINUOS))==0xffff)
|
if ((handle = SetBitFilter(PID, (sec<<8)|0x00ff, SECTION_CONTINUOS))==0xffff)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
seclen=0;
|
seclen=0;
|
||||||
pfd.fd=fsvbi;
|
if (!cFile::AnyFileReady(fsvbi, 20000))
|
||||||
pfd.events=POLLIN;
|
|
||||||
if (poll(&pfd, 1, 20000)==0)
|
|
||||||
{
|
{
|
||||||
//cerr << "Timeout\n";
|
//cerr << "Timeout\n";
|
||||||
return -1;
|
return -1;
|
||||||
@ -312,13 +308,12 @@ char * cEIT::mjd2string(unsigned short mjd)
|
|||||||
/** */
|
/** */
|
||||||
int cEIT::GetEIT()
|
int cEIT::GetEIT()
|
||||||
{
|
{
|
||||||
unsigned char buf[1024];
|
unsigned char buf[4096+1]; // max. allowed size for any EIT section (+1 for safety ;-)
|
||||||
eit_t *eit;
|
eit_t *eit;
|
||||||
struct eit_loop_struct1 *eitloop;
|
struct eit_loop_struct1 *eitloop;
|
||||||
struct eit_short_event_descriptor_struct *eitevt;
|
struct eit_short_event_descriptor_struct *eitevt;
|
||||||
int seclen;
|
unsigned int seclen;
|
||||||
unsigned short handle, pid;
|
unsigned short handle, pid;
|
||||||
struct pollfd pfd;
|
|
||||||
eit_event * pevt = (eit_event *)0;
|
eit_event * pevt = (eit_event *)0;
|
||||||
time_t tstart;
|
time_t tstart;
|
||||||
|
|
||||||
@ -344,9 +339,7 @@ int cEIT::GetEIT()
|
|||||||
tstart = time(NULL);
|
tstart = time(NULL);
|
||||||
while ((!evtRunning.bIsValid || !evtNext.bIsValid) && nReceivedEITs < 20 && difftime(time(NULL), tstart) < 4)
|
while ((!evtRunning.bIsValid || !evtNext.bIsValid) && nReceivedEITs < 20 && difftime(time(NULL), tstart) < 4)
|
||||||
{
|
{
|
||||||
pfd.fd=fsvbi;
|
if (!cFile::AnyFileReady(fsvbi, 5000))
|
||||||
pfd.events=POLLIN;
|
|
||||||
if (poll(&pfd, 1, 5000)==0)
|
|
||||||
{
|
{
|
||||||
//cerr << "Timeout\n";
|
//cerr << "Timeout\n";
|
||||||
CloseFilter(handle);
|
CloseFilter(handle);
|
||||||
@ -357,6 +350,8 @@ int cEIT::GetEIT()
|
|||||||
seclen=(buf[6]<<8)|buf[7];
|
seclen=(buf[6]<<8)|buf[7];
|
||||||
pid=(buf[4]<<8)|buf[5];
|
pid=(buf[4]<<8)|buf[5];
|
||||||
|
|
||||||
|
if (seclen >= sizeof(buf))
|
||||||
|
seclen = sizeof(buf) - 1;
|
||||||
read(fsvbi, buf, seclen);
|
read(fsvbi, buf, seclen);
|
||||||
|
|
||||||
if (seclen < (int)(sizeof(eit_t)
|
if (seclen < (int)(sizeof(eit_t)
|
||||||
|
35
interface.c
35
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.15 2000/09/10 16:04:14 kls Exp $
|
* $Id: interface.c 1.19 2000/09/19 17:41:23 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "interface.h"
|
#include "interface.h"
|
||||||
@ -29,11 +29,19 @@ cInterface::cInterface(void)
|
|||||||
open = 0;
|
open = 0;
|
||||||
cols[0] = 0;
|
cols[0] = 0;
|
||||||
keyFromWait = kNone;
|
keyFromWait = kNone;
|
||||||
|
SVDRP = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cInterface::Init(void)
|
void cInterface::Init(int SVDRPport)
|
||||||
{
|
{
|
||||||
RcIo.SetCode(Keys.code, Keys.address);
|
RcIo.SetCode(Keys.code, Keys.address);
|
||||||
|
if (SVDRPport)
|
||||||
|
SVDRP = new cSVDRP(SVDRPport);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cInterface::Cleanup(void)
|
||||||
|
{
|
||||||
|
delete SVDRP;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cInterface::Open(int NumCols, int NumLines)
|
void cInterface::Open(int NumCols, int NumLines)
|
||||||
@ -52,10 +60,6 @@ void cInterface::Close(void)
|
|||||||
|
|
||||||
unsigned int cInterface::GetCh(bool Wait)
|
unsigned int cInterface::GetCh(bool Wait)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_OSD
|
|
||||||
timeout(0);
|
|
||||||
getch(); // just to make 'ncurses' display the window:
|
|
||||||
#endif
|
|
||||||
if (RcIo.InputAvailable(Wait)) {
|
if (RcIo.InputAvailable(Wait)) {
|
||||||
unsigned int Command;
|
unsigned int Command;
|
||||||
return RcIo.GetCommand(&Command, NULL) ? Command : 0;
|
return RcIo.GetCommand(&Command, NULL) ? Command : 0;
|
||||||
@ -65,21 +69,24 @@ unsigned int cInterface::GetCh(bool Wait)
|
|||||||
|
|
||||||
eKeys cInterface::GetKey(bool Wait)
|
eKeys cInterface::GetKey(bool Wait)
|
||||||
{
|
{
|
||||||
|
if (SVDRP)
|
||||||
|
SVDRP->Process();
|
||||||
eKeys Key = keyFromWait != kNone ? keyFromWait : Keys.Get(GetCh(Wait));
|
eKeys Key = keyFromWait != kNone ? keyFromWait : Keys.Get(GetCh(Wait));
|
||||||
keyFromWait = kNone;
|
keyFromWait = kNone;
|
||||||
return Key;
|
return Key;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cInterface::PutKey(eKeys Key)
|
||||||
|
{
|
||||||
|
keyFromWait = Key;
|
||||||
|
}
|
||||||
|
|
||||||
eKeys cInterface::Wait(int Seconds, bool KeepChar)
|
eKeys cInterface::Wait(int Seconds, bool KeepChar)
|
||||||
{
|
{
|
||||||
int t0 = time_ms() + Seconds * 1000;
|
|
||||||
eKeys Key = kNone;
|
eKeys Key = kNone;
|
||||||
|
RcIo.Flush(500);
|
||||||
while (time_ms() < t0) {
|
if (cFile::AnyFileReady(-1, Seconds * 1000))
|
||||||
Key = GetKey();
|
Key = GetKey();
|
||||||
if (Key != kNone)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (KeepChar)
|
if (KeepChar)
|
||||||
keyFromWait = Key;
|
keyFromWait = Key;
|
||||||
return Key;
|
return Key;
|
||||||
@ -227,7 +234,7 @@ 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...");
|
||||||
RcIo.Flush(3);
|
RcIo.Flush(3000);
|
||||||
ClearEol(0, 5);
|
ClearEol(0, 5);
|
||||||
ClearEol(0, 6);
|
ClearEol(0, 6);
|
||||||
break;
|
break;
|
||||||
|
@ -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.11 2000/09/10 10:35:46 kls Exp $
|
* $Id: interface.h 1.13 2000/09/18 22:29:31 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __INTERFACE_H
|
#ifndef __INTERFACE_H
|
||||||
@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "dvbapi.h"
|
#include "dvbapi.h"
|
||||||
|
#include "svdrp.h"
|
||||||
|
|
||||||
class cInterface {
|
class cInterface {
|
||||||
public:
|
public:
|
||||||
@ -20,16 +21,19 @@ private:
|
|||||||
int open;
|
int open;
|
||||||
int cols[MaxCols];
|
int cols[MaxCols];
|
||||||
eKeys keyFromWait;
|
eKeys keyFromWait;
|
||||||
|
cSVDRP *SVDRP;
|
||||||
unsigned int GetCh(bool Wait = true);
|
unsigned int GetCh(bool Wait = true);
|
||||||
void QueryKeys(void);
|
void QueryKeys(void);
|
||||||
void HelpButton(int Index, const char *Text, eDvbColor FgColor, eDvbColor BgColor);
|
void HelpButton(int Index, const char *Text, eDvbColor FgColor, eDvbColor BgColor);
|
||||||
eKeys Wait(int Seconds = 1, bool KeepChar = false);
|
eKeys Wait(int Seconds = 1, bool KeepChar = false);
|
||||||
public:
|
public:
|
||||||
cInterface(void);
|
cInterface(void);
|
||||||
void Init(void);
|
void Init(int SVDRPport = 0);
|
||||||
|
void Cleanup(void);
|
||||||
void Open(int NumCols = MenuColumns, int NumLines = MenuLines);
|
void Open(int NumCols = MenuColumns, int NumLines = MenuLines);
|
||||||
void Close(void);
|
void Close(void);
|
||||||
eKeys GetKey(bool Wait = true);
|
eKeys GetKey(bool Wait = true);
|
||||||
|
void PutKey(eKeys Key);
|
||||||
void Clear(void);
|
void Clear(void);
|
||||||
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);
|
||||||
|
4
menu.c
4
menu.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: menu.c 1.26 2000/09/10 15:06:15 kls Exp $
|
* $Id: menu.c 1.27 2000/09/11 21:13:46 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "menu.h"
|
#include "menu.h"
|
||||||
@ -1190,7 +1190,7 @@ eOSState cDirectChannelSelect::ProcessKey(eKeys Key)
|
|||||||
if (number >= 0) {
|
if (number >= 0) {
|
||||||
number = number * 10 + Key - k0;
|
number = number * 10 + Key - k0;
|
||||||
cChannel *channel = Channels.GetByNumber(number);
|
cChannel *channel = Channels.GetByNumber(number);
|
||||||
char *Name = channel ? channel->name : "*** Invalid Channel ***";
|
const char *Name = channel ? channel->name : "*** Invalid Channel ***";
|
||||||
int BufSize = MenuColumns + 1;
|
int BufSize = MenuColumns + 1;
|
||||||
char buffer[BufSize];
|
char buffer[BufSize];
|
||||||
snprintf(buffer, BufSize, "%d %s", number, Name);
|
snprintf(buffer, BufSize, "%d %s", number, Name);
|
||||||
|
60
remote.c
60
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.11 2000/07/29 16:23:47 kls Exp $
|
* $Id: remote.c 1.13 2000/09/19 17:40:52 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "remote.h"
|
#include "remote.h"
|
||||||
@ -49,33 +49,29 @@ cRcIoBase::~cRcIoBase()
|
|||||||
|
|
||||||
cRcIoKBD::cRcIoKBD(void)
|
cRcIoKBD::cRcIoKBD(void)
|
||||||
{
|
{
|
||||||
|
f.Open(0); // stdin
|
||||||
}
|
}
|
||||||
|
|
||||||
cRcIoKBD::~cRcIoKBD()
|
cRcIoKBD::~cRcIoKBD()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void cRcIoKBD::Flush(int WaitSeconds)
|
void cRcIoKBD::Flush(int WaitMs)
|
||||||
{
|
{
|
||||||
time_t t0 = time(NULL);
|
int t0 = time_ms();
|
||||||
|
|
||||||
timeout(10);
|
timeout(10);
|
||||||
for (;;) {
|
for (;;) {
|
||||||
while (getch() > 0)
|
while (getch() > 0)
|
||||||
t0 = time(NULL);
|
t0 = time_ms();
|
||||||
if (time(NULL) - t0 >= WaitSeconds)
|
if (time_ms() - t0 >= WaitMs)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cRcIoKBD::InputAvailable(bool Wait)
|
bool cRcIoKBD::InputAvailable(bool Wait)
|
||||||
{
|
{
|
||||||
timeout(Wait ? 1000 : 10);
|
return f.Ready(Wait);
|
||||||
int ch = getch();
|
|
||||||
if (ch == ERR)
|
|
||||||
return false;
|
|
||||||
ungetch(ch);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cRcIoKBD::GetCommand(unsigned int *Command, unsigned short *)
|
bool cRcIoKBD::GetCommand(unsigned int *Command, unsigned short *)
|
||||||
@ -98,7 +94,7 @@ cRcIoRCU::cRcIoRCU(char *DeviceName)
|
|||||||
code = 0;
|
code = 0;
|
||||||
address = 0xFFFF;
|
address = 0xFFFF;
|
||||||
lastNumber = 0;
|
lastNumber = 0;
|
||||||
if ((f = open(DeviceName, O_RDWR | O_NONBLOCK)) >= 0) {
|
if (f.Open(DeviceName, O_RDWR | O_NONBLOCK)) {
|
||||||
struct termios t;
|
struct termios t;
|
||||||
if (tcgetattr(f, &t) == 0) {
|
if (tcgetattr(f, &t) == 0) {
|
||||||
cfsetspeed(&t, B9600);
|
cfsetspeed(&t, B9600);
|
||||||
@ -107,17 +103,14 @@ cRcIoRCU::cRcIoRCU(char *DeviceName)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
LOG_ERROR_STR(DeviceName);
|
LOG_ERROR_STR(DeviceName);
|
||||||
close(f);
|
f.Close();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
LOG_ERROR_STR(DeviceName);
|
LOG_ERROR_STR(DeviceName);
|
||||||
f = -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cRcIoRCU::~cRcIoRCU()
|
cRcIoRCU::~cRcIoRCU()
|
||||||
{
|
{
|
||||||
if (f >= 0)
|
|
||||||
close(f);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int cRcIoRCU::ReceiveByte(bool Wait)
|
int cRcIoRCU::ReceiveByte(bool Wait)
|
||||||
@ -135,7 +128,7 @@ int cRcIoRCU::ReceiveByte(bool Wait)
|
|||||||
|
|
||||||
bool cRcIoRCU::SendByteHandshake(unsigned char c)
|
bool cRcIoRCU::SendByteHandshake(unsigned char c)
|
||||||
{
|
{
|
||||||
if (f >= 0) {
|
if (f.IsOpen()) {
|
||||||
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(); reply >= 0;) {
|
||||||
@ -179,21 +172,21 @@ bool cRcIoRCU::SetMode(unsigned char Mode)
|
|||||||
return SendCommand(mode);
|
return SendCommand(mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cRcIoRCU::Flush(int WaitSeconds)
|
void cRcIoRCU::Flush(int WaitMs)
|
||||||
{
|
{
|
||||||
time_t t0 = time(NULL);
|
int t0 = time_ms();
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
while (ReceiveByte(false) >= 0)
|
while (ReceiveByte(false) >= 0)
|
||||||
t0 = time(NULL);
|
t0 = time_ms();
|
||||||
if (time(NULL) - t0 >= WaitSeconds)
|
if (time_ms() - t0 >= WaitMs)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cRcIoRCU::InputAvailable(bool Wait)
|
bool cRcIoRCU::InputAvailable(bool Wait)
|
||||||
{
|
{
|
||||||
return DataAvailable(f, Wait);
|
return f.Ready(Wait);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cRcIoRCU::GetCommand(unsigned int *Command, unsigned short *Address)
|
bool cRcIoRCU::GetCommand(unsigned int *Command, unsigned short *Address)
|
||||||
@ -349,22 +342,21 @@ cRcIoLIRC::cRcIoLIRC(char *DeviceName)
|
|||||||
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);
|
||||||
f = socket(AF_UNIX, SOCK_STREAM, 0);
|
int sock = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||||
if (f >= 0) {
|
if (sock >= 0) {
|
||||||
if (connect(f, (struct sockaddr *)&addr, sizeof(addr)) >= 0)
|
if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) >= 0) {
|
||||||
|
f.Open(sock);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
LOG_ERROR_STR(DeviceName);
|
LOG_ERROR_STR(DeviceName);
|
||||||
close(f);
|
close(sock);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
LOG_ERROR_STR(DeviceName);
|
LOG_ERROR_STR(DeviceName);
|
||||||
f = -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cRcIoLIRC::~cRcIoLIRC()
|
cRcIoLIRC::~cRcIoLIRC()
|
||||||
{
|
{
|
||||||
if (f >= 0)
|
|
||||||
close(f);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *cRcIoLIRC::ReceiveString(void)
|
const char *cRcIoLIRC::ReceiveString(void)
|
||||||
@ -389,24 +381,24 @@ const char *cRcIoLIRC::ReceiveString(void)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cRcIoLIRC::Flush(int WaitSeconds)
|
void cRcIoLIRC::Flush(int WaitMs)
|
||||||
{
|
{
|
||||||
char buf[LIRC_BUFFER_SIZE];
|
char buf[LIRC_BUFFER_SIZE];
|
||||||
time_t t0 = time(NULL);
|
int t0 = time_ms();
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
while (InputAvailable(false)) {
|
while (InputAvailable(false)) {
|
||||||
read(f, buf, sizeof(buf));
|
read(f, buf, sizeof(buf));
|
||||||
t0 = time(NULL);
|
t0 = time_ms();
|
||||||
}
|
}
|
||||||
if (time(NULL) - t0 >= WaitSeconds)
|
if (time_ms() - t0 >= WaitMs)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cRcIoLIRC::InputAvailable(bool Wait)
|
bool cRcIoLIRC::InputAvailable(bool Wait)
|
||||||
{
|
{
|
||||||
return DataAvailable(f, Wait);
|
return f.Ready(Wait);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cRcIoLIRC::GetCommand(unsigned int *Command, unsigned short *)
|
bool cRcIoLIRC::GetCommand(unsigned int *Command, unsigned short *)
|
||||||
|
17
remote.h
17
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.7 2000/07/15 16:32:43 kls Exp $
|
* $Id: remote.h 1.9 2000/09/19 17:39:36 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __REMOTE_H
|
#ifndef __REMOTE_H
|
||||||
@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
#include "tools.h"
|
||||||
|
|
||||||
class cRcIoBase {
|
class cRcIoBase {
|
||||||
protected:
|
protected:
|
||||||
@ -28,7 +29,7 @@ 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 WaitSeconds = 0) {}
|
virtual void Flush(int WaitMs = 0) {}
|
||||||
virtual bool InputAvailable(bool Wait = false) = 0;
|
virtual bool InputAvailable(bool Wait = false) = 0;
|
||||||
virtual bool GetCommand(unsigned int *Command, unsigned short *Address = NULL) = 0;
|
virtual bool GetCommand(unsigned int *Command, unsigned short *Address = NULL) = 0;
|
||||||
};
|
};
|
||||||
@ -36,10 +37,12 @@ public:
|
|||||||
#if defined REMOTE_KBD
|
#if defined REMOTE_KBD
|
||||||
|
|
||||||
class cRcIoKBD : public cRcIoBase {
|
class cRcIoKBD : public cRcIoBase {
|
||||||
|
private:
|
||||||
|
cFile f;
|
||||||
public:
|
public:
|
||||||
cRcIoKBD(void);
|
cRcIoKBD(void);
|
||||||
virtual ~cRcIoKBD();
|
virtual ~cRcIoKBD();
|
||||||
virtual void Flush(int WaitSeconds = 0);
|
virtual void Flush(int WaitMs = 0);
|
||||||
virtual bool InputAvailable(bool Wait = false);
|
virtual bool InputAvailable(bool Wait = false);
|
||||||
virtual bool GetCommand(unsigned int *Command, unsigned short *Address = NULL);
|
virtual bool GetCommand(unsigned int *Command, unsigned short *Address = NULL);
|
||||||
};
|
};
|
||||||
@ -48,7 +51,7 @@ public:
|
|||||||
|
|
||||||
class cRcIoRCU : public cRcIoBase {
|
class cRcIoRCU : public cRcIoBase {
|
||||||
private:
|
private:
|
||||||
int f;
|
cFile f;
|
||||||
unsigned char dp, code, mode;
|
unsigned char dp, code, mode;
|
||||||
unsigned short address;
|
unsigned short address;
|
||||||
int lastNumber;
|
int lastNumber;
|
||||||
@ -66,7 +69,7 @@ public:
|
|||||||
virtual void SetPoints(unsigned char Dp, bool On);
|
virtual void SetPoints(unsigned char Dp, bool On);
|
||||||
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 WaitSeconds = 0);
|
virtual void Flush(int WaitMs = 0);
|
||||||
virtual bool InputAvailable(bool Wait = false);
|
virtual bool InputAvailable(bool Wait = false);
|
||||||
virtual bool GetCommand(unsigned int *Command, unsigned short *Address = NULL);
|
virtual bool GetCommand(unsigned int *Command, unsigned short *Address = NULL);
|
||||||
};
|
};
|
||||||
@ -76,13 +79,13 @@ public:
|
|||||||
class cRcIoLIRC : public cRcIoBase {
|
class cRcIoLIRC : public cRcIoBase {
|
||||||
private:
|
private:
|
||||||
enum { LIRC_KEY_BUF = 8, LIRC_BUFFER_SIZE = 128 };
|
enum { LIRC_KEY_BUF = 8, LIRC_BUFFER_SIZE = 128 };
|
||||||
int f;
|
cFile f;
|
||||||
char keyName[LIRC_KEY_BUF];
|
char keyName[LIRC_KEY_BUF];
|
||||||
const char *ReceiveString(void);
|
const char *ReceiveString(void);
|
||||||
public:
|
public:
|
||||||
cRcIoLIRC(char *DeviceName);
|
cRcIoLIRC(char *DeviceName);
|
||||||
virtual ~cRcIoLIRC();
|
virtual ~cRcIoLIRC();
|
||||||
virtual void Flush(int WaitSeconds = 0);
|
virtual void Flush(int WaitMs = 0);
|
||||||
virtual bool InputAvailable(bool Wait = false);
|
virtual bool InputAvailable(bool Wait = false);
|
||||||
virtual bool GetCommand(unsigned int *Command, unsigned short *Address = NULL);
|
virtual bool GetCommand(unsigned int *Command, unsigned short *Address = NULL);
|
||||||
};
|
};
|
||||||
|
280
svdrp.c
280
svdrp.c
@ -10,7 +10,7 @@
|
|||||||
* and interact with the Video Disk Recorder - or write a full featured
|
* and interact with the Video Disk Recorder - or write a full featured
|
||||||
* graphical interface that sits on top of an SVDRP connection.
|
* graphical interface that sits on top of an SVDRP connection.
|
||||||
*
|
*
|
||||||
* $Id: svdrp.c 1.6 2000/09/09 10:51:21 kls Exp $
|
* $Id: svdrp.c 1.10 2000/09/17 13:39:37 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define _GNU_SOURCE
|
#define _GNU_SOURCE
|
||||||
@ -120,8 +120,15 @@ const char *HelpPages[] = {
|
|||||||
" Delete channel.",
|
" Delete channel.",
|
||||||
"DELT <number>\n"
|
"DELT <number>\n"
|
||||||
" Delete timer.",
|
" Delete timer.",
|
||||||
|
"GRAB <filename> [ jpeg | pnm [ <quality> [ <sizex> <sizey> ] ] ]\n"
|
||||||
|
" Grab the current frame and save it to the given file. Images can\n"
|
||||||
|
" be stored as JPEG (default) or PNM, at the given quality (default\n"
|
||||||
|
" is 'maximum', only applies to JPEG) and size (default is full screen).",
|
||||||
"HELP [ <topic> ]\n"
|
"HELP [ <topic> ]\n"
|
||||||
" The HELP command gives help info.",
|
" The HELP command gives help info.",
|
||||||
|
"HITK [ <key> ]\n"
|
||||||
|
" Hit the given remote control key. Without option a list of all\n"
|
||||||
|
" valid key names is given.",
|
||||||
"LSTC [ <number> | <name> ]\n"
|
"LSTC [ <number> | <name> ]\n"
|
||||||
" List channels. Without option, all channels are listed. Otherwise\n"
|
" List channels. Without option, all channels are listed. Otherwise\n"
|
||||||
" only the given channel is listed. If a name is given, all channels\n"
|
" only the given channel is listed. If a name is given, all channels\n"
|
||||||
@ -147,6 +154,16 @@ const char *HelpPages[] = {
|
|||||||
" Create a new timer. Settings must be in the same format as returned\n"
|
" Create a new timer. Settings must be in the same format as returned\n"
|
||||||
" by the LSTT command. It is an error if a timer with the same channel,\n"
|
" by the LSTT command. It is an error if a timer with the same channel,\n"
|
||||||
" day, start and stop time already exists.",
|
" day, start and stop time already exists.",
|
||||||
|
"OVLF <sizex> <sizey> <fbaddr> <bpp> <palette>\n"
|
||||||
|
" Set the size, address depth and palette of the overlay.",
|
||||||
|
"OVLG <sizex> <sizey> <posx> <posy>\n"
|
||||||
|
" Set the size and position of the overlay.",
|
||||||
|
"OVLC <clipcount> <base16-CRect-array>\n"
|
||||||
|
" Set the overlay clipping rectangles.",
|
||||||
|
"OVLP <brightness> <colour> <hue> <contrast>\n"
|
||||||
|
" Set the picture parameters for the overlay.",
|
||||||
|
"OVLO 0 | 1\n"
|
||||||
|
" Switch the overlay on or off.",
|
||||||
"UPDT <settings>\n"
|
"UPDT <settings>\n"
|
||||||
" Updates a timer. Settings must be in the same format as returned\n"
|
" Updates a timer. Settings must be in the same format as returned\n"
|
||||||
" by the LSTT command. If a timer with the same channel, day, start\n"
|
" by the LSTT command. If a timer with the same channel, day, start\n"
|
||||||
@ -206,7 +223,6 @@ const char *GetHelpPage(const char *Cmd)
|
|||||||
cSVDRP::cSVDRP(int Port)
|
cSVDRP::cSVDRP(int Port)
|
||||||
:socket(Port)
|
:socket(Port)
|
||||||
{
|
{
|
||||||
filedes = -1;
|
|
||||||
isyslog(LOG_INFO, "SVDRP listening on port %d", Port);
|
isyslog(LOG_INFO, "SVDRP listening on port %d", Port);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -217,14 +233,13 @@ cSVDRP::~cSVDRP()
|
|||||||
|
|
||||||
void cSVDRP::Close(void)
|
void cSVDRP::Close(void)
|
||||||
{
|
{
|
||||||
if (filedes >= 0) {
|
if (file.IsOpen()) {
|
||||||
//TODO how can we get the *full* hostname?
|
//TODO how can we get the *full* hostname?
|
||||||
char buffer[MAXCMDBUFFER];
|
char buffer[MAXCMDBUFFER];
|
||||||
gethostname(buffer, sizeof(buffer));
|
gethostname(buffer, sizeof(buffer));
|
||||||
Reply(221, "%s closing connection", buffer);
|
Reply(221, "%s closing connection", buffer);
|
||||||
isyslog(LOG_INFO, "closing connection"); //TODO store IP#???
|
isyslog(LOG_INFO, "closing connection"); //TODO store IP#???
|
||||||
close(filedes);
|
file.Close();
|
||||||
filedes = -1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -232,11 +247,14 @@ bool cSVDRP::Send(const char *s, int length)
|
|||||||
{
|
{
|
||||||
if (length < 0)
|
if (length < 0)
|
||||||
length = strlen(s);
|
length = strlen(s);
|
||||||
int wbytes = write(filedes, s, length);
|
int wbytes = write(file, s, length);
|
||||||
if (wbytes == length)
|
if (wbytes == length)
|
||||||
return true;
|
return true;
|
||||||
if (wbytes < 0)
|
if (wbytes < 0) {
|
||||||
LOG_ERROR;
|
LOG_ERROR;
|
||||||
|
file.Close();
|
||||||
|
cDvbApi::PrimaryDvbApi->OvlO(false);
|
||||||
|
}
|
||||||
else //XXX while...???
|
else //XXX while...???
|
||||||
esyslog(LOG_ERR, "Wrote %d bytes to client while expecting %d\n", wbytes, length);
|
esyslog(LOG_ERR, "Wrote %d bytes to client while expecting %d\n", wbytes, length);
|
||||||
return false;
|
return false;
|
||||||
@ -244,7 +262,7 @@ bool cSVDRP::Send(const char *s, int length)
|
|||||||
|
|
||||||
void cSVDRP::Reply(int Code, const char *fmt, ...)
|
void cSVDRP::Reply(int Code, const char *fmt, ...)
|
||||||
{
|
{
|
||||||
if (filedes >= 0) {
|
if (file.IsOpen()) {
|
||||||
if (Code != 0) {
|
if (Code != 0) {
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
@ -274,7 +292,7 @@ void cSVDRP::Reply(int Code, const char *fmt, ...)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void cSVDRP::CmdChan(const char *Option)
|
void cSVDRP::CmdCHAN(const char *Option)
|
||||||
{
|
{
|
||||||
if (*Option) {
|
if (*Option) {
|
||||||
int n = -1;
|
int n = -1;
|
||||||
@ -331,13 +349,13 @@ void cSVDRP::CmdChan(const char *Option)
|
|||||||
Reply(550, "Unable to find channel \"%d\"", CurrentChannel);
|
Reply(550, "Unable to find channel \"%d\"", CurrentChannel);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cSVDRP::CmdDelc(const char *Option)
|
void cSVDRP::CmdDELC(const char *Option)
|
||||||
{
|
{
|
||||||
//TODO combine this with menu action (timers must be updated)
|
//TODO combine this with menu action (timers must be updated)
|
||||||
Reply(502, "DELC not yet implemented");
|
Reply(502, "DELC not yet implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
void cSVDRP::CmdDelt(const char *Option)
|
void cSVDRP::CmdDELT(const char *Option)
|
||||||
{
|
{
|
||||||
if (*Option) {
|
if (*Option) {
|
||||||
if (isnumber(Option)) {
|
if (isnumber(Option)) {
|
||||||
@ -362,7 +380,68 @@ void cSVDRP::CmdDelt(const char *Option)
|
|||||||
Reply(501, "Missing timer number");
|
Reply(501, "Missing timer number");
|
||||||
}
|
}
|
||||||
|
|
||||||
void cSVDRP::CmdHelp(const char *Option)
|
void cSVDRP::CmdGRAB(const char *Option)
|
||||||
|
{
|
||||||
|
char *FileName = NULL;
|
||||||
|
bool Jpeg = true;
|
||||||
|
int Quality = -1, SizeX = -1, SizeY = -1;
|
||||||
|
if (*Option) {
|
||||||
|
char buf[strlen(Option) + 1];
|
||||||
|
char *p = strcpy(buf, Option);
|
||||||
|
const char *delim = " \t";
|
||||||
|
FileName = strtok(p, delim);
|
||||||
|
if ((p = strtok(NULL, delim)) != NULL) {
|
||||||
|
if (strcasecmp(p, "JPEG") == 0)
|
||||||
|
Jpeg = true;
|
||||||
|
else if (strcasecmp(p, "PNM") == 0)
|
||||||
|
Jpeg = false;
|
||||||
|
else {
|
||||||
|
Reply(501, "Unknown image type \"%s\"", p);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((p = strtok(NULL, delim)) != NULL) {
|
||||||
|
if (isnumber(p))
|
||||||
|
Quality = atoi(p);
|
||||||
|
else {
|
||||||
|
Reply(501, "Illegal quality \"%s\"", p);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((p = strtok(NULL, delim)) != NULL) {
|
||||||
|
if (isnumber(p))
|
||||||
|
SizeX = atoi(p);
|
||||||
|
else {
|
||||||
|
Reply(501, "Illegal sizex \"%s\"", p);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ((p = strtok(NULL, delim)) != NULL) {
|
||||||
|
if (isnumber(p))
|
||||||
|
SizeY = atoi(p);
|
||||||
|
else {
|
||||||
|
Reply(501, "Illegal sizey \"%s\"", p);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Reply(501, "Missing sizey");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((p = strtok(NULL, delim)) != NULL) {
|
||||||
|
Reply(501, "Unexpected parameter \"%s\"", p);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (cDvbApi::PrimaryDvbApi->GrabImage(FileName, Jpeg, Quality, SizeX, SizeY))
|
||||||
|
Reply(250, "Grabbed image %s", Option);
|
||||||
|
else
|
||||||
|
Reply(451, "Grab image failed");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Reply(501, "Missing filename");
|
||||||
|
}
|
||||||
|
|
||||||
|
void cSVDRP::CmdHELP(const char *Option)
|
||||||
{
|
{
|
||||||
if (*Option) {
|
if (*Option) {
|
||||||
const char *hp = GetHelpPage(Option);
|
const char *hp = GetHelpPage(Option);
|
||||||
@ -390,7 +469,27 @@ void cSVDRP::CmdHelp(const char *Option)
|
|||||||
Reply(214, "End of HELP info");
|
Reply(214, "End of HELP info");
|
||||||
}
|
}
|
||||||
|
|
||||||
void cSVDRP::CmdLstc(const char *Option)
|
void cSVDRP::CmdHITK(const char *Option)
|
||||||
|
{
|
||||||
|
if (*Option) {
|
||||||
|
eKeys k = Keys.Translate(Option);
|
||||||
|
if (k != kNone) {
|
||||||
|
Interface.PutKey(k);
|
||||||
|
Reply(250, "Key \"%s\" accepted", Option);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Reply(504, "Unknown key: \"%s\"", Option);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Reply(-214, "Valid <key> names for the HITK command:");
|
||||||
|
for (int i = 0; i < kNone; i++) {
|
||||||
|
Reply(-214, " %s", Keys.keys[i].name);
|
||||||
|
}
|
||||||
|
Reply(214, "End of key list");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cSVDRP::CmdLSTC(const char *Option)
|
||||||
{
|
{
|
||||||
if (*Option) {
|
if (*Option) {
|
||||||
if (isnumber(Option)) {
|
if (isnumber(Option)) {
|
||||||
@ -433,7 +532,7 @@ void cSVDRP::CmdLstc(const char *Option)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void cSVDRP::CmdLstt(const char *Option)
|
void cSVDRP::CmdLSTT(const char *Option)
|
||||||
{
|
{
|
||||||
if (*Option) {
|
if (*Option) {
|
||||||
if (isnumber(Option)) {
|
if (isnumber(Option)) {
|
||||||
@ -457,7 +556,7 @@ void cSVDRP::CmdLstt(const char *Option)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void cSVDRP::CmdModc(const char *Option)
|
void cSVDRP::CmdMODC(const char *Option)
|
||||||
{
|
{
|
||||||
if (*Option) {
|
if (*Option) {
|
||||||
char *tail;
|
char *tail;
|
||||||
@ -486,7 +585,7 @@ void cSVDRP::CmdModc(const char *Option)
|
|||||||
Reply(501, "Missing channel settings");
|
Reply(501, "Missing channel settings");
|
||||||
}
|
}
|
||||||
|
|
||||||
void cSVDRP::CmdModt(const char *Option)
|
void cSVDRP::CmdMODT(const char *Option)
|
||||||
{
|
{
|
||||||
if (*Option) {
|
if (*Option) {
|
||||||
char *tail;
|
char *tail;
|
||||||
@ -519,19 +618,19 @@ void cSVDRP::CmdModt(const char *Option)
|
|||||||
Reply(501, "Missing timer settings");
|
Reply(501, "Missing timer settings");
|
||||||
}
|
}
|
||||||
|
|
||||||
void cSVDRP::CmdMovc(const char *Option)
|
void cSVDRP::CmdMOVC(const char *Option)
|
||||||
{
|
{
|
||||||
//TODO combine this with menu action (timers must be updated)
|
//TODO combine this with menu action (timers must be updated)
|
||||||
Reply(502, "MOVC not yet implemented");
|
Reply(502, "MOVC not yet implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
void cSVDRP::CmdMovt(const char *Option)
|
void cSVDRP::CmdMOVT(const char *Option)
|
||||||
{
|
{
|
||||||
//TODO combine this with menu action
|
//TODO combine this with menu action
|
||||||
Reply(502, "MOVT not yet implemented");
|
Reply(502, "MOVT not yet implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
void cSVDRP::CmdNewc(const char *Option)
|
void cSVDRP::CmdNEWC(const char *Option)
|
||||||
{
|
{
|
||||||
if (*Option) {
|
if (*Option) {
|
||||||
cChannel *channel = new cChannel;
|
cChannel *channel = new cChannel;
|
||||||
@ -549,7 +648,7 @@ void cSVDRP::CmdNewc(const char *Option)
|
|||||||
Reply(501, "Missing channel settings");
|
Reply(501, "Missing channel settings");
|
||||||
}
|
}
|
||||||
|
|
||||||
void cSVDRP::CmdNewt(const char *Option)
|
void cSVDRP::CmdNEWT(const char *Option)
|
||||||
{
|
{
|
||||||
if (*Option) {
|
if (*Option) {
|
||||||
cTimer *timer = new cTimer;
|
cTimer *timer = new cTimer;
|
||||||
@ -573,7 +672,107 @@ void cSVDRP::CmdNewt(const char *Option)
|
|||||||
Reply(501, "Missing timer settings");
|
Reply(501, "Missing timer settings");
|
||||||
}
|
}
|
||||||
|
|
||||||
void cSVDRP::CmdUpdt(const char *Option)
|
void cSVDRP::CmdOVLF(const char *Option)
|
||||||
|
{
|
||||||
|
if (*Option) {
|
||||||
|
int SizeX = 0, SizeY = 0, Bpp = 0, Palette = 0, FbAddr = 0;
|
||||||
|
if (5 == sscanf(Option, "%d %d %x %d %d", &SizeX, &SizeY, &FbAddr, &Bpp, &Palette)) {
|
||||||
|
//somehow_set_overlay_geometry;
|
||||||
|
if (cDvbApi::PrimaryDvbApi->OvlF(SizeX, SizeY, FbAddr, Bpp, Palette))
|
||||||
|
Reply(250, "Overlay framebuffer set");
|
||||||
|
else
|
||||||
|
Reply(451, "Illegal overlay framebuffer settings");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Reply(501, "Could not parse overlay framebuffer settings");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Reply(501, "Missing overlay framebuffer settings");
|
||||||
|
}
|
||||||
|
|
||||||
|
void cSVDRP::CmdOVLG(const char *Option)
|
||||||
|
{
|
||||||
|
if (*Option) {
|
||||||
|
int SizeX = 0, SizeY = 0, PosX = 0, PosY = 0;
|
||||||
|
if (4 == sscanf(Option, "%d %d %d %d", &SizeX, &SizeY, &PosX, &PosY)) {
|
||||||
|
//somehow_set_overlay_geometry;
|
||||||
|
if (cDvbApi::PrimaryDvbApi->OvlG(SizeX, SizeY, PosX, PosY))
|
||||||
|
Reply(250, "Overlay geometry set");
|
||||||
|
else
|
||||||
|
Reply(451, "Illegal overlay geometry settings");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Reply(501, "Could not parse overlay geometry settings");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Reply(501, "Missing overlay geometry settings");
|
||||||
|
}
|
||||||
|
|
||||||
|
void cSVDRP::CmdOVLC(const char *Option)
|
||||||
|
{
|
||||||
|
if (*Option) {
|
||||||
|
int ClipCount = 0;
|
||||||
|
unsigned char s[2 * MAXCLIPRECTS * sizeof(CRect) + 2];
|
||||||
|
if (2 == sscanf(Option, "%d %s", &ClipCount, s)) {
|
||||||
|
// Base16-decoding of CRect-array:
|
||||||
|
unsigned char *p = (unsigned char*)ovlClipRects;
|
||||||
|
int i = 0, size = sizeof(CRect)*ClipCount;
|
||||||
|
for (int j = 0; i < size; i++) {
|
||||||
|
p[i] = (s[j++] - 65);
|
||||||
|
p[i] += (s[j++] - 65) << 4;
|
||||||
|
}
|
||||||
|
if (((unsigned)ClipCount == (i / sizeof(CRect))) && (ClipCount >= 0)) {
|
||||||
|
// apply it:
|
||||||
|
if (cDvbApi::PrimaryDvbApi->OvlC(ClipCount, ovlClipRects))
|
||||||
|
Reply(250, "Overlay-Clipping set");
|
||||||
|
else
|
||||||
|
Reply(451, "Illegal overlay clipping settings");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Reply(501, "Error parsing Overlay-Clipping settings");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Reply(501, "Missing Clipping settings");
|
||||||
|
}
|
||||||
|
|
||||||
|
void cSVDRP::CmdOVLP(const char *Option)
|
||||||
|
{
|
||||||
|
if (*Option) {
|
||||||
|
int Brightness = 0, Colour = 0, Hue = 0, Contrast = 0;
|
||||||
|
if (4 == sscanf(Option, "%d %d %d %d", &Brightness, &Colour, &Hue, &Contrast)) {
|
||||||
|
//somehow_set_overlay_picture_settings;
|
||||||
|
if (cDvbApi::PrimaryDvbApi->OvlP(Brightness, Colour, Hue, Contrast))
|
||||||
|
Reply(250, "Overlay picture settings set");
|
||||||
|
else
|
||||||
|
Reply(451, "Illegal overlay picture settings");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Reply(501, "Could not parse overlay picture settings");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Reply(501, "Missing overlay picture settings");
|
||||||
|
}
|
||||||
|
|
||||||
|
void cSVDRP::CmdOVLO(const char *Option)
|
||||||
|
{
|
||||||
|
if (*Option) {
|
||||||
|
int Value;
|
||||||
|
if (1 == sscanf(Option, "%d", &Value)) {
|
||||||
|
//somehow_set_overlay_picture_settings;
|
||||||
|
if (cDvbApi::PrimaryDvbApi->OvlO(Value))
|
||||||
|
Reply(250, "Overlay capture set");
|
||||||
|
else
|
||||||
|
Reply(451, "Error setting overlay capture");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Reply(501, "Could not parse status");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Reply(501, "Missing overlay capture status");
|
||||||
|
}
|
||||||
|
|
||||||
|
void cSVDRP::CmdUPDT(const char *Option)
|
||||||
{
|
{
|
||||||
if (*Option) {
|
if (*Option) {
|
||||||
cTimer *timer = new cTimer;
|
cTimer *timer = new cTimer;
|
||||||
@ -612,19 +811,26 @@ void cSVDRP::Execute(char *Cmd)
|
|||||||
while (*s && !isspace(*s))
|
while (*s && !isspace(*s))
|
||||||
s++;
|
s++;
|
||||||
*s++ = 0;
|
*s++ = 0;
|
||||||
if (CMD("CHAN")) CmdChan(s);
|
if (CMD("CHAN")) CmdCHAN(s);
|
||||||
else if (CMD("DELC")) CmdDelc(s);
|
else if (CMD("DELC")) CmdDELC(s);
|
||||||
else if (CMD("DELT")) CmdDelt(s);
|
else if (CMD("DELT")) CmdDELT(s);
|
||||||
else if (CMD("HELP")) CmdHelp(s);
|
else if (CMD("GRAB")) CmdGRAB(s);
|
||||||
else if (CMD("LSTC")) CmdLstc(s);
|
else if (CMD("HELP")) CmdHELP(s);
|
||||||
else if (CMD("LSTT")) CmdLstt(s);
|
else if (CMD("HITK")) CmdHITK(s);
|
||||||
else if (CMD("MODC")) CmdModc(s);
|
else if (CMD("LSTC")) CmdLSTC(s);
|
||||||
else if (CMD("MODT")) CmdModt(s);
|
else if (CMD("LSTT")) CmdLSTT(s);
|
||||||
else if (CMD("MOVC")) CmdMovc(s);
|
else if (CMD("MODC")) CmdMODC(s);
|
||||||
else if (CMD("MOVT")) CmdMovt(s);
|
else if (CMD("MODT")) CmdMODT(s);
|
||||||
else if (CMD("NEWC")) CmdNewc(s);
|
else if (CMD("MOVC")) CmdMOVC(s);
|
||||||
else if (CMD("NEWT")) CmdNewt(s);
|
else if (CMD("MOVT")) CmdMOVT(s);
|
||||||
else if (CMD("UPDT")) CmdUpdt(s);
|
else if (CMD("NEWC")) CmdNEWC(s);
|
||||||
|
else if (CMD("NEWT")) CmdNEWT(s);
|
||||||
|
else if (CMD("OVLF")) CmdOVLF(s);
|
||||||
|
else if (CMD("OVLG")) CmdOVLG(s);
|
||||||
|
else if (CMD("OVLC")) CmdOVLC(s);
|
||||||
|
else if (CMD("OVLP")) CmdOVLP(s);
|
||||||
|
else if (CMD("OVLO")) CmdOVLO(s);
|
||||||
|
else if (CMD("UPDT")) CmdUPDT(s);
|
||||||
else if (CMD("QUIT")
|
else if (CMD("QUIT")
|
||||||
|| CMD("\x04")) Close();
|
|| CMD("\x04")) Close();
|
||||||
else Reply(500, "Command unrecognized: \"%s\"", Cmd);
|
else Reply(500, "Command unrecognized: \"%s\"", Cmd);
|
||||||
@ -632,9 +838,9 @@ void cSVDRP::Execute(char *Cmd)
|
|||||||
|
|
||||||
void cSVDRP::Process(void)
|
void cSVDRP::Process(void)
|
||||||
{
|
{
|
||||||
bool SendGreeting = filedes < 0;
|
bool SendGreeting = !file.IsOpen();
|
||||||
|
|
||||||
if (filedes >= 0 || (filedes = socket.Accept()) >= 0) {
|
if (file.IsOpen() || file.Open(socket.Accept())) {
|
||||||
char buffer[MAXCMDBUFFER];
|
char buffer[MAXCMDBUFFER];
|
||||||
if (SendGreeting) {
|
if (SendGreeting) {
|
||||||
//TODO how can we get the *full* hostname?
|
//TODO how can we get the *full* hostname?
|
||||||
@ -642,7 +848,7 @@ void cSVDRP::Process(void)
|
|||||||
time_t now = time(NULL);
|
time_t now = time(NULL);
|
||||||
Reply(220, "%s SVDRP VideoDiskRecorder %s; %s", buffer, VDRVERSION, ctime(&now));
|
Reply(220, "%s SVDRP VideoDiskRecorder %s; %s", buffer, VDRVERSION, ctime(&now));
|
||||||
}
|
}
|
||||||
int rbytes = readstring(filedes, buffer, sizeof(buffer) - 1);
|
int rbytes = file.ReadString(buffer, sizeof(buffer) - 1);
|
||||||
if (rbytes > 0) {
|
if (rbytes > 0) {
|
||||||
//XXX overflow check???
|
//XXX overflow check???
|
||||||
// strip trailing whitespace:
|
// strip trailing whitespace:
|
||||||
|
41
svdrp.h
41
svdrp.h
@ -4,12 +4,15 @@
|
|||||||
* 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: svdrp.h 1.2 2000/08/06 12:45:28 kls Exp $
|
* $Id: svdrp.h 1.6 2000/09/17 13:22:04 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __SVDRP_H
|
#ifndef __SVDRP_H
|
||||||
#define __SVDRP_H
|
#define __SVDRP_H
|
||||||
|
|
||||||
|
#include "dvbapi.h"
|
||||||
|
#include "tools.h"
|
||||||
|
|
||||||
class cSocket {
|
class cSocket {
|
||||||
private:
|
private:
|
||||||
int port;
|
int port;
|
||||||
@ -26,23 +29,31 @@ public:
|
|||||||
class cSVDRP {
|
class cSVDRP {
|
||||||
private:
|
private:
|
||||||
cSocket socket;
|
cSocket socket;
|
||||||
int filedes;
|
cFile file;
|
||||||
|
CRect ovlClipRects[MAXCLIPRECTS];
|
||||||
void Close(void);
|
void Close(void);
|
||||||
bool Send(const char *s, int length = -1);
|
bool Send(const char *s, int length = -1);
|
||||||
void Reply(int Code, const char *fmt, ...);
|
void Reply(int Code, const char *fmt, ...);
|
||||||
void CmdChan(const char *Option);
|
void CmdCHAN(const char *Option);
|
||||||
void CmdDelc(const char *Option);
|
void CmdDELC(const char *Option);
|
||||||
void CmdDelt(const char *Option);
|
void CmdDELT(const char *Option);
|
||||||
void CmdHelp(const char *Option);
|
void CmdGRAB(const char *Option);
|
||||||
void CmdLstc(const char *Option);
|
void CmdHELP(const char *Option);
|
||||||
void CmdLstt(const char *Option);
|
void CmdHITK(const char *Option);
|
||||||
void CmdModc(const char *Option);
|
void CmdLSTC(const char *Option);
|
||||||
void CmdModt(const char *Option);
|
void CmdLSTT(const char *Option);
|
||||||
void CmdMovc(const char *Option);
|
void CmdMODC(const char *Option);
|
||||||
void CmdMovt(const char *Option);
|
void CmdMODT(const char *Option);
|
||||||
void CmdNewc(const char *Option);
|
void CmdMOVC(const char *Option);
|
||||||
void CmdNewt(const char *Option);
|
void CmdMOVT(const char *Option);
|
||||||
void CmdUpdt(const char *Option);
|
void CmdNEWC(const char *Option);
|
||||||
|
void CmdNEWT(const char *Option);
|
||||||
|
void CmdOVLF(const char *Option);
|
||||||
|
void CmdOVLG(const char *Option);
|
||||||
|
void CmdOVLC(const char *Option);
|
||||||
|
void CmdOVLP(const char *Option);
|
||||||
|
void CmdOVLO(const char *Option);
|
||||||
|
void CmdUPDT(const char *Option);
|
||||||
void Execute(char *Cmd);
|
void Execute(char *Cmd);
|
||||||
public:
|
public:
|
||||||
cSVDRP(int Port);
|
cSVDRP(int Port);
|
||||||
|
12
timers.conf
12
timers.conf
@ -1,12 +1,14 @@
|
|||||||
1:15:M------:2128:2205:99:7:Neues:
|
1:15:M------:2128:2205:99:7:Neues:
|
||||||
1:3:-T-----:2013:2125:99:99:SevenDays
|
1:3:-T-----:2013:2125:99:99:SevenDays:
|
||||||
1:10:-T-----:2058:2202:99:10:Quarks:
|
0:10:-T-----:2058:2202:99:10:Quarks:
|
||||||
1:26:-T-----:2255:0005:99:99:UFO:
|
1:26:-T-----:2255:0015:99:99:UFO:
|
||||||
0:3:---T---:2211:2300:99:10:Switch:
|
1:3:---T---:2215:2315:99:10:IngoAppelt:
|
||||||
1:2:----F--:2140:2225:10:10:WWW:
|
1:2:----F--:2140:2225:10:10:WWW:
|
||||||
|
1:1:----F--:2212:2325:99:99:7Tage7Koepfe:
|
||||||
1:11:-----S-:2158:2235:99:99:Computer:
|
1:11:-----S-:2158:2235:99:99:Computer:
|
||||||
1:2:-----S-:2213:2320:99:30:Wochenshow:
|
1:2:-----S-:2213:2320:99:30:Wochenshow:
|
||||||
1:11:------S:2058:2120:99:10:Centauri:
|
1:11:------S:2013:2035:99:10:Centauri:
|
||||||
|
1:14:------S:2158:2235:99:14:MaxUndLisa:
|
||||||
1:15:MTWTF--:1828:1901:10:5:nano:
|
1:15:MTWTF--:1828:1901:10:5:nano:
|
||||||
1:1:-TWTF--:0955:1040:99:99:Ellen:
|
1:1:-TWTF--:0955:1040:99:99:Ellen:
|
||||||
1:1:MTWTF--:1553:1710:99:99:Hammerman:
|
1:1:MTWTF--:1553:1710:99:99:Hammerman:
|
||||||
|
157
tools.c
157
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.14 2000/09/09 12:53:34 kls Exp $
|
* $Id: tools.c 1.19 2000/09/19 17:55:09 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define _GNU_SOURCE
|
#define _GNU_SOURCE
|
||||||
@ -12,31 +12,20 @@
|
|||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#if defined(DEBUG_OSD)
|
||||||
|
#include <ncurses.h>
|
||||||
|
#endif
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#define MaxBuffer 1000
|
#define MaxBuffer 1000
|
||||||
|
|
||||||
int SysLogLevel = 3;
|
int SysLogLevel = 3;
|
||||||
|
|
||||||
bool DataAvailable(int filedes, bool wait)
|
|
||||||
{
|
|
||||||
if (filedes >= 0) {
|
|
||||||
fd_set set;
|
|
||||||
FD_ZERO(&set);
|
|
||||||
FD_SET(filedes, &set);
|
|
||||||
struct timeval timeout;
|
|
||||||
timeout.tv_sec = wait ? 1 : 0;
|
|
||||||
timeout.tv_usec = wait ? 0 : 10000;
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
write(filedes, &c, sizeof(c));
|
write(filedes, &c, sizeof(c));
|
||||||
@ -56,32 +45,12 @@ char readchar(int filedes)
|
|||||||
|
|
||||||
bool readint(int filedes, int &n)
|
bool readint(int filedes, int &n)
|
||||||
{
|
{
|
||||||
return DataAvailable(filedes) && read(filedes, &n, sizeof(n)) == sizeof(n);
|
return cFile::AnyFileReady(filedes, 0) && read(filedes, &n, sizeof(n)) == sizeof(n);
|
||||||
}
|
|
||||||
|
|
||||||
int readstring(int filedes, char *buffer, int size, bool wait = false)
|
|
||||||
{
|
|
||||||
int rbytes = 0;
|
|
||||||
|
|
||||||
while (DataAvailable(filedes, wait)) {
|
|
||||||
int n = read(filedes, buffer + rbytes, size - rbytes);
|
|
||||||
if (n == 0)
|
|
||||||
break; // EOF
|
|
||||||
if (n < 0) {
|
|
||||||
LOG_ERROR;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
rbytes += n;
|
|
||||||
if (rbytes == size)
|
|
||||||
break;
|
|
||||||
wait = false;
|
|
||||||
}
|
|
||||||
return rbytes;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void purge(int filedes)
|
void purge(int filedes)
|
||||||
{
|
{
|
||||||
while (DataAvailable(filedes))
|
while (cFile::AnyFileReady(filedes, 0))
|
||||||
readchar(filedes);
|
readchar(filedes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -153,6 +122,14 @@ bool isnumber(const char *s)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *AddDirectory(const char *DirName, const char *FileName)
|
||||||
|
{
|
||||||
|
static char *buf = NULL;
|
||||||
|
delete buf;
|
||||||
|
asprintf(&buf, "%s/%s", DirName && *DirName ? DirName : ".", FileName);
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
#define DFCMD "df -m %s"
|
#define DFCMD "df -m %s"
|
||||||
|
|
||||||
uint FreeDiskSpaceMB(const char *Directory)
|
uint FreeDiskSpaceMB(const char *Directory)
|
||||||
@ -313,6 +290,110 @@ void KillProcess(pid_t pid, int Timeout)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --- cFile -----------------------------------------------------------------
|
||||||
|
|
||||||
|
bool cFile::files[FD_SETSIZE] = { false };
|
||||||
|
int cFile::maxFiles = 0;
|
||||||
|
|
||||||
|
cFile::cFile(void)
|
||||||
|
{
|
||||||
|
f = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
cFile::~cFile()
|
||||||
|
{
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool cFile::Open(const char *FileName, int Flags, mode_t Mode)
|
||||||
|
{
|
||||||
|
if (!IsOpen())
|
||||||
|
return Open(open(FileName, Flags, Mode));
|
||||||
|
esyslog(LOG_ERR, "ERROR: attempt to re-open %s", FileName);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool cFile::Open(int FileDes)
|
||||||
|
{
|
||||||
|
if (FileDes >= 0) {
|
||||||
|
if (!IsOpen()) {
|
||||||
|
f = FileDes;
|
||||||
|
if (f >= 0) {
|
||||||
|
if (f < FD_SETSIZE) {
|
||||||
|
if (f >= maxFiles)
|
||||||
|
maxFiles = f + 1;
|
||||||
|
if (!files[f])
|
||||||
|
files[f] = true;
|
||||||
|
else
|
||||||
|
esyslog(LOG_ERR, "ERROR: file descriptor %d already in files[]", f);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
esyslog(LOG_ERR, "ERROR: file descriptor %d is larger than FD_SETSIZE (%d)", f, FD_SETSIZE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
esyslog(LOG_ERR, "ERROR: attempt to re-open file descriptor %d", FileDes);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cFile::Close(void)
|
||||||
|
{
|
||||||
|
if (f >= 0) {
|
||||||
|
close(f);
|
||||||
|
files[f] = false;
|
||||||
|
f = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int cFile::ReadString(char *Buffer, int Size)
|
||||||
|
{
|
||||||
|
int rbytes = 0;
|
||||||
|
bool wait = true;
|
||||||
|
|
||||||
|
while (Ready(wait)) {
|
||||||
|
int n = read(f, Buffer + rbytes, 1);
|
||||||
|
if (n == 0)
|
||||||
|
break; // EOF
|
||||||
|
if (n < 0) {
|
||||||
|
LOG_ERROR;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
rbytes += n;
|
||||||
|
if (rbytes == Size || Buffer[rbytes - 1] == '\n')
|
||||||
|
break;
|
||||||
|
wait = false;
|
||||||
|
}
|
||||||
|
return rbytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool cFile::Ready(bool Wait)
|
||||||
|
{
|
||||||
|
return f >= 0 && AnyFileReady(f, Wait ? 1000 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool cFile::AnyFileReady(int FileDes, int TimeoutMs)
|
||||||
|
{
|
||||||
|
#ifdef DEBUG_OSD
|
||||||
|
refresh();
|
||||||
|
#endif
|
||||||
|
fd_set set;
|
||||||
|
FD_ZERO(&set);
|
||||||
|
for (int i = 0; i < maxFiles; i++) {
|
||||||
|
if (files[i])
|
||||||
|
FD_SET(i, &set);
|
||||||
|
}
|
||||||
|
if (0 <= FileDes && FileDes < FD_SETSIZE && !files[FileDes])
|
||||||
|
FD_SET(FileDes, &set); // in case we come in with an arbitrary descriptor
|
||||||
|
if (TimeoutMs == 0)
|
||||||
|
TimeoutMs = 10; // load gets too heavy with 0
|
||||||
|
struct timeval timeout;
|
||||||
|
timeout.tv_sec = TimeoutMs / 1000;
|
||||||
|
timeout.tv_usec = (TimeoutMs % 1000) * 1000;
|
||||||
|
return select(FD_SETSIZE, &set, NULL, NULL, &timeout) > 0 && (FileDes < 0 || FD_ISSET(FileDes, &set));
|
||||||
|
}
|
||||||
|
|
||||||
// --- cListObject -----------------------------------------------------------
|
// --- cListObject -----------------------------------------------------------
|
||||||
|
|
||||||
cListObject::cListObject(void)
|
cListObject::cListObject(void)
|
||||||
|
26
tools.h
26
tools.h
@ -4,16 +4,17 @@
|
|||||||
* 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.13 2000/09/09 12:53:10 kls Exp $
|
* $Id: tools.h 1.15 2000/09/17 07:58:19 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __TOOLS_H
|
#ifndef __TOOLS_H
|
||||||
#define __TOOLS_H
|
#define __TOOLS_H
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <syslog.h>
|
#include <syslog.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
extern int SysLogLevel;
|
extern int SysLogLevel;
|
||||||
@ -30,12 +31,10 @@ extern int SysLogLevel;
|
|||||||
|
|
||||||
#define DELETENULL(p) (delete (p), p = NULL)
|
#define DELETENULL(p) (delete (p), p = NULL)
|
||||||
|
|
||||||
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);
|
||||||
bool readint(int filedes, int &n);
|
bool readint(int filedes, int &n);
|
||||||
int readstring(int filedes, char *buffer, int size, bool wait = false);
|
|
||||||
void purge(int filedes);
|
void purge(int filedes);
|
||||||
char *readline(FILE *f);
|
char *readline(FILE *f);
|
||||||
char *strn0cpy(char *dest, const char *src, size_t n);
|
char *strn0cpy(char *dest, const char *src, size_t n);
|
||||||
@ -44,6 +43,7 @@ char *skipspace(char *s);
|
|||||||
int time_ms(void);
|
int time_ms(void);
|
||||||
void delay_ms(int ms);
|
void delay_ms(int ms);
|
||||||
bool isnumber(const char *s);
|
bool isnumber(const char *s);
|
||||||
|
const char *AddDirectory(const char *DirName, const char *FileName);
|
||||||
uint FreeDiskSpaceMB(const char *Directory);
|
uint FreeDiskSpaceMB(const char *Directory);
|
||||||
bool DirectoryOk(const char *DirName, bool LogErrors = false);
|
bool DirectoryOk(const char *DirName, bool LogErrors = false);
|
||||||
bool MakeDirs(const char *FileName, bool IsDirectory = false);
|
bool MakeDirs(const char *FileName, bool IsDirectory = false);
|
||||||
@ -51,6 +51,24 @@ bool RemoveFileOrDir(const char *FileName, bool FollowSymlinks = false);
|
|||||||
bool CheckProcess(pid_t pid);
|
bool CheckProcess(pid_t pid);
|
||||||
void KillProcess(pid_t pid, int Timeout = MAXPROCESSTIMEOUT);
|
void KillProcess(pid_t pid, int Timeout = MAXPROCESSTIMEOUT);
|
||||||
|
|
||||||
|
class cFile {
|
||||||
|
private:
|
||||||
|
static bool files[];
|
||||||
|
static int maxFiles;
|
||||||
|
int f;
|
||||||
|
public:
|
||||||
|
cFile(void);
|
||||||
|
~cFile();
|
||||||
|
operator int () { return f; }
|
||||||
|
bool Open(const char *FileName, int Flags, mode_t Mode = S_IRUSR | S_IWUSR | S_IRGRP);
|
||||||
|
bool Open(int FileDes);
|
||||||
|
void Close(void);
|
||||||
|
bool IsOpen(void) { return f >= 0; }
|
||||||
|
int ReadString(char *Buffer, int Size);
|
||||||
|
bool Ready(bool Wait = true);
|
||||||
|
static bool AnyFileReady(int FileDes = -1, int TimeoutMs = 1000);
|
||||||
|
};
|
||||||
|
|
||||||
class cListObject {
|
class cListObject {
|
||||||
private:
|
private:
|
||||||
cListObject *prev, *next;
|
cListObject *prev, *next;
|
||||||
|
44
vdr.c
44
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.30 2000/09/10 14:33:09 kls Exp $
|
* $Id: vdr.c 1.35 2000/09/20 16:45:01 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
@ -34,7 +34,6 @@
|
|||||||
#include "interface.h"
|
#include "interface.h"
|
||||||
#include "menu.h"
|
#include "menu.h"
|
||||||
#include "recording.h"
|
#include "recording.h"
|
||||||
#include "svdrp.h"
|
|
||||||
#include "tools.h"
|
#include "tools.h"
|
||||||
#include "videodir.h"
|
#include "videodir.h"
|
||||||
|
|
||||||
@ -46,9 +45,11 @@
|
|||||||
|
|
||||||
static int Interrupted = 0;
|
static int Interrupted = 0;
|
||||||
|
|
||||||
void SignalHandler(int signum)
|
static void SignalHandler(int signum)
|
||||||
{
|
{
|
||||||
Interrupted = signum;
|
if (signum != SIGPIPE)
|
||||||
|
Interrupted = signum;
|
||||||
|
signal(signum, SignalHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
@ -58,9 +59,11 @@ int main(int argc, char *argv[])
|
|||||||
#define DEFAULTSVDRPPORT 2001
|
#define DEFAULTSVDRPPORT 2001
|
||||||
|
|
||||||
int SVDRPport = DEFAULTSVDRPPORT;
|
int SVDRPport = DEFAULTSVDRPPORT;
|
||||||
|
const char *ConfigDirectory = NULL;
|
||||||
bool DaemonMode = false;
|
bool DaemonMode = false;
|
||||||
|
|
||||||
static struct option long_options[] = {
|
static struct option long_options[] = {
|
||||||
|
{ "config", required_argument, NULL, 'c' },
|
||||||
{ "daemon", no_argument, NULL, 'd' },
|
{ "daemon", no_argument, NULL, 'd' },
|
||||||
{ "help", no_argument, NULL, 'h' },
|
{ "help", no_argument, NULL, 'h' },
|
||||||
{ "log", required_argument, NULL, 'l' },
|
{ "log", required_argument, NULL, 'l' },
|
||||||
@ -71,10 +74,14 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
int c;
|
int c;
|
||||||
int option_index = 0;
|
int option_index = 0;
|
||||||
while ((c = getopt_long(argc, argv, "dhl:p:v:", long_options, &option_index)) != -1) {
|
while ((c = getopt_long(argc, argv, "c:dhl:p:v:", long_options, &option_index)) != -1) {
|
||||||
switch (c) {
|
switch (c) {
|
||||||
|
case 'c': ConfigDirectory = optarg;
|
||||||
|
break;
|
||||||
case 'd': DaemonMode = true; break;
|
case 'd': DaemonMode = true; break;
|
||||||
case 'h': printf("Usage: vdr [OPTION]\n\n"
|
case 'h': printf("Usage: vdr [OPTION]\n\n" // for easier orientation, this is column 80|
|
||||||
|
" -c DIR, --config=DIR read config files from DIR (default is to read them\n"
|
||||||
|
" from the video directory)\n"
|
||||||
" -h, --help display this help and exit\n"
|
" -h, --help display this help and exit\n"
|
||||||
" -d, --daemon run in daemon mode\n"
|
" -d, --daemon run in daemon mode\n"
|
||||||
" -l LEVEL, --log=LEVEL set log level (default: 3)\n"
|
" -l LEVEL, --log=LEVEL set log level (default: 3)\n"
|
||||||
@ -108,6 +115,8 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'v': VideoDirectory = optarg;
|
case 'v': VideoDirectory = optarg;
|
||||||
|
while (optarg && *optarg && optarg[strlen(optarg) - 1] == '/')
|
||||||
|
optarg[strlen(optarg) - 1] = 0;
|
||||||
break;
|
break;
|
||||||
default: abort();
|
default: abort();
|
||||||
}
|
}
|
||||||
@ -128,7 +137,7 @@ int main(int argc, char *argv[])
|
|||||||
// Daemon mode:
|
// Daemon mode:
|
||||||
|
|
||||||
if (DaemonMode) {
|
if (DaemonMode) {
|
||||||
#ifndef DEBUG_OSD
|
#if !defined(DEBUG_OSD) && !defined(REMOTE_KBD)
|
||||||
pid_t pid = fork();
|
pid_t pid = fork();
|
||||||
if (pid < 0) {
|
if (pid < 0) {
|
||||||
fprintf(stderr, "%s\n", strerror(errno));
|
fprintf(stderr, "%s\n", strerror(errno));
|
||||||
@ -141,7 +150,7 @@ int main(int argc, char *argv[])
|
|||||||
fclose(stdout);
|
fclose(stdout);
|
||||||
fclose(stderr);
|
fclose(stderr);
|
||||||
#else
|
#else
|
||||||
fprintf(stderr, "vdr: can't run in daemon mode with DEBUG_OSD on!\n");
|
fprintf(stderr, "vdr: can't run in daemon mode with DEBUG_OSD or REMOTE_KBD on!\n");
|
||||||
abort();
|
abort();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -154,16 +163,19 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
// Configuration data:
|
// Configuration data:
|
||||||
|
|
||||||
Setup.Load("setup.conf");
|
if (!ConfigDirectory)
|
||||||
Channels.Load("channels.conf");
|
ConfigDirectory = VideoDirectory;
|
||||||
Timers.Load("timers.conf");
|
|
||||||
|
Setup.Load(AddDirectory(ConfigDirectory, "setup.conf"));
|
||||||
|
Channels.Load(AddDirectory(ConfigDirectory, "channels.conf"));
|
||||||
|
Timers.Load(AddDirectory(ConfigDirectory, "timers.conf"));
|
||||||
#ifdef REMOTE_LIRC
|
#ifdef REMOTE_LIRC
|
||||||
Keys.SetDummyValues();
|
Keys.SetDummyValues();
|
||||||
#else
|
#else
|
||||||
if (!Keys.Load(KEYS_CONF))
|
if (!Keys.Load(AddDirectory(ConfigDirectory, KEYS_CONF)))
|
||||||
Interface.LearnKeys();
|
Interface.LearnKeys();
|
||||||
#endif
|
#endif
|
||||||
Interface.Init();
|
Interface.Init(SVDRPport);
|
||||||
|
|
||||||
cDvbApi::SetPrimaryDvbApi(Setup.PrimaryDVB);
|
cDvbApi::SetPrimaryDvbApi(Setup.PrimaryDVB);
|
||||||
|
|
||||||
@ -174,10 +186,10 @@ int main(int argc, char *argv[])
|
|||||||
if (signal(SIGHUP, SignalHandler) == SIG_IGN) signal(SIGHUP, SIG_IGN);
|
if (signal(SIGHUP, SignalHandler) == SIG_IGN) signal(SIGHUP, SIG_IGN);
|
||||||
if (signal(SIGINT, SignalHandler) == SIG_IGN) signal(SIGINT, SIG_IGN);
|
if (signal(SIGINT, SignalHandler) == SIG_IGN) signal(SIGINT, SIG_IGN);
|
||||||
if (signal(SIGTERM, SignalHandler) == SIG_IGN) signal(SIGTERM, SIG_IGN);
|
if (signal(SIGTERM, SignalHandler) == SIG_IGN) signal(SIGTERM, SIG_IGN);
|
||||||
|
if (signal(SIGPIPE, SignalHandler) == SIG_IGN) signal(SIGPIPE, SIG_IGN);
|
||||||
|
|
||||||
// Main program loop:
|
// Main program loop:
|
||||||
|
|
||||||
cSVDRP *SVDRP = SVDRPport ? new cSVDRP(SVDRPport) : NULL;
|
|
||||||
cOsdBase *Menu = NULL;
|
cOsdBase *Menu = NULL;
|
||||||
cReplayControl *ReplayControl = NULL;
|
cReplayControl *ReplayControl = NULL;
|
||||||
int LastChannel = -1;
|
int LastChannel = -1;
|
||||||
@ -267,13 +279,11 @@ int main(int argc, char *argv[])
|
|||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (SVDRP)
|
|
||||||
SVDRP->Process();//TODO lock menu vs. SVDRP?
|
|
||||||
}
|
}
|
||||||
isyslog(LOG_INFO, "caught signal %d", Interrupted);
|
isyslog(LOG_INFO, "caught signal %d", Interrupted);
|
||||||
delete Menu;
|
delete Menu;
|
||||||
delete ReplayControl;
|
delete ReplayControl;
|
||||||
delete SVDRP;
|
Interface.Cleanup();
|
||||||
cDvbApi::Cleanup();
|
cDvbApi::Cleanup();
|
||||||
isyslog(LOG_INFO, "exiting");
|
isyslog(LOG_INFO, "exiting");
|
||||||
if (SysLogLevel > 0)
|
if (SysLogLevel > 0)
|
||||||
|
@ -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: videodir.c 1.1 2000/07/29 15:21:42 kls Exp $
|
* $Id: videodir.c 1.2 2000/09/15 13:23:47 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "videodir.h"
|
#include "videodir.h"
|
||||||
@ -137,7 +137,7 @@ int OpenVideoFile(const char *FileName, int Flags)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int Result = open(ActualFileName, Flags, S_IRUSR | S_IWUSR);
|
int Result = open(ActualFileName, Flags, S_IRUSR | S_IWUSR | S_IRGRP);
|
||||||
if (ActualFileName != FileName)
|
if (ActualFileName != FileName)
|
||||||
delete ActualFileName;
|
delete ActualFileName;
|
||||||
return Result;
|
return Result;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user