mirror of
https://github.com/vdr-projects/vdr.git
synced 2025-03-01 10:50:46 +00:00
Version 0.67
- The EIT information is now gathered in a separate thread. - The sytem time can now be synchronized to the time broadcast in the DVB data stream. This can be enabled in the "Setup" menu by setting "SetSystemTime" to 1. Note that this works only if VDR is running under a user id that has permisson to set the system time. - The new item "Schedule" in the "Main" menu opens VDR's EPG (thanks to Robert Schneider). See the MANUAL file for a detailed description. - The new setup parameters MarginStart and MarginStop define how long (in minutes) before the official start time of a broadcast VDR shall begin recording, and how long after the official end time it shall stop recording. These are used when a recording is programmed from the "Schedules" menu. - The delay value in the dvb.c.071.diff patch to the driver has been increased to '3', because on some systems the OSD was not displayed correctly. If you are running an already patched version 0.71 driver and encounter problems with the OSD, please make sure the parameter in the ddelay call is '3', not '2'. - Fixed initializing the RCU remote control code (didn't work after switching on the system). - Problematic characters in recording names (which can come from timers that are programmed via the "Schedules" menu) are now replaced by suitable substitutes.
This commit is contained in:
parent
a379eb714f
commit
a69b3211dc
2
BUGS
2
BUGS
@ -4,3 +4,5 @@ Video Disk Recorder - Known Bugs
|
|||||||
* Sometimes the picture "jumps" as if a frame is skipped.
|
* Sometimes the picture "jumps" as if a frame is skipped.
|
||||||
Presumably this is a problem in the card driver or firmware?
|
Presumably this is a problem in the card driver or firmware?
|
||||||
|
|
||||||
|
* The first picture captured with the GRAB command in SVDRP
|
||||||
|
is empty. Also, these pictures appear to be too dark.
|
||||||
|
@ -26,6 +26,7 @@ Guido Fiala <gfiala@s.netic.de>
|
|||||||
|
|
||||||
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
|
||||||
|
for extending EIT support to implement a complete EPG
|
||||||
|
|
||||||
Niels de Carpentier <niels@casema.net>
|
Niels de Carpentier <niels@casema.net>
|
||||||
for adding a workaround for a driver timing problem in cDvbApi::Cmd()
|
for adding a workaround for a driver timing problem in cDvbApi::Cmd()
|
||||||
|
24
HISTORY
24
HISTORY
@ -241,3 +241,27 @@ Video Disk Recorder Revision History
|
|||||||
- The "Blue" button in the "Main" menu can now be used to "Resume" a previously
|
- The "Blue" button in the "Main" menu can now be used to "Resume" a previously
|
||||||
stopped replay session (suggested by Martin Hammerschmid).
|
stopped replay session (suggested by Martin Hammerschmid).
|
||||||
- The low and high LNB frequencies can now be changed in the "Setup" menu.
|
- The low and high LNB frequencies can now be changed in the "Setup" menu.
|
||||||
|
|
||||||
|
2000-11-01: Version 0.67
|
||||||
|
|
||||||
|
- The EIT information is now gathered in a separate thread.
|
||||||
|
- The sytem time can now be synchronized to the time broadcast in the DVB data
|
||||||
|
stream. This can be enabled in the "Setup" menu by setting "SetSystemTime" to
|
||||||
|
1. Note that this works only if VDR is running under a user id that has
|
||||||
|
permisson to set the system time.
|
||||||
|
- The new item "Schedule" in the "Main" menu opens VDR's EPG (thanks to Robert
|
||||||
|
Schneider). See the MANUAL file for a detailed description.
|
||||||
|
- The new setup parameters MarginStart and MarginStop define how long (in
|
||||||
|
minutes) before the official start time of a broadcast VDR shall begin
|
||||||
|
recording, and how long after the official end time it shall stop recording.
|
||||||
|
These are used when a recording is programmed from the "Schedules" menu.
|
||||||
|
- The delay value in the dvb.c.071.diff patch to the driver has been increased
|
||||||
|
to '3', because on some systems the OSD was not displayed correctly. If you
|
||||||
|
are running an already patched version 0.71 driver and encounter problems
|
||||||
|
with the OSD, please make sure the parameter in the ddelay call is '3', not
|
||||||
|
'2'.
|
||||||
|
- Fixed initializing the RCU remote control code (didn't work after switching
|
||||||
|
on the system).
|
||||||
|
- Problematic characters in recording names (which can come from timers that
|
||||||
|
are programmed via the "Schedules" menu) are now replaced by suitable
|
||||||
|
substitutes.
|
||||||
|
59
MANUAL
59
MANUAL
@ -53,20 +53,60 @@ Video Disk Recorder User's Manual
|
|||||||
At any point in the menu system, pressing the "Menu" key again will
|
At any point in the menu system, pressing the "Menu" key again will
|
||||||
immediately leave the menu system (discarding any pending changes).
|
immediately leave the menu system (discarding any pending changes).
|
||||||
|
|
||||||
|
* The "Schedule" Menu
|
||||||
|
|
||||||
|
The "Schedule" menu implements VDR's "Electronic Program Guide" (EPG).
|
||||||
|
|
||||||
|
Select "Schedule" from the "Main" menu and you get a list of all upcoming
|
||||||
|
broadcasts on the current channel.
|
||||||
|
|
||||||
|
"Up" and "Down" can be used to scroll through this list, and pressing "Ok"
|
||||||
|
displays detailed information about the selected programme. Pressing "Ok"
|
||||||
|
again (or pressing "Back") gets you back into the "Schedule" menu.
|
||||||
|
|
||||||
|
From the "Schedule" menu, the "Green" button opens the "What's on now?"
|
||||||
|
menu, which displays all programmes that are currently running on all
|
||||||
|
channels that broadcast their programme information on the current
|
||||||
|
transponder, or from channels that have been current lately (VDR stores
|
||||||
|
all information it gathers in an internal list). The more channels you
|
||||||
|
have been switching through lately, the longer this list will be.
|
||||||
|
The "Yellow" button opens the "What's on next?" menu, which lists all
|
||||||
|
programmes that will start next on all channels.
|
||||||
|
|
||||||
|
Inside the "What's on now/next?" menus the "Green" button toggles between
|
||||||
|
the "Now" and "Next" display, and the "Yellow" button gets you back to the
|
||||||
|
"Schedule" menu of the current channel.
|
||||||
|
|
||||||
|
The "Red" button allows you to instantly program a timer to record the
|
||||||
|
selected programme. You will get into the "Edit Timer" menu in which
|
||||||
|
everything has already been filled in, and you can make any modifications
|
||||||
|
you may want to apply. Note that the Start and Stop time are offset by the
|
||||||
|
MarginStart and MarginStop parameters (see Setup) in order to make sure the
|
||||||
|
entire programme is recorded in case it doesn't exactly adhere to its
|
||||||
|
published start/stop times. Of course, no guarantee can be given that the
|
||||||
|
default margin values will be sufficient, so in case this recording is
|
||||||
|
really important you may want to add an extra margin ;-)
|
||||||
|
|
||||||
|
The "Blue" button can be pressed to switch to the channel with the selected
|
||||||
|
programme.
|
||||||
|
|
||||||
* Selecting a Channel
|
* Selecting a Channel
|
||||||
|
|
||||||
There are three ways to select a channel:
|
There are four ways to select a channel:
|
||||||
|
|
||||||
1. With no On Screen Menu displayed press the "Up" or "Down" key to switch
|
1. With no On Screen Menu displayed press the "Up" or "Down" key to switch
|
||||||
to the next higher or lower channel.
|
to the next higher or lower channel.
|
||||||
2. Press the "Menu" button to bring up the On Screen Menu, select "Channels"
|
2. Press the "Menu" button to bring up the On Screen Menu, select "Channels"
|
||||||
and browse through the list with the "Up" and "Down" key; to switch to the
|
and browse through the list with the "Up" and "Down" key; to switch to the
|
||||||
selected channel press "Ok".
|
selected channel press "Ok".
|
||||||
2. Directly type in the channel number with the numeric keys ('0'..'9');
|
3. Directly type in the channel number with the numeric keys ('0'..'9');
|
||||||
if no key is pressed for about half a second, the digits collected so
|
if no key is pressed for about half a second, the digits collected so
|
||||||
far will define the channel number.
|
far will define the channel number.
|
||||||
|
4. From the "Now", "Next" and "Event" menus (accessible through the "Schedule"
|
||||||
|
menu) by pressing the "Blue" button.
|
||||||
|
|
||||||
Pressing the '0' key toggles between the current and the previous channel.
|
Pressing the '0' key in normal viewing mode toggles between the current and
|
||||||
|
the previous channel.
|
||||||
|
|
||||||
After switching to a different channel the channel number and name, as well
|
After switching to a different channel the channel number and name, as well
|
||||||
as the current time are displayed at the top of the screen. If available, the
|
as the current time are displayed at the top of the screen. If available, the
|
||||||
@ -178,6 +218,9 @@ Video Disk Recorder User's Manual
|
|||||||
If this field is left blank, the channel name will be used to form
|
If this field is left blank, the channel name will be used to form
|
||||||
the name of the recording.
|
the name of the recording.
|
||||||
|
|
||||||
|
A timer can also be programmed by pressing the "Red" button on the "Schedule",
|
||||||
|
"Now", "Next" or "Event" menus.
|
||||||
|
|
||||||
* Parameters in the "Setup" menu
|
* Parameters in the "Setup" menu
|
||||||
|
|
||||||
Select "Setup" from the "Main" menu to enter the setup menu. From there you can
|
Select "Setup" from the "Main" menu to enter the setup menu. From there you can
|
||||||
@ -216,3 +259,13 @@ Video Disk Recorder User's Manual
|
|||||||
|
|
||||||
LnbFrequLo = 9750 The low and high LNB frequencies (in MHz)
|
LnbFrequLo = 9750 The low and high LNB frequencies (in MHz)
|
||||||
LnbFrequHi = 10600
|
LnbFrequHi = 10600
|
||||||
|
|
||||||
|
SetSystemTime = 0 Defines whether the system time will be set according to
|
||||||
|
the time received from the DVB data stream.
|
||||||
|
0 = system time will not be set
|
||||||
|
1 = system time wil be set
|
||||||
|
Note that this works only if VDR is running under a user
|
||||||
|
id that has permisson to set the system time.
|
||||||
|
MarginStart = 2 Defines how many minutes before the official start time
|
||||||
|
MarginStop = 10 of a broadcast VDR shall start recording, and how long
|
||||||
|
after the official end time it shall stop recording.
|
||||||
|
20
Makefile
20
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.13 2000/10/07 16:24:08 kls Exp $
|
# $Id: Makefile 1.14 2000/10/28 16:24:16 kls Exp $
|
||||||
|
|
||||||
DVBDIR = ../DVB
|
DVBDIR = ../DVB
|
||||||
|
|
||||||
@ -35,20 +35,20 @@ font: genfontfile fontosd.c
|
|||||||
|
|
||||||
# Dependencies:
|
# Dependencies:
|
||||||
|
|
||||||
config.o : config.c config.h dvbapi.h dvbosd.h eit.h font.h interface.h svdrp.h tools.h
|
config.o : config.c config.h dvbapi.h dvbosd.h eit.h font.h interface.h remote.h svdrp.h thread.h tools.h
|
||||||
dvbapi.o : dvbapi.c config.h dvbapi.h dvbosd.h font.h interface.h svdrp.h tools.h videodir.h
|
dvbapi.o : dvbapi.c config.h dvbapi.h dvbosd.h eit.h font.h interface.h remote.h svdrp.h thread.h tools.h videodir.h
|
||||||
dvbosd.o : dvbosd.c dvbosd.h font.h tools.h
|
dvbosd.o : dvbosd.c dvbosd.h font.h tools.h
|
||||||
eit.o : eit.c eit.h tools.h
|
eit.o : eit.c eit.h thread.h tools.h
|
||||||
font.o : font.c font.h fontosd.c tools.h
|
font.o : font.c font.h fontosd.c tools.h
|
||||||
interface.o: interface.c config.h dvbapi.h dvbosd.h eit.h font.h interface.h remote.h svdrp.h thread.h tools.h
|
interface.o: interface.c config.h dvbapi.h dvbosd.h eit.h font.h interface.h remote.h svdrp.h thread.h tools.h
|
||||||
menu.o : menu.c config.h dvbapi.h dvbosd.h font.h interface.h menu.h osd.h recording.h svdrp.h tools.h
|
menu.o : menu.c config.h dvbapi.h dvbosd.h eit.h font.h interface.h menu.h osd.h recording.h remote.h svdrp.h thread.h tools.h
|
||||||
osd.o : osd.c config.h dvbapi.h dvbosd.h font.h interface.h osd.h svdrp.h tools.h
|
osd.o : osd.c config.h dvbapi.h dvbosd.h eit.h font.h interface.h osd.h remote.h svdrp.h thread.h tools.h
|
||||||
recording.o: recording.c config.h dvbapi.h dvbosd.h font.h interface.h recording.h svdrp.h tools.h videodir.h
|
recording.o: recording.c config.h dvbapi.h dvbosd.h eit.h font.h interface.h recording.h remote.h svdrp.h thread.h tools.h videodir.h
|
||||||
remote.o : remote.c config.h dvbapi.h dvbosd.h font.h remote.h thread.h tools.h
|
remote.o : remote.c config.h dvbapi.h dvbosd.h eit.h font.h remote.h thread.h tools.h
|
||||||
svdrp.o : svdrp.c config.h dvbapi.h dvbosd.h font.h interface.h svdrp.h tools.h
|
svdrp.o : svdrp.c config.h dvbapi.h dvbosd.h eit.h font.h interface.h remote.h svdrp.h thread.h tools.h
|
||||||
thread.o : thread.c thread.h
|
thread.o : thread.c thread.h
|
||||||
tools.o : tools.c tools.h
|
tools.o : tools.c tools.h
|
||||||
vdr.o : vdr.c config.h dvbapi.h dvbosd.h font.h interface.h menu.h osd.h recording.h svdrp.h tools.h videodir.h
|
vdr.o : vdr.c config.h dvbapi.h dvbosd.h eit.h font.h interface.h menu.h osd.h recording.h remote.h svdrp.h thread.h tools.h videodir.h
|
||||||
videodir.o : videodir.c tools.h videodir.h
|
videodir.o : videodir.c tools.h videodir.h
|
||||||
|
|
||||||
# The main program:
|
# The main program:
|
||||||
|
@ -6,6 +6,7 @@ ARD:11837:h:1:27500:101:102:0:28106
|
|||||||
BR3:11837:h:1:27500:201:202:0:28107
|
BR3:11837:h:1:27500:201:202:0:28107
|
||||||
Hessen-3:11837:h:1:27500:301:302:0:28108
|
Hessen-3:11837:h:1:27500:301:302:0:28108
|
||||||
N3:12110:h:1:27500:2401:2402:0:28224
|
N3:12110:h:1:27500:2401:2402:0:28224
|
||||||
|
:Group 1
|
||||||
SR3:11837:h:1:27500:501:502:0:28110
|
SR3:11837:h:1:27500:501:502:0:28110
|
||||||
WDR:11837:h:1:27500:601:602:0:28111
|
WDR:11837:h:1:27500:601:602:0:28111
|
||||||
BR-alpha:11837:h:1:27500:701:702:0:28112
|
BR-alpha:11837:h:1:27500:701:702:0:28112
|
||||||
@ -15,9 +16,11 @@ ZDF:11954:h:1:27500:110:120:0:28006
|
|||||||
3sat:11954:h:1:27500:210:220:0:28007
|
3sat:11954:h:1:27500:210:220:0:28007
|
||||||
KiKa:11954:h:1:27500:310:320:0:28008
|
KiKa:11954:h:1:27500:310:320:0:28008
|
||||||
arte:11836:h:1:27500:401:402:0:28109
|
arte:11836:h:1:27500:401:402:0:28109
|
||||||
|
:Group 2
|
||||||
Eurosport:11954:h:1:27500:410:420:0:28009
|
Eurosport:11954:h:1:27500:410:420:0:28009
|
||||||
ORF Sat:11954:h:1:27500:506:507:0:28010
|
ORF Sat:11954:h:1:27500:506:507:0:28010
|
||||||
ZDF.info:11954:h:1:27500:610:620:0:28011
|
ZDF.info:11954:h:1:27500:610:620:0:28011
|
||||||
|
:Group 3
|
||||||
CNN:12168:v:1:27500:165:100:0:0
|
CNN:12168:v:1:27500:165:100:0:0
|
||||||
Super RTL:12188:h:1:27500:165:120:0:12040
|
Super RTL:12188:h:1:27500:165:120:0:12040
|
||||||
VOX:12188:h:1:27500:167:136:0:12060
|
VOX:12188:h:1:27500:167:136:0:12060
|
||||||
|
100
config.c
100
config.c
@ -4,18 +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: config.c 1.26 2000/10/08 16:10:40 kls Exp $
|
* $Id: config.c 1.29 2000/11/01 18:22:43 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "dvbapi.h"
|
#include "dvbapi.h"
|
||||||
#include "eit.h"
|
|
||||||
#include "interface.h"
|
#include "interface.h"
|
||||||
|
|
||||||
extern cEIT EIT;
|
|
||||||
|
|
||||||
// -- cKeys ------------------------------------------------------------------
|
// -- cKeys ------------------------------------------------------------------
|
||||||
|
|
||||||
tKey keyTable[] = { // "Up" and "Down" must be the first two keys!
|
tKey keyTable[] = { // "Up" and "Down" must be the first two keys!
|
||||||
@ -267,15 +264,14 @@ bool cChannel::Switch(cDvbApi *DvbApi)
|
|||||||
isyslog(LOG_INFO, "switching to channel %d", number);
|
isyslog(LOG_INFO, "switching to channel %d", number);
|
||||||
CurrentChannel = number;
|
CurrentChannel = number;
|
||||||
for (int i = 3; i--;) {
|
for (int i = 3; i--;) {
|
||||||
if (DvbApi->SetChannel(frequency, polarization, diseqc, srate, vpid, apid, ca, pnr)) {
|
if (DvbApi->SetChannel(frequency, polarization, diseqc, srate, vpid, apid, ca, pnr))
|
||||||
EIT.SetProgramNumber(pnr);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
esyslog(LOG_ERR, "retrying");
|
esyslog(LOG_ERR, "retrying");
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
Interface->Info(DvbApi->Recording() ? "Channel locked (recording)!" : name);
|
if (DvbApi->Recording())
|
||||||
|
Interface->Info("Channel locked (recording)!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -306,6 +302,47 @@ cTimer::cTimer(bool Instant)
|
|||||||
snprintf(file, sizeof(file), "%s%s", Setup.MarkInstantRecord ? "@" : "", ch->name);
|
snprintf(file, sizeof(file), "%s%s", Setup.MarkInstantRecord ? "@" : "", ch->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cTimer::cTimer(const cEventInfo *EventInfo)
|
||||||
|
{
|
||||||
|
startTime = stopTime = 0;
|
||||||
|
recording = false;
|
||||||
|
active = true;
|
||||||
|
cChannel *ch = Channels.GetByServiceID(EventInfo->GetServiceID());
|
||||||
|
channel = ch ? ch->number : 0;
|
||||||
|
time_t tstart = EventInfo->GetTime();
|
||||||
|
time_t tstop = tstart + EventInfo->GetDuration() + Setup.MarginStop * 60;
|
||||||
|
tstart -= Setup.MarginStart * 60;
|
||||||
|
struct tm *time = localtime(&tstart);
|
||||||
|
day = time->tm_mday;
|
||||||
|
start = time->tm_hour * 100 + time->tm_min;
|
||||||
|
time = localtime(&tstop);
|
||||||
|
stop = time->tm_hour * 100 + time->tm_min;
|
||||||
|
if (stop >= 2400)
|
||||||
|
stop -= 2400;
|
||||||
|
priority = 99;
|
||||||
|
lifetime = 99;
|
||||||
|
*file = 0;
|
||||||
|
const char *Title = EventInfo->GetTitle();
|
||||||
|
if (!isempty(Title))
|
||||||
|
strn0cpy(file, EventInfo->GetTitle(), sizeof(file));
|
||||||
|
summary = NULL;
|
||||||
|
const char *Subtitle = EventInfo->GetSubtitle();
|
||||||
|
if (isempty(Subtitle))
|
||||||
|
Subtitle = "";
|
||||||
|
const char *Summary = EventInfo->GetExtendedDescription();
|
||||||
|
if (isempty(Summary))
|
||||||
|
Summary = "";
|
||||||
|
if (*Subtitle || *Summary) {
|
||||||
|
asprintf(&summary, "%s%s%s", Subtitle, (*Subtitle && *Summary) ? "\n\n" : "", Summary);
|
||||||
|
char *p = summary;
|
||||||
|
while (*p) {
|
||||||
|
if (*p == '\n')
|
||||||
|
*p = '|';
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
cTimer::~cTimer()
|
cTimer::~cTimer()
|
||||||
{
|
{
|
||||||
delete summary;
|
delete summary;
|
||||||
@ -388,14 +425,33 @@ bool cTimer::Parse(const char *s)
|
|||||||
char *buffer2 = NULL;
|
char *buffer2 = NULL;
|
||||||
delete summary;
|
delete summary;
|
||||||
summary = NULL;
|
summary = NULL;
|
||||||
|
//XXX Apparently sscanf() doesn't work correctly if the last %a argument
|
||||||
|
//XXX results in an empty string (this firt occured when the EIT gathering
|
||||||
|
//XXX was put into a separate thread - don't know why this happens...
|
||||||
|
//XXX As a cure we copy the original string and add a blank.
|
||||||
|
//XXX If anybody can shed some light on why sscanf() failes here, I'd love
|
||||||
|
//XXX to hear about that!
|
||||||
|
char *s2 = NULL;
|
||||||
|
int l2 = strlen(s);
|
||||||
|
if (s[l2 - 2] == ':') { // note that 's' has a trailing '\n'
|
||||||
|
s2 = (char *)malloc(l2 + 2);
|
||||||
|
strcat(strn0cpy(s2, s, l2), " \n");
|
||||||
|
s = s2;
|
||||||
|
}
|
||||||
if (8 <= sscanf(s, "%d:%d:%a[^:]:%d:%d:%d:%d:%a[^:\n]:%a[^\n]", &active, &channel, &buffer1, &start, &stop, &priority, &lifetime, &buffer2, &summary)) {
|
if (8 <= sscanf(s, "%d:%d:%a[^:]:%d:%d:%d:%d:%a[^:\n]:%a[^\n]", &active, &channel, &buffer1, &start, &stop, &priority, &lifetime, &buffer2, &summary)) {
|
||||||
|
if (summary && !*skipspace(summary)) {
|
||||||
|
delete summary;
|
||||||
|
summary = NULL;
|
||||||
|
}
|
||||||
//TODO add more plausibility checks
|
//TODO add more plausibility checks
|
||||||
day = ParseDay(buffer1);
|
day = ParseDay(buffer1);
|
||||||
strn0cpy(file, buffer2, MaxFileName);
|
strn0cpy(file, buffer2, MaxFileName);
|
||||||
delete buffer1;
|
delete buffer1;
|
||||||
delete buffer2;
|
delete buffer2;
|
||||||
|
delete s2;
|
||||||
return day != 0;
|
return day != 0;
|
||||||
}
|
}
|
||||||
|
delete s2;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -550,6 +606,17 @@ cChannel *cChannels::GetByNumber(int Number)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cChannel *cChannels::GetByServiceID(unsigned short ServiceId)
|
||||||
|
{
|
||||||
|
cChannel *channel = (cChannel *)First();
|
||||||
|
while (channel) {
|
||||||
|
if (channel->pnr == ServiceId)
|
||||||
|
return channel;
|
||||||
|
channel = (cChannel *)channel->Next();
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
bool cChannels::SwitchTo(int Number, cDvbApi *DvbApi)
|
bool cChannels::SwitchTo(int Number, cDvbApi *DvbApi)
|
||||||
{
|
{
|
||||||
cChannel *channel = GetByNumber(Number);
|
cChannel *channel = GetByNumber(Number);
|
||||||
@ -562,14 +629,6 @@ const char *cChannels::GetChannelNameByNumber(int Number)
|
|||||||
return channel ? channel->name : NULL;
|
return channel ? channel->name : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
eKeys cChannels::ShowChannel(int Number, bool Switched, bool Group)
|
|
||||||
{
|
|
||||||
cChannel *channel = Group ? Get(Number) : GetByNumber(Number);
|
|
||||||
if (channel)
|
|
||||||
return Interface->DisplayChannel(channel->number, channel->name, !Switched || Setup.ShowInfoOnChSwitch);
|
|
||||||
return kNone;
|
|
||||||
}
|
|
||||||
|
|
||||||
// -- cTimers ----------------------------------------------------------------
|
// -- cTimers ----------------------------------------------------------------
|
||||||
|
|
||||||
cTimers Timers;
|
cTimers Timers;
|
||||||
@ -599,6 +658,9 @@ cSetup::cSetup(void)
|
|||||||
MarkInstantRecord = 1;
|
MarkInstantRecord = 1;
|
||||||
LnbFrequLo = 9750;
|
LnbFrequLo = 9750;
|
||||||
LnbFrequHi = 10600;
|
LnbFrequHi = 10600;
|
||||||
|
SetSystemTime = 0;
|
||||||
|
MarginStart = 2;
|
||||||
|
MarginStop = 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cSetup::Parse(char *s)
|
bool cSetup::Parse(char *s)
|
||||||
@ -613,6 +675,9 @@ bool cSetup::Parse(char *s)
|
|||||||
else if (!strcasecmp(Name, "MarkInstantRecord")) MarkInstantRecord = atoi(Value);
|
else if (!strcasecmp(Name, "MarkInstantRecord")) MarkInstantRecord = atoi(Value);
|
||||||
else if (!strcasecmp(Name, "LnbFrequLo")) LnbFrequLo = atoi(Value);
|
else if (!strcasecmp(Name, "LnbFrequLo")) LnbFrequLo = atoi(Value);
|
||||||
else if (!strcasecmp(Name, "LnbFrequHi")) LnbFrequHi = atoi(Value);
|
else if (!strcasecmp(Name, "LnbFrequHi")) LnbFrequHi = atoi(Value);
|
||||||
|
else if (!strcasecmp(Name, "SetSystemTime")) SetSystemTime = atoi(Value);
|
||||||
|
else if (!strcasecmp(Name, "MarginStart")) MarginStart = atoi(Value);
|
||||||
|
else if (!strcasecmp(Name, "MarginStop")) MarginStop = atoi(Value);
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
@ -660,6 +725,9 @@ bool cSetup::Save(const char *FileName)
|
|||||||
fprintf(f, "MarkInstantRecord = %d\n", MarkInstantRecord);
|
fprintf(f, "MarkInstantRecord = %d\n", MarkInstantRecord);
|
||||||
fprintf(f, "LnbFrequLo = %d\n", LnbFrequLo);
|
fprintf(f, "LnbFrequLo = %d\n", LnbFrequLo);
|
||||||
fprintf(f, "LnbFrequHi = %d\n", LnbFrequHi);
|
fprintf(f, "LnbFrequHi = %d\n", LnbFrequHi);
|
||||||
|
fprintf(f, "SetSystemTime = %d\n", SetSystemTime);
|
||||||
|
fprintf(f, "MarginStart = %d\n", MarginStart);
|
||||||
|
fprintf(f, "MarginStop = %d\n", MarginStop);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
isyslog(LOG_INFO, "saved setup to %s", FileName);
|
isyslog(LOG_INFO, "saved setup to %s", FileName);
|
||||||
return true;
|
return true;
|
||||||
|
10
config.h
10
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.27 2000/10/08 16:33:48 kls Exp $
|
* $Id: config.h 1.29 2000/11/01 13:42:29 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __CONFIG_H
|
#ifndef __CONFIG_H
|
||||||
@ -15,9 +15,10 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include "dvbapi.h"
|
#include "dvbapi.h"
|
||||||
|
#include "eit.h"
|
||||||
#include "tools.h"
|
#include "tools.h"
|
||||||
|
|
||||||
#define VDRVERSION "0.66"
|
#define VDRVERSION "0.67"
|
||||||
|
|
||||||
#define MaxBuffer 10000
|
#define MaxBuffer 10000
|
||||||
|
|
||||||
@ -113,6 +114,7 @@ public:
|
|||||||
char file[MaxFileName];
|
char file[MaxFileName];
|
||||||
char *summary;
|
char *summary;
|
||||||
cTimer(bool Instant = false);
|
cTimer(bool Instant = false);
|
||||||
|
cTimer(const cEventInfo *EventInfo);
|
||||||
~cTimer();
|
~cTimer();
|
||||||
cTimer& operator= (const cTimer &Timer);
|
cTimer& operator= (const cTimer &Timer);
|
||||||
const char *ToText(void);
|
const char *ToText(void);
|
||||||
@ -204,10 +206,10 @@ public:
|
|||||||
int GetNextNormal(int Idx); // Get next normal channel (not group)
|
int GetNextNormal(int Idx); // Get next normal channel (not group)
|
||||||
void ReNumber(void); // Recalculate 'number' based on channel type
|
void ReNumber(void); // Recalculate 'number' based on channel type
|
||||||
cChannel *GetByNumber(int Number);
|
cChannel *GetByNumber(int Number);
|
||||||
|
cChannel *GetByServiceID(unsigned short ServiceId);
|
||||||
const char *GetChannelNameByNumber(int Number);
|
const char *GetChannelNameByNumber(int Number);
|
||||||
bool SwitchTo(int Number, cDvbApi *DvbApi = NULL);
|
bool SwitchTo(int Number, cDvbApi *DvbApi = NULL);
|
||||||
int MaxNumber(void) { return maxNumber; }
|
int MaxNumber(void) { return maxNumber; }
|
||||||
eKeys ShowChannel(int Number, bool Switched, bool Group = false);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class cTimers : public cConfig<cTimer> {
|
class cTimers : public cConfig<cTimer> {
|
||||||
@ -234,6 +236,8 @@ public:
|
|||||||
int MarkInstantRecord;
|
int MarkInstantRecord;
|
||||||
int LnbFrequLo;
|
int LnbFrequLo;
|
||||||
int LnbFrequHi;
|
int LnbFrequHi;
|
||||||
|
int SetSystemTime;
|
||||||
|
int MarginStart, MarginStop;
|
||||||
cSetup(void);
|
cSetup(void);
|
||||||
bool Load(const char *FileName);
|
bool Load(const char *FileName);
|
||||||
bool Save(const char *FileName = NULL);
|
bool Save(const char *FileName = NULL);
|
||||||
|
@ -81,7 +81,7 @@
|
|||||||
BlitBitmap(dvb, dvb->osdwin, x0, y0+i*lpb, 1);
|
BlitBitmap(dvb, dvb->osdwin, x0, y0+i*lpb, 1);
|
||||||
- data+=bpl;
|
- data+=bpl;
|
||||||
+ data+=lpb*inc; //XXX kls: incrementing must be done in "one byte per pixel"
|
+ data+=lpb*inc; //XXX kls: incrementing must be done in "one byte per pixel"
|
||||||
+ ddelay(2); //XXX kls: without this the block is sometimes not fully displayed - firmware bug?
|
+ ddelay(3); //XXX kls: without this the block is sometimes not fully displayed - firmware bug?
|
||||||
}
|
}
|
||||||
if (brest) {
|
if (brest) {
|
||||||
- LoadBitmap(dvb, BITMAP8, w, brest/bpl, inc, data);
|
- LoadBitmap(dvb, BITMAP8, w, brest/bpl, inc, data);
|
||||||
|
67
dvbapi.c
67
dvbapi.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: dvbapi.c 1.31 2000/10/08 16:14:45 kls Exp $
|
* $Id: dvbapi.c 1.34 2000/11/01 09:19:27 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "dvbapi.h"
|
#include "dvbapi.h"
|
||||||
@ -25,6 +25,7 @@ extern "C" {
|
|||||||
#include "videodir.h"
|
#include "videodir.h"
|
||||||
|
|
||||||
#define VIDEODEVICE "/dev/video"
|
#define VIDEODEVICE "/dev/video"
|
||||||
|
#define VBIDEVICE "/dev/vbi"
|
||||||
|
|
||||||
// The size of the array used to buffer video data:
|
// The size of the array used to buffer video data:
|
||||||
#define VIDEOBUFSIZE (1024*1024)
|
#define VIDEOBUFSIZE (1024*1024)
|
||||||
@ -1084,14 +1085,27 @@ int cDvbApi::NumDvbApis = 0;
|
|||||||
cDvbApi *cDvbApi::dvbApi[MAXDVBAPI] = { NULL };
|
cDvbApi *cDvbApi::dvbApi[MAXDVBAPI] = { NULL };
|
||||||
cDvbApi *cDvbApi::PrimaryDvbApi = NULL;
|
cDvbApi *cDvbApi::PrimaryDvbApi = NULL;
|
||||||
|
|
||||||
cDvbApi::cDvbApi(const char *FileName)
|
cDvbApi::cDvbApi(const char *VideoFileName, const char *VbiFileName)
|
||||||
{
|
{
|
||||||
|
siProcessor = NULL;
|
||||||
pidRecord = pidReplay = 0;
|
pidRecord = pidReplay = 0;
|
||||||
fromRecord = toRecord = -1;
|
fromRecord = toRecord = -1;
|
||||||
fromReplay = toReplay = -1;
|
fromReplay = toReplay = -1;
|
||||||
videoDev = open(FileName, O_RDWR | O_NONBLOCK);
|
videoDev = open(VideoFileName, O_RDWR | O_NONBLOCK);
|
||||||
if (videoDev < 0)
|
if (videoDev >= 0) {
|
||||||
LOG_ERROR;
|
siProcessor = new cSIProcessor(VbiFileName);
|
||||||
|
if (!NumDvbApis) // only the first one shall set the system time
|
||||||
|
siProcessor->SetUseTSTime(Setup.SetSystemTime);
|
||||||
|
siProcessor->AddFilter(0x14, 0x70); // TDT
|
||||||
|
siProcessor->AddFilter(0x14, 0x73); // TOT
|
||||||
|
siProcessor->AddFilter(0x12, 0x4e); // event info, actual TS, present/following
|
||||||
|
siProcessor->AddFilter(0x12, 0x4f); // event info, other TS, present/following
|
||||||
|
siProcessor->AddFilter(0x12, 0x50); // event info, actual TS, schedule
|
||||||
|
siProcessor->AddFilter(0x12, 0x60); // event info, other TS, schedule
|
||||||
|
siProcessor->Start();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
LOG_ERROR_STR(VideoFileName);
|
||||||
cols = rows = 0;
|
cols = rows = 0;
|
||||||
|
|
||||||
ovlGeoSet = ovlStat = ovlFbSet = false;
|
ovlGeoSet = ovlStat = ovlFbSet = false;
|
||||||
@ -1104,7 +1118,7 @@ cDvbApi::cDvbApi(const char *FileName)
|
|||||||
nonl();
|
nonl();
|
||||||
cbreak();
|
cbreak();
|
||||||
noecho();
|
noecho();
|
||||||
timeout(1000);
|
timeout(10);
|
||||||
#endif
|
#endif
|
||||||
#if defined(DEBUG_OSD)
|
#if defined(DEBUG_OSD)
|
||||||
memset(&colorPairs, 0, sizeof(colorPairs));
|
memset(&colorPairs, 0, sizeof(colorPairs));
|
||||||
@ -1121,6 +1135,7 @@ cDvbApi::cDvbApi(const char *FileName)
|
|||||||
cDvbApi::~cDvbApi()
|
cDvbApi::~cDvbApi()
|
||||||
{
|
{
|
||||||
if (videoDev >= 0) {
|
if (videoDev >= 0) {
|
||||||
|
delete siProcessor;
|
||||||
Close();
|
Close();
|
||||||
Stop();
|
Stop();
|
||||||
StopRecord();
|
StopRecord();
|
||||||
@ -1174,11 +1189,9 @@ int cDvbApi::Index(void)
|
|||||||
|
|
||||||
bool cDvbApi::Init(void)
|
bool cDvbApi::Init(void)
|
||||||
{
|
{
|
||||||
char fileName[strlen(VIDEODEVICE) + 10];
|
|
||||||
int i;
|
|
||||||
|
|
||||||
NumDvbApis = 0;
|
NumDvbApis = 0;
|
||||||
for (i = 0; i < MAXDVBAPI; i++) {
|
for (int i = 0; i < MAXDVBAPI; i++) {
|
||||||
|
char fileName[strlen(VIDEODEVICE) + 10];
|
||||||
sprintf(fileName, "%s%d", VIDEODEVICE, i);
|
sprintf(fileName, "%s%d", VIDEODEVICE, i);
|
||||||
if (access(fileName, F_OK | R_OK | W_OK) == 0) {
|
if (access(fileName, F_OK | R_OK | W_OK) == 0) {
|
||||||
dsyslog(LOG_INFO, "probing %s", fileName);
|
dsyslog(LOG_INFO, "probing %s", fileName);
|
||||||
@ -1188,7 +1201,9 @@ bool cDvbApi::Init(void)
|
|||||||
int r = ioctl(f, VIDIOCGCAP, &cap);
|
int r = ioctl(f, VIDIOCGCAP, &cap);
|
||||||
close(f);
|
close(f);
|
||||||
if (r == 0 && (cap.type & VID_TYPE_DVB)) {
|
if (r == 0 && (cap.type & VID_TYPE_DVB)) {
|
||||||
dvbApi[i] = new cDvbApi(fileName);
|
char vbiFileName[strlen(VBIDEVICE) + 10];
|
||||||
|
sprintf(vbiFileName, "%s%d", VBIDEVICE, i);
|
||||||
|
dvbApi[i] = new cDvbApi(fileName, vbiFileName);
|
||||||
NumDvbApis++;
|
NumDvbApis++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1223,6 +1238,13 @@ void cDvbApi::Cleanup(void)
|
|||||||
PrimaryDvbApi = NULL;
|
PrimaryDvbApi = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const cSchedules *cDvbApi::Schedules(cThreadLock *ThreadLock) const
|
||||||
|
{
|
||||||
|
if (siProcessor && ThreadLock->Lock(siProcessor))
|
||||||
|
return siProcessor->Schedules();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
bool cDvbApi::GrabImage(const char *FileName, bool Jpeg, int Quality, int SizeX, int SizeY)
|
bool cDvbApi::GrabImage(const char *FileName, bool Jpeg, int Quality, int SizeX, int SizeY)
|
||||||
{
|
{
|
||||||
int result = 0;
|
int result = 0;
|
||||||
@ -1576,6 +1598,24 @@ void cDvbApi::ClrEol(int x, int y, eDvbColor color)
|
|||||||
Fill(x, y, cols - x, 1, color);
|
Fill(x, y, cols - x, 1, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int cDvbApi::CellWidth(void)
|
||||||
|
{
|
||||||
|
#ifdef DEBUG_OSD
|
||||||
|
return 1;
|
||||||
|
#else
|
||||||
|
return charWidth;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
int cDvbApi::Width(unsigned char c)
|
||||||
|
{
|
||||||
|
#ifdef DEBUG_OSD
|
||||||
|
return 1;
|
||||||
|
#else
|
||||||
|
return osd->Width(c);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void cDvbApi::Text(int x, int y, const char *s, eDvbColor colorFg, eDvbColor colorBg)
|
void cDvbApi::Text(int x, int y, const char *s, eDvbColor colorFg, eDvbColor colorBg)
|
||||||
{
|
{
|
||||||
if (x < 0) x = cols + x;
|
if (x < 0) x = cols + x;
|
||||||
@ -1671,8 +1711,11 @@ bool cDvbApi::SetChannel(int FrequencyMHz, char Polarization, int Diseqc, int Sr
|
|||||||
front.fec = 8;
|
front.fec = 8;
|
||||||
front.AFC = 1;
|
front.AFC = 1;
|
||||||
ioctl(videoDev, VIDIOCSFRONTEND, &front);
|
ioctl(videoDev, VIDIOCSFRONTEND, &front);
|
||||||
if (front.sync & 0x1F == 0x1F)
|
if (front.sync & 0x1F == 0x1F) {
|
||||||
|
if (siProcessor)
|
||||||
|
siProcessor->SetCurrentServiceID(Pnr);
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
esyslog(LOG_ERR, "ERROR: channel not sync'ed (front.sync=%X)!", front.sync);
|
esyslog(LOG_ERR, "ERROR: channel not sync'ed (front.sync=%X)!", front.sync);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
16
dvbapi.h
16
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.18 2000/10/03 11:26:10 kls Exp $
|
* $Id: dvbapi.h 1.20 2000/11/01 09:18:50 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __DVBAPI_H
|
#ifndef __DVBAPI_H
|
||||||
@ -21,6 +21,7 @@ typedef unsigned char __u8;
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <dvb.h>
|
#include <dvb.h>
|
||||||
#include "dvbosd.h"
|
#include "dvbosd.h"
|
||||||
|
#include "eit.h"
|
||||||
|
|
||||||
// Overlay facilities
|
// Overlay facilities
|
||||||
#define MAXCLIPRECTS 100
|
#define MAXCLIPRECTS 100
|
||||||
@ -44,7 +45,8 @@ public:
|
|||||||
class cDvbApi {
|
class cDvbApi {
|
||||||
private:
|
private:
|
||||||
int videoDev;
|
int videoDev;
|
||||||
cDvbApi(const char *FileName);
|
cSIProcessor *siProcessor;
|
||||||
|
cDvbApi(const char *VideoFileName, const char *VbiFileName);
|
||||||
public:
|
public:
|
||||||
~cDvbApi();
|
~cDvbApi();
|
||||||
|
|
||||||
@ -71,6 +73,14 @@ 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.
|
||||||
|
|
||||||
|
// EIT facilities
|
||||||
|
|
||||||
|
const cSchedules *Schedules(cThreadLock *ThreadLock) const;
|
||||||
|
// Caller must provide a cThreadLock which has to survive the entire
|
||||||
|
// time the returned cSchedules is accessed. Once the cSchedules is no
|
||||||
|
// longer used, the cThreadLock must be destroyed.
|
||||||
|
void SetUseTSTime(bool On) { if (siProcessor) siProcessor->SetUseTSTime(On); }
|
||||||
|
|
||||||
// Image Grab facilities
|
// Image Grab facilities
|
||||||
|
|
||||||
bool GrabImage(const char *FileName, bool Jpeg = true, int Quality = -1, int SizeX = -1, int SizeY = -1);
|
bool GrabImage(const char *FileName, bool Jpeg = true, int Quality = -1, int SizeX = -1, int SizeY = -1);
|
||||||
@ -112,6 +122,8 @@ public:
|
|||||||
void Clear(void);
|
void Clear(void);
|
||||||
void Fill(int x, int y, int w, int h, eDvbColor color = clrBackground);
|
void Fill(int x, int y, int w, int h, eDvbColor color = clrBackground);
|
||||||
void ClrEol(int x, int y, eDvbColor color = clrBackground);
|
void ClrEol(int x, int y, eDvbColor color = clrBackground);
|
||||||
|
int CellWidth(void);
|
||||||
|
int Width(unsigned char c);
|
||||||
void Text(int x, int y, const char *s, eDvbColor colorFg = clrWhite, eDvbColor colorBg = clrBackground);
|
void Text(int x, int y, const char *s, eDvbColor colorFg = clrWhite, eDvbColor colorBg = clrBackground);
|
||||||
void Flush(void);
|
void Flush(void);
|
||||||
|
|
||||||
|
7
dvbosd.c
7
dvbosd.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: dvbosd.c 1.3 2000/10/07 14:42:48 kls Exp $
|
* $Id: dvbosd.c 1.4 2000/11/01 09:13:32 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "dvbosd.h"
|
#include "dvbosd.h"
|
||||||
@ -76,6 +76,11 @@ void cBitmap::SetPixel(int x, int y, eDvbColor Color)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int cBitmap::Width(unsigned char c)
|
||||||
|
{
|
||||||
|
return font ? font->Width(c) : -1;
|
||||||
|
}
|
||||||
|
|
||||||
void cBitmap::Text(int x, int y, const char *s, eDvbColor ColorFg, eDvbColor ColorBg)
|
void cBitmap::Text(int x, int y, const char *s, eDvbColor ColorFg, eDvbColor ColorBg)
|
||||||
{
|
{
|
||||||
if (bitmap) {
|
if (bitmap) {
|
||||||
|
3
dvbosd.h
3
dvbosd.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: dvbosd.h 1.1 2000/10/01 15:00:00 kls Exp $
|
* $Id: dvbosd.h 1.2 2000/11/01 09:13:44 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __DVBOSD_H
|
#ifndef __DVBOSD_H
|
||||||
@ -56,6 +56,7 @@ public:
|
|||||||
void SetFont(eDvbFont Font);
|
void SetFont(eDvbFont Font);
|
||||||
bool Dirty(void);
|
bool Dirty(void);
|
||||||
void SetPixel(int x, int y, eDvbColor Color);
|
void SetPixel(int x, int y, eDvbColor Color);
|
||||||
|
int Width(unsigned char c);
|
||||||
void Text(int x, int y, const char *s, eDvbColor ColorFg = clrWhite, eDvbColor ColorBg = clrBackground);
|
void Text(int x, int y, const char *s, eDvbColor ColorFg = clrWhite, eDvbColor ColorBg = clrBackground);
|
||||||
void Fill(int x1, int y1, int x2, int y2, eDvbColor Color);
|
void Fill(int x1, int y1, int x2, int y2, eDvbColor Color);
|
||||||
void Clear(void);
|
void Clear(void);
|
||||||
|
179
eit.h
179
eit.h
@ -13,80 +13,127 @@
|
|||||||
* 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.h 1.1 2000/09/03 10:23:24 kls Exp $
|
* $Id: eit.h 1.2 2000/10/29 10:21:56 kls Exp $
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
|
|
||||||
#ifndef __EIT_H
|
#ifndef __EIT_H
|
||||||
#define __EIT_H
|
#define __EIT_H
|
||||||
|
|
||||||
#include <dvb_v4l.h>
|
#include "thread.h"
|
||||||
|
#include "tools.h"
|
||||||
|
|
||||||
typedef struct eit_event {
|
class cEventInfo : public cListObject {
|
||||||
|
friend class cSchedule;
|
||||||
bool bIsValid;
|
friend class cEIT;
|
||||||
char szTitle[512];
|
private:
|
||||||
char szSubTitle[512];
|
unsigned short uServiceID; // Service ID of program for that event
|
||||||
char szDate[12];
|
bool bIsFollowing; // true if this is the next event on this channel
|
||||||
char szTime[12];
|
bool bIsPresent; // true if this is the present event running
|
||||||
|
char *pExtendedDescription; // Extended description of this event
|
||||||
}eit_event;
|
char *pSubtitle; // Subtitle of event
|
||||||
|
char *pTitle; // Title of event
|
||||||
/**
|
unsigned short uEventID; // Event ID of this event
|
||||||
*@author Robert Schneider
|
long lDuration; // duration of event in seconds
|
||||||
*/
|
time_t tTime; // Start time
|
||||||
|
u_char cExtendedDescriptorNumber; // current extended descriptor number that has to be inserted
|
||||||
class cEIT {
|
int nChannelNumber; // the actual channel number from VDR's channel list (used in cMenuSchedule for sorting by channel number)
|
||||||
|
protected:
|
||||||
|
void SetFollowing(bool foll);
|
||||||
|
void SetPresent(bool pres);
|
||||||
|
bool SetTitle(char *string);
|
||||||
|
void SetServiceID(unsigned short servid);
|
||||||
|
void SetEventID(unsigned short evid);
|
||||||
|
void SetDuration(long l);
|
||||||
|
void SetTime(time_t t);
|
||||||
|
bool AddExtendedDescription(char *string);
|
||||||
|
bool SetSubtitle(char *string);
|
||||||
|
void IncreaseExtendedDescriptorNumber(void);
|
||||||
|
cEventInfo(unsigned short serviceid, unsigned short eventid);
|
||||||
public:
|
public:
|
||||||
cEIT();
|
~cEventInfo();
|
||||||
~cEIT();
|
const char *GetTimeString(void) const;
|
||||||
/** */
|
const char *GetEndTimeString(void) const;
|
||||||
int GetEIT();
|
const char *GetDate(void) const;
|
||||||
/** */
|
bool IsFollowing(void) const;
|
||||||
int SetProgramNumber(unsigned short pnr);
|
bool IsPresent(void) const;
|
||||||
/** Retrieves the string representing the time of the current event */
|
const char *GetExtendedDescription(void) const;
|
||||||
char * GetRunningTime();
|
const char *GetSubtitle(void) const;
|
||||||
/** Retrieves the string representing the date of the current event */
|
const char *GetTitle(void) const;
|
||||||
char * GetRunningDate();
|
unsigned short GetEventID(void) const;
|
||||||
/** Retrieves the string for the running subtitle */
|
long GetDuration(void) const;
|
||||||
char * GetRunningSubtitle();
|
time_t GetTime(void) const;
|
||||||
/** retrieves the string for the running title */
|
u_char GetExtendedDescriptorNumber(void) const;
|
||||||
char * GetRunningTitle();
|
unsigned short GetServiceID(void) const;
|
||||||
/** Retrieves the string representing the time of the next event */
|
int GetChannelNumber(void) const { return nChannelNumber; }
|
||||||
char * GetNextTime();
|
void SetChannelNumber(int ChannelNumber) const { ((cEventInfo *)this)->nChannelNumber = ChannelNumber; } // doesn't modify the EIT data, so it's ok to make it 'const'
|
||||||
/** Retrieves the string representing the date of the next event */
|
};
|
||||||
char * GetNextDate();
|
|
||||||
/** Retrieves the string for the next subtitle */
|
|
||||||
char * GetNextSubtitle();
|
|
||||||
/** retrieves the string for the next title */
|
|
||||||
char * GetNextTitle();
|
|
||||||
/** */
|
|
||||||
bool IsValid();
|
|
||||||
|
|
||||||
protected: // Protected attributes
|
class cSchedule : public cListObject {
|
||||||
/** Device name of VBI device */
|
friend class cSchedules;
|
||||||
const char * cszBitFilter;
|
friend class cEIT;
|
||||||
protected: // Protected attributes
|
private:
|
||||||
/** handle to VBI device (usually /dev/vbi) */
|
cEventInfo *pPresent;
|
||||||
int fsvbi;
|
cEventInfo *pFollowing;
|
||||||
/** Describes the event next on */
|
unsigned short uServiceID;
|
||||||
eit_event evtNext;
|
cList<cEventInfo> Events;
|
||||||
/** Describes the running event */
|
protected:
|
||||||
eit_event evtRunning;
|
void SetServiceID(unsigned short servid);
|
||||||
protected: // Protected methods
|
bool SetFollowingEvent(cEventInfo *pEvent);
|
||||||
/** Set the bitfilter in vbi device to return
|
bool SetPresentEvent(cEventInfo *pEvent);
|
||||||
correct tables */
|
void Cleanup(time_t tTime);
|
||||||
int SetBitFilter(unsigned short pid, unsigned short section, unsigned short mode);
|
void Cleanup(void);
|
||||||
/** */
|
cSchedule(unsigned short servid = 0);
|
||||||
int GetSection(unsigned char *buf, ushort PID, unsigned char sec);
|
public:
|
||||||
/** */
|
~cSchedule();
|
||||||
int CloseFilter(unsigned short handle);
|
const cEventInfo *GetPresentEvent(void) const;
|
||||||
/** */
|
const cEventInfo *GetFollowingEvent(void) const;
|
||||||
char * mjd2string(unsigned short mjd);
|
unsigned short GetServiceID(void) const;
|
||||||
/** */
|
const cEventInfo *GetEvent(unsigned short uEventID) const;
|
||||||
int strdvbcpy(unsigned char *dst, unsigned char *src, int max);
|
const cEventInfo *GetEvent(time_t tTime) const;
|
||||||
public: // Public attributes
|
const cEventInfo *GetEventNumber(int n) const { return Events.Get(n); }
|
||||||
/** */
|
int NumEvents(void) const { return Events.Count(); }
|
||||||
unsigned short uProgramNumber;
|
};
|
||||||
|
|
||||||
|
class cSchedules : public cList<cSchedule> {
|
||||||
|
friend class cSIProcessor;
|
||||||
|
private:
|
||||||
|
const cSchedule *pCurrentSchedule;
|
||||||
|
unsigned short uCurrentServiceID;
|
||||||
|
protected:
|
||||||
|
bool SetCurrentServiceID(unsigned short servid);
|
||||||
|
void Cleanup();
|
||||||
|
public:
|
||||||
|
cSchedules(void);
|
||||||
|
~cSchedules();
|
||||||
|
const cSchedule *GetSchedule(unsigned short servid) const;
|
||||||
|
const cSchedule *GetSchedule(void) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct sip_filter {
|
||||||
|
|
||||||
|
u_char pid;
|
||||||
|
u_char tid;
|
||||||
|
int handle;
|
||||||
|
bool inuse;
|
||||||
|
|
||||||
|
}SIP_FILTER;
|
||||||
|
|
||||||
|
class cSIProcessor : public cThread {
|
||||||
|
private:
|
||||||
|
cSchedules *schedules;
|
||||||
|
bool useTStime;
|
||||||
|
SIP_FILTER *filters;
|
||||||
|
int fsvbi;
|
||||||
|
bool RefreshFilters(void);
|
||||||
|
void Action(void);
|
||||||
|
public:
|
||||||
|
cSIProcessor(const char *FileName);
|
||||||
|
~cSIProcessor();
|
||||||
|
bool SetUseTSTime(bool use);
|
||||||
|
bool AddFilter(u_char pid, u_char tid);
|
||||||
|
bool ShutDownFilters(void);
|
||||||
|
bool SetCurrentServiceID(unsigned short servid);
|
||||||
|
const cSchedules *Schedules(void) { return schedules; }
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
157
interface.c
157
interface.c
@ -4,14 +4,12 @@
|
|||||||
* 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.25 2000/10/08 16:34:17 kls Exp $
|
* $Id: interface.c 1.28 2000/11/01 15:27:52 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "interface.h"
|
#include "interface.h"
|
||||||
|
#include <ctype.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include "eit.h"
|
|
||||||
|
|
||||||
cEIT EIT;
|
|
||||||
|
|
||||||
cInterface *Interface = NULL;
|
cInterface *Interface = NULL;
|
||||||
|
|
||||||
@ -19,6 +17,7 @@ cInterface::cInterface(int SVDRPport)
|
|||||||
{
|
{
|
||||||
open = 0;
|
open = 0;
|
||||||
cols[0] = 0;
|
cols[0] = 0;
|
||||||
|
width = height = 0;
|
||||||
keyFromWait = kNone;
|
keyFromWait = kNone;
|
||||||
rcIo = NULL;
|
rcIo = NULL;
|
||||||
SVDRP = NULL;
|
SVDRP = NULL;
|
||||||
@ -43,15 +42,17 @@ cInterface::~cInterface()
|
|||||||
void cInterface::Open(int NumCols, int NumLines)
|
void cInterface::Open(int NumCols, int NumLines)
|
||||||
{
|
{
|
||||||
if (!open++)
|
if (!open++)
|
||||||
cDvbApi::PrimaryDvbApi->Open(NumCols, NumLines);
|
cDvbApi::PrimaryDvbApi->Open(width = NumCols, height = NumLines);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cInterface::Close(void)
|
void cInterface::Close(void)
|
||||||
{
|
{
|
||||||
if (open == 1)
|
if (open == 1)
|
||||||
Clear();
|
Clear();
|
||||||
if (!--open)
|
if (!--open) {
|
||||||
cDvbApi::PrimaryDvbApi->Close();
|
cDvbApi::PrimaryDvbApi->Close();
|
||||||
|
width = height = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int cInterface::GetCh(bool Wait, bool *Repeat, bool *Release)
|
unsigned int cInterface::GetCh(bool Wait, bool *Repeat, bool *Release)
|
||||||
@ -114,6 +115,18 @@ void cInterface::ClearEol(int x, int y, eDvbColor Color)
|
|||||||
cDvbApi::PrimaryDvbApi->ClrEol(x, y, Color);
|
cDvbApi::PrimaryDvbApi->ClrEol(x, y, Color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cInterface::Fill(int x, int y, int w, int h, eDvbColor Color)
|
||||||
|
{
|
||||||
|
if (open)
|
||||||
|
cDvbApi::PrimaryDvbApi->Fill(x, y, w, h, Color);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cInterface::Flush(void)
|
||||||
|
{
|
||||||
|
if (open)
|
||||||
|
cDvbApi::PrimaryDvbApi->Flush();
|
||||||
|
}
|
||||||
|
|
||||||
void cInterface::SetCols(int *c)
|
void cInterface::SetCols(int *c)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < MaxCols; i++) {
|
for (int i = 0; i < MaxCols; i++) {
|
||||||
@ -123,6 +136,74 @@ void cInterface::SetCols(int *c)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *cInterface::WrapText(const char *Text, int Width, int *Height)
|
||||||
|
{
|
||||||
|
// Wraps the Text to make it fit into the area defined by the given Width
|
||||||
|
// (which is given in character cells).
|
||||||
|
// The actual number of lines resulting from this operation is returned in
|
||||||
|
// Height.
|
||||||
|
// The returned string is newly created on the heap and the caller
|
||||||
|
// is responsible for deleting it once it is no longer used.
|
||||||
|
// Wrapping is done by inserting the necessary number of newline
|
||||||
|
// characters into the string.
|
||||||
|
|
||||||
|
int Lines = 1;
|
||||||
|
char *t = strdup(Text);
|
||||||
|
char *Blank = NULL;
|
||||||
|
char *Delim = NULL;
|
||||||
|
int w = 0;
|
||||||
|
|
||||||
|
Width *= cDvbApi::PrimaryDvbApi->CellWidth();
|
||||||
|
|
||||||
|
while (*t && t[strlen(t) - 1] == '\n')
|
||||||
|
t[strlen(t) - 1] = 0; // skips trailing newlines
|
||||||
|
|
||||||
|
for (char *p = t; *p; ) {
|
||||||
|
if (*p == '\n') {
|
||||||
|
Lines++;
|
||||||
|
w = 0;
|
||||||
|
Blank = Delim = NULL;
|
||||||
|
p++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else if (isspace(*p))
|
||||||
|
Blank = p;
|
||||||
|
int cw = cDvbApi::PrimaryDvbApi->Width(*p);
|
||||||
|
if (w + cw > Width) {
|
||||||
|
if (Blank) {
|
||||||
|
*Blank = '\n';
|
||||||
|
p = Blank;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Here's the ugly part, where we don't have any whitespace to
|
||||||
|
// punch in a newline, so we need to make room for it:
|
||||||
|
if (Delim)
|
||||||
|
p = Delim + 1; // let's fall back to the most recent delimiter
|
||||||
|
char *s = new char[strlen(t) + 2]; // The additional '\n' plus the terminating '\0'
|
||||||
|
int l = p - t;
|
||||||
|
strncpy(s, t, l);
|
||||||
|
s[l] = '\n';
|
||||||
|
strcpy(s + l + 1, p);
|
||||||
|
delete t;
|
||||||
|
t = s;
|
||||||
|
p = t + l;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
w += cw;
|
||||||
|
if (strchr("-.,:;!?_", *p)) {
|
||||||
|
Delim = p;
|
||||||
|
Blank = NULL;
|
||||||
|
}
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
|
||||||
|
*Height = Lines;
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
void cInterface::Write(int x, int y, const char *s, eDvbColor FgColor, eDvbColor BgColor)
|
void cInterface::Write(int x, int y, const char *s, eDvbColor FgColor, eDvbColor BgColor)
|
||||||
{
|
{
|
||||||
if (open)
|
if (open)
|
||||||
@ -157,7 +238,7 @@ void cInterface::WriteText(int x, int y, const char *s, eDvbColor FgColor, eDvbC
|
|||||||
|
|
||||||
void cInterface::Title(const char *s)
|
void cInterface::Title(const char *s)
|
||||||
{
|
{
|
||||||
int x = (MenuColumns - strlen(s)) / 2;
|
int x = (Width() - strlen(s)) / 2;
|
||||||
if (x < 0)
|
if (x < 0)
|
||||||
x = 0;
|
x = 0;
|
||||||
ClearEol(0, 0, clrCyan);
|
ClearEol(0, 0, clrCyan);
|
||||||
@ -206,7 +287,7 @@ bool cInterface::Confirm(const char *s)
|
|||||||
void cInterface::HelpButton(int Index, const char *Text, eDvbColor FgColor, eDvbColor BgColor)
|
void cInterface::HelpButton(int Index, const char *Text, eDvbColor FgColor, eDvbColor BgColor)
|
||||||
{
|
{
|
||||||
if (open && Text) {
|
if (open && Text) {
|
||||||
const int w = MenuColumns / 4;
|
const int w = Width() / 4;
|
||||||
int l = (w - strlen(Text)) / 2;
|
int l = (w - strlen(Text)) / 2;
|
||||||
if (l < 0)
|
if (l < 0)
|
||||||
l = 0;
|
l = 0;
|
||||||
@ -334,65 +415,9 @@ void cInterface::LearnKeys(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
eKeys cInterface::DisplayChannel(int Number, const char *Name, bool WithInfo)
|
void cInterface::DisplayChannelNumber(int Number)
|
||||||
{
|
{
|
||||||
// Number = 0 is used for channel group display and no EIT
|
rcIo->Number(Number);
|
||||||
if (Number)
|
|
||||||
rcIo->Number(Number);
|
|
||||||
if (Name && !Recording()) {
|
|
||||||
Open(MenuColumns, 5);
|
|
||||||
cDvbApi::PrimaryDvbApi->Fill(0, 0, MenuColumns, 1, clrBackground);
|
|
||||||
int BufSize = MenuColumns + 1;
|
|
||||||
char buffer[BufSize];
|
|
||||||
if (Number)
|
|
||||||
snprintf(buffer, BufSize, "%d %s", Number, Name ? Name : "");
|
|
||||||
else
|
|
||||||
snprintf(buffer, BufSize, "%s", Name ? Name : "");
|
|
||||||
Write(0, 0, buffer);
|
|
||||||
time_t t = time(NULL);
|
|
||||||
struct tm *now = localtime(&t);
|
|
||||||
snprintf(buffer, BufSize, "%02d:%02d", now->tm_hour, now->tm_min);
|
|
||||||
Write(-5, 0, buffer);
|
|
||||||
cDvbApi::PrimaryDvbApi->Flush();
|
|
||||||
|
|
||||||
char *RunningTitle = "", *RunningSubtitle = "", *NextTitle = "", *NextSubtitle = "";
|
|
||||||
int Lines = 0;
|
|
||||||
if (Number && WithInfo && EIT.IsValid()) {
|
|
||||||
if (*(RunningTitle = EIT.GetRunningTitle())) Lines++;
|
|
||||||
if (*(RunningSubtitle = EIT.GetRunningSubtitle())) Lines++;
|
|
||||||
if (*(NextTitle = EIT.GetNextTitle())) Lines++;
|
|
||||||
if (*(NextSubtitle = EIT.GetNextSubtitle())) Lines++;
|
|
||||||
}
|
|
||||||
if (Lines > 0) {
|
|
||||||
const int t = 6;
|
|
||||||
int l = 1;
|
|
||||||
cDvbApi::PrimaryDvbApi->Fill(0, 1, MenuColumns, Lines, clrBackground);
|
|
||||||
if (*RunningTitle) {
|
|
||||||
Write(0, l, EIT.GetRunningTime(), clrYellow, clrBackground);
|
|
||||||
Write(t, l, RunningTitle, clrCyan, clrBackground);
|
|
||||||
l++;
|
|
||||||
}
|
|
||||||
if (*RunningSubtitle) {
|
|
||||||
Write(t, l, RunningSubtitle, clrCyan, clrBackground);
|
|
||||||
l++;
|
|
||||||
}
|
|
||||||
if (*NextTitle) {
|
|
||||||
Write(0, l, EIT.GetNextTime(), clrYellow, clrBackground);
|
|
||||||
Write(t, l, NextTitle, clrCyan, clrBackground);
|
|
||||||
l++;
|
|
||||||
}
|
|
||||||
if (*NextSubtitle) {
|
|
||||||
Write(t, l, NextSubtitle, clrCyan, clrBackground);
|
|
||||||
}
|
|
||||||
cDvbApi::PrimaryDvbApi->Flush();
|
|
||||||
}
|
|
||||||
eKeys Key = Wait(5, true);
|
|
||||||
if (Key == kOk)
|
|
||||||
GetKey();
|
|
||||||
Close();
|
|
||||||
return Key;
|
|
||||||
}
|
|
||||||
return kNone;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void cInterface::DisplayRecording(int Index, bool On)
|
void cInterface::DisplayRecording(int Index, bool On)
|
||||||
|
10
interface.h
10
interface.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: interface.h 1.16 2000/10/08 12:15:49 kls Exp $
|
* $Id: interface.h 1.19 2000/11/01 15:27:23 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __INTERFACE_H
|
#ifndef __INTERFACE_H
|
||||||
@ -19,6 +19,7 @@ class cInterface {
|
|||||||
public:
|
public:
|
||||||
enum { MaxCols = 5 };
|
enum { MaxCols = 5 };
|
||||||
private:
|
private:
|
||||||
|
int width, height;
|
||||||
int open;
|
int open;
|
||||||
int cols[MaxCols];
|
int cols[MaxCols];
|
||||||
eKeys keyFromWait;
|
eKeys keyFromWait;
|
||||||
@ -33,11 +34,16 @@ public:
|
|||||||
~cInterface();
|
~cInterface();
|
||||||
void Open(int NumCols = MenuColumns, int NumLines = MenuLines);
|
void Open(int NumCols = MenuColumns, int NumLines = MenuLines);
|
||||||
void Close(void);
|
void Close(void);
|
||||||
|
int Width(void) { return width; }
|
||||||
|
int Height(void) { return height; }
|
||||||
eKeys GetKey(bool Wait = true);
|
eKeys GetKey(bool Wait = true);
|
||||||
void PutKey(eKeys Key);
|
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 Fill(int x, int y, int w, int h, eDvbColor color = clrBackground);
|
||||||
|
void Flush(void);
|
||||||
void SetCols(int *c);
|
void SetCols(int *c);
|
||||||
|
char *WrapText(const char *Text, int Width, int *Height);
|
||||||
void Write(int x, int y, const char *s, eDvbColor FgColor = clrWhite, eDvbColor BgColor = clrBackground);
|
void Write(int x, int y, const char *s, eDvbColor FgColor = clrWhite, eDvbColor BgColor = clrBackground);
|
||||||
void WriteText(int x, int y, const char *s, eDvbColor FgColor = clrWhite, eDvbColor BgColor = clrBackground);
|
void WriteText(int x, int y, const char *s, eDvbColor FgColor = clrWhite, eDvbColor BgColor = clrBackground);
|
||||||
void Title(const char *s);
|
void Title(const char *s);
|
||||||
@ -47,7 +53,7 @@ public:
|
|||||||
bool Confirm(const char *s);
|
bool Confirm(const char *s);
|
||||||
void Help(const char *Red, const char *Green = NULL, const char *Yellow = NULL, const char *Blue = NULL);
|
void Help(const char *Red, const char *Green = NULL, const char *Yellow = NULL, const char *Blue = NULL);
|
||||||
void LearnKeys(void);
|
void LearnKeys(void);
|
||||||
eKeys DisplayChannel(int Number, const char *Name = NULL, bool WithInfo = false);
|
void DisplayChannelNumber(int Number);
|
||||||
void DisplayRecording(int Index, bool On);
|
void DisplayRecording(int Index, bool On);
|
||||||
bool Recording(void);
|
bool Recording(void);
|
||||||
};
|
};
|
||||||
|
567
menu.c
567
menu.c
@ -4,15 +4,16 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: menu.c 1.36 2000/10/08 16:11:22 kls Exp $
|
* $Id: menu.c 1.40 2000/11/01 16:14:48 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "menu.h"
|
#include "menu.h"
|
||||||
#include <ctype.h>
|
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#include "eit.h"
|
||||||
|
|
||||||
#define MENUTIMEOUT 120 // seconds
|
#define MENUTIMEOUT 120 // seconds
|
||||||
|
|
||||||
@ -725,7 +726,107 @@ eOSState cMenuChannels::ProcessKey(eKeys Key)
|
|||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- cMenuSummary --------------------------------------------------------
|
// --- cMenuTextItem ---------------------------------------------------------
|
||||||
|
|
||||||
|
class cMenuTextItem : public cOsdItem {
|
||||||
|
private:
|
||||||
|
char *text;
|
||||||
|
int x, y, w, h, lines, offset;
|
||||||
|
eDvbColor fgColor, bgColor;
|
||||||
|
public:
|
||||||
|
cMenuTextItem(const char *Text, int X, int Y, int W, int H = -1, eDvbColor FgColor = clrWhite, eDvbColor BgColor = clrBackground);
|
||||||
|
~cMenuTextItem();
|
||||||
|
int Height(void) { return h; }
|
||||||
|
void Clear(void);
|
||||||
|
virtual void Display(int Offset = -1, eDvbColor FgColor = clrWhite, eDvbColor BgColor = clrBackground);
|
||||||
|
bool CanScrollUp(void) { return offset > 0; }
|
||||||
|
bool CanScrollDown(void) { return h + offset < lines; }
|
||||||
|
void ScrollUp(void);
|
||||||
|
void ScrollDown(void);
|
||||||
|
virtual eOSState ProcessKey(eKeys Key);
|
||||||
|
};
|
||||||
|
|
||||||
|
cMenuTextItem::cMenuTextItem(const char *Text, int X, int Y, int W, int H, eDvbColor FgColor, eDvbColor BgColor)
|
||||||
|
{
|
||||||
|
x = X;
|
||||||
|
y = Y;
|
||||||
|
w = W;
|
||||||
|
h = H;
|
||||||
|
fgColor = FgColor;
|
||||||
|
bgColor = BgColor;
|
||||||
|
offset = 0;
|
||||||
|
text = Interface->WrapText(Text, w - 1, &lines);
|
||||||
|
if (h < 0)
|
||||||
|
h = lines;
|
||||||
|
}
|
||||||
|
|
||||||
|
cMenuTextItem::~cMenuTextItem()
|
||||||
|
{
|
||||||
|
delete text;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cMenuTextItem::Clear(void)
|
||||||
|
{
|
||||||
|
Interface->Fill(x, y, w, h, bgColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cMenuTextItem::Display(int Offset, eDvbColor FgColor, eDvbColor BgColor)
|
||||||
|
{
|
||||||
|
int l = 0;
|
||||||
|
char *t = text;
|
||||||
|
while (*t) {
|
||||||
|
char *n = strchr(t, '\n');
|
||||||
|
if (l >= offset) {
|
||||||
|
if (n)
|
||||||
|
*n = 0;
|
||||||
|
Interface->Write(x, y + l - offset, t, fgColor, bgColor);
|
||||||
|
if (n)
|
||||||
|
*n = '\n';
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!n)
|
||||||
|
break;
|
||||||
|
t = n + 1;
|
||||||
|
if (++l >= h + offset)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// scroll indicators use inverted color scheme!
|
||||||
|
if (CanScrollUp()) Interface->Write(x + w - 1, y, "^", bgColor, fgColor);
|
||||||
|
if (CanScrollDown()) Interface->Write(x + w - 1, y + h - 1, "v", bgColor, fgColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cMenuTextItem::ScrollUp(void)
|
||||||
|
{
|
||||||
|
if (CanScrollUp()) {
|
||||||
|
Clear();
|
||||||
|
offset--;
|
||||||
|
Display();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cMenuTextItem::ScrollDown(void)
|
||||||
|
{
|
||||||
|
if (CanScrollDown()) {
|
||||||
|
Clear();
|
||||||
|
offset++;
|
||||||
|
Display();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
eOSState cMenuTextItem::ProcessKey(eKeys Key)
|
||||||
|
{
|
||||||
|
switch (Key) {
|
||||||
|
case kUp|k_Repeat:
|
||||||
|
case kUp: ScrollUp(); break;
|
||||||
|
case kDown|k_Repeat:
|
||||||
|
case kDown: ScrollDown(); break;
|
||||||
|
default: return osUnknown;
|
||||||
|
}
|
||||||
|
return osContinue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- cMenuSummary ----------------------------------------------------------
|
||||||
|
|
||||||
class cMenuSummary : public cOsdMenu {
|
class cMenuSummary : public cOsdMenu {
|
||||||
public:
|
public:
|
||||||
@ -736,29 +837,7 @@ public:
|
|||||||
cMenuSummary::cMenuSummary(const char *Text)
|
cMenuSummary::cMenuSummary(const char *Text)
|
||||||
:cOsdMenu("Summary")
|
:cOsdMenu("Summary")
|
||||||
{
|
{
|
||||||
while (*Text) {
|
Add(new cMenuTextItem(Text, 1, 2, MenuColumns - 2, MAXOSDITEMS));
|
||||||
char line[MenuColumns + 1];
|
|
||||||
char *p = line;
|
|
||||||
const char *b = NULL;
|
|
||||||
*p++ = ' ';
|
|
||||||
while (*Text && p - line < MenuColumns - 2) {
|
|
||||||
if (isspace(*Text))
|
|
||||||
b = Text; // remember the blank
|
|
||||||
if (*Text == '\n')
|
|
||||||
break;
|
|
||||||
*p++ = *Text++;
|
|
||||||
}
|
|
||||||
if (*Text) {
|
|
||||||
if (b && Text - b > 0) {
|
|
||||||
p -= Text - b;
|
|
||||||
Text = b + 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
Text++;
|
|
||||||
}
|
|
||||||
*p = 0;
|
|
||||||
Add(new cOsdItem(line, osBack));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
eOSState cMenuSummary::ProcessKey(eKeys Key)
|
eOSState cMenuSummary::ProcessKey(eKeys Key)
|
||||||
@ -973,6 +1052,278 @@ eOSState cMenuTimers::ProcessKey(eKeys Key)
|
|||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --- cMenuEvent ------------------------------------------------------------
|
||||||
|
|
||||||
|
class cMenuEvent : public cOsdMenu {
|
||||||
|
private:
|
||||||
|
const cEventInfo *eventInfo;
|
||||||
|
public:
|
||||||
|
cMenuEvent(const cEventInfo *EventInfo, bool CanSwitch = false);
|
||||||
|
cMenuEvent(bool Now);
|
||||||
|
virtual eOSState ProcessKey(eKeys Key);
|
||||||
|
};
|
||||||
|
|
||||||
|
cMenuEvent::cMenuEvent(const cEventInfo *EventInfo, bool CanSwitch)
|
||||||
|
:cOsdMenu("Event")
|
||||||
|
{
|
||||||
|
eventInfo = EventInfo;
|
||||||
|
if (eventInfo) {
|
||||||
|
cChannel *channel = Channels.GetByServiceID(eventInfo->GetServiceID());
|
||||||
|
if (channel) {
|
||||||
|
const char *p;
|
||||||
|
char *buffer;
|
||||||
|
asprintf(&buffer, "%-17.*s %.*s %s - %s", 17, channel->name, 5, eventInfo->GetDate(), eventInfo->GetTimeString(), eventInfo->GetEndTimeString());
|
||||||
|
SetTitle(buffer, false);
|
||||||
|
int Line = 2;
|
||||||
|
cMenuTextItem *item;
|
||||||
|
if (!isempty(p = eventInfo->GetTitle())) {
|
||||||
|
Add(item = new cMenuTextItem(p, 1, Line, MenuColumns - 2, -1, clrCyan));
|
||||||
|
Line += item->Height() + 1;
|
||||||
|
}
|
||||||
|
if (!isempty(p = eventInfo->GetSubtitle())) {
|
||||||
|
Add(item = new cMenuTextItem(p, 1, Line, MenuColumns - 2, -1, clrYellow));
|
||||||
|
Line += item->Height() + 1;
|
||||||
|
}
|
||||||
|
if (!isempty(p = eventInfo->GetExtendedDescription()))
|
||||||
|
Add(new cMenuTextItem(p, 1, Line, MenuColumns - 2, Height() - Line - 2, clrCyan), true);
|
||||||
|
SetHelp("Record", NULL, NULL, CanSwitch ? "Switch" : NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
eOSState cMenuEvent::ProcessKey(eKeys Key)
|
||||||
|
{
|
||||||
|
eOSState state = cOsdMenu::ProcessKey(Key);
|
||||||
|
|
||||||
|
if (state == osUnknown) {
|
||||||
|
switch (Key) {
|
||||||
|
case kOk: return osBack;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- cMenuWhatsOnItem ------------------------------------------------------
|
||||||
|
|
||||||
|
class cMenuWhatsOnItem : public cOsdItem {
|
||||||
|
public:
|
||||||
|
const cEventInfo *eventInfo;
|
||||||
|
cMenuWhatsOnItem(const cEventInfo *EventInfo);
|
||||||
|
};
|
||||||
|
|
||||||
|
cMenuWhatsOnItem::cMenuWhatsOnItem(const cEventInfo *EventInfo)
|
||||||
|
{
|
||||||
|
eventInfo = EventInfo;
|
||||||
|
char *buffer = NULL;
|
||||||
|
cChannel *channel = Channels.GetByNumber(eventInfo->GetChannelNumber());
|
||||||
|
asprintf(&buffer, "%d\t%.*s\t%.*s\t%s", eventInfo->GetChannelNumber(), 6, channel ? channel->name : "???", 5, eventInfo->GetTimeString(), eventInfo->GetTitle());
|
||||||
|
SetText(buffer, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- cMenuWhatsOn ----------------------------------------------------------
|
||||||
|
|
||||||
|
class cMenuWhatsOn : public cOsdMenu {
|
||||||
|
private:
|
||||||
|
eOSState Record(void);
|
||||||
|
eOSState Switch(void);
|
||||||
|
public:
|
||||||
|
cMenuWhatsOn(const cSchedules *Schedules, bool Now);
|
||||||
|
virtual eOSState ProcessKey(eKeys Key);
|
||||||
|
};
|
||||||
|
|
||||||
|
static int CompareEventChannel(const void *p1, const void *p2)
|
||||||
|
{
|
||||||
|
return (int)( (*(const cEventInfo **)p1)->GetChannelNumber() - (*(const cEventInfo **)p2)->GetChannelNumber());
|
||||||
|
}
|
||||||
|
|
||||||
|
cMenuWhatsOn::cMenuWhatsOn(const cSchedules *Schedules, bool Now)
|
||||||
|
:cOsdMenu(Now ? "What's on now?" : "What's on next?", 4, 7, 6)
|
||||||
|
{
|
||||||
|
const cSchedule *Schedule = Schedules->First();
|
||||||
|
const cEventInfo **pArray = NULL;
|
||||||
|
int num = 0;
|
||||||
|
|
||||||
|
while (Schedule) {
|
||||||
|
pArray = (const cEventInfo **)realloc(pArray, (num + 1) * sizeof(cEventInfo *));
|
||||||
|
|
||||||
|
pArray[num] = Now ? Schedule->GetPresentEvent() : Schedule->GetFollowingEvent();
|
||||||
|
if (pArray[num]) {
|
||||||
|
cChannel *channel = Channels.GetByServiceID(pArray[num]->GetServiceID());
|
||||||
|
if (channel) {
|
||||||
|
pArray[num]->SetChannelNumber(channel->number);
|
||||||
|
num++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Schedule = (const cSchedule *)Schedules->Next(Schedule);
|
||||||
|
}
|
||||||
|
|
||||||
|
qsort(pArray, num, sizeof(cEventInfo *), CompareEventChannel);
|
||||||
|
|
||||||
|
for (int a = 0; a < num; a++)
|
||||||
|
Add(new cMenuWhatsOnItem(pArray[a]));
|
||||||
|
|
||||||
|
delete pArray;
|
||||||
|
SetHelp("Record", Now ? "Next" : "Now", "Schedule", "Switch");
|
||||||
|
}
|
||||||
|
|
||||||
|
eOSState cMenuWhatsOn::Switch(void)
|
||||||
|
{
|
||||||
|
cMenuWhatsOnItem *item = (cMenuWhatsOnItem *)Get(Current());
|
||||||
|
if (item) {
|
||||||
|
cChannel *channel = Channels.GetByServiceID(item->eventInfo->GetServiceID());
|
||||||
|
if (channel && channel->Switch())
|
||||||
|
return osEnd;
|
||||||
|
}
|
||||||
|
Interface->Error("Can't switch channel!");
|
||||||
|
return osContinue;
|
||||||
|
}
|
||||||
|
|
||||||
|
eOSState cMenuWhatsOn::Record(void)
|
||||||
|
{
|
||||||
|
cMenuWhatsOnItem *item = (cMenuWhatsOnItem *)Get(Current());
|
||||||
|
if (item) {
|
||||||
|
cTimer *timer = new cTimer(item->eventInfo);
|
||||||
|
Timers.Add(timer);
|
||||||
|
Timers.Save();
|
||||||
|
isyslog(LOG_INFO, "timer %d added", timer->Index() + 1);
|
||||||
|
return AddSubMenu(new cMenuEditTimer(timer->Index(), true));
|
||||||
|
}
|
||||||
|
return osContinue;
|
||||||
|
}
|
||||||
|
|
||||||
|
eOSState cMenuWhatsOn::ProcessKey(eKeys Key)
|
||||||
|
{
|
||||||
|
eOSState state = cOsdMenu::ProcessKey(Key);
|
||||||
|
|
||||||
|
if (state == osUnknown) {
|
||||||
|
switch (Key) {
|
||||||
|
case kRed: return Record();
|
||||||
|
case kYellow: return osBack;
|
||||||
|
case kBlue: return Switch();
|
||||||
|
case kOk: if (Count())
|
||||||
|
return AddSubMenu(new cMenuEvent(((cMenuWhatsOnItem *)Get(Current()))->eventInfo, true));
|
||||||
|
break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- cMenuScheduleItem -----------------------------------------------------
|
||||||
|
|
||||||
|
class cMenuScheduleItem : public cOsdItem {
|
||||||
|
public:
|
||||||
|
const cEventInfo *eventInfo;
|
||||||
|
cMenuScheduleItem(const cEventInfo *EventInfo);
|
||||||
|
};
|
||||||
|
|
||||||
|
cMenuScheduleItem::cMenuScheduleItem(const cEventInfo *EventInfo)
|
||||||
|
{
|
||||||
|
eventInfo = EventInfo;
|
||||||
|
char *buffer = NULL;
|
||||||
|
asprintf(&buffer, "%.*s\t%.*s\t%s", 5, eventInfo->GetDate(), 5, eventInfo->GetTimeString(), eventInfo->GetTitle());
|
||||||
|
SetText(buffer, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- cMenuSchedule ---------------------------------------------------------
|
||||||
|
|
||||||
|
class cMenuSchedule : public cOsdMenu {
|
||||||
|
private:
|
||||||
|
cThreadLock threadLock;
|
||||||
|
const cSchedules *schedules;
|
||||||
|
bool now, next;
|
||||||
|
eOSState Record(void);
|
||||||
|
void PrepareSchedule(void);
|
||||||
|
void PrepareWhatsOnNext(bool On);
|
||||||
|
public:
|
||||||
|
cMenuSchedule(void);
|
||||||
|
virtual eOSState ProcessKey(eKeys Key);
|
||||||
|
};
|
||||||
|
|
||||||
|
cMenuSchedule::cMenuSchedule(void)
|
||||||
|
:cOsdMenu("Schedule", 6, 6)
|
||||||
|
{
|
||||||
|
now = next = false;
|
||||||
|
cChannel *channel = Channels.GetByNumber(CurrentChannel);
|
||||||
|
if (channel) {
|
||||||
|
char *buffer = NULL;
|
||||||
|
asprintf(&buffer, "Schedule - %s", channel->name);
|
||||||
|
SetTitle(buffer, false);
|
||||||
|
}
|
||||||
|
PrepareSchedule();
|
||||||
|
SetHelp("Record", "Now", "Next");
|
||||||
|
}
|
||||||
|
|
||||||
|
static int CompareEventTime(const void *p1, const void *p2)
|
||||||
|
{
|
||||||
|
return (int)((*(cEventInfo **)p1)->GetTime() - (*(cEventInfo **)p2)->GetTime());
|
||||||
|
}
|
||||||
|
|
||||||
|
void cMenuSchedule::PrepareSchedule(void)
|
||||||
|
{
|
||||||
|
schedules = cDvbApi::PrimaryDvbApi->Schedules(&threadLock);
|
||||||
|
if (schedules) {
|
||||||
|
const cSchedule *Schedule = schedules->GetSchedule();
|
||||||
|
int num = Schedule->NumEvents();
|
||||||
|
const cEventInfo **pArray = (const cEventInfo **)malloc(num * sizeof(cEventInfo *));
|
||||||
|
if (pArray) {
|
||||||
|
time_t now = time(NULL);
|
||||||
|
int numreal = 0;
|
||||||
|
for (int a = 0; a < num; a++) {
|
||||||
|
const cEventInfo *EventInfo = Schedule->GetEventNumber(a);
|
||||||
|
if (EventInfo->GetTime() + EventInfo->GetDuration() > now)
|
||||||
|
pArray[numreal++] = EventInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
qsort(pArray, numreal, sizeof(cEventInfo *), CompareEventTime);
|
||||||
|
|
||||||
|
for (int a = 0; a < numreal; a++)
|
||||||
|
Add(new cMenuScheduleItem(pArray[a]));
|
||||||
|
delete pArray;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
eOSState cMenuSchedule::Record(void)
|
||||||
|
{
|
||||||
|
cMenuScheduleItem *item = (cMenuScheduleItem *)Get(Current());
|
||||||
|
if (item) {
|
||||||
|
cTimer *timer = new cTimer(item->eventInfo);
|
||||||
|
Timers.Add(timer);
|
||||||
|
Timers.Save();
|
||||||
|
isyslog(LOG_INFO, "timer %d added", timer->Index() + 1);
|
||||||
|
return AddSubMenu(new cMenuEditTimer(timer->Index(), true));
|
||||||
|
}
|
||||||
|
return osContinue;
|
||||||
|
}
|
||||||
|
|
||||||
|
eOSState cMenuSchedule::ProcessKey(eKeys Key)
|
||||||
|
{
|
||||||
|
eOSState state = cOsdMenu::ProcessKey(Key);
|
||||||
|
|
||||||
|
if (state == osUnknown) {
|
||||||
|
switch (Key) {
|
||||||
|
case kRed: return Record();
|
||||||
|
case kGreen: if (!now && !next) {
|
||||||
|
now = true;
|
||||||
|
return AddSubMenu(new cMenuWhatsOn(schedules, true));
|
||||||
|
}
|
||||||
|
now = !now;
|
||||||
|
next = !next;
|
||||||
|
return AddSubMenu(new cMenuWhatsOn(schedules, now));
|
||||||
|
case kYellow: return AddSubMenu(new cMenuWhatsOn(schedules, false));
|
||||||
|
case kOk: if (Count())
|
||||||
|
return AddSubMenu(new cMenuEvent(((cMenuScheduleItem *)Get(Current()))->eventInfo));
|
||||||
|
break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (!HasSubMenu())
|
||||||
|
now = next = false;
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
|
||||||
// --- cMenuRecordingItem ----------------------------------------------------
|
// --- cMenuRecordingItem ----------------------------------------------------
|
||||||
|
|
||||||
class cMenuRecordingItem : public cOsdItem {
|
class cMenuRecordingItem : public cOsdItem {
|
||||||
@ -1089,6 +1440,9 @@ cMenuSetup::cMenuSetup(void)
|
|||||||
Add(new cMenuEditBoolItem("MarkInstantRecord", &data.MarkInstantRecord));
|
Add(new cMenuEditBoolItem("MarkInstantRecord", &data.MarkInstantRecord));
|
||||||
Add(new cMenuEditIntItem( "LnbFrequLo", &data.LnbFrequLo));
|
Add(new cMenuEditIntItem( "LnbFrequLo", &data.LnbFrequLo));
|
||||||
Add(new cMenuEditIntItem( "LnbFrequHi", &data.LnbFrequHi));
|
Add(new cMenuEditIntItem( "LnbFrequHi", &data.LnbFrequHi));
|
||||||
|
Add(new cMenuEditIntItem( "SetSystemTime", &data.SetSystemTime));
|
||||||
|
Add(new cMenuEditIntItem( "MarginStart", &data.MarginStart));
|
||||||
|
Add(new cMenuEditIntItem( "MarginStop", &data.MarginStop));
|
||||||
}
|
}
|
||||||
|
|
||||||
eOSState cMenuSetup::ProcessKey(eKeys Key)
|
eOSState cMenuSetup::ProcessKey(eKeys Key)
|
||||||
@ -1098,6 +1452,7 @@ eOSState cMenuSetup::ProcessKey(eKeys Key)
|
|||||||
if (state == osUnknown) {
|
if (state == osUnknown) {
|
||||||
switch (Key) {
|
switch (Key) {
|
||||||
case kOk: state = (Setup.PrimaryDVB != data.PrimaryDVB) ? osSwitchDvb : osBack;
|
case kOk: state = (Setup.PrimaryDVB != data.PrimaryDVB) ? osSwitchDvb : osBack;
|
||||||
|
cDvbApi::PrimaryDvbApi->SetUseTSTime(data.SetSystemTime);
|
||||||
Setup = data;
|
Setup = data;
|
||||||
Setup.Save();
|
Setup.Save();
|
||||||
break;
|
break;
|
||||||
@ -1114,6 +1469,7 @@ eOSState cMenuSetup::ProcessKey(eKeys Key)
|
|||||||
cMenuMain::cMenuMain(bool Replaying)
|
cMenuMain::cMenuMain(bool Replaying)
|
||||||
:cOsdMenu("Main")
|
:cOsdMenu("Main")
|
||||||
{
|
{
|
||||||
|
Add(new cOsdItem("Schedule", osSchedule));
|
||||||
Add(new cOsdItem("Channels", osChannels));
|
Add(new cOsdItem("Channels", osChannels));
|
||||||
Add(new cOsdItem("Timer", osTimer));
|
Add(new cOsdItem("Timer", osTimer));
|
||||||
Add(new cOsdItem("Recordings", osRecordings));
|
Add(new cOsdItem("Recordings", osRecordings));
|
||||||
@ -1137,6 +1493,7 @@ eOSState cMenuMain::ProcessKey(eKeys Key)
|
|||||||
eOSState state = cOsdMenu::ProcessKey(Key);
|
eOSState state = cOsdMenu::ProcessKey(Key);
|
||||||
|
|
||||||
switch (state) {
|
switch (state) {
|
||||||
|
case osSchedule: return AddSubMenu(new cMenuSchedule);
|
||||||
case osChannels: return AddSubMenu(new cMenuChannels);
|
case osChannels: return AddSubMenu(new cMenuChannels);
|
||||||
case osTimer: return AddSubMenu(new cMenuTimers);
|
case osTimer: return AddSubMenu(new cMenuTimers);
|
||||||
case osRecordings: return AddSubMenu(new cMenuRecordings);
|
case osRecordings: return AddSubMenu(new cMenuRecordings);
|
||||||
@ -1166,58 +1523,166 @@ eOSState cMenuMain::ProcessKey(eKeys Key)
|
|||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- cDirectChannelSelect --------------------------------------------------
|
// --- cDisplayChannel -------------------------------------------------------
|
||||||
|
|
||||||
#define DIRECTCHANNELTIMEOUT 500 //ms
|
#define DIRECTCHANNELTIMEOUT 500 //ms
|
||||||
|
#define INFOTIMEOUT 5000 //ms
|
||||||
|
|
||||||
cDirectChannelSelect::cDirectChannelSelect(eKeys FirstKey)
|
cDisplayChannel::cDisplayChannel(int Number, bool Switched, bool Group)
|
||||||
|
:cOsdBase(true)
|
||||||
|
{
|
||||||
|
group = Group;
|
||||||
|
withInfo = !group && (!Switched || Setup.ShowInfoOnChSwitch);
|
||||||
|
lines = 0;
|
||||||
|
oldNumber = number = 0;
|
||||||
|
cChannel *channel = Group ? Channels.Get(Number) : Channels.GetByNumber(Number);
|
||||||
|
Interface->Open(MenuColumns, 5);
|
||||||
|
if (channel) {
|
||||||
|
DisplayChannel(channel);
|
||||||
|
DisplayInfo();
|
||||||
|
}
|
||||||
|
lastTime = time_ms();
|
||||||
|
}
|
||||||
|
|
||||||
|
cDisplayChannel::cDisplayChannel(eKeys FirstKey)
|
||||||
:cOsdBase(true)
|
:cOsdBase(true)
|
||||||
{
|
{
|
||||||
oldNumber = CurrentChannel;
|
oldNumber = CurrentChannel;
|
||||||
number = 0;
|
number = 0;
|
||||||
lastTime = time_ms();
|
lastTime = time_ms();
|
||||||
Interface->Open(MenuColumns, 1);
|
Interface->Open(MenuColumns, 5);
|
||||||
ProcessKey(FirstKey);
|
ProcessKey(FirstKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
cDirectChannelSelect::~cDirectChannelSelect()
|
cDisplayChannel::~cDisplayChannel()
|
||||||
{
|
{
|
||||||
if (number < 0)
|
if (number < 0)
|
||||||
Interface->DisplayChannel(oldNumber);
|
Interface->DisplayChannelNumber(oldNumber);
|
||||||
Interface->Close();
|
Interface->Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
eOSState cDirectChannelSelect::ProcessKey(eKeys Key)
|
void cDisplayChannel::DisplayChannel(const cChannel *Channel)
|
||||||
|
{
|
||||||
|
if (!Interface->Recording()) {
|
||||||
|
if (Channel && Channel->number)
|
||||||
|
Interface->DisplayChannelNumber(Channel->number);
|
||||||
|
int BufSize = Width() + 1;
|
||||||
|
char buffer[BufSize];
|
||||||
|
if (Channel && Channel->number)
|
||||||
|
snprintf(buffer, BufSize, "%d %s", Channel->number, Channel->name);
|
||||||
|
else
|
||||||
|
snprintf(buffer, BufSize, "%s", Channel ? Channel->name : "*** Invalid Channel ***");
|
||||||
|
Interface->Fill(0, 0, MenuColumns, 1, clrBackground);
|
||||||
|
Interface->Write(0, 0, buffer);
|
||||||
|
time_t t = time(NULL);
|
||||||
|
struct tm *now = localtime(&t);
|
||||||
|
snprintf(buffer, BufSize, "%02d:%02d", now->tm_hour, now->tm_min);
|
||||||
|
Interface->Write(-5, 0, buffer);
|
||||||
|
Interface->Flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cDisplayChannel::DisplayInfo(void)
|
||||||
|
{
|
||||||
|
if (withInfo) {
|
||||||
|
const cEventInfo *Present = NULL, *Following = NULL;
|
||||||
|
cThreadLock ThreadLock;
|
||||||
|
const cSchedules *Schedules = cDvbApi::PrimaryDvbApi->Schedules(&ThreadLock);
|
||||||
|
if (Schedules) {
|
||||||
|
const cSchedule *Schedule = Schedules->GetSchedule();
|
||||||
|
if (Schedule) {
|
||||||
|
const char *PresentTitle = NULL, *PresentSubtitle = NULL, *FollowingTitle = NULL, *FollowingSubtitle = NULL;
|
||||||
|
int Lines = 0;
|
||||||
|
if ((Present = Schedule->GetPresentEvent()) != NULL) {
|
||||||
|
PresentTitle = Present->GetTitle();
|
||||||
|
if (!isempty(PresentTitle))
|
||||||
|
Lines++;
|
||||||
|
PresentSubtitle = Present->GetSubtitle();
|
||||||
|
if (!isempty(PresentSubtitle))
|
||||||
|
Lines++;
|
||||||
|
}
|
||||||
|
if ((Following = Schedule->GetFollowingEvent()) != NULL) {
|
||||||
|
FollowingTitle = Following->GetTitle();
|
||||||
|
if (!isempty(FollowingTitle))
|
||||||
|
Lines++;
|
||||||
|
FollowingSubtitle = Following->GetSubtitle();
|
||||||
|
if (!isempty(FollowingSubtitle))
|
||||||
|
Lines++;
|
||||||
|
}
|
||||||
|
if (Lines > lines) {
|
||||||
|
const int t = 6;
|
||||||
|
int l = 1;
|
||||||
|
Interface->Fill(0, 1, MenuColumns, Lines, clrBackground);
|
||||||
|
if (!isempty(PresentTitle)) {
|
||||||
|
Interface->Write(0, l, Present->GetTimeString(), clrYellow, clrBackground);
|
||||||
|
Interface->Write(t, l, PresentTitle, clrCyan, clrBackground);
|
||||||
|
l++;
|
||||||
|
}
|
||||||
|
if (!isempty(PresentSubtitle)) {
|
||||||
|
Interface->Write(t, l, PresentSubtitle, clrCyan, clrBackground);
|
||||||
|
l++;
|
||||||
|
}
|
||||||
|
if (!isempty(FollowingTitle)) {
|
||||||
|
Interface->Write(0, l, Following->GetTimeString(), clrYellow, clrBackground);
|
||||||
|
Interface->Write(t, l, FollowingTitle, clrCyan, clrBackground);
|
||||||
|
l++;
|
||||||
|
}
|
||||||
|
if (!isempty(FollowingSubtitle)) {
|
||||||
|
Interface->Write(t, l, FollowingSubtitle, clrCyan, clrBackground);
|
||||||
|
}
|
||||||
|
Interface->Flush();
|
||||||
|
lines = Lines;
|
||||||
|
lastTime = time_ms();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
eOSState cDisplayChannel::ProcessKey(eKeys Key)
|
||||||
{
|
{
|
||||||
switch (Key) {
|
switch (Key) {
|
||||||
case k0 ... k9:
|
case k0:
|
||||||
|
if (number == 0) {
|
||||||
|
// keep the "Toggle channels" function working
|
||||||
|
Interface->PutKey(Key);
|
||||||
|
return osEnd;
|
||||||
|
}
|
||||||
|
case k1 ... k9:
|
||||||
if (number >= 0) {
|
if (number >= 0) {
|
||||||
number = number * 10 + Key - k0;
|
number = number * 10 + Key - k0;
|
||||||
cChannel *channel = Channels.GetByNumber(number);
|
if (number > 0) {
|
||||||
const char *Name = channel ? channel->name : "*** Invalid Channel ***";
|
cChannel *channel = Channels.GetByNumber(number);
|
||||||
int BufSize = MenuColumns + 1;
|
DisplayChannel(channel);
|
||||||
char buffer[BufSize];
|
lastTime = time_ms();
|
||||||
snprintf(buffer, BufSize, "%d %s", number, Name);
|
if (!channel) {
|
||||||
Interface->DisplayChannel(number);
|
number = -1;
|
||||||
Interface->Clear();
|
lastTime += 1000;
|
||||||
Interface->Write(0, 0, buffer);
|
}
|
||||||
lastTime = time_ms();
|
|
||||||
if (!channel) {
|
|
||||||
number = -1;
|
|
||||||
lastTime += 1000;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case kNone:
|
case kNone:
|
||||||
if (time_ms() - lastTime > DIRECTCHANNELTIMEOUT) {
|
if (number && time_ms() - lastTime > DIRECTCHANNELTIMEOUT) {
|
||||||
if (number > 0 && !Channels.SwitchTo(number))
|
if (number > 0 && !Channels.SwitchTo(number))
|
||||||
number = -1;
|
number = -1;
|
||||||
|
return osEnd;
|
||||||
}
|
}
|
||||||
else
|
break;
|
||||||
break;
|
//TODO
|
||||||
default: return osEnd;
|
//XXX case kGreen: return osEventNow;
|
||||||
|
//XXX case kYellow: return osEventNext;
|
||||||
|
case kOk: if (group)
|
||||||
|
Channels.SwitchTo(Channels.Get(Channels.GetNextNormal(CurrentGroup))->number);
|
||||||
|
return osEnd;
|
||||||
|
default: Interface->PutKey(Key);
|
||||||
|
return osEnd;
|
||||||
};
|
};
|
||||||
return osContinue;
|
if (time_ms() - lastTime < INFOTIMEOUT) {
|
||||||
|
DisplayInfo();
|
||||||
|
return osContinue;
|
||||||
|
}
|
||||||
|
return osEnd;
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- cRecordControl --------------------------------------------------------
|
// --- cRecordControl --------------------------------------------------------
|
||||||
|
16
menu.h
16
menu.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: menu.h 1.12 2000/10/08 15:21:52 kls Exp $
|
* $Id: menu.h 1.13 2000/11/01 14:03:09 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _MENU_H
|
#ifndef _MENU_H
|
||||||
@ -24,14 +24,18 @@ public:
|
|||||||
virtual eOSState ProcessKey(eKeys Key);
|
virtual eOSState ProcessKey(eKeys Key);
|
||||||
};
|
};
|
||||||
|
|
||||||
class cDirectChannelSelect : public cOsdBase {
|
class cDisplayChannel : public cOsdBase {
|
||||||
private:
|
private:
|
||||||
int oldNumber;
|
bool withInfo, group;
|
||||||
int number;
|
int lines;
|
||||||
int lastTime;
|
int lastTime;
|
||||||
|
int oldNumber, number;
|
||||||
|
void DisplayChannel(const cChannel *Channel);
|
||||||
|
void DisplayInfo(void);
|
||||||
public:
|
public:
|
||||||
cDirectChannelSelect(eKeys FirstKey);
|
cDisplayChannel(int Number, bool Switched, bool Group = false);
|
||||||
virtual ~cDirectChannelSelect();
|
cDisplayChannel(eKeys FirstKey);
|
||||||
|
virtual ~cDisplayChannel();
|
||||||
virtual eOSState ProcessKey(eKeys Key);
|
virtual eOSState ProcessKey(eKeys Key);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
15
osd.c
15
osd.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: osd.c 1.9 2000/10/08 12:20:34 kls Exp $
|
* $Id: osd.c 1.11 2000/11/01 11:21:51 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "osd.h"
|
#include "osd.h"
|
||||||
@ -24,7 +24,7 @@ cOsdItem::cOsdItem(eOSState State)
|
|||||||
bgColor = clrBackground;
|
bgColor = clrBackground;
|
||||||
}
|
}
|
||||||
|
|
||||||
cOsdItem::cOsdItem(char *Text, eOSState State)
|
cOsdItem::cOsdItem(const char *Text, eOSState State)
|
||||||
{
|
{
|
||||||
text = NULL;
|
text = NULL;
|
||||||
offset = -1;
|
offset = -1;
|
||||||
@ -74,7 +74,7 @@ eOSState cOsdItem::ProcessKey(eKeys Key)
|
|||||||
|
|
||||||
// --- cOsdMenu --------------------------------------------------------------
|
// --- cOsdMenu --------------------------------------------------------------
|
||||||
|
|
||||||
cOsdMenu::cOsdMenu(char *Title, int c0, int c1, int c2, int c3, int c4)
|
cOsdMenu::cOsdMenu(const char *Title, int c0, int c1, int c2, int c3, int c4)
|
||||||
{
|
{
|
||||||
visible = false;
|
visible = false;
|
||||||
title = strdup(Title);
|
title = strdup(Title);
|
||||||
@ -108,6 +108,12 @@ void cOsdMenu::SetStatus(const char *s)
|
|||||||
Interface->Status(status);
|
Interface->Status(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cOsdMenu::SetTitle(const char *Title, bool Copy)
|
||||||
|
{
|
||||||
|
delete title;
|
||||||
|
title = Copy ? strdup(Title) : Title;
|
||||||
|
}
|
||||||
|
|
||||||
void cOsdMenu::SetHelp(const char *Red, const char *Green, const char *Yellow, const char *Blue)
|
void cOsdMenu::SetHelp(const char *Red, const char *Green, const char *Yellow, const char *Blue)
|
||||||
{
|
{
|
||||||
// strings are NOT copied - must be constants!!!
|
// strings are NOT copied - must be constants!!!
|
||||||
@ -164,7 +170,8 @@ void cOsdMenu::Display(void)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Interface->Status(status);
|
if (!isempty(status))
|
||||||
|
Interface->Status(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cOsdMenu::RefreshCurrent(void)
|
void cOsdMenu::RefreshCurrent(void)
|
||||||
|
16
osd.h
16
osd.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: osd.h 1.11 2000/09/10 09:50:38 kls Exp $
|
* $Id: osd.h 1.14 2000/11/01 14:29:07 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __OSD_H
|
#ifndef __OSD_H
|
||||||
@ -19,6 +19,7 @@
|
|||||||
enum eOSState { osUnknown,
|
enum eOSState { osUnknown,
|
||||||
osMenu,
|
osMenu,
|
||||||
osContinue,
|
osContinue,
|
||||||
|
osSchedule,
|
||||||
osChannels,
|
osChannels,
|
||||||
osTimer,
|
osTimer,
|
||||||
osRecordings,
|
osRecordings,
|
||||||
@ -43,13 +44,13 @@ protected:
|
|||||||
eDvbColor fgColor, bgColor;
|
eDvbColor fgColor, bgColor;
|
||||||
public:
|
public:
|
||||||
cOsdItem(eOSState State = osUnknown);
|
cOsdItem(eOSState State = osUnknown);
|
||||||
cOsdItem(char *Text, eOSState State = osUnknown);
|
cOsdItem(const char *Text, eOSState State = osUnknown);
|
||||||
virtual ~cOsdItem();
|
virtual ~cOsdItem();
|
||||||
bool HasUserColor(void) { return userColor; }
|
bool HasUserColor(void) { return userColor; }
|
||||||
void SetText(const char *Text, bool Copy = true);
|
void SetText(const char *Text, bool Copy = true);
|
||||||
void SetColor(eDvbColor FgColor, eDvbColor BgColor = clrBackground);
|
void SetColor(eDvbColor FgColor, eDvbColor BgColor = clrBackground);
|
||||||
const char *Text(void) { return text; }
|
const char *Text(void) { return text; }
|
||||||
void Display(int Offset = -1, eDvbColor FgColor = clrWhite, eDvbColor BgColor = clrBackground);
|
virtual void Display(int Offset = -1, eDvbColor FgColor = clrWhite, eDvbColor BgColor = clrBackground);
|
||||||
virtual void Set(void) {}
|
virtual void Set(void) {}
|
||||||
virtual eOSState ProcessKey(eKeys Key);
|
virtual eOSState ProcessKey(eKeys Key);
|
||||||
};
|
};
|
||||||
@ -60,13 +61,15 @@ protected:
|
|||||||
public:
|
public:
|
||||||
cOsdBase(bool FastResponse = false) { needsFastResponse = FastResponse; }
|
cOsdBase(bool FastResponse = false) { needsFastResponse = FastResponse; }
|
||||||
virtual ~cOsdBase() {}
|
virtual ~cOsdBase() {}
|
||||||
virtual eOSState ProcessKey(eKeys Key) = 0;
|
int Width(void) { return Interface->Width(); }
|
||||||
|
int Height(void) { return Interface->Height(); }
|
||||||
bool NeedsFastResponse(void) { return needsFastResponse; }
|
bool NeedsFastResponse(void) { return needsFastResponse; }
|
||||||
|
virtual eOSState ProcessKey(eKeys Key) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class cOsdMenu : public cOsdBase, public cList<cOsdItem> {
|
class cOsdMenu : public cOsdBase, public cList<cOsdItem> {
|
||||||
private:
|
private:
|
||||||
char *title;
|
const char *title;
|
||||||
int cols[cInterface::MaxCols];
|
int cols[cInterface::MaxCols];
|
||||||
int first, current, marked;
|
int first, current, marked;
|
||||||
cOsdMenu *subMenu;
|
cOsdMenu *subMenu;
|
||||||
@ -83,10 +86,11 @@ protected:
|
|||||||
eOSState AddSubMenu(cOsdMenu *SubMenu);
|
eOSState AddSubMenu(cOsdMenu *SubMenu);
|
||||||
bool HasSubMenu(void) { return subMenu; }
|
bool HasSubMenu(void) { return subMenu; }
|
||||||
void SetStatus(const char *s);
|
void SetStatus(const char *s);
|
||||||
|
void SetTitle(const char *Title, bool Copy = true);
|
||||||
void SetHelp(const char *Red, const char *Green = NULL, const char *Yellow = NULL, const char *Blue = NULL);
|
void SetHelp(const char *Red, const char *Green = NULL, const char *Yellow = NULL, const char *Blue = NULL);
|
||||||
virtual void Del(int Index);
|
virtual void Del(int Index);
|
||||||
public:
|
public:
|
||||||
cOsdMenu(char *Title, int c0 = 0, int c1 = 0, int c2 = 0, int c3 = 0, int c4 = 0);
|
cOsdMenu(const char *Title, int c0 = 0, int c1 = 0, int c2 = 0, int c3 = 0, int c4 = 0);
|
||||||
virtual ~cOsdMenu();
|
virtual ~cOsdMenu();
|
||||||
int Current(void) { return current; }
|
int Current(void) { return current; }
|
||||||
void Add(cOsdItem *Item, bool Current = false);
|
void Add(cOsdItem *Item, bool Current = false);
|
||||||
|
@ -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: recording.c 1.19 2000/10/08 12:20:53 kls Exp $
|
* $Id: recording.c 1.20 2000/11/01 16:00:36 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define _GNU_SOURCE
|
#define _GNU_SOURCE
|
||||||
@ -86,6 +86,13 @@ cRecording::cRecording(cTimer *Timer)
|
|||||||
titleBuffer = NULL;
|
titleBuffer = NULL;
|
||||||
fileName = NULL;
|
fileName = NULL;
|
||||||
name = strdup(Timer->file);
|
name = strdup(Timer->file);
|
||||||
|
// substitute characters that would cause problems in file names:
|
||||||
|
for (char *p = name; *p; p++) {
|
||||||
|
switch (*p) {
|
||||||
|
case '\n': *p = ' '; break;
|
||||||
|
case '/': *p = '-'; break;
|
||||||
|
}
|
||||||
|
}
|
||||||
summary = Timer->summary ? strdup(Timer->summary) : NULL;
|
summary = Timer->summary ? strdup(Timer->summary) : NULL;
|
||||||
if (summary)
|
if (summary)
|
||||||
strreplace(summary, '|', '\n');
|
strreplace(summary, '|', '\n');
|
||||||
|
@ -1,7 +0,0 @@
|
|||||||
# VDR Setup
|
|
||||||
PrimaryDVB = 1
|
|
||||||
ShowInfoOnChSwitch = 1
|
|
||||||
MenuScrollPage = 1
|
|
||||||
MarkInstantRecord = 1
|
|
||||||
LnbFrequLo = 9750
|
|
||||||
LnbFrequHi = 10600
|
|
19
thread.c
19
thread.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: thread.c 1.2 2000/10/08 16:45:50 kls Exp $
|
* $Id: thread.c 1.3 2000/10/28 15:26:02 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "thread.h"
|
#include "thread.h"
|
||||||
@ -88,16 +88,27 @@ void cThread::WakeUp(void)
|
|||||||
|
|
||||||
cThreadLock::cThreadLock(cThread *Thread)
|
cThreadLock::cThreadLock(cThread *Thread)
|
||||||
{
|
{
|
||||||
thread = Thread;
|
thread = NULL;
|
||||||
locked = Thread->Lock();
|
locked = false;
|
||||||
|
Lock(Thread);
|
||||||
}
|
}
|
||||||
|
|
||||||
cThreadLock::~cThreadLock()
|
cThreadLock::~cThreadLock()
|
||||||
{
|
{
|
||||||
if (locked)
|
if (thread && locked)
|
||||||
thread->Unlock();
|
thread->Unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool cThreadLock::Lock(cThread *Thread)
|
||||||
|
{
|
||||||
|
if (Thread && !thread) {
|
||||||
|
thread = Thread;
|
||||||
|
locked = Thread->Lock();
|
||||||
|
return locked;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool cThreadLock::Locked(void)
|
bool cThreadLock::Locked(void)
|
||||||
{
|
{
|
||||||
return locked;
|
return locked;
|
||||||
|
5
thread.h
5
thread.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: thread.h 1.1 2000/10/08 08:36:21 kls Exp $
|
* $Id: thread.h 1.2 2000/10/28 15:08:09 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __THREAD_H
|
#ifndef __THREAD_H
|
||||||
@ -47,8 +47,9 @@ private:
|
|||||||
cThread *thread;
|
cThread *thread;
|
||||||
bool locked;
|
bool locked;
|
||||||
public:
|
public:
|
||||||
cThreadLock(cThread *Thread);
|
cThreadLock(cThread *Thread = NULL);
|
||||||
~cThreadLock();
|
~cThreadLock();
|
||||||
|
bool Lock(cThread *Thread);
|
||||||
bool Locked(void);
|
bool Locked(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
13
timers.conf
13
timers.conf
@ -1,16 +1,15 @@
|
|||||||
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:
|
1:10:-T-----:2058:2202:99:10:Quarks:
|
||||||
1:26:-T-----:2320:0040:99:99:UFO:
|
1:26:-T-----:2250:0005:99:99:UFO:
|
||||||
1:14:--W----:1920:2020:99:99:Rettungsflieger:
|
1:14:--W----:1920:2020:99:99:Rettungsflieger:
|
||||||
1:2:--W----:2110:2325:99:99:BulleVonToelz:
|
0:2:--W----:2110:2325:99:99:BulleVonToelz:
|
||||||
1:3:---T---:2210:2315:99:10:IngoAppelt:
|
1:3:---T---:2210:2315:99:10:IngoAppelt:
|
||||||
0:2:----F--:2140:2225:10:10:WWW:
|
1:2:----F--:2013:2125:99:99:Farscape:
|
||||||
1:1:----F--:2212:2325:99:99:7Tage7Koepfe:
|
1:1:----F--:2215:2325:99:99:7Tage7Koepfe:
|
||||||
1:11:-----S-:2058:2135:99:99:Computer:
|
1:11:-----S-:2058:2135:99:99:Computer:
|
||||||
1:2:-----S-:2211:2340:99:30:Wochenshow:
|
1:2:-----S-:2250:0005:99:30:Wochenshow:
|
||||||
1:11:------S:2013:2035: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:MTWTF--:1553:1710:99:99:Hammerman:
|
1:1:MTWTF--:1553:1710:99:99:Hammerman:
|
||||||
|
1:3:3:0220:0350:99:99:Seven Days - Das Tor zur Zeit:Die Rache des Alien||Als das Zeitsprung-Team die Leiche eines bei Roswell gefundenen Aliens obduziert, entdecken sie einen Chip in seiner Wirbelsäule. Dr. Ballard, der ähnliche Rückenprobleme wie der Alien hat, lässt sich den Chip einsetzen. Tatsächlich regeneriert Ballard vollständig. Doch dann ändert sich sein Verhalten: Er wird dem Alien immer ähnlicher. Schließlich gelingt es ihm, mit einer Superwaffe Millionen Menschen zu töten - einschließlich des Zeitsprung-Teams. Nur Parker überlebt.
|
||||||
|
15
tools.c
15
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.21 2000/10/07 18:02:24 kls Exp $
|
* $Id: tools.c 1.22 2000/10/29 11:21:55 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define _GNU_SOURCE
|
#define _GNU_SOURCE
|
||||||
@ -85,11 +85,16 @@ char *strreplace(char *s, char c1, char c2)
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *skipspace(char *s)
|
char *skipspace(const char *s)
|
||||||
{
|
{
|
||||||
while (*s && isspace(*s))
|
while (*s && isspace(*s))
|
||||||
s++;
|
s++;
|
||||||
return s;
|
return (char *)s;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isempty(const char *s)
|
||||||
|
{
|
||||||
|
return !(s && *skipspace(s));
|
||||||
}
|
}
|
||||||
|
|
||||||
int time_ms(void)
|
int time_ms(void)
|
||||||
@ -520,7 +525,7 @@ void cListBase::Clear(void)
|
|||||||
objects = lastObject = NULL;
|
objects = lastObject = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
cListObject *cListBase::Get(int Index)
|
cListObject *cListBase::Get(int Index) const
|
||||||
{
|
{
|
||||||
if (Index < 0)
|
if (Index < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -530,7 +535,7 @@ cListObject *cListBase::Get(int Index)
|
|||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
int cListBase::Count(void)
|
int cListBase::Count(void) const
|
||||||
{
|
{
|
||||||
int n = 0;
|
int n = 0;
|
||||||
cListObject *object = objects;
|
cListObject *object = objects;
|
||||||
|
19
tools.h
19
tools.h
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'vdr.c' for copyright information and
|
* See the main source file 'vdr.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: tools.h 1.17 2000/10/07 18:00:21 kls Exp $
|
* $Id: tools.h 1.18 2000/10/29 11:19:20 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __TOOLS_H
|
#ifndef __TOOLS_H
|
||||||
@ -40,7 +40,8 @@ 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);
|
||||||
char *strreplace(char *s, char c1, char c2);
|
char *strreplace(char *s, char c1, char c2);
|
||||||
char *skipspace(char *s);
|
char *skipspace(const char *s);
|
||||||
|
bool isempty(const 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);
|
||||||
@ -80,8 +81,8 @@ public:
|
|||||||
void Append(cListObject *Object);
|
void Append(cListObject *Object);
|
||||||
void Unlink(void);
|
void Unlink(void);
|
||||||
int Index(void);
|
int Index(void);
|
||||||
cListObject *Prev(void) { return prev; }
|
cListObject *Prev(void) const { return prev; }
|
||||||
cListObject *Next(void) { return next; }
|
cListObject *Next(void) const { return next; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class cListBase {
|
class cListBase {
|
||||||
@ -95,15 +96,15 @@ public:
|
|||||||
virtual void Move(int From, int To);
|
virtual void Move(int From, int To);
|
||||||
void Move(cListObject *From, cListObject *To);
|
void Move(cListObject *From, cListObject *To);
|
||||||
void Clear(void);
|
void Clear(void);
|
||||||
cListObject *Get(int Index);
|
cListObject *Get(int Index) const;
|
||||||
int Count(void);
|
int Count(void) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class T> class cList : public cListBase {
|
template<class T> class cList : public cListBase {
|
||||||
public:
|
public:
|
||||||
T *Get(int Index) { return (T *)cListBase::Get(Index); }
|
T *Get(int Index) const { return (T *)cListBase::Get(Index); }
|
||||||
T *First(void) { return (T *)objects; }
|
T *First(void) const { return (T *)objects; }
|
||||||
T *Next(T *object) { return (T *)object->Next(); }
|
T *Next(const T *object) const { return (T *)object->Next(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //__TOOLS_H
|
#endif //__TOOLS_H
|
||||||
|
24
vdr.c
24
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.39 2000/10/08 14:49:25 kls Exp $
|
* $Id: vdr.c 1.41 2000/11/01 14:31:32 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
@ -161,10 +161,6 @@ int main(int argc, char *argv[])
|
|||||||
if (!cDvbApi::Init())
|
if (!cDvbApi::Init())
|
||||||
abort();
|
abort();
|
||||||
|
|
||||||
// User interface:
|
|
||||||
|
|
||||||
Interface = new cInterface(SVDRPport);
|
|
||||||
|
|
||||||
// Configuration data:
|
// Configuration data:
|
||||||
|
|
||||||
if (!ConfigDirectory)
|
if (!ConfigDirectory)
|
||||||
@ -176,14 +172,21 @@ int main(int argc, char *argv[])
|
|||||||
#ifdef REMOTE_LIRC
|
#ifdef REMOTE_LIRC
|
||||||
Keys.SetDummyValues();
|
Keys.SetDummyValues();
|
||||||
#else
|
#else
|
||||||
if (!Keys.Load(AddDirectory(ConfigDirectory, KEYS_CONF)))
|
bool KeysLoaded = Keys.Load(AddDirectory(ConfigDirectory, KEYS_CONF));
|
||||||
Interface->LearnKeys();
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
cDvbApi::SetPrimaryDvbApi(Setup.PrimaryDVB);
|
cDvbApi::SetPrimaryDvbApi(Setup.PrimaryDVB);
|
||||||
|
|
||||||
Channels.SwitchTo(CurrentChannel);
|
Channels.SwitchTo(CurrentChannel);
|
||||||
|
|
||||||
|
// User interface:
|
||||||
|
|
||||||
|
Interface = new cInterface(SVDRPport);
|
||||||
|
#ifndef REMOTE_LIRC
|
||||||
|
if (!KeysLoaded)
|
||||||
|
Interface->LearnKeys();
|
||||||
|
#endif
|
||||||
|
|
||||||
// Signal handlers:
|
// Signal handlers:
|
||||||
|
|
||||||
if (signal(SIGHUP, SignalHandler) == SIG_IGN) signal(SIGHUP, SIG_IGN);
|
if (signal(SIGHUP, SignalHandler) == SIG_IGN) signal(SIGHUP, SIG_IGN);
|
||||||
@ -202,7 +205,7 @@ int main(int argc, char *argv[])
|
|||||||
// Channel display:
|
// Channel display:
|
||||||
if (CurrentChannel != LastChannel) {
|
if (CurrentChannel != LastChannel) {
|
||||||
if (!Menu)
|
if (!Menu)
|
||||||
Channels.ShowChannel(CurrentChannel, LastChannel > 0);
|
Menu = new cDisplayChannel(CurrentChannel, LastChannel > 0);
|
||||||
PreviousChannel = LastChannel;
|
PreviousChannel = LastChannel;
|
||||||
LastChannel = CurrentChannel;
|
LastChannel = CurrentChannel;
|
||||||
}
|
}
|
||||||
@ -262,7 +265,7 @@ int main(int argc, char *argv[])
|
|||||||
// Direct Channel Select:
|
// Direct Channel Select:
|
||||||
case k1 ... k9:
|
case k1 ... k9:
|
||||||
if (!Interface->Recording())
|
if (!Interface->Recording())
|
||||||
Menu = new cDirectChannelSelect(key);
|
Menu = new cDisplayChannel(key);
|
||||||
break;
|
break;
|
||||||
// Left/Right rotates trough channel groups:
|
// Left/Right rotates trough channel groups:
|
||||||
case kLeft|k_Repeat:
|
case kLeft|k_Repeat:
|
||||||
@ -276,8 +279,7 @@ int main(int argc, char *argv[])
|
|||||||
CurrentGroup = Channels.GetPrevGroup(CurrentGroup < 1 ? 1 : CurrentGroup);
|
CurrentGroup = Channels.GetPrevGroup(CurrentGroup < 1 ? 1 : CurrentGroup);
|
||||||
if (CurrentGroup < 0)
|
if (CurrentGroup < 0)
|
||||||
CurrentGroup = SaveGroup;
|
CurrentGroup = SaveGroup;
|
||||||
if (Channels.ShowChannel(CurrentGroup, false, true) == kOk)
|
Menu = new cDisplayChannel(CurrentGroup, false, true);
|
||||||
Channels.SwitchTo(Channels.Get(Channels.GetNextNormal(CurrentGroup))->number);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
// Up/Down Channel Select:
|
// Up/Down Channel Select:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user