mirror of
https://github.com/VDR4Arch/vdr.git
synced 2023-10-10 13:36:52 +02:00
Implemented actual record/replay; support for CICAM
This commit is contained in:
parent
571686d909
commit
735093b8fa
23
BUGS
Normal file
23
BUGS
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
Video Disk Recorder - Known Bugs
|
||||||
|
--------------------------------
|
||||||
|
|
||||||
|
* Sometimes picture and sound drift apart.
|
||||||
|
Presumably this is a problem in the card driver or firmware?
|
||||||
|
|
||||||
|
* When the on-screen display is activated during recording,
|
||||||
|
the video data stream gets corrupted, which results in a
|
||||||
|
distorted picture when replaying such a recording.
|
||||||
|
I assume this is a problem in the driver of firmware.
|
||||||
|
There is no such problem in replay mode.
|
||||||
|
|
||||||
|
* After a replay session the screen may go blank.
|
||||||
|
Haven't figured out yet how to ensure that it switches back to
|
||||||
|
the current channel.
|
||||||
|
|
||||||
|
* Every now and then the on-screen display shows nothing but
|
||||||
|
"noise". If that occurs, I have to stop the 'osm' program
|
||||||
|
and do a 'make reload' for the card driver. After that it
|
||||||
|
works fine again.
|
||||||
|
Presumably this is a problem in the card driver or firmware?
|
||||||
|
Or could it be a problem with the hardware?
|
||||||
|
Does anybody else observe this?
|
8
HISTORY
8
HISTORY
@ -10,3 +10,11 @@ Video Disk Recorder OSM Revision History
|
|||||||
- Support for "Red", "Green", "Yellow", "Blue" buttons.
|
- Support for "Red", "Green", "Yellow", "Blue" buttons.
|
||||||
- Channels and Timers can now be added, deleted and moved.
|
- Channels and Timers can now be added, deleted and moved.
|
||||||
- Basic record/play file handling support (no actual record/playback yet).
|
- Basic record/play file handling support (no actual record/playback yet).
|
||||||
|
|
||||||
|
2000-04-15: Version 0.03
|
||||||
|
|
||||||
|
- Actual record/replay now works.
|
||||||
|
- Dropped the idea of different "recording qualities" (a 36GB harddisk is
|
||||||
|
able to store some 18 hours in full quality, so we don't really need that).
|
||||||
|
- Termination signals are now caught and the program cleans up before exiting.
|
||||||
|
- Support for CICAM.
|
||||||
|
39
MANUAL
Normal file
39
MANUAL
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
Video Disk Recorder User's Manual
|
||||||
|
---------------------------------
|
||||||
|
|
||||||
|
* Selecting a Channel
|
||||||
|
|
||||||
|
You can select a channel either by pressing the "Up" or "Down" key (while
|
||||||
|
no On Screen Menu is displayed), or browsing through the channel list in
|
||||||
|
the menu and pressing "Ok" on the desired channel.
|
||||||
|
|
||||||
|
* Instant Recording
|
||||||
|
|
||||||
|
You can start recording the current channel by pressing the "Record"
|
||||||
|
button. This will create a timer event named "instant" that start
|
||||||
|
at the current time and records for two hours.
|
||||||
|
If you want to modify the recording time you need to edit the timer.
|
||||||
|
Stop instant recording by disabling or deleting the timer.
|
||||||
|
|
||||||
|
* Replaying a Recording
|
||||||
|
|
||||||
|
All recordings are listed in the "Recordings" menu. Browse through the
|
||||||
|
list with the "Up" and "Down" button and press "Ok" (or the "Red" button)
|
||||||
|
to start playback.
|
||||||
|
|
||||||
|
* Replay Control
|
||||||
|
|
||||||
|
- "Begin" Positions to beginning of the recording and starts playback
|
||||||
|
from there.
|
||||||
|
- "Pause" Halts playback at the current frame. Press again to continue
|
||||||
|
playback.
|
||||||
|
- "Stop" Stops playback and stores the current position, so that
|
||||||
|
playback can be resumed later at that point.
|
||||||
|
- "Search" Runs playback forward or backward at a higher speed. Press
|
||||||
|
again to resume normal speed.
|
||||||
|
- "Skip" Skips about 60 seconds forward or backward.
|
||||||
|
|
||||||
|
* Programming the Timer
|
||||||
|
|
||||||
|
Use the "Timer" menu to maintain your list of timer controlled recordings.
|
||||||
|
|
72
README
72
README
@ -36,34 +36,13 @@ about that driver). For example, if the DVB driver was
|
|||||||
extracted into the directory /home/kls/vdr/DVB, then this
|
extracted into the directory /home/kls/vdr/DVB, then this
|
||||||
package should be extracted into /home/kls/vdr/OSM.
|
package should be extracted into /home/kls/vdr/OSM.
|
||||||
|
|
||||||
In order for the menu colors to work correctly you may want
|
This program requires the card driver version 0.04 or higher
|
||||||
to replace the function RGB2YUV() in DVB/driver/dvb.c with
|
to work properly.
|
||||||
|
|
||||||
static u32 RGB2YUV(u16 R, u16 G, u16 B)
|
|
||||||
{
|
|
||||||
u16 y, u, v;
|
|
||||||
u16 Y, Cr, Cb;
|
|
||||||
|
|
||||||
y = R * 77 + G * 150 + B * 29; // Luma=0.299R+0.587G+0.114B 0..65535
|
|
||||||
u = 2048+B * 8 -(y>>5); // Cr 0..4095
|
|
||||||
v = 2048+R * 8 -(y>>5); // Cb 0..4095
|
|
||||||
|
|
||||||
Y = y >> 8;
|
|
||||||
Cb= u >> 4;
|
|
||||||
Cr= v >> 4;
|
|
||||||
|
|
||||||
return Cr|(Cb<<16)|(Y<<8);
|
|
||||||
}
|
|
||||||
|
|
||||||
(this may no longer be necessary with driver versions after 0.03c).
|
|
||||||
|
|
||||||
After extracting the package, change into the OSM directory
|
After extracting the package, change into the OSM directory
|
||||||
and type 'make'. This should produce an executable file
|
and type 'make'. This should produce an executable file
|
||||||
named 'osm', which can be run after the DVB driver has been
|
named 'osm', which can be run after the DVB driver has been
|
||||||
installed. There may be several warnings about "implicit declaration
|
installed.
|
||||||
of function `int asprintf(...)'" during the compilation, which I was
|
|
||||||
unable to avoid (anybody know how to avoid them?). Just ignore them,
|
|
||||||
the program will work, anyway.
|
|
||||||
|
|
||||||
There are two macros you can use to customize the 'osm' program
|
There are two macros you can use to customize the 'osm' program
|
||||||
at compile time. Adding "DEBUG_REMOTE=1" to the 'make' call
|
at compile time. Adding "DEBUG_REMOTE=1" to the 'make' call
|
||||||
@ -88,28 +67,43 @@ The meaning of the data entries may still vary in future releases,
|
|||||||
so for the moment please look at the source code (config.c) to see
|
so for the moment please look at the source code (config.c) to see
|
||||||
the meaning of the various fields.
|
the meaning of the various fields.
|
||||||
|
|
||||||
There is no way of adding or deleting channels or timers yet, this
|
|
||||||
will be implemented later.
|
|
||||||
|
|
||||||
Learning the remote control keys:
|
Learning the remote control keys:
|
||||||
---------------------------------
|
---------------------------------
|
||||||
|
|
||||||
The remote control configuration file 'keys.conf' that comes with
|
There is no default 'keys.conf' file, so if you compile the program
|
||||||
this package contains the codes for the "d-box" remote control unit.
|
without 'DEBUG_REMOTE=1' you will have to go through a "teach-in"
|
||||||
If you want to use a different remote control unit, simply delete
|
session that allows the program to learn your remote control codes.
|
||||||
the file 'keys.conf' and restart the 'osm' program. The program will
|
It will first attempt to determine the basic data transfer mode and
|
||||||
then start a key learning session in which it first attempts to determine
|
timing of your remote control unit, and then will ask you to press one
|
||||||
the basic data transfer mode and timing of your remote control unit,
|
key after the other so that it can learn the various key codes. You will
|
||||||
and then will ask you to press one key after the other so that it can
|
at least need to provide an "Up" and a "Down" key, so that you can switch
|
||||||
learn the various key codes. You will at least need to provide an "Up"
|
channels. The rest of the key definitions is optional, but the more keys
|
||||||
and a "Down" key, so that you can switch channels. The rest of the key
|
you define, the more you will be able to navigate through the menus and
|
||||||
definitions is optional, but the more keys you define, the more you
|
control recording/replaying.
|
||||||
will be able to navigate through the menus.
|
|
||||||
|
|
||||||
If the program has been built with "DEBUG_REMOTE=1", it will use the
|
If the program has been built with "DEBUG_REMOTE=1", it will use the
|
||||||
key configuration file 'keys-pc.conf', so that you won't loose data
|
key configuration file 'keys-pc.conf', so that you won't loose data
|
||||||
when switching between normal and debug mode.
|
when switching between normal and debug mode.
|
||||||
|
|
||||||
|
The default PC key assignments are:
|
||||||
|
|
||||||
|
Up, Down, Left, Right Crsr keys in numeric block
|
||||||
|
Menu '5' in numeric block
|
||||||
|
Ok Enter
|
||||||
|
Back Backspace
|
||||||
|
0..9 '0'..'9' in top row
|
||||||
|
Red, Green, Yellow, Blue 'F1'..'F4'
|
||||||
|
Record 'r'
|
||||||
|
Pause 'p'
|
||||||
|
Stop 's'
|
||||||
|
Begin 'B'
|
||||||
|
SearchForward 'f'
|
||||||
|
SearchBack 'b'
|
||||||
|
SkipForward 'PgDn' in numeric block
|
||||||
|
SkipBack 'PgUp' in numeric block
|
||||||
|
|
||||||
|
If you prefer different key assignments, simply delete the file
|
||||||
|
'keys-pc.conf' and restart 'osm' to get into learning mode.
|
||||||
|
|
||||||
Navigating through the On Screen Menus:
|
Navigating through the On Screen Menus:
|
||||||
---------------------------------------
|
---------------------------------------
|
||||||
|
|
||||||
|
6
TODO
6
TODO
@ -1,7 +1,7 @@
|
|||||||
TODO list for the Video Disk Recorder project
|
TODO list for the Video Disk Recorder project
|
||||||
---------------------------------------------
|
---------------------------------------------
|
||||||
|
|
||||||
* Implement recording to disk and playback from disk.
|
* Channel select via numeric keys.
|
||||||
* Make it work with two DVB-S PCI cards to allow simultaneous
|
* Make it work with two DVB-S PCI cards to allow simultaneous
|
||||||
recording of one programme, while replaying another programme
|
recording of one programme, while replaying another programme
|
||||||
(or maybe the same one, but time delayed).
|
(or maybe the same one, but time delayed).
|
||||||
@ -10,3 +10,7 @@ TODO list for the Video Disk Recorder project
|
|||||||
* Implement "on-disk editing" to allow "cutting out" of certain
|
* Implement "on-disk editing" to allow "cutting out" of certain
|
||||||
scenes in order to archive them (or, reversely, cut out
|
scenes in order to archive them (or, reversely, cut out
|
||||||
commercial breaks).
|
commercial breaks).
|
||||||
|
* Implement on-screen display of replay progress (progress bar
|
||||||
|
and/or time index).
|
||||||
|
* Implement channel scanning.
|
||||||
|
* Better support for encrypted channels.
|
||||||
|
218
channels.conf
218
channels.conf
@ -1,109 +1,109 @@
|
|||||||
RTL:12188:h:1:27500:163:104
|
RTL:12188:h:1:27500:163:104:0:0
|
||||||
Sat.1:12552:v:1:22000:163:104
|
Sat.1:12552:v:1:22000:163:104:0:0
|
||||||
Pro 7:12480:v:1:27500:255:256
|
Pro 7:12480:v:1:27500:255:256:0:0
|
||||||
RTL2:12188:h:1:27500:166:128
|
RTL2:12188:h:1:27500:166:128:0:0
|
||||||
ARD:11837:h:1:27500:101:102
|
ARD:11837:h:1:27500:101:102:0:0
|
||||||
BR3:11837:h:1:27500:201:202
|
BR3:11837:h:1:27500:201:202:0:0
|
||||||
Hessen 3:11837:h:1:27500:301:302
|
Hessen 3:11837:h:1:27500:301:302:0:0
|
||||||
N3:11837:h:1:27500:401:402
|
N3:11837:h:1:27500:401:402:0:0
|
||||||
SR3:11837:h:1:27500:501:502
|
SR3:11837:h:1:27500:501:502:0:0
|
||||||
WDR:11837:h:1:27500:601:602
|
WDR:11837:h:1:27500:601:602:0:0
|
||||||
BR alpha:11837:h:1:27500:701:702
|
BR alpha:11837:h:1:27500:701:702:0:0
|
||||||
SWR BW:11837:h:1:27500:801:802
|
SWR BW:11837:h:1:27500:801:802:0:0
|
||||||
Phoenix:11837:h:1:27500:901:902
|
Phoenix:11837:h:1:27500:901:902:0:0
|
||||||
ZDF:11954:h:1:27500:110:120
|
ZDF:11954:h:1:27500:110:120:0:0
|
||||||
3sat:11954:h:1:27500:210:220
|
3sat:11954:h:1:27500:210:220:0:0
|
||||||
Kinderkanal:11954:h:1:27500:310:320
|
Kinderkanal:11954:h:1:27500:310:320:0:0
|
||||||
arte:11954:h:1:27500:360:370
|
arte:11954:h:1:27500:360:370:0:0
|
||||||
phoenix:11954:h:1:27500:410:420
|
phoenix:11954:h:1:27500:410:420:0:0
|
||||||
ORF Sat:11954:h:1:27500:506:507
|
ORF Sat:11954:h:1:27500:506:507:0:0
|
||||||
ZDF Infobox:11954:h:1:27500:610:620
|
ZDF Infobox:11954:h:1:27500:610:620:0:0
|
||||||
CNN:12168:v:1:27500:165:100
|
CNN:12168:v:1:27500:165:100:0:0
|
||||||
Super RTL:12188:h:1:27500:165:120
|
Super RTL:12188:h:1:27500:165:120:0:0
|
||||||
VOX:12188:h:1:27500:167:136
|
VOX:12188:h:1:27500:167:136:0:0
|
||||||
DW TV:12363:v:1:27500:305:306
|
DW TV:12363:v:1:27500:305:306:0:0
|
||||||
Kabel 1:12480:v:1:27500:511:512
|
Kabel 1:12480:v:1:27500:511:512:0:0
|
||||||
TM3:12480:v:1:27500:767:768
|
TM3:12480:v:1:27500:767:768:0:0
|
||||||
DSF:12480:v:1:27500:1023:1024
|
DSF:12480:v:1:27500:1023:1024:0:0
|
||||||
HOT:12480:v:1:27500:1279:1280
|
HOT:12480:v:1:27500:1279:1280:0:0
|
||||||
BloombergTV:12552:v:1:22000:162:99
|
BloombergTV:12552:v:1:22000:162:99:0:0
|
||||||
Sky News:12552:v:1:22000:305:306
|
Sky News:12552:v:1:22000:305:306:0:0
|
||||||
KinderNet:12574:h:1:22000:163:92
|
KinderNet:12574:h:1:22000:163:92:0:0
|
||||||
Alice:12610:v:1:22000:162:96
|
Alice:12610:v:1:22000:162:96:0:0
|
||||||
n-tv:12670:v:1:22000:162:96
|
n-tv:12670:v:1:22000:162:96:0:0
|
||||||
Grand Tour.:12670:v:1:22000:289:290
|
Grand Tour.:12670:v:1:22000:289:290:0:0
|
||||||
TW1:12692:h:1:22000:166:167
|
TW1:12692:h:1:22000:166:167:0:0
|
||||||
Eins Extra:12722:h:1:22000:101:102
|
Eins Extra:12722:h:1:22000:101:102:0:0
|
||||||
Eins Festival:12722:h:1:22000:201:202
|
Eins Festival:12722:h:1:22000:201:202:0:0
|
||||||
Eins MuXx:12722:h:1:22000:301:302
|
Eins MuXx:12722:h:1:22000:301:302:0:0
|
||||||
MDR:12722:h:1:22000:401:402
|
MDR:12722:h:1:22000:401:402:0:0
|
||||||
ORB:12722:h:1:22000:501:502
|
ORB:12722:h:1:22000:501:502:0:0
|
||||||
B1:12722:h:1:22000:601:602
|
B1:12722:h:1:22000:601:602:0:0
|
||||||
ARD Online-Kanal:12722:h:1:22000:8191:701
|
ARD Online-Kanal:12722:h:1:22000:8191:701:0:0
|
||||||
Premiere World Promo:11798:h:1:27500:255:256
|
Premiere World Promo:11798:h:1:27500:255:256:0:0
|
||||||
TV Niepokalanow:11876:h:1:27500:305:321
|
TV Niepokalanow:11876:h:1:27500:305:321:0:0
|
||||||
test card:11798:h:1:27500:511:512
|
Premiere:11798:h:1:27500:1023:1024:1:10
|
||||||
Mosaico:11934:v:1:27500:165:100
|
Mosaico:11934:v:1:27500:165:100:0:0
|
||||||
Andalucia TV:11934:v:1:27500:166:104
|
Andalucia TV:11934:v:1:27500:166:104:0:0
|
||||||
TVC Internacional:11934:v:1:27500:167:108
|
TVC Internacional:11934:v:1:27500:167:108:0:0
|
||||||
Nasza TV:11992:h:1:27500:165:98
|
Nasza TV:11992:h:1:27500:165:98:0:0
|
||||||
WishLine test:12012:v:1:27500:163:90
|
WishLine test:12012:v:1:27500:163:90:0:0
|
||||||
Pro 7 Austria:12051:v:1:27500:161:84
|
Pro 7 Austria:12051:v:1:27500:161:84:0:0
|
||||||
Kabel 1 Schweiz:12051:v:1:27500:162:163
|
Kabel 1 Schweiz:12051:v:1:27500:162:163:0:0
|
||||||
Kabel 1 Austria:12051:v:1:27500:166:167
|
Kabel 1 Austria:12051:v:1:27500:166:167:0:0
|
||||||
Pro 7 Schweiz:12051:v:1:27500:289:290
|
Pro 7 Schweiz:12051:v:1:27500:289:290:0:0
|
||||||
Kiosque:12129:v:1:27500:160:80
|
Kiosque:12129:v:1:27500:160:80:0:0
|
||||||
KTO:12129:v:1:27500:170:120
|
KTO:12129:v:1:27500:170:120:0:0
|
||||||
TCM:12168:v:1:27500:160:80
|
TCM:12168:v:1:27500:160:80:0:0
|
||||||
Cartoon Network France & Spain:12168:v:1:27500:161:84
|
Cartoon Network France & Spain:12168:v:1:27500:161:84:0:0
|
||||||
TVBS Europe:12168:v:1:27500:162:88
|
TVBS Europe:12168:v:1:27500:162:88:0:0
|
||||||
TVBS Europe:12168:v:1:27500:162:89
|
TVBS Europe:12168:v:1:27500:162:89:0:0
|
||||||
Travel:12168:v:1:27500:163:92
|
Travel:12168:v:1:27500:163:92:0:0
|
||||||
TCM Espania:12168:v:1:27500:164:96
|
TCM Espania:12168:v:1:27500:164:96:0:0
|
||||||
MTV Spain:12168:v:1:27500:167:112
|
MTV Spain:12168:v:1:27500:167:112:0:0
|
||||||
TCM France:12168:v:1:27500:169:64
|
TCM France:12168:v:1:27500:169:64:0:0
|
||||||
RTL2 CH:12188:h:1:27500:164:112
|
RTL2 CH:12188:h:1:27500:164:112:0:0
|
||||||
La Cinquieme:12207:v:1:27500:160:80
|
La Cinquieme:12207:v:1:27500:160:80:0:0
|
||||||
ARTE:12207:v:1:27500:165:100
|
ARTE:12207:v:1:27500:165:100:0:0
|
||||||
Post Filial TV:12226:h:1:27500:255:256
|
Post Filial TV:12226:h:1:27500:255:256:0:0
|
||||||
Canal Canaris:12246:v:1:27500:160:80
|
Canal Canaris:12246:v:1:27500:160:80:0:0
|
||||||
Canal Canaris:12246:v:1:27500:160:81
|
Canal Canaris:12246:v:1:27500:160:81:0:0
|
||||||
Canal Canaris:12246:v:1:27500:160:82
|
Canal Canaris:12246:v:1:27500:160:82:0:0
|
||||||
Canal Canaris:12246:v:1:27500:160:83
|
Canal Canaris:12246:v:1:27500:160:83:0:0
|
||||||
AB Sat Passion promo:12266:h:1:27500:160:80
|
AB Sat Passion promo:12266:h:1:27500:160:80:0:0
|
||||||
AB Channel 1:12266:h:1:27500:161:84
|
AB Channel 1:12266:h:1:27500:161:84:0:0
|
||||||
Taquilla 0:12285:v:1:27500:165:100
|
Taquilla 0:12285:v:1:27500:165:100:0:0
|
||||||
CSAT:12324:v:1:27500:160:80
|
CSAT:12324:v:1:27500:160:80:0:0
|
||||||
Mosaique:12324:v:1:27500:162:88
|
Mosaique:12324:v:1:27500:162:88:0:0
|
||||||
Mosaique 2:12324:v:1:27500:163:92
|
Mosaique 2:12324:v:1:27500:163:92:0:0
|
||||||
Mosaique 3:12324:v:1:27500:164:96
|
Mosaique 3:12324:v:1:27500:164:96:0:0
|
||||||
Le Sesame C+:12324:v:1:27500:165:1965
|
Le Sesame C+:12324:v:1:27500:165:1965:0:0
|
||||||
FEED:12344:h:1:27500:163:92
|
FEED:12344:h:1:27500:163:92:0:0
|
||||||
RTM 1:12363:v:1:27500:162:96
|
RTM 1:12363:v:1:27500:162:96:0:0
|
||||||
ESC 1:12363:v:1:27500:163:104
|
ESC 1:12363:v:1:27500:163:104:0:0
|
||||||
TV5 Europe:12363:v:1:27500:164:112
|
TV5 Europe:12363:v:1:27500:164:112:0:0
|
||||||
TV7 Tunisia:12363:v:1:27500:166:128
|
TV7 Tunisia:12363:v:1:27500:166:128:0:0
|
||||||
ARTE:12363:v:1:27500:167:137
|
ARTE:12363:v:1:27500:167:137:0:0
|
||||||
RAI Uno:12363:v:1:27500:289:290
|
RAI Uno:12363:v:1:27500:289:290:0:0
|
||||||
RTP International:12363:v:1:27500:300:301
|
RTP International:12363:v:1:27500:300:301:0:0
|
||||||
Fashion TV:12402:v:1:27500:163:92
|
Fashion TV:12402:v:1:27500:163:92:0:0
|
||||||
VideoService:12422:h:1:27500:255:256
|
VideoService:12422:h:1:27500:255:256:0:0
|
||||||
Beta Research promo:12422:h:1:27500:1023:1024
|
Beta Research promo:12422:h:1:27500:1023:1024:0:0
|
||||||
Canal Canarias:12441:v:1:27500:160:80
|
Canal Canarias:12441:v:1:27500:160:80:0:0
|
||||||
TVC International:12441:v:1:27500:512:660
|
TVC International:12441:v:1:27500:512:660:0:0
|
||||||
Fitur:12441:v:1:27500:514:662
|
Fitur:12441:v:1:27500:514:662:0:0
|
||||||
Astra Info 1:12552:v:1:22000:164:112
|
Astra Info 1:12552:v:1:22000:164:112:0:0
|
||||||
Astra Info 2:12552:v:1:22000:165:120
|
Astra Info 2:12552:v:1:22000:165:120:0:0
|
||||||
Astra Vision 1:12552:v:1:22000:168:144
|
Astra Vision 1:12552:v:1:22000:168:144:0:0
|
||||||
Astra Vision 1:12552:v:1:22000:168:145
|
Astra Vision 1:12552:v:1:22000:168:145:0:0
|
||||||
Astra Vision 1:12552:v:1:22000:168:146
|
Astra Vision 1:12552:v:1:22000:168:146:0:0
|
||||||
Astra Vision 1:12552:v:1:22000:168:147
|
Astra Vision 1:12552:v:1:22000:168:147:0:0
|
||||||
Astra Vision 1:12552:v:1:22000:168:148
|
Astra Vision 1:12552:v:1:22000:168:148:0:0
|
||||||
Astra Vision 1:12552:v:1:22000:168:149
|
Astra Vision 1:12552:v:1:22000:168:149:0:0
|
||||||
Astra Vision 1:12552:v:1:22000:168:150
|
Astra Vision 1:12552:v:1:22000:168:150:0:0
|
||||||
RTL Tele Letzebuerg:12552:v:1:22000:168:144
|
RTL Tele Letzebuerg:12552:v:1:22000:168:144:0:0
|
||||||
Astra Mosaic:12552:v:1:22000:175:176
|
Astra Mosaic:12552:v:1:22000:175:176:0:0
|
||||||
MHP test:12604:h:1:22000:5632:8191
|
MHP test:12604:h:1:22000:5632:8191:0:0
|
||||||
Bloomberg TV Spain:12610:v:1:22000:45:49
|
Bloomberg TV Spain:12610:v:1:22000:45:49:0:0
|
||||||
Video Italia:12610:v:1:22000:121:122
|
Video Italia:12610:v:1:22000:121:122:0:0
|
||||||
AC 3 promo:12670:v:1:22000:308:256
|
AC 3 promo:12670:v:1:22000:308:256:0:0
|
||||||
|
95
config.c
95
config.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'osm.c' for copyright information and
|
* See the main source file 'osm.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: config.c 1.2 2000/03/05 16:14:27 kls Exp $
|
* $Id: config.c 1.3 2000/04/15 12:48:00 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
@ -16,28 +16,36 @@
|
|||||||
// -- cKeys ------------------------------------------------------------------
|
// -- cKeys ------------------------------------------------------------------
|
||||||
|
|
||||||
tKey keyTable[] = { // "Up" and "Down" must be the first two keys!
|
tKey keyTable[] = { // "Up" and "Down" must be the first two keys!
|
||||||
{ kUp, "Up", 0 },
|
{ kUp, "Up", 0 },
|
||||||
{ kDown, "Down", 0 },
|
{ kDown, "Down", 0 },
|
||||||
{ kMenu, "Menu", 0 },
|
{ kMenu, "Menu", 0 },
|
||||||
{ kOk, "Ok", 0 },
|
{ kOk, "Ok", 0 },
|
||||||
{ kBack, "Back", 0 },
|
{ kBack, "Back", 0 },
|
||||||
{ kLeft, "Left", 0 },
|
{ kLeft, "Left", 0 },
|
||||||
{ kRight, "Right", 0 },
|
{ kRight, "Right", 0 },
|
||||||
{ k0, "0", 0 },
|
{ k0, "0", 0 },
|
||||||
{ k1, "1", 0 },
|
{ k1, "1", 0 },
|
||||||
{ k2, "2", 0 },
|
{ k2, "2", 0 },
|
||||||
{ k3, "3", 0 },
|
{ k3, "3", 0 },
|
||||||
{ k4, "4", 0 },
|
{ k4, "4", 0 },
|
||||||
{ k5, "5", 0 },
|
{ k5, "5", 0 },
|
||||||
{ k6, "6", 0 },
|
{ k6, "6", 0 },
|
||||||
{ k7, "7", 0 },
|
{ k7, "7", 0 },
|
||||||
{ k8, "8", 0 },
|
{ k8, "8", 0 },
|
||||||
{ k9, "9", 0 },
|
{ k9, "9", 0 },
|
||||||
{ kRed, "Red", 0 },
|
{ kRed, "Red", 0 },
|
||||||
{ kGreen, "Green", 0 },
|
{ kGreen, "Green", 0 },
|
||||||
{ kYellow, "Yellow", 0 },
|
{ kYellow, "Yellow", 0 },
|
||||||
{ kBlue, "Blue", 0 },
|
{ kBlue, "Blue", 0 },
|
||||||
{ kNone, "", 0 },
|
{ kRecord, "Record", 0 },
|
||||||
|
{ kPause, "Pause", 0 },
|
||||||
|
{ kStop, "Stop", 0 },
|
||||||
|
{ kBegin, "Begin", 0 },
|
||||||
|
{ kSearchForward, "SearchForward", 0 },
|
||||||
|
{ kSearchBack, "SearchBack", 0 },
|
||||||
|
{ kSkipForward, "SkipForward", 0 },
|
||||||
|
{ kSkipBack, "SkipBack", 0 },
|
||||||
|
{ kNone, "", 0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
cKeys::cKeys(void)
|
cKeys::cKeys(void)
|
||||||
@ -88,7 +96,7 @@ bool cKeys::Load(char *FileName)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (Name) {
|
if (Name) {
|
||||||
fprintf(stderr, "unknown key in %s, line %d\n", fileName, line);
|
esyslog(LOG_ERR, "unknown key in %s, line %d\n", fileName, line);
|
||||||
result = false;
|
result = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -96,17 +104,17 @@ bool cKeys::Load(char *FileName)
|
|||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
fprintf(stderr, "error in %s, line %d\n", fileName, line);
|
esyslog(LOG_ERR, "error in %s, line %d\n", fileName, line);
|
||||||
result = false;
|
result = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
fclose(f);
|
fclose(f);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
fprintf(stderr, "can't open '%s'\n", fileName);
|
esyslog(LOG_ERR, "can't open '%s'\n", fileName);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
fprintf(stderr, "no key configuration file name supplied!\n");
|
esyslog(LOG_ERR, "no key configuration file name supplied!\n");
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -172,12 +180,14 @@ cChannel::cChannel(const cChannel *Channel)
|
|||||||
srate = Channel ? Channel->srate : 27500;
|
srate = Channel ? Channel->srate : 27500;
|
||||||
vpid = Channel ? Channel->vpid : 255;
|
vpid = Channel ? Channel->vpid : 255;
|
||||||
apid = Channel ? Channel->apid : 256;
|
apid = Channel ? Channel->apid : 256;
|
||||||
|
ca = Channel ? Channel->ca : 0;
|
||||||
|
pnr = Channel ? Channel->pnr : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cChannel::Parse(char *s)
|
bool cChannel::Parse(char *s)
|
||||||
{
|
{
|
||||||
char *buffer = NULL;
|
char *buffer = NULL;
|
||||||
if (7 == sscanf(s, "%a[^:]:%d:%c:%d:%d:%d:%d", &buffer, &frequency, &polarization, &diseqc, &srate, &vpid, &apid)) {
|
if (9 == sscanf(s, "%a[^:]:%d:%c:%d:%d:%d:%d:%d:%d", &buffer, &frequency, &polarization, &diseqc, &srate, &vpid, &apid, &ca, &pnr)) {
|
||||||
strncpy(name, buffer, MaxChannelName - 1);
|
strncpy(name, buffer, MaxChannelName - 1);
|
||||||
name[strlen(buffer)] = 0;
|
name[strlen(buffer)] = 0;
|
||||||
delete buffer;
|
delete buffer;
|
||||||
@ -188,20 +198,21 @@ bool cChannel::Parse(char *s)
|
|||||||
|
|
||||||
bool cChannel::Save(FILE *f)
|
bool cChannel::Save(FILE *f)
|
||||||
{
|
{
|
||||||
return fprintf(f, "%s:%d:%c:%d:%d:%d:%d\n", name, frequency, polarization, diseqc, srate, vpid, apid) > 0;
|
return fprintf(f, "%s:%d:%c:%d:%d:%d:%d:%d:%d\n", name, frequency, polarization, diseqc, srate, vpid, apid, ca, pnr) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cChannel::Switch(void)
|
bool cChannel::Switch(void)
|
||||||
{
|
{
|
||||||
if (!ChannelLocked) {
|
if (!DvbApi.Recording()) {
|
||||||
isyslog(LOG_INFO, "switching to channel %d", Index() + 1);
|
isyslog(LOG_INFO, "switching to channel %d", Index() + 1);
|
||||||
CurrentChannel = Index();
|
CurrentChannel = Index();
|
||||||
Interface.DisplayChannel(CurrentChannel + 1, name);
|
Interface.DisplayChannel(CurrentChannel + 1, name);
|
||||||
for (int i = 3; --i;) {
|
for (int i = 3; --i;) {
|
||||||
if (DvbSetChannel(frequency, polarization, diseqc, srate, vpid, apid))
|
if (DvbApi.SetChannel(frequency, polarization, diseqc, srate, vpid, apid, ca, pnr))
|
||||||
return true;
|
return true;
|
||||||
esyslog(LOG_ERR, "retrying");
|
esyslog(LOG_ERR, "retrying");
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
Interface.Info("Channel locked (recording)!");
|
Interface.Info("Channel locked (recording)!");
|
||||||
return false;
|
return false;
|
||||||
@ -215,20 +226,23 @@ bool cChannel::SwitchTo(int i)
|
|||||||
|
|
||||||
// -- cTimer -----------------------------------------------------------------
|
// -- cTimer -----------------------------------------------------------------
|
||||||
|
|
||||||
cTimer::cTimer(void)
|
cTimer::cTimer(bool Instant)
|
||||||
{
|
{
|
||||||
startTime = stopTime = 0;
|
startTime = stopTime = 0;
|
||||||
recording = false;
|
recording = false;
|
||||||
active = 1;
|
active = Instant;
|
||||||
channel = CurrentChannel + 1;
|
channel = CurrentChannel + 1;
|
||||||
day = 1; //XXX today!
|
time_t t = time(NULL);
|
||||||
start = 0; //XXX now!
|
struct tm *now = localtime(&t);
|
||||||
stop = 0; //XXX now + 2h!
|
day = now->tm_mday;
|
||||||
|
start = now->tm_hour * 100 + now->tm_min;
|
||||||
|
stop = start + 200; // "instant recording" records 2 hours by default
|
||||||
|
if (stop >= 2400)
|
||||||
|
stop -= 2400;
|
||||||
//TODO VPS???
|
//TODO VPS???
|
||||||
quality = 'H';
|
|
||||||
priority = 99;
|
priority = 99;
|
||||||
lifetime = 99;
|
lifetime = 99;
|
||||||
*file = 0;
|
strcpy(file, Instant ? "instant" : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
int cTimer::TimeToInt(int t)
|
int cTimer::TimeToInt(int t)
|
||||||
@ -286,7 +300,7 @@ bool cTimer::Parse(char *s)
|
|||||||
{
|
{
|
||||||
char *buffer1 = NULL;
|
char *buffer1 = NULL;
|
||||||
char *buffer2 = NULL;
|
char *buffer2 = NULL;
|
||||||
if (9 == sscanf(s, "%d:%d:%a[^:]:%d:%d:%c:%d:%d:%as", &active, &channel, &buffer1, &start, &stop, &quality, &priority, &lifetime, &buffer2)) {
|
if (8 == sscanf(s, "%d:%d:%a[^:]:%d:%d:%d:%d:%as", &active, &channel, &buffer1, &start, &stop, &priority, &lifetime, &buffer2)) {
|
||||||
day = ParseDay(buffer1);
|
day = ParseDay(buffer1);
|
||||||
strncpy(file, buffer2, MaxFileName - 1);
|
strncpy(file, buffer2, MaxFileName - 1);
|
||||||
file[strlen(buffer2)] = 0;
|
file[strlen(buffer2)] = 0;
|
||||||
@ -299,7 +313,7 @@ bool cTimer::Parse(char *s)
|
|||||||
|
|
||||||
bool cTimer::Save(FILE *f)
|
bool cTimer::Save(FILE *f)
|
||||||
{
|
{
|
||||||
return fprintf(f, "%d:%d:%s:%d:%d:%c:%d:%d:%s\n", active, channel, PrintDay(day), start, stop, quality, priority, lifetime, file) > 0;
|
return fprintf(f, "%d:%d:%s:%d:%d:%d:%d:%s\n", active, channel, PrintDay(day), start, stop, priority, lifetime, file) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cTimer::IsSingleEvent(void)
|
bool cTimer::IsSingleEvent(void)
|
||||||
@ -383,7 +397,6 @@ cKeys Keys;
|
|||||||
// -- cChannels --------------------------------------------------------------
|
// -- cChannels --------------------------------------------------------------
|
||||||
|
|
||||||
int CurrentChannel = 0;
|
int CurrentChannel = 0;
|
||||||
bool ChannelLocked = false;
|
|
||||||
|
|
||||||
cChannels Channels;
|
cChannels Channels;
|
||||||
|
|
||||||
|
21
config.h
21
config.h
@ -4,12 +4,13 @@
|
|||||||
* See the main source file 'osm.c' for copyright information and
|
* See the main source file 'osm.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: config.h 1.2 2000/03/05 14:58:23 kls Exp $
|
* $Id: config.h 1.3 2000/04/15 12:44:23 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __CONFIG_H
|
#ifndef __CONFIG_H
|
||||||
#define __CONFIG_H
|
#define __CONFIG_H
|
||||||
|
|
||||||
|
#define _GNU_SOURCE
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
@ -30,6 +31,14 @@ enum eKeys { // "Up" and "Down" must be the first two keys!
|
|||||||
kGreen,
|
kGreen,
|
||||||
kYellow,
|
kYellow,
|
||||||
kBlue,
|
kBlue,
|
||||||
|
kRecord,
|
||||||
|
kPause,
|
||||||
|
kStop,
|
||||||
|
kBegin,
|
||||||
|
kSearchForward,
|
||||||
|
kSearchBack,
|
||||||
|
kSkipForward,
|
||||||
|
kSkipBack,
|
||||||
kNone
|
kNone
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -64,6 +73,8 @@ public:
|
|||||||
int srate;
|
int srate;
|
||||||
int vpid;
|
int vpid;
|
||||||
int apid;
|
int apid;
|
||||||
|
int ca;
|
||||||
|
int pnr;
|
||||||
cChannel(void);
|
cChannel(void);
|
||||||
cChannel(const cChannel *Channel);
|
cChannel(const cChannel *Channel);
|
||||||
bool Parse(char *s);
|
bool Parse(char *s);
|
||||||
@ -84,11 +95,10 @@ public:
|
|||||||
int start;
|
int start;
|
||||||
int stop;
|
int stop;
|
||||||
//TODO VPS???
|
//TODO VPS???
|
||||||
char quality;
|
|
||||||
int priority;
|
int priority;
|
||||||
int lifetime;
|
int lifetime;
|
||||||
char file[MaxFileName];
|
char file[MaxFileName];
|
||||||
cTimer(void);
|
cTimer(bool Instant = false);
|
||||||
bool Parse(char *s);
|
bool Parse(char *s);
|
||||||
bool Save(FILE *f);
|
bool Save(FILE *f);
|
||||||
bool IsSingleEvent(void);
|
bool IsSingleEvent(void);
|
||||||
@ -128,7 +138,7 @@ public:
|
|||||||
if (l->Parse(buffer))
|
if (l->Parse(buffer))
|
||||||
Add(l);
|
Add(l);
|
||||||
else {
|
else {
|
||||||
fprintf(stderr, "error in %s, line %d\n", fileName, line);
|
esyslog(LOG_ERR, "error in %s, line %d\n", fileName, line);
|
||||||
delete l;
|
delete l;
|
||||||
result = false;
|
result = false;
|
||||||
break;
|
break;
|
||||||
@ -137,7 +147,7 @@ public:
|
|||||||
fclose(f);
|
fclose(f);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fprintf(stderr, "can't open '%s'\n", fileName);
|
esyslog(LOG_ERR, "can't open '%s'\n", fileName);
|
||||||
result = false;
|
result = false;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
@ -168,7 +178,6 @@ class cChannels : public cConfig<cChannel> {};
|
|||||||
class cTimers : public cConfig<cTimer> {};
|
class cTimers : public cConfig<cTimer> {};
|
||||||
|
|
||||||
extern int CurrentChannel;
|
extern int CurrentChannel;
|
||||||
extern bool ChannelLocked;
|
|
||||||
|
|
||||||
extern cChannels Channels;
|
extern cChannels Channels;
|
||||||
extern cTimers Timers;
|
extern cTimers Timers;
|
||||||
|
121
dvbapi.h
121
dvbapi.h
@ -4,20 +4,21 @@
|
|||||||
* See the main source file 'osm.c' for copyright information and
|
* See the main source file 'osm.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: dvbapi.h 1.2 2000/03/06 19:47:20 kls Exp $
|
* $Id: dvbapi.h 1.3 2000/04/15 13:36:10 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __DVBAPI_H
|
#ifndef __DVBAPI_H
|
||||||
#define __DVBAPI_H
|
#define __DVBAPI_H
|
||||||
|
|
||||||
// FIXME: these should be defined in ../DVB/driver/dvb.h!!!
|
// FIXME: these should be defined in ../DVB/driver/dvb.h!!!
|
||||||
typedef unsigned int u32;
|
typedef unsigned int __u32;
|
||||||
typedef unsigned short u16;
|
typedef unsigned short __u16;
|
||||||
typedef unsigned char u8;
|
typedef unsigned char __u8;
|
||||||
|
|
||||||
#if defined(DEBUG_OSD) || defined(DEBUG_REMOTE)
|
#if defined(DEBUG_OSD) || defined(DEBUG_REMOTE)
|
||||||
#include <ncurses.h>
|
#include <ncurses.h>
|
||||||
#endif
|
#endif
|
||||||
|
#include <stdio.h>
|
||||||
#include "../DVB/driver/dvb.h"
|
#include "../DVB/driver/dvb.h"
|
||||||
|
|
||||||
enum eDvbColor { clrBackground,
|
enum eDvbColor { clrBackground,
|
||||||
@ -36,56 +37,15 @@ enum eDvbColor { clrBackground,
|
|||||||
clrWhite,
|
clrWhite,
|
||||||
};
|
};
|
||||||
|
|
||||||
extern const char *DvbQuality; // Low, Medium, High
|
class cDvbApi {
|
||||||
|
|
||||||
bool DvbSetChannel(int FrequencyMHz, char Polarization, int Diseqc, int Srate, int Vpid, int Apid);
|
|
||||||
|
|
||||||
class cDvbRecorder {
|
|
||||||
private:
|
private:
|
||||||
bool recording;
|
int videoDev;
|
||||||
public:
|
public:
|
||||||
cDvbRecorder(void);
|
cDvbApi(void);
|
||||||
~cDvbRecorder();
|
~cDvbApi();
|
||||||
bool Recording(void);
|
|
||||||
// Returns true if this recorder is currently recording, false if it
|
// On Screen Display facilities
|
||||||
// is playing back or does nothing.
|
|
||||||
bool Record(const char *FileName, char Quality);
|
|
||||||
// Starts recording the current channel into the given file, with the
|
|
||||||
// given quality level. Any existing file will be overwritten.
|
|
||||||
// Returns true if recording was started successfully.
|
|
||||||
// If there is already a recording session active, false will be
|
|
||||||
// returned.
|
|
||||||
bool Play(const char *FileName, int Frame = 0);
|
|
||||||
// Starts playback of the given file, at the optional Frame (default
|
|
||||||
// is the beginning of the file). If Frame is beyond the last recorded
|
|
||||||
// frame in the file (or if it is negative), playback will be positioned
|
|
||||||
// to the last frame in the file (or the frame with the absolute value of
|
|
||||||
// Frame) and will do an implicit Pause() there.
|
|
||||||
// If there is already a playback session active, it will be stopped
|
|
||||||
// and the new file or frame (which may be in the same file) will
|
|
||||||
// be played back.
|
|
||||||
bool FastForward(void);
|
|
||||||
// Runs the current playback session forward at a higher speed.
|
|
||||||
// TODO allow different fast forward speeds???
|
|
||||||
bool FastRewind(void);
|
|
||||||
// Runs the current playback session backwards forward at a higher speed.
|
|
||||||
// TODO allow different fast rewind speeds???
|
|
||||||
bool Pause(void);
|
|
||||||
// Pauses the current recording or playback session, or resumes a paused
|
|
||||||
// session.
|
|
||||||
// Returns true if there is actually a recording or playback session
|
|
||||||
// active that was paused/resumed.
|
|
||||||
void Stop(void);
|
|
||||||
// Stops the current recording or playback session.
|
|
||||||
int Frame(void);
|
|
||||||
// Returns the number of the current frame in the current recording or
|
|
||||||
// playback session, which can be used to start playback at a given position.
|
|
||||||
// The number returned is the actual number of frames counted from the
|
|
||||||
// beginning of the current file.
|
|
||||||
// The very first frame has the number 1.
|
|
||||||
};
|
|
||||||
|
|
||||||
class cDvbOsd {
|
|
||||||
private:
|
private:
|
||||||
enum { charWidth = 12, // average character width
|
enum { charWidth = 12, // average character width
|
||||||
lineHeight = 27 // smallest text height
|
lineHeight = 27 // smallest text height
|
||||||
@ -95,19 +55,70 @@ private:
|
|||||||
enum { MaxColorPairs = 16 };
|
enum { MaxColorPairs = 16 };
|
||||||
int colorPairs[MaxColorPairs];
|
int colorPairs[MaxColorPairs];
|
||||||
void SetColor(eDvbColor colorFg, eDvbColor colorBg = clrBackground);
|
void SetColor(eDvbColor colorFg, eDvbColor colorBg = clrBackground);
|
||||||
#else
|
|
||||||
void Cmd(OSD_Command cmd, int color = 0, int x0 = 0, int y0 = 0, int x1 = 0, int y1 = 0, const void *data = NULL);
|
|
||||||
#endif
|
#endif
|
||||||
int cols, rows;
|
int cols, rows;
|
||||||
|
void Cmd(OSD_Command cmd, int color = 0, int x0 = 0, int y0 = 0, int x1 = 0, int y1 = 0, const void *data = NULL);
|
||||||
public:
|
public:
|
||||||
cDvbOsd(void);
|
|
||||||
~cDvbOsd();
|
|
||||||
void Open(int w, int h);
|
void Open(int w, int h);
|
||||||
void Close(void);
|
void Close(void);
|
||||||
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);
|
||||||
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);
|
||||||
|
|
||||||
|
// Channel facilities
|
||||||
|
|
||||||
|
bool SetChannel(int FrequencyMHz, char Polarization, int Diseqc, int Srate, int Vpid, int Apid, int Ca, int Pnr);
|
||||||
|
|
||||||
|
// Record/Replay facilities
|
||||||
|
|
||||||
|
private:
|
||||||
|
enum { dvbStop = 1, // let's not have 0 as a command
|
||||||
|
dvbPauseReplay,
|
||||||
|
dvbFastForward,
|
||||||
|
dvbFastRewind,
|
||||||
|
dvbSkip,
|
||||||
|
};
|
||||||
|
bool isMainProcess;
|
||||||
|
pid_t pidRecord, pidReplay;
|
||||||
|
int fromRecord, toRecord;
|
||||||
|
int fromReplay, toReplay;
|
||||||
|
void SetReplayMode(int Mode);
|
||||||
|
void KillProcess(pid_t pid);
|
||||||
|
public:
|
||||||
|
bool Recording(void);
|
||||||
|
// Returns true if we are currently recording.
|
||||||
|
bool Replaying(void);
|
||||||
|
// Returns true if we are currently replaying.
|
||||||
|
bool StartRecord(const char *FileName);
|
||||||
|
// Starts recording the current channel into the given file.
|
||||||
|
// In order to be able to record longer movies,
|
||||||
|
// a numerical suffix will be appended to the file name. The inital
|
||||||
|
// value of that suffix will be larger than any existing file under
|
||||||
|
// the given name, thus allowing an interrupted recording to continue
|
||||||
|
// gracefully.
|
||||||
|
// Returns true if recording was started successfully.
|
||||||
|
// If there is already a recording session active, false will be
|
||||||
|
// returned.
|
||||||
|
void StopRecord(void);
|
||||||
|
// Stops the current recording session (if any).
|
||||||
|
bool StartReplay(const char *FileName);
|
||||||
|
// Starts replaying the given file.
|
||||||
|
// If there is already a replay session active, it will be stopped
|
||||||
|
// and the new file will be played back.
|
||||||
|
void StopReplay(void);
|
||||||
|
// Stops the current replay session (if any).
|
||||||
|
void PauseReplay(void);
|
||||||
|
// Pauses the current replay session, or resumes a paused session.
|
||||||
|
void FastForward(void);
|
||||||
|
// Runs the current replay session forward at a higher speed.
|
||||||
|
void FastRewind(void);
|
||||||
|
// Runs the current replay session backwards at a higher speed.
|
||||||
|
void Skip(int Seconds);
|
||||||
|
// Skips the given number of seconds in the current replay session.
|
||||||
|
// The sign of 'Seconds' determines the direction in which to skip.
|
||||||
|
// Use a very large negative value to go all the way back to the
|
||||||
|
// beginning of the recording.
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //__DVBAPI_H
|
#endif //__DVBAPI_H
|
||||||
|
25
interface.c
25
interface.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'osm.c' for copyright information and
|
* See the main source file 'osm.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: interface.c 1.2 2000/03/06 19:45:03 kls Exp $
|
* $Id: interface.c 1.3 2000/04/15 17:38:11 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "interface.h"
|
#include "interface.h"
|
||||||
@ -15,10 +15,10 @@
|
|||||||
#define MenuColumns 40
|
#define MenuColumns 40
|
||||||
|
|
||||||
#ifndef DEBUG_REMOTE
|
#ifndef DEBUG_REMOTE
|
||||||
cRcIo RcIo("/dev/ttyS1");//XXX
|
cRcIo RcIo("/dev/ttyS1");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
cDvbOsd DvbOsd; //XXX member of cInterface???
|
cDvbApi DvbApi; //XXX member of cInterface???
|
||||||
|
|
||||||
cInterface Interface;
|
cInterface Interface;
|
||||||
|
|
||||||
@ -38,19 +38,22 @@ void cInterface::Init(void)
|
|||||||
void cInterface::Open(void)
|
void cInterface::Open(void)
|
||||||
{
|
{
|
||||||
if (!open++)
|
if (!open++)
|
||||||
DvbOsd.Open(MenuColumns, MenuLines);
|
DvbApi.Open(MenuColumns, MenuLines);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cInterface::Close(void)
|
void cInterface::Close(void)
|
||||||
{
|
{
|
||||||
|
if (open == 1)
|
||||||
|
Clear();
|
||||||
if (!--open)
|
if (!--open)
|
||||||
DvbOsd.Close();
|
DvbApi.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int cInterface::GetCh(void)
|
unsigned int cInterface::GetCh(void)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_REMOTE
|
#ifdef DEBUG_REMOTE
|
||||||
return getch();
|
int c = getch();
|
||||||
|
return (c > 0) ? c : 0;
|
||||||
#else
|
#else
|
||||||
//XXX #ifdef DEBUG_OSD
|
//XXX #ifdef DEBUG_OSD
|
||||||
//XXX wrefresh(window);//XXX
|
//XXX wrefresh(window);//XXX
|
||||||
@ -80,13 +83,13 @@ eKeys cInterface::Wait(int Seconds)
|
|||||||
void cInterface::Clear(void)
|
void cInterface::Clear(void)
|
||||||
{
|
{
|
||||||
if (open)
|
if (open)
|
||||||
DvbOsd.Clear();
|
DvbApi.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void cInterface::ClearEol(int x, int y, eDvbColor Color)
|
void cInterface::ClearEol(int x, int y, eDvbColor Color)
|
||||||
{
|
{
|
||||||
if (open)
|
if (open)
|
||||||
DvbOsd.ClrEol(x, y, Color);
|
DvbApi.ClrEol(x, y, Color);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cInterface::SetCols(int *c)
|
void cInterface::SetCols(int *c)
|
||||||
@ -101,7 +104,7 @@ void cInterface::SetCols(int *c)
|
|||||||
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)
|
||||||
DvbOsd.Text(x, y, s, FgColor, BgColor);
|
DvbApi.Text(x, y, s, FgColor, BgColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cInterface::WriteText(int x, int y, const char *s, bool Current)
|
void cInterface::WriteText(int x, int y, const char *s, bool Current)
|
||||||
@ -187,8 +190,8 @@ void cInterface::HelpButton(int Index, const char *Text, eDvbColor FgColor, eDvb
|
|||||||
int l = (w - strlen(Text)) / 2;
|
int l = (w - strlen(Text)) / 2;
|
||||||
if (l < 0)
|
if (l < 0)
|
||||||
l = 0;
|
l = 0;
|
||||||
DvbOsd.Fill(Index * w, -1, w, 1, BgColor);
|
DvbApi.Fill(Index * w, -1, w, 1, BgColor);
|
||||||
DvbOsd.Text(Index * w + l, -1, Text, FgColor, BgColor);
|
DvbApi.Text(Index * w + l, -1, Text, FgColor, BgColor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'osm.c' for copyright information and
|
* See the main source file 'osm.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: interface.h 1.2 2000/02/27 14:54:02 kls Exp $
|
* $Id: interface.h 1.3 2000/03/19 14:03:28 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __INTERFACE_H
|
#ifndef __INTERFACE_H
|
||||||
@ -45,5 +45,6 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
extern cInterface Interface;
|
extern cInterface Interface;
|
||||||
|
extern cDvbApi DvbApi; //XXX member of cInterface???
|
||||||
|
|
||||||
#endif //__INTERFACE_H
|
#endif //__INTERFACE_H
|
||||||
|
BIN
keys-pc.conf
BIN
keys-pc.conf
Binary file not shown.
23
keys.conf
23
keys.conf
@ -1,23 +0,0 @@
|
|||||||
Code B
|
|
||||||
Address 0000
|
|
||||||
Up 000047E2
|
|
||||||
Down 000007E2
|
|
||||||
Menu 000011E2
|
|
||||||
Ok 000079E2
|
|
||||||
Back 00001AE2
|
|
||||||
Left 000005E2
|
|
||||||
Right 000045E2
|
|
||||||
0 00007FE2
|
|
||||||
1 00003FE2
|
|
||||||
2 00005FE2
|
|
||||||
3 00001FE2
|
|
||||||
4 00006FE2
|
|
||||||
5 00002FE2
|
|
||||||
6 00004FE2
|
|
||||||
7 00000FE2
|
|
||||||
8 000077E2
|
|
||||||
9 000037E2
|
|
||||||
Red 000025E2
|
|
||||||
Green 00002AE2
|
|
||||||
Yellow 00005AE2
|
|
||||||
Blue 00000000
|
|
29
menu.c
29
menu.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'osm.c' for copyright information and
|
* See the main source file 'osm.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: menu.c 1.2 2000/03/05 15:37:31 kls Exp $
|
* $Id: menu.c 1.3 2000/04/15 15:07:36 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "menu.h"
|
#include "menu.h"
|
||||||
@ -502,13 +502,15 @@ cMenuEditChannel::cMenuEditChannel(int Index)
|
|||||||
channel = Channels.Get(Index);
|
channel = Channels.Get(Index);
|
||||||
if (channel) {
|
if (channel) {
|
||||||
data = *channel;
|
data = *channel;
|
||||||
Add(new cMenuEditStrItem("Name", data.name, sizeof(data.name), FileNameChars));
|
Add(new cMenuEditStrItem( "Name", data.name, sizeof(data.name), FileNameChars));
|
||||||
Add(new cMenuEditIntItem("Frequency", &data.frequency, 10000, 13000)); //TODO exact limits???
|
Add(new cMenuEditIntItem( "Frequency", &data.frequency, 10000, 13000)); //TODO exact limits???
|
||||||
Add(new cMenuEditChrItem("Polarization", &data.polarization, "hv"));
|
Add(new cMenuEditChrItem( "Polarization", &data.polarization, "hv"));
|
||||||
Add(new cMenuEditIntItem("Diseqc", &data.diseqc, 0, 10)); //TODO exact limits???
|
Add(new cMenuEditIntItem( "Diseqc", &data.diseqc, 0, 10)); //TODO exact limits???
|
||||||
Add(new cMenuEditIntItem("Srate", &data.srate, 22000, 27500)); //TODO exact limits - toggle???
|
Add(new cMenuEditIntItem( "Srate", &data.srate, 22000, 27500)); //TODO exact limits - toggle???
|
||||||
Add(new cMenuEditIntItem("Vpid", &data.vpid, 0, 10000)); //TODO exact limits???
|
Add(new cMenuEditIntItem( "Vpid", &data.vpid, 0, 10000)); //TODO exact limits???
|
||||||
Add(new cMenuEditIntItem("Apid", &data.apid, 0, 10000)); //TODO exact limits???
|
Add(new cMenuEditIntItem( "Apid", &data.apid, 0, 10000)); //TODO exact limits???
|
||||||
|
Add(new cMenuEditBoolItem("CA", &data.ca));
|
||||||
|
Add(new cMenuEditIntItem( "Pnr", &data.pnr, 0, 10000)); //TODO exact limits???
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -599,7 +601,7 @@ eOSState cMenuChannels::Edit(void)
|
|||||||
{
|
{
|
||||||
if (HasSubMenu() || Count() == 0)
|
if (HasSubMenu() || Count() == 0)
|
||||||
return osContinue;
|
return osContinue;
|
||||||
isyslog(LOG_INFO, "editing timer %d", Current() + 1);
|
isyslog(LOG_INFO, "editing channel %d", Current() + 1);
|
||||||
return AddSubMenu(new cMenuEditChannel(Current()));
|
return AddSubMenu(new cMenuEditChannel(Current()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -711,23 +713,24 @@ private:
|
|||||||
cTimer *timer;
|
cTimer *timer;
|
||||||
cTimer data;
|
cTimer data;
|
||||||
public:
|
public:
|
||||||
cMenuEditTimer(int Index);
|
cMenuEditTimer(int Index, bool New = false);
|
||||||
virtual eOSState ProcessKey(eKeys Key);
|
virtual eOSState ProcessKey(eKeys Key);
|
||||||
};
|
};
|
||||||
|
|
||||||
cMenuEditTimer::cMenuEditTimer(int Index)
|
cMenuEditTimer::cMenuEditTimer(int Index, bool New)
|
||||||
:cOsdMenu("Edit Timer", 10)
|
:cOsdMenu("Edit Timer", 10)
|
||||||
{
|
{
|
||||||
timer = Timers.Get(Index);
|
timer = Timers.Get(Index);
|
||||||
if (timer) {
|
if (timer) {
|
||||||
data = *timer;
|
data = *timer;
|
||||||
|
if (New)
|
||||||
|
data.active = 1;
|
||||||
Add(new cMenuEditBoolItem("Active", &data.active));
|
Add(new cMenuEditBoolItem("Active", &data.active));
|
||||||
Add(new cMenuEditChanItem("Channel", &data.channel));
|
Add(new cMenuEditChanItem("Channel", &data.channel));
|
||||||
Add(new cMenuEditDayItem( "Day", &data.day));
|
Add(new cMenuEditDayItem( "Day", &data.day));
|
||||||
Add(new cMenuEditTimeItem("Start", &data.start));
|
Add(new cMenuEditTimeItem("Start", &data.start));
|
||||||
Add(new cMenuEditTimeItem("Stop", &data.stop));
|
Add(new cMenuEditTimeItem("Stop", &data.stop));
|
||||||
//TODO VPS???
|
//TODO VPS???
|
||||||
Add(new cMenuEditChrItem( "Quality", &data.quality, DvbQuality));
|
|
||||||
Add(new cMenuEditIntItem( "Priority", &data.priority, 0, 99));
|
Add(new cMenuEditIntItem( "Priority", &data.priority, 0, 99));
|
||||||
Add(new cMenuEditIntItem( "Lifetime", &data.lifetime, 0, 99));
|
Add(new cMenuEditIntItem( "Lifetime", &data.lifetime, 0, 99));
|
||||||
Add(new cMenuEditStrItem( "File", data.file, sizeof(data.file), FileNameChars));
|
Add(new cMenuEditStrItem( "File", data.file, sizeof(data.file), FileNameChars));
|
||||||
@ -843,7 +846,7 @@ eOSState cMenuTimers::New(void)
|
|||||||
Add(new cMenuTimerItem(timer->Index()/*XXX*/, timer), true);
|
Add(new cMenuTimerItem(timer->Index()/*XXX*/, timer), true);
|
||||||
Timers.Save();
|
Timers.Save();
|
||||||
isyslog(LOG_INFO, "timer %d added", timer->Index() + 1);
|
isyslog(LOG_INFO, "timer %d added", timer->Index() + 1);
|
||||||
return AddSubMenu(new cMenuEditTimer(Current()));
|
return AddSubMenu(new cMenuEditTimer(Current(), true));
|
||||||
}
|
}
|
||||||
|
|
||||||
eOSState cMenuTimers::Del(void)
|
eOSState cMenuTimers::Del(void)
|
||||||
|
150
osm.c
150
osm.c
@ -22,9 +22,10 @@
|
|||||||
*
|
*
|
||||||
* 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: osm.c 1.2 2000/03/05 17:18:15 kls Exp $
|
* $Id: osm.c 1.3 2000/04/15 14:04:21 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <signal.h>
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "interface.h"
|
#include "interface.h"
|
||||||
#include "menu.h"
|
#include "menu.h"
|
||||||
@ -37,6 +38,13 @@
|
|||||||
#define KEYS_CONF "keys.conf"
|
#define KEYS_CONF "keys.conf"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static int Interrupted = 0;
|
||||||
|
|
||||||
|
void SignalHandler(int signum)
|
||||||
|
{
|
||||||
|
Interrupted = signum;
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
openlog("vdr", LOG_PID | LOG_CONS, LOG_USER);
|
openlog("vdr", LOG_PID | LOG_CONS, LOG_USER);
|
||||||
@ -50,69 +58,93 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
cChannel::SwitchTo(CurrentChannel);
|
cChannel::SwitchTo(CurrentChannel);
|
||||||
|
|
||||||
|
if (signal(SIGHUP, SignalHandler) == SIG_IGN) signal(SIGHUP, SIG_IGN);
|
||||||
|
if (signal(SIGINT, SignalHandler) == SIG_IGN) signal(SIGINT, SIG_IGN);
|
||||||
|
if (signal(SIGTERM, SignalHandler) == SIG_IGN) signal(SIGTERM, SIG_IGN);
|
||||||
|
|
||||||
cMenuMain *Menu = NULL;
|
cMenuMain *Menu = NULL;
|
||||||
cTimer *Timer = NULL;
|
cTimer *Timer = NULL;
|
||||||
cRecording *Recording = NULL;
|
cRecording *Recording = NULL;
|
||||||
|
|
||||||
for (;;) {
|
while (!Interrupted) {
|
||||||
AssertFreeDiskSpace();
|
AssertFreeDiskSpace();
|
||||||
if (!Recording && !Timer && (Timer = cTimer::GetMatch()) != NULL) {
|
if (!Recording && !Timer && (Timer = cTimer::GetMatch()) != NULL) {
|
||||||
DELETENULL(Menu);
|
DELETENULL(Menu);
|
||||||
// make sure the timer won't be deleted:
|
// make sure the timer won't be deleted:
|
||||||
Timer->SetRecording(true);
|
Timer->SetRecording(true);
|
||||||
// switch to channel:
|
// switch to channel:
|
||||||
cChannel::SwitchTo(Timer->channel - 1);
|
cChannel::SwitchTo(Timer->channel - 1);
|
||||||
ChannelLocked = true;
|
// start recording:
|
||||||
// start recording:
|
Recording = new cRecording(Timer);
|
||||||
Recording = new cRecording(Timer);
|
if (!Recording->Record())
|
||||||
if (!Recording->Record())
|
DELETENULL(Recording);
|
||||||
DELETENULL(Recording);
|
|
||||||
}
|
|
||||||
if (Timer && !Timer->Matches()) {
|
|
||||||
// stop recording:
|
|
||||||
if (Recording) {
|
|
||||||
Recording->Stop();
|
|
||||||
DELETENULL(Recording);
|
|
||||||
}
|
|
||||||
// release channel and timer:
|
|
||||||
ChannelLocked = false;
|
|
||||||
Timer->SetRecording(false);
|
|
||||||
// clear single event timer:
|
|
||||||
if (Timer->IsSingleEvent()) {
|
|
||||||
DELETENULL(Menu); // must make sure no menu uses it
|
|
||||||
isyslog(LOG_INFO, "deleting timer %d", Timer->Index() + 1);
|
|
||||||
Timers.Del(Timer);
|
|
||||||
Timers.Save();
|
|
||||||
}
|
|
||||||
Timer = NULL;
|
|
||||||
}
|
|
||||||
eKeys key = Interface.GetKey();
|
|
||||||
if (Menu) {
|
|
||||||
switch (Menu->ProcessKey(key)) {
|
|
||||||
default: if (key != kMenu)
|
|
||||||
break;
|
|
||||||
case osBack:
|
|
||||||
case osEnd: DELETENULL(Menu);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
if (Timer && !Timer->Matches()) {
|
||||||
else {
|
// stop recording:
|
||||||
switch (key) {
|
if (Recording) {
|
||||||
case kMenu: Menu = new cMenuMain;
|
Recording->Stop();
|
||||||
Menu->Display();
|
DELETENULL(Recording);
|
||||||
break;
|
}
|
||||||
case kUp:
|
// release timer:
|
||||||
case kDown: {
|
Timer->SetRecording(false);
|
||||||
int n = CurrentChannel + (key == kUp ? 1 : -1);
|
// clear single event timer:
|
||||||
cChannel *channel = Channels.Get(n);
|
if (Timer->IsSingleEvent()) {
|
||||||
if (channel)
|
DELETENULL(Menu); // must make sure no menu uses it
|
||||||
channel->Switch();
|
isyslog(LOG_INFO, "deleting timer %d", Timer->Index() + 1);
|
||||||
}
|
Timers.Del(Timer);
|
||||||
break;
|
Timers.Save();
|
||||||
default: break;
|
}
|
||||||
|
Timer = NULL;
|
||||||
}
|
}
|
||||||
}
|
eKeys key = Interface.GetKey();
|
||||||
}
|
if (Menu) {
|
||||||
|
switch (Menu->ProcessKey(key)) {
|
||||||
|
default: if (key != kMenu)
|
||||||
|
break;
|
||||||
|
case osBack:
|
||||||
|
case osEnd: DELETENULL(Menu);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
switch (key) {
|
||||||
|
// Record/Replay Control:
|
||||||
|
case kBegin: DvbApi.Skip(-INT_MAX); break;
|
||||||
|
case kRecord: if (!DvbApi.Recording()) {
|
||||||
|
cTimer *timer = new cTimer(true);
|
||||||
|
Timers.Add(timer);
|
||||||
|
Timers.Save();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Interface.Error("Already recording!");
|
||||||
|
break;
|
||||||
|
case kPause: DvbApi.PauseReplay(); break;
|
||||||
|
case kStop: DvbApi.StopReplay(); break;
|
||||||
|
case kSearchBack: DvbApi.FastRewind(); break;
|
||||||
|
case kSearchForward: DvbApi.FastForward(); break;
|
||||||
|
case kSkipBack: DvbApi.Skip(-60); break;
|
||||||
|
case kSkipForward: DvbApi.Skip(60); break;
|
||||||
|
// Menu Control:
|
||||||
|
case kMenu: Menu = new cMenuMain;
|
||||||
|
Menu->Display();
|
||||||
|
break;
|
||||||
|
case kUp:
|
||||||
|
case kDown: {
|
||||||
|
int n = CurrentChannel + (key == kUp ? 1 : -1);
|
||||||
|
cChannel *channel = Channels.Get(n);
|
||||||
|
if (channel)
|
||||||
|
channel->Switch();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
isyslog(LOG_INFO, "caught signal %d", Interrupted);
|
||||||
|
DvbApi.StopRecord();
|
||||||
|
DvbApi.StopReplay();
|
||||||
|
//TODO kill any remaining sub-processes!
|
||||||
|
isyslog(LOG_INFO, "exiting", Interrupted);
|
||||||
closelog();
|
closelog();
|
||||||
return 1;
|
return 0;
|
||||||
}
|
}
|
||||||
|
110
recording.c
110
recording.c
@ -4,9 +4,10 @@
|
|||||||
* See the main source file 'osm.c' for copyright information and
|
* See the main source file 'osm.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: recording.c 1.1 2000/03/05 17:16:22 kls Exp $
|
* $Id: recording.c 1.2 2000/04/15 13:29:02 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define _GNU_SOURCE
|
||||||
#include "recording.h"
|
#include "recording.h"
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -16,17 +17,17 @@
|
|||||||
|
|
||||||
#define RECEXT ".rec"
|
#define RECEXT ".rec"
|
||||||
#define DELEXT ".del"
|
#define DELEXT ".del"
|
||||||
#define DATAFORMAT "%4d-%02d-%02d.%02d:%02d.%c.%02d.%02d" RECEXT
|
#define DATAFORMAT "%4d-%02d-%02d.%02d:%02d.%02d.%02d" RECEXT
|
||||||
#define NAMEFORMAT "%s/%s/" DATAFORMAT
|
#define NAMEFORMAT "%s/%s/" DATAFORMAT
|
||||||
|
|
||||||
#define FINDCMD "find %s -type f -name '%s'"
|
#define FINDCMD "find %s -type d -name '%s'"
|
||||||
|
|
||||||
#define DFCMD "df -m %s"
|
#define DFCMD "df -m %s"
|
||||||
#define MINDISKSPACE 1024 // MB
|
#define MINDISKSPACE 1024 // MB
|
||||||
|
|
||||||
const char *BaseDir = "/video";//XXX
|
#define DISKCHECKDELTA 300 // seconds between checks for free disk space
|
||||||
|
|
||||||
cDvbRecorder *Recorder = NULL;
|
const char *BaseDir = "/video";
|
||||||
|
|
||||||
static bool LowDiskSpace(void)
|
static bool LowDiskSpace(void)
|
||||||
{
|
{
|
||||||
@ -58,51 +59,54 @@ void AssertFreeDiskSpace(void)
|
|||||||
// With every call to this function we try to actually remove
|
// With every call to this function we try to actually remove
|
||||||
// a file, or mark a file for removal ("delete" it), so that
|
// a file, or mark a file for removal ("delete" it), so that
|
||||||
// it will get removed during the next call.
|
// it will get removed during the next call.
|
||||||
if (Recorder && Recorder->Recording() && LowDiskSpace()) {
|
static time_t LastFreeDiskCheck = 0;
|
||||||
// Remove the oldest file that has been "deleted":
|
if (time(NULL) - LastFreeDiskCheck > DISKCHECKDELTA) {
|
||||||
cRecordings Recordings;
|
LastFreeDiskCheck = time(NULL);
|
||||||
if (Recordings.Load(true)) {
|
if (DvbApi.Recording() && LowDiskSpace()) {
|
||||||
cRecording *r = Recordings.First();
|
// Remove the oldest file that has been "deleted":
|
||||||
cRecording *r0 = r;
|
cRecordings Recordings;
|
||||||
while (r) {
|
if (Recordings.Load(true)) {
|
||||||
if (r->start < r0->start)
|
cRecording *r = Recordings.First();
|
||||||
r0 = r;
|
cRecording *r0 = r;
|
||||||
r = Recordings.Next(r);
|
while (r) {
|
||||||
}
|
if (r->start < r0->start)
|
||||||
if (r0 && r0->Remove())
|
r0 = r;
|
||||||
return;
|
r = Recordings.Next(r);
|
||||||
}
|
}
|
||||||
// No "deleted" files to remove, so let's see if we can delete a recording:
|
if (r0 && r0->Remove())
|
||||||
if (Recordings.Load(false)) {
|
return;
|
||||||
cRecording *r = Recordings.First();
|
}
|
||||||
cRecording *r0 = NULL;
|
// No "deleted" files to remove, so let's see if we can delete a recording:
|
||||||
while (r) {
|
if (Recordings.Load(false)) {
|
||||||
if ((time(NULL) - r->start) / SECSINDAY > r->lifetime) {
|
cRecording *r = Recordings.First();
|
||||||
if (r0) {
|
cRecording *r0 = NULL;
|
||||||
if (r->priority < r0->priority)
|
while (r) {
|
||||||
|
if ((time(NULL) - r->start) / SECSINDAY > r->lifetime) {
|
||||||
|
if (r0) {
|
||||||
|
if (r->priority < r0->priority)
|
||||||
|
r0 = r;
|
||||||
|
}
|
||||||
|
else
|
||||||
r0 = r;
|
r0 = r;
|
||||||
}
|
}
|
||||||
else
|
r = Recordings.Next(r);
|
||||||
r0 = r;
|
|
||||||
}
|
}
|
||||||
r = Recordings.Next(r);
|
if (r0 && r0->Delete())
|
||||||
}
|
return;
|
||||||
if (r0 && r0->Delete())
|
}
|
||||||
return;
|
// Unable to free disk space, but there's nothing we can do about that...
|
||||||
|
esyslog(LOG_ERR, "low disk space, but no recordings to delete");
|
||||||
}
|
}
|
||||||
// Unable to free disk space, but there's nothing we can do about that...
|
|
||||||
//TODO maybe a log entry - but make sure it doesn't come too often
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- cRecording ------------------------------------------------------------
|
// --- cRecording ------------------------------------------------------------
|
||||||
|
|
||||||
cRecording::cRecording(const char *Name, time_t Start, char Quality, int Priority, int LifeTime)
|
cRecording::cRecording(const char *Name, time_t Start, int Priority, int LifeTime)
|
||||||
{
|
{
|
||||||
fileName = NULL;
|
fileName = NULL;
|
||||||
name = strdup(Name);
|
name = strdup(Name);
|
||||||
start = Start;
|
start = Start;
|
||||||
quality = Quality;
|
|
||||||
priority = Priority;
|
priority = Priority;
|
||||||
lifetime = LifeTime;
|
lifetime = LifeTime;
|
||||||
}
|
}
|
||||||
@ -112,7 +116,6 @@ cRecording::cRecording(cTimer *Timer)
|
|||||||
fileName = NULL;
|
fileName = NULL;
|
||||||
name = strdup(Timer->file);
|
name = strdup(Timer->file);
|
||||||
start = Timer->StartTime();
|
start = Timer->StartTime();
|
||||||
quality = Timer->quality;
|
|
||||||
priority = Timer->priority;
|
priority = Timer->priority;
|
||||||
lifetime = Timer->lifetime;
|
lifetime = Timer->lifetime;
|
||||||
}
|
}
|
||||||
@ -127,7 +130,7 @@ cRecording::cRecording(const char *FileName)
|
|||||||
if (p) {
|
if (p) {
|
||||||
time_t now = time(NULL);
|
time_t now = time(NULL);
|
||||||
struct tm t = *localtime(&now); // this initializes the time zone in 't'
|
struct tm t = *localtime(&now); // this initializes the time zone in 't'
|
||||||
if (8 == sscanf(p + 1, DATAFORMAT, &t.tm_year, &t.tm_mon, &t.tm_mday, &t.tm_hour, &t.tm_min, &quality, &priority, &lifetime)) {
|
if (7 == sscanf(p + 1, DATAFORMAT, &t.tm_year, &t.tm_mon, &t.tm_mday, &t.tm_hour, &t.tm_min, &priority, &lifetime)) {
|
||||||
t.tm_year -= 1900;
|
t.tm_year -= 1900;
|
||||||
t.tm_mon--;
|
t.tm_mon--;
|
||||||
t.tm_sec = 0;
|
t.tm_sec = 0;
|
||||||
@ -149,7 +152,7 @@ const char *cRecording::FileName(void)
|
|||||||
{
|
{
|
||||||
if (!fileName) {
|
if (!fileName) {
|
||||||
struct tm *t = localtime(&start);
|
struct tm *t = localtime(&start);
|
||||||
asprintf(&fileName, NAMEFORMAT, BaseDir, name, t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, quality, priority, lifetime);
|
asprintf(&fileName, NAMEFORMAT, BaseDir, name, t->tm_year + 1900, t->tm_mon + 1, t->tm_mday, t->tm_hour, t->tm_min, priority, lifetime);
|
||||||
}
|
}
|
||||||
return fileName;
|
return fileName;
|
||||||
}
|
}
|
||||||
@ -163,7 +166,7 @@ bool cRecording::Delete(void)
|
|||||||
strncpy(ext, DELEXT, strlen(ext));
|
strncpy(ext, DELEXT, strlen(ext));
|
||||||
isyslog(LOG_INFO, "deleting recording %s", FileName());
|
isyslog(LOG_INFO, "deleting recording %s", FileName());
|
||||||
if (rename(FileName(), NewName) == -1) {
|
if (rename(FileName(), NewName) == -1) {
|
||||||
esyslog(LOG_ERR, "ERROR: %s", strerror(errno));
|
esyslog(LOG_ERR, "ERROR: %s: %s", FileName(), strerror(errno));
|
||||||
result = false;
|
result = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -173,40 +176,23 @@ bool cRecording::Delete(void)
|
|||||||
|
|
||||||
bool cRecording::Remove(void)
|
bool cRecording::Remove(void)
|
||||||
{
|
{
|
||||||
bool result = true;
|
|
||||||
isyslog(LOG_INFO, "removing recording %s", FileName());
|
isyslog(LOG_INFO, "removing recording %s", FileName());
|
||||||
if (remove(FileName()) == -1) {
|
return RemoveFileOrDir(FileName());
|
||||||
esyslog(LOG_ERR, "ERROR: %s", strerror(errno));
|
|
||||||
result = false;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool cRecording::AssertRecorder(void)
|
|
||||||
{
|
|
||||||
if (!Recorder || !Recorder->Recording()) {
|
|
||||||
if (!Recorder)
|
|
||||||
Recorder = new cDvbRecorder;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
Interface.Error("Recorder is in use!");
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cRecording::Record(void)
|
bool cRecording::Record(void)
|
||||||
{
|
{
|
||||||
return AssertRecorder() && Recorder->Record(FileName(), quality);
|
return DvbApi.StartRecord(FileName());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cRecording::Play(void)
|
bool cRecording::Play(void)
|
||||||
{
|
{
|
||||||
return AssertRecorder() && Recorder->Play(FileName());
|
return DvbApi.StartReplay(FileName());
|
||||||
}
|
}
|
||||||
|
|
||||||
void cRecording::Stop(void)
|
void cRecording::Stop(void)
|
||||||
{
|
{
|
||||||
if (Recorder)
|
DvbApi.StopRecord();
|
||||||
Recorder->Stop();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- cRecordings -----------------------------------------------------------
|
// --- cRecordings -----------------------------------------------------------
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'osm.c' for copyright information and
|
* See the main source file 'osm.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: recording.h 1.1 2000/03/05 15:57:27 kls Exp $
|
* $Id: recording.h 1.2 2000/04/14 15:12:42 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __RECORDING_H
|
#ifndef __RECORDING_H
|
||||||
@ -15,21 +15,16 @@
|
|||||||
#include "dvbapi.h"
|
#include "dvbapi.h"
|
||||||
#include "tools.h"
|
#include "tools.h"
|
||||||
|
|
||||||
extern cDvbRecorder *Recorder;
|
|
||||||
|
|
||||||
void AssertFreeDiskSpace(void);
|
void AssertFreeDiskSpace(void);
|
||||||
|
|
||||||
class cRecording : public cListObject {
|
class cRecording : public cListObject {
|
||||||
private:
|
|
||||||
bool AssertRecorder(void);
|
|
||||||
public:
|
public:
|
||||||
char *name;
|
char *name;
|
||||||
char *fileName;
|
char *fileName;
|
||||||
time_t start;
|
time_t start;
|
||||||
char quality;
|
|
||||||
int priority;
|
int priority;
|
||||||
int lifetime;
|
int lifetime;
|
||||||
cRecording(const char *Name, time_t Start, char Quality, int Priority, int LifeTime);
|
cRecording(const char *Name, time_t Start, int Priority, int LifeTime);
|
||||||
cRecording(cTimer *Timer);
|
cRecording(cTimer *Timer);
|
||||||
cRecording(const char *FileName);
|
cRecording(const char *FileName);
|
||||||
~cRecording();
|
~cRecording();
|
||||||
|
9
remote.c
9
remote.c
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'osm.c' for copyright information and
|
* See the main source file 'osm.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: remote.c 1.1 2000/02/19 13:36:48 kls Exp $
|
* $Id: remote.c 1.2 2000/04/15 16:00:51 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "remote.h"
|
#include "remote.h"
|
||||||
@ -221,7 +221,7 @@ bool cRcIo::String(char *s)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Number(n, mode == modeH);
|
return Number(n, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cRcIo::DetectCode(unsigned char *Code, unsigned short *Address)
|
bool cRcIo::DetectCode(unsigned char *Code, unsigned short *Address)
|
||||||
@ -244,8 +244,11 @@ bool cRcIo::DetectCode(unsigned char *Code, unsigned short *Address)
|
|||||||
String(buf);
|
String(buf);
|
||||||
SetCode(*Code, 0);
|
SetCode(*Code, 0);
|
||||||
unsigned int Command;
|
unsigned int Command;
|
||||||
if (GetCommand(&Command, Address))
|
if (GetCommand(&Command, Address)) {
|
||||||
|
SetMode(modeB);
|
||||||
|
String("----");
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
if (*Code < 'D') {
|
if (*Code < 'D') {
|
||||||
(*Code)++;
|
(*Code)++;
|
||||||
return false;
|
return false;
|
||||||
|
15
timers.conf
15
timers.conf
@ -1,6 +1,9 @@
|
|||||||
1:2:-----S-:2205:2320:H:99:99:Wochenshow
|
1:15:MTWTF--:1828:1901:10:5:nano
|
||||||
0:15:M------:2125:2205:H:99:99:Neues
|
1:3:M------:2110:2230:99:10:SevenDays
|
||||||
1:15:MTWTF--:1828:1901:M:10:5:nano
|
1:10:-T-----:2058:2150:99:10:Quarks
|
||||||
1:3:M------:2110:2230:H:99:99:SevenDays
|
1:3:---T---:2158:2300:99:10:Switch
|
||||||
1:3:---T---:2215:2300:H:99:99:Switch
|
1:2:----F--:2110:2155:99:10:Anke
|
||||||
1:14:------S:2210:2255:H:99:99:Olli
|
1:1:----F--:2210:2325:99:10:7Tage7Koepfe
|
||||||
|
1:15:-----S-:1358:1435:99:7:Neues
|
||||||
|
1:1:-----S-:1445:1600:99:10:Hammerman
|
||||||
|
1:2:-----S-:2205:2320:99:10:Wochenshow
|
||||||
|
91
tools.c
91
tools.c
@ -4,18 +4,46 @@
|
|||||||
* See the main source file 'osm.c' for copyright information and
|
* See the main source file 'osm.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: tools.c 1.2 2000/03/05 14:33:58 kls Exp $
|
* $Id: tools.c 1.3 2000/04/15 15:10:05 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define _GNU_SOURCE
|
||||||
#include "tools.h"
|
#include "tools.h"
|
||||||
|
#include <dirent.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#define MaxBuffer 1000
|
#define MaxBuffer 1000
|
||||||
|
|
||||||
|
int SysLogLevel = 3;
|
||||||
|
|
||||||
|
void writechar(int filedes, char c)
|
||||||
|
{
|
||||||
|
write(filedes, &c, sizeof(c));
|
||||||
|
}
|
||||||
|
|
||||||
|
void writeint(int filedes, int n)
|
||||||
|
{
|
||||||
|
write(filedes, &n, sizeof(n));
|
||||||
|
}
|
||||||
|
|
||||||
|
char readchar(int filedes)
|
||||||
|
{
|
||||||
|
char c;
|
||||||
|
read(filedes, &c, 1);
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool readint(int filedes, int &n)
|
||||||
|
{
|
||||||
|
//XXX timeout!!
|
||||||
|
return read(filedes, &n, sizeof(n));
|
||||||
|
}
|
||||||
|
|
||||||
char *readline(FILE *f)
|
char *readline(FILE *f)
|
||||||
{
|
{
|
||||||
static char buffer[MaxBuffer];
|
static char buffer[MaxBuffer];
|
||||||
@ -30,36 +58,83 @@ char *readline(FILE *f)
|
|||||||
|
|
||||||
int time_ms(void)
|
int time_ms(void)
|
||||||
{
|
{
|
||||||
|
static time_t t0 = 0;
|
||||||
struct timeval t;
|
struct timeval t;
|
||||||
if (gettimeofday(&t, NULL) == 0)
|
if (gettimeofday(&t, NULL) == 0) {
|
||||||
return t.tv_sec * 1000 + t.tv_usec / 1000;
|
if (t0 == 0)
|
||||||
|
t0 = t.tv_sec; // this avoids an overflow (we only work with deltas)
|
||||||
|
return (t.tv_sec - t0) * 1000 + t.tv_usec / 1000;
|
||||||
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MakeDirs(const char *FileName)
|
void delay_ms(int ms)
|
||||||
|
{
|
||||||
|
int t0 = time_ms();
|
||||||
|
while (time_ms() - t0 < ms)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MakeDirs(const char *FileName, bool IsDirectory)
|
||||||
{
|
{
|
||||||
bool result = true;
|
bool result = true;
|
||||||
char *s = strdup(FileName);
|
char *s = strdup(FileName);
|
||||||
char *p = s;
|
char *p = s;
|
||||||
if (*p == '/')
|
if (*p == '/')
|
||||||
p++;
|
p++;
|
||||||
while ((p = strchr(p, '/')) != NULL) {
|
while ((p = strchr(p, '/')) != NULL || IsDirectory) {
|
||||||
*p = 0;
|
if (p)
|
||||||
|
*p = 0;
|
||||||
struct stat fs;
|
struct stat fs;
|
||||||
if (stat(s, &fs) != 0 || !S_ISDIR(fs.st_mode)) {
|
if (stat(s, &fs) != 0 || !S_ISDIR(fs.st_mode)) {
|
||||||
isyslog(LOG_INFO, "creating directory %s", s);
|
isyslog(LOG_INFO, "creating directory %s", s);
|
||||||
if (mkdir(s, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) == -1) {
|
if (mkdir(s, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) == -1) {
|
||||||
esyslog(LOG_ERR, "ERROR while creating directory %s: %s", s, strerror(errno));
|
esyslog(LOG_ERR, "ERROR: %s: %s", s, strerror(errno));
|
||||||
result = false;
|
result = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*p++ = '/';
|
if (p)
|
||||||
|
*p++ = '/';
|
||||||
|
else
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
delete s;
|
delete s;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool RemoveFileOrDir(const char *FileName)
|
||||||
|
{
|
||||||
|
struct stat st;
|
||||||
|
if (stat(FileName, &st) == 0) {
|
||||||
|
if (S_ISDIR(st.st_mode)) {
|
||||||
|
DIR *d = opendir(FileName);
|
||||||
|
if (d) {
|
||||||
|
struct dirent *e;
|
||||||
|
while ((e = readdir(d)) != NULL) {
|
||||||
|
if (strcmp(e->d_name, ".") && strcmp(e->d_name, "..")) {
|
||||||
|
char *buffer;
|
||||||
|
asprintf(&buffer, "%s/%s", FileName, e->d_name);
|
||||||
|
if (remove(buffer) < 0)
|
||||||
|
esyslog(LOG_ERR, "ERROR: %s: %s", buffer, strerror(errno));
|
||||||
|
delete buffer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
closedir(d);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
esyslog(LOG_ERR, "ERROR: %s: %s", FileName, strerror(errno));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (remove(FileName) == 0)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
esyslog(LOG_ERR, "ERROR: %s: %s", FileName, strerror(errno));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// --- cListObject -----------------------------------------------------------
|
// --- cListObject -----------------------------------------------------------
|
||||||
|
|
||||||
cListObject::cListObject(void)
|
cListObject::cListObject(void)
|
||||||
|
24
tools.h
24
tools.h
@ -4,7 +4,7 @@
|
|||||||
* See the main source file 'osm.c' for copyright information and
|
* See the main source file 'osm.c' for copyright information and
|
||||||
* how to reach the author.
|
* how to reach the author.
|
||||||
*
|
*
|
||||||
* $Id: tools.h 1.2 2000/03/05 16:14:05 kls Exp $
|
* $Id: tools.h 1.3 2000/04/15 15:09:47 kls Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef __TOOLS_H
|
#ifndef __TOOLS_H
|
||||||
@ -13,18 +13,28 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <syslog.h>
|
#include <syslog.h>
|
||||||
|
|
||||||
//TODO
|
extern int SysLogLevel;
|
||||||
#define dsyslog syslog
|
|
||||||
#define esyslog syslog
|
#define esyslog if (SysLogLevel > 0) syslog
|
||||||
#define isyslog syslog
|
#define isyslog if (SysLogLevel > 1) syslog
|
||||||
|
#define dsyslog if (SysLogLevel > 2) syslog
|
||||||
|
|
||||||
|
#define LOG_ERROR esyslog(LOG_ERR, "ERROR (%s,%d): %s", __FILE__, __LINE__, strerror(errno))
|
||||||
|
#define LOG_ERROR_STR(s) esyslog(LOG_ERR, "ERROR: %s: %s", s, strerror(errno));
|
||||||
|
|
||||||
#define SECSINDAY 86400
|
#define SECSINDAY 86400
|
||||||
|
|
||||||
#define DELETENULL(p) (delete (p), p = NULL)
|
#define DELETENULL(p) (delete (p), p = NULL)
|
||||||
|
|
||||||
|
void writechar(int filedes, char c);
|
||||||
|
void writeint(int filedes, int n);
|
||||||
|
char readchar(int filedes);
|
||||||
|
bool readint(int filedes, int &n);
|
||||||
char *readline(FILE *f);
|
char *readline(FILE *f);
|
||||||
int time_ms(void);
|
int time_ms(void);
|
||||||
bool MakeDirs(const char *FileName);
|
void delay_ms(int ms);
|
||||||
|
bool MakeDirs(const char *FileName, bool IsDirectory = false);
|
||||||
|
bool RemoveFileOrDir(const char *FileName);
|
||||||
|
|
||||||
class cListObject {
|
class cListObject {
|
||||||
private:
|
private:
|
||||||
@ -47,7 +57,7 @@ public:
|
|||||||
virtual ~cListBase();
|
virtual ~cListBase();
|
||||||
void Add(cListObject *Object);
|
void Add(cListObject *Object);
|
||||||
void Del(cListObject *Object);
|
void Del(cListObject *Object);
|
||||||
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);
|
||||||
|
Loading…
Reference in New Issue
Block a user